From bc6f51793802626453e13911336f46107b20c441 Mon Sep 17 00:00:00 2001
From: Mark Goddard <mark@stackhpc.com>
Date: Wed, 29 Nov 2017 21:47:15 +0000
Subject: [PATCH 1/8] Remove SELinux reboot from development docs

---
 doc/source/development.rst | 13 -------------
 1 file changed, 13 deletions(-)

diff --git a/doc/source/development.rst b/doc/source/development.rst
index 78b428a7a..1dd6f5021 100644
--- a/doc/source/development.rst
+++ b/doc/source/development.rst
@@ -62,19 +62,6 @@ Configure the controller host::
 
     kayobe overcloud host configure
 
-During execution of this command, SELinux will be disabled and the VM will be
-rebooted, causing you to be logged out. Wait for the VM to finish rebooting and
-log in, performing the same environment setup steps as before::
-
-    vagrant ssh
-    source kayobe-venv/bin/activate
-    cd /vagrant
-    source kayobe-env
-
-Run the host configuration command again to completion::
-
-    kayobe overcloud host configure
-
 At this point, container images must be acquired. They can either be built
 locally or pulled from an image repository if appropriate images are available.
 

From b5eb53f60e06dde8af4b4c88389340fc5785b8ed Mon Sep 17 00:00:00 2001
From: Mark Goddard <mark@stackhpc.com>
Date: Wed, 10 Jan 2018 19:47:06 +0000
Subject: [PATCH 2/8] Check whether image cache directory is writeable

---
 ansible/kolla-openstack.yml      | 4 +++-
 ansible/overcloud-ipa-images.yml | 4 +++-
 2 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/ansible/kolla-openstack.yml b/ansible/kolla-openstack.yml
index cf8abca30..40752c464 100644
--- a/ansible/kolla-openstack.yml
+++ b/ansible/kolla-openstack.yml
@@ -60,7 +60,9 @@
             owner: "{{ lookup('env', 'USER') }}"
             group: "{{ lookup('env', 'USER') }}"
           become: True
-          when: not image_cache_stat.stat.exists
+          when: >-
+            not image_cache_stat.stat.exists or
+            not image_cache_stat.stat.writeable
 
         - name: Ensure Ironic Python Agent images are copied onto the local machine
           fetch:
diff --git a/ansible/overcloud-ipa-images.yml b/ansible/overcloud-ipa-images.yml
index 7c0ee8f5b..e32829b25 100644
--- a/ansible/overcloud-ipa-images.yml
+++ b/ansible/overcloud-ipa-images.yml
@@ -76,7 +76,9 @@
         owner: "{{ ansible_user }}"
         group: "{{ ansible_user }}"
       become: True
-      when: not image_cache_stat.stat.exists
+      when: >-
+        not image_cache_stat.stat.exists or
+        not image_cache_stat.stat.writeable
 
     - name: Ensure locally built Ironic Python Agent (IPA) images are copied
       copy:

From 53714fc5a9f20ca89bc0162b41cba63aba154868 Mon Sep 17 00:00:00 2001
From: Mark Goddard <mark@stackhpc.com>
Date: Fri, 12 Jan 2018 18:26:26 +0000
Subject: [PATCH 3/8] Add a unit test for kayobe seed service deploy

---
 kayobe/cli/commands.py                 |  3 +-
 kayobe/tests/unit/cli/test_commands.py | 40 ++++++++++++++++++++++++++
 2 files changed, 42 insertions(+), 1 deletion(-)

diff --git a/kayobe/cli/commands.py b/kayobe/cli/commands.py
index a2f340dc2..0f9b7fbe5 100644
--- a/kayobe/cli/commands.py
+++ b/kayobe/cli/commands.py
@@ -461,7 +461,8 @@ class SeedServiceDeploy(KollaAnsibleMixin, KayobeAnsibleMixin, VaultMixin,
         playbooks = _build_playbook_list("kolla-ansible")
         self.run_kayobe_playbooks(parsed_args, playbooks, tags="config")
 
-        self.run_kayobe_playbook(parsed_args, "ansible/kolla-bifrost.yml")
+        playbooks = _build_playbook_list("kolla-bifrost")
+        self.run_kayobe_playbooks(parsed_args, playbooks)
         self.run_kolla_ansible_seed(parsed_args, "deploy-bifrost")
         playbooks = _build_playbook_list(
             "seed-introspection-rules", "dell-switch-bmp")
diff --git a/kayobe/tests/unit/cli/test_commands.py b/kayobe/tests/unit/cli/test_commands.py
index d89d8b9fe..bc528afa6 100644
--- a/kayobe/tests/unit/cli/test_commands.py
+++ b/kayobe/tests/unit/cli/test_commands.py
@@ -387,6 +387,46 @@ class TestCase(unittest.TestCase):
         ]
         self.assertEqual(expected_calls, mock_run.call_args_list)
 
+    @mock.patch.object(commands.KayobeAnsibleMixin,
+                       "run_kayobe_playbooks")
+    @mock.patch.object(commands.KollaAnsibleMixin,
+                       "run_kolla_ansible_seed")
+    def test_service_deploy(self, mock_kolla_run, mock_run):
+        command = commands.SeedServiceDeploy(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/kolla-ansible.yml"],
+                tags="config",
+            ),
+            mock.call(
+                mock.ANY,
+                ["ansible/kolla-bifrost.yml"],
+            ),
+            mock.call(
+                mock.ANY,
+                [
+                    "ansible/seed-introspection-rules.yml",
+                    "ansible/dell-switch-bmp.yml",
+                ],
+            ),
+        ]
+        self.assertEqual(expected_calls, mock_run.call_args_list)
+
+        expected_calls = [
+            mock.call(
+                mock.ANY,
+                "deploy-bifrost",
+            ),
+        ]
+        self.assertEqual(expected_calls, mock_kolla_run.call_args_list)
+
     @mock.patch.object(commands.KayobeAnsibleMixin,
                        "run_kayobe_config_dump")
     @mock.patch.object(commands.KayobeAnsibleMixin,

From 9c1d085d2e52396d05397afb0f658224bda0087c Mon Sep 17 00:00:00 2001
From: Mark Goddard <mark@stackhpc.com>
Date: Fri, 12 Jan 2018 18:29:20 +0000
Subject: [PATCH 4/8] Workaround issue in CentOS cloud images with resolv.conf

The CentOS cloud images from 7.2 (1511) onwards have a bogus name server
entry in /etc/resolv.conf, 10.0.2.3. Cloud-init only appends name server
entries to this file, and will not remove this bogus entry. Typically this
leads to a delay of around 30 seconds when connecting via SSH, due to a
timeout in NSS. The workaround employed here is to remove this bogus entry
from the image using virt-customize, if it exists. See
https://bugs.centos.org/view.php?id=14369.

Fixes: #112
---
 ansible/group_vars/all/overcloud              | 12 +++++++
 ...overcloud-host-image-workaround-resolv.yml | 36 +++++++++++++++++++
 doc/source/release-notes.rst                  |  7 ++++
 etc/kayobe/overcloud.yml                      | 12 +++++++
 kayobe/cli/commands.py                        |  5 ++-
 kayobe/tests/unit/cli/test_commands.py        |  1 +
 6 files changed, 72 insertions(+), 1 deletion(-)
 create mode 100644 ansible/overcloud-host-image-workaround-resolv.yml

diff --git a/ansible/group_vars/all/overcloud b/ansible/group_vars/all/overcloud
index 58923c3dc..5c3cff206 100644
--- a/ansible/group_vars/all/overcloud
+++ b/ansible/group_vars/all/overcloud
@@ -15,3 +15,15 @@ overcloud_groups: >
 # As a special case, the group 'ignore' can be used to specify hosts that
 # should not be added to the inventory.
 overcloud_group_hosts_map: {}
+
+###############################################################################
+# Overcloud host image configuration.
+
+# The CentOS cloud images from 7.2 (1511) onwards have a bogus name server
+# entry in /etc/resolv.conf, 10.0.2.3. Cloud-init only appends name server
+# entries to this file, and will not remove this bogus entry. Typically this
+# leads to a delay of around 30 seconds when connecting via SSH, due to a
+# timeout in NSS. The workaround employed here is to remove this bogus entry
+# 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
diff --git a/ansible/overcloud-host-image-workaround-resolv.yml b/ansible/overcloud-host-image-workaround-resolv.yml
new file mode 100644
index 000000000..665679519
--- /dev/null
+++ b/ansible/overcloud-host-image-workaround-resolv.yml
@@ -0,0 +1,36 @@
+---
+# The CentOS cloud images from 7.2 (1511) onwards have a bogus name server
+# entry in /etc/resolv.conf, 10.0.2.3. Cloud-init only appends name server
+# entries to this file, and will not remove this bogus entry. Typically this
+# leads to a delay of around 30 seconds when connecting via SSH, due to a
+# timeout in NSS. The workaround employed here is to remove this bogus entry
+# from the image using virt-customize, if it exists. See
+# https://bugs.centos.org/view.php?id=14369.
+
+- name: Ensure the overcloud host image has bogus name server entries removed
+  hosts: seed
+  tags:
+    - overcloud-host-image-workaround
+  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: Ensure the overcloud host image has bogus name server entries removed
+          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 --edit \"/etc/resolv.conf:s/^nameserver 10\.0\.2\.3\$//\""'
+      when: overcloud_host_image_workaround_resolv_enabled | bool
diff --git a/doc/source/release-notes.rst b/doc/source/release-notes.rst
index f3f868a24..74228aea6 100644
--- a/doc/source/release-notes.rst
+++ b/doc/source/release-notes.rst
@@ -87,6 +87,13 @@ Upgrade Notes
 
   The previous behaviour of installing python dependencies directly to the host
   can be used by setting ``kolla_ansible_target_venv`` to ``None``.
+* Adds a workaround for an issue with CentOS cloud images 7.2 (1511) onwards,
+  which have a bogus name server entry in /etc/resolv.conf, 10.0.2.3.
+  Cloud-init only appends name server entries to this file, and will not remove
+  this bogus entry. Typically this leads to a delay of around 30 seconds when
+  connecting via SSH, due to a timeout in NSS. The workaround employed here is
+  to remove this bogus entry from the image using virt-customize, if it exists.
+  See https://bugs.centos.org/view.php?id=14369.
 
 Kayobe 3.0.0
 ============
diff --git a/etc/kayobe/overcloud.yml b/etc/kayobe/overcloud.yml
index 0d54d0cb2..4b35737a7 100644
--- a/etc/kayobe/overcloud.yml
+++ b/etc/kayobe/overcloud.yml
@@ -13,6 +13,18 @@
 # should not be added to the inventory.
 #overcloud_group_hosts_map:
 
+###############################################################################
+# Overcloud host image configuration.
+
+# The CentOS cloud images from 7.2 (1511) onwards have a bogus name server
+# entry in /etc/resolv.conf, 10.0.2.3. Cloud-init only appends name server
+# entries to this file, and will not remove this bogus entry. Typically this
+# leads to a delay of around 30 seconds when connecting via SSH, due to a
+# timeout in NSS. The workaround employed here is to remove this bogus entry
+# from the image using virt-customize, if it exists. See
+# https://bugs.centos.org/view.php?id=14369.
+#overcloud_host_image_workaround_resolv_enabled:
+
 ###############################################################################
 # 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 0f9b7fbe5..0640f9966 100644
--- a/kayobe/cli/commands.py
+++ b/kayobe/cli/commands.py
@@ -450,6 +450,7 @@ class SeedServiceDeploy(KollaAnsibleMixin, KayobeAnsibleMixin, VaultMixin,
     * Configures the bifrost service.
     * 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.
     * Configures ironic inspector introspection rules in the bifrost inspector
       service.
     * When enabled, configures a Bare Metal Provisioning (BMP) environment for
@@ -465,7 +466,9 @@ class SeedServiceDeploy(KollaAnsibleMixin, KayobeAnsibleMixin, VaultMixin,
         self.run_kayobe_playbooks(parsed_args, playbooks)
         self.run_kolla_ansible_seed(parsed_args, "deploy-bifrost")
         playbooks = _build_playbook_list(
-            "seed-introspection-rules", "dell-switch-bmp")
+            "overcloud-host-image-workaround-resolv",
+            "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 bc528afa6..ced4c27df 100644
--- a/kayobe/tests/unit/cli/test_commands.py
+++ b/kayobe/tests/unit/cli/test_commands.py
@@ -412,6 +412,7 @@ class TestCase(unittest.TestCase):
             mock.call(
                 mock.ANY,
                 [
+                    "ansible/overcloud-host-image-workaround-resolv.yml",
                     "ansible/seed-introspection-rules.yml",
                     "ansible/dell-switch-bmp.yml",
                 ],

From 40c6a060b013eb7fcc693d86ab9ffbc0ca4d33af Mon Sep 17 00:00:00 2001
From: Mark Goddard <mark@stackhpc.com>
Date: Fri, 12 Jan 2018 18:34:35 +0000
Subject: [PATCH 5/8] Install pip when not using a kayobe target virtualenv

Previously we were relying on kolla-ansible's baremetal role to install pip, but if
virtualenvs are used for the target hosts with kolla-ansible (but not kayobe), then
pip will not be installed to the system site packages. This change installs pip
using easy_install if target virtualenvs are not in use for kayobe.
---
 ansible/kayobe-target-venv.yml | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/ansible/kayobe-target-venv.yml b/ansible/kayobe-target-venv.yml
index 10cf3ffbd..74e290b47 100644
--- a/ansible/kayobe-target-venv.yml
+++ b/ansible/kayobe-target-venv.yml
@@ -52,3 +52,9 @@
           vars:
             activate_virtualenv_path: "{{ virtualenv }}"
       when: virtualenv is defined
+
+    - name: Ensure pip is installed
+      easy_install:
+        name: pip
+      become: True
+      when: virtualenv is not defined

From 666203595a5a4d6868379846aac3a06bb31a634f Mon Sep 17 00:00:00 2001
From: Mark Goddard <mark@stackhpc.com>
Date: Fri, 12 Jan 2018 18:35:59 +0000
Subject: [PATCH 6/8] Configure all DNS servers for bifrost-provisioned
 overcloud hosts

Previously only a single DNS server was configured.
---
 ansible/kolla-bifrost-hostvars.yml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/ansible/kolla-bifrost-hostvars.yml b/ansible/kolla-bifrost-hostvars.yml
index 8306c13aa..202672d95 100644
--- a/ansible/kolla-bifrost-hostvars.yml
+++ b/ansible/kolla-bifrost-hostvars.yml
@@ -39,7 +39,7 @@
       # seed as a gateway to allow external access until other networks have
       # been configured.
       ipv4_gateway: "{{ provision_oc_net_name | net_gateway or provision_oc_net_name | net_ip(seed_host) }}"
-      ipv4_nameserver: "{{ resolv_nameservers[0] }}"
+      ipv4_nameserver: "{{ resolv_nameservers }}"
   tasks:
     - name: Ensure the Bifrost host variable files exist
       copy:

From 856cbed0575a9d75a28cc59f1a1e0ecfb7dd9eb7 Mon Sep 17 00:00:00 2001
From: Mark Goddard <mark@stackhpc.com>
Date: Fri, 12 Jan 2018 18:37:15 +0000
Subject: [PATCH 7/8] Add gitignore for libvirt-host and libvirt-vm roles

---
 .gitignore | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/.gitignore b/.gitignore
index 0074ab611..b3f49b815 100644
--- a/.gitignore
+++ b/.gitignore
@@ -57,6 +57,8 @@ ansible/roles/mrlesmithjr.manage-lvm/
 ansible/roles/MichaelRigart.interfaces/
 ansible/roles/stackhpc.drac/
 ansible/roles/stackhpc.drac-facts/
+ansible/roles/stackhpc.libvirt-host/
+ansible/roles/stackhpc.libvirt-vm/
 ansible/roles/stackhpc.os-flavors/
 ansible/roles/stackhpc.os-images/
 ansible/roles/stackhpc.os-ironic-state/

From dbb92fb42d016b46124a183df1c9dc437430874c Mon Sep 17 00:00:00 2001
From: Mark Goddard <mark@stackhpc.com>
Date: Tue, 16 Jan 2018 17:53:04 +0000
Subject: [PATCH 8/8] Pass MTU configuration to seed VM's configdrive

This ensures that the seed VM honours any MTU configuration following its
initial provisioning.
---
 ansible/filter_plugins/networks.py | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/ansible/filter_plugins/networks.py b/ansible/filter_plugins/networks.py
index b2f2f3019..3c5d03f1a 100644
--- a/ansible/filter_plugins/networks.py
+++ b/ansible/filter_plugins/networks.py
@@ -390,12 +390,14 @@ def net_configdrive_network_device(context, name, inventory_hostname=None):
     netmask = net_mask(context, name, inventory_hostname)
     gateway = net_gateway(context, name, inventory_hostname)
     bootproto = 'static' if ip is not None else 'dhcp'
+    mtu = net_mtu(context, name, inventory_hostname)
     interface = {
         'device': device,
         'address': ip,
         'netmask': netmask,
         'gateway': gateway,
         'bootproto': bootproto,
+        'mtu': mtu,
     }
     interface = {k: v for k, v in interface.items() if v is not None}
     return interface