diff --git a/lib/ansible/module_utils/facts/system/cmdline.py b/lib/ansible/module_utils/facts/system/cmdline.py index 612132a0787..dbce3843b85 100644 --- a/lib/ansible/module_utils/facts/system/cmdline.py +++ b/lib/ansible/module_utils/facts/system/cmdline.py @@ -27,24 +27,30 @@ class CmdLineFactCollector(BaseFactCollector): name = 'cmdline' _fact_ids = set() - def collect(self, module=None, collected_facts=None): - cmdline_facts = {} - - data = get_file_content('/proc/cmdline') - - if not data: - return cmdline_facts - - cmdline_facts['cmdline'] = {} + def _get_proc_cmdline(self): + return get_file_content('/proc/cmdline') + def _parse_proc_cmdline(self, data): + cmdline_dict = {} try: - for piece in shlex.split(data): + for piece in shlex.split(data, posix=False): item = piece.split('=', 1) if len(item) == 1: - cmdline_facts['cmdline'][item[0]] = True + cmdline_dict[item[0]] = True else: - cmdline_facts['cmdline'][item[0]] = item[1] + cmdline_dict[item[0]] = item[1] except ValueError: pass + return cmdline_dict + + def collect(self, module=None, collected_facts=None): + cmdline_facts = {} + + data = self._get_proc_cmdline() + + if not data: + return cmdline_facts + + cmdline_facts['cmdline'] = self._parse_proc_cmdline(data) return cmdline_facts diff --git a/test/units/module_utils/facts/test_collectors.py b/test/units/module_utils/facts/test_collectors.py index 9920052364c..a356422ea98 100644 --- a/test/units/module_utils/facts/test_collectors.py +++ b/test/units/module_utils/facts/test_collectors.py @@ -119,6 +119,49 @@ class TestCmdLineFacts(BaseFactsTest): fact_namespace = 'ansible_cmdline' collector_class = CmdLineFactCollector + def test_parse_proc_cmdline_uefi(self): + uefi_cmdline = r'initrd=\70ef65e1a04a47aea04f7b5145ea3537\4.10.0-19-generic\initrd root=UUID=50973b75-4a66-4bf0-9764-2b7614489e64 ro quiet' + expected = {'initrd': r'\70ef65e1a04a47aea04f7b5145ea3537\4.10.0-19-generic\initrd', + 'root': 'UUID=50973b75-4a66-4bf0-9764-2b7614489e64', + 'quiet': True, + 'ro': True} + fact_collector = self.collector_class() + facts_dict = fact_collector._parse_proc_cmdline(uefi_cmdline) + + self.assertDictEqual(facts_dict, expected) + + def test_parse_proc_cmdline_fedora(self): + cmdline_fedora = r'BOOT_IMAGE=/vmlinuz-4.10.16-200.fc25.x86_64 root=/dev/mapper/fedora-root ro rd.lvm.lv=fedora/root rd.luks.uuid=luks-c80b7537-358b-4a07-b88c-c59ef187479b rd.lvm.lv=fedora/swap rhgb quiet LANG=en_US.UTF-8' # noqa + + expected = {'BOOT_IMAGE': '/vmlinuz-4.10.16-200.fc25.x86_64', + 'LANG': 'en_US.UTF-8', + 'quiet': True, + 'rd.luks.uuid': 'luks-c80b7537-358b-4a07-b88c-c59ef187479b', + 'rd.lvm.lv': 'fedora/swap', + 'rhgb': True, + 'ro': True, + 'root': '/dev/mapper/fedora-root'} + + fact_collector = self.collector_class() + facts_dict = fact_collector._parse_proc_cmdline(cmdline_fedora) + + self.assertDictEqual(facts_dict, expected) + + def test_parse_proc_cmdline_dup_console(self): + example = r'BOOT_IMAGE=/boot/vmlinuz-4.4.0-72-generic root=UUID=e12e46d9-06c9-4a64-a7b3-60e24b062d90 ro console=tty1 console=ttyS0' + + # FIXME: Two 'console' keywords? Using a dict for the fact value here loses info. Currently the 'last' one wins + expected = {'BOOT_IMAGE': '/boot/vmlinuz-4.4.0-72-generic', + 'root': 'UUID=e12e46d9-06c9-4a64-a7b3-60e24b062d90', + 'ro': True, + 'console': 'ttyS0'} + + fact_collector = self.collector_class() + facts_dict = fact_collector._parse_proc_cmdline(example) + + # TODO: fails because we lose a 'console' + self.assertDictEqual(facts_dict, expected) + class TestDistributionFacts(BaseFactsTest): __test__ = True