Skip to content

Commit d7e3515

Browse files
committed
Add new subcommand: mosh
1 parent 2db7e21 commit d7e3515

File tree

1 file changed

+57
-1
lines changed

1 file changed

+57
-1
lines changed

geofrontcli/cli.py

Lines changed: 57 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,12 @@
4141
except subprocess.CalledProcessError:
4242
pass
4343

44+
MOSH_PROGRAM = None
45+
try:
46+
MOSH_PROGRAM = subprocess.check_output([WHICH_CMD, 'mosh']).strip() or None
47+
except subprocess.CalledProcessError:
48+
pass
49+
4450

4551
parser = argparse.ArgumentParser(description='Geofront client utility')
4652
parser.add_argument(
@@ -287,6 +293,33 @@ def get_ssh_options(remote):
287293
return options
288294

289295

296+
def get_mosh_options(remote, ssh):
297+
"""Translate the given ``remote`` to a corresponding :program:`mosh`
298+
options. For example, it returns the following list for ``'user@host'``::
299+
300+
['--', 'user@host']
301+
302+
The remote can contain the port number or omit the user login as well
303+
e.g. ``'host:22'``::
304+
305+
['--ssh="/usr/bin/ssh -p 22"', '--', 'host']
306+
307+
"""
308+
remote_match = REMOTE_PATTERN.match(remote)
309+
if not remote_match:
310+
raise ValueError('invalid remote format: ' + str(remote))
311+
options = []
312+
user = remote_match.group('user')
313+
host = remote_match.group('host')
314+
if user:
315+
host = user + '@' + host
316+
port = remote_match.group('port')
317+
if port:
318+
ssh += b' -p ' + port.encode('utf-8')
319+
options.extend([b'--ssh', ssh, b'--', host])
320+
return options
321+
322+
290323
@subparser
291324
def colonize(args):
292325
"""Make the given remote to allow the current master key.
@@ -395,6 +428,29 @@ def scp(args):
395428
scp.add_argument('destination', help='the destination path')
396429

397430

431+
@subparser
432+
def mosh(args, alias=None):
433+
"""Mosh to the remote through Geofront's temporary authorization."""
434+
if not args.mosh:
435+
mosh.error('could not detect mosh client.')
436+
remote = authorize.call(args, alias=alias)
437+
try:
438+
options = get_mosh_options(remote, ssh=args.ssh)
439+
except ValueError as e:
440+
mosh.error(str(e))
441+
command = [args.mosh] + options
442+
print(command)
443+
subprocess.call(command)
444+
445+
446+
mosh.add_argument('remote', help='the remote alias to mosh')
447+
mosh.add_argument(
448+
'-M', '--mosh',
449+
default=MOSH_PROGRAM,
450+
required=False,
451+
help='mosh client to use' + (' [%(default)s]' if MOSH_PROGRAM else '')
452+
)
453+
398454
@subparser
399455
def go(args):
400456
"""Select a remote and SSH to it at once (in interactive way)."""
@@ -407,7 +463,7 @@ def go(args):
407463
ssh.call(args, alias=alias)
408464

409465

410-
for p in authenticate, authorize, start, ssh, scp, go:
466+
for p in authenticate, authorize, start, ssh, scp, mosh, go:
411467
p.add_argument(
412468
'-O', '--no-open-browser',
413469
dest='open_browser',

0 commit comments

Comments
 (0)