from tempfile import TemporaryDirectory
from typing import Any, Callable, Dict, List, Tuple, Union
import sh
+from collections import OrderedDict
"""
MIT License
self.files = []
self.system_services: List[Path] = []
self.user_services: List[Path] = []
+ self.exec_name = ""
class CustomXMLSEC(object):
TEMPLATE_HEAD="""
"""
MANIFEST_TEMPLATE="""<?xml version="1.0" encoding="utf-8" standalone="no"?>
-<manifest xmlns="http://tizen.org/ns/packages" api-version="1.0.0" package="org.tizen.isu.{}" res-type="tizen.isu.resource.{}" res-version="{}" version="1.0.0">
+<manifest xmlns="http://tizen.org/ns/packages" api-version="{}" package="org.tizen.isu.{}" res-type="tizen.isu.resource.{}" res-version="{}" version="{}">
+ <profile name="{}"/>
+ <service-application appid="org.tizen.isu.{}" auto-restart="true" exec="{}" multiple="false" on-boot="true" taskmanage="false" type="capp"/>
<label>{}</label>
<isu>
<name>{}</name>
file_content = self.FILE_TEMPLATE.format(file_path, sha256)
file.write(file_content)
- def _make_tizen_manifest(self):
+ def _make_tizen_manifest(self, profile_name, supplementary_config_data):
config_file = CustomConfigParser()
config_file.read_config("isu.cfg")
name = config_file.sections['isu']['name']
version = config_file.sections['isu']['version']
+ api_version = supplementary_config_data['tz_build_version']
+ exec_name = supplementary_config_data['exec_name']
- content = self.MANIFEST_TEMPLATE.format(name, name, version, name, name, version)
+ content = self.MANIFEST_TEMPLATE.format(api_version, name, name, version, api_version, profile_name, name, exec_name, name, name, version)
with open("tizen-manifest.xml", "w") as file:
file.write(content)
self.sign_signature(sig_file_name, key, password)
- def run(self, out_dir, name):
- self._make_tizen_manifest()
+ def run(self, out_dir, profile_name, name, supplementary_config_data):
+ self._make_tizen_manifest(profile_name, supplementary_config_data)
self._gen_signature(True, self.key_author, self.password_author)
self._gen_signature(False, self.key_distributor, self.password_distributor)
logger.debug("Maker RPK archive")
section_name = line[1:-1]
if section_name in self.sections:
raise Exception("Section {} already exist".format(section_name))
- self.sections[section_name] = {}
+ self.sections[section_name] = OrderedDict()
current_section = section_name
else:
splitted = line.split("=")
class ISUPkgsMakerCtx:
- def __init__(self, images_dir: Path, use_images: bool, tmp_dir: Path, out_dir: Path, key: Union[Path, None], file_mapper: FileMapper):
+ def __init__(self, images_dir: Path, use_images: bool, tmp_dir: Path, profile_name: str, out_dir: Path, key: Union[Path, None], file_mapper: FileMapper):
self.images_dir = images_dir
self.use_images = use_images
self.tmp_dir = tmp_dir
+ self.profile_name = profile_name
self.out_dir = out_dir
self.key = key
self.file_mapper = file_mapper
ISU_CFG_D_DIR = "isu.cfg.d"
def __init__(self, isudir_path: Path, cfg: Config, mounts: Dict[str, Union[Mounter, NoMounter]], isu_pkgs_ctx: ISUPkgsMakerCtx):
+ self._supplementary_config_data = None
self._ctx = ISUSinglePkgMakerCtx(isudir_path, cfg, mounts, isu_pkgs_ctx)
if os.path.exists(self._ctx.work_dir):
def _rpk_pkg(self, rpk_info):
with CustomXMLSEC(rpk_info, self._ctx.pkg_dir) as rpk_maker:
- return rpk_maker.run(self._ctx.out_dir, self._ctx.cfg.name)
+ return rpk_maker.run(self._ctx.out_dir, self._ctx.profile_name, self._ctx.cfg.name, self._supplementary_config_data)
def _make_isu_cfg(self):
tb_path = self._ctx.file_mapper.find_path(Path('/etc/tizen-build.conf'), self._ctx.mounts)
for file in self._ctx.cfg.files:
config_file['files'][file] = None
+ supplementary_config_data = dict()
+ supplementary_config_data['tz_build_version'] = tizen_build.get_value('TZ_BUILD_FULLVER')
+ # we assume that the main binary file is the first file specified in the [files] section
+ # of the isu.cfg config file
+ section_files = self._ctx.cfg.files
+ exec_name = section_files[0] if len(section_files) > 0 else ""
+ supplementary_config_data['exec_name'] = os.path.basename(exec_name)
+ self._supplementary_config_data = supplementary_config_data
+
with open(self._ctx.pkg_dir / self.ISU_CFG_FILE, 'w') as out_file:
config_file.write(out_file)
class ISUPkgsMaker:
- def __init__(self, images_dir: Path, use_images: bool, tmp_dir: Path, out_dir: Path, key: Union[Path, None], file_mapper: FileMapper):
- self._ctx = ISUPkgsMakerCtx(images_dir, use_images, tmp_dir, out_dir, key, file_mapper)
+ def __init__(self, images_dir: Path, use_images: bool, tmp_dir: Path, profile_name: str, out_dir: Path, key: Union[Path, None], file_mapper: FileMapper):
+ self._ctx = ISUPkgsMakerCtx(images_dir, use_images, tmp_dir, profile_name, out_dir, key, file_mapper)
def __enter__(self):
return self
return []
def load_config(self, cfg_file: Path):
- config_file = configparser.ConfigParser(allow_no_value=True)
- config_file.read(cfg_file)
+ config_file = CustomConfigParser()
+ config_file.read_config(cfg_file)
cfg = Config()
for section in ["isu", "files"]:
- if section not in config_file:
+ if section not in config_file.sections:
raise InvalidConfigException(f"No \"{section}\" section in the config file.")
for key in ["name", "version"]:
- if key not in config_file["isu"]:
+ if key not in config_file.sections["isu"]:
raise InvalidConfigException(f"No \"{key}\" key in the \"isu\" section.")
- cfg.name = config_file['isu']['name']
+ cfg.name = config_file.sections['isu']['name']
- system_service = config_file['isu'].get('system_service')
+ system_service = config_file.sections['isu'].get('system_service')
cfg.system_services = list(map(lambda x: Path(x), self._split(system_service)))
- user_service = config_file['isu'].get('user_service')
+ user_service = config_file.sections['isu'].get('user_service')
cfg.user_services = list(map(lambda x: Path(x), self._split(user_service)))
- cfg.files = [f_name for f_name in config_file['files']]
+ cfg.files = [f_name for f_name in config_file.sections['files']]
logger.info(f"Config {cfg_file} ({cfg.name}) loaded.")
help="File with image<->path mapping")
parser.add_argument('--key', '-k', type=str, required=False,
help="Signing key")
+ parser.add_argument('--profile-name', type=str, required=False,
+ default=os.getenv('PROFILE_NAME'),
+ help="Profile name")
parser.add_argument('--exit_on_any_error', '-e', action='store_true',
required=False, help="Terminate after any error")
with ISUPkgsMaker(Path(os.path.realpath(args.src)),
args.use_images,
Path(tmp_dir),
+ args.profile_name,
Path(os.path.realpath(args.out)),
Path(args.key) if args.key else None,
map) as isu_pkgs_maker:
import tempfile
import base64
import urllib
+from collections import OrderedDict
"""
MIT License
self.files = []
self.system_services = []
self.user_services = []
+ self.exec_name = ""
class CustomExitStack:
def __init__(self):
"""
MANIFEST_TEMPLATE="""<?xml version="1.0" encoding="utf-8" standalone="no"?>
-<manifest xmlns="http://tizen.org/ns/packages" api-version="1.0.0" package="org.tizen.isu.{}" res-type="tizen.isu.resource.{}" res-version="{}" version="1.0.0">
+<manifest xmlns="http://tizen.org/ns/packages" api-version="{}" package="org.tizen.isu.{}" res-type="tizen.isu.resource.{}" res-version="{}" version="{}">
+ <profile name="{}"/>
+ <service-application appid="org.tizen.isu.{}" auto-restart="true" exec="{}" multiple="false" on-boot="true" taskmanage="false" type="capp"/>
<label>{}</label>
<isu>
<name>{}</name>
file_content = self.FILE_TEMPLATE.format(file_path, sha256)
file.write(file_content)
- def _make_tizen_manifest(self):
+ def _make_tizen_manifest(self, profile_name, supplementary_config_data):
config_file = CustomConfigParser()
config_file.read_config("isu.cfg")
name = config_file.sections['isu']['name']
version = config_file.sections['isu']['version']
+ api_version = supplementary_config_data['tz_build_version']
+ exec_name = supplementary_config_data['exec_name']
- content = self.MANIFEST_TEMPLATE.format(name, name, version, name, name, version)
+ content = self.MANIFEST_TEMPLATE.format(api_version, name, name, version, api_version, profile_name, name, exec_name, name, name, version)
with open("tizen-manifest.xml", "w") as file:
file.write(content)
self.sign_signature(sig_file_name, key, password)
- def run(self, out_dir, name):
- self._make_tizen_manifest()
+ def run(self, out_dir, profile_name, name, supplementary_config_data):
+ self._make_tizen_manifest(profile_name, supplementary_config_data)
self._gen_signature(True, self.key_author, self.password_author)
self._gen_signature(False, self.key_distributor, self.password_distributor)
logger.debug("Maker RPK archive")
section_name = line[1:-1]
if section_name in self.sections:
raise Exception("Section {} already exist".format(section_name))
- self.sections[section_name] = {}
+ self.sections[section_name] = OrderedDict()
current_section = section_name
else:
splitted = line.split("=")
class ISUPkgsMakerCtx(object):
- def __init__(self, images_dir, use_images, tmp_dir, out_dir, key, file_mapper):
+ def __init__(self, images_dir, use_images, tmp_dir, profile_name, out_dir, key, file_mapper):
self.images_dir = images_dir
self.use_images = use_images
self.tmp_dir = tmp_dir
+ self.profile_name = profile_name
self.out_dir = out_dir
self.key = key
self.file_mapper = file_mapper
ISU_CFG_D_DIR = "isu.cfg.d"
def __init__(self, isudir_path, cfg, mounts, isu_pkgs_ctx):
+ self._supplementary_config_data = None
self._ctx = ISUSinglePkgMakerCtx(isudir_path, cfg, mounts, isu_pkgs_ctx)
if os.path.exists(str(self._ctx.work_dir)):
def _rpk_pkg(self, rpk_info):
with CustomXMLSEC(rpk_info, self._ctx.pkg_dir) as rpk_maker:
- return rpk_maker.run(self._ctx.out_dir, self._ctx.cfg.name)
+ return rpk_maker.run(self._ctx.out_dir, self._ctx.profile_name, self._ctx.cfg.name, self._supplementary_config_data)
def _make_isu_cfg(self):
for file in self._ctx.cfg.files:
config_file.sections['files'][file] = None
+ supplementary_config_data = dict()
+ supplementary_config_data['tz_build_version'] = tizen_build.get_value('TZ_BUILD_FULLVER')
+ # we assume that the main binary file is the first file specified in the [files] section
+ # of the isu.cfg config file
+ section_files = self._ctx.cfg.files
+ exec_name = section_files[0] if len(section_files) > 0 else ""
+ supplementary_config_data['exec_name'] = os.path.basename(exec_name)
+ self._supplementary_config_data = supplementary_config_data
+
out_file = os.path.join(self._ctx.pkg_dir, self.ISU_CFG_FILE)
config_file.write_config(out_file)
class ISUPkgsMaker:
- def __init__(self, images_dir, use_images, tmp_dir, out_dir, key, file_mapper):
- self._ctx = ISUPkgsMakerCtx(images_dir, use_images, tmp_dir, out_dir, key, file_mapper)
+ def __init__(self, images_dir, use_images, tmp_dir, profile_name, out_dir, key, file_mapper):
+ self._ctx = ISUPkgsMakerCtx(images_dir, use_images, tmp_dir, profile_name, out_dir, key, file_mapper)
def __enter__(self):
return self
cfg.system_services = list(map(lambda x: x, self._split(system_service)))
user_service = config_file.sections['isu'].get('user_service')
cfg.user_services = list(map(lambda x: x, self._split(user_service)))
- cfg.files = [f_name for f_name in config_file.sections['files'].keys()]
+ cfg.files = [f_name for f_name in config_file.sections['files']]
logger.info("Config {} ({}) loaded.".format(cfg_file, cfg.name))
help="File with image<->path mapping")
parser.add_argument('--key', '-k', type=str, required=False,
help="Signing key")
+ parser.add_argument('--profile-name', type=str, required=False,
+ default=os.getenv('PROFILE_NAME'),
+ help="Profile name")
parser.add_argument('--exit_on_any_error', '-e', action='store_true',
required=False, help="Terminate after any error")
with ISUPkgsMaker(os.path.realpath(args.src),
args.use_images,
tmp_dir,
+ args.profile_name,
os.path.realpath(args.out),
args.key,
map) as isu_pkgs_maker: