All:
I am working on a project which would like to know if the current
machine is a guest, and if so what type of guest it is. This
functionality is currently available in virt-what[1]. The current
implementation is a bash shell which invokes a C libary. Our project
would be interested in seeing this functionality provided as a library
(C or python is preferred). I sample python patch (probably not the
best) is attached.
Would other folks see value in a library such as this? I am concerned
that if projects each take different takes on this functionality by
copying the code we are likely to diverge with un-desirable results.
-- bk
[1] http://people.redhat.com/~rjones/virt-what/
>From b8207f73a5cea4a7ec36f0d8e332828d900ee406 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 | 172 ++++++++++------------------------------------------
virt_detect.py | 184 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
6 files changed, 225 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..e6d9f92 100644
--- a/virt-what.in
+++ b/virt-what.in
@@ -1,152 +1,46 @@
-#!/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()
+types = vd.hypervisor_types()
- if grep -q 'QEMU' /proc/cpuinfo; then
- if [ "$cpuid" = "KVMKVMKVM" ]; then
- echo kvm
- else
- echo qemu
- fi
- fi
-fi
+for type in types:
+ print type
diff --git a/virt_detect.py b/virt_detect.py
new file mode 100644
index 0000000..7d05752
--- /dev/null
+++ b/virt_detect.py
@@ -0,0 +1,184 @@
+#
+# 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"
+xen = "xen"
+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_types(self):
+ types = []
+ is_xen = False;
+ if self.on_vmware(): types.append(vmware)
+ if self.on_virtualpc(): types.append(virtualpc)
+ if self.on_virtualbox(): types.append(virtualbox)
+ if self.on_openvz(): types.append(openvz)
+ if self.on_uml(): types.append(uml)
+ if self.on_xen_hvm():
+ types.append(xenhvm)
+ is_xen = True
+ if self.is_xen_dom0():
+ types.append(xendom0)
+ is_xen = True
+ if self.is_xen_domU():
+ types.append(xendomU)
+ is_xen = True
+ if self.on_kvm(): types.append(kvm)
+ if self.on_qemu(): types.append(qemu)
+
+ if is_xen:
+ types.append(xen)
+
+ return types
+
+ 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-tools-list mailing list
[email protected]
https://www.redhat.com/mailman/listinfo/virt-tools-list