blob: dec9ba386bfd541c8e52e55b5812d199ae3c3cef [file] [log] [blame]
Hanna Arhipova55cc1292019-01-08 14:22:18 +02001import cStringIO
2import logging
3import select
Hanna Arhipova16e93fb2019-01-23 19:03:01 +02004import utils
Hanna Arhipova55cc1292019-01-08 14:22:18 +02005import paramiko
6
7
8logger = logging.getLogger(__name__)
9
10# Suppress paramiko logging
11logging.getLogger("paramiko").setLevel(logging.WARNING)
12
13
14class SSHTransport(object):
15 def __init__(self, address, username, password=None,
16 private_key=None, look_for_keys=False, *args, **kwargs):
17
18 self.address = address
19 self.username = username
20 self.password = password
21 if private_key is not None:
22 self.private_key = paramiko.RSAKey.from_private_key(
23 cStringIO.StringIO(private_key))
24 else:
25 self.private_key = None
26
27 self.look_for_keys = look_for_keys
28 self.buf_size = 1024
29 self.channel_timeout = 10.0
30
31 def _get_ssh_connection(self):
32 ssh = paramiko.SSHClient()
33 ssh.set_missing_host_key_policy(
34 paramiko.AutoAddPolicy())
35 ssh.connect(self.address, username=self.username,
36 password=self.password, pkey=self.private_key,
37 timeout=self.channel_timeout)
38 logger.debug("Successfully connected to: {0}".format(self.address))
39 return ssh
40
41 def _get_sftp_connection(self):
42 transport = paramiko.Transport((self.address, 22))
43 transport.connect(username=self.username,
44 password=self.password,
45 pkey=self.private_key)
46
47 return paramiko.SFTPClient.from_transport(transport)
48
49 def exec_sync(self, cmd):
50 logger.debug("Executing {0} on host {1}".format(cmd, self.address))
51 ssh = self._get_ssh_connection()
52 transport = ssh.get_transport()
53 channel = transport.open_session()
54 channel.fileno()
55 channel.exec_command(cmd)
56 channel.shutdown_write()
57 out_data = []
58 err_data = []
59 poll = select.poll()
60 poll.register(channel, select.POLLIN)
61
62 while True:
63 ready = poll.poll(self.channel_timeout)
64 if not any(ready):
65 continue
66 if not ready[0]:
67 continue
68 out_chunk = err_chunk = None
69 if channel.recv_ready():
70 out_chunk = channel.recv(self.buf_size)
71 out_data += out_chunk,
72 if channel.recv_stderr_ready():
73 err_chunk = channel.recv_stderr(self.buf_size)
74 err_data += err_chunk,
75 if channel.closed and not err_chunk and not out_chunk:
76 break
77 exit_status = channel.recv_exit_status()
78 logger.debug("Command {0} executed with status: {1}"
79 .format(cmd, exit_status))
80 return (
81 exit_status, ''.join(out_data).strip(), ''.join(err_data).strip())
82
83 def exec_command(self, cmd):
84 exit_status, stdout, stderr = self.exec_sync(cmd)
85 return stdout
86
87 def check_call(self, command, error_info=None, expected=None,
88 raise_on_err=True):
89 """Execute command and check for return code
90 :type command: str
91 :type error_info: str
92 :type expected: list
93 :type raise_on_err: bool
94 :rtype: ExecResult
95 :raises: DevopsCalledProcessError
96 """
97 if expected is None:
98 expected = [0]
99 ret = self.exec_sync(command)
100 exit_code, stdout_str, stderr_str = ret
101 if exit_code not in expected:
102 message = (
103 "{append}Command '{cmd}' returned exit code {code} while "
104 "expected {expected}\n"
105 "\tSTDOUT:\n"
106 "{stdout}"
107 "\n\tSTDERR:\n"
108 "{stderr}".format(
109 append=error_info + '\n' if error_info else '',
110 cmd=command,
111 code=exit_code,
112 expected=expected,
113 stdout=stdout_str,
114 stderr=stderr_str
115 ))
116 logger.error(message)
117 if raise_on_err:
118 exit()
119 return ret
120
121 def put_file(self, source_path, destination_path):
122 sftp = self._get_sftp_connection()
123 sftp.put(source_path, destination_path)
124 sftp.close()
125
126 def get_file(self, source_path, destination_path):
127 sftp = self._get_sftp_connection()
128 sftp.get(source_path, destination_path)
129 sftp.close()
130
131
132class prepare_iperf(object):
133
134 def __init__(self,fip,user='ubuntu',password='password', private_key=None):
135 transport = SSHTransport(fip, user, password, private_key)
136 config = utils.get_configuration()
137 preparation_cmd = config.get('iperf_prep_string') or ['']
138 transport.exec_command(preparation_cmd)
Ievgeniia Zadorozhna55261342019-11-11 16:26:28 +0300139
140 # Install iperf using apt or downloaded deb package
141 internet_at_vms = utils.get_configuration().get("internet_at_vms")
142 if internet_at_vms.lower() == 'false':
143 logger.debug("Using downloaded iperf package")
144 transport.put_file("/var/lib/iperf_2.0.5+dfsg1-2_amd64.deb",
145 "/home/ubuntu/iperf_2.0.5+dfsg1-2_amd64.deb")
146 transport.exec_command(
147 'sudo dpkg -i /home/ubuntu/iperf_2.0.5+dfsg1-2_amd64.deb')
148 else:
149 logger.debug("Installing iperf using apt")
150 transport.exec_command(
151 'sudo apt-get update; sudo apt-get install -y iperf')
152
153 # Log whether iperf is installed with version
154 check = transport.exec_command('dpkg -l | grep iperf')
155 logger.debug(check)
156
157 # Staring iperf server
158 transport.exec_command('nohup iperf -s > file 2>&1 &')