Improve ironic deployment image build for overcloud

Overcloud deployment images can now be built via:

kayobe overcloud deployment image build

This should be done prior to running kayobe overcloud service deploy.
In order to build IPA images, the ipa_build_images variable should be
set to True. In this case, these images will be used by the overcloud's
ironic inspector service during hardware inspection, and by ironic
during provisioning.
This commit is contained in:
Mark Goddard 2017-08-22 15:06:04 +00:00
parent ebb81e49f1
commit 5d6658b353
13 changed files with 244 additions and 273 deletions

View File

@ -1,14 +0,0 @@
---
- name: Ensure Ironic Python Agent images are built
hosts: controllers[0]
vars:
# This can be set to True to force rebuilding images.
ipa_build_force: False
roles:
- role: ipa-build
ipa_build_venv: "{{ virtualenv_path }}/ipa-build"
ipa_build_image_cache_path: "{{ image_cache_path }}"
ipa_build_source_checkout_path: "{{ source_checkout_path }}"
ipa_build_kernel_name: "{{ ipa_images_kernel_name }}"
ipa_build_ramdisk_name: "{{ ipa_images_ramdisk_name }}"
when: "{{ ipa_build_images | bool }}"

View File

@ -1,49 +0,0 @@
---
- name: Ensure Ironic Python Agent (IPA) images are downloaded and registered
hosts: controllers[0]
pre_tasks:
- name: Validate OpenStack password authentication parameters
fail:
msg: >
Required OpenStack authentication parameter {{ item }} is
{% if item in openstack_auth %}empty{% else %}not present{% endif %}
in openstack_auth. Have you sourced the environment file?
when:
- "{{ openstack_auth_type == 'password' }}"
- "{{ item not in openstack_auth or not openstack_auth[item] }}"
with_items: "{{ openstack_auth_password_required_params }}"
tags:
- config-validation
- block:
- name: Check for the presence of locally built Ironic Python Agent (IPA) images
stat:
path: "{{ image_cache_path }}/{{ item }}"
get_md5: False
get_checksum: False
mime: False
with_items:
- "{{ ipa_images_kernel_name }}"
- "{{ ipa_images_ramdisk_name }}"
register: ipa_image_stat
- name: Validate the presence of locally built Ironic Python Agent (IPA) images
fail:
msg: >
Expected locally built Ironic Python Agent (IPA) image
{{ item.item }} was not present in {{ image_cache_path }}.
with_items: "{{ ipa_image_stat.results }}"
when: "{{ not item.stat.exists }}"
when: "{{ ipa_build_images | bool }}"
tags:
- config-validation
roles:
- role: ipa-images
ipa_images_venv: "{{ virtualenv_path }}/shade"
ipa_images_openstack_auth_type: "{{ openstack_auth_type }}"
ipa_images_openstack_auth: "{{ openstack_auth }}"
ipa_images_cache_path: "{{ image_cache_path }}"
# Don't pass the kernel and ramdisk image URLs if using built images.
ipa_images_kernel_url: "{{ ipa_build_images | ternary(None, ipa_kernel_upstream_url) }}"
ipa_images_ramdisk_url: "{{ ipa_build_images | ternary(None, ipa_ramdisk_upstream_url) }}"

View File

@ -1,9 +1,74 @@
---
- name: Ensure locally built Ironic Python Agent images are copied
hosts: controllers[0]
vars:
# These are the filenames generated by overcloud-ipa-build.yml.
ipa_image_name: "ipa"
ipa_images:
- "{{ ipa_image_name }}.vmlinuz"
- "{{ ipa_image_name }}.initramfs"
tasks:
- block:
- block:
- name: Check for the presence of locally built Ironic Python Agent (IPA) images
stat:
path: "{{ image_cache_path }}/{{ ipa_image_name }}/{{ item }}"
get_md5: False
get_checksum: False
mime: False
with_items: "{{ ipa_images }}"
register: ipa_image_stat
- name: Validate the presence of locally built Ironic Python Agent (IPA) images
fail:
msg: >
Expected locally built Ironic Python Agent (IPA) image
{{ item.item }} was not present in
{{ image_cache_path }}/{{ ipa_image_name }}.
with_items: "{{ ipa_image_stat.results }}"
when: not item.stat.exists
tags:
- config-validation
- name: Check whether the image cache directory exists
local_action:
module: stat
path: "{{ hostvars.localhost.image_cache_path }}"
get_md5: False
get_checksum: False
mime: False
register: image_cache_stat
- name: Ensure the image cache directory exists
local_action:
module: file
path: "{{ hostvars.localhost.image_cache_path }}"
state: directory
owner: "{{ lookup('env', 'USER') }}"
group: "{{ lookup('env', 'USER') }}"
become: True
when: not image_cache_stat.stat.exists
- name: Ensure Ironic Python Agent images are copied onto the local machine
fetch:
src: "{{ image_cache_path }}/{{ ipa_image_name }}/{{ item.src }}"
dest: "{{ hostvars.localhost.image_cache_path }}/{{ ipa_image_name }}/{{ item.dest }}"
flat: True
with_items:
- src: "{{ ipa_images[0] }}"
dest: "{{ ipa_images_kernel_name }}"
- src: "{{ ipa_images[1] }}"
dest: "{{ ipa_images_ramdisk_name }}"
when: ipa_build_images | bool
tags:
- config
- name: Ensure Kolla OpenStack components are configured
hosts: config-mgmt
vars:
switch_type_to_device_type:
dellos9: netmiko_dell_force10
ipa_image_name: "ipa"
pre_tasks:
- block:
- name: Check whether Kolla extra configuration files exist
@ -72,6 +137,18 @@
}]
}}
with_items: "{{ kolla_neutron_ml2_generic_switch_hosts }}"
- name: Set facts containing IPA kernel and ramdisk URLs
set_fact:
kolla_inspector_ipa_kernel_upstream_url: "{{ inspector_ipa_kernel_upstream_url }}"
kolla_inspector_ipa_ramdisk_upstream_url: "{{ inspector_ipa_ramdisk_upstream_url }}"
when: not ipa_build_images | bool
- name: Set facts containing IPA kernel and ramdisk paths
set_fact:
kolla_inspector_ipa_kernel_path: "{{ image_cache_path }}/{{ ipa_image_name }}/{{ ipa_images_kernel_name }}"
kolla_inspector_ipa_ramdisk_path: "{{ image_cache_path }}/{{ ipa_image_name }}/{{ ipa_images_ramdisk_name }}"
when: ipa_build_images | bool
tags:
- config
roles:
@ -84,8 +161,6 @@
kolla_inspector_enable_discovery: "{{ inspector_enable_discovery }}"
kolla_inspector_discovery_enroll_node_driver: "{{ inspector_discovery_enroll_node_driver }}"
kolla_inspector_extra_kernel_options: "{{ inspector_extra_kernel_options }}"
kolla_inspector_ipa_kernel_upstream_url: "{{ inspector_ipa_kernel_upstream_url }}"
kolla_inspector_ipa_ramdisk_upstream_url: "{{ inspector_ipa_ramdisk_upstream_url }}"
# Ironic inspector's dnsmasq configuration.
kolla_inspector_dhcp_pool_start: "{{ inspection_net_name | net_inspection_allocation_pool_start }}"
kolla_inspector_dhcp_pool_end: "{{ inspection_net_name | net_inspection_allocation_pool_end }}"

View File

@ -0,0 +1,26 @@
---
# Build and install an Ironic Python Agent (IPA) image for the overcloud's
# ironic and ironic-inspector services.
#
# The images will be stored in {{ image_cache_path }}/{{ ipa_image_name }}.
- name: Ensure Ironic Python Agent images are built and installed
hosts: controllers[0]
vars:
ipa_image_name: "ipa"
tasks:
- name: Ensure Ironic Python Agent images are built
include_role:
name: stackhpc.os-images
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

@ -0,0 +1,87 @@
---
- name: Ensure Ironic Python Agent (IPA) images are downloaded and registered
hosts: controllers[0]
vars:
# These are the filenames generated by overcloud-ipa-build.yml.
ipa_image_name: "ipa"
ipa_images:
- "{{ ipa_image_name }}.vmlinuz"
- "{{ ipa_image_name }}.initramfs"
pre_tasks:
- name: Validate OpenStack password authentication parameters
fail:
msg: >
Required OpenStack authentication parameter {{ item }} is
{% if item in openstack_auth %}empty{% else %}not present{% endif %}
in openstack_auth. Have you sourced the environment file?
when:
- openstack_auth_type == 'password'
- item not in openstack_auth or not openstack_auth[item]
with_items: "{{ openstack_auth_password_required_params }}"
tags:
- config-validation
- block:
- name: Check for the presence of locally built Ironic Python Agent (IPA) images
stat:
path: "{{ image_cache_path }}/{{ ipa_image_name }}/{{ item }}"
get_md5: False
get_checksum: False
mime: False
with_items: "{{ ipa_images }}"
register: ipa_image_stat
- name: Validate the presence of locally built Ironic Python Agent (IPA) images
fail:
msg: >
Expected locally built Ironic Python Agent (IPA) image
{{ item.item }} was not present in {{ image_cache_path }}.
with_items: "{{ ipa_image_stat.results }}"
when: not item.stat.exists
when: ipa_build_images | bool
tags:
- config-validation
- name: Set fact containing the Ironic Python Agent (IPA) image URLs
set_fact:
# Don't pass the kernel and ramdisk image URLs if using built images.
ipa_images_kernel_url: "{{ ipa_kernel_upstream_url }}"
ipa_images_ramdisk_url: "{{ ipa_ramdisk_upstream_url }}"
when: not ipa_build_images | bool
- name: Check whether the image cache directory exists
stat:
path: "{{ image_cache_path }}"
get_md5: False
get_checksum: False
mime: False
register: image_cache_stat
- name: Ensure the image cache directory exists
stat:
path: "{{ image_cache_path }}"
state: directory
owner: "{{ ansible_user }}"
group: "{{ ansible_user }}"
become: True
when: not image_cache_stat.stat.exists
- name: Ensure locally built Ironic Python Agent (IPA) images are copied
copy:
src: "{{ image_cache_path }}/{{ ipa_image_name }}/{{ item.src }}"
dest: "{{ image_cache_path }}/{{ ipa_image_name }}/{{ item.dest }}"
remote_src: True
with_items:
- src: "{{ ipa_images[0] }}"
dest: "{{ ipa_images_kernel_name }}"
- src: "{{ ipa_images[1] }}"
dest: "{{ ipa_images_ramdisk_name }}"
when:
- ipa_build_images | bool
- item.src != item.dest
roles:
- role: ipa-images
ipa_images_venv: "{{ virtualenv_path }}/shade"
ipa_images_openstack_auth_type: "{{ openstack_auth_type }}"
ipa_images_openstack_auth: "{{ openstack_auth }}"
ipa_images_cache_path: "{{ image_cache_path }}/{{ ipa_image_name }}"

View File

@ -1,64 +0,0 @@
Ironic Python Agent (IPA) Image Build
=====================================
This role can be used to build kernel and ramdisk images for OpenStack Ironic
Python Agent (IPA).
Requirements
------------
None
Role Variables
--------------
`ipa_build_venv` is a path to a directory in which to create a virtualenv.
`ipa_build_install_epel`: Whether to install EPEL repository package.
`ipa_build_install_package_dependencies`: Whether to install package
dependencies.
`ipa_build_cache_path`: Path to directory in which to store built images.
`ipa_build_source_url`: URL of IPA source repository.
`ipa_build_source_version`: Version of IPA source repository.
`ipa_build_upper_constraints_file_url`: URL of IPA upper constraints file.
`ipa_build_custom_upper_constraints`: Custom python package version constraints
for IPA. Dict mapping package name to upper version constraint.
`ipa_build_kernel_name`: Name of kernel image to save.
`ipa_build_ramdisk_name`: Name of ramdisk image to save.
`ipa_build_force`: Whether to force rebuilding images when they already exist.
Dependencies
------------
None
Example Playbook
----------------
The following playbook installs openstackclient in a virtualenv.
---
- name: Ensure Ironic Python Agent (IPA) images are built
hosts: localhost
roles:
- role: ipa-build
ipa_build_venv: "~/ipa-build-venv"
ipa_build_cache_path: "~/ipa-build-cache"
ipa_build_source_url: "https://github.com/openstack/ironic-python-agent"
ipa_build_source_version: "master"
ipa_build_kernel_name: "ipa.vmlinuz"
ipa_build_ramdisk_name: "ipa.initramfs"
Author Information
------------------
- Mark Goddard (<mark@stackhpc.com>)

View File

@ -1,37 +0,0 @@
---
# Path to a directory in which to create a virtualenv.
ipa_build_venv:
# Path to a directory in which to clone the IPA source repository.
ipa_build_source_checkout_path:
# Whether to install EPEL repository package.
ipa_build_install_epel: True
# Whether to install package dependencies.
ipa_build_install_package_dependencies: True
# Path to directory in which to store built images.
ipa_build_cache_path:
# URL of IPA source repository.
ipa_build_source_url:
# Version of IPA source repository.
ipa_build_source_version:
# URL of IPA upper constraints file.
ipa_build_upper_constraints_file_url:
# Custom python package version constraints for IPA. Dict mapping package name
# to upper version constraint.
ipa_build_custom_upper_constraints:
# Name of kernel image to save.
ipa_build_kernel_name:
# Name of ramdisk image to save.
ipa_build_ramdisk_name:
# Whether to force rebuilding images when they already exist.
ipa_build_force: False

View File

@ -1,104 +0,0 @@
---
- name: Ensure EPEL repo is installed
yum:
name: epel-release
state: installed
become: True
when: "{{ ipa_build_install_epel | bool }}"
- name: Ensure required packages are installed
yum:
name: "{{ item }}"
state: installed
become: True
with_items:
- gcc
- libffi-devel
- openssl-devel
- python-devel
- python-pip
- python-virtualenv
when: "{{ ipa_build_install_package_dependencies | bool }}"
- name: Ensure source code checkout and image cache directories exist
file:
path: "{{ ipa_build_source_checkout_path }}"
state: directory
owner: "{{ ansible_user }}"
group: "{{ ansible_user }}"
recurse: True
with_items:
- "{{ ipa_build_source_checkout_path }}"
- "{{ ipa_build_image_cache_path }}"
become: True
- name: Ensure Ironic Python Agent (IPA) source code checkout exists
git:
repo: "{{ ipa_build_source_url }}"
dest: "{{ ipa_build_source_checkout_path }}/ironic-python-agent"
version: "{{ ipa_build_source_version }}"
- name: Ensure the latest version of pip is installed
pip:
name: "{{ item.name }}"
state: latest
virtualenv: "{{ ipa_build_venv or omit }}"
with_items:
- { name: pip }
- name: Ensure required Python packages are installed
pip:
requirements: "{{ ipa_build_source_checkout_path }}/ironic-python-agent/requirements.txt"
state: present
virtualenv: "{{ ipa_build_venv or omit }}"
- name: Ensure upper constraints file is downloaded
uri:
url: "{{ ipa_build_upper_constraints_file_url }}"
return_content: yes
when: "{{ ipa_build_upper_constraints_file_url != None }}"
register: upper_constraints
- name: Ensure custom upper constraints are set
copy:
content: |
{% for line in upper_constraints.content.splitlines() %}
{% set package, _, version = line.partition('===') %}
{{ package }}==={{ ipa_build_custom_upper_constraints.get(package, version) }}
{% endfor %}
dest: "{{ ipa_build_source_checkout_path }}/ironic-python-agent/upper-constraints.txt"
when: "{{ ipa_build_upper_constraints_file_url != None }}"
- name: Ensure existing Ironic Python Agent (IPA) images are removed when forcing rebuild
file:
path: "{{ ipa_build_source_checkout_path }}/ironic-python-agent/imagebuild/coreos/UPLOAD/{{ item }}"
state: absent
with_items:
- "coreos_production_pxe.vmlinuz"
- "coreos_production_pxe_image-oem.cpio.gz"
when: "{{ ipa_build_force | bool }}"
- name: Ensure Ironic Python Agent (IPA) images are built
shell: >
{% if ipa_build_venv | bool %}
source {{ ipa_build_venv }}/bin/activate &&
{% endif %}
{% if ipa_build_upper_constraints_file_url is defined %}
export UPPER_CONSTRAINTS_FILE="{{ ipa_build_source_checkout_path }}/ironic-python-agent/upper-constraints.txt" &&
{% endif %}
make clean &&
make
args:
chdir: "{{ ipa_build_source_checkout_path }}/ironic-python-agent/imagebuild/coreos"
creates: "{{ ipa_build_source_checkout_path }}/ironic-python-agent/imagebuild/coreos/UPLOAD/coreos_production_pxe_image-oem.cpio.gz"
- name: Ensure built Ironic Python Agent (IPA) images are cached
copy:
src: "{{ ipa_build_source_checkout_path }}/ironic-python-agent/imagebuild/coreos/UPLOAD/{{ item.src }}"
dest: "{{ ipa_build_image_cache_path }}/{{ item.dest }}"
remote_src: True
with_items:
- src: "coreos_production_pxe.vmlinuz"
dest: "{{ ipa_build_kernel_name }}"
- src: "coreos_production_pxe_image-oem.cpio.gz"
dest: "{{ ipa_build_ramdisk_name }}"

View File

@ -148,11 +148,21 @@ kolla_inspector_discovery_enroll_node_driver:
kolla_inspector_extra_kernel_options:
# URL of Ironic Python Agent (IPA) kernel image for Ironic Inspector.
# Mutually exclusive with kolla_inspector_ipa_kernel_path.
kolla_inspector_ipa_kernel_upstream_url:
# URL of Ironic Python Agent (IPA) ramdisk image for Ironic Inspector.
# Mutually exclusive with kolla_inspector_ipa_ramdisk_path.
kolla_inspector_ipa_ramdisk_upstream_url:
# Path to Ironic Python Agent (IPA) kernel image for Ironic Inspector.
# Mutually exclusive with kolla_inspector_ipa_kernel_upstream_url.
kolla_inspector_ipa_kernel_path:
# Path to Ironic Python Agent (IPA) ramdisk image for Ironic Inspector.
# Mutually exclusive with kolla_inspector_ipa_ramdisk_upstream_url.
kolla_inspector_ipa_ramdisk_path:
# Free form extra configuration to append to ironic-inspector.conf.
kolla_extra_inspector:

View File

@ -39,7 +39,7 @@
- "{{ kolla_extra_fluentd_output_path }}/*.conf"
when: "{{ kolla_extra_fluentd_output_path != None }}"
- name: Ensure the ironic inspector kernel and ramdisk exist
- name: Ensure the ironic inspector kernel and ramdisk are downloaded
get_url:
url: "{{ item.url }}"
dest: "{{ kolla_node_custom_config_path }}/ironic/{{ item.dest }}"
@ -47,4 +47,18 @@
with_items:
- { url: "{{ kolla_inspector_ipa_kernel_upstream_url }}", dest: "ironic-agent.kernel" }
- { url: "{{ kolla_inspector_ipa_ramdisk_upstream_url }}", dest: "ironic-agent.initramfs" }
when: "{{ kolla_enable_ironic | bool }}"
when:
- kolla_enable_ironic | bool
- item.url != None
- name: Ensure the ironic inspector kernel and ramdisk are copied
copy:
src: "{{ item.path }}"
dest: "{{ kolla_node_custom_config_path }}/ironic/{{ item.dest }}"
mode: 0640
with_items:
- { path: "{{ kolla_inspector_ipa_kernel_path }}", dest: "ironic-agent.kernel" }
- { path: "{{ kolla_inspector_ipa_ramdisk_path }}", dest: "ironic-agent.initramfs" }
when:
- kolla_enable_ironic | bool
- item.path != None

View File

@ -291,6 +291,23 @@ pull images from the configured image registry::
(kayobe-venv) $ kayobe overcloud container image pull
Building Deployment Images
--------------------------
.. note::
It is possible to use prebuilt deployment images. In this case, 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
apply local image customisation or to use a downstream version of Ironic Python
Agent (IPA). In order to build IPA images, the ``ipa_build_images`` variable
should be set to ``True``. To build images locally::
(kayobe-venv) $ kayobe overcloud deployment image build
Deploying Containerised Services
--------------------------------

View File

@ -622,13 +622,22 @@ class OvercloudContainerImageBuild(KayobeAnsibleMixin, VaultMixin, Command):
extra_vars=extra_vars)
class OvercloudDeploymentImageBuild(KayobeAnsibleMixin, VaultMixin, Command):
"""Build the overcloud deployment kernel and ramdisk images."""
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)
class OvercloudPostConfigure(KayobeAnsibleMixin, VaultMixin, Command):
"""Perform post-deployment configuration."""
def take_action(self, parsed_args):
self.app.LOG.debug("Performing post-deployment configuration")
playbooks = _build_playbook_list(
"ipa-build", "ipa-images", "overcloud-introspection-rules",
"overcloud-ipa-images", "overcloud-introspection-rules",
"overcloud-introspection-rules-dell-lldp-workaround",
"provision-net")
self.run_kayobe_playbooks(parsed_args, playbooks)

View File

@ -58,6 +58,7 @@ setup(
'overcloud_bios_raid_configure = kayobe.cli.commands:OvercloudBIOSRAIDConfigure',
'overcloud_container_image_build = kayobe.cli.commands:OvercloudContainerImageBuild',
'overcloud_container_image_pull = kayobe.cli.commands:OvercloudContainerImagePull',
'overcloud_deployment_image_build = kayobe.cli.commands:OvercloudDeploymentImageBuild',
'overcloud_deprovision = kayobe.cli.commands:OvercloudDeprovision',
'overcloud_hardware_inspect = kayobe.cli.commands:OvercloudHardwareInspect',
'overcloud_host_configure = kayobe.cli.commands:OvercloudHostConfigure',