blob: 7f2f3e62488b355aa68e9d945fd53d0a7720ad19 [file] [log] [blame]
Anthony Youngb62b4ca2011-10-26 22:29:08 -07001#!/bin/bash
2#
3# Copyright (c) 2011 Citrix Systems, Inc.
4# Copyright 2011 OpenStack LLC.
Anthony Youngb62b4ca2011-10-26 22:29:08 -07005# All Rights Reserved.
6#
7# Licensed under the Apache License, Version 2.0 (the "License"); you may
8# not use this file except in compliance with the License. You may obtain
9# a copy of the License at
10#
11# http://www.apache.org/licenses/LICENSE-2.0
12#
13# Unless required by applicable law or agreed to in writing, software
14# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
16# License for the specific language governing permissions and limitations
17# under the License.
18#
19
20set -eux
21
John Garbuttdaadf742012-04-27 18:28:28 +010022if [ -a /etc/xensource-inventory]
23then
24 . /etc/xensource-inventory
25else
26 . /etc/xcp/inventory
27fi
Anthony Youngb62b4ca2011-10-26 22:29:08 -070028
29NAME="XenServer OpenStack VPX"
30DATA_VDI_SIZE="500MiB"
31BRIDGE_M=
32BRIDGE_P=
33KERNEL_PARAMS=
34VPX_FILE=os-vpx.xva
35AS_TEMPLATE=
36FROM_TEMPLATE=
37RAM=
38WAIT_FOR_NETWORK=
39BALLOONING=
40
41usage()
42{
43cat << EOF
44
45 Usage: $0 [-f FILE_PATH] [-d DISK_SIZE] [-v BRIDGE_NAME] [-m BRIDGE_NAME] [-p BRIDGE_NAME]
Renuka Apte836955f2012-04-02 15:22:55 -070046 [-k PARAMS] [-r RAM] [-i|-c] [-w] [-b] [-l NAME_LABEL] [-t TEMPLATE_NW_INSTALL]
Anthony Youngb62b4ca2011-10-26 22:29:08 -070047
48 Installs XenServer OpenStack VPX.
49
50 OPTIONS:
51
52 -h Shows this message.
53 -i Install OpenStack VPX as template.
54 -c Clone from existing template.
55 -w Wait for the network settings to show up before exiting.
56 -b Enable memory ballooning. When set min_RAM=RAM/2 max_RAM=RAM.
57 -f path Specifies the path to the XVA.
58 Default to ./os-vpx.xva.
59 -d disk-size Specifies the size in MiB for the data disk.
60 Defaults to 500 MiB.
61 -m bridge Specifies the bridge for the isolated management network.
62 Defaults to xenbr0.
63 -v bridge Specifies the bridge for the vm network
64 -p bridge Specifies the bridge for the externally facing network.
65 -k params Specifies kernel parameters.
66 -r MiB Specifies RAM used by the VPX, in MiB.
67 By default it will take the value from the XVA.
Renuka Aptee98cc122012-01-26 11:58:56 -080068 -l name Specifies the name label for the VM.
Renuka Apte836955f2012-04-02 15:22:55 -070069 -t template Network install an openstack domU from this template
Anthony Youngb62b4ca2011-10-26 22:29:08 -070070
71 EXAMPLES:
72
73 Create a VPX that connects to the isolated management network using the
74 default bridge with a data disk of 1GiB:
75 install-os-vpx.sh -f /root/os-vpx-devel.xva -d 1024
76
77 Create a VPX that connects to the isolated management network using xenbr1
78 as bridge:
79 install-os-vpx.sh -m xenbr1
80
81 Create a VPX that connects to both the management and public networks
82 using xenbr1 and xapi4 as bridges:
83 install-os-vpx.sh -m xenbr1 -p xapi4
84
85 Create a VPX that connects to both the management and public networks
86 using the default for management traffic:
87 install-os-vpx.sh -m xapi4
88
89 Create a VPX that automatically becomes the master:
90 install-os-vpx.sh -k geppetto_master=true
91
92EOF
93}
94
95get_params()
96{
Renuka Apte836955f2012-04-02 15:22:55 -070097 while getopts "hicwbf:d:v:m:p:k:r:l:t:" OPTION;
Anthony Youngb62b4ca2011-10-26 22:29:08 -070098 do
99 case $OPTION in
100 h) usage
101 exit 1
102 ;;
103 i)
104 AS_TEMPLATE=1
105 ;;
106 c)
107 FROM_TEMPLATE=1
108 ;;
109 w)
110 WAIT_FOR_NETWORK=1
111 ;;
112 b)
113 BALLOONING=1
114 ;;
115 f)
116 VPX_FILE=$OPTARG
117 ;;
118 d)
119 DATA_VDI_SIZE="${OPTARG}MiB"
120 ;;
121 m)
122 BRIDGE_M=$OPTARG
123 ;;
124 p)
125 BRIDGE_P=$OPTARG
126 ;;
127 k)
128 KERNEL_PARAMS=$OPTARG
129 ;;
130 r)
131 RAM=$OPTARG
132 ;;
133 v)
134 BRIDGE_V=$OPTARG
135 ;;
Renuka Apte836955f2012-04-02 15:22:55 -0700136 l)
Renuka Aptee98cc122012-01-26 11:58:56 -0800137 NAME_LABEL=$OPTARG
138 ;;
Renuka Apte836955f2012-04-02 15:22:55 -0700139 t)
140 TEMPLATE_NAME=$OPTARG
141 ;;
Anthony Youngb62b4ca2011-10-26 22:29:08 -0700142 ?)
143 usage
144 exit
145 ;;
146 esac
147 done
148 if [[ -z $BRIDGE_M ]]
149 then
150 BRIDGE_M=xenbr0
151 fi
152}
153
154
155xe_min()
156{
157 local cmd="$1"
158 shift
159 xe "$cmd" --minimal "$@"
160}
161
162
163get_dest_sr()
164{
165 IFS=,
166 sr_uuids=$(xe sr-list --minimal other-config:i18n-key=local-storage)
167 dest_sr=""
168 for sr_uuid in $sr_uuids
169 do
170 pbd=$(xe pbd-list --minimal sr-uuid=$sr_uuid host-uuid=$INSTALLATION_UUID)
171 if [ "$pbd" ]
172 then
173 echo "$sr_uuid"
174 unset IFS
175 return
176 fi
177 done
178 unset IFS
179
180 dest_sr=$(xe_min sr-list uuid=$(xe_min pool-list params=default-SR))
181 if [ "$dest_sr" = "" ]
182 then
183 echo "No local storage and no default storage; cannot import VPX." >&2
184 exit 1
185 else
186 echo "$dest_sr"
187 fi
188}
189
190
191find_network()
192{
193 result=$(xe_min network-list bridge="$1")
194 if [ "$result" = "" ]
195 then
196 result=$(xe_min network-list name-label="$1")
197 fi
198 echo "$result"
199}
200
201
202find_template()
203{
204 xe_min template-list other-config:os-vpx=true
205}
206
207
208renumber_system_disk()
209{
210 local v="$1"
211 local vdi_uuid=$(xe_min vbd-list vm-uuid="$v" type=Disk userdevice=xvda \
212 params=vdi-uuid)
213 if [ "$vdi_uuid" ]
214 then
215 local vbd_uuid=$(xe_min vbd-list vm-uuid="$v" vdi-uuid="$vdi_uuid")
216 xe vbd-destroy uuid="$vbd_uuid"
217 local new_vbd_uuid=$(xe vbd-create vm-uuid="$v" vdi-uuid="$vdi_uuid" \
218 device=0 bootable=true type=Disk)
219 xe vbd-param-set other-config:owner uuid="$new_vbd_uuid"
220 fi
221}
222
223
224create_vif()
225{
226 xe vif-create vm-uuid="$1" network-uuid="$2" device="$3"
227}
228
229create_gi_vif()
230{
231 local v="$1"
232 # Note that we've made the outbound device eth1, so that it comes up after
233 # the guest installer VIF, which means that the outbound one wins in terms
234 # of gateway.
235 local gi_network_uuid=$(xe_min network-list \
236 other-config:is_guest_installer_network=true)
237 create_vif "$v" "$gi_network_uuid" "0" >/dev/null
238}
239
240create_vm_vif()
241{
242 local v="$1"
243 echo "Installing management interface on $BRIDGE_V."
244 local out_network_uuid=$(find_network "$BRIDGE_V")
245 create_vif "$v" "$out_network_uuid" "1" >/dev/null
246}
247
248create_management_vif()
249{
250 local v="$1"
251 echo "Installing management interface on $BRIDGE_M."
252 local out_network_uuid=$(find_network "$BRIDGE_M")
253 create_vif "$v" "$out_network_uuid" "2" >/dev/null
254}
255
256
257# This installs the interface for public traffic, only if a bridge is specified
Hengqing Hu3b719e52012-03-09 16:03:00 +0800258# The interface is not configured at this stage, but it will be, once the admin
Anthony Youngb62b4ca2011-10-26 22:29:08 -0700259# tasks are complete for the services of this VPX
260create_public_vif()
261{
262 local v="$1"
263 if [[ -z $BRIDGE_P ]]
264 then
265 echo "Skipping installation of interface for public traffic."
266 else
267 echo "Installing public interface on $BRIDGE_P."
268 pub_network_uuid=$(find_network "$BRIDGE_P")
269 create_vif "$v" "$pub_network_uuid" "3" >/dev/null
270 fi
271}
272
273
274label_system_disk()
275{
276 local v="$1"
277 local vdi_uuid=$(xe_min vbd-list vm-uuid="$v" type=Disk userdevice=0 \
278 params=vdi-uuid)
279 xe vdi-param-set \
280 name-label="$NAME system disk" \
281 other-config:os-vpx=true \
282 uuid=$vdi_uuid
283}
284
285
286create_data_disk()
287{
288 local v="$1"
289
290 local sys_vdi_uuid=$(xe_min vbd-list vm-uuid="$v" type=Disk params=vdi-uuid)
291 local data_vdi_uuid=$(xe_min vdi-list other-config:os-vpx-data=true)
292
293 if echo "$data_vdi_uuid" | grep -q ,
294 then
295 echo "Multiple data disks found -- assuming that you want a new one."
296 data_vdi_uuid=""
297 else
298 data_in_use=$(xe_min vbd-list vdi-uuid="$data_vdi_uuid")
299 if [ "$data_in_use" != "" ]
300 then
301 echo "Data disk already in use -- will create another one."
302 data_vdi_uuid=""
303 fi
304 fi
305
306 if [ "$data_vdi_uuid" = "" ]
307 then
308 echo -n "Creating new data disk ($DATA_VDI_SIZE)... "
309 sr_uuid=$(xe_min vdi-list params=sr-uuid uuid="$sys_vdi_uuid")
310 data_vdi_uuid=$(xe vdi-create name-label="$NAME data disk" \
311 sr-uuid="$sr_uuid" \
312 type=user \
313 virtual-size="$DATA_VDI_SIZE")
314 xe vdi-param-set \
315 other-config:os-vpx-data=true \
316 uuid="$data_vdi_uuid"
317 dom0_uuid=$(xe_min vm-list is-control-domain=true)
318 vbd_uuid=$(xe vbd-create device=autodetect type=Disk \
319 vdi-uuid="$data_vdi_uuid" vm-uuid="$dom0_uuid")
320 xe vbd-plug uuid=$vbd_uuid
321 dev=$(xe_min vbd-list params=device uuid=$vbd_uuid)
322 mke2fs -q -j -m0 /dev/$dev
323 e2label /dev/$dev vpxstate
324 xe vbd-unplug uuid=$vbd_uuid
325 xe vbd-destroy uuid=$vbd_uuid
326 else
327 echo -n "Attaching old data disk... "
328 fi
329 vbd_uuid=$(xe vbd-create device=2 type=Disk \
330 vdi-uuid="$data_vdi_uuid" vm-uuid="$v")
331 xe vbd-param-set other-config:os-vpx-data=true uuid=$vbd_uuid
332 echo "done."
333}
334
335
336set_kernel_params()
337{
338 local v="$1"
339 local args=$KERNEL_PARAMS
Anthony Youngb62b4ca2011-10-26 22:29:08 -0700340 if [ "$args" != "" ]
341 then
342 echo "Passing Geppetto args to VPX: $args."
Renuka Apte0af143b2012-04-02 15:46:53 -0700343 pvargs=$(xe vm-param-get param-name=PV-args uuid="$v")
344 args="$pvargs $args"
Anthony Youngb62b4ca2011-10-26 22:29:08 -0700345 xe vm-param-set PV-args="$args" uuid="$v"
346 fi
347}
348
349
350set_memory()
351{
352 local v="$1"
353 if [ "$RAM" != "" ]
354 then
355 echo "Setting RAM to $RAM MiB."
356 [ "$BALLOONING" == 1 ] && RAM_MIN=$(($RAM / 2)) || RAM_MIN=$RAM
357 xe vm-memory-limits-set static-min=16MiB static-max=${RAM}MiB \
358 dynamic-min=${RAM_MIN}MiB dynamic-max=${RAM}MiB \
359 uuid="$v"
360 fi
361}
362
363
364# Make the VM auto-start on server boot.
365set_auto_start()
366{
367 local v="$1"
368 xe vm-param-set uuid="$v" other-config:auto_poweron=true
369}
370
371
372set_all()
373{
374 local v="$1"
375 set_kernel_params "$v"
376 set_memory "$v"
377 set_auto_start "$v"
378 label_system_disk "$v"
379 create_gi_vif "$v"
380 create_vm_vif "$v"
381 create_management_vif "$v"
382 create_public_vif "$v"
383}
384
385
386log_vifs()
387{
388 local v="$1"
389
390 (IFS=,
391 for vif in $(xe_min vif-list vm-uuid="$v")
392 do
393 dev=$(xe_min vif-list uuid="$vif" params=device)
394 mac=$(xe_min vif-list uuid="$vif" params=MAC | sed -e 's/:/-/g')
395 echo "eth$dev has MAC $mac."
396 done
397 unset IFS) | sort
398}
399
400
401destroy_vifs()
402{
403 local v="$1"
404 IFS=,
405 for vif in $(xe_min vif-list vm-uuid="$v")
406 do
407 xe vif-destroy uuid="$vif"
408 done
409 unset IFS
410}
411
412
413get_params "$@"
414
415thisdir=$(dirname "$0")
416
417if [ "$FROM_TEMPLATE" ]
418then
419 template_uuid=$(find_template)
420 name=$(xe_min template-list params=name-label uuid="$template_uuid")
421 echo -n "Cloning $name... "
422 vm_uuid=$(xe vm-clone vm="$template_uuid" new-name-label="$name")
423 xe vm-param-set is-a-template=false uuid="$vm_uuid"
424 echo $vm_uuid.
425
426 destroy_vifs "$vm_uuid"
427 set_all "$vm_uuid"
Renuka Apte836955f2012-04-02 15:22:55 -0700428elif [ "$TEMPLATE_NAME" ]
429then
430 echo $TEMPLATE_NAME
Renuka Apte0af143b2012-04-02 15:46:53 -0700431 vm_uuid=$(xe_min vm-install template="$TEMPLATE_NAME" new-name-label="$NAME_LABEL")
Renuka Apte836955f2012-04-02 15:22:55 -0700432 destroy_vifs "$vm_uuid"
433 set_auto_start "$vm_uuid"
434 create_gi_vif "$vm_uuid"
435 create_vm_vif "$vm_uuid"
436 create_management_vif "$vm_uuid"
437 create_public_vif "$vm_uuid"
Renuka Apte0af143b2012-04-02 15:46:53 -0700438 set_kernel_params "$vm_uuid"
439 xe vm-param-set other-config:os-vpx=true uuid="$vm_uuid"
440 xe vm-param-set actions-after-reboot=Destroy uuid="$vm_uuid"
441 set_memory "$vm_uuid"
Anthony Youngb62b4ca2011-10-26 22:29:08 -0700442else
443 if [ ! -f "$VPX_FILE" ]
444 then
445 # Search $thisdir/$VPX_FILE too. In particular, this is used when
446 # installing the VPX from the supp-pack, because we want to be able to
447 # invoke this script from the RPM and the firstboot script.
448 if [ -f "$thisdir/$VPX_FILE" ]
449 then
450 VPX_FILE="$thisdir/$VPX_FILE"
451 else
452 echo "$VPX_FILE does not exist." >&2
453 exit 1
454 fi
455 fi
456
457 echo "Found OS-VPX File: $VPX_FILE. "
458
459 dest_sr=$(get_dest_sr)
460
461 echo -n "Installing $NAME... "
462 vm_uuid=$(xe vm-import filename=$VPX_FILE sr-uuid="$dest_sr")
463 echo $vm_uuid.
464
465 renumber_system_disk "$vm_uuid"
466
Renuka Aptee98cc122012-01-26 11:58:56 -0800467 nl=${NAME_LABEL:-$(xe_min vm-list params=name-label uuid=$vm_uuid)}
Anthony Youngb62b4ca2011-10-26 22:29:08 -0700468 xe vm-param-set \
469 "name-label=${nl/ import/}" \
470 other-config:os-vpx=true \
471 uuid=$vm_uuid
472
473 set_all "$vm_uuid"
474 create_data_disk "$vm_uuid"
475
476 if [ "$AS_TEMPLATE" ]
477 then
478 xe vm-param-set uuid="$vm_uuid" is-a-template=true \
479 other-config:instant=true
480 echo -n "Installing VPX from template... "
481 vm_uuid=$(xe vm-clone vm="$vm_uuid" new-name-label="${nl/ import/}")
482 xe vm-param-set is-a-template=false uuid="$vm_uuid"
483 echo "$vm_uuid."
484 fi
485fi
486
487
488log_vifs "$vm_uuid"
489
490echo -n "Starting VM... "
491xe vm-start uuid=$vm_uuid
492echo "done."
493
494
495show_ip()
496{
497 ip_addr=$(echo "$1" | sed -n "s,^.*"$2"/ip: \([^;]*\).*$,\1,p")
498 echo -n "IP address for $3: "
499 if [ "$ip_addr" = "" ]
500 then
501 echo "did not appear."
502 else
503 echo "$ip_addr."
504 fi
505}
506
507
508if [ "$WAIT_FOR_NETWORK" ]
509then
510 echo "Waiting for network configuration... "
511 i=0
512 while [ $i -lt 600 ]
513 do
514 ip=$(xe_min vm-list params=networks uuid=$vm_uuid)
515 if [ "$ip" != "<not in database>" ]
516 then
517 show_ip "$ip" "1" "$BRIDGE_M"
518 if [[ $BRIDGE_P ]]
519 then
520 show_ip "$ip" "2" "$BRIDGE_P"
521 fi
522 echo "Installation complete."
523 exit 0
524 fi
525 sleep 10
526 let i=i+1
527 done
528fi