Source code for ovirtlago.reposetup

#!/usr/bin/env python
# Copyright 2016 Red Hat, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA
# Refer to the README and COPYING files for full details of the license

import functools
import re
import itertools
import shutil
import logging
import os

from lago import log_utils
from lago.utils import (

from . import utils

LOGGER = logging.getLogger(__name__)
LogTask = functools.partial(log_utils.LogTask, logger=LOGGER)
log_task = functools.partial(log_utils.log_task, logger=LOGGER)

[docs]class RepositoryError(Exception): pass
[docs]class RepositoryMergeError(RepositoryError): pass
[docs]def merge(output_dir, sources): with LogTask('Running repoman'): res = run_command( [ 'repoman', '--option=main.on_empty_source=warn', '--option=store.RPMStore.on_wrong_distro=copy_to_all', '--option=store.RPMStore.rpm_dir=', output_dir, 'add' ] + sources ) if res.code: raise RepositoryMergeError( 'Failed to merge repos %s into %s' % (sources, output_dir) )
[docs]def with_repo_server(func): @functools.wraps(func) def wrapper(*args, **kwargs): with utils.repo_server_context(args[0]): return func(*args, **kwargs) return wrapper
[docs]def _fix_reposync_issues(reposync_out, repo_path): """ Fix for the issue described at:: """ if len(repo_path) == 0 or len(reposync_out) == 0: LOGGER.warning( ( 'unable to run _fix_reposync_issues, no reposync output ' 'or empty repo path.' ) ) return rpm_regex = r'[a-z]{1}[a-zA-Z0-9._\\-]+' wrong_version = re.compile( r'(?P<package_name>' + rpm_regex + r'): \[Errno 256\]' ) wrong_release = re.compile(r'(?P<package_name>' + rpm_regex + r') FAILED') packages = set( itertools.chain( wrong_version.findall(reposync_out), wrong_release.findall(reposync_out) ) ) count = 0 LOGGER.debug( 'detected package errors in reposync output in repo_path:%s: %s', repo_path, ','.join(packages) ) for dirpath, _, filenames in os.walk(repo_path): rpms = ( file for file in filenames if file.endswith('.rpm') and dirpath.startswith(repo_path) ) for rpm in rpms: if any(map(rpm.startswith, packages)): bad_package = os.path.join(dirpath, rpm)'removing conflicting RPM: %s', bad_package) os.unlink(bad_package) count = count + 1 if count > 0: LOGGER.debug( ( 'removed %s conflicting packages, see ' ' ' 'for more details.' ), count )
[docs]def sync_rpm_repository(repo_path, yum_config, repos): lock_path = os.path.join(repo_path, 'repolock') if not os.path.exists(repo_path): os.makedirs(repo_path) reposync_base_cmd = [ 'reposync', '--config=%s' % yum_config, '--download_path=%s' % repo_path, '--newest-only', '--delete', '--cachedir=%s/cache' % repo_path ] with LogTask('Running reposync'): for repo in repos: with LockFile(lock_path, timeout=180): reposync_cmd = reposync_base_cmd + ['--repoid=%s' % repo] ret, out, _ = run_command(reposync_cmd) if not ret: LOGGER.debug('reposync on repo %s: success.' % repo) continue'repo: %s: failed, re-running.', repo) _fix_reposync_issues( reposync_out=out, repo_path=os.path.join(repo_path, repo) ) ret, _, _ = run_command(reposync_cmd) if not ret: continue 'repo: %s: failed. clearing cache and re-running.', repo ) shutil.rmtree('%s/cache' % repo_path) ret, out, err = run_command(reposync_cmd) if ret: LOGGER.error( 'reposync command failed for repoid: %s', repo ) LOGGER.error( 'reposync stdout for repoid: %s: \n%s', repo, out ) LOGGER.error( 'reposync stderr for repoid: %s: \n%s', repo, err ) raise RuntimeError( ( 'Failed to run reposync 3 times ' 'for repoid: %s, aborting.' ) % repo )