From d1ba6d5027a98afaebc4713881b914a98f8bad94 Mon Sep 17 00:00:00 2001
From: Will Szumski <will@stackhpc.com>
Date: Mon, 18 Jun 2018 11:34:17 +0100
Subject: [PATCH] add cloud-init workaround

The version of cloud-init included with CentOS7.5 (0.7.9-24)
fails to assign an IP address on VLAN subinterfaces. This
workaround upgrades cloud-init to 18.2 using a private
repository.

Story: 2002610
Task: 22229
Change-Id: Idc570b9ca7558dfd42246c74b1ec0331011d692f
---
 ansible/group_vars/all/overcloud              |  8 +++
 ...cloud-host-image-workaround-cloud-init.yml | 66 +++++++++++++++++++
 doc/source/deployment.rst                     | 34 ++++++++++
 etc/kayobe/overcloud.yml                      |  8 +++
 kayobe/cli/commands.py                        |  2 +
 kayobe/tests/unit/cli/test_commands.py        |  1 +
 ...ound-cloud-init-vlan-0efa97b866d46783.yaml |  7 ++
 7 files changed, 126 insertions(+)
 create mode 100644 ansible/overcloud-host-image-workaround-cloud-init.yml
 create mode 100644 releasenotes/notes/workaround-cloud-init-vlan-0efa97b866d46783.yaml

diff --git a/ansible/group_vars/all/overcloud b/ansible/group_vars/all/overcloud
index b37c6ae66..90ed6a2b8 100644
--- a/ansible/group_vars/all/overcloud
+++ b/ansible/group_vars/all/overcloud
@@ -30,3 +30,11 @@ disable_cloud_init: False
 # from the image using virt-customize, if it exists. See
 # https://bugs.centos.org/view.php?id=14369.
 overcloud_host_image_workaround_resolv_enabled: True
+
+# Workaround a CentOS 7.5 bug: cloud-init 0.7.9-24 does not correctly set
+# an IP address for VLAN subinterfaces configured with the Openstack metadata
+# format/Config drive. # See, https://bugs.centos.org/view.php?id=14964.
+overcloud_host_image_workaround_cloud_init_enabled: False
+
+# cloud-init repository for overcloud_host_image_workaround_cloud_init_enabled
+overcloud_host_image_workaround_cloud_init_repo: https://stackhpc.github.io/cloud-init-repo/
diff --git a/ansible/overcloud-host-image-workaround-cloud-init.yml b/ansible/overcloud-host-image-workaround-cloud-init.yml
new file mode 100644
index 000000000..94fd775da
--- /dev/null
+++ b/ansible/overcloud-host-image-workaround-cloud-init.yml
@@ -0,0 +1,66 @@
+---
+# Workaround a CentOS 7.5 bug: cloud-init 0.7.9-24 does not correctly set
+# an IP address for VLAN subinterfaces configured with the Openstack metadata
+# format/Config drive. # See, https://bugs.centos.org/view.php?id=14964.
+- name: Ensure the overcloud host image uses an updated version of cloud-init
+  hosts: seed
+  tags:
+    - overcloud-host-image-workaround
+  vars:
+    custom_repo_tmp_path: /tmp/cloud-init-upstream.repo
+  tasks:
+    - block:
+        - name: Ensure libguestfs-tools is installed
+          command: >
+            docker exec bifrost_deploy
+            bash -c '
+            ansible localhost
+            --connection local
+            --become
+            -m yum
+            -a "name=libguestfs-tools state=installed"'
+        - name: Template cloud-init-repo
+          copy:
+            content: |
+              [cloudinit]
+              name=StackHPC cloud-init
+              baseurl={{ overcloud_host_image_workaround_cloud_init_repo }}
+              gpgcheck=0
+              enabled=1
+            dest: "{{ custom_repo_tmp_path }}"
+        - name: Copy cloud init repo into docker container
+          command: docker cp {{ custom_repo_tmp_path }} bifrost_deploy:{{ custom_repo_tmp_path }}
+        - name: Clean up template on seed
+          file:
+            path: "{{ custom_repo_tmp_path }}"
+            state: absent
+        - name: Install custom repo
+          command: >
+            docker exec bifrost_deploy
+            bash -c '
+            export LIBGUESTFS_BACKEND=direct &&
+            ansible localhost
+            --connection local
+            --become
+            -m command
+            -a "virt-customize -a /httpboot/deployment_image.qcow2 --upload {{ custom_repo_tmp_path }}:/etc/yum.repos.d/"'
+        - name: Clean up tmp file in docker container
+          command: >
+            docker exec bifrost_deploy
+            bash -c '
+            ansible localhost
+            --connection local
+            --become
+            -m file
+            -a "path=\"{{ custom_repo_tmp_path }}\" state=absent"'
+        - name: upgrade cloud init
+          command: >
+            docker exec bifrost_deploy
+            bash -c '
+            export LIBGUESTFS_BACKEND=direct &&
+            ansible localhost
+            --connection local
+            --become
+            -m command
+            -a "virt-customize -a /httpboot/deployment_image.qcow2 --install cloud-init"'
+      when: overcloud_host_image_workaround_cloud_init_enabled | bool
diff --git a/doc/source/deployment.rst b/doc/source/deployment.rst
index 29f03b5ad..3e1df7909 100644
--- a/doc/source/deployment.rst
+++ b/doc/source/deployment.rst
@@ -133,6 +133,40 @@ image name regular expressions::
 In order to push images to a registry after they are built, add the ``--push``
 argument.
 
+Workaround VLAN cloud-init issue
+--------------------------------
+
+If you wish to configure the overcloud hosts to use a tagged VLAN for the admin
+network interface, you must set
+``overcloud_host_image_workaround_cloud_init_enabled``
+to True in ``${KAYOBE_CONFIG_PATH}/etc/kayobe/overcloud.yml``::
+
+    overcloud_host_image_workaround_cloud_init_enabled: True
+
+prior to deploying the containerised services with::
+
+    (kayobe) $ kayobe seed service deploy
+
+Kayobe will then patch the overcloud host image to include a more recent
+version of cloud-init. This is to workaround a bug in the version of
+cloud-init currently shipped with CentOS 7.5 (0.7.9-24 at the time of writing),
+which doesn't set the IP address of VLAN subinterfaces. See:
+https://bugs.centos.org/view.php?id=14964.
+
+The default repository used to obtain the package is currently hosted on github
+in the `cloud-init-repo <https://github.com/stackhpc/cloud-init-repo>`_
+repository. You can override this by setting ``overcloud_host_image_workaround_cloud_init_repo``
+in ``${KAYOBE_CONFIG_PATH}/etc/kayobe/overcloud.yml``::
+
+   overcloud_host_image_workaround_cloud_init_repo: https://stackhpc.github.io/cloud-init-repo/
+
+The source code used to build the updated package can be obtained from
+the `cloud-init-repo-source <https://github.com/stackhpc/cloud-init-repo-source>`_
+repository.
+
+As this is not an offical package, there may be latent bugs when using
+functionality the kayobe developers have not used themselves.
+
 Deploying Containerised Services
 --------------------------------
 
diff --git a/etc/kayobe/overcloud.yml b/etc/kayobe/overcloud.yml
index 5c4828ad4..96001a62f 100644
--- a/etc/kayobe/overcloud.yml
+++ b/etc/kayobe/overcloud.yml
@@ -28,6 +28,14 @@
 # https://bugs.centos.org/view.php?id=14369.
 #overcloud_host_image_workaround_resolv_enabled:
 
+# Workaround a CentOS 7.5 bug: cloud-init 0.7.9-24 does not correctly set
+# an IP address for VLAN subinterfaces configured with the Openstack metadata
+# format/Config drive. # See, https://bugs.centos.org/view.php?id=14964.
+#overcloud_host_image_workaround_cloud_init_enabled:
+
+# cloud-init repository for overcloud_host_image_workaround_cloud_init_enabled
+#overcloud_host_image_workaround_cloud_init_repo: https://stackhpc.github.io/cloud-init-repo/
+
 ###############################################################################
 # Dummy variable to allow Ansible to accept this file.
 workaround_ansible_issue_8743: yes
diff --git a/kayobe/cli/commands.py b/kayobe/cli/commands.py
index d2c766a7b..506be7eae 100644
--- a/kayobe/cli/commands.py
+++ b/kayobe/cli/commands.py
@@ -449,6 +449,7 @@ class SeedServiceDeploy(KollaAnsibleMixin, KayobeAnsibleMixin, VaultMixin,
     * Deploys the bifrost container using kolla-ansible.
     * Builds disk images for the overcloud hosts using Diskimage Builder (DIB).
     * Performs a workaround in the overcloud host image to fix resolv.conf.
+    * Performs a workaround in the overcloud host image to update cloud-init
     * Configures ironic inspector introspection rules in the bifrost inspector
       service.
     * When enabled, configures a Bare Metal Provisioning (BMP) environment for
@@ -465,6 +466,7 @@ class SeedServiceDeploy(KollaAnsibleMixin, KayobeAnsibleMixin, VaultMixin,
         self.run_kolla_ansible_seed(parsed_args, "deploy-bifrost")
         playbooks = _build_playbook_list(
             "overcloud-host-image-workaround-resolv",
+            "overcloud-host-image-workaround-cloud-init",
             "seed-introspection-rules",
             "dell-switch-bmp")
         self.run_kayobe_playbooks(parsed_args, playbooks)
diff --git a/kayobe/tests/unit/cli/test_commands.py b/kayobe/tests/unit/cli/test_commands.py
index 1dde429ea..6debdcb53 100644
--- a/kayobe/tests/unit/cli/test_commands.py
+++ b/kayobe/tests/unit/cli/test_commands.py
@@ -411,6 +411,7 @@ class TestCase(unittest.TestCase):
                 mock.ANY,
                 [
                     "ansible/overcloud-host-image-workaround-resolv.yml",
+                    "ansible/overcloud-host-image-workaround-cloud-init.yml",
                     "ansible/seed-introspection-rules.yml",
                     "ansible/dell-switch-bmp.yml",
                 ],
diff --git a/releasenotes/notes/workaround-cloud-init-vlan-0efa97b866d46783.yaml b/releasenotes/notes/workaround-cloud-init-vlan-0efa97b866d46783.yaml
new file mode 100644
index 000000000..763fd283a
--- /dev/null
+++ b/releasenotes/notes/workaround-cloud-init-vlan-0efa97b866d46783.yaml
@@ -0,0 +1,7 @@
+---
+features:
+  - |
+    Adds an option to upgrade cloud-init in the overcloud host images,
+    ``overcloud_host_image_workaround_cloud_init_enabled``. Please see:
+    `Story 2002610 <https://storyboard.openstack.org/#!/story/2002610>`_
+    for full details.