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,20 +20,28 @@
- ipa-build
vars:
ipa_image_name: "ipa"
ipa_image_force_rebuild: false
tasks:
- name: Ensure Ironic Python Agent images are built
include_role:
name: stackhpc.os-images
vars:
os_images_venv: "{{ virtualenv_path }}/ipa-build-dib"
os_images_cache: "{{ image_cache_path }}"
os_images_common: ""
os_images_list:
- name: "{{ ipa_image_name }}"
elements: "{{ ipa_build_dib_elements }}"
env: "{{ ipa_build_dib_env }}"
# Avoid needing to install qemu-img for qcow2 image.
type: raw
os_images_git_elements: "{{ ipa_build_dib_git_elements }}"
os_images_upload: False
- 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
include_role:
name: stackhpc.os-images
vars:
os_images_venv: "{{ virtualenv_path }}/ipa-build-dib"
os_images_cache: "{{ image_cache_path }}"
os_images_common: ""
os_images_list:
- name: "{{ ipa_image_name }}"
elements: "{{ ipa_build_dib_elements }}"
env: "{{ ipa_build_dib_env }}"
# Avoid needing to install qemu-img for qcow2 image.
type: raw
os_images_git_elements: "{{ ipa_build_dib_git_elements }}"
os_images_upload: False
when: ipa_build_images | bool

View File

@ -11,8 +11,15 @@
ipa_images:
- "{{ ipa_image_name }}.vmlinuz"
- "{{ ipa_image_name }}.initramfs"
ipa_image_force_rebuild: false
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
include_role:
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
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)
-------------------------------------
@ -333,6 +336,11 @@ Building Deployment Images
It is possible to use prebuilt deployment images. In this case, this step
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
tarballs <https://tarballs.openstack.org/ironic-python-agent>`_ or another
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
If images have been built previously, they will not be rebuilt. To force
rebuilding images, use the ``--force-rebuild`` argument.
Deploying Containerised Services
--------------------------------

View File

@ -514,10 +514,22 @@ class SeedDeploymentImageBuild(KayobeAnsibleMixin, VaultMixin, Command):
(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):
self.app.LOG.debug("Building seed deployment images")
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):
@ -1073,10 +1085,22 @@ class OvercloudContainerImageBuild(KayobeAnsibleMixin, VaultMixin, Command):
class OvercloudDeploymentImageBuild(KayobeAnsibleMixin, VaultMixin, Command):
"""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):
self.app.LOG.debug("Building overcloud deployment images")
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):

View File

@ -387,6 +387,48 @@ class TestCase(unittest.TestCase):
]
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,
"run_kayobe_playbooks")
@mock.patch.object(commands.KollaAnsibleMixin,
@ -674,6 +716,48 @@ class TestCase(unittest.TestCase):
]
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,
"run_kayobe_playbooks")
def test_overcloud_post_configure(self, mock_run):