summaryrefslogtreecommitdiffstats
path: root/lib/ansible/module_utils/facts/virtual/sunos.py
blob: 1e92677e4ce7e290628c09b3d9c2db6d562ef770 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
# This file is part of Ansible
#
# Ansible 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.
#
# Ansible 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 Ansible.  If not, see <http://www.gnu.org/licenses/>.

from __future__ import (absolute_import, division, print_function)
__metaclass__ = type

import os

from ansible.module_utils.facts.virtual.base import Virtual, VirtualCollector


class SunOSVirtual(Virtual):
    """
    This is a SunOS-specific subclass of Virtual.  It defines
    - virtualization_type
    - virtualization_role
    - container
    """
    platform = 'SunOS'

    def get_virtual_facts(self):
        virtual_facts = {}
        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:
                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:
                rc, out, err = self.module.run_command(modinfo)
                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'

        # Detect domaining on Sparc hardware
        virtinfo = self.module.get_bin_path('virtinfo')
        if virtinfo:
            # The output of virtinfo is different whether we are on a machine with logical
            # domains ('LDoms') on a T-series or domains ('Domains') on a M-series. Try LDoms first.
            rc, out, err = self.module.run_command("/usr/sbin/virtinfo -p")
            # The output contains multiple lines with different keys like this:
            #   DOMAINROLE|impl=LDoms|control=false|io=false|service=false|root=false
            # The output may also be not formatted and the returncode is set to 0 regardless of the error condition:
            #   virtinfo can only be run from the global zone
            if rc == 0:
                try:
                    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 = []
                            for field in fields[2:]:
                                arg = field.split('=')
                                if arg[1] == 'true':
                                    hostfeatures.append(arg[0])
                            if len(hostfeatures) > 0:
                                virtual_facts['virtualization_role'] = 'host (' + ','.join(hostfeatures) + ')'
                except ValueError:
                    pass

        else:
            smbios = self.module.get_bin_path('smbios')
            if not smbios:
                return
            rc, out, err = self.module.run_command(smbios)
            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


class SunOSVirtualCollector(VirtualCollector):
    _fact_class = SunOSVirtual
    _platform = 'SunOS'