forked from robotstreamer/robotstreamer
-
Notifications
You must be signed in to change notification settings - Fork 0
/
reverse_ssh.py
141 lines (88 loc) · 4.08 KB
/
reverse_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
127
128
129
130
131
132
133
134
135
136
137
138
139
import os
import sys
import asyncio
import websockets
import time
import argparse
import json
import _thread
import traceback
import subprocess
statusEndpoint = {'host': 'status.robotstreamer.com', 'port': 6020}
parser = argparse.ArgumentParser(description='start reverse ssh program')
parser.add_argument('robot_id', help='Robot ID')
parser.add_argument('--reverse-ssh-host', default='[email protected]')
parser.add_argument('--reverse-ssh-key-file', default='/home/pi/rsjumpbox0.pem')
commandArgs = parser.parse_args()
robotID = commandArgs.robot_id
print("robot id:", robotID)
async def startReverseSSH(websocketToStatusService):
print("starting reverse ssh process")
await websocketToStatusService.send(json.dumps({"type": "info",
"result": "starting reverse ssh process on robot"}))
try:
commandList = ["/usr/bin/ssh",
"-X",
"-i", commandArgs.reverse_ssh_key_file,
"-N",
"-R", "2222:localhost:22",
"-o", "StrictHostKeyChecking=no",
commandArgs.reverse_ssh_host]
print(" ".join(commandList))
result = subprocess.check_output(commandList, stderr=subprocess.STDOUT)
except subprocess.CalledProcessError as e:
result = str(e.returncode) + " " + str(e.output)
except:
result = sys.exc_info()[0]
traceback.print_exc()
print("sending start reverse ssh info message to", websocketToStatusService)
await websocketToStatusService.send(json.dumps({"type": "info",
"result": "reverse ssh process finished running: " + str(result)}))
print("reverse ssh result", result)
async def stopReverseSSH(senderWebsocket):
print("handling stop reverse ssh process")
resultCode = subprocess.call(["killall", "ssh"])
print("result code of killall ssh:", resultCode)
async def handleStatusMessages():
print("running handle status messages")
url = 'ws://%s:%s' % (statusEndpoint['host'], statusEndpoint['port'])
print("chat url:", url)
async with websockets.connect(url) as websocket:
print("connected to control service at", url)
print("chat websocket object:", websocket)
print("starting websocket.send")
await websocket.send(json.dumps({"type":"connect",
"robot_id":robotID,
"local_address":subprocess.check_output(["hostname", "-I"]).decode("utf-8").strip()}))
while True:
print("awaiting message")
message = await websocket.recv()
print("received message:", message)
j = json.loads(message)
print("json message:", j)
if 'type' in j:
t = j['type']
if t == "start_reverse_ssh":
f = lambda: asyncio.new_event_loop().run_until_complete(startReverseSSH(websocket))
_thread.start_new_thread(f, ())
print("finished sending start reverse ssh. it should be running now")
elif t == "stop_reverse_ssh":
await stopReverseSSH(websocket)
print("finished sending stop reverse ssh")
else:
print("invalid message:", j)
def startStatus():
while True:
time.sleep(2) #todo: only wait as needed (wait for interenet)
print("starting asyncio new event loop")
try:
asyncio.new_event_loop().run_until_complete(handleStatusMessages())
except:
print("error: asyncio.new_event_loop has crashed")
traceback.print_exc()
def main():
print(commandArgs)
print("starting")
startStatus()
if __name__ == '__main__':
main()