blob: 4afb71cf43e238e5cb9eeb9ae0405f89ad043358 (
plain)
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
186
187
188
189
|
---
- name: "Creating VM"
block:
- set_fact:
vm_name: "{{ node_names[item.0 | int] }}"
- set_fact:
vm_log_file: "{{ node_logdir }}/{{ vm_name }}_console.log"
vm_host_group: "{{ vm_default_groups }}"
- set_fact:
vm_host_group: "{{ vm_default_groups | union(vm_groups[vm_name]) }}"
when: vm_groups[vm_name] is defined
- name: set prealloc arg for Debian
set_fact:
prealloc: "--prealloc-metadata"
when:
- ansible_os_family == 'Debian'
- vm_libvirt_uri == 'qemu:///system'
- name: list info on pools
virt_pool:
command: facts
uri: "{{ vm_libvirt_uri }}"
- name: list existing vms
virt:
command: list_vms
register: existing_vms
- block:
- name: Check if volume exists
stat:
path: "{{ opnfv_image_path }}/{{ vm_name }}.qcow2"
register: _vm_volume_prepared
- name: Resize opnfv VM image to {{ item.disks[0].disk_capacity }}
command: "qemu-img resize {{ opnfv_image_path }}/opnfv.qcow2 {{ item.1.disks[0].disk_capacity }}"
when:
- vm_name == 'opnfv'
- _vm_volume_prepared.stat.exists
# NOTE(pas-ha) Ansible still lacks modules to operate on libvirt volumes
# mbuil: Assuming there is only one disk [0]
- name: create volume for vm
command: >
virsh --connect {{ vm_libvirt_uri }}
vol-create-as {{ node_storage_pool }} {{ vm_name }}.qcow2
{{ item.1.disks[0].disk_capacity }}
--format qcow2 {{ prealloc|default("") }}
when:
- not _vm_volume_prepared.stat.exists
- (vm_name + '.qcow2') not in ansible_libvirt_pools[node_storage_pool].volumes
- name: set path to the volume created
set_fact:
vm_volume_path: "{{ ansible_libvirt_pools[node_storage_pool].path }}/{{ vm_name }}.qcow2"
- name: pre-touch the vm volume
file:
state: touch
path: "{{ vm_volume_path }}"
when: vm_libvirt_uri == 'qemu:///system'
# NOTE(TheJulia): CentOS default installs with an XFS root, and chattr
# fails to set +C on XFS. This could be more elegant, however the use
# case is for CI testing.
- name: set copy-on-write for volume on non-CentOS systems
command: chattr +C {{ vm_volume_path }}
ignore_errors: yes
when:
- ansible_distribution != 'CentOS'
- vm_libvirt_uri == 'qemu:///system'
# Fetches the xml descriptor from the template
- name: create_vm
virt:
command: define
name: "{{ vm_name }}"
uri: "{{ vm_libvirt_uri }}"
xml: "{{ lookup('template', 'vm.xml.j2') }}"
rescue:
- name: "Execute `dmesg` to collect debugging output should VM creation fail."
command: dmesg
- name: >
"Execute `virsh capabilities` to collect debugging output
should VM creation fail."
command: virsh capabilities
- name: "Abort due to failed VM creation"
fail: >
msg="VM creation step failed, please review dmesg
output for additional details"
when: vm_name not in existing_vms.list_vms
# TODO(pas-ha) replace 'command: vbmc ...' tasks
# with a custom Ansible module using vbmc Python API
- name: get list of nodes from virtualbmc
command: vbmc list
environment:
PATH: "{{ lookup('env', 'XCI_VENV') }}/bin"
register: vbmc_list
- debug: var=vbmc_list
# NOTE(NobodyCam): Space at the end of the find clause is required for proper matching.
- name: delete vm from virtualbmc if it is there
command: vbmc delete {{ vm_name }}
environment:
PATH: "{{ lookup('env', 'XCI_VENV') }}/bin"
when: vbmc_list.stdout.find(vm_name) != -1
- set_fact:
virtual_ipmi_port: "{{ (vm_ipmi_port_start|default(623) | int ) + (item.0 | int) }}"
- name: plug vm into vbmc
command: vbmc add {{ vm_name }} --libvirt-uri {{ vm_libvirt_uri }} --port {{ virtual_ipmi_port }}
environment:
PATH: "{{ lookup('env', 'XCI_VENV') }}/bin"
- name: start virtualbmc
command: vbmc start {{ vm_name }}
environment:
PATH: "{{ lookup('env', 'XCI_VENV') }}/bin"
- name: get list of nodes from virtualbmc
command: vbmc list
environment:
PATH: "{{ lookup('env', 'XCI_VENV') }}/bin"
register: vbmc_list2
- debug: var=vbmc_list2
- name: get XML of the vm
virt:
name: "{{ vm_name }}"
command: get_xml
register: vm_xml
- name: Fetch the index for admin network
set_fact:
admin_index: "{{ (vm_name == 'opnfv') | ternary(opnfv_vm_idf.net_config.admin.interface, idf.net_config.admin.interface) | int }}"
- name: Fetch the ip
set_fact:
vm_ip: "{{ item.1.interfaces[admin_index | int].address }}"
# Assumes there is only a single NIC per VM
- name: get MAC from vm XML
set_fact:
vm_mac: "{{ (vm_xml.get_xml | regex_findall(\"<mac address='.*'/>\") | first).split('=') | last | regex_replace(\"['/>]\", '') }}"
# NOTE(pas-ha) using default username and password set by virtualbmc - "admin" and "password" respectively
# see vbmc add --help
- name: set the json entry for vm
set_fact:
vm_data:
name: "{{ vm_name }}"
uuid: "{{ vm_name | to_uuid }}"
host_groups: "{{ vm_host_group }}"
driver: "{{ vm_node_driver|default('ipmi') }}"
driver_info:
power:
ipmi_address: "192.168.122.1"
ipmi_port: "{{ virtual_ipmi_port }}"
ipmi_username: "{{ item.1.remote_management.user }}"
ipmi_password: "{{ item.1.remote_management.pass }}"
nics:
- mac: "{{ vm_mac }}"
ansible_ssh_host: "{{ vm_ip }}"
ipv4_address: "{{ vm_ip }}"
properties:
cpu_arch: "{{ item.1.node.arch }}"
ram: "{{ item.1.node.memory.rstrip('G') }}"
cpus: "{{ item.1.node.cpus }}"
disk_size: "{{ item.1.disks[0].disk_capacity.rstrip('G') }}"
- name: add created vm info
set_fact:
nodes_json_data: "{{ nodes_json_data | combine({vm_name: vm_data}) }}"
when: vm_name != 'opnfv'
- name: Record OPNFV VM ip
set_fact:
opnfv_vm_ip: "{{ vm_ip }}"
when: vm_name == 'opnfv'
when: (num_nodes | int) > (item.0 | int)
|