Add firmware update support using SUM

This commit adds firmware update support using
Smart Update Manager version from 8.0.0.

Change-Id: I405b640476b708ba6bd12e7a1840d45586d77e7e
This commit is contained in:
Aparna 2017-08-17 06:51:32 +00:00
parent b448d89897
commit 973de4ae5e
2 changed files with 83 additions and 13 deletions

View File

@ -32,11 +32,15 @@ from proliantutils import utils
HPSUM_LOCATION = 'hp/swpackages/hpsum'
SUM_LOCATION = 'packages/smartupdate'
WAIT_TIME_DISK_LABEL_TO_BE_VISIBLE = 5
# List of log files created by SUM based firmware update.
OUTPUT_FILES = ['/var/hp/log/localhost/hpsum_log.txt',
'/var/hp/log/localhost/hpsum_detail_log.txt']
'/var/hp/log/localhost/hpsum_detail_log.txt',
'/var/log/sum/localhost/sum_log.txt',
'/var/log/sum/localhost/sum_detail_log.txt']
EXIT_CODE_TO_STRING = {
0: "The smart component was installed successfully.",
@ -48,7 +52,7 @@ EXIT_CODE_TO_STRING = {
}
def _execute_sum(sum_file_path, components=None):
def _execute_sum(sum_file_path, mount_point, components=None):
"""Executes the SUM based firmware update command.
This method executes the SUM based firmware update command to update the
@ -59,6 +63,7 @@ def _execute_sum(sum_file_path, components=None):
executed
:param components: A list of components to be updated. If it is None, all
the firmware components are updated.
:param mount_point: Location in which SPP iso is mounted.
:returns: A string with the statistics of the updated/failed components.
:raises: SUMOperationError, when the SUM based firmware update operation
on the node fails.
@ -66,7 +71,18 @@ def _execute_sum(sum_file_path, components=None):
cmd = ' --c ' + ' --c '.join(components) if components else ''
try:
processutils.execute(sum_file_path, '--s', '--romonly', cmd)
if SUM_LOCATION in sum_file_path:
location = os.path.join(mount_point, 'packages')
# NOTE: 'launch_sum.sh' binary is part of SPP ISO and it is
# available in the SPP mount point (eg:'/mount/launch_sum.sh').
# 'launch_sum.sh' binary calls the 'smartupdate' binary by passing
# the arguments.
processutils.execute('./launch_sum.sh', '--s', '--romonly',
'--use_location', location, cmd,
cwd=mount_point)
else:
processutils.execute(sum_file_path, '--s', '--romonly', cmd)
except processutils.ProcessExecutionError as e:
result = _parse_sum_ouput(e.exit_code)
if result:
@ -203,12 +219,16 @@ def update_firmware(node):
"%(error)s" % {'device': vmedia_device_file, 'error': e})
raise exception.SUMOperationError(reason=msg)
# Executes the SUM based firmware update by passing the default hpsum
# executable path and the components specified, if any.
sum_file_path = os.path.join(vmedia_mount_point, HPSUM_LOCATION)
components = node['clean_step']['args'].get('components')
# Executes the SUM based firmware update by passing the 'smartupdate'
# executable path if exists else 'hpsum' executable path and the
# components specified (if any).
sum_file_path = os.path.join(vmedia_mount_point, SUM_LOCATION)
if not os.path.exists(sum_file_path):
sum_file_path = os.path.join(vmedia_mount_point, HPSUM_LOCATION)
result = _execute_sum(sum_file_path, components=components)
components = node['clean_step']['args'].get('components')
result = _execute_sum(sum_file_path, vmedia_mount_point,
components=components)
processutils.trycmd("umount", vmedia_mount_point)
finally:

View File

@ -64,7 +64,8 @@ class SUMFirmwareUpdateTest(testtools.TestCase):
"Failed: 0.")
}
stdout = sum_controller._execute_sum("hpsum", components=None)
stdout = sum_controller._execute_sum("hpsum", "/tmp/hpsum",
components=None)
self.assertEqual(ret_value, stdout)
execute_mock.assert_called_once_with('hpsum', '--s', '--romonly', '')
@ -78,11 +79,13 @@ class SUMFirmwareUpdateTest(testtools.TestCase):
ret_value = ("Summary: The smart component was not installed. Node is "
"already up-to-date.")
stdout = sum_controller._execute_sum("hpsum",
stdout = sum_controller._execute_sum("/tmp/sum/packages/smartupdate",
"/tmp/sum",
components=["foo", "bar"])
execute_mock.assert_called_once_with(
"hpsum", "--s", "--romonly", " --c foo --c bar")
"./launch_sum.sh", "--s", "--romonly", "--use_location",
"/tmp/sum/packages", " --c foo --c bar", cwd='/tmp/sum')
self.assertEqual(ret_value, stdout)
@mock.patch.object(sum_controller,
@ -107,7 +110,8 @@ class SUMFirmwareUpdateTest(testtools.TestCase):
execute_mock.side_effect = processutils.ProcessExecutionError(
stdout=value, stderr=None, exit_code=253)
stdout = sum_controller._execute_sum("hpsum", components=None)
stdout = sum_controller._execute_sum("hpsum", "/tmp/hpsum",
components=None)
self.assertEqual(ret, stdout)
execute_mock.assert_called_once_with(
@ -124,6 +128,7 @@ class SUMFirmwareUpdateTest(testtools.TestCase):
ex = self.assertRaises(exception.SUMOperationError,
sum_controller._execute_sum, "hpsum",
"/tmp/hpsum",
None)
self.assertIn(value, str(ex))
@ -180,8 +185,53 @@ class SUMFirmwareUpdateTest(testtools.TestCase):
execute_mock.assert_any_call('mount', "/dev/disk/by-label/SPP_LABEL",
"/tempdir")
execute_sum_mock.assert_any_call('/tempdir/hp/swpackages/hpsum',
'/tempdir',
components=None)
exists_mock.assert_called_once_with("/dev/disk/by-label/SPP_LABEL")
calls = [mock.call("/dev/disk/by-label/SPP_LABEL"),
mock.call("/tempdir/packages/smartupdate")]
exists_mock.assert_has_calls(calls, any_order=False)
execute_mock.assert_any_call('umount', "/tempdir")
mkdtemp_mock.assert_called_once_with()
rmtree_mock.assert_called_once_with("/tempdir", ignore_errors=True)
self.assertEqual('SUCCESS', ret_val)
@mock.patch.object(utils, 'validate_href')
@mock.patch.object(utils, 'verify_image_checksum')
@mock.patch.object(sum_controller, '_execute_sum')
@mock.patch.object(os, 'listdir')
@mock.patch.object(shutil, 'rmtree', autospec=True)
@mock.patch.object(tempfile, 'mkdtemp', autospec=True)
@mock.patch.object(os.path, 'exists')
@mock.patch.object(os, 'mkdir')
@mock.patch.object(processutils, 'execute')
@mock.patch.object(ilo_client, 'IloClient', spec_set=True, autospec=True)
def test_update_firmware_sum(self, client_mock, execute_mock, mkdir_mock,
exists_mock, mkdtemp_mock, rmtree_mock,
listdir_mock, execute_sum_mock,
verify_image_mock, validate_mock):
ilo_mock_object = client_mock.return_value
eject_media_mock = ilo_mock_object.eject_virtual_media
insert_media_mock = ilo_mock_object.insert_virtual_media
execute_sum_mock.return_value = 'SUCCESS'
listdir_mock.return_value = ['SPP_LABEL']
mkdtemp_mock.return_value = "/tempdir"
null_output = ["", ""]
exists_mock.side_effect = [True, True]
execute_mock.side_effect = [null_output, null_output]
ret_val = sum_controller.update_firmware(self.node)
eject_media_mock.assert_called_once_with('CDROM')
insert_media_mock.assert_called_once_with('http://1.2.3.4/SPP.iso',
'CDROM')
execute_mock.assert_any_call('mount', "/dev/disk/by-label/SPP_LABEL",
"/tempdir")
execute_sum_mock.assert_any_call('/tempdir/packages/smartupdate',
'/tempdir',
components=None)
calls = [mock.call("/dev/disk/by-label/SPP_LABEL"),
mock.call("/tempdir/packages/smartupdate")]
exists_mock.assert_has_calls(calls, any_order=False)
execute_mock.assert_any_call('umount', "/tempdir")
mkdtemp_mock.assert_called_once_with()
rmtree_mock.assert_called_once_with("/tempdir", ignore_errors=True)