xref: /OK3568_Linux_fs/yocto/poky/meta/lib/oe/lsb.py (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun#
2*4882a593Smuzhiyun# SPDX-License-Identifier: GPL-2.0-only
3*4882a593Smuzhiyun#
4*4882a593Smuzhiyun
5*4882a593Smuzhiyundef get_os_release():
6*4882a593Smuzhiyun    """Get all key-value pairs from /etc/os-release as a dict"""
7*4882a593Smuzhiyun    from collections import OrderedDict
8*4882a593Smuzhiyun
9*4882a593Smuzhiyun    data = OrderedDict()
10*4882a593Smuzhiyun    if os.path.exists('/etc/os-release'):
11*4882a593Smuzhiyun        with open('/etc/os-release') as f:
12*4882a593Smuzhiyun            for line in f:
13*4882a593Smuzhiyun                try:
14*4882a593Smuzhiyun                    key, val = line.rstrip().split('=', 1)
15*4882a593Smuzhiyun                except ValueError:
16*4882a593Smuzhiyun                    continue
17*4882a593Smuzhiyun                data[key.strip()] = val.strip('"')
18*4882a593Smuzhiyun    return data
19*4882a593Smuzhiyun
20*4882a593Smuzhiyundef release_dict_osr():
21*4882a593Smuzhiyun    """ Populate a dict with pertinent values from /etc/os-release """
22*4882a593Smuzhiyun    data = {}
23*4882a593Smuzhiyun    os_release = get_os_release()
24*4882a593Smuzhiyun    if 'ID' in os_release:
25*4882a593Smuzhiyun        data['DISTRIB_ID'] = os_release['ID']
26*4882a593Smuzhiyun    if 'VERSION_ID' in os_release:
27*4882a593Smuzhiyun        data['DISTRIB_RELEASE'] = os_release['VERSION_ID']
28*4882a593Smuzhiyun
29*4882a593Smuzhiyun    return data
30*4882a593Smuzhiyun
31*4882a593Smuzhiyundef release_dict_lsb():
32*4882a593Smuzhiyun    """ Return the output of lsb_release -ir as a dictionary """
33*4882a593Smuzhiyun    from subprocess import PIPE
34*4882a593Smuzhiyun
35*4882a593Smuzhiyun    try:
36*4882a593Smuzhiyun        output, err = bb.process.run(['lsb_release', '-ir'], stderr=PIPE)
37*4882a593Smuzhiyun    except bb.process.CmdError as exc:
38*4882a593Smuzhiyun        return {}
39*4882a593Smuzhiyun
40*4882a593Smuzhiyun    lsb_map = { 'Distributor ID': 'DISTRIB_ID',
41*4882a593Smuzhiyun                'Release': 'DISTRIB_RELEASE'}
42*4882a593Smuzhiyun    lsb_keys = lsb_map.keys()
43*4882a593Smuzhiyun
44*4882a593Smuzhiyun    data = {}
45*4882a593Smuzhiyun    for line in output.splitlines():
46*4882a593Smuzhiyun        if line.startswith("-e"):
47*4882a593Smuzhiyun            line = line[3:]
48*4882a593Smuzhiyun        try:
49*4882a593Smuzhiyun            key, value = line.split(":\t", 1)
50*4882a593Smuzhiyun        except ValueError:
51*4882a593Smuzhiyun            continue
52*4882a593Smuzhiyun        if key in lsb_keys:
53*4882a593Smuzhiyun            data[lsb_map[key]] = value
54*4882a593Smuzhiyun
55*4882a593Smuzhiyun    if len(data.keys()) != 2:
56*4882a593Smuzhiyun        return None
57*4882a593Smuzhiyun
58*4882a593Smuzhiyun    return data
59*4882a593Smuzhiyun
60*4882a593Smuzhiyundef release_dict_file():
61*4882a593Smuzhiyun    """ Try to gather release information manually when other methods fail """
62*4882a593Smuzhiyun    data = {}
63*4882a593Smuzhiyun    try:
64*4882a593Smuzhiyun        if os.path.exists('/etc/lsb-release'):
65*4882a593Smuzhiyun            data = {}
66*4882a593Smuzhiyun            with open('/etc/lsb-release') as f:
67*4882a593Smuzhiyun                for line in f:
68*4882a593Smuzhiyun                    key, value = line.split("=", 1)
69*4882a593Smuzhiyun                    data[key] = value.strip()
70*4882a593Smuzhiyun        elif os.path.exists('/etc/redhat-release'):
71*4882a593Smuzhiyun            data = {}
72*4882a593Smuzhiyun            with open('/etc/redhat-release') as f:
73*4882a593Smuzhiyun                distro = f.readline().strip()
74*4882a593Smuzhiyun            import re
75*4882a593Smuzhiyun            match = re.match(r'(.*) release (.*) \((.*)\)', distro)
76*4882a593Smuzhiyun            if match:
77*4882a593Smuzhiyun                data['DISTRIB_ID'] = match.group(1)
78*4882a593Smuzhiyun                data['DISTRIB_RELEASE'] = match.group(2)
79*4882a593Smuzhiyun        elif os.path.exists('/etc/SuSE-release'):
80*4882a593Smuzhiyun            data = {}
81*4882a593Smuzhiyun            data['DISTRIB_ID'] = 'SUSE LINUX'
82*4882a593Smuzhiyun            with open('/etc/SuSE-release') as f:
83*4882a593Smuzhiyun                for line in f:
84*4882a593Smuzhiyun                    if line.startswith('VERSION = '):
85*4882a593Smuzhiyun                        data['DISTRIB_RELEASE'] = line[10:].rstrip()
86*4882a593Smuzhiyun                        break
87*4882a593Smuzhiyun
88*4882a593Smuzhiyun    except IOError:
89*4882a593Smuzhiyun        return {}
90*4882a593Smuzhiyun    return data
91*4882a593Smuzhiyun
92*4882a593Smuzhiyundef distro_identifier(adjust_hook=None):
93*4882a593Smuzhiyun    """Return a distro identifier string based upon lsb_release -ri,
94*4882a593Smuzhiyun       with optional adjustment via a hook"""
95*4882a593Smuzhiyun
96*4882a593Smuzhiyun    import re
97*4882a593Smuzhiyun
98*4882a593Smuzhiyun    # Try /etc/os-release first, then the output of `lsb_release -ir` and
99*4882a593Smuzhiyun    # finally fall back on parsing various release files in order to determine
100*4882a593Smuzhiyun    # host distro name and version.
101*4882a593Smuzhiyun    distro_data = release_dict_osr()
102*4882a593Smuzhiyun    if not distro_data:
103*4882a593Smuzhiyun        distro_data = release_dict_lsb()
104*4882a593Smuzhiyun    if not distro_data:
105*4882a593Smuzhiyun        distro_data = release_dict_file()
106*4882a593Smuzhiyun
107*4882a593Smuzhiyun    distro_id = distro_data.get('DISTRIB_ID', '')
108*4882a593Smuzhiyun    release = distro_data.get('DISTRIB_RELEASE', '')
109*4882a593Smuzhiyun
110*4882a593Smuzhiyun    if adjust_hook:
111*4882a593Smuzhiyun        distro_id, release = adjust_hook(distro_id, release)
112*4882a593Smuzhiyun    if not distro_id:
113*4882a593Smuzhiyun        return "unknown"
114*4882a593Smuzhiyun    # Filter out any non-alphanumerics and convert to lowercase
115*4882a593Smuzhiyun    distro_id = re.sub(r'\W', '', distro_id).lower()
116*4882a593Smuzhiyun
117*4882a593Smuzhiyun    if release:
118*4882a593Smuzhiyun        id_str = '{0}-{1}'.format(distro_id, release)
119*4882a593Smuzhiyun    else:
120*4882a593Smuzhiyun        id_str = distro_id
121*4882a593Smuzhiyun    return id_str.replace(' ','-').replace('/','-')
122