def process_install_requests(self) -> command_call_type: """ Process package install requests for image phase (chroot) :return: process results in command type :rtype: namedtuple """ update_command = ['chroot', self.root_dir, 'apt-get'] update_command.extend( Path.move_to_root(self.root_dir, self.apt_get_args) ) update_command.extend(self.custom_args) update_command.append('update') Command.run(update_command, self.command_env) apt_get_command = ['chroot', self.root_dir, 'apt-get'] apt_get_command.extend( Path.move_to_root(self.root_dir, self.apt_get_args) ) apt_get_command.extend(self.custom_args) apt_get_command.append('install') apt_get_command.extend(self._package_requests()) return Command.call( apt_get_command, self.command_env )
def process_install_requests(self) -> command_call_type: """ Process package install requests for image phase (chroot) :return: process results in command type :rtype: namedtuple """ exclude_args = [] if self.exclude_requests: # For DNF, excluding a package means removing it from # the solver operation. This is done by adding --exclude # to the command line. This means that if the package is # hard required by another package, it will break the transaction. for package in self.exclude_requests: exclude_args.append('--exclude=' + package) chroot_dnf_args = Path.move_to_root(self.root_dir, self.dnf_args) bash_command = [ 'chroot', self.root_dir, 'microdnf' ] + chroot_dnf_args + self.custom_args + exclude_args + [ 'install' ] + self.package_requests self.cleanup_requests() return Command.call(['bash', '-c', ' '.join(bash_command)], self.command_env)
def process_delete_requests(self, force=False): """ Process package delete requests (chroot) :param bool force: force deletion: true|false :raises KiwiRequestError: if none of the packages to delete is installed. :return: process results in command type :rtype: namedtuple """ delete_items = [] for delete_item in self.package_requests: try: Command.run( ['chroot', self.root_dir, 'rpm', '-q', delete_item]) delete_items.append(delete_item) except Exception: # ignore packages which are not installed pass if not delete_items: raise KiwiRequestError( 'None of the requested packages to delete are installed') self.cleanup_requests() if force: delete_options = ['--nodeps', '--allmatches', '--noscripts'] return Command.call(['chroot', self.root_dir, 'rpm', '-e'] + delete_options + delete_items, self.command_env) else: chroot_dnf_args = Path.move_to_root(self.root_dir, self.dnf_args) return Command.call(['chroot', self.root_dir, 'microdnf'] + chroot_dnf_args + self.custom_args + ['remove'] + delete_items, self.command_env)
def process_delete_requests(self, force=False): """ Process package delete requests (chroot) :param bool force: force deletion: true|false :raises KiwiRequestError: if none of the packages to delete is installed :return: process results in command type :rtype: namedtuple """ delete_items = [] for delete_item in self.package_requests: try: Command.run( ['chroot', self.root_dir, 'pacman', '-Qi', delete_item]) delete_items.append(delete_item) except Exception: # ignore packages which are not installed pass if not delete_items: raise KiwiRequestError( 'None of the requested packages to delete are installed') self.cleanup_requests() chroot_pacman_args = Path.move_to_root(self.root_dir, self.pacman_args) return Command.call(['chroot', self.root_dir, 'pacman'] + chroot_pacman_args + self.custom_args + ['-Rdd' if force else '-Rs'] + delete_items, self.command_env)
def update(self) -> command_call_type: """ Process package update requests (chroot) :return: process results in command type :rtype: namedtuple """ chroot_dnf_args = Path.move_to_root(self.root_dir, self.dnf_args) return Command.call(['chroot', self.root_dir, 'microdnf'] + chroot_dnf_args + self.custom_args + ['upgrade'], self.command_env)
def setup(self): repository = mock.Mock() repository.root_dir = 'root-dir' self.command_env = { 'HOME': '/home/ms', 'ZYPP_CONF': 'root-dir/my/zypp.conf' } repository.runtime_config = mock.MagicMock( return_value={ 'zypper_args': ['--reposd-dir', 'root-dir/my/repos'], 'command_env': self.command_env }) self.manager = PackageManagerZypper(repository) self.chroot_zypper_args = Path.move_to_root('root-dir', self.manager.zypper_args) self.chroot_command_env = self.manager.command_env zypp_conf = self.manager.command_env['ZYPP_CONF'] self.chroot_command_env['ZYPP_CONF'] = \ Path.move_to_root('root-dir', [zypp_conf])[0]
def update(self): """ Process package update requests (chroot) :return: process results in command type :rtype: namedtuple """ chroot_pacman_args = Path.move_to_root(self.root_dir, self.pacman_args) return Command.call(['chroot', self.root_dir, 'pacman'] + chroot_pacman_args + self.custom_args + ['-Su'], self.command_env)
def post_init(self, custom_args: List = []) -> None: """ Post initialization method Store custom zypper arguments :param list custom_args: custom zypper arguments """ self.anonymousId_file = '/var/lib/zypp/AnonymousUniqueId' self.custom_args = custom_args runtime_config = self.repository.runtime_config() self.zypper_args = runtime_config['zypper_args'] self.chroot_zypper_args = Path.move_to_root(self.root_dir, self.zypper_args) self.command_env = runtime_config['command_env'] self.chroot_command_env = dict(self.command_env) if 'ZYPP_CONF' in self.command_env: self.chroot_command_env['ZYPP_CONF'] = Path.move_to_root( self.root_dir, [self.command_env['ZYPP_CONF']])[0]
def post_init(self, custom_args=None): """ Post initialization method Store custom zypper arguments :param list custom_args: custom zypper arguments """ self.custom_args = custom_args if not custom_args: self.custom_args = [] runtime_config = self.repository.runtime_config() self.zypper_args = runtime_config['zypper_args'] self.chroot_zypper_args = Path.move_to_root(self.root_dir, self.zypper_args) self.command_env = runtime_config['command_env'] self.chroot_command_env = dict(self.command_env) if 'ZYPP_CONF' in self.command_env: self.chroot_command_env['ZYPP_CONF'] = Path.move_to_root( self.root_dir, [self.command_env['ZYPP_CONF']])[0]
def update(self) -> command_call_type: """ Process package update requests (chroot) :return: process results in command type :rtype: namedtuple """ apt_get_command = ['chroot', self.root_dir, 'apt-get'] apt_get_command.extend( Path.move_to_root(self.root_dir, self.apt_get_args)) apt_get_command.extend(self.custom_args) apt_get_command.append('upgrade') return Command.call(apt_get_command, self.command_env)
def process_install_requests(self) -> command_call_type: """ Process package install requests for image phase (chroot) :return: process results in command type :rtype: namedtuple """ chroot_pacman_args = Path.move_to_root(self.root_dir, self.pacman_args) pacman_command = ['chroot', self.root_dir, 'pacman' ] + chroot_pacman_args + self.custom_args + [ '-S', '--needed' ] + self.package_requests self.cleanup_requests() return Command.call(pacman_command, self.command_env)
def process_delete_requests(self, force=False): """ Process package delete requests (chroot) :param bool force: force deletion: true|false :raises KiwiRequestError: if none of the packages to delete is installed :return: process results in command type :rtype: namedtuple """ delete_items = [] for delete_item in self._package_requests(): try: Command.run( ['chroot', self.root_dir, 'dpkg', '-l', delete_item] ) delete_items.append(delete_item) except Exception: # ignore packages which are not installed pass if not delete_items: raise KiwiRequestError( 'None of the requested packages to delete are installed' ) if force: apt_get_command = ['chroot', self.root_dir, 'dpkg'] apt_get_command.extend(['--force-all', '-r']) apt_get_command.extend(delete_items) else: apt_get_command = ['chroot', self.root_dir, 'apt-get'] apt_get_command.extend( Path.move_to_root(self.root_dir, self.apt_get_args) ) apt_get_command.extend(self.custom_args) apt_get_command.extend(['--auto-remove', 'remove']) apt_get_command.extend(delete_items) return Command.call( apt_get_command, self.command_env )
def process_delete_requests(self, force: bool = False) -> command_call_type: """ Process package delete requests (chroot) :param bool force: force deletion: true|false :raises KiwiRequestError: if none of the packages to delete is installed :return: process results in command type :rtype: namedtuple """ delete_items = [] for delete_item in self._package_requests(): try: Command.run( ['chroot', self.root_dir, 'dpkg', '-l', delete_item] ) delete_items.append(delete_item) except Exception: # ignore packages which are not installed pass if not delete_items: raise KiwiRequestError( 'None of the requested packages to delete are installed' ) # deleting debs for some reason can also trigger package # scripts from the libc-bin (glibc) package. This often # results in calls like ldconfig which failed unless the # system would be really running. Since the deletion # happens via chroot and with the system in offline mode # many attempts to uninstall a package, even cracefully # failed for this reason. So far I only saw the workaround # to make ldconfig a noop during the process of uninstall. # This is not a nice solution and I dislike it. However, # the only one I could come up with to turn the package # uninstall in a useful feature in kiwi. Command.run( [ 'cp', f'{self.root_dir}/usr/sbin/ldconfig', f'{self.root_dir}/usr/sbin/ldconfig.orig' ] ) Command.run( [ 'cp', f'{self.root_dir}/usr/bin/true', f'{self.root_dir}/usr/sbin/ldconfig' ] ) if force: # force deleting debs only worked well for me when ignoring # the pre/post-inst and pre/post-remove codings. No idea why it # ends in so many conflicts but if you want to force get rid # of stuff this was the only way I could come up with. There # are still cases when it does not work depending on the many # code that runs on deleting for package in delete_items: pre_delete_pattern = \ f'{self.root_dir}/var/lib/dpkg/info/{package}*.pre*' post_delete_pattern = \ f'{self.root_dir}/var/lib/dpkg/info/{package}*.post*' for delete_file in glob.iglob(pre_delete_pattern): Path.wipe(delete_file) for delete_file in glob.iglob(post_delete_pattern): Path.wipe(delete_file) apt_get_command = ['chroot', self.root_dir, 'dpkg'] apt_get_command.extend( [ '--remove', '--force-remove-reinstreq', '--force-remove-essential', '--force-depends' ] ) apt_get_command.extend(delete_items) else: apt_get_command = ['chroot', self.root_dir, 'apt-get'] apt_get_command.extend( Path.move_to_root(self.root_dir, self.apt_get_args) ) apt_get_command.extend(self.custom_args) apt_get_command.extend(['--auto-remove', 'remove']) apt_get_command.extend(delete_items) return Command.call( apt_get_command, self.command_env )
def test_move_to_root(self): assert ['/usr/bin', '/sbin'] == Path.move_to_root('/root_dir', ['/root_dir/usr/bin', '/sbin'])