Support forcing rebuild of deployment images

It is hard to know when disk images need to be rebuilt, and the
stackhpc.os-images role simply checks for the presence of the DIB output
directory to indicate that an image exists. In some cases, we may wish to force
the rebuilding of a deployment (IPA) image, when we know there are changes to
apply. This change adds a --force-rebuild argument to the following commands:

kayobe seed deployment image build
kayobe overcloud deployment image build

Change-Id: I580811a4f621df9445ef32773ca66bcf303dad9b
This commit is contained in:
Mark Goddard 2018-05-10 14:16:27 +00:00
parent b80e94ca36
commit 22cf08e882
5 changed files with 151 additions and 17 deletions

View File

@ -20,7 +20,15 @@
- ipa-build - ipa-build
vars: vars:
ipa_image_name: "ipa" ipa_image_name: "ipa"
ipa_image_force_rebuild: false
tasks: tasks:
- block:
- name: Ensure existing Ironic Python Agent images are removed (force rebuild)
file:
path: "{{ image_cache_path }}/{{ ipa_image_name }}"
state: absent
when: ipa_image_force_rebuild | bool
- name: Ensure Ironic Python Agent images are built - name: Ensure Ironic Python Agent images are built
include_role: include_role:
name: stackhpc.os-images name: stackhpc.os-images

View File

@ -11,8 +11,15 @@
ipa_images: ipa_images:
- "{{ ipa_image_name }}.vmlinuz" - "{{ ipa_image_name }}.vmlinuz"
- "{{ ipa_image_name }}.initramfs" - "{{ ipa_image_name }}.initramfs"
ipa_image_force_rebuild: false
tasks: tasks:
- block: - block:
- name: Ensure existing Ironic Python Agent images are removed (force rebuild)
file:
path: "{{ image_cache_path }}/{{ ipa_image_name }}"
state: absent
when: ipa_image_force_rebuild | bool
- name: Ensure Ironic Python Agent images are built - name: Ensure Ironic Python Agent images are built
include_role: include_role:
name: stackhpc.os-images name: stackhpc.os-images

View File

@ -164,6 +164,9 @@ should be set to ``True``. To build images locally::
(kayobe) $ kayobe seed deployment image build (kayobe) $ kayobe seed deployment image build
If images have been built previously, they will not be rebuilt. To force
rebuilding images, use the ``--force-rebuild`` argument.
Accessing the Seed via SSH (Optional) Accessing the Seed via SSH (Optional)
------------------------------------- -------------------------------------
@ -333,6 +336,11 @@ Building Deployment Images
It is possible to use prebuilt deployment images. In this case, this step It is possible to use prebuilt deployment images. In this case, this step
can be skipped. can be skipped.
.. note::
Deployment images are only required for the overcloud when Ironic is in use.
Otherwise, this step can be skipped.
It is possible to use prebuilt deployment images from the `OpenStack hosted It is possible to use prebuilt deployment images from the `OpenStack hosted
tarballs <https://tarballs.openstack.org/ironic-python-agent>`_ or another tarballs <https://tarballs.openstack.org/ironic-python-agent>`_ or another
source. In some cases it may be necessary to build images locally either to source. In some cases it may be necessary to build images locally either to
@ -342,6 +350,9 @@ should be set to ``True``. To build images locally::
(kayobe) $ kayobe overcloud deployment image build (kayobe) $ kayobe overcloud deployment image build
If images have been built previously, they will not be rebuilt. To force
rebuilding images, use the ``--force-rebuild`` argument.
Deploying Containerised Services Deploying Containerised Services
-------------------------------- --------------------------------

View File

@ -514,10 +514,22 @@ class SeedDeploymentImageBuild(KayobeAnsibleMixin, VaultMixin, Command):
(DIB) for use when provisioning and inspecting the overcloud hosts. (DIB) for use when provisioning and inspecting the overcloud hosts.
""" """
def get_parser(self, prog_name):
parser = super(SeedDeploymentImageBuild, self).get_parser(
prog_name)
group = parser.add_argument_group("Deployment Image Build")
group.add_argument("--force-rebuild", action="store_true",
help="whether to force rebuilding the images")
return parser
def take_action(self, parsed_args): def take_action(self, parsed_args):
self.app.LOG.debug("Building seed deployment images") self.app.LOG.debug("Building seed deployment images")
playbooks = _build_playbook_list("seed-ipa-build") playbooks = _build_playbook_list("seed-ipa-build")
self.run_kayobe_playbooks(parsed_args, playbooks) extra_vars = {}
if parsed_args.force_rebuild:
extra_vars["ipa_image_force_rebuild"] = True
self.run_kayobe_playbooks(parsed_args, playbooks,
extra_vars=extra_vars)
class OvercloudInventoryDiscover(KayobeAnsibleMixin, VaultMixin, Command): class OvercloudInventoryDiscover(KayobeAnsibleMixin, VaultMixin, Command):
@ -1073,10 +1085,22 @@ class OvercloudContainerImageBuild(KayobeAnsibleMixin, VaultMixin, Command):
class OvercloudDeploymentImageBuild(KayobeAnsibleMixin, VaultMixin, Command): class OvercloudDeploymentImageBuild(KayobeAnsibleMixin, VaultMixin, Command):
"""Build the overcloud deployment kernel and ramdisk images.""" """Build the overcloud deployment kernel and ramdisk images."""
def get_parser(self, prog_name):
parser = super(OvercloudDeploymentImageBuild, self).get_parser(
prog_name)
group = parser.add_argument_group("Deployment Image Build")
group.add_argument("--force-rebuild", action="store_true",
help="whether to force rebuilding the images")
return parser
def take_action(self, parsed_args): def take_action(self, parsed_args):
self.app.LOG.debug("Building overcloud deployment images") self.app.LOG.debug("Building overcloud deployment images")
playbooks = _build_playbook_list("overcloud-ipa-build") playbooks = _build_playbook_list("overcloud-ipa-build")
self.run_kayobe_playbooks(parsed_args, playbooks) extra_vars = {}
if parsed_args.force_rebuild:
extra_vars["ipa_image_force_rebuild"] = True
self.run_kayobe_playbooks(parsed_args, playbooks,
extra_vars=extra_vars)
class OvercloudPostConfigure(KayobeAnsibleMixin, VaultMixin, Command): class OvercloudPostConfigure(KayobeAnsibleMixin, VaultMixin, Command):

View File

@ -387,6 +387,48 @@ class TestCase(unittest.TestCase):
] ]
self.assertEqual(expected_calls, mock_run.call_args_list) self.assertEqual(expected_calls, mock_run.call_args_list)
@mock.patch.object(commands.KayobeAnsibleMixin,
"run_kayobe_playbooks")
def test_seed_deployment_image_build(self, mock_run):
command = commands.SeedDeploymentImageBuild(TestApp(), [])
parser = command.get_parser("test")
parsed_args = parser.parse_args([])
result = command.run(parsed_args)
self.assertEqual(0, result)
expected_calls = [
mock.call(
mock.ANY,
[
"ansible/seed-ipa-build.yml",
],
extra_vars={},
),
]
self.assertEqual(expected_calls, mock_run.call_args_list)
@mock.patch.object(commands.KayobeAnsibleMixin,
"run_kayobe_playbooks")
def test_seed_deployment_image_build_force_rebuild(self, mock_run):
command = commands.SeedDeploymentImageBuild(TestApp(), [])
parser = command.get_parser("test")
parsed_args = parser.parse_args(["--force-rebuild"])
result = command.run(parsed_args)
self.assertEqual(0, result)
expected_calls = [
mock.call(
mock.ANY,
[
"ansible/seed-ipa-build.yml",
],
extra_vars={"ipa_image_force_rebuild": True},
),
]
self.assertEqual(expected_calls, mock_run.call_args_list)
@mock.patch.object(commands.KayobeAnsibleMixin, @mock.patch.object(commands.KayobeAnsibleMixin,
"run_kayobe_playbooks") "run_kayobe_playbooks")
@mock.patch.object(commands.KollaAnsibleMixin, @mock.patch.object(commands.KollaAnsibleMixin,
@ -674,6 +716,48 @@ class TestCase(unittest.TestCase):
] ]
self.assertEqual(expected_calls, mock_run.call_args_list) self.assertEqual(expected_calls, mock_run.call_args_list)
@mock.patch.object(commands.KayobeAnsibleMixin,
"run_kayobe_playbooks")
def test_overcloud_deployment_image_build(self, mock_run):
command = commands.OvercloudDeploymentImageBuild(TestApp(), [])
parser = command.get_parser("test")
parsed_args = parser.parse_args([])
result = command.run(parsed_args)
self.assertEqual(0, result)
expected_calls = [
mock.call(
mock.ANY,
[
"ansible/overcloud-ipa-build.yml",
],
extra_vars={},
),
]
self.assertEqual(expected_calls, mock_run.call_args_list)
@mock.patch.object(commands.KayobeAnsibleMixin,
"run_kayobe_playbooks")
def test_overcloud_deployment_image_build_force_rebuild(self, mock_run):
command = commands.OvercloudDeploymentImageBuild(TestApp(), [])
parser = command.get_parser("test")
parsed_args = parser.parse_args(["--force-rebuild"])
result = command.run(parsed_args)
self.assertEqual(0, result)
expected_calls = [
mock.call(
mock.ANY,
[
"ansible/overcloud-ipa-build.yml",
],
extra_vars={"ipa_image_force_rebuild": True},
),
]
self.assertEqual(expected_calls, mock_run.call_args_list)
@mock.patch.object(commands.KayobeAnsibleMixin, @mock.patch.object(commands.KayobeAnsibleMixin,
"run_kayobe_playbooks") "run_kayobe_playbooks")
def test_overcloud_post_configure(self, mock_run): def test_overcloud_post_configure(self, mock_run):