#!/bin/sh
#
# 2014 Daniel Heule  (hda at sfs.biz)
# 2014 Thomas Oettli (otho at sfs.biz)
# 2020 Evilham (contact at evilham.com)
#
# This file is part of cdist.
#
# cdist is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# cdist is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with cdist. If not, see <http://www.gnu.org/licenses/>.
#

os=$("$__explorer/os")

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
}

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
    ;;

    "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
    ;;

    *)
        # Defaulting to linux for compatibility with previous cdist behaviour

        if [ -d "/proc/vz" ] && [ ! -d "/proc/bc" ]; then
            echo openvz
            exit
        fi

        if [ -e "/proc/1/environ" ] &&
            tr '\000' '\n' < "/proc/1/environ" | grep -Eiq '^container='; then
            echo lxc
            exit
        fi

        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

echo "unknown"
