summaryrefslogtreecommitdiff
path: root/tools/ds-identify
diff options
context:
space:
mode:
Diffstat (limited to 'tools/ds-identify')
-rwxr-xr-xtools/ds-identify136
1 files changed, 114 insertions, 22 deletions
diff --git a/tools/ds-identify b/tools/ds-identify
index b78b2731..c93d4a77 100755
--- a/tools/ds-identify
+++ b/tools/ds-identify
@@ -124,7 +124,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 Hetzner IBMCloud Oracle"
+OVF SmartOS Scaleway Hetzner IBMCloud Oracle Exoscale RbxCloud"
DI_DSLIST=""
DI_MODE=""
DI_ON_FOUND=""
@@ -179,13 +179,39 @@ debug() {
echo "$@" 1>&3
}
+dmi_decode() {
+ local sys_field="$1" dmi_field="" val=""
+ command -v dmidecode >/dev/null 2>&1 || {
+ warn "No dmidecode program. Cannot read $sys_field."
+ return 1
+ }
+ case "$1" in
+ sys_vendor) dmi_field="system-manufacturer";;
+ product_name) dmi_field="system-product-name";;
+ product_uuid) dmi_field="system-uuid";;
+ product_serial) dmi_field="system-serial-number";;
+ chassis_asset_tag) dmi_field="chassis-asset-tag";;
+ *) error "Unknown field $sys_field. Cannot call dmidecode."
+ return 1;;
+ esac
+ val=$(dmidecode --quiet "--string=$dmi_field" 2>/dev/null) || return 1
+ _RET="$val"
+}
+
get_dmi_field() {
local path="${PATH_SYS_CLASS_DMI_ID}/$1"
- if [ ! -f "$path" ] || [ ! -r "$path" ]; then
- _RET="$UNAVAILABLE"
+ _RET="$UNAVAILABLE"
+ if [ -d "${PATH_SYS_CLASS_DMI_ID}" ]; then
+ if [ -f "$path" ] && [ -r "$path" ]; then
+ read _RET < "${path}" || _RET="$ERROR"
+ return
+ fi
+ # if `/sys/class/dmi/id` exists, but not the object we're looking for,
+ # do *not* fallback to dmidecode!
return
fi
- read _RET < "${path}" || _RET="$ERROR"
+ dmi_decode "$1" || _RET="$ERROR"
+ return
}
block_dev_with_label() {
@@ -267,6 +293,31 @@ detect_virt() {
if [ $r -eq 0 ] || { [ $r -ne 0 ] && [ "$out" = "none" ]; }; then
virt="$out"
fi
+ elif [ "$DI_UNAME_KERNEL_NAME" = "FreeBSD" ]; then
+ # Map FreeBSD's vm_guest names to those systemd-detect-virt that
+ # don't match up. See
+ # https://github.com/freebsd/freebsd/blob/master/sys/kern/subr_param.c#L144-L160
+ # https://www.freedesktop.org/software/systemd/man/systemd-detect-virt.html
+ #
+ # systemd | kern.vm_guest
+ # ---------------------+---------------
+ # none | none
+ # kvm | kvm
+ # vmware | vmware
+ # microsoft | hv
+ # oracle | vbox
+ # xen | xen
+ # parallels | parallels
+ # bhyve | bhyve
+ # vm-other | generic
+ out=$(sysctl -qn kern.vm_guest 2>/dev/null) && {
+ case "$out" in
+ hv) virt="microsoft" ;;
+ vbox) virt="oracle" ;;
+ generic) "vm-other";;
+ *) virt="$out"
+ esac
+ }
fi
_RET="$virt"
}
@@ -553,6 +604,11 @@ dscheck_CloudStack() {
return $DS_NOT_FOUND
}
+dscheck_Exoscale() {
+ dmi_product_name_matches "Exoscale*" && return $DS_FOUND
+ return $DS_NOT_FOUND
+}
+
dscheck_CloudSigma() {
# http://paste.ubuntu.com/23624795/
dmi_product_name_matches "CloudSigma" && return $DS_FOUND
@@ -620,7 +676,7 @@ dscheck_MAAS() {
}
dscheck_NoCloud() {
- local fslabel="cidata" d=""
+ local fslabel="cidata CIDATA" d=""
case " ${DI_KERNEL_CMDLINE} " in
*\ ds=nocloud*) return ${DS_FOUND};;
esac
@@ -632,9 +688,10 @@ dscheck_NoCloud() {
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
+ if has_fs_with_label $fslabel; then
return ${DS_FOUND}
fi
+
return ${DS_NOT_FOUND}
}
@@ -696,6 +753,11 @@ dscheck_OpenNebula() {
return ${DS_NOT_FOUND}
}
+dscheck_RbxCloud() {
+ has_fs_with_label "CLOUDMD" "cloudmd" && return ${DS_FOUND}
+ return ${DS_NOT_FOUND}
+}
+
ovf_vmware_guest_customization() {
# vmware guest customization
@@ -762,13 +824,37 @@ is_cdrom_ovf() {
# explicitly skip known labels of other types. rd_rdfe is azure.
case "$label" in
- config-2|CONFIG-2|rd_rdfe_stable*|cidata) return 1;;
+ config-2|CONFIG-2|rd_rdfe_stable*|cidata|CIDATA) return 1;;
esac
+ # skip device which size is 10MB or larger
+ local size="" sfile="${PATH_SYS_CLASS_BLOCK}/${dev##*/}/size"
+ [ -f "$sfile" ] || return 1
+ read size <"$sfile" || { warn "failed reading from $sfile"; return 1; }
+ # size is in 512 byte units. so convert to MB (integer division)
+ if [ $((size/2048)) -ge 10 ]; then
+ debug 2 "$dev: size $((size/2048))MB is considered too large for OVF"
+ return 1
+ fi
+
local idstr="http://schemas.dmtf.org/ovf/environment/1"
grep --quiet --ignore-case "$idstr" "${PATH_ROOT}$dev"
}
+has_ovf_cdrom() {
+ # DI_ISO9660_DEVS is <device>=label,<device>=label2
+ # like /dev/sr0=OVF-TRANSPORT,/dev/other=with spaces
+ if [ "${DI_ISO9660_DEVS#${UNAVAILABLE}:}" = "${DI_ISO9660_DEVS}" ]; then
+ local oifs="$IFS"
+ # shellcheck disable=2086
+ { IFS=","; set -- ${DI_ISO9660_DEVS}; IFS="$oifs"; }
+ for tok in "$@"; do
+ is_cdrom_ovf "${tok%%=*}" "${tok#*=}" && return 0
+ done
+ fi
+ return 1
+}
+
dscheck_OVF() {
check_seed_dir ovf ovf-env.xml && return "${DS_FOUND}"
@@ -779,20 +865,9 @@ dscheck_OVF() {
ovf_vmware_transport_guestinfo && return "${DS_FOUND}"
- # DI_ISO9660_DEVS is <device>=label,<device>=label2
- # like /dev/sr0=OVF-TRANSPORT,/dev/other=with spaces
- if [ "${DI_ISO9660_DEVS#${UNAVAILABLE}:}" = "${DI_ISO9660_DEVS}" ]; then
- local oifs="$IFS"
- # shellcheck disable=2086
- { IFS=","; set -- ${DI_ISO9660_DEVS}; IFS="$oifs"; }
- for tok in "$@"; do
- is_cdrom_ovf "${tok%%=*}" "${tok#*=}" && return $DS_FOUND
- done
- fi
+ has_ovf_cdrom && return "${DS_FOUND}"
- if ovf_vmware_guest_customization; then
- return ${DS_FOUND}
- fi
+ ovf_vmware_guest_customization && return "${DS_FOUND}"
return ${DS_NOT_FOUND}
}
@@ -872,9 +947,18 @@ ec2_identify_platform() {
local default="$1"
local serial="${DI_DMI_PRODUCT_SERIAL}"
- # brightbox https://bugs.launchpad.net/cloud-init/+bug/1661693
case "$serial" in
- *brightbox.com) _RET="Brightbox"; return 0;;
+ *.brightbox.com) _RET="Brightbox"; return 0;;
+ esac
+
+ local asset_tag="${DI_DMI_CHASSIS_ASSET_TAG}"
+ case "$asset_tag" in
+ *.zstack.io) _RET="ZStack"; return 0;;
+ esac
+
+ local vendor="${DI_DMI_SYS_VENDOR}"
+ case "$vendor" in
+ e24cloud) _RET="E24cloud"; return 0;;
esac
# AWS http://docs.aws.amazon.com/AWSEC2/
@@ -978,6 +1062,14 @@ dscheck_OpenStack() {
return ${DS_FOUND}
fi
+ # LP: #1669875 : allow identification of OpenStack by asset tag
+ if dmi_chassis_asset_tag_matches "$nova"; then
+ return ${DS_FOUND}
+ fi
+ if dmi_chassis_asset_tag_matches "$compute"; then
+ return ${DS_FOUND}
+ fi
+
# LP: #1715241 : arch other than intel are not identified properly.
case "$DI_UNAME_MACHINE" in
i?86|x86_64) :;;