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:
parent
b448d89897
commit
973de4ae5e
|
@ -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:
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue