blob: b0d7976a43e9e3e908dd18d4bdb0c665131f4659 [file] [log] [blame]
Denis Egorenkoc2656402019-04-19 18:17:50 +04001#!/bin/bash
2
Denis Egorenko0d045ae2019-06-04 18:23:11 +04003set -e
4
Denis Egorenkoc2656402019-04-19 18:17:50 +04005envFile="$(pwd)/env_vars.sh"
6if [[ ! -f ${envFile} ]]; then
7 echo "ERROR: Can not find 'env_vars' libfile (${envFile}), check your mcp/mcp-common-scripts repo."
8 exit 1
9else
10 source ${envFile}
11fi
12
Denis Egorenko6cb60522019-07-17 21:36:52 +040013function count_netmask {
14 local network=$1
15 local cidr=$(echo $network | cut -f 2 -d '/')
16 local ones="printf '1%.0s' {1..${cidr}}"
17 local zeros="printf '0%.0s' {1..$(( 32 - ${cidr} ))}"
18 local netmask_binary="$(echo $ones | bash)$(echo $zeros | bash)"
19 local netmask_decimal=""
20 for i in 0 8 16 24; do
21 netmask_decimal+="$(echo $((2#${netmask_binary:${i}:8})))"
22 [[ "${i}" != '24' ]] && netmask_decimal+='.'
23 done
24 echo "${netmask_decimal}"
25}
26
Denis Egorenkoc2656402019-04-19 18:17:50 +040027function check_packages {
28 local slave=$1
29 local packages="libvirt-bin qemu-kvm"
30 if [[ -n "${slave}" ]]; then
Denis Egorenko28b8d042019-05-03 13:57:51 +040031 packages="${packages} qemu-utils python-ipaddress genisoimage"
Denis Egorenkoc2656402019-04-19 18:17:50 +040032 fi
33 for i in $packages; do
34 dpkg -s $i &> /dev/null || { echo "Package $i is not installed!"; exit 1; }
35 done
36}
37
Denis Egorenkoabe23c52019-05-30 16:53:55 +040038function check_bridge_exists {
39 local bridgeName=${1}
40 local optionName=${2}
41 local bridgeExists=$(brctl show | grep ${bridgeName})
42 if [ -z "${bridgeExists}" ]; then
43 echo "Option ${optionName} is set to False, which means using bridge ${bridgeName}, but it doesn't exist."
44 echo "Consider to switch to ${optionName}=True, which will lead to using local hosted networks."
45 echo "Or create bridge ${bridgeName} manually: https://docs.mirantis.com/mcp/q4-18/mcp-deployment-guide/deploy-mcp-drivetrain/prerequisites-dtrain.html"
46 exit 1
47 fi
48}
49
50function prereq_check {
51 local slave=${1}
52 check_packages "${slave}"
Denis Egorenko6c9aef32019-06-07 19:19:02 +040053 if [[ "${VM_MGM_BRIDGE_DISABLE}" =~ [Ff]alse ]]; then
54 check_bridge_exists "${VM_MGM_BRIDGE_NAME}" "VM_MGM_BRIDGE_DISABLE"
55 fi
56 if [[ "${VM_CTL_BRIDGE_DISABLE}" =~ [Ff]alse ]]; then
57 check_bridge_exists "${VM_CTL_BRIDGE_NAME}" "VM_CTL_BRIDGE_DISABLE"
58 fi
59 if [[ -n "${NON_DEFAULT_LIBVIRT_DIR}" ]]; then
60 echo "All files will be saved under ${NON_DEFAULT_LIBVIRT_DIR} directory. Make sure that libvirt-qemu:kvm has access rights to that path."
61 fi
Denis Egorenkoabe23c52019-05-30 16:53:55 +040062}
63
64function do_create_new_network {
65 local netName=${1}
66 local netExists=$(virsh net-list | grep ${netName})
67 if [ -n "${netExists}" ] && [[ "${RECREATE_NETWORKS_IF_EXISTS}" =~ [Ff]alse ]]; then
68 echo 'false'
69 else
70 echo 'true'
71 fi
72}
73
Denis Egorenkoc2656402019-04-19 18:17:50 +040074function create_network {
75 local network=${1}
76 virsh net-destroy ${network} 2> /dev/null || true
77 virsh net-undefine ${network} 2> /dev/null || true
78 virsh net-define ${network}.xml
79 virsh net-autostart ${network}
80 virsh net-start ${network}
81}
82
83function create_bridge_network {
84 local network=$1
85 local bridge_name=$2
Denis Egorenkoabe23c52019-05-30 16:53:55 +040086 local createNetwork=$(do_create_new_network "${network}")
87 if [ "${createNetwork}" == 'true' ]; then
88 cat <<EOF > $(pwd)/${network}.xml
Denis Egorenkoc2656402019-04-19 18:17:50 +040089<network>
90 <name>${network}</name>
91 <forward mode="bridge"/>
92 <bridge name="${bridge_name}" />
93</network>
94EOF
Denis Egorenkoabe23c52019-05-30 16:53:55 +040095 create_network ${network}
96 fi
Denis Egorenkoc2656402019-04-19 18:17:50 +040097}
98
99function create_host_network {
100 local network=$1
101 local gateway=$2
102 local netmask=$3
103 local nat=${4:-false}
Denis Egorenkoabe23c52019-05-30 16:53:55 +0400104 local createNetwork=$(do_create_new_network "${network}")
105 if [ "${createNetwork}" == 'true' ]; then
106 cat <<EOF > $(pwd)/${network}.xml
Denis Egorenkoc2656402019-04-19 18:17:50 +0400107<network>
108 <name>${network}</name>
109 <bridge name="${network}" />
110 <ip address="${gateway}" netmask="${netmask}"/>
111EOF
Denis Egorenkoabe23c52019-05-30 16:53:55 +0400112 if [[ "${nat}" =~ [Tt]rue ]]; then
113 cat <<EOF>> $(pwd)/${network}.xml
Denis Egorenkoc2656402019-04-19 18:17:50 +0400114 <forward mode="nat"/>
115EOF
Denis Egorenkoabe23c52019-05-30 16:53:55 +0400116 fi
117 cat <<EOF>> $(pwd)/${network}.xml
Denis Egorenkoc2656402019-04-19 18:17:50 +0400118</network>
119EOF
Denis Egorenkoabe23c52019-05-30 16:53:55 +0400120 create_network ${network}
121 fi
Denis Egorenkoc2656402019-04-19 18:17:50 +0400122}
123
Denis Egorenkoabe23c52019-05-30 16:53:55 +0400124function place_file_under_libvirt_owned_dir() {
125 local file=${1}
126 local libvirtPath=${2-'/var/lib/libvirt/images'}
127 local basenameFile=$(basename ${file})
128 cp "${file}" "${libvirtPath}/${basenameFile}"
129 chown libvirt-qemu:kvm "${libvirtPath}/${basenameFile}"
Denis Egorenkoc2656402019-04-19 18:17:50 +0400130 echo "${libvirtPath}/${basenameFile}"
131}
132
133function render_config() {
134 local vmName=$1
135 local vmMemKB=$2
136 local vmCPUs=$3
137 local vmSourceDisk=$4
138 local vmConfigDisk=$5
Denis Egorenkoc2656402019-04-19 18:17:50 +0400139 # Template definition
140 cat <<EOF > $(pwd)/${vmName}-vm.xml
141<domain type='kvm'>
142 <name>$vmName</name>
143 <memory unit='KiB'>$vmMemKB</memory>
144 <currentMemory unit='KiB'>$vmMemKB</currentMemory>
145 <vcpu placement='static'>$vmCPUs</vcpu>
146 <resource>
147 <partition>/machine</partition>
148 </resource>
149 <os>
150 <type >hvm</type>
151 <boot dev='hd'/>
152 </os>
153 <features>
154 <acpi/>
155 </features>
156 <clock offset='utc'>
157 <timer name='rtc' tickpolicy='catchup'/>
158 <timer name='pit' tickpolicy='delay'/>
159 <timer name='hpet' present='no'/>
160 </clock>
161 <pm>
162 <suspend-to-mem enabled='no'/>
163 <suspend-to-disk enabled='no'/>
164 </pm>
165 <devices>
166 <emulator>/usr/bin/kvm-spice</emulator>
167 <disk type='file' device='disk'>
168 <driver name='qemu' type='qcow2' cache='none'/>
169 <source file='$vmSourceDisk'/>
170 <target dev='vda' bus='virtio'/>
171 <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x0'/>
172 </disk>
173EOF
174 if [[ -n "${vmConfigDisk}" ]]; then
175 cat <<EOF >> $(pwd)/${vmName}-vm.xml
176 <disk type='file' device='cdrom'>
177 <driver name='qemu' type='raw'/>
178 <source file='$vmConfigDisk'/>
179 <backingStore/>
180 <target dev='hda' bus='ide'/>
181 <readonly/>
182 <address type='drive' controller='0' bus='0' target='0' unit='0'/>
183 </disk>
184EOF
185 fi
186
Denis Egorenko0d045ae2019-06-04 18:23:11 +0400187 local allocationDataFile=$(isoinfo -i ${VM_CONFIG_DISK} -J -f | grep -w "allocation_data.yml")
Denis Egorenkoc2656402019-04-19 18:17:50 +0400188 if [[ "${VM_MGM_BRIDGE_DISABLE}" =~ [Ff]alse ]]; then
Denis Egorenkoabe23c52019-05-30 16:53:55 +0400189 create_bridge_network "${VM_MGM_NETWORK_NAME}" "${VM_MGM_BRIDGE_NAME}"
Denis Egorenkoc2656402019-04-19 18:17:50 +0400190 cat <<EOF >> $(pwd)/${vmName}-vm.xml
191 <interface type='bridge'>
192 <source bridge='$VM_MGM_BRIDGE_NAME'/>
193 <model type='virtio'/>
194 <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
195 </interface>
196EOF
197 else
Denis Egorenko0d045ae2019-06-04 18:23:11 +0400198 local vmMgmNetworkGateway=$(isoinfo -i ${VM_CONFIG_DISK} -J -x ${allocationDataFile} | grep -w 'deploy_network_gateway' | cut -f 2 -d ':' | tr -d ' ')
199 local vmMgmNetworkMask=$(isoinfo -i ${VM_CONFIG_DISK} -J -x ${allocationDataFile} | grep -w 'deploy_network_netmask' | cut -f 2 -d ':' | tr -d ' ')
200 create_host_network "${VM_MGM_NETWORK_NAME}" "${vmMgmNetworkGateway}" "${vmMgmNetworkMask}" true
Denis Egorenkoc2656402019-04-19 18:17:50 +0400201 cat <<EOF >> $(pwd)/${vmName}-vm.xml
202 <interface type='network'>
203 <source network='$VM_MGM_NETWORK_NAME'/>
204 <model type='virtio'/>
205 <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
206 </interface>
207EOF
208fi
209
210 if [[ "${VM_MGM_BRIDGE_DISABLE}" =~ [Ff]alse ]]; then
Denis Egorenkoabe23c52019-05-30 16:53:55 +0400211 create_bridge_network "${VM_CTL_NETWORK_NAME}" "${VM_CTL_BRIDGE_NAME}"
Denis Egorenkoc2656402019-04-19 18:17:50 +0400212 cat <<EOF >> $(pwd)/${vmName}-vm.xml
213 <interface type='bridge'>
214 <source bridge='$VM_CTL_BRIDGE_NAME'/>
215 <model type='virtio'/>
216 <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>
217 </interface>
218EOF
219 else
Denis Egorenko0d045ae2019-06-04 18:23:11 +0400220 local vmCtlNetworkGateway=$(isoinfo -i ${VM_CONFIG_DISK} -J -x ${allocationDataFile} | grep -w 'infra_config_address' | cut -f 2 -d ':' | tr -d ' ' | sed -r "s/\.[[:digit:]]+$/\.1/g")
221 local vmCtlNetworkMask=$(isoinfo -i ${VM_CONFIG_DISK} -J -x ${allocationDataFile} | grep -w 'control_network_netmask' | cut -f 2 -d ':' | tr -d ' ')
222 create_host_network "${VM_CTL_NETWORK_NAME}" "${vmCtlNetworkGateway}" "${vmCtlNetworkMask}"
Denis Egorenkoc2656402019-04-19 18:17:50 +0400223 cat <<EOF >> $(pwd)/${vmName}-vm.xml
224 <interface type='network'>
225 <source network='$VM_CTL_NETWORK_NAME'/>
226 <model type='virtio'/>
227 <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>
228 </interface>
229EOF
230fi
231
Denis Egorenko6cb60522019-07-17 21:36:52 +0400232 if [[ "${VM_PUBLIC_NET_NEEDED}" =~ [Tt]rue ]]; then
233 if [[ "${VM_PUBLIC_BRIDGE_DISABLE}" =~ [Ff]alse ]]; then
234 create_bridge_network "${VM_PUBLIC_NETWORK_NAME}" "${VM_PUBLIC_BRIDGE_NAME}"
235 cat <<EOF >> $(pwd)/${vmName}-vm.xml
236 <interface type='bridge'>
237 <source bridge='$VM_PUBLIC_BRIDGE_NAME'/>
238 <model type='virtio'/>
239 <address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x0'/>
240 </interface>
241EOF
242 else
243 local vmPublicNetworkGateway=$(isoinfo -i ${VM_CONFIG_DISK} -J -x ${allocationDataFile} | grep -w 'openstack_public_neutron_subnet_gateway' | cut -f 2 -d ':' | tr -d ' ')
244 local vmPublicNetworkCIDR=$(isoinfo -i ${VM_CONFIG_DISK} -J -x ${allocationDataFile} | grep -w 'openstack_public_neutron_subnet_cidr' | cut -f 2 -d ':' | tr -d ' ')
245 local vmPublicNetworkMask=$(count_netmask "${vmPublicNetworkCIDR}")
246 create_host_network "${VM_PUBLIC_NETWORK_NAME}" "${vmPublicNetworkGateway}" "${vmPublicNetworkMask}" true
247 cat <<EOF >> $(pwd)/${vmName}-vm.xml
248 <interface type='network'>
249 <source network='$VM_PUBLIC_NETWORK_NAME'/>
250 <model type='virtio'/>
251 <address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x0'/>
252 </interface>
253EOF
254 fi
255fi
256
Denis Egorenkoc2656402019-04-19 18:17:50 +0400257 cat <<EOF >> $(pwd)/${vmName}-vm.xml
258 <serial type='pty'>
259 <source path='/dev/pts/1'/>
260 <target port='0'/>
261 </serial>
262 <console type='pty' tty='/dev/pts/1'>
263 <source path='/dev/pts/1'/>
264 <target type='serial' port='0'/>
265 </console>
266 <graphics type='vnc' port='-1' autoport='yes' listen='127.0.0.1'>
267 <listen type='address' address='127.0.0.1'/>
268 </graphics>
269 <rng model='virtio'>
270 <backend model='random'>/dev/random</backend>
271 </rng>
272 </devices>
273</domain>
274EOF
275
276 echo "INFO: rendered VM config:"
277 cat $(pwd)/${vmName}-vm.xml
278}