Build overcloud host image directly with DIB

As a first step towards supporting multiple overcloud disk images, this
change introduces a new command to build a disk image directly with DIB:
`kayobe overcloud host image build`.

It also disables building a root disk image during Bifrost bootstrap if
overcloud_dib_build_host_images is set to true.

Change-Id: I93d242889e225b4e60254f6b9cc5eeb457294ac8
Story: 2002098
Task: 41693
This commit is contained in:
Pierre Riteau 2021-11-26 09:28:00 +01:00
parent 52d7523c0c
commit c35f112a14
11 changed files with 258 additions and 3 deletions

View File

@ -0,0 +1,54 @@
---
# Overcloud host disk image configuration.
###############################################################################
# Diskimage-builder configuration for overcloud host disk images.
# Whether to build host disk images with DIB directly instead of through
# Bifrost. Setting it to true disables Bifrost image build and allows images to
# be built with the `kayobe overcloud host image build` command. Default value
# is False. This will change in a future release.
overcloud_dib_build_host_images: False
# DIB base OS element. Default is {{ os_distribution }}.
overcloud_dib_os_element: "{{ os_distribution }}"
# DIB image OS release. Default is {{ os_release }}.
overcloud_dib_os_release: "{{ os_release }}"
# List of default DIB elements. Default is ["centos", "cloud-init-datasources",
# "disable-selinux", "enable-serial-console", "vm"] when
# overcloud_dib_os_element is "centos", or ["ubuntu", "cloud-init-datasources",
# "enable-serial-console", "vm"] when overcloud_dib_os_element is "ubuntu".
overcloud_dib_elements_default:
- "{{ overcloud_dib_os_element }}"
- "cloud-init-datasources"
- "{% if overcloud_dib_os_element == 'centos' %}disable-selinux{% endif %}"
- "enable-serial-console"
- "vm"
# List of additional DIB elements. Default is none.
overcloud_dib_elements_extra: []
# List of DIB elements. Default is a combination of
# overcloud_dib_elements_default and overcloud_dib_elements_extra.
overcloud_dib_elements: "{{ overcloud_dib_elements_default | select | list + overcloud_dib_elements_extra }}"
# DIB default environment variables. Default is
# {"DIB_BOOTLOADER_DEFAULT_CMDLINE": "nofb nomodeset gfxpayload=text
# net.ifnames=1", "DIB_CLOUD_INIT_DATASOURCES": "ConfigDrive", "DIB_RELEASE":
# "{{ overcloud_dib_os_release }}"}.
overcloud_dib_env_vars_default:
DIB_BOOTLOADER_DEFAULT_CMDLINE: "nofb nomodeset gfxpayload=text net.ifnames=1"
DIB_CLOUD_INIT_DATASOURCES: "ConfigDrive"
DIB_RELEASE: "{{ overcloud_dib_os_release }}"
# DIB additional environment variables. Default is none.
overcloud_dib_env_vars_extra: {}
# DIB environment variables. Default is combination of
# overcloud_dib_env_vars_default and overcloud_dib_env_vars_extra.
overcloud_dib_env_vars: "{{ overcloud_dib_env_vars_default | combine(overcloud_dib_env_vars_extra) }}"
# List of DIB packages to install. Default is to install no extra packages.
overcloud_dib_packages: []

View File

@ -0,0 +1,51 @@
---
# Build and install a overcloud host disk image for the seed host's ironic
# service.
- name: Ensure overcloud host disk image is built and installed
hosts: seed
tags:
- overcloud-host-image-build
vars:
overcloud_host_image_name: "deployment_image"
overcloud_host_disk_images:
- "{{ overcloud_host_image_name }}.qcow2"
overcloud_host_image_force_rebuild: False
tasks:
- block:
- name: Ensure overcloud host disk image is built
include_role:
name: stackhpc.os-images
vars:
os_images_venv: "{{ virtualenv_path }}/overcloud-host-image-dib"
os_images_package_state: latest
os_images_upper_constraints_file: "{{ pip_upper_constraints_file }}"
os_images_cache: "{{ image_cache_path }}"
os_images_common: ""
os_images_list:
- name: "{{ overcloud_host_image_name }}"
elements: "{{ overcloud_dib_elements }}"
env: "{{ overcloud_dib_env_vars }}"
packages: "{{ overcloud_dib_packages }}"
type: qcow2
os_images_upload: False
os_images_force_rebuild: "{{ overcloud_host_image_force_rebuild }}"
- name: Ensure overcloud host disk image is copied onto seed
copy:
src: "{{ image_cache_path }}/{{ overcloud_host_image_name }}/{{ item }}"
dest: "/etc/kolla/bifrost/{{ item }}"
remote_src: True
with_items: "{{ overcloud_host_disk_images }}"
become: True
- name: Copy overcloud host disk image into /httpboot
command: >
docker exec bifrost_deploy
bash -c 'ansible -vvvv target
-i /bifrost/playbooks/inventory/target
-m copy
-a "src=/etc/bifrost/{{ item }} dest=/httpboot/{{ item }}"
-e "ansible_python_interpreter=/var/lib/kolla/venv/bin/python"'
with_items: "{{ overcloud_host_disk_images }}"
when: overcloud_dib_build_host_images | bool

View File

@ -1,4 +1,5 @@
---
{% if not overcloud_dib_build_host_images | bool %}
# Diskimage-builder element for base OS.
dib_os_element: "{{ kolla_bifrost_dib_os_element }}"
@ -13,3 +14,9 @@ dib_elements: "{{ (kolla_bifrost_dib_elements + [kolla_bifrost_dib_init_element]
# List of DIB image packages.
dib_packages: "{{ kolla_bifrost_dib_packages | join(',') }}"
{% else %}
# Stop building overcloud host image using Bifrost. This needs to be defined
# here to override the default true value set in kolla-ansible in
# ansible/roles/bifrost/templates/dib.yml.j2.
create_image_via_dib: False
{% endif %}

View File

@ -53,8 +53,8 @@
- name: Copy Ironic Python Agent images into /httpboot
command: >
docker exec bifrost_deploy
bash -c 'export OS_CLOUD=bifrost &&
ansible -vvvv target -i /bifrost/playbooks/inventory/target
bash -c 'ansible -vvvv target
-i /bifrost/playbooks/inventory/target
-m copy
-a "src=/etc/bifrost/{{ item }} dest=/httpboot/{{ item }}"
-e "ansible_python_interpreter=/var/lib/kolla/venv/bin/python"'

View File

@ -219,6 +219,11 @@ function is_ironic_enabled {
[[ $ironic_enabled =~ ^true$ ]]
}
function is_overcloud_host_image_built_by_dib {
overcloud_dib_build_host_images=$(kayobe configuration dump --host controllers[0] --var-name overcloud_dib_build_host_images)
[[ $overcloud_dib_build_host_images =~ ^true$ ]]
}
function environment_setup {
# NOTE: Virtualenv's activate script references an unbound variable.
set +u
@ -316,6 +321,13 @@ function seed_deploy {
else
echo "Not building seed deployment images"
fi
if is_overcloud_host_image_built_by_dib; then
echo "Building overcloud host images"
run_kayobe overcloud host image build
else
echo "Not building overcloud host images"
fi
}
function seed_upgrade {

View File

@ -0,0 +1,50 @@
---
# Overcloud host disk image configuration.
###############################################################################
# Diskimage-builder configuration for overcloud host disk images.
# Whether to build host disk images with DIB directly instead of through
# Bifrost. Setting it to true disables Bifrost image build and allows images to
# be built with the `kayobe overcloud host image build` command. Default value
# is False. This will change in a future release.
#overcloud_dib_build_host_images:
# DIB base OS element. Default is {{ os_distribution }}.
#overcloud_dib_os_element:
# DIB image OS release. Default is {{ os_release }}.
#overcloud_dib_os_release:
# List of default DIB elements. Default is ["centos", "cloud-init-datasources",
# "disable-selinux", "enable-serial-console", "vm"] when
# overcloud_dib_os_element is "centos", or ["ubuntu", "cloud-init-datasources",
# "enable-serial-console", "vm"] when overcloud_dib_os_element is "ubuntu".
#overcloud_dib_elements_default:
# List of additional DIB elements. Default is none.
#overcloud_dib_elements_extra:
# List of DIB elements. Default is a combination of
# overcloud_dib_elements_default and overcloud_dib_elements_extra.
#overcloud_dib_elements:
# DIB default environment variables. Default is
# {"DIB_BOOTLOADER_DEFAULT_CMDLINE": "nofb nomodeset gfxpayload=text
# net.ifnames=1", "DIB_CLOUD_INIT_DATASOURCES": "ConfigDrive", "DIB_RELEASE":
# "{{ overcloud_dib_os_release }}"}.
#overcloud_dib_env_vars_default:
# DIB additional environment variables. Default is none.
#overcloud_dib_env_vars_extra:
# DIB environment variables. Default is combination of
# overcloud_dib_env_vars_default and overcloud_dib_env_vars_extra.
#overcloud_dib_env_vars:
# List of DIB packages to install. Default is to install no extra packages.
#overcloud_dib_packages:
###############################################################################
# Dummy variable to allow Ansible to accept this file.
workaround_ansible_issue_8743: yes

View File

@ -1762,6 +1762,31 @@ class OvercloudDeploymentImageBuild(KayobeAnsibleMixin, VaultMixin, Command):
extra_vars=extra_vars)
class OvercloudHostImageBuild(KayobeAnsibleMixin, VaultMixin, Command):
"""Build overcloud host disk images.
Builds host disk images using Diskimage Builder (DIB) for use when
provisioning the overcloud hosts.
"""
def get_parser(self, prog_name):
parser = super(OvercloudHostImageBuild, self).get_parser(
prog_name)
group = parser.add_argument_group("Host 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 host disk images")
playbooks = _build_playbook_list("overcloud-host-image-build")
extra_vars = {}
if parsed_args.force_rebuild:
extra_vars["overcloud_host_image_force_rebuild"] = True
self.run_kayobe_playbooks(parsed_args, playbooks,
extra_vars=extra_vars)
class OvercloudPostConfigure(KayobeAnsibleMixin, VaultMixin, Command):
"""Perform post-deployment configuration.

View File

@ -2000,6 +2000,50 @@ class TestCase(unittest.TestCase):
]
self.assertEqual(expected_calls, mock_run.call_args_list)
@mock.patch.object(commands.KayobeAnsibleMixin,
"run_kayobe_playbooks")
def test_overcloud_host_image_build(self, mock_run):
command = commands.OvercloudHostImageBuild(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,
[
utils.get_data_files_path(
"ansible", "overcloud-host-image-build.yml"),
],
extra_vars={},
),
]
self.assertEqual(expected_calls, mock_run.call_args_list)
@mock.patch.object(commands.KayobeAnsibleMixin,
"run_kayobe_playbooks")
def test_overcloud_host_image_build_force_rebuild(self, mock_run):
command = commands.OvercloudHostImageBuild(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,
[
utils.get_data_files_path(
"ansible", "overcloud-host-image-build.yml"),
],
extra_vars={"overcloud_host_image_force_rebuild": True},
),
]
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):

View File

@ -35,4 +35,7 @@ aio_bridge_ports:
# Build seed deployment images (IPA) with extra-hardware element
ipa_build_images: true
ipa_build_dib_elements_extra:
- "extra-hardware"
- "extra-hardware"
# Build overcloud host image
overcloud_dib_build_host_images: true

View File

@ -102,6 +102,12 @@ copy_logs() {
cp /opt/kayobe/images/ipa/ipa.stderr /opt/kayobe/images/ipa/ipa.stdout ${LOG_DIR}/kayobe/
fi
# Overcloud host image build logs
if [[ -f /opt/kayobe/images/deployment_image/deployment_image.stderr ]] || [[ -f /opt/kayobe/images/deployment_image/deployment_image.stdout ]]; then
mkdir -p ${LOG_DIR}/kayobe
cp /opt/kayobe/images/deployment_image/deployment_image.stderr /opt/kayobe/images/deployment_image/deployment_image.stdout ${LOG_DIR}/kayobe/
fi
# Rename files to .txt; this is so that when displayed via
# logs.openstack.org clicking results in the browser shows the
# files, rather than trying to send it to another app or make you

View File

@ -61,6 +61,7 @@ kayobe.cli=
overcloud_facts_gather = kayobe.cli.commands:OvercloudFactsGather
overcloud_hardware_inspect = kayobe.cli.commands:OvercloudHardwareInspect
overcloud_host_configure = kayobe.cli.commands:OvercloudHostConfigure
overcloud_host_image_build = kayobe.cli.commands:OvercloudHostImageBuild
overcloud_host_package_update = kayobe.cli.commands:OvercloudHostPackageUpdate
overcloud_host_command_run = kayobe.cli.commands:OvercloudHostCommandRun
overcloud_host_upgrade = kayobe.cli.commands:OvercloudHostUpgrade
@ -148,6 +149,8 @@ kayobe.cli.overcloud_hardware_inspect =
hooks = kayobe.cli.commands:HookDispatcher
kayobe.cli.overcloud_host_configure =
hooks = kayobe.cli.commands:HookDispatcher
kayobe.cli.overcloud_host_image_build =
hooks = kayobe.cli.commands:HookDispatcher
kayobe.cli.overcloud_host_package_update =
hooks = kayobe.cli.commands:HookDispatcher
kayobe.cli.overcloud_host_command_run =