Fix OS related grains on Debian

On Debian 8 (jessie), salt report these grains when lsb-release is
installed:

 * os: Debian
 * os_family: Debian
 * osarch: amd64
 * oscodename: jessie
 * osfinger: Debian-8
 * osfullname: Debian
 * osmajorrelease: 8
 * osrelease: 8.2
 * osrelease_info: [8, 2]

When lsb-release is not installed, these grains are reported

 * os: Debian GNU
 * os_family: Debian GNU
 * osarch: x86_64
 * oscodename: Debian GNU
 * osfullname: Debian GNU
 * osrelease: 8
 * osrelease_info: [8]

The previous salt 2015.5.3 release report these grains when
lsb-release is not installed:

 * os: Debian
 * os_family: Debian
 * osarch: amd64
 * oscodename:
 * osfullname: Debian GNU/Linux
 * osrelease: 8.2
 * osrelease_info: [8, 2]

If lsb-release is not installed, /etc/os-release will be queried to
retrieve the operating system information. The regular expression that
parses /etc/os-release is too strict and matches only "Debian GNU" of
"Debian GNU/Linux" from the NAME field.

So follow the os-release file format specification and accept all valid
UTF-8 characters. Also do not convert the parameter names to lower-case
(for matching) since the specification defines all parameters in capital
letters.

Then salt will report these grains without lsb-release installed:

 * os: Debian
 * os_family: Debian
 * osarch: amd64
 * oscodename: Debian GNU/Linux 8 (jessie)
 * osfullname: Debian GNU/Linux
 * osrelease: 8
 * osrelease_info: [8]
This commit is contained in:
Benjamin Drung 2015-11-06 16:14:10 +01:00
parent cf79722260
commit 92a17d4cae

View File

@ -1011,6 +1011,31 @@ def _get_interfaces():
return _INTERFACES
def _parse_os_release():
'''
Parse /etc/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()
with salt.utils.fopen(filename) as ifile:
regex = re.compile('^([\\w]+)=(?:\'|")?(.*?)(?:\'|")?$')
for line in ifile:
match = regex.match(line.strip('\n'))
if match:
# Shell special characters ("$", quotes, backslash, backtick)
# are escaped with backslashes
data[match.group(1)] = re.sub(r'\\([$"\'\\`])', r'\1', match.group(2))
return data
def os_data():
'''
Return grains pertaining to the operating system
@ -1141,32 +1166,14 @@ def os_data():
'lsb_{0}'.format(match.groups()[0].lower())
] = match.groups()[1].rstrip()
if 'lsb_distrib_id' not in grains:
if os.path.isfile('/etc/os-release'):
# Arch ARM Linux - SUSE 12+ - openSUSE 13+
with salt.utils.fopen('/etc/os-release') as ifile:
# Imitate lsb-release
for line in ifile:
# NAME="Arch Linux ARM"
# ID=archarm
# ID_LIKE=arch
# PRETTY_NAME="Arch Linux ARM"
# ANSI_COLOR="0;36"
# HOME_URL="http://archlinuxarm.org/"
# SUPPORT_URL="https://archlinuxarm.org/forum"
# BUG_REPORT_URL=
# "https://github.com/archlinuxarm/PKGBUILDs/issues"
regex = re.compile(
'^([\\w]+)=(?:\'|")?([\\w\\s\\.\\-_]+)(?:\'|")?'
)
match = regex.match(line.rstrip('\n'))
if match:
name, value = match.groups()
if name.lower() == 'name':
grains['lsb_distrib_id'] = value.strip()
elif name.lower() == 'version_id':
grains['lsb_distrib_release'] = value
elif name.lower() == 'pretty_name':
grains['lsb_distrib_codename'] = value
if os.path.isfile('/etc/os-release') or os.path.isfile('/usr/lib/os-release'):
os_release = _parse_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:
grains['lsb_distrib_codename'] = os_release['PRETTY_NAME']
elif os.path.isfile('/etc/SuSE-release'):
grains['lsb_distrib_id'] = 'SUSE'
with salt.utils.fopen('/etc/SuSE-release') as fhr: