summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeorge Kraft <george.kraft@calxeda.com>2013-04-30 16:45:23 -0500
committerGeorge Kraft <george.kraft@calxeda.com>2013-04-30 16:45:23 -0500
commit8a6795c724a23f876ff0f00b6884145cd258e4f3 (patch)
tree9433c870fc73910dde109bffaa33eb9a8dad2cd2
parent096e8b341a82520e4603d95c806a195089cc709a (diff)
downloadcxmanage-8a6795c724a23f876ff0f00b6884145cd258e4f3.tar.gz
CXMAN-196: Node: Add post-verification checks to firmware update
For now, we check that the image type is the same, the priority is incremented, crc32 check passes, and the image is activated.
-rw-r--r--cxmanage_api/node.py29
-rw-r--r--cxmanage_test/node_test.py26
2 files changed, 48 insertions, 7 deletions
diff --git a/cxmanage_api/node.py b/cxmanage_api/node.py
index b99cbd6..bf05291 100644
--- a/cxmanage_api/node.py
+++ b/cxmanage_api/node.py
@@ -637,6 +637,8 @@ class Node(object):
if (priority == None):
priority = self._get_next_priority(fwinfo, package)
+ updated_partitions = []
+
for image in package.images:
if (image.type == "UBOOTENV"):
# Get partitions
@@ -666,6 +668,7 @@ class Node(object):
except (ValueError, Exception):
self._upload_image(image, running_part, priority)
+ updated_partitions += [running_part, factory_part]
else:
# Get the partitions
if (partition_arg == "BOTH"):
@@ -680,9 +683,35 @@ class Node(object):
for partition in partitions:
self._upload_image(image, partition, priority)
+ updated_partitions += partitions
+
if package.version:
self.bmc.set_firmware_version(package.version)
+ # Post verify
+ fwinfo = self.get_firmware_info()
+ for old_partition in updated_partitions:
+ partition_id = int(old_partition.partition)
+ new_partition = fwinfo[partition_id]
+
+ if new_partition.type != old_partition.type:
+ raise Exception("Update failed (partition %i, type changed)"
+ % partition_id)
+
+ if int(new_partition.priority, 16) != priority:
+ raise Exception("Update failed (partition %i, wrong priority)"
+ % partition_id)
+
+ if int(new_partition.flags, 16) & 2 != 0:
+ raise Exception("Update failed (partition %i, not activated)"
+ % partition_id)
+
+ result = self.bmc.check_firmware(partition_id)
+ if not hasattr(result, "crc32") or result.error != None:
+ raise Exception("Update failed (partition %i, post-crc32 fail)"
+ % partition_id)
+
+
def config_reset(self):
"""Resets configuration to factory defaults.
diff --git a/cxmanage_test/node_test.py b/cxmanage_test/node_test.py
index 00ad275..05b618f 100644
--- a/cxmanage_test/node_test.py
+++ b/cxmanage_test/node_test.py
@@ -39,7 +39,8 @@ from pyipmi import IpmiError
from pyipmi.bmc import LanBMC
from cxmanage_test import TestImage, TestSensor, random_file
-from cxmanage_api.simg import create_simg
+from cxmanage_api import temp_file
+from cxmanage_api.simg import create_simg, get_simg_header
from cxmanage_api.node import Node
from cxmanage_api.tftp import InternalTftp, ExternalTftp
from cxmanage_api.ubootenv import UbootEnv
@@ -49,13 +50,13 @@ from cxmanage_api.cx_exceptions import IPDiscoveryError
NUM_NODES = 4
ADDRESSES = ["192.168.100.%i" % x for x in range(1, NUM_NODES + 1)]
+TFTP = InternalTftp()
class NodeTest(unittest.TestCase):
""" Tests involving cxmanage Nodes """
def setUp(self):
- tftp = InternalTftp()
- self.nodes = [Node(ip_address=ip, tftp=tftp, bmc=DummyBMC,
+ self.nodes = [Node(ip_address=ip, tftp=TFTP, bmc=DummyBMC,
image=TestImage, ubootenv=DummyUbootEnv,
ipretriever=DummyIPRetriever, verbose=True)
for ip in ADDRESSES]
@@ -187,16 +188,16 @@ class NodeTest(unittest.TestCase):
for partition in changed_partitions:
self.assertEqual(partition.updates, 1)
self.assertEqual(partition.retrieves, 0)
- self.assertEqual(partition.checks, 1)
+ self.assertEqual(partition.checks, 2)
self.assertEqual(partition.activates, 1)
self.assertEqual(ubootenv_partition.updates, 1)
self.assertEqual(ubootenv_partition.retrieves, 1)
- self.assertEqual(ubootenv_partition.checks, 1)
+ self.assertEqual(ubootenv_partition.checks, 2)
self.assertEqual(ubootenv_partition.activates, 1)
- self.assertEqual(node.bmc.executed[-1],
- ("set_firmware_version", "0.0.1"))
+ self.assertTrue(("set_firmware_version", "0.0.1")
+ in node.bmc.executed)
def test_config_reset(self):
""" Test node.config_reset method """
@@ -405,6 +406,16 @@ class DummyBMC(LanBMC):
partition, image_type, tftp_addr))
self.partitions[partition].updates += 1
+ localfile = temp_file()
+ TFTP.get_file(filename, localfile)
+
+ contents = open(localfile).read()
+ simg = get_simg_header(contents)
+ self.partitions[partition].fwinfo.offset = "%8x" % simg.imgoff
+ self.partitions[partition].fwinfo.size = "%8x" % simg.imglen
+ self.partitions[partition].fwinfo.priority = "%8x" % simg.priority
+ self.partitions[partition].fwinfo.daddr = "%8x" % simg.daddr
+
class Result:
def __init__(self):
self.tftp_handle_id = 0
@@ -673,6 +684,7 @@ class DummyBMC(LanBMC):
def fabric_rm_macaddr(self, nodeid=0, iface=0, macaddr=None):
self.executed.append('fabric_rm_macaddr')
+
class Partition:
def __init__(self, partition, type, offset=0,
size=0, priority=0, daddr=0, in_use=None):