virt facts: allow guest/host to have >1 virt tech (#70832)
Change: - Allow systems to declare multiple virt techs. For example if a system is both a docker container, but virtualized on KVM, show both. If a system is set up to run virtualbox and KVM VMs, show both. - This is done by introducing new facts keys: - virtualization_tech_guest - virtualization_tech_host - Backwards compatibility is preserved by keeping track of the previous return-points and refusing to update those keys after we would have returned, but now returning them at the end, so that the new keys can accumulate their data. Test Plan: - Local - CI Tickets: - Refs #66304 - Refs #17151 - Refs #17058 - Probably others Signed-off-by: Rick Elrod <rick@elrod.me>
This commit is contained in:
parent
fc83055425
commit
4e55b93613
10 changed files with 357 additions and 126 deletions
2
changelogs/fragments/multivirt.yml
Normal file
2
changelogs/fragments/multivirt.yml
Normal file
|
@ -0,0 +1,2 @@
|
|||
minor_changes:
|
||||
- New virtualization facts, ``virtualization_tech_guest`` and ``virtualization_tech_host`` now allow for conveying when a system is a host or guest of multiple virtualization technologies.
|
|
@ -131,7 +131,8 @@ No notable changes
|
|||
Noteworthy module changes
|
||||
-------------------------
|
||||
|
||||
* facts - ``ansible_virtualization_type`` now tries to report a more accurate result than ``xen`` when virtualized and not running on Xen.
|
||||
* facts - On NetBSD, ``ansible_virtualization_type`` now tries to report a more accurate result than ``xen`` when virtualized and not running on Xen.
|
||||
* facts - Virtualization facts now include ``virtualization_tech_guest`` and ``virtualization_tech_host`` keys. These are lists of virtualization technologies that a guest is a part of, or that a host provides, respectively. As an example, a host may be set up to provide both KVM and VirtualBox, and these will be included in ``virtualization_tech_host``, and a podman container running on a VM powered by KVM will have a ``virtualization_tech_guest`` of ``["kvm", "podman", "container"]``.
|
||||
|
||||
|
||||
Plugins
|
||||
|
|
|
@ -46,16 +46,24 @@ class Virtual:
|
|||
return virtual_facts
|
||||
|
||||
def get_virtual_facts(self):
|
||||
virtual_facts = {'virtualization_type': '',
|
||||
'virtualization_role': ''}
|
||||
virtual_facts = {
|
||||
'virtualization_type': '',
|
||||
'virtualization_role': '',
|
||||
'virtualization_tech_guest': set(),
|
||||
'virtualization_tech_host': set(),
|
||||
}
|
||||
return virtual_facts
|
||||
|
||||
|
||||
class VirtualCollector(BaseFactCollector):
|
||||
name = 'virtual'
|
||||
_fact_class = Virtual
|
||||
_fact_ids = set(['virtualization_type',
|
||||
'virtualization_role'])
|
||||
_fact_ids = set([
|
||||
'virtualization_type',
|
||||
'virtualization_role',
|
||||
'virtualization_tech_guest',
|
||||
'virtualization_tech_host',
|
||||
])
|
||||
|
||||
def collect(self, module=None, collected_facts=None):
|
||||
collected_facts = collected_facts or {}
|
||||
|
|
|
@ -32,23 +32,45 @@ class FreeBSDVirtual(Virtual, VirtualSysctlDetectionMixin):
|
|||
|
||||
def get_virtual_facts(self):
|
||||
virtual_facts = {}
|
||||
host_tech = set()
|
||||
guest_tech = set()
|
||||
|
||||
# Set empty values as default
|
||||
virtual_facts['virtualization_type'] = ''
|
||||
virtual_facts['virtualization_role'] = ''
|
||||
|
||||
if os.path.exists('/dev/xen/xenstore'):
|
||||
guest_tech.add('xen')
|
||||
virtual_facts['virtualization_type'] = 'xen'
|
||||
virtual_facts['virtualization_role'] = 'guest'
|
||||
|
||||
if virtual_facts['virtualization_type'] == '':
|
||||
virtual_product_facts = self.detect_virt_product('kern.vm_guest') or self.detect_virt_product(
|
||||
'hw.hv_vendor') or self.detect_virt_product('security.jail.jailed')
|
||||
virtual_facts.update(virtual_product_facts)
|
||||
kern_vm_guest = self.detect_virt_product('kern.vm_guest')
|
||||
guest_tech.update(kern_vm_guest['virtualization_tech_guest'])
|
||||
host_tech.update(kern_vm_guest['virtualization_tech_host'])
|
||||
|
||||
hw_hv_vendor = self.detect_virt_product('hw.hv_vendor')
|
||||
guest_tech.update(hw_hv_vendor['virtualization_tech_guest'])
|
||||
host_tech.update(hw_hv_vendor['virtualization_tech_host'])
|
||||
|
||||
sec_jail_jailed = self.detect_virt_product('security.jail.jailed')
|
||||
guest_tech.update(sec_jail_jailed['virtualization_tech_guest'])
|
||||
host_tech.update(sec_jail_jailed['virtualization_tech_host'])
|
||||
|
||||
if virtual_facts['virtualization_type'] == '':
|
||||
sysctl = kern_vm_guest or hw_hv_vendor or sec_jail_jailed
|
||||
# We call update here, then re-set virtualization_tech_host/guest
|
||||
# later.
|
||||
virtual_facts.update(sysctl)
|
||||
|
||||
virtual_vendor_facts = self.detect_virt_vendor('hw.model')
|
||||
guest_tech.update(virtual_vendor_facts['virtualization_tech_guest'])
|
||||
host_tech.update(virtual_vendor_facts['virtualization_tech_host'])
|
||||
|
||||
if virtual_facts['virtualization_type'] == '':
|
||||
virtual_facts.update(virtual_vendor_facts)
|
||||
|
||||
virtual_facts['virtualization_tech_guest'] = guest_tech
|
||||
virtual_facts['virtualization_tech_host'] = host_tech
|
||||
return virtual_facts
|
||||
|
||||
|
||||
|
|
|
@ -32,28 +32,38 @@ class HPUXVirtual(Virtual):
|
|||
|
||||
def get_virtual_facts(self):
|
||||
virtual_facts = {}
|
||||
host_tech = set()
|
||||
guest_tech = set()
|
||||
|
||||
if os.path.exists('/usr/sbin/vecheck'):
|
||||
rc, out, err = self.module.run_command("/usr/sbin/vecheck")
|
||||
if rc == 0:
|
||||
guest_tech.add('HP vPar')
|
||||
virtual_facts['virtualization_type'] = 'guest'
|
||||
virtual_facts['virtualization_role'] = 'HP vPar'
|
||||
if os.path.exists('/opt/hpvm/bin/hpvminfo'):
|
||||
rc, out, err = self.module.run_command("/opt/hpvm/bin/hpvminfo")
|
||||
if rc == 0 and re.match('.*Running.*HPVM vPar.*', out):
|
||||
guest_tech.add('HPVM vPar')
|
||||
virtual_facts['virtualization_type'] = 'guest'
|
||||
virtual_facts['virtualization_role'] = 'HPVM vPar'
|
||||
elif rc == 0 and re.match('.*Running.*HPVM guest.*', out):
|
||||
guest_tech.add('HPVM IVM')
|
||||
virtual_facts['virtualization_type'] = 'guest'
|
||||
virtual_facts['virtualization_role'] = 'HPVM IVM'
|
||||
elif rc == 0 and re.match('.*Running.*HPVM host.*', out):
|
||||
guest_tech.add('HPVM')
|
||||
virtual_facts['virtualization_type'] = 'host'
|
||||
virtual_facts['virtualization_role'] = 'HPVM'
|
||||
if os.path.exists('/usr/sbin/parstatus'):
|
||||
rc, out, err = self.module.run_command("/usr/sbin/parstatus")
|
||||
if rc == 0:
|
||||
guest_tech.add('HP nPar')
|
||||
virtual_facts['virtualization_type'] = 'guest'
|
||||
virtual_facts['virtualization_role'] = 'HP nPar'
|
||||
|
||||
virtual_facts['virtualization_tech_guest'] = guest_tech
|
||||
virtual_facts['virtualization_tech_host'] = host_tech
|
||||
return virtual_facts
|
||||
|
||||
|
||||
|
|
|
@ -35,140 +35,217 @@ class LinuxVirtual(Virtual):
|
|||
# For more information, check: http://people.redhat.com/~rjones/virt-what/
|
||||
def get_virtual_facts(self):
|
||||
virtual_facts = {}
|
||||
|
||||
# We want to maintain compatibility with the old "virtualization_type"
|
||||
# and "virtualization_role" entries, so we need to track if we found
|
||||
# them. We won't return them until the end, but if we found them early,
|
||||
# we should avoid updating them again.
|
||||
found_virt = False
|
||||
|
||||
# But as we go along, we also want to track virt tech the new way.
|
||||
host_tech = set()
|
||||
guest_tech = set()
|
||||
|
||||
# lxc/docker
|
||||
if os.path.exists('/proc/1/cgroup'):
|
||||
for line in get_file_lines('/proc/1/cgroup'):
|
||||
if re.search(r'/docker(/|-[0-9a-f]+\.scope)', line):
|
||||
guest_tech.add('docker')
|
||||
if not found_virt:
|
||||
virtual_facts['virtualization_type'] = 'docker'
|
||||
virtual_facts['virtualization_role'] = 'guest'
|
||||
return virtual_facts
|
||||
found_virt = True
|
||||
if re.search('/lxc/', line) or re.search('/machine.slice/machine-lxc', line):
|
||||
guest_tech.add('lxc')
|
||||
if not found_virt:
|
||||
virtual_facts['virtualization_type'] = 'lxc'
|
||||
virtual_facts['virtualization_role'] = 'guest'
|
||||
return virtual_facts
|
||||
found_virt = True
|
||||
|
||||
# lxc does not always appear in cgroups anymore but sets 'container=lxc' environment var, requires root privs
|
||||
if os.path.exists('/proc/1/environ'):
|
||||
for line in get_file_lines('/proc/1/environ', line_sep='\x00'):
|
||||
if re.search('container=lxc', line):
|
||||
guest_tech.add('lxc')
|
||||
if not found_virt:
|
||||
virtual_facts['virtualization_type'] = 'lxc'
|
||||
virtual_facts['virtualization_role'] = 'guest'
|
||||
return virtual_facts
|
||||
found_virt = True
|
||||
if re.search('container=podman', line):
|
||||
guest_tech.add('podman')
|
||||
if not found_virt:
|
||||
virtual_facts['virtualization_type'] = 'podman'
|
||||
virtual_facts['virtualization_role'] = 'guest'
|
||||
return virtual_facts
|
||||
found_virt = True
|
||||
if re.search('^container=.', line):
|
||||
guest_tech.add('container')
|
||||
if not found_virt:
|
||||
virtual_facts['virtualization_type'] = 'container'
|
||||
virtual_facts['virtualization_role'] = 'guest'
|
||||
return virtual_facts
|
||||
found_virt = True
|
||||
|
||||
if os.path.exists('/proc/vz') and not os.path.exists('/proc/lve'):
|
||||
virtual_facts['virtualization_type'] = 'openvz'
|
||||
if os.path.exists('/proc/bc'):
|
||||
host_tech.add('openvz')
|
||||
if not found_virt:
|
||||
virtual_facts['virtualization_role'] = 'host'
|
||||
else:
|
||||
guest_tech.add('openvz')
|
||||
if not found_virt:
|
||||
virtual_facts['virtualization_role'] = 'guest'
|
||||
return virtual_facts
|
||||
found_virt = True
|
||||
|
||||
systemd_container = get_file_content('/run/systemd/container')
|
||||
if systemd_container:
|
||||
guest_tech.add(systemd_container)
|
||||
if not found_virt:
|
||||
virtual_facts['virtualization_type'] = systemd_container
|
||||
virtual_facts['virtualization_role'] = 'guest'
|
||||
return virtual_facts
|
||||
found_virt = True
|
||||
|
||||
if os.path.exists("/proc/xen"):
|
||||
virtual_facts['virtualization_type'] = 'xen'
|
||||
virtual_facts['virtualization_role'] = 'guest'
|
||||
is_xen_host = False
|
||||
try:
|
||||
for line in get_file_lines('/proc/xen/capabilities'):
|
||||
if "control_d" in line:
|
||||
virtual_facts['virtualization_role'] = 'host'
|
||||
is_xen_host = True
|
||||
except IOError:
|
||||
pass
|
||||
return virtual_facts
|
||||
|
||||
if is_xen_host:
|
||||
host_tech.add('xen')
|
||||
if not found_virt:
|
||||
virtual_facts['virtualization_type'] = 'xen'
|
||||
virtual_facts['virtualization_role'] = 'host'
|
||||
else:
|
||||
if not found_virt:
|
||||
virtual_facts['virtualization_type'] = 'xen'
|
||||
virtual_facts['virtualization_role'] = 'guest'
|
||||
found_virt = True
|
||||
|
||||
# assume guest for this block
|
||||
if not found_virt:
|
||||
virtual_facts['virtualization_role'] = 'guest'
|
||||
|
||||
product_name = get_file_content('/sys/devices/virtual/dmi/id/product_name')
|
||||
|
||||
if product_name in ('KVM', 'KVM Server', 'Bochs', 'AHV'):
|
||||
guest_tech.add('kvm')
|
||||
if not found_virt:
|
||||
virtual_facts['virtualization_type'] = 'kvm'
|
||||
return virtual_facts
|
||||
found_virt = True
|
||||
|
||||
if product_name == 'RHEV Hypervisor':
|
||||
guest_tech.add('RHEV')
|
||||
if not found_virt:
|
||||
virtual_facts['virtualization_type'] = 'RHEV'
|
||||
return virtual_facts
|
||||
found_virt = True
|
||||
|
||||
if product_name in ('VMware Virtual Platform', 'VMware7,1'):
|
||||
guest_tech.add('VMware')
|
||||
if not found_virt:
|
||||
virtual_facts['virtualization_type'] = 'VMware'
|
||||
return virtual_facts
|
||||
found_virt = True
|
||||
|
||||
if product_name in ('OpenStack Compute', 'OpenStack Nova'):
|
||||
guest_tech.add('openstack')
|
||||
if not found_virt:
|
||||
virtual_facts['virtualization_type'] = 'openstack'
|
||||
return virtual_facts
|
||||
found_virt = True
|
||||
|
||||
bios_vendor = get_file_content('/sys/devices/virtual/dmi/id/bios_vendor')
|
||||
|
||||
if bios_vendor == 'Xen':
|
||||
guest_tech.add('xen')
|
||||
if not found_virt:
|
||||
virtual_facts['virtualization_type'] = 'xen'
|
||||
return virtual_facts
|
||||
found_virt = True
|
||||
|
||||
if bios_vendor == 'innotek GmbH':
|
||||
guest_tech.add('virtualbox')
|
||||
if not found_virt:
|
||||
virtual_facts['virtualization_type'] = 'virtualbox'
|
||||
return virtual_facts
|
||||
found_virt = True
|
||||
|
||||
if bios_vendor in ('Amazon EC2', 'DigitalOcean', 'Hetzner'):
|
||||
guest_tech.add('kvm')
|
||||
if not found_virt:
|
||||
virtual_facts['virtualization_type'] = 'kvm'
|
||||
return virtual_facts
|
||||
found_virt = True
|
||||
|
||||
sys_vendor = get_file_content('/sys/devices/virtual/dmi/id/sys_vendor')
|
||||
|
||||
KVM_SYS_VENDORS = ('QEMU', 'oVirt', 'Amazon EC2', 'DigitalOcean', 'Google', 'Scaleway', 'Nutanix')
|
||||
if sys_vendor in KVM_SYS_VENDORS:
|
||||
guest_tech.add('kvm')
|
||||
if not found_virt:
|
||||
virtual_facts['virtualization_type'] = 'kvm'
|
||||
return virtual_facts
|
||||
found_virt = True
|
||||
|
||||
# FIXME: This does also match hyperv
|
||||
if sys_vendor == 'Microsoft Corporation':
|
||||
guest_tech.add('VirtualPC')
|
||||
if not found_virt:
|
||||
virtual_facts['virtualization_type'] = 'VirtualPC'
|
||||
return virtual_facts
|
||||
found_virt = True
|
||||
|
||||
if sys_vendor == 'Parallels Software International Inc.':
|
||||
guest_tech.add('parallels')
|
||||
if not found_virt:
|
||||
virtual_facts['virtualization_type'] = 'parallels'
|
||||
return virtual_facts
|
||||
found_virt = True
|
||||
|
||||
if sys_vendor == 'OpenStack Foundation':
|
||||
guest_tech.add('openstack')
|
||||
if not found_virt:
|
||||
virtual_facts['virtualization_type'] = 'openstack'
|
||||
return virtual_facts
|
||||
found_virt = True
|
||||
|
||||
# unassume guest
|
||||
if not found_virt:
|
||||
del virtual_facts['virtualization_role']
|
||||
|
||||
if os.path.exists('/proc/self/status'):
|
||||
for line in get_file_lines('/proc/self/status'):
|
||||
if re.match(r'^VxID:\s+\d+', line):
|
||||
if not found_virt:
|
||||
virtual_facts['virtualization_type'] = 'linux_vserver'
|
||||
if re.match(r'^VxID:\s+0', line):
|
||||
host_tech.add('linux_vserver')
|
||||
if not found_virt:
|
||||
virtual_facts['virtualization_role'] = 'host'
|
||||
else:
|
||||
guest_tech.add('linux_vserver')
|
||||
if not found_virt:
|
||||
virtual_facts['virtualization_role'] = 'guest'
|
||||
return virtual_facts
|
||||
found_virt = True
|
||||
|
||||
if os.path.exists('/proc/cpuinfo'):
|
||||
for line in get_file_lines('/proc/cpuinfo'):
|
||||
if re.match('^model name.*QEMU Virtual CPU', line):
|
||||
guest_tech.add('kvm')
|
||||
if not found_virt:
|
||||
virtual_facts['virtualization_type'] = 'kvm'
|
||||
elif re.match('^vendor_id.*User Mode Linux', line):
|
||||
guest_tech.add('uml')
|
||||
if not found_virt:
|
||||
virtual_facts['virtualization_type'] = 'uml'
|
||||
elif re.match('^model name.*UML', line):
|
||||
guest_tech.add('uml')
|
||||
if not found_virt:
|
||||
virtual_facts['virtualization_type'] = 'uml'
|
||||
elif re.match('^machine.*CHRP IBM pSeries .emulated by qemu.', line):
|
||||
guest_tech.add('kvm')
|
||||
if not found_virt:
|
||||
virtual_facts['virtualization_type'] = 'kvm'
|
||||
elif re.match('^vendor_id.*PowerVM Lx86', line):
|
||||
guest_tech.add('powervm_lx86')
|
||||
if not found_virt:
|
||||
virtual_facts['virtualization_type'] = 'powervm_lx86'
|
||||
elif re.match('^vendor_id.*IBM/S390', line):
|
||||
guest_tech.add('PR/SM')
|
||||
if not found_virt:
|
||||
virtual_facts['virtualization_type'] = 'PR/SM'
|
||||
lscpu = self.module.get_bin_path('lscpu')
|
||||
if lscpu:
|
||||
|
@ -178,16 +255,24 @@ class LinuxVirtual(Virtual):
|
|||
data = line.split(":", 1)
|
||||
key = data[0].strip()
|
||||
if key == 'Hypervisor':
|
||||
virtual_facts['virtualization_type'] = data[1].strip()
|
||||
tech = data[1].strip()
|
||||
guest_tech.add(tech)
|
||||
if not found_virt:
|
||||
virtual_facts['virtualization_type'] = tech
|
||||
else:
|
||||
guest_tech.add('ibm_systemz')
|
||||
if not found_virt:
|
||||
virtual_facts['virtualization_type'] = 'ibm_systemz'
|
||||
else:
|
||||
continue
|
||||
if virtual_facts['virtualization_type'] == 'PR/SM':
|
||||
if not found_virt:
|
||||
virtual_facts['virtualization_role'] = 'LPAR'
|
||||
else:
|
||||
if not found_virt:
|
||||
virtual_facts['virtualization_role'] = 'guest'
|
||||
return virtual_facts
|
||||
if not found_virt:
|
||||
found_virt = True
|
||||
|
||||
# Beware that we can have both kvm and virtualbox running on a single system
|
||||
if os.path.exists("/proc/modules") and os.access('/proc/modules', os.R_OK):
|
||||
|
@ -197,6 +282,8 @@ class LinuxVirtual(Virtual):
|
|||
modules.append(data[0])
|
||||
|
||||
if 'kvm' in modules:
|
||||
host_tech.add('kvm')
|
||||
if not found_virt:
|
||||
virtual_facts['virtualization_type'] = 'kvm'
|
||||
virtual_facts['virtualization_role'] = 'host'
|
||||
|
||||
|
@ -206,23 +293,32 @@ class LinuxVirtual(Virtual):
|
|||
try:
|
||||
with open(f) as virt_fh:
|
||||
comm_content = virt_fh.read().rstrip()
|
||||
|
||||
if comm_content in ('vdsm', 'vdsmd'):
|
||||
# We add both kvm and RHEV to host_tech in this case.
|
||||
# It's accurate. RHEV uses KVM.
|
||||
host_tech.add('RHEV')
|
||||
if not found_virt:
|
||||
virtual_facts['virtualization_type'] = 'RHEV'
|
||||
break
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
return virtual_facts
|
||||
found_virt = True
|
||||
|
||||
if 'vboxdrv' in modules:
|
||||
host_tech.add('virtualbox')
|
||||
if not found_virt:
|
||||
virtual_facts['virtualization_type'] = 'virtualbox'
|
||||
virtual_facts['virtualization_role'] = 'host'
|
||||
return virtual_facts
|
||||
found_virt = True
|
||||
|
||||
if 'virtio' in modules:
|
||||
host_tech.add('kvm')
|
||||
if not found_virt:
|
||||
virtual_facts['virtualization_type'] = 'kvm'
|
||||
virtual_facts['virtualization_role'] = 'guest'
|
||||
return virtual_facts
|
||||
found_virt = True
|
||||
|
||||
# In older Linux Kernel versions, /sys filesystem is not available
|
||||
# dmidecode is the safest option to parse virtualization related values
|
||||
|
@ -234,20 +330,28 @@ class LinuxVirtual(Virtual):
|
|||
# Strip out commented lines (specific dmidecode output)
|
||||
vendor_name = ''.join([line.strip() for line in out.splitlines() if not line.startswith('#')])
|
||||
if vendor_name.startswith('VMware'):
|
||||
guest_tech.add('VMware')
|
||||
if not found_virt:
|
||||
virtual_facts['virtualization_type'] = 'VMware'
|
||||
virtual_facts['virtualization_role'] = 'guest'
|
||||
return virtual_facts
|
||||
found_virt = True
|
||||
|
||||
if os.path.exists('/dev/kvm'):
|
||||
host_tech.add('kvm')
|
||||
if not found_virt:
|
||||
virtual_facts['virtualization_type'] = 'kvm'
|
||||
virtual_facts['virtualization_role'] = 'host'
|
||||
return virtual_facts
|
||||
found_virt = True
|
||||
|
||||
# If none of the above matches, return 'NA' for virtualization_type
|
||||
# and virtualization_role. This allows for proper grouping.
|
||||
if not found_virt:
|
||||
virtual_facts['virtualization_type'] = 'NA'
|
||||
virtual_facts['virtualization_role'] = 'NA'
|
||||
found_virt = True
|
||||
|
||||
virtual_facts['virtualization_tech_guest'] = guest_tech
|
||||
virtual_facts['virtualization_tech_host'] = host_tech
|
||||
return virtual_facts
|
||||
|
||||
|
||||
|
|
|
@ -27,29 +27,44 @@ class NetBSDVirtual(Virtual, VirtualSysctlDetectionMixin):
|
|||
|
||||
def get_virtual_facts(self):
|
||||
virtual_facts = {}
|
||||
host_tech = set()
|
||||
guest_tech = set()
|
||||
|
||||
# Set empty values as default
|
||||
virtual_facts['virtualization_type'] = ''
|
||||
virtual_facts['virtualization_role'] = ''
|
||||
|
||||
virtual_product_facts = self.detect_virt_product('machdep.dmi.system-product')
|
||||
guest_tech.update(virtual_product_facts['virtualization_tech_guest'])
|
||||
host_tech.update(virtual_product_facts['virtualization_tech_host'])
|
||||
virtual_facts.update(virtual_product_facts)
|
||||
|
||||
if virtual_facts['virtualization_type'] == '':
|
||||
virtual_vendor_facts = self.detect_virt_vendor('machdep.dmi.system-vendor')
|
||||
guest_tech.update(virtual_vendor_facts['virtualization_tech_guest'])
|
||||
host_tech.update(virtual_vendor_facts['virtualization_tech_host'])
|
||||
|
||||
if virtual_facts['virtualization_type'] == '':
|
||||
virtual_facts.update(virtual_vendor_facts)
|
||||
|
||||
# The above logic is tried first for backwards compatibility. If
|
||||
# something above matches, use it. Otherwise if the result is still
|
||||
# empty, try machdep.hypervisor.
|
||||
if virtual_facts['virtualization_type'] == '':
|
||||
virtual_vendor_facts = self.detect_virt_vendor('machdep.hypervisor')
|
||||
guest_tech.update(virtual_vendor_facts['virtualization_tech_guest'])
|
||||
host_tech.update(virtual_vendor_facts['virtualization_tech_host'])
|
||||
|
||||
if virtual_facts['virtualization_type'] == '':
|
||||
virtual_facts.update(virtual_vendor_facts)
|
||||
|
||||
if (virtual_facts['virtualization_type'] == '' and
|
||||
os.path.exists('/dev/xencons')):
|
||||
if os.path.exists('/dev/xencons'):
|
||||
guest_tech.add('xen')
|
||||
|
||||
if virtual_facts['virtualization_type'] == '':
|
||||
virtual_facts['virtualization_type'] = 'xen'
|
||||
virtual_facts['virtualization_role'] = 'guest'
|
||||
|
||||
virtual_facts['virtualization_tech_guest'] = guest_tech
|
||||
virtual_facts['virtualization_tech_host'] = host_tech
|
||||
return virtual_facts
|
||||
|
||||
|
||||
|
|
|
@ -35,16 +35,23 @@ class OpenBSDVirtual(Virtual, VirtualSysctlDetectionMixin):
|
|||
|
||||
def get_virtual_facts(self):
|
||||
virtual_facts = {}
|
||||
host_tech = set()
|
||||
guest_tech = set()
|
||||
|
||||
# Set empty values as default
|
||||
virtual_facts['virtualization_type'] = ''
|
||||
virtual_facts['virtualization_role'] = ''
|
||||
|
||||
virtual_product_facts = self.detect_virt_product('hw.product')
|
||||
guest_tech.update(virtual_product_facts['virtualization_tech_guest'])
|
||||
host_tech.update(virtual_product_facts['virtualization_tech_host'])
|
||||
virtual_facts.update(virtual_product_facts)
|
||||
|
||||
if virtual_facts['virtualization_type'] == '':
|
||||
virtual_vendor_facts = self.detect_virt_vendor('hw.vendor')
|
||||
guest_tech.update(virtual_vendor_facts['virtualization_tech_guest'])
|
||||
host_tech.update(virtual_vendor_facts['virtualization_tech_host'])
|
||||
|
||||
if virtual_facts['virtualization_type'] == '':
|
||||
virtual_facts.update(virtual_vendor_facts)
|
||||
|
||||
# Check the dmesg if vmm(4) attached, indicating the host is
|
||||
|
@ -53,9 +60,12 @@ class OpenBSDVirtual(Virtual, VirtualSysctlDetectionMixin):
|
|||
for line in dmesg_boot.splitlines():
|
||||
match = re.match('^vmm0 at mainbus0: (SVM/RVI|VMX/EPT)$', line)
|
||||
if match:
|
||||
host_tech.add('vmm')
|
||||
virtual_facts['virtualization_type'] = 'vmm'
|
||||
virtual_facts['virtualization_role'] = 'host'
|
||||
|
||||
virtual_facts['virtualization_tech_guest'] = guest_tech
|
||||
virtual_facts['virtualization_tech_host'] = host_tech
|
||||
return virtual_facts
|
||||
|
||||
|
||||
|
|
|
@ -32,19 +32,27 @@ class SunOSVirtual(Virtual):
|
|||
|
||||
def get_virtual_facts(self):
|
||||
virtual_facts = {}
|
||||
# Check if it's a zone
|
||||
host_tech = set()
|
||||
guest_tech = set()
|
||||
|
||||
# Check if it's a zone
|
||||
zonename = self.module.get_bin_path('zonename')
|
||||
if zonename:
|
||||
rc, out, err = self.module.run_command(zonename)
|
||||
if rc == 0 and out.rstrip() != "global":
|
||||
if rc == 0:
|
||||
if out.rstrip() == "global":
|
||||
host_tech.add('zone')
|
||||
else:
|
||||
guest_tech.add('zone')
|
||||
virtual_facts['container'] = 'zone'
|
||||
|
||||
# Check if it's a branded zone (i.e. Solaris 8/9 zone)
|
||||
if os.path.isdir('/.SUNWnative'):
|
||||
guest_tech.add('zone')
|
||||
virtual_facts['container'] = 'zone'
|
||||
|
||||
# If it's a zone check if we can detect if our global zone is itself virtualized.
|
||||
# Relies on the "guest tools" (e.g. vmware tools) to be installed
|
||||
|
||||
if 'container' in virtual_facts and virtual_facts['container'] == 'zone':
|
||||
modinfo = self.module.get_bin_path('modinfo')
|
||||
if modinfo:
|
||||
|
@ -52,13 +60,16 @@ class SunOSVirtual(Virtual):
|
|||
if rc == 0:
|
||||
for line in out.splitlines():
|
||||
if 'VMware' in line:
|
||||
guest_tech.add('vmware')
|
||||
virtual_facts['virtualization_type'] = 'vmware'
|
||||
virtual_facts['virtualization_role'] = 'guest'
|
||||
if 'VirtualBox' in line:
|
||||
guest_tech.add('virtualbox')
|
||||
virtual_facts['virtualization_type'] = 'virtualbox'
|
||||
virtual_facts['virtualization_role'] = 'guest'
|
||||
|
||||
if os.path.exists('/proc/vz'):
|
||||
guest_tech.add('virtuozzo')
|
||||
virtual_facts['virtualization_type'] = 'virtuozzo'
|
||||
virtual_facts['virtualization_role'] = 'guest'
|
||||
|
||||
|
@ -77,6 +88,7 @@ class SunOSVirtual(Virtual):
|
|||
for line in out.splitlines():
|
||||
fields = line.split('|')
|
||||
if fields[0] == 'DOMAINROLE' and fields[1] == 'impl=LDoms':
|
||||
guest_tech.add('ldom')
|
||||
virtual_facts['virtualization_type'] = 'ldom'
|
||||
virtual_facts['virtualization_role'] = 'guest'
|
||||
hostfeatures = []
|
||||
|
@ -97,21 +109,28 @@ class SunOSVirtual(Virtual):
|
|||
if rc == 0:
|
||||
for line in out.splitlines():
|
||||
if 'VMware' in line:
|
||||
guest_tech.add('vmware')
|
||||
virtual_facts['virtualization_type'] = 'vmware'
|
||||
virtual_facts['virtualization_role'] = 'guest'
|
||||
elif 'Parallels' in line:
|
||||
guest_tech.add('parallels')
|
||||
virtual_facts['virtualization_type'] = 'parallels'
|
||||
virtual_facts['virtualization_role'] = 'guest'
|
||||
elif 'VirtualBox' in line:
|
||||
guest_tech.add('virtualbox')
|
||||
virtual_facts['virtualization_type'] = 'virtualbox'
|
||||
virtual_facts['virtualization_role'] = 'guest'
|
||||
elif 'HVM domU' in line:
|
||||
guest_tech.add('xen')
|
||||
virtual_facts['virtualization_type'] = 'xen'
|
||||
virtual_facts['virtualization_role'] = 'guest'
|
||||
elif 'KVM' in line:
|
||||
guest_tech.add('kvm')
|
||||
virtual_facts['virtualization_type'] = 'kvm'
|
||||
virtual_facts['virtualization_role'] = 'guest'
|
||||
|
||||
virtual_facts['virtualization_tech_guest'] = guest_tech
|
||||
virtual_facts['virtualization_tech_host'] = host_tech
|
||||
return virtual_facts
|
||||
|
||||
|
||||
|
|
|
@ -25,48 +25,88 @@ class VirtualSysctlDetectionMixin(object):
|
|||
|
||||
def detect_virt_product(self, key):
|
||||
virtual_product_facts = {}
|
||||
host_tech = set()
|
||||
guest_tech = set()
|
||||
|
||||
# We do similar to what we do in linux.py -- We want to allow multiple
|
||||
# virt techs to show up, but maintain compatibility, so we have to track
|
||||
# when we would have stopped, even though now we go through everything.
|
||||
found_virt = False
|
||||
|
||||
self.detect_sysctl()
|
||||
if self.sysctl_path:
|
||||
rc, out, err = self.module.run_command("%s -n %s" % (self.sysctl_path, key))
|
||||
if rc == 0:
|
||||
if re.match('(KVM|kvm|Bochs|SmartDC).*', out):
|
||||
guest_tech.add('kvm')
|
||||
if not found_virt:
|
||||
virtual_product_facts['virtualization_type'] = 'kvm'
|
||||
virtual_product_facts['virtualization_role'] = 'guest'
|
||||
elif re.match('.*VMware.*', out):
|
||||
found_virt = True
|
||||
if re.match('.*VMware.*', out):
|
||||
guest_tech.add('VMware')
|
||||
if not found_virt:
|
||||
virtual_product_facts['virtualization_type'] = 'VMware'
|
||||
virtual_product_facts['virtualization_role'] = 'guest'
|
||||
elif out.rstrip() == 'VirtualBox':
|
||||
found_virt = True
|
||||
if out.rstrip() == 'VirtualBox':
|
||||
guest_tech.add('virtualbox')
|
||||
if not found_virt:
|
||||
virtual_product_facts['virtualization_type'] = 'virtualbox'
|
||||
virtual_product_facts['virtualization_role'] = 'guest'
|
||||
elif re.match('(HVM domU|XenPVH|XenPV|XenPVHVM).*', out):
|
||||
found_virt = True
|
||||
if re.match('(HVM domU|XenPVH|XenPV|XenPVHVM).*', out):
|
||||
guest_tech.add('xen')
|
||||
if not found_virt:
|
||||
virtual_product_facts['virtualization_type'] = 'xen'
|
||||
virtual_product_facts['virtualization_role'] = 'guest'
|
||||
elif out.rstrip() == 'Hyper-V':
|
||||
found_virt = True
|
||||
if out.rstrip() == 'Hyper-V':
|
||||
guest_tech.add('Hyper-V')
|
||||
if not found_virt:
|
||||
virtual_product_facts['virtualization_type'] = 'Hyper-V'
|
||||
virtual_product_facts['virtualization_role'] = 'guest'
|
||||
elif out.rstrip() == 'Parallels':
|
||||
found_virt = True
|
||||
if out.rstrip() == 'Parallels':
|
||||
guest_tech.add('parallels')
|
||||
if not found_virt:
|
||||
virtual_product_facts['virtualization_type'] = 'parallels'
|
||||
virtual_product_facts['virtualization_role'] = 'guest'
|
||||
elif out.rstrip() == 'RHEV Hypervisor':
|
||||
found_virt = True
|
||||
if out.rstrip() == 'RHEV Hypervisor':
|
||||
guest_tech.add('RHEV')
|
||||
if not found_virt:
|
||||
virtual_product_facts['virtualization_type'] = 'RHEV'
|
||||
virtual_product_facts['virtualization_role'] = 'guest'
|
||||
elif (key == 'security.jail.jailed') and (out.rstrip() == '1'):
|
||||
found_virt = True
|
||||
if (key == 'security.jail.jailed') and (out.rstrip() == '1'):
|
||||
guest_tech.add('jails')
|
||||
if not found_virt:
|
||||
virtual_product_facts['virtualization_type'] = 'jails'
|
||||
virtual_product_facts['virtualization_role'] = 'guest'
|
||||
found_virt = True
|
||||
|
||||
virtual_product_facts['virtualization_tech_guest'] = guest_tech
|
||||
virtual_product_facts['virtualization_tech_host'] = host_tech
|
||||
return virtual_product_facts
|
||||
|
||||
def detect_virt_vendor(self, key):
|
||||
virtual_vendor_facts = {}
|
||||
host_tech = set()
|
||||
guest_tech = set()
|
||||
self.detect_sysctl()
|
||||
if self.sysctl_path:
|
||||
rc, out, err = self.module.run_command("%s -n %s" % (self.sysctl_path, key))
|
||||
if rc == 0:
|
||||
if out.rstrip() == 'QEMU':
|
||||
guest_tech.add('kvm')
|
||||
virtual_vendor_facts['virtualization_type'] = 'kvm'
|
||||
virtual_vendor_facts['virtualization_role'] = 'guest'
|
||||
if out.rstrip() == 'OpenBSD':
|
||||
guest_tech.add('vmm')
|
||||
virtual_vendor_facts['virtualization_type'] = 'vmm'
|
||||
virtual_vendor_facts['virtualization_role'] = 'guest'
|
||||
|
||||
virtual_vendor_facts['virtualization_tech_guest'] = guest_tech
|
||||
virtual_vendor_facts['virtualization_tech_host'] = host_tech
|
||||
return virtual_vendor_facts
|
||||
|
|
Loading…
Reference in a new issue