From edcac70b2a99ce532dd5bca9a0b8fc5bf6dc5148 Mon Sep 17 00:00:00 2001
From: Dennis Camera <cdist@dtnr.ch>
Date: Wed, 21 Jul 2021 13:22:34 +0200
Subject: [PATCH] [explorer/machine_type] Reimplement

---
 cdist/conf/explorer/machine_type | 986 ++++++++++++++++++++++++++++---
 1 file changed, 904 insertions(+), 82 deletions(-)

diff --git a/cdist/conf/explorer/machine_type b/cdist/conf/explorer/machine_type
index 1c84f4d7..29f98849 100755
--- a/cdist/conf/explorer/machine_type
+++ b/cdist/conf/explorer/machine_type
@@ -1,8 +1,6 @@
-#!/bin/sh
+#!/bin/sh -e
 #
-# 2014 Daniel Heule  (hda at sfs.biz)
-# 2014 Thomas Oettli (otho at sfs.biz)
-# 2020 Evilham (contact at evilham.com)
+# 2021 Dennis Camera (cdist at dtnr.ch)
 #
 # This file is part of cdist.
 #
@@ -19,91 +17,915 @@
 # You should have received a copy of the GNU General Public License
 # along with cdist. If not, see <http://www.gnu.org/licenses/>.
 #
+# This explorer tries to determine what type of machine the target to be
+# configured is (container, virtual machine, bare-metal).
+#
+# It will print one line for each layer it can detect.
+# The format of all lines is: TYPE[ VERB VENDOR]
+#
+# VERB does not have a special meaning, it is just for better readability.
+#
+# e.g.
+# container on lxc
+# virtual by kvm-spapr
+#
+# The third word of each line can be composed of different parts concatenated with a `-'
+# (minus) character, with each component being a specification of the previous,
+# e.g.:
+#  - lxc-libvirt             (LXC container, managed by libvirt)
+#  - lpar-s390 / lpar-power  (LPAR running on IBM S/390 or POWER, respectively)
+#  - xen-hvm / xen-pv        (Xen HVM vs para-virtualization)
+#
+# If this explorer cannot determine any information it will print nothing.
+#
 
-os=$("$__explorer/os")
+# Add /sbin and /usr/sbin to the path so we can find system
+# binaries like dmidecode.
+PATH=$(getconf PATH 2>/dev/null) || PATH='/usr/bin:/bin'
+PATH="/sbin:/usr/sbin:${PATH}"
+export PATH
 
-vendor_string_to_machine_type() {
-    for vendor in vmware bochs kvm qemu virtualbox bhyve; do
-        if echo "${1}" | grep -q -i "${vendor}"; then
-            if [ "${vendor}" = "bochs" ] || [ "${vendor}" = "qemu" ]; then
-                vendor="kvm"
-            fi
-            echo "virtual_by_${vendor}"
-            exit
-        fi
-    done
+arch=$(uname -m | sed -e 's/i.86/i386/' -e 's/arm.*/arm/')
+uname_s=$(uname -s)
+
+
+is_command() { command -v "$1" >/dev/null 2>&1; }
+
+is_oneof() (
+	x=$1; shift
+	for y
+	do
+		test "${x}" = "${y}" || continue
+		return 0
+	done
+	return 1
+)
+
+tolower() { LC_ALL=C tr '[:upper:]' '[:lower:]'; }
+
+# shellcheck disable=SC2086
+glob_exists() { set -- $1; test -e "$1"; }
+
+get_dmi_field() {
+	if is_oneof "${uname_s}" NetBSD
+	then
+		case $1
+		in
+			(system-manufacturer) _mib=machdep.dmi.system-vendor ;;
+			(system-product-name) _mib=machdep.dmi.system-product ;;
+			(system-version|system-uuid) _mib=machdep.dmi.$1 ;;
+			(bios-vendor|bios-version) _mib=machdep.dmi.$1 ;;
+			(biod-release-date) _mib=machdep.dmi.bios-date ;;
+			(*) _mib= ;;
+		esac
+
+		test -n "${_mib}" && get_sysctl "${_mib}" | grep -e . && return
+	fi
+
+	if is_command dmidecode
+	then
+		dmidecode -s "$1"
+	elif test -d "${dmi_sysfs-}"
+	then
+		case $1
+		in
+			(system-manufacturer) _filename=sys_vendor ;;
+			(system-product-name) _filename=product_name ;;
+			(*) _filename=$(echo "$1" | tr - _) ;;
+		esac
+		if test -r "${dmi_sysfs-}/${_filename}"
+		then
+			cat "${dmi_sysfs}/${_filename}"
+		fi
+		unset _filename
+	elif test "${uname_s}" = OpenBSD
+	then
+		# NOTE: something similar to system-manufacutrer and system-product-name
+		#       is available on OpenBSD in sysctl
+		case $1
+		in
+			(system-manufacturer) _mib=hw.vendor ;;
+			(system-product-name) _mib=hw.product ;;
+			(*) _mib= ;;
+		esac
+
+		test -n "${_mib}" && get_sysctl "${_mib}" | grep -e . && return
+	fi
+
+	return 1
 }
 
-case "$os" in
-    "freebsd")
-        # FreeBSD does not have /proc/cpuinfo even when procfs is used.
-        # Instead there is a sysctl kern.vm_guest.
-        # Which is 'none' if physical, else the virtualisation.
-        vm_guest="$(sysctl -n kern.vm_guest 2>/dev/null || true)"
-        if [ -n "${vm_guest}" ]; then
-            if [ "${vm_guest}" = "none" ]; then
-                echo "physical"
-                exit
-            fi
-            echo "virtual_by_${vm_guest}"
-            exit
-        fi
-    ;;
+has_cpuinfo() { test -e /proc/cpuinfo; }
 
-    "openbsd")
-        # OpenBSD can also use the sysctl's: hw.vendor or hw.product.
-        # Note we can be reasonably sure about a machine being virtualised
-        # as long as we can identify the virtualisation technology.
-        # But not so much about it being physical...
-        # Patches are welcome / reach out if you have better ideas.
-        for sysctl in hw.vendor hw.product; do
-            # This exits if we can make a reasonable judgement
-            vendor_string_to_machine_type "$(sysctl -n "${sysctl}")"
-        done
-    ;;
+get_sysctl() {
+	is_command sysctl && sysctl -n "$1" 2>/dev/null
+}
 
-    *)
-        # Defaulting to linux for compatibility with previous cdist behaviour
 
-        if [ -d "/proc/vz" ] && [ ! -d "/proc/bc" ]; then
-            echo openvz
-            exit
-        fi
+# Check for container
 
-        if [ -e "/proc/1/environ" ] &&
-            tr '\000' '\n' < "/proc/1/environ" | grep -Eiq '^container='; then
-            echo lxc
-            exit
-        fi
+has_ct_pid_1() {
+	test -r /run/systemd/container -o -r /proc/1/environ
+}
 
-        if [ -r /proc/cpuinfo ]; then
-            # this should only exist on virtual guest machines,
-            # tested on vmware, xen, kvm, bhyve
-            if grep -q "hypervisor" /proc/cpuinfo; then
-                # this file is aviable in xen guest systems
-                if [ -r /sys/hypervisor/type ]; then
-                    if grep -q -i "xen" /sys/hypervisor/type; then
-                        echo virtual_by_xen
-                        exit
-                    fi
-                else
-                    for vendor_file in /sys/class/dmi/id/product_name \
-                                       /sys/class/dmi/id/sys_vendor \
-                                       /sys/class/dmi/id/chasis_vendor; do
-                        if [ -r ${vendor_file} ]; then
-                            # This exits if we can make a reasonable judgement
-                            vendor_string_to_machine_type "$(cat "${vendor_file}")"
-                        fi
-                    done
-                fi
-                echo "virtual_by_unknown"
-                exit
-            else
-                echo "physical"
-                exit
-            fi
-        fi
-    ;;
-esac
+translate_container_name() {
+	case $1
+	in
+		('lxc')
+			echo lxc ;;
+		('lxc-libvirt')
+			echo lxc-libvirt ;;
+		('podman')
+			echo podman ;;
+		('systemd-nspawn')
+			echo systemd_nspawn ;;
+		(*)
+			return 1 ;;
+	esac
+	return 0
+}
 
-echo "unknown"
+check_ct_pid_1() {
+	if test -r /run/systemd/container
+	then
+		translate_container_name "$(head -n1 /run/systemd/container)" \
+		&& return 0
+	fi
+
+	if test -r /proc/1/environ
+	then
+		translate_container_name "$(
+			LC_ALL=C tr '\000' '\n' </proc/1/environ \
+			| sed -n -e 's/^container=//p')" \
+		&& return 0
+	fi
+
+	return 1
+}
+
+has_ct_cgroup() {
+	test -r /proc/self/cgroup
+}
+
+check_ct_cgroup() {
+	if grep -q -e ':/docker/' /proc/self/cgroup
+	then
+		echo docker
+	elif grep -q -e ':/lxc/.*\.libvirt-lxc$' /proc/self/cgroup
+	then
+		echo libvirt-lxc
+	elif grep -q -F '/libpod-' /proc/self/cgroup
+	then
+		echo podman
+	else
+		return 1
+	fi
+}
+
+check_ct_files() {
+	if test -e /.dockerenv -o -e /run/.dockerenv -o -e /.dockerinit
+	then
+		echo docker
+	elif test -f /run/.containerenv
+	then
+		# https://github.com/containers/podman/issues/3586#issuecomment-661918679
+		echo podman
+	elif test -d /proc/vz -a ! -d /proc/bc -a -f /proc/user_beancounters \
+		|| test -d /.cpt_hardlink_dir_*/
+	then
+		# Virtuozzo / OpenVZ
+		#
+		# /proc/vz: always exists if OpenVZ kernel is running
+		# /proc/bc: exists only on node (not inside container)
+		# /proc/user_beancounters - exists inside container
+		#
+		# /.cpt_hardlink_dir_*/ may be (?) created by vzctl:
+		# https://github.com/kolyshkin/vzctl/commit/09e974f
+
+		echo openvz
+	elif grep -qie 'Microsoft\|WSL' /proc/sys/kernel/osrelease /proc/version 2>/dev/null
+	then
+		# https://github.com/Microsoft/WSL/issues/423#issuecomment-221627364
+		echo wsl
+	elif test -d /var/.cagefs
+	then
+		# https://docs.cloudlinux.com/cloudlinux_os_components/#cagefs
+		# CageFS is not "really" a container, but it isn't a chroot either.
+		echo cagefs
+	elif test -e /proc/self/status && grep -q -e '^VxID: [0-9]\{1,\}' /proc/self/status
+	then
+		# Linux-VServer
+		if grep -q -x -F 'VxID: 0' /proc/self/status
+		then
+			# host
+			return 1
+		else
+			# guest
+			echo linux_vserver
+		fi
+	else
+		return 1
+	fi
+}
+
+check_ct_os_specific() (
+	if jailed=$(get_sysctl security.jail.jailed) && test "${jailed}" = 1
+	then
+		# FreeBSD jail
+		echo jail
+		return 0
+	fi
+
+	if is_command zonename && test "$(zonename)" != global
+	then
+		# Solaris zone
+		echo zone
+		return 0
+	fi
+
+	return 1
+)
+
+
+# Check for hypervisor
+
+guess_hypervisor_from_cpu_model() {
+	case $1
+	in
+		(*\ KVM\ *)
+			echo kvm ;;
+		(*\ QEMU\ *|QEMU\ *)
+			echo qemu ;;
+		(*)
+			return 1 ;;
+	esac
+}
+
+has_vm_cpuinfo() { has_cpuinfo; }
+
+check_vm_cpuinfo() {
+	if grep -q -F 'User Mode Linux' /proc/cpuinfo \
+		|| grep -q -F 'UML' /proc/cpuinfo
+	then
+		# User Mode Linux
+		echo uml
+	elif grep -q -e '^vendor_id.*: PowerVM Lx86' /proc/cpuinfo
+	then
+		# IBM PowerVM Lx86 (Linux/x86 emulator)
+		echo powervm_lx86
+	elif grep -q -e '^vendor_id.*: IBM/S390' /proc/cpuinfo
+	then
+		# IBM SystemZ (S/390)
+		if test -f /proc/sysinfo
+		then
+			if grep -q -e '^VM[0-9]* Control Program: KVM/Linux' /proc/sysinfo
+			then
+				echo kvm-s390
+				return 0
+			elif grep -q -e '^VM[0-9]* Control Program: z/VM' /proc/sysinfo
+			then
+				echo zvm
+				return 0
+			elif grep -q -e '^LPAR ' /proc/sysinfo
+			then
+				echo zvm-lpar
+				return 0
+			fi
+		fi
+		return 1
+	else
+		if grep -q -e '^model name.*:' /proc/cpuinfo
+		then
+			sed -n -e 's/^model name[^:]*: *//p' /proc/cpuinfo \
+			| while read -r _cpu_model
+			  do
+				  guess_hypervisor_from_cpu_model "${_cpu_model}"
+			  done \
+			| sort \
+			| uniq -c \
+			| awk '
+			  { if ($1 > most_c) { most_c = $1; most_s = $2 } }
+			  END {
+				if (most_s) print most_s
+				exit !most_s
+			  }' \
+			&& return 0
+		fi
+		return 1
+	fi
+}
+
+check_vm_arch_specific() {
+	case ${arch}
+	in
+		(ppc64|ppc64le)
+			# Check PPC64 LPAR, KVM
+
+			# example /proc/cpuinfo line indicating 'not baremetal'
+			# platform	: pSeries
+			#
+			# example /proc/ppc64/lparcfg systemtype line
+			# system_type=IBM pSeries (emulated by qemu)
+
+			if has_cpuinfo && grep -q -e 'platform.**pSeries' /proc/cpuinfo
+			then
+				if test -e /proc/ppc64/lparcfg
+				then
+					# Assume LPAR, now detect shared or dedicated
+					if grep -q -x -F 'shared_processor_mode=1' /proc/ppc64/lparcfg
+					then
+						echo powervm-shared
+						return 0
+					else
+						echo powervm-dedicated
+						return 0
+					fi
+				fi
+			fi
+			;;
+		(sparc*)
+			# Check for SPARC LDoms
+
+			if test -e /dev/mdesc
+			then
+				if test -d /sys/class/vlds/ctrl -a -d /sys/class/vlds/sp
+				then
+					# control LDom
+					return 1
+				else
+					# guest LDom
+					echo ldom-sparc
+				fi
+
+				# MDPROP=/usr/lib/ldoms/mdprop.py
+				# if test -x "${MDPROP}"
+				# then
+				# 	if test -n "$("${MDPROP}" -v iodevice device-type=pciex)"
+				# 	then
+				# 		echo ldoms-root
+				# 		echo ldoms-io
+				# 	elif test -n "$("${MDPROP}" -v iov-device vf-id=0)"
+				# 	then
+				# 		echo ldoms-io
+				# 	fi
+				# fi
+				return 0
+			fi
+			;;
+		(i?86|x86*|amd64|i86pc)
+			# Check CPUID
+			#
+			# Many fullvirt hypervisors give an indication through CPUID.  Use
+			# the virt-what helper program to get this information if available.
+
+			for CPUID_HELPER in \
+				$(command -v virt-what-cpuid-helper 2>/dev/null) \
+				/usr/lib/x86_64-*/virt-what-cpuid-helper \
+				/usr/lib/i?86-*/virt-what-cpuid-helper \
+				/usr/lib/virt-what/virt-what-cpuid-helper
+			do
+				if test -x "${CPUID_HELPER:?}"; then break; fi
+			done
+
+			if test -x "${CPUID_HELPER-}"
+			then
+				case $(command "${CPUID_HELPER}")
+				in
+					('bhyve bhyve ')
+						echo bhyve
+						;;
+					('LKVMLKVMLKVM')
+						echo lkvm
+						;;
+					('KVMKVMKVM')
+						echo kvm
+						;;
+					('TCGTCGTCGTCG')
+						echo qemu-tcg
+						;;
+					('Microsoft Hv')
+						# http://blogs.msdn.com/b/sqlosteam/archive/2010/10/30/is-this-real-the-metaphysics-of-hardware-virtualization.aspx
+						echo hyperv
+						;;
+					('OpenBSDVMM58')
+						# OpenBSD/VMM
+						echo openbsd_vmm
+						;;
+					('VMwareVMware')
+						# check added by Chetan Loke.
+						echo vmware
+						;;
+					('XenVMMXenVMM')
+						if has dmi
+						then
+							# https://access.redhat.com/solutions/222903
+							echo xen-hvm
+						else
+							echo xen-paravirt
+						fi
+						;;
+					(*)
+						return 1 ;;
+				esac
+				return 0
+			fi
+
+			unset CPUID_HELPER
+
+			# VMM CPUID flag denotes that this system is running under a VMM
+			if is_oneof "${uname_s}" Darwin
+			then
+				get_sysctl machdep.cpu.features | tr ' ' '\n' | grep -qixF VMM \
+				&& return 0
+			fi
+			if has_cpuinfo \
+				&& grep -q -i -e '^flags.*:.*\(hypervisor\|vmm\)' /proc/cpuinfo
+			then
+				return 0
+			fi
+			;;
+		(ia64)
+			if test -d /sys/bus/xen -a ! -d /sys/bus/xen-backend
+			then
+				# PV-on-HVM drivers installed in a Xen guest
+				echo xen-hvm
+				return 0
+			fi
+			;;
+	esac
+	return 1
+}
+
+has_vm_dmi() {
+	# Check for various products in SMBIOS/DMI.
+	# Note that DMI doesn't exist on all architectures (only x86 and some ARM).
+	# On other architectures the $dmi variable will be empty.
+
+	if test -d /sys/class/dmi/id/
+	then
+		dmi_sysfs=/sys/class/dmi/id
+	elif test -d /sys/devices/virtual/dmi/id/
+	then
+		dmi_sysfs=/sys/devices/virtual/dmi/id
+	fi
+
+	# shellcheck disable=SC2015
+	{
+		is_command dmidecode \
+		&& (
+			# dmidecode needs to exit 0 and not print the No SMBIOS/DMI line
+			dmi_out=$(dmidecode 2>&1) \
+			&& ! printf '%s\n' "${dmi_out}" \
+				 | grep -qF 'No SMBIOS nor DMI entry point found, sorry.'
+			) \
+		|| test -d "${dmi_sysfs}"
+	}
+}
+
+check_vm_dmi() {
+	case $(get_dmi_field system-product-name)
+	in
+		(*.metal)
+			if test "$(get_dmi_field system-manufacturer)" = 'Amazon EC2'
+			then
+				# AWS EC2 bare metal -> no virtualisation
+				return 1
+			fi
+			;;
+		('BHYVE')
+			echo bhyve
+			return 0
+			;;
+		('Google Compute Engine')
+			echo gce
+			return 0
+			;;
+		('RHEV Hypervisor')
+			# Red Hat Enterprise Virtualization
+			echo rhev
+			return 0
+			;;
+		('KVM'|'Bochs'|'KVM Virtual Machine')
+			echo kvm
+			return 0
+			;;
+		('Parallels Virtual Platform')
+			echo parallels
+			return 0
+			;;
+		('VirtualBox')
+			echo virtualbox
+			return 0
+			;;
+		('VMware Virtual Platform')
+			echo vmware
+			return 0
+			;;
+	esac
+
+	case $(get_dmi_field system-manufacturer)
+	in
+		('Alibaba'*)
+			case $(get_dmi_field system-product-name)
+			in
+				('Alibaba Cloud ECS')
+					echo alibaba-ecs
+					;;
+				(*)
+					echo alibaba
+					;;
+			esac
+			return 0
+			;;
+		('Amazon EC2')
+			# AWS on bare-metal or KVM
+			echo aws-ec2
+			return 0
+			;;
+		('innotek GmbH'|'Oracle Corporation')
+			echo virtualbox
+			return 0
+			;;
+		('Joyent')
+			if test "$(get_dmi_field system-product-name)" = 'SmartDC HVM'
+			then
+				# SmartOS KVM
+				echo kvm-smartdc_hvm
+				return 0
+			fi
+			;;
+		('Microsoft Corporation'*)
+			if test "$(get_dmi_field system-product-name)" = 'Virtual Machine'
+			then
+				if test -e /proc/irq/7/hyperv \
+				|| expr "$(get_dmi_field bios-version)" : 'VRTUAL.*' >/dev/null
+				then
+					echo hyperv
+					return 0
+				fi
+
+				case $(get_dmi_field system-version)
+				in
+					(VPC[0-9]*|VS2005*|*[Vv]irtual*[Pp][Cc]*)
+						echo virtualpc
+						return 0
+						;;
+					(*)
+						echo hyperv
+						return 0
+						;;
+				esac
+			fi
+			;;
+		('Nutanix')
+			# Nutanix AHV. Similar to KVM.
+			if test "$(get_dmi_field system-product-name)" = 'AHV'
+			then
+				echo nutanix_ahv
+				return 0
+			fi
+			;;
+		('oVirt')
+			echo ovirt
+			return 0
+			;;
+		('Parallels Software International Inc.')
+			echo parallels
+			return 0
+			;;
+		('QEMU')
+			echo qemu
+			return 0
+			;;
+		('VMware, Inc.')
+			echo vmware
+			return 0
+			;;
+	esac
+
+	case $(get_dmi_field bios-vendor)
+	in
+		('Amazon EC2')
+			# AWS on bare-metal or KVM
+			echo aws-ec2
+			return 0
+			;;
+		('BHYVE')
+			echo bhyve
+			return 0
+			;;
+		('innotek GmbH')
+			echo virtualbox
+			return 0
+			;;
+		('Parallels Software International Inc.')
+			echo parallels
+			return 0
+			;;
+		('Xen')
+			if get_dmi_field bios-version | grep -q -e '\([0-9]\{1,\}\.\)\{2\}amazon'
+			then
+				# AWS on Xen
+				echo aws-xen
+				return 0
+			fi
+			;;
+	esac
+
+	return 1
+}
+
+check_vm_hyp_specific() {
+	if is_command vmware-checkvm && vmware-checkvm >/dev/null
+	then
+		# vmware-checkvm is provided by VMware's open-vm-tools
+		echo vmware
+		return 0
+	elif test -d /proc/xen
+	then
+		test -r /proc/xen/capabilities &&
+		if grep -q -F 'control_d' /proc/xen/capabilities 2>/dev/null
+		then
+			# Xen dom0
+			return 1
+		else
+			# Xen domU
+			echo xen
+			return 0
+		fi
+	fi
+	return 1
+}
+
+has_vm_dt() {
+	# OpenFirmware/Das U-Boot device-tree
+	test -d /proc/device-tree
+}
+
+check_vm_dt() {
+	case ${arch}
+	in
+		(arm|aarch64)
+			if test -r /proc/device-tree/hypervisor/compatible
+			then
+				if grep -q -F 'xen' /proc/device-tree/hypervisor/compatible
+				then
+					echo xen
+					return 0
+				elif grep -q -F 'vmware' /proc/device-tree/hypervisor/compatible
+				then
+					# e.g. VMware ESXi on ARM
+					echo vmware
+					return 0
+				fi
+			fi
+			if glob_exists /proc/device-tree/fw-cfg@*/compatible
+			then
+				# qemu,fw-cfg-mmio
+				sed -e 's/,.*$//' /proc/device-tree/fw-cfg@*/compatible | head -n1
+				return 0
+			fi
+			if grep -q -F 'dummy-virt' /proc/device-tree/compatible
+			then
+				echo lkvm
+				return 0
+			fi
+			;;
+		(ppc64*)
+			if test -d /proc/device-tree/hypervisor \
+				&& grep -qF 'linux,kvm' /proc/device-tree/hypervisor/compatible
+			then
+				# We are running as a spapr KVM guest on ppc64
+				echo kvm-spapr
+				return 0
+			fi
+			if test -r /proc/device-tree/ibm,partition-name \
+				&& test -r /proc/device-tree/hmc-managed\? \
+				&& test -r /proc/device-tree/chosen/qemu,graphic-width
+			then
+				echo powervm
+			fi
+			;;
+	esac
+	return 1
+}
+
+has_vm_sys_hypervisor() {
+	test -d /sys/hypervisor/
+}
+
+check_vm_sys_hypervisor() {
+	test -r /sys/hypervisor/type &&
+	case $(head -n1 /sys/hypervisor/type)
+	in
+		(xen)
+			# Ordinary kernel with pv_ops.	There does not seem to be
+			# enough information at present to tell whether this is dom0
+			# or domU.
+			echo xen
+			return 0
+			;;
+	esac
+	return 1
+}
+
+check_vm_os_specific() {
+	_hyp_generic=false
+
+	case ${uname_s}
+	in
+		(Darwin)
+			if hv_vmm_present=$(get_sysctl kern.hv_vmm_present) \
+				&& test "${hv_vmm_present}" -ne 0
+			then
+				_hyp_generic=true
+			fi
+			;;
+		(FreeBSD)
+			# FreeBSD does not have /proc/cpuinfo even when procfs is used.
+			# Instead there is a sysctl kern.vm_guest.
+			# Which is 'none' if physical, else the virtualisation.
+			vm_guest=$(get_sysctl kern.vm_guest | tolower) &&
+			case ${vm_guest}
+			in
+				(none) ;;
+				(generic) _hyp_generic=true ;;
+				(*)
+					# kernel could detect hypervisor
+					case ${vm_guest}
+					in
+						(hv) echo hyperv ;;
+						(vbox) echo virtualbox ;;
+						(*) echo "${vm_guest}" ;;
+					esac
+					return 0
+					;;
+			esac
+			;;
+		(NetBSD)
+			machdep_hv=$(get_sysctl machdep.hypervisor | tolower) &&
+			case ${machdep_hv}
+			in
+				(none) ;;
+				(generic) _hyp_generic=true ;;
+				(*)
+					# kernel could detect hypervisor
+					case ${machdep_hv}
+					in
+						(hyper-v) echo hyperv ;;
+						(xenhvm*) echo xen-hvm ;;
+						(xenpv*) echo xen-pv ;;
+						(xen*) echo xen ;;
+						(*) echo "${machdep_hv}" ;;
+					esac
+					return 0
+					;;
+			esac
+			;;
+		(OpenBSD)
+			if is_command hostctl && glob_exists /dev/pvbus[0-9]*
+			then
+				for _pvbus in /dev/pvbus[0-9]*
+				do
+					_h_out=$(hostctl -f "${_pvbus}" -t 2>/dev/null) || continue
+					case $(expr "${_h_out}" : '[^:]*: *\(.*\)$')
+					in
+						(KVM) echo kvm ;;
+						(Hyper-V) echo hyperv ;;
+						(VMware) echo vmware ;;
+						(Xen) echo xen ;;
+						(bhyve) echo bhyve ;;
+						(OpenBSD) echo openbsd_vmm ;;
+					esac
+					return 0
+				done
+			fi
+			;;
+		(SunOS)
+			diag_conf=$(prtdiag | sed -n -e 's/.*Configuration: *//p' -e '/^$/q')
+			# NOTE: Don't use -e or -F in Solaris grep
+			if printf '%s\n' "${diag_conf}" | grep -q -i QEMU
+			then
+				echo qemu
+				return 0
+			elif printf '%s\n' "${diag_conf}" | grep -q -i VMware
+			then
+				echo vmware
+				return 0
+			fi
+			;;
+		(Linux)
+			if is_command dmesg
+			then
+				while read -r line
+				do
+					case ${line}
+					in
+						('Booting paravirtualized kernel on ')
+							case $(expr "${line}" : '.* kernel on \(.*\)')
+							in
+								('Xen')
+									echo xen-pv; return 0 ;;
+								('bare hardware')
+									return 1 ;;
+							esac
+							;;
+						('Hypervisor detected')
+							case $(expr "${line}" : '.*: *\(.*\)')
+							in
+								('ACRN')
+									echo acrn ;;
+								('Jailhouse')
+									echo jailhouse ;;
+								('KVM')
+									echo kvm ;;
+								('Microsoft Hyper-V')
+									echo hyperv ;;
+								('VMware')
+									echo vmware ;;
+								('Xen HVM')
+									echo xen-hvm ;;
+								('Xen PV')
+									echo xen-pv ;;
+							esac
+							return 0
+							;;
+						(lpar:*' under hypervisor')
+							return 0 ;;
+					esac
+				done <<-EOF
+				$(dmesg 2>/dev/null | awk '
+				/Booting paravirtualized kernel on /
+				/Hypervisor detected: /
+				/lpar: .* under hypervisor/
+				')
+				EOF
+			fi
+	esac
+
+	# Try to guess hypervisor based on CPU model (sysctl hw.model if available)
+	if cpu_model=$(get_sysctl hw.model)
+	then
+		guess_hypervisor_from_cpu_model "${cpu_model}" && return 0
+	fi
+
+	if ${_hyp_generic}
+	then
+		# cannot say which hypervisor, but one was detected
+		return 0
+	else
+		return 1
+	fi
+}
+
+run_stage() {
+	if type "has_$1_$2" >/dev/null 2>&1
+	then
+		"has_$1_$2"
+	else
+		true
+	fi \
+	&& "check_$1_$2"
+}
+
+
+# Execute container stages
+
+for stage in \
+	pid_1 cgroup files os_specific
+do
+	ctengine=$(run_stage ct ${stage}) || continue
+	is_contained=true
+	if test -n "${ctengine}"
+	then
+		echo container on "${ctengine}"
+		break
+	fi
+done
+if ${is_contained:-false} && test -z "${ctengine}"
+then
+	# none of the stages could determine the specific container engine, but
+	# we are running in some container.
+	echo container
+fi
+
+
+# Execute virtual machine / hypervisor stages
+
+for stage in \
+	os_specific hyp_specific sys_hypervisor dt dmi cpuinfo arch_specific
+do
+	hypervisor=$(run_stage vm ${stage}) || continue
+	is_virtual=true
+	if test -n "${hypervisor}"
+	then
+		echo virtual by "${hypervisor}"
+		break
+	fi
+done
+if ${is_virtual:-false} && test -z "${hypervisor}"
+then
+	# none of the stages could determine the specific hypervisor, but
+	# we are virtual.
+	echo virtual
+fi