def test_poll_show_progress_raises(self, mock_command): match_method = CommandProcess(mock_command).create_match_method( self.fake_matcher) process = CommandProcess(mock_command) process.command.command.process.poll = self.flow process.command.command.output_available = self.flow_out_available process.command.command.error_available = self.flow_err_available process.command.command.output.read = self.flow_out process.command.command.error.read = self.flow_err process.command.command.process.returncode = 1 process.poll_show_progress(['a', 'b'], match_method)
def test_poll_show_progress(self, mock_command): match_method = CommandProcess(mock_command).create_match_method( self.fake_matcher) process = CommandProcess(mock_command) process.command.command.process.poll = self.flow process.command.command.output_available = self.flow_out_available process.command.command.error_available = self.flow_err_available process.command.command.output.read = self.flow_out process.command.command.error.read = self.flow_err process.command.command.process.returncode = 0 with self._caplog.at_level(logging.DEBUG): process.poll_show_progress(['a', 'b'], match_method) assert 'system: data' in self._caplog.text
def test_poll_show_progress(self, mock_log_debug, mock_command): match_method = CommandProcess(mock_command).create_match_method( self.fake_matcher) process = CommandProcess(mock_command) process.command.command.process.poll = self.flow process.command.command.output_available = self.flow_out_available process.command.command.error_available = self.flow_err_available process.command.command.output.read = self.flow_out process.command.command.error.read = self.flow_err process.command.command.process.returncode = 0 process.poll_show_progress(['a', 'b'], match_method) assert mock_log_debug.call_args_list == [ call('%s: %s', 'system', 'data') ]
def test_destructor(self, mock_command): process = CommandProcess(mock_command) process.command.command.process.returncode = None process.command.command.process.pid = 42 process.command.command.process.kill = mock.Mock() process.__del__() process.command.command.process.kill.assert_called_once_with()
def _call_script_no_chroot( self, name, option_list, working_directory ): if not working_directory: working_directory = self.root_dir script_path = os.path.abspath( os.sep.join([self.root_dir, 'image', name]) ) if os.path.exists(script_path): bash_command = [ 'cd', working_directory, '&&', 'bash', '--norc', script_path, ' '.join(option_list) ] if log.getLogFlags().get('run-scripts-in-screen'): # Run scripts in a screen session if requested config_script = Command.call( ['screen', '-t', '-X', 'bash', '-c', ' '.join(bash_command)] ) else: # In standard mode run script through bash config_script = Command.call( ['bash', '-c', ' '.join(bash_command)] ) process = CommandProcess( command=config_script, log_topic='Calling ' + name + ' script' ) result = process.poll_and_watch() if result.returncode != 0: raise KiwiScriptFailed( '{0} failed: {1}'.format(name, result.stderr) )
def install_packages(self, manager, packages): """ Install one or more packages using the package manager inside of the new root directory :param object manager: instance of a :class:`PackageManager` subclass :param list packages: package list :raises KiwiSystemInstallPackagesFailed: if installation process fails """ log.info('Installing system packages (chroot)') all_install_items = self._setup_requests( manager, packages ) if all_install_items: process = CommandProcess( command=manager.process_install_requests(), log_topic='system' ) try: process.poll_show_progress( items_to_complete=all_install_items, match_method=process.create_match_method( manager.match_package_installed ) ) except Exception as issue: raise KiwiSystemInstallPackagesFailed( self.issue_message.format( headline='Package installation failed', reason=issue ) )
def delete_packages(self, manager, packages, force=False): """ Delete one or more packages using the package manager inside of the new root directory :param object manager: PackageManager :param list packages: package list :param bool force: force deletion true|false """ log.info('Deleting system packages (chroot)') all_delete_items = self._setup_requests( manager, packages ) if all_delete_items: process = CommandProcess( command=manager.process_delete_requests(force), log_topic='system' ) try: process.poll_show_progress( items_to_complete=all_delete_items, match_method=process.create_match_method( manager.match_package_deleted ) ) except Exception as e: raise KiwiSystemDeletePackagesFailed( 'Package deletion failed: %s' % format(e) )
def _call_script(self, name, option_list=None): script_path = os.path.join(self.root_dir, 'image', name) if os.path.exists(script_path): options = option_list or [] if log.getLogFlags().get('run-scripts-in-screen'): # Run scripts in a screen session if requested command = ['screen', '-t', '-X', 'chroot', self.root_dir] else: # In standard mode run scripts without a terminal # associated to them command = ['chroot', self.root_dir] if not Path.access(script_path, os.X_OK): command.append('bash') command.append( os.path.join(defaults.IMAGE_METADATA_DIR, name) ) command.extend(options) profile = Profile(self.xml_state) caller_environment = copy.deepcopy(os.environ) caller_environment.update(profile.get_settings()) config_script = Command.call(command, caller_environment) process = CommandProcess( command=config_script, log_topic='Calling ' + name + ' script' ) result = process.poll_and_watch() if result.returncode != 0: raise KiwiScriptFailed( '{0} failed: {1}'.format(name, result.stderr) )
def install_packages(self, manager, packages): """ Install one or more packages using the package manager inside of the new root directory :param object manager: PackageManager :param list packages: package list """ log.info('Installing system packages (chroot)') all_install_items = self._setup_requests( manager, packages ) if all_install_items: process = CommandProcess( command=manager.process_install_requests(), log_topic='system' ) try: process.poll_show_progress( items_to_complete=all_install_items, match_method=process.create_match_method( manager.match_package_installed ) ) except Exception as e: raise KiwiSystemInstallPackagesFailed( 'Package installation failed: %s' % format(e) )
def delete_packages(self, manager, packages, force=False): """ Delete one or more packages using the package manager inside of the new root directory. If the removal is set with `force` flag only listed packages are deleted and any dependency break or leftover is ignored. :param object manager: instance of a :class:`PackageManager` subclass :param list packages: package list :param bool force: force deletion true|false :raises KiwiSystemDeletePackagesFailed: if installation process fails """ all_delete_items = self._setup_requests(manager, packages) if all_delete_items: log.info('{0} system packages (chroot)'.format( 'Force deleting' if force else 'Uninstall')) process = CommandProcess( command=manager.process_delete_requests(force), log_topic='system') try: process.poll_show_progress( items_to_complete=all_delete_items, match_method=process.create_match_method( manager.match_package_deleted)) except Exception as issue: raise KiwiSystemDeletePackagesFailed( self.issue_message.format( headline='Package deletion failed', reason=issue))
def _call_script_no_chroot(self, name, option_list, working_directory): if not working_directory: working_directory = self.root_dir script_path = os.path.abspath( os.sep.join([self.root_dir, 'image', name])) if os.path.exists(script_path): bash_command = [ 'cd', working_directory, '&&', 'bash', '--norc', script_path, ' '.join(option_list) ] if log.getLogLevel() == logging.DEBUG and not \ Defaults.is_buildservice_worker(): # In debug mode run scripts in a screen session to # allow attaching and debugging config_script = Command.call([ 'screen', '-t', '-X', 'bash', '-c', ' '.join(bash_command) ]) else: # In standard mode run script through bash config_script = Command.call( ['bash', '-c', ' '.join(bash_command)]) process = CommandProcess(command=config_script, log_topic='Calling ' + name + ' script') result = process.poll_and_watch() if result.returncode != 0: raise KiwiScriptFailed('{0} failed: {1}'.format( name, result.stderr))
def install_bootstrap(self, manager: PackageManagerBase, plus_packages: List = None) -> None: """ Install system software using the package manager from the host, also known as bootstrapping :param object manager: instance of a :class:`PackageManager` subclass :param list plus_packages: list of additional packages :raises KiwiBootStrapPhaseFailed: if the bootstrapping process fails either installing packages or including bootstrap archives """ if not self.xml_state.get_bootstrap_packages_sections() \ and not plus_packages: log.warning('No <packages> sections marked as "bootstrap" found') log.info('Processing of bootstrap stage skipped') return log.info('Installing bootstrap packages') bootstrap_packages = self.xml_state.get_bootstrap_packages( plus_packages) collection_type = self.xml_state.get_bootstrap_collection_type() log.info('--> collection type: %s', collection_type) bootstrap_collections = self.xml_state.get_bootstrap_collections() bootstrap_products = self.xml_state.get_bootstrap_products() bootstrap_archives = self.xml_state.get_bootstrap_archives() # process package installations if collection_type == 'onlyRequired': manager.process_only_required() else: manager.process_plus_recommended() all_install_items = self._setup_requests(manager, bootstrap_packages, bootstrap_collections, bootstrap_products) process = CommandProcess( command=manager.process_install_requests_bootstrap(self.root_bind), log_topic='bootstrap') try: process.poll_show_progress( items_to_complete=all_install_items, match_method=process.create_match_method( manager.match_package_installed)) except Exception as issue: if manager.has_failed(process.returncode()): raise KiwiBootStrapPhaseFailed( self.issue_message.format( headline='Bootstrap package installation failed', reason=issue)) manager.post_process_install_requests_bootstrap(self.root_bind) # process archive installations if bootstrap_archives: try: self._install_archives(bootstrap_archives) except Exception as issue: raise KiwiBootStrapPhaseFailed( self.issue_message.format( headline='Bootstrap archive installation failed', reason=issue))
def install_system(self, manager): """ Install system software using the package manager inside of the new root directory. This is done via a chroot operation and requires the desired package manager to became installed via the bootstrap phase :param object manager: instance of a :class:`PackageManager` subclass :raises KiwiInstallPhaseFailed: if the install process fails either installing packages or including any archive """ log.info( 'Installing system (chroot) for build type: %s', self.xml_state.get_build_type_name() ) collection_type = self.xml_state.get_system_collection_type() log.info('--> collection type: %s', collection_type) system_packages = self.xml_state.get_system_packages() system_collections = self.xml_state.get_system_collections() system_products = self.xml_state.get_system_products() system_archives = self.xml_state.get_system_archives() system_packages_ignored = self.xml_state.get_system_ignore_packages() # process package installations if collection_type == 'onlyRequired': manager.process_only_required() else: manager.process_plus_recommended() all_install_items = self._setup_requests( manager, system_packages, system_collections, system_products, system_packages_ignored ) if all_install_items: process = CommandProcess( command=manager.process_install_requests(), log_topic='system' ) try: process.poll_show_progress( items_to_complete=all_install_items, match_method=process.create_match_method( manager.match_package_installed ) ) except Exception as issue: if manager.has_failed(process.returncode()): raise KiwiInstallPhaseFailed( 'System package installation failed: {0}'.format(issue) ) # process archive installations if system_archives: try: self._install_archives(system_archives) except Exception as e: raise KiwiInstallPhaseFailed( 'System archive installation failed: %s' % format(e) )
def test_poll_raises(self, mock_command): process = CommandProcess(mock_command) process.command.command.process.poll = self.flow process.command.command.output_available = self.flow_out_available process.command.command.error_available = self.flow_err_available process.command.command.output.read = self.flow_out process.command.command.error.read = self.flow_err process.command.command.output.read.return_value = 'data' process.command.command.process.returncode = 1 process.poll()
def _call_script(self, name): if os.path.exists(self.root_dir + '/image/' + name): config_script = Command.call( ['chroot', self.root_dir, 'bash', '/image/' + name]) process = CommandProcess(command=config_script, log_topic='Calling ' + name + ' script') result = process.poll_and_watch() if result.returncode != 0: raise KiwiScriptFailed('%s failed: %s' % (name, format(result.stderr)))
def test_poll(self, mock_command): process = CommandProcess(mock_command) process.command.command.process.poll = self.flow process.command.command.output_available = self.flow_out_available process.command.command.error_available = self.flow_err_available process.command.command.output.read = self.flow_out process.command.command.error.read = self.flow_err process.command.command.process.returncode = 0 with self._caplog.at_level(logging.DEBUG): process.poll() assert 'system: data' in self._caplog.text
def test_poll(self, mock_log_debug, mock_command): process = CommandProcess(mock_command) process.command.command.process.poll = self.flow process.command.command.output_available = self.flow_out_available process.command.command.error_available = self.flow_err_available process.command.command.output.read = self.flow_out process.command.command.error.read = self.flow_err process.command.command.process.returncode = 0 process.poll() assert mock_log_debug.call_args_list == [ call('%s: %s', 'system', 'data') ]
def install_bootstrap(self, manager): """ Install system software using the package manager from the host, also known as bootstrapping """ if not self.xml_state.get_bootstrap_packages_sections(): log.warning('No <packages> sections marked as "bootstrap" found') log.info('Processing of bootstrap stage skipped') return log.info('Installing bootstrap packages') bootstrap_packages = self.xml_state.get_bootstrap_packages() collection_type = self.xml_state.get_bootstrap_collection_type() log.info('--> collection type: %s', collection_type) bootstrap_collections = self.xml_state.get_bootstrap_collections() bootstrap_products = self.xml_state.get_bootstrap_products() bootstrap_archives = self.xml_state.get_bootstrap_archives() # process package installations if collection_type == 'onlyRequired': manager.process_only_required() else: manager.process_plus_recommended() all_install_items = self._setup_requests( manager, bootstrap_packages, bootstrap_collections, bootstrap_products ) process = CommandProcess( command=manager.process_install_requests_bootstrap(), log_topic='bootstrap' ) try: process.poll_show_progress( items_to_complete=all_install_items, match_method=process.create_match_method( manager.match_package_installed ) ) except Exception as e: raise KiwiBootStrapPhaseFailed( 'Bootstrap package installation failed: %s' % format(e) ) manager.dump_reload_package_database() # process archive installations if bootstrap_archives: try: self._install_archives(bootstrap_archives) except Exception as e: raise KiwiBootStrapPhaseFailed( 'Bootstrap archive installation failed: %s' % format(e) )
def _call_script(self, name): script_path = os.path.join(self.root_dir, 'image', name) if os.path.exists(script_path): command = ['chroot', self.root_dir] if not Path.access(script_path, os.X_OK): command += ['bash'] command += ['/image/' + name] config_script = Command.call(command) process = CommandProcess(command=config_script, log_topic='Calling ' + name + ' script') result = process.poll_and_watch() if result.returncode != 0: raise KiwiScriptFailed('%s failed: %s' % (name, format(result.stderr)))
def test_poll_and_watch(self, mock_command): process = CommandProcess(mock_command) process.command.command.process.poll = self.flow process.command.command.output_available = self.flow_out_available process.command.command.error_available = self.flow_err_available process.command.command.output.read = self.flow_out process.command.command.error.read = self.flow_err process.command.command.process.returncode = 1 with self._caplog.at_level(logging.DEBUG): result = process.poll_and_watch() assert '--------------out start-------------' in self._caplog.text assert 'data' in self._caplog.text assert '--------------out stop--------------' in self._caplog.text assert result.stderr == 'error'
def update_system(self, manager): """ Install package updates from the used repositories. the process uses the package manager from inside of the new root directory :param object manager: PackageManager """ log.info('Update system (chroot)') process = CommandProcess(command=manager.update(), log_topic='update') try: process.poll() except Exception as e: raise KiwiSystemUpdateFailed('System update failed: %s' % format(e))
def _call_script_no_chroot(self, name, option_list, working_directory): if not working_directory: working_directory = self.root_dir script_path = os.path.abspath( os.sep.join([self.root_dir, 'image', name])) if os.path.exists(script_path): bash_command = [ 'cd', working_directory, '&&', 'bash', '--norc', script_path, ' '.join(option_list) ] config_script = Command.call( ['bash', '-c', ' '.join(bash_command)]) process = CommandProcess(command=config_script, log_topic='Calling ' + name + ' script') result = process.poll_and_watch() if result.returncode != 0: raise KiwiScriptFailed('%s failed: %s' % (name, format(result.stderr)))
def update_system(self, manager): """ Install package updates from the used repositories. the process uses the package manager from inside of the new root directory :param object manager: instance of a :class:`PackageManager` subclass :raises KiwiSystemUpdateFailed: if packages update fails """ log.info('Update system (chroot)') process = CommandProcess(command=manager.update(), log_topic='update') try: process.poll() except Exception as issue: raise KiwiSystemUpdateFailed( self.issue_message.format(headline='System update failed', reason=issue))
def _call_script(self, name, option_list=None): script_path = os.path.join(self.root_dir, 'image', name) if os.path.exists(script_path): options = option_list or [] command = ['chroot', self.root_dir] if not Path.access(script_path, os.X_OK): command.append('bash') command.append(os.path.join(defaults.IMAGE_METADATA_DIR, name)) command.extend(options) profile = Profile(self.xml_state) caller_environment = copy.deepcopy(os.environ) caller_environment.update(profile.get_settings()) config_script = Command.call(command, caller_environment) process = CommandProcess(command=config_script, log_topic='Calling ' + name + ' script') result = process.poll_and_watch() if result.returncode != 0: raise KiwiScriptFailed('{0} failed: {1}'.format( name, result.stderr))
def test_poll_and_watch(self, mock_log_debug, mock_command): process = CommandProcess(mock_command) process.command.command.process.poll = self.flow process.command.command.output_available = self.flow_out_available process.command.command.error_available = self.flow_err_available process.command.command.output.read = self.flow_out process.command.command.error.read = self.flow_err process.command.command.process.returncode = 1 result = process.poll_and_watch() call = mock_log_debug.call_args_list[0] assert mock_log_debug.call_args_list[0] == \ call('--------------out start-------------') call = mock_log_debug.call_args_list[1] assert mock_log_debug.call_args_list[1] == \ call('data') call = mock_log_debug.call_args_list[2] assert mock_log_debug.call_args_list[2] == \ call('--------------out stop--------------') assert result.stderr == 'error'
def test_returncode(self, mock_command): command = mock.Mock() mock_command.return_value = command process = CommandProcess(command) assert process.returncode() == command.process.returncode
def test_create_match_method(self, mock_command): match_method = CommandProcess(mock_command).create_match_method( self.fake_matcher) assert match_method('a', 'b') is True