From 3b24e566f6f7f44eb2d10e8bfb841ede17c983f3 Mon Sep 17 00:00:00 2001
From: Mark Goddard <mark@stackhpc.com>
Date: Fri, 6 Dec 2019 16:27:26 +0000
Subject: [PATCH] CentOS 8: Deploy CentOS 8 containers

* HAProxy is now 1.8 in CentOS 8
* Support python3 in baremetal role
* Remove support for environments without python2 installed (this could
  not have worked since we gather facts before this point)

Workarounds:

* Using CentOS 7 yum repo for Docker, with module_hotfixes

Change-Id: I30bd3d58f6224ad4c9575ba66c74deabe6895cc4
Partially-Implements: blueprint centos-rhel-8
---
 ansible/group_vars/all.yml                    |  4 ++--
 ansible/roles/baremetal/defaults/main.yml     | 23 +++++++++++++++----
 ansible/roles/baremetal/tasks/install.yml     | 20 ++++++++--------
 ansible/roles/baremetal/tasks/pre-install.yml | 22 +++++++++++-------
 .../roles/haproxy/templates/haproxy_run.sh.j2 |  3 ++-
 5 files changed, 45 insertions(+), 27 deletions(-)

diff --git a/ansible/group_vars/all.yml b/ansible/group_vars/all.yml
index 4e53d496a6..f2c33738f2 100644
--- a/ansible/group_vars/all.yml
+++ b/ansible/group_vars/all.yml
@@ -1105,9 +1105,9 @@ influxdb_address: "{{ kolla_internal_fqdn }}"
 # Internal Image options
 #########################
 distro_python_version_map: {
-  "centos": "2.7",
+  "centos": "{{ '3.6' if ansible_distribution_major_version is version(8, '>=') else '2.7' }}",
   "debian": "3.7",
-  "rhel": "2.7",
+  "rhel": "{{ '3.6' if ansible_distribution_major_version is version(8, '>=') else '2.7' }}",
   "ubuntu": "3.6"
 }
 
diff --git a/ansible/roles/baremetal/defaults/main.yml b/ansible/roles/baremetal/defaults/main.yml
index 2466ef3d40..50d31c4edd 100644
--- a/ansible/roles/baremetal/defaults/main.yml
+++ b/ansible/roles/baremetal/defaults/main.yml
@@ -11,7 +11,9 @@ docker_apt_package: "docker-ce"
 
 # Docker Yum repository configuration.
 docker_yum_url: "https://download.docker.com/linux/{{ ansible_distribution | lower }}"
-docker_yum_baseurl: "{{ docker_yum_url }}/{{ ansible_distribution_major_version | lower }}/$basearch/stable"
+# FIXME(mgoddard): Use {{ ansible_distribution_major_version | lower }} rather
+# than 7.
+docker_yum_baseurl: "{{ docker_yum_url }}/7/$basearch/stable"
 docker_yum_gpgkey: "{{ docker_yum_url }}/gpg"
 docker_yum_gpgcheck: true
 docker_yum_package: "docker-ce"
@@ -36,12 +38,20 @@ docker_custom_config: {}
 
 # Ubuntu 18+ does not have easy_install available due to
 # https://bugs.launchpad.net/ubuntu/+source/python-setuptools/+bug/1774419.
+# CentOS/RHEL 8 does not have easy_install.
 easy_install_available: >-
   {{ not (ansible_distribution == 'Ubuntu' and
           ansible_distribution_major_version is version(18, 'ge'))
      and
      not (ansible_distribution == 'Debian' and
-          ansible_distribution_major_version is version(10, 'ge')) }}
+          ansible_distribution_major_version is version(10, 'ge'))
+     and
+     not (ansible_os_family == 'RedHat' and
+          ansible_distribution_major_version is version(8, 'ge')) }}
+
+# Version of python used to execute Ansible modules.
+host_python_version: "{{ ansible_python.version.major }}.{{ ansible_python.version.minor }}"
+host_python_major_version: "{{ ansible_python.version.major }}"
 
 # Ubuntu 18+ bundles nfs-ganesha 2.6.0 with Ceph Mimic packages,
 # which does udp rpcbind test even with NFSv3 disabled - therefore
@@ -49,15 +59,18 @@ easy_install_available: >-
 debian_pkg_install:
  - "{{ docker_apt_package }}"
  - git
- - "{% if not easy_install_available %}python-pip{% endif %}"
- - python-setuptools
+ - "python{% if host_python_major_version == '3' %}3{% endif %}-setuptools"
+ - "{% if not easy_install_available %}python{% if host_python_major_version == '3' %}3{% endif %}-pip{% endif %}"
+ - "{% if virtualenv is not none %}python{% if host_python_major_version == '3' %}3{% endif %}-virtualenv{% endif %}"
  - "{% if enable_host_ntp | bool %}ntp{% endif %}"
  - "{% if enable_ceph_nfs|bool %}rpcbind{% endif %}"
 
 redhat_pkg_install:
  - "{{ docker_yum_package }}"
  - git
- - python-setuptools
+ - "{% if host_python_major_version == '2' %}python-setuptools{% endif %}"
+ - "{% if not easy_install_available %}python{{ host_python_major_version }}-pip{% endif %}"
+ - "{% if virtualenv is not none %}python{{ host_python_major_version }}-virtualenv{% endif %}"
  - "{% if enable_host_ntp | bool %}ntp{% endif %}"
  - sudo
 
diff --git a/ansible/roles/baremetal/tasks/install.yml b/ansible/roles/baremetal/tasks/install.yml
index c8d1f33dec..4dbb03c454 100644
--- a/ansible/roles/baremetal/tasks/install.yml
+++ b/ansible/roles/baremetal/tasks/install.yml
@@ -55,21 +55,23 @@
   register: apt_install_result
 
 - name: Install deltarpm packages
+  vars:
+    package_name: "{{ 'deltarpm' if ansible_distribution_major_version == '7' else 'drpm' }}"
   package:
-    name: deltarpm
+    name: "{{ package_name }}"
     state: present
     update_cache: yes
   become: True
   when: ansible_os_family == 'RedHat'
 
-- name: Install yum packages
+- name: Install RPM packages
   package:
     name: "{{ (redhat_pkg_install | join(' ')).split() }}"
     state: present
     update_cache: yes
   become: True
   when: ansible_os_family == 'RedHat'
-  register: yum_install_result
+  register: rpm_install_result
 
 # If any packages were updated, and any containers were running, wait for the
 # daemon to come up and start all previously running containers.
@@ -101,14 +103,7 @@
     - running_containers.rc == 0
     - running_containers.stdout != ''
   vars:
-    install_result: "{{ yum_install_result if ansible_os_family == 'RedHat' else apt_install_result }}"
-
-- name: Install virtualenv packages
-  package:
-    name: python-virtualenv
-    state: present
-  become: True
-  when: virtualenv is not none
+    install_result: "{{ rpm_install_result if ansible_os_family == 'RedHat' else apt_install_result }}"
 
 - name: Install pip
   easy_install:
@@ -124,6 +119,7 @@
     name: pip>19.3
     virtualenv: "{{ virtualenv }}"
     virtualenv_site_packages: "{{ virtualenv_site_packages }}"
+    virtualenv_python: "python{{ host_python_version }}"
   become: True
   when: virtualenv is not none
 
@@ -131,8 +127,10 @@
   pip:
     # NOTE(hrw) docker 2.4.2 is in kolla-ansible requirements
     name: docker>=2.4.2
+    executable: "{{ virtualenv is none | ternary('pip' ~ host_python_major_version, omit) }}"
     virtualenv: "{{ virtualenv is none | ternary(omit, virtualenv) }}"
     virtualenv_site_packages: "{{ virtualenv is none | ternary(omit, virtualenv_site_packages) }}"
+    virtualenv_python: "{{ virtualenv is none | ternary(omit, 'python' ~ host_python_version) }}"
   become: True
 
 - name: Remove packages
diff --git a/ansible/roles/baremetal/tasks/pre-install.yml b/ansible/roles/baremetal/tasks/pre-install.yml
index e53d5452e6..f13d7c8f7a 100644
--- a/ansible/roles/baremetal/tasks/pre-install.yml
+++ b/ansible/roles/baremetal/tasks/pre-install.yml
@@ -1,12 +1,4 @@
 ---
-# NOTE: raw install is required to support cloud images which do not have python installed
-- name: "Install python2"
-  become: True
-  raw: "yum install -y python || (apt-get update && apt-get install -y python2.7)"
-
-- name: Gather facts
-  setup:
-
 - name: Ensure localhost in /etc/hosts
   lineinfile:
     dest: /etc/hosts
@@ -134,6 +126,20 @@
             gpgkey: "{{ docker_yum_gpgkey }}"
           become: True
 
+        # NOTE(yoctozepto): above cannot set this but we require it
+        # to install containerd.io due to runc being a modular package
+        # in CentOS 8
+        # see: https://bugzilla.redhat.com/show_bug.cgi?id=1734081
+        - name: Ensure module_hotfixes enabled for docker
+          lineinfile:
+            dest: /etc/yum.repos.d/docker.repo
+            regexp: "^module_hotfixes"
+            line: "module_hotfixes = True"
+            state: present
+          become: True
+          when:
+            - ansible_distribution_major_version == '8'
+
         - name: Install docker rpm gpg key
           rpm_key:
             state: present
diff --git a/ansible/roles/haproxy/templates/haproxy_run.sh.j2 b/ansible/roles/haproxy/templates/haproxy_run.sh.j2
index 6c2e1feef0..c556e6f9f4 100644
--- a/ansible/roles/haproxy/templates/haproxy_run.sh.j2
+++ b/ansible/roles/haproxy/templates/haproxy_run.sh.j2
@@ -1,5 +1,6 @@
 #!/bin/bash -x
-{% set haproxy_cmd='/usr/sbin/haproxy -W -db' if kolla_base_distro in ['debian', 'ubuntu']  else '/usr/sbin/haproxy-systemd-wrapper' %}
+{% set has_haproxy_1_8=kolla_base_distro in ['debian', 'ubuntu'] or (kolla_base_distro == 'centos' and ansible_distribution_major_version is version(8, '>=')) %}
+{% set haproxy_cmd='/usr/sbin/haproxy -W -db' if has_haproxy_1_8 else '/usr/sbin/haproxy-systemd-wrapper' %}
 
 # We need to run haproxy with one `-f` for each service, because including an
 # entire config directory was not a feature until version 1.7 of HAProxy.