diff --git a/lib/ansible/module_utils/facts.py b/lib/ansible/module_utils/facts.py index 5d910a6b4c3..34950a209f1 100644 --- a/lib/ansible/module_utils/facts.py +++ b/lib/ansible/module_utils/facts.py @@ -32,6 +32,10 @@ import datetime import getpass import pwd +from ansible.module_utils.basic import get_all_subclasses +from ansible.module_utils.six import PY3, iteritems + +# py2 vs py3; replace with six via ansiballz try: # python2 import ConfigParser as configparser @@ -39,10 +43,6 @@ except ImportError: # python3 import configparser -from ansible.module_utils.basic import get_all_subclasses -from ansible.module_utils.six import PY3 - -# py2 vs py3; replace with six via ansiballz try: # python2 from StringIO import StringIO @@ -50,7 +50,6 @@ except ImportError: # python3 from io import StringIO - try: # python2 from string import maketrans @@ -58,17 +57,6 @@ except ImportError: # python3 maketrans = str.maketrans # TODO: is this really identical? -try: - dict.iteritems -except AttributeError: - # Python 3 - def iteritems(d): - return d.items() -else: - # Python 2 - def iteritems(d): - return d.iteritems() - try: # Python 2 long @@ -280,6 +268,13 @@ class Facts(object): # if that fails read it with ConfigParser # if that fails, skip it rc, out, err = self.module.run_command(fn) + try: + out = out.decode('utf-8', 'strict') + except UnicodeError: + fact = 'error loading fact - output of running %s was not utf-8' % fn + local[fact_base] = fact + self.facts['local'] = local + return else: out = get_file_content(fn, default='') @@ -406,6 +401,7 @@ class Facts(object): if lsb_path: rc, out, err = self.module.run_command([lsb_path, "-a"]) if rc == 0: + out = out.decode('utf-8', 'replace') self.facts['lsb'] = {} for line in out.split('\n'): if len(line) < 1 or ':' not in line: @@ -476,6 +472,7 @@ class Facts(object): capsh_path = self.module.get_bin_path('capsh') if capsh_path: rc, out, err = self.module.run_command([capsh_path, "--print"]) + out = out.decode('utf-8', 'replace') enforced_caps = [] enforced = 'NA' for line in out.split('\n'): @@ -1139,10 +1136,23 @@ class LinuxHardware(Hardware): self.facts['processor_threads_per_core'] = 1 self.facts['processor_vcpus'] = i else: - self.facts['processor_count'] = sockets and len(sockets) or i - self.facts['processor_cores'] = sockets.values() and sockets.values()[0] or 1 - self.facts['processor_threads_per_core'] = ((cores.values() and - cores.values()[0] or 1) / self.facts['processor_cores']) + if sockets: + self.facts['processor_count'] = len(sockets) + else: + self.facts['processor_count'] = i + + socket_values = list(sockets.values()) + if socket_values: + self.facts['processor_cores'] = socket_values[0] + else: + self.facts['processor_cores'] = 1 + + core_values = list(cores.values()) + if core_values: + self.facts['processor_threads_per_core'] = core_values[0] // self.facts['processor_cores'] + else: + self.facts['processor_threads_per_core'] = 1 // self.facts['processor_cores'] + self.facts['processor_vcpus'] = (self.facts['processor_threads_per_core'] * self.facts['processor_count'] * self.facts['processor_cores']) @@ -1270,6 +1280,7 @@ class LinuxHardware(Hardware): rc, out, err = self._run_findmnt(findmnt_path) if rc != 0: return bind_mounts + out = out.decode('utf-8', 'replace') # find bind mounts, in case /etc/mtab is a symlink to /proc/mounts for line in out.splitlines(): @@ -1349,6 +1360,7 @@ class LinuxHardware(Hardware): lspci = self.module.get_bin_path('lspci') if lspci: rc, pcidata, err = self.module.run_command([lspci, '-D']) + pcidata = pcidata.decode('utf-8', 'replace') else: pcidata = None @@ -2191,6 +2203,7 @@ class LinuxNetwork(Network): if v == 'v6' and not socket.has_ipv6: continue rc, out, err = self.module.run_command(command[v]) + out = out.decode('utf-8', 'replace') if not out: # v6 routing may result in # RTNETLINK answers: Invalid argument @@ -2357,11 +2370,11 @@ class LinuxNetwork(Network): args = [ip_path, 'addr', 'show', 'primary', device] rc, stdout, stderr = self.module.run_command(args) - primary_data = stdout + primary_data = stdout.decode('utf-8', 'replace') args = [ip_path, 'addr', 'show', 'secondary', device] rc, stdout, stderr = self.module.run_command(args) - secondary_data = stdout + secondary_data = stdout.decode('utf-8', 'decode') parse_ip_output(primary_data) parse_ip_output(secondary_data, secondary=True) @@ -2384,6 +2397,7 @@ class LinuxNetwork(Network): if ethtool_path: args = [ethtool_path, '-k', device] rc, stdout, stderr = self.module.run_command(args) + stdout = stdout.decode('utf-8', 'replace') if rc == 0: for line in stdout.strip().split('\n'): if not line or line.endswith(":"): diff --git a/test/units/module_utils/test_facts.py b/test/units/module_utils/test_facts.py index c2a47863de4..2ccdc3fd072 100644 --- a/test/units/module_utils/test_facts.py +++ b/test/units/module_utils/test_facts.py @@ -170,7 +170,7 @@ class TestSunOSVirtual(BaseTestFactsPlatform): fact_class = facts.SunOSVirtual -LSBLK_OUTPUT = """ +LSBLK_OUTPUT = b""" /dev/sda /dev/sda1 32caaec3-ef40-4691-a3b6-438c3f9bc1c0 /dev/sda2 66Ojcd-ULtu-1cZa-Tywo-mx0d-RF4O-ysA9jK @@ -187,7 +187,7 @@ LSBLK_OUTPUT = """ /dev/mapper/docker-253:1-1050967-pool """ -LSBLK_OUTPUT_2 = """ +LSBLK_OUTPUT_2 = b""" /dev/sda /dev/sda1 32caaec3-ef40-4691-a3b6-438c3f9bc1c0 /dev/sda2 66Ojcd-ULtu-1cZa-Tywo-mx0d-RF4O-ysA9jK @@ -401,7 +401,7 @@ MTAB_ENTRIES = \ BIND_MOUNTS = ['/not/a/real/bind_mount'] -FINDMNT_OUTPUT = """ +FINDMNT_OUTPUT = b""" /sys sysfs sysfs rw,nosuid,nodev,noexec,relatime,seclabel /proc proc proc rw,nosuid,nodev,noexec,relatime /dev devtmpfs devtmpfs rw,nosuid,seclabel,size=8044400k,nr_inodes=2011100,mode=755 @@ -517,9 +517,9 @@ class TestFactsLinuxHardwareGetMountFacts(unittest.TestCase): lsblk_uuids = lh._lsblk_uuid() self.assertIsInstance(lsblk_uuids, dict) - self.assertIn('/dev/loop9', lsblk_uuids) - self.assertIn('/dev/sda1', lsblk_uuids) - self.assertEquals(lsblk_uuids['/dev/sda1'], '32caaec3-ef40-4691-a3b6-438c3f9bc1c0') + self.assertIn(b'/dev/loop9', lsblk_uuids) + self.assertIn(b'/dev/sda1', lsblk_uuids) + self.assertEquals(lsblk_uuids[b'/dev/sda1'], b'32caaec3-ef40-4691-a3b6-438c3f9bc1c0') @patch('ansible.module_utils.facts.LinuxHardware._run_lsblk', return_value=(37, LSBLK_OUTPUT,'')) def test_lsblk_uuid_non_zero(self, mock_run_lsblk): @@ -545,7 +545,7 @@ class TestFactsLinuxHardwareGetMountFacts(unittest.TestCase): lh = facts.LinuxHardware(module=module, load_on_init=False) lsblk_uuids = lh._lsblk_uuid() self.assertIsInstance(lsblk_uuids, dict) - self.assertIn('/dev/loop0', lsblk_uuids) - self.assertIn('/dev/sda1', lsblk_uuids) - self.assertEquals(lsblk_uuids['/dev/mapper/an-example-mapper with a space in the name'], '84639acb-013f-4d2f-9392-526a572b4373') - self.assertEquals(lsblk_uuids['/dev/sda1'], '32caaec3-ef40-4691-a3b6-438c3f9bc1c0') + self.assertIn(b'/dev/loop0', lsblk_uuids) + self.assertIn(b'/dev/sda1', lsblk_uuids) + self.assertEquals(lsblk_uuids[b'/dev/mapper/an-example-mapper with a space in the name'], b'84639acb-013f-4d2f-9392-526a572b4373') + self.assertEquals(lsblk_uuids[b'/dev/sda1'], b'32caaec3-ef40-4691-a3b6-438c3f9bc1c0')