summaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rwxr-xr-xtools/ds-identify127
-rwxr-xr-xtools/pipremove14
-rwxr-xr-xtools/run-centos91
3 files changed, 191 insertions, 41 deletions
diff --git a/tools/ds-identify b/tools/ds-identify
index cd268242..9a2db5c4 100755
--- a/tools/ds-identify
+++ b/tools/ds-identify
@@ -92,6 +92,7 @@ DI_DMI_SYS_VENDOR=""
DI_DMI_PRODUCT_SERIAL=""
DI_DMI_PRODUCT_UUID=""
DI_FS_LABELS=""
+DI_FS_UUIDS=""
DI_ISO9660_DEVS=""
DI_KERNEL_CMDLINE=""
DI_VIRT=""
@@ -114,7 +115,7 @@ DI_DSNAME=""
# be searched if there is no setting found in config.
DI_DSLIST_DEFAULT="MAAS ConfigDrive NoCloud AltCloud Azure Bigstep \
CloudSigma CloudStack DigitalOcean AliYun Ec2 GCE OpenNebula OpenStack \
-OVF SmartOS Scaleway"
+OVF SmartOS Scaleway Hetzner IBMCloud"
DI_DSLIST=""
DI_MODE=""
DI_ON_FOUND=""
@@ -123,6 +124,8 @@ DI_ON_NOTFOUND=""
DI_EC2_STRICT_ID_DEFAULT="true"
+_IS_IBM_CLOUD=""
+
error() {
set -- "ERROR:" "$@";
debug 0 "$@"
@@ -186,7 +189,8 @@ block_dev_with_label() {
read_fs_info() {
cached "${DI_BLKID_OUTPUT}" && return 0
# do not rely on links in /dev/disk which might not be present yet.
- # note that older blkid versions do not report DEVNAME in 'export' output.
+ # Note that blkid < 2.22 (centos6, trusty) do not output DEVNAME.
+ # that means that DI_ISO9660_DEVS will not be set.
if is_container; then
# blkid will in a container, or at least currently in lxd
# not provide useful information.
@@ -195,7 +199,7 @@ read_fs_info() {
return
fi
local oifs="$IFS" line="" delim=","
- local ret=0 out="" labels="" dev="" label="" ftype="" isodevs=""
+ local ret=0 out="" labels="" dev="" label="" ftype="" isodevs="" uuids=""
out=$(blkid -c /dev/null -o export) || {
ret=$?
error "failed running [$ret]: blkid -c /dev/null -o export"
@@ -203,22 +207,29 @@ read_fs_info() {
DI_ISO9660_DEVS="$UNAVAILABLE:error"
return $ret
}
- IFS="$CR"
- set -- $out
- IFS="$oifs"
- for line in "$@" ""; do
+ # 'set --' will collapse multiple consecutive entries in IFS for
+ # whitespace characters (\n, tab, " ") so we cannot rely on getting
+ # empty lines in "$@" below.
+ IFS="$CR"; set -- $out; IFS="$oifs"
+
+ for line in "$@"; do
case "${line}" in
- DEVNAME=*) dev=${line#DEVNAME=};;
+ DEVNAME=*)
+ [ -n "$dev" -a "$ftype" = "iso9660" ] &&
+ isodevs="${isodevs} ${dev}=$label"
+ ftype=""; dev=""; label="";
+ dev=${line#DEVNAME=};;
LABEL=*) label="${line#LABEL=}";
labels="${labels}${line#LABEL=}${delim}";;
TYPE=*) ftype=${line#TYPE=};;
- "") if [ "$ftype" = "iso9660" ]; then
- isodevs="${isodevs} ${dev}=$label"
- fi
- ftype=""; devname=""; label="";
+ UUID=*) uuids="${uuids}${line#UUID=}$delim";;
esac
done
+ [ -n "$dev" -a "$ftype" = "iso9660" ] &&
+ isodevs="${isodevs} ${dev}=$label"
+
DI_FS_LABELS="${labels%${delim}}"
+ DI_FS_UUIDS="${uuids%${delim}}"
DI_ISO9660_DEVS="${isodevs# }"
}
@@ -431,14 +442,25 @@ dmi_sys_vendor_is() {
[ "${DI_DMI_SYS_VENDOR}" = "$1" ]
}
-has_fs_with_label() {
- local label="$1"
- case ",${DI_FS_LABELS}," in
- *,$label,*) return 0;;
+has_fs_with_uuid() {
+ case ",${DI_FS_UUIDS}," in
+ *,$1,*) return 0;;
esac
return 1
}
+has_fs_with_label() {
+ # has_fs_with_label(label1[ ,label2 ..])
+ # return 0 if a there is a filesystem that matches any of the labels.
+ local label=""
+ for label in "$@"; do
+ case ",${DI_FS_LABELS}," in
+ *,$label,*) return 0;;
+ esac
+ done
+ return 1
+}
+
nocase_equal() {
# nocase_equal(a, b)
# return 0 if case insenstive comparision a.lower() == b.lower()
@@ -470,6 +492,16 @@ check_seed_dir() {
return 0
}
+check_writable_seed_dir() {
+ # ubuntu core bind-mounts /writable/system-data/var/lib/cloud
+ # over the top of /var/lib/cloud, but the mount might not be done yet.
+ local wdir="/writable/system-data"
+ [ -d "${PATH_ROOT}$wdir" ] || return 1
+ local sdir="${PATH_ROOT}$wdir${PATH_VAR_LIB_CLOUD#${PATH_ROOT}}"
+ local PATH_VAR_LIB_CLOUD="$sdir"
+ check_seed_dir "$@"
+}
+
probe_floppy() {
cached "${STATE_FLOPPY_PROBED}" && return "${STATE_FLOPPY_PROBED}"
local fpath=/dev/floppy
@@ -567,8 +599,11 @@ dscheck_NoCloud() {
case " ${DI_DMI_PRODUCT_SERIAL} " in
*\ ds=nocloud*) return ${DS_FOUND};;
esac
+
+ is_ibm_cloud && return ${DS_NOT_FOUND}
for d in nocloud nocloud-net; do
check_seed_dir "$d" meta-data user-data && return ${DS_FOUND}
+ check_writable_seed_dir "$d" meta-data user-data && return ${DS_FOUND}
done
if has_fs_with_label "${fslabel}"; then
return ${DS_FOUND}
@@ -577,9 +612,8 @@ dscheck_NoCloud() {
}
check_configdrive_v2() {
- if has_fs_with_label "config-2"; then
- return ${DS_FOUND}
- elif has_fs_with_label "CONFIG-2"; then
+ is_ibm_cloud && return ${DS_NOT_FOUND}
+ if has_fs_with_label CONFIG-2 config-2; then
return ${DS_FOUND}
fi
# look in /config-drive <vlc>/seed/config_drive for a directory
@@ -633,8 +667,9 @@ ovf_vmware_guest_customization() {
# we have to have the plugin to do vmware customization
local found="" pkg="" pre="${PATH_ROOT}/usr/lib"
+ local ppath="plugins/vmsvc/libdeployPkgPlugin.so"
for pkg in vmware-tools open-vm-tools; do
- if [ -f "$pre/$pkg/plugins/vmsvc/libdeployPkgPlugin.so" ]; then
+ if [ -f "$pre/$pkg/$ppath" -o -f "${pre}64/$pkg/$ppath" ]; then
found="$pkg"; break;
fi
done
@@ -685,15 +720,12 @@ dscheck_OVF() {
# Azure provides ovf. Skip false positive by dis-allowing.
is_azure_chassis && return $DS_NOT_FOUND
- local isodevs="${DI_ISO9660_DEVS}"
- case "$isodevs" in
- ""|$UNAVAILABLE:*) return ${DS_NOT_FOUND};;
- esac
-
# DI_ISO9660_DEVS is <device>=label, like /dev/sr0=OVF-TRANSPORT
- for tok in $isodevs; do
- is_cdrom_ovf "${tok%%=*}" "${tok#*=}" && return $DS_FOUND
- done
+ if [ "${DI_ISO9660_DEVS#${UNAVAILABLE}:}" = "${DI_ISO9660_DEVS}" ]; then
+ for tok in ${DI_ISO9660_DEVS}; do
+ is_cdrom_ovf "${tok%%=*}" "${tok#*=}" && return $DS_FOUND
+ done
+ fi
if ovf_vmware_guest_customization; then
return ${DS_FOUND}
@@ -879,6 +911,10 @@ dscheck_OpenStack() {
return ${DS_FOUND}
fi
+ if dmi_chassis_asset_tag_matches "OpenTelekomCloud"; then
+ return ${DS_FOUND}
+ fi
+
# LP: #1715241 : arch other than intel are not identified properly.
case "$DI_UNAME_MACHINE" in
i?86|x86_64) :;;
@@ -964,6 +1000,41 @@ dscheck_Scaleway() {
return ${DS_NOT_FOUND}
}
+dscheck_Hetzner() {
+ dmi_sys_vendor_is Hetzner && return ${DS_FOUND}
+ return ${DS_NOT_FOUND}
+}
+
+is_ibm_provisioning() {
+ [ -f "${PATH_ROOT}/root/provisioningConfiguration.cfg" ]
+}
+
+is_ibm_cloud() {
+ cached "${_IS_IBM_CLOUD}" && return ${_IS_IBM_CLOUD}
+ local ret=1
+ if [ "$DI_VIRT" = "xen" ]; then
+ if is_ibm_provisioning; then
+ ret=0
+ elif has_fs_with_label METADATA metadata; then
+ ret=0
+ elif has_fs_with_uuid 9796-932E &&
+ has_fs_with_label CONFIG-2 config-2; then
+ ret=0
+ fi
+ fi
+ _IS_IBM_CLOUD=$ret
+ return $ret
+}
+
+dscheck_IBMCloud() {
+ if is_ibm_provisioning; then
+ debug 1 "cloud-init disabled during provisioning on IBMCloud"
+ return ${DS_NOT_FOUND}
+ fi
+ is_ibm_cloud && return ${DS_FOUND}
+ return ${DS_NOT_FOUND}
+}
+
collect_info() {
read_virt
read_pid1_product_name
diff --git a/tools/pipremove b/tools/pipremove
new file mode 100755
index 00000000..f8f4ff11
--- /dev/null
+++ b/tools/pipremove
@@ -0,0 +1,14 @@
+#!/usr/bin/python3
+import subprocess
+import sys
+
+for pkg in sys.argv[1:]:
+ try:
+ exec('import %s' % pkg) # pylint: disable=W0122
+ except ImportError:
+ continue
+ sys.stderr.write("%s removing package %s\n" % (sys.argv[0], pkg))
+ ret = subprocess.Popen(['pip', 'uninstall', '--yes', pkg]).wait()
+ if ret != 0:
+ sys.stderr.write("Failed to uninstall %s (%d)\n" % (pkg, ret))
+ sys.exit(ret)
diff --git a/tools/run-centos b/tools/run-centos
index d58ef3e8..cb241ee5 100755
--- a/tools/run-centos
+++ b/tools/run-centos
@@ -23,6 +23,9 @@ Usage: ${0##*/} [ options ] version
options:
-a | --artifact keep .rpm artifacts
+ --dirty apply local changes before running tests.
+ If not provided, a clean checkout of branch is tested.
+ Inside container, changes are in local-changes.diff.
-k | --keep keep container after tests
-r | --rpm build .rpm
-s | --srpm build .src.rpm
@@ -80,25 +83,84 @@ inside() {
inject_cloud_init(){
# take current cloud-init git dir and put it inside $name at
# ~$user/cloud-init.
- local name="$1" user="$2" top_d="" dname="" pstat=""
- top_d=$(git rev-parse --show-toplevel) || {
- errorrc "Failed to get git top level in $PWD";
+ local name="$1" user="$2" dirty="$3"
+ local changes="" top_d="" dname="cloud-init" pstat=""
+ local gitdir="" commitish=""
+ gitdir=$(git rev-parse --git-dir) || {
+ errorrc "Failed to get git dir in $PWD";
return
}
- dname=$(basename "${top_d}") || return
- debug 1 "collecting ${top_d} ($dname) into user $user in $name."
- tar -C "${top_d}/.." -cpf - "$dname" |
+ local t=${gitdir%/*}
+ case "$t" in
+ */worktrees)
+ if [ -f "${t%worktrees}/config" ]; then
+ gitdir="${t%worktrees}"
+ fi
+ esac
+
+ # attempt to get branch name.
+ commitish=$(git rev-parse --abbrev-ref HEAD) || {
+ errorrc "Failed git rev-parse --abbrev-ref HEAD"
+ return
+ }
+ if [ "$commitish" = "HEAD" ]; then
+ # detached head
+ commitish=$(git rev-parse HEAD) || {
+ errorrc "failed git rev-parse HEAD"
+ return
+ }
+ fi
+
+ local local_changes=false
+ if ! git diff --quiet "$commitish"; then
+ # there are local changes not committed.
+ local_changes=true
+ if [ "$dirty" = "false" ]; then
+ error "WARNING: You had uncommitted changes. Those changes will "
+ error "be put into 'local-changes.diff' inside the container. "
+ error "To test these changes you must pass --dirty."
+ fi
+ fi
+
+ debug 1 "collecting ${gitdir} ($dname) into user $user in $name."
+ tar -C "${gitdir}" -cpf - . |
inside_as "$name" "$user" sh -ec '
dname=$1
+ commitish=$2
rm -Rf "$dname"
+ mkdir -p $dname/.git
+ cd $dname/.git
tar -xpf -
- [ "$dname" = "cloud-init" ] || mv "$dname" cloud-init' \
- extract "$dname"
+ cd ..
+ git config core.bare false
+ out=$(git checkout $commitish 2>&1) ||
+ { echo "failed git checkout $commitish: $out" 1>&2; exit 1; }
+ out=$(git checkout . 2>&1) ||
+ { echo "failed git checkout .: $out" 1>&2; exit 1; }
+ ' extract "$dname" "$commitish"
[ "${PIPESTATUS[*]}" = "0 0" ] || {
- error "Failed to push tarball of '$top_d' into $name" \
+ error "Failed to push tarball of '$gitdir' into $name" \
" for user $user (dname=$dname)"
return 1
}
+
+ echo "local_changes=$local_changes dirty=$dirty"
+ if [ "$local_changes" = "true" ]; then
+ git diff "$commitish" |
+ inside_as "$name" "$user" sh -exc '
+ cd "$1"
+ if [ "$2" = "true" ]; then
+ git apply
+ else
+ cat > local-changes.diff
+ fi
+ ' insert_changes "$dname" "$dirty"
+ [ "${PIPESTATUS[*]}" = "0 0" ] || {
+ error "Failed to apply local changes."
+ return 1
+ }
+ fi
+
return 0
}
@@ -179,7 +241,7 @@ delete_container() {
main() {
local short_opts="ahkrsuv"
- local long_opts="artifact,help,keep,rpm,srpm,unittest,verbose"
+ local long_opts="artifact,dirty,help,keep,rpm,srpm,unittest,verbose"
local getopt_out=""
getopt_out=$(getopt --name "${0##*/}" \
--options "${short_opts}" --long "${long_opts}" -- "$@") &&
@@ -188,11 +250,13 @@ main() {
local cur="" next=""
local artifact="" keep="" rpm="" srpm="" unittest="" version=""
+ local dirty=false
while [ $# -ne 0 ]; do
cur="${1:-}"; next="${2:-}";
case "$cur" in
-a|--artifact) artifact=1;;
+ --dirty) dirty=true;;
-h|--help) Usage ; exit 0;;
-k|--keep) KEEP=true;;
-r|--rpm) rpm=1;;
@@ -231,7 +295,7 @@ main() {
inside "$name" useradd "$user"
debug 1 "inserting cloud-init"
- inject_cloud_init "$name" "$user" || {
+ inject_cloud_init "$name" "$user" "$dirty" || {
errorrc "FAIL: injecting cloud-init into $name failed."
return
}
@@ -244,12 +308,13 @@ main() {
local errors=0
inside_as_cd "$name" "$user" "$cdir" \
- sh -ec "git checkout .; git status" ||
+ sh -ec "git status" ||
{ errorrc "git checkout failed."; errors=$(($errors+1)); }
if [ -n "$unittest" ]; then
debug 1 "running unit tests."
- inside_as_cd "$name" "$user" "$cdir" nosetests tests/unittests ||
+ inside_as_cd "$name" "$user" "$cdir" \
+ nosetests tests/unittests cloudinit ||
{ errorrc "nosetests failed."; errors=$(($errors+1)); }
fi