blob: 6b6254be638cba3b4d03192b056a58f0b53619e5 [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 Hofer1e487272017-09-14 12:55:11 -050068 if 'Purpose' in image_properties and 'Version' in image_properties \
69 and image_properties['Purpose'] != var.VERSION_PURPOSE_HOST \
Charles Paul Hofer9f74d3a2017-08-18 09:54:28 -050070 and image_properties['Version'] != cur_img_version:
Charles Paul Hoferda24d0a2017-08-09 15:03:40 -050071 return image_name
72 BuiltIn().fail("Did not find any non-running BMC images.")
73
74###############################################################################
75
76
77###############################################################################
Charles Paul Hoferde7d4082017-08-08 14:41:01 -050078def delete_all_pnor_images():
79
80 r"""
81 Delete all PNOR images from the BMC.
82 """
83
George Keishing8e984782017-08-30 14:16:18 -050084 status, images = keyword.run_key("Get Software Objects "
85 + var.VERSION_PURPOSE_HOST)
Charles Paul Hoferde7d4082017-08-08 14:41:01 -050086 for image_name in images:
George Keishing8e984782017-08-30 14:16:18 -050087 BuiltIn().log_to_console(image_name)
88 # Delete twice, in case the image is in the /tmp/images directory
89 keyword.run_key("Call Method " + image_name
90 + " delete data={\"data\":[]}")
91 keyword.run_key("Call Method " + image_name
92 + " delete data={\"data\":[]}")
Charles Paul Hoferde7d4082017-08-08 14:41:01 -050093
94###############################################################################
95
96
97###############################################################################
98def wait_for_activation_state_change(version_id, initial_state):
99
100 r"""
101 Wait for the current activation state of ${version_id} to
102 change from the state provided by the calling function.
103
104 Description of argument(s):
105 version_id The version ID whose state change we are waiting for.
106 initial_state The activation state we want to wait for.
107 """
108
109 keyword.run_key_u("Open Connection And Log In")
110 retry = 0
111 while (retry < 20):
112 status, software_state = keyword.run_key("Read Properties " +
113 var.SOFTWARE_VERSION_URI + str(version_id))
114 current_state = (software_state)["Activation"]
115 if (initial_state == current_state):
116 time.sleep(60)
117 retry += 1
118 else:
119 return
120 return
121
122###############################################################################
123
Saqib Khanfb1f6ae2017-04-26 13:24:41 -0500124
125###############################################################################
126def get_latest_file(dir_path):
127
128 r"""
129 Get the path to the latest uploaded file.
130
131 Description of argument(s):
132 dir_path Path to the dir from which the name of the last
133 updated file or folder will be returned to the
134 calling function.
135 """
136
Charles Paul Hoferde7d4082017-08-08 14:41:01 -0500137 keyword.run_key_u("Open Connection And Log In")
Saqib Khanfb1f6ae2017-04-26 13:24:41 -0500138 status, ret_values =\
Charles Paul Hoferde7d4082017-08-08 14:41:01 -0500139 keyword.run_key("Execute Command On BMC cd " + dir_path
Saqib Khanfb1f6ae2017-04-26 13:24:41 -0500140 + "; stat -c '%Y %n' * | sort -k1,1nr | head -n 1", ignore=1)
141 return ret_values.split(" ")[-1]
142
143###############################################################################
144
145
146###############################################################################
147def get_version_tar(tar_file_path):
148
149 r"""
150 Read the image version from the MANIFEST inside the tarball.
151
152 Description of argument(s):
153 tar_file_path The path to a tar file that holds the image
154 version inside the MANIFEST.
155 """
156
157 tar = tarfile.open(tar_file_path)
158 for member in tar.getmembers():
159 f=tar.extractfile(member)
160 content=f.read()
161 if "version=" in content:
162 content = content.split("\n")
163 content = [x for x in content if "version=" in x]
164 version = content[0].split("=")[-1]
165 break
166 tar.close()
167 return version
168
169###############################################################################
170
171
172###############################################################################
173def get_image_version(file_path):
174
175 r"""
176 Read the file for a version object.
177
178 Description of argument(s):
179 file_path The path to a file that holds the image version.
180 """
181
Charles Paul Hoferde7d4082017-08-08 14:41:01 -0500182 keyword.run_key_u("Open Connection And Log In")
Saqib Khanfb1f6ae2017-04-26 13:24:41 -0500183 status, ret_values =\
Charles Paul Hoferde7d4082017-08-08 14:41:01 -0500184 keyword.run_key("Execute Command On BMC cat "
Saqib Khanbb8b63f2017-05-24 10:58:01 -0500185 + file_path + " | grep \"version=\"", ignore=1)
186 return (ret_values.split("\n")[0]).split("=")[-1]
Saqib Khanfb1f6ae2017-04-26 13:24:41 -0500187
188###############################################################################
189
190
191###############################################################################
192def get_image_purpose(file_path):
193
194 r"""
195 Read the file for a purpose object.
196
197 Description of argument(s):
198 file_path The path to a file that holds the image purpose.
199 """
200
Charles Paul Hoferde7d4082017-08-08 14:41:01 -0500201 keyword.run_key_u("Open Connection And Log In")
Saqib Khanfb1f6ae2017-04-26 13:24:41 -0500202 status, ret_values =\
Charles Paul Hoferde7d4082017-08-08 14:41:01 -0500203 keyword.run_key("Execute Command On BMC cat "
Saqib Khanbb8b63f2017-05-24 10:58:01 -0500204 + file_path + " | grep \"purpose=\"", ignore=1)
Saqib Khanfb1f6ae2017-04-26 13:24:41 -0500205 return ret_values.split("=")[-1]
206
207###############################################################################
208
209
210###############################################################################
211def get_image_path(image_version):
212
213 r"""
214 Query the upload image dir for the presence of image matching
215 the version that was read from the MANIFEST before uploading
216 the image. Based on the purpose verify the activation object
217 exists and is either READY or INVALID.
218
219 Description of argument(s):
220 image_version The version of the image that should match one
221 of the images in the upload dir.
222 """
223
Charles Paul Hoferde7d4082017-08-08 14:41:01 -0500224 keyword.run_key_u("Open Connection And Log In")
Saqib Khanfb1f6ae2017-04-26 13:24:41 -0500225 status, image_list =\
Charles Paul Hofer9f74d3a2017-08-18 09:54:28 -0500226 keyword.run_key("Execute Command On BMC ls -d "
227 + var.IMAGE_UPLOAD_DIR_PATH + "*/")
Saqib Khanfb1f6ae2017-04-26 13:24:41 -0500228
229 image_list = image_list.split("\n")
230 retry = 0
231 while (retry < 10):
232 for i in range(0, len(image_list)):
233 version = get_image_version(image_list[i] + "MANIFEST")
234 if (version == image_version):
235 return image_list[i]
236 time.sleep(10)
237 retry += 1
238
239###############################################################################
240
241
242###############################################################################
Charles Paul Hofer9f74d3a2017-08-18 09:54:28 -0500243def verify_image_upload(image_version,
244 timeout=3):
Saqib Khanfb1f6ae2017-04-26 13:24:41 -0500245
246 r"""
247 Verify the image was uploaded correctly and that it created
Charles Paul Hofer6b972682017-07-20 11:36:56 -0500248 a valid d-bus object. If the first check for the image
249 fails, try again until we reach the timeout.
250
251 Description of argument(s):
Charles Paul Hofer9f74d3a2017-08-18 09:54:28 -0500252 image_version The version from the image's manifest file
253 (e.g. "IBM-witherspoon-redbud-ibm-OP9_v1.17_1.68").
254 timeout How long, in minutes, to keep trying to find the
255 image on the BMC. Default is 3 minutes.
Saqib Khanfb1f6ae2017-04-26 13:24:41 -0500256 """
257
Saqib Khanfb1f6ae2017-04-26 13:24:41 -0500258 image_path = get_image_path(image_version)
259 image_version_id = image_path.split("/")[-2]
260
Charles Paul Hoferde7d4082017-08-08 14:41:01 -0500261 keyword.run_key_u("Open Connection And Log In")
Saqib Khanfb1f6ae2017-04-26 13:24:41 -0500262 image_purpose = get_image_purpose(image_path + "MANIFEST")
Saqib Khanbb8b63f2017-05-24 10:58:01 -0500263 if (image_purpose == var.VERSION_PURPOSE_BMC or
264 image_purpose == var.VERSION_PURPOSE_HOST):
George Keishingff1e3ec2017-07-20 01:58:21 -0500265 uri = var.SOFTWARE_VERSION_URI + image_version_id
Charles Paul Hofer6b972682017-07-20 11:36:56 -0500266 ret_values = ""
267 for itr in range(timeout * 2):
268 status, ret_values = \
Charles Paul Hoferde7d4082017-08-08 14:41:01 -0500269 keyword.run_key("Read Attribute " + uri + " Activation")
Saqib Khanfb1f6ae2017-04-26 13:24:41 -0500270
Charles Paul Hofer6b972682017-07-20 11:36:56 -0500271 if ((ret_values == var.READY) or (ret_values == var.INVALID)
272 or (ret_values == var.ACTIVE)):
Charles Paul Hofercef61992017-08-18 10:14:18 -0500273 return True, image_version_id
Charles Paul Hofer6b972682017-07-20 11:36:56 -0500274 else:
275 time.sleep(30)
276
277 # If we exit the for loop, the timeout has been reached
278 gp.print_var(ret_values)
Charles Paul Hofercef61992017-08-18 10:14:18 -0500279 return False, None
Saqib Khanfb1f6ae2017-04-26 13:24:41 -0500280 else:
Saqib Khanbb8b63f2017-05-24 10:58:01 -0500281 gp.print_var(image_purpose)
Charles Paul Hofercef61992017-08-18 10:14:18 -0500282 return False, None
Saqib Khanfb1f6ae2017-04-26 13:24:41 -0500283
284###############################################################################
Charles P. Hofer1d20acd2017-07-05 15:24:40 -0500285
286
287###############################################################################
Charles Paul Hofer6b972682017-07-20 11:36:56 -0500288def verify_image_not_in_bmc_uploads_dir(image_version, timeout=3):
Charles P. Hofer1d20acd2017-07-05 15:24:40 -0500289
290 r"""
291 Check that an image with the given version is not unpacked inside of the
292 BMCs image uploads directory. If no image is found, retry every 30 seconds
Charles Paul Hofer6b972682017-07-20 11:36:56 -0500293 until the given timeout is hit, in case the BMC takes time
294 unpacking the image.
Charles P. Hofer1d20acd2017-07-05 15:24:40 -0500295
296 Description of argument(s):
297 image_version The version of the image to look for on the BMC.
Charles Paul Hofer6b972682017-07-20 11:36:56 -0500298 timeout How long, in minutes, to try to find an image on the BMC.
299 Default is 3 minutes.
Charles P. Hofer1d20acd2017-07-05 15:24:40 -0500300 """
301
Charles Paul Hoferde7d4082017-08-08 14:41:01 -0500302 keyword.run_key('Open Connection And Log In')
Charles Paul Hofer6b972682017-07-20 11:36:56 -0500303 for i in range(timeout * 2):
Charles Paul Hoferde7d4082017-08-08 14:41:01 -0500304 stat, grep_res = keyword.run_key('Execute Command On BMC '
Charles Paul Hofer9f74d3a2017-08-18 09:54:28 -0500305 + 'ls ' + var.IMAGE_UPLOAD_DIR_PATH + '*/MANIFEST 2>/dev/null '
Charles P. Hofer1d20acd2017-07-05 15:24:40 -0500306 + '| xargs grep -rl "version=' + image_version + '"')
307 image_dir = os.path.dirname(grep_res.split('\n')[0])
308 if '' != image_dir:
Charles Paul Hoferde7d4082017-08-08 14:41:01 -0500309 keyword.run_key('Execute Command On BMC rm -rf ' + image_dir)
Charles P. Hofer1d20acd2017-07-05 15:24:40 -0500310 BuiltIn().fail('Found invalid BMC Image: ' + image_dir)
311 time.sleep(30)
312
George Keishing8e984782017-08-30 14:16:18 -0500313###############################################################################