diff options
Diffstat (limited to 'tools')
-rwxr-xr-x | tools/ds-identify | 127 | ||||
-rwxr-xr-x | tools/pipremove | 14 | ||||
-rwxr-xr-x | tools/run-centos | 91 |
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 |