#!/usr/bin/python3
#
# /**************************************************************************
# * Copyright 2017-2018 IoT.bzh
# *
# * author: Romain Forlot <romain.forlot@iot.bzh>
# *
# * Licensed under the Apache License, Version 2.0 (the "License");
# * you may not use this file except in compliance with the License.
# * You may obtain a copy of the License at
# *
# * http://www.apache.org/licenses/LICENSE-2.0
# *
# * Unless required by applicable law or agreed to in writing, software
# * distributed under the License is distributed on an "AS IS" BASIS,
# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# * See the License for the specific language governing permissions and
# * limitations under the License.
# **************************************************************************/
import os
import sys
import json
import logging
import inspect
import fnmatch
import argparse
import subprocess
from subprocess import DEVNULL
import re
PARSER = argparse.ArgumentParser(
description='Lists available and installed SDKs')
PARSER.add_argument('-debug', dest='debug', action='store_true',
help='Output debug log messages')
ARGS = PARSER.parse_args()
if ARGS.debug:
logging.basicConfig(level=logging.DEBUG,
format='%(asctime)s:%(levelname)s: %(message)s')
else:
logging.basicConfig(level=logging.INFO,
format='%(asctime)s:%(levelname)s: %(message)s')
SCRIPT_PATH = os.path.dirname(os.path.abspath(
inspect.getfile(inspect.currentframe())))
ENV = subprocess.check_output(
[os.path.join(SCRIPT_PATH, './_env-init.sh'), '-print']).splitlines()
SDK_ROOT_DIR = None
for elt in ENV:
# only match what defines a variable
z = re.match(r"^(\w+)=([^']*)$", elt.decode())
if z:
k = z.group(1)
v = z.group(2)
if k == 'SDK_ROOT_DIR':
SDK_ROOT_DIR = v.rstrip('/')
elif k == 'SDK_ENV_SETUP_FILENAME':
SDK_ENV_SETUP_FILENAME = v
if SDK_ROOT_DIR is None:
logging.error('No SDK_ROOT_DIR environment variable found.')
exit(1)
elif SDK_ENV_SETUP_FILENAME is None:
SDK_ENV_SETUP_FILENAME = 'environment-setup*'
# Get list of available SDKs
SDK_DB_FILEPATH = os.path.join(SDK_ROOT_DIR, 'sdks_latest.json')
if not os.path.exists(SDK_DB_FILEPATH):
DB_UPDATE_FILEPATH = os.path.join(SCRIPT_PATH, 'db-update')
os.system(DB_UPDATE_FILEPATH + ' ' + SDK_DB_FILEPATH)
SDK_DB_JSON = json.load(open(SDK_DB_FILEPATH, 'r'))
for one_sdk in SDK_DB_JSON:
one_sdk['status'] = 'Not Installed'
one_sdk['uuid'] = ''
INSTALLED_SDK = []
for root, dirs, files in os.walk(SDK_ROOT_DIR):
depth = root[len(SDK_ROOT_DIR) + len(os.path.sep):].count(os.path.sep)
# Limit the walking depth of processed directories
if depth >= 4:
dirs[:] = []
# Only process SDK dir matching profile/version/arch or
# profile/version/arch/tag
elif depth != 2 and depth != 3:
continue
# Only consider SDK as valid if environment-setup and version files and
# sysroots directory can be found
EF, VF, SR = '', '', ''
for one_dir in dirs:
if fnmatch.fnmatch(one_dir, 'sysroots'):
SR = os.path.join(root, one_dir)
for one_file in files:
if fnmatch.fnmatch(one_file, SDK_ENV_SETUP_FILENAME):
EF = os.path.join(root, one_file)
elif fnmatch.fnmatch(one_file, 'version-*'):
VF = os.path.join(root, one_file)
if EF != '' and VF != '' and SR != '':
logging.debug('Adding installed SDK ' + root)
INSTALLED_SDK.append(
{'ENV_FILE': EF, 'VERSION_FILE': VF, 'SYSROOTS': SR})
elif (EF == '' and VF != '') or (EF != '' and VF == ''):
logging.debug(
'WARNING SDK ignored : root=%s, EnvFile=%s, VersionFile=%s, sysroots=%s', root, EF, VF, SR)
for one_sdk in INSTALLED_SDK:
logging.debug('Processing %s', one_sdk['ENV_FILE'])
envFile = one_sdk['ENV_FILE'].split(SDK_ROOT_DIR+'/')[1]
PROFILE = envFile.split('/')[0]
VERSION = envFile.split('/')[1]
ARCH = envFile.split('/')[2]
# and specific case for qemu where arch is not the same (qemux86-64 vs corei7-64)
if ARCH == 'corei7-64':
# Use /etc/rpm/platform to distinguish qemux86-64 from corei7-64 architecture
grepQemu = subprocess.call(['grep', '-q', 'qemux86', os.path.join(
one_sdk['SYSROOTS'], 'corei7-64-agl-linux', 'etc', 'rpm', 'platform')],
stdout=DEVNULL, stderr=subprocess.STDOUT)
if grepQemu == 0:
ARCH = 'qemux86-64'
DIR = os.path.dirname(one_sdk['ENV_FILE'])
if PROFILE == '' or VERSION == '' or ARCH == '' or DIR == '':
logging.debug('Path not compliant, skipping')
continue
UUID = os.path.basename(os.path.normpath(DIR))
SDK_DATE = ''
for line in open(one_sdk['VERSION_FILE']).readlines():
if line.startswith('Timestamp'):
D = line.split(':')[1]
if D:
D = D.strip()
SDK_DATE = '{}-{}-{} {}:{}'.format(
D[0:4], D[4:6], D[6:8], D[8:10], D[10:12])
logging.debug('Found date: %s', SDK_DATE)
# Check if installed SDKs match the ones listed in json file
found = False
for sdk in SDK_DB_JSON:
# Matching based on profile + version + arch fields
if sdk['profile'] == PROFILE and sdk['version'] == VERSION and sdk['arch'] == ARCH:
if sdk['status'] == 'Installed':
continue
# Additional verification based on url used to generate UUID (see also same logic in add script)
if sdk['url'] != '':
try:
ps = subprocess.Popen(
('echo', sdk['url']), stdout=subprocess.PIPE)
uuid_md5 = subprocess.check_output(
('md5sum'), stdin=ps.stdout)
ps.wait()
if str(uuid_md5).split(' ')[0][2:] != UUID:
continue
except:
e = sys.exc_info()[0]
logging.error('Error while checking UUID: ' % e)
found = True
sdk['status'] = 'Installed'
sdk['date'] = SDK_DATE
sdk['setupFile'] = one_sdk['ENV_FILE']
sdk['path'] = DIR
sdk['uuid'] = UUID
break
if not found:
logging.debug('Not found in database, add: ' +
PROFILE + '-' + ARCH + '-' + VERSION)
NEW_SDK = {
'name': PROFILE + '-' + ARCH + '-' + VERSION,
'uuid': UUID,
'description': 'AGL SDK ' + ARCH + ' (version ' + VERSION + ')',
'profile': PROFILE,
'version': VERSION,
'arch': ARCH,
'path': DIR,
'url': '',
'image_url': '',
'status': 'Installed',
'date': SDK_DATE,
'size': '',
'md5sum': '',
'setupFile': one_sdk['ENV_FILE']
}
SDK_DB_JSON.append(NEW_SDK)
print(json.dumps(SDK_DB_JSON))