blob: a785fe6cf0dbd1dcfadb41807ecfb259dfa47445 [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###############################################################################
23def delete_all_pnor_images():
24
25 r"""
26 Delete all PNOR images from the BMC.
27 """
28
29 status, images = keyword.run_key("Read Properties "
30 + var.SOFTWARE_VERSION_URI + "enumerate")
31 for image_name in images:
32 image_id = image_name.split('/')[-1]
33 image_purpose = images[image_name]["Purpose"]
34 if var.VERSION_PURPOSE_HOST == image_purpose:
35 # Delete twice, in case the image is in the /tmp/images directory
36 keyword.run_key("Call Method " + var.SOFTWARE_VERSION_URI
37 + image_id + " delete data={\"data\":[]}")
38 keyword.run_key("Call Method " + var.SOFTWARE_VERSION_URI
39 + image_id + " delete data={\"data\":[]}")
40
41###############################################################################
42
43
44###############################################################################
45def wait_for_activation_state_change(version_id, initial_state):
46
47 r"""
48 Wait for the current activation state of ${version_id} to
49 change from the state provided by the calling function.
50
51 Description of argument(s):
52 version_id The version ID whose state change we are waiting for.
53 initial_state The activation state we want to wait for.
54 """
55
56 keyword.run_key_u("Open Connection And Log In")
57 retry = 0
58 while (retry < 20):
59 status, software_state = keyword.run_key("Read Properties " +
60 var.SOFTWARE_VERSION_URI + str(version_id))
61 current_state = (software_state)["Activation"]
62 if (initial_state == current_state):
63 time.sleep(60)
64 retry += 1
65 else:
66 return
67 return
68
69###############################################################################
70
Saqib Khanfb1f6ae2017-04-26 13:24:41 -050071
72###############################################################################
73def get_latest_file(dir_path):
74
75 r"""
76 Get the path to the latest uploaded file.
77
78 Description of argument(s):
79 dir_path Path to the dir from which the name of the last
80 updated file or folder will be returned to the
81 calling function.
82 """
83
Charles Paul Hoferde7d4082017-08-08 14:41:01 -050084 keyword.run_key_u("Open Connection And Log In")
Saqib Khanfb1f6ae2017-04-26 13:24:41 -050085 status, ret_values =\
Charles Paul Hoferde7d4082017-08-08 14:41:01 -050086 keyword.run_key("Execute Command On BMC cd " + dir_path
Saqib Khanfb1f6ae2017-04-26 13:24:41 -050087 + "; stat -c '%Y %n' * | sort -k1,1nr | head -n 1", ignore=1)
88 return ret_values.split(" ")[-1]
89
90###############################################################################
91
92
93###############################################################################
94def get_version_tar(tar_file_path):
95
96 r"""
97 Read the image version from the MANIFEST inside the tarball.
98
99 Description of argument(s):
100 tar_file_path The path to a tar file that holds the image
101 version inside the MANIFEST.
102 """
103
104 tar = tarfile.open(tar_file_path)
105 for member in tar.getmembers():
106 f=tar.extractfile(member)
107 content=f.read()
108 if "version=" in content:
109 content = content.split("\n")
110 content = [x for x in content if "version=" in x]
111 version = content[0].split("=")[-1]
112 break
113 tar.close()
114 return version
115
116###############################################################################
117
118
119###############################################################################
120def get_image_version(file_path):
121
122 r"""
123 Read the file for a version object.
124
125 Description of argument(s):
126 file_path The path to a file that holds the image version.
127 """
128
Charles Paul Hoferde7d4082017-08-08 14:41:01 -0500129 keyword.run_key_u("Open Connection And Log In")
Saqib Khanfb1f6ae2017-04-26 13:24:41 -0500130 status, ret_values =\
Charles Paul Hoferde7d4082017-08-08 14:41:01 -0500131 keyword.run_key("Execute Command On BMC cat "
Saqib Khanbb8b63f2017-05-24 10:58:01 -0500132 + file_path + " | grep \"version=\"", ignore=1)
133 return (ret_values.split("\n")[0]).split("=")[-1]
Saqib Khanfb1f6ae2017-04-26 13:24:41 -0500134
135###############################################################################
136
137
138###############################################################################
139def get_image_purpose(file_path):
140
141 r"""
142 Read the file for a purpose object.
143
144 Description of argument(s):
145 file_path The path to a file that holds the image purpose.
146 """
147
Charles Paul Hoferde7d4082017-08-08 14:41:01 -0500148 keyword.run_key_u("Open Connection And Log In")
Saqib Khanfb1f6ae2017-04-26 13:24:41 -0500149 status, ret_values =\
Charles Paul Hoferde7d4082017-08-08 14:41:01 -0500150 keyword.run_key("Execute Command On BMC cat "
Saqib Khanbb8b63f2017-05-24 10:58:01 -0500151 + file_path + " | grep \"purpose=\"", ignore=1)
Saqib Khanfb1f6ae2017-04-26 13:24:41 -0500152 return ret_values.split("=")[-1]
153
154###############################################################################
155
156
157###############################################################################
158def get_image_path(image_version):
159
160 r"""
161 Query the upload image dir for the presence of image matching
162 the version that was read from the MANIFEST before uploading
163 the image. Based on the purpose verify the activation object
164 exists and is either READY or INVALID.
165
166 Description of argument(s):
167 image_version The version of the image that should match one
168 of the images in the upload dir.
169 """
170
Saqib Khanbb8b63f2017-05-24 10:58:01 -0500171 upload_dir = BuiltIn().get_variable_value("${upload_dir_path}")
Charles Paul Hoferde7d4082017-08-08 14:41:01 -0500172 keyword.run_key_u("Open Connection And Log In")
Saqib Khanfb1f6ae2017-04-26 13:24:41 -0500173 status, image_list =\
Charles Paul Hoferde7d4082017-08-08 14:41:01 -0500174 keyword.run_key("Execute Command On BMC ls -d " + upload_dir
Saqib Khanfb1f6ae2017-04-26 13:24:41 -0500175 + "*/")
176
177 image_list = image_list.split("\n")
178 retry = 0
179 while (retry < 10):
180 for i in range(0, len(image_list)):
181 version = get_image_version(image_list[i] + "MANIFEST")
182 if (version == image_version):
183 return image_list[i]
184 time.sleep(10)
185 retry += 1
186
187###############################################################################
188
189
190###############################################################################
Charles Paul Hofer6b972682017-07-20 11:36:56 -0500191def verify_image_upload(timeout=3):
Saqib Khanfb1f6ae2017-04-26 13:24:41 -0500192
193 r"""
194 Verify the image was uploaded correctly and that it created
Charles Paul Hofer6b972682017-07-20 11:36:56 -0500195 a valid d-bus object. If the first check for the image
196 fails, try again until we reach the timeout.
197
198 Description of argument(s):
199 timeout How long, in minutes, to keep trying to find the
200 image on the BMC. Default is 3 minutes.
Saqib Khanfb1f6ae2017-04-26 13:24:41 -0500201 """
202
Saqib Khanbb8b63f2017-05-24 10:58:01 -0500203 image_version = BuiltIn().get_variable_value("${image_version}")
Saqib Khanfb1f6ae2017-04-26 13:24:41 -0500204 image_path = get_image_path(image_version)
205 image_version_id = image_path.split("/")[-2]
Saqib Khanbb8b63f2017-05-24 10:58:01 -0500206 BuiltIn().set_global_variable("${version_id}", image_version_id)
Saqib Khanfb1f6ae2017-04-26 13:24:41 -0500207
Charles Paul Hoferde7d4082017-08-08 14:41:01 -0500208 keyword.run_key_u("Open Connection And Log In")
Saqib Khanfb1f6ae2017-04-26 13:24:41 -0500209 image_purpose = get_image_purpose(image_path + "MANIFEST")
Saqib Khanbb8b63f2017-05-24 10:58:01 -0500210 if (image_purpose == var.VERSION_PURPOSE_BMC or
211 image_purpose == var.VERSION_PURPOSE_HOST):
George Keishingff1e3ec2017-07-20 01:58:21 -0500212 uri = var.SOFTWARE_VERSION_URI + image_version_id
Charles Paul Hofer6b972682017-07-20 11:36:56 -0500213 ret_values = ""
214 for itr in range(timeout * 2):
215 status, ret_values = \
Charles Paul Hoferde7d4082017-08-08 14:41:01 -0500216 keyword.run_key("Read Attribute " + uri + " Activation")
Saqib Khanfb1f6ae2017-04-26 13:24:41 -0500217
Charles Paul Hofer6b972682017-07-20 11:36:56 -0500218 if ((ret_values == var.READY) or (ret_values == var.INVALID)
219 or (ret_values == var.ACTIVE)):
220 return True
221 else:
222 time.sleep(30)
223
224 # If we exit the for loop, the timeout has been reached
225 gp.print_var(ret_values)
226 return False
Saqib Khanfb1f6ae2017-04-26 13:24:41 -0500227 else:
Saqib Khanbb8b63f2017-05-24 10:58:01 -0500228 gp.print_var(image_purpose)
Saqib Khanfb1f6ae2017-04-26 13:24:41 -0500229 return False
230
231###############################################################################
Charles P. Hofer1d20acd2017-07-05 15:24:40 -0500232
233
234###############################################################################
Charles Paul Hofer6b972682017-07-20 11:36:56 -0500235def verify_image_not_in_bmc_uploads_dir(image_version, timeout=3):
Charles P. Hofer1d20acd2017-07-05 15:24:40 -0500236
237 r"""
238 Check that an image with the given version is not unpacked inside of the
239 BMCs image uploads directory. If no image is found, retry every 30 seconds
Charles Paul Hofer6b972682017-07-20 11:36:56 -0500240 until the given timeout is hit, in case the BMC takes time
241 unpacking the image.
Charles P. Hofer1d20acd2017-07-05 15:24:40 -0500242
243 Description of argument(s):
244 image_version The version of the image to look for on the BMC.
Charles Paul Hofer6b972682017-07-20 11:36:56 -0500245 timeout How long, in minutes, to try to find an image on the BMC.
246 Default is 3 minutes.
Charles P. Hofer1d20acd2017-07-05 15:24:40 -0500247 """
248
Charles Paul Hoferde7d4082017-08-08 14:41:01 -0500249 keyword.run_key('Open Connection And Log In')
Charles P. Hofer346c0452017-07-14 15:29:50 -0500250 upload_dir_path = BuiltIn().get_variable_value("${upload_dir_path}")
Charles Paul Hofer6b972682017-07-20 11:36:56 -0500251 for i in range(timeout * 2):
Charles Paul Hoferde7d4082017-08-08 14:41:01 -0500252 stat, grep_res = keyword.run_key('Execute Command On BMC '
Charles P. Hofer1d20acd2017-07-05 15:24:40 -0500253 + 'ls ' + upload_dir_path + '*/MANIFEST 2>/dev/null '
254 + '| xargs grep -rl "version=' + image_version + '"')
255 image_dir = os.path.dirname(grep_res.split('\n')[0])
256 if '' != image_dir:
Charles Paul Hoferde7d4082017-08-08 14:41:01 -0500257 keyword.run_key('Execute Command On BMC rm -rf ' + image_dir)
Charles P. Hofer1d20acd2017-07-05 15:24:40 -0500258 BuiltIn().fail('Found invalid BMC Image: ' + image_dir)
259 time.sleep(30)
260
Charles Paul Hoferde7d4082017-08-08 14:41:01 -0500261###############################################################################