def del_media(name, root, logger, ignore_error=False): try: monitor(['urpmi.removemedia', '--urpmi-root', root, name], logger=logger) except CalledProcessError: if not ignore_error: raise
def rsync(src, dst, completion_start=0, completion_end=0, set_completion=lambda *args: None, logger=None, rootfs=None, options=[]): if rootfs: src = rootfs + src dst = rootfs + dst # # This is used to get the total number of files created by rsync # out = check_output(['rsync', '-a', '--stats', '--dry-run', src, dst]) out = out.decode() # whatever the local used, it seems that rsync uses comma as # thousand seperator. pattern = re.compile('Total file size: ([0-9,]+)') match = pattern.search(out) total = int(match.group(1).replace(',', '')) if total == 0: set_completion(completion_end) return def stdout_handler(p, line, data): bytes = 0 if data is None else data bytes += int(line) delta = completion_end - completion_start set_completion(completion_start + int(delta * bytes / total)) return bytes # # Don't log rsync's output since it's not really interesting for # the user as we report the number of bytes actually transferred # for reporting progression. But log the command run. # cmd = ['rsync'] + options + ['-a', '--out-format=%b', src, dst] logger.debug('running: %s' % ' '.join(cmd)) monitor(cmd, logger=None, stdout_handler=stdout_handler)
def install(pkgs, root=None, completion_start=0, completion_end=0, set_completion=lambda *args: None, logger=None, options=[]): pacman_opts = ['--needed'] + options def stdout_handler(p, line, data): if data is None: data = (0, 0, re.compile(r'Packages \(([0-9]+)\)')) count, total, pattern = data match = pattern.search(line) if not match: pass elif total == 0: total = int(match.group(1)) * 2 pattern = re.compile(r'downloading |(re)?installing ') else: if not line.startswith('downloading '): count = max(count, total / 2) count += 1 delta = completion_end - completion_start set_completion(completion_start + delta * count / total) return (count, total, pattern) if pkgs: if root: monitor(['pacstrap', root] + pacman_opts + pkgs, logger=logger, stdout_handler=stdout_handler) else: monitor(['pacman'] + pkgs + pacman_opts, logger=logger, stdout_handler=stdout_handler) # Make sure to set completion level specially when packages are # already installed (and --needed options is used). set_completion(completion_end)
def install(pkgs, root=None, completion_start=0, completion_end=0, set_completion=lambda *args: None, logger=None, options=[]): urpmi_opts = _urpmi_extra_options urpmi_opts += ["--auto", "--downloader=curl", "--curl-options='-s'"] urpmi_opts += ["--rsync-options=-q"] urpmi_opts += options def stdout_handler(p, line, data): pattern = re.compile(r'\s+([0-9]+)/([0-9]+): ') match = pattern.match(line) if match: count, total = map(int, match.group(1, 2)) delta = completion_end - completion_start set_completion(completion_start + delta * count / total) if pkgs: if not root: cmd = ['urpmi'] + urpmi_opts + pkgs monitor(cmd, logger=logger, stdout_hander=stdout_hander) else: cmd = ['urpmi', '--urpmi-root', root] + urpmi_opts + pkgs monitor_chroot(root, cmd, chrooter=None, logger=logger, stdout_handler=stdout_handler) # Make sure to set completion level specially in the case where the # packages are already installed. set_completion(completion_end)
def add_repository(repo, root, logger): cmd = ['urpmi.addmedia', '--urpmi-root', root] cmd += ['--curl', '--curl-options=-s', '--rsync-options=-q'] cmd += ['--distrib', repo] monitor(cmd, logger=logger)
def urpmi_init(repositories, root, logger=lambda *args: None): if repositories: # # One or more distributions have been specified, configure the # rootfs in order to use the first good one. For now we don't # try to configure several repositories since it seems that # urpmi(1) doesn't like it, specially when the cdrom comes at # first... # # If the installation step has been # restarted the config file already exists. # monitor(['rm', '-f', root + '/etc/urpmi/urpmi.cfg'], logger=logger) for repo in repositories: try: # don't log any errors since they're not fatal. add_repository(repo, root, None) except CalledProcessError: logger.debug('failed to register repository: %s, skipping...' % repo) else: logger.info(_('using repository %s') % repo) logger.debug('active medias:') monitor( ['urpmq', '--urpmi-root', root, '--list-media', 'active'], logger) break # For now let the 'installation' step failed if none of the # repos has been registered. else: # # If no repository has been specified, we use the host urpmi # setup but don't import any passwords to avoid leaking # secrets. # logger.info(_('Using urpmi configuration from host')) # The directory can exist already, when retrying an # installation. if not os.path.exists(os.path.join(root, 'etc/urpmi')): os.makedirs(os.path.join(root, 'etc/urpmi/')) monitor( ["cp", '/etc/urpmi/urpmi.cfg', os.path.join(root, 'etc/urpmi/')], logger=logger) logger.info(_('Retrieving repository public keys')) monitor( ['urpmi.update', '--urpmi-root', root, '-a', '--force-key', '-q'], logger=logger) # # Import the user's options as default urpmi options for the # target system. # if settings.Urpmi.options: logger.debug('Adding user options in target urpmi.cfg: %s', settings.Urpmi.options) _urpmi_config_set_options(settings.Urpmi.options.split(), root + '/etc/urpmi/urpmi.cfg')
def _monitor(self, args, **kwargs): if "logger" not in kwargs: kwargs["logger"] = self.logger monitor(args, **kwargs)