---
# TODO: Add support for choosing base image based on deployment_type and os
# wanted (os wanted needs support added in bin/cluster with sane defaults:
# fedora/centos for origin, rhel for enterprise)

# TODO: create a role to encapsulate some of this complexity, possibly also
# create a module to manage the storage tasks, network tasks, and possibly
# even handle the libvirt tasks to set metadata in the domain xml and be able
# to create/query data about vms without having to use xml the python libvirt
# bindings look like a good candidate for this

- name: Download Base Cloud image
  get_url:
    url: '{{ image_url }}'
    sha256sum: '{{ image_sha256 }}'
    dest: '{{ libvirt_storage_pool_path }}/{{ [image_name, image_compression] | difference([""]) | join(".") }}'
  when: ( lookup("oo_option", "skip_image_download") | default("no", True) | lower ) in ["false", "no"]
  register: downloaded_image

- name: Uncompress xz compressed base cloud image
  command: 'unxz -kf {{ libvirt_storage_pool_path }}/{{ [image_name, image_compression] | join(".") }}'
  args:
    creates: '{{ libvirt_storage_pool_path }}/{{ image_name }}'
  when: image_compression in ["xz"] and downloaded_image.changed

- name: Uncompress tgz compressed base cloud image
  command: 'tar zxvf {{ libvirt_storage_pool_path }}/{{ [image_name, image_compression] | join(".") }}'
  args:
    creates: '{{ libvirt_storage_pool_path }}/{{ image_name }}'
  when: image_compression in ["tgz"] and downloaded_image.changed

- name: Uncompress gzip compressed base cloud image
  command: 'gunzip {{ libvirt_storage_pool_path }}/{{ [image_name, image_compression] | join(".") }}'
  args:
    creates: '{{ libvirt_storage_pool_path }}/{{ image_name }}'
  when: image_compression in ["gz"] and downloaded_image.changed

- name: Create the cloud-init config drive path
  file:
    dest: '{{ libvirt_storage_pool_path }}/{{ item }}_configdrive/'
    state: directory
  with_items: '{{ instances }}'

- name: Create the cloud-init config drive files
  template:
    src: '{{ item[1] }}'
    dest: '{{ libvirt_storage_pool_path }}/{{ item[0] }}_configdrive/{{ item[1] }}'
  with_nested:
    - '{{ instances }}'
    - [ user-data, meta-data ]

- name: Create the cloud-init config drive
  command: 'genisoimage -output {{ libvirt_storage_pool_path }}/{{ item }}_cloud-init.iso -volid cidata -joliet -rock user-data meta-data'
  args:
    chdir: '{{ libvirt_storage_pool_path }}/{{ item }}_configdrive/'
    creates: '{{ libvirt_storage_pool_path }}/{{ item }}_cloud-init.iso'
  with_items: '{{ instances }}'

- name: Refresh the libvirt storage pool for openshift
  command: 'virsh -c {{ libvirt_uri }} pool-refresh {{ libvirt_storage_pool }}'

- name: Create VM drives
  command: 'virsh -c {{ libvirt_uri }} vol-create-as {{ libvirt_storage_pool }} {{ item }}.qcow2 10G --format qcow2 --backing-vol {{ image_name }} --backing-vol-format qcow2'
  with_items: '{{ instances }}'

- name: Create VM docker drives
  command: 'virsh -c {{ libvirt_uri }} vol-create-as {{ libvirt_storage_pool }} {{ item }}-docker.qcow2 10G --format qcow2 --allocation 0'
  with_items: '{{ instances }}'

- name: Create VMs
  virt:
    name: '{{ item }}'
    command: define
    xml: "{{ lookup('template', '../templates/domain.xml') }}"
    uri: '{{ libvirt_uri }}'
  with_items: '{{ instances }}'

- name: Start VMs
  virt:
    name: '{{ item }}'
    state: running
    uri: '{{ libvirt_uri }}'
  with_items: '{{ instances }}'

- name: Wait for the VMs to get an IP
  shell: 'virsh -c {{ libvirt_uri }} net-dhcp-leases {{ libvirt_network }} | egrep -c ''{{ instances | join("|") }}'''
  register: nb_allocated_ips
  until: nb_allocated_ips.stdout == '{{ instances | length }}'
  retries: 60
  delay: 3
  when: instances | length != 0

- name: Collect IP addresses of the VMs
  shell: 'virsh -c {{ libvirt_uri }} net-dhcp-leases {{ libvirt_network }} | awk ''$6 == "{{ item }}" {gsub(/\/.*/, "", $5); print $5}'''
  register: scratch_ip
  with_items: '{{ instances }}'

- set_fact:
    ips: "{{ scratch_ip.results | default([]) | oo_collect('stdout') }}"

- set_fact:
    node_label:
      type: "{{ g_sub_host_type }}"
  when: instances | length > 0 and type == "node"

- set_fact:
    node_label:
      type: "{{ type }}"
  when: instances | length > 0 and type != "node"

- name: Add new instances
  add_host:
    hostname: '{{ item.0 }}'
    ansible_ssh_host: '{{ item.1 }}'
    ansible_ssh_user: "{{ deployment_vars[deployment_type].ssh_user }}"
    ansible_become: "{{ deployment_vars[deployment_type].become }}"
    groups: "tag_environment-{{ cluster_env }}, tag_host-type-{{ type }}, tag_sub-host-type-{{ g_sub_host_type }}, tag_clusterid-{{ cluster_id }}"
    openshift_node_labels: "{{ node_label }}"
    libvirt_ip_address: "{{ item.1 }}"
  with_together:
    - '{{ instances }}'
    - '{{ ips }}'

- name: Wait for ssh
  wait_for:
    host: '{{ item }}'
    port: 22
  with_items: '{{ ips }}'

- name: Wait for openshift user setup
  command: 'ssh -o StrictHostKeyChecking=no -o PasswordAuthentication=no -o ConnectTimeout=10 -o UserKnownHostsFile=/dev/null openshift@{{ item.1 }} echo openshift user is setup'
  register: result
  until: result.rc == 0
  retries: 30
  delay: 1
  with_together:
    - '{{ instances }}'
    - '{{ ips }}'
