From 1e510883987821bb572429fcf4f16176f9f286b1 Mon Sep 17 00:00:00 2001
From: Andy McCrae <andy.mccrae@gmail.com>
Date: Fri, 27 May 2016 16:39:23 +0100
Subject: [PATCH] Add 16.04 support

Implements: blueprint support-ubuntu-1604
Change-Id: Ide4d2c5e7753aa56bd82f0de913217f0df8860b9
---
 defaults/main.yml                             | 20 ------
 meta/main.yml                                 |  5 +-
 .../ironic-1604-support-b9ebb12ee4d78275.yaml |  3 +
 tasks/ironic_api_install.yml                  | 14 ++--
 tasks/ironic_conductor_install.yml            | 30 +++------
 tasks/ironic_conductor_post_install.yml       |  4 +-
 ...ronic_upstart_init.yml => ironic_init.yml} |  2 +-
 tasks/ironic_init_common.yml                  | 31 +++++++++
 tasks/ironic_init_systemd.yml                 | 48 +++++++++++++
 ...ommon_init.yml => ironic_init_upstart.yml} | 18 +----
 tasks/ironic_install.yml                      | 11 +++
 tasks/ironic_install_apt.yml                  | 39 +++++++++++
 tasks/main.yml                                | 67 +++++++++++++------
 templates/ironic-systemd-init.j2              | 25 +++++++
 templates/ironic-systemd-tempfiles.j2         |  4 ++
 vars/ubuntu-14.04.yml                         | 42 ++++++++++++
 vars/ubuntu-16.04.yml                         | 44 ++++++++++++
 17 files changed, 317 insertions(+), 90 deletions(-)
 create mode 100644 releasenotes/notes/ironic-1604-support-b9ebb12ee4d78275.yaml
 rename tasks/{ironic_upstart_init.yml => ironic_init.yml} (95%)
 create mode 100644 tasks/ironic_init_common.yml
 create mode 100644 tasks/ironic_init_systemd.yml
 rename tasks/{ironic_upstart_common_init.yml => ironic_init_upstart.yml} (78%)
 create mode 100644 tasks/ironic_install_apt.yml
 create mode 100644 templates/ironic-systemd-init.j2
 create mode 100644 templates/ironic-systemd-tempfiles.j2
 create mode 100644 vars/ubuntu-14.04.yml
 create mode 100644 vars/ubuntu-16.04.yml

diff --git a/defaults/main.yml b/defaults/main.yml
index 302a9cec..d3e2e940 100644
--- a/defaults/main.yml
+++ b/defaults/main.yml
@@ -148,26 +148,6 @@ ironic_pip_packages:
   - python-ironicclient
   - python-swiftclient
 
-ironic_api_apt_packages:
-  - apache2
-  - apache2-utils
-  - libapache2-mod-wsgi
-
-ironic_conductor_apt_packages:
-  - libxml2-dev
-  - syslinux
-  - syslinux-common
-  - libxslt1-dev
-  - qemu-utils
-  - libpq-dev
-  - python-yaml
-  - open-iscsi
-  - ipmitool
-  - tftpd-hpa
-
-ironic_conductor_standalone_apt_packages:
-  - isc-dhcp-server
-
 ## RabbitMQ info
 ironic_rabbitmq_userid: ironic
 ironic_rabbitmq_vhost: /ironic
diff --git a/meta/main.yml b/meta/main.yml
index e2731aaf..a70d3a5b 100644
--- a/meta/main.yml
+++ b/meta/main.yml
@@ -22,6 +22,7 @@ galaxy_info:
   - name: Ubuntu
     versions:
     - trusty
+    - xenial
   categories:
   - cloud
   - baremetal
@@ -33,6 +34,8 @@ dependencies:
   - role: pip_install
     when:
       - ironic_developer_mode | bool
-  - apt_package_pinning
+  - role: apt_package_pinning
+    when:
+      - ansible_pkg_mgr == 'apt'
   - galera_client
   - openstack_openrc
diff --git a/releasenotes/notes/ironic-1604-support-b9ebb12ee4d78275.yaml b/releasenotes/notes/ironic-1604-support-b9ebb12ee4d78275.yaml
new file mode 100644
index 00000000..8d05d57c
--- /dev/null
+++ b/releasenotes/notes/ironic-1604-support-b9ebb12ee4d78275.yaml
@@ -0,0 +1,3 @@
+---
+features:
+  - The ``ironic`` role now supports Ubuntu 16.04 and SystemD.
diff --git a/tasks/ironic_api_install.yml b/tasks/ironic_api_install.yml
index bc52b2bd..1e5c9a25 100644
--- a/tasks/ironic_api_install.yml
+++ b/tasks/ironic_api_install.yml
@@ -13,15 +13,11 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-- name: Install ironic-api specific apt packages
-  apt:
-    pkg: "{{ item }}"
-    state: latest
-  register: install_packages
-  until: install_packages|success
-  retries: 5
-  delay: 2
-  with_items: "{{ ironic_api_apt_packages }}"
+- include: ironic_install_apt.yml
+  when:
+    - ansible_pkg_mgr == 'apt'
+  vars:
+    apt_pkgs: "{{ ironic_api_apt_packages }}"
   tags:
     - ironic-install
     - ironic-api
diff --git a/tasks/ironic_conductor_install.yml b/tasks/ironic_conductor_install.yml
index e8d4b94e..ccb6ecfa 100644
--- a/tasks/ironic_conductor_install.yml
+++ b/tasks/ironic_conductor_install.yml
@@ -13,30 +13,22 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-- name: Install ironic-conductor specific apt packages
-  apt:
-    pkg: "{{ item }}"
-    state: latest
-  register: install_packages
-  until: install_packages|success
-  retries: 5
-  delay: 2
-  with_items: "{{ ironic_conductor_apt_packages }}"
+- include: ironic_install_apt.yml
+  when:
+    - ansible_pkg_mgr == 'apt'
+  vars:
+    apt_pkgs: "{{ ironic_conductor_apt_packages }}"
   tags:
     - ironic-install
     - ironic-conductor
     - ironic-apt-packages
 
-- name: Install ironic-conductor standalone apt packages
-  apt:
-    pkg: "{{ item }}"
-    state: latest
-  register: install_packages
-  until: install_packages|success
-  retries: 5
-  delay: 2
-  with_items: "{{ ironic_conductor_standalone_apt_packages }}"
-  when: ironic_standalone
+- include: ironic_install_apt.yml
+  when:
+    - ansible_pkg_mgr == 'apt'
+    - ironic_standalone
+  vars:
+    apt_pkgs: "{{ ironic_conductor_standalone_apt_packages }}"
   tags:
     - ironic-install
     - ironic-conductor
diff --git a/tasks/ironic_conductor_post_install.yml b/tasks/ironic_conductor_post_install.yml
index 2dce0660..d33e243f 100644
--- a/tasks/ironic_conductor_post_install.yml
+++ b/tasks/ironic_conductor_post_install.yml
@@ -56,7 +56,7 @@
 ## there is no idempotent way of doing this without several tasks
 ## which is a wasted effort.
 - name: Copy syslinux pxlinux.0
-  command: cp /usr/lib/syslinux/pxelinux.0 /tftpboot/pxelinux.0
+  command: "cp {{ ironic_pxelinux_path }} /tftpboot/pxelinux.0"
   tags:
     - tftpd-hpa
 
@@ -65,6 +65,6 @@
 ## there is no idempotent way of doing this without several tasks
 ## which is a wasted effort.
 - name: Copy syslinux chain.c32
-  command: cp /usr/lib/syslinux/chain.c32 /tftpboot/chain.c32
+  command: "cp {{ ironic_chainc32_path }} /tftpboot/chain.c32"
   tags:
     - tftpd-hpa
diff --git a/tasks/ironic_upstart_init.yml b/tasks/ironic_init.yml
similarity index 95%
rename from tasks/ironic_upstart_init.yml
rename to tasks/ironic_init.yml
index 62fd5955..af1e8b40 100644
--- a/tasks/ironic_upstart_init.yml
+++ b/tasks/ironic_init.yml
@@ -13,7 +13,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-- include: ironic_upstart_common_init.yml
+- include: ironic_init_common.yml
   vars:
     program_name: "{{ ironic_conductor_program_name }}"
     service_name: "{{ ironic_service_name }}"
diff --git a/tasks/ironic_init_common.yml b/tasks/ironic_init_common.yml
new file mode 100644
index 00000000..0e157a55
--- /dev/null
+++ b/tasks/ironic_init_common.yml
@@ -0,0 +1,31 @@
+---
+# Copyright 2016, Rackspace US, Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+- include: ironic_init_upstart.yml
+  when: pid1_name == "init"
+  tags:
+    - ironic-init
+
+- include: ironic_init_systemd.yml
+  when: pid1_name == "systemd"
+  tags:
+    - ironic-init
+
+- name: Load service
+  service:
+   name: "{{ program_name }}"
+   enabled: "yes"
+  notify:
+    - Restart ironic services
diff --git a/tasks/ironic_init_systemd.yml b/tasks/ironic_init_systemd.yml
new file mode 100644
index 00000000..8e43d59f
--- /dev/null
+++ b/tasks/ironic_init_systemd.yml
@@ -0,0 +1,48 @@
+---
+# Copyright 2016, Rackspace US, Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+- name: Create ironic TEMP dirs
+  file:
+    path: "{{ item.path }}/{{ program_name }}"
+    state: directory
+    owner: "{{ system_user }}"
+    group: "{{ system_group }}"
+    mode: "2755"
+  with_items:
+    - { path: "/var/run" }
+    - { path: "/var/lock" }
+
+- name: Create tempfile.d entry
+  template:
+    src: "ironic-systemd-tempfiles.j2"
+    dest: "/etc/tmpfiles.d/ironic.conf"
+    mode: "0644"
+    owner: "root"
+    group: "root"
+
+- name: Place the systemd init script
+  template:
+    src: "ironic-systemd-init.j2"
+    dest: "/etc/systemd/system/{{ program_name }}.service"
+    mode: "0644"
+    owner: "root"
+    group: "root"
+  register: systemd_init
+
+- name: Reload the systemd daemon
+  command: "systemctl daemon-reload"
+  when: systemd_init | changed
+  notify:
+    - Restart ironic services
diff --git a/tasks/ironic_upstart_common_init.yml b/tasks/ironic_init_upstart.yml
similarity index 78%
rename from tasks/ironic_upstart_common_init.yml
rename to tasks/ironic_init_upstart.yml
index a586c203..8db7b3c7 100644
--- a/tasks/ironic_upstart_common_init.yml
+++ b/tasks/ironic_init_upstart.yml
@@ -20,27 +20,13 @@
     mode: "0644"
     owner: "root"
     group: "root"
+  register: upstart_init
   notify:
     - Restart ironic services
-  tags:
-    - upstart-init
-    - ironic-init
 
 - name: Reload init scripts
   shell: |
     initctl reload-configuration
+  when: upstart_init | changed
   notify:
     - Restart ironic services
-  tags:
-    - upstart-init
-    - ironic-init
-
-- name: Load service
-  service:
-   name: "{{ program_name }}"
-   enabled: "yes"
-  notify:
-    - Restart ironic services
-  tags:
-    - upstart-init
-    - ironic-init
diff --git a/tasks/ironic_install.yml b/tasks/ironic_install.yml
index 09d60a8c..a54d1aaa 100644
--- a/tasks/ironic_install.yml
+++ b/tasks/ironic_install.yml
@@ -26,6 +26,17 @@
     - ironic-install
     - ironic-pip-packages
 
+- include: ironic_install_apt.yml
+  when:
+    - ansible_pkg_mgr == 'apt'
+    - ironic_developer_mode | bool
+  vars:
+    apt_pkgs: "{{ ironic_developer_apt_packages }}"
+  tags:
+    - ironic-install
+    - ironic-apt
+    - ironic-apt-packages
+
 - name: Clone requirements git repository
   git:
     repo: "{{ ironic_requirements_git_repo }}"
diff --git a/tasks/ironic_install_apt.yml b/tasks/ironic_install_apt.yml
new file mode 100644
index 00000000..5525d39d
--- /dev/null
+++ b/tasks/ironic_install_apt.yml
@@ -0,0 +1,39 @@
+---
+# Copyright 2016, Rackspace US, Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+- name: Update apt sources
+  apt:
+    update_cache: yes
+    cache_valid_time: "{{ cache_timeout }}"
+  register: apt_update
+  until: apt_update|success
+  retries: 5
+  delay: 2
+  tags:
+    - ironic-apt-packages
+
+- name: Install apt packages
+  apt:
+    pkg: "{{ item }}"
+    state: latest
+  register: install_packages
+  until: install_packages|success
+  retries: 5
+  delay: 2
+  with_items:
+    - "{{ apt_pkgs }}"
+  tags:
+    - ironic-install
+    - ironic-apt-packages
diff --git a/tasks/main.yml b/tasks/main.yml
index 7818767d..5a53e788 100644
--- a/tasks/main.yml
+++ b/tasks/main.yml
@@ -13,33 +13,56 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-  - include: ironic_pre_install.yml
-  - include: ironic_install.yml
+- name: Check init system
+  command: cat /proc/1/comm
+  register: _pid1_name
+  tags:
+    - always
 
-  - include: ironic_api_install.yml
-    when: >
-      inventory_hostname in groups['ironic_api']
+- name: Set the name of pid1
+  set_fact:
+    pid1_name: "{{ _pid1_name.stdout }}"
+  tags:
+    - always
 
-  - include: ironic_conductor_install.yml
-    when: >
-      inventory_hostname in groups['ironic_conductor']
+- name: Gather variables for each operating system
+  include_vars: "{{ item }}"
+  with_first_found:
+    - "{{ ansible_distribution | lower }}-{{ ansible_distribution_version | lower }}.yml"
+    - "{{ ansible_distribution | lower }}-{{ ansible_distribution_major_version | lower }}.yml"
+    - "{{ ansible_os_family | lower }}-{{ ansible_distribution_major_version | lower }}.yml"
+    - "{{ ansible_distribution | lower }}.yml"
+    - "{{ ansible_os_family | lower }}.yml"
+  tags:
+    - always
 
-  - include: ironic_post_install.yml
+- include: ironic_pre_install.yml
+- include: ironic_install.yml
 
-  - include: ironic_api_post_install.yml
-    when: >
-      inventory_hostname in groups['ironic_api']
+- include: ironic_api_install.yml
+  when: >
+    inventory_hostname in groups['ironic_api']
 
-  - include: ironic_conductor_post_install.yml
-    when: >
-      inventory_hostname in groups['ironic_conductor']
+- include: ironic_conductor_install.yml
+  when: >
+    inventory_hostname in groups['ironic_conductor']
 
-  - include: ironic_db_setup.yml
-    when: >
-      inventory_hostname == groups['ironic_conductor'][0]
+- include: ironic_post_install.yml
 
-  - include: ironic_upstart_init.yml
+- include: ironic_api_post_install.yml
+  when: >
+    inventory_hostname in groups['ironic_api']
 
-  - include: ironic_service_setup.yml
-    when: >
-      inventory_hostname == groups['ironic_api'][0]
+- include: ironic_conductor_post_install.yml
+  when: >
+    inventory_hostname in groups['ironic_conductor']
+
+- include: ironic_db_setup.yml
+  when: >
+    inventory_hostname == groups['ironic_conductor'][0]
+
+- include: ironic_init.yml
+
+- include: ironic_service_setup.yml
+  when: >
+    inventory_hostname == groups['ironic_api'][0]
diff --git a/templates/ironic-systemd-init.j2 b/templates/ironic-systemd-init.j2
new file mode 100644
index 00000000..f1c2618b
--- /dev/null
+++ b/templates/ironic-systemd-init.j2
@@ -0,0 +1,25 @@
+# {{ ansible_managed }}
+
+[Unit]
+Description=ironic openstack service
+After=syslog.target
+After=network.target
+
+[Service]
+Type=simple
+User={{ system_user }}
+Group={{ system_group }}
+
+{% if program_override is defined %}
+ExecStart={{ program_override }} {{ program_config_options|default('') }} --log-file=/var/log/ironic/{{ program_name }}.log
+{% else %}
+ExecStart={{ ironic_bin }}/{{ program_name }} {{ program_config_options|default('') }} --log-file=/var/log/ironic/{{ program_name }}.log
+{% endif %}
+
+# Give a reasonable amount of time for the server to start up/shut down
+TimeoutSec=300
+Restart=on-failure
+RestartSec=150
+
+[Install]
+WantedBy=multi-user.target
diff --git a/templates/ironic-systemd-tempfiles.j2 b/templates/ironic-systemd-tempfiles.j2
new file mode 100644
index 00000000..b723d85d
--- /dev/null
+++ b/templates/ironic-systemd-tempfiles.j2
@@ -0,0 +1,4 @@
+# {{ ansible_managed }}
+
+D /var/lock/{{ program_name }} 2755 {{ system_user }} {{ system_group }}
+D /var/run/{{ program_name }} 2755 {{ system_user }} {{ system_group }}
diff --git a/vars/ubuntu-14.04.yml b/vars/ubuntu-14.04.yml
new file mode 100644
index 00000000..863be3a6
--- /dev/null
+++ b/vars/ubuntu-14.04.yml
@@ -0,0 +1,42 @@
+---
+# Copyright 2016, Rackspace US, Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+cache_timeout: 600
+
+ironic_developer_apt_packages:
+  - git-core
+
+ironic_api_apt_packages:
+  - apache2
+  - apache2-utils
+  - libapache2-mod-wsgi
+
+ironic_conductor_apt_packages:
+  - libxml2-dev
+  - syslinux
+  - syslinux-common
+  - libxslt1-dev
+  - qemu-utils
+  - libpq-dev
+  - python-yaml
+  - open-iscsi
+  - ipmitool
+  - tftpd-hpa
+
+ironic_conductor_standalone_apt_packages:
+  - isc-dhcp-server
+
+ironic_pxelinux_path: "/usr/lib/syslinux/pxelinux.0"
+ironic_chainc32_path: "/usr/lib/syslinux/chain.c32"
diff --git a/vars/ubuntu-16.04.yml b/vars/ubuntu-16.04.yml
new file mode 100644
index 00000000..6b7e3eb5
--- /dev/null
+++ b/vars/ubuntu-16.04.yml
@@ -0,0 +1,44 @@
+---
+# Copyright 2016, Rackspace US, Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+cache_timeout: 600
+
+ironic_developer_apt_packages:
+  - git-core
+  - libffi-dev
+
+ironic_api_apt_packages:
+  - apache2
+  - apache2-utils
+  - libapache2-mod-wsgi
+
+ironic_conductor_apt_packages:
+  - libxml2-dev
+  - syslinux
+  - syslinux-common
+  - pxelinux
+  - libxslt1-dev
+  - qemu-utils
+  - libpq-dev
+  - python-yaml
+  - open-iscsi
+  - ipmitool
+  - tftpd-hpa
+
+ironic_conductor_standalone_apt_packages:
+  - isc-dhcp-server
+
+ironic_pxelinux_path: "/usr/lib/PXELINUX/pxelinux.0"
+ironic_chainc32_path: "/usr/lib/syslinux/modules/efi64/chain.c32"