Fix seed VM interface ordering

Currently the ordering of network interfaces in the seed VM is
non-deterministic. This happens because we apply the 'unique' filter to
the network_interfaces list, which does not guarantee a deterministic
ordering. This list is then transformed and passed to the
stackhpc.libvirt-vm role.

There are two consequences of this:

* it is not possible to determine which interface names should be used
  prior to creating a seed VM
* if a seed VM is recreated, the interface ordering may change

This change fixes the issue by sorting the network_interfaces list
alphabetically before it is transformed and passed to the
stackhpc.libvirt-vm.

A new 'seed_vm_interfaces' variable is also added, which allows for
customisation of the VM's interfaces - potentially allowing for more
complex setups such as trunked VLANs.

Story: 2007259
Task: 38621

There is a second issue, which is that if the seed VM has a
network interface not configured with a gateway, cloud-init will fail to
configure the network interfaces on the host. This has been observed on
CentOS 8, but is probably more tied to the version of cloud-init, and
may affect CentOS 7. The following error is seen in the cloud-init logs:

    KeyError: 'gateway'

This change has been addressed in the jriguera.configdrive role, and
this change updates the version used in requirements.yml.

Story: 2007769
Task: 39993

Change-Id: Ib6ab41a3ba320a1fe15d0d23561fad2fab7861e6
This commit is contained in:
Mark Goddard 2020-06-08 09:53:12 +01:00
parent c2f049c6f0
commit 7bcc5579e2
5 changed files with 40 additions and 35 deletions

View File

@ -48,3 +48,6 @@ seed_vm_data_capacity: 100G
# Format of the seed VM data volume.
seed_vm_data_format: qcow2
# List of network interfaces to attach to the seed VM.
seed_vm_interfaces: "{{ network_interfaces | sort | map('net_libvirt_vm_network') | list }}"

View File

@ -29,29 +29,6 @@
group: "{{ ansible_user_gid }}"
become: True
- name: Create a temporary user data file locally
tempfile:
state: file
register: seed_user_data_file
delegate_to: localhost
# The user data script is used to bring up the network interfaces that will
# be configured by metadata in the configdrive. For some reason resolv.conf
# gets configured with 660 permissions, so fix that here also.
- name: Ensure the user data file exists
copy:
content: |
#!/bin/bash
{% for interface in hostvars[seed_host].network_interfaces | map('net_interface', seed_host) %}
# Bounce {{ interface }}.
ifdown {{ interface }}
ifup {{ interface }}
{% endfor %}
# Fix permissions of resolv.conf.
chmod 644 /etc/resolv.conf
dest: "{{ seed_user_data_file.path }}"
delegate_to: localhost
roles:
- role: jriguera.configdrive
# For now assume the VM OS family is the same as the hypervisor's.
@ -71,7 +48,6 @@
{{ hostvars[seed_host].network_interfaces |
map('net_configdrive_network_device', seed_host) |
list }}
configdrive_config_user_data_path: "{{ seed_user_data_file.path }}"
tasks:
- name: Set a fact containing the configdrive image path
@ -91,14 +67,6 @@
with_items:
- "{{ image_cache_path }}/{{ seed_host | to_uuid }}.gz"
- name: Ensure unnecessary local files are removed
file:
path: "{{ item }}"
state: absent
with_items:
- "{{ seed_user_data_file.path }}"
delegate_to: localhost
- name: Ensure that the seed VM is provisioned
hosts: seed-hypervisor
vars:
@ -128,8 +96,7 @@
memory_mb: "{{ hostvars[seed_host].seed_vm_memory_mb }}"
vcpus: "{{ hostvars[seed_host].seed_vm_vcpus }}"
volumes: "{{ hostvars[seed_host].seed_vm_volumes + [seed_vm_configdrive_volume] }}"
interfaces: >
{{ hostvars[seed_host].network_interfaces | map('net_libvirt_vm_network') | list }}
interfaces: "{{ hostvars[seed_host].seed_vm_interfaces }}"
console_log_enabled: true
become: True

View File

@ -33,6 +33,22 @@
# Format of the seed VM data volume.
#seed_vm_data_format:
# List of network interfaces to attach to the seed VM. Format is as accepted by
# the stackhpc.libvirt-vm role's libvirt_vms.interfaces variable. Default is
# one interface for each network in 'network_interfaces'.
#
# Example with one interface connected to a libvirt network called
# 'libvirt-net', and another interface directly plugged into a host device
# called 'eth1':
#
# seed_vm_interfaces:
# - network: libvirt-net
# - type: direct
# source:
# dev: eth1
#
#seed_vm_interfaces:
###############################################################################
# Dummy variable to allow Ansible to accept this file.
workaround_ansible_issue_8743: yes

View File

@ -0,0 +1,19 @@
---
fixes:
- |
Fixes an issue with seed VMs with multiple network interfaces where
interfaces could come up in a different order if the VM is recreated. The
interfaces are now created in alphabetical order of their Kayobe network
name by default. See `story 2007259
<https://storyboard.openstack.org/#!/story/2007259>`__ for details.
features:
- |
Adds a ``seed_vm_interfaces`` variable which defines the network interfaces
to which the seed VM is attached.
upgrade:
- |
The default order of network interfaces in the seed VM is now sorted
alphabetically based on their Kayobe network name. This may require the
seed's network interface names to be changed in configuration if the seed
VM is recreated. See `story 2007259
<https://storyboard.openstack.org/#!/story/2007259>`__ for details.

View File

@ -3,7 +3,7 @@
version: 1.3.1
- src: jriguera.configdrive
# There are no versioned releases of this role.
version: a5c3c19d0cda7b6960c9200a30b5dbe73d2eef96
version: 56daf0017783bd4fa5722da4ee91b66ddd4e6b6a
- src: MichaelRigart.interfaces
version: v1.5.0
- src: mrlesmithjr.manage-lvm