diff --git a/playbooks/roles/bifrost-configdrives-dynamic/tasks/main.yml b/playbooks/roles/bifrost-configdrives-dynamic/tasks/main.yml index 311e41180..d2c0ee826 100644 --- a/playbooks/roles/bifrost-configdrives-dynamic/tasks/main.yml +++ b/playbooks/roles/bifrost-configdrives-dynamic/tasks/main.yml @@ -16,28 +16,35 @@ # the host's assigned UUID value. - name: "Update facts from ironic to fill in any missing values" include: update_facts_from_ironic.yaml + - name: "Identify ssh_public_key if ssh_public_key_path is defined" include: ssh_public_key_path.yaml when: ssh_public_key is undefined and ssh_public_key_path is defined + - name: "Make temporary folder to build configdrive" local_action: command mktemp -d register: variable_configdrive_location + - name: "Make metadata folder - /openstack/{{ metadata_version }}" file: state: directory name: "{{ variable_configdrive_location.stdout }}/{{ uuid }}/openstack/{{ metadata_version }}/" + - name: "Make metadata folder - /openstack/latest" file: state: directory name: "{{ variable_configdrive_location.stdout }}/{{ uuid }}/openstack/latest/" + - name: "Place template in each openstack/{{ metadata_version }} folder" template: src: openstack_meta_data.json.j2 dest: "{{ variable_configdrive_location.stdout }}/{{ uuid }}/openstack/{{ metadata_version }}/meta_data.json" + - name: "Place template in each openstack/latest folder" template: src: openstack_meta_data.json.j2 dest: "{{ variable_configdrive_location.stdout }}/{{ uuid }}/openstack/latest/meta_data.json" + - name: "Generate network_info" network_metadata: ipv4_address: "{{ ipv4_address | default('') }}" @@ -50,44 +57,55 @@ nics: "{{ nics | default(omit) }}" node_network_info: "{{ node_network_info | default({}) }}" when: addressing_mode is undefined or "dhcp" not in addressing_mode + - name: "Place network info template in each openstack/latest folder" template: src: network_info.json.j2 dest: "{{ variable_configdrive_location.stdout }}/{{ uuid }}/openstack/latest/network_info.json" when: addressing_mode is undefined or "dhcp" not in addressing_mode + - name: "Make metadata folder - /openstack/latest" file: state: directory name: "{{ variable_configdrive_location.stdout }}/{{ uuid }}/openstack/content/" + - name: "Write network Debian style interface template" local_action: template src=interfaces.j2 dest={{ variable_configdrive_location.stdout }}/{{ uuid }}/openstack/content/0000 when: write_interfaces_file | bool == true + - name: "Check if mkisofs is available" shell: mkisofs --help &> /dev/null ignore_errors: yes register: test_mkisofs + - name: "If mkisofs is not available, fallback to genisoimage" set_fact: iso_gen_utility: "genisoimage" when: ('genisoimage' in test_mkisofs.stderr) or test_mkisofs.rc != 0 + - name: "Check if genisoimage is available" shell: genisoimage --help &> /dev/null ignore_errors: yes register: test_genisoimage + - name: "fail if genisoimage is not available." fail: msg="Neither mkisofs or genisoimage is available. Cannot make config drive files." when: test_genisoimage.rc != 0 and test_mkisofs.rc != 0 + - name: "Make config drive files" become: yes command: "{{iso_gen_utility}} -R -V config-2 -o {{http_boot_folder}}/configdrive-{{ uuid }}.iso {{ variable_configdrive_location.stdout }}/{{ uuid }}" + - name: "Make config drive files base64 encoded and gzip compressed" become: yes shell: gzip -c {{http_boot_folder}}/configdrive-{{ uuid }}.iso | base64 > {{http_boot_folder}}/configdrive-{{ uuid }}.iso.gz + - name: "Cleanup configdrive .iso files" become: yes file: state: absent name: "{{http_boot_folder}}/configdrive-{{ uuid }}.iso" + - name: "Cleanup configdrive temp folder" become: yes file: diff --git a/playbooks/roles/bifrost-configdrives-dynamic/tasks/ssh_public_key_path.yaml b/playbooks/roles/bifrost-configdrives-dynamic/tasks/ssh_public_key_path.yaml index d3fee82f2..781e05b58 100644 --- a/playbooks/roles/bifrost-configdrives-dynamic/tasks/ssh_public_key_path.yaml +++ b/playbooks/roles/bifrost-configdrives-dynamic/tasks/ssh_public_key_path.yaml @@ -16,8 +16,10 @@ local_action: stat path={{ ssh_public_key_path }} register: test_ssh_public_key_path when: ssh_public_key_path is defined + - name: "Defined ssh_public_key_path - Error if ssh_public_key_path is not valid" local_action: fail msg="ssh_public_key_path is not valid." when: test_ssh_public_key_path.stat.exists == false + - name: "Defined ssh_public_key_path - Read SSH public key in" set_fact: ssh_public_key="{{ lookup('file', ssh_public_key_path ) }}" diff --git a/playbooks/roles/bifrost-create-vm-nodes/tasks/main.yml b/playbooks/roles/bifrost-create-vm-nodes/tasks/main.yml index 889d8d341..3d877a1eb 100644 --- a/playbooks/roles/bifrost-create-vm-nodes/tasks/main.yml +++ b/playbooks/roles/bifrost-create-vm-nodes/tasks/main.yml @@ -23,11 +23,13 @@ set_fact: ansible_os_family: "Suse" when: ansible_os_family | search("openSUSE Tumbleweed") + - name: Ensure openSUSE Leap has the correct family set_fact: ansible_os_family: "Suse" when: (ansible_os_family | search("SUSE LINUX")) or (ansible_os_family | search("openSUSE Leap")) + - name: "Update apt cache if Ubuntu/Debian" apt: update_cache: yes diff --git a/playbooks/roles/bifrost-ironic-install/tasks/create_tftpboot.yml b/playbooks/roles/bifrost-ironic-install/tasks/create_tftpboot.yml index c7b708768..3144d37d4 100644 --- a/playbooks/roles/bifrost-ironic-install/tasks/create_tftpboot.yml +++ b/playbooks/roles/bifrost-ironic-install/tasks/create_tftpboot.yml @@ -20,43 +20,58 @@ - /tftpboot/pxelinux.cfg - "{{ http_boot_folder }}" - "{{ http_boot_folder }}/pxelinux.cfg" + - name: "Place tftpd map-file" copy: src=tftpboot-map-file dest=/tftpboot/map-file owner=ironic group=ironic + - name: "Disable service {{ tftp_service_name }}" service: name="{{ tftp_service_name }}" state=stopped enabled=no + - name: "Set pxelinux.0 source (for Ubuntu >=14.10)" set_fact: syslinux_tftp_dir: '/usr/lib/PXELINUX' when: ansible_distribution == 'Ubuntu' and ansible_distribution_version|version_compare('14.10', '>=') + - name: "Determine if pxelinux.0 is in place" stat: path=/tftpboot/pxelinux.0 register: test_pxelinux + - name: "Place pxelinux.0" copy: src={{ syslinux_tftp_dir }}/pxelinux.0 dest=/tftpboot when: test_pxelinux.stat.exists == false + - name: "Place boot.ipxe helper script /etc/ironic" copy: src=boot.ipxe dest=/etc/ironic/boot.ipxe owner=ironic group=ironic mode=0744 + - name: "Pre-stage boot.ipxe into /httpboot/" copy: src=boot.ipxe dest=/httpboot/boot.ipxe owner=ironic group=ironic mode=0744 + - name: "Place tftp config file" copy: src=xinetd.tftp dest=/etc/xinetd.d/tftp + - name: "Download ipxe files if asked" include: get_ipxe.yml when: download_ipxe | bool == true + - name: "Copy iPXE image into place" copy: src={{ ipxe_dir }}/undionly.kpxe dest=/tftpboot/ + # NOTE(TheJulia): Copy full iPXE chain loader images in case they are required. - name: "Copy full iPXE image into /httpboot" copy: src={{ ipxe_dir }}/{{ ipxe_full_binary }} dest=/httpboot/ + - name: "Copy full iPXE image into /tftpboot" copy: src={{ ipxe_dir }}/{{ ipxe_full_binary }} dest=/tftpboot/ + # 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 + - name: "Inspector - Place default tftp boot file in {{ http_boot_folder}}/pxelinux.cfg/" template: src=inspector-default-boot-ipxe.j2 diff --git a/playbooks/roles/bifrost-ironic-install/tasks/download_ipa_image.yml b/playbooks/roles/bifrost-ironic-install/tasks/download_ipa_image.yml index 3263ae395..e6e2652b2 100644 --- a/playbooks/roles/bifrost-ironic-install/tasks/download_ipa_image.yml +++ b/playbooks/roles/bifrost-ironic-install/tasks/download_ipa_image.yml @@ -18,12 +18,15 @@ - name: "Test if IPA kernel is present" stat: path={{ ipa_kernel }} register: test_ipa_kernel_present + - name: "Download IPA kernel" get_url: url={{ ipa_kernel_upstream_url }} dest={{ ipa_kernel }} timeout=300 when: test_ipa_kernel_present.stat.exists == false + - name: "Test if IPA image is present" stat: path={{ ipa_ramdisk }} register: test_ipa_image_present + - name: "Download IPA image" get_url: url={{ ipa_ramdisk_upstream_url }} dest={{ ipa_ramdisk }} timeout=300 when: test_ipa_image_present.stat.exists == false diff --git a/playbooks/roles/bifrost-ironic-install/tasks/get_ipxe.yml b/playbooks/roles/bifrost-ironic-install/tasks/get_ipxe.yml index 765e1eb66..64711221d 100644 --- a/playbooks/roles/bifrost-ironic-install/tasks/get_ipxe.yml +++ b/playbooks/roles/bifrost-ironic-install/tasks/get_ipxe.yml @@ -20,6 +20,7 @@ owner=root group=root mode=0755 + - name: Get ipxe files get_url: url: "https://boot.ipxe.org/{{ item }}" diff --git a/playbooks/roles/bifrost-ironic-install/tasks/inspector_install.yml b/playbooks/roles/bifrost-ironic-install/tasks/inspector_install.yml index 108dc5191..33177459b 100644 --- a/playbooks/roles/bifrost-ironic-install/tasks/inspector_install.yml +++ b/playbooks/roles/bifrost-ironic-install/tasks/inspector_install.yml @@ -19,6 +19,7 @@ state=latest sourcedir={{ ironicinspector_git_folder }} source_install={{ ironicinspector_source_install }} + - name: "Inspector - PIP client install" include: pip_install.yml package=python-ironic-inspector-client diff --git a/playbooks/roles/bifrost-ironic-install/tasks/main.yml b/playbooks/roles/bifrost-ironic-install/tasks/main.yml index fecc231d4..f728310c8 100644 --- a/playbooks/roles/bifrost-ironic-install/tasks/main.yml +++ b/playbooks/roles/bifrost-ironic-install/tasks/main.yml @@ -22,11 +22,13 @@ set_fact: ansible_os_family: "Suse" when: ansible_os_family | search("openSUSE Tumbleweed") + - name: Ensure openSUSE Leap has the correct family set_fact: ansible_os_family: "Suse" when: (ansible_os_family | search("SUSE LINUX")) or (ansible_os_family | search("openSUSE Leap")) + # 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. @@ -35,23 +37,28 @@ 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: "Install Ironic deps" include: install.yml when: skip_package_install | bool != True + - name: "Bootstrap Ironic" include: bootstrap.yml when: skip_bootstrap | bool != True + - name: "Start Ironic services" include: start.yml when: skip_start | bool != True diff --git a/playbooks/roles/bifrost-ironic-install/tasks/start.yml b/playbooks/roles/bifrost-ironic-install/tasks/start.yml index 9bb3683e8..ebc80a21d 100644 --- a/playbooks/roles/bifrost-ironic-install/tasks/start.yml +++ b/playbooks/roles/bifrost-ironic-install/tasks/start.yml @@ -16,42 +16,54 @@ - name: "Reload systemd configuration" command: systemctl daemon-reload when: init_template == 'systemd_template.j2' + - name: "Start database service" service: name={{ mysql_service_name }} state=started + - name: "Start rabbitmq-server" service: name=rabbitmq-server state=started + - name: "start ironic-inspector" include: inspector_start.yml when: enable_inspector | bool == true + - 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 + # 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: "Stop existing libvirt dnsmasq processes" command: killall -w dnsmasq when: "{{ testing | bool == true and include_dhcp_server | bool == true }}" + - 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 == true }}" + - 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 == true }}" diff --git a/playbooks/roles/bifrost-test-vm/tasks/main.yml b/playbooks/roles/bifrost-test-vm/tasks/main.yml index 574ea6229..6a0892cc3 100644 --- a/playbooks/roles/bifrost-test-vm/tasks/main.yml +++ b/playbooks/roles/bifrost-test-vm/tasks/main.yml @@ -18,6 +18,7 @@ set_fact: deprecated: true when: deprecated_test_playbook | bool == true + - name: > "Execute ping step to verify connectivity and login to the host. If this fails, the configdrive may not have loaded." @@ -25,6 +26,7 @@ # hostname. This is because cirros lacks sftp support. raw: hostname register: instance_hostname + - name: > 'Error if hostname is set to "ubuntu", "cirros", "debian", or "centos"' # TODO: Presently this step is unable to cycle through each host and verify