예제 #1
0
 def _find_debuginfo(cls, debug, pkg):
     name = RpmHelper.split_nevra(os.path.basename(pkg))['name']
     debuginfo = '{}-debuginfo'.format(name)
     find = [x for x in debug if RpmHelper.split_nevra(os.path.basename(x))['name'] == debuginfo]
     if find:
         return find[0]
     srpm = RpmHelper.get_info_from_rpm(pkg, rpm.RPMTAG_SOURCERPM)
     debuginfo = '{}-debuginfo'.format(RpmHelper.split_nevra(srpm)['name'])
     find = [x for x in debug if RpmHelper.split_nevra(os.path.basename(x))['name'] == debuginfo]
     if find:
         return find[0]
     return None
예제 #2
0
 def _find_debuginfo(cls, debug, pkg):
     name = RpmHelper.split_nevra(os.path.basename(pkg))['name']
     debuginfo = '{}-debuginfo'.format(name)
     find = [x for x in debug if RpmHelper.split_nevra(os.path.basename(x))['name'] == debuginfo]
     if find:
         return find[0]
     srpm = RpmHelper.get_header_from_rpm(pkg).sourcerpm
     debuginfo = '{}-debuginfo'.format(RpmHelper.split_nevra(srpm)['name'])
     find = [x for x in debug if RpmHelper.split_nevra(os.path.basename(x))['name'] == debuginfo]
     if find:
         return find[0]
     return None
예제 #3
0
    def run_check(cls, results_dir, **kwargs):
        """Compares old and new RPMs using abipkgdiff"""
        # Check if ABI changes occured
        cls.abi_changes = None
        cls.results_dir = os.path.join(results_dir, cls.name)
        os.makedirs(cls.results_dir)
        debug_old, rest_pkgs_old = cls._get_packages_for_abipkgdiff(
            results_store.get_build('old'))
        debug_new, rest_pkgs_new = cls._get_packages_for_abipkgdiff(
            results_store.get_build('new'))
        cmd = [cls.CMD]
        reports = {}
        for pkg in rest_pkgs_old:
            command = list(cmd)
            debug = cls._find_debuginfo(debug_old, pkg)
            if debug:
                command.append('--d1')
                command.append(debug)
            old_name = RpmHelper.split_nevra(os.path.basename(pkg))['name']
            find = [
                x for x in rest_pkgs_new if RpmHelper.split_nevra(
                    os.path.basename(x))['name'] == old_name
            ]
            if not find:
                logger.warning('New version of package %s was not found!',
                               old_name)
                continue
            new_pkg = find[0]
            debug = cls._find_debuginfo(debug_new, new_pkg)
            if debug:
                command.append('--d2')
                command.append(debug)
            command.append(pkg)
            command.append(new_pkg)
            logger.verbose('Package name for ABI comparison %s', old_name)
            output = os.path.join(cls.results_dir, old_name + '.txt')
            try:
                ret_code = ProcessHelper.run_subprocess(command,
                                                        output_file=output)
            except OSError:
                raise CheckerNotFoundError(
                    "Checker '{}' was not found or installed.".format(
                        cls.name))

            if int(ret_code) & cls.ABIDIFF_ERROR and int(
                    ret_code) & cls.ABIDIFF_USAGE_ERROR:
                raise RebaseHelperError(
                    'Execution of {} failed.\nCommand line is: {}'.format(
                        cls.CMD, cmd))
            reports[old_name] = int(ret_code)
        return dict(packages=cls.parse_abi_logs(reports),
                    abi_changes=cls.abi_changes,
                    path=cls.get_checker_output_dir_short())
예제 #4
0
    def prepare(cls, spec, conf):
        """
        Checks if all build dependencies are installed. If not, asks user whether they should be installed.
        If he agrees, installs build dependencies using PolicyKit.

        :param spec: SpecFile object
        """
        req_pkgs = spec.get_requires()
        if not RpmHelper.all_packages_installed(req_pkgs):
            question = '\nSome build dependencies are missing. Do you want to install them now'
            if conf.non_interactive or InputHelper.get_message(question):
                if RpmHelper.install_build_dependencies(spec.get_path(), assume_yes=conf.non_interactive) != 0:
                    raise RebaseHelperError('Failed to install build dependencies')
예제 #5
0
    def prepare(cls, spec, conf):
        """
        Checks if all build dependencies are installed. If not, asks user whether they should be installed.
        If he agrees, installs build dependencies using PolicyKit.

        :param spec: SpecFile object
        """
        req_pkgs = spec.get_requires()
        if not RpmHelper.all_packages_installed(req_pkgs):
            question = '\nSome build dependencies are missing. Do you want to install them now'
            if conf.non_interactive or InputHelper.get_message(question):
                if RpmHelper.install_build_dependencies(spec.get_path(), assume_yes=conf.non_interactive) != 0:
                    raise RebaseHelperError('Failed to install build dependencies')
예제 #6
0
 def run_check(cls, results_dir, **kwargs):
     """Compares old and new RPMs using abipkgdiff"""
     # Check if ABI changes occured
     cls.results_dir = os.path.join(results_dir, cls.name)
     cls.prepare_results_dir()
     debug_old, rest_pkgs_old = cls._get_packages_for_abipkgdiff(results_store.get_build('old'))
     debug_new, rest_pkgs_new = cls._get_packages_for_abipkgdiff(results_store.get_build('new'))
     ret_codes = {}
     for pkg in rest_pkgs_old:
         command = [cls.CMD]
         command_fallback = [cls.CMD]
         debug = cls._find_debuginfo(debug_old, pkg)
         if debug:
             command.append('--d1')
             command.append(debug)
         old_name = RpmHelper.split_nevra(os.path.basename(pkg))['name']
         find = [x for x in rest_pkgs_new if RpmHelper.split_nevra(os.path.basename(x))['name'] == old_name]
         if not find:
             logger.warning('New version of package %s was not found!', old_name)
             continue
         new_pkg = find[0]
         debug = cls._find_debuginfo(debug_new, new_pkg)
         if debug:
             command.append('--d2')
             command.append(debug)
         command.extend([pkg, new_pkg])
         command_fallback.extend([pkg, new_pkg])
         logger.verbose('Package name for ABI comparison %s', old_name)
         output = os.path.join(cls.results_dir, old_name + '.txt')
         for cmd in [command, command_fallback]:
             try:
                 ret_code = ProcessHelper.run_subprocess(cmd, output_file=output)
             except OSError as e:
                 raise CheckerNotFoundError("Checker '{}' was not found or installed.".format(cls.name)) from e
             if int(ret_code) & cls.ABIDIFF_ERROR and int(ret_code) & cls.ABIDIFF_USAGE_ERROR:
                 raise RebaseHelperError(
                     'Execution of {} failed.\nCommand line is: {}'.format(cls.CMD, ' '.join(cmd)))
             if int(ret_code) & cls.ABIDIFF_ERROR:
                 # abipkgdiff might not be able to read the debuginfo, try again without it
                 continue
             break
         ret_codes[old_name] = int(ret_code)
     return dict(packages=cls.parse_abi_logs(ret_codes),
                 abi_changes=any(x & cls.ABIDIFF_ABI_CHANGE for x in ret_codes.values()),
                 abi_incompatible_changes=any(x & cls.ABIDIFF_ABI_INCOMPATIBLE_CHANGE for x in ret_codes.values()),
                 path=cls.get_checker_output_dir_short(),
                 ret_codes=ret_codes)
예제 #7
0
    def download_task_results(cls, session, tasklist, destination):
        """Downloads packages and logs of finished Koji tasks.

        Args:
            session (koji.ClientSession): Active Koji session instance.
            tasklist (list): List of task IDs.
            destination (str): Path where to download files to.

        Returns:
            tuple: List of downloaded RPMs and list of downloaded logs.

        Raises:
            DownloadError: If download failed.

        """
        rpms = []
        logs = []
        for task_id in tasklist:
            logger.info('Downloading packages and logs for task %s', task_id)
            task = session.getTaskInfo(task_id, request=True)
            if task['state'] in [koji.TASK_STATES['FREE'], koji.TASK_STATES['OPEN']]:
                logger.info('Task %s is still running!', task_id)
                continue
            elif task['state'] != koji.TASK_STATES['CLOSED']:
                logger.info('Task %s did not complete successfully!', task_id)
            if task['method'] == 'buildArch':
                tasks = [task]
            elif task['method'] == 'build':
                opts = dict(parent=task_id, method='buildArch', decode=True,
                            state=[koji.TASK_STATES['CLOSED'], koji.TASK_STATES['FAILED']])
                tasks = session.listTasks(opts=opts)
            else:
                logger.info('Task %s is not a build or buildArch task!', task_id)
                continue
            for task in tasks:
                base_path = koji.pathinfo.taskrelpath(task['id'])
                output = session.listTaskOutput(task['id'])
                for filename in output:
                    local_path = os.path.join(destination, filename)
                    download = False
                    fn, ext = os.path.splitext(filename)
                    if ext == '.rpm':
                        if task['state'] != koji.TASK_STATES['CLOSED']:
                            continue
                        if local_path not in rpms:
                            nevra = RpmHelper.split_nevra(fn)
                            # FIXME: multiple arches
                            download = nevra['arch'] in ['noarch', 'x86_64']
                            if download:
                                rpms.append(local_path)
                    else:
                        if local_path not in logs:
                            download = True
                            logs.append(local_path)
                    if download:
                        logger.info('Downloading file %s', filename)
                        url = '/'.join([session.opts['topurl'], 'work', base_path, filename])
                        DownloadHelper.download_file(url, local_path)
        return rpms, logs
예제 #8
0
 def _find_debuginfo(cls, debug, pkg):
     name = RpmHelper.split_nevra(os.path.basename(pkg))['name']
     debuginfo = '{}-debuginfo'.format(name)
     find = [
         x for x in debug
         if RpmHelper.split_nevra(os.path.basename(x))['name'] == debuginfo
     ]
     if find:
         return find[0]
     srpm = RpmHelper.get_info_from_rpm(pkg, rpm.RPMTAG_SOURCERPM)
     debuginfo = '{}-debuginfo'.format(RpmHelper.split_nevra(srpm)['name'])
     find = [
         x for x in debug
         if RpmHelper.split_nevra(os.path.basename(x))['name'] == debuginfo
     ]
     if find:
         return find[0]
     return None
예제 #9
0
    def run_check(cls, results_dir, **kwargs):
        old_headers = [
            RpmHelper.get_header_from_rpm(x)
            for x in results_store.get_old_build().get('rpm', [])
        ]
        new_headers = [
            RpmHelper.get_header_from_rpm(x)
            for x in results_store.get_new_build().get('rpm', [])
        ]
        soname_changes: SonameChanges = collections.defaultdict(
            lambda: collections.defaultdict(list))
        for old in old_headers:
            new = [x for x in new_headers if x.name == old.name]
            if not new:
                logger.warning('New version of package %s was not found!',
                               old.name)
                continue
            else:
                new = new[0]
            old_sonames = cls._get_sonames(old.provides)
            new_sonames = cls._get_sonames(new.provides)
            for old_soname in old_sonames:
                if old_soname in new_sonames:
                    new_sonames.remove(old_soname)
                    continue
                soname = [
                    x for x in new_sonames if os.path.splitext(x)[0] ==
                    os.path.splitext(old_soname)[0]
                ]
                if not soname:
                    soname_changes[old.name]['removed'].append(old_soname)
                else:
                    soname_changes[old.name]['changed'].append({
                        'from': old_soname,
                        'to': soname[0]
                    })
                    new_sonames.remove(soname[0])

            if new_sonames:
                soname_changes[old.name]['added'] = list(new_sonames)

        return dict(soname_changes=soname_changes)
예제 #10
0
    def run_check(cls, results_dir, **kwargs):
        """Compares old and new RPMs using abipkgdiff"""
        # Check if ABI changes occured
        cls.abi_changes = False
        cls.results_dir = os.path.join(results_dir, cls.name)
        os.makedirs(cls.results_dir)
        debug_old, rest_pkgs_old = cls._get_packages_for_abipkgdiff(results_store.get_build('old'))
        debug_new, rest_pkgs_new = cls._get_packages_for_abipkgdiff(results_store.get_build('new'))
        cmd = [cls.CMD]
        reports = {}
        for pkg in rest_pkgs_old:
            command = list(cmd)
            debug = cls._find_debuginfo(debug_old, pkg)
            if debug:
                command.append('--d1')
                command.append(debug)
            old_name = RpmHelper.split_nevra(os.path.basename(pkg))['name']
            find = [x for x in rest_pkgs_new if RpmHelper.split_nevra(os.path.basename(x))['name'] == old_name]
            if not find:
                logger.warning('New version of package %s was not found!', old_name)
                continue
            new_pkg = find[0]
            debug = cls._find_debuginfo(debug_new, new_pkg)
            if debug:
                command.append('--d2')
                command.append(debug)
            command.append(pkg)
            command.append(new_pkg)
            logger.verbose('Package name for ABI comparison %s', old_name)
            output = os.path.join(cls.results_dir, old_name + '.txt')
            try:
                ret_code = ProcessHelper.run_subprocess(command, output_file=output)
            except OSError:
                raise CheckerNotFoundError("Checker '{}' was not found or installed.".format(cls.name))

            if int(ret_code) & cls.ABIDIFF_ERROR and int(ret_code) & cls.ABIDIFF_USAGE_ERROR:
                raise RebaseHelperError('Execution of {} failed.\nCommand line is: {}'.format(cls.CMD, cmd))
            reports[old_name] = int(ret_code)
        return dict(packages=cls.parse_abi_logs(reports),
                    abi_changes=cls.abi_changes,
                    path=cls.get_checker_output_dir_short())
예제 #11
0
    def run_check(cls, results_dir, **kwargs):
        cls.results_dir = os.path.join(results_dir, 'rpminspect-srpm')
        cls.prepare_results_dir()

        result = {
            'path': cls.get_checker_output_dir_short(),
            'files': [],
            'checks': {}
        }
        old_pkg = results_store.get_old_build()['srpm']
        new_pkg = results_store.get_new_build()['srpm']
        name = RpmHelper.split_nevra(os.path.basename(old_pkg))['name']
        outfile, pkg_data = cls.run_rpminspect(cls.results_dir, old_pkg,
                                               new_pkg)
        result['files'].append(os.path.basename(outfile))
        result['checks'][name] = pkg_data

        return result
예제 #12
0
 def _get_rpm_info(cls, name, packages):
     if packages is None:
         return None
     basic_package = sorted(packages)[0]
     return RpmHelper.get_info_from_rpm(basic_package, name)
예제 #13
0
 def _get_rpm_info(cls, name, packages):
     if packages is None:
         return None
     basic_package = sorted(packages)[0]
     return getattr(RpmHelper.get_header_from_rpm(basic_package), name)
예제 #14
0
 def _get_rpm_info(cls, name, packages):
     if packages is None:
         return None
     basic_package = sorted(packages)[0]
     return RpmHelper.get_info_from_rpm(basic_package, name)
예제 #15
0
    def download_task_results(cls, session, tasklist, destination):
        """Downloads packages and logs of finished Koji tasks.

        Args:
            session (koji.ClientSession): Active Koji session instance.
            tasklist (list): List of task IDs.
            destination (str): Path where to download files to.

        Returns:
            tuple: List of downloaded RPMs and list of downloaded logs.

        Raises:
            DownloadError: If download failed.

        """
        rpms = []
        logs = []
        for task_id in tasklist:
            logger.info('Downloading packages and logs for task %s', task_id)
            task = session.getTaskInfo(task_id, request=True)
            if task['state'] in [
                    koji.TASK_STATES['FREE'], koji.TASK_STATES['OPEN']
            ]:
                logger.info('Task %s is still running!', task_id)
                continue
            elif task['state'] != koji.TASK_STATES['CLOSED']:
                logger.info('Task %s did not complete successfully!', task_id)
            if task['method'] == 'buildArch':
                tasks = [task]
            elif task['method'] == 'build':
                opts = dict(parent=task_id,
                            method='buildArch',
                            decode=True,
                            state=[
                                koji.TASK_STATES['CLOSED'],
                                koji.TASK_STATES['FAILED']
                            ])
                tasks = session.listTasks(opts=opts)
            else:
                logger.info('Task %s is not a build or buildArch task!',
                            task_id)
                continue
            for task in tasks:
                base_path = koji.pathinfo.taskrelpath(task['id'])
                output = session.listTaskOutput(task['id'])
                for filename in output:
                    local_path = os.path.join(destination, filename)
                    download = False
                    fn, ext = os.path.splitext(filename)
                    if ext == '.rpm':
                        if task['state'] != koji.TASK_STATES['CLOSED']:
                            continue
                        if local_path not in rpms:
                            nevra = RpmHelper.split_nevra(fn)
                            # FIXME: multiple arches
                            download = nevra['arch'] in ['noarch', 'x86_64']
                            if download:
                                rpms.append(local_path)
                    else:
                        if local_path not in logs:
                            download = True
                            logs.append(local_path)
                    if download:
                        logger.info('Downloading file %s', filename)
                        url = '/'.join([
                            session.opts['topurl'], 'work', base_path, filename
                        ])
                        DownloadHelper.download_file(url, local_path)
        return rpms, logs
예제 #16
0
 def test_split_nevra(self, nevra, name, epoch, version, release, arch):
     assert RpmHelper.split_nevra(nevra) == dict(name=name, epoch=epoch, version=version,
                                                 release=release, arch=arch)
예제 #17
0
 def test_split_nevra(self, nevra, name, epoch, version, release, arch):
     assert RpmHelper.split_nevra(nevra) == dict(name=name,
                                                 epoch=epoch,
                                                 version=version,
                                                 release=release,
                                                 arch=arch)
예제 #18
0
 def test_all_packages_installed_existing(self):
     assert RpmHelper.all_packages_installed(['glibc', 'coreutils']) is True
예제 #19
0
 def test_is_package_installed_non_existing(self):
     assert RpmHelper.is_package_installed('non-existing-package') is False
     assert RpmHelper.is_package_installed('another-non-existing-package') is False
예제 #20
0
 def test_is_package_installed_existing(self):
     assert RpmHelper.is_package_installed('glibc') is True
     assert RpmHelper.is_package_installed('coreutils') is True
예제 #21
0
 def test_is_package_installed_existing(self):
     assert RpmHelper.is_package_installed('glibc') is True
     assert RpmHelper.is_package_installed('coreutils') is True
예제 #22
0
 def test_is_package_installed_non_existing(self):
     assert RpmHelper.is_package_installed('non-existing-package') is False
     assert RpmHelper.is_package_installed(
         'another-non-existing-package') is False
예제 #23
0
 def test_all_packages_installed_existing(self):
     assert RpmHelper.all_packages_installed(['glibc', 'coreutils']) is True
예제 #24
0
 def test_all_packages_installed_one_non_existing(self):
     assert RpmHelper.all_packages_installed(['glibc', 'coreutils', 'non-existing-package']) is False
예제 #25
0
 def _get_rpms(cls, rpm_list):
     rpm_dict = {}
     for rpm_name in rpm_list:
         rpm_dict[RpmHelper.get_info_from_rpm(rpm_name, 'name')] = rpm_name
     return rpm_dict
예제 #26
0
 def test_all_packages_installed_one_non_existing(self):
     assert RpmHelper.all_packages_installed(
         ['glibc', 'coreutils', 'non-existing-package']) is False