blob: dd1cdc318bea58a10e877729fd087bfc5ed9f605 [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 Hoferc1fa2bc2017-08-18 16:44:03 -050023def verify_no_duplicate_image_priorities(image_purpose):
24
25 r"""
26 Check that there are no active images with the same purpose and priority.
27
28 Description of argument(s):
29 image_purpose The purpose that images must have to be checked for
30 priority duplicates.
31 """
32
33 taken_priorities = {}
34 _, image_names = keyword.run_key("Get Software Objects "
35 + "version_type=" + image_purpose)
36
37 for image_name in image_names:
38 _, image = keyword.run_key("Get Host Software Property " + image_name)
39 if image["Activation"] != var.ACTIVE:
40 continue
41 image_priority = image["Priority"]
42 if image_priority in taken_priorities:
43 BuiltIn().fail("Found active images with the same priority.\n"
44 + gp.sprint_vars(image, taken_priorities[image_priority]))
Charles Paul Hofera5673162017-08-30 09:49:16 -050045 taken_priorities[image_priority] = image
Charles Paul Hoferc1fa2bc2017-08-18 16:44:03 -050046
47###############################################################################
48
49
50###############################################################################
Charles Paul Hoferda24d0a2017-08-09 15:03:40 -050051def get_non_running_bmc_software_object():
52
53 r"""
54 Get the URI to a BMC image from software that is not running on the BMC.
55 """
56
57 # Get the version of the image currently running on the BMC.
58 _, cur_img_version = keyword.run_key("Get BMC Version")
59 # Remove the surrounding double quotes from the version.
60 cur_img_version = cur_img_version.replace('"', '')
61
62 _, images = keyword.run_key("Read Properties "
63 + var.SOFTWARE_VERSION_URI + "enumerate")
64
65 for image_name in images:
66 _, image_properties = keyword.run_key(
67 "Get Host Software Property " + image_name)
Charles Paul Hofer9f74d3a2017-08-18 09:54:28 -050068 if image_properties['Purpose'] != var.VERSION_PURPOSE_HOST \
69 and image_properties['Version'] != cur_img_version:
Charles Paul Hoferda24d0a2017-08-09 15:03:40 -050070 return image_name
71 BuiltIn().fail("Did not find any non-running BMC images.")
72
73###############################################################################
74
75
76###############################################################################
Charles Paul Hoferde7d4082017-08-08 14:41:01 -050077def delete_all_pnor_images():
78
79 r"""
80 Delete all PNOR images from the BMC.
81 """
82
George Keishing8e984782017-08-30 14:16:18 -050083 status, images = keyword.run_key("Get Software Objects "
84 + var.VERSION_PURPOSE_HOST)
Charles Paul Hoferde7d4082017-08-08 14:41:01 -050085 for image_name in images:
George Keishing8e984782017-08-30 14:16:18 -050086 BuiltIn().log_to_console(image_name)
87 # Delete twice, in case the image is in the /tmp/images directory
88 keyword.run_key("Call Method " + image_name
89 + " delete data={\"data\":[]}")
90 keyword.run_key("Call Method " + image_name
91 + " delete data={\"data\":[]}")
Charles Paul Hoferde7d4082017-08-08 14:41:01 -050092
93###############################################################################
94
95
96###############################################################################
97def wait_for_activation_state_change(version_id, initial_state):
98
99 r"""
100 Wait for the current activation state of ${version_id} to
101 change from the state provided by the calling function.
102
103 Description of argument(s):
104 version_id The version ID whose state change we are waiting for.
105 initial_state The activation state we want to wait for.
106 """
107
108 keyword.run_key_u("Open Connection And Log In")
109 retry = 0
110 while (retry < 20):
111 status, software_state = keyword.run_key("Read Properties " +
112 var.SOFTWARE_VERSION_URI + str(version_id))
113 current_state = (software_state)["Activation"]
114 if (initial_state == current_state):
115 time.sleep(60)
116 retry += 1
117 else:
118 return
119 return
120
121###############################################################################
122
Saqib Khanfb1f6ae2017-04-26 13:24:41 -0500123
124###############################################################################
125def get_latest_file(dir_path):
126
127 r"""
128 Get the path to the latest uploaded file.
129
130 Description of argument(s):
131 dir_path Path to the dir from which the name of the last
132 updated file or folder will be returned to the
133 calling function.
134 """
135
Charles Paul Hoferde7d4082017-08-08 14:41:01 -0500136 keyword.run_key_u("Open Connection And Log In")
Saqib Khanfb1f6ae2017-04-26 13:24:41 -0500137 status, ret_values =\
Charles Paul Hoferde7d4082017-08-08 14:41:01 -0500138 keyword.run_key("Execute Command On BMC cd " + dir_path
Saqib Khanfb1f6ae2017-04-26 13:24:41 -0500139 + "; stat -c '%Y %n' * | sort -k1,1nr | head -n 1", ignore=1)
140 return ret_values.split(" ")[-1]
141
142###############################################################################
143
144
145###############################################################################
146def get_version_tar(tar_file_path):
147
148 r"""
149 Read the image version from the MANIFEST inside the tarball.
150
151 Description of argument(s):
152 tar_file_path The path to a tar file that holds the image
153 version inside the MANIFEST.
154 """
155
156 tar = tarfile.open(tar_file_path)
157 for member in tar.getmembers():
158 f=tar.extractfile(member)
159 content=f.read()
160 if "version=" in content:
161 content = content.split("\n")
162 content = [x for x in content if "version=" in x]
163 version = content[0].split("=")[-1]
164 break
165 tar.close()
166 return version
167
168###############################################################################
169
170
171###############################################################################
172def get_image_version(file_path):
173
174 r"""
175 Read the file for a version object.
176
177 Description of argument(s):
178 file_path The path to a file that holds the image version.
179 """
180
Charles Paul Hoferde7d4082017-08-08 14:41:01 -0500181 keyword.run_key_u("Open Connection And Log In")
Saqib Khanfb1f6ae2017-04-26 13:24:41 -0500182 status, ret_values =\
Charles Paul Hoferde7d4082017-08-08 14:41:01 -0500183 keyword.run_key("Execute Command On BMC cat "
Saqib Khanbb8b63f2017-05-24 10:58:01 -0500184 + file_path + " | grep \"version=\"", ignore=1)
185 return (ret_values.split("\n")[0]).split("=")[-1]
Saqib Khanfb1f6ae2017-04-26 13:24:41 -0500186
187###############################################################################
188
189
190###############################################################################
191def get_image_purpose(file_path):
192
193 r"""
194 Read the file for a purpose object.
195
196 Description of argument(s):
197 file_path The path to a file that holds the image purpose.
198 """
199
Charles Paul Hoferde7d4082017-08-08 14:41:01 -0500200 keyword.run_key_u("Open Connection And Log In")
Saqib Khanfb1f6ae2017-04-26 13:24:41 -0500201 status, ret_values =\
Charles Paul Hoferde7d4082017-08-08 14:41:01 -0500202 keyword.run_key("Execute Command On BMC cat "
Saqib Khanbb8b63f2017-05-24 10:58:01 -0500203 + file_path + " | grep \"purpose=\"", ignore=1)
Saqib Khanfb1f6ae2017-04-26 13:24:41 -0500204 return ret_values.split("=")[-1]
205
206###############################################################################
207
208
209###############################################################################
210def get_image_path(image_version):
211
212 r"""
213 Query the upload image dir for the presence of image matching
214 the version that was read from the MANIFEST before uploading
215 the image. Based on the purpose verify the activation object
216 exists and is either READY or INVALID.
217
218 Description of argument(s):
219 image_version The version of the image that should match one
220 of the images in the upload dir.
221 """
222
Charles Paul Hoferde7d4082017-08-08 14:41:01 -0500223 keyword.run_key_u("Open Connection And Log In")
Saqib Khanfb1f6ae2017-04-26 13:24:41 -0500224 status, image_list =\
Charles Paul Hofer9f74d3a2017-08-18 09:54:28 -0500225 keyword.run_key("Execute Command On BMC ls -d "
226 + var.IMAGE_UPLOAD_DIR_PATH + "*/")
Saqib Khanfb1f6ae2017-04-26 13:24:41 -0500227
228 image_list = image_list.split("\n")
229 retry = 0
230 while (retry < 10):
231 for i in range(0, len(image_list)):
232 version = get_image_version(image_list[i] + "MANIFEST")
233 if (version == image_version):
234 return image_list[i]
235 time.sleep(10)
236 retry += 1
237
238###############################################################################
239
240
241###############################################################################
Charles Paul Hofer9f74d3a2017-08-18 09:54:28 -0500242def verify_image_upload(image_version,
243 timeout=3):
Saqib Khanfb1f6ae2017-04-26 13:24:41 -0500244
245 r"""
246 Verify the image was uploaded correctly and that it created
Charles Paul Hofer6b972682017-07-20 11:36:56 -0500247 a valid d-bus object. If the first check for the image
248 fails, try again until we reach the timeout.
249
250 Description of argument(s):
Charles Paul Hofer9f74d3a2017-08-18 09:54:28 -0500251 image_version The version from the image's manifest file
252 (e.g. "IBM-witherspoon-redbud-ibm-OP9_v1.17_1.68").
253 timeout How long, in minutes, to keep trying to find the
254 image on the BMC. Default is 3 minutes.
Saqib Khanfb1f6ae2017-04-26 13:24:41 -0500255 """
256
Saqib Khanfb1f6ae2017-04-26 13:24:41 -0500257 image_path = get_image_path(image_version)
258 image_version_id = image_path.split("/")[-2]
259
Charles Paul Hoferde7d4082017-08-08 14:41:01 -0500260 keyword.run_key_u("Open Connection And Log In")
Saqib Khanfb1f6ae2017-04-26 13:24:41 -0500261 image_purpose = get_image_purpose(image_path + "MANIFEST")
Saqib Khanbb8b63f2017-05-24 10:58:01 -0500262 if (image_purpose == var.VERSION_PURPOSE_BMC or
263 image_purpose == var.VERSION_PURPOSE_HOST):
George Keishingff1e3ec2017-07-20 01:58:21 -0500264 uri = var.SOFTWARE_VERSION_URI + image_version_id
Charles Paul Hofer6b972682017-07-20 11:36:56 -0500265 ret_values = ""
266 for itr in range(timeout * 2):
267 status, ret_values = \
Charles Paul Hoferde7d4082017-08-08 14:41:01 -0500268 keyword.run_key("Read Attribute " + uri + " Activation")
Saqib Khanfb1f6ae2017-04-26 13:24:41 -0500269
Charles Paul Hofer6b972682017-07-20 11:36:56 -0500270 if ((ret_values == var.READY) or (ret_values == var.INVALID)
271 or (ret_values == var.ACTIVE)):
Charles Paul Hofercef61992017-08-18 10:14:18 -0500272 return True, image_version_id
Charles Paul Hofer6b972682017-07-20 11:36:56 -0500273 else:
274 time.sleep(30)
275
276 # If we exit the for loop, the timeout has been reached
277 gp.print_var(ret_values)
Charles Paul Hofercef61992017-08-18 10:14:18 -0500278 return False, None
Saqib Khanfb1f6ae2017-04-26 13:24:41 -0500279 else:
Saqib Khanbb8b63f2017-05-24 10:58:01 -0500280 gp.print_var(image_purpose)
Charles Paul Hofercef61992017-08-18 10:14:18 -0500281 return False, None
Saqib Khanfb1f6ae2017-04-26 13:24:41 -0500282
283###############################################################################
Charles P. Hofer1d20acd2017-07-05 15:24:40 -0500284
285
286###############################################################################
Charles Paul Hofer6b972682017-07-20 11:36:56 -0500287def verify_image_not_in_bmc_uploads_dir(image_version, timeout=3):
Charles P. Hofer1d20acd2017-07-05 15:24:40 -0500288
289 r"""
290 Check that an image with the given version is not unpacked inside of the
291 BMCs image uploads directory. If no image is found, retry every 30 seconds
Charles Paul Hofer6b972682017-07-20 11:36:56 -0500292 until the given timeout is hit, in case the BMC takes time
293 unpacking the image.
Charles P. Hofer1d20acd2017-07-05 15:24:40 -0500294
295 Description of argument(s):
296 image_version The version of the image to look for on the BMC.
Charles Paul Hofer6b972682017-07-20 11:36:56 -0500297 timeout How long, in minutes, to try to find an image on the BMC.
298 Default is 3 minutes.
Charles P. Hofer1d20acd2017-07-05 15:24:40 -0500299 """
300
Charles Paul Hoferde7d4082017-08-08 14:41:01 -0500301 keyword.run_key('Open Connection And Log In')
Charles Paul Hofer6b972682017-07-20 11:36:56 -0500302 for i in range(timeout * 2):
Charles Paul Hoferde7d4082017-08-08 14:41:01 -0500303 stat, grep_res = keyword.run_key('Execute Command On BMC '
Charles Paul Hofer9f74d3a2017-08-18 09:54:28 -0500304 + 'ls ' + var.IMAGE_UPLOAD_DIR_PATH + '*/MANIFEST 2>/dev/null '
Charles P. Hofer1d20acd2017-07-05 15:24:40 -0500305 + '| xargs grep -rl "version=' + image_version + '"')
306 image_dir = os.path.dirname(grep_res.split('\n')[0])
307 if '' != image_dir:
Charles Paul Hoferde7d4082017-08-08 14:41:01 -0500308 keyword.run_key('Execute Command On BMC rm -rf ' + image_dir)
Charles P. Hofer1d20acd2017-07-05 15:24:40 -0500309 BuiltIn().fail('Found invalid BMC Image: ' + image_dir)
310 time.sleep(30)
311
George Keishing8e984782017-08-30 14:16:18 -0500312###############################################################################