Merge branch 'master' into roles
diff --git a/aztest.yml b/aztest.yml
new file mode 100644
index 0000000..d115075
--- /dev/null
+++ b/aztest.yml
@@ -0,0 +1,16 @@
+---
+# aztest playbook, for installing OpenCloud
+
+- hosts: head
+ roles:
+ - { role: common-prep, become: yes }
+ - { role: head-prep, become: yes }
+ - juju-user-prep
+ - juju-setup
+
+- hosts: compute
+ become: yes
+ roles:
+ - { role: common-prep, become: yes }
+ - { role: compute-prep, become: yes }
+
diff --git a/docs/install_opencloud_site.md b/docs/install_opencloud_site.md
index 26c50f1..daaa23b 100644
--- a/docs/install_opencloud_site.md
+++ b/docs/install_opencloud_site.md
@@ -1,16 +1,16 @@
-**Introduction**
+## Introduction
-The following steps areis required in order to bring up a new opencloud sites.
+The following steps are required in order to bring up a new OpenCloud sites.
1. Allocate servers
-2. (Re)IInstall Uubuntu
+2. Install Uubuntu
-3. Install openstack controller & compute nodes
+3. Install OpenStack controller & compute nodes
-4. Add site’s openstack controller to xos
+4. Add site’s OpenStack controller to xos
-**Allocate Servers**
+## Allocate Servers
**It may happen that for different reasons that few servers are offline. **Allocating servers involves finding those nodes that are offline and bringing them back online. In most cases just rebooting the nodes will bring them back online. Sometimes they may be offline for hardware malfunctions or maintenance. In that case someone would need to provide help, locally from the facility.
@@ -18,7 +18,7 @@
Note: For example, for the Stanford cluster, the script should be located I’ve installed the ipmi-cmd.sh on node4.stanford.vicci.org. You should be able to reboot nodes from there.
-**Install Ubuntu**
+## Install Ubuntu
Opencloud nodes are expected to be Ubuntu 14.x.
@@ -42,6 +42,14 @@
After reboot, the machine should go through the Ubuntu installation automatically. At the end of the process, the ones registered as administrators should be notified of the successfully installation. If you’re not an official opencloud.us administrator, just try to log into the machines again after 20-30 mins form the reboot.
+3. Update Ubuntu
+
+```
+sudo apt-get update
+sudo apt-get dist-upgrade
+```
+
+
**Install Openstack**
Ansible is a software that enables easy centralized configuration and management of a set of machines.
diff --git a/group_vars/aztest b/group_vars/aztest
new file mode 100644
index 0000000..33268ca
--- /dev/null
+++ b/group_vars/aztest
@@ -0,0 +1,6 @@
+---
+# file: group_vars/aztest
+
+mgmt_net_prefix: 192.168.250
+
+cloudlab: false
diff --git a/inventory/aztest b/inventory/aztest
new file mode 100644
index 0000000..1de8b89
--- /dev/null
+++ b/inventory/aztest
@@ -0,0 +1,5 @@
+[head]
+node11.opencloud.cs.arizona.edu ansible_ssh_user=ubuntu
+
+[compute]
+node12.opencloud.cs.arizona.edu ansible_ssh_user=ubuntu
diff --git a/library/juju_facts.py b/library/juju_facts.py
new file mode 100644
index 0000000..70850e0
--- /dev/null
+++ b/library/juju_facts.py
@@ -0,0 +1,27 @@
+#!/usr/bin/python
+
+import json
+import subprocess
+
+def dict_keys_dash_to_underscore(dashed):
+ underscored = dict((k.replace('-','_'),v) for k,v in dashed.items())
+ return underscored
+
+juju_status_json = subprocess.check_output("juju status --format=json", shell=True)
+juju_status = json.loads(juju_status_json)
+
+juju_machines = {}
+for index, data in juju_status['machines'].iteritems():
+ data_underscore = dict_keys_dash_to_underscore(data)
+ juju_machines[data_underscore["dns_name"]] = data_underscore
+ juju_machines[data_underscore["dns_name"]]["machine_id"] = index
+
+print json.dumps({
+ "changed": True,
+ "ansible_facts" : {
+ "juju_enviromnment": juju_status['environment'],
+ "juju_machines": juju_machines,
+ "juju_services": juju_status['services'],
+ },
+})
+
diff --git a/roles/cloudlab-prep/tasks/main.yml b/roles/cloudlab-prep/tasks/main.yml
new file mode 100644
index 0000000..e23168b
--- /dev/null
+++ b/roles/cloudlab-prep/tasks/main.yml
@@ -0,0 +1,7 @@
+---
+# roles/cloudlab-prep/tasks/main.yml
+
+- name: Set up extra disk space
+ command: /usr/testbed/bin/mkextrafs -f /var/lib/uvtool/libvirt/images
+ creates=/var/lib/uvtool/libvirt/images/lost+found
+
diff --git a/roles/common-prep/tasks/main.yml b/roles/common-prep/tasks/main.yml
new file mode 100644
index 0000000..0e5474d
--- /dev/null
+++ b/roles/common-prep/tasks/main.yml
@@ -0,0 +1,16 @@
+---
+# file: roles/common-prep/tasks/main.yml
+
+- name: Upgrade system to current using apt
+ apt: update_cache=yes upgrade=dist
+
+- name: Install standard packages
+ apt: pkg={{ item }} state=present
+ with_items:
+ - tmux
+ - vim
+
+- name: Enable vim syntax highlighting
+ lineinfile: dest=/etc/vim/vimrc
+ regexp="^\s*syntax on"
+ line="syntax on"
diff --git a/roles/compute-prep/tasks/main.yml b/roles/compute-prep/tasks/main.yml
new file mode 100644
index 0000000..aedd62a
--- /dev/null
+++ b/roles/compute-prep/tasks/main.yml
@@ -0,0 +1,8 @@
+---
+# file: roles/compute-prep/tasks/main.yml
+
+- name: Install packages
+ apt: name={{ item }} state=latest update_cache=yes
+ with_items:
+ - python-yaml
+
diff --git a/roles/head-prep/tasks/main.yml b/roles/head-prep/tasks/main.yml
new file mode 100644
index 0000000..7755eba
--- /dev/null
+++ b/roles/head-prep/tasks/main.yml
@@ -0,0 +1,76 @@
+---
+# file: roles/head-prep/tasks/main.yml
+
+- name: Install prerequisites for using PPA repos
+ apt:
+ name={{ item }}
+ with_items:
+ - python-pycurl
+ - software-properties-common
+
+- name: Add Ansible/Juju repositories
+ apt_repository:
+ repo={{ item }}
+ with_items:
+ - "ppa:juju/stable"
+ - "ppa:ansible/ansible"
+
+- name: Install packages
+ apt:
+ name={{ item }}
+ state=latest
+ update_cache=yes
+ with_items:
+ - ansible
+ - uvtool
+ - git
+ - bzr
+ - juju-core
+ - python-novaclient
+ - python-neutronclient
+ - python-keystoneclient
+ - python-glanceclient
+
+- name: Obtain the juju-ansible tool from github
+ git:
+ repo=https://github.com/cmars/juju-ansible.git
+ dest=/usr/local/src/juju-ansible
+ version="HEAD"
+
+- name: Create symlinks to the juju-ansible tool
+ file:
+ src=/usr/local/src/juju-ansible/juju-ansible
+ dest={{ item }}
+ state=link
+ with_items:
+ - "/usr/local/bin/juju-ansible"
+ - "/usr/local/bin/juju-ansible-playbook"
+
+- name: Prepare user account and generate SSH key
+ user:
+ name={{ ansible_user_id }}
+ generate_ssh_key=yes
+ groups="libvirtd" append=yes
+
+- name: Get public key
+ shell: cat {{ ansible_user_dir }}/.ssh/id_rsa.pub
+ register: sshkey
+
+- name: Add key to this user account
+ authorized_key:
+ user={{ ansible_user_id }}
+ key="{{ sshkey.stdout }}"
+
+- name: Copy keypair to /tmp
+ shell: cp -f {{ ansible_user_dir }}/.ssh/{{ item }} /tmp; chmod +r /tmp/{{ item }}
+ with_items:
+ - id_rsa
+ - id_rsa.pub
+
+- name: Get ubuntu image for uvtool
+ shell: uvt-simplestreams-libvirt sync --source http://cloud-images.ubuntu.com/daily release={{ ansible_distribution_release }} arch=amd64
+
+
+
+
+
diff --git a/roles/juju-setup/defaults/main.yml b/roles/juju-setup/defaults/main.yml
new file mode 100644
index 0000000..d4f77a1
--- /dev/null
+++ b/roles/juju-setup/defaults/main.yml
@@ -0,0 +1,67 @@
+---
+# roles/juju-setup/defaults/main.yml
+
+openstack_version: kilo
+openstack_cfg_path: /usr/local/src/openstack.cfg
+
+head_vm_list:
+ - { name: "juju", cpu: "1", memMB: "2048", diskGB: "20" }
+ - { name: "ceilometer", cpu: "1", memMB: "2048", diskGB: "20" }
+ - { name: "glance", cpu: "2", memMB: "4096", diskGB: "160" }
+ - { name: "keystone", cpu: "2", memMB: "4096", diskGB: "40" }
+ - { name: "mysql", cpu: "2", memMB: "4096", diskGB: "40" }
+ - { name: "nagios", cpu: "1", memMB: "2048", diskGB: "20" }
+ - { name: "neutron-api", cpu: "2", memMB: "4096", diskGB: "40" }
+ - { name: "neutron-gateway", cpu: "2", memMB: "4096", diskGB: "40" }
+ - { name: "nova-cloud-controller", cpu: "2", memMB: "4096", diskGB: "40" }
+ - { name: "openstack-dashboard", cpu: "1", memMB: "2048", diskGB: "20" }
+ - { name: "rabbitmq-server", cpu: "2", memMB: "4096", diskGB: "40" }
+
+vm_service_list:
+ - ceilometer
+ - glance
+ - keystone
+ - mysql
+ - nagios
+ - neutron-api
+ - neutron-gateway
+ - nova-cloud-controller
+ - openstack-dashboard
+ - rabbitmq-server
+
+standalone_service_list:
+ - ntp
+ - nrpe
+ - ceilometer-agent
+ - neutron-openvswitch
+
+service_relations:
+ - name: keystone
+ relations: [ "mysql", "nrpe", ]
+ - name: nova-cloud-controller
+ relations: [ "mysql", "rabbitmq-server", "glance", "keystone", "nrpe", ]
+ - name: glance
+ relations: [ "mysql", "keystone", "nrpe", ]
+ - name: neutron-gateway
+ relations: [ "neutron-api", "nova-cloud-controller", "mysql", "nrpe", ]
+ - name: "neutron-gateway:amqp"
+ relations: [ "rabbitmq-server:amqp", ]
+ - name: neutron-api
+ relations: [ "keystone", "neutron-openvswitch", "mysql", "rabbitmq-server", "nova-cloud-controller", "nrpe", ]
+ - name: neutron-openvswitch
+ relations: [ "rabbitmq-server", ]
+ - name: openstack-dashboard
+ relations: [ "keystone", "nrpe", ]
+ - name: nagios
+ relations: [ "nrpe", ]
+ - name: "mysql:juju-info"
+ relations: [ "nrpe:general-info", ]
+ - name: rabbitmq-server
+ relations: [ "nrpe", ]
+ - name: ceilometer
+ relations: [ "mongodb", "rabbitmq-server", "nagios", "nrpe", ]
+ - name: "ceilometer:identity-service"
+ relations: [ "keystone:identity-service", ]
+ - name: "ceilometer:ceilometer-service"
+ relations: [ "ceilometer-agent:ceilometer-service", ]
+
diff --git a/roles/juju-setup/tasks/main.yml b/roles/juju-setup/tasks/main.yml
new file mode 100644
index 0000000..7935fe3
--- /dev/null
+++ b/roles/juju-setup/tasks/main.yml
@@ -0,0 +1,84 @@
+---
+# roles/juju-setup/main/tasks.yml
+
+- name: create Virtual Machines with uvt-kvm
+ shell: uvt-kvm create {{ item.name }} --cpu={{ item.cpu }} --memory={{ item.memMB }} --disk={{ item.diskGB }}; \
+ uvt-kvm wait --insecure {{ item.name }}
+ creates=/var/lib/uvtool/libvirt/images/{{ item.name }}.qcow
+ with_items: "{{ head_vm_list }}"
+
+- name: discover VM IP addresses
+ shell: "uvt-kvm ip {{ item.name }}"
+ with_items: "{{ head_vm_list }}"
+ register: vm_ip
+
+- name: Create /etc/hosts with VM IP addresses
+ become: yes
+ template:
+ src=hosts.j2
+ dest=/etc/hosts
+
+- name: Create /etc/ansible/hosts file
+ become: yes
+ template:
+ src=ansible_hosts.j2
+ dest=/etc/ansible/hosts
+
+- name: Verify that we can log into every VM
+ command: ansible services -m ping -u ubuntu
+
+- name: Initialize Juju
+ command: juju generate-config
+ creates={{ ansible_user_dir }}/.juju/environments.yaml
+
+- name: Create Juju config file from template
+ template:
+ src=environments.yaml.j2
+ dest={{ ansible_user_dir }}/.juju/environments.yaml
+
+- name: Bootstrap Juju
+ command: juju bootstrap
+ creates={{ ansible_user_dir }}/.juju/environments/manual.jenv
+
+- name: Create openstack.cfg for Juju from template
+ become: yes
+ template:
+ src=openstack.cfg.j2
+ dest={{ openstack_cfg_path }}
+
+# Code for this is in library/juju_facts.py
+- name: Obtain Juju Facts
+ juju_facts:
+
+# For setwise operations on desired vs Juju state:
+# list of VM names in head_vm_list dict: head_vm_list | map(attribute='name') | list
+# list of active juju_machines names: juju_machines.keys()
+# list of active juju_services names: juju_services.keys()
+
+- name: Add machines to Juju
+ command: "juju add-machine ssh:{{ item }}"
+ with_items: "{{ head_vm_list | map(attribute='name') | list | difference( juju_machines.keys() ) }}"
+
+- name: Deploy services that are hosted in their own VM
+ command: "juju deploy {{ item }} --to {{ juju_machines[item]['machine_id'] }} --config={{ openstack_cfg_path }}"
+ with_items: "{{ vm_service_list | difference( juju_services.keys() ) }}"
+
+- name: Deploy mongodb to ceilometer VM
+ command: "juju deploy mongodb --to {{ juju_machines['ceilometer']['machine_id'] }} --config={{ openstack_cfg_path }}"
+ when: juju_services['mongodb'] is undefined
+
+- name: Deploy services that don't have their own VM
+ command: "juju deploy {{ item }} --config={{ openstack_cfg_path }}"
+ with_items: "{{ standalone_service_list | difference( juju_services.keys() ) }}"
+
+# FIXME: ignoring errors when creating relationships.
+# Previous method wasn't idempotent either
+
+- name: Create relations between services
+ command: "juju add-relation '{{ item.0.name }}' '{{ item.1 }}'"
+ ignore_errors: True
+ with_subelements:
+ - "{{ service_relations }}"
+ - relations
+
+# Need to wait for services to come up here
diff --git a/roles/juju-setup/templates/ansible_hosts.j2 b/roles/juju-setup/templates/ansible_hosts.j2
new file mode 100644
index 0000000..9b6096e
--- /dev/null
+++ b/roles/juju-setup/templates/ansible_hosts.j2
@@ -0,0 +1,8 @@
+[localhost]
+127.0.0.1 hostname={{ ansible_fqdn }}
+
+[services]
+{% for vm in head_vm_list -%}
+{{ vm.name }}
+{% endfor -%}
+
diff --git a/roles/juju-setup/templates/environments.yaml.j2 b/roles/juju-setup/templates/environments.yaml.j2
new file mode 100644
index 0000000..e575b23
--- /dev/null
+++ b/roles/juju-setup/templates/environments.yaml.j2
@@ -0,0 +1,7 @@
+default: manual
+environments:
+ manual:
+ type: manual
+ bootstrap-host: juju
+ bootstrap-user: ubuntu
+ default-series: {{ ansible_distribution_release }}
diff --git a/roles/juju-setup/templates/hosts.j2 b/roles/juju-setup/templates/hosts.j2
new file mode 100644
index 0000000..ebc3706
--- /dev/null
+++ b/roles/juju-setup/templates/hosts.j2
@@ -0,0 +1,10 @@
+127.0.0.1 localhost
+127.0.1.1 ubuntu
+{% for host in vm_ip.results -%}
+{{ host.stdout }} {{ host.item.name }}
+{% endfor -%}
+
+# The following lines are desirable for IPv6 capable hosts
+::1 localhost ip6-localhost ip6-loopback
+ff02::1 ip6-allnodes
+ff02::2 ip6-allrouters
diff --git a/roles/juju-setup/templates/openstack.cfg.j2 b/roles/juju-setup/templates/openstack.cfg.j2
new file mode 100644
index 0000000..063d239
--- /dev/null
+++ b/roles/juju-setup/templates/openstack.cfg.j2
@@ -0,0 +1,39 @@
+ceilometer:
+ceilometer-agent:
+glance:
+ openstack-origin: "cloud:trusty-kilo"
+keystone:
+ admin-password: ""
+ https-service-endpoints: "True"
+ openstack-origin: "cloud:trusty-kilo"
+ use-https: "yes"
+mysql:
+mongodb:
+nagios:
+neutron-api:
+ flat-network-providers: "*"
+ openstack-origin: "cloud:trusty-kilo"
+ vlan-ranges: "physnet1:1000:2000 nat"
+neutron-gateway:
+ bridge-mappings: "physnet1:br-data nat:br-nat"
+ flat-network-providers: "*"
+ instance-mtu: "1400"
+ openstack-origin: "cloud:trusty-kilo"
+ vlan-ranges: "physnet1:1000:2000 nat"
+neutron-openvswitch:
+ bridge-mappings: "physnet1:br-data nat:br-nat"
+ disable-security-groups: "True"
+ flat-network-providers: "*"
+ vlan-ranges: "physnet1:1000:2000 nat"
+nova-cloud-controller:
+ console-access-protocol: "novnc"
+ network-manager: "Neutron"
+ openstack-origin: "cloud:trusty-kilo"
+ntp:
+ source: "0.ubuntu.pool.ntp.org 1.ubuntu.pool.ntp.org 2.ubuntu.pool.ntp.org 3.ubuntu.pool.ntp.org"
+nrpe:
+openstack-dashboard:
+ openstack-origin: "cloud:trusty-kilo"
+rabbitmq-server:
+ ssl: "on"
+
diff --git a/roles/juju-user-prep/files/ansible.cfg b/roles/juju-user-prep/files/ansible.cfg
new file mode 100644
index 0000000..dd43d2b
--- /dev/null
+++ b/roles/juju-user-prep/files/ansible.cfg
@@ -0,0 +1,2 @@
+[defaults]
+host_key_checking = false
diff --git a/roles/juju-user-prep/tasks/main.yml b/roles/juju-user-prep/tasks/main.yml
new file mode 100644
index 0000000..6f675fd
--- /dev/null
+++ b/roles/juju-user-prep/tasks/main.yml
@@ -0,0 +1,15 @@
+---
+# roles/juju-user-prep/main/tasks.yml
+
+- name: Disable host key checking in ~/.ssh/config
+ lineinfile:
+ dest={{ ansible_user_dir }}/.ssh/config
+ line="StrictHostKeyChecking no"
+ create=yes
+ mode=0600
+
+- name: Disable host key checking in ~/.ansible.cfg
+ copy:
+ src=ansible.cfg
+ dest={{ ansible_user_dir }}/.ansible.cfg
+
diff --git a/roles/test-prep/tasks/main.yml b/roles/test-prep/tasks/main.yml
new file mode 100644
index 0000000..1ebf604
--- /dev/null
+++ b/roles/test-prep/tasks/main.yml
@@ -0,0 +1,9 @@
+---
+# roles/test-prep/tasks/main.yml
+
+- name: Add local resolver to /etc/resolv.conf
+ lineinfile:
+ dest=/etc/resolv.conf
+ insertafter=".*DO NOT EDIT THIS FILE.*"
+ line="nameserver 192.168.122.1"
+
diff --git a/roles/xos-install/defaults/main.yml b/roles/xos-install/defaults/main.yml
new file mode 100644
index 0000000..ba26bf6
--- /dev/null
+++ b/roles/xos-install/defaults/main.yml
@@ -0,0 +1,6 @@
+---
+# default variables for xos-install role
+
+xos_repo_url: "https://github.com/open-cloud/xos.git"
+xos_repo_dest: "~/xos"
+xos_repo_branch: "HEAD"
diff --git a/roles/xos-install/tasks/main.yml b/roles/xos-install/tasks/main.yml
new file mode 100644
index 0000000..d982c26
--- /dev/null
+++ b/roles/xos-install/tasks/main.yml
@@ -0,0 +1,7 @@
+---
+# tasks for xos-install role
+
+ - name: checkout XOS repo
+ git: repo={{ xos_repo_url }}
+ dest={{ xos_repo_dest }}
+ version={{ xos_repo_branch }}