We discussed this a bit yesterday. I have some python client code which needs to know "is guest" and optionally the hypervisor type. The supplied patch uses the same detection logic as the bash script, but puts it into a python library. The detection logic may be a bit dubious, but at least this would allow a single place for such logic.

-- bk
>From 99d0beb3eef35de112dc8e5db582ed24815e7f52 Mon Sep 17 00:00:00 2001
From: Bryan Kearney <[email protected]>
Date: Thu, 11 Nov 2010 09:51:22 -0500
Subject: [PATCH] Move the logic for detecting the hypervisor type into a python library. This should allow other tools to make use of the same logic. The binary (now python instead of bash) just calls into the library

---
 .gitignore     |    1 +
 Makefile.am    |    2 +
 README         |    2 +
 configure.ac   |    3 +
 virt-what.in   |  175 ++++++++++++--------------------------------------------
 virt_detect.py |  171 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 6 files changed, 215 insertions(+), 139 deletions(-)
 create mode 100644 virt_detect.py

diff --git a/.gitignore b/.gitignore
index 72dc52e..35e5ae6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -20,3 +20,4 @@ virt-what
 virt-what-cpuid-helper
 virt-what.1
 virt-what.txt
+py-compile
diff --git a/Makefile.am b/Makefile.am
index 5f76d8f..605684d 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -26,6 +26,8 @@ libexec_PROGRAMS = virt-what-cpuid-helper
 
 man_MANS = virt-what.1
 
+python_PYTHON = virt_detect.py
+
 virt-what.1: virt-what.pod
 	pod2man -c "Virtualization Support" --release "$(PACKAGE)-$(VERSION)" \
 	  $< > $@
diff --git a/README b/README
index a363ddb..c46ebff 100644
--- a/README
+++ b/README
@@ -7,6 +7,8 @@ sort of virtualization you are running inside.
 
 Build:
 
+  aclocal
+  autoconf
   ./configure
   make
 
diff --git a/configure.ac b/configure.ac
index 137e1f4..0ff5cdc 100644
--- a/configure.ac
+++ b/configure.ac
@@ -23,6 +23,9 @@ AC_PROG_CC_STDC
 AC_PROG_INSTALL
 AC_PROG_CPP
 
+dnl Python library
+AM_PATH_PYTHON
+
 AC_C_PROTOTYPES
 test "x$U" != "x" && AC_MSG_ERROR([Compiler not ANSI compliant])
 
diff --git a/virt-what.in b/virt-what.in
index 96c18b4..c7b34a5 100644
--- a/virt-what.in
+++ b/virt-what.in
@@ -1,152 +1,49 @@
-#!/bin/bash -
-# @configure_input@
-# Copyright (C) 2008-2010 Red Hat Inc.
+#!/usr/bin/python
 #
-# This program 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 2 of the License, or
-# (at your option) any later version.
+# Copyright (c) 2010 Red Hat, Inc.
 #
-# This program 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.
+# Authors: Pradeep Kilambi
 #
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-# 'virt-what' tries to detect the type of virtualization being
-# used (or none at all if we're running on bare-metal).  It prints
-# out one of more lines each being a 'fact' about the virtualization.
+# This software is licensed to you under the GNU General Public License,
+# version 2 (GPLv2). There is NO WARRANTY for this software, express or
+# implied, including the implied warranties of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv2
+# along with this software; if not, see
+# http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
 #
-# Please see also the manual page virt-what(1).
-# This script should be run as root.
+# Red Hat trademarks are not licensed under GPLv2. No permission is
+# granted to use or replicate Red Hat trademarks that are incorporated
+# in this software or its documentation.
 #
-# The following resources were useful in writing this script:
-# . http://www.dmo.ca/blog/20080530151107
-
 VERSION="@VERSION@"
 
-function fail {
-    echo "virt-what: $1"
-    exit 1
-}
-
-function usage {
-    echo "virt-what [options]"
-    echo "Options:"
-    echo "  --help          Display this help"
-    echo "  --version       Display version and exit"
-    exit 0
-}
-
-# Handle the command line arguments, if any.
-
-TEMP=`getopt -o v --long help --long version -n 'virt-what' -- "$@"`
-if [ $? != 0 ]; then exit 1; fi
-eval set -- "$TEMP"
-
-while true; do
-    case "$1" in
-	--help) usage ;;
-	-v|--version) echo $VERSION; exit 0 ;;
-	--) shift; break ;;
-	*) fail "internal error" ;;
-    esac
-done
-
-# Check we're running as root.
-
-uid=`id -u`
-if [ "$uid" != 0 ]; then
-    fail "this script must be run as root"
-fi
-
-# Add /sbin and /usr/sbin to the path so we can find system
-# binaries like dmicode.
-# Add /usr/libexec to the path so we can find the helper binary.
-pref...@prefix@
-exec_pref...@exec_prefix@
-pa...@libexecdir@:/sbin:/usr/sbin:$PATH
-
-# Many fullvirt hypervisors give an indication through CPUID.  Use the
-# helper program to get this information.
-
-cpuid=`virt-what-cpuid-helper`
-
-# Check for various products in the BIOS information.
-
-dmi=`dmidecode 2>&1`
-
-# Check for VMware.
-# cpuid check added by Chetan Loke.
-
-if [ "$cpuid" = "VMwareVMware" ]; then
-    echo vmware
-elif echo "$dmi" | grep -q 'Manufacturer: VMware'; then
-    echo vmware
-fi
-
-# Check for VirtualPC.
-
-if echo "$dmi" | grep -q 'Manufacturer: Microsoft Corporation'; then
-    echo virtualpc
-fi
-
-# Check for VirtualBox.
-# Added by Laurent Léonard.
-if echo "$dmi" | grep -q 'Manufacturer: innotek GmbH'; then
-    echo virtualbox
-fi
-
-# Check for OpenVZ / Virtuozzo.
-# Added by Evgeniy Sokolov.
-# /proc/vz - always exists if OpenVZ kernel is running (inside and outside
-# container)
-# /proc/bc - exists on node, but not inside container.
-
-if [ -d /proc/vz -a ! -d /proc/bc ]; then
-    echo openvz
-fi
+import os
+import sys
+from optparse import OptionParser
+from virt_detect import VirtDetect
 
-# Check for UML.
-# Added by Laurent Léonard.
-if grep -q 'UML' /proc/cpuinfo; then
-    echo uml
-fi
+# quick check to see if you are a super-user.
+if os.getuid() != 0:
+    sys.stderr.write('ERROR: must be root to execute\n')
+    sys.exit(8)
 
-# Check for Xen.
+# Parse out any arguments
+args = sys.argv[1:]
 
-if [ "$cpuid" = "XenVMMXenVMM" ]; then
-    echo xen; echo xen-hvm
-    is_xen=1
-elif [ -f /proc/xen/capabilities ]; then
-    echo xen
-    if grep -q "control_d" /proc/xen/capabilities; then
-        echo xen-dom0
-    else
-        echo xen-domU
-    fi
-    is_xen=1
-elif [ -d /proc/xen ]; then
-    # This directory can be present when Xen paravirt drivers are
-    # installed, even on baremetal.  Don't confuse people by
-    # printing anything.
-    :
-fi
+parser = OptionParser("usage: virt-what [OPTIONS]")
+parser.add_option("-v", "--version", action="store_true",
+    dest="show_version",default=False, help="show the version and exit")
+(options, args) = parser.parse_args(args)
 
-# Check for QEMU/KVM.
+if (options.show_version):
+    print VERSION
+    sys.exit(0)
 
-if [ ! "$is_xen" ]; then
-    # Disable this test if we know this is Xen already, because Xen
-    # uses QEMU for its device model.
+vd = VirtDetect()
+type = vd.hypervisor_type()
 
-    if grep -q 'QEMU' /proc/cpuinfo; then
-	if [ "$cpuid" = "KVMKVMKVM" ]; then
-	    echo kvm
-	else
-	    echo qemu
-	fi
-    fi
-fi
+#Special xen checks
+if type is not None:
+    if "xen" in type:
+        print "xen"
+    print type
diff --git a/virt_detect.py b/virt_detect.py
new file mode 100644
index 0000000..bac638a
--- /dev/null
+++ b/virt_detect.py
@@ -0,0 +1,171 @@
+#
+# Module to probe Hardware info from the system
+#
+# Copyright (c) 2010 Red Hat, Inc.
+#
+# Authors: Pradeep Kilambi <[email protected]>
+#
+# This software is licensed to you under the GNU General Public License,
+# version 2 (GPLv2). There is NO WARRANTY for this software, express or
+# implied, including the implied warranties of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv2
+# along with this software; if not, see
+# http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+#
+# Red Hat trademarks are not licensed under GPLv2. No permission is
+# granted to use or replicate Red Hat trademarks that are incorporated
+# in this software or its documentation.
+#
+
+import os
+import sys
+import dmidecode
+
+kvm        = "kvm"
+qemu       = "qemu"
+vmware     = "vmware"
+virtualpc  = "virtualpc"
+virtualbox = "virtualbox"
+openvz     = "openvz"
+uml        = "uml"
+xenhvm     = "xen-hvm"
+xendom0    = "xen-dom0"
+xendomU    = "xen-domU"
+
+
+# The logic was take from virt-what located at
+# http://people.redhat.com/~rjones/virt-what/
+class VirtDetect:
+
+    def __init__(self):
+        self.cpuid = os.popen("/usr/libexec/virt-what-cpuid-helper").read().strip();
+
+        self.dmi = {
+                "bios": dmidecode.bios(),
+                "processor": dmidecode.processor(),
+                "system": dmidecode.system(),
+                "chassis": dmidecode.chassis(),
+            }
+
+    # Check for VMware.
+    # cpuid check added by Chetan Loke.
+    def on_vmware(self):
+        return (self.cpuid == "VMwareVMware") or (self._is_manufacturer("VMware"))
+
+    def on_virtualpc(self):
+        return self._is_manufacturer("Microsoft Corporation")
+
+    # Check for VirtualBox.
+    # Added by Laurent Leonard.
+    def on_virtualbox(self):
+        return self._is_manufacturer("innotek GmbH")
+
+    # Check for UML.
+    # Added by Laurent Leonard.
+    def on_uml(self):
+        return self._grep("/proc/cpuinfo", "UML")
+
+    def on_xen_hvm(self):
+        return (self.cpuid == "XenVMMXenVMM")
+
+    def is_xen_dom0(self):
+        xen = False
+        if (os.path.exists("proc/xen/capablities")):
+            xen = self_grep("proc/xen/capablities", control_d)
+        return xen
+
+    def is_xen_domU(self):
+        xen = False
+        if (os.path.exists("proc/xen/capablities")):
+            xen = not self_grep("proc/xen/capablities", control_d)
+        return xen
+
+    # Check for OpenVZ / Virtuozzo.
+    # Added by Evgeniy Sokolov.
+    # Need to make sure not xen before running this since
+    # Xen uses QEMU for its device model
+    def on_kvm(self):
+        kvm = False
+        if not (self.on_xen_hvm() or self.is_xen_dom0() or self.is_xen_domU()):
+            if self._grep("/proc/cpuinfo", "QEMU"):
+                kvm = (self.cpuid == "KVMKVMKVM")
+        return kvm
+
+    # Need to make sure not xen before running this since
+    # Xen uses QEMU for its device model
+    def on_qemu(self):
+        qemu = False
+        if not (self.on_xen_hvm() or self.is_xen_dom0() or self.is_xen_domU()):
+            if self._grep("/proc/cpuinfo", "QEMU"):
+                qemu = not self.cpuid != "KVMKVMKVM"
+        return qemu
+
+
+
+    # /proc/vz - always exists if OpenVZ kernel is running (inside and outside
+    # container)
+    # /proc/bc - exists on node, but not inside container.
+    def on_openvz(self):
+        return (os.path.exists("/proc/vz")) and not (os.path.exists("/proc/bc"))
+
+    def hypervisor_type(self):
+       if self.on_vmware(): return vmware
+       if self.on_virtualpc(): return virtualpc
+       if self.on_virtualbox(): return virtualbox
+       if self.on_openvz(): return openvz
+       if self.on_uml(): return uml
+       if self.on_xen_hvm(): return xenhvm
+       if self.is_xen_dom0(): return xendom0
+       if self.is_xen_domU(): return xendomU
+       if self.on_kvm(): return kvm
+       if self.on_qemu(): return qemu
+       return None
+
+    def _is_manufacturer(self, mf):
+        found = False
+        for key, value in self.dmi["processor"].items():
+            if mf == value["data"]["Manufacturer"]["Vendor"]:
+                found = True
+                break
+        if not found:
+            for key, value in self.dmi["bios"].items():
+                if "Vendor" in value["data"]:
+                    if mf == value["data"]["Vendor"]:
+                        found = True
+                        break
+        if not found:
+            for key, value in self.dmi["system"].items():
+                if "Manufacturer" in value["data"]:
+                    if mf == value["data"]["Manufacturer"]:
+                        found = True
+                        break
+        if not found:
+            for key, value in self.dmi["chassis"].items():
+                if "Manufacturer" in value["data"]:
+                    if mf == value["data"]["Manufacturer"]:
+                        found = True
+                        break
+        return found
+
+
+    def _grep(self, fname, data):
+        found = False
+        if (os.path.exists(fname)):
+            for line in open(fname):
+                if data in line:
+                    found = True
+                    break
+        return found
+
+if __name__ == '__main__':
+    g = VirtDetect()
+    print "On VMWare:     %i" % g.on_vmware()
+    print "On VirtualPC:  %i" % g.on_vmware()
+    print "On Virtualbox: %i" % g.on_virtualbox()
+    print "On Openvz:     %i" % g.on_openvz()
+    print "On UML:        %i" % g.on_uml()
+    print "On XenHVM:     %i" % g.on_xen_hvm()
+    print "Is XenDom0:    %i" % g.is_xen_dom0()
+    print "Is XenDomU:    %i" % g.is_xen_domU()
+    print "On Qemu:       %i" % g.on_qemu()
+    print "On KVM:        %i" % g.on_kvm()
-- 
1.7.3.2

_______________________________________________
virt mailing list
[email protected]
https://admin.fedoraproject.org/mailman/listinfo/virt

Reply via email to