blob: 50268784f7788b408b05e124dbd8ff0ab39edbdd [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)
Charles Paul Hofer9f74d3a2017-08-18 09:54:28 -050040 if image_properties['Purpose'] != var.VERSION_PURPOSE_HOST \
41 and image_properties['Version'] != cur_img_version:
Charles Paul Hoferda24d0a2017-08-09 15:03:40 -050042 return image_name
43 BuiltIn().fail("Did not find any non-running BMC images.")
44
45###############################################################################
46
47
48###############################################################################
Charles Paul Hoferde7d4082017-08-08 14:41:01 -050049def delete_all_pnor_images():
50
51 r"""
52 Delete all PNOR images from the BMC.
53 """
54
55 status, images = keyword.run_key("Read Properties "
56 + var.SOFTWARE_VERSION_URI + "enumerate")
57 for image_name in images:
58 image_id = image_name.split('/')[-1]
59 image_purpose = images[image_name]["Purpose"]
60 if var.VERSION_PURPOSE_HOST == image_purpose:
61 # Delete twice, in case the image is in the /tmp/images directory
62 keyword.run_key("Call Method " + var.SOFTWARE_VERSION_URI
63 + image_id + " delete data={\"data\":[]}")
64 keyword.run_key("Call Method " + var.SOFTWARE_VERSION_URI
65 + image_id + " delete data={\"data\":[]}")
66
67###############################################################################
68
69
70###############################################################################
71def wait_for_activation_state_change(version_id, initial_state):
72
73 r"""
74 Wait for the current activation state of ${version_id} to
75 change from the state provided by the calling function.
76
77 Description of argument(s):
78 version_id The version ID whose state change we are waiting for.
79 initial_state The activation state we want to wait for.
80 """
81
82 keyword.run_key_u("Open Connection And Log In")
83 retry = 0
84 while (retry < 20):
85 status, software_state = keyword.run_key("Read Properties " +
86 var.SOFTWARE_VERSION_URI + str(version_id))
87 current_state = (software_state)["Activation"]
88 if (initial_state == current_state):
89 time.sleep(60)
90 retry += 1
91 else:
92 return
93 return
94
95###############################################################################
96
Saqib Khanfb1f6ae2017-04-26 13:24:41 -050097
98###############################################################################
99def get_latest_file(dir_path):
100
101 r"""
102 Get the path to the latest uploaded file.
103
104 Description of argument(s):
105 dir_path Path to the dir from which the name of the last
106 updated file or folder will be returned to the
107 calling function.
108 """
109
Charles Paul Hoferde7d4082017-08-08 14:41:01 -0500110 keyword.run_key_u("Open Connection And Log In")
Saqib Khanfb1f6ae2017-04-26 13:24:41 -0500111 status, ret_values =\
Charles Paul Hoferde7d4082017-08-08 14:41:01 -0500112 keyword.run_key("Execute Command On BMC cd " + dir_path
Saqib Khanfb1f6ae2017-04-26 13:24:41 -0500113 + "; stat -c '%Y %n' * | sort -k1,1nr | head -n 1", ignore=1)
114 return ret_values.split(" ")[-1]
115
116###############################################################################
117
118
119###############################################################################
120def get_version_tar(tar_file_path):
121
122 r"""
123 Read the image version from the MANIFEST inside the tarball.
124
125 Description of argument(s):
126 tar_file_path The path to a tar file that holds the image
127 version inside the MANIFEST.
128 """
129
130 tar = tarfile.open(tar_file_path)
131 for member in tar.getmembers():
132 f=tar.extractfile(member)
133 content=f.read()
134 if "version=" in content:
135 content = content.split("\n")
136 content = [x for x in content if "version=" in x]
137 version = content[0].split("=")[-1]
138 break
139 tar.close()
140 return version
141
142###############################################################################
143
144
145###############################################################################
146def get_image_version(file_path):
147
148 r"""
149 Read the file for a version object.
150
151 Description of argument(s):
152 file_path The path to a file that holds the image version.
153 """
154
Charles Paul Hoferde7d4082017-08-08 14:41:01 -0500155 keyword.run_key_u("Open Connection And Log In")
Saqib Khanfb1f6ae2017-04-26 13:24:41 -0500156 status, ret_values =\
Charles Paul Hoferde7d4082017-08-08 14:41:01 -0500157 keyword.run_key("Execute Command On BMC cat "
Saqib Khanbb8b63f2017-05-24 10:58:01 -0500158 + file_path + " | grep \"version=\"", ignore=1)
159 return (ret_values.split("\n")[0]).split("=")[-1]
Saqib Khanfb1f6ae2017-04-26 13:24:41 -0500160
161###############################################################################
162
163
164###############################################################################
165def get_image_purpose(file_path):
166
167 r"""
168 Read the file for a purpose object.
169
170 Description of argument(s):
171 file_path The path to a file that holds the image purpose.
172 """
173
Charles Paul Hoferde7d4082017-08-08 14:41:01 -0500174 keyword.run_key_u("Open Connection And Log In")
Saqib Khanfb1f6ae2017-04-26 13:24:41 -0500175 status, ret_values =\
Charles Paul Hoferde7d4082017-08-08 14:41:01 -0500176 keyword.run_key("Execute Command On BMC cat "
Saqib Khanbb8b63f2017-05-24 10:58:01 -0500177 + file_path + " | grep \"purpose=\"", ignore=1)
Saqib Khanfb1f6ae2017-04-26 13:24:41 -0500178 return ret_values.split("=")[-1]
179
180###############################################################################
181
182
183###############################################################################
184def get_image_path(image_version):
185
186 r"""
187 Query the upload image dir for the presence of image matching
188 the version that was read from the MANIFEST before uploading
189 the image. Based on the purpose verify the activation object
190 exists and is either READY or INVALID.
191
192 Description of argument(s):
193 image_version The version of the image that should match one
194 of the images in the upload dir.
195 """
196
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 Hofer9f74d3a2017-08-18 09:54:28 -0500199 keyword.run_key("Execute Command On BMC ls -d "
200 + var.IMAGE_UPLOAD_DIR_PATH + "*/")
Saqib Khanfb1f6ae2017-04-26 13:24:41 -0500201
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 Hofer9f74d3a2017-08-18 09:54:28 -0500216def verify_image_upload(image_version,
217 timeout=3):
Saqib Khanfb1f6ae2017-04-26 13:24:41 -0500218
219 r"""
220 Verify the image was uploaded correctly and that it created
Charles Paul Hofer6b972682017-07-20 11:36:56 -0500221 a valid d-bus object. If the first check for the image
222 fails, try again until we reach the timeout.
223
224 Description of argument(s):
Charles Paul Hofer9f74d3a2017-08-18 09:54:28 -0500225 image_version The version from the image's manifest file
226 (e.g. "IBM-witherspoon-redbud-ibm-OP9_v1.17_1.68").
227 timeout How long, in minutes, to keep trying to find the
228 image on the BMC. Default is 3 minutes.
Saqib Khanfb1f6ae2017-04-26 13:24:41 -0500229 """
230
Saqib Khanfb1f6ae2017-04-26 13:24:41 -0500231 image_path = get_image_path(image_version)
232 image_version_id = image_path.split("/")[-2]
233
Charles Paul Hoferde7d4082017-08-08 14:41:01 -0500234 keyword.run_key_u("Open Connection And Log In")
Saqib Khanfb1f6ae2017-04-26 13:24:41 -0500235 image_purpose = get_image_purpose(image_path + "MANIFEST")
Saqib Khanbb8b63f2017-05-24 10:58:01 -0500236 if (image_purpose == var.VERSION_PURPOSE_BMC or
237 image_purpose == var.VERSION_PURPOSE_HOST):
George Keishingff1e3ec2017-07-20 01:58:21 -0500238 uri = var.SOFTWARE_VERSION_URI + image_version_id
Charles Paul Hofer6b972682017-07-20 11:36:56 -0500239 ret_values = ""
240 for itr in range(timeout * 2):
241 status, ret_values = \
Charles Paul Hoferde7d4082017-08-08 14:41:01 -0500242 keyword.run_key("Read Attribute " + uri + " Activation")
Saqib Khanfb1f6ae2017-04-26 13:24:41 -0500243
Charles Paul Hofer6b972682017-07-20 11:36:56 -0500244 if ((ret_values == var.READY) or (ret_values == var.INVALID)
245 or (ret_values == var.ACTIVE)):
Charles Paul Hofercef61992017-08-18 10:14:18 -0500246 return True, image_version_id
Charles Paul Hofer6b972682017-07-20 11:36:56 -0500247 else:
248 time.sleep(30)
249
250 # If we exit the for loop, the timeout has been reached
251 gp.print_var(ret_values)
Charles Paul Hofercef61992017-08-18 10:14:18 -0500252 return False, None
Saqib Khanfb1f6ae2017-04-26 13:24:41 -0500253 else:
Saqib Khanbb8b63f2017-05-24 10:58:01 -0500254 gp.print_var(image_purpose)
Charles Paul Hofercef61992017-08-18 10:14:18 -0500255 return False, None
Saqib Khanfb1f6ae2017-04-26 13:24:41 -0500256
257###############################################################################
Charles P. Hofer1d20acd2017-07-05 15:24:40 -0500258
259
260###############################################################################
Charles Paul Hofer6b972682017-07-20 11:36:56 -0500261def verify_image_not_in_bmc_uploads_dir(image_version, timeout=3):
Charles P. Hofer1d20acd2017-07-05 15:24:40 -0500262
263 r"""
264 Check that an image with the given version is not unpacked inside of the
265 BMCs image uploads directory. If no image is found, retry every 30 seconds
Charles Paul Hofer6b972682017-07-20 11:36:56 -0500266 until the given timeout is hit, in case the BMC takes time
267 unpacking the image.
Charles P. Hofer1d20acd2017-07-05 15:24:40 -0500268
269 Description of argument(s):
270 image_version The version of the image to look for on the BMC.
Charles Paul Hofer6b972682017-07-20 11:36:56 -0500271 timeout How long, in minutes, to try to find an image on the BMC.
272 Default is 3 minutes.
Charles P. Hofer1d20acd2017-07-05 15:24:40 -0500273 """
274
Charles Paul Hoferde7d4082017-08-08 14:41:01 -0500275 keyword.run_key('Open Connection And Log In')
Charles Paul Hofer6b972682017-07-20 11:36:56 -0500276 for i in range(timeout * 2):
Charles Paul Hoferde7d4082017-08-08 14:41:01 -0500277 stat, grep_res = keyword.run_key('Execute Command On BMC '
Charles Paul Hofer9f74d3a2017-08-18 09:54:28 -0500278 + 'ls ' + var.IMAGE_UPLOAD_DIR_PATH + '*/MANIFEST 2>/dev/null '
Charles P. Hofer1d20acd2017-07-05 15:24:40 -0500279 + '| xargs grep -rl "version=' + image_version + '"')
280 image_dir = os.path.dirname(grep_res.split('\n')[0])
281 if '' != image_dir:
Charles Paul Hoferde7d4082017-08-08 14:41:01 -0500282 keyword.run_key('Execute Command On BMC rm -rf ' + image_dir)
Charles P. Hofer1d20acd2017-07-05 15:24:40 -0500283 BuiltIn().fail('Found invalid BMC Image: ' + image_dir)
284 time.sleep(30)
285
Charles Paul Hoferde7d4082017-08-08 14:41:01 -0500286###############################################################################