# 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 == true and test_libvirt_dnsmasq.stat.exists | bool == true and testing|bool == true - 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