import os
import sys
import re
import time
import paramiko
import fabric
import tarfile
from tkinter import *
from tkinter import messagebox
from threading import Thread
# TODO: config
height = 600
width = 700
server_password_default = 'gta'
run_file_endswith = '.sh'
run_cmd = 'bash'
connection_timeout = 10
info_connection_timeout = 2
def get_servers() -> dict:
servers ={}
with open('servers.txt', 'r') as f:
for line in f.readlines():
line_ = line.split(',')
line_ = [t.strip() for t in line_]
name = line_[0]
url = line_[1]
url_ = url.split('@')
user = url_[0]
ip, port = url_[1].split(':')
servers[name] = {'user':user, 'ip':ip, 'port':port}
return servers
servers = get_servers()
# print('servers: ', servers)
def get_envs(env_list_dir='.') -> list:
envs = []
for dir in os.listdir(env_list_dir):
if not os.path.isdir(dir): continue
if dir.startswith('_'): continue
envs.append(dir)
return envs
envs = get_envs()
# print('envs:', envs)
def print_server_info(name):
server = servers[name]
return name + ' ' + server['user'] + '@' + server['ip'] + ':' + server['port']
# window
window = Tk()
window.title('autoenv')
screenwidth = window.winfo_screenwidth()
screenheight = window.winfo_screenheight()
alignstr = '%dx%d+%d+%d' % (width, height, (screenwidth-width)/2, (screenheight-height)/2*0.8)
window.geometry(alignstr)
# frame_list
frame_list = Frame()
frame_list.pack(side=TOP, fill=BOTH, expand=True)
list_envs, list_servers = Listbox(frame_list, exportselection=False), Listbox(frame_list, exportselection=False)
scrollnar_envs, scrollnar_servers = Scrollbar(frame_list), Scrollbar(frame_list)
list_envs.config(yscrollcommand=scrollnar_envs.set)
list_servers.config(yscrollcommand=scrollnar_servers.set)
scrollnar_envs.config(command=list_envs.yview)
scrollnar_servers.config(command=list_servers.yview)
list_envs.pack(side=LEFT, fill=BOTH, expand=True)
scrollnar_envs.pack(side=LEFT, fill=Y)
list_servers.pack(side=LEFT, fill=BOTH, expand=True)
scrollnar_servers.pack(side=LEFT, fill=Y)
for name in envs: list_envs.insert('end', name)
for name in servers.keys(): list_servers.insert(END, print_server_info(name))
[list_servers.itemconfig(i, bg='#e0f0ff') for i in range(len(servers.keys())) if i%2]
[list_envs.itemconfig(i, bg='#e0f0ff') for i in range(len(envs)) if i%2]
# frame_console
frame_console = Frame()
frame_console.pack(side=TOP, fill=BOTH, expand=True)
console = Text(frame_console, fg='white', bg='black')
scrollnar_console = Scrollbar(frame_console)
console.config(yscrollcommand=scrollnar_console.set)
scrollnar_console.config(command=console.yview)
console.pack(side=LEFT, fill=BOTH, expand=True)
scrollnar_console.pack(side=LEFT, fill=Y)
class Redirector:
def __init__(self, text) -> None:
self.text = text
def write(self, string):
def write_():
self.text.insert('end', string)
self.text.see('end')
Thread(target=write_, daemon=True).start()
def flush(self): pass
sys.stdout = Redirector(console)
# frame_ctl
frame_ctl = Frame(window).pack(side=TOP, fill=X, expand=False)
lb_run = Label(frame_ctl, text='runfile: ').pack(side=LEFT)
runfile_v = StringVar(value='run' + run_file_endswith)
entry_run = Entry(frame_ctl, textvariable=runfile_v, width=12).pack(side=LEFT, fill=X, expand=True)
lb_password = Label(frame_ctl, text='password: ').pack(side=LEFT)
password_v = StringVar(value=server_password_default)
entry_password = Entry(frame_ctl, textvariable=password_v, show='*', width=12).pack(side=LEFT, fill=X, expand=True)
def check():
try:
server_name = list_servers.get(list_servers.curselection()).split(' ')[0].strip()
server = servers[server_name]
except: return False
conn = fabric.Connection(server['ip'], user=server['user'],
port=int(server['port']), connect_kwargs={"password": password_v.get()},
connect_timeout=info_connection_timeout)
try:
mem = conn.run('free -h | grep Mem', hide='stdout').stdout.strip().split(' ')
mem = [t for t in mem if len(t)>0]
disk = conn.run('df ~ -kh | grep G', hide='stdout').stdout.strip().split(' ')
disk = [t for t in disk if len(t)>0]
except:
messagebox.showinfo(title='error', message='connection: ' + server['ip'] + ':' + server['port'])
conn.close()
return False
mem_info = 'mem: ' + mem[2] + '/' + mem[1]
disk_info = 'disk: ' + disk[2] + '/' + disk[1]
print('[' + server_name + ']' + '[used/total] ' + mem_info + ', ' + disk_info)
conn.close()
return True
btn_info = Button(frame_ctl, text='Info', bg='gray', command=check).pack(side=LEFT, fill=X, expand=True)
def terminal():
try:
server_name = list_servers.get(list_servers.curselection()).split(' ')[0].strip()
server = servers[server_name]
except: return
try: env = '~/' + list_envs.get(list_envs.curselection()).strip().replace('-', '/')
except: env = '~'
os.system('start cmd /k ssh -t -p ' + server['port'] + ' ' + server['user'] + '@' + server['ip'] + ' \" cd ' + env + '; bash --login\"')
btn_terminal = Button(frame_ctl, text='Terminal', bg='gray', command=terminal).pack(side=LEFT, fill=X, expand=True)
def auth():
try:
server_name = list_servers.get(list_servers.curselection()).split(' ')[0].strip()
server = servers[server_name]
except: return
conn = fabric.Connection(server['ip'], user=server['user'],
port=server['port'], connect_kwargs={"password": password_v.get()},
connect_timeout=connection_timeout)
try:
pwd = conn.run('cd ~; pwd').stdout.strip()
except:
messagebox.showinfo(title='error', message='connection: ' + server['ip'] + ':' + server['port'])
conn.close()
return
join = os.path.join
pub_key = join(join(os.path.expanduser('~'), '.ssh'), 'id_rsa.pub')
if not os.path.exists(pub_key): os.system('ssh-keygen -t rsa')
remote_author_file = pwd + '/.ssh/authorized_keys'
local_author_file = 'authorized_keys-' + str(round(time.time()*1000))
try:
conn.get(remote_author_file, local_author_file)
with open(local_author_file, 'r') as f: lines = f.readlines()
lines = [t.strip() for t in lines if len(t)>5]
except: lines = []
with open(pub_key, 'r') as f: item = f.readlines()[0].strip()
if item in lines:
conn.close()
os.remove(local_author_file)
return
lines.append(item)
out = '\n'.join(lines)
with open(local_author_file, 'w') as f: f.write(out)
try:
conn.put(local_author_file, remote_author_file)
conn.run('chmod 600 {}'.format(remote_author_file))
except Exception as e:
messagebox.showinfo(title='error', message=str(e))
conn.close()
os.remove(local_author_file)
return
conn.close()
os.remove(local_author_file)
return
btn_auth = Button(frame_ctl, text='Auth', bg='gray', command=auth).pack(side=LEFT, fill=X, expand=True)
btn_dispatch = Button(frame_ctl, text='Dispatch', bg='gray')
def dispatch_():
try:
env = list_envs.get(list_envs.curselection()).strip()
server_name = list_servers.get(list_servers.curselection()).split(' ')[0].strip()
server = servers[server_name]
except: return
notice = messagebox.askokcancel('notice', env + ' -> ' + server_name + '\nrelevant files will be deleted')
if not notice: return
print(env, ' -> ', server_name)
def change_to_lf(endswith):
for root, _, files in os.walk(env):
for file in files:
put_localpath = os.path.realpath(os.path.join(root, file))
if put_localpath.endswith(endswith):
# print('-> lf ' + put_localpath)
with open(put_localpath, 'rb') as f: temp = f.read()
temp = temp.replace(b'\r\n', b'\n')
with open(put_localpath, 'wb') as f: f.write(temp)
change_to_lf(run_file_endswith)
# connect
conn = fabric.Connection(server['ip'], user=server['user'],
port=server['port'], connect_kwargs={"password": password_v.get()},
connect_timeout=connection_timeout)
try:
pwd = conn.run('cd ~; pwd').stdout.strip()
except:
messagebox.showinfo(title='error', message='connection: ' + server['ip'] + ':' + server['port'])
conn.close()
return
put_remotepath = pwd + '/' + '/'.join(re.split(r'[-]', env))
try:
conn.run("mkdir -p {0}; cd {0}".format(put_remotepath))
except Exception as e:
messagebox.showinfo(title='error', message=str(e))
conn.close()
return
env_file = env + '-' + str(round(time.time()*1000)) + '.tar.gz'
try:
with tarfile.open(env_file, 'w:gz') as tar: tar.add(env, arcname=os.path.basename('.'))
except Exception as e:
messagebox.showinfo(title='error', message=str(e))
conn.close()
return
try:
conn.put(env_file, put_remotepath) # no callback
except Exception as e:
messagebox.showinfo(title='error', message=str(e))
conn.close()
return
try:
conn.run("cd {0}; tar -xzvf {1}; rm -rf {1}".format(put_remotepath, env_file))
except Exception as e:
messagebox.showinfo(title='error', message=str(e))
conn.close()
os.remove(env_file)
return
os.remove(env_file)
try:
conn.run("cd {0}; {2} {1}".format(put_remotepath, runfile_v.get(), run_cmd), pty=True, encoding='utf-8')
except:
messagebox.showinfo(title='partial success', message=server_name + '\nrunfile failed')
conn.close()
return
messagebox.showinfo(title='success', message=server_name)
conn.close()
def dispatch():
def run():
btn_dispatch.config(state=DISABLED)
dispatch_()
btn_dispatch.config(state=NORMAL)
Thread(target=run, daemon=True).start()
btn_dispatch.config(command=dispatch)
btn_dispatch.pack(side=LEFT, fill=X, expand=True)
window.mainloop()
if [ ! -f ./vsc/code-server ]; then
wget https://github.com/cdr/code-server/releases/download/v3.12.0/code-server-3.12.0-linux-amd64.tar.gz -O vsc.tar.gz
mkdir ./vsc && tar -zxvf vsc.tar.gz -C ./vsc --strip-components 1
rm -rf vsc.tar.gz
fi
VSBASE=$(pwd)
IPADD=$(ifconfig | grep "inet " | grep "broadcast" | awk '{print $2}')
cd vsc
tmux kill-session -t $VSBASE
tmux new -s $VSBASE -d
for port in {8081..18081}
do
PORTCT=$(lsof -i -P -n | grep LISTEN | grep :$port | wc -l)
if [ $PORTCT = "0" ]; then
PORTUSE=$port
break
fi
done
tmux send -t $VSBASE "PASSWORD=gta ./code-server --host 0.0.0.0 --port $PORTUSE" Enter
echo http://$IPADD:$PORTUSE 2>&1 | tee ../url.log
import os
import re
import time
import paramiko
import fabric
import tarfile
from tkinter import *
from tkinter import messagebox
# TODO: config
height = 420
width = 450
server_password_default = 'gta'
run_file_endswith = '.sh'
run_cmd = 'bash'
connection_timeout = 10
info_connection_timeout = 2
def get_servers() -> dict:
servers ={}
with open('servers.txt', 'r') as f:
for line in f.readlines():
line_ = line.split(',')
line_ = [t.strip() for t in line_]
name = line_[0]
url = line_[1]
url_ = url.split('@')
user = url_[0]
ip, port = url_[1].split(':')
servers[name] = {'user':user, 'ip':ip, 'port':port}
return servers
servers = get_servers()
# print('servers: ', servers)
def get_envs(env_list_dir='.') -> list:
envs = []
for dir in os.listdir(env_list_dir):
if not os.path.isdir(dir): continue
if dir.startswith('_'): continue
envs.append(dir)
return envs
envs = get_envs()
# print('envs:', envs)
def print_server_info(name):
server = servers[name]
return name + ' ' + server['user'] + '@' + server['ip'] + ':' + server['port']
window = Tk()
window.title('autoenv')
screenwidth = window.winfo_screenwidth()
screenheight = window.winfo_screenheight()
alignstr = '%dx%d+%d+%d' % (width, height, (screenwidth-width)/2, (screenheight-height)/2*0.8)
window.geometry(alignstr)
frame_list = Frame()
frame_list.pack(side=TOP, fill=BOTH, expand=True)
list_envs, list_servers = Listbox(frame_list, exportselection=False), Listbox(frame_list, exportselection=False)
scrollnar_envs, scrollnar_servers = Scrollbar(frame_list), Scrollbar(frame_list)
list_envs.config(yscrollcommand=scrollnar_envs.set)
list_servers.config(yscrollcommand=scrollnar_servers.set)
scrollnar_envs.config(command=list_envs.yview)
scrollnar_servers.config(command=list_servers.yview)
list_envs.pack(side=LEFT, fill=BOTH, expand=True)
scrollnar_envs.pack(side=LEFT, fill=Y)
list_servers.pack(side=LEFT, fill=BOTH, expand=True)
scrollnar_servers.pack(side=LEFT, fill=Y)
for name in envs: list_envs.insert('end', name)
for name in servers.keys(): list_servers.insert(END, print_server_info(name))
[list_servers.itemconfig(i, bg='#e0f0ff') for i in range(len(servers.keys())) if i%2]
[list_envs.itemconfig(i, bg='#e0f0ff') for i in range(len(envs)) if i%2]
info = StringVar(value='[please select machine][used/total]')
lb_info = Label(textvariable=info).pack(side=TOP, fill=X)
frame_ctl = Frame(window).pack(side=TOP, fill=X, expand=False)
lb_run = Label(frame_ctl, text='runfile: ').pack(side=LEFT)
runfile_v = StringVar(value='run' + run_file_endswith)
entry_run = Entry(frame_ctl, textvariable=runfile_v, width=12).pack(side=LEFT, fill=X, expand=True)
lb_password = Label(frame_ctl, text='password: ').pack(side=LEFT)
password_v = StringVar(value=server_password_default)
entry_password = Entry(frame_ctl, textvariable=password_v, show='*', width=12).pack(side=LEFT, fill=X, expand=True)
def dispatch():
try:
env = list_envs.get(list_envs.curselection()).strip()
server_name = list_servers.get(list_servers.curselection()).split(' ')[0].strip()
server = servers[server_name]
except: return
notice = messagebox.askokcancel('notice', env + ' -> ' + server_name + '\nrelevant files will be deleted')
if not notice: return
print(env, ' -> ', server_name)
def change_to_lf(endswith):
for root, _, files in os.walk(env):
for file in files:
put_localpath = os.path.realpath(os.path.join(root, file))
if put_localpath.endswith(endswith):
# print('-> lf ' + put_localpath)
with open(put_localpath, 'rb') as f: temp = f.read()
temp = temp.replace(b'\r\n', b'\n')
with open(put_localpath, 'wb') as f: f.write(temp)
change_to_lf(run_file_endswith)
# connect
conn = fabric.Connection(server['ip'], user=server['user'],
port=server['port'], connect_kwargs={"password": password_v.get()},
connect_timeout=connection_timeout)
try:
pwd = conn.run('cd ~; pwd').stdout.strip()
except:
messagebox.showinfo(title='error', message='connection: ' + server['ip'] + ':' + server['port'])
conn.close()
return
put_remotepath = pwd + '/' + '/'.join(re.split(r'[-]', env))
try:
conn.run("mkdir -p {0}; cd {0}".format(put_remotepath))
except Exception as e:
messagebox.showinfo(title='error', message=str(e))
conn.close()
return
env_file = env + '-' + str(round(time.time()*1000)) + '.tar.gz'
try:
with tarfile.open(env_file, 'w:gz') as tar: tar.add(env, arcname=os.path.basename('.'))
except Exception as e:
messagebox.showinfo(title='error', message=str(e))
conn.close()
return
try:
conn.put(env_file, put_remotepath) # no callback
except Exception as e:
messagebox.showinfo(title='error', message=str(e))
conn.close()
return
try:
conn.run("cd {0}; tar -xzvf {1}; rm -rf {1}".format(put_remotepath, env_file))
except Exception as e:
messagebox.showinfo(title='error', message=str(e))
conn.close()
os.remove(env_file)
return
os.remove(env_file)
try:
conn.run("cd {0}; {2} {1}".format(put_remotepath, runfile_v.get(), run_cmd), pty=True, encoding='utf-8')
except:
messagebox.showinfo(title='partial success', message=server_name + '\nrunfile failed')
conn.close()
return
messagebox.showinfo(title='success', message=server_name)
conn.close()
def check():
try:
server_name = list_servers.get(list_servers.curselection()).split(' ')[0].strip()
server = servers[server_name]
except: return False
conn = fabric.Connection(server['ip'], user=server['user'],
port=int(server['port']), connect_kwargs={"password": password_v.get()},
connect_timeout=info_connection_timeout)
try:
mem = conn.run('free -h | grep Mem', hide='stdout').stdout.strip().split(' ')
mem = [t for t in mem if len(t)>0]
disk = conn.run('df ~ -kh | grep G', hide='stdout').stdout.strip().split(' ')
disk = [t for t in disk if len(t)>0]
except:
messagebox.showinfo(title='error', message='connection: ' + server['ip'] + ':' + server['port'])
conn.close()
return False
mem_info = 'mem: ' + mem[2] + '/' + mem[1]
disk_info = 'disk: ' + disk[2] + '/' + disk[1]
info.set('[' + server_name + ']' + '[used/total] ' + mem_info + ', ' + disk_info)
conn.close()
return True
def terminal():
try:
server_name = list_servers.get(list_servers.curselection()).split(' ')[0].strip()
server = servers[server_name]
except: return
try: env = '~/' + list_envs.get(list_envs.curselection()).strip().replace('-', '/')
except: env = '~'
os.system('start cmd /k ssh -t -p ' + server['port'] + ' ' + server['user'] + '@' + server['ip'] + ' \" cd ' + env + '; bash --login\"')
def auth():
try:
server_name = list_servers.get(list_servers.curselection()).split(' ')[0].strip()
server = servers[server_name]
except: return
conn = fabric.Connection(server['ip'], user=server['user'],
port=server['port'], connect_kwargs={"password": password_v.get()},
connect_timeout=connection_timeout)
try:
pwd = conn.run('cd ~; pwd').stdout.strip()
except:
messagebox.showinfo(title='error', message='connection: ' + server['ip'] + ':' + server['port'])
conn.close()
return
join = os.path.join
pub_key = join(join(os.path.expanduser('~'), '.ssh'), 'id_rsa.pub')
if not os.path.exists(pub_key): os.system('ssh-keygen -t rsa')
remote_author_file = pwd + '/.ssh/authorized_keys'
local_author_file = 'authorized_keys-' + str(round(time.time()*1000))
try:
conn.get(remote_author_file, local_author_file)
with open(local_author_file, 'r') as f: lines = f.readlines()
lines = [t.strip() for t in lines if len(t)>5]
except: lines = []
with open(pub_key, 'r') as f: item = f.readlines()[0].strip()
if item in lines:
conn.close()
os.remove(local_author_file)
return
lines.append(item)
out = '\n'.join(lines)
with open(local_author_file, 'w') as f: f.write(out)
try:
conn.put(local_author_file, remote_author_file)
conn.run('chmod 600 {}'.format(remote_author_file))
except Exception as e:
messagebox.showinfo(title='error', message=str(e))
conn.close()
os.remove(local_author_file)
return
conn.close()
os.remove(local_author_file)
return
btn_info = Button(frame_ctl, text='Info', bg='gray', command=check).pack(side=LEFT, fill=X, expand=True)
btn_auth = Button(frame_ctl, text='Auth', bg='gray', command=auth).pack(side=LEFT, fill=X, expand=True)
btn_terminal = Button(frame_ctl, text='Terminal', bg='gray', command=terminal).pack(side=LEFT, fill=X, expand=True)
btn_dispatch = Button(frame_ctl, text='Dispatch', bg='gray', command=dispatch).pack(side=LEFT, fill=X, expand=True)
window.mainloop()
import os
import re
import time
import paramiko
import fabric
import tarfile
from tkinter import *
from tkinter import messagebox
# TODO: config
height = 420
width = 450
server_password_default = 'gta'
run_file_endswith = '.sh'
run_cmd = 'bash'
connection_timeout = 10
info_connection_timeout = 2
proxy = 'http://child-prc.intel.com:913'
vscode_url = 'https://github.com/cdr/code-server/releases/download/v3.12.0/code-server-3.12.0-linux-amd64.tar.gz'
def get_servers() -> dict:
servers ={}
with open('servers.txt', 'r') as f:
for line in f.readlines():
line_ = line.split(',')
line_ = [t.strip() for t in line_]
name = line_[0]
url = line_[1]
url_ = url.split('@')
user = url_[0]
ip, port = url_[1].split(':')
servers[name] = {'user':user, 'ip':ip, 'port':port}
return servers
servers = get_servers()
# print('servers: ', servers)
def get_envs(env_list_dir='.') -> list:
envs = []
for dir in os.listdir(env_list_dir):
if not os.path.isdir(dir): continue
if dir.startswith('_'): continue
envs.append(dir)
return envs
envs = get_envs()
# print('envs:', envs)
def print_server_info(name):
server = servers[name]
return name + ' ' + server['user'] + '@' + server['ip'] + ':' + server['port']
window = Tk()
window.title('autoenv')
screenwidth = window.winfo_screenwidth()
screenheight = window.winfo_screenheight()
alignstr = '%dx%d+%d+%d' % (width, height, (screenwidth-width)/2, (screenheight-height)/2*0.8)
window.geometry(alignstr)
frame_list = Frame()
frame_list.pack(side=TOP, fill=BOTH, expand=True)
list_envs, list_servers = Listbox(frame_list, exportselection=False), Listbox(frame_list, exportselection=False)
scrollnar_envs, scrollnar_servers = Scrollbar(frame_list), Scrollbar(frame_list)
list_envs.config(yscrollcommand=scrollnar_envs.set)
list_servers.config(yscrollcommand=scrollnar_servers.set)
scrollnar_envs.config(command=list_envs.yview)
scrollnar_servers.config(command=list_servers.yview)
list_envs.pack(side=LEFT, fill=BOTH, expand=True)
scrollnar_envs.pack(side=LEFT, fill=Y)
list_servers.pack(side=LEFT, fill=BOTH, expand=True)
scrollnar_servers.pack(side=LEFT, fill=Y)
for name in envs: list_envs.insert('end', name)
for name in servers.keys(): list_servers.insert(END, print_server_info(name))
[list_servers.itemconfig(i, bg='#e0f0ff') for i in range(len(servers.keys())) if i%2]
[list_envs.itemconfig(i, bg='#e0f0ff') for i in range(len(envs)) if i%2]
info = StringVar(value='[please select machine][used/total]')
lb_info = Label(textvariable=info).pack(side=TOP, fill=X)
frame_ctl = Frame(window).pack(side=TOP, fill=X, expand=False)
lb_run = Label(frame_ctl, text='runfile: ').pack(side=LEFT)
runfile_v = StringVar(value='run' + run_file_endswith)
entry_run = Entry(frame_ctl, textvariable=runfile_v, width=12).pack(side=LEFT, fill=X, expand=True)
lb_password = Label(frame_ctl, text='password: ').pack(side=LEFT)
password_v = StringVar(value=server_password_default)
entry_password = Entry(frame_ctl, textvariable=password_v, show='*', width=12).pack(side=LEFT, fill=X, expand=True)
def dispatch():
try:
env = list_envs.get(list_envs.curselection()).strip()
server_name = list_servers.get(list_servers.curselection()).split(' ')[0].strip()
server = servers[server_name]
except: return
notice = messagebox.askokcancel('notice', env + ' -> ' + server_name + '\nrelevant files will be deleted')
if not notice: return
print(env, ' -> ', server_name)
def change_to_lf(endswith):
for root, _, files in os.walk(env):
for file in files:
put_localpath = os.path.realpath(os.path.join(root, file))
if put_localpath.endswith(endswith):
# print('-> lf ' + put_localpath)
with open(put_localpath, 'rb') as f: temp = f.read()
temp = temp.replace(b'\r\n', b'\n')
with open(put_localpath, 'wb') as f: f.write(temp)
change_to_lf(run_file_endswith)
# connect
conn = fabric.Connection(server['ip'], user=server['user'],
port=server['port'], connect_kwargs={"password": password_v.get()},
connect_timeout=connection_timeout)
try:
pwd = conn.run('cd ~; pwd').stdout.strip()
except:
messagebox.showinfo(title='error', message='connection: ' + server['ip'] + ':' + server['port'])
conn.close()
return
put_remotepath = pwd + '/' + '/'.join(re.split(r'[-]', env))
try:
conn.run("mkdir -p {0}; cd {0}".format(put_remotepath))
except Exception as e:
messagebox.showinfo(title='error', message=str(e))
conn.close()
return
env_file = env + '-' + str(round(time.time()*1000)) + '.tar.gz'
try:
with tarfile.open(env_file, 'w:gz') as tar: tar.add(env, arcname=os.path.basename('.'))
except Exception as e:
messagebox.showinfo(title='error', message=str(e))
conn.close()
return
try:
conn.put(env_file, put_remotepath) # no callback
except Exception as e:
messagebox.showinfo(title='error', message=str(e))
conn.close()
return
try:
conn.run("cd {0}; tar -xzvf {1}; rm -rf {1}".format(put_remotepath, env_file))
except Exception as e:
messagebox.showinfo(title='error', message=str(e))
conn.close()
os.remove(env_file)
return
os.remove(env_file)
try:
conn.run("cd {0}; {2} {1}".format(put_remotepath, runfile_v.get(), run_cmd), pty=True, encoding='utf-8')
except:
messagebox.showinfo(title='partial success', message=server_name + '\nrunfile failed')
conn.close()
return
messagebox.showinfo(title='success', message=server_name)
conn.close()
def check():
try:
server_name = list_servers.get(list_servers.curselection()).split(' ')[0].strip()
server = servers[server_name]
except: return False
conn = fabric.Connection(server['ip'], user=server['user'],
port=int(server['port']), connect_kwargs={"password": password_v.get()},
connect_timeout=info_connection_timeout)
try:
mem = conn.run('free -h | grep Mem', hide='stdout').stdout.strip().split(' ')
mem = [t for t in mem if len(t)>0]
disk = conn.run('df ~ -kh | grep G', hide='stdout').stdout.strip().split(' ')
disk = [t for t in disk if len(t)>0]
except:
messagebox.showinfo(title='error', message='connection: ' + server['ip'] + ':' + server['port'])
conn.close()
return False
mem_info = 'mem: ' + mem[2] + '/' + mem[1]
disk_info = 'disk: ' + disk[2] + '/' + disk[1]
info.set('[' + server_name + ']' + '[used/total] ' + mem_info + ', ' + disk_info)
conn.close()
return True
def terminal():
try:
server_name = list_servers.get(list_servers.curselection()).split(' ')[0].strip()
server = servers[server_name]
except: return
try: env = '~/' + list_envs.get(list_envs.curselection()).strip().replace('-', '/')
except: env = '~'
os.system('start cmd /k ssh -t -p ' + server['port'] + ' ' + server['user'] + '@' + server['ip'] + ' \" cd ' + env + '; bash --login\"')
def auth():
try:
server_name = list_servers.get(list_servers.curselection()).split(' ')[0].strip()
server = servers[server_name]
except: return
conn = fabric.Connection(server['ip'], user=server['user'],
port=server['port'], connect_kwargs={"password": password_v.get()},
connect_timeout=connection_timeout)
try:
pwd = conn.run('cd ~; pwd').stdout.strip()
except:
messagebox.showinfo(title='error', message='connection: ' + server['ip'] + ':' + server['port'])
conn.close()
return
join = os.path.join
pub_key = join(join(os.path.expanduser('~'), '.ssh'), 'id_rsa.pub')
if not os.path.exists(pub_key):
os.system('ssh-keygen -t rsa')
remote_file = pwd + '/.ssh/id_rsa' + '-' + str(round(time.time()*1000)) + '.pub'
cmd = '''
import os
import stat
try:
with open('{0}', 'r') as f: lines = f.readlines()
lines = [t.strip() for t in lines if len(t)>5]
except: lines = []
with open('{1}', 'r') as f: item = f.readlines()[0].strip()
if item not in lines:
lines.append(item)
out = '\\n'.join(lines)
with open('{0}', 'w') as f: f.write(out)
os.remove('{1}')
os.chmod('{0}', stat.S_IRWXU)
'''.format(pwd+'/.ssh/authorized_keys', remote_file)
try:
conn.put(pub_key, remote_file) # no callback
conn.run('python -c \"{}\"'.format(cmd))
except Exception as e:
messagebox.showinfo(title='error', message=str(e))
conn.close()
return
conn.close()
return
def vscode():
try:
env = list_envs.get(list_envs.curselection()).strip()
server_name = list_servers.get(list_servers.curselection()).split(' ')[0].strip()
server = servers[server_name]
except: return
conn = fabric.Connection(server['ip'], user=server['user'],
port=server['port'], connect_kwargs={"password": server['password']},
connect_timeout=connection_timeout)
try:
pwd = conn.run('cd ~; pwd').stdout.strip()
except:
messagebox.showinfo(title='error', message='connection: ' + server['ip'] + ':' + server['port'])
conn.close()
return
put_remotepath = pwd + '/' + '/'.join(re.split(r'[-]', env))
__proxy = 'export http_proxy={0}; export https_proxy={0};'.format(proxy)
__wget = 'wget {0} -O vsc.tar.gz;'.format(vscode_url)
__tar = 'mkdir ./vsc && tar -zxvf vsc.tar.gz -C ./vsc --strip-components 1; rm -rf vsc.tar.gz;'
__tmux = 'cd vsc; tmux kill-session -t {0}; tmux new -s {0} -d;'.format(env)
try:
conn.run(__proxy + 'mkdir -p {0}; cd {0};'.format(put_remotepath) + __wget + __tar + __tmux)
except:
messagebox.showinfo(title='error', message='connection: ' + server['ip'] + ':' + server['port'])
conn.close()
return
port = 8081
try:
conn.run('tmux send -t {0} \'PASSWORD={1} ./code-server --host 0.0.0.0 --port {2}\' Enter;'.format(env, server['password'], port))
except:
port += 1
print(port)
btn_info = Button(frame_ctl, text='Info', bg='gray', command=check).pack(side=LEFT, fill=X, expand=True)
btn_auth = Button(frame_ctl, text='Auth', bg='gray', command=auth).pack(side=LEFT, fill=X, expand=True)
btn_terminal = Button(frame_ctl, text='Terminal', bg='gray', command=terminal).pack(side=LEFT, fill=X, expand=True)
btn_dispatch = Button(frame_ctl, text='Dispatch', bg='gray', command=dispatch).pack(side=LEFT, fill=X, expand=True)
window.mainloop()
'''
server.txt
NAME1, xx@101.11.40.61:22, ddd
NAME2, yy@101.11.40.11:32, sss
'''
import os
import re
import time
import paramiko
import fabric
import tarfile
import pyautogui
pyautogui.FAILSAFE = True
from tkinter import *
from tkinter import messagebox
# TODO: config
run_file_endswith = '.sh'
run_cmd = 'bash'
connection_timeout = 10
def get_servers() -> dict:
servers ={}
with open('servers.txt', 'r') as f:
for line in f.readlines():
line_ = line.split(',')
line_ = [t.strip() for t in line_]
name = line_[0]
url = line_[1]
password = line_[2]
url_ = url.split('@')
user = url_[0]
ip, port = url_[1].split(':')
servers[name] = {'user':user, 'ip':ip, 'port':port,
'password':password}
return servers
servers = get_servers()
# print('servers: ', servers)
def get_envs(env_list_dir='.') -> list:
envs = []
for dir in os.listdir(env_list_dir):
if not os.path.isdir(dir): continue
envs.append(dir)
return envs
envs = get_envs()
# print('envs:', envs)
def print_server_info(name):
server = servers[name]
return name + ' ' + server['user'] + '@' + server['ip'] + ':' + server['port']
window = Tk()
window.title('autoenv')
width = height = 440
screenwidth = window.winfo_screenwidth()
screenheight = window.winfo_screenheight()
alignstr = '%dx%d+%d+%d' % (width, height, (screenwidth-width)/2, (screenheight-height)/2*0.8)
window.geometry(alignstr)
frame_list = Frame()
frame_list.pack(side=TOP, fill=BOTH, expand=True)
list_envs, list_servers = Listbox(frame_list, exportselection=False), Listbox(frame_list, exportselection=False)
scrollnar_envs, scrollnar_servers = Scrollbar(frame_list), Scrollbar(frame_list)
list_envs.config(yscrollcommand=scrollnar_envs.set)
list_servers.config(yscrollcommand=scrollnar_servers.set)
scrollnar_envs.config(command=list_envs.yview)
scrollnar_servers.config(command=list_servers.yview)
list_envs.pack(side=LEFT, fill=BOTH, expand=True)
scrollnar_envs.pack(side=LEFT, fill=Y)
list_servers.pack(side=LEFT, fill=BOTH, expand=True)
scrollnar_servers.pack(side=LEFT, fill=Y)
for name in envs: list_envs.insert('end', name)
for name in servers.keys(): list_servers.insert(END, print_server_info(name))
[list_servers.itemconfig(i, bg='#e0f0ff') for i in range(len(servers.keys())) if i%2]
[list_envs.itemconfig(i, bg='#e0f0ff') for i in range(len(envs)) if i%2]
info = StringVar(value='[please select machine][used/total]')
lb_info = Label(textvariable=info).pack(side=TOP, fill=X)
frame_ctl = Frame(window).pack(side=TOP, fill=X, expand=False)
lb_run = Label(frame_ctl, text='runfile: ').pack(side=LEFT)
runfile_v = StringVar(value='run' + run_file_endswith)
entry_run = Entry(frame_ctl, textvariable=runfile_v, width=14).pack(side=LEFT, fill=X, expand=True)
def dispatch():
try:
env = list_envs.get(list_envs.curselection()).strip()
server_name = list_servers.get(list_servers.curselection()).split(' ')[0].strip()
server = servers[server_name]
except: return
notice = messagebox.askokcancel('notice', env + ' -> ' + server_name + '\nrelevant files will be deleted')
if not notice: return
print(env, ' -> ', server_name)
def change_to_lf(endswith):
for root, _, files in os.walk(env):
for file in files:
put_localpath = os.path.realpath(os.path.join(root, file))
if put_localpath.endswith(endswith):
# print('-> lf ' + put_localpath)
with open(put_localpath, 'rb') as f: temp = f.read()
temp = temp.replace(b'\r\n', b'\n')
with open(put_localpath, 'wb') as f: f.write(temp)
change_to_lf(run_file_endswith)
# connect
conn = fabric.Connection(server['ip'], user=server['user'],
port=server['port'], connect_kwargs={"password": server['password']},
connect_timeout=connection_timeout)
try:
pwd = conn.run('cd ~; pwd').stdout.strip()
except:
messagebox.showinfo(title='error', message='connection: ' + server['ip'] + ':' + server['port'])
conn.close()
return
put_remotepath = pwd + '/' + '/'.join(re.split(r'[-]', env))
if len(put_remotepath) <= len(pwd) + 2:
messagebox.showinfo(title='error', message='path')
conn.close()
return
try:
conn.run("mkdir -p {0}; cd {0}".format(put_remotepath))
except Exception as e:
messagebox.showinfo(title='error', message=str(e))
conn.close()
return
env_file = env + '-' + str(round(time.time()*1000)) + '.tar.gz'
try:
with tarfile.open(env_file, 'w:gz') as tar: tar.add(env, arcname=os.path.basename('.'))
except Exception as e:
messagebox.showinfo(title='error', message=str(e))
conn.close()
return
try:
conn.put(env_file, put_remotepath) # no callback
except Exception as e:
messagebox.showinfo(title='error', message=str(e))
conn.close()
return
try:
conn.run("cd {0}; tar -xzvf {1}; rm -rf {1}".format(put_remotepath, env_file))
except Exception as e:
messagebox.showinfo(title='error', message=str(e))
conn.close()
os.remove(env_file)
return
os.remove(env_file)
try:
conn.run("cd {0}; {2} {1}".format(put_remotepath, runfile_v.get(), run_cmd), pty=True, encoding='utf-8')
except:
messagebox.showinfo(title='partial success', message=server_name + '\nrunfile failed')
conn.close()
return
messagebox.showinfo(title='success', message=server_name)
conn.close()
def check():
try:
server_name = list_servers.get(list_servers.curselection()).split(' ')[0].strip()
server = servers[server_name]
except: return False
conn = fabric.Connection(server['ip'], user=server['user'],
port=int(server['port']), connect_kwargs={"password": server['password']},
connect_timeout=2)
try:
mem = conn.run('free -h | grep Mem', hide='stdout').stdout.strip().split(' ')
mem = [t for t in mem if len(t)>0]
disk = conn.run('df ~ -kh | grep G', hide='stdout').stdout.strip().split(' ')
disk = [t for t in disk if len(t)>0]
except:
messagebox.showinfo(title='error', message='connection: ' + server['ip'] + ':' + server['port'])
conn.close()
return False
mem_info = 'mem: ' + mem[2] + '/' + mem[1]
disk_info = 'disk: ' + disk[2] + '/' + disk[1]
info.set('[' + server_name + ']' + '[used/total] ' + mem_info + ', ' + disk_info)
return True
def press(cmd, enter=True):
pyautogui.write(cmd, interval=0.005)
if enter: pyautogui.press('enter')
def terminal():
try:
server_name = list_servers.get(list_servers.curselection()).split(' ')[0].strip()
server = servers[server_name]
except: return
# if not check(): return
# try: env = list_envs.get(list_envs.curselection()).strip()
# except: env = '~'
os.system('start cmd /k ssh -p ' + server['port'] + ' ' + server['user'] + '@' + server['ip'])
# time.sleep(1)
# press(server['password'])
# env = env.replace('-', '/')
# if env != '~': press('cd ~/' + env)
btn_info = Button(frame_ctl, text='info', bg='gray', command=check).pack(side=LEFT, fill=X, expand=True)
btn_terminal = Button(frame_ctl, text='terminal', bg='gray', command=terminal).pack(side=LEFT, fill=X, expand=True)
btn_dispatch = Button(frame_ctl, text='Dispatch', bg='gray', command=dispatch).pack(side=LEFT, fill=X, expand=True)
window.mainloop()
'''
author:xytpai@foxmail.com
autoenv:
|__ _servers_
| |__ home.bat
|__ autoenv-test
| |__ requirements.txt
| |__ run.sh
|__ autoenv.py
|__ requirements.txt
home.bat:
ssh -oPort=6000 xytpai@111.11.111.111
requirements.txt:
paramiko
fabric
selenium
run.sh:
pip uninstall -r requirements.txt
pip install -r requirements.txt
'''
import os
import re
import time
import paramiko
import fabric
import tarfile
from tkinter import *
from tkinter import messagebox
# TODO: config
server_password_default = 'gta'
server_root = '_servers_' # cannot use ./servers
server_file_endswith = '.bat'
run_file_endswith = '.sh'
run_cmd = 'bash'
connection_timeout = 10
def get_servers(server_root, server_file_endswith) -> dict:
servers = {}
for root, _, files in os.walk(server_root):
for file in files:
path = os.path.join(root, file)
if path.endswith(server_file_endswith):
with open(path, 'r') as f:
items = re.split(r'[ =]', f.readline())
port = 22
for item in items:
item = item.strip()
if '@' in item:
item = item.split('@')
user = item[0]
ip = item[1]
else:
try: port = int(item)
except: continue
name = file[:len(file)-len(server_file_endswith)]
servers[name] = {'user':user, 'ip':ip, 'port':port}
return servers
servers = get_servers(server_root, server_file_endswith)
# print('servers: ', servers)
def get_envs(env_list_dir='.', exclude_dirs=[server_root]) -> list:
envs = []
for dir in os.listdir(env_list_dir):
if not os.path.isdir(dir): continue
if dir in exclude_dirs: continue
envs.append(dir)
return envs
envs = get_envs()
# print('envs:', envs)
window = Tk()
window.title('autoenv')
width = height = 440
screenwidth = window.winfo_screenwidth()
screenheight = window.winfo_screenheight()
alignstr = '%dx%d+%d+%d' % (width, height, (screenwidth-width)/2, (screenheight-height)/2*0.8)
window.geometry(alignstr)
frame_list = Frame()
frame_list.pack(side=TOP, fill=BOTH, expand=True)
list_envs, list_servers = Listbox(frame_list, exportselection=False), Listbox(frame_list, exportselection=False)
scrollnar_envs, scrollnar_servers = Scrollbar(frame_list), Scrollbar(frame_list)
list_envs.config(yscrollcommand=scrollnar_envs.set)
list_servers.config(yscrollcommand=scrollnar_servers.set)
scrollnar_envs.config(command=list_envs.yview)
scrollnar_servers.config(command=list_servers.yview)
list_envs.pack(side=LEFT, fill=BOTH, expand=True)
scrollnar_envs.pack(side=LEFT, fill=Y)
list_servers.pack(side=LEFT, fill=BOTH, expand=True)
scrollnar_servers.pack(side=LEFT, fill=Y)
for name in envs: list_envs.insert('end', name)
for name in servers.keys(): list_servers.insert('end', name+' '+servers[name]['ip']+':'+str(servers[name]['port']))
[list_servers.itemconfig(i, bg='#e0f0ff') for i in range(len(servers.keys())) if i%2]
[list_envs.itemconfig(i, bg='#e0f0ff') for i in range(len(envs)) if i%2]
info = StringVar(value='[please select machine][used/total]')
lb_info = Label(textvariable=info).pack(side=TOP, fill=X)
frame_ctl = Frame(window).pack(side=TOP, fill=X, expand=False)
lb_run = Label(frame_ctl, text='runfile: ').pack(side=LEFT)
runfile_v = StringVar(value='run' + run_file_endswith)
entry_run = Entry(frame_ctl, textvariable=runfile_v, width=14).pack(side=LEFT, fill=X, expand=True)
lb_password = Label(frame_ctl, text='password: ').pack(side=LEFT)
password_v = StringVar(value=server_password_default)
entry_password = Entry(frame_ctl, textvariable=password_v, show='*', width=14).pack(side=LEFT, fill=X, expand=True)
def dispatch():
try:
env = list_envs.get(list_envs.curselection()).strip()
server_name = list_servers.get(list_servers.curselection()).split(' ')[0].strip()
except: return
notice = messagebox.askokcancel('notice', env + ' -> ' + server_name + '\noriginal folder will be removed')
if not notice: return
print(env, ' -> ', server_name)
def change_to_lf(endswith):
for root, _, files in os.walk(env):
for file in files:
put_localpath = os.path.realpath(os.path.join(root, file))
if put_localpath.endswith(endswith):
# print('-> lf ' + put_localpath)
with open(put_localpath, 'rb') as f: temp = f.read()
temp = temp.replace(b'\r\n', b'\n')
with open(put_localpath, 'wb') as f: f.write(temp)
change_to_lf(run_file_endswith)
# connect
conn = fabric.Connection(servers[server_name]['ip'], user=servers[server_name]['user'],
port=servers[server_name]['port'],
connect_kwargs={"password": password_v.get()}, connect_timeout=connection_timeout)
try:
pwd = conn.run('cd ~; pwd').stdout.strip()
except:
messagebox.showinfo(title='error', message='connection: ' + servers[server_name]['ip'])
conn.close()
return
put_remotepath = pwd + '/' + '/'.join(re.split(r'[-]', env))
if len(put_remotepath) <= len(pwd) + 2:
messagebox.showinfo(title='error', message='path')
conn.close()
return
try:
conn.run("mkdir -p {0}; cd {0}; rm -rf *".format(put_remotepath))
except Exception as e:
messagebox.showinfo(title='error', message=str(e))
conn.close()
return
env_file = env + '-' + str(round(time.time()*1000)) + '.tar.gz'
try:
with tarfile.open(env_file, 'w:gz') as tar: tar.add(env, arcname=os.path.basename('.'))
except Exception as e:
messagebox.showinfo(title='error', message=str(e))
conn.close()
return
try:
conn.put(env_file, put_remotepath) # no callback
except Exception as e:
messagebox.showinfo(title='error', message=str(e))
conn.close()
return
try:
conn.run("cd {0}; tar -xzvf {1}; rm -rf {1}".format(put_remotepath, env_file))
except Exception as e:
messagebox.showinfo(title='error', message=str(e))
conn.close()
os.remove(env_file)
return
os.remove(env_file)
try:
conn.run("cd {0}; {2} {1}".format(put_remotepath, runfile_v.get(), run_cmd), pty=True, encoding='utf-8')
except:
messagebox.showinfo(title='partial success', message=server_name + '\nrunfile failed')
conn.close()
return
messagebox.showinfo(title='success', message=server_name)
conn.close()
def check():
try:
server_name = list_servers.get(list_servers.curselection()).split(' ')[0].strip()
except: return
conn = fabric.Connection(servers[server_name]['ip'], user=servers[server_name]['user'],
port=servers[server_name]['port'],
connect_kwargs={"password": password_v.get()}, connect_timeout=connection_timeout)
try:
mem = conn.run('free -h | grep Mem', hide='stdout').stdout.strip().split(' ')
mem = [t for t in mem if len(t)>0]
disk = conn.run('df ~ -kh | grep G', hide='stdout').stdout.strip().split(' ')
disk = [t for t in disk if len(t)>0]
except:
messagebox.showinfo(title='error', message='connection: ' + servers[server_name]['ip'])
conn.close()
return
mem_info = 'mem: ' + mem[2] + '/' + mem[1]
disk_info = 'disk: ' + disk[2] + '/' + disk[1]
info.set('[' + server_name + ']' + '[used/total] ' + mem_info + ', ' + disk_info)
def terminal():
try:
server_name = list_servers.get(list_servers.curselection()).split(' ')[0].strip()
except: return
os.system(os.path.join(server_root, server_name + server_file_endswith))
btn_info = Button(frame_ctl, text='info', bg='gray', command=check).pack(side=LEFT, fill=X, expand=True)
btn_terminal = Button(frame_ctl, text='terminal', bg='gray', command=terminal).pack(side=LEFT, fill=X, expand=True)
btn_dispatch = Button(frame_ctl, text='Dispatch', bg='gray', command=dispatch).pack(side=LEFT, fill=X, expand=True)
window.mainloop()