diff options
author | Igor Galić <me+github@igalic.co> | 2019-12-12 01:32:14 +0100 |
---|---|---|
committer | Ryan Harper <ryan.harper@canonical.com> | 2019-12-11 18:32:14 -0600 |
commit | 11ef73e9500dcb325be85f8099a42d8d2e4caf95 (patch) | |
tree | e07ce0672b24d0b9aab37b668c2596841ce4b713 /tools | |
parent | 37ffa8d2bf1d56769a40fea26228b82e33ab1fff (diff) | |
download | vyos-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')
-rwxr-xr-x | tools/ds-identify | 57 |
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" } |