blob: c33d360b520662240d558b0ff90b27f0a2219402 [file] [log] [blame]
Saqib Khanfb1f6ae2017-04-26 13:24:41 -05001#!/usr/bin/env python
2
3r"""
Charles Paul Hoferde7d4082017-08-08 14:41:01 -05004This module provides utilities for code updates.
Saqib Khanfb1f6ae2017-04-26 13:24:41 -05005"""
6
7import os
Saqib Khanfb1f6ae2017-04-26 13:24:41 -05008import re
Charles Paul Hoferde7d4082017-08-08 14:41:01 -05009import sys
Saqib Khanfb1f6ae2017-04-26 13:24:41 -050010import tarfile
11import time
12
13robot_pgm_dir_path = os.path.dirname(__file__) + os.sep
Charles Paul Hoferde7d4082017-08-08 14:41:01 -050014repo_data_path = re.sub('/lib', '/data', robot_pgm_dir_path)
Saqib Khanfb1f6ae2017-04-26 13:24:41 -050015sys.path.append(repo_data_path)
16
Charles Paul Hoferde7d4082017-08-08 14:41:01 -050017import gen_robot_keyword as keyword
Saqib Khanfb1f6ae2017-04-26 13:24:41 -050018import gen_print as gp
19import variables as var
20from robot.libraries.BuiltIn import BuiltIn
21
Charles Paul Hoferde7d4082017-08-08 14:41:01 -050022###############################################################################
Charles Paul Hoferda24d0a2017-08-09 15:03:40 -050023def get_non_running_bmc_software_object():
24
25 r"""
26 Get the URI to a BMC image from software that is not running on the BMC.
27 """
28
29 # Get the version of the image currently running on the BMC.
30 _, cur_img_version = keyword.run_key("Get BMC Version")
31 # Remove the surrounding double quotes from the version.
32 cur_img_version = cur_img_version.replace('"', '')
33
34 _, images = keyword.run_key("Read Properties "
35 + var.SOFTWARE_VERSION_URI + "enumerate")
36
37 for image_name in images:
38 _, image_properties = keyword.run_key(
39 "Get Host Software Property " + image_name)
40 if image_properties['Version'] != cur_img_version:
41 return image_name
42 BuiltIn().fail("Did not find any non-running BMC images.")
43
44###############################################################################
45
46
47###############################################################################
Charles Paul Hoferde7d4082017-08-08 14:41:01 -050048def delete_all_pnor_images():
49
50 r"""
51 Delete all PNOR images from the BMC.
52 """
53
54 status, images = keyword.run_key("Read Properties "
55 + var.SOFTWARE_VERSION_URI + "enumerate")
56 for image_name in images:
57 image_id = image_name.split('/')[-1]
58 image_purpose = images[image_name]["Purpose"]
59 if var.VERSION_PURPOSE_HOST == image_purpose:
60 # Delete twice, in case the image is in the /tmp/images directory
61 keyword.run_key("Call Method " + var.SOFTWARE_VERSION_URI
62 + image_id + " delete data={\"data\":[]}")
63 keyword.run_key("Call Method " + var.SOFTWARE_VERSION_URI
64 + image_id + " delete data={\"data\":[]}")
65
66###############################################################################
67
68
69###############################################################################
70def wait_for_activation_state_change(version_id, initial_state):
71
72 r"""
73 Wait for the current activation state of ${version_id} to
74 change from the state provided by the calling function.
75
76 Description of argument(s):
77 version_id The version ID whose state change we are waiting for.
78 initial_state The activation state we want to wait for.
79 """
80
81 keyword.run_key_u("Open Connection And Log In")
82 retry = 0
83 while (retry < 20):
84 status, software_state = keyword.run_key("Read Properties " +
85 var.SOFTWARE_VERSION_URI + str(version_id))
86 current_state = (software_state)["Activation"]
87 if (initial_state == current_state):
88 time.sleep(60)
89 retry += 1
90 else:
91 return
92 return
93
94###############################################################################
95
Saqib Khanfb1f6ae2017-04-26 13:24:41 -050096
97###############################################################################
98def get_latest_file(dir_path):
99
100 r"""
101 Get the path to the latest uploaded file.
102
103 Description of argument(s):
104 dir_path Path to the dir from which the name of the last
105 updated file or folder will be returned to the
106 calling function.
107 """
108
Charles Paul Hoferde7d4082017-08-08 14:41:01 -0500109 keyword.run_key_u("Open Connection And Log In")
Saqib Khanfb1f6ae2017-04-26 13:24:41 -0500110 status, ret_values =\
Charles Paul Hoferde7d4082017-08-08 14:41:01 -0500111 keyword.run_key("Execute Command On BMC cd " + dir_path
Saqib Khanfb1f6ae2017-04-26 13:24:41 -0500112 + "; stat -c '%Y %n' * | sort -k1,1nr | head -n 1", ignore=1)
113 return ret_values.split(" ")[-1]
114
115###############################################################################
116
117
118###############################################################################
119def get_version_tar(tar_file_path):
120
121 r"""
122 Read the image version from the MANIFEST inside the tarball.
123
124 Description of argument(s):
125 tar_file_path The path to a tar file that holds the image
126 version inside the MANIFEST.
127 """
128
129 tar = tarfile.open(tar_file_path)
130 for member in tar.getmembers():
131 f=tar.extractfile(member)
132 content=f.read()
133 if "version=" in content:
134 content = content.split("\n")
135 content = [x for x in content if "version=" in x]
136 version = content[0].split("=")[-1]
137 break
138 tar.close()
139 return version
140
141###############################################################################
142
143
144###############################################################################
145def get_image_version(file_path):
146
147 r"""
148 Read the file for a version object.
149
150 Description of argument(s):
151 file_path The path to a file that holds the image version.
152 """
153
Charles Paul Hoferde7d4082017-08-08 14:41:01 -0500154 keyword.run_key_u("Open Connection And Log In")
Saqib Khanfb1f6ae2017-04-26 13:24:41 -0500155 status, ret_values =\
Charles Paul Hoferde7d4082017-08-08 14:41:01 -0500156 keyword.run_key("Execute Command On BMC cat "
Saqib Khanbb8b63f2017-05-24 10:58:01 -0500157 + file_path + " | grep \"version=\"", ignore=1)
158 return (ret_values.split("\n")[0]).split("=")[-1]
Saqib Khanfb1f6ae2017-04-26 13:24:41 -0500159
160###############################################################################
161
162
163###############################################################################
164def get_image_purpose(file_path):
165
166 r"""
167 Read the file for a purpose object.
168
169 Description of argument(s):
170 file_path The path to a file that holds the image purpose.
171 """
172
Charles Paul Hoferde7d4082017-08-08 14:41:01 -0500173 keyword.run_key_u("Open Connection And Log In")
Saqib Khanfb1f6ae2017-04-26 13:24:41 -0500174 status, ret_values =\
Charles Paul Hoferde7d4082017-08-08 14:41:01 -0500175 keyword.run_key("Execute Command On BMC cat "
Saqib Khanbb8b63f2017-05-24 10:58:01 -0500176 + file_path + " | grep \"purpose=\"", ignore=1)
Saqib Khanfb1f6ae2017-04-26 13:24:41 -0500177 return ret_values.split("=")[-1]
178
179###############################################################################
180
181
182###############################################################################
183def get_image_path(image_version):
184
185 r"""
186 Query the upload image dir for the presence of image matching
187 the version that was read from the MANIFEST before uploading
188 the image. Based on the purpose verify the activation object
189 exists and is either READY or INVALID.
190
191 Description of argument(s):
192 image_version The version of the image that should match one
193 of the images in the upload dir.
194 """
195
Saqib Khanbb8b63f2017-05-24 10:58:01 -0500196 upload_dir = BuiltIn().get_variable_value("${upload_dir_path}")
Charles Paul Hoferde7d4082017-08-08 14:41:01 -0500197 keyword.run_key_u("Open Connection And Log In")
Saqib Khanfb1f6ae2017-04-26 13:24:41 -0500198 status, image_list =\
Charles Paul Hoferde7d4082017-08-08 14:41:01 -0500199 keyword.run_key("Execute Command On BMC ls -d " + upload_dir
Saqib Khanfb1f6ae2017-04-26 13:24:41 -0500200 + "*/")
201
202 image_list = image_list.split("\n")
203 retry = 0
204 while (retry < 10):
205 for i in range(0, len(image_list)):
206 version = get_image_version(image_list[i] + "MANIFEST")
207 if (version == image_version):
208 return image_list[i]
209 time.sleep(10)
210 retry += 1
211
212###############################################################################
213
214
215###############################################################################
Charles Paul Hofercef61992017-08-18 10:14:18 -0500216def verify_image_upload(image_version, timeout=3):
Saqib Khanfb1f6ae2017-04-26 13:24:41 -0500217
218 r"""
219 Verify the image was uploaded correctly and that it created
Charles Paul Hofer6b972682017-07-20 11:36:56 -0500220 a valid d-bus object. If the first check for the image
221 fails, try again until we reach the timeout.
222
223 Description of argument(s):
Charles Paul Hofercef61992017-08-18 10:14:18 -0500224 image_version The version from the image's manifest file.
Charles Paul Hofer6b972682017-07-20 11:36:56 -0500225 timeout How long, in minutes, to keep trying to find the
226 image on the BMC. Default is 3 minutes.
Saqib Khanfb1f6ae2017-04-26 13:24:41 -0500227 """
228
Saqib Khanfb1f6ae2017-04-26 13:24:41 -0500229 image_path = get_image_path(image_version)
230 image_version_id = image_path.split("/")[-2]
231
Charles Paul Hoferde7d4082017-08-08 14:41:01 -0500232 keyword.run_key_u("Open Connection And Log In")
Saqib Khanfb1f6ae2017-04-26 13:24:41 -0500233 image_purpose = get_image_purpose(image_path + "MANIFEST")
Saqib Khanbb8b63f2017-05-24 10:58:01 -0500234 if (image_purpose == var.VERSION_PURPOSE_BMC or
235 image_purpose == var.VERSION_PURPOSE_HOST):
George Keishingff1e3ec2017-07-20 01:58:21 -0500236 uri = var.SOFTWARE_VERSION_URI + image_version_id
Charles Paul Hofer6b972682017-07-20 11:36:56 -0500237 ret_values = ""
238 for itr in range(timeout * 2):
239 status, ret_values = \
Charles Paul Hoferde7d4082017-08-08 14:41:01 -0500240 keyword.run_key("Read Attribute " + uri + " Activation")
Saqib Khanfb1f6ae2017-04-26 13:24:41 -0500241
Charles Paul Hofer6b972682017-07-20 11:36:56 -0500242 if ((ret_values == var.READY) or (ret_values == var.INVALID)
243 or (ret_values == var.ACTIVE)):
Charles Paul Hofercef61992017-08-18 10:14:18 -0500244 return True, image_version_id
Charles Paul Hofer6b972682017-07-20 11:36:56 -0500245 else:
246 time.sleep(30)
247
248 # If we exit the for loop, the timeout has been reached
249 gp.print_var(ret_values)
Charles Paul Hofercef61992017-08-18 10:14:18 -0500250 return False, None
Saqib Khanfb1f6ae2017-04-26 13:24:41 -0500251 else:
Saqib Khanbb8b63f2017-05-24 10:58:01 -0500252 gp.print_var(image_purpose)
Charles Paul Hofercef61992017-08-18 10:14:18 -0500253 return False, None
Saqib Khanfb1f6ae2017-04-26 13:24:41 -0500254
255###############################################################################
Charles P. Hofer1d20acd2017-07-05 15:24:40 -0500256
257
258###############################################################################
Charles Paul Hofer6b972682017-07-20 11:36:56 -0500259def verify_image_not_in_bmc_uploads_dir(image_version, timeout=3):
Charles P. Hofer1d20acd2017-07-05 15:24:40 -0500260
261 r"""
262 Check that an image with the given version is not unpacked inside of the
263 BMCs image uploads directory. If no image is found, retry every 30 seconds
Charles Paul Hofer6b972682017-07-20 11:36:56 -0500264 until the given timeout is hit, in case the BMC takes time
265 unpacking the image.
Charles P. Hofer1d20acd2017-07-05 15:24:40 -0500266
267 Description of argument(s):
268 image_version The version of the image to look for on the BMC.
Charles Paul Hofer6b972682017-07-20 11:36:56 -0500269 timeout How long, in minutes, to try to find an image on the BMC.
270 Default is 3 minutes.
Charles P. Hofer1d20acd2017-07-05 15:24:40 -0500271 """
272
Charles Paul Hoferde7d4082017-08-08 14:41:01 -0500273 keyword.run_key('Open Connection And Log In')
Charles P. Hofer346c0452017-07-14 15:29:50 -0500274 upload_dir_path = BuiltIn().get_variable_value("${upload_dir_path}")
Charles Paul Hofer6b972682017-07-20 11:36:56 -0500275 for i in range(timeout * 2):
Charles Paul Hoferde7d4082017-08-08 14:41:01 -0500276 stat, grep_res = keyword.run_key('Execute Command On BMC '
Charles P. Hofer1d20acd2017-07-05 15:24:40 -0500277 + 'ls ' + upload_dir_path + '*/MANIFEST 2>/dev/null '
278 + '| xargs grep -rl "version=' + image_version + '"')
279 image_dir = os.path.dirname(grep_res.split('\n')[0])
280 if '' != image_dir:
Charles Paul Hoferde7d4082017-08-08 14:41:01 -0500281 keyword.run_key('Execute Command On BMC rm -rf ' + image_dir)
Charles P. Hofer1d20acd2017-07-05 15:24:40 -0500282 BuiltIn().fail('Found invalid BMC Image: ' + image_dir)
283 time.sleep(30)
284
Charles Paul Hoferde7d4082017-08-08 14:41:01 -0500285###############################################################################