summaryrefslogtreecommitdiff
path: root/tools/ds-identify
diff options
context:
space:
mode:
authorIgor Galić <me+github@igalic.co>2019-12-12 01:32:14 +0100
committerRyan Harper <ryan.harper@canonical.com>2019-12-11 18:32:14 -0600
commit11ef73e9500dcb325be85f8099a42d8d2e4caf95 (patch)
treee07ce0672b24d0b9aab37b668c2596841ce4b713 /tools/ds-identify
parent37ffa8d2bf1d56769a40fea26228b82e33ab1fff (diff)
downloadvyos-cloud-init-11ef73e9500dcb325be85f8099a42d8d2e4caf95.tar.gz
vyos-cloud-init-11ef73e9500dcb325be85f8099a42d8d2e4caf95.zip
ds_identify: if /sys is not available use dmidecode (#42)
On non-Linux systems, `/sys` won't be available. In these cases, we can query `dmidecode(8)` directly. This PR implements a dmi_decode function to query the same fields ds-identify would otherwise read from /sys. This path is taken when /sys isn't present. In addition to adding dmidecode support, non-Linux systems also need to map in virtualization detection as systemd-detect-virt is not present; on FreeBSD, use sysctl kern.vm_guest and provide a mapping[1] between BSD values and those that match with systemd-detect-virt[2]. 1. https://github.com/freebsd/freebsd/blob/master/sys/kern/subr_param.c#L149-L157 2. https://www.freedesktop.org/software/systemd/man/systemd-detect-virt.html LP: #1852442
Diffstat (limited to 'tools/ds-identify')
-rwxr-xr-xtools/ds-identify57
1 files changed, 54 insertions, 3 deletions
diff --git a/tools/ds-identify b/tools/ds-identify
index 20a99ee9..c93d4a77 100755
--- a/tools/ds-identify
+++ b/tools/ds-identify
@@ -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"
}