eoptasks: execute actual ssh command in a fork, to get return code
This commit is contained in:
parent
a8ea335101
commit
311e4e6983
|
@ -38,6 +38,7 @@ import json
|
|||
import os
|
||||
import random
|
||||
import re
|
||||
import subprocess
|
||||
import socket
|
||||
import sys
|
||||
import time
|
||||
|
@ -64,12 +65,6 @@ class Server:
|
|||
def __repr__(self):
|
||||
return '<Server %s %r>' % (self.name, self.keywords)
|
||||
|
||||
def shell(self):
|
||||
return 'ssh %s' % self.name
|
||||
|
||||
def cmd(self, cmd, *args):
|
||||
return 'ssh -t %s "%s %s"' % (self.name, cmd, ' '.join(args))
|
||||
|
||||
|
||||
def get_servers():
|
||||
servers = []
|
||||
|
@ -97,6 +92,8 @@ def parse_args():
|
|||
parser.add_argument('-l', '--list-servers', action='store_true')
|
||||
parser.add_argument('--session-name', dest='session_name', type=str)
|
||||
parser.add_argument('--status-window', action='store_true')
|
||||
parser.add_argument('--command-window', action='store_true')
|
||||
parser.add_argument('--command-server-name', dest='command_server_name', type=str)
|
||||
parser.add_argument('-k', dest='keywords', type=str)
|
||||
parser.add_argument('cmd', type=str, nargs='?', default=None)
|
||||
parser.add_argument('args', nargs=argparse.REMAINDER)
|
||||
|
@ -118,7 +115,8 @@ def filter_servers(servers, args):
|
|||
selected_servers = servers
|
||||
return selected_servers
|
||||
|
||||
def status_window(session_name):
|
||||
def status_window(args):
|
||||
session_name = args.session_name
|
||||
curses.setupterm()
|
||||
window = curses.initscr()
|
||||
window.addstr(0, 0, 'eoptasks', curses.A_STANDOUT)
|
||||
|
@ -130,6 +128,7 @@ def status_window(session_name):
|
|||
sock.bind(server_address)
|
||||
sock.listen(1)
|
||||
e = None
|
||||
servers_results = {}
|
||||
while True:
|
||||
connection, client_address = sock.accept()
|
||||
try:
|
||||
|
@ -139,10 +138,15 @@ def status_window(session_name):
|
|||
if not data:
|
||||
break
|
||||
json_msg += data
|
||||
servers_info = json.loads(json_msg.decode('utf-8'))
|
||||
msg = json.loads(json_msg.decode('utf-8'))
|
||||
finally:
|
||||
connection.close()
|
||||
|
||||
if msg.get('@type') == 'servers-info':
|
||||
servers_info = msg['info']
|
||||
elif msg.get('@type') == 'server-result':
|
||||
servers_results.update(msg['info'])
|
||||
|
||||
try:
|
||||
height, width = window.getmaxyx()
|
||||
max_length = max([len(x) for x in servers_info.keys()]) + 4
|
||||
|
@ -156,6 +160,8 @@ def status_window(session_name):
|
|||
'running': '⏳',
|
||||
'done': '🆗',
|
||||
}.get(servers_info[server_name]['status'], '💤')
|
||||
if servers_results.get(server_name) == 'error':
|
||||
status_icon = '❗'
|
||||
window.addstr(y, x, status_icon)
|
||||
if y > height-4:
|
||||
break
|
||||
|
@ -174,10 +180,57 @@ def status_window(session_name):
|
|||
time.sleep(5)
|
||||
|
||||
|
||||
def send_status_message(tmux_session_name, msg):
|
||||
sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
|
||||
server_address = '/tmp/.eoptasks.%s' % tmux_session_name
|
||||
try:
|
||||
sock.connect(server_address)
|
||||
except socket.error as e:
|
||||
return
|
||||
sock.sendall(json.dumps(msg).encode('utf-8'))
|
||||
sock.close()
|
||||
|
||||
|
||||
def command_window(args):
|
||||
tmux_session_name = args.session_name
|
||||
cmd = {
|
||||
'apt.update': 'sudo apt update',
|
||||
'apt.upgrade': 'sudo apt update && sudo apt full-upgrade -y',
|
||||
# collectstatic is useful after an upgrade of gadjo.
|
||||
'collectstatic': '''sudo -u authentic-multitenant authentic2-multitenant-manage collectstatic --noinput;
|
||||
sudo -u bijoe bijoe-manage collectstatic --noinput;
|
||||
sudo -u chrono chrono-manage collectstatic --noinput;
|
||||
sudo -u combo combo-manage collectstatic --noinput;
|
||||
sudo -u corbo corbo-manage collectstatic --noinput;
|
||||
sudo -u fargo fargo-manage collectstatic --noinput;
|
||||
sudo -u hobo hobo-manage collectstatic --noinput;
|
||||
sudo -u passerelle passerelle-manage collectstatic --noinput;
|
||||
sudo -u wcs wcs-manage collectstatic;
|
||||
/bin/true'''.replace('\n', ''),
|
||||
# combo.reload is useful to get a new {% start_timestamp %} after an
|
||||
# upgrade of publik-base-theme.
|
||||
'combo.reload': '''sudo service combo reload; /bin/true''',
|
||||
# hobo-agent.restart is the fastest way to get the number of threads
|
||||
# used by celery under control :/
|
||||
'hobo-agent.restart': '''test -e /etc/hobo-agent/settings.py && sudo supervisorctl restart hobo-agent''',
|
||||
}.get(args.cmd, args.cmd)
|
||||
if args.args:
|
||||
cmd += ' ' + ' '.join(['"%s"' % x for x in args.args])
|
||||
rc = subprocess.call(['ssh', '-t', args.command_server_name] + [cmd])
|
||||
if rc != 0:
|
||||
send_status_message(tmux_session_name,
|
||||
{'@type': 'server-result',
|
||||
'info': {args.command_server_name: 'error'}})
|
||||
input('type enter to quit --> ')
|
||||
|
||||
args = parse_args()
|
||||
|
||||
if args.session_name and args.status_window:
|
||||
status_window(args.session_name)
|
||||
if args.status_window:
|
||||
status_window(args)
|
||||
sys.exit(0)
|
||||
|
||||
if args.command_window:
|
||||
command_window(args)
|
||||
sys.exit(0)
|
||||
|
||||
servers = get_servers()
|
||||
|
@ -203,6 +256,7 @@ def init_tmux_session():
|
|||
os.unlink(server_address)
|
||||
except OSError:
|
||||
pass
|
||||
os.environ['SHELL'] = '/bin/sh'
|
||||
os.system('tmux new-session -s %s -n 🌑 -d %s --status-window --session-name %s' % (
|
||||
tmux_session_name, sys.argv[0], tmux_session_name))
|
||||
return tmux_session_name
|
||||
|
@ -220,28 +274,6 @@ else:
|
|||
tmux = libtmux.Server()
|
||||
session = tmux.find_where({'session_name': tmux_session_name})
|
||||
|
||||
cmd = {
|
||||
'apt.update': 'sudo apt update',
|
||||
'apt.upgrade': 'sudo apt update && sudo apt full-upgrade -y',
|
||||
# collectstatic is useful after an upgrade of gadjo.
|
||||
'collectstatic': '''sudo -u authentic-multitenant authentic2-multitenant-manage collectstatic --noinput;
|
||||
sudo -u bijoe bijoe-manage collectstatic --noinput;
|
||||
sudo -u chrono chrono-manage collectstatic --noinput;
|
||||
sudo -u combo combo-manage collectstatic --noinput;
|
||||
sudo -u corbo corbo-manage collectstatic --noinput;
|
||||
sudo -u fargo fargo-manage collectstatic --noinput;
|
||||
sudo -u hobo hobo-manage collectstatic --noinput;
|
||||
sudo -u passerelle passerelle-manage collectstatic --noinput;
|
||||
sudo -u wcs wcs-manage collectstatic;
|
||||
/bin/true'''.replace('\n', ''),
|
||||
# combo.reload is useful to get a new {% start_timestamp %} after an
|
||||
# upgrade of publik-base-theme.
|
||||
'combo.reload': '''sudo service combo reload; /bin/true''',
|
||||
# hobo-agent.restart is the fastest way to get the number of threads
|
||||
# used by celery under control :/
|
||||
'hobo-agent.restart': '''test -e /etc/hobo-agent/settings.py && sudo supervisorctl restart hobo-agent''',
|
||||
}.get(args.cmd, args.cmd)
|
||||
|
||||
status_window = session.attached_window
|
||||
|
||||
all_servers = selected_servers[:]
|
||||
|
@ -260,15 +292,7 @@ else:
|
|||
server_info['status'] = 'running'
|
||||
elif server_info['status'] == 'running':
|
||||
server_info['status'] = 'done'
|
||||
|
||||
sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
|
||||
server_address = '/tmp/.eoptasks.%s' % tmux_session_name
|
||||
try:
|
||||
sock.connect(server_address)
|
||||
except socket.error:
|
||||
return
|
||||
sock.sendall(json.dumps(servers_info).encode('utf-8'))
|
||||
sock.close()
|
||||
send_status_message(tmux_session_name, {'@type': 'servers-info', 'info': servers_info})
|
||||
|
||||
while selected_servers:
|
||||
current_clusters = [cluster_name(x.name) for x in session.list_windows()]
|
||||
|
@ -276,10 +300,16 @@ else:
|
|||
if cluster_name(server.name) in current_clusters:
|
||||
continue
|
||||
selected_servers.remove(server)
|
||||
window_cmd = '%s --session-name %s --command-window --command-server-name %s "%s" %s' % (
|
||||
sys.argv[0],
|
||||
tmux_session_name,
|
||||
server.name,
|
||||
args.cmd,
|
||||
' '.join(['"%s"' % x for x in args.args]))
|
||||
session.new_window(
|
||||
attach=False,
|
||||
window_name=server.name,
|
||||
window_shell=server.cmd(cmd, *args.args))
|
||||
window_shell=window_cmd)
|
||||
break
|
||||
else:
|
||||
time.sleep(0.1)
|
||||
|
|
Loading…
Reference in New Issue