Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Port some changes that occured on v1 get_facts modules to v2 #10768

Merged
merged 1 commit into from
Apr 19, 2015
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
199 changes: 170 additions & 29 deletions v2/ansible/module_utils/facts.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,8 @@ class Facts(object):
_I386RE = re.compile(r'i([3456]86|86pc)')
# For the most part, we assume that platform.dist() will tell the truth.
# This is the fallback to handle unknowns or exceptions
OSDIST_LIST = ( ('/etc/redhat-release', 'RedHat'),
OSDIST_LIST = ( ('/etc/oracle-release', 'Oracle Linux'),
('/etc/redhat-release', 'RedHat'),
('/etc/vmware-release', 'VMwareESX'),
('/etc/openwrt_release', 'OpenWrt'),
('/etc/system-release', 'OtherLinux'),
Expand Down Expand Up @@ -170,9 +171,14 @@ def get_platform_facts(self):
if self.facts['system'] == 'Linux':
self.get_distribution_facts()
elif self.facts['system'] == 'AIX':
rc, out, err = module.run_command("/usr/sbin/bootinfo -p")
data = out.split('\n')
self.facts['architecture'] = data[0]
try:
rc, out, err = module.run_command("/usr/sbin/bootinfo -p")
data = out.split('\n')
self.facts['architecture'] = data[0]
except:
self.facts['architecture'] = 'Not Available'
elif self.facts['system'] == 'OpenBSD':
self.facts['architecture'] = platform.uname()[5]


def get_local_facts(self):
Expand Down Expand Up @@ -229,8 +235,8 @@ def get_distribution_facts(self):
RedHat = 'RedHat', Fedora = 'RedHat', CentOS = 'RedHat', Scientific = 'RedHat',
SLC = 'RedHat', Ascendos = 'RedHat', CloudLinux = 'RedHat', PSBM = 'RedHat',
OracleLinux = 'RedHat', OVS = 'RedHat', OEL = 'RedHat', Amazon = 'RedHat',
XenServer = 'RedHat', Ubuntu = 'Debian', Debian = 'Debian', SLES = 'Suse',
SLED = 'Suse', OpenSuSE = 'Suse', SuSE = 'Suse', Gentoo = 'Gentoo', Funtoo = 'Gentoo',
XenServer = 'RedHat', Ubuntu = 'Debian', Debian = 'Debian', Raspbian = 'Debian', SLES = 'Suse',
SLED = 'Suse', openSUSE = 'Suse', SuSE = 'Suse', Gentoo = 'Gentoo', Funtoo = 'Gentoo',
Archlinux = 'Archlinux', Mandriva = 'Mandrake', Mandrake = 'Mandrake',
Solaris = 'Solaris', Nexenta = 'Solaris', OmniOS = 'Solaris', OpenIndiana = 'Solaris',
SmartOS = 'Solaris', AIX = 'AIX', Alpine = 'Alpine', MacOSX = 'Darwin',
Expand Down Expand Up @@ -261,6 +267,10 @@ def get_distribution_facts(self):
self.facts['distribution'] = 'FreeBSD'
self.facts['distribution_release'] = platform.release()
self.facts['distribution_version'] = platform.version()
elif self.facts['system'] == 'NetBSD':
self.facts['distribution'] = 'NetBSD'
self.facts['distribution_release'] = platform.release()
self.facts['distribution_version'] = platform.version()
elif self.facts['system'] == 'OpenBSD':
self.facts['distribution'] = 'OpenBSD'
self.facts['distribution_release'] = platform.release()
Expand All @@ -284,6 +294,13 @@ def get_distribution_facts(self):
# Once we determine the value is one of these distros
# we trust the values are always correct
break
elif name == 'Oracle Linux':
data = get_file_content(path)
if 'Oracle Linux' in data:
self.facts['distribution'] = name
else:
self.facts['distribution'] = data.split()[0]
break
elif name == 'RedHat':
data = get_file_content(path)
if 'Red Hat' in data:
Expand Down Expand Up @@ -354,24 +371,49 @@ def get_distribution_facts(self):
data = get_file_content(path)
if 'suse' in data.lower():
if path == '/etc/os-release':
release = re.search("PRETTY_NAME=[^(]+ \(?([^)]+?)\)", data)
distdata = get_file_content(path).split('\n')[0]
self.facts['distribution'] = distdata.split('=')[1]
if release:
self.facts['distribution_release'] = release.groups()[0]
break
for line in data.splitlines():
distribution = re.search("^NAME=(.*)", line)
if distribution:
self.facts['distribution'] = distribution.group(1).strip('"')
distribution_version = re.search('^VERSION_ID="?([0-9]+\.?[0-9]*)"?', line) # example pattern are 13.04 13.0 13
if distribution_version:
self.facts['distribution_version'] = distribution_version.group(1)
if 'open' in data.lower():
release = re.search("^PRETTY_NAME=[^(]+ \(?([^)]+?)\)", line)
if release:
self.facts['distribution_release'] = release.groups()[0]
elif 'enterprise' in data.lower():
release = re.search('^VERSION_ID="?[0-9]+\.?([0-9]*)"?', line) # SLES doesn't got funny release names
if release:
release = release.group(1)
else:
release = "0" # no minor number, so it is the first release
self.facts['distribution_release'] = release
break
elif path == '/etc/SuSE-release':
data = data.splitlines()
distdata = get_file_content(path).split('\n')[0]
self.facts['distribution'] = distdata.split()[0]
for line in data:
release = re.search('CODENAME *= *([^\n]+)', line)
if release:
self.facts['distribution_release'] = release.groups()[0].strip()
break
if 'open' in data.lower():
data = data.splitlines()
distdata = get_file_content(path).split('\n')[0]
self.facts['distribution'] = distdata.split()[0]
for line in data:
release = re.search('CODENAME *= *([^\n]+)', line)
if release:
self.facts['distribution_release'] = release.groups()[0].strip()
elif 'enterprise' in data.lower():
lines = data.splitlines()
distribution = lines[0].split()[0]
if "Server" in data:
self.facts['distribution'] = "SLES"
elif "Desktop" in data:
self.facts['distribution'] = "SLED"
for line in lines:
release = re.search('PATCHLEVEL = ([0-9]+)', line) # SLES doesn't got funny release names
if release:
self.facts['distribution_release'] = release.group(1)
self.facts['distribution_version'] = self.facts['distribution_version'] + '.' + release.group(1)
elif name == 'Debian':
data = get_file_content(path)
if 'Debian' in data:
if 'Debian' in data or 'Raspbian' in data:
release = re.search("PRETTY_NAME=[^(]+ \(?([^)]+?)\)", data)
if release:
self.facts['distribution_release'] = release.groups()[0]
Expand Down Expand Up @@ -403,7 +445,10 @@ def get_distribution_facts(self):
self.facts['distribution_release'] = release.group(1).strip('"')
else:
self.facts['distribution'] = name

machine_id = get_file_content("/var/lib/dbus/machine-id") or get_file_content("/etc/machine-id")
if machine_id:
machine_id = machine_id.split('\n')[0]
self.facts["machine_id"] = machine_id
self.facts['os_family'] = self.facts['distribution']
if self.facts['distribution'] in OS_FAMILY:
self.facts['os_family'] = OS_FAMILY[self.facts['distribution']]
Expand Down Expand Up @@ -462,7 +507,7 @@ def get_lsb_facts(self):
if rc == 0:
self.facts['lsb'] = {}
for line in out.split('\n'):
if len(line) < 1:
if len(line) < 1 or ':' not in line:
continue
value = line.split(':', 1)[1].strip()
if 'LSB Version:' in line:
Expand Down Expand Up @@ -635,6 +680,7 @@ def populate(self):
self.get_memory_facts()
self.get_dmi_facts()
self.get_device_facts()
self.get_uptime_facts()
try:
self.get_mount_facts()
except TimeoutError:
Expand Down Expand Up @@ -855,13 +901,14 @@ def get_mount_facts(self):
size_available = statvfs_result.f_bsize * (statvfs_result.f_bavail)
except OSError, e:
continue

uuid = 'NA'
lsblkPath = module.get_bin_path("lsblk")
rc, out, err = module.run_command("%s -ln --output UUID %s" % (lsblkPath, fields[0]), use_unsafe_shell=True)
if lsblkPath:
rc, out, err = module.run_command("%s -ln --output UUID %s" % (lsblkPath, fields[0]), use_unsafe_shell=True)

if rc == 0:
uuid = out.strip()
else:
uuid = 'NA'
if rc == 0:
uuid = out.strip()

self.facts['mounts'].append(
{'mount': fields[1],
Expand Down Expand Up @@ -973,6 +1020,9 @@ def get_device_facts(self):

self.facts['devices'][diskname] = d

def get_uptime_facts(self):
uptime_seconds_string = get_file_content('/proc/uptime').split(' ')[0]
self.facts['uptime_seconds'] = int(float(uptime_seconds_string))

class SunOSHardware(Hardware):
"""
Expand All @@ -987,6 +1037,10 @@ def __init__(self):
def populate(self):
self.get_cpu_facts()
self.get_memory_facts()
try:
self.get_mount_facts()
except TimeoutError:
pass
return self.facts

def get_cpu_facts(self):
Expand Down Expand Up @@ -1047,6 +1101,17 @@ def get_memory_facts(self):
self.facts['swap_allocated_mb'] = allocated / 1024
self.facts['swap_reserved_mb'] = reserved / 1024

@timeout(10)
def get_mount_facts(self):
self.facts['mounts'] = []
# For a detailed format description see mnttab(4)
# special mount_point fstype options time
fstab = get_file_content('/etc/mnttab')
if fstab:
for line in fstab.split('\n'):
fields = line.rstrip('\n').split('\t')
self.facts['mounts'].append({'mount': fields[1], 'device': fields[0], 'fstype' : fields[2], 'options': fields[3], 'time': fields[4]})

class OpenBSDHardware(Hardware):
"""
OpenBSD-specific subclass of Hardware. Defines memory, CPU and device facts:
Expand All @@ -1071,6 +1136,7 @@ def populate(self):
self.get_memory_facts()
self.get_processor_facts()
self.get_device_facts()
self.get_mount_facts()
return self.facts

def get_sysctl(self):
Expand All @@ -1083,6 +1149,19 @@ def get_sysctl(self):
sysctl[key] = value.strip()
return sysctl

@timeout(10)
def get_mount_facts(self):
self.facts['mounts'] = []
fstab = get_file_content('/etc/fstab')
if fstab:
for line in fstab.split('\n'):
if line.startswith('#') or line.strip() == '':
continue
fields = re.sub(r'\s+',' ',line.rstrip('\n')).split()
if fields[1] == 'none' or fields[3] == 'xx':
continue
self.facts['mounts'].append({'mount': fields[1], 'device': fields[0], 'fstype' : fields[2], 'options': fields[3]})

def get_memory_facts(self):
# Get free memory. vmstat output looks like:
# procs memory page disks traps cpu
Expand Down Expand Up @@ -2133,7 +2212,40 @@ def get_interfaces_info(self, ifconfig_path):
self.parse_inet6_line(words, current_if, ips)
else:
self.parse_unknown_line(words, current_if, ips)

uname_path = module.get_bin_path('uname')
if uname_path:
rc, out, err = module.run_command([uname_path, '-W'])
# don't bother with wpars it does not work
# zero means not in wpar
if out.split()[0] == '0':
if current_if['macaddress'] == 'unknown' and re.match('^en', current_if['device']):
entstat_path = module.get_bin_path('entstat')
if entstat_path:
rc, out, err = module.run_command([entstat_path, current_if['device'] ])
if rc != 0:
break
for line in out.split('\n'):
if not line:
pass
buff = re.match('^Hardware Address: (.*)', line)
if buff:
current_if['macaddress'] = buff.group(1)

buff = re.match('^Device Type:', line)
if buff and re.match('.*Ethernet', line):
current_if['type'] = 'ether'
# device must have mtu attribute in ODM
if 'mtu' not in current_if:
lsattr_path = module.get_bin_path('lsattr')
if lsattr_path:
rc, out, err = module.run_command([lsattr_path,'-El', current_if['device'] ])
if rc != 0:
break
for line in out.split('\n'):
if line:
words = line.split()
if words[0] == 'mtu':
current_if['mtu'] = words[1]
return interfaces, ips

# AIX 'ifconfig -a' does not inform about MTU, so remove current_if['mtu'] here
Expand Down Expand Up @@ -2360,6 +2472,11 @@ def get_virtual_facts(self):
self.facts['virtualization_role'] = 'guest'
return

if sys_vendor == 'oVirt':
self.facts['virtualization_type'] = 'kvm'
self.facts['virtualization_role'] = 'guest'
return

if os.path.exists('/proc/self/status'):
for line in get_file_lines('/proc/self/status'):
if re.match('^VxID: \d+', line):
Expand Down Expand Up @@ -2514,6 +2631,30 @@ def get_virtual_facts(self):
if 'VirtualBox' in line:
self.facts['virtualization_type'] = 'virtualbox'
self.facts['virtualization_role'] = 'guest'
# Detect domaining on Sparc hardware
if os.path.exists("/usr/sbin/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 = 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 formated and the returncode is set to 0 regardless of the error condition:
# virtinfo can only be run from the global zone
try:
for line in out.split('\n'):
fields = line.split('|')
if( fields[0] == 'DOMAINROLE' and fields[1] == 'impl=LDoms' ):
self.facts['virtualization_type'] = 'ldom'
self.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 ):
self.facts['virtualization_role'] = 'host (' + ','.join(hostfeatures) + ')'
except ValueError, e:
pass

def get_file_content(path, default=None, strip=True):
data = default
Expand Down