def test_set_target_arch(self): sys.argv = [ sys.argv[0], '--target-arch', 'artificial', 'system', 'build', '--description', 'description', '--target-dir', 'directory' ] cli = Cli() cli.get_global_args() assert Defaults.get_platform_name() == 'artificial'
def test_warning_on_use_of_legacy_disk_type(self): sys.argv = [ sys.argv[0], '--type', 'vmx', 'system', 'build', '--description', 'description', '--target-dir', 'directory' ] cli = Cli() with self._caplog.at_level(logging.WARNING): cli.get_global_args() assert 'vmx type is now a subset of oem, --type set to oem' in \ self._caplog.text
def test_get_global_args(self): self.cli.all_args['--config'] = 'config-file' sys.argv = [ sys.argv[0], '--config', 'config-file', 'system', 'build', '--description', 'description', '--target-dir', 'directory' ] cli = Cli() assert cli.get_global_args() == self.expected_global_args
def __init__(self, reread=False): global RUNTIME_CONFIG if not RUNTIME_CONFIG or reread: cli = Cli() config_file = None custom_config_file = cli.get_global_args().get('--config') if custom_config_file: config_file = custom_config_file if not os.path.isfile(config_file): raise KiwiRuntimeConfigFileError( f'Custom config file {config_file!r} not found') elif self._home_path(): config_file = os.sep.join( [self._home_path(), '.config', 'kiwi', 'config.yml']) if not config_file or not os.path.exists(config_file): config_file = '/etc/kiwi.yml' if os.path.exists(config_file): log.info(f'Reading runtime config file: {config_file!r}') with open(config_file, 'r') as config: RUNTIME_CONFIG = yaml.safe_load(config)
class TestCli: @fixture(autouse=True) def inject_fixtures(self, caplog): self._caplog = caplog def setup(self): self.help_global_args = { 'help': False, '--compat': False, 'compat': False, '--type': None, 'image': False, 'system': True, '-h': False, '--logfile': None, '--color-output': False, '<legacy_args>': [], '--version': False, '--debug': False, 'result': False, '--profile': [], '--shared-cache-dir': '/var/cache/kiwi', '--help': False, '--config': None } self.command_args = { '--add-repo': [], '--allow-existing-root': False, '--description': 'description', '--help': False, '--ignore-repos': False, '--ignore-repos-used-for-build': False, '--clear-cache': False, '--root': 'directory', '--set-repo': None, '--add-package': [], '--add-bootstrap-package': [], '--delete-package': [], '--set-container-derived-from': None, '--set-container-tag': None, '--add-container-label': [], '--signing-key': [], '-h': False, 'help': False, 'prepare': True, 'system': True } self.cli = Cli() self.loaded_command = self.cli.load_command() def teardown(self): sys.argv = argv_kiwi_tests @patch('kiwi.cli.Help.show') def test_show_and_exit_on_help_request(self, help_show): self.cli.all_args['help'] = True with raises(SystemExit): self.cli.show_and_exit_on_help_request() help_show.assert_called_once_with('kiwi') def test_get_servicename_system(self): cli = Cli() assert cli.get_servicename() == 'system' def test_get_servicename_compat_as_option(self): sys.argv = [ sys.argv[0], '--compat', '--', '--build', 'description', '--type', 'oem', '-d', 'destination' ] cli = Cli() assert cli.get_servicename() == 'compat' def test_get_servicename_compat_as_service(self): sys.argv = [ sys.argv[0], 'compat', '--build', 'description', '--type', 'oem', '-d', 'destination' ] cli = Cli() assert cli.get_servicename() == 'compat' def test_warning_on_use_of_legacy_disk_type(self): sys.argv = [ sys.argv[0], '--type', 'vmx', 'system', 'build', '--description', 'description', '--target-dir', 'directory' ] cli = Cli() with self._caplog.at_level(logging.WARNING): cli.get_global_args() assert 'vmx type is now a subset of oem, --type set to oem' in \ self._caplog.text def test_get_servicename_image(self): sys.argv = [ sys.argv[0], 'image', 'resize', '--target-dir', 'directory', '--size', '20g' ] cli = Cli() assert cli.get_servicename() == 'image' def test_get_servicename_result(self): sys.argv = [sys.argv[0], 'result', 'list', '--target-dir', 'directory'] cli = Cli() assert cli.get_servicename() == 'result' def test_get_command(self): assert self.cli.get_command() == 'prepare' def test_get_command_args(self): assert self.cli.get_command_args() == self.command_args def test_get_global_args(self): assert self.cli.get_global_args() == self.help_global_args def test_load_command(self): assert self.cli.load_command() == self.loaded_command @patch('kiwi.cli.Cli.invoke_kiwicompat') def test_load_command_compat_mode(self, mock_compat): sys.argv = [ sys.argv[0], '--compat', '--', '--build', 'description', '--type', 'oem', '-d', 'destination' ] cli = Cli() cli.load_command() mock_compat.assert_called_once_with( ['--build', 'description', '--type', 'oem', '-d', 'destination']) @patch('kiwi.cli.Path.which') @patch('os.execvp') def test_invoke_kiwicompat_exec_failed(self, mock_exec, mock_which): mock_which.return_value = 'kiwicompat' mock_exec.side_effect = Exception with raises(KiwiCompatError): self.cli.invoke_kiwicompat([]) def test_load_command_unknown(self): self.cli.loaded = False self.cli.all_args['<command>'] = 'foo' with raises(KiwiCommandNotLoaded): self.cli.load_command() def test_load_command_undefined(self): self.cli.loaded = False self.cli.all_args['<command>'] = None with raises(KiwiLoadCommandUndefined): self.cli.load_command() def test_get_command_args_not_loaded(self): sys.argv = [sys.argv[0], 'system', 'command-not-implemented'] cli = Cli() with raises(KiwiCommandNotLoaded): cli.get_command_args() def test_get_servicename_unknown(self): self.cli.all_args['system'] = False self.cli.all_args['foo'] = False with raises(KiwiUnknownServiceName): self.cli.get_servicename()
class TestCli(object): def setup(self): self.help_global_args = { 'help': False, '--compat': False, 'compat': False, '--type': None, 'image': False, 'system': True, '-h': False, '--logfile': None, '--color-output': False, '<legacy_args>': [], '--version': False, '--debug': False, 'result': False, '--profile': [], '--shared-cache-dir': '/var/cache/kiwi', '--help': False } self.command_args = { '--add-repo': [], '--allow-existing-root': False, '--description': 'description', '--help': False, '--ignore-repos': False, '--ignore-repos-used-for-build': False, '--clear-cache': False, '--root': 'directory', '--set-repo': None, '--add-package': [], '--delete-package': [], '--set-container-derived-from': None, '--set-container-tag': None, '--signing-key': [], '-h': False, 'help': False, 'prepare': True, 'system': True } self.cli = Cli() self.loaded_command = self.cli.load_command() def teardown(self): sys.argv = argv_kiwi_tests @raises(SystemExit) @patch('kiwi.cli.Help.show') def test_show_and_exit_on_help_request(self, help_show): self.cli.all_args['help'] = True self.cli.show_and_exit_on_help_request() help_show.assert_called_once_with('kiwi') def test_get_servicename_system(self): cli = Cli() assert cli.get_servicename() == 'system' def test_get_servicename_compat_as_option(self): sys.argv = [ sys.argv[0], '--compat', '--', '--build', 'description', '--type', 'vmx', '-d', 'destination' ] cli = Cli() assert cli.get_servicename() == 'compat' def test_get_servicename_compat_as_service(self): sys.argv = [ sys.argv[0], 'compat', '--build', 'description', '--type', 'vmx', '-d', 'destination' ] cli = Cli() assert cli.get_servicename() == 'compat' def test_get_servicename_image(self): sys.argv = [ sys.argv[0], 'image', 'resize', '--target-dir', 'directory', '--size', '20g' ] cli = Cli() assert cli.get_servicename() == 'image' def test_get_servicename_result(self): sys.argv = [ sys.argv[0], 'result', 'list', '--target-dir', 'directory' ] cli = Cli() assert cli.get_servicename() == 'result' def test_get_command(self): assert self.cli.get_command() == 'prepare' def test_get_command_args(self): print(self.cli.get_command_args()) assert self.cli.get_command_args() == self.command_args def test_get_global_args(self): assert self.cli.get_global_args() == self.help_global_args def test_load_command(self): assert self.cli.load_command() == self.loaded_command @patch('kiwi.cli.Cli.invoke_kiwicompat') def test_load_command_compat_mode(self, mock_compat): sys.argv = [ sys.argv[0], '--compat', '--', '--build', 'description', '--type', 'vmx', '-d', 'destination' ] cli = Cli() cli.load_command() mock_compat.assert_called_once_with( ['--build', 'description', '--type', 'vmx', '-d', 'destination'] ) @raises(KiwiCompatError) @patch('kiwi.cli.Path.which') @patch('os.execvp') def test_invoke_kiwicompat_exec_failed(self, mock_exec, mock_which): mock_which.return_value = 'kiwicompat' mock_exec.side_effect = Exception self.cli.invoke_kiwicompat([]) @raises(KiwiCommandNotFound) @patch('kiwi.cli.Path.which') def test_invoke_kiwicompat_not_found(self, mock_which): mock_which.return_value = None self.cli.invoke_kiwicompat([]) @raises(SystemExit) def test_load_command_unknown(self): self.cli.loaded = False self.cli.all_args['<command>'] = 'foo' self.cli.load_command() @raises(KiwiLoadCommandUndefined) def test_load_command_undefined(self): self.cli.loaded = False self.cli.all_args['<command>'] = None self.cli.load_command() @raises(KiwiCommandNotLoaded) def test_get_command_args_not_loaded(self): sys.argv = [ sys.argv[0], 'system', 'command-not-implemented' ] cli = Cli() cli.get_command_args() @raises(KiwiUnknownServiceName) def test_get_servicename_unknown(self): self.cli.all_args['system'] = False self.cli.all_args['foo'] = False self.cli.get_servicename()
class CliTask: """ Base class for all task classes, loads the task and provides the interface to the command options and the XML description Attributes * :attr:`should_perform_task_setup` Indicates if the task should perform the setup steps which covers the following task configurations: * setup debug level * setup logfile * setup color output """ def __init__(self, should_perform_task_setup=True): self.cli = Cli() # initialize runtime checker self.runtime_checker = None # initialize runtime configuration self.runtime_config = RuntimeConfig() # help requested self.cli.show_and_exit_on_help_request() # load/import task module self.task = self.cli.load_command() # get command specific args self.command_args = self.cli.get_command_args() # get global args self.global_args = self.cli.get_global_args() # initialize generic runtime check dicts self.checks_before_command_args = { 'check_minimal_required_preferences': [], 'check_efi_mode_for_disk_overlay_correctly_setup': [], 'check_initrd_selection_required': [], 'check_boot_description_exists': [], 'check_consistent_kernel_in_boot_and_system_image': [], 'check_container_tool_chain_installed': [], 'check_volume_setup_defines_reserved_labels': [], 'check_volume_setup_defines_multiple_fullsize_volumes': [], 'check_volume_setup_has_no_root_definition': [], 'check_volume_label_used_with_lvm': [], 'check_xen_uniquely_setup_as_server_or_guest': [], 'check_mediacheck_installed': [], 'check_dracut_module_for_live_iso_in_package_list': [], 'check_dracut_module_for_disk_overlay_in_package_list': [], 'check_dracut_module_for_disk_oem_in_package_list': [], 'check_dracut_module_for_oem_install_in_package_list': [], 'check_architecture_supports_iso_firmware_setup': [], 'check_appx_naming_conventions_valid': [], 'check_syslinux_installed_if_isolinux_is_used': [], 'check_image_type_unique': [] } self.checks_after_command_args = { 'check_repositories_configured': [], 'check_image_include_repos_publicly_resolvable': [] } if should_perform_task_setup: # set log level if self.global_args['--debug']: log.setLogLevel(logging.DEBUG) else: log.setLogLevel(logging.INFO) # set log file if self.global_args['--logfile']: log.set_logfile(self.global_args['--logfile']) if self.global_args['--color-output']: log.set_color_format() def load_xml_description(self, description_directory): """ Load, upgrade, validate XML description Attributes * :attr:`xml_data` instance of XML data toplevel domain (image), stateless data * :attr:`config_file` used config file path * :attr:`xml_state` Instance of XMLState, stateful data """ log.info('Loading XML description') config_file = description_directory + '/config.xml' if not os.path.exists(config_file): # alternative config file lookup location config_file = description_directory + '/image/config.xml' if not os.path.exists(config_file): # glob config file search, first match wins glob_match = description_directory + '/*.kiwi' for kiwi_file in sorted(glob.iglob(glob_match)): config_file = kiwi_file break if not os.path.exists(config_file): raise KiwiConfigFileNotFound('no XML description found in %s' % description_directory) self.description = XMLDescription(config_file) self.xml_data = self.description.load() self.config_file = config_file.replace('//', '/') self.xml_state = XMLState(self.xml_data, self.global_args['--profile'], self.global_args['--type']) log.info('--> loaded %s', self.config_file) if self.xml_state.build_type: log.info('--> Selected build type: %s', self.xml_state.get_build_type_name()) if self.xml_state.profiles: log.info('--> Selected profiles: %s', ','.join(self.xml_state.profiles)) self.runtime_checker = RuntimeChecker(self.xml_state) def quadruple_token(self, option): """ Helper method for commandline options of the form --option a,b,c,d Make sure to provide a common result for option values which separates the information in a comma separated list of values :return: common option value representation :rtype: str """ tokens = option.split(',', 3) return [ self._pop_token(tokens) if len(tokens) else None for _ in range(0, 4) ] def sextuple_token(self, option): """ Helper method for commandline options of the form --option a,b,c,d,e,f Make sure to provide a common result for option values which separates the information in a comma separated list of values :return: common option value representation :rtype: str """ tokens = option.split(',', 5) return [ self._pop_token(tokens) if len(tokens) else None for _ in range(0, 6) ] def run_checks(self, checks): """ This method runs the given runtime checks excluding the ones disabled in the runtime configuration file. :param dict checks: A dictionary with the runtime method names as keys and their arguments list as the values. """ exclude_list = self.runtime_config.get_disabled_runtime_checks() if self.runtime_checker is not None: for method, args in { key: value for key, value in checks.items() if key not in exclude_list }.items(): attrgetter(method)(self.runtime_checker)(*args) def _pop_token(self, tokens): token = tokens.pop(0) if len(token) > 0 and token == 'true': return True elif len(token) > 0 and token == 'false': return False else: return token
class CliTask(object): """ Base class for all task classes, loads the task and provides the interface to the command options and the XML description Attributes * :attr:`should_perform_task_setup` Indicates if the task should perform the setup steps which covers the following task configurations: * setup debug level * setup logfile * setup color output """ def __init__(self, should_perform_task_setup=True): from ..logger import log self.cli = Cli() # initialize runtime checker self.runtime_checker = None # initialize runtime configuration self.runtime_config = RuntimeConfig() # help requested self.cli.show_and_exit_on_help_request() # load/import task module self.task = self.cli.load_command() # get command specific args self.command_args = self.cli.get_command_args() # get global args self.global_args = self.cli.get_global_args() if should_perform_task_setup: # set log level if self.global_args['--debug']: log.setLogLevel(logging.DEBUG) else: log.setLogLevel(logging.INFO) # set log file if self.global_args['--logfile']: log.set_logfile(self.global_args['--logfile']) if self.global_args['--color-output']: log.set_color_format() def load_xml_description(self, description_directory): """ Load, upgrade, validate XML description Attributes * :attr:`xml_data` instance of XML data toplevel domain (image), stateless data * :attr:`config_file` used config file path * :attr:`xml_state` Instance of XMLState, stateful data """ from ..logger import log log.info('Loading XML description') config_file = description_directory + '/config.xml' if not os.path.exists(config_file): # alternative config file lookup location config_file = description_directory + '/image/config.xml' if not os.path.exists(config_file): # glob config file search, first match wins glob_match = description_directory + '/*.kiwi' for kiwi_file in glob.iglob(glob_match): config_file = kiwi_file break if not os.path.exists(config_file): raise KiwiConfigFileNotFound('no XML description found in %s' % description_directory) description = XMLDescription(config_file) self.xml_data = description.load() self.config_file = config_file.replace('//', '/') self.xml_state = XMLState(self.xml_data, self.global_args['--profile'], self.global_args['--type']) log.info('--> loaded %s', self.config_file) if self.xml_state.build_type: log.info('--> Selected build type: %s', self.xml_state.get_build_type_name()) if self.xml_state.profiles: log.info('--> Selected profiles: %s', ','.join(self.xml_state.profiles)) self.runtime_checker = RuntimeChecker(self.xml_state) def quadruple_token(self, option): """ Helper method for commandline options of the form --option a,b,c,d Make sure to provide a common result for option values which separates the information in a comma separated list of values :return: common option value representation :rtype: str """ tokens = option.split(',', 3) return [ self._pop_token(tokens) if len(tokens) else None for _ in range(0, 4) ] def sextuple_token(self, option): """ Helper method for commandline options of the form --option a,b,c,d,e,f Make sure to provide a common result for option values which separates the information in a comma separated list of values :return: common option value representation :rtype: str """ tokens = option.split(',', 5) return [ self._pop_token(tokens) if len(tokens) else None for _ in range(0, 6) ] def _pop_token(self, tokens): token = tokens.pop(0) if len(token) > 0 and token == 'true': return True elif len(token) > 0 and token == 'false': return False else: return token
class TestCli(object): def setup(self): self.help_global_args = { 'help': False, '--compat': False, '--type': None, 'system': True, '-h': False, '--logfile': None, '--color-output': False, '<legacy_args>': [], '--version': False, '--debug': False, 'result': False, '--profile': [], '--help': False } self.command_args = { '--add-repo': [], '--allow-existing-root': False, '--description': 'description', '--help': False, '--obs-repo-internal': False, '--root': 'directory', '--set-repo': None, '--add-package': [], '--delete-package': [], '-h': False, 'help': False, 'prepare': True, 'system': True } sys.argv = [ sys.argv[0], 'system', 'prepare', '--description', 'description', '--root', 'directory' ] self.cli = Cli() self.loaded_command = self.cli.load_command() @raises(SystemExit) @patch('kiwi.cli.Help.show') def test_show_and_exit_on_help_request(self, help_show): self.cli.all_args['help'] = True self.cli.show_and_exit_on_help_request() help_show.assert_called_once_with('kiwi') def test_get_servicename_system(self): sys.argv = [ sys.argv[0], 'system', 'prepare', '--description', 'description', '--root', 'directory' ] cli = Cli() assert cli.get_servicename() == 'system' def test_get_servicename_compat(self): sys.argv = [ sys.argv[0], '--compat', '--', '--build', 'description', '--type', 'vmx', '-d', 'destination' ] cli = Cli() assert cli.get_servicename() == 'compat' def test_get_servicename_result(self): sys.argv = [sys.argv[0], 'result', 'list', '--target-dir', 'directory'] cli = Cli() assert cli.get_servicename() == 'result' def test_get_command(self): assert self.cli.get_command() == 'prepare' def test_get_command_args(self): print(self.cli.get_command_args()) assert self.cli.get_command_args() == self.command_args def test_get_global_args(self): assert self.cli.get_global_args() == self.help_global_args def test_load_command(self): assert self.cli.load_command() == self.loaded_command @patch('kiwi.cli.Cli.invoke_kiwicompat') def test_load_command_compat_mode(self, mock_compat): sys.argv = [ sys.argv[0], '--compat', '--', '--build', 'description', '--type', 'vmx', '-d', 'destination' ] cli = Cli() cli.load_command() mock_compat.assert_called_once_with( ['--build', 'description', '--type', 'vmx', '-d', 'destination']) @raises(KiwiCompatError) @patch('os.path.exists') @patch('os.execvp') def test_invoke_kiwicompat_exec_failed(self, mock_exec, mock_exists): mock_exists.return_value = True mock_exec.side_effect = Exception self.cli.invoke_kiwicompat([]) @raises(SystemExit) def test_load_command_unknown(self): self.cli.loaded = False self.cli.all_args['<command>'] = 'foo' self.cli.load_command() @raises(KiwiLoadCommandUndefined) def test_load_command_undefined(self): self.cli.loaded = False self.cli.all_args['<command>'] = None self.cli.load_command() @raises(KiwiCommandNotLoaded) def test_get_command_args_not_loaded(self): sys.argv = [sys.argv[0], 'system', 'command-not-implemented'] cli = Cli() cli.get_command_args() @raises(KiwiUnknownServiceName) def test_get_servicename_unknown(self): self.cli.all_args['system'] = False self.cli.all_args['foo'] = False self.cli.get_servicename()
class TestCli(object): def setup(self): self.help_global_args = { 'help': False, '--compat': False, '--type': None, 'system': True, '-h': False, '--logfile': None, '--color-output': False, '<legacy_args>': [], '--version': False, '--debug': False, 'result': False, '--profile': [], '--help': False } self.command_args = { '--add-repo': [], '--allow-existing-root': False, '--description': 'description', '--help': False, '--obs-repo-internal': False, '--root': 'directory', '--set-repo': None, '--add-package': [], '--delete-package': [], '-h': False, 'help': False, 'prepare': True, 'system': True } sys.argv = [ sys.argv[0], 'system', 'prepare', '--description', 'description', '--root', 'directory' ] self.cli = Cli() self.loaded_command = self.cli.load_command() @raises(SystemExit) @patch('kiwi.cli.Help.show') def test_show_and_exit_on_help_request(self, help_show): self.cli.all_args['help'] = True self.cli.show_and_exit_on_help_request() help_show.assert_called_once_with('kiwi') def test_get_servicename_system(self): sys.argv = [ sys.argv[0], 'system', 'prepare', '--description', 'description', '--root', 'directory' ] cli = Cli() assert cli.get_servicename() == 'system' def test_get_servicename_compat(self): sys.argv = [ sys.argv[0], '--compat', '--', '--build', 'description', '--type', 'vmx', '-d', 'destination' ] cli = Cli() assert cli.get_servicename() == 'compat' def test_get_servicename_result(self): sys.argv = [ sys.argv[0], 'result', 'list', '--target-dir', 'directory' ] cli = Cli() assert cli.get_servicename() == 'result' def test_get_command(self): assert self.cli.get_command() == 'prepare' def test_get_command_args(self): print(self.cli.get_command_args()) assert self.cli.get_command_args() == self.command_args def test_get_global_args(self): assert self.cli.get_global_args() == self.help_global_args def test_load_command(self): assert self.cli.load_command() == self.loaded_command @patch('kiwi.cli.Cli.invoke_kiwicompat') def test_load_command_compat_mode(self, mock_compat): sys.argv = [ sys.argv[0], '--compat', '--', '--build', 'description', '--type', 'vmx', '-d', 'destination' ] cli = Cli() cli.load_command() mock_compat.assert_called_once_with( ['--build', 'description', '--type', 'vmx', '-d', 'destination'] ) @raises(KiwiCompatError) @patch('os.path.exists') @patch('os.execvp') def test_invoke_kiwicompat_exec_failed(self, mock_exec, mock_exists): mock_exists.return_value = True mock_exec.side_effect = Exception self.cli.invoke_kiwicompat([]) @raises(SystemExit) def test_load_command_unknown(self): self.cli.loaded = False self.cli.all_args['<command>'] = 'foo' self.cli.load_command() @raises(KiwiLoadCommandUndefined) def test_load_command_undefined(self): self.cli.loaded = False self.cli.all_args['<command>'] = None self.cli.load_command() @raises(KiwiCommandNotLoaded) def test_get_command_args_not_loaded(self): sys.argv = [ sys.argv[0], 'system', 'command-not-implemented' ] cli = Cli() cli.get_command_args() @raises(KiwiUnknownServiceName) def test_get_servicename_unknown(self): self.cli.all_args['system'] = False self.cli.all_args['foo'] = False self.cli.get_servicename()
class CliTask(object): """ Base class for all task classes, loads the task and provides the interface to the command options and the XML description Attributes * :attr:`should_perform_task_setup` Indicates if the task should perform the setup steps which covers the following task configurations: * setup debug level * setup logfile * setup color output """ def __init__(self, should_perform_task_setup=True): from ..logger import log self.cli = Cli() # initialize runtime checker self.runtime_checker = None # initialize runtime configuration self.runtime_config = RuntimeConfig() # help requested self.cli.show_and_exit_on_help_request() # load/import task module self.task = self.cli.load_command() # get command specific args self.command_args = self.cli.get_command_args() # get global args self.global_args = self.cli.get_global_args() if should_perform_task_setup: # set log level if self.global_args['--debug']: log.setLogLevel(logging.DEBUG) else: log.setLogLevel(logging.INFO) # set log file if self.global_args['--logfile']: log.set_logfile( self.global_args['--logfile'] ) if self.global_args['--color-output']: log.set_color_format() def load_xml_description(self, description_directory): """ Load, upgrade, validate XML description Attributes * :attr:`xml_data` instance of XML data toplevel domain (image), stateless data * :attr:`config_file` used config file path * :attr:`xml_state` Instance of XMLState, stateful data """ from ..logger import log log.info('Loading XML description') config_file = description_directory + '/config.xml' if not os.path.exists(config_file): # alternative config file lookup location config_file = description_directory + '/image/config.xml' if not os.path.exists(config_file): # glob config file search, first match wins glob_match = description_directory + '/*.kiwi' for kiwi_file in glob.iglob(glob_match): config_file = kiwi_file break if not os.path.exists(config_file): raise KiwiConfigFileNotFound( 'no XML description found in %s' % description_directory ) description = XMLDescription( config_file ) self.xml_data = description.load() self.config_file = config_file.replace('//', '/') self.xml_state = XMLState( self.xml_data, self.global_args['--profile'], self.global_args['--type'] ) log.info('--> loaded %s', self.config_file) if self.xml_state.build_type: log.info( '--> Selected build type: %s', self.xml_state.get_build_type_name() ) if self.xml_state.profiles: log.info( '--> Selected profiles: %s', ','.join(self.xml_state.profiles) ) self.runtime_checker = RuntimeChecker(self.xml_state) def quadruple_token(self, option): """ Helper method for commandline options of the form --option a,b,c,d Make sure to provide a common result for option values which separates the information in a comma separated list of values :return: common option value representation :rtype: str """ tokens = option.split(',', 3) return [ self._pop_token(tokens) if len(tokens) else None for _ in range( 0, 4 ) ] def sextuple_token(self, option): """ Helper method for commandline options of the form --option a,b,c,d,e,f Make sure to provide a common result for option values which separates the information in a comma separated list of values :return: common option value representation :rtype: str """ tokens = option.split(',', 5) return [ self._pop_token(tokens) if len(tokens) else None for _ in range( 0, 6 ) ] def _pop_token(self, tokens): token = tokens.pop(0) if len(token) > 0 and token == 'true': return True elif len(token) > 0 and token == 'false': return False else: return token