|
1
|
|
|
'''ssh client |
|
2
|
|
|
use with, or finally close |
|
3
|
|
|
See |
|
4
|
|
|
https://daanlenaerts.com/blog/2016/07/01/python-and-ssh-paramiko-shell/ |
|
5
|
|
|
https://stackoverflow.com/questions/39606573/unable-to-kill-python-script |
|
6
|
|
|
''' |
|
7
|
|
|
import threading |
|
8
|
|
|
import paramiko |
|
9
|
|
|
|
|
10
|
|
|
class Ssh: |
|
11
|
|
|
'''communicate with miner through ssh''' |
|
12
|
|
|
shell = None |
|
13
|
|
|
client = None |
|
14
|
|
|
transport = None |
|
15
|
|
|
closed = False |
|
16
|
|
|
|
|
17
|
|
|
strdata = '' |
|
18
|
|
|
alldata = '' |
|
19
|
|
|
|
|
20
|
|
|
def __init__(self, address, username='root', password='admin', port=22): |
|
21
|
|
|
print("Connecting to server on ip {0}:{1}".format(address, port)) |
|
22
|
|
|
self.client = paramiko.client.SSHClient() |
|
23
|
|
|
self.client.set_missing_host_key_policy(paramiko.client.AutoAddPolicy()) |
|
24
|
|
|
self.client.connect(address, port=port, username=username, password=password, look_for_keys=False) |
|
25
|
|
|
print("Connection created") |
|
26
|
|
|
self.thread = threading.Thread(target=self.process) |
|
27
|
|
|
self.thread.start() |
|
28
|
|
|
|
|
29
|
|
|
def exec_command(self, command): |
|
30
|
|
|
'''use this if you only need to run ONE command |
|
31
|
|
|
This is the preferred way to communicate with miner |
|
32
|
|
|
returns a list of lines as the response to the command |
|
33
|
|
|
''' |
|
34
|
|
|
_, stdout_, _ = self.client.exec_command(command) |
|
35
|
|
|
#this will make it block until response is received |
|
36
|
|
|
stdout_.channel.recv_exit_status() |
|
37
|
|
|
return stdout_.readlines() |
|
38
|
|
|
|
|
39
|
|
|
def close_connection(self): |
|
40
|
|
|
'''close the ssh connection''' |
|
41
|
|
|
self.thread.join(timeout=10) |
|
42
|
|
|
if self.client != None: |
|
43
|
|
|
self.client.close() |
|
44
|
|
|
if self.transport is not None: |
|
45
|
|
|
self.transport.close() |
|
46
|
|
|
self.closed = True |
|
47
|
|
|
|
|
48
|
|
|
def open_shell(self): |
|
49
|
|
|
'''open shell command to run a series of command |
|
50
|
|
|
try to avoid if possible |
|
51
|
|
|
may have some async/threading issues |
|
52
|
|
|
''' |
|
53
|
|
|
self.shell = self.client.invoke_shell() |
|
54
|
|
|
|
|
55
|
|
|
def send_shell(self, command): |
|
56
|
|
|
'''send command to shell''' |
|
57
|
|
|
if self.shell: |
|
58
|
|
|
self.shell.send(command + "\n") |
|
59
|
|
|
else: |
|
60
|
|
|
print("Shell not opened.") |
|
61
|
|
|
|
|
62
|
|
|
def process(self): |
|
63
|
|
|
'''process the commands''' |
|
64
|
|
|
while self.closed is False: |
|
65
|
|
|
# Print data when available |
|
66
|
|
|
if self.shell != None and self.shell.recv_ready(): |
|
67
|
|
|
alldata = self.shell.recv(1024) |
|
68
|
|
|
while self.shell.recv_ready(): |
|
69
|
|
|
alldata += self.shell.recv(1024) |
|
70
|
|
|
strdata = str(alldata, "utf8") |
|
71
|
|
|
strdata.replace('\r', '') |
|
72
|
|
|
print(strdata, end="") |
|
73
|
|
|
if strdata.endswith("$ "): |
|
74
|
|
|
print("\n$ ", end="") |
|
75
|
|
|
print("ssh process closed") |
|
76
|
|
|
|
|
77
|
|
|
def get(self, remotefile, localfile): |
|
78
|
|
|
ftp_client = self.client.open_sftp() |
|
79
|
|
|
ftp_client.get(remotefile, localfile) |
|
80
|
|
|
ftp_client.close() |
|
81
|
|
|
|
|
82
|
|
|
def put(self, localfile, remotefile): |
|
83
|
|
|
ftp_client = self.client.open_sftp() |
|
84
|
|
|
ftp_client.put(localfile, remotefile) |
|
85
|
|
|
ftp_client.close() |
|
86
|
|
|
|