Merge remote-tracking branch 'origin/master' into roles
diff --git a/scripts/compute-ext-net-tutorial.sh b/scripts/compute-ext-net-tutorial.sh
new file mode 100755
index 0000000..50090a9
--- /dev/null
+++ b/scripts/compute-ext-net-tutorial.sh
@@ -0,0 +1,17 @@
+#!/bin/sh
+
+apt-get update
+apt-get install bridge-utils
+brctl addbr databr
+ifconfig databr 10.168.0.1/24 up
+ip link add address 02:42:0a:a8:00:01 type veth
+ifconfig veth0 up
+ifconfig veth1 up
+brctl addif databr veth0
+ip addr add 10.168.1.1/24 dev databr
+iptables -t nat -A POSTROUTING -s 10.168.0.0/16 \! -d 10.168.0.0/16 -j MASQUERADE
+sysctl -w net.ipv4.ip_forward=1
+sysctl -w net.ipv4.conf.all.send_redirects=0
+sysctl -w net.ipv4.conf.default.send_redirects=0
+sysctl -w net.ipv4.conf.eth0.send_redirects=0
+sysctl -w net.ipv4.conf.databr.send_redirects=0
\ No newline at end of file
diff --git a/scripts/single-node-pod.sh b/scripts/single-node-pod.sh
new file mode 100755
index 0000000..0cbd3a4
--- /dev/null
+++ b/scripts/single-node-pod.sh
@@ -0,0 +1,23 @@
+#!/bin/bash
+
+cd ~
+git clone https://github.com/open-cloud/openstack-cluster-setup.git
+cd ~/openstack-cluster-setup
+./bootstrap.sh
+ansible-playbook -i cord-test-hosts cord-setup.yml
+
+ssh ubuntu@onos-cord "cd cord; sudo docker-compose up -d"
+ssh ubuntu@xos "cd xos/xos/configurations/cord-pod; sudo docker-compose pull"
+
+# Need to wait for OpenStack services to come up before running any XOS "make" commands
+echo "Waiting for the OpenStack services to fully come up."
+echo "This can take 30 minutes or more, be patient!"
+i=0
+until juju status --format=summary|grep "started:  23" > /dev/null
+do
+    sleep 60
+    (( i += 1 ))
+    echo "Waited $i minutes"
+done
+
+echo "All OpenStack services are up."
\ No newline at end of file
diff --git a/unc-compute.yml b/unc-compute.yml
new file mode 100644
index 0000000..c342483
--- /dev/null
+++ b/unc-compute.yml
@@ -0,0 +1,72 @@
+---
+- hosts: head
+  sudo: no
+  user: ubuntu
+  tasks:
+  - name: Remind user what is going to happen
+    pause: prompt="Install nova-compute on all unused machines managed by Juju"
+
+  - name: Deploy nova-compute
+    script: scripts/juju-compute-setup.py
+
+  - name: Try to avoid race condition
+    pause: seconds=5
+
+  - name: Wait until nova-compute is deployed
+    script: scripts/wait-for-services.sh
+
+  - name: Make sure we're using KVM
+    shell: juju set nova-compute virt-type=kvm
+
+  - name: Add nova-compute relations
+    script: scripts/juju-compute-relations.py
+
+  - name: Try to avoid race condition
+    pause: seconds=5
+
+  - name: Wait until relations are added
+    script: scripts/wait-for-services.sh
+
+# Play: set up ansible-pull for OpenCloud-specific files on nova-compute nodes
+- hosts: compute
+  sudo: yes
+  user: ubuntu
+  vars:
+
+    # schedule is fed directly to cron
+    schedule: '*/15 * * * *'
+
+    # User to run ansible-pull as from cron
+    cron_user: root
+
+    # File that ansible will use for logs
+    logfile: /var/log/ansible-pull.log
+
+    # Directory to where repository will be cloned
+    workdir: /var/lib/ansible/local
+
+    # Repository to check out
+    # repo must contain a local.yml file at top level
+    #repo_url: git://github.com/sfromm/ansible-playbooks.git
+    repo_url: git://github.com/andybavier/opencloud-nova-compute-ansible.git
+
+    # Branch or tag to checkout
+    repo_version: kilo
+
+  tasks:
+
+  - name: Install ansible
+    apt: name=ansible state=installed
+
+  - name: Basic ansible inventory
+    template: src=templates/etc/ansible/hosts.j2
+      dest=/etc/ansible/hosts
+
+  - name: Create local directory to work from
+    file: path={{workdir}} state=directory owner=root group=root mode=0751
+
+  - name: Create crontab entry to clone/pull git repository
+    template: src=templates/etc/cron.d/ansible-pull.j2 dest=/etc/cron.d/ansible-pull owner=root group=root mode=0644
+
+  - name: Create logrotate entry for ansible-pull.log
+    template: src=templates/etc/logrotate.d/ansible-pull.j2 dest=/etc/logrotate.d/ansible-pull owner=root group=root mode=0644
diff --git a/unc-hosts b/unc-hosts
new file mode 100644
index 0000000..8d3ab66
--- /dev/null
+++ b/unc-hosts
@@ -0,0 +1,11 @@
+head    ansible_ssh_host=rc-tsdn-01.its.unc.edu
+
+[compute]
+rc-tsdn-02.its.unc.edu
+rc-tsdn-03.its.unc.edu
+rc-tsdn-04.its.unc.edu
+rc-tsdn-05.its.unc.edu
+rc-tsdn-06.its.unc.edu
+
+[all:vars]
+cloudlab=false
diff --git a/unc-setup.yml b/unc-setup.yml
new file mode 100644
index 0000000..463a6e5
--- /dev/null
+++ b/unc-setup.yml
@@ -0,0 +1,280 @@
+---
+# Play: set up head node
+# Assumes basic /etc/ansible/hosts file
+- hosts: head
+  user: ubuntu
+  sudo: yes
+  vars:
+    # Each OpenCloud cluster needs a unique mgmt_net_prefix
+    mgmt_net_prefix: 192.168.105
+  tasks:
+
+  - apt: name={{ item }} update_cache=yes
+    with_items:
+    - python-pycurl
+    - software-properties-common
+
+  - name: Add Juju repository
+    apt_repository: repo="ppa:juju/stable"
+
+  - name: Add Ansible repository
+    apt_repository: repo="ppa:ansible/ansible"
+
+  - name: Update Ansible cache
+    apt: update_cache=yes
+
+  - name: Install packages
+    apt: name={{ item }} state=latest
+    with_items:
+    - ansible
+    - uvtool
+    - git
+    - bzr
+    - juju-core
+    - python-novaclient
+    - python-neutronclient
+    - python-keystoneclient
+    - python-glanceclient
+
+  - name: Get juju-ansible git repo
+    git: repo=https://github.com/cmars/juju-ansible.git
+      dest=/usr/local/src/juju-ansible
+
+  - name: Set up juju-ansible symlink
+    file: dest=/usr/local/bin/juju-ansible
+      src=/usr/local/src/juju-ansible/juju-ansible
+      state=link
+
+  - name: Set up juju-ansible-playbook symlink
+    file: dest=/usr/local/bin/juju-ansible-playbook
+      src=/usr/local/src/juju-ansible/juju-ansible
+      state=link
+
+  - name: Generate key to use in VMs
+    user: name={{ ansible_env['SUDO_USER'] }} generate_ssh_key=yes
+
+  - name: (CloudLab) Set up extra disk space
+    shell: /usr/testbed/bin/mkextrafs /var/lib/uvtool/libvirt/images
+      creates=/var/lib/uvtool/libvirt/images/lost+found
+    when: cloudlab
+
+  - name: Add myself to libvirtd group
+    user: name={{ ansible_env['SUDO_USER'] }}
+      groups=libvirtd
+      append=yes
+
+  - name: Get trusty image for uvtool
+    shell: uvt-simplestreams-libvirt sync --source http://cloud-images.ubuntu.com/daily release=trusty arch=amd64
+
+  - name: Change the virbr0 subnet to {{ mgmt_net_prefix }}.0/24
+    template: src=templates/etc/libvirt/qemu/networks/default.xml.j2
+      dest=/etc/libvirt/qemu/networks/default.xml
+    notify:
+    - recreate default net
+
+  handlers:
+  - name: recreate default net
+    script: scripts/recreate-virbr0.sh
+
+# Play: create VMs to host OpenStack services
+- hosts: head
+  user: ubuntu
+  sudo: yes
+  tasks:
+  - name: Create VMs to host OpenCloud services
+    sudo: no
+    script: scripts/create-vms.sh
+
+  - include: tasks/vm-ips.yml
+
+  - name: Add VMs to /etc/hosts
+    template: src=templates/etc/hosts.j2
+      dest=/etc/hosts
+    notify:
+    - Reload dnsmasq
+
+  - name: Set up /etc/ansible/hosts
+    template: src=templates/etc/ansible/hosts.j2
+      dest=/etc/ansible/hosts
+
+  - name: Copy ansible.cfg to disable host key checking
+    sudo: no
+    copy: src=files/ansible.cfg
+      dest={{ ansible_env['PWD'] }}/.ansible.cfg
+
+  - name: Touch ~/.ssh/config
+    sudo: no
+    file: path={{ ansible_env['PWD'] }}/.ssh/config state=touch
+
+  - name: Disable host key checking in SSH
+    sudo: no
+    lineinfile: dest={{ ansible_env['PWD'] }}/.ssh/config
+      line="StrictHostKeyChecking no"
+
+  - name: Test that we can log into every VM
+    sudo: no
+    shell: ansible services -m ping -u ubuntu
+
+  handlers:
+  - name: Reload dnsmasq
+    shell: killall -HUP dnsmasq
+
+# Play: Install services using Juju
+- hosts: head
+  user: ubuntu
+  vars:
+    charm_src: /usr/local/src/charms/trusty
+  tasks:
+  - name: Initialize Juju
+    sudo: no
+    shell: juju generate-config
+      creates={{ ansible_env['PWD'] }}/.juju/environments.yaml
+
+  - shell: uvt-kvm ip juju
+    register: juju_ip
+
+  - name: Juju config file
+    sudo: no
+    template: src=templates/environments.yaml.j2
+      dest={{ ansible_env['PWD'] }}/.juju/environments.yaml
+
+  - name: Bootstrap Juju
+    sudo: no
+    shell: juju bootstrap
+      creates={{ ansible_env['PWD'] }}/.juju/environments/manual.jenv
+
+  - name: Copy openstack.cfg for Juju
+    sudo: yes
+    copy: src=files/openstack.cfg
+      dest=/usr/local/src/openstack.cfg
+
+  - name: Check for /usr/local/src/charms/trusty
+    sudo: yes
+    file: path={{ charm_src }}
+       state=directory
+       mode=0755
+
+  - name: Deploy OpenStack services with Juju
+    script: scripts/juju-setup.py
+
+  - name: Add all Juju relations between services
+    script: scripts/juju-relations.py
+
+  - name: Wait for relations to be fully added
+    script: scripts/wait-for-services.sh
+
+# Play: Use libvirt hooks to set up iptables
+- hosts: head
+  user: ubuntu
+  sudo: yes
+  tasks:
+  - name: Enable port forwarding for services
+    copy: src=files/{{ item }}
+      dest={{ item }}
+      mode=0755
+    notify:
+    - reload libvirt config
+    - run qemu hook
+    with_items:
+    - /etc/libvirt/hooks/daemon
+    - /etc/libvirt/hooks/qemu
+
+  handlers:
+  - name: reload libvirt config
+    shell: killall -HUP libvirtd
+
+  - name: run qemu hook
+    shell: /etc/libvirt/hooks/qemu start start
+
+# Play: Create credentials, set up some basic OpenStack
+- hosts: head
+  user: ubuntu
+  sudo: no
+  tasks:
+
+  - name: Get keystone admin password
+    shell: juju run --unit=keystone/0 "sudo cat /var/lib/keystone/keystone.passwd"
+    register: keystone_password
+
+  - shell: uvt-kvm ip keystone
+    register: keystone_ip
+
+  - name: Create credentials
+    template: src=templates/admin-openrc.sh.j2
+     dest={{ ansible_env['PWD'] }}/admin-openrc.sh
+
+  - name: (CloudLab) Make sure that /root/setup exists
+    file: path=/root/setup state=directory
+    sudo: yes
+    when: cloudlab
+
+  - name: (CloudLab) Copy credentials to /root/setup
+    shell: scp admin-openrc.sh /root/setup
+    sudo: yes
+    when: cloudlab
+
+  - name: Copy credentials to nova-cloud-controller
+    shell: "scp admin-openrc.sh ubuntu@nova-cloud-controller:"
+
+  - name: Copy network setup script
+    sudo: yes
+    copy: src=scripts/network-setup.sh
+      dest=/usr/local/src/network-setup.sh
+      mode=0755
+
+  - name: Run network setup script
+    shell: ansible nova-cloud-controller -m script -u ubuntu -a "/usr/local/src/network-setup.sh"
+
+  - name: Get public key
+    shell: cat {{ ansible_env['PWD'] }}/.ssh/id_rsa.pub
+    register: sshkey
+
+  - name: Copy CA certificate
+    shell: sudo juju scp nova-cloud-controller/0:/usr/local/share/ca-certificates/keystone_juju_ca_cert.crt /usr/local/share/ca-certificates
+      creates=/usr/local/share/ca-certificates/keystone_juju_ca_cert.crt
+
+  - name: Update CA ca-certificates
+    shell: update-ca-certificates
+    sudo: yes
+
+- hosts: compute
+  user: ubuntu
+  sudo: yes
+  vars:
+    control_net: "{{ hostvars['head']['ansible_virbr0']['ipv4']['network'] }}/24"
+    gateway: "{{ hostvars['head']['ansible_default_ipv4']['address'] }}"
+  tasks:
+  - name: Install package needed by Juju
+    apt: name=python-yaml state=present
+
+  - name: Add key
+    authorized_key: user="{{ ansible_env['SUDO_USER'] }}"
+      key="{{ hostvars['head']['sshkey']['stdout'] }}"
+
+  - name: Add route via /etc/rc.local
+    template: src=templates/etc/rc.local.cloudlab
+      dest=/etc/rc.local
+      mode=0755
+    when: cloudlab
+    notify:
+    - run /etc/rc.local
+
+  - name: Add route via /etc/rc.local
+    template: src=templates/etc/rc.local
+      dest=/etc/rc.local
+      mode=0755
+    when: not cloudlab
+    notify:
+    - run /etc/rc.local
+
+  - name: Touch ~/.ssh/config
+    file: path=/var/lib/nova state=directory
+
+  - name: (CloudLab) Set up extra disk space
+    shell: /usr/testbed/bin/mkextrafs /var/lib/nova
+      creates=/var/lib/nova/lost+found
+    when: cloudlab
+
+  handlers:
+  - name: run /etc/rc.local
+    shell: /etc/rc.local