Speed up the install by parallelizing OpenStack and XOS setup

Change-Id: I51657c92400cf7dc5cddf5ade3e906d4cf28e29b
diff --git a/cord-head-playbook.yml b/cord-head-playbook.yml
index 84c30c3..52cca82 100644
--- a/cord-head-playbook.yml
+++ b/cord-head-playbook.yml
@@ -43,17 +43,26 @@
     - create-lxd
     - create-vms
 
-- name: Create docker images
+- name: Start OpenStack install
+  hosts: head
+  roles:
+    - juju-setup
+
+- name: XOS setup
   hosts: head
   roles:
     - xos-build
+    - xos-install
 
-- name: Set up VMs and juju
+- name: Finish OpenStack install
   hosts: head
   roles:
-    - xos-install
+    - juju-finish
+
+- name: Set up VMs
+  hosts: head
+  roles:
     - onos-vm-install
-    - juju-setup
 
 - name: Start ONOS and XOS
   hosts: head
diff --git a/roles/juju-setup/handlers/main.yml b/roles/juju-finish/handlers/main.yml
similarity index 100%
rename from roles/juju-setup/handlers/main.yml
rename to roles/juju-finish/handlers/main.yml
diff --git a/roles/juju-finish/tasks/main.yml b/roles/juju-finish/tasks/main.yml
new file mode 100644
index 0000000..be58be3
--- /dev/null
+++ b/roles/juju-finish/tasks/main.yml
@@ -0,0 +1,52 @@
+# run another time, so services will be in juju_services list
+- name: Obtain Juju Facts after service creation
+  juju_facts:
+  register: result
+  until: result | success
+  retries: 3
+  delay: 15
+
+# 1800s = 30m. Usually takes 10-12m on cloudlab for relations to come up
+# Only checks for first port in list
+- name: Wait for juju services to have open ports
+  wait_for:
+    host={{ item.name }}
+    port={{ item.forwarded_ports[0].int }}
+    timeout=1800
+  with_items: "{{ head_lxd_list | selectattr('forwarded_ports', 'defined') | list }}"
+
+# secondary wait, as waiting on ports isn't enough. Probably only need one of these...
+# 160*15s = 2400s = 40m max wait
+- name: Wait for juju services to start
+  command: juju status --format=summary
+  register: juju_summary
+  until: juju_summary.stdout.find("pending:") == -1
+  retries: 160
+  delay: 15
+  tags:
+   - skip_ansible_lint # checking/waiting on a system to be up
+
+- name: Create admin-openrc.sh credentials file
+  template:
+   src=admin-openrc.sh.j2
+   dest={{ ansible_user_dir }}/admin-openrc.sh
+
+- name: Copy nova-cloud-controller CA certificate to head
+  command: juju scp {{ juju_services['nova-cloud-controller']['units'].keys()[0] }}:/usr/local/share/ca-certificates/keystone_juju_ca_cert.crt {{ ansible_user_dir }}
+  register: result
+  until: result | success
+  retries: 40
+  delay: 15
+  tags:
+   - skip_ansible_lint # checking/waiting on file availibilty
+
+- name: Copy cert to system location
+  become: yes
+  copy:
+    src: "{{ ansible_user_dir }}/keystone_juju_ca_cert.crt"
+    dest: "/usr/local/share/ca-certificates/keystone_juju_ca_cert.crt"
+    remote_src: true
+  notify:
+    - update-ca-certificates
+    - Move cert to all service VMs
+    - update-ca-certificates in service VMs
diff --git a/roles/juju-setup/templates/admin-openrc.sh.j2 b/roles/juju-finish/templates/admin-openrc.sh.j2
similarity index 100%
rename from roles/juju-setup/templates/admin-openrc.sh.j2
rename to roles/juju-finish/templates/admin-openrc.sh.j2
diff --git a/roles/juju-setup/tasks/main.yml b/roles/juju-setup/tasks/main.yml
index b29cbdf..a1883dd 100644
--- a/roles/juju-setup/tasks/main.yml
+++ b/roles/juju-setup/tasks/main.yml
@@ -23,6 +23,10 @@
 # Code for this is in library/juju_facts.py
 - name: Obtain Juju Facts for creating machines
   juju_facts:
+  register: result
+  until: result | success
+  retries: 3
+  delay: 15
 
 - name: Pause to let Juju settle before adding machines
   pause:
@@ -41,6 +45,10 @@
 # run this again, so machines will be in the juju_machines list
 - name: Obtain Juju Facts after machine creation
   juju_facts:
+  register: result
+  until: result | success
+  retries: 3
+  delay: 15
 
 - name: Deploy services that are hosted in their own VM
   when: "{{ lxd_service_list | difference( juju_services.keys() ) | length }}"
@@ -61,52 +69,3 @@
     - relations
   tags:
    - skip_ansible_lint # benign to do this more than once, hard to check for
-
-# run another time, so services will be in juju_services list
-- name: Obtain Juju Facts after service creation
-  juju_facts:
-
-# 1800s = 30m. Usually takes 10-12m on cloudlab for relations to come up
-# Only checks for first port in list
-- name: Wait for juju services to have open ports
-  wait_for:
-    host={{ item.name }}
-    port={{ item.forwarded_ports[0].int }}
-    timeout=1800
-  with_items: "{{ head_lxd_list | selectattr('forwarded_ports', 'defined') | list }}"
-
-# secondary wait, as waiting on ports isn't enough. Probably only need one of these...
-# 160*15s = 2400s = 40m max wait
-- name: Wait for juju services to start
-  command: juju status --format=summary
-  register: juju_summary
-  until: juju_summary.stdout.find("pending:") == -1
-  retries: 160
-  delay: 15
-  tags:
-   - skip_ansible_lint # checking/waiting on a system to be up
-
-- name: Create admin-openrc.sh credentials file
-  template:
-   src=admin-openrc.sh.j2
-   dest={{ ansible_user_dir }}/admin-openrc.sh
-
-- name: Copy nova-cloud-controller CA certificate to head
-  command: juju scp {{ juju_services['nova-cloud-controller']['units'].keys()[0] }}:/usr/local/share/ca-certificates/keystone_juju_ca_cert.crt {{ ansible_user_dir }}
-  register: result
-  until: result | success
-  retries: 40
-  delay: 15
-  tags:
-   - skip_ansible_lint # checking/waiting on file availibilty
-
-- name: Copy cert to system location
-  become: yes
-  copy:
-    src: "{{ ansible_user_dir }}/keystone_juju_ca_cert.crt"
-    dest: "/usr/local/share/ca-certificates/keystone_juju_ca_cert.crt"
-    remote_src: true
-  notify:
-    - update-ca-certificates
-    - Move cert to all service VMs
-    - update-ca-certificates in service VMs