Merge pull request #46139 from bdrung/os-grains

Add os grains test cases for Debian/Ubuntu and fix oscodename on Ubuntu
This commit is contained in:
Nicole Thomas 2018-02-26 11:44:04 -05:00 committed by GitHub
commit 89cf2e5061
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 239 additions and 111 deletions

View file

@ -1218,19 +1218,22 @@ def _get_interfaces():
return _INTERFACES
def _parse_os_release():
def _parse_os_release(os_release_files):
'''
Parse /etc/os-release and return a parameter dictionary
Parse os-release and return a parameter dictionary
See http://www.freedesktop.org/software/systemd/man/os-release.html
for specification of the file format.
'''
filename = '/etc/os-release'
if not os.path.isfile(filename):
filename = '/usr/lib/os-release'
data = dict()
for filename in os_release_files:
if os.path.isfile(filename):
break
else:
# None of the specified os-release files exist
return data
with salt.utils.fopen(filename) as ifile:
regex = re.compile('^([\\w]+)=(?:\'|")?(.*?)(?:\'|")?$')
for line in ifile:
@ -1414,13 +1417,15 @@ def os_data():
# to be incorrectly set to "Arch".
grains['osfullname'] = 'Antergos Linux'
elif 'lsb_distrib_id' not in grains:
if os.path.isfile('/etc/os-release') or os.path.isfile('/usr/lib/os-release'):
os_release = _parse_os_release()
os_release = _parse_os_release(['/etc/os-release', '/usr/lib/os-release'])
if os_release:
if 'NAME' in os_release:
grains['lsb_distrib_id'] = os_release['NAME'].strip()
if 'VERSION_ID' in os_release:
grains['lsb_distrib_release'] = os_release['VERSION_ID']
if 'PRETTY_NAME' in os_release:
if 'VERSION_CODENAME' in os_release:
grains['lsb_distrib_codename'] = os_release['VERSION_CODENAME']
elif 'PRETTY_NAME' in os_release:
codename = os_release['PRETTY_NAME']
# https://github.com/saltstack/salt/issues/44108
if os_release['ID'] == 'debian':
@ -1689,7 +1694,7 @@ def os_data():
grains['osrelease_info']
)
os_name = grains['os' if grains.get('os') in (
'FreeBSD', 'OpenBSD', 'NetBSD', 'Mac', 'Raspbian') else 'osfullname']
'Debian', 'FreeBSD', 'OpenBSD', 'NetBSD', 'Mac', 'Raspbian') else 'osfullname']
grains['osfinger'] = '{0}-{1}'.format(
os_name, grains['osrelease'] if os_name in ('Ubuntu',) else grains['osrelease_info'][0])

View file

@ -0,0 +1,10 @@
# Taken from base-files 7.1wheezy11
PRETTY_NAME="Debian GNU/Linux 7 (wheezy)"
NAME="Debian GNU/Linux"
VERSION_ID="7"
VERSION="7 (wheezy)"
ID=debian
ANSI_COLOR="1;31"
HOME_URL="http://www.debian.org/"
SUPPORT_URL="http://www.debian.org/support/"
BUG_REPORT_URL="http://bugs.debian.org/"

View file

@ -0,0 +1,9 @@
# Taken from base-files 8+deb8u10
PRETTY_NAME="Debian GNU/Linux 8 (jessie)"
NAME="Debian GNU/Linux"
VERSION_ID="8"
VERSION="8 (jessie)"
ID=debian
HOME_URL="http://www.debian.org/"
SUPPORT_URL="http://www.debian.org/support"
BUG_REPORT_URL="https://bugs.debian.org/"

View file

@ -0,0 +1,9 @@
# Taken from base-files 9.9+deb9u3
PRETTY_NAME="Debian GNU/Linux 9 (stretch)"
NAME="Debian GNU/Linux"
VERSION_ID="9"
VERSION="9 (stretch)"
ID=debian
HOME_URL="https://www.debian.org/"
SUPPORT_URL="https://www.debian.org/support"
BUG_REPORT_URL="https://bugs.debian.org/"

View file

@ -0,0 +1,12 @@
# Taken from base-files 9.4ubuntu4.5
NAME="Ubuntu"
VERSION="16.04.3 LTS (Xenial Xerus)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 16.04.3 LTS"
VERSION_ID="16.04"
HOME_URL="http://www.ubuntu.com/"
SUPPORT_URL="http://help.ubuntu.com/"
BUG_REPORT_URL="http://bugs.launchpad.net/ubuntu/"
VERSION_CODENAME=xenial
UBUNTU_CODENAME=xenial

View file

@ -0,0 +1,13 @@
# Taken from base-files 9.6ubuntu102
NAME="Ubuntu"
VERSION="17.10 (Artful Aardvark)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 17.10"
VERSION_ID="17.10"
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
VERSION_CODENAME=artful
UBUNTU_CODENAME=artful

View file

@ -39,6 +39,7 @@ IP4_ADD2 = '10.0.0.2'
IP6_LOCAL = '::1'
IP6_ADD1 = '2001:4860:4860::8844'
IP6_ADD2 = '2001:4860:4860::8888'
OS_RELEASE_DIR = os.path.join(os.path.dirname(__file__), "os-releases")
@skipIf(NO_MOCK, NO_MOCK_REASON)
@ -49,6 +50,35 @@ class CoreGrainsTestCase(TestCase, LoaderModuleMockMixin):
def setup_loader_modules(self):
return {core: {}}
@patch("os.path.isfile")
def test_parse_etc_os_release(self, path_isfile_mock):
path_isfile_mock.side_effect = lambda x: x == "/usr/lib/os-release"
with salt.utils.fopen(os.path.join(OS_RELEASE_DIR, "ubuntu-17.10")) as os_release_file:
os_release_content = os_release_file.readlines()
with patch("salt.utils.fopen", mock_open()) as os_release_file:
os_release_file.return_value.__iter__.return_value = os_release_content
os_release = core._parse_os_release(["/etc/os-release", "/usr/lib/os-release"])
self.assertEqual(os_release, {
"NAME": "Ubuntu",
"VERSION": "17.10 (Artful Aardvark)",
"ID": "ubuntu",
"ID_LIKE": "debian",
"PRETTY_NAME": "Ubuntu 17.10",
"VERSION_ID": "17.10",
"HOME_URL": "https://www.ubuntu.com/",
"SUPPORT_URL": "https://help.ubuntu.com/",
"BUG_REPORT_URL": "https://bugs.launchpad.net/ubuntu/",
"PRIVACY_POLICY_URL": "https://www.ubuntu.com/legal/terms-and-policies/privacy-policy",
"VERSION_CODENAME": "artful",
"UBUNTU_CODENAME": "artful",
})
@patch("os.path.isfile")
def test_missing_os_release(self, path_isfile_mock):
path_isfile_mock.return_value = False
os_release = core._parse_os_release(["/etc/os-release", "/usr/lib/os-release"])
self.assertEqual(os_release, {})
@skipIf(not salt.utils.is_linux(), 'System is not Linux')
def test_gnu_slash_linux_in_os_name(self):
'''
@ -147,9 +177,6 @@ class CoreGrainsTestCase(TestCase, LoaderModuleMockMixin):
_path_exists_map = {
'/proc/1/cmdline': False
}
_path_isfile_map = {
'/etc/os-release': True,
}
_os_release_map = {
'NAME': 'SLES',
'VERSION': '12-SP1',
@ -161,9 +188,6 @@ class CoreGrainsTestCase(TestCase, LoaderModuleMockMixin):
}
path_exists_mock = MagicMock(side_effect=lambda x: _path_exists_map[x])
path_isfile_mock = MagicMock(
side_effect=lambda x: _path_isfile_map.get(x, False)
)
empty_mock = MagicMock(return_value={})
osarch_mock = MagicMock(return_value="amd64")
os_release_mock = MagicMock(return_value=_os_release_map)
@ -191,7 +215,7 @@ class CoreGrainsTestCase(TestCase, LoaderModuleMockMixin):
with patch('{0}.__import__'.format(built_in),
side_effect=_import_mock):
# Skip all the /etc/*-release stuff (not pertinent)
with patch.object(os.path, 'isfile', path_isfile_mock):
with patch.object(os.path, 'isfile', MagicMock(return_value=False)):
with patch.object(core, '_parse_os_release', os_release_mock):
# Mock linux_distribution to give us the OS
# name that we want.
@ -209,11 +233,16 @@ class CoreGrainsTestCase(TestCase, LoaderModuleMockMixin):
self.assertEqual(os_grains.get('os_family'), 'Suse')
self.assertEqual(os_grains.get('os'), 'SUSE')
def _run_suse_os_grains_tests(self, os_release_map):
path_isfile_mock = MagicMock(side_effect=lambda x: x in os_release_map['files'])
def _run_os_grains_tests(self, os_release_filename, os_release_map, expectation):
path_isfile_mock = MagicMock(side_effect=lambda x: x in os_release_map.get('files', []))
empty_mock = MagicMock(return_value={})
osarch_mock = MagicMock(return_value="amd64")
os_release_mock = MagicMock(return_value=os_release_map.get('os_release_file'))
if os_release_filename:
os_release_data = core._parse_os_release(
[os.path.join(OS_RELEASE_DIR, os_release_filename)])
else:
os_release_data = os_release_map.get('os_release_file', {})
os_release_mock = MagicMock(return_value=os_release_data)
orig_import = __import__
if six.PY2:
@ -243,10 +272,11 @@ class CoreGrainsTestCase(TestCase, LoaderModuleMockMixin):
# Mock linux_distribution to give us the OS
# name that we want.
distro_mock = MagicMock(
return_value=('SUSE test', 'version', 'arch')
return_value=os_release_map['linux_distribution']
)
with patch("salt.utils.fopen", mock_open()) as suse_release_file:
suse_release_file.return_value.__iter__.return_value = os_release_map.get('suse_release_file', '').splitlines()
suse_release_file.return_value.__iter__.return_value = \
os_release_map.get('suse_release_file', '').splitlines()
with patch.object(core, 'linux_distribution', distro_mock):
with patch.object(core, '_linux_gpu_data', empty_mock):
with patch.object(core, '_linux_cpudata', empty_mock):
@ -255,13 +285,16 @@ class CoreGrainsTestCase(TestCase, LoaderModuleMockMixin):
with patch.dict(core.__salt__, {'cmd.run': osarch_mock}):
os_grains = core.os_data()
self.assertEqual(os_grains.get('os'), 'SUSE')
self.assertEqual(os_grains.get('os_family'), 'Suse')
self.assertEqual(os_grains.get('osfullname'), os_release_map['osfullname'])
self.assertEqual(os_grains.get('oscodename'), os_release_map['oscodename'])
self.assertEqual(os_grains.get('osrelease'), os_release_map['osrelease'])
self.assertListEqual(list(os_grains.get('osrelease_info')), os_release_map['osrelease_info'])
self.assertEqual(os_grains.get('osmajorrelease'), os_release_map['osmajorrelease'])
grains = {k: v for k, v in os_grains.items()
if k in set(["os", "os_family", "osfullname", "oscodename", "osfinger",
"osrelease", "osrelease_info", "osmajorrelease"])}
self.assertEqual(grains, expectation)
def _run_suse_os_grains_tests(self, os_release_map, expectation):
os_release_map['linux_distribution'] = ('SUSE test', 'version', 'arch')
expectation['os'] = 'SUSE'
expectation['os_family'] = 'Suse'
self._run_os_grains_tests(None, os_release_map, expectation)
@skipIf(not salt.utils.is_linux(), 'System is not Linux')
def test_suse_os_grains_sles11sp3(self):
@ -273,14 +306,17 @@ class CoreGrainsTestCase(TestCase, LoaderModuleMockMixin):
VERSION = 11
PATCHLEVEL = 3
''',
'files': ["/etc/SuSE-release"],
}
expectation = {
'oscodename': 'SUSE Linux Enterprise Server 11 SP3',
'osfullname': "SLES",
'osrelease': '11.3',
'osrelease_info': [11, 3],
'osrelease_info': (11, 3),
'osmajorrelease': 11,
'files': ["/etc/SuSE-release"],
'osfinger': 'SLES-11',
}
self._run_suse_os_grains_tests(_os_release_map)
self._run_suse_os_grains_tests(_os_release_map, expectation)
@skipIf(not salt.utils.is_linux(), 'System is not Linux')
def test_suse_os_grains_sles11sp4(self):
@ -297,14 +333,16 @@ PATCHLEVEL = 3
'ANSI_COLOR': '0;32',
'CPE_NAME': 'cpe:/o:suse:sles:11:4'
},
}
expectation = {
'oscodename': 'SUSE Linux Enterprise Server 11 SP4',
'osfullname': "SLES",
'osrelease': '11.4',
'osrelease_info': [11, 4],
'osrelease_info': (11, 4),
'osmajorrelease': 11,
'files': ["/etc/os-release"],
'osfinger': 'SLES-11',
}
self._run_suse_os_grains_tests(_os_release_map)
self._run_suse_os_grains_tests(_os_release_map, expectation)
@skipIf(not salt.utils.is_linux(), 'System is not Linux')
def test_suse_os_grains_sles12(self):
@ -321,14 +359,16 @@ PATCHLEVEL = 3
'ANSI_COLOR': '0;32',
'CPE_NAME': 'cpe:/o:suse:sles:12'
},
}
expectation = {
'oscodename': 'SUSE Linux Enterprise Server 12',
'osfullname': "SLES",
'osrelease': '12',
'osrelease_info': [12],
'osrelease_info': (12,),
'osmajorrelease': 12,
'files': ["/etc/os-release"],
'osfinger': 'SLES-12',
}
self._run_suse_os_grains_tests(_os_release_map)
self._run_suse_os_grains_tests(_os_release_map, expectation)
@skipIf(not salt.utils.is_linux(), 'System is not Linux')
def test_suse_os_grains_sles12sp1(self):
@ -345,14 +385,16 @@ PATCHLEVEL = 3
'ANSI_COLOR': '0;32',
'CPE_NAME': 'cpe:/o:suse:sles:12:sp1'
},
}
expectation = {
'oscodename': 'SUSE Linux Enterprise Server 12 SP1',
'osfullname': "SLES",
'osrelease': '12.1',
'osrelease_info': [12, 1],
'osrelease_info': (12, 1),
'osmajorrelease': 12,
'files': ["/etc/os-release"],
'osfinger': 'SLES-12',
}
self._run_suse_os_grains_tests(_os_release_map)
self._run_suse_os_grains_tests(_os_release_map, expectation)
@skipIf(not salt.utils.is_linux(), 'System is not Linux')
def test_suse_os_grains_opensuse_leap_42_1(self):
@ -369,14 +411,16 @@ PATCHLEVEL = 3
'ANSI_COLOR': '0;32',
'CPE_NAME': 'cpe:/o:opensuse:opensuse:42.1'
},
}
expectation = {
'oscodename': 'openSUSE Leap 42.1 (x86_64)',
'osfullname': "Leap",
'osrelease': '42.1',
'osrelease_info': [42, 1],
'osrelease_info': (42, 1),
'osmajorrelease': 42,
'files': ["/etc/os-release"],
'osfinger': 'Leap-42',
}
self._run_suse_os_grains_tests(_os_release_map)
self._run_suse_os_grains_tests(_os_release_map, expectation)
@skipIf(not salt.utils.is_linux(), 'System is not Linux')
def test_suse_os_grains_tumbleweed(self):
@ -393,90 +437,116 @@ PATCHLEVEL = 3
'ANSI_COLOR': '0;32',
'CPE_NAME': 'cpe:/o:opensuse:opensuse:20160504'
},
}
expectation = {
'oscodename': 'openSUSE Tumbleweed (20160504) (x86_64)',
'osfullname': "Tumbleweed",
'osrelease': '20160504',
'osrelease_info': [20160504],
'osrelease_info': (20160504,),
'osmajorrelease': 20160504,
'files': ["/etc/os-release"],
'osfinger': 'Tumbleweed-20160504',
}
self._run_suse_os_grains_tests(_os_release_map)
self._run_suse_os_grains_tests(_os_release_map, expectation)
@skipIf(not salt.utils.is_linux(), 'System is not Linux')
def test_ubuntu_os_grains(self):
def test_debian_7_os_grains(self):
'''
Test if OS grains are parsed correctly in Ubuntu Xenial Xerus
Test if OS grains are parsed correctly in Debian 7 "wheezy"
'''
_os_release_map = {
'os_release_file': {
'NAME': 'Ubuntu',
'VERSION': '16.04.1 LTS (Xenial Xerus)',
'VERSION_ID': '16.04',
'PRETTY_NAME': '',
'ID': 'ubuntu',
},
'linux_distribution': ('debian', '7.11', ''),
}
expectation = {
'os': 'Debian',
'os_family': 'Debian',
'oscodename': 'wheezy',
'osfullname': 'Debian GNU/Linux',
'osrelease': '7',
'osrelease_info': (7,),
'osmajorrelease': 7,
'osfinger': 'Debian-7',
}
self._run_os_grains_tests("debian-7", _os_release_map, expectation)
@skipIf(not salt.utils.is_linux(), 'System is not Linux')
def test_debian_8_os_grains(self):
'''
Test if OS grains are parsed correctly in Debian 8 "jessie"
'''
_os_release_map = {
'linux_distribution': ('debian', '8.10', ''),
}
expectation = {
'os': 'Debian',
'os_family': 'Debian',
'oscodename': 'jessie',
'osfullname': 'Debian GNU/Linux',
'osrelease': '8',
'osrelease_info': (8,),
'osmajorrelease': 8,
'osfinger': 'Debian-8',
}
self._run_os_grains_tests("debian-8", _os_release_map, expectation)
@skipIf(not salt.utils.is_linux(), 'System is not Linux')
def test_debian_9_os_grains(self):
'''
Test if OS grains are parsed correctly in Debian 9 "stretch"
'''
_os_release_map = {
'linux_distribution': ('debian', '9.3', ''),
}
expectation = {
'os': 'Debian',
'os_family': 'Debian',
'oscodename': 'stretch',
'osfullname': 'Debian GNU/Linux',
'osrelease': '9',
'osrelease_info': (9,),
'osmajorrelease': 9,
'osfinger': 'Debian-9',
}
self._run_os_grains_tests("debian-9", _os_release_map, expectation)
@skipIf(not salt.utils.is_linux(), 'System is not Linux')
def test_ubuntu_xenial_os_grains(self):
'''
Test if OS grains are parsed correctly in Ubuntu 16.04 "Xenial Xerus"
'''
_os_release_map = {
'linux_distribution': ('Ubuntu', '16.04', 'xenial'),
}
expectation = {
'os': 'Ubuntu',
'os_family': 'Debian',
'oscodename': 'xenial',
'osfullname': 'Ubuntu',
'osrelease': '16.04',
'osrelease_info': [16, 4],
'osrelease_info': (16, 4),
'osmajorrelease': 16,
'osfinger': 'Ubuntu-16.04',
}
self._run_ubuntu_os_grains_tests(_os_release_map)
self._run_os_grains_tests("ubuntu-16.04", _os_release_map, expectation)
def _run_ubuntu_os_grains_tests(self, os_release_map):
path_isfile_mock = MagicMock(side_effect=lambda x: x in ['/etc/os-release'])
empty_mock = MagicMock(return_value={})
osarch_mock = MagicMock(return_value="amd64")
os_release_mock = MagicMock(return_value=os_release_map.get('os_release_file'))
if six.PY2:
built_in = '__builtin__'
else:
built_in = 'builtins'
orig_import = __import__
def _import_mock(name, *args):
if name == 'lsb_release':
raise ImportError('No module named lsb_release')
return orig_import(name, *args)
# Skip the first if statement
with patch.object(salt.utils, 'is_proxy',
MagicMock(return_value=False)):
# Skip the selinux/systemd stuff (not pertinent)
with patch.object(core, '_linux_bin_exists',
MagicMock(return_value=False)):
# Skip the init grain compilation (not pertinent)
with patch.object(os.path, 'exists', path_isfile_mock):
# Ensure that lsb_release fails to import
with patch('{0}.__import__'.format(built_in),
side_effect=_import_mock):
# Skip all the /etc/*-release stuff (not pertinent)
with patch.object(os.path, 'isfile', path_isfile_mock):
with patch.object(core, '_parse_os_release', os_release_mock):
# Mock linux_distribution to give us the OS
# name that we want.
distro_mock = MagicMock(return_value=('Ubuntu', '16.04', 'xenial'))
with patch("salt.utils.fopen", mock_open()) as suse_release_file:
suse_release_file.return_value.__iter__.return_value = os_release_map.get(
'suse_release_file', '').splitlines()
with patch.object(core, 'linux_distribution', distro_mock):
with patch.object(core, '_linux_gpu_data', empty_mock):
with patch.object(core, '_linux_cpudata', empty_mock):
with patch.object(core, '_virtual', empty_mock):
# Mock the osarch
with patch.dict(core.__salt__, {'cmd.run': osarch_mock}):
os_grains = core.os_data()
self.assertEqual(os_grains.get('os'), 'Ubuntu')
self.assertEqual(os_grains.get('os_family'), 'Debian')
self.assertEqual(os_grains.get('osfullname'), os_release_map['osfullname'])
self.assertEqual(os_grains.get('oscodename'), os_release_map['oscodename'])
self.assertEqual(os_grains.get('osrelease'), os_release_map['osrelease'])
self.assertListEqual(list(os_grains.get('osrelease_info')), os_release_map['osrelease_info'])
self.assertEqual(os_grains.get('osmajorrelease'), os_release_map['osmajorrelease'])
@skipIf(not salt.utils.is_linux(), 'System is not Linux')
def test_ubuntu_artful_os_grains(self):
'''
Test if OS grains are parsed correctly in Ubuntu 17.10 "Artful Aardvark"
'''
_os_release_map = {
'linux_distribution': ('Ubuntu', '17.10', 'artful'),
}
expectation = {
'os': 'Ubuntu',
'os_family': 'Debian',
'oscodename': 'artful',
'osfullname': 'Ubuntu',
'osrelease': '17.10',
'osrelease_info': (17, 10),
'osmajorrelease': 17,
'osfinger': 'Ubuntu-17.10',
}
self._run_os_grains_tests("ubuntu-17.10", _os_release_map, expectation)
def test_docker_virtual(self):
'''