root / snf-tools / synnefo_tools / burnin / cyclades_common.py @ 8c67f82e
History | View | Annotate | Download (11.6 kB)
1 | d246be88 | Ilias Tsitsimpis | # Copyright 2013 GRNET S.A. All rights reserved.
|
---|---|---|---|
2 | d246be88 | Ilias Tsitsimpis | #
|
3 | d246be88 | Ilias Tsitsimpis | # Redistribution and use in source and binary forms, with or
|
4 | d246be88 | Ilias Tsitsimpis | # without modification, are permitted provided that the following
|
5 | d246be88 | Ilias Tsitsimpis | # conditions are met:
|
6 | d246be88 | Ilias Tsitsimpis | #
|
7 | d246be88 | Ilias Tsitsimpis | # 1. Redistributions of source code must retain the above
|
8 | d246be88 | Ilias Tsitsimpis | # copyright notice, this list of conditions and the following
|
9 | d246be88 | Ilias Tsitsimpis | # disclaimer.
|
10 | d246be88 | Ilias Tsitsimpis | #
|
11 | d246be88 | Ilias Tsitsimpis | # 2. Redistributions in binary form must reproduce the above
|
12 | d246be88 | Ilias Tsitsimpis | # copyright notice, this list of conditions and the following
|
13 | d246be88 | Ilias Tsitsimpis | # disclaimer in the documentation and/or other materials
|
14 | d246be88 | Ilias Tsitsimpis | # provided with the distribution.
|
15 | d246be88 | Ilias Tsitsimpis | #
|
16 | d246be88 | Ilias Tsitsimpis | # THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
|
17 | d246be88 | Ilias Tsitsimpis | # OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
18 | d246be88 | Ilias Tsitsimpis | # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
19 | d246be88 | Ilias Tsitsimpis | # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
|
20 | d246be88 | Ilias Tsitsimpis | # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
21 | d246be88 | Ilias Tsitsimpis | # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
22 | d246be88 | Ilias Tsitsimpis | # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
23 | d246be88 | Ilias Tsitsimpis | # USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
24 | d246be88 | Ilias Tsitsimpis | # AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
25 | d246be88 | Ilias Tsitsimpis | # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
26 | d246be88 | Ilias Tsitsimpis | # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
27 | d246be88 | Ilias Tsitsimpis | # POSSIBILITY OF SUCH DAMAGE.
|
28 | d246be88 | Ilias Tsitsimpis | #
|
29 | d246be88 | Ilias Tsitsimpis | # The views and conclusions contained in the software and
|
30 | d246be88 | Ilias Tsitsimpis | # documentation are those of the authors and should not be
|
31 | d246be88 | Ilias Tsitsimpis | # interpreted as representing official policies, either expressed
|
32 | d246be88 | Ilias Tsitsimpis | # or implied, of GRNET S.A.
|
33 | d246be88 | Ilias Tsitsimpis | |
34 | d246be88 | Ilias Tsitsimpis | """
|
35 | d246be88 | Ilias Tsitsimpis | Utility functions for Cyclades Tests
|
36 | d246be88 | Ilias Tsitsimpis | Cyclades require a lot helper functions and `common'
|
37 | d246be88 | Ilias Tsitsimpis | had grown too much.
|
38 | d246be88 | Ilias Tsitsimpis |
|
39 | d246be88 | Ilias Tsitsimpis | """
|
40 | d246be88 | Ilias Tsitsimpis | |
41 | d246be88 | Ilias Tsitsimpis | import time |
42 | cee3ee9b | Ilias Tsitsimpis | import base64 |
43 | d246be88 | Ilias Tsitsimpis | import socket |
44 | d246be88 | Ilias Tsitsimpis | import random |
45 | cee3ee9b | Ilias Tsitsimpis | import paramiko |
46 | cee3ee9b | Ilias Tsitsimpis | import tempfile |
47 | d246be88 | Ilias Tsitsimpis | import subprocess |
48 | d246be88 | Ilias Tsitsimpis | |
49 | d246be88 | Ilias Tsitsimpis | from synnefo_tools.burnin.common import BurninTests |
50 | d246be88 | Ilias Tsitsimpis | |
51 | d246be88 | Ilias Tsitsimpis | |
52 | d246be88 | Ilias Tsitsimpis | # Too many public methods. pylint: disable-msg=R0904
|
53 | d246be88 | Ilias Tsitsimpis | class CycladesTests(BurninTests): |
54 | d246be88 | Ilias Tsitsimpis | """Extends the BurninTests class for Cyclades"""
|
55 | 8c67f82e | Ilias Tsitsimpis | def _ry_until_timeout_expires(self, opmsg, check_fun): |
56 | d246be88 | Ilias Tsitsimpis | """Try to perform an action until timeout expires"""
|
57 | d246be88 | Ilias Tsitsimpis | assert callable(check_fun), "Not a function" |
58 | d246be88 | Ilias Tsitsimpis | |
59 | d246be88 | Ilias Tsitsimpis | action_timeout = self.action_timeout
|
60 | d246be88 | Ilias Tsitsimpis | action_warning = self.action_warning
|
61 | d246be88 | Ilias Tsitsimpis | if action_warning > action_timeout:
|
62 | d246be88 | Ilias Tsitsimpis | action_warning = action_timeout |
63 | d246be88 | Ilias Tsitsimpis | |
64 | 8c67f82e | Ilias Tsitsimpis | start_time = int(time.time())
|
65 | 8c67f82e | Ilias Tsitsimpis | end_time = start_time + action_warning |
66 | 8c67f82e | Ilias Tsitsimpis | while end_time > time.time():
|
67 | d246be88 | Ilias Tsitsimpis | try:
|
68 | 8c67f82e | Ilias Tsitsimpis | ret_value = check_fun() |
69 | 8c67f82e | Ilias Tsitsimpis | self.info("Operation `%s' finished in %s seconds", |
70 | 8c67f82e | Ilias Tsitsimpis | opmsg, int(time.time()) - start_time)
|
71 | 8c67f82e | Ilias Tsitsimpis | return ret_value
|
72 | d246be88 | Ilias Tsitsimpis | except Retry:
|
73 | d246be88 | Ilias Tsitsimpis | time.sleep(self.query_interval)
|
74 | 8c67f82e | Ilias Tsitsimpis | self.warning("Operation `%s' is taking too long after %s seconds", |
75 | 8c67f82e | Ilias Tsitsimpis | opmsg, int(time.time()) - start_time)
|
76 | 8c67f82e | Ilias Tsitsimpis | |
77 | 8c67f82e | Ilias Tsitsimpis | end_time = start_time + action_timeout |
78 | 8c67f82e | Ilias Tsitsimpis | while end_time > time.time():
|
79 | d246be88 | Ilias Tsitsimpis | try:
|
80 | 8c67f82e | Ilias Tsitsimpis | ret_value = check_fun() |
81 | 8c67f82e | Ilias Tsitsimpis | self.info("Operation `%s' finished in %s seconds", |
82 | 8c67f82e | Ilias Tsitsimpis | opmsg, int(time.time()) - start_time)
|
83 | 8c67f82e | Ilias Tsitsimpis | return ret_value
|
84 | d246be88 | Ilias Tsitsimpis | except Retry:
|
85 | d246be88 | Ilias Tsitsimpis | time.sleep(self.query_interval)
|
86 | 8c67f82e | Ilias Tsitsimpis | self.error("Operation `%s' timed out after %s seconds", |
87 | 8c67f82e | Ilias Tsitsimpis | opmsg, int(time.time()) - start_time)
|
88 | d246be88 | Ilias Tsitsimpis | self.fail("time out") |
89 | d246be88 | Ilias Tsitsimpis | |
90 | d246be88 | Ilias Tsitsimpis | def _get_list_of_servers(self, detail=False): |
91 | d246be88 | Ilias Tsitsimpis | """Get (detailed) list of servers"""
|
92 | d246be88 | Ilias Tsitsimpis | if detail:
|
93 | d246be88 | Ilias Tsitsimpis | self.info("Getting detailed list of servers") |
94 | d246be88 | Ilias Tsitsimpis | else:
|
95 | d246be88 | Ilias Tsitsimpis | self.info("Getting simple list of servers") |
96 | d246be88 | Ilias Tsitsimpis | return self.clients.cyclades.list_servers(detail=detail) |
97 | d246be88 | Ilias Tsitsimpis | |
98 | d246be88 | Ilias Tsitsimpis | def _get_server_details(self, server): |
99 | d246be88 | Ilias Tsitsimpis | """Get details for a server"""
|
100 | d246be88 | Ilias Tsitsimpis | self.info("Getting details for server %s with id %s", |
101 | d246be88 | Ilias Tsitsimpis | server['name'], server['id']) |
102 | d246be88 | Ilias Tsitsimpis | return self.clients.cyclades.get_server_details(server['id']) |
103 | d246be88 | Ilias Tsitsimpis | |
104 | cee3ee9b | Ilias Tsitsimpis | def _create_server(self, name, image, flavor, personality): |
105 | d246be88 | Ilias Tsitsimpis | """Create a new server"""
|
106 | d246be88 | Ilias Tsitsimpis | self.info("Creating a server with name %s", name) |
107 | d246be88 | Ilias Tsitsimpis | self.info("Using image %s with id %s", image['name'], image['id']) |
108 | d246be88 | Ilias Tsitsimpis | self.info("Using flavor %s with id %s", flavor['name'], flavor['id']) |
109 | d246be88 | Ilias Tsitsimpis | server = self.clients.cyclades.create_server(
|
110 | cee3ee9b | Ilias Tsitsimpis | name, flavor['id'], image['id'], personality=personality) |
111 | d246be88 | Ilias Tsitsimpis | |
112 | d246be88 | Ilias Tsitsimpis | self.info("Server id: %s", server['id']) |
113 | d246be88 | Ilias Tsitsimpis | self.info("Server password: %s", server['adminPass']) |
114 | d246be88 | Ilias Tsitsimpis | |
115 | d246be88 | Ilias Tsitsimpis | self.assertEqual(server['name'], name) |
116 | d246be88 | Ilias Tsitsimpis | self.assertEqual(server['flavor']['id'], flavor['id']) |
117 | d246be88 | Ilias Tsitsimpis | self.assertEqual(server['image']['id'], image['id']) |
118 | d246be88 | Ilias Tsitsimpis | self.assertEqual(server['status'], "BUILD") |
119 | d246be88 | Ilias Tsitsimpis | |
120 | d246be88 | Ilias Tsitsimpis | return server
|
121 | d246be88 | Ilias Tsitsimpis | |
122 | d246be88 | Ilias Tsitsimpis | def _get_connection_username(self, server): |
123 | d246be88 | Ilias Tsitsimpis | """Determine the username to use to connect to the server"""
|
124 | d246be88 | Ilias Tsitsimpis | users = server['metadata'].get("users", None) |
125 | d246be88 | Ilias Tsitsimpis | ret_user = None
|
126 | d246be88 | Ilias Tsitsimpis | if users is not None: |
127 | d246be88 | Ilias Tsitsimpis | user_list = users.split() |
128 | d246be88 | Ilias Tsitsimpis | if "root" in user_list: |
129 | d246be88 | Ilias Tsitsimpis | ret_user = "root"
|
130 | d246be88 | Ilias Tsitsimpis | else:
|
131 | d246be88 | Ilias Tsitsimpis | ret_user = random.choice(user_list) |
132 | d246be88 | Ilias Tsitsimpis | else:
|
133 | d246be88 | Ilias Tsitsimpis | # Return the login name for connections based on the server OS
|
134 | d246be88 | Ilias Tsitsimpis | self.info("Could not find `users' metadata in server. Let's guess") |
135 | d246be88 | Ilias Tsitsimpis | os_value = server['metadata'].get("os") |
136 | d246be88 | Ilias Tsitsimpis | if os_value in ("Ubuntu", "Kubuntu", "Fedora"): |
137 | d246be88 | Ilias Tsitsimpis | ret_user = "user"
|
138 | d246be88 | Ilias Tsitsimpis | elif os_value in ("windows", "windows_alpha1"): |
139 | d246be88 | Ilias Tsitsimpis | ret_user = "Administrator"
|
140 | d246be88 | Ilias Tsitsimpis | else:
|
141 | d246be88 | Ilias Tsitsimpis | ret_user = "root"
|
142 | d246be88 | Ilias Tsitsimpis | |
143 | d246be88 | Ilias Tsitsimpis | self.assertIsNotNone(ret_user)
|
144 | d246be88 | Ilias Tsitsimpis | self.info("User's login name: %s", ret_user) |
145 | d246be88 | Ilias Tsitsimpis | return ret_user
|
146 | d246be88 | Ilias Tsitsimpis | |
147 | d246be88 | Ilias Tsitsimpis | def _insist_on_server_transition(self, server, curr_status, new_status): |
148 | d246be88 | Ilias Tsitsimpis | """Insist on server transiting from curr_status to new_status"""
|
149 | d246be88 | Ilias Tsitsimpis | def check_fun(): |
150 | d246be88 | Ilias Tsitsimpis | """Check server status"""
|
151 | d246be88 | Ilias Tsitsimpis | srv = self.clients.cyclades.get_server_details(server['id']) |
152 | d246be88 | Ilias Tsitsimpis | if srv['status'] == curr_status: |
153 | d246be88 | Ilias Tsitsimpis | raise Retry()
|
154 | d246be88 | Ilias Tsitsimpis | elif srv['status'] == new_status: |
155 | d246be88 | Ilias Tsitsimpis | return
|
156 | d246be88 | Ilias Tsitsimpis | else:
|
157 | d246be88 | Ilias Tsitsimpis | msg = "Server %s went to unexpected status %s"
|
158 | d246be88 | Ilias Tsitsimpis | self.error(msg, server['name'], srv['status']) |
159 | d246be88 | Ilias Tsitsimpis | self.fail(msg % (server['name'], srv['status'])) |
160 | d246be88 | Ilias Tsitsimpis | opmsg = "Waiting for server %s to transit from %s to %s"
|
161 | d246be88 | Ilias Tsitsimpis | self.info(opmsg, server['name'], curr_status, new_status) |
162 | d246be88 | Ilias Tsitsimpis | opmsg = opmsg % (server['name'], curr_status, new_status)
|
163 | d246be88 | Ilias Tsitsimpis | self._try_until_timeout_expires(opmsg, check_fun)
|
164 | d246be88 | Ilias Tsitsimpis | |
165 | d246be88 | Ilias Tsitsimpis | def _insist_on_tcp_connection(self, family, host, port): |
166 | d246be88 | Ilias Tsitsimpis | """Insist on tcp connection"""
|
167 | d246be88 | Ilias Tsitsimpis | def check_fun(): |
168 | d246be88 | Ilias Tsitsimpis | """Get a connected socket from the specified family to host:port"""
|
169 | d246be88 | Ilias Tsitsimpis | sock = None
|
170 | d246be88 | Ilias Tsitsimpis | for res in socket.getaddrinfo(host, port, family, |
171 | d246be88 | Ilias Tsitsimpis | socket.SOCK_STREAM, 0,
|
172 | d246be88 | Ilias Tsitsimpis | socket.AI_PASSIVE): |
173 | d246be88 | Ilias Tsitsimpis | fam, socktype, proto, _, saddr = res |
174 | d246be88 | Ilias Tsitsimpis | try:
|
175 | d246be88 | Ilias Tsitsimpis | sock = socket.socket(fam, socktype, proto) |
176 | d246be88 | Ilias Tsitsimpis | except socket.error:
|
177 | d246be88 | Ilias Tsitsimpis | sock = None
|
178 | d246be88 | Ilias Tsitsimpis | continue
|
179 | d246be88 | Ilias Tsitsimpis | try:
|
180 | d246be88 | Ilias Tsitsimpis | sock.connect(saddr) |
181 | d246be88 | Ilias Tsitsimpis | except socket.error:
|
182 | d246be88 | Ilias Tsitsimpis | sock.close() |
183 | d246be88 | Ilias Tsitsimpis | sock = None
|
184 | d246be88 | Ilias Tsitsimpis | continue
|
185 | d246be88 | Ilias Tsitsimpis | if sock is None: |
186 | d246be88 | Ilias Tsitsimpis | raise Retry
|
187 | d246be88 | Ilias Tsitsimpis | return sock
|
188 | d246be88 | Ilias Tsitsimpis | familystr = {socket.AF_INET: "IPv4", socket.AF_INET6: "IPv6", |
189 | d246be88 | Ilias Tsitsimpis | socket.AF_UNSPEC: "Unspecified-IPv4/6"}
|
190 | d246be88 | Ilias Tsitsimpis | opmsg = "Connecting over %s to %s:%s"
|
191 | d246be88 | Ilias Tsitsimpis | self.info(opmsg, familystr.get(family, "Unknown"), host, port) |
192 | d246be88 | Ilias Tsitsimpis | opmsg = opmsg % (familystr.get(family, "Unknown"), host, port)
|
193 | d246be88 | Ilias Tsitsimpis | return self._try_until_timeout_expires(opmsg, check_fun) |
194 | d246be88 | Ilias Tsitsimpis | |
195 | cee3ee9b | Ilias Tsitsimpis | def _get_ip(self, server, version=4): |
196 | d246be88 | Ilias Tsitsimpis | """Get the public IP of a server from the detailed server info"""
|
197 | d246be88 | Ilias Tsitsimpis | assert version in (4, 6) |
198 | d246be88 | Ilias Tsitsimpis | |
199 | d246be88 | Ilias Tsitsimpis | nics = server['attachments']
|
200 | d246be88 | Ilias Tsitsimpis | public_addrs = None
|
201 | d246be88 | Ilias Tsitsimpis | for nic in nics: |
202 | d246be88 | Ilias Tsitsimpis | net_id = nic['network_id']
|
203 | d246be88 | Ilias Tsitsimpis | if self.clients.cyclades.get_network_details(net_id)['public']: |
204 | d246be88 | Ilias Tsitsimpis | public_addrs = nic['ipv' + str(version)] |
205 | d246be88 | Ilias Tsitsimpis | |
206 | d246be88 | Ilias Tsitsimpis | self.assertIsNotNone(public_addrs)
|
207 | cee3ee9b | Ilias Tsitsimpis | msg = "Server's public IPv%s is %s"
|
208 | cee3ee9b | Ilias Tsitsimpis | self.info(msg, version, public_addrs)
|
209 | d246be88 | Ilias Tsitsimpis | return public_addrs
|
210 | d246be88 | Ilias Tsitsimpis | |
211 | cee3ee9b | Ilias Tsitsimpis | def _insist_on_ping(self, ip_addr, version=4): |
212 | d246be88 | Ilias Tsitsimpis | """Test server responds to a single IPv4 of IPv6 ping"""
|
213 | d246be88 | Ilias Tsitsimpis | def check_fun(): |
214 | d246be88 | Ilias Tsitsimpis | """Ping to server"""
|
215 | d246be88 | Ilias Tsitsimpis | cmd = ("ping%s -c 3 -w 20 %s" %
|
216 | d246be88 | Ilias Tsitsimpis | ("6" if version == 6 else "", ip_addr)) |
217 | d246be88 | Ilias Tsitsimpis | ping = subprocess.Popen( |
218 | d246be88 | Ilias Tsitsimpis | cmd, shell=True, stdout=subprocess.PIPE,
|
219 | d246be88 | Ilias Tsitsimpis | stderr=subprocess.PIPE) |
220 | d246be88 | Ilias Tsitsimpis | ping.communicate() |
221 | d246be88 | Ilias Tsitsimpis | ret = ping.wait() |
222 | d246be88 | Ilias Tsitsimpis | if ret != 0: |
223 | d246be88 | Ilias Tsitsimpis | raise Retry
|
224 | cee3ee9b | Ilias Tsitsimpis | assert version in (4, 6) |
225 | d246be88 | Ilias Tsitsimpis | opmsg = "Sent IPv%s ping requests to %s"
|
226 | d246be88 | Ilias Tsitsimpis | self.info(opmsg, version, ip_addr)
|
227 | d246be88 | Ilias Tsitsimpis | opmsg = opmsg % (version, ip_addr) |
228 | d246be88 | Ilias Tsitsimpis | self._try_until_timeout_expires(opmsg, check_fun)
|
229 | d246be88 | Ilias Tsitsimpis | |
230 | cee3ee9b | Ilias Tsitsimpis | def _image_is(self, image, osfamily): |
231 | cee3ee9b | Ilias Tsitsimpis | """Return true if the image is of `osfamily'"""
|
232 | cee3ee9b | Ilias Tsitsimpis | d_image = self.clients.cyclades.get_image_details(image['id']) |
233 | cee3ee9b | Ilias Tsitsimpis | return d_image['metadata']['osfamily'].lower().find(osfamily) >= 0 |
234 | cee3ee9b | Ilias Tsitsimpis | |
235 | cee3ee9b | Ilias Tsitsimpis | def _ssh_execute(self, hostip, username, password, command): |
236 | cee3ee9b | Ilias Tsitsimpis | """Execute a command via ssh"""
|
237 | cee3ee9b | Ilias Tsitsimpis | ssh = paramiko.SSHClient() |
238 | cee3ee9b | Ilias Tsitsimpis | ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) |
239 | cee3ee9b | Ilias Tsitsimpis | try:
|
240 | cee3ee9b | Ilias Tsitsimpis | ssh.connect(hostip, username=username, password=password) |
241 | cee3ee9b | Ilias Tsitsimpis | except socket.error as err: |
242 | cee3ee9b | Ilias Tsitsimpis | self.fail(err)
|
243 | cee3ee9b | Ilias Tsitsimpis | try:
|
244 | cee3ee9b | Ilias Tsitsimpis | _, stdout, _ = ssh.exec_command(command) |
245 | cee3ee9b | Ilias Tsitsimpis | except paramiko.SSHException as err: |
246 | cee3ee9b | Ilias Tsitsimpis | self.fail(err)
|
247 | cee3ee9b | Ilias Tsitsimpis | status = stdout.channel.recv_exit_status() |
248 | cee3ee9b | Ilias Tsitsimpis | output = stdout.readlines() |
249 | cee3ee9b | Ilias Tsitsimpis | ssh.close() |
250 | cee3ee9b | Ilias Tsitsimpis | return output, status
|
251 | cee3ee9b | Ilias Tsitsimpis | |
252 | cee3ee9b | Ilias Tsitsimpis | def _insist_get_hostname_over_ssh(self, hostip, username, password): |
253 | cee3ee9b | Ilias Tsitsimpis | """Connect to server using ssh and get it's hostname"""
|
254 | cee3ee9b | Ilias Tsitsimpis | def check_fun(): |
255 | cee3ee9b | Ilias Tsitsimpis | """Get hostname"""
|
256 | cee3ee9b | Ilias Tsitsimpis | try:
|
257 | cee3ee9b | Ilias Tsitsimpis | lines, status = self._ssh_execute(
|
258 | cee3ee9b | Ilias Tsitsimpis | hostip, username, password, "hostname")
|
259 | cee3ee9b | Ilias Tsitsimpis | self.assertEqual(status, 0) |
260 | cee3ee9b | Ilias Tsitsimpis | self.assertEqual(len(lines), 1) |
261 | cee3ee9b | Ilias Tsitsimpis | # Remove new line
|
262 | cee3ee9b | Ilias Tsitsimpis | return lines[0].strip('\n') |
263 | cee3ee9b | Ilias Tsitsimpis | except AssertionError: |
264 | cee3ee9b | Ilias Tsitsimpis | raise Retry()
|
265 | cee3ee9b | Ilias Tsitsimpis | opmsg = "Connecting to server using ssh and get it's hostname"
|
266 | cee3ee9b | Ilias Tsitsimpis | self.info(opmsg)
|
267 | cee3ee9b | Ilias Tsitsimpis | hostname = self._try_until_timeout_expires(opmsg, check_fun)
|
268 | cee3ee9b | Ilias Tsitsimpis | self.info("Server's hostname is %s", hostname) |
269 | cee3ee9b | Ilias Tsitsimpis | return hostname
|
270 | cee3ee9b | Ilias Tsitsimpis | |
271 | cee3ee9b | Ilias Tsitsimpis | # Too many arguments. pylint: disable-msg=R0913
|
272 | cee3ee9b | Ilias Tsitsimpis | def _check_file_through_ssh(self, hostip, username, password, |
273 | cee3ee9b | Ilias Tsitsimpis | remotepath, content): |
274 | cee3ee9b | Ilias Tsitsimpis | """Fetch file from server and compare contents"""
|
275 | cee3ee9b | Ilias Tsitsimpis | self.info("Fetching file %s from remote server", remotepath) |
276 | cee3ee9b | Ilias Tsitsimpis | transport = paramiko.Transport((hostip, 22))
|
277 | cee3ee9b | Ilias Tsitsimpis | transport.connect(username=username, password=password) |
278 | cee3ee9b | Ilias Tsitsimpis | with tempfile.NamedTemporaryFile() as ftmp: |
279 | cee3ee9b | Ilias Tsitsimpis | sftp = paramiko.SFTPClient.from_transport(transport) |
280 | cee3ee9b | Ilias Tsitsimpis | sftp.get(remotepath, ftmp.name) |
281 | cee3ee9b | Ilias Tsitsimpis | sftp.close() |
282 | cee3ee9b | Ilias Tsitsimpis | transport.close() |
283 | cee3ee9b | Ilias Tsitsimpis | self.info("Comparing file contents") |
284 | cee3ee9b | Ilias Tsitsimpis | remote_content = base64.b64encode(ftmp.read()) |
285 | cee3ee9b | Ilias Tsitsimpis | self.assertEqual(content, remote_content)
|
286 | cee3ee9b | Ilias Tsitsimpis | |
287 | d246be88 | Ilias Tsitsimpis | |
288 | d246be88 | Ilias Tsitsimpis | class Retry(Exception): |
289 | d246be88 | Ilias Tsitsimpis | """Retry the action
|
290 | d246be88 | Ilias Tsitsimpis |
|
291 | d246be88 | Ilias Tsitsimpis | This is used by _try_unit_timeout_expires method.
|
292 | d246be88 | Ilias Tsitsimpis |
|
293 | d246be88 | Ilias Tsitsimpis | """ |