/
create-vm.sh
185 lines (168 loc) · 5.46 KB
/
create-vm.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
#!/bin/bash
set -ex
WORKSPACE=${WORKSPACE:-/tmp}
JOB_NAME=${JOB_NAME:-rdo-ci}
JOB_NAME_SIMPLIFIED=$((sed 's/scenario//; s/weirdo-//') <<< $JOB_NAME)
BUILD_NUMBER=${BUILD_NUMBER:-001}
ANSIBLE_HOSTS=${ANSIBLE_HOSTS:-$WORKSPACE/hosts}
CLOUD_CONFIG=${CLOUD_CONFIG:-~/.config/openstack/clouds.yaml}
LOGSERVER="logs.rdoproject.org ansible_user=uploader"
# Ansible config
CLOUD=${CLOUD:-rdo-cloud}
NETWORK=${NETWORK:-private}
NAME="${JOB_NAME_SIMPLIFIED}-${BUILD_NUMBER}"
IMAGE=${IMAGE:-template-centos7-weirdo-cr}
TIMEOUT=${TIMEOUT:-120}
FLAVOR=${FLAVOR:-rdo.m1.nodepool}
VM_INFO="${WORKSPACE}/vminfo.json"
if [ ! -f "${CLOUD_CONFIG}" ]; then
echo "Configuration file does not exist: ${CLOUD_CONFIG}"
exit 1
fi
pushd $WORKSPACE
# Install dependencies
[[ ! -d provision_venv ]] && virtualenv provision_venv
source provision_venv/bin/activate
pip install ansible==2.3.1.0 ara shade
ara_location=$(python -c "import os,ara; print(os.path.dirname(ara.__file__))")
export ANSIBLE_HOST_KEY_CHECKING=False
export ANSIBLE_CALLBACK_PLUGINS="${ara_location}/plugins/callbacks"
export ANSIBLE_GATHERING="implicit"
# Unreachable tasks may not be handled: https://github.com/ansible/ansible/issues/18287
export ANSIBLE_SSH_RETRIES=6
export ARA_DATABASE="sqlite:///${WORKSPACE}/${JOB_NAME}.sqlite"
# Write the header of the hosts file
cat << EOF > ${ANSIBLE_HOSTS}
[logserver]
${LOGSERVER}
[openstack_nodes]
EOF
cat <<EOF >create-vm.yml
- name: Create job virtual machine
hosts: localhost
gather_facts: true
vars:
fmt: '%Y-%m-%dT%H:%M:%SZ'
tasks:
- name: Validate cloud authentication
os_auth:
cloud: "${CLOUD}"
- name: Gather tenant facts
os_server_facts:
cloud: "${CLOUD}"
- block:
- name: Delete VMs in ERROR state or too old
os_server:
state: "absent"
cloud: "${CLOUD}"
name: "{{ item.name }}"
timeout: "${TIMEOUT}"
delete_fip: True
wait: "yes"
when: item.status == "ERROR" or ((ansible_date_time.iso8601|to_datetime(fmt)) - (item.created|to_datetime(fmt))).days >= 1
with_items:
- "{{ openstack_servers }}"
rescue:
- name: Handling virtual machine deletion failure
debug:
msg: "The stale VM cleanup failed, trying again ..."
- name: Delete VMs in ERROR state or too old, take 2
os_server:
state: "absent"
cloud: "${CLOUD}"
name: "{{ item.name }}"
timeout: "${TIMEOUT}"
delete_fip: True
wait: "yes"
ignore_errors: "yes"
when: item.status == "ERROR" or ((ansible_date_time.iso8601|to_datetime(fmt)) - (item.created|to_datetime(fmt))).days >= 1
with_items:
- "{{ openstack_servers }}"
# Be a bit resilient to failures by trying at least twice
- block:
- name: Create job virtual machine
os_server:
state: "present"
cloud: "${CLOUD}"
name: "${NAME}"
image: "${IMAGE}"
flavor: "${FLAVOR}"
network: "${NETWORK}"
reuse_ips: "no"
timeout: "${TIMEOUT}"
config_drive: "yes"
boot_from_volume: "yes"
terminate_volume: "yes"
volume_size: 80
wait: "yes"
meta:
hostname: "${NAME}"
job_name: "${JOB_NAME}"
build_number: "${BUILD_NUMBER}"
register: vm
rescue:
- name: Handling virtual machine creation failure
debug:
msg: "The virtual machine creation failed, trying again ..."
- name: Create job virtual machine (second attempt)
os_server:
state: "present"
cloud: "${CLOUD}"
name: "${NAME}"
image: "${IMAGE}"
flavor: "${FLAVOR}"
network: "${NETWORK}"
reuse_ips: "no"
timeout: "${TIMEOUT}"
config_drive: "yes"
boot_from_volume: "yes"
terminate_volume: "yes"
volume_size: 100
wait: "yes"
meta:
hostname: "${NAME}"
job_name: "${JOB_NAME}"
build_number: "${BUILD_NUMBER}"
register: vm
- name: Dump complete virtual machine info
vars:
ansible_python_interpreter: "/usr/bin/python"
copy:
content: "{{ vm | to_nice_json }}"
dest: "${VM_INFO}"
- name: Wait until server is up and runnning
local_action:
module: "wait_for"
port: "22"
host: "{{ vm.openstack.accessIPv4 }}"
search_regex: "OpenSSH"
delay: "10"
- name: Add server to inventory
add_host:
hostname: "{{ vm.openstack.name }}"
ansible_ssh_host: "{{ vm.openstack.accessIPv4 }}"
ansible_user: "centos"
ansible_become: "yes"
ansible_become_user: "root"
- name: Ensure the server is reachable
ping:
register: ping
until: ping | success
retries: 6
delay: 5
delegate_to: "{{ vm.openstack.name }}"
- name: Write inventory
vars:
ansible_python_interpreter: "/usr/bin/python"
lineinfile:
dest: "${ANSIBLE_HOSTS}"
line: >-
{{ vm.openstack.name }}
ansible_host={{ vm.openstack.accessIPv4 }}
ansible_user=centos
ansible_become=yes
ansible_become_user=root
EOF
ansible-playbook -i 'localhost' create-vm.yml
deactivate
popd