diff --git a/doc/source/administration/seed.rst b/doc/source/administration/seed.rst index 2ea6d878f..f2aa91b27 100644 --- a/doc/source/administration/seed.rst +++ b/doc/source/administration/seed.rst @@ -45,6 +45,10 @@ To only install updates that have been marked security related:: Note that these commands do not affect packages installed in containers, only those installed on the host. +Packages can also be updated on the seed hypervisor host, if one is in use:: + + (kayobe) $ kayobe seed hypervisor package update --packages , + Kernel Updates -------------- diff --git a/doc/source/upgrading.rst b/doc/source/upgrading.rst index e2ed53a45..8d46f9ea3 100644 --- a/doc/source/upgrading.rst +++ b/doc/source/upgrading.rst @@ -130,7 +130,26 @@ Upgrading the Seed Hypervisor ============================= Currently, upgrading the seed hypervisor services is not supported. It may -however be necessary to upgrade some host services:: +however be necessary to upgrade host packages and some host services. + +Upgrading Host Packages +----------------------- + +Prior to upgrading the seed hypervisor, it may be desirable to upgrade system +packages on the seed hypervisor host. + +To update all eligible packages, use ``*``, escaping if necessary:: + + (kayobe) $ kayobe seed hypervisor host package update --packages * + +To only install updates that have been marked security related:: + + (kayobe) $ kayobe seed hypervisor host package update --packages --security + +Upgrading Host Services +----------------------- + +It may be necessary to upgrade some host services:: (kayobe) $ kayobe seed hypervisor host upgrade diff --git a/kayobe/cli/commands.py b/kayobe/cli/commands.py index dbb8bcc3a..6162b07aa 100644 --- a/kayobe/cli/commands.py +++ b/kayobe/cli/commands.py @@ -333,6 +333,33 @@ class SeedHypervisorHostConfigure(KollaAnsibleMixin, KayobeAnsibleMixin, limit="seed-hypervisor") +class SeedHypervisorHostPackageUpdate(KayobeAnsibleMixin, VaultMixin, Command): + """Update packages on the seed hypervisor host.""" + + def get_parser(self, prog_name): + parser = super(SeedHypervisorHostPackageUpdate, self).get_parser( + prog_name) + group = parser.add_argument_group("Host Package Updates") + group.add_argument("--packages", required=True, + help="List of packages to update. Use '*' to " + "update all packages.") + group.add_argument("--security", action='store_true', + help="Only install updates that have been marked " + "security related.") + return parser + + def take_action(self, parsed_args): + self.app.LOG.debug("Updating seed hypervisor host packages") + extra_vars = { + "host_package_update_packages": parsed_args.packages, + "host_package_update_security": parsed_args.security, + } + playbooks = _build_playbook_list("host-package-update") + self.run_kayobe_playbooks(parsed_args, playbooks, + limit="seed-hypervisor", + extra_vars=extra_vars) + + class SeedHypervisorHostCommandRun(KayobeAnsibleMixin, VaultMixin, Command): """Run command on the seed hypervisor host.""" diff --git a/kayobe/tests/unit/cli/test_commands.py b/kayobe/tests/unit/cli/test_commands.py index b4788fdea..f20de7e81 100644 --- a/kayobe/tests/unit/cli/test_commands.py +++ b/kayobe/tests/unit/cli/test_commands.py @@ -302,6 +302,84 @@ class TestCase(unittest.TestCase): ] self.assertEqual(expected_calls, mock_run.call_args_list) + @mock.patch.object(commands.KayobeAnsibleMixin, + "run_kayobe_playbooks") + def test_seed_hypervisor_host_package_update_all(self, mock_run): + command = commands.SeedHypervisorHostPackageUpdate(TestApp(), []) + parser = command.get_parser("test") + parsed_args = parser.parse_args(["--packages", "*"]) + + result = command.run(parsed_args) + self.assertEqual(0, result) + + expected_calls = [ + mock.call( + mock.ANY, + [ + utils.get_data_files_path( + "ansible", "host-package-update.yml"), + ], + limit="seed-hypervisor", + extra_vars={ + "host_package_update_packages": "*", + "host_package_update_security": False, + }, + ), + ] + self.assertEqual(expected_calls, mock_run.call_args_list) + + @mock.patch.object(commands.KayobeAnsibleMixin, + "run_kayobe_playbooks") + def test_seed_hypervisor_host_package_update_list(self, mock_run): + command = commands.SeedHypervisorHostPackageUpdate(TestApp(), []) + parser = command.get_parser("test") + parsed_args = parser.parse_args(["--packages", "p1,p2"]) + + result = command.run(parsed_args) + self.assertEqual(0, result) + + expected_calls = [ + mock.call( + mock.ANY, + [ + utils.get_data_files_path( + "ansible", "host-package-update.yml"), + ], + limit="seed-hypervisor", + extra_vars={ + "host_package_update_packages": "p1,p2", + "host_package_update_security": False, + }, + ), + ] + self.assertEqual(expected_calls, mock_run.call_args_list) + + @mock.patch.object(commands.KayobeAnsibleMixin, + "run_kayobe_playbooks") + def test_seed_hypervisor_host_package_update_security(self, mock_run): + command = commands.SeedHypervisorHostPackageUpdate(TestApp(), []) + parser = command.get_parser("test") + parsed_args = parser.parse_args(["--packages", "*", "--security"]) + + result = command.run(parsed_args) + self.assertEqual(0, result) + + expected_calls = [ + mock.call( + mock.ANY, + [ + utils.get_data_files_path( + "ansible", "host-package-update.yml"), + ], + limit="seed-hypervisor", + extra_vars={ + "host_package_update_packages": "*", + "host_package_update_security": True, + }, + ), + ] + self.assertEqual(expected_calls, mock_run.call_args_list) + @mock.patch.object(commands.KayobeAnsibleMixin, "run_kayobe_playbooks") def test_seed_hypervisor_host_upgrade(self, mock_run): diff --git a/releasenotes/notes/seed-hypervisor-host-package-update-2ad745a2d9fec134.yaml b/releasenotes/notes/seed-hypervisor-host-package-update-2ad745a2d9fec134.yaml new file mode 100644 index 000000000..433d335f4 --- /dev/null +++ b/releasenotes/notes/seed-hypervisor-host-package-update-2ad745a2d9fec134.yaml @@ -0,0 +1,7 @@ +--- +features: + - | + Add command to update packages on the seed hypervisor host, as already + available for seed and overcloud hosts: + + ``kayobe seed hypervisor host package update --packages ``