21dd36b834
Changed out the patch that Bifrost retreives for installation as the patch that was present landed in Ironic today. The new patch is to address ipmi retries on busy BMCs where multiple nodes share the same BMC address.
263 lines
13 KiB
YAML
263 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.
|
|
---
|
|
- name: "Update Package Cache"
|
|
apt: update_cache=yes
|
|
- name: "Install packages"
|
|
apt: name={{ item }}
|
|
with_items: required_packages_ubuntu
|
|
# Step required for Ubuntu 14.10
|
|
- name: "Install 14.10 packages"
|
|
apt: name={{ item }}
|
|
with_items:
|
|
- pxelinux
|
|
when: ansible_distribution_version|version_compare('14.10', '>=')
|
|
- name: "Install testing packages"
|
|
apt: name={{ item }}
|
|
when: testing is defined and testing == true
|
|
with_items:
|
|
- libvirt-bin
|
|
- qemu-utils
|
|
- qemu-kvm
|
|
- sgabios
|
|
- name: "Ensuring /opt/stack is present"
|
|
file: name=/opt/stack state=directory owner=root group=root
|
|
- name: "Retrieving latest known os_ironic.py file"
|
|
get_url: url={{ latest_os_ironic_url }} dest=/opt/stack/ansible/lib/ansible/modules/extras/cloud/os_ironic.py
|
|
- name: "Retrieving latest known os_ironic_node.py file"
|
|
get_url: url={{ latest_os_ironic_node_url }} dest=/opt/stack/ansible/lib/ansible/modules/extras/cloud/os_ironic_node.py
|
|
- name: "Downloading Ironic"
|
|
command: git clone https://git.openstack.org/openstack/ironic chdir=/opt/stack creates=/opt/stack/ironic
|
|
- name: "Ironic - checking out master branch"
|
|
command: git checkout -f master chdir=/opt/stack/ironic
|
|
- name: "Ironic - resetting master branch"
|
|
command: git reset --hard master chdir=/opt/stack/ironic
|
|
- name: "Ironic - resyncing to current master branch"
|
|
command: git pull --ff-only chdir=/opt/stack/ironic/
|
|
# TODO: Remove this once it has landed.
|
|
- name: "Ironic - Temporary - Retrieve 168120 - IPMI Retry logic"
|
|
shell: git fetch https://jkreger@review.openstack.org/openstack/ironic refs/changes/20/168120/1 && git checkout FETCH_HEAD chdir=/opt/stack/ironic
|
|
- name: "Ironic Client - Install from source if configured to do so."
|
|
include: shade_source_install.yml
|
|
when: skip_install is not defined and ironicclient_source_install is defined and ironicclient_source_install == true
|
|
- name: "Ironic Client - Install from pip"
|
|
pip: name=python-ironicclient state=present
|
|
when: skip_install is not defined and (ironicclient_source_install is not defined or ironicclient_source_install == false)
|
|
- name: "proliantutils - Install from pip"
|
|
pip: name=proliantutils state=present
|
|
when: skip_install is not defined
|
|
# TODO: The next package is installed via git and then manyally installed
|
|
# as the os_ironic and os_ironic_node are under active development and
|
|
# may require features that have not yet been released in shade.
|
|
# TODO: If the portion below remains for any period of time, it should
|
|
# be converted to an include... or consider converting to the integrated
|
|
# git module.
|
|
- name: "Shade - Install from source if configured to do so"
|
|
include: shade_source_install.yml
|
|
when: skip_install is not defined and shade_source_install is defined and shade_source_install == true
|
|
- name: "Shade - Installing patched shade library."
|
|
pip: name=shade state=latest
|
|
when: skip_install is not defined and (shade_source_install is not defined or shade_source_install == false)
|
|
- name: "Include diskimage-builder installation"
|
|
include: dib_install.yml
|
|
when: create_image_via_dib == true
|
|
- name: "Starting MySQL"
|
|
service: name=mysql state=started
|
|
- name: "Starting rabbitmq-server"
|
|
service: name=rabbitmq-server state=started
|
|
- name: "RabbitMQ - Testing if hostname is defined firsts 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: "Ensuring guest user is removed from rabbitmq"
|
|
rabbitmq_user: user=guest state=absent force=yes
|
|
- name: "Creating 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: login_user=root login_password={{ mysql_password }} name=ironic state=present encoding=utf8
|
|
register: test_created_db
|
|
no_log: True
|
|
- name: "MySQL - Creating user for Ironic"
|
|
mysql_user: login_user=root login_password={{ mysql_password }} name=ironic password={{ ironic_db_password }} priv=ironic.*:ALL state=present
|
|
no_log: True
|
|
- name: "Install Ironic using pip"
|
|
pip: name=/opt/stack/ironic state=latest
|
|
when: skip_install is not defined
|
|
- name: "Ensure /etc/ironic exists"
|
|
file: name=/etc/ironic state=directory
|
|
- name: "Place Ironic Config file"
|
|
template: src=ironic.conf.j2 dest=/etc/ironic/ironic.conf
|
|
- name: "Place Ironic IPA Agent PXE configuration file"
|
|
template: src=agent_config.template.j2 dest=/etc/ironic/agent_config.template
|
|
- name: "Copy policy.json to /etc/ironic"
|
|
copy: src=/opt/stack/ironic/etc/ironic/policy.json dest=/etc/ironic/
|
|
- name: "Creating Ironic DB Schema"
|
|
command: ironic-dbsync --config-file /etc/ironic/ironic.conf create_schema
|
|
when: test_created_db.changed == true
|
|
- name: "Upgrading Ironic DB Schema"
|
|
command: ironic-dbsync --config-file /etc/ironic/ironic.conf upgrade
|
|
when: test_created_db.changed == false
|
|
- name: "Creating an ironic service group"
|
|
group: name=ironic
|
|
- name: "Creating an ironic service user"
|
|
user: name=ironic group=ironic
|
|
- name: "Adding ironic user to libvirtd group"
|
|
user: name=ironic group=libvirtd append=yes
|
|
when: testing == true
|
|
- name: "Creating SSH directory for ironic user"
|
|
local_action: file path=/home/ironic/.ssh owner=ironic group=ironic mode=0700 state=directory
|
|
when: testing == true
|
|
- name: "Checking for ironic user SSH key"
|
|
local_action: stat path=/home/ironic/.ssh/id_rsa
|
|
register: test_ironic_pvt_key
|
|
- name: "Generating 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: "Setting 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: "Setting 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: "Creating authorized_keys file for ironic user"
|
|
local_action: command cp -p /home/ironic/.ssh/id_rsa.pub /home/ironic/.ssh/authorized_keys
|
|
when: testing == true
|
|
- name: "Placing services"
|
|
template: src=init_template.j2 dest=/etc/init/{{item.service_name}}.conf owner=root group=root
|
|
with_items:
|
|
- { service_name: 'ironic-api', username: 'ironic', args: '--config-file /etc/ironic/ironic.conf'}
|
|
- { service_name: 'ironic-conductor', username: 'ironic', args: '--config-file /etc/ironic/ironic.conf'}
|
|
- 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=reloaded
|
|
- name: "Setting up PXE and iPXE folders"
|
|
file: name={{item}} owner=ironic group=ironic state=directory
|
|
with_items:
|
|
- /tftpboot
|
|
- /tftpboot/pxelinux.cfg
|
|
- "{{ http_boot_folder }}"
|
|
- name: "Placing tftpd map-file"
|
|
copy: src=tftpboot-map-file dest=/tftpboot/map-file owner=ironic group=ironic
|
|
- name: "Disable service tftpd-hpa"
|
|
service: name=tftpd-hpa state=stopped enabled=no
|
|
- name: "Placing pxelinux.0 (pre-14.10)"
|
|
copy: src=/usr/lib/syslinux/pxelinux.0 dest=/tftpboot
|
|
when: ansible_distribution_version|version_compare('14.10', '<')
|
|
- name: "Placing pxelinux.0 (>=14.10)"
|
|
copy: src=/usr/lib/PXELINUX/pxelinux.0 dest=/tftpboot
|
|
when: ansible_distribution_version|version_compare('14.10', '>=')
|
|
- name: "Place boot.ipxe helper script to HTTP root"
|
|
copy: src=boot.ipxe dest=/httpboot/boot.ipxe
|
|
- name: "Place tftp config file"
|
|
copy: src=xinetd.tftp dest=/etc/xinetd.d/tftp
|
|
- name: "Copy iPXE image into place"
|
|
copy: src=/usr/lib/ipxe/undionly.kpxe dest=/tftpboot/
|
|
- name: "Deploy dnsmasq configuration file"
|
|
template: src=dnsmasq.conf.j2 dest=/etc/dnsmasq.conf
|
|
# 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: "Looking for libvirt dnsmasq config"
|
|
stat: path=/etc/dnsmasq.d/libvirt-bin
|
|
register: test_libvirt_dnsmasq
|
|
- name: "Disabling libvirt dnsmasq config"
|
|
command: mv /etc/dnsmasq.d/libvirt-bin /etc/dnsmasq.d/libvirt-bin~
|
|
when: test_libvirt_dnsmasq.stat.exists == true and testing == true
|
|
- name: "Stopping existing libvirt dnsmasq processes"
|
|
command: killall -w dnsmasq
|
|
when: testing == true
|
|
# 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: "Enabling 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: "Looking for sgabios in /usr/share/qemu"
|
|
stat: path=/usr/share/qemu/sgabios.bin
|
|
register: test_sgabios_qemu
|
|
- name: "Looking 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: "Deploying nginx configuration file for serving HTTP requests"
|
|
template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf
|
|
- name: "Ensuring dnsmasq is running"
|
|
service: name={{ item }} state=started
|
|
with_items:
|
|
- xinetd
|
|
- dnsmasq
|
|
- nginx
|
|
- name: "Sending services a reload signal"
|
|
service: name={{ item }} state=reloaded
|
|
with_items:
|
|
- xinetd
|
|
- nginx
|
|
- name: "Sending services a force-reload signal"
|
|
command: /etc/init.d/dnsmasq force-reload
|
|
# Similar logic to below can be utilized to retrieve files
|
|
- name: "Determine if folder exists, else create and populate folder."
|
|
stat: path=/tftpboot/master_images
|
|
register: test_master_images
|
|
- name: "Create master_images folder"
|
|
file: name=/tftpboot/master_images state=directory owner=ironic group=ironic
|
|
when: test_master_images.stat.exists == false
|
|
# This is overly complex, however get_url will always re-retrieve the file
|
|
# if it already exists, and this is to prevent that behavior.
|
|
- name: "Test if CoreOS kernel is present"
|
|
stat: path={{ http_boot_folder }}/coreos_production_pxe.vmlinuz
|
|
register: test_core_os_kernel_present
|
|
- name: "Download CoreOS kernel"
|
|
get_url: url=http://tarballs.openstack.org/ironic-python-agent/coreos/files/coreos_production_pxe.vmlinuz dest={{ http_boot_folder }}/coreos_production_pxe.vmlinuz
|
|
when: test_core_os_kernel_present.stat.exists == false
|
|
- name: "Test if CoreOS image is present"
|
|
stat: path={{ http_boot_folder }}/coreos_production_pxe_image-oem.cpio.gz
|
|
register: test_core_os_image_present
|
|
- name: "Download CoreOS image"
|
|
get_url: url=http://tarballs.openstack.org/ironic-python-agent/coreos/files/coreos_production_pxe_image-oem.cpio.gz dest={{ http_boot_folder }}/coreos_production_pxe_image-oem.cpio.gz
|
|
when: test_core_os_image_present.stat.exists == false
|
|
- name: "Test if Ubuntu 14.04 server cloud amd64 is present"
|
|
stat: path={{ deploy_image }}
|
|
register: test_os_image_present
|
|
- name: "Download Ubuntu image"
|
|
get_url: url=http://cloud-images.ubuntu.com/releases/trusty/release/ubuntu-14.04-server-cloudimg-amd64.tar.gz dest=/httpboot/ubuntu-14.04-server-cloudimg-amd64.tar.gz
|
|
when: test_os_image_present.stat.exists == false and create_image_via_dib == false
|
|
- name: "Extract Ubuntu image"
|
|
command: tar -xvzf ubuntu-14.04-server-cloudimg-amd64.tar.gz chdir=/httpboot creates=/httpboot/trusty-server-cloudimg-amd64.img
|
|
when: test_os_image_present.stat.exists == false and create_image_via_dib == false
|
|
# Create bootable image takes a partition image, prepends space for a
|
|
# bootloader, partition table, and then installs the bootloader.
|
|
#
|
|
# If attempting to utilize a base Ubuntu image, diskimage-builder
|
|
# is the recommended, and default path.
|
|
- name: "Creating bootable image"
|
|
include: create_bootable_image.yml
|
|
when: test_os_image_present.stat.exists == false and transform_boot_image == true and create_image_via_dib == false
|
|
# DIB is presently the default path.
|
|
- name: "Creating image via disk imae builder"
|
|
include: create_dib_image.yml
|
|
when: test_os_image_present.stat.exists == false and transform_boot_image == false and create_image_via_dib == true
|