-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgazua.py
162 lines (117 loc) · 4.42 KB
/
gazua.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
# -*- coding: utf-8 -*-
import os
import sys
import collections
import urwid
import ssh
from uuid import uuid4
from logger import log
from widget import SelectableText
from widget import SSHCheckBox
from widget import SearchableFrame
from urwid import Edit
from urwid import Text
from urwid import Columns
from urwid import MainLoop
from urwid import AttrMap
from urwid import LineBox
from urwid import ListBox
from urwid import SimpleFocusListWalker
SEARCH_EDIT = Edit('search: ')
HEADER = AttrMap(SEARCH_EDIT, 'header')
SESSION_NAME_PREFIX = "gz-"
SELECTED_HOSTS = []
GROUP_WIDGETS = []
HOST_WIDGETS = collections.OrderedDict()
def create_tmux_command():
session = create_session_name()
commands = [
"tmux new-session -s %s -d -x 2000 -y 2000" % session,
"tmux send-keys -t %s 'ssh %s' C-m" % (session, SELECTED_HOSTS[0])
]
is_multi_selection = len(SELECTED_HOSTS) > 1
if is_multi_selection:
for i, hostname in enumerate(SELECTED_HOSTS[1:]):
commands += [
"tmux split-window -v -t %s" % session,
"tmux send-keys -t %s:0.%d 'ssh %s' C-m" % (
session, i + 1, hostname)
]
commands += [
"tmux select-layout 'tiled'",
"tmux set-window-option synchronize-panes on",
"tmux attach -t %s" % session
]
return commands
def create_session_name():
return SESSION_NAME_PREFIX + str(uuid4().hex)
def run_tmux():
is_tmux_runnable = len(SELECTED_HOSTS) > 0
if is_tmux_runnable:
commands = create_tmux_command()
os.system("; ".join(commands))
sys.exit(0)
def on_group_changed():
focus_item = group_listbox.get_focus()
for group_widget in GROUP_WIDGETS:
if group_widget == focus_item[0]:
group_widget.set_attr_map({None: 'group_focus'})
else:
group_widget.set_attr_map({None: None})
group_widget = focus_item[0].original_widget[0].text
host_listbox.body = SimpleFocusListWalker(HOST_WIDGETS[group_widget])
for widget_attrs in HOST_WIDGETS.values():
for host_attr in widget_attrs:
host_attr.original_widget[0].set_state(False)
def on_host_selected(checkbox, state, hostname):
if state:
SELECTED_HOSTS.append(hostname)
else:
SELECTED_HOSTS.remove(hostname)
configs = ssh.parse_config()
for group, hosts in configs.items():
if group not in HOST_WIDGETS:
HOST_WIDGETS[group] = []
for host, values in hosts.items():
host_widget = SSHCheckBox(run_tmux, host)
ipaddr = values.get('HostName', 'unknown')
ipaddr_widget = Text(ipaddr, align='left')
column_widget = Columns([host_widget, ipaddr_widget], dividechars=2)
urwid.connect_signal(host_widget, 'change', on_host_selected, host)
host_widget = AttrMap(column_widget, None, 'host_focus')
HOST_WIDGETS[group].append(host_widget)
group_widget = SelectableText(group, wrap='clip')
count_widget = Text(str(len(hosts)), align='left')
arrow_widget = Text(">", align='right')
column_widget = Columns(
[group_widget, count_widget, arrow_widget], dividechars=2)
group_widget = AttrMap(column_widget, None)
GROUP_WIDGETS.append(group_widget)
group_model = SimpleFocusListWalker(GROUP_WIDGETS)
group_listbox = ListBox(group_model)
group_box = LineBox(group_listbox, tlcorner='', tline='', lline='',
trcorner='', blcorner='', rline='│', bline='', brcorner='')
urwid.connect_signal(group_model, "modified", on_group_changed)
first_host_widget = HOST_WIDGETS[HOST_WIDGETS.keys()[0]]
host_model = SimpleFocusListWalker(first_host_widget)
host_listbox = ListBox(host_model)
host_box = LineBox(host_listbox, tlcorner='', tline='', lline='',
trcorner='', blcorner='', rline='', bline='', brcorner='')
GROUP_WIDGETS[0].set_attr_map({None: 'group_focus'})
columns = Columns([group_box, host_box])
body = LineBox(columns)
palette = [
('header', 'white', 'dark red', 'bold'),
('group', 'black', 'yellow', 'bold'),
('host', 'black', 'dark green'),
('group_focus', 'black', 'dark green'),
('host_focus', 'black', 'yellow'),
('settler', 'black', 'dark green'),
]
frame = SearchableFrame(SEARCH_EDIT, body, header=HEADER)
def show_or_exit(key):
if key == 'esc':
raise urwid.ExitMainLoop()
loop = MainLoop(frame, palette, handle_mouse=False,
unhandled_input=show_or_exit)
loop.run()