--- # Copyright 2019 Nokia # 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. # Block traffic during nodes power on/off so that possible old deployment # clients cannot connect new deployment services (like mysql) and ruin # the installation. - name: Block traffic on infra_internal iptables: state: present action: insert chain: INPUT jump: REJECT in_interface: "{{ networking['infra_internal']['interface'] }}" when: - installation_phase == "provisioning-started" - not virtual_env run_once: true - name: Power off nodes environment: OS_AUTH_TOKEN: "fake-token" IRONIC_URL: "{{ ironic_service_adminurl }}" command: "/usr/bin/ironic node-set-power-state {{baremetal_ironic_node_id.uuid}} off" when: - not virtual_env - installation_phase == "provisioning-started" retries: 5 delay: 10 - name: Power off nodes command: "openstack --os-cloud default baremetal node power off {{baremetal_ironic_node_id.uuid}}" when: - not virtual_env - installation_phase != "provisioning-started" retries: 5 delay: 10 - name: Ensure nodes are powered off environment: OS_AUTH_TOKEN: "fake-token" IRONIC_URL: "{{ ironic_service_adminurl }}" os_node_power_check: auth: auth_type: 'None' ironic_url: "{{ ironic_service_adminurl }}" nodes_details: - "{{ baremetal_ironic_node_id }}" power_state: 'power off' until: power_pending_list | length == 0 retries: 30 delay: 6 when: - not virtual_env - installation_phase == "provisioning-started" #no_log: True - name: Ensure nodes are powered off os_node_power_check: cloud: default auth_type: password ironic_url: "{{ ironic_service_adminurl }}" nodes_details: - "{{ baremetal_ironic_node_id }}" power_state: 'power off' endpoint_type: internal until: power_pending_list | length == 0 retries: 30 delay: 6 when: - not virtual_env - installation_phase != "provisioning-started" #no_log: True # Sleep to make sure power is off - name: Sleep for 15 seconds pause: seconds: 15 when: not virtual_env - name: Create config-drive directories for all nodes file: path: "/var/lib/ironic/confdrive/{{baremetal_ironic_node_id.name}}/openstack/latest/" state: "directory" owner: "ironic" group: "ironic" mode: "0775" - name: Generate config-drive files config_template: src: "{{item.src}}" dest: "/var/lib/ironic/confdrive/{{baremetal_ironic_node_id.name}}/openstack/latest/{{item.dest}}" owner: "ironic" group: "ironic" mode: "0644" config_type: "{{item.config_type}}" with_items: - "{{ config_drive_templates }}" - name: Stat config-drive files to check if they exists stat: path: "/var/lib/ironic/confdrive/{{ baremetal_ironic_node_id.name }}.base64" register: confdrive_stat - name: Prepare Config-drive ISO file shell: | # Generated ISO genisoimage -o /var/lib/ironic/confdrive/{{ baremetal_ironic_node_id.name }}.iso -ldots -allow-lowercase -allow-multidot -l -publisher 'ironicclient-configdrive 0.1' -quiet -J -r -V config-2 /var/lib/ironic/confdrive/{{ baremetal_ironic_node_id.name }} # Zip it! gzip /var/lib/ironic/confdrive/{{ baremetal_ironic_node_id.name }}.iso # Encode it to base64 base64 -w 0 /var/lib/ironic/confdrive/{{ baremetal_ironic_node_id.name }}.iso.gz > /var/lib/ironic/confdrive/{{ baremetal_ironic_node_id.name }}.base64 chown ironic:ironic /var/lib/ironic/confdrive/{{ baremetal_ironic_node_id.name }}.iso.gz chown ironic:ironic /var/lib/ironic/confdrive/{{ baremetal_ironic_node_id.name }}.base64 chmod o+r /var/lib/ironic/confdrive/{{ baremetal_ironic_node_id.name }}.iso.gz chmod o+r /var/lib/ironic/confdrive/{{ baremetal_ironic_node_id.name }}.base64 when: not confdrive_stat.stat.exists - name: Remove os_net_config temp files file: dest: "/tmp/{{baremetal_ironic_node_id.name}}_config.yaml" state: absent - name: Calculate md5sum of Golden image stat: path: "/opt/images/guest-image.img" get_md5: yes register: golden_img_md5sum run_once: true - name: Enable traffic on infra_internal iptables: state: absent chain: INPUT jump: REJECT in_interface: "{{ networking['infra_internal']['interface'] }}" when: - installation_phase == "provisioning-started" - not virtual_env run_once: true - set_fact: initiator_host: "{{ lookup('file', '/etc/hostname') }}" - set_fact: initiator_host_ip: "{{ hostvars[initiator_host]['networking']['infra_internal']['ip'] }}" - name: Configure Baremetal deployment environment: OS_AUTH_TOKEN: "fake-token" IRONIC_URL: "{{ ironic_service_adminurl }}" os_ironic_node: auth: auth_type: 'None' ironic_url: "{{ ironic_service_adminurl }}" uuid: "{{baremetal_ironic_node_id.uuid}}" deploy: False state: present power: absent maintenance: False instance_info: root_gb: 10 image_source: "http://{{initiator_host_ip}}:{{golden_image_http_port}}/guest-image.img" image_checksum: "{{golden_img_md5sum.stat.md5}}" when: - installation_phase == "provisioning-started" - name: Configure Baremetal deployment os_ironic_node: cloud: default endpoint_type: internal auth_type: password uuid: "{{baremetal_ironic_node_id.uuid}}" deploy: False state: present power: absent maintenance: False instance_info: root_gb: 10 image_source: "http://{{initiator_host_ip}}:{{golden_image_http_port}}/guest-image.img" image_checksum: "{{golden_img_md5sum.stat.md5}}" when: - installation_phase != "provisioning-started" - name: Start Baremetal deployment environment: OS_AUTH_TOKEN: "fake-token" IRONIC_URL: "{{ ironic_service_adminurl }}" os_ironic_node: auth: auth_type: 'None' ironic_url: "{{ ironic_service_adminurl }}" deploy: True power: present config_drive: "{{lookup('file', '/var/lib/ironic/confdrive/{{ baremetal_ironic_node_id.name }}.base64')}}" uuid: "{{baremetal_ironic_node_id.uuid}}" instance_info: root_gb: 10 image_source: "http://{{initiator_host_ip}}:{{golden_image_http_port}}/guest-image.img" image_checksum: "{{golden_img_md5sum.stat.md5}}" when: - installation_phase == "provisioning-started" - name: Start Baremetal deployment os_ironic_node: cloud: default endpoint_type: internal auth_type: password deploy: True power: present config_drive: "{{lookup('file', '/var/lib/ironic/confdrive/{{ baremetal_ironic_node_id.name }}.base64')}}" uuid: "{{baremetal_ironic_node_id.uuid}}" instance_info: root_gb: 10 image_source: "http://{{initiator_host_ip}}:{{golden_image_http_port}}/guest-image.img" image_checksum: "{{golden_img_md5sum.stat.md5}}" when: - installation_phase != "provisioning-started" - name: Verify node provisioning state. Waiting for 60mins max. environment: OS_AUTH_TOKEN: "fake-token" IRONIC_URL: "{{ ironic_service_adminurl }}" os_node_provision_check: auth: auth_type: 'None' ironic_url: "{{ ironic_service_adminurl }}" nodes_details: - "{{baremetal_ironic_node_id}}" register: baremetal_ironic_node_provisionin_results until: provision_pending_list | length == 0 retries: 360 delay: 10 when: - installation_phase == "provisioning-started" - name: Checking for any deployment failures fail: msg: "One or more nodes failed in deployment. {{baremetal_ironic_node_provisionin_results['ansible_facts']['provision_failed_list'] }}" when: - installation_phase == "provisioning-started" - baremetal_ironic_node_provisionin_results['ansible_facts']['provision_failed_list'] | length > 0 - name: Verify node provisioning state. Waiting for 60mins max. os_node_provision_check: cloud: default endpoint_type: internal auth_type: password nodes_details: - "{{baremetal_ironic_node_id}}" register: baremetal_ironic_node_provisionin_results until: provision_pending_list | length == 0 retries: 360 delay: 10 when: - installation_phase != "provisioning-started" - name: Checking for any deployment failures fail: msg: "One or more nodes failed in deployment. {{baremetal_ironic_node_provisionin_results['ansible_facts']['provision_failed_list'] }}" when: - installation_phase != "provisioning-started" - baremetal_ironic_node_provisionin_results['ansible_facts']['provision_failed_list'] | length > 0 - set_fact: net_conn_details: "{{ ironic_node_details.driver_info.power.os_net_config | json_query('network_config[*].addresses[0].ip_netmask') | ipaddr('address') }}" when: ironic_node_details.driver_info.power.os_net_config.network_config[0].type != 'ovs_bridge' no_log: True - set_fact: net_conn_details: "{{ ironic_node_details.driver_info.power.os_net_config | json_query('network_config[*].members[*].addresses[0].ip_netmask')|first | ipaddr('address') }}" when: ironic_node_details.driver_info.power.os_net_config.network_config[0].type == 'ovs_bridge' no_log: True # JanneS: until looping is a fix for the problem in wait_for module; it does not catch socket error in recv if peer closes the connection. - name: Verify remote node ssh ports active. Waiting for 60mins max. wait_for: host: "{{ net_conn_details[0] }}" port: 22 search_regex: OpenSSH sleep: 5 timeout: 3600 register: remote_success until: remote_success | success retries: 3 - name: Wait for remote node ssh login. Waiting for 10mins max. become: "{{ users.admin_user_name }}" local_action: shell ssh -oBatchMode=yes -4 -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null {{ net_conn_details[0] }} "echo success" register: user_enabled until: user_enabled.stdout.find("success") != -1 retries: 90 delay: 10