From 65780acbf752f5d0d8bd4d2202b7fe8aff8e83dd Mon Sep 17 00:00:00 2001 From: Ilya Etingof Date: Fri, 7 Feb 2020 11:15:09 +0100 Subject: [PATCH] Add system boot device/mode commands The new commands are: # shows allowed boot devices and boot mode sushycli system boot show # set system boot device/boot mode sushycli system boot set ... Change-Id: If3e6dedacf3b6e51e04c27489420ecd0ab7c0f4a Story: 2006608 Task: 36776 --- setup.cfg | 2 + sushycli/system_boot.py | 93 ++++++++++++++++++++++++ sushycli/tests/unit/cmd/test_sushycli.py | 60 +++++++++++++++ 3 files changed, 155 insertions(+) create mode 100644 sushycli/system_boot.py diff --git a/setup.cfg b/setup.cfg index 5af4eeb..358b3ff 100644 --- a/setup.cfg +++ b/setup.cfg @@ -26,6 +26,8 @@ console_scripts = sushycli = sushycli.cmd.sushycli:main sushycli = + system_boot_show = sushycli.system_boot:SystemBootShow + system_boot_set = sushycli.system_boot:SystemBootSet chassis_list = sushycli.chassis_list:ChassisList chassis_inventory_show = sushycli.chassis_inventory:ChassisInventoryShow manager_list = sushycli.manager_list:ManagerList diff --git a/sushycli/system_boot.py b/sushycli/system_boot.py new file mode 100644 index 0000000..82368f7 --- /dev/null +++ b/sushycli/system_boot.py @@ -0,0 +1,93 @@ +# -*- coding: utf-8 -*- + +# Copyright 2010-2020 OpenStack Foundation +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +import sushy + +from sushycli import base_system + + +class SystemBootShow(base_system.BaseLister): + """Show system boot information""" + + def take_action(self, args): + """Show system boot information command action""" + + root = super(SystemBootShow, self).take_action(args) + + sys_inst = root.get_system(args.system_id) + + colunms = [ + 'Boot mode', + 'Available boot modes', + 'Boot device', + 'Available boot devices' + ] + + boot_modes = sorted(sys_inst.boot.allowed_values) + boot_devices = sorted( + sys_inst.get_allowed_system_boot_source_values()) + + values = [[sys_inst.boot.mode, ', '.join(boot_modes), + sys_inst.boot.target, ', '.join(boot_devices)]] + + return colunms, values + + +class SystemBootSet(base_system.BaseCommand): + """Set the system boot mode/device + + Change system boot mode and device specifying the frequency; + either it is disabled, applied once or persistent for future reboots + """ + + def get_parser(self, prog_name): + """Set boot device command parser""" + + parser = super(SystemBootSet, self).get_parser(prog_name) + + parser.add_argument( + '--target', + choices=['none', 'pxe', 'floppy', 'cd', 'usb', 'hdd'], + type=lambda x: x.lower(), + required=True, + help='the target boot source') + parser.add_argument( + '--enabled', + type=lambda x: x.lower(), + choices=['disabled', 'once', 'continuous'], + help='Next reboot only or persistent to all future reboots, ' + 'default is set to boot once') + parser.add_argument( + '--mode', + choices=['bios', 'uefi'], + type=lambda x: x.lower(), + help='the machine boot mode') + + return parser + + def take_action(self, args): + """Set boot device command action""" + + root = super(SystemBootSet, self).take_action(args) + + sys_inst = root.get_system(args.system_id) + + sys_inst.set_system_boot_source( + args.target, + enabled=args.enabled, + mode=sushy.BOOT_SOURCE_MODE_UEFI + if args.mode == 'uefi' else sushy.BOOT_SOURCE_MODE_BIOS) + return 0 diff --git a/sushycli/tests/unit/cmd/test_sushycli.py b/sushycli/tests/unit/cmd/test_sushycli.py index e812441..d02f6b7 100644 --- a/sushycli/tests/unit/cmd/test_sushycli.py +++ b/sushycli/tests/unit/cmd/test_sushycli.py @@ -51,6 +51,66 @@ class SuchyCliTestCase(base.TestCase): mock_write.assert_has_calls(expected_calls) + @mock.patch('sys.stdout.write', autospec=True) + def test_system_boot_show(self, mock_write, mock_sushy): + + mock_root = mock_sushy.return_value + + mock_system = mock_root.get_system.return_value + + mock_system.boot.mode = 'Disabled' + mock_system.boot.allowed_values = ['Pxe', 'Cd', 'Hdd'] + mock_gasbsv = mock_system.get_allowed_system_boot_source_values + mock_gasbsv.return_value = {'hdd', 'pxe', 'cd'} + mock_system.boot.target = 'Hdd' + + main(['system', 'boot', 'show', + '--username', 'jelly', '--password', 'fish', + '--service-endpoint', 'http://fish.me', + '--system-id', '/redfish/v1/Systems/1']) + + mock_sushy.assert_called_once_with( + 'http://fish.me', password='fish', username='jelly') + + expected_calls = [ + mock.call('+-----------+----------------------+-------------+----' + '--------------------+\n| Boot mode | Available boot mo' + 'des | Boot device | Available boot devices |\n+-------' + '----+----------------------+-------------+------------' + '------------+\n| Disabled | Cd, Hdd, Pxe | Hd' + 'd | cd, hdd, pxe |\n+-----------+---' + '-------------------+-------------+--------------------' + '----+'), + mock.call('\n') + ] + + mock_write.assert_has_calls(expected_calls) + + def test_system_boot_set(self, mock_sushy): + + main(['system', 'boot', 'set', + '--username', 'jelly', '--password', 'fish', + '--service-endpoint', 'http://fish.me', + '--system-id', '/redfish/v1/Systems/1', + '--target', 'cd', + '--enabled', 'once', + '--mode', 'uefi']) + + mock_sushy.assert_called_once_with( + 'http://fish.me', password='fish', username='jelly') + + mock_root = mock_sushy.return_value + + mock_root.get_system.assert_called_once_with( + '/redfish/v1/Systems/1') + + mock_system = mock_root.get_system.return_value + + mock_system.set_system_boot_source.\ + assert_called_once_with(sushy.BOOT_SOURCE_TARGET_CD, + enabled=sushy.BOOT_SOURCE_ENABLED_ONCE, + mode=sushy.BOOT_SOURCE_MODE_UEFI) + @mock.patch('sys.stdout.write', autospec=True) def test_chassis_inventory_show(self, mock_write, mock_sushy):