Beispiel #1
0
 def _populate_rpm_artifacts(self, modules, repo_id):
     cur = self.conn.cursor()
     try: # pylint: disable=too-many-nested-blocks
         nevras_in_repo = self._get_nevras_in_repo(repo_id)
         to_associate = set()
         for module in modules:
             if 'artifacts' in module:
                 for artifact in module['artifacts']:
                     split_pkg_name = rpm.parse_rpm_name(artifact, default_epoch='0')
                     if split_pkg_name in nevras_in_repo:
                         to_associate.add((nevras_in_repo[split_pkg_name], module['stream_id'],))
                     else:
                         self.logger.info('Nevra %s missing in repo %s', artifact, repo_id)
         if to_associate:
             execute_values(cur,
                            """select pkg_id, stream_id from module_rpm_artifact
                                inner join (values %s) t(pkg_id, stream_id)
                                using (pkg_id, stream_id)
                            """, list(to_associate), page_size=len(to_associate))
             for r_pkg_id, r_stream_id in cur.fetchall():
                 to_associate.remove((r_pkg_id, r_stream_id,))
         if to_associate:
             execute_values(cur,
                            """insert into module_rpm_artifact (pkg_id, stream_id)
                               values %s""",
                            list(to_associate), page_size=len(to_associate))
         self.conn.commit()
     except Exception: # pylint: disable=broad-except
         self.logger.exception("Failure while populating rpm artifacts")
         self.conn.rollback()
     finally:
         cur.close()
Beispiel #2
0
 def test_parse_5_epoch(self):
     """Test parsing valid rpm name with no epoch and specify default epoch"""
     name, epoch, ver, rel, arch = rpm.parse_rpm_name('389-ds-base-1.3.7.8-1.fc27.src.rpm', default_epoch="1")
     self.assertEqual("1", epoch)
     self.assertEqual("389-ds-base", name)
     self.assertEqual("1.3.7.8", ver)
     self.assertEqual("1.fc27", rel)
     self.assertEqual("src", arch)
Beispiel #3
0
 def test_parse_4_epoch(self):
     """Test parsing valid rpm name with epoch preceeding version."""
     name, epoch, ver, rel, arch = rpm.parse_rpm_name('perl-DBD-Pg-2:3.7.4-2.module+el8+2517+b1471f1c.x86_64')
     self.assertEqual("2", epoch)
     self.assertEqual("perl-DBD-Pg", name)
     self.assertEqual("3.7.4", ver)
     self.assertEqual("2.module+el8+2517+b1471f1c", rel)
     self.assertEqual("x86_64", arch)
Beispiel #4
0
 def test_parse_3_epoch(self):
     """Test parsing valid rpm name with epoch preceeding package name."""
     name, epoch, ver, rel, arch = rpm.parse_rpm_name('3:Agda-2.5.2-9.fc27.x86_64.rpm')
     self.assertEqual("3", epoch)
     self.assertEqual("Agda", name)
     self.assertEqual("2.5.2", ver)
     self.assertEqual("9.fc27", rel)
     self.assertEqual("x86_64", arch)
Beispiel #5
0
 def test_parse_2_rpm(self):
     """Test parsing valid rpm name."""
     name, epoch, ver, rel, arch = rpm.parse_rpm_name('Agda-2.5.2-9.fc27.x86_64.rpm')
     self.assertEqual(None, epoch)
     self.assertEqual("Agda", name)
     self.assertEqual("2.5.2", ver)
     self.assertEqual("9.fc27", rel)
     self.assertEqual("x86_64", arch)
Beispiel #6
0
 def test_parse_1_srpm(self):
     """Test parsing valid srpm name."""
     name, epoch, ver, rel, arch = rpm.parse_rpm_name('389-ds-base-1.3.7.8-1.fc27.src.rpm')
     self.assertEqual(None, epoch)
     self.assertEqual("389-ds-base", name)
     self.assertEqual("1.3.7.8", ver)
     self.assertEqual("1.fc27", rel)
     self.assertEqual("src", arch)
Beispiel #7
0
 def test_parse_6_invalid_rpmname(self):
     """Test parsing invalid rpm name."""
     with self.assertRaises(rpm.RPMParseException):
         rpm.parse_rpm_name('foo')
     with self.assertRaises(rpm.RPMParseException):
         rpm.parse_rpm_name('foo.rpm')
     with self.assertRaises(rpm.RPMParseException):
         rpm.parse_rpm_name('foo-1.3.x86.rpm')
     with self.assertRaises(rpm.RPMParseException):
         rpm.parse_rpm_name('2:389-ds-base-4:1.3.7.8-1.fc27.src.rpm')
Beispiel #8
0
 def test_split_packagename(self):
     """Test splitting package name into N,E,V,R,A."""
     pkg_name = "bash-0:4.2.46-20.el7_2.x86_64.rpm"
     name, epoch, version, release, arch = rpm.parse_rpm_name(pkg_name, default_epoch='0')
     assert name == "bash"
     assert epoch == "0"
     assert version == "4.2.46"
     assert release == "20.el7_2"
     assert arch == "x86_64"
Beispiel #9
0
 def _get_source_package_id(self, pkg):
     source_package_id = None
     if pkg["srpm"]:
         name, epoch, ver, rel, arch = rpm.parse_rpm_name(
             pkg["srpm"], default_epoch=pkg["epoch"])
         name_id = self.package_name_map[name]
         evr_id = self.evr_map[(epoch, ver, rel)]
         arch_id = self.arch_map[arch]
         source_package_id = self.package_map[(name_id, evr_id, arch_id)]
     return source_package_id
Beispiel #10
0
 def _get_source_packages(packages):
     unique_source_packages = set()
     for pkg in packages:
         if pkg["srpm"]:
             unique_source_packages.add(rpm.parse_rpm_name(pkg["srpm"], default_epoch=pkg["epoch"],
                                                           raise_exception=True))
     source_packages = []
     for name, epoch, ver, rel, arch in unique_source_packages:
         source_packages.append(dict(name=name, epoch=epoch, ver=ver, rel=rel, arch=arch,
                                     srpm=None, summary=None, description=None))
     return source_packages
Beispiel #11
0
 def test_parse_7_invalid_noraise(self):
     """Test parsing invalid rpm name."""
     for name in [
             'foo',
             'foo.rpm',
             'foo-1.3.x86.rpm',
             '2:389-ds-base-4:1.3.7.8-1.fc27.src.rpm',
     ]:
         name, epoch, ver, rel, arch = rpm.parse_rpm_name(name)
         self.assertEqual(None, epoch)
         self.assertEqual("", name)
         self.assertEqual("", ver)
         self.assertEqual("", rel)
         self.assertEqual("", arch)
Beispiel #12
0
    def process_list(self, data):
        """ Processes whole package_list and returns info. """
        packages = data.get("package_list")
        response = {"package_list": {}}

        db_connection = self.db_pool.get_connection()
        with db_connection.get_cursor() as cursor:
            for package in packages:
                name, epoch, version, release, arch = parse_rpm_name(package, default_epoch='0')
                cursor.execute("""select distinct p.summary, p.description,
                                  pn2.name, evr2.epoch, evr2.version, evr2.release, a2.name,
                                  cs.label, cs.name, a.name, r.releasever,
                                  pn3.name
                                  from package p
                                  left join package_name pn on pn.id = p.name_id 
                                  left join arch ap on p.arch_id = ap.id 
                                  left join evr on p.evr_id = evr.id 
                                  left join package p2 on p2.id = p.source_package_id 
                                  left join package_name pn2 on p2.name_id = pn2.id
                                  left join evr evr2 on p2.evr_id = evr2.id 
                                  left join arch a2 on p2.arch_id = a2.id
                                  left join pkg_repo pr on pr.pkg_id = p.id 
                                  left join repo r on r.id = pr.repo_id 
                                  left join content_set cs on cs.id = r.content_set_id 
                                  left join arch a on a.id = r.basearch_id
                                  left join package p3 on p3.source_package_id = p.id
                                  left join package_name pn3 on p3.name_id = pn3.id
                                  where pn.name = '%s' 
                                  and ap.name = '%s' 
                                  and evr.epoch = '%s' 
                                  and evr.version = '%s' 
                                  and evr.release = '%s'
                               """ % (name, arch, epoch, version, release))
                query = cursor.fetchall()
                pkgs = {}
                pkgs[package] = {}
                for item in query:
                    pkgs[package] = {"summary": item[PACKAGE_SUMMARY],
                                     "description": item[PACKAGE_DESCRIPTION],
                                     "source_package": join_rpm_name(item[SOURCE_PACKAGE_NAME],
                                                                     item[SOURCE_PACKAGE_EPOCH],
                                                                     item[SOURCE_PACKAGE_VERSION],
                                                                     item[SOURCE_PACKAGE_RELEASE],
                                                                     item[SOURCE_PACKAGE_ARCH]),
                                     "repositories": self._build_repositories(query),
                                     "binary_package_list": self._build_binary_packages(query)
                                    }
                response["package_list"].update(pkgs)
        self.db_pool.return_connection(db_connection)
        return response
Beispiel #13
0
 def process_input_packages(self, data: dict) -> (dict, dict):
     """Parse input NEVRAs and filter out unknown (or without updates) package names."""
     latest_only = data.get("latest_only", False)
     packages_to_process = filter_package_list(
         data.get('package_list', None), latest_only)
     filtered_packages_to_process = {}
     update_list = {}
     if packages_to_process is not None:
         for pkg in packages_to_process:
             update_list[pkg] = {}
             name, epoch, ver, rel, arch = parse_rpm_name(pkg,
                                                          default_epoch='0')
             if name in self.db_cache.packagename2id:
                 if self.db_cache.packagename2id[
                         name] in self.db_cache.updates_index:
                     filtered_packages_to_process[pkg] = {
                         'parsed_nevra': (name, epoch, ver, rel, arch)
                     }
     return filtered_packages_to_process, update_list
Beispiel #14
0
 def _state_import_check(self, item):
     """Check if state is in DB, return None if it's up to date and row to import otherwise."""
     if item["version"] <= self.oval_state_version_map.get(item["id"], -1):
         return None
     evr_id = evr_operation_id = None
     if item['evr'] is not None:
         # FIXME: as an input to common.rpm.parse_rpm_name, we don't have function to parse evr only
         fake_nevra = f"pn-{item['evr']}.noarch"
         _, epoch, version, release, _ = parse_rpm_name(fake_nevra)
         evr_id = self.evr_map.get((epoch, version, release))
         if not evr_id:
             self.logger.warning("EVR not found: %s, %s, %s", epoch, version, release)
             return None
     if item["evr_operation"] is not None:
         evr_operation_id = self.evr_operation_map.get(item["evr_operation"])
         if not evr_operation_id:
             self.logger.warning("Unsupported EVR operation: %s", item["evr_operation"])
             return None
     return item["id"], evr_id, evr_operation_id, item["version"]
Beispiel #15
0
 def _populate_states(self, oval_file_id, states):
     query = """insert into oval_rpminfo_state (oval_id, evr_id, evr_operation_id, version) values %s
                on conflict (oval_id) do update set
                evr_id = EXCLUDED.evr_id, evr_operation_id = EXCLUDED.evr_operation_id,
                version = EXCLUDED.version
                returning id, oval_id, version"""
     # Parse EVR first
     for state in states:
         if state['evr'] is not None:
             # FIXME: as an input to common.rpm.parse_rpm_name, we don't have function to parse evr only
             fake_nevra = f"pn-{state['evr']}.noarch"
             _, epoch, version, release, _ = parse_rpm_name(fake_nevra)
             state['evr'] = (epoch, version, release)
     # Populate missing EVRs
     self.package_store.populate_evrs(
         {state['evr']
          for state in states if state['evr'] is not None})
     self._populate_data("states", states, self._state_import_check, query,
                         self._state_refresh_maps)
     self._populate_associations("file", "states", "file_id",
                                 "rpminfo_state_id",
                                 "oval_file_rpminfo_state", oval_file_id,
                                 states, self.oval_state_map)
     for state in states:
         if state["arch_operation"] is not None and state[
                 "arch_operation"] not in self.SUPPORTED_ARCH_OPERATIONS:
             self.logger.warning("Unsupported arch operation: %s",
                                 state["arch_operation"])
             continue
         if state[
                 "id"] in self.oval_state_map:  # Make sure state is imported
             # Simplified logic, can contain any regex but RH oval files contains only logical OR
             archs = []
             if state["arch"] is not None:
                 archs.extend([{
                     "id": arch
                 } for arch in state["arch"].split("|")])
             self._populate_associations("state", "archs",
                                         "rpminfo_state_id", "arch_id",
                                         "oval_rpminfo_state_arch",
                                         self.oval_state_map[state["id"]],
                                         archs, self.package_store.arch_map)
Beispiel #16
0
    def process_list(self, api_version, data):  # pylint: disable=unused-argument
        """
        Returns package details.

        :param data: json request parsed into data structure

        :returns: json response with package details
        """
        packages = data.get('package_list', None)
        # By default, don't include third party data
        want_third_party = data.get('third_party', False)

        packagelist = {}
        if not packages:
            return packagelist

        for pkg in packages:
            packagedata = packagelist.setdefault(pkg, {})
            is_third_party = False

            name, epoch, ver, rel, arch = parse_rpm_name(pkg,
                                                         default_epoch='0')
            if name in self.cache.packagename2id \
                    and (epoch, ver, rel) in self.cache.evr2id \
                    and arch in self.cache.arch2id:
                name_id = self.cache.packagename2id[name]
                evr_id = self.cache.evr2id[(epoch, ver, rel)]
                arch_id = self.cache.arch2id[arch]
                pkg_id = self.cache.nevra2pkgid.get((name_id, evr_id, arch_id),
                                                    None)
                if pkg_id:
                    pkg_detail = self.cache.package_details[pkg_id]
                    packagedata['summary'] = self.cache.strings.get(
                        pkg_detail[PKG_SUMMARY_ID], None)
                    packagedata['description'] = self.cache.strings.get(
                        pkg_detail[PKG_DESC_ID], None)
                    packagedata['source_package'] = self._get_source_package(
                        pkg_detail)
                    packagedata['repositories'] = []
                    packagedata[
                        'package_list'] = self._get_built_binary_packages(
                            pkg_id)
                    if pkg_id in self.cache.pkgid2repoids:
                        for repo_id in self.cache.pkgid2repoids[pkg_id]:
                            repodetail = self.cache.repo_detail[repo_id]
                            is_third_party = is_third_party or bool(
                                repodetail[REPO_THIRD_PARTY])
                            repodata = {
                                'label':
                                repodetail[REPO_LABEL],
                                'name':
                                repodetail[REPO_NAME],
                                'basearch':
                                utils.none2empty(repodetail[REPO_BASEARCH]),
                                'releasever':
                                utils.none2empty(repodetail[REPO_RELEASEVER]),
                            }
                            packagedata['repositories'].append(repodata)

            # If the package is third party, then remove it from result
            if not want_third_party and is_third_party:
                del packagelist[pkg]

        response = {'package_list': packagelist}

        return response