Fix qemu sdk detection
[src/xds/xds-server.git] / scripts / sdks / agl / db-dump
1 #!/usr/bin/python3
2 #
3 # /**************************************************************************
4 # * Copyright 2017-2018 IoT.bzh
5 # *
6 # * author: Romain Forlot <romain.forlot@iot.bzh>
7 # *
8 # * Licensed under the Apache License, Version 2.0 (the "License");
9 # * you may not use this file except in compliance with the License.
10 # * You may obtain a copy of the License at
11 # *
12 # *     http://www.apache.org/licenses/LICENSE-2.0
13 # *
14 # * Unless required by applicable law or agreed to in writing, software
15 # * distributed under the License is distributed on an "AS IS" BASIS,
16 # * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 # * See the License for the specific language governing permissions and
18 # * limitations under the License.
19 # **************************************************************************/
20
21 import os
22 import sys
23 import json
24 import logging
25 import inspect
26 import fnmatch
27 import argparse
28 import subprocess
29 import re
30
31 PARSER = argparse.ArgumentParser(
32     description='Lists available and installed SDKs')
33 PARSER.add_argument('-debug', dest='debug', action='store_true',
34                     help='Output debug log messages')
35
36 ARGS = PARSER.parse_args()
37
38 if ARGS.debug:
39     logging.basicConfig(level=logging.DEBUG,
40                         format='%(asctime)s:%(levelname)s: %(message)s')
41 else:
42     logging.basicConfig(level=logging.INFO,
43                         format='%(asctime)s:%(levelname)s: %(message)s')
44
45 SCRIPT_PATH = os.path.dirname(os.path.abspath(
46     inspect.getfile(inspect.currentframe())))
47
48 ENV = subprocess.check_output(
49     [os.path.join(SCRIPT_PATH, './_env-init.sh'), '-print']).splitlines()
50
51 SDK_ROOT_DIR = None
52 for elt in ENV:
53     # only match what defines a variable
54     z = re.match(r"^(\w+)=([^']*)$", elt.decode())
55     if z:
56         k = z.group(1)
57         v = z.group(2)
58         if k == 'SDK_ROOT_DIR':
59             SDK_ROOT_DIR = v.rstrip('/')
60         elif k == 'SDK_ENV_SETUP_FILENAME':
61             SDK_ENV_SETUP_FILENAME = v
62
63 if SDK_ROOT_DIR is None:
64     logging.error('No SDK_ROOT_DIR environment variable found.')
65     exit(1)
66 elif SDK_ENV_SETUP_FILENAME is None:
67     SDK_ENV_SETUP_FILENAME = 'environment-setup*'
68
69 # Get list of available SDKs
70 SDK_DB_FILEPATH = os.path.join(SDK_ROOT_DIR, 'sdks_latest.json')
71
72 if not os.path.exists(SDK_DB_FILEPATH):
73     DB_UPDATE_FILEPATH = os.path.join(SCRIPT_PATH, 'db-update')
74     os.system(DB_UPDATE_FILEPATH + ' ' + SDK_DB_FILEPATH)
75
76 SDK_DB_JSON = json.load(open(SDK_DB_FILEPATH, 'r'))
77
78 for one_sdk in SDK_DB_JSON:
79     one_sdk['status'] = 'Not Installed'
80     one_sdk['uuid'] = ''
81
82 INSTALLED_SDK = []
83 for root, dirs, files in os.walk(SDK_ROOT_DIR):
84     depth = root[len(SDK_ROOT_DIR) + len(os.path.sep):].count(os.path.sep)
85     # Limit the walking depth of processed directories
86     if depth >= 4:
87         dirs[:] = []
88     # Only process SDK dir matching profile/version/arch or
89     # profile/version/arch/tag
90     elif depth != 2 and depth != 3:
91         continue
92
93     # Only consider SDK as valid if environment-setup and version files and
94     # sysroots directory can be found
95     EF, VF, SR = '', '', ''
96     for one_dir in dirs:
97         if fnmatch.fnmatch(one_dir, 'sysroots'):
98             SR = os.path.join(root, one_dir)
99
100     for one_file in files:
101         if fnmatch.fnmatch(one_file, SDK_ENV_SETUP_FILENAME):
102             EF = os.path.join(root, one_file)
103         elif fnmatch.fnmatch(one_file, 'version-*'):
104             VF = os.path.join(root, one_file)
105     if EF != '' and VF != '' and SR != '':
106         logging.debug('Adding installed SDK ' + root)
107         INSTALLED_SDK.append(
108             {'ENV_FILE': EF, 'VERSION_FILE': VF, 'SYSROOTS': SR})
109     elif (EF == '' and VF != '') or (EF != '' and VF == ''):
110         logging.debug(
111             'WARNING SDK ignored : root=%s, EnvFile=%s, VersionFile=%s, sysroots=%s', root, EF, VF, SR)
112
113 for one_sdk in INSTALLED_SDK:
114     logging.debug('Processing %s', one_sdk['ENV_FILE'])
115     envFile = one_sdk['ENV_FILE'].split(SDK_ROOT_DIR+'/')[1]
116     PROFILE = envFile.split('/')[0]
117     VERSION = envFile.split('/')[1]
118     ARCH = envFile.split('/')[2]
119     # and specific case for qemu where arch is not the same (qemux86-64 vs corei7-64)
120     if ARCH == 'corei7-64':
121         # Use /etc/rpm/platform to distinguish qemux86-64 from corei7-64 architecture
122         grepQemu = subprocess.call(['grep', '-q', 'qemux86', os.path.join(
123             one_sdk['SYSROOTS'], 'corei7-64-agl-linux', 'etc', 'rpm', 'platform')])
124         if grepQemu == 0:
125             ARCH = 'qemux86-64'
126
127     DIR = os.path.dirname(one_sdk['ENV_FILE'])
128     if PROFILE == '' or VERSION == '' or ARCH == '' or DIR == '':
129         logging.debug('Path not compliant, skipping')
130         continue
131
132     UUID = os.path.basename(os.path.normpath(DIR))
133
134     SDK_DATE = ''
135     for line in open(one_sdk['VERSION_FILE']).readlines():
136         if line.startswith('Timestamp'):
137             D = line.split(':')[1]
138             if D:
139                 D = D.strip()
140                 SDK_DATE = '{}-{}-{} {}:{}'.format(
141                     D[0:4], D[4:6], D[6:8], D[8:10], D[10:12])
142                 logging.debug('Found date: %s', SDK_DATE)
143
144     # Check if installed SDKs match the ones listed in json file
145     found = False
146     for sdk in SDK_DB_JSON:
147         # Matching based on profile + version + arch fields
148         if sdk['profile'] == PROFILE and sdk['version'] == VERSION and sdk['arch'] == ARCH:
149             if sdk['status'] == 'Installed':
150                 continue
151             # Additional verification based on url used to generate UUID (see also same logic in add script)
152             if sdk['url'] != '':
153                 try:
154                     ps = subprocess.Popen(
155                         ('echo', sdk['url']), stdout=subprocess.PIPE)
156                     uuid_md5 = subprocess.check_output(
157                         ('md5sum'), stdin=ps.stdout)
158                     ps.wait()
159                     if str(uuid_md5).split(' ')[0][2:] != UUID:
160                         continue
161                 except:
162                     e = sys.exc_info()[0]
163                     logging.error('Error while checking UUID: ' % e)
164
165             found = True
166             sdk['status'] = 'Installed'
167             sdk['date'] = SDK_DATE
168             sdk['setupFile'] = one_sdk['ENV_FILE']
169             sdk['path'] = DIR
170             sdk['uuid'] = UUID
171             break
172
173     if not found:
174         logging.debug('Not found in database, add: ' +
175                       PROFILE + '-' + ARCH + '-' + VERSION)
176         NEW_SDK = {
177             'name': PROFILE + '-' + ARCH + '-' + VERSION,
178             'uuid': UUID,
179             'description': 'AGL SDK ' + ARCH + ' (version ' + VERSION + ')',
180             'profile': PROFILE,
181             'version': VERSION,
182             'arch': ARCH,
183             'path': DIR,
184             'url': '',
185             'status': 'Installed',
186             'date': SDK_DATE,
187             'size': '',
188             'md5sum': '',
189             'setupFile': one_sdk['ENV_FILE']
190         }
191         SDK_DB_JSON.append(NEW_SDK)
192
193 print(json.dumps(SDK_DB_JSON))