...
 
Commits (1)
from __future__ import print_function
import os
import sys
import json
import signal
import logging
import argparse
......@@ -36,10 +38,15 @@ Add '-h' after individual commands for command help.
Node names may be specified with wildcard/globbing, e.g. 'SUS_*'.
A single '*' will act on all configured nodes (where appropriate).
""",
prefix_chars='-+',
)
parser.add_argument('-d', '--debug', action='store_true',
help="print debug information to stderr")
parser.add_argument('+t', dest='terminal', action='store_false',
help="disable ssh pseudo-term for remote connections")
parser.add_argument('-x', dest='usex', action='store_true',
help="run command in background xterm")
# parser.add_argument('-v', '--version', action='version',
# version='Guardctrl {}'.format(__version__),
# help="print guardctrl version and exit")
......@@ -353,13 +360,16 @@ subparser.add_parser('journalctl')
##################################################
def main():
signal.signal(signal.SIGINT, signal.SIG_DFL)
signal.signal(signal.SIGPIPE, signal.SIG_DFL)
def main_local():
# handle invocation as ssh ForceCommand
if os.getenv('SSH_ORIGINAL_COMMAND') and len(sys.argv) == 1:
sys.argv += os.getenv('SSH_ORIGINAL_COMMAND').split()
ssh_args = os.getenv('SSH_ORIGINAL_COMMAND')
if ssh_args and len(sys.argv) == 1:
# assume json argument encoding if the first character is the
# json bracket list start character
if ssh_args[0] == '[':
sys.argv += json.loads(ssh_args)
else:
sys.argv += os.getenv('SSH_ORIGINAL_COMMAND').split()
# parse known args first, just to get debug flag and handle direct
# sys commands
......@@ -383,5 +393,80 @@ def main():
args.func(args)
def main_remote():
parser = argparse.ArgumentParser(prefix_chars='-+', add_help=False)
parser.add_argument('+t', dest='terminal', action='store_false')
parser.add_argument('-x', dest='usex', action='store_true')
wargs, args = parser.parse_known_args()
IFO = os.getenv('IFO')
GUARDCTRL_USER = os.getenv('GUARDCTRL_USER', 'guardian')
GUARDCTRL_HOST = os.getenv('GUARDCTRL_HOST', '{}guardian'.format(IFO.lower()))
SSH_CMD = [
'ssh',
'-q',
'-S', '~/.ssh/controls/%r@%h:%p',
'-o', 'ControlMaster=auto',
'-o', 'ControlPersist=600',
]
XTERM_CMD = [
'xterm',
'-hold',
'-si', '-sk', '+sb',
'-geometry', '150x80',
'-bg', 'DodgerBlue4',
'-fg', 'white',
'-fa', 'Monospace',
'-fs', '10',
]
# force TTY by default, with "+t" option to unset and allow
# separate stdout/stderr streams
if wargs.terminal:
SSH_CMD += ['-t']
SSH_CMD += [
'{}@{}'.format(GUARDCTRL_USER, GUARDCTRL_HOST),
'--',
]
# create a directory for the ssh control sockets
try:
os.makedirs('~/.ssh/controls/')
except:
pass
# json encode commands for ssh, to pass spaces in a reasonable way
args_enc = json.dumps(args)
if wargs.usex:
cmd = XTERM_CMD + \
['-title', 'guardctrl: {}'.format(args), '-e'] + \
SSH_CMD + [args_enc]
# launch in background
subprocess.Popen(cmd)
else:
cmd = SSH_CMD + [args_enc]
# launch in foreground
subprocess.call(cmd)
def main():
signal.signal(signal.SIGINT, signal.SIG_DFL)
signal.signal(signal.SIGPIPE, signal.SIG_DFL)
if os.path.exists('~/.guardctrl-home') or os.getenv('GUARDCTRL_LOCAL'):
main_local()
elif os.getenv('GUARDCTRL_HOST'):
main_remote()
else:
main_local()
if __name__ == '__main__':
main()