-
Notifications
You must be signed in to change notification settings - Fork 0
/
ssh.py
126 lines (113 loc) · 5.8 KB
/
ssh.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
import time
from pathlib import Path
import paramiko
from rich.console import Console
from rich.panel import Panel
from rich.progress import BarColumn, Progress, TextColumn
from rich.theme import Theme
from scp import SCPClient
from wizard import Wizard
class Action:
GET = "data.get"
PUT = "data.put"
PUT_DB = "data.put.db"
DELETE = "data.delete"
CHOICES = [GET, PUT, PUT_DB, DELETE]
custom_theme = Theme({"info": "dim cyan", "warning": "magenta", "danger": "bold red"})
console = Console(theme=custom_theme)
def ssh(_robot_ip: str, action: str):
"""Do the work."""
ssh_client = paramiko.SSHClient()
ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
# https://medium.com/@michal_73101/paramiko-and-openssh-generated-keys-26524dccb259
# ssh-keygen -m PEM -t rsa -b 2048 -f id_paramiko
# https://support.opentrons.com/en/articles/3203681-setting-up-ssh-access-to-your-ot-2
# connect robot via usb and get ip
# from ~/.ssh
# curl \
# -H 'Content-Type: application/json' \
# -d "{\"key\":\"$(cat id_paramiko.pub)\"}" \
# $ROBOT_IP:31950/server/ssh_keys
# local
key_file: Path = Path("results/key")
pkey = paramiko.RSAKey.from_private_key_file(str(key_file.resolve()))
assert key_file.is_file()
disabled_algorithms = {"pubkeys": ["rsa-sha2-512", "rsa-sha2-256"]}
# must have disabled_algorithms so it uses the 2048?
ssh_client.connect(hostname=_robot_ip, username="root", pkey=pkey, disabled_algorithms=disabled_algorithms)
text_column = TextColumn("{task.description}")
bar_column = BarColumn()
with Progress(text_column, bar_column, console=console) as progresso:
def progress(filename, size, sent, address):
"""Print progress."""
if isinstance(filename, bytes):
filename = filename.decode()
percent_done = float(sent) / float(size) * 100
progresso.update(task1, total=size, advance=sent, refresh=True)
if percent_done >= 100:
progresso.console.print(f"[bold purple]({address[0]}) {filename} downloaded")
match action: # noqa: E999 https://github.com/charliermarsh/ruff/issues/282
case Action.GET:
console.print(
Panel(
"[bold green] Compressing and downloading the /data directory.[/]",
style="bold magenta",
)
)
task2 = progresso.add_task("[sky_blue3]Compressing...")
stdin, stdout, stderr = ssh_client.exec_command("cd /data && tar -zcvf data.tar.gz .")
exit_status = stdout.channel.recv_exit_status() # Blocking call
if exit_status == 0:
progresso.update(task2, completed=100, refresh=True)
progresso.console.print("[sky_blue3]data directory compressed")
else:
progresso.console.print("Error", exit_status)
stdin.close()
task1 = progresso.add_task("[red]Downloading...")
with SCPClient(ssh_client.get_transport(), progress4=progress) as scp:
scp.get("/data/data.tar.gz", local_path=f"{str(time.time_ns())}data.tar.gz")
case Action.PUT_DB:
task1 = progresso.add_task("[red]Uploading...", start=False)
# stop the robot-server
stdin, stdout, stderr = ssh_client.exec_command("systemctl stop opentrons-robot-server")
exit_status = stdout.channel.recv_exit_status() # Blocking call
# delete the database dir
stdin, stdout, stderr = ssh_client.exec_command("rm -rf /data/opentrons_robot_server")
exit_status = stdout.channel.recv_exit_status() # Blocking call
# push the new dir
with SCPClient(ssh_client.get_transport(), progress4=progress) as scp:
scp.put("results/opentrons_robot_server", "/data/opentrons_robot_server", recursive=True)
# stdin, stdout, stderr = ssh_client.exec_command("cd /data && tar -xf data.tar.gz")
# exit_status = stdout.channel.recv_exit_status() # Blocking call
# if exit_status == 0:
# console.print("File Put")
# else:
# console.print("Error", exit_status)
# stdin, stdout, stderr = ssh_client.exec_command("rm /data/data.tar.gz")
# exit_status = stdout.channel.recv_exit_status() # Blocking call
# if exit_status == 0:
# console.print("File Put")
# else:
# console.print("Error", exit_status)
# stdin, stdout, stderr = ssh_client.exec_command("systemctl restart opentrons-robot-server")
# exit_status = stdout.channel.recv_exit_status() # Blocking call
# if exit_status == 0:
# console.print("File Put")
# else:
# console.print("Error", exit_status)
# # requests.post(f"http://{robot_ip}}:31950/server/restart")
# # restart robot server `systemctl restart opentrons-robot-server`
case Action.DELETE:
console.print(
Panel(
"[bold green] deleting data/opentrons_robot_server[/]",
style="bold magenta",
)
)
stdin, stdout, stderr = ssh_client.exec_command("rm -rf /data/opentrons_robot_server")
ssh_client.close()
if __name__ == "__main__":
wizard = Wizard(console)
robot_ip = wizard.validate_ip()
action = wizard.choices(question="What action to take?", choices=Action.CHOICES, default=Action.GET)
ssh(_robot_ip=robot_ip, action=action)