예제 #1
0
파일: cli_test.py 프로젝트: rabueker/kiwi
 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'
예제 #2
0
파일: cli_test.py 프로젝트: rtamalin/kiwi
 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
예제 #3
0
파일: cli_test.py 프로젝트: rabueker/kiwi
 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
예제 #4
0
    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)
예제 #5
0
파일: cli_test.py 프로젝트: rtamalin/kiwi
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()
예제 #6
0
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()
예제 #7
0
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
예제 #8
0
파일: base.py 프로젝트: kylozhang/kiwi
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
예제 #9
0
파일: cli_test.py 프로젝트: ChrisBr/kiwi
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()
예제 #10
0
파일: cli_test.py 프로젝트: ChrisBr/kiwi
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()
예제 #11
0
파일: base.py 프로젝트: Conan-Kudo/kiwi
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