blob: 43e46380d7b8c71a60d6dd329fe2fabac7ab4927 [file] [log] [blame]
Brad Bishopc342db32019-05-15 21:57:59 -04001#
2# SPDX-License-Identifier: GPL-2.0-only
3#
4
Brad Bishopd7bf8c12018-02-25 22:55:05 -05005def get_os_release():
6 """Get all key-value pairs from /etc/os-release as a dict"""
7 from collections import OrderedDict
8
9 data = OrderedDict()
10 if os.path.exists('/etc/os-release'):
11 with open('/etc/os-release') as f:
12 for line in f:
13 try:
14 key, val = line.rstrip().split('=', 1)
15 except ValueError:
16 continue
17 data[key.strip()] = val.strip('"')
18 return data
19
Brad Bishop6e60e8b2018-02-01 10:27:11 -050020def release_dict_osr():
21 """ Populate a dict with pertinent values from /etc/os-release """
Brad Bishop6e60e8b2018-02-01 10:27:11 -050022 data = {}
Brad Bishopd7bf8c12018-02-25 22:55:05 -050023 os_release = get_os_release()
24 if 'ID' in os_release:
25 data['DISTRIB_ID'] = os_release['ID']
26 if 'VERSION_ID' in os_release:
27 data['DISTRIB_RELEASE'] = os_release['VERSION_ID']
Brad Bishop6e60e8b2018-02-01 10:27:11 -050028
29 return data
30
31def release_dict_lsb():
32 """ Return the output of lsb_release -ir as a dictionary """
Patrick Williamsc124f4f2015-09-15 14:41:29 -050033 from subprocess import PIPE
34
35 try:
36 output, err = bb.process.run(['lsb_release', '-ir'], stderr=PIPE)
37 except bb.process.CmdError as exc:
Brad Bishop6e60e8b2018-02-01 10:27:11 -050038 return {}
39
40 lsb_map = { 'Distributor ID': 'DISTRIB_ID',
41 'Release': 'DISTRIB_RELEASE'}
42 lsb_keys = lsb_map.keys()
Patrick Williamsc124f4f2015-09-15 14:41:29 -050043
44 data = {}
45 for line in output.splitlines():
Brad Bishop6e60e8b2018-02-01 10:27:11 -050046 if line.startswith("-e"):
47 line = line[3:]
Patrick Williamsc124f4f2015-09-15 14:41:29 -050048 try:
49 key, value = line.split(":\t", 1)
50 except ValueError:
51 continue
Brad Bishop6e60e8b2018-02-01 10:27:11 -050052 if key in lsb_keys:
53 data[lsb_map[key]] = value
54
55 if len(data.keys()) != 2:
56 return None
57
Patrick Williamsc124f4f2015-09-15 14:41:29 -050058 return data
59
60def release_dict_file():
Brad Bishop6e60e8b2018-02-01 10:27:11 -050061 """ Try to gather release information manually when other methods fail """
62 data = {}
Patrick Williamsc124f4f2015-09-15 14:41:29 -050063 try:
64 if os.path.exists('/etc/lsb-release'):
65 data = {}
66 with open('/etc/lsb-release') as f:
67 for line in f:
68 key, value = line.split("=", 1)
69 data[key] = value.strip()
70 elif os.path.exists('/etc/redhat-release'):
71 data = {}
72 with open('/etc/redhat-release') as f:
73 distro = f.readline().strip()
74 import re
75 match = re.match(r'(.*) release (.*) \((.*)\)', distro)
76 if match:
77 data['DISTRIB_ID'] = match.group(1)
78 data['DISTRIB_RELEASE'] = match.group(2)
Patrick Williamsc124f4f2015-09-15 14:41:29 -050079 elif os.path.exists('/etc/SuSE-release'):
80 data = {}
81 data['DISTRIB_ID'] = 'SUSE LINUX'
82 with open('/etc/SuSE-release') as f:
83 for line in f:
84 if line.startswith('VERSION = '):
85 data['DISTRIB_RELEASE'] = line[10:].rstrip()
86 break
87
88 except IOError:
Brad Bishop6e60e8b2018-02-01 10:27:11 -050089 return {}
Patrick Williamsc124f4f2015-09-15 14:41:29 -050090 return data
91
92def distro_identifier(adjust_hook=None):
93 """Return a distro identifier string based upon lsb_release -ri,
94 with optional adjustment via a hook"""
95
Patrick Williamsd8c66bc2016-06-20 12:57:21 -050096 import re
97
Brad Bishop6e60e8b2018-02-01 10:27:11 -050098 # Try /etc/os-release first, then the output of `lsb_release -ir` and
99 # finally fall back on parsing various release files in order to determine
100 # host distro name and version.
101 distro_data = release_dict_osr()
102 if not distro_data:
103 distro_data = release_dict_lsb()
104 if not distro_data:
105 distro_data = release_dict_file()
106
107 distro_id = distro_data.get('DISTRIB_ID', '')
108 release = distro_data.get('DISTRIB_RELEASE', '')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500109
110 if adjust_hook:
111 distro_id, release = adjust_hook(distro_id, release)
112 if not distro_id:
Brad Bishop00e122a2019-10-05 11:10:57 -0400113 return "unknown"
114 # Filter out any non-alphanumerics and convert to lowercase
115 distro_id = re.sub(r'\W', '', distro_id).lower()
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500116
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500117 if release:
Brad Bishop00e122a2019-10-05 11:10:57 -0400118 id_str = '{0}-{1}'.format(distro_id, release)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500119 else:
120 id_str = distro_id
121 return id_str.replace(' ','-').replace('/','-')