bifrost/playbooks/roles/bifrost-ironic-install/tasks/main.yml

301 lines
13 KiB
YAML

# Copyright (c) 2015 Hewlett-Packard Development Company, L.P.
#
# 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.
---
# NOTE(cinerama) dummy-defaults.yml is an empty defaults file. We use it
# here to ensure that with_first_found won't fail should we not have
# defaults for a particular distribution, version, etc.
- name: Include OS family-specific defaults
include_vars: "{{ item }}"
with_first_found:
- "../defaults/required_defaults_{{ ansible_os_family }}_family.yml"
- "../defaults/dummy-defaults.yml"
- name: Include OS distribution-specific defaults
include_vars: "{{ item }}"
with_first_found:
- "../defaults/required_defaults_{{ ansible_distribution }}.yml"
- "../defaults/dummy-defaults.yml"
- name: Include OS version-specific defaults
include_vars: "{{ item }}"
with_first_found:
- "../defaults/required_defaults_{{ ansible_distribution }}_{{ansible_distribution_release }}.yml"
- "../defaults/required_defaults_{{ ansible_distribution }}_{{ ansible_distribution_version }}.yml"
- "../defaults/dummy-defaults.yml"
- name: "Update Package Cache"
apt: update_cache=yes
when: ansible_os_family == 'Debian'
- name: "Install packages"
action: "{{ ansible_pkg_mgr }} name={{ item }} state=present"
with_items: required_packages
# Step required for Ubuntu 14.10
- name: "Install Ubuntu 14.10 (and later) packages"
action: "{{ ansible_pkg_mgr }} name={{ item }} state=present"
with_items:
- pxelinux
when: ansible_distribution_version|version_compare('14.10', '>=') and ansible_distribution == 'Ubuntu'
- name: "If running in CI, set source install facts just to be sure"
set_fact:
shade_source_install: true
ironicclient_source_install: true
when: ci_testing | bool == true
# NOTE(TheJulia) While we don't necessarilly require /opt/stack any longer
# and it should already be created by the Ansible setup, we will leave this
# here for the time being.
- name: "Ensure /opt/stack is present"
file: name=/opt/stack state=directory owner=root group=root
- name: "proliantutils - Install from pip"
include: pip_install.yml
package=proliantutils
state=present
when: skip_install is not defined and testing | bool != true
- name: "UcsSdk - Install from pip"
include: pip_install.yml
package=UcsSdk
version=0.8.1.9
when: skip_install is not defined and testing | bool != true
- name: "Install iSCSI client if PXE driver support is enabled"
package:
name: "{{ iscsi_client_package }}"
state: present
when: skip_install is not defined and enable_pxe_drivers | bool == true
- name: "Shade - Install"
include: pip_install.yml
package=shade
state=latest
sourcedir={{ shade_git_folder }}
source_install={{ shade_source_install }}
when: skip_install is not defined
- name: "dib-utils - install from pip"
include: pip_install.yml
package=dib-utils
state=present
when: skip_install is not defined and create_image_via_dib == true
- name: "Diskimage-builder - Install"
include: pip_install.yml
package=diskimage-builder
sourcedir={{ dib_git_folder }}
source_install=true
when: skip_install is not defined and create_image_via_dib == true
- name: "Ironic Client - Install"
include: pip_install.yml
package=python-ironicclient
state=latest
sourcedir={{ ironicclient_git_folder }}
source_install={{ ironicclient_source_install }}
when: skip_install is not defined
- name: "Start database service"
service: name={{ mysql_service_name }} state=started
- name: "Start rabbitmq-server"
service: name=rabbitmq-server state=started
- name: "RabbitMQ - Testing if hostname is defined in /etc/hosts"
command: grep -i "127.0.0.1.*{{ ansible_hostname }}\ localhost" /etc/hosts
ignore_errors: yes
register: test_grep_fix_hostname
- name: "RabbitMQ - Fixing /etc/hosts"
command: sed -i 's/localhost/{{ ansible_hostname }} localhost/' /etc/hosts
when: test_grep_fix_hostname.rc != 0
- name: "Ensure guest user is removed from rabbitmq"
rabbitmq_user: user=guest state=absent force=yes
- name: "Create ironic user in RabbitMQ"
rabbitmq_user: user=ironic password={{ ironic_db_password }} force=yes state=present configure_priv=.* write_priv=.* read_priv=.*
no_log: true
- name: "MySQL - Creating DB"
mysql_db: name=ironic state=present encoding=utf8 login_user="{{ mysql_username | default(None) }}" login_password="{{ mysql_password | default(None) }}"
register: test_created_db
- name: "MySQL - Creating user for Ironic"
mysql_user: name=ironic password='{{ ironic_db_password }}' priv=ironic.*:ALL state=present login_user="{{ mysql_username | default(None) }}" login_password="{{ mysql_password | default(None) }}"
- name: "Install Ironic using pip"
include: pip_install.yml
package=ironic
state=latest
sourcedir={{ ironic_git_folder }}
source_install=true
when: skip_install is not defined
- name: "Create an ironic service group"
group:
name: "ironic"
- name: "Create an ironic service user"
user:
name: "ironic"
group: "ironic"
- name: "Ensure /etc/ironic exists"
file:
name: "/etc/ironic"
state: directory
owner: "ironic"
group: "ironic"
mode: 0755
# Note(TheJulia): The rootwrap copies will need to be re-tooled
# to possibly directly retreive current files if a source install
# is not utilized.
- name: "Copy rootwrap.conf from ironic source folder"
copy:
src: "{{ ironic_git_folder }}/etc/ironic/rootwrap.conf"
dest: "/etc/ironic/rootwrap.conf"
mode: 0644
owner: root
group: root
when: skip_install is not defined and enable_pxe_drivers | bool == true
- name: "Copy rootwrap.d contents from ironic source folder"
copy:
src: "{{ ironic_git_folder }}/etc/ironic/rootwrap.d/"
dest: "/etc/ironic/rootwrap.d"
mode: 0644
owner: root
group: root
directory_mode: yes
when: skip_install is not defined and enable_pxe_drivers | bool == true
- name: "Generate ironic Configuration"
include: ironic_config.yml
- name: "Copy policy.json to /etc/ironic"
copy: src="{{ ironic_git_folder }}/etc/ironic/policy.json" dest=/etc/ironic/ owner=ironic group=ironic mode=0644
- name: "Create ironic DB Schema"
command: ironic-dbsync --config-file /etc/ironic/ironic.conf create_schema
when: test_created_db.changed == true
- name: "Upgrade ironic DB Schema"
command: ironic-dbsync --config-file /etc/ironic/ironic.conf upgrade
when: test_created_db.changed == false
- name: "Do RedHat-specific changes for libvirt"
include: redhat_libvirt_changes.yml
when: ansible_os_family == 'RedHat'
- name: "Add ironic user to virtualization group"
user: name=ironic group="{{ virt_group }}" append=yes
when: testing == true
- name: "Create SSH directory for ironic user"
local_action: file path=/home/ironic/.ssh owner=ironic group=ironic mode=0700 state=directory
when: testing == true
- name: "Check for ironic user SSH key"
local_action: stat path=/home/ironic/.ssh/id_rsa
register: test_ironic_pvt_key
- name: "Generate SSH key for ironic user"
local_action: command ssh-keygen -f /home/ironic/.ssh/id_rsa -N ""
when: testing == true and test_ironic_pvt_key.stat.exists == false
- name: "Set ownership on ironic SSH private key"
local_action: file name=/home/ironic/.ssh/id_rsa owner=ironic group=ironic mode=0600 state=file
when: testing == true and test_ironic_pvt_key.stat.exists == false
- name: "Set ownership on ironic SSH public key"
local_action: file name=/home/ironic/.ssh/id_rsa.pub owner=ironic group=ironic mode=0644 state=file
when: testing == true and test_ironic_pvt_key.stat.exists == false
- name: "Create authorized_keys file for ironic user"
command: cp -p /home/ironic/.ssh/id_rsa.pub /home/ironic/.ssh/authorized_keys
when: testing == true
- name: "Create service folder if systemd template is defined"
file:
path: "{{ init_dest_dir }}"
state: directory
mode: 0755
when: init_template == 'systemd_template.j2'
- name: "Install ironic-inspector to permit use of inspection interface"
include: inspector_install.yml
when: enable_inspector | bool
- name: "Get ironic-api & ironic-conductor install location"
shell: echo $(dirname $(which ironic-api))
register: ironic_install_prefix
- name: "Set permissions for /var/lib/ironic for the ironic user"
file:
path: "{{ item }}"
state: directory
mode: 0750
owner: "ironic"
group: "ironic"
with_items:
- "/var/lib/ironic"
- "/var/lib/ironic/images"
- name: "Place ironic services"
template: src={{ init_template }} dest={{ init_dest_dir }}{{item.service_name}}{{ init_ext }} owner=root group=root
with_items:
- { service_path: "{{ ironic_install_prefix.stdout }}", service_name: 'ironic-api', username: 'ironic', args: '--config-file /etc/ironic/ironic.conf'}
- { service_path: "{{ ironic_install_prefix.stdout }}", service_name: 'ironic-conductor', username: 'ironic', args: '--config-file /etc/ironic/ironic.conf'}
- name: "Reload systemd configuration"
command: systemctl daemon-reload
when: init_template == 'systemd_template.j2'
- name: "Start ironic-conductor"
service: name=ironic-conductor state=started
- name: "Start ironic-api"
service: name=ironic-api state=started
- name: "Start ironic-conductor"
service: name=ironic-conductor state=restarted
- name: "Start ironic-api"
service: name=ironic-api state=restarted
- name: "Create and populate /tftpboot"
include: create_tftpboot.yml
- name: "Setup Inventory Hosts Directory"
file: path=/etc/dnsmasq.d/bifrost.hosts.d state=directory owner=root group=root mode=0755
when: "{{inventory_dhcp|bool}}"
- name: "Setup Inventory DHCP Hosts Directory"
file: path=/etc/dnsmasq.d/bifrost.dhcp-hosts.d state=directory owner=root group=root mode=0755
when: "{{inventory_dhcp|bool}}"
- name: "Deploy dnsmasq configuration file"
template: src=dnsmasq.conf.j2 dest=/etc/dnsmasq.conf
when: "{{include_dhcp_server|bool}}"
# NOTE(Shrews) When testing, we want to use our custom dnsmasq.conf file,
# not the one supplied by libvirt. And the libvirt started dnsmasq processes
# are not controlled by upstart, so we need to manually kill those.
- name: "Look for libvirt dnsmasq config"
stat: path=/etc/dnsmasq.d/libvirt-bin
register: test_libvirt_dnsmasq
when: "{{include_dhcp_server|bool}}"
- name: "Disable libvirt dnsmasq config"
command: mv /etc/dnsmasq.d/libvirt-bin /etc/dnsmasq.d/libvirt-bin~
when: "{{include_dhcp_server|bool and test_libvirt_dnsmasq.stat.exists|bool and testing|bool}}"
- name: "Stop existing libvirt dnsmasq processes"
command: killall -w dnsmasq
when: "{{testing|bool and include_dhcp_server|bool}}"
# NOTE(Shrews) We need to enable ip forwarding for the libvirt bridge to
# operate properly with dnsmasq. This should be done before starting dnsmasq.
- name: "Enable IP forwarding in sysctl"
sysctl: name="net.ipv4.ip_forward" value=1 sysctl_set=yes state=present reload=yes
when: testing == true
# NOTE(Shrews) Ubuntu packaging+apparmor issue prevents libvirt from loading
# the ROM from /usr/share/misc.
- name: "Look for sgabios in {{ sgabios_dir }}"
stat: path={{ sgabios_dir }}/sgabios.bin
register: test_sgabios_qemu
- name: "Look for sgabios in /usr/share/misc"
stat: path=/usr/share/misc/sgabios.bin
register: test_sgabios_misc
- name: "Place sgabios.bin"
command: cp /usr/share/misc/sgabios.bin /usr/share/qemu/sgabios.bin
when: test_sgabios_qemu == false and test_sgabios_misc == true and testing == true
- name: "Deploy nginx configuration file for serving HTTP requests"
template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf
- name: "Ensure services are running with current config"
service: name={{ item }} state=restarted
with_items:
- xinetd
- nginx
- name: "Ensure dnsmasq is running with current config"
service: name={{ item }} state=restarted
with_items:
- dnsmasq
when: "{{include_dhcp_server|bool}}"
- name: "Send services a reload signal"
service: name={{ item }} state=reloaded
with_items:
- xinetd
- nginx
- name: "Send services a force-reload signal"
service: name=dnsmasq state=restarted
when: "{{include_dhcp_server|bool}}"
- name: "Download Ironic Python Agent kernel & image"
include: download_ipa_image.yml
when: download_ipa | bool == true
- name: "Download cirros to use for deployment if requested"
get_url: url={{ cirros_deploy_image_upstream_url }} dest="{{ deploy_image }}"
when: "{{use_cirros|bool}}"
- name: "Explicitly permit nginx port (TCP) for file downloads from nodes to be provisioned"
command: iptables -I INPUT -p tcp --dport {{nginx_port}} -i {{network_interface}} -j ACCEPT
- name: "Explicitly permit TCP/6385 for IPA callback"
command: iptables -I INPUT -p tcp --dport 6385 -i {{network_interface}} -j ACCEPT