forked from openstack/devstack
-
Notifications
You must be signed in to change notification settings - Fork 0
/
functions
869 lines (779 loc) · 31.2 KB
/
functions
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
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
#!/bin/bash
#
# functions - DevStack-specific functions
#
# The following variables are assumed to be defined by certain functions:
#
# - ``DATABASE_BACKENDS``
# - ``ENABLED_SERVICES``
# - ``FILES``
# - ``GLANCE_HOSTPORT``
#
# ensure we don't re-source this in the same environment
[[ -z "$_DEVSTACK_FUNCTIONS" ]] || return 0
declare -r -g _DEVSTACK_FUNCTIONS=1
# Include the common functions
FUNC_DIR=$(cd $(dirname "${BASH_SOURCE:-$0}") && pwd)
source ${FUNC_DIR}/functions-common
source ${FUNC_DIR}/inc/ini-config
source ${FUNC_DIR}/inc/meta-config
source ${FUNC_DIR}/inc/python
source ${FUNC_DIR}/inc/rootwrap
# Save trace setting
_XTRACE_FUNCTIONS=$(set +o | grep xtrace)
set +o xtrace
# Check if a function already exists
function function_exists {
declare -f -F $1 > /dev/null
}
# short_source prints out the current location of the caller in a way
# that strips redundant directories. This is useful for PS4 usage.
function short_source {
saveIFS=$IFS
IFS=" "
called=($(caller 0))
IFS=$saveIFS
file=${called[2]}
file=${file#$RC_DIR/}
printf "%-40s " "$file:${called[1]}:${called[0]}"
}
# PS4 is exported to child shells and uses the 'short_source' function, so
# export it so child shells have access to the 'short_source' function also.
export -f short_source
# Download a file from a URL
#
# Will check cache (in $FILES) or download given URL.
#
# Argument is the URL to the remote file
#
# Will echo the local path to the file as the output. Will die on
# failure to download.
#
# Files can be pre-cached for CI environments, see EXTRA_CACHE_URLS
# and tools/image_list.sh
function get_extra_file {
local file_url=$1
file_name=$(basename "$file_url")
if [[ $file_url != file* ]]; then
# If the file isn't cache, download it
if [[ ! -f $FILES/$file_name ]]; then
wget --progress=dot:giga -t 2 -c $file_url -O $FILES/$file_name
if [[ $? -ne 0 ]]; then
die "$file_url could not be downloaded"
fi
fi
echo "$FILES/$file_name"
return
else
# just strip the file:// bit and that's the path to the file
echo $file_url | sed 's/$file:\/\///g'
fi
}
# Generate image property arguments for OSC
#
# Arguments: properties, one per, like propname=value
#
# Result is --property propname1=value1 --property propname2=value2
function _image_properties_to_arg {
local result=""
for property in $*; do
result+=" --property $property"
done
echo $result
}
# Upload an image to glance using the configured mechanism
#
# Arguments:
# image name
# container format
# disk format
# path to image file
# optional properties (format of propname=value)
#
function _upload_image {
local image_name="$1"
shift
local container="$1"
shift
local disk="$1"
shift
local image="$1"
shift
local properties
local useimport
properties=$(_image_properties_to_arg $*)
if [[ "$GLANCE_USE_IMPORT_WORKFLOW" == "True" ]]; then
useimport="--import"
fi
openstack --os-cloud=devstack-admin --os-region-name="$REGION_NAME" image create "$image_name" --public --container-format "$container" --disk-format "$disk" $useimport $properties < "${image}"
}
# Retrieve an image from a URL and upload into Glance.
# Uses the following variables:
#
# - ``FILES`` must be set to the cache dir
# - ``GLANCE_HOSTPORT``
#
# upload_image image-url
function upload_image {
local image_url=$1
local image image_fname image_name
# Create a directory for the downloaded image tarballs.
mkdir -p $FILES/images
image_fname=`basename "$image_url"`
if [[ $image_url != file* ]]; then
# Downloads the image (uec ami+akistyle), then extracts it.
if [[ ! -f $FILES/$image_fname || "$(stat -c "%s" $FILES/$image_fname)" = "0" ]]; then
wget --progress=dot:giga -c $image_url -O $FILES/$image_fname
if [[ $? -ne 0 ]]; then
echo "Not found: $image_url"
return
fi
fi
image="$FILES/${image_fname}"
else
# File based URL (RFC 1738): ``file://host/path``
# Remote files are not considered here.
# unix: ``file:///home/user/path/file``
# windows: ``file:///C:/Documents%20and%20Settings/user/path/file``
image=$(echo $image_url | sed "s/^file:\/\///g")
if [[ ! -f $image || "$(stat -c "%s" $image)" == "0" ]]; then
echo "Not found: $image_url"
return
fi
fi
# OpenVZ-format images are provided as .tar.gz, but not decompressed prior to loading
if [[ "$image_url" =~ 'openvz' ]]; then
image_name="${image_fname%.tar.gz}"
_upload_image "$image_name" ami ami "$image"
return
fi
# vmdk format images
if [[ "$image_url" =~ '.vmdk' ]]; then
image_name="${image_fname%.vmdk}"
# Before we can upload vmdk type images to glance, we need to know it's
# disk type, storage adapter, and networking adapter. These values are
# passed to glance as custom properties.
# We take these values from the vmdk file if populated. Otherwise, we use
# vmdk filename, which is expected in the following format:
#
# <name>-<disk type>;<storage adapter>;<network adapter>
#
# If the filename does not follow the above format then the vsphere
# driver will supply default values.
local vmdk_disktype=""
local vmdk_net_adapter="e1000"
local path_len
# vmdk adapter type
local vmdk_adapter_type
vmdk_adapter_type="$(head -25 $image | { grep -a -F -m 1 'ddb.adapterType =' $image || true; })"
vmdk_adapter_type="${vmdk_adapter_type#*\"}"
vmdk_adapter_type="${vmdk_adapter_type%?}"
# vmdk disk type
local vmdk_create_type
vmdk_create_type="$(head -25 $image | { grep -a -F -m 1 'createType=' $image || true; })"
vmdk_create_type="${vmdk_create_type#*\"}"
vmdk_create_type="${vmdk_create_type%\"*}"
descriptor_data_pair_msg="Monolithic flat and VMFS disks "`
`"should use a descriptor-data pair."
if [[ "$vmdk_create_type" = "monolithicSparse" ]]; then
vmdk_disktype="sparse"
elif [[ "$vmdk_create_type" = "monolithicFlat" || "$vmdk_create_type" = "vmfs" ]]; then
# Attempt to retrieve the ``*-flat.vmdk``
local flat_fname
flat_fname="$(head -25 $image | { grep -G 'RW\|RDONLY [0-9]+ FLAT\|VMFS' $image || true; })"
flat_fname="${flat_fname#*\"}"
flat_fname="${flat_fname%?}"
if [[ -z "$flat_fname" ]]; then
flat_fname="$image_name-flat.vmdk"
fi
path_len=`expr ${#image_url} - ${#image_fname}`
local flat_url="${image_url:0:$path_len}$flat_fname"
warn $LINENO "$descriptor_data_pair_msg"`
`" Attempt to retrieve the *-flat.vmdk: $flat_url"
if [[ $flat_url != file* ]]; then
if [[ ! -f $FILES/$flat_fname || \
"$(stat -c "%s" $FILES/$flat_fname)" = "0" ]]; then
wget --progress=dot:giga -c $flat_url -O $FILES/$flat_fname
fi
image="$FILES/${flat_fname}"
else
image=$(echo $flat_url | sed "s/^file:\/\///g")
if [[ ! -f $image || "$(stat -c "%s" $image)" == "0" ]]; then
echo "Flat disk not found: $flat_url"
return 1
fi
fi
image_name="${flat_fname}"
vmdk_disktype="preallocated"
elif [[ "$vmdk_create_type" = "streamOptimized" ]]; then
vmdk_disktype="streamOptimized"
elif [[ -z "$vmdk_create_type" ]]; then
# *-flat.vmdk provided: attempt to retrieve the descriptor (*.vmdk)
# to retrieve appropriate metadata
if [[ ${image_name: -5} != "-flat" ]]; then
warn $LINENO "Expected filename suffix: '-flat'."`
`" Filename provided: ${image_name}"
else
descriptor_fname="${image_name:0:${#image_name} - 5}.vmdk"
path_len=`expr ${#image_url} - ${#image_fname}`
local flat_path="${image_url:0:$path_len}"
local descriptor_url=$flat_path$descriptor_fname
warn $LINENO "$descriptor_data_pair_msg"`
`" Attempt to retrieve the descriptor *.vmdk: $descriptor_url"
if [[ $flat_path != file* ]]; then
if [[ ! -f $FILES/$descriptor_fname || \
"$(stat -c "%s" $FILES/$descriptor_fname)" = "0" ]]; then
wget -c $descriptor_url -O $FILES/$descriptor_fname
fi
descriptor_url="$FILES/$descriptor_fname"
else
descriptor_url=$(echo $descriptor_url | sed "s/^file:\/\///g")
if [[ ! -f $descriptor_url || \
"$(stat -c "%s" $descriptor_url)" == "0" ]]; then
echo "Descriptor not found: $descriptor_url"
return 1
fi
fi
vmdk_adapter_type="$(head -25 $descriptor_url | { grep -a -F -m 1 'ddb.adapterType =' $descriptor_url || true; })"
vmdk_adapter_type="${vmdk_adapter_type#*\"}"
vmdk_adapter_type="${vmdk_adapter_type%?}"
fi
vmdk_disktype="preallocated"
else
vmdk_disktype="preallocated"
fi
# NOTE: For backwards compatibility reasons, colons may be used in place
# of semi-colons for property delimiters but they are not permitted
# characters in NTFS filesystems.
property_string=`echo "$image_name" | { grep -oP '(?<=-)(?!.*-).*[:;].*[:;].*$' || true; }`
IFS=':;' read -a props <<< "$property_string"
vmdk_disktype="${props[0]:-$vmdk_disktype}"
vmdk_adapter_type="${props[1]:-$vmdk_adapter_type}"
vmdk_net_adapter="${props[2]:-$vmdk_net_adapter}"
_upload_image "$image_name" bare vmdk "$image" vmware_disktype="$vmdk_disktype" vmware_adaptertype="$vmdk_adapter_type" hw_vif_model="$vmdk_net_adapter"
return
fi
# XenServer-vhd-ovf-format images are provided as .vhd.tgz
# and should not be decompressed prior to loading
if [[ "$image_url" =~ '.vhd.tgz' ]]; then
image_name="${image_fname%.vhd.tgz}"
local force_vm_mode=""
if [[ "$image_name" =~ 'cirros' ]]; then
# Cirros VHD image currently only boots in PV mode.
# Nova defaults to PV for all VHD images, but
# the glance setting is needed for booting
# directly from volume.
force_vm_mode="vm_mode=xen"
fi
_upload_image "$image_name" ovf vhd "$image" $force_vm_mode
return
fi
# .xen-raw.tgz suggests a Xen capable raw image inside a tgz.
# and should not be decompressed prior to loading.
# Setting metadata, so PV mode is used.
if [[ "$image_url" =~ '.xen-raw.tgz' ]]; then
image_name="${image_fname%.xen-raw.tgz}"
_upload_image "$image_name" tgz raw "$image" vm_mode=xen
return
fi
if [[ "$image_url" =~ '.hds' ]]; then
image_name="${image_fname%.hds}"
vm_mode=${image_name##*-}
if [[ $vm_mode != 'exe' && $vm_mode != 'hvm' ]]; then
die $LINENO "Unknown vm_mode=${vm_mode} for Virtuozzo image"
fi
_upload_image "$image_name" bare ploop "$image" vm_mode=$vm_mode
return
fi
local kernel=""
local ramdisk=""
local disk_format=""
local container_format=""
local unpack=""
local img_property=""
# NOTE(danms): If we're on libvirt/qemu or libvirt/kvm, set the hw_rng_model
# to libvirt in the image properties.
if [[ "$VIRT_DRIVER" == "libvirt" ]]; then
if [[ "$LIBVIRT_TYPE" == "qemu" || "$LIBVIRT_TYPE" == "kvm" ]]; then
img_property="hw_rng_model=virtio"
fi
fi
case "$image_fname" in
*.tar.gz|*.tgz)
# Extract ami and aki files
[ "${image_fname%.tar.gz}" != "$image_fname" ] &&
image_name="${image_fname%.tar.gz}" ||
image_name="${image_fname%.tgz}"
local xdir="$FILES/images/$image_name"
rm -Rf "$xdir";
mkdir "$xdir"
tar -zxf $image -C "$xdir"
kernel=$(for f in "$xdir/"*-vmlinuz* "$xdir/"aki-*/image; do
[ -f "$f" ] && echo "$f" && break; done; true)
ramdisk=$(for f in "$xdir/"*-initrd* "$xdir/"ari-*/image; do
[ -f "$f" ] && echo "$f" && break; done; true)
image=$(for f in "$xdir/"*.img "$xdir/"ami-*/image; do
[ -f "$f" ] && echo "$f" && break; done; true)
if [[ -z "$image_name" ]]; then
image_name=$(basename "$image" ".img")
fi
;;
*.img)
image_name=$(basename "$image" ".img")
local format
format=$(qemu-img info ${image} | awk '/^file format/ { print $3; exit }')
if [[ ",qcow2,raw,vdi,vmdk,vpc," =~ ",$format," ]]; then
disk_format=$format
else
disk_format=raw
fi
container_format=bare
;;
*.img.gz)
image_name=$(basename "$image" ".img.gz")
disk_format=raw
container_format=bare
unpack=zcat
;;
*.img.bz2)
image_name=$(basename "$image" ".img.bz2")
disk_format=qcow2
container_format=bare
unpack=bunzip2
;;
*.qcow2)
image_name=$(basename "$image" ".qcow2")
disk_format=qcow2
container_format=bare
;;
*.qcow2.xz)
image_name=$(basename "$image" ".qcow2.xz")
disk_format=qcow2
container_format=bare
unpack=unxz
;;
*.raw)
image_name=$(basename "$image" ".raw")
disk_format=raw
container_format=bare
;;
*.iso)
image_name=$(basename "$image" ".iso")
disk_format=iso
container_format=bare
;;
*.vhd|*.vhdx|*.vhd.gz|*.vhdx.gz)
local extension="${image_fname#*.}"
image_name=$(basename "$image" ".$extension")
disk_format=$(echo $image_fname | grep -oP '(?<=\.)vhdx?(?=\.|$)')
container_format=bare
if [ "${image_fname##*.}" == "gz" ]; then
unpack=zcat
fi
;;
*) echo "Do not know what to do with $image_fname"; false;;
esac
if is_arch "ppc64le" || is_arch "ppc64" || is_arch "ppc"; then
img_property="$img_property hw_cdrom_bus=scsi os_command_line=console=hvc0"
fi
if is_arch "aarch64"; then
img_property="$img_property hw_machine_type=virt hw_cdrom_bus=scsi hw_scsi_model=virtio-scsi os_command_line='console=ttyAMA0'"
fi
if [ "$container_format" = "bare" ]; then
if [ "$unpack" = "zcat" ]; then
_upload_image "$image_name" $container_format $disk_format <(zcat --force "$image") $img_property
elif [ "$unpack" = "bunzip2" ]; then
_upload_image "$image_name" $container_format $disk_format <(bunzip2 -cdk "$image") $img_property
elif [ "$unpack" = "unxz" ]; then
# NOTE(brtknr): unxz the file first and cleanup afterwards to
# prevent timeout while Glance tries to upload image (e.g. to Swift).
local tmp_dir
local image_path
tmp_dir=$(mktemp -d)
image_path="$tmp_dir/$image_name"
unxz -cv "${image}" > "$image_path"
_upload_image "$image_name" $container_format $disk_format "$image_path" $img_property
rm -rf $tmp_dir
else
_upload_image "$image_name" $container_format $disk_format "$image" $img_property
fi
else
# Use glance client to add the kernel the root filesystem.
# We parse the results of the first upload to get the glance ID of the
# kernel for use when uploading the root filesystem.
local kernel_id="" ramdisk_id="";
if [ -n "$kernel" ]; then
kernel_id=$(openstack --os-cloud=devstack-admin --os-region-name="$REGION_NAME" image create "$image_name-kernel" $(_image_properties_to_arg $img_property) --public --container-format aki --disk-format aki < "$kernel" | grep ' id ' | get_field 2)
fi
if [ -n "$ramdisk" ]; then
ramdisk_id=$(openstack --os-cloud=devstack-admin --os-region-name="$REGION_NAME" image create "$image_name-ramdisk" $(_image_properties_to_arg $img_property) --public --container-format ari --disk-format ari < "$ramdisk" | grep ' id ' | get_field 2)
fi
_upload_image "${image_name%.img}" ami ami "$image" ${kernel_id:+ kernel_id=$kernel_id} ${ramdisk_id:+ ramdisk_id=$ramdisk_id} $img_property
fi
}
# Set the database backend to use
# When called from stackrc/localrc DATABASE_BACKENDS has not been
# initialized yet, just save the configuration selection and call back later
# to validate it.
#
# ``$1`` - the name of the database backend to use (mysql, postgresql, ...)
function use_database {
if [[ -z "$DATABASE_BACKENDS" ]]; then
# No backends registered means this is likely called from ``localrc``
# This is now deprecated usage
DATABASE_TYPE=$1
deprecated "The database backend needs to be properly set in ENABLED_SERVICES; use_database is deprecated localrc"
else
# This should no longer get called...here for posterity
use_exclusive_service DATABASE_BACKENDS DATABASE_TYPE $1
fi
}
#Macro for curl statements. curl requires -g option for literal IPv6 addresses.
CURL_GET="${CURL_GET:-curl -g}"
# Wait for an HTTP server to start answering requests
# wait_for_service timeout url
#
# If the service we want is behind a proxy, the proxy may be available
# before the service. Compliant proxies will return a 503 in this case
# Loop until we get something else.
# Also check for the case where there is no proxy and the service just
# hasn't started yet. curl returns 7 for Failed to connect to host.
function wait_for_service {
local timeout=$1
local url=$2
local rval=0
time_start "wait_for_service"
timeout $timeout bash -x <<EOF || rval=$?
while [[ \$( ${CURL_GET} -k --noproxy '*' -s -o /dev/null -w '%{http_code}' ${url} ) == 503 || \$? -eq 7 ]]; do
sleep 1
done
EOF
time_stop "wait_for_service"
return $rval
}
function wait_for_compute {
local timeout=$1
local rval=0
local compute_hostname
time_start "wait_for_service"
compute_hostname=$(iniget $NOVA_CONF DEFAULT host)
if [[ -z $compute_hostname ]]; then
compute_hostname=$(hostname)
fi
timeout $timeout bash -x <<EOF || rval=$?
ID=""
while [[ "\$ID" == "" ]]; do
sleep 1
if [[ "$VIRT_DRIVER" = 'fake' ]]; then
# When using the fake driver the compute hostnames have a suffix of 1 to NUMBER_FAKE_NOVA_COMPUTE
ID=\$(openstack --os-cloud devstack-admin --os-region "$REGION_NAME" compute service list --host `hostname`1 --service nova-compute -c ID -f value)
else
ID=\$(openstack --os-cloud devstack-admin --os-region "$REGION_NAME" compute service list --host "$compute_hostname" --service nova-compute -c ID -f value)
fi
done
EOF
time_stop "wait_for_service"
# Figure out what's happening on platforms where this doesn't work
if [[ "$rval" != 0 ]]; then
echo "Didn't find service registered by hostname after $timeout seconds"
openstack --os-cloud devstack-admin --os-region "$REGION_NAME" compute service list
fi
return $rval
}
# ping check
# Uses globals ``ENABLED_SERVICES``, ``TOP_DIR``, ``PRIVATE_NETWORK``
# ping_check <ip> [boot-timeout] [from_net] [expected]
function ping_check {
local ip=$1
local timeout=${2:-30}
local from_net=${3:-""}
local expected=${4:-True}
local op="!"
local failmsg="[Fail] Couldn't ping server"
local ping_cmd="ping"
# if we don't specify a from_net we're expecting things to work
# fine from our local box.
if [[ -n "$from_net" ]]; then
# TODO(stephenfin): Is there any way neutron could be disabled now?
if is_service_enabled neutron; then
ping_cmd="$TOP_DIR/tools/ping_neutron.sh $from_net"
fi
fi
# inverse the logic if we're testing no connectivity
if [[ "$expected" != "True" ]]; then
op=""
failmsg="[Fail] Could ping server"
fi
# Because we've transformed this command so many times, print it
# out at the end.
local check_command="while $op $ping_cmd -c1 -w1 $ip; do sleep 1; done"
echo "Checking connectivity with $check_command"
if ! timeout $timeout sh -c "$check_command"; then
die $LINENO $failmsg
fi
}
# Get ip of instance
function get_instance_ip {
local vm_id=$1
local network_name=$2
local addresses
local ip
addresses=$(openstack server show -c addresses -f value "$vm_id")
ip=$(echo $addresses | sed -n "s/^.*$network_name=\([0-9\.]*\).*$/\1/p")
if [[ $ip = "" ]];then
echo "addresses of server $vm_id : $addresses"
die $LINENO "[Fail] Couldn't get ipaddress of VM"
fi
echo $ip
}
# ssh check
# ssh_check net-name key-file floating-ip default-user active-timeout
function ssh_check {
if is_service_enabled neutron; then
_ssh_check_neutron "$1" $2 $3 $4 $5
return
fi
_ssh_check_novanet "$1" $2 $3 $4 $5
}
function _ssh_check_novanet {
local NET_NAME=$1
local KEY_FILE=$2
local FLOATING_IP=$3
local DEFAULT_INSTANCE_USER=$4
local ACTIVE_TIMEOUT=$5
local probe_cmd=""
if ! timeout $ACTIVE_TIMEOUT sh -c "while ! ssh -o StrictHostKeyChecking=no -i $KEY_FILE ${DEFAULT_INSTANCE_USER}@$FLOATING_IP echo success; do sleep 1; done"; then
die $LINENO "server didn't become ssh-able!"
fi
}
# Get the location of the $module-rootwrap executables, where module is cinder
# or nova.
# get_rootwrap_location module
function get_rootwrap_location {
local module=$1
echo "$(get_python_exec_prefix)/$module-rootwrap"
}
# Path permissions sanity check
# check_path_perm_sanity path
function check_path_perm_sanity {
# Ensure no element of the path has 0700 permissions, which is very
# likely to cause issues for daemons. Inspired by default 0700
# homedir permissions on RHEL and common practice of making DEST in
# the stack user's homedir.
local real_path
real_path=$(readlink -f $1)
local rebuilt_path=""
for i in $(echo ${real_path} | tr "/" " "); do
rebuilt_path=$rebuilt_path"/"$i
if [[ $(stat -c '%a' ${rebuilt_path}) = 700 ]]; then
echo "*** DEST path element"
echo "*** ${rebuilt_path}"
echo "*** appears to have 0700 permissions."
echo "*** This is very likely to cause fatal issues for DevStack daemons."
if [[ -n "$SKIP_PATH_SANITY" ]]; then
return
else
echo "*** Set SKIP_PATH_SANITY to skip this check"
die $LINENO "Invalid path permissions"
fi
fi
done
}
# vercmp ver1 op ver2
# Compare VER1 to VER2
# - op is one of < <= == >= >
# - returns true if satisified
# e.g.
# if vercmp 1.0 "<" 2.0; then
# ...
# fi
function vercmp {
local v1=$1
local op=$2
local v2=$3
local result
# sort the two numbers with sort's "-V" argument. Based on if v2
# swapped places with v1, we can determine ordering.
result=$(echo -e "$v1\n$v2" | sort -V | head -1)
case $op in
"==")
[ "$v1" = "$v2" ]
return
;;
">")
[ "$v1" != "$v2" ] && [ "$result" = "$v2" ]
return
;;
"<")
[ "$v1" != "$v2" ] && [ "$result" = "$v1" ]
return
;;
">=")
[ "$result" = "$v2" ]
return
;;
"<=")
[ "$result" = "$v1" ]
return
;;
*)
die $LINENO "unrecognised op: $op"
;;
esac
}
# This sets up defaults we like in devstack for logging for tracking
# down issues, and makes sure everything is done the same between
# projects.
# NOTE(jh): Historically this function switched between three different
# functions: setup_systemd_logging, setup_colorized_logging and
# setup_standard_logging_identity. Since we always run with systemd now,
# this could be cleaned up, but the other functions may still be in use
# by plugins. Since deprecations haven't worked in the past, we'll just
# leave them in place.
function setup_logging {
setup_systemd_logging $1
}
# This function sets log formatting options for colorizing log
# output to stdout. It is meant to be called by lib modules.
function setup_colorized_logging {
local conf_file=$1
# Add color to logging output
iniset $conf_file DEFAULT logging_context_format_string "%(asctime)s.%(msecs)03d %(color)s%(levelname)s %(name)s [[01;36m%(request_id)s [00;36m%(project_name)s %(user_name)s%(color)s] [01;35m%(instance)s%(color)s%(message)s[00m"
iniset $conf_file DEFAULT logging_default_format_string "%(asctime)s.%(msecs)03d %(color)s%(levelname)s %(name)s [[00;36m-%(color)s] [01;35m%(instance)s%(color)s%(message)s[00m"
iniset $conf_file DEFAULT logging_debug_format_suffix "[00;33mfrom (pid=%(process)d) %(funcName)s %(pathname)s:%(lineno)d[00m"
iniset $conf_file DEFAULT logging_exception_prefix "%(color)s%(asctime)s.%(msecs)03d TRACE %(name)s [01;35m%(instance)s[00m"
}
function setup_systemd_logging {
local conf_file=$1
# NOTE(sdague): this is a nice to have, and means we're using the
# native systemd path, which provides for things like search on
# request-id. However, there may be an eventlet interaction here,
# so going off for now.
USE_JOURNAL=$(trueorfalse False USE_JOURNAL)
local pidstr=""
if [[ "$USE_JOURNAL" == "True" ]]; then
iniset $conf_file DEFAULT use_journal "True"
# if we are using the journal directly, our process id is already correct
else
pidstr="(pid=%(process)d) "
fi
iniset $conf_file DEFAULT logging_debug_format_suffix "[00;33m{{${pidstr}%(funcName)s %(pathname)s:%(lineno)d}}[00m"
iniset $conf_file DEFAULT logging_context_format_string "%(color)s%(levelname)s %(name)s [[01;36m%(global_request_id)s %(request_id)s [00;36m%(project_name)s %(user_name)s%(color)s] [01;35m%(instance)s%(color)s%(message)s[00m"
iniset $conf_file DEFAULT logging_default_format_string "%(color)s%(levelname)s %(name)s [[00;36m-%(color)s] [01;35m%(instance)s%(color)s%(message)s[00m"
iniset $conf_file DEFAULT logging_exception_prefix "ERROR %(name)s [01;35m%(instance)s[00m"
}
function setup_standard_logging_identity {
local conf_file=$1
iniset $conf_file DEFAULT logging_user_identity_format "%(project_name)s %(user_name)s"
}
# These functions are provided for basic fall-back functionality for
# projects that include parts of DevStack (Grenade). stack.sh will
# override these with more specific versions for DevStack (with fancy
# spinners, etc). We never override an existing version
if ! function_exists echo_summary; then
function echo_summary {
echo $@
}
fi
if ! function_exists echo_nolog; then
function echo_nolog {
echo $@
}
fi
# create_disk - Create backing disk
function create_disk {
local node_number
local disk_image=${1}
local storage_data_dir=${2}
local loopback_disk_size=${3}
# Create a loopback disk and format it to XFS.
if [[ -e ${disk_image} ]]; then
if egrep -q ${storage_data_dir} /proc/mounts; then
sudo umount ${storage_data_dir}
sudo rm -f ${disk_image}
fi
fi
sudo mkdir -p ${storage_data_dir}/drives/images
sudo truncate -s ${loopback_disk_size} ${disk_image}
# Make a fresh XFS filesystem. Use bigger inodes so xattr can fit in
# a single inode. Keeping the default inode size (256) will result in multiple
# inodes being used to store xattr. Retrieving the xattr will be slower
# since we have to read multiple inodes. This statement is true for both
# Swift and Ceph.
sudo mkfs.xfs -f -i size=1024 ${disk_image}
# Mount the disk with mount options to make it as efficient as possible
if ! egrep -q ${storage_data_dir} /proc/mounts; then
sudo mount -t xfs -o loop,noatime,nodiratime,logbufs=8 \
${disk_image} ${storage_data_dir}
fi
}
# set_mtu - Set MTU on a device
function set_mtu {
local dev=$1
local mtu=$2
sudo ip link set mtu $mtu dev $dev
}
# running_in_container - Returns true otherwise false
function running_in_container {
[[ $(systemd-detect-virt --container) != 'none' ]]
}
# enable_kernel_bridge_firewall - Enable kernel support for bridge firewalling
function enable_kernel_bridge_firewall {
# Load bridge module. This module provides access to firewall for bridged
# frames; and also on older kernels (pre-3.18) it provides sysctl knobs to
# enable/disable bridge firewalling
sudo modprobe bridge
# For newer kernels (3.18+), those sysctl settings are split into a separate
# kernel module (br_netfilter). Load it too, if present.
sudo modprobe br_netfilter 2>> /dev/null || :
# Enable bridge firewalling in case it's disabled in kernel (upstream
# default is enabled, but some distributions may decide to change it).
# This is at least needed for RHEL 7.2 and earlier releases.
for proto in ip ip6; do
sudo sysctl -w net.bridge.bridge-nf-call-${proto}tables=1
done
}
# Set a systemd system override
#
# This sets a system-side override in system.conf. A per-service
# override would be /etc/systemd/system/${service}.service/override.conf
function set_systemd_override {
local key="$1"
local value="$2"
local sysconf="/etc/systemd/system.conf"
iniset -sudo "${sysconf}" "Manager" "$key" "$value"
echo "Set systemd system override for ${key}=${value}"
sudo systemctl daemon-reload
}
# Get a random port from the local port range
#
# This function returns an available port in the local port range. The search
# order is not truly random, but should be considered a random value by the
# user because it depends on the state of your local system.
function get_random_port {
read lower_port upper_port < /proc/sys/net/ipv4/ip_local_port_range
while true; do
for (( port = upper_port ; port >= lower_port ; port-- )); do
sudo lsof -i ":$port" &> /dev/null
if [[ $? > 0 ]] ; then
break 2
fi
done
done
echo $port
}
# Save some state information
#
# Write out various useful state information to /etc/devstack-version
function write_devstack_version {
cat - <<EOF | sudo tee /etc/devstack-version >/dev/null
DevStack Version: ${DEVSTACK_SERIES}
Change: $(git log --format="%H %s %ci" -1)
OS Version: ${os_VENDOR} ${os_RELEASE} ${os_CODENAME}
EOF
}
# Restore xtrace
$_XTRACE_FUNCTIONS
# Local variables:
# mode: shell-script
# End: