From 34c2d96b3685a927749536017add6538578fb2df Mon Sep 17 00:00:00 2001 From: Ales Raszka Date: Thu, 28 Feb 2019 10:59:49 +0100 Subject: [PATCH 1/6] featurefmt: Extract PotentialNamespace PotentialNamespace is feature namespace extracted while detecting features in layer. It will server for special feature detector. The current detectors return empty namespace. --- database/models.go | 21 +- database/pgsql/complex_test.go | 2 +- database/pgsql/feature_test.go | 6 +- database/pgsql/testutil.go | 10 +- ext/featurefmt/apk/apk_test.go | 22 +- ext/featurefmt/dpkg/dpkg.go | 4 +- ext/featurefmt/dpkg/dpkg_test.go | 312 ++++++++-------- ext/featurefmt/rpm/rpm.go | 4 +- ext/featurefmt/rpm/rpm_test.go | 610 +++++++++++++++---------------- 9 files changed, 496 insertions(+), 495 deletions(-) diff --git a/database/models.go b/database/models.go index 9abba3c0..ebbeb658 100644 --- a/database/models.go +++ b/database/models.go @@ -166,22 +166,23 @@ func NewNamespace(name string, versionFormat string) *Namespace { // dpkg is the version format of the installer package manager, which in this // case could be dpkg or apk. type Feature struct { - Name string `json:"name"` - Version string `json:"version"` - VersionFormat string `json:"versionFormat"` - Type FeatureType `json:"type"` + Name string `json:"name"` + Version string `json:"version"` + VersionFormat string `json:"versionFormat"` + Type FeatureType `json:"type"` + PotentialNamespace Namespace `json:"potentialNamespace"` } -func NewFeature(name string, version string, versionFormat string, featureType FeatureType) *Feature { - return &Feature{name, version, versionFormat, featureType} +func NewFeature(name string, version string, versionFormat string, featureType FeatureType, namespace Namespace) *Feature { + return &Feature{name, version, versionFormat, featureType, namespace} } -func NewBinaryPackage(name string, version string, versionFormat string) *Feature { - return &Feature{name, version, versionFormat, BinaryPackage} +func NewBinaryPackage(name string, version string, versionFormat string, namespace Namespace) *Feature { + return &Feature{name, version, versionFormat, BinaryPackage, namespace} } -func NewSourcePackage(name string, version string, versionFormat string) *Feature { - return &Feature{name, version, versionFormat, SourcePackage} +func NewSourcePackage(name string, version string, versionFormat string, namespace Namespace) *Feature { + return &Feature{name, version, versionFormat, SourcePackage, namespace} } // NamespacedFeature is a feature with determined namespace and can be affected diff --git a/database/pgsql/complex_test.go b/database/pgsql/complex_test.go index 5b42ccfa..28e14479 100644 --- a/database/pgsql/complex_test.go +++ b/database/pgsql/complex_test.go @@ -65,7 +65,7 @@ func testGenRandomVulnerabilityAndNamespacedFeature(t *testing.T, store database for i := 0; i < numFeatures; i++ { version := rand.Intn(numFeatures) - features[i] = *database.NewSourcePackage(featureName, strconv.Itoa(version), featureVersionFormat) + features[i] = *database.NewSourcePackage(featureName, strconv.Itoa(version), featureVersionFormat, database.Namespace{}) nsFeatures[i] = database.NamespacedFeature{ Namespace: namespace, Feature: features[i], diff --git a/database/pgsql/feature_test.go b/database/pgsql/feature_test.go index 574bfeab..4f546c91 100644 --- a/database/pgsql/feature_test.go +++ b/database/pgsql/feature_test.go @@ -28,7 +28,7 @@ func TestPersistFeatures(t *testing.T) { defer cleanup() invalid := database.Feature{} - valid := *database.NewBinaryPackage("mount", "2.31.1-0.4ubuntu3.1", "dpkg") + valid := *database.NewBinaryPackage("mount", "2.31.1-0.4ubuntu3.1", "dpkg", database.Namespace{}) // invalid require.NotNil(t, tx.PersistFeatures([]database.Feature{invalid})) @@ -45,9 +45,9 @@ func TestPersistNamespacedFeatures(t *testing.T) { defer cleanup() // existing features - f1 := database.NewSourcePackage("ourchat", "0.5", "dpkg") + f1 := database.NewSourcePackage("ourchat", "0.5", "dpkg", database.Namespace{}) // non-existing features - f2 := database.NewSourcePackage("fake!", "", "") + f2 := database.NewSourcePackage("fake!", "", "", database.Namespace{}) // exising namespace n1 := database.NewNamespace("debian:7", "dpkg") // non-existing namespace diff --git a/database/pgsql/testutil.go b/database/pgsql/testutil.go index abfb743a..475a1b43 100644 --- a/database/pgsql/testutil.go +++ b/database/pgsql/testutil.go @@ -38,11 +38,11 @@ import ( // int keys must be the consistent with the database ID. var ( realFeatures = map[int]database.Feature{ - 1: {"ourchat", "0.5", "dpkg", "source"}, - 2: {"openssl", "1.0", "dpkg", "source"}, - 3: {"openssl", "2.0", "dpkg", "source"}, - 4: {"fake", "2.0", "rpm", "source"}, - 5: {"mount", "2.31.1-0.4ubuntu3.1", "dpkg", "binary"}, + 1: {"ourchat", "0.5", "dpkg", "source", database.Namespace{}}, + 2: {"openssl", "1.0", "dpkg", "source", database.Namespace{}}, + 3: {"openssl", "2.0", "dpkg", "source", database.Namespace{}}, + 4: {"fake", "2.0", "rpm", "source", database.Namespace{}}, + 5: {"mount", "2.31.1-0.4ubuntu3.1", "dpkg", "binary", database.Namespace{}}, } realNamespaces = map[int]database.Namespace{ diff --git a/ext/featurefmt/apk/apk_test.go b/ext/featurefmt/apk/apk_test.go index 72ec5098..ef9fcb24 100644 --- a/ext/featurefmt/apk/apk_test.go +++ b/ext/featurefmt/apk/apk_test.go @@ -28,17 +28,17 @@ func TestAPKFeatureDetection(t *testing.T) { "valid case", map[string]string{"lib/apk/db/installed": "apk/testdata/valid"}, []database.Feature{ - {"apk-tools", "2.6.7-r0", "dpkg", "binary"}, - {"musl", "1.1.14-r10", "dpkg", "binary"}, - {"libssl1.0", "1.0.2h-r1", "dpkg", "binary"}, - {"libc-utils", "0.7-r0", "dpkg", "binary"}, - {"busybox", "1.24.2-r9", "dpkg", "binary"}, - {"scanelf", "1.1.6-r0", "dpkg", "binary"}, - {"alpine-keys", "1.1-r0", "dpkg", "binary"}, - {"libcrypto1.0", "1.0.2h-r1", "dpkg", "binary"}, - {"zlib", "1.2.8-r2", "dpkg", "binary"}, - {"musl-utils", "1.1.14-r10", "dpkg", "binary"}, - {"alpine-baselayout", "3.0.3-r0", "dpkg", "binary"}, + {"apk-tools", "2.6.7-r0", "dpkg", "binary", database.Namespace{}}, + {"musl", "1.1.14-r10", "dpkg", "binary", database.Namespace{}}, + {"libssl1.0", "1.0.2h-r1", "dpkg", "binary", database.Namespace{}}, + {"libc-utils", "0.7-r0", "dpkg", "binary", database.Namespace{}}, + {"busybox", "1.24.2-r9", "dpkg", "binary", database.Namespace{}}, + {"scanelf", "1.1.6-r0", "dpkg", "binary", database.Namespace{}}, + {"alpine-keys", "1.1-r0", "dpkg", "binary", database.Namespace{}}, + {"libcrypto1.0", "1.0.2h-r1", "dpkg", "binary", database.Namespace{}}, + {"zlib", "1.2.8-r2", "dpkg", "binary", database.Namespace{}}, + {"musl-utils", "1.1.14-r10", "dpkg", "binary", database.Namespace{}}, + {"alpine-baselayout", "3.0.3-r0", "dpkg", "binary", database.Namespace{}}, }, }, } { diff --git a/ext/featurefmt/dpkg/dpkg.go b/ext/featurefmt/dpkg/dpkg.go index e68f7be1..829b3813 100644 --- a/ext/featurefmt/dpkg/dpkg.go +++ b/ext/featurefmt/dpkg/dpkg.go @@ -123,7 +123,7 @@ func parseDpkgDB(scanner *bufio.Scanner) (binaryPackage *database.Feature, sourc if err := versionfmt.Valid(dpkg.ParserName, version); err != nil { log.WithError(err).WithFields(log.Fields{"name": name, "version": version}).Warning("skipped unparseable package") } else { - binaryPackage = &database.Feature{name, version, dpkg.ParserName, database.BinaryPackage} + binaryPackage = &database.Feature{name, version, dpkg.ParserName, database.BinaryPackage, database.Namespace{}} } } @@ -145,7 +145,7 @@ func parseDpkgDB(scanner *bufio.Scanner) (binaryPackage *database.Feature, sourc if err := versionfmt.Valid(dpkg.ParserName, version); err != nil { log.WithError(err).WithFields(log.Fields{"name": name, "version": version}).Warning("skipped unparseable package") } else { - sourcePackage = &database.Feature{sourceName, sourceVersion, dpkg.ParserName, database.SourcePackage} + sourcePackage = &database.Feature{sourceName, sourceVersion, dpkg.ParserName, database.SourcePackage, database.Namespace{}} } } diff --git a/ext/featurefmt/dpkg/dpkg_test.go b/ext/featurefmt/dpkg/dpkg_test.go index 6bfb9bc7..7039e3f9 100644 --- a/ext/featurefmt/dpkg/dpkg_test.go +++ b/ext/featurefmt/dpkg/dpkg_test.go @@ -28,168 +28,168 @@ func TestListFeatures(t *testing.T) { "valid status file", map[string]string{"var/lib/dpkg/status": "dpkg/testdata/valid"}, []database.Feature{ - {"libapt-pkg5.0", "1.6.3ubuntu0.1", "dpkg", "binary"}, - {"perl-base", "5.26.1-6ubuntu0.2", "dpkg", "binary"}, - {"libmount1", "2.31.1-0.4ubuntu3.1", "dpkg", "binary"}, - {"perl", "5.26.1-6ubuntu0.2", "dpkg", "source"}, - {"libgnutls30", "3.5.18-1ubuntu1", "dpkg", "binary"}, - {"liblzma5", "5.2.2-1.3", "dpkg", "binary"}, - {"ncurses-bin", "6.1-1ubuntu1.18.04", "dpkg", "binary"}, - {"lsb", "9.20170808ubuntu1", "dpkg", "source"}, - {"sed", "4.4-2", "dpkg", "source"}, - {"libsystemd0", "237-3ubuntu10.3", "dpkg", "binary"}, - {"procps", "2:3.3.12-3ubuntu1.1", "dpkg", "source"}, - {"login", "1:4.5-1ubuntu1", "dpkg", "binary"}, - {"libunistring2", "0.9.9-0ubuntu1", "dpkg", "binary"}, - {"sed", "4.4-2", "dpkg", "binary"}, - {"libselinux", "2.7-2build2", "dpkg", "source"}, - {"libseccomp", "2.3.1-2.1ubuntu4", "dpkg", "source"}, - {"libss2", "1.44.1-1", "dpkg", "binary"}, - {"liblz4-1", "0.0~r131-2ubuntu3", "dpkg", "binary"}, - {"libsemanage1", "2.7-2build2", "dpkg", "binary"}, - {"libtasn1-6", "4.13-2", "dpkg", "source"}, - {"libzstd1", "1.3.3+dfsg-2ubuntu1", "dpkg", "binary"}, - {"fdisk", "2.31.1-0.4ubuntu3.1", "dpkg", "binary"}, - {"xz-utils", "5.2.2-1.3", "dpkg", "source"}, - {"lsb-base", "9.20170808ubuntu1", "dpkg", "binary"}, - {"libpam-modules-bin", "1.1.8-3.6ubuntu2", "dpkg", "binary"}, - {"dash", "0.5.8-2.10", "dpkg", "binary"}, - {"gnupg2", "2.2.4-1ubuntu1.1", "dpkg", "source"}, - {"libfdisk1", "2.31.1-0.4ubuntu3.1", "dpkg", "binary"}, - {"lz4", "0.0~r131-2ubuntu3", "dpkg", "source"}, - {"libpam0g", "1.1.8-3.6ubuntu2", "dpkg", "binary"}, - {"libc-bin", "2.27-3ubuntu1", "dpkg", "binary"}, - {"libcap-ng", "0.7.7-3.1", "dpkg", "source"}, - {"libcom-err2", "1.44.1-1", "dpkg", "binary"}, - {"libudev1", "237-3ubuntu10.3", "dpkg", "binary"}, - {"debconf", "1.5.66", "dpkg", "binary"}, - {"tar", "1.29b-2", "dpkg", "binary"}, - {"diffutils", "1:3.6-1", "dpkg", "source"}, - {"gcc-8", "8-20180414-1ubuntu2", "dpkg", "source"}, - {"e2fsprogs", "1.44.1-1", "dpkg", "source"}, - {"bzip2", "1.0.6-8.1", "dpkg", "source"}, - {"diffutils", "1:3.6-1", "dpkg", "binary"}, - {"grep", "3.1-2", "dpkg", "binary"}, - {"libgcc1", "1:8-20180414-1ubuntu2", "dpkg", "binary"}, - {"bash", "4.4.18-2ubuntu1", "dpkg", "source"}, - {"libtinfo5", "6.1-1ubuntu1.18.04", "dpkg", "binary"}, - {"procps", "2:3.3.12-3ubuntu1.1", "dpkg", "binary"}, - {"bzip2", "1.0.6-8.1", "dpkg", "binary"}, - {"init-system-helpers", "1.51", "dpkg", "binary"}, - {"libncursesw5", "6.1-1ubuntu1.18.04", "dpkg", "binary"}, - {"init-system-helpers", "1.51", "dpkg", "source"}, - {"libpam-modules", "1.1.8-3.6ubuntu2", "dpkg", "binary"}, - {"libext2fs2", "1.44.1-1", "dpkg", "binary"}, - {"libacl1", "2.2.52-3build1", "dpkg", "binary"}, - {"hostname", "3.20", "dpkg", "binary"}, - {"libgpg-error", "1.27-6", "dpkg", "source"}, - {"acl", "2.2.52-3build1", "dpkg", "source"}, - {"apt", "1.6.3ubuntu0.1", "dpkg", "binary"}, - {"base-files", "10.1ubuntu2.2", "dpkg", "source"}, - {"libgpg-error0", "1.27-6", "dpkg", "binary"}, - {"audit", "1:2.8.2-1ubuntu1", "dpkg", "source"}, - {"hostname", "3.20", "dpkg", "source"}, - {"gzip", "1.6-5ubuntu1", "dpkg", "binary"}, - {"libc6", "2.27-3ubuntu1", "dpkg", "binary"}, - {"libnettle6", "3.4-1", "dpkg", "binary"}, - {"sysvinit-utils", "2.88dsf-59.10ubuntu1", "dpkg", "binary"}, - {"debianutils", "4.8.4", "dpkg", "source"}, - {"libstdc++6", "8-20180414-1ubuntu2", "dpkg", "binary"}, - {"libsepol", "2.7-1", "dpkg", "source"}, - {"libpcre3", "2:8.39-9", "dpkg", "binary"}, - {"libuuid1", "2.31.1-0.4ubuntu3.1", "dpkg", "binary"}, - {"systemd", "237-3ubuntu10.3", "dpkg", "source"}, - {"tar", "1.29b-2", "dpkg", "source"}, - {"ubuntu-keyring", "2018.02.28", "dpkg", "source"}, - {"passwd", "1:4.5-1ubuntu1", "dpkg", "binary"}, - {"sysvinit", "2.88dsf-59.10ubuntu1", "dpkg", "source"}, - {"libidn2-0", "2.0.4-1.1build2", "dpkg", "binary"}, - {"libhogweed4", "3.4-1", "dpkg", "binary"}, - {"db5.3", "5.3.28-13.1ubuntu1", "dpkg", "source"}, - {"sensible-utils", "0.0.12", "dpkg", "source"}, - {"dpkg", "1.19.0.5ubuntu2", "dpkg", "source"}, - {"libp11-kit0", "0.23.9-2", "dpkg", "binary"}, - {"glibc", "2.27-3ubuntu1", "dpkg", "source"}, - {"mount", "2.31.1-0.4ubuntu3.1", "dpkg", "binary"}, - {"libsemanage-common", "2.7-2build2", "dpkg", "binary"}, - {"libblkid1", "2.31.1-0.4ubuntu3.1", "dpkg", "binary"}, - {"libdebconfclient0", "0.213ubuntu1", "dpkg", "binary"}, - {"libffi", "3.2.1-8", "dpkg", "source"}, - {"pam", "1.1.8-3.6ubuntu2", "dpkg", "source"}, - {"bsdutils", "1:2.31.1-0.4ubuntu3.1", "dpkg", "binary"}, - {"libtasn1-6", "4.13-2", "dpkg", "binary"}, - {"libaudit-common", "1:2.8.2-1ubuntu1", "dpkg", "binary"}, - {"gpgv", "2.2.4-1ubuntu1.1", "dpkg", "binary"}, - {"libzstd", "1.3.3+dfsg-2ubuntu1", "dpkg", "source"}, - {"base-passwd", "3.5.44", "dpkg", "source"}, - {"adduser", "3.116ubuntu1", "dpkg", "binary"}, - {"libattr1", "1:2.4.47-2build1", "dpkg", "binary"}, - {"libncurses5", "6.1-1ubuntu1.18.04", "dpkg", "binary"}, - {"coreutils", "8.28-1ubuntu1", "dpkg", "binary"}, - {"base-passwd", "3.5.44", "dpkg", "binary"}, - {"ubuntu-keyring", "2018.02.28", "dpkg", "binary"}, - {"adduser", "3.116ubuntu1", "dpkg", "source"}, - {"libsmartcols1", "2.31.1-0.4ubuntu3.1", "dpkg", "binary"}, - {"libunistring", "0.9.9-0ubuntu1", "dpkg", "source"}, - {"mawk", "1.3.3-17ubuntu3", "dpkg", "source"}, - {"coreutils", "8.28-1ubuntu1", "dpkg", "source"}, - {"attr", "1:2.4.47-2build1", "dpkg", "source"}, - {"gmp", "2:6.1.2+dfsg-2", "dpkg", "source"}, - {"libsemanage", "2.7-2build2", "dpkg", "source"}, - {"libselinux1", "2.7-2build2", "dpkg", "binary"}, - {"libseccomp2", "2.3.1-2.1ubuntu4", "dpkg", "binary"}, - {"zlib1g", "1:1.2.11.dfsg-0ubuntu2", "dpkg", "binary"}, - {"dash", "0.5.8-2.10", "dpkg", "source"}, - {"gnutls28", "3.5.18-1ubuntu1", "dpkg", "source"}, - {"libpam-runtime", "1.1.8-3.6ubuntu2", "dpkg", "binary"}, - {"libgcrypt20", "1.8.1-4ubuntu1.1", "dpkg", "source"}, - {"sensible-utils", "0.0.12", "dpkg", "binary"}, - {"p11-kit", "0.23.9-2", "dpkg", "source"}, - {"ncurses-base", "6.1-1ubuntu1.18.04", "dpkg", "binary"}, - {"e2fsprogs", "1.44.1-1", "dpkg", "binary"}, - {"libgcrypt20", "1.8.1-4ubuntu1.1", "dpkg", "binary"}, - {"libprocps6", "2:3.3.12-3ubuntu1.1", "dpkg", "binary"}, - {"debconf", "1.5.66", "dpkg", "source"}, - {"gcc-8-base", "8-20180414-1ubuntu2", "dpkg", "binary"}, - {"base-files", "10.1ubuntu2.2", "dpkg", "binary"}, - {"libbz2-1.0", "1.0.6-8.1", "dpkg", "binary"}, - {"grep", "3.1-2", "dpkg", "source"}, - {"bash", "4.4.18-2ubuntu1", "dpkg", "binary"}, - {"libgmp10", "2:6.1.2+dfsg-2", "dpkg", "binary"}, - {"shadow", "1:4.5-1ubuntu1", "dpkg", "source"}, - {"libidn2", "2.0.4-1.1build2", "dpkg", "source"}, - {"gzip", "1.6-5ubuntu1", "dpkg", "source"}, - {"util-linux", "2.31.1-0.4ubuntu3.1", "dpkg", "binary"}, - {"libaudit1", "1:2.8.2-1ubuntu1", "dpkg", "binary"}, - {"libsepol1", "2.7-1", "dpkg", "binary"}, - {"pcre3", "2:8.39-9", "dpkg", "source"}, - {"apt", "1.6.3ubuntu0.1", "dpkg", "source"}, - {"nettle", "3.4-1", "dpkg", "source"}, - {"util-linux", "2.31.1-0.4ubuntu3.1", "dpkg", "source"}, - {"libcap-ng0", "0.7.7-3.1", "dpkg", "binary"}, - {"debianutils", "4.8.4", "dpkg", "binary"}, - {"ncurses", "6.1-1ubuntu1.18.04", "dpkg", "source"}, - {"libffi6", "3.2.1-8", "dpkg", "binary"}, - {"cdebconf", "0.213ubuntu1", "dpkg", "source"}, - {"findutils", "4.6.0+git+20170828-2", "dpkg", "source"}, - {"libdb5.3", "5.3.28-13.1ubuntu1", "dpkg", "binary"}, - {"zlib", "1:1.2.11.dfsg-0ubuntu2", "dpkg", "source"}, - {"findutils", "4.6.0+git+20170828-2", "dpkg", "binary"}, - {"dpkg", "1.19.0.5ubuntu2", "dpkg", "binary"}, - {"mawk", "1.3.3-17ubuntu3", "dpkg", "binary"}, + {"libapt-pkg5.0", "1.6.3ubuntu0.1", "dpkg", "binary", database.Namespace{}}, + {"perl-base", "5.26.1-6ubuntu0.2", "dpkg", "binary", database.Namespace{}}, + {"libmount1", "2.31.1-0.4ubuntu3.1", "dpkg", "binary", database.Namespace{}}, + {"perl", "5.26.1-6ubuntu0.2", "dpkg", "source", database.Namespace{}}, + {"libgnutls30", "3.5.18-1ubuntu1", "dpkg", "binary", database.Namespace{}}, + {"liblzma5", "5.2.2-1.3", "dpkg", "binary", database.Namespace{}}, + {"ncurses-bin", "6.1-1ubuntu1.18.04", "dpkg", "binary", database.Namespace{}}, + {"lsb", "9.20170808ubuntu1", "dpkg", "source", database.Namespace{}}, + {"sed", "4.4-2", "dpkg", "source", database.Namespace{}}, + {"libsystemd0", "237-3ubuntu10.3", "dpkg", "binary", database.Namespace{}}, + {"procps", "2:3.3.12-3ubuntu1.1", "dpkg", "source", database.Namespace{}}, + {"login", "1:4.5-1ubuntu1", "dpkg", "binary", database.Namespace{}}, + {"libunistring2", "0.9.9-0ubuntu1", "dpkg", "binary", database.Namespace{}}, + {"sed", "4.4-2", "dpkg", "binary", database.Namespace{}}, + {"libselinux", "2.7-2build2", "dpkg", "source", database.Namespace{}}, + {"libseccomp", "2.3.1-2.1ubuntu4", "dpkg", "source", database.Namespace{}}, + {"libss2", "1.44.1-1", "dpkg", "binary", database.Namespace{}}, + {"liblz4-1", "0.0~r131-2ubuntu3", "dpkg", "binary", database.Namespace{}}, + {"libsemanage1", "2.7-2build2", "dpkg", "binary", database.Namespace{}}, + {"libtasn1-6", "4.13-2", "dpkg", "source", database.Namespace{}}, + {"libzstd1", "1.3.3+dfsg-2ubuntu1", "dpkg", "binary", database.Namespace{}}, + {"fdisk", "2.31.1-0.4ubuntu3.1", "dpkg", "binary", database.Namespace{}}, + {"xz-utils", "5.2.2-1.3", "dpkg", "source", database.Namespace{}}, + {"lsb-base", "9.20170808ubuntu1", "dpkg", "binary", database.Namespace{}}, + {"libpam-modules-bin", "1.1.8-3.6ubuntu2", "dpkg", "binary", database.Namespace{}}, + {"dash", "0.5.8-2.10", "dpkg", "binary", database.Namespace{}}, + {"gnupg2", "2.2.4-1ubuntu1.1", "dpkg", "source", database.Namespace{}}, + {"libfdisk1", "2.31.1-0.4ubuntu3.1", "dpkg", "binary", database.Namespace{}}, + {"lz4", "0.0~r131-2ubuntu3", "dpkg", "source", database.Namespace{}}, + {"libpam0g", "1.1.8-3.6ubuntu2", "dpkg", "binary", database.Namespace{}}, + {"libc-bin", "2.27-3ubuntu1", "dpkg", "binary", database.Namespace{}}, + {"libcap-ng", "0.7.7-3.1", "dpkg", "source", database.Namespace{}}, + {"libcom-err2", "1.44.1-1", "dpkg", "binary", database.Namespace{}}, + {"libudev1", "237-3ubuntu10.3", "dpkg", "binary", database.Namespace{}}, + {"debconf", "1.5.66", "dpkg", "binary", database.Namespace{}}, + {"tar", "1.29b-2", "dpkg", "binary", database.Namespace{}}, + {"diffutils", "1:3.6-1", "dpkg", "source", database.Namespace{}}, + {"gcc-8", "8-20180414-1ubuntu2", "dpkg", "source", database.Namespace{}}, + {"e2fsprogs", "1.44.1-1", "dpkg", "source", database.Namespace{}}, + {"bzip2", "1.0.6-8.1", "dpkg", "source", database.Namespace{}}, + {"diffutils", "1:3.6-1", "dpkg", "binary", database.Namespace{}}, + {"grep", "3.1-2", "dpkg", "binary", database.Namespace{}}, + {"libgcc1", "1:8-20180414-1ubuntu2", "dpkg", "binary", database.Namespace{}}, + {"bash", "4.4.18-2ubuntu1", "dpkg", "source", database.Namespace{}}, + {"libtinfo5", "6.1-1ubuntu1.18.04", "dpkg", "binary", database.Namespace{}}, + {"procps", "2:3.3.12-3ubuntu1.1", "dpkg", "binary", database.Namespace{}}, + {"bzip2", "1.0.6-8.1", "dpkg", "binary", database.Namespace{}}, + {"init-system-helpers", "1.51", "dpkg", "binary", database.Namespace{}}, + {"libncursesw5", "6.1-1ubuntu1.18.04", "dpkg", "binary", database.Namespace{}}, + {"init-system-helpers", "1.51", "dpkg", "source", database.Namespace{}}, + {"libpam-modules", "1.1.8-3.6ubuntu2", "dpkg", "binary", database.Namespace{}}, + {"libext2fs2", "1.44.1-1", "dpkg", "binary", database.Namespace{}}, + {"libacl1", "2.2.52-3build1", "dpkg", "binary", database.Namespace{}}, + {"hostname", "3.20", "dpkg", "binary", database.Namespace{}}, + {"libgpg-error", "1.27-6", "dpkg", "source", database.Namespace{}}, + {"acl", "2.2.52-3build1", "dpkg", "source", database.Namespace{}}, + {"apt", "1.6.3ubuntu0.1", "dpkg", "binary", database.Namespace{}}, + {"base-files", "10.1ubuntu2.2", "dpkg", "source", database.Namespace{}}, + {"libgpg-error0", "1.27-6", "dpkg", "binary", database.Namespace{}}, + {"audit", "1:2.8.2-1ubuntu1", "dpkg", "source", database.Namespace{}}, + {"hostname", "3.20", "dpkg", "source", database.Namespace{}}, + {"gzip", "1.6-5ubuntu1", "dpkg", "binary", database.Namespace{}}, + {"libc6", "2.27-3ubuntu1", "dpkg", "binary", database.Namespace{}}, + {"libnettle6", "3.4-1", "dpkg", "binary", database.Namespace{}}, + {"sysvinit-utils", "2.88dsf-59.10ubuntu1", "dpkg", "binary", database.Namespace{}}, + {"debianutils", "4.8.4", "dpkg", "source", database.Namespace{}}, + {"libstdc++6", "8-20180414-1ubuntu2", "dpkg", "binary", database.Namespace{}}, + {"libsepol", "2.7-1", "dpkg", "source", database.Namespace{}}, + {"libpcre3", "2:8.39-9", "dpkg", "binary", database.Namespace{}}, + {"libuuid1", "2.31.1-0.4ubuntu3.1", "dpkg", "binary", database.Namespace{}}, + {"systemd", "237-3ubuntu10.3", "dpkg", "source", database.Namespace{}}, + {"tar", "1.29b-2", "dpkg", "source", database.Namespace{}}, + {"ubuntu-keyring", "2018.02.28", "dpkg", "source", database.Namespace{}}, + {"passwd", "1:4.5-1ubuntu1", "dpkg", "binary", database.Namespace{}}, + {"sysvinit", "2.88dsf-59.10ubuntu1", "dpkg", "source", database.Namespace{}}, + {"libidn2-0", "2.0.4-1.1build2", "dpkg", "binary", database.Namespace{}}, + {"libhogweed4", "3.4-1", "dpkg", "binary", database.Namespace{}}, + {"db5.3", "5.3.28-13.1ubuntu1", "dpkg", "source", database.Namespace{}}, + {"sensible-utils", "0.0.12", "dpkg", "source", database.Namespace{}}, + {"dpkg", "1.19.0.5ubuntu2", "dpkg", "source", database.Namespace{}}, + {"libp11-kit0", "0.23.9-2", "dpkg", "binary", database.Namespace{}}, + {"glibc", "2.27-3ubuntu1", "dpkg", "source", database.Namespace{}}, + {"mount", "2.31.1-0.4ubuntu3.1", "dpkg", "binary", database.Namespace{}}, + {"libsemanage-common", "2.7-2build2", "dpkg", "binary", database.Namespace{}}, + {"libblkid1", "2.31.1-0.4ubuntu3.1", "dpkg", "binary", database.Namespace{}}, + {"libdebconfclient0", "0.213ubuntu1", "dpkg", "binary", database.Namespace{}}, + {"libffi", "3.2.1-8", "dpkg", "source", database.Namespace{}}, + {"pam", "1.1.8-3.6ubuntu2", "dpkg", "source", database.Namespace{}}, + {"bsdutils", "1:2.31.1-0.4ubuntu3.1", "dpkg", "binary", database.Namespace{}}, + {"libtasn1-6", "4.13-2", "dpkg", "binary", database.Namespace{}}, + {"libaudit-common", "1:2.8.2-1ubuntu1", "dpkg", "binary", database.Namespace{}}, + {"gpgv", "2.2.4-1ubuntu1.1", "dpkg", "binary", database.Namespace{}}, + {"libzstd", "1.3.3+dfsg-2ubuntu1", "dpkg", "source", database.Namespace{}}, + {"base-passwd", "3.5.44", "dpkg", "source", database.Namespace{}}, + {"adduser", "3.116ubuntu1", "dpkg", "binary", database.Namespace{}}, + {"libattr1", "1:2.4.47-2build1", "dpkg", "binary", database.Namespace{}}, + {"libncurses5", "6.1-1ubuntu1.18.04", "dpkg", "binary", database.Namespace{}}, + {"coreutils", "8.28-1ubuntu1", "dpkg", "binary", database.Namespace{}}, + {"base-passwd", "3.5.44", "dpkg", "binary", database.Namespace{}}, + {"ubuntu-keyring", "2018.02.28", "dpkg", "binary", database.Namespace{}}, + {"adduser", "3.116ubuntu1", "dpkg", "source", database.Namespace{}}, + {"libsmartcols1", "2.31.1-0.4ubuntu3.1", "dpkg", "binary", database.Namespace{}}, + {"libunistring", "0.9.9-0ubuntu1", "dpkg", "source", database.Namespace{}}, + {"mawk", "1.3.3-17ubuntu3", "dpkg", "source", database.Namespace{}}, + {"coreutils", "8.28-1ubuntu1", "dpkg", "source", database.Namespace{}}, + {"attr", "1:2.4.47-2build1", "dpkg", "source", database.Namespace{}}, + {"gmp", "2:6.1.2+dfsg-2", "dpkg", "source", database.Namespace{}}, + {"libsemanage", "2.7-2build2", "dpkg", "source", database.Namespace{}}, + {"libselinux1", "2.7-2build2", "dpkg", "binary", database.Namespace{}}, + {"libseccomp2", "2.3.1-2.1ubuntu4", "dpkg", "binary", database.Namespace{}}, + {"zlib1g", "1:1.2.11.dfsg-0ubuntu2", "dpkg", "binary", database.Namespace{}}, + {"dash", "0.5.8-2.10", "dpkg", "source", database.Namespace{}}, + {"gnutls28", "3.5.18-1ubuntu1", "dpkg", "source", database.Namespace{}}, + {"libpam-runtime", "1.1.8-3.6ubuntu2", "dpkg", "binary", database.Namespace{}}, + {"libgcrypt20", "1.8.1-4ubuntu1.1", "dpkg", "source", database.Namespace{}}, + {"sensible-utils", "0.0.12", "dpkg", "binary", database.Namespace{}}, + {"p11-kit", "0.23.9-2", "dpkg", "source", database.Namespace{}}, + {"ncurses-base", "6.1-1ubuntu1.18.04", "dpkg", "binary", database.Namespace{}}, + {"e2fsprogs", "1.44.1-1", "dpkg", "binary", database.Namespace{}}, + {"libgcrypt20", "1.8.1-4ubuntu1.1", "dpkg", "binary", database.Namespace{}}, + {"libprocps6", "2:3.3.12-3ubuntu1.1", "dpkg", "binary", database.Namespace{}}, + {"debconf", "1.5.66", "dpkg", "source", database.Namespace{}}, + {"gcc-8-base", "8-20180414-1ubuntu2", "dpkg", "binary", database.Namespace{}}, + {"base-files", "10.1ubuntu2.2", "dpkg", "binary", database.Namespace{}}, + {"libbz2-1.0", "1.0.6-8.1", "dpkg", "binary", database.Namespace{}}, + {"grep", "3.1-2", "dpkg", "source", database.Namespace{}}, + {"bash", "4.4.18-2ubuntu1", "dpkg", "binary", database.Namespace{}}, + {"libgmp10", "2:6.1.2+dfsg-2", "dpkg", "binary", database.Namespace{}}, + {"shadow", "1:4.5-1ubuntu1", "dpkg", "source", database.Namespace{}}, + {"libidn2", "2.0.4-1.1build2", "dpkg", "source", database.Namespace{}}, + {"gzip", "1.6-5ubuntu1", "dpkg", "source", database.Namespace{}}, + {"util-linux", "2.31.1-0.4ubuntu3.1", "dpkg", "binary", database.Namespace{}}, + {"libaudit1", "1:2.8.2-1ubuntu1", "dpkg", "binary", database.Namespace{}}, + {"libsepol1", "2.7-1", "dpkg", "binary", database.Namespace{}}, + {"pcre3", "2:8.39-9", "dpkg", "source", database.Namespace{}}, + {"apt", "1.6.3ubuntu0.1", "dpkg", "source", database.Namespace{}}, + {"nettle", "3.4-1", "dpkg", "source", database.Namespace{}}, + {"util-linux", "2.31.1-0.4ubuntu3.1", "dpkg", "source", database.Namespace{}}, + {"libcap-ng0", "0.7.7-3.1", "dpkg", "binary", database.Namespace{}}, + {"debianutils", "4.8.4", "dpkg", "binary", database.Namespace{}}, + {"ncurses", "6.1-1ubuntu1.18.04", "dpkg", "source", database.Namespace{}}, + {"libffi6", "3.2.1-8", "dpkg", "binary", database.Namespace{}}, + {"cdebconf", "0.213ubuntu1", "dpkg", "source", database.Namespace{}}, + {"findutils", "4.6.0+git+20170828-2", "dpkg", "source", database.Namespace{}}, + {"libdb5.3", "5.3.28-13.1ubuntu1", "dpkg", "binary", database.Namespace{}}, + {"zlib", "1:1.2.11.dfsg-0ubuntu2", "dpkg", "source", database.Namespace{}}, + {"findutils", "4.6.0+git+20170828-2", "dpkg", "binary", database.Namespace{}}, + {"dpkg", "1.19.0.5ubuntu2", "dpkg", "binary", database.Namespace{}}, + {"mawk", "1.3.3-17ubuntu3", "dpkg", "binary", database.Namespace{}}, }, }, { "corrupted status file", map[string]string{"var/lib/dpkg/status": "dpkg/testdata/corrupted"}, []database.Feature{ - {"libpam-modules-bin", "1.1.8-3.1ubuntu3", "dpkg", "binary"}, - {"gcc-5", "5.1.1-12ubuntu1", "dpkg", "source"}, - {"makedev", "2.3.1-93ubuntu1", "dpkg", "binary"}, - {"libgcc1", "1:5.1.1-12ubuntu1", "dpkg", "binary"}, - {"pam", "1.1.8-3.1ubuntu3", "dpkg", "source"}, - {"makedev", "2.3.1-93ubuntu1", "dpkg", "source"}, - {"libpam-runtime", "1.1.8-3.1ubuntu3", "dpkg", "binary"}, + {"libpam-modules-bin", "1.1.8-3.1ubuntu3", "dpkg", "binary", database.Namespace{}}, + {"gcc-5", "5.1.1-12ubuntu1", "dpkg", "source", database.Namespace{}}, + {"makedev", "2.3.1-93ubuntu1", "dpkg", "binary", database.Namespace{}}, + {"libgcc1", "1:5.1.1-12ubuntu1", "dpkg", "binary", database.Namespace{}}, + {"pam", "1.1.8-3.1ubuntu3", "dpkg", "source", database.Namespace{}}, + {"makedev", "2.3.1-93ubuntu1", "dpkg", "source", database.Namespace{}}, + {"libpam-runtime", "1.1.8-3.1ubuntu3", "dpkg", "binary", database.Namespace{}}, }, }, } { diff --git a/ext/featurefmt/rpm/rpm.go b/ext/featurefmt/rpm/rpm.go index 388212ea..f8ae887c 100644 --- a/ext/featurefmt/rpm/rpm.go +++ b/ext/featurefmt/rpm/rpm.go @@ -122,7 +122,7 @@ func parseRPMOutput(raw string) (rpmPackage *database.Feature, srpmPackage *data return } - rpmPackage = &database.Feature{name, version, rpm.ParserName, database.BinaryPackage} + rpmPackage = &database.Feature{name, version, rpm.ParserName, database.BinaryPackage, database.Namespace{}} srpmName, srpmVersion, srpmRelease, _, err := parseSourceRPM(srpm) if err != nil { log.WithError(err).WithFields(log.Fields{"name": name, "sourcerpm": srpm}).Warning("skipped unparseable package") @@ -134,7 +134,7 @@ func parseRPMOutput(raw string) (rpmPackage *database.Feature, srpmPackage *data return } - srpmPackage = &database.Feature{srpmName, srpmVersion, rpm.ParserName, database.SourcePackage} + srpmPackage = &database.Feature{srpmName, srpmVersion, rpm.ParserName, database.SourcePackage, database.Namespace{}} return } diff --git a/ext/featurefmt/rpm/rpm_test.go b/ext/featurefmt/rpm/rpm_test.go index ae5a70c5..b85b96d5 100644 --- a/ext/featurefmt/rpm/rpm_test.go +++ b/ext/featurefmt/rpm/rpm_test.go @@ -25,307 +25,307 @@ import ( ) var expectedBigCaseInfo = []database.Feature{ - {"libmount", "2.32.1-1.fc28", "rpm", "binary"}, - {"libffi", "3.1-16.fc28", "rpm", "binary"}, - {"libunistring", "0.9.10-1.fc28", "rpm", "binary"}, - {"fedora-repos", "28-5", "rpm", "binary"}, - {"libarchive", "3.3.1-4.fc28", "rpm", "source"}, - {"langpacks", "1.0-12.fc28", "rpm", "source"}, - {"readline", "7.0-11.fc28", "rpm", "source"}, - {"gzip", "1.9-3.fc28", "rpm", "source"}, - {"libverto", "0.3.0-5.fc28", "rpm", "source"}, - {"ncurses-base", "6.1-5.20180224.fc28", "rpm", "binary"}, - {"libfdisk", "2.32.1-1.fc28", "rpm", "binary"}, - {"libselinux", "2.8-1.fc28", "rpm", "source"}, - {"nss-util", "3.38.0-1.0.fc28", "rpm", "source"}, - {"mpfr", "3.1.6-1.fc28", "rpm", "source"}, - {"libunistring", "0.9.10-1.fc28", "rpm", "source"}, - {"libpcap", "14:1.9.0-1.fc28", "rpm", "binary"}, - {"libarchive", "3.3.1-4.fc28", "rpm", "binary"}, - {"gmp", "1:6.1.2-7.fc28", "rpm", "binary"}, - {"crypto-policies", "20180425-5.git6ad4018.fc28", "rpm", "source"}, - {"gzip", "1.9-3.fc28", "rpm", "binary"}, - {"fedora-release", "28-2", "rpm", "source"}, - {"zlib", "1.2.11-8.fc28", "rpm", "binary"}, - {"crypto-policies", "20180425-5.git6ad4018.fc28", "rpm", "binary"}, - {"lz4", "1.8.1.2-4.fc28", "rpm", "source"}, - {"keyutils", "1.5.10-6.fc28", "rpm", "source"}, - {"gpgme", "1.10.0-4.fc28", "rpm", "binary"}, - {"libgpg-error", "1.31-1.fc28", "rpm", "binary"}, - {"gnutls", "3.6.3-4.fc28", "rpm", "source"}, - {"coreutils", "8.29-7.fc28", "rpm", "source"}, - {"libsepol", "2.8-1.fc28", "rpm", "source"}, - {"libssh", "0.8.2-1.fc28", "rpm", "binary"}, - {"libpwquality", "1.4.0-7.fc28", "rpm", "binary"}, - {"dnf-conf", "2.7.5-12.fc28", "rpm", "binary"}, - {"basesystem", "11-5.fc28", "rpm", "source"}, - {"setup", "2.11.4-1.fc28", "rpm", "binary"}, - {"libmetalink", "0.1.3-6.fc28", "rpm", "source"}, - {"texinfo", "6.5-4.fc28", "rpm", "source"}, - {"expat", "2.2.5-3.fc28", "rpm", "source"}, - {"ncurses", "6.1-5.20180224.fc28", "rpm", "source"}, - {"libpwquality", "1.4.0-7.fc28", "rpm", "source"}, - {"pcre", "8.42-3.fc28", "rpm", "binary"}, - {"sssd", "1.16.3-2.fc28", "rpm", "source"}, - {"basesystem", "11-5.fc28", "rpm", "binary"}, - {"systemd-pam", "238-9.git0e0aa59.fc28", "rpm", "binary"}, - {"python3-six", "1.11.0-3.fc28", "rpm", "binary"}, - {"libcurl", "7.59.0-6.fc28", "rpm", "binary"}, - {"qrencode", "3.4.4-5.fc28", "rpm", "source"}, - {"xz", "5.2.4-2.fc28", "rpm", "source"}, - {"libpkgconf", "1.4.2-1.fc28", "rpm", "binary"}, - {"libzstd", "1.3.5-1.fc28", "rpm", "binary"}, - {"bash", "4.4.23-1.fc28", "rpm", "binary"}, - {"cyrus-sasl", "2.1.27-0.2rc7.fc28", "rpm", "source"}, - {"ncurses-libs", "6.1-5.20180224.fc28", "rpm", "binary"}, - {"xz-libs", "5.2.4-2.fc28", "rpm", "binary"}, - {"dbus", "1.12.10-1.fc28", "rpm", "source"}, - {"grep", "3.1-5.fc28", "rpm", "binary"}, - {"libusbx", "1.0.22-1.fc28", "rpm", "binary"}, - {"audit", "2.8.4-2.fc28", "rpm", "source"}, - {"sed", "4.5-1.fc28", "rpm", "binary"}, - {"sqlite", "3.22.0-4.fc28", "rpm", "source"}, - {"openldap", "2.4.46-3.fc28", "rpm", "binary"}, - {"gawk", "4.2.1-1.fc28", "rpm", "binary"}, - {"gpgme", "1.10.0-4.fc28", "rpm", "source"}, - {"lvm2", "2.02.177-5.fc28", "rpm", "source"}, - {"nspr", "4.19.0-1.fc28", "rpm", "source"}, - {"libsolv", "0.6.35-1.fc28", "rpm", "source"}, - {"info", "6.5-4.fc28", "rpm", "binary"}, - {"openssl-libs", "1:1.1.0h-3.fc28", "rpm", "binary"}, - {"libxcrypt", "4.1.2-1.fc28", "rpm", "binary"}, - {"libselinux", "2.8-1.fc28", "rpm", "binary"}, - {"libgcc", "8.1.1-5.fc28", "rpm", "binary"}, - {"cracklib", "2.9.6-13.fc28", "rpm", "binary"}, - {"python3-libs", "3.6.6-1.fc28", "rpm", "binary"}, - {"glibc-langpack-en", "2.27-32.fc28", "rpm", "binary"}, - {"json-c", "0.13.1-2.fc28", "rpm", "binary"}, - {"gnupg2", "2.2.8-1.fc28", "rpm", "source"}, - {"openssl", "1:1.1.0h-3.fc28", "rpm", "binary"}, - {"glibc-common", "2.27-32.fc28", "rpm", "binary"}, - {"p11-kit-trust", "0.23.12-1.fc28", "rpm", "binary"}, - {"zstd", "1.3.5-1.fc28", "rpm", "source"}, - {"libxml2", "2.9.8-4.fc28", "rpm", "source"}, - {"dbus", "1:1.12.10-1.fc28", "rpm", "binary"}, - {"ca-certificates", "2018.2.24-1.0.fc28", "rpm", "binary"}, - {"libcomps", "0.1.8-11.fc28", "rpm", "binary"}, - {"nss", "3.38.0-1.0.fc28", "rpm", "binary"}, - {"libcom_err", "1.44.2-0.fc28", "rpm", "binary"}, - {"keyutils-libs", "1.5.10-6.fc28", "rpm", "binary"}, - {"libseccomp", "2.3.3-2.fc28", "rpm", "binary"}, - {"elfutils-libs", "0.173-1.fc28", "rpm", "binary"}, - {"libuuid", "2.32.1-1.fc28", "rpm", "binary"}, - {"pkgconf", "1.4.2-1.fc28", "rpm", "source"}, - {"grep", "3.1-5.fc28", "rpm", "source"}, - {"libpcap", "1.9.0-1.fc28", "rpm", "source"}, - {"deltarpm", "3.6-25.fc28", "rpm", "binary"}, - {"krb5-libs", "1.16.1-13.fc28", "rpm", "binary"}, - {"glibc", "2.27-32.fc28", "rpm", "binary"}, - {"libseccomp", "2.3.3-2.fc28", "rpm", "source"}, - {"libsemanage", "2.8-2.fc28", "rpm", "binary"}, - {"openssl-pkcs11", "0.4.8-1.fc28", "rpm", "binary"}, - {"libxml2", "2.9.8-4.fc28", "rpm", "binary"}, - {"e2fsprogs", "1.44.2-0.fc28", "rpm", "source"}, - {"file-libs", "5.33-7.fc28", "rpm", "binary"}, - {"elfutils-default-yama-scope", "0.173-1.fc28", "rpm", "binary"}, - {"glibc", "2.27-32.fc28", "rpm", "source"}, - {"publicsuffix-list-dafsa", "20180514-1.fc28", "rpm", "binary"}, - {"popt", "1.16-14.fc28", "rpm", "binary"}, - {"libnsl2", "1.2.0-2.20180605git4a062cf.fc28", "rpm", "binary"}, - {"lua-libs", "5.3.4-10.fc28", "rpm", "binary"}, - {"libsemanage", "2.8-2.fc28", "rpm", "source"}, - {"glibc-minimal-langpack", "2.27-32.fc28", "rpm", "binary"}, - {"attr", "2.4.48-3.fc28", "rpm", "source"}, - {"gdbm", "1.14.1-4.fc28", "rpm", "source"}, - {"pkgconf", "1.4.2-1.fc28", "rpm", "binary"}, - {"acl", "2.2.53-1.fc28", "rpm", "source"}, - {"gnutls", "3.6.3-4.fc28", "rpm", "binary"}, - {"fedora-repos", "28-5", "rpm", "source"}, - {"python3-pip", "9.0.3-2.fc28", "rpm", "binary"}, - {"libnsl2", "1.2.0-2.20180605git4a062cf.fc28", "rpm", "source"}, - {"rpm", "4.14.1-9.fc28", "rpm", "binary"}, - {"libutempter", "1.1.6-14.fc28", "rpm", "source"}, - {"libdnf", "0.11.1-3.fc28", "rpm", "source"}, - {"vim-minimal", "2:8.1.328-1.fc28", "rpm", "binary"}, - {"tzdata", "2018e-1.fc28", "rpm", "binary"}, - {"nettle", "3.4-2.fc28", "rpm", "binary"}, - {"python-pip", "9.0.3-2.fc28", "rpm", "source"}, - {"python-six", "1.11.0-3.fc28", "rpm", "source"}, - {"diffutils", "3.6-4.fc28", "rpm", "binary"}, - {"rpm-plugin-selinux", "4.14.1-9.fc28", "rpm", "binary"}, - {"shadow-utils", "2:4.6-1.fc28", "rpm", "binary"}, - {"pkgconf-pkg-config", "1.4.2-1.fc28", "rpm", "binary"}, - {"cracklib-dicts", "2.9.6-13.fc28", "rpm", "binary"}, - {"libblkid", "2.32.1-1.fc28", "rpm", "binary"}, - {"python-setuptools", "39.2.0-6.fc28", "rpm", "source"}, - {"libsss_idmap", "1.16.3-2.fc28", "rpm", "binary"}, - {"libksba", "1.3.5-7.fc28", "rpm", "source"}, - {"sssd-client", "1.16.3-2.fc28", "rpm", "binary"}, - {"curl", "7.59.0-6.fc28", "rpm", "binary"}, - {"pam", "1.3.1-1.fc28", "rpm", "binary"}, - {"libsigsegv", "2.11-5.fc28", "rpm", "binary"}, - {"langpacks-en", "1.0-12.fc28", "rpm", "binary"}, - {"nss-softokn-freebl", "3.38.0-1.0.fc28", "rpm", "binary"}, - {"glib2", "2.56.1-4.fc28", "rpm", "binary"}, - {"python3-gobject-base", "3.28.3-1.fc28", "rpm", "binary"}, - {"libffi", "3.1-16.fc28", "rpm", "source"}, - {"libmodulemd", "1.6.2-2.fc28", "rpm", "source"}, - {"openssl", "1.1.0h-3.fc28", "rpm", "source"}, - {"libyaml", "0.1.7-5.fc28", "rpm", "source"}, - {"pam", "1.3.1-1.fc28", "rpm", "source"}, - {"iptables", "1.6.2-3.fc28", "rpm", "source"}, - {"util-linux", "2.32.1-1.fc28", "rpm", "source"}, - {"libsmartcols", "2.32.1-1.fc28", "rpm", "binary"}, - {"dnf", "2.7.5-12.fc28", "rpm", "binary"}, - {"glib2", "2.56.1-4.fc28", "rpm", "source"}, - {"lua", "5.3.4-10.fc28", "rpm", "source"}, - {"nss-softokn", "3.38.0-1.0.fc28", "rpm", "source"}, - {"python3-dnf", "2.7.5-12.fc28", "rpm", "binary"}, - {"filesystem", "3.8-2.fc28", "rpm", "binary"}, - {"libsss_nss_idmap", "1.16.3-2.fc28", "rpm", "binary"}, - {"pcre2", "10.31-10.fc28", "rpm", "source"}, - {"libyaml", "0.1.7-5.fc28", "rpm", "binary"}, - {"python3-rpm", "4.14.1-9.fc28", "rpm", "binary"}, - {"zlib", "1.2.11-8.fc28", "rpm", "source"}, - {"libutempter", "1.1.6-14.fc28", "rpm", "binary"}, - {"pcre2", "10.31-10.fc28", "rpm", "binary"}, - {"libtirpc", "1.0.3-3.rc2.fc28", "rpm", "source"}, - {"pkgconf-m4", "1.4.2-1.fc28", "rpm", "binary"}, - {"libreport", "2.9.5-1.fc28", "rpm", "source"}, - {"vim", "8.1.328-1.fc28", "rpm", "source"}, - {"file", "5.33-7.fc28", "rpm", "source"}, - {"shadow-utils", "4.6-1.fc28", "rpm", "source"}, - {"sqlite-libs", "3.22.0-4.fc28", "rpm", "binary"}, - {"setup", "2.11.4-1.fc28", "rpm", "source"}, - {"gcc", "8.1.1-5.fc28", "rpm", "source"}, - {"mpfr", "3.1.6-1.fc28", "rpm", "binary"}, - {"device-mapper", "1.02.146-5.fc28", "rpm", "binary"}, - {"p11-kit", "0.23.12-1.fc28", "rpm", "source"}, - {"fedora-release", "28-2", "rpm", "binary"}, - {"libnghttp2", "1.32.1-1.fc28", "rpm", "binary"}, - {"libcap-ng", "0.7.9-4.fc28", "rpm", "source"}, - {"iptables-libs", "1.6.2-3.fc28", "rpm", "binary"}, - {"audit-libs", "2.8.4-2.fc28", "rpm", "binary"}, - {"libsigsegv", "2.11-5.fc28", "rpm", "source"}, - {"rootfiles", "8.1-22.fc28", "rpm", "source"}, - {"kmod-libs", "25-2.fc28", "rpm", "binary"}, - {"lz4-libs", "1.8.1.2-4.fc28", "rpm", "binary"}, - {"libassuan", "2.5.1-3.fc28", "rpm", "source"}, - {"p11-kit", "0.23.12-1.fc28", "rpm", "binary"}, - {"nss-sysinit", "3.38.0-1.0.fc28", "rpm", "binary"}, - {"libcap-ng", "0.7.9-4.fc28", "rpm", "binary"}, - {"bash", "4.4.23-1.fc28", "rpm", "source"}, - {"pygobject3", "3.28.3-1.fc28", "rpm", "source"}, - {"dnf-yum", "2.7.5-12.fc28", "rpm", "binary"}, - {"nss-softokn", "3.38.0-1.0.fc28", "rpm", "binary"}, - {"expat", "2.2.5-3.fc28", "rpm", "binary"}, - {"libassuan", "2.5.1-3.fc28", "rpm", "binary"}, - {"libdb", "5.3.28-30.fc28", "rpm", "binary"}, - {"tar", "2:1.30-3.fc28", "rpm", "binary"}, - {"sed", "4.5-1.fc28", "rpm", "source"}, - {"libmetalink", "0.1.3-6.fc28", "rpm", "binary"}, - {"python-smartcols", "0.3.0-2.fc28", "rpm", "source"}, - {"systemd", "238-9.git0e0aa59.fc28", "rpm", "source"}, - {"python-iniparse", "0.4-30.fc28", "rpm", "source"}, - {"libsepol", "2.8-1.fc28", "rpm", "binary"}, - {"libattr", "2.4.48-3.fc28", "rpm", "binary"}, - {"python3-smartcols", "0.3.0-2.fc28", "rpm", "binary"}, - {"libdb", "5.3.28-30.fc28", "rpm", "source"}, - {"libmodulemd", "1.6.2-2.fc28", "rpm", "binary"}, - {"python3-hawkey", "0.11.1-3.fc28", "rpm", "binary"}, - {"dbus-libs", "1:1.12.10-1.fc28", "rpm", "binary"}, - {"chkconfig", "1.10-4.fc28", "rpm", "source"}, - {"libargon2", "20161029-5.fc28", "rpm", "binary"}, - {"openssl-pkcs11", "0.4.8-1.fc28", "rpm", "source"}, - {"libusbx", "1.0.22-1.fc28", "rpm", "source"}, - {"python3-setuptools", "39.2.0-6.fc28", "rpm", "binary"}, - {"chkconfig", "1.10-4.fc28", "rpm", "binary"}, - {"openldap", "2.4.46-3.fc28", "rpm", "source"}, - {"bzip2", "1.0.6-26.fc28", "rpm", "source"}, - {"npth", "1.5-4.fc28", "rpm", "source"}, - {"libtirpc", "1.0.3-3.rc2.fc28", "rpm", "binary"}, - {"util-linux", "2.32.1-1.fc28", "rpm", "binary"}, - {"nss", "3.38.0-1.0.fc28", "rpm", "source"}, - {"elfutils", "0.173-1.fc28", "rpm", "source"}, - {"libcomps", "0.1.8-11.fc28", "rpm", "source"}, - {"libxcrypt", "4.1.2-1.fc28", "rpm", "source"}, - {"gnupg2", "2.2.8-1.fc28", "rpm", "binary"}, - {"libdnf", "0.11.1-3.fc28", "rpm", "binary"}, - {"cracklib", "2.9.6-13.fc28", "rpm", "source"}, - {"libidn2", "2.0.5-1.fc28", "rpm", "source"}, - {"bzip2-libs", "1.0.6-26.fc28", "rpm", "binary"}, - {"json-c", "0.13.1-2.fc28", "rpm", "source"}, - {"gdbm", "1:1.14.1-4.fc28", "rpm", "binary"}, - {"pcre", "8.42-3.fc28", "rpm", "source"}, - {"systemd", "238-9.git0e0aa59.fc28", "rpm", "binary"}, - {"cryptsetup-libs", "2.0.4-1.fc28", "rpm", "binary"}, - {"dnf", "2.7.5-12.fc28", "rpm", "source"}, - {"ca-certificates", "2018.2.24-1.0.fc28", "rpm", "source"}, - {"libidn2", "2.0.5-1.fc28", "rpm", "binary"}, - {"libpsl", "0.20.2-2.fc28", "rpm", "binary"}, - {"gdbm-libs", "1:1.14.1-4.fc28", "rpm", "binary"}, - {"kmod", "25-2.fc28", "rpm", "source"}, - {"libreport-filesystem", "2.9.5-1.fc28", "rpm", "binary"}, - {"ima-evm-utils", "1.1-2.fc28", "rpm", "source"}, - {"nghttp2", "1.32.1-1.fc28", "rpm", "source"}, - {"cyrus-sasl-lib", "2.1.27-0.2rc7.fc28", "rpm", "binary"}, - {"libsolv", "0.6.35-1.fc28", "rpm", "binary"}, - {"cryptsetup", "2.0.4-1.fc28", "rpm", "source"}, - {"filesystem", "3.8-2.fc28", "rpm", "source"}, - {"libcap", "2.25-9.fc28", "rpm", "source"}, - {"libpsl", "0.20.2-2.fc28", "rpm", "source"}, - {"deltarpm", "3.6-25.fc28", "rpm", "source"}, - {"fedora-gpg-keys", "28-5", "rpm", "binary"}, - {"ima-evm-utils", "1.1-2.fc28", "rpm", "binary"}, - {"nss-tools", "3.38.0-1.0.fc28", "rpm", "binary"}, - {"libtasn1", "4.13-2.fc28", "rpm", "source"}, - {"elfutils-libelf", "0.173-1.fc28", "rpm", "binary"}, - {"device-mapper-libs", "1.02.146-5.fc28", "rpm", "binary"}, - {"gobject-introspection", "1.56.1-1.fc28", "rpm", "source"}, - {"publicsuffix-list", "20180514-1.fc28", "rpm", "source"}, - {"libcap", "2.25-9.fc28", "rpm", "binary"}, - {"librepo", "1.8.1-7.fc28", "rpm", "binary"}, - {"rpm-sign-libs", "4.14.1-9.fc28", "rpm", "binary"}, - {"coreutils-single", "8.29-7.fc28", "rpm", "binary"}, - {"libacl", "2.2.53-1.fc28", "rpm", "binary"}, - {"popt", "1.16-14.fc28", "rpm", "source"}, - {"libtasn1", "4.13-2.fc28", "rpm", "binary"}, - {"gawk", "4.2.1-1.fc28", "rpm", "source"}, - {"diffutils", "3.6-4.fc28", "rpm", "source"}, - {"libgpg-error", "1.31-1.fc28", "rpm", "source"}, - {"libdb-utils", "5.3.28-30.fc28", "rpm", "binary"}, - {"python3-iniparse", "0.4-30.fc28", "rpm", "binary"}, - {"acl", "2.2.53-1.fc28", "rpm", "binary"}, - {"libssh", "0.8.2-1.fc28", "rpm", "source"}, - {"python3-librepo", "1.8.1-7.fc28", "rpm", "binary"}, - {"gobject-introspection", "1.56.1-1.fc28", "rpm", "binary"}, - {"rpm", "4.14.1-9.fc28", "rpm", "source"}, - {"libgcrypt", "1.8.3-1.fc28", "rpm", "source"}, - {"curl", "7.59.0-6.fc28", "rpm", "source"}, - {"tzdata", "2018e-1.fc28", "rpm", "source"}, - {"krb5", "1.16.1-13.fc28", "rpm", "source"}, - {"librepo", "1.8.1-7.fc28", "rpm", "source"}, - {"python3-gpg", "1.10.0-4.fc28", "rpm", "binary"}, - {"nettle", "3.4-2.fc28", "rpm", "source"}, - {"libgcrypt", "1.8.3-1.fc28", "rpm", "binary"}, - {"python3", "3.6.6-1.fc28", "rpm", "binary"}, - {"python3-libcomps", "0.1.8-11.fc28", "rpm", "binary"}, - {"rpm-libs", "4.14.1-9.fc28", "rpm", "binary"}, - {"nspr", "4.19.0-1.fc28", "rpm", "binary"}, - {"argon2", "20161029-5.fc28", "rpm", "source"}, - {"tar", "1.30-3.fc28", "rpm", "source"}, - {"qrencode-libs", "3.4.4-5.fc28", "rpm", "binary"}, - {"gmp", "6.1.2-7.fc28", "rpm", "source"}, - {"libverto", "0.3.0-5.fc28", "rpm", "binary"}, - {"python3", "3.6.6-1.fc28", "rpm", "source"}, - {"libksba", "1.3.5-7.fc28", "rpm", "binary"}, - {"readline", "7.0-11.fc28", "rpm", "binary"}, - {"rpm-build-libs", "4.14.1-9.fc28", "rpm", "binary"}, - {"npth", "1.5-4.fc28", "rpm", "binary"}, - {"rootfiles", "8.1-22.fc28", "rpm", "binary"}, - {"rpm-plugin-systemd-inhibit", "4.14.1-9.fc28", "rpm", "binary"}, - {"systemd-libs", "238-9.git0e0aa59.fc28", "rpm", "binary"}, - {"nss-util", "3.38.0-1.0.fc28", "rpm", "binary"}, + {"libmount", "2.32.1-1.fc28", "rpm", "binary", database.Namespace{}}, + {"libffi", "3.1-16.fc28", "rpm", "binary", database.Namespace{}}, + {"libunistring", "0.9.10-1.fc28", "rpm", "binary", database.Namespace{}}, + {"fedora-repos", "28-5", "rpm", "binary", database.Namespace{}}, + {"libarchive", "3.3.1-4.fc28", "rpm", "source", database.Namespace{}}, + {"langpacks", "1.0-12.fc28", "rpm", "source", database.Namespace{}}, + {"readline", "7.0-11.fc28", "rpm", "source", database.Namespace{}}, + {"gzip", "1.9-3.fc28", "rpm", "source", database.Namespace{}}, + {"libverto", "0.3.0-5.fc28", "rpm", "source", database.Namespace{}}, + {"ncurses-base", "6.1-5.20180224.fc28", "rpm", "binary", database.Namespace{}}, + {"libfdisk", "2.32.1-1.fc28", "rpm", "binary", database.Namespace{}}, + {"libselinux", "2.8-1.fc28", "rpm", "source", database.Namespace{}}, + {"nss-util", "3.38.0-1.0.fc28", "rpm", "source", database.Namespace{}}, + {"mpfr", "3.1.6-1.fc28", "rpm", "source", database.Namespace{}}, + {"libunistring", "0.9.10-1.fc28", "rpm", "source", database.Namespace{}}, + {"libpcap", "14:1.9.0-1.fc28", "rpm", "binary", database.Namespace{}}, + {"libarchive", "3.3.1-4.fc28", "rpm", "binary", database.Namespace{}}, + {"gmp", "1:6.1.2-7.fc28", "rpm", "binary", database.Namespace{}}, + {"crypto-policies", "20180425-5.git6ad4018.fc28", "rpm", "source", database.Namespace{}}, + {"gzip", "1.9-3.fc28", "rpm", "binary", database.Namespace{}}, + {"fedora-release", "28-2", "rpm", "source", database.Namespace{}}, + {"zlib", "1.2.11-8.fc28", "rpm", "binary", database.Namespace{}}, + {"crypto-policies", "20180425-5.git6ad4018.fc28", "rpm", "binary", database.Namespace{}}, + {"lz4", "1.8.1.2-4.fc28", "rpm", "source", database.Namespace{}}, + {"keyutils", "1.5.10-6.fc28", "rpm", "source", database.Namespace{}}, + {"gpgme", "1.10.0-4.fc28", "rpm", "binary", database.Namespace{}}, + {"libgpg-error", "1.31-1.fc28", "rpm", "binary", database.Namespace{}}, + {"gnutls", "3.6.3-4.fc28", "rpm", "source", database.Namespace{}}, + {"coreutils", "8.29-7.fc28", "rpm", "source", database.Namespace{}}, + {"libsepol", "2.8-1.fc28", "rpm", "source", database.Namespace{}}, + {"libssh", "0.8.2-1.fc28", "rpm", "binary", database.Namespace{}}, + {"libpwquality", "1.4.0-7.fc28", "rpm", "binary", database.Namespace{}}, + {"dnf-conf", "2.7.5-12.fc28", "rpm", "binary", database.Namespace{}}, + {"basesystem", "11-5.fc28", "rpm", "source", database.Namespace{}}, + {"setup", "2.11.4-1.fc28", "rpm", "binary", database.Namespace{}}, + {"libmetalink", "0.1.3-6.fc28", "rpm", "source", database.Namespace{}}, + {"texinfo", "6.5-4.fc28", "rpm", "source", database.Namespace{}}, + {"expat", "2.2.5-3.fc28", "rpm", "source", database.Namespace{}}, + {"ncurses", "6.1-5.20180224.fc28", "rpm", "source", database.Namespace{}}, + {"libpwquality", "1.4.0-7.fc28", "rpm", "source", database.Namespace{}}, + {"pcre", "8.42-3.fc28", "rpm", "binary", database.Namespace{}}, + {"sssd", "1.16.3-2.fc28", "rpm", "source", database.Namespace{}}, + {"basesystem", "11-5.fc28", "rpm", "binary", database.Namespace{}}, + {"systemd-pam", "238-9.git0e0aa59.fc28", "rpm", "binary", database.Namespace{}}, + {"python3-six", "1.11.0-3.fc28", "rpm", "binary", database.Namespace{}}, + {"libcurl", "7.59.0-6.fc28", "rpm", "binary", database.Namespace{}}, + {"qrencode", "3.4.4-5.fc28", "rpm", "source", database.Namespace{}}, + {"xz", "5.2.4-2.fc28", "rpm", "source", database.Namespace{}}, + {"libpkgconf", "1.4.2-1.fc28", "rpm", "binary", database.Namespace{}}, + {"libzstd", "1.3.5-1.fc28", "rpm", "binary", database.Namespace{}}, + {"bash", "4.4.23-1.fc28", "rpm", "binary", database.Namespace{}}, + {"cyrus-sasl", "2.1.27-0.2rc7.fc28", "rpm", "source", database.Namespace{}}, + {"ncurses-libs", "6.1-5.20180224.fc28", "rpm", "binary", database.Namespace{}}, + {"xz-libs", "5.2.4-2.fc28", "rpm", "binary", database.Namespace{}}, + {"dbus", "1.12.10-1.fc28", "rpm", "source", database.Namespace{}}, + {"grep", "3.1-5.fc28", "rpm", "binary", database.Namespace{}}, + {"libusbx", "1.0.22-1.fc28", "rpm", "binary", database.Namespace{}}, + {"audit", "2.8.4-2.fc28", "rpm", "source", database.Namespace{}}, + {"sed", "4.5-1.fc28", "rpm", "binary", database.Namespace{}}, + {"sqlite", "3.22.0-4.fc28", "rpm", "source", database.Namespace{}}, + {"openldap", "2.4.46-3.fc28", "rpm", "binary", database.Namespace{}}, + {"gawk", "4.2.1-1.fc28", "rpm", "binary", database.Namespace{}}, + {"gpgme", "1.10.0-4.fc28", "rpm", "source", database.Namespace{}}, + {"lvm2", "2.02.177-5.fc28", "rpm", "source", database.Namespace{}}, + {"nspr", "4.19.0-1.fc28", "rpm", "source", database.Namespace{}}, + {"libsolv", "0.6.35-1.fc28", "rpm", "source", database.Namespace{}}, + {"info", "6.5-4.fc28", "rpm", "binary", database.Namespace{}}, + {"openssl-libs", "1:1.1.0h-3.fc28", "rpm", "binary", database.Namespace{}}, + {"libxcrypt", "4.1.2-1.fc28", "rpm", "binary", database.Namespace{}}, + {"libselinux", "2.8-1.fc28", "rpm", "binary", database.Namespace{}}, + {"libgcc", "8.1.1-5.fc28", "rpm", "binary", database.Namespace{}}, + {"cracklib", "2.9.6-13.fc28", "rpm", "binary", database.Namespace{}}, + {"python3-libs", "3.6.6-1.fc28", "rpm", "binary", database.Namespace{}}, + {"glibc-langpack-en", "2.27-32.fc28", "rpm", "binary", database.Namespace{}}, + {"json-c", "0.13.1-2.fc28", "rpm", "binary", database.Namespace{}}, + {"gnupg2", "2.2.8-1.fc28", "rpm", "source", database.Namespace{}}, + {"openssl", "1:1.1.0h-3.fc28", "rpm", "binary", database.Namespace{}}, + {"glibc-common", "2.27-32.fc28", "rpm", "binary", database.Namespace{}}, + {"p11-kit-trust", "0.23.12-1.fc28", "rpm", "binary", database.Namespace{}}, + {"zstd", "1.3.5-1.fc28", "rpm", "source", database.Namespace{}}, + {"libxml2", "2.9.8-4.fc28", "rpm", "source", database.Namespace{}}, + {"dbus", "1:1.12.10-1.fc28", "rpm", "binary", database.Namespace{}}, + {"ca-certificates", "2018.2.24-1.0.fc28", "rpm", "binary", database.Namespace{}}, + {"libcomps", "0.1.8-11.fc28", "rpm", "binary", database.Namespace{}}, + {"nss", "3.38.0-1.0.fc28", "rpm", "binary", database.Namespace{}}, + {"libcom_err", "1.44.2-0.fc28", "rpm", "binary", database.Namespace{}}, + {"keyutils-libs", "1.5.10-6.fc28", "rpm", "binary", database.Namespace{}}, + {"libseccomp", "2.3.3-2.fc28", "rpm", "binary", database.Namespace{}}, + {"elfutils-libs", "0.173-1.fc28", "rpm", "binary", database.Namespace{}}, + {"libuuid", "2.32.1-1.fc28", "rpm", "binary", database.Namespace{}}, + {"pkgconf", "1.4.2-1.fc28", "rpm", "source", database.Namespace{}}, + {"grep", "3.1-5.fc28", "rpm", "source", database.Namespace{}}, + {"libpcap", "1.9.0-1.fc28", "rpm", "source", database.Namespace{}}, + {"deltarpm", "3.6-25.fc28", "rpm", "binary", database.Namespace{}}, + {"krb5-libs", "1.16.1-13.fc28", "rpm", "binary", database.Namespace{}}, + {"glibc", "2.27-32.fc28", "rpm", "binary", database.Namespace{}}, + {"libseccomp", "2.3.3-2.fc28", "rpm", "source", database.Namespace{}}, + {"libsemanage", "2.8-2.fc28", "rpm", "binary", database.Namespace{}}, + {"openssl-pkcs11", "0.4.8-1.fc28", "rpm", "binary", database.Namespace{}}, + {"libxml2", "2.9.8-4.fc28", "rpm", "binary", database.Namespace{}}, + {"e2fsprogs", "1.44.2-0.fc28", "rpm", "source", database.Namespace{}}, + {"file-libs", "5.33-7.fc28", "rpm", "binary", database.Namespace{}}, + {"elfutils-default-yama-scope", "0.173-1.fc28", "rpm", "binary", database.Namespace{}}, + {"glibc", "2.27-32.fc28", "rpm", "source", database.Namespace{}}, + {"publicsuffix-list-dafsa", "20180514-1.fc28", "rpm", "binary", database.Namespace{}}, + {"popt", "1.16-14.fc28", "rpm", "binary", database.Namespace{}}, + {"libnsl2", "1.2.0-2.20180605git4a062cf.fc28", "rpm", "binary", database.Namespace{}}, + {"lua-libs", "5.3.4-10.fc28", "rpm", "binary", database.Namespace{}}, + {"libsemanage", "2.8-2.fc28", "rpm", "source", database.Namespace{}}, + {"glibc-minimal-langpack", "2.27-32.fc28", "rpm", "binary", database.Namespace{}}, + {"attr", "2.4.48-3.fc28", "rpm", "source", database.Namespace{}}, + {"gdbm", "1.14.1-4.fc28", "rpm", "source", database.Namespace{}}, + {"pkgconf", "1.4.2-1.fc28", "rpm", "binary", database.Namespace{}}, + {"acl", "2.2.53-1.fc28", "rpm", "source", database.Namespace{}}, + {"gnutls", "3.6.3-4.fc28", "rpm", "binary", database.Namespace{}}, + {"fedora-repos", "28-5", "rpm", "source", database.Namespace{}}, + {"python3-pip", "9.0.3-2.fc28", "rpm", "binary", database.Namespace{}}, + {"libnsl2", "1.2.0-2.20180605git4a062cf.fc28", "rpm", "source", database.Namespace{}}, + {"rpm", "4.14.1-9.fc28", "rpm", "binary", database.Namespace{}}, + {"libutempter", "1.1.6-14.fc28", "rpm", "source", database.Namespace{}}, + {"libdnf", "0.11.1-3.fc28", "rpm", "source", database.Namespace{}}, + {"vim-minimal", "2:8.1.328-1.fc28", "rpm", "binary", database.Namespace{}}, + {"tzdata", "2018e-1.fc28", "rpm", "binary", database.Namespace{}}, + {"nettle", "3.4-2.fc28", "rpm", "binary", database.Namespace{}}, + {"python-pip", "9.0.3-2.fc28", "rpm", "source", database.Namespace{}}, + {"python-six", "1.11.0-3.fc28", "rpm", "source", database.Namespace{}}, + {"diffutils", "3.6-4.fc28", "rpm", "binary", database.Namespace{}}, + {"rpm-plugin-selinux", "4.14.1-9.fc28", "rpm", "binary", database.Namespace{}}, + {"shadow-utils", "2:4.6-1.fc28", "rpm", "binary", database.Namespace{}}, + {"pkgconf-pkg-config", "1.4.2-1.fc28", "rpm", "binary", database.Namespace{}}, + {"cracklib-dicts", "2.9.6-13.fc28", "rpm", "binary", database.Namespace{}}, + {"libblkid", "2.32.1-1.fc28", "rpm", "binary", database.Namespace{}}, + {"python-setuptools", "39.2.0-6.fc28", "rpm", "source", database.Namespace{}}, + {"libsss_idmap", "1.16.3-2.fc28", "rpm", "binary", database.Namespace{}}, + {"libksba", "1.3.5-7.fc28", "rpm", "source", database.Namespace{}}, + {"sssd-client", "1.16.3-2.fc28", "rpm", "binary", database.Namespace{}}, + {"curl", "7.59.0-6.fc28", "rpm", "binary", database.Namespace{}}, + {"pam", "1.3.1-1.fc28", "rpm", "binary", database.Namespace{}}, + {"libsigsegv", "2.11-5.fc28", "rpm", "binary", database.Namespace{}}, + {"langpacks-en", "1.0-12.fc28", "rpm", "binary", database.Namespace{}}, + {"nss-softokn-freebl", "3.38.0-1.0.fc28", "rpm", "binary", database.Namespace{}}, + {"glib2", "2.56.1-4.fc28", "rpm", "binary", database.Namespace{}}, + {"python3-gobject-base", "3.28.3-1.fc28", "rpm", "binary", database.Namespace{}}, + {"libffi", "3.1-16.fc28", "rpm", "source", database.Namespace{}}, + {"libmodulemd", "1.6.2-2.fc28", "rpm", "source", database.Namespace{}}, + {"openssl", "1.1.0h-3.fc28", "rpm", "source", database.Namespace{}}, + {"libyaml", "0.1.7-5.fc28", "rpm", "source", database.Namespace{}}, + {"pam", "1.3.1-1.fc28", "rpm", "source", database.Namespace{}}, + {"iptables", "1.6.2-3.fc28", "rpm", "source", database.Namespace{}}, + {"util-linux", "2.32.1-1.fc28", "rpm", "source", database.Namespace{}}, + {"libsmartcols", "2.32.1-1.fc28", "rpm", "binary", database.Namespace{}}, + {"dnf", "2.7.5-12.fc28", "rpm", "binary", database.Namespace{}}, + {"glib2", "2.56.1-4.fc28", "rpm", "source", database.Namespace{}}, + {"lua", "5.3.4-10.fc28", "rpm", "source", database.Namespace{}}, + {"nss-softokn", "3.38.0-1.0.fc28", "rpm", "source", database.Namespace{}}, + {"python3-dnf", "2.7.5-12.fc28", "rpm", "binary", database.Namespace{}}, + {"filesystem", "3.8-2.fc28", "rpm", "binary", database.Namespace{}}, + {"libsss_nss_idmap", "1.16.3-2.fc28", "rpm", "binary", database.Namespace{}}, + {"pcre2", "10.31-10.fc28", "rpm", "source", database.Namespace{}}, + {"libyaml", "0.1.7-5.fc28", "rpm", "binary", database.Namespace{}}, + {"python3-rpm", "4.14.1-9.fc28", "rpm", "binary", database.Namespace{}}, + {"zlib", "1.2.11-8.fc28", "rpm", "source", database.Namespace{}}, + {"libutempter", "1.1.6-14.fc28", "rpm", "binary", database.Namespace{}}, + {"pcre2", "10.31-10.fc28", "rpm", "binary", database.Namespace{}}, + {"libtirpc", "1.0.3-3.rc2.fc28", "rpm", "source", database.Namespace{}}, + {"pkgconf-m4", "1.4.2-1.fc28", "rpm", "binary", database.Namespace{}}, + {"libreport", "2.9.5-1.fc28", "rpm", "source", database.Namespace{}}, + {"vim", "8.1.328-1.fc28", "rpm", "source", database.Namespace{}}, + {"file", "5.33-7.fc28", "rpm", "source", database.Namespace{}}, + {"shadow-utils", "4.6-1.fc28", "rpm", "source", database.Namespace{}}, + {"sqlite-libs", "3.22.0-4.fc28", "rpm", "binary", database.Namespace{}}, + {"setup", "2.11.4-1.fc28", "rpm", "source", database.Namespace{}}, + {"gcc", "8.1.1-5.fc28", "rpm", "source", database.Namespace{}}, + {"mpfr", "3.1.6-1.fc28", "rpm", "binary", database.Namespace{}}, + {"device-mapper", "1.02.146-5.fc28", "rpm", "binary", database.Namespace{}}, + {"p11-kit", "0.23.12-1.fc28", "rpm", "source", database.Namespace{}}, + {"fedora-release", "28-2", "rpm", "binary", database.Namespace{}}, + {"libnghttp2", "1.32.1-1.fc28", "rpm", "binary", database.Namespace{}}, + {"libcap-ng", "0.7.9-4.fc28", "rpm", "source", database.Namespace{}}, + {"iptables-libs", "1.6.2-3.fc28", "rpm", "binary", database.Namespace{}}, + {"audit-libs", "2.8.4-2.fc28", "rpm", "binary", database.Namespace{}}, + {"libsigsegv", "2.11-5.fc28", "rpm", "source", database.Namespace{}}, + {"rootfiles", "8.1-22.fc28", "rpm", "source", database.Namespace{}}, + {"kmod-libs", "25-2.fc28", "rpm", "binary", database.Namespace{}}, + {"lz4-libs", "1.8.1.2-4.fc28", "rpm", "binary", database.Namespace{}}, + {"libassuan", "2.5.1-3.fc28", "rpm", "source", database.Namespace{}}, + {"p11-kit", "0.23.12-1.fc28", "rpm", "binary", database.Namespace{}}, + {"nss-sysinit", "3.38.0-1.0.fc28", "rpm", "binary", database.Namespace{}}, + {"libcap-ng", "0.7.9-4.fc28", "rpm", "binary", database.Namespace{}}, + {"bash", "4.4.23-1.fc28", "rpm", "source", database.Namespace{}}, + {"pygobject3", "3.28.3-1.fc28", "rpm", "source", database.Namespace{}}, + {"dnf-yum", "2.7.5-12.fc28", "rpm", "binary", database.Namespace{}}, + {"nss-softokn", "3.38.0-1.0.fc28", "rpm", "binary", database.Namespace{}}, + {"expat", "2.2.5-3.fc28", "rpm", "binary", database.Namespace{}}, + {"libassuan", "2.5.1-3.fc28", "rpm", "binary", database.Namespace{}}, + {"libdb", "5.3.28-30.fc28", "rpm", "binary", database.Namespace{}}, + {"tar", "2:1.30-3.fc28", "rpm", "binary", database.Namespace{}}, + {"sed", "4.5-1.fc28", "rpm", "source", database.Namespace{}}, + {"libmetalink", "0.1.3-6.fc28", "rpm", "binary", database.Namespace{}}, + {"python-smartcols", "0.3.0-2.fc28", "rpm", "source", database.Namespace{}}, + {"systemd", "238-9.git0e0aa59.fc28", "rpm", "source", database.Namespace{}}, + {"python-iniparse", "0.4-30.fc28", "rpm", "source", database.Namespace{}}, + {"libsepol", "2.8-1.fc28", "rpm", "binary", database.Namespace{}}, + {"libattr", "2.4.48-3.fc28", "rpm", "binary", database.Namespace{}}, + {"python3-smartcols", "0.3.0-2.fc28", "rpm", "binary", database.Namespace{}}, + {"libdb", "5.3.28-30.fc28", "rpm", "source", database.Namespace{}}, + {"libmodulemd", "1.6.2-2.fc28", "rpm", "binary", database.Namespace{}}, + {"python3-hawkey", "0.11.1-3.fc28", "rpm", "binary", database.Namespace{}}, + {"dbus-libs", "1:1.12.10-1.fc28", "rpm", "binary", database.Namespace{}}, + {"chkconfig", "1.10-4.fc28", "rpm", "source", database.Namespace{}}, + {"libargon2", "20161029-5.fc28", "rpm", "binary", database.Namespace{}}, + {"openssl-pkcs11", "0.4.8-1.fc28", "rpm", "source", database.Namespace{}}, + {"libusbx", "1.0.22-1.fc28", "rpm", "source", database.Namespace{}}, + {"python3-setuptools", "39.2.0-6.fc28", "rpm", "binary", database.Namespace{}}, + {"chkconfig", "1.10-4.fc28", "rpm", "binary", database.Namespace{}}, + {"openldap", "2.4.46-3.fc28", "rpm", "source", database.Namespace{}}, + {"bzip2", "1.0.6-26.fc28", "rpm", "source", database.Namespace{}}, + {"npth", "1.5-4.fc28", "rpm", "source", database.Namespace{}}, + {"libtirpc", "1.0.3-3.rc2.fc28", "rpm", "binary", database.Namespace{}}, + {"util-linux", "2.32.1-1.fc28", "rpm", "binary", database.Namespace{}}, + {"nss", "3.38.0-1.0.fc28", "rpm", "source", database.Namespace{}}, + {"elfutils", "0.173-1.fc28", "rpm", "source", database.Namespace{}}, + {"libcomps", "0.1.8-11.fc28", "rpm", "source", database.Namespace{}}, + {"libxcrypt", "4.1.2-1.fc28", "rpm", "source", database.Namespace{}}, + {"gnupg2", "2.2.8-1.fc28", "rpm", "binary", database.Namespace{}}, + {"libdnf", "0.11.1-3.fc28", "rpm", "binary", database.Namespace{}}, + {"cracklib", "2.9.6-13.fc28", "rpm", "source", database.Namespace{}}, + {"libidn2", "2.0.5-1.fc28", "rpm", "source", database.Namespace{}}, + {"bzip2-libs", "1.0.6-26.fc28", "rpm", "binary", database.Namespace{}}, + {"json-c", "0.13.1-2.fc28", "rpm", "source", database.Namespace{}}, + {"gdbm", "1:1.14.1-4.fc28", "rpm", "binary", database.Namespace{}}, + {"pcre", "8.42-3.fc28", "rpm", "source", database.Namespace{}}, + {"systemd", "238-9.git0e0aa59.fc28", "rpm", "binary", database.Namespace{}}, + {"cryptsetup-libs", "2.0.4-1.fc28", "rpm", "binary", database.Namespace{}}, + {"dnf", "2.7.5-12.fc28", "rpm", "source", database.Namespace{}}, + {"ca-certificates", "2018.2.24-1.0.fc28", "rpm", "source", database.Namespace{}}, + {"libidn2", "2.0.5-1.fc28", "rpm", "binary", database.Namespace{}}, + {"libpsl", "0.20.2-2.fc28", "rpm", "binary", database.Namespace{}}, + {"gdbm-libs", "1:1.14.1-4.fc28", "rpm", "binary", database.Namespace{}}, + {"kmod", "25-2.fc28", "rpm", "source", database.Namespace{}}, + {"libreport-filesystem", "2.9.5-1.fc28", "rpm", "binary", database.Namespace{}}, + {"ima-evm-utils", "1.1-2.fc28", "rpm", "source", database.Namespace{}}, + {"nghttp2", "1.32.1-1.fc28", "rpm", "source", database.Namespace{}}, + {"cyrus-sasl-lib", "2.1.27-0.2rc7.fc28", "rpm", "binary", database.Namespace{}}, + {"libsolv", "0.6.35-1.fc28", "rpm", "binary", database.Namespace{}}, + {"cryptsetup", "2.0.4-1.fc28", "rpm", "source", database.Namespace{}}, + {"filesystem", "3.8-2.fc28", "rpm", "source", database.Namespace{}}, + {"libcap", "2.25-9.fc28", "rpm", "source", database.Namespace{}}, + {"libpsl", "0.20.2-2.fc28", "rpm", "source", database.Namespace{}}, + {"deltarpm", "3.6-25.fc28", "rpm", "source", database.Namespace{}}, + {"fedora-gpg-keys", "28-5", "rpm", "binary", database.Namespace{}}, + {"ima-evm-utils", "1.1-2.fc28", "rpm", "binary", database.Namespace{}}, + {"nss-tools", "3.38.0-1.0.fc28", "rpm", "binary", database.Namespace{}}, + {"libtasn1", "4.13-2.fc28", "rpm", "source", database.Namespace{}}, + {"elfutils-libelf", "0.173-1.fc28", "rpm", "binary", database.Namespace{}}, + {"device-mapper-libs", "1.02.146-5.fc28", "rpm", "binary", database.Namespace{}}, + {"gobject-introspection", "1.56.1-1.fc28", "rpm", "source", database.Namespace{}}, + {"publicsuffix-list", "20180514-1.fc28", "rpm", "source", database.Namespace{}}, + {"libcap", "2.25-9.fc28", "rpm", "binary", database.Namespace{}}, + {"librepo", "1.8.1-7.fc28", "rpm", "binary", database.Namespace{}}, + {"rpm-sign-libs", "4.14.1-9.fc28", "rpm", "binary", database.Namespace{}}, + {"coreutils-single", "8.29-7.fc28", "rpm", "binary", database.Namespace{}}, + {"libacl", "2.2.53-1.fc28", "rpm", "binary", database.Namespace{}}, + {"popt", "1.16-14.fc28", "rpm", "source", database.Namespace{}}, + {"libtasn1", "4.13-2.fc28", "rpm", "binary", database.Namespace{}}, + {"gawk", "4.2.1-1.fc28", "rpm", "source", database.Namespace{}}, + {"diffutils", "3.6-4.fc28", "rpm", "source", database.Namespace{}}, + {"libgpg-error", "1.31-1.fc28", "rpm", "source", database.Namespace{}}, + {"libdb-utils", "5.3.28-30.fc28", "rpm", "binary", database.Namespace{}}, + {"python3-iniparse", "0.4-30.fc28", "rpm", "binary", database.Namespace{}}, + {"acl", "2.2.53-1.fc28", "rpm", "binary", database.Namespace{}}, + {"libssh", "0.8.2-1.fc28", "rpm", "source", database.Namespace{}}, + {"python3-librepo", "1.8.1-7.fc28", "rpm", "binary", database.Namespace{}}, + {"gobject-introspection", "1.56.1-1.fc28", "rpm", "binary", database.Namespace{}}, + {"rpm", "4.14.1-9.fc28", "rpm", "source", database.Namespace{}}, + {"libgcrypt", "1.8.3-1.fc28", "rpm", "source", database.Namespace{}}, + {"curl", "7.59.0-6.fc28", "rpm", "source", database.Namespace{}}, + {"tzdata", "2018e-1.fc28", "rpm", "source", database.Namespace{}}, + {"krb5", "1.16.1-13.fc28", "rpm", "source", database.Namespace{}}, + {"librepo", "1.8.1-7.fc28", "rpm", "source", database.Namespace{}}, + {"python3-gpg", "1.10.0-4.fc28", "rpm", "binary", database.Namespace{}}, + {"nettle", "3.4-2.fc28", "rpm", "source", database.Namespace{}}, + {"libgcrypt", "1.8.3-1.fc28", "rpm", "binary", database.Namespace{}}, + {"python3", "3.6.6-1.fc28", "rpm", "binary", database.Namespace{}}, + {"python3-libcomps", "0.1.8-11.fc28", "rpm", "binary", database.Namespace{}}, + {"rpm-libs", "4.14.1-9.fc28", "rpm", "binary", database.Namespace{}}, + {"nspr", "4.19.0-1.fc28", "rpm", "binary", database.Namespace{}}, + {"argon2", "20161029-5.fc28", "rpm", "source", database.Namespace{}}, + {"tar", "1.30-3.fc28", "rpm", "source", database.Namespace{}}, + {"qrencode-libs", "3.4.4-5.fc28", "rpm", "binary", database.Namespace{}}, + {"gmp", "6.1.2-7.fc28", "rpm", "source", database.Namespace{}}, + {"libverto", "0.3.0-5.fc28", "rpm", "binary", database.Namespace{}}, + {"python3", "3.6.6-1.fc28", "rpm", "source", database.Namespace{}}, + {"libksba", "1.3.5-7.fc28", "rpm", "binary", database.Namespace{}}, + {"readline", "7.0-11.fc28", "rpm", "binary", database.Namespace{}}, + {"rpm-build-libs", "4.14.1-9.fc28", "rpm", "binary", database.Namespace{}}, + {"npth", "1.5-4.fc28", "rpm", "binary", database.Namespace{}}, + {"rootfiles", "8.1-22.fc28", "rpm", "binary", database.Namespace{}}, + {"rpm-plugin-systemd-inhibit", "4.14.1-9.fc28", "rpm", "binary", database.Namespace{}}, + {"systemd-libs", "238-9.git0e0aa59.fc28", "rpm", "binary", database.Namespace{}}, + {"nss-util", "3.38.0-1.0.fc28", "rpm", "binary", database.Namespace{}}, } func TestRpmFeatureDetection(t *testing.T) { @@ -334,10 +334,10 @@ func TestRpmFeatureDetection(t *testing.T) { "valid small case", map[string]string{"var/lib/rpm/Packages": "rpm/testdata/valid"}, []database.Feature{ - {"centos-release", "7-1.1503.el7.centos.2.8", "rpm", "binary"}, - {"filesystem", "3.2-18.el7", "rpm", "binary"}, - {"centos-release", "7-1.1503.el7.centos.2.8", "rpm", "source"}, - {"filesystem", "3.2-18.el7", "rpm", "source"}, + {"centos-release", "7-1.1503.el7.centos.2.8", "rpm", "binary", database.Namespace{}}, + {"filesystem", "3.2-18.el7", "rpm", "binary", database.Namespace{}}, + {"centos-release", "7-1.1503.el7.centos.2.8", "rpm", "source", database.Namespace{}}, + {"filesystem", "3.2-18.el7", "rpm", "source", database.Namespace{}}, }, }, { From 44c4a6f3ce2e18ba41fe137e9bfefb98fdf65501 Mon Sep 17 00:00:00 2001 From: Ales Raszka Date: Thu, 28 Feb 2019 11:02:39 +0100 Subject: [PATCH 2/6] Store PotentialNamespace in database PotentialNamespace is part of layer_feature table and it is also stored in namespace table. --- database/models.go | 10 +++++- database/pgsql/feature.go | 19 ++++++---- database/pgsql/feature_test.go | 2 +- database/pgsql/layer.go | 36 ++++++++++++------- .../pgsql/migrations/00001_initial_schema.go | 1 + database/pgsql/queries.go | 3 +- 6 files changed, 49 insertions(+), 22 deletions(-) diff --git a/database/models.go b/database/models.go index ebbeb658..7e8fd0a9 100644 --- a/database/models.go +++ b/database/models.go @@ -17,6 +17,7 @@ package database import ( "database/sql/driver" "encoding/json" + "fmt" "time" "github.com/coreos/clair/pkg/pagination" @@ -123,10 +124,13 @@ func (l *Layer) GetFeatures() []Feature { } func (l *Layer) GetNamespaces() []Namespace { - namespaces := make([]Namespace, 0, len(l.Namespaces)) + namespaces := make([]Namespace, 0, len(l.Namespaces)+len(l.Features)) for _, ns := range l.Namespaces { namespaces = append(namespaces, ns.Namespace) } + for _, f := range l.Features { + namespaces = append(namespaces, f.Feature.PotentialNamespace) + } return namespaces } @@ -195,6 +199,10 @@ type NamespacedFeature struct { Namespace Namespace `json:"namespace"` } +func (nf *NamespacedFeature) Key() string { + return fmt.Sprintf("%s-%s-%s-%s-%s-%s", nf.Name, nf.Version, nf.VersionFormat, nf.Type, nf.Namespace.Name, nf.Namespace.VersionFormat) +} + func NewNamespacedFeature(namespace *Namespace, feature *Feature) *NamespacedFeature { // TODO: namespaced feature should use pointer values return &NamespacedFeature{*feature, *namespace} diff --git a/database/pgsql/feature.go b/database/pgsql/feature.go index 66b47c50..58f12dbd 100644 --- a/database/pgsql/feature.go +++ b/database/pgsql/feature.go @@ -17,6 +17,7 @@ package pgsql import ( "database/sql" "sort" + "strconv" "github.com/lib/pq" log "github.com/sirupsen/logrus" @@ -311,7 +312,7 @@ func (tx *pgSession) findNamespacedFeatureIDs(nfs []database.NamespacedFeature) return nil, nil } - nfsMap := map[database.NamespacedFeature]int64{} + nfsMap := map[string]int64{} keys := make([]interface{}, 0, len(nfs)*5) for _, nf := range nfs { keys = append(keys, nf.Name, nf.Version, nf.VersionFormat, nf.Type, nf.Namespace.Name) @@ -334,12 +335,12 @@ func (tx *pgSession) findNamespacedFeatureIDs(nfs []database.NamespacedFeature) if err != nil { return nil, handleError("searchNamespacedFeature", err) } - nfsMap[nf] = id + nfsMap[nf.Key()] = id } ids := make([]sql.NullInt64, len(nfs)) for i, nf := range nfs { - if id, ok := nfsMap[nf]; ok { + if id, ok := nfsMap[nf.Key()]; ok { ids[i] = sql.NullInt64{id, true} } else { ids[i] = sql.NullInt64{} @@ -359,13 +360,14 @@ func (tx *pgSession) findFeatureIDs(fs []database.Feature) ([]sql.NullInt64, err return nil, err } - fMap := map[database.Feature]sql.NullInt64{} + fMap := map[string]sql.NullInt64{} keys := make([]interface{}, 0, len(fs)*4) for _, f := range fs { typeID := types.byName[f.Type] keys = append(keys, f.Name, f.Version, f.VersionFormat, typeID) - fMap[f] = sql.NullInt64{} + mapKey := f.Name + f.Version + f.VersionFormat + strconv.Itoa(typeID) + fMap[mapKey] = sql.NullInt64{} } rows, err := tx.Query(querySearchFeatureID(len(fs)), keys...) @@ -386,12 +388,15 @@ func (tx *pgSession) findFeatureIDs(fs []database.Feature) ([]sql.NullInt64, err } f.Type = types.byID[typeID] - fMap[f] = id + mapKey := f.Name + f.Version + f.VersionFormat + strconv.Itoa(typeID) + fMap[mapKey] = id } ids := make([]sql.NullInt64, len(fs)) for i, f := range fs { - ids[i] = fMap[f] + typeID := types.byName[f.Type] + mapKey := f.Name + f.Version + f.VersionFormat + strconv.Itoa(typeID) + ids[i] = fMap[mapKey] } return ids, nil diff --git a/database/pgsql/feature_test.go b/database/pgsql/feature_test.go index 4f546c91..7b47b37f 100644 --- a/database/pgsql/feature_test.go +++ b/database/pgsql/feature_test.go @@ -182,7 +182,7 @@ func TestFindNamespacedFeatureIDs(t *testing.T) { expectedIDs = append(expectedIDs, 1) namespace := realNamespaces[1] - features = append(features, *database.NewNamespacedFeature(&namespace, database.NewBinaryPackage("not-found", "1.0", "dpkg"))) // test not found feature + features = append(features, *database.NewNamespacedFeature(&namespace, database.NewBinaryPackage("not-found", "1.0", "dpkg", database.Namespace{}))) // test not found feature ids, err := tx.findNamespacedFeatureIDs(features) require.Nil(t, err) diff --git a/database/pgsql/layer.go b/database/pgsql/layer.go index a071eb4b..9561c7a1 100644 --- a/database/pgsql/layer.go +++ b/database/pgsql/layer.go @@ -37,10 +37,11 @@ const ( SELECT id FROM layer WHERE hash = $1` findLayerFeatures = ` - SELECT f.name, f.version, f.version_format, t.name, lf.detector_id - FROM layer_feature AS lf, feature AS f, feature_type AS t + SELECT f.name, f.version, f.version_format, t.name, lf.detector_id, ns.name, ns.version_format + FROM layer_feature AS lf, feature AS f, feature_type AS t, namespace AS ns WHERE lf.feature_id = f.id AND t.id = f.type + AND lf.namespace_id = ns.id AND lf.layer_id = $1` findLayerNamespaces = ` @@ -61,9 +62,10 @@ type dbLayerNamespace struct { // dbLayerFeature represents the layer_feature table type dbLayerFeature struct { - layerID int64 - featureID int64 - detectorID int64 + layerID int64 + featureID int64 + detectorID int64 + namespaceID int64 } func (tx *pgSession) FindLayer(hash string) (database.Layer, bool, error) { @@ -199,10 +201,16 @@ func (tx *pgSession) persistAllLayerFeatures(layerID int64, features []database. if err != nil { return err } - + var namespaces []database.Namespace + for _, feature := range features { + namespaces = append(namespaces, feature.PotentialNamespace) + } + nameSpaceIDs, _ := tx.findNamespaceIDs(namespaces) + featureNamespaceMap := map[database.Namespace]sql.NullInt64{} rawFeatures := make([]database.Feature, 0, len(features)) - for _, f := range features { + for i, f := range features { rawFeatures = append(rawFeatures, f.Feature) + featureNamespaceMap[f.PotentialNamespace] = nameSpaceIDs[i] } featureIDs, err := tx.findFeatureIDs(rawFeatures) @@ -213,12 +221,16 @@ func (tx *pgSession) persistAllLayerFeatures(layerID int64, features []database. dbFeatures := make([]dbLayerFeature, 0, len(features)) for i, f := range features { detectorID := detectorMap.byValue[f.By] - featureID := featureIDs[i].Int64 if !featureIDs[i].Valid { return database.ErrMissingEntities } + featureID := featureIDs[i].Int64 + if !featureNamespaceMap[f.PotentialNamespace].Valid { + return database.ErrMissingEntities + } + namespaceID := featureNamespaceMap[f.PotentialNamespace].Int64 - dbFeatures = append(dbFeatures, dbLayerFeature{layerID, featureID, detectorID}) + dbFeatures = append(dbFeatures, dbLayerFeature{layerID, featureID, detectorID, namespaceID}) } if err := tx.persistLayerFeatures(dbFeatures); err != nil { @@ -236,9 +248,9 @@ func (tx *pgSession) persistLayerFeatures(features []dbLayerFeature) error { sort.Slice(features, func(i, j int) bool { return features[i].featureID < features[j].featureID }) - keys := make([]interface{}, 0, len(features)*3) + keys := make([]interface{}, 0, len(features)*4) for _, f := range features { - keys = append(keys, f.layerID, f.featureID, f.detectorID) + keys = append(keys, f.layerID, f.featureID, f.detectorID, f.namespaceID) } _, err := tx.Exec(queryPersistLayerFeature(len(features)), keys...) @@ -308,7 +320,7 @@ func (tx *pgSession) findLayerFeatures(layerID int64, detectors detectorMap) ([] detectorID int64 feature database.LayerFeature ) - if err := rows.Scan(&feature.Name, &feature.Version, &feature.VersionFormat, &feature.Type, &detectorID); err != nil { + if err := rows.Scan(&feature.Name, &feature.Version, &feature.VersionFormat, &feature.Type, &detectorID, &feature.PotentialNamespace.Name, &feature.PotentialNamespace.VersionFormat); err != nil { return nil, handleError("findLayerFeatures", err) } diff --git a/database/pgsql/migrations/00001_initial_schema.go b/database/pgsql/migrations/00001_initial_schema.go index b1f3bd76..85b2b49c 100644 --- a/database/pgsql/migrations/00001_initial_schema.go +++ b/database/pgsql/migrations/00001_initial_schema.go @@ -89,6 +89,7 @@ var ( layer_id INT REFERENCES layer ON DELETE CASCADE, feature_id INT REFERENCES feature ON DELETE CASCADE, detector_id INT REFERENCES detector ON DELETE CASCADE, + namespace_id INT REFERENCES namespace ON DELETE CASCADE, UNIQUE (layer_id, feature_id));`, `CREATE INDEX ON layer_feature(layer_id);`, diff --git a/database/pgsql/queries.go b/database/pgsql/queries.go index 5cd5c3c9..111dc30e 100644 --- a/database/pgsql/queries.go +++ b/database/pgsql/queries.go @@ -124,7 +124,8 @@ func queryPersistLayerFeature(count int) string { "layer_feature_layer_id_feature_id_key", "layer_id", "feature_id", - "detector_id") + "detector_id", + "namespace_id") } func queryPersistNamespace(count int) string { From 60ef726677cdd74bea0d8ad9a5e2a32faf70f7da Mon Sep 17 00:00:00 2001 From: Ales Raszka Date: Wed, 6 Mar 2019 10:24:14 +0100 Subject: [PATCH 3/6] Move PotentialNamespace to LayerFeature PotentialNamespace should be in LayerFeature instead of Feature struct. Feature extractors were updated to return LayerFeature instead of Feature. --- database/dbutil.go | 13 + database/models.go | 35 +- database/pgsql/complex_test.go | 2 +- database/pgsql/feature_test.go | 8 +- database/pgsql/layer.go | 14 +- database/pgsql/layer_test.go | 20 +- database/pgsql/testutil.go | 18 +- ext/featurefmt/apk/apk.go | 6 +- ext/featurefmt/apk/apk_test.go | 24 +- ext/featurefmt/dpkg/dpkg.go | 10 +- ext/featurefmt/dpkg/dpkg_test.go | 316 ++++++++-------- ext/featurefmt/driver.go | 10 +- ext/featurefmt/rpm/rpm.go | 16 +- ext/featurefmt/rpm/rpm_test.go | 614 +++++++++++++++---------------- ext/featurefmt/testutil.go | 6 +- 15 files changed, 566 insertions(+), 546 deletions(-) diff --git a/database/dbutil.go b/database/dbutil.go index e8e1f912..6581e252 100644 --- a/database/dbutil.go +++ b/database/dbutil.go @@ -60,6 +60,19 @@ func ConvertFeatureSetToFeatures(features mapset.Set) []Feature { return uniqueFeatures } +func ConvertFeatureSerToLayerFeatures(features mapset.Set) []LayerFeature { + uniqueLayerFeatures := make([]LayerFeature, 0, features.Cardinality()) + for f := range features.Iter() { + feature := f.(Feature) + layerFeature := LayerFeature{ + Feature: feature, + } + uniqueLayerFeatures = append(uniqueLayerFeatures, layerFeature) + } + + return uniqueLayerFeatures +} + // FindKeyValueAndRollback wraps session FindKeyValue function with begin and // roll back. func FindKeyValueAndRollback(datastore Datastore, key string) (value string, ok bool, err error) { diff --git a/database/models.go b/database/models.go index 7e8fd0a9..7dd36dfe 100644 --- a/database/models.go +++ b/database/models.go @@ -129,7 +129,9 @@ func (l *Layer) GetNamespaces() []Namespace { namespaces = append(namespaces, ns.Namespace) } for _, f := range l.Features { - namespaces = append(namespaces, f.Feature.PotentialNamespace) + if f.PotentialNamespace.Valid() { + namespaces = append(namespaces, f.PotentialNamespace) + } } return namespaces @@ -148,7 +150,8 @@ type LayerFeature struct { Feature `json:"feature"` // By is the detector found the feature. - By Detector `json:"by"` + By Detector `json:"by"` + PotentialNamespace Namespace `json:"potentialNamespace"` } // Namespace is the contextual information around features. @@ -163,6 +166,13 @@ func NewNamespace(name string, versionFormat string) *Namespace { return &Namespace{name, versionFormat} } +func (ns *Namespace) Valid() bool { + if ns.Name == "" || ns.VersionFormat == "" { + return false + } + return true +} + // Feature represents a package detected in a layer but the namespace is not // determined. // @@ -170,23 +180,22 @@ func NewNamespace(name string, versionFormat string) *Namespace { // dpkg is the version format of the installer package manager, which in this // case could be dpkg or apk. type Feature struct { - Name string `json:"name"` - Version string `json:"version"` - VersionFormat string `json:"versionFormat"` - Type FeatureType `json:"type"` - PotentialNamespace Namespace `json:"potentialNamespace"` + Name string `json:"name"` + Version string `json:"version"` + VersionFormat string `json:"versionFormat"` + Type FeatureType `json:"type"` } -func NewFeature(name string, version string, versionFormat string, featureType FeatureType, namespace Namespace) *Feature { - return &Feature{name, version, versionFormat, featureType, namespace} +func NewFeature(name string, version string, versionFormat string, featureType FeatureType) *Feature { + return &Feature{name, version, versionFormat, featureType} } -func NewBinaryPackage(name string, version string, versionFormat string, namespace Namespace) *Feature { - return &Feature{name, version, versionFormat, BinaryPackage, namespace} +func NewBinaryPackage(name string, version string, versionFormat string) *Feature { + return &Feature{name, version, versionFormat, BinaryPackage} } -func NewSourcePackage(name string, version string, versionFormat string, namespace Namespace) *Feature { - return &Feature{name, version, versionFormat, SourcePackage, namespace} +func NewSourcePackage(name string, version string, versionFormat string) *Feature { + return &Feature{name, version, versionFormat, SourcePackage} } // NamespacedFeature is a feature with determined namespace and can be affected diff --git a/database/pgsql/complex_test.go b/database/pgsql/complex_test.go index 28e14479..5b42ccfa 100644 --- a/database/pgsql/complex_test.go +++ b/database/pgsql/complex_test.go @@ -65,7 +65,7 @@ func testGenRandomVulnerabilityAndNamespacedFeature(t *testing.T, store database for i := 0; i < numFeatures; i++ { version := rand.Intn(numFeatures) - features[i] = *database.NewSourcePackage(featureName, strconv.Itoa(version), featureVersionFormat, database.Namespace{}) + features[i] = *database.NewSourcePackage(featureName, strconv.Itoa(version), featureVersionFormat) nsFeatures[i] = database.NamespacedFeature{ Namespace: namespace, Feature: features[i], diff --git a/database/pgsql/feature_test.go b/database/pgsql/feature_test.go index 7b47b37f..574bfeab 100644 --- a/database/pgsql/feature_test.go +++ b/database/pgsql/feature_test.go @@ -28,7 +28,7 @@ func TestPersistFeatures(t *testing.T) { defer cleanup() invalid := database.Feature{} - valid := *database.NewBinaryPackage("mount", "2.31.1-0.4ubuntu3.1", "dpkg", database.Namespace{}) + valid := *database.NewBinaryPackage("mount", "2.31.1-0.4ubuntu3.1", "dpkg") // invalid require.NotNil(t, tx.PersistFeatures([]database.Feature{invalid})) @@ -45,9 +45,9 @@ func TestPersistNamespacedFeatures(t *testing.T) { defer cleanup() // existing features - f1 := database.NewSourcePackage("ourchat", "0.5", "dpkg", database.Namespace{}) + f1 := database.NewSourcePackage("ourchat", "0.5", "dpkg") // non-existing features - f2 := database.NewSourcePackage("fake!", "", "", database.Namespace{}) + f2 := database.NewSourcePackage("fake!", "", "") // exising namespace n1 := database.NewNamespace("debian:7", "dpkg") // non-existing namespace @@ -182,7 +182,7 @@ func TestFindNamespacedFeatureIDs(t *testing.T) { expectedIDs = append(expectedIDs, 1) namespace := realNamespaces[1] - features = append(features, *database.NewNamespacedFeature(&namespace, database.NewBinaryPackage("not-found", "1.0", "dpkg", database.Namespace{}))) // test not found feature + features = append(features, *database.NewNamespacedFeature(&namespace, database.NewBinaryPackage("not-found", "1.0", "dpkg"))) // test not found feature ids, err := tx.findNamespacedFeatureIDs(features) require.Nil(t, err) diff --git a/database/pgsql/layer.go b/database/pgsql/layer.go index 9561c7a1..4c1497fb 100644 --- a/database/pgsql/layer.go +++ b/database/pgsql/layer.go @@ -65,7 +65,7 @@ type dbLayerFeature struct { layerID int64 featureID int64 detectorID int64 - namespaceID int64 + namespaceID sql.NullInt64 } func (tx *pgSession) FindLayer(hash string) (database.Layer, bool, error) { @@ -210,14 +210,16 @@ func (tx *pgSession) persistAllLayerFeatures(layerID int64, features []database. rawFeatures := make([]database.Feature, 0, len(features)) for i, f := range features { rawFeatures = append(rawFeatures, f.Feature) - featureNamespaceMap[f.PotentialNamespace] = nameSpaceIDs[i] + if f.PotentialNamespace.Valid() { + featureNamespaceMap[f.PotentialNamespace] = nameSpaceIDs[i] + } } featureIDs, err := tx.findFeatureIDs(rawFeatures) if err != nil { return err } - + var namespaceID sql.NullInt64 dbFeatures := make([]dbLayerFeature, 0, len(features)) for i, f := range features { detectorID := detectorMap.byValue[f.By] @@ -225,10 +227,7 @@ func (tx *pgSession) persistAllLayerFeatures(layerID int64, features []database. return database.ErrMissingEntities } featureID := featureIDs[i].Int64 - if !featureNamespaceMap[f.PotentialNamespace].Valid { - return database.ErrMissingEntities - } - namespaceID := featureNamespaceMap[f.PotentialNamespace].Int64 + namespaceID = featureNamespaceMap[f.PotentialNamespace] dbFeatures = append(dbFeatures, dbLayerFeature{layerID, featureID, detectorID, namespaceID}) } @@ -249,6 +248,7 @@ func (tx *pgSession) persistLayerFeatures(features []dbLayerFeature) error { return features[i].featureID < features[j].featureID }) keys := make([]interface{}, 0, len(features)*4) + for _, f := range features { keys = append(keys, f.layerID, f.featureID, f.detectorID, f.namespaceID) } diff --git a/database/pgsql/layer_test.go b/database/pgsql/layer_test.go index 5211eb11..86ada23e 100644 --- a/database/pgsql/layer_test.go +++ b/database/pgsql/layer_test.go @@ -41,7 +41,7 @@ var persistLayerTests = []struct { name: "random-forest", by: []database.Detector{realDetectors[2]}, features: []database.LayerFeature{ - {realFeatures[1], realDetectors[1]}, + {realFeatures[1], realDetectors[1], database.Namespace{}}, }, err: "parameters are not valid", }, @@ -51,7 +51,7 @@ var persistLayerTests = []struct { err: "associated immutable entities are missing in the database", by: []database.Detector{realDetectors[2]}, features: []database.LayerFeature{ - {fakeFeatures[1], realDetectors[2]}, + {fakeFeatures[1], realDetectors[2], database.Namespace{}}, }, }, { @@ -74,8 +74,8 @@ var persistLayerTests = []struct { name: "hamsterhouse", by: []database.Detector{realDetectors[1], realDetectors[2]}, features: []database.LayerFeature{ - {realFeatures[1], realDetectors[2]}, - {realFeatures[2], realDetectors[2]}, + {realFeatures[1], realDetectors[2], database.Namespace{}}, + {realFeatures[2], realDetectors[2], database.Namespace{}}, }, namespaces: []database.LayerNamespace{ {realNamespaces[1], realDetectors[1]}, @@ -84,8 +84,8 @@ var persistLayerTests = []struct { Hash: "hamsterhouse", By: []database.Detector{realDetectors[1], realDetectors[2]}, Features: []database.LayerFeature{ - {realFeatures[1], realDetectors[2]}, - {realFeatures[2], realDetectors[2]}, + {realFeatures[1], realDetectors[2], database.Namespace{}}, + {realFeatures[2], realDetectors[2], database.Namespace{}}, }, Namespaces: []database.LayerNamespace{ {realNamespaces[1], realDetectors[1]}, @@ -97,7 +97,7 @@ var persistLayerTests = []struct { name: "layer-1", by: []database.Detector{realDetectors[3], realDetectors[4]}, features: []database.LayerFeature{ - {realFeatures[4], realDetectors[3]}, + {realFeatures[4], realDetectors[3], database.Namespace{}}, }, namespaces: []database.LayerNamespace{ {realNamespaces[3], realDetectors[4]}, @@ -106,9 +106,9 @@ var persistLayerTests = []struct { Hash: "layer-1", By: []database.Detector{realDetectors[1], realDetectors[2], realDetectors[3], realDetectors[4]}, Features: []database.LayerFeature{ - {realFeatures[1], realDetectors[2]}, - {realFeatures[2], realDetectors[2]}, - {realFeatures[4], realDetectors[3]}, + {realFeatures[1], realDetectors[2], database.Namespace{}}, + {realFeatures[2], realDetectors[2], database.Namespace{}}, + {realFeatures[4], realDetectors[3], database.Namespace{}}, }, Namespaces: []database.LayerNamespace{ {realNamespaces[1], realDetectors[1]}, diff --git a/database/pgsql/testutil.go b/database/pgsql/testutil.go index 475a1b43..d6ceb145 100644 --- a/database/pgsql/testutil.go +++ b/database/pgsql/testutil.go @@ -38,11 +38,11 @@ import ( // int keys must be the consistent with the database ID. var ( realFeatures = map[int]database.Feature{ - 1: {"ourchat", "0.5", "dpkg", "source", database.Namespace{}}, - 2: {"openssl", "1.0", "dpkg", "source", database.Namespace{}}, - 3: {"openssl", "2.0", "dpkg", "source", database.Namespace{}}, - 4: {"fake", "2.0", "rpm", "source", database.Namespace{}}, - 5: {"mount", "2.31.1-0.4ubuntu3.1", "dpkg", "binary", database.Namespace{}}, + 1: {"ourchat", "0.5", "dpkg", "source"}, + 2: {"openssl", "1.0", "dpkg", "source"}, + 3: {"openssl", "2.0", "dpkg", "source"}, + 4: {"fake", "2.0", "rpm", "source"}, + 5: {"mount", "2.31.1-0.4ubuntu3.1", "dpkg", "binary"}, } realNamespaces = map[int]database.Namespace{ @@ -70,8 +70,8 @@ var ( Hash: "layer-1", By: []database.Detector{realDetectors[1], realDetectors[2]}, Features: []database.LayerFeature{ - {realFeatures[1], realDetectors[2]}, - {realFeatures[2], realDetectors[2]}, + {realFeatures[1], realDetectors[2], database.Namespace{}}, + {realFeatures[2], realDetectors[2], database.Namespace{}}, }, Namespaces: []database.LayerNamespace{ {realNamespaces[1], realDetectors[1]}, @@ -81,8 +81,8 @@ var ( Hash: "layer-4", By: []database.Detector{realDetectors[1], realDetectors[2], realDetectors[3], realDetectors[4]}, Features: []database.LayerFeature{ - {realFeatures[4], realDetectors[3]}, - {realFeatures[3], realDetectors[2]}, + {realFeatures[4], realDetectors[3], database.Namespace{}}, + {realFeatures[3], realDetectors[2], database.Namespace{}}, }, Namespaces: []database.LayerNamespace{ {realNamespaces[1], realDetectors[1]}, diff --git a/ext/featurefmt/apk/apk.go b/ext/featurefmt/apk/apk.go index 6389b825..dcc9f5eb 100644 --- a/ext/featurefmt/apk/apk.go +++ b/ext/featurefmt/apk/apk.go @@ -39,10 +39,10 @@ func valid(pkg *database.Feature) bool { return pkg.Name != "" && pkg.Version != "" } -func (l lister) ListFeatures(files tarutil.FilesMap) ([]database.Feature, error) { +func (l lister) ListFeatures(files tarutil.FilesMap) ([]database.LayerFeature, error) { file, exists := files["lib/apk/db/installed"] if !exists { - return []database.Feature{}, nil + return []database.LayerFeature{}, nil } // Iterate over each line in the "installed" file attempting to parse each @@ -86,7 +86,7 @@ func (l lister) ListFeatures(files tarutil.FilesMap) ([]database.Feature, error) packages.Add(pkg) } - return database.ConvertFeatureSetToFeatures(packages), nil + return database.ConvertFeatureSerToLayerFeatures(packages), nil } func (l lister) RequiredFilenames() []string { diff --git a/ext/featurefmt/apk/apk_test.go b/ext/featurefmt/apk/apk_test.go index ef9fcb24..24b2c81e 100644 --- a/ext/featurefmt/apk/apk_test.go +++ b/ext/featurefmt/apk/apk_test.go @@ -27,18 +27,18 @@ func TestAPKFeatureDetection(t *testing.T) { { "valid case", map[string]string{"lib/apk/db/installed": "apk/testdata/valid"}, - []database.Feature{ - {"apk-tools", "2.6.7-r0", "dpkg", "binary", database.Namespace{}}, - {"musl", "1.1.14-r10", "dpkg", "binary", database.Namespace{}}, - {"libssl1.0", "1.0.2h-r1", "dpkg", "binary", database.Namespace{}}, - {"libc-utils", "0.7-r0", "dpkg", "binary", database.Namespace{}}, - {"busybox", "1.24.2-r9", "dpkg", "binary", database.Namespace{}}, - {"scanelf", "1.1.6-r0", "dpkg", "binary", database.Namespace{}}, - {"alpine-keys", "1.1-r0", "dpkg", "binary", database.Namespace{}}, - {"libcrypto1.0", "1.0.2h-r1", "dpkg", "binary", database.Namespace{}}, - {"zlib", "1.2.8-r2", "dpkg", "binary", database.Namespace{}}, - {"musl-utils", "1.1.14-r10", "dpkg", "binary", database.Namespace{}}, - {"alpine-baselayout", "3.0.3-r0", "dpkg", "binary", database.Namespace{}}, + []database.LayerFeature{ + {Feature: database.Feature{"apk-tools", "2.6.7-r0", "dpkg", "binary"}}, + {Feature: database.Feature{"musl", "1.1.14-r10", "dpkg", "binary"}}, + {Feature: database.Feature{"libssl1.0", "1.0.2h-r1", "dpkg", "binary"}}, + {Feature: database.Feature{"libc-utils", "0.7-r0", "dpkg", "binary"}}, + {Feature: database.Feature{"busybox", "1.24.2-r9", "dpkg", "binary"}}, + {Feature: database.Feature{"scanelf", "1.1.6-r0", "dpkg", "binary"}}, + {Feature: database.Feature{"alpine-keys", "1.1-r0", "dpkg", "binary"}}, + {Feature: database.Feature{"libcrypto1.0", "1.0.2h-r1", "dpkg", "binary"}}, + {Feature: database.Feature{"zlib", "1.2.8-r2", "dpkg", "binary"}}, + {Feature: database.Feature{"musl-utils", "1.1.14-r10", "dpkg", "binary"}}, + {Feature: database.Feature{"alpine-baselayout", "3.0.3-r0", "dpkg", "binary"}}, }, }, } { diff --git a/ext/featurefmt/dpkg/dpkg.go b/ext/featurefmt/dpkg/dpkg.go index 829b3813..2b5fd876 100644 --- a/ext/featurefmt/dpkg/dpkg.go +++ b/ext/featurefmt/dpkg/dpkg.go @@ -45,10 +45,10 @@ func init() { featurefmt.RegisterLister("dpkg", "1.0", &lister{}) } -func (l lister) ListFeatures(files tarutil.FilesMap) ([]database.Feature, error) { +func (l lister) ListFeatures(files tarutil.FilesMap) ([]database.LayerFeature, error) { f, hasFile := files["var/lib/dpkg/status"] if !hasFile { - return []database.Feature{}, nil + return []database.LayerFeature{}, nil } packages := mapset.NewSet() @@ -69,7 +69,7 @@ func (l lister) ListFeatures(files tarutil.FilesMap) ([]database.Feature, error) } } - return database.ConvertFeatureSetToFeatures(packages), nil + return database.ConvertFeatureSerToLayerFeatures(packages), nil } // parseDpkgDB consumes the status file scanner exactly one package info, until @@ -123,7 +123,7 @@ func parseDpkgDB(scanner *bufio.Scanner) (binaryPackage *database.Feature, sourc if err := versionfmt.Valid(dpkg.ParserName, version); err != nil { log.WithError(err).WithFields(log.Fields{"name": name, "version": version}).Warning("skipped unparseable package") } else { - binaryPackage = &database.Feature{name, version, dpkg.ParserName, database.BinaryPackage, database.Namespace{}} + binaryPackage = &database.Feature{name, version, dpkg.ParserName, database.BinaryPackage} } } @@ -145,7 +145,7 @@ func parseDpkgDB(scanner *bufio.Scanner) (binaryPackage *database.Feature, sourc if err := versionfmt.Valid(dpkg.ParserName, version); err != nil { log.WithError(err).WithFields(log.Fields{"name": name, "version": version}).Warning("skipped unparseable package") } else { - sourcePackage = &database.Feature{sourceName, sourceVersion, dpkg.ParserName, database.SourcePackage, database.Namespace{}} + sourcePackage = &database.Feature{sourceName, sourceVersion, dpkg.ParserName, database.SourcePackage} } } diff --git a/ext/featurefmt/dpkg/dpkg_test.go b/ext/featurefmt/dpkg/dpkg_test.go index 7039e3f9..2c925f0a 100644 --- a/ext/featurefmt/dpkg/dpkg_test.go +++ b/ext/featurefmt/dpkg/dpkg_test.go @@ -27,169 +27,169 @@ func TestListFeatures(t *testing.T) { { "valid status file", map[string]string{"var/lib/dpkg/status": "dpkg/testdata/valid"}, - []database.Feature{ - {"libapt-pkg5.0", "1.6.3ubuntu0.1", "dpkg", "binary", database.Namespace{}}, - {"perl-base", "5.26.1-6ubuntu0.2", "dpkg", "binary", database.Namespace{}}, - {"libmount1", "2.31.1-0.4ubuntu3.1", "dpkg", "binary", database.Namespace{}}, - {"perl", "5.26.1-6ubuntu0.2", "dpkg", "source", database.Namespace{}}, - {"libgnutls30", "3.5.18-1ubuntu1", "dpkg", "binary", database.Namespace{}}, - {"liblzma5", "5.2.2-1.3", "dpkg", "binary", database.Namespace{}}, - {"ncurses-bin", "6.1-1ubuntu1.18.04", "dpkg", "binary", database.Namespace{}}, - {"lsb", "9.20170808ubuntu1", "dpkg", "source", database.Namespace{}}, - {"sed", "4.4-2", "dpkg", "source", database.Namespace{}}, - {"libsystemd0", "237-3ubuntu10.3", "dpkg", "binary", database.Namespace{}}, - {"procps", "2:3.3.12-3ubuntu1.1", "dpkg", "source", database.Namespace{}}, - {"login", "1:4.5-1ubuntu1", "dpkg", "binary", database.Namespace{}}, - {"libunistring2", "0.9.9-0ubuntu1", "dpkg", "binary", database.Namespace{}}, - {"sed", "4.4-2", "dpkg", "binary", database.Namespace{}}, - {"libselinux", "2.7-2build2", "dpkg", "source", database.Namespace{}}, - {"libseccomp", "2.3.1-2.1ubuntu4", "dpkg", "source", database.Namespace{}}, - {"libss2", "1.44.1-1", "dpkg", "binary", database.Namespace{}}, - {"liblz4-1", "0.0~r131-2ubuntu3", "dpkg", "binary", database.Namespace{}}, - {"libsemanage1", "2.7-2build2", "dpkg", "binary", database.Namespace{}}, - {"libtasn1-6", "4.13-2", "dpkg", "source", database.Namespace{}}, - {"libzstd1", "1.3.3+dfsg-2ubuntu1", "dpkg", "binary", database.Namespace{}}, - {"fdisk", "2.31.1-0.4ubuntu3.1", "dpkg", "binary", database.Namespace{}}, - {"xz-utils", "5.2.2-1.3", "dpkg", "source", database.Namespace{}}, - {"lsb-base", "9.20170808ubuntu1", "dpkg", "binary", database.Namespace{}}, - {"libpam-modules-bin", "1.1.8-3.6ubuntu2", "dpkg", "binary", database.Namespace{}}, - {"dash", "0.5.8-2.10", "dpkg", "binary", database.Namespace{}}, - {"gnupg2", "2.2.4-1ubuntu1.1", "dpkg", "source", database.Namespace{}}, - {"libfdisk1", "2.31.1-0.4ubuntu3.1", "dpkg", "binary", database.Namespace{}}, - {"lz4", "0.0~r131-2ubuntu3", "dpkg", "source", database.Namespace{}}, - {"libpam0g", "1.1.8-3.6ubuntu2", "dpkg", "binary", database.Namespace{}}, - {"libc-bin", "2.27-3ubuntu1", "dpkg", "binary", database.Namespace{}}, - {"libcap-ng", "0.7.7-3.1", "dpkg", "source", database.Namespace{}}, - {"libcom-err2", "1.44.1-1", "dpkg", "binary", database.Namespace{}}, - {"libudev1", "237-3ubuntu10.3", "dpkg", "binary", database.Namespace{}}, - {"debconf", "1.5.66", "dpkg", "binary", database.Namespace{}}, - {"tar", "1.29b-2", "dpkg", "binary", database.Namespace{}}, - {"diffutils", "1:3.6-1", "dpkg", "source", database.Namespace{}}, - {"gcc-8", "8-20180414-1ubuntu2", "dpkg", "source", database.Namespace{}}, - {"e2fsprogs", "1.44.1-1", "dpkg", "source", database.Namespace{}}, - {"bzip2", "1.0.6-8.1", "dpkg", "source", database.Namespace{}}, - {"diffutils", "1:3.6-1", "dpkg", "binary", database.Namespace{}}, - {"grep", "3.1-2", "dpkg", "binary", database.Namespace{}}, - {"libgcc1", "1:8-20180414-1ubuntu2", "dpkg", "binary", database.Namespace{}}, - {"bash", "4.4.18-2ubuntu1", "dpkg", "source", database.Namespace{}}, - {"libtinfo5", "6.1-1ubuntu1.18.04", "dpkg", "binary", database.Namespace{}}, - {"procps", "2:3.3.12-3ubuntu1.1", "dpkg", "binary", database.Namespace{}}, - {"bzip2", "1.0.6-8.1", "dpkg", "binary", database.Namespace{}}, - {"init-system-helpers", "1.51", "dpkg", "binary", database.Namespace{}}, - {"libncursesw5", "6.1-1ubuntu1.18.04", "dpkg", "binary", database.Namespace{}}, - {"init-system-helpers", "1.51", "dpkg", "source", database.Namespace{}}, - {"libpam-modules", "1.1.8-3.6ubuntu2", "dpkg", "binary", database.Namespace{}}, - {"libext2fs2", "1.44.1-1", "dpkg", "binary", database.Namespace{}}, - {"libacl1", "2.2.52-3build1", "dpkg", "binary", database.Namespace{}}, - {"hostname", "3.20", "dpkg", "binary", database.Namespace{}}, - {"libgpg-error", "1.27-6", "dpkg", "source", database.Namespace{}}, - {"acl", "2.2.52-3build1", "dpkg", "source", database.Namespace{}}, - {"apt", "1.6.3ubuntu0.1", "dpkg", "binary", database.Namespace{}}, - {"base-files", "10.1ubuntu2.2", "dpkg", "source", database.Namespace{}}, - {"libgpg-error0", "1.27-6", "dpkg", "binary", database.Namespace{}}, - {"audit", "1:2.8.2-1ubuntu1", "dpkg", "source", database.Namespace{}}, - {"hostname", "3.20", "dpkg", "source", database.Namespace{}}, - {"gzip", "1.6-5ubuntu1", "dpkg", "binary", database.Namespace{}}, - {"libc6", "2.27-3ubuntu1", "dpkg", "binary", database.Namespace{}}, - {"libnettle6", "3.4-1", "dpkg", "binary", database.Namespace{}}, - {"sysvinit-utils", "2.88dsf-59.10ubuntu1", "dpkg", "binary", database.Namespace{}}, - {"debianutils", "4.8.4", "dpkg", "source", database.Namespace{}}, - {"libstdc++6", "8-20180414-1ubuntu2", "dpkg", "binary", database.Namespace{}}, - {"libsepol", "2.7-1", "dpkg", "source", database.Namespace{}}, - {"libpcre3", "2:8.39-9", "dpkg", "binary", database.Namespace{}}, - {"libuuid1", "2.31.1-0.4ubuntu3.1", "dpkg", "binary", database.Namespace{}}, - {"systemd", "237-3ubuntu10.3", "dpkg", "source", database.Namespace{}}, - {"tar", "1.29b-2", "dpkg", "source", database.Namespace{}}, - {"ubuntu-keyring", "2018.02.28", "dpkg", "source", database.Namespace{}}, - {"passwd", "1:4.5-1ubuntu1", "dpkg", "binary", database.Namespace{}}, - {"sysvinit", "2.88dsf-59.10ubuntu1", "dpkg", "source", database.Namespace{}}, - {"libidn2-0", "2.0.4-1.1build2", "dpkg", "binary", database.Namespace{}}, - {"libhogweed4", "3.4-1", "dpkg", "binary", database.Namespace{}}, - {"db5.3", "5.3.28-13.1ubuntu1", "dpkg", "source", database.Namespace{}}, - {"sensible-utils", "0.0.12", "dpkg", "source", database.Namespace{}}, - {"dpkg", "1.19.0.5ubuntu2", "dpkg", "source", database.Namespace{}}, - {"libp11-kit0", "0.23.9-2", "dpkg", "binary", database.Namespace{}}, - {"glibc", "2.27-3ubuntu1", "dpkg", "source", database.Namespace{}}, - {"mount", "2.31.1-0.4ubuntu3.1", "dpkg", "binary", database.Namespace{}}, - {"libsemanage-common", "2.7-2build2", "dpkg", "binary", database.Namespace{}}, - {"libblkid1", "2.31.1-0.4ubuntu3.1", "dpkg", "binary", database.Namespace{}}, - {"libdebconfclient0", "0.213ubuntu1", "dpkg", "binary", database.Namespace{}}, - {"libffi", "3.2.1-8", "dpkg", "source", database.Namespace{}}, - {"pam", "1.1.8-3.6ubuntu2", "dpkg", "source", database.Namespace{}}, - {"bsdutils", "1:2.31.1-0.4ubuntu3.1", "dpkg", "binary", database.Namespace{}}, - {"libtasn1-6", "4.13-2", "dpkg", "binary", database.Namespace{}}, - {"libaudit-common", "1:2.8.2-1ubuntu1", "dpkg", "binary", database.Namespace{}}, - {"gpgv", "2.2.4-1ubuntu1.1", "dpkg", "binary", database.Namespace{}}, - {"libzstd", "1.3.3+dfsg-2ubuntu1", "dpkg", "source", database.Namespace{}}, - {"base-passwd", "3.5.44", "dpkg", "source", database.Namespace{}}, - {"adduser", "3.116ubuntu1", "dpkg", "binary", database.Namespace{}}, - {"libattr1", "1:2.4.47-2build1", "dpkg", "binary", database.Namespace{}}, - {"libncurses5", "6.1-1ubuntu1.18.04", "dpkg", "binary", database.Namespace{}}, - {"coreutils", "8.28-1ubuntu1", "dpkg", "binary", database.Namespace{}}, - {"base-passwd", "3.5.44", "dpkg", "binary", database.Namespace{}}, - {"ubuntu-keyring", "2018.02.28", "dpkg", "binary", database.Namespace{}}, - {"adduser", "3.116ubuntu1", "dpkg", "source", database.Namespace{}}, - {"libsmartcols1", "2.31.1-0.4ubuntu3.1", "dpkg", "binary", database.Namespace{}}, - {"libunistring", "0.9.9-0ubuntu1", "dpkg", "source", database.Namespace{}}, - {"mawk", "1.3.3-17ubuntu3", "dpkg", "source", database.Namespace{}}, - {"coreutils", "8.28-1ubuntu1", "dpkg", "source", database.Namespace{}}, - {"attr", "1:2.4.47-2build1", "dpkg", "source", database.Namespace{}}, - {"gmp", "2:6.1.2+dfsg-2", "dpkg", "source", database.Namespace{}}, - {"libsemanage", "2.7-2build2", "dpkg", "source", database.Namespace{}}, - {"libselinux1", "2.7-2build2", "dpkg", "binary", database.Namespace{}}, - {"libseccomp2", "2.3.1-2.1ubuntu4", "dpkg", "binary", database.Namespace{}}, - {"zlib1g", "1:1.2.11.dfsg-0ubuntu2", "dpkg", "binary", database.Namespace{}}, - {"dash", "0.5.8-2.10", "dpkg", "source", database.Namespace{}}, - {"gnutls28", "3.5.18-1ubuntu1", "dpkg", "source", database.Namespace{}}, - {"libpam-runtime", "1.1.8-3.6ubuntu2", "dpkg", "binary", database.Namespace{}}, - {"libgcrypt20", "1.8.1-4ubuntu1.1", "dpkg", "source", database.Namespace{}}, - {"sensible-utils", "0.0.12", "dpkg", "binary", database.Namespace{}}, - {"p11-kit", "0.23.9-2", "dpkg", "source", database.Namespace{}}, - {"ncurses-base", "6.1-1ubuntu1.18.04", "dpkg", "binary", database.Namespace{}}, - {"e2fsprogs", "1.44.1-1", "dpkg", "binary", database.Namespace{}}, - {"libgcrypt20", "1.8.1-4ubuntu1.1", "dpkg", "binary", database.Namespace{}}, - {"libprocps6", "2:3.3.12-3ubuntu1.1", "dpkg", "binary", database.Namespace{}}, - {"debconf", "1.5.66", "dpkg", "source", database.Namespace{}}, - {"gcc-8-base", "8-20180414-1ubuntu2", "dpkg", "binary", database.Namespace{}}, - {"base-files", "10.1ubuntu2.2", "dpkg", "binary", database.Namespace{}}, - {"libbz2-1.0", "1.0.6-8.1", "dpkg", "binary", database.Namespace{}}, - {"grep", "3.1-2", "dpkg", "source", database.Namespace{}}, - {"bash", "4.4.18-2ubuntu1", "dpkg", "binary", database.Namespace{}}, - {"libgmp10", "2:6.1.2+dfsg-2", "dpkg", "binary", database.Namespace{}}, - {"shadow", "1:4.5-1ubuntu1", "dpkg", "source", database.Namespace{}}, - {"libidn2", "2.0.4-1.1build2", "dpkg", "source", database.Namespace{}}, - {"gzip", "1.6-5ubuntu1", "dpkg", "source", database.Namespace{}}, - {"util-linux", "2.31.1-0.4ubuntu3.1", "dpkg", "binary", database.Namespace{}}, - {"libaudit1", "1:2.8.2-1ubuntu1", "dpkg", "binary", database.Namespace{}}, - {"libsepol1", "2.7-1", "dpkg", "binary", database.Namespace{}}, - {"pcre3", "2:8.39-9", "dpkg", "source", database.Namespace{}}, - {"apt", "1.6.3ubuntu0.1", "dpkg", "source", database.Namespace{}}, - {"nettle", "3.4-1", "dpkg", "source", database.Namespace{}}, - {"util-linux", "2.31.1-0.4ubuntu3.1", "dpkg", "source", database.Namespace{}}, - {"libcap-ng0", "0.7.7-3.1", "dpkg", "binary", database.Namespace{}}, - {"debianutils", "4.8.4", "dpkg", "binary", database.Namespace{}}, - {"ncurses", "6.1-1ubuntu1.18.04", "dpkg", "source", database.Namespace{}}, - {"libffi6", "3.2.1-8", "dpkg", "binary", database.Namespace{}}, - {"cdebconf", "0.213ubuntu1", "dpkg", "source", database.Namespace{}}, - {"findutils", "4.6.0+git+20170828-2", "dpkg", "source", database.Namespace{}}, - {"libdb5.3", "5.3.28-13.1ubuntu1", "dpkg", "binary", database.Namespace{}}, - {"zlib", "1:1.2.11.dfsg-0ubuntu2", "dpkg", "source", database.Namespace{}}, - {"findutils", "4.6.0+git+20170828-2", "dpkg", "binary", database.Namespace{}}, - {"dpkg", "1.19.0.5ubuntu2", "dpkg", "binary", database.Namespace{}}, - {"mawk", "1.3.3-17ubuntu3", "dpkg", "binary", database.Namespace{}}, + []database.LayerFeature{ + {Feature: database.Feature{"libapt-pkg5.0", "1.6.3ubuntu0.1", "dpkg", "binary"}}, + {Feature: database.Feature{"perl-base", "5.26.1-6ubuntu0.2", "dpkg", "binary"}}, + {Feature: database.Feature{"libmount1", "2.31.1-0.4ubuntu3.1", "dpkg", "binary"}}, + {Feature: database.Feature{"perl", "5.26.1-6ubuntu0.2", "dpkg", "source"}}, + {Feature: database.Feature{"libgnutls30", "3.5.18-1ubuntu1", "dpkg", "binary"}}, + {Feature: database.Feature{"liblzma5", "5.2.2-1.3", "dpkg", "binary"}}, + {Feature: database.Feature{"ncurses-bin", "6.1-1ubuntu1.18.04", "dpkg", "binary"}}, + {Feature: database.Feature{"lsb", "9.20170808ubuntu1", "dpkg", "source"}}, + {Feature: database.Feature{"sed", "4.4-2", "dpkg", "source"}}, + {Feature: database.Feature{"libsystemd0", "237-3ubuntu10.3", "dpkg", "binary"}}, + {Feature: database.Feature{"procps", "2:3.3.12-3ubuntu1.1", "dpkg", "source"}}, + {Feature: database.Feature{"login", "1:4.5-1ubuntu1", "dpkg", "binary"}}, + {Feature: database.Feature{"libunistring2", "0.9.9-0ubuntu1", "dpkg", "binary"}}, + {Feature: database.Feature{"sed", "4.4-2", "dpkg", "binary"}}, + {Feature: database.Feature{"libselinux", "2.7-2build2", "dpkg", "source"}}, + {Feature: database.Feature{"libseccomp", "2.3.1-2.1ubuntu4", "dpkg", "source"}}, + {Feature: database.Feature{"libss2", "1.44.1-1", "dpkg", "binary"}}, + {Feature: database.Feature{"liblz4-1", "0.0~r131-2ubuntu3", "dpkg", "binary"}}, + {Feature: database.Feature{"libsemanage1", "2.7-2build2", "dpkg", "binary"}}, + {Feature: database.Feature{"libtasn1-6", "4.13-2", "dpkg", "source"}}, + {Feature: database.Feature{"libzstd1", "1.3.3+dfsg-2ubuntu1", "dpkg", "binary"}}, + {Feature: database.Feature{"fdisk", "2.31.1-0.4ubuntu3.1", "dpkg", "binary"}}, + {Feature: database.Feature{"xz-utils", "5.2.2-1.3", "dpkg", "source"}}, + {Feature: database.Feature{"lsb-base", "9.20170808ubuntu1", "dpkg", "binary"}}, + {Feature: database.Feature{"libpam-modules-bin", "1.1.8-3.6ubuntu2", "dpkg", "binary"}}, + {Feature: database.Feature{"dash", "0.5.8-2.10", "dpkg", "binary"}}, + {Feature: database.Feature{"gnupg2", "2.2.4-1ubuntu1.1", "dpkg", "source"}}, + {Feature: database.Feature{"libfdisk1", "2.31.1-0.4ubuntu3.1", "dpkg", "binary"}}, + {Feature: database.Feature{"lz4", "0.0~r131-2ubuntu3", "dpkg", "source"}}, + {Feature: database.Feature{"libpam0g", "1.1.8-3.6ubuntu2", "dpkg", "binary"}}, + {Feature: database.Feature{"libc-bin", "2.27-3ubuntu1", "dpkg", "binary"}}, + {Feature: database.Feature{"libcap-ng", "0.7.7-3.1", "dpkg", "source"}}, + {Feature: database.Feature{"libcom-err2", "1.44.1-1", "dpkg", "binary"}}, + {Feature: database.Feature{"libudev1", "237-3ubuntu10.3", "dpkg", "binary"}}, + {Feature: database.Feature{"debconf", "1.5.66", "dpkg", "binary"}}, + {Feature: database.Feature{"tar", "1.29b-2", "dpkg", "binary"}}, + {Feature: database.Feature{"diffutils", "1:3.6-1", "dpkg", "source"}}, + {Feature: database.Feature{"gcc-8", "8-20180414-1ubuntu2", "dpkg", "source"}}, + {Feature: database.Feature{"e2fsprogs", "1.44.1-1", "dpkg", "source"}}, + {Feature: database.Feature{"bzip2", "1.0.6-8.1", "dpkg", "source"}}, + {Feature: database.Feature{"diffutils", "1:3.6-1", "dpkg", "binary"}}, + {Feature: database.Feature{"grep", "3.1-2", "dpkg", "binary"}}, + {Feature: database.Feature{"libgcc1", "1:8-20180414-1ubuntu2", "dpkg", "binary"}}, + {Feature: database.Feature{"bash", "4.4.18-2ubuntu1", "dpkg", "source"}}, + {Feature: database.Feature{"libtinfo5", "6.1-1ubuntu1.18.04", "dpkg", "binary"}}, + {Feature: database.Feature{"procps", "2:3.3.12-3ubuntu1.1", "dpkg", "binary"}}, + {Feature: database.Feature{"bzip2", "1.0.6-8.1", "dpkg", "binary"}}, + {Feature: database.Feature{"init-system-helpers", "1.51", "dpkg", "binary"}}, + {Feature: database.Feature{"libncursesw5", "6.1-1ubuntu1.18.04", "dpkg", "binary"}}, + {Feature: database.Feature{"init-system-helpers", "1.51", "dpkg", "source"}}, + {Feature: database.Feature{"libpam-modules", "1.1.8-3.6ubuntu2", "dpkg", "binary"}}, + {Feature: database.Feature{"libext2fs2", "1.44.1-1", "dpkg", "binary"}}, + {Feature: database.Feature{"libacl1", "2.2.52-3build1", "dpkg", "binary"}}, + {Feature: database.Feature{"hostname", "3.20", "dpkg", "binary"}}, + {Feature: database.Feature{"libgpg-error", "1.27-6", "dpkg", "source"}}, + {Feature: database.Feature{"acl", "2.2.52-3build1", "dpkg", "source"}}, + {Feature: database.Feature{"apt", "1.6.3ubuntu0.1", "dpkg", "binary"}}, + {Feature: database.Feature{"base-files", "10.1ubuntu2.2", "dpkg", "source"}}, + {Feature: database.Feature{"libgpg-error0", "1.27-6", "dpkg", "binary"}}, + {Feature: database.Feature{"audit", "1:2.8.2-1ubuntu1", "dpkg", "source"}}, + {Feature: database.Feature{"hostname", "3.20", "dpkg", "source"}}, + {Feature: database.Feature{"gzip", "1.6-5ubuntu1", "dpkg", "binary"}}, + {Feature: database.Feature{"libc6", "2.27-3ubuntu1", "dpkg", "binary"}}, + {Feature: database.Feature{"libnettle6", "3.4-1", "dpkg", "binary"}}, + {Feature: database.Feature{"sysvinit-utils", "2.88dsf-59.10ubuntu1", "dpkg", "binary"}}, + {Feature: database.Feature{"debianutils", "4.8.4", "dpkg", "source"}}, + {Feature: database.Feature{"libstdc++6", "8-20180414-1ubuntu2", "dpkg", "binary"}}, + {Feature: database.Feature{"libsepol", "2.7-1", "dpkg", "source"}}, + {Feature: database.Feature{"libpcre3", "2:8.39-9", "dpkg", "binary"}}, + {Feature: database.Feature{"libuuid1", "2.31.1-0.4ubuntu3.1", "dpkg", "binary"}}, + {Feature: database.Feature{"systemd", "237-3ubuntu10.3", "dpkg", "source"}}, + {Feature: database.Feature{"tar", "1.29b-2", "dpkg", "source"}}, + {Feature: database.Feature{"ubuntu-keyring", "2018.02.28", "dpkg", "source"}}, + {Feature: database.Feature{"passwd", "1:4.5-1ubuntu1", "dpkg", "binary"}}, + {Feature: database.Feature{"sysvinit", "2.88dsf-59.10ubuntu1", "dpkg", "source"}}, + {Feature: database.Feature{"libidn2-0", "2.0.4-1.1build2", "dpkg", "binary"}}, + {Feature: database.Feature{"libhogweed4", "3.4-1", "dpkg", "binary"}}, + {Feature: database.Feature{"db5.3", "5.3.28-13.1ubuntu1", "dpkg", "source"}}, + {Feature: database.Feature{"sensible-utils", "0.0.12", "dpkg", "source"}}, + {Feature: database.Feature{"dpkg", "1.19.0.5ubuntu2", "dpkg", "source"}}, + {Feature: database.Feature{"libp11-kit0", "0.23.9-2", "dpkg", "binary"}}, + {Feature: database.Feature{"glibc", "2.27-3ubuntu1", "dpkg", "source"}}, + {Feature: database.Feature{"mount", "2.31.1-0.4ubuntu3.1", "dpkg", "binary"}}, + {Feature: database.Feature{"libsemanage-common", "2.7-2build2", "dpkg", "binary"}}, + {Feature: database.Feature{"libblkid1", "2.31.1-0.4ubuntu3.1", "dpkg", "binary"}}, + {Feature: database.Feature{"libdebconfclient0", "0.213ubuntu1", "dpkg", "binary"}}, + {Feature: database.Feature{"libffi", "3.2.1-8", "dpkg", "source"}}, + {Feature: database.Feature{"pam", "1.1.8-3.6ubuntu2", "dpkg", "source"}}, + {Feature: database.Feature{"bsdutils", "1:2.31.1-0.4ubuntu3.1", "dpkg", "binary"}}, + {Feature: database.Feature{"libtasn1-6", "4.13-2", "dpkg", "binary"}}, + {Feature: database.Feature{"libaudit-common", "1:2.8.2-1ubuntu1", "dpkg", "binary"}}, + {Feature: database.Feature{"gpgv", "2.2.4-1ubuntu1.1", "dpkg", "binary"}}, + {Feature: database.Feature{"libzstd", "1.3.3+dfsg-2ubuntu1", "dpkg", "source"}}, + {Feature: database.Feature{"base-passwd", "3.5.44", "dpkg", "source"}}, + {Feature: database.Feature{"adduser", "3.116ubuntu1", "dpkg", "binary"}}, + {Feature: database.Feature{"libattr1", "1:2.4.47-2build1", "dpkg", "binary"}}, + {Feature: database.Feature{"libncurses5", "6.1-1ubuntu1.18.04", "dpkg", "binary"}}, + {Feature: database.Feature{"coreutils", "8.28-1ubuntu1", "dpkg", "binary"}}, + {Feature: database.Feature{"base-passwd", "3.5.44", "dpkg", "binary"}}, + {Feature: database.Feature{"ubuntu-keyring", "2018.02.28", "dpkg", "binary"}}, + {Feature: database.Feature{"adduser", "3.116ubuntu1", "dpkg", "source"}}, + {Feature: database.Feature{"libsmartcols1", "2.31.1-0.4ubuntu3.1", "dpkg", "binary"}}, + {Feature: database.Feature{"libunistring", "0.9.9-0ubuntu1", "dpkg", "source"}}, + {Feature: database.Feature{"mawk", "1.3.3-17ubuntu3", "dpkg", "source"}}, + {Feature: database.Feature{"coreutils", "8.28-1ubuntu1", "dpkg", "source"}}, + {Feature: database.Feature{"attr", "1:2.4.47-2build1", "dpkg", "source"}}, + {Feature: database.Feature{"gmp", "2:6.1.2+dfsg-2", "dpkg", "source"}}, + {Feature: database.Feature{"libsemanage", "2.7-2build2", "dpkg", "source"}}, + {Feature: database.Feature{"libselinux1", "2.7-2build2", "dpkg", "binary"}}, + {Feature: database.Feature{"libseccomp2", "2.3.1-2.1ubuntu4", "dpkg", "binary"}}, + {Feature: database.Feature{"zlib1g", "1:1.2.11.dfsg-0ubuntu2", "dpkg", "binary"}}, + {Feature: database.Feature{"dash", "0.5.8-2.10", "dpkg", "source"}}, + {Feature: database.Feature{"gnutls28", "3.5.18-1ubuntu1", "dpkg", "source"}}, + {Feature: database.Feature{"libpam-runtime", "1.1.8-3.6ubuntu2", "dpkg", "binary"}}, + {Feature: database.Feature{"libgcrypt20", "1.8.1-4ubuntu1.1", "dpkg", "source"}}, + {Feature: database.Feature{"sensible-utils", "0.0.12", "dpkg", "binary"}}, + {Feature: database.Feature{"p11-kit", "0.23.9-2", "dpkg", "source"}}, + {Feature: database.Feature{"ncurses-base", "6.1-1ubuntu1.18.04", "dpkg", "binary"}}, + {Feature: database.Feature{"e2fsprogs", "1.44.1-1", "dpkg", "binary"}}, + {Feature: database.Feature{"libgcrypt20", "1.8.1-4ubuntu1.1", "dpkg", "binary"}}, + {Feature: database.Feature{"libprocps6", "2:3.3.12-3ubuntu1.1", "dpkg", "binary"}}, + {Feature: database.Feature{"debconf", "1.5.66", "dpkg", "source"}}, + {Feature: database.Feature{"gcc-8-base", "8-20180414-1ubuntu2", "dpkg", "binary"}}, + {Feature: database.Feature{"base-files", "10.1ubuntu2.2", "dpkg", "binary"}}, + {Feature: database.Feature{"libbz2-1.0", "1.0.6-8.1", "dpkg", "binary"}}, + {Feature: database.Feature{"grep", "3.1-2", "dpkg", "source"}}, + {Feature: database.Feature{"bash", "4.4.18-2ubuntu1", "dpkg", "binary"}}, + {Feature: database.Feature{"libgmp10", "2:6.1.2+dfsg-2", "dpkg", "binary"}}, + {Feature: database.Feature{"shadow", "1:4.5-1ubuntu1", "dpkg", "source"}}, + {Feature: database.Feature{"libidn2", "2.0.4-1.1build2", "dpkg", "source"}}, + {Feature: database.Feature{"gzip", "1.6-5ubuntu1", "dpkg", "source"}}, + {Feature: database.Feature{"util-linux", "2.31.1-0.4ubuntu3.1", "dpkg", "binary"}}, + {Feature: database.Feature{"libaudit1", "1:2.8.2-1ubuntu1", "dpkg", "binary"}}, + {Feature: database.Feature{"libsepol1", "2.7-1", "dpkg", "binary"}}, + {Feature: database.Feature{"pcre3", "2:8.39-9", "dpkg", "source"}}, + {Feature: database.Feature{"apt", "1.6.3ubuntu0.1", "dpkg", "source"}}, + {Feature: database.Feature{"nettle", "3.4-1", "dpkg", "source"}}, + {Feature: database.Feature{"util-linux", "2.31.1-0.4ubuntu3.1", "dpkg", "source"}}, + {Feature: database.Feature{"libcap-ng0", "0.7.7-3.1", "dpkg", "binary"}}, + {Feature: database.Feature{"debianutils", "4.8.4", "dpkg", "binary"}}, + {Feature: database.Feature{"ncurses", "6.1-1ubuntu1.18.04", "dpkg", "source"}}, + {Feature: database.Feature{"libffi6", "3.2.1-8", "dpkg", "binary"}}, + {Feature: database.Feature{"cdebconf", "0.213ubuntu1", "dpkg", "source"}}, + {Feature: database.Feature{"findutils", "4.6.0+git+20170828-2", "dpkg", "source"}}, + {Feature: database.Feature{"libdb5.3", "5.3.28-13.1ubuntu1", "dpkg", "binary"}}, + {Feature: database.Feature{"zlib", "1:1.2.11.dfsg-0ubuntu2", "dpkg", "source"}}, + {Feature: database.Feature{"findutils", "4.6.0+git+20170828-2", "dpkg", "binary"}}, + {Feature: database.Feature{"dpkg", "1.19.0.5ubuntu2", "dpkg", "binary"}}, + {Feature: database.Feature{"mawk", "1.3.3-17ubuntu3", "dpkg", "binary"}}, }, }, { "corrupted status file", map[string]string{"var/lib/dpkg/status": "dpkg/testdata/corrupted"}, - []database.Feature{ - {"libpam-modules-bin", "1.1.8-3.1ubuntu3", "dpkg", "binary", database.Namespace{}}, - {"gcc-5", "5.1.1-12ubuntu1", "dpkg", "source", database.Namespace{}}, - {"makedev", "2.3.1-93ubuntu1", "dpkg", "binary", database.Namespace{}}, - {"libgcc1", "1:5.1.1-12ubuntu1", "dpkg", "binary", database.Namespace{}}, - {"pam", "1.1.8-3.1ubuntu3", "dpkg", "source", database.Namespace{}}, - {"makedev", "2.3.1-93ubuntu1", "dpkg", "source", database.Namespace{}}, - {"libpam-runtime", "1.1.8-3.1ubuntu3", "dpkg", "binary", database.Namespace{}}, + []database.LayerFeature{ + {Feature: database.Feature{"libpam-modules-bin", "1.1.8-3.1ubuntu3", "dpkg", "binary"}}, + {Feature: database.Feature{"gcc-5", "5.1.1-12ubuntu1", "dpkg", "source"}}, + {Feature: database.Feature{"makedev", "2.3.1-93ubuntu1", "dpkg", "binary"}}, + {Feature: database.Feature{"libgcc1", "1:5.1.1-12ubuntu1", "dpkg", "binary"}}, + {Feature: database.Feature{"pam", "1.1.8-3.1ubuntu3", "dpkg", "source"}}, + {Feature: database.Feature{"makedev", "2.3.1-93ubuntu1", "dpkg", "source"}}, + {Feature: database.Feature{"libpam-runtime", "1.1.8-3.1ubuntu3", "dpkg", "binary"}}, }, }, } { diff --git a/ext/featurefmt/driver.go b/ext/featurefmt/driver.go index 8263b3aa..524973dc 100644 --- a/ext/featurefmt/driver.go +++ b/ext/featurefmt/driver.go @@ -33,7 +33,7 @@ var ( // Lister represents an ability to list the features present in an image layer. type Lister interface { // ListFeatures produces a list of Features present in an image layer. - ListFeatures(tarutil.FilesMap) ([]database.Feature, error) + ListFeatures(tarutil.FilesMap) ([]database.LayerFeature, error) // RequiredFilenames returns the list of files required to be in the FilesMap // provided to the ListFeatures method. @@ -89,12 +89,10 @@ func ListFeatures(files tarutil.FilesMap, toUse []database.Detector) ([]database return nil, err } - for _, f := range fs { - features = append(features, database.LayerFeature{ - Feature: f, - By: lister.info, - }) + for i := range fs { + fs[i].By = lister.info } + features = append(features, fs...) } else { log.WithField("Name", d).Fatal("unknown feature detector") diff --git a/ext/featurefmt/rpm/rpm.go b/ext/featurefmt/rpm/rpm.go index f8ae887c..b85bc81f 100644 --- a/ext/featurefmt/rpm/rpm.go +++ b/ext/featurefmt/rpm/rpm.go @@ -59,10 +59,10 @@ func isIgnored(packageName string) bool { return false } -func (l lister) ListFeatures(files tarutil.FilesMap) ([]database.Feature, error) { +func (l lister) ListFeatures(files tarutil.FilesMap) ([]database.LayerFeature, error) { f, hasFile := files["var/lib/rpm/Packages"] if !hasFile { - return []database.Feature{}, nil + return []database.LayerFeature{}, nil } // Write the required "Packages" file to disk @@ -70,13 +70,13 @@ func (l lister) ListFeatures(files tarutil.FilesMap) ([]database.Feature, error) defer os.RemoveAll(tmpDir) if err != nil { log.WithError(err).Error("could not create temporary folder for RPM detection") - return []database.Feature{}, commonerr.ErrFilesystem + return []database.LayerFeature{}, commonerr.ErrFilesystem } err = ioutil.WriteFile(tmpDir+"/Packages", f, 0700) if err != nil { log.WithError(err).Error("could not create temporary file for RPM detection") - return []database.Feature{}, commonerr.ErrFilesystem + return []database.LayerFeature{}, commonerr.ErrFilesystem } // Extract binary package names because RHSA refers to binary package names. @@ -85,7 +85,7 @@ func (l lister) ListFeatures(files tarutil.FilesMap) ([]database.Feature, error) log.WithError(err).WithField("output", string(out)).Error("failed to query RPM") // Do not bubble up because we probably won't be able to fix it, // the database must be corrupted - return []database.Feature{}, nil + return []database.LayerFeature{}, nil } packages := mapset.NewSet() @@ -101,7 +101,7 @@ func (l lister) ListFeatures(files tarutil.FilesMap) ([]database.Feature, error) } } - return database.ConvertFeatureSetToFeatures(packages), nil + return database.ConvertFeatureSerToLayerFeatures(packages), nil } func parseRPMOutput(raw string) (rpmPackage *database.Feature, srpmPackage *database.Feature) { @@ -122,7 +122,7 @@ func parseRPMOutput(raw string) (rpmPackage *database.Feature, srpmPackage *data return } - rpmPackage = &database.Feature{name, version, rpm.ParserName, database.BinaryPackage, database.Namespace{}} + rpmPackage = &database.Feature{name, version, rpm.ParserName, database.BinaryPackage} srpmName, srpmVersion, srpmRelease, _, err := parseSourceRPM(srpm) if err != nil { log.WithError(err).WithFields(log.Fields{"name": name, "sourcerpm": srpm}).Warning("skipped unparseable package") @@ -134,7 +134,7 @@ func parseRPMOutput(raw string) (rpmPackage *database.Feature, srpmPackage *data return } - srpmPackage = &database.Feature{srpmName, srpmVersion, rpm.ParserName, database.SourcePackage, database.Namespace{}} + srpmPackage = &database.Feature{srpmName, srpmVersion, rpm.ParserName, database.SourcePackage} return } diff --git a/ext/featurefmt/rpm/rpm_test.go b/ext/featurefmt/rpm/rpm_test.go index b85b96d5..668f670c 100644 --- a/ext/featurefmt/rpm/rpm_test.go +++ b/ext/featurefmt/rpm/rpm_test.go @@ -24,308 +24,308 @@ import ( "github.com/coreos/clair/ext/versionfmt/rpm" ) -var expectedBigCaseInfo = []database.Feature{ - {"libmount", "2.32.1-1.fc28", "rpm", "binary", database.Namespace{}}, - {"libffi", "3.1-16.fc28", "rpm", "binary", database.Namespace{}}, - {"libunistring", "0.9.10-1.fc28", "rpm", "binary", database.Namespace{}}, - {"fedora-repos", "28-5", "rpm", "binary", database.Namespace{}}, - {"libarchive", "3.3.1-4.fc28", "rpm", "source", database.Namespace{}}, - {"langpacks", "1.0-12.fc28", "rpm", "source", database.Namespace{}}, - {"readline", "7.0-11.fc28", "rpm", "source", database.Namespace{}}, - {"gzip", "1.9-3.fc28", "rpm", "source", database.Namespace{}}, - {"libverto", "0.3.0-5.fc28", "rpm", "source", database.Namespace{}}, - {"ncurses-base", "6.1-5.20180224.fc28", "rpm", "binary", database.Namespace{}}, - {"libfdisk", "2.32.1-1.fc28", "rpm", "binary", database.Namespace{}}, - {"libselinux", "2.8-1.fc28", "rpm", "source", database.Namespace{}}, - {"nss-util", "3.38.0-1.0.fc28", "rpm", "source", database.Namespace{}}, - {"mpfr", "3.1.6-1.fc28", "rpm", "source", database.Namespace{}}, - {"libunistring", "0.9.10-1.fc28", "rpm", "source", database.Namespace{}}, - {"libpcap", "14:1.9.0-1.fc28", "rpm", "binary", database.Namespace{}}, - {"libarchive", "3.3.1-4.fc28", "rpm", "binary", database.Namespace{}}, - {"gmp", "1:6.1.2-7.fc28", "rpm", "binary", database.Namespace{}}, - {"crypto-policies", "20180425-5.git6ad4018.fc28", "rpm", "source", database.Namespace{}}, - {"gzip", "1.9-3.fc28", "rpm", "binary", database.Namespace{}}, - {"fedora-release", "28-2", "rpm", "source", database.Namespace{}}, - {"zlib", "1.2.11-8.fc28", "rpm", "binary", database.Namespace{}}, - {"crypto-policies", "20180425-5.git6ad4018.fc28", "rpm", "binary", database.Namespace{}}, - {"lz4", "1.8.1.2-4.fc28", "rpm", "source", database.Namespace{}}, - {"keyutils", "1.5.10-6.fc28", "rpm", "source", database.Namespace{}}, - {"gpgme", "1.10.0-4.fc28", "rpm", "binary", database.Namespace{}}, - {"libgpg-error", "1.31-1.fc28", "rpm", "binary", database.Namespace{}}, - {"gnutls", "3.6.3-4.fc28", "rpm", "source", database.Namespace{}}, - {"coreutils", "8.29-7.fc28", "rpm", "source", database.Namespace{}}, - {"libsepol", "2.8-1.fc28", "rpm", "source", database.Namespace{}}, - {"libssh", "0.8.2-1.fc28", "rpm", "binary", database.Namespace{}}, - {"libpwquality", "1.4.0-7.fc28", "rpm", "binary", database.Namespace{}}, - {"dnf-conf", "2.7.5-12.fc28", "rpm", "binary", database.Namespace{}}, - {"basesystem", "11-5.fc28", "rpm", "source", database.Namespace{}}, - {"setup", "2.11.4-1.fc28", "rpm", "binary", database.Namespace{}}, - {"libmetalink", "0.1.3-6.fc28", "rpm", "source", database.Namespace{}}, - {"texinfo", "6.5-4.fc28", "rpm", "source", database.Namespace{}}, - {"expat", "2.2.5-3.fc28", "rpm", "source", database.Namespace{}}, - {"ncurses", "6.1-5.20180224.fc28", "rpm", "source", database.Namespace{}}, - {"libpwquality", "1.4.0-7.fc28", "rpm", "source", database.Namespace{}}, - {"pcre", "8.42-3.fc28", "rpm", "binary", database.Namespace{}}, - {"sssd", "1.16.3-2.fc28", "rpm", "source", database.Namespace{}}, - {"basesystem", "11-5.fc28", "rpm", "binary", database.Namespace{}}, - {"systemd-pam", "238-9.git0e0aa59.fc28", "rpm", "binary", database.Namespace{}}, - {"python3-six", "1.11.0-3.fc28", "rpm", "binary", database.Namespace{}}, - {"libcurl", "7.59.0-6.fc28", "rpm", "binary", database.Namespace{}}, - {"qrencode", "3.4.4-5.fc28", "rpm", "source", database.Namespace{}}, - {"xz", "5.2.4-2.fc28", "rpm", "source", database.Namespace{}}, - {"libpkgconf", "1.4.2-1.fc28", "rpm", "binary", database.Namespace{}}, - {"libzstd", "1.3.5-1.fc28", "rpm", "binary", database.Namespace{}}, - {"bash", "4.4.23-1.fc28", "rpm", "binary", database.Namespace{}}, - {"cyrus-sasl", "2.1.27-0.2rc7.fc28", "rpm", "source", database.Namespace{}}, - {"ncurses-libs", "6.1-5.20180224.fc28", "rpm", "binary", database.Namespace{}}, - {"xz-libs", "5.2.4-2.fc28", "rpm", "binary", database.Namespace{}}, - {"dbus", "1.12.10-1.fc28", "rpm", "source", database.Namespace{}}, - {"grep", "3.1-5.fc28", "rpm", "binary", database.Namespace{}}, - {"libusbx", "1.0.22-1.fc28", "rpm", "binary", database.Namespace{}}, - {"audit", "2.8.4-2.fc28", "rpm", "source", database.Namespace{}}, - {"sed", "4.5-1.fc28", "rpm", "binary", database.Namespace{}}, - {"sqlite", "3.22.0-4.fc28", "rpm", "source", database.Namespace{}}, - {"openldap", "2.4.46-3.fc28", "rpm", "binary", database.Namespace{}}, - {"gawk", "4.2.1-1.fc28", "rpm", "binary", database.Namespace{}}, - {"gpgme", "1.10.0-4.fc28", "rpm", "source", database.Namespace{}}, - {"lvm2", "2.02.177-5.fc28", "rpm", "source", database.Namespace{}}, - {"nspr", "4.19.0-1.fc28", "rpm", "source", database.Namespace{}}, - {"libsolv", "0.6.35-1.fc28", "rpm", "source", database.Namespace{}}, - {"info", "6.5-4.fc28", "rpm", "binary", database.Namespace{}}, - {"openssl-libs", "1:1.1.0h-3.fc28", "rpm", "binary", database.Namespace{}}, - {"libxcrypt", "4.1.2-1.fc28", "rpm", "binary", database.Namespace{}}, - {"libselinux", "2.8-1.fc28", "rpm", "binary", database.Namespace{}}, - {"libgcc", "8.1.1-5.fc28", "rpm", "binary", database.Namespace{}}, - {"cracklib", "2.9.6-13.fc28", "rpm", "binary", database.Namespace{}}, - {"python3-libs", "3.6.6-1.fc28", "rpm", "binary", database.Namespace{}}, - {"glibc-langpack-en", "2.27-32.fc28", "rpm", "binary", database.Namespace{}}, - {"json-c", "0.13.1-2.fc28", "rpm", "binary", database.Namespace{}}, - {"gnupg2", "2.2.8-1.fc28", "rpm", "source", database.Namespace{}}, - {"openssl", "1:1.1.0h-3.fc28", "rpm", "binary", database.Namespace{}}, - {"glibc-common", "2.27-32.fc28", "rpm", "binary", database.Namespace{}}, - {"p11-kit-trust", "0.23.12-1.fc28", "rpm", "binary", database.Namespace{}}, - {"zstd", "1.3.5-1.fc28", "rpm", "source", database.Namespace{}}, - {"libxml2", "2.9.8-4.fc28", "rpm", "source", database.Namespace{}}, - {"dbus", "1:1.12.10-1.fc28", "rpm", "binary", database.Namespace{}}, - {"ca-certificates", "2018.2.24-1.0.fc28", "rpm", "binary", database.Namespace{}}, - {"libcomps", "0.1.8-11.fc28", "rpm", "binary", database.Namespace{}}, - {"nss", "3.38.0-1.0.fc28", "rpm", "binary", database.Namespace{}}, - {"libcom_err", "1.44.2-0.fc28", "rpm", "binary", database.Namespace{}}, - {"keyutils-libs", "1.5.10-6.fc28", "rpm", "binary", database.Namespace{}}, - {"libseccomp", "2.3.3-2.fc28", "rpm", "binary", database.Namespace{}}, - {"elfutils-libs", "0.173-1.fc28", "rpm", "binary", database.Namespace{}}, - {"libuuid", "2.32.1-1.fc28", "rpm", "binary", database.Namespace{}}, - {"pkgconf", "1.4.2-1.fc28", "rpm", "source", database.Namespace{}}, - {"grep", "3.1-5.fc28", "rpm", "source", database.Namespace{}}, - {"libpcap", "1.9.0-1.fc28", "rpm", "source", database.Namespace{}}, - {"deltarpm", "3.6-25.fc28", "rpm", "binary", database.Namespace{}}, - {"krb5-libs", "1.16.1-13.fc28", "rpm", "binary", database.Namespace{}}, - {"glibc", "2.27-32.fc28", "rpm", "binary", database.Namespace{}}, - {"libseccomp", "2.3.3-2.fc28", "rpm", "source", database.Namespace{}}, - {"libsemanage", "2.8-2.fc28", "rpm", "binary", database.Namespace{}}, - {"openssl-pkcs11", "0.4.8-1.fc28", "rpm", "binary", database.Namespace{}}, - {"libxml2", "2.9.8-4.fc28", "rpm", "binary", database.Namespace{}}, - {"e2fsprogs", "1.44.2-0.fc28", "rpm", "source", database.Namespace{}}, - {"file-libs", "5.33-7.fc28", "rpm", "binary", database.Namespace{}}, - {"elfutils-default-yama-scope", "0.173-1.fc28", "rpm", "binary", database.Namespace{}}, - {"glibc", "2.27-32.fc28", "rpm", "source", database.Namespace{}}, - {"publicsuffix-list-dafsa", "20180514-1.fc28", "rpm", "binary", database.Namespace{}}, - {"popt", "1.16-14.fc28", "rpm", "binary", database.Namespace{}}, - {"libnsl2", "1.2.0-2.20180605git4a062cf.fc28", "rpm", "binary", database.Namespace{}}, - {"lua-libs", "5.3.4-10.fc28", "rpm", "binary", database.Namespace{}}, - {"libsemanage", "2.8-2.fc28", "rpm", "source", database.Namespace{}}, - {"glibc-minimal-langpack", "2.27-32.fc28", "rpm", "binary", database.Namespace{}}, - {"attr", "2.4.48-3.fc28", "rpm", "source", database.Namespace{}}, - {"gdbm", "1.14.1-4.fc28", "rpm", "source", database.Namespace{}}, - {"pkgconf", "1.4.2-1.fc28", "rpm", "binary", database.Namespace{}}, - {"acl", "2.2.53-1.fc28", "rpm", "source", database.Namespace{}}, - {"gnutls", "3.6.3-4.fc28", "rpm", "binary", database.Namespace{}}, - {"fedora-repos", "28-5", "rpm", "source", database.Namespace{}}, - {"python3-pip", "9.0.3-2.fc28", "rpm", "binary", database.Namespace{}}, - {"libnsl2", "1.2.0-2.20180605git4a062cf.fc28", "rpm", "source", database.Namespace{}}, - {"rpm", "4.14.1-9.fc28", "rpm", "binary", database.Namespace{}}, - {"libutempter", "1.1.6-14.fc28", "rpm", "source", database.Namespace{}}, - {"libdnf", "0.11.1-3.fc28", "rpm", "source", database.Namespace{}}, - {"vim-minimal", "2:8.1.328-1.fc28", "rpm", "binary", database.Namespace{}}, - {"tzdata", "2018e-1.fc28", "rpm", "binary", database.Namespace{}}, - {"nettle", "3.4-2.fc28", "rpm", "binary", database.Namespace{}}, - {"python-pip", "9.0.3-2.fc28", "rpm", "source", database.Namespace{}}, - {"python-six", "1.11.0-3.fc28", "rpm", "source", database.Namespace{}}, - {"diffutils", "3.6-4.fc28", "rpm", "binary", database.Namespace{}}, - {"rpm-plugin-selinux", "4.14.1-9.fc28", "rpm", "binary", database.Namespace{}}, - {"shadow-utils", "2:4.6-1.fc28", "rpm", "binary", database.Namespace{}}, - {"pkgconf-pkg-config", "1.4.2-1.fc28", "rpm", "binary", database.Namespace{}}, - {"cracklib-dicts", "2.9.6-13.fc28", "rpm", "binary", database.Namespace{}}, - {"libblkid", "2.32.1-1.fc28", "rpm", "binary", database.Namespace{}}, - {"python-setuptools", "39.2.0-6.fc28", "rpm", "source", database.Namespace{}}, - {"libsss_idmap", "1.16.3-2.fc28", "rpm", "binary", database.Namespace{}}, - {"libksba", "1.3.5-7.fc28", "rpm", "source", database.Namespace{}}, - {"sssd-client", "1.16.3-2.fc28", "rpm", "binary", database.Namespace{}}, - {"curl", "7.59.0-6.fc28", "rpm", "binary", database.Namespace{}}, - {"pam", "1.3.1-1.fc28", "rpm", "binary", database.Namespace{}}, - {"libsigsegv", "2.11-5.fc28", "rpm", "binary", database.Namespace{}}, - {"langpacks-en", "1.0-12.fc28", "rpm", "binary", database.Namespace{}}, - {"nss-softokn-freebl", "3.38.0-1.0.fc28", "rpm", "binary", database.Namespace{}}, - {"glib2", "2.56.1-4.fc28", "rpm", "binary", database.Namespace{}}, - {"python3-gobject-base", "3.28.3-1.fc28", "rpm", "binary", database.Namespace{}}, - {"libffi", "3.1-16.fc28", "rpm", "source", database.Namespace{}}, - {"libmodulemd", "1.6.2-2.fc28", "rpm", "source", database.Namespace{}}, - {"openssl", "1.1.0h-3.fc28", "rpm", "source", database.Namespace{}}, - {"libyaml", "0.1.7-5.fc28", "rpm", "source", database.Namespace{}}, - {"pam", "1.3.1-1.fc28", "rpm", "source", database.Namespace{}}, - {"iptables", "1.6.2-3.fc28", "rpm", "source", database.Namespace{}}, - {"util-linux", "2.32.1-1.fc28", "rpm", "source", database.Namespace{}}, - {"libsmartcols", "2.32.1-1.fc28", "rpm", "binary", database.Namespace{}}, - {"dnf", "2.7.5-12.fc28", "rpm", "binary", database.Namespace{}}, - {"glib2", "2.56.1-4.fc28", "rpm", "source", database.Namespace{}}, - {"lua", "5.3.4-10.fc28", "rpm", "source", database.Namespace{}}, - {"nss-softokn", "3.38.0-1.0.fc28", "rpm", "source", database.Namespace{}}, - {"python3-dnf", "2.7.5-12.fc28", "rpm", "binary", database.Namespace{}}, - {"filesystem", "3.8-2.fc28", "rpm", "binary", database.Namespace{}}, - {"libsss_nss_idmap", "1.16.3-2.fc28", "rpm", "binary", database.Namespace{}}, - {"pcre2", "10.31-10.fc28", "rpm", "source", database.Namespace{}}, - {"libyaml", "0.1.7-5.fc28", "rpm", "binary", database.Namespace{}}, - {"python3-rpm", "4.14.1-9.fc28", "rpm", "binary", database.Namespace{}}, - {"zlib", "1.2.11-8.fc28", "rpm", "source", database.Namespace{}}, - {"libutempter", "1.1.6-14.fc28", "rpm", "binary", database.Namespace{}}, - {"pcre2", "10.31-10.fc28", "rpm", "binary", database.Namespace{}}, - {"libtirpc", "1.0.3-3.rc2.fc28", "rpm", "source", database.Namespace{}}, - {"pkgconf-m4", "1.4.2-1.fc28", "rpm", "binary", database.Namespace{}}, - {"libreport", "2.9.5-1.fc28", "rpm", "source", database.Namespace{}}, - {"vim", "8.1.328-1.fc28", "rpm", "source", database.Namespace{}}, - {"file", "5.33-7.fc28", "rpm", "source", database.Namespace{}}, - {"shadow-utils", "4.6-1.fc28", "rpm", "source", database.Namespace{}}, - {"sqlite-libs", "3.22.0-4.fc28", "rpm", "binary", database.Namespace{}}, - {"setup", "2.11.4-1.fc28", "rpm", "source", database.Namespace{}}, - {"gcc", "8.1.1-5.fc28", "rpm", "source", database.Namespace{}}, - {"mpfr", "3.1.6-1.fc28", "rpm", "binary", database.Namespace{}}, - {"device-mapper", "1.02.146-5.fc28", "rpm", "binary", database.Namespace{}}, - {"p11-kit", "0.23.12-1.fc28", "rpm", "source", database.Namespace{}}, - {"fedora-release", "28-2", "rpm", "binary", database.Namespace{}}, - {"libnghttp2", "1.32.1-1.fc28", "rpm", "binary", database.Namespace{}}, - {"libcap-ng", "0.7.9-4.fc28", "rpm", "source", database.Namespace{}}, - {"iptables-libs", "1.6.2-3.fc28", "rpm", "binary", database.Namespace{}}, - {"audit-libs", "2.8.4-2.fc28", "rpm", "binary", database.Namespace{}}, - {"libsigsegv", "2.11-5.fc28", "rpm", "source", database.Namespace{}}, - {"rootfiles", "8.1-22.fc28", "rpm", "source", database.Namespace{}}, - {"kmod-libs", "25-2.fc28", "rpm", "binary", database.Namespace{}}, - {"lz4-libs", "1.8.1.2-4.fc28", "rpm", "binary", database.Namespace{}}, - {"libassuan", "2.5.1-3.fc28", "rpm", "source", database.Namespace{}}, - {"p11-kit", "0.23.12-1.fc28", "rpm", "binary", database.Namespace{}}, - {"nss-sysinit", "3.38.0-1.0.fc28", "rpm", "binary", database.Namespace{}}, - {"libcap-ng", "0.7.9-4.fc28", "rpm", "binary", database.Namespace{}}, - {"bash", "4.4.23-1.fc28", "rpm", "source", database.Namespace{}}, - {"pygobject3", "3.28.3-1.fc28", "rpm", "source", database.Namespace{}}, - {"dnf-yum", "2.7.5-12.fc28", "rpm", "binary", database.Namespace{}}, - {"nss-softokn", "3.38.0-1.0.fc28", "rpm", "binary", database.Namespace{}}, - {"expat", "2.2.5-3.fc28", "rpm", "binary", database.Namespace{}}, - {"libassuan", "2.5.1-3.fc28", "rpm", "binary", database.Namespace{}}, - {"libdb", "5.3.28-30.fc28", "rpm", "binary", database.Namespace{}}, - {"tar", "2:1.30-3.fc28", "rpm", "binary", database.Namespace{}}, - {"sed", "4.5-1.fc28", "rpm", "source", database.Namespace{}}, - {"libmetalink", "0.1.3-6.fc28", "rpm", "binary", database.Namespace{}}, - {"python-smartcols", "0.3.0-2.fc28", "rpm", "source", database.Namespace{}}, - {"systemd", "238-9.git0e0aa59.fc28", "rpm", "source", database.Namespace{}}, - {"python-iniparse", "0.4-30.fc28", "rpm", "source", database.Namespace{}}, - {"libsepol", "2.8-1.fc28", "rpm", "binary", database.Namespace{}}, - {"libattr", "2.4.48-3.fc28", "rpm", "binary", database.Namespace{}}, - {"python3-smartcols", "0.3.0-2.fc28", "rpm", "binary", database.Namespace{}}, - {"libdb", "5.3.28-30.fc28", "rpm", "source", database.Namespace{}}, - {"libmodulemd", "1.6.2-2.fc28", "rpm", "binary", database.Namespace{}}, - {"python3-hawkey", "0.11.1-3.fc28", "rpm", "binary", database.Namespace{}}, - {"dbus-libs", "1:1.12.10-1.fc28", "rpm", "binary", database.Namespace{}}, - {"chkconfig", "1.10-4.fc28", "rpm", "source", database.Namespace{}}, - {"libargon2", "20161029-5.fc28", "rpm", "binary", database.Namespace{}}, - {"openssl-pkcs11", "0.4.8-1.fc28", "rpm", "source", database.Namespace{}}, - {"libusbx", "1.0.22-1.fc28", "rpm", "source", database.Namespace{}}, - {"python3-setuptools", "39.2.0-6.fc28", "rpm", "binary", database.Namespace{}}, - {"chkconfig", "1.10-4.fc28", "rpm", "binary", database.Namespace{}}, - {"openldap", "2.4.46-3.fc28", "rpm", "source", database.Namespace{}}, - {"bzip2", "1.0.6-26.fc28", "rpm", "source", database.Namespace{}}, - {"npth", "1.5-4.fc28", "rpm", "source", database.Namespace{}}, - {"libtirpc", "1.0.3-3.rc2.fc28", "rpm", "binary", database.Namespace{}}, - {"util-linux", "2.32.1-1.fc28", "rpm", "binary", database.Namespace{}}, - {"nss", "3.38.0-1.0.fc28", "rpm", "source", database.Namespace{}}, - {"elfutils", "0.173-1.fc28", "rpm", "source", database.Namespace{}}, - {"libcomps", "0.1.8-11.fc28", "rpm", "source", database.Namespace{}}, - {"libxcrypt", "4.1.2-1.fc28", "rpm", "source", database.Namespace{}}, - {"gnupg2", "2.2.8-1.fc28", "rpm", "binary", database.Namespace{}}, - {"libdnf", "0.11.1-3.fc28", "rpm", "binary", database.Namespace{}}, - {"cracklib", "2.9.6-13.fc28", "rpm", "source", database.Namespace{}}, - {"libidn2", "2.0.5-1.fc28", "rpm", "source", database.Namespace{}}, - {"bzip2-libs", "1.0.6-26.fc28", "rpm", "binary", database.Namespace{}}, - {"json-c", "0.13.1-2.fc28", "rpm", "source", database.Namespace{}}, - {"gdbm", "1:1.14.1-4.fc28", "rpm", "binary", database.Namespace{}}, - {"pcre", "8.42-3.fc28", "rpm", "source", database.Namespace{}}, - {"systemd", "238-9.git0e0aa59.fc28", "rpm", "binary", database.Namespace{}}, - {"cryptsetup-libs", "2.0.4-1.fc28", "rpm", "binary", database.Namespace{}}, - {"dnf", "2.7.5-12.fc28", "rpm", "source", database.Namespace{}}, - {"ca-certificates", "2018.2.24-1.0.fc28", "rpm", "source", database.Namespace{}}, - {"libidn2", "2.0.5-1.fc28", "rpm", "binary", database.Namespace{}}, - {"libpsl", "0.20.2-2.fc28", "rpm", "binary", database.Namespace{}}, - {"gdbm-libs", "1:1.14.1-4.fc28", "rpm", "binary", database.Namespace{}}, - {"kmod", "25-2.fc28", "rpm", "source", database.Namespace{}}, - {"libreport-filesystem", "2.9.5-1.fc28", "rpm", "binary", database.Namespace{}}, - {"ima-evm-utils", "1.1-2.fc28", "rpm", "source", database.Namespace{}}, - {"nghttp2", "1.32.1-1.fc28", "rpm", "source", database.Namespace{}}, - {"cyrus-sasl-lib", "2.1.27-0.2rc7.fc28", "rpm", "binary", database.Namespace{}}, - {"libsolv", "0.6.35-1.fc28", "rpm", "binary", database.Namespace{}}, - {"cryptsetup", "2.0.4-1.fc28", "rpm", "source", database.Namespace{}}, - {"filesystem", "3.8-2.fc28", "rpm", "source", database.Namespace{}}, - {"libcap", "2.25-9.fc28", "rpm", "source", database.Namespace{}}, - {"libpsl", "0.20.2-2.fc28", "rpm", "source", database.Namespace{}}, - {"deltarpm", "3.6-25.fc28", "rpm", "source", database.Namespace{}}, - {"fedora-gpg-keys", "28-5", "rpm", "binary", database.Namespace{}}, - {"ima-evm-utils", "1.1-2.fc28", "rpm", "binary", database.Namespace{}}, - {"nss-tools", "3.38.0-1.0.fc28", "rpm", "binary", database.Namespace{}}, - {"libtasn1", "4.13-2.fc28", "rpm", "source", database.Namespace{}}, - {"elfutils-libelf", "0.173-1.fc28", "rpm", "binary", database.Namespace{}}, - {"device-mapper-libs", "1.02.146-5.fc28", "rpm", "binary", database.Namespace{}}, - {"gobject-introspection", "1.56.1-1.fc28", "rpm", "source", database.Namespace{}}, - {"publicsuffix-list", "20180514-1.fc28", "rpm", "source", database.Namespace{}}, - {"libcap", "2.25-9.fc28", "rpm", "binary", database.Namespace{}}, - {"librepo", "1.8.1-7.fc28", "rpm", "binary", database.Namespace{}}, - {"rpm-sign-libs", "4.14.1-9.fc28", "rpm", "binary", database.Namespace{}}, - {"coreutils-single", "8.29-7.fc28", "rpm", "binary", database.Namespace{}}, - {"libacl", "2.2.53-1.fc28", "rpm", "binary", database.Namespace{}}, - {"popt", "1.16-14.fc28", "rpm", "source", database.Namespace{}}, - {"libtasn1", "4.13-2.fc28", "rpm", "binary", database.Namespace{}}, - {"gawk", "4.2.1-1.fc28", "rpm", "source", database.Namespace{}}, - {"diffutils", "3.6-4.fc28", "rpm", "source", database.Namespace{}}, - {"libgpg-error", "1.31-1.fc28", "rpm", "source", database.Namespace{}}, - {"libdb-utils", "5.3.28-30.fc28", "rpm", "binary", database.Namespace{}}, - {"python3-iniparse", "0.4-30.fc28", "rpm", "binary", database.Namespace{}}, - {"acl", "2.2.53-1.fc28", "rpm", "binary", database.Namespace{}}, - {"libssh", "0.8.2-1.fc28", "rpm", "source", database.Namespace{}}, - {"python3-librepo", "1.8.1-7.fc28", "rpm", "binary", database.Namespace{}}, - {"gobject-introspection", "1.56.1-1.fc28", "rpm", "binary", database.Namespace{}}, - {"rpm", "4.14.1-9.fc28", "rpm", "source", database.Namespace{}}, - {"libgcrypt", "1.8.3-1.fc28", "rpm", "source", database.Namespace{}}, - {"curl", "7.59.0-6.fc28", "rpm", "source", database.Namespace{}}, - {"tzdata", "2018e-1.fc28", "rpm", "source", database.Namespace{}}, - {"krb5", "1.16.1-13.fc28", "rpm", "source", database.Namespace{}}, - {"librepo", "1.8.1-7.fc28", "rpm", "source", database.Namespace{}}, - {"python3-gpg", "1.10.0-4.fc28", "rpm", "binary", database.Namespace{}}, - {"nettle", "3.4-2.fc28", "rpm", "source", database.Namespace{}}, - {"libgcrypt", "1.8.3-1.fc28", "rpm", "binary", database.Namespace{}}, - {"python3", "3.6.6-1.fc28", "rpm", "binary", database.Namespace{}}, - {"python3-libcomps", "0.1.8-11.fc28", "rpm", "binary", database.Namespace{}}, - {"rpm-libs", "4.14.1-9.fc28", "rpm", "binary", database.Namespace{}}, - {"nspr", "4.19.0-1.fc28", "rpm", "binary", database.Namespace{}}, - {"argon2", "20161029-5.fc28", "rpm", "source", database.Namespace{}}, - {"tar", "1.30-3.fc28", "rpm", "source", database.Namespace{}}, - {"qrencode-libs", "3.4.4-5.fc28", "rpm", "binary", database.Namespace{}}, - {"gmp", "6.1.2-7.fc28", "rpm", "source", database.Namespace{}}, - {"libverto", "0.3.0-5.fc28", "rpm", "binary", database.Namespace{}}, - {"python3", "3.6.6-1.fc28", "rpm", "source", database.Namespace{}}, - {"libksba", "1.3.5-7.fc28", "rpm", "binary", database.Namespace{}}, - {"readline", "7.0-11.fc28", "rpm", "binary", database.Namespace{}}, - {"rpm-build-libs", "4.14.1-9.fc28", "rpm", "binary", database.Namespace{}}, - {"npth", "1.5-4.fc28", "rpm", "binary", database.Namespace{}}, - {"rootfiles", "8.1-22.fc28", "rpm", "binary", database.Namespace{}}, - {"rpm-plugin-systemd-inhibit", "4.14.1-9.fc28", "rpm", "binary", database.Namespace{}}, - {"systemd-libs", "238-9.git0e0aa59.fc28", "rpm", "binary", database.Namespace{}}, - {"nss-util", "3.38.0-1.0.fc28", "rpm", "binary", database.Namespace{}}, +var expectedBigCaseInfo = []database.LayerFeature{ + {Feature: database.Feature{"libmount", "2.32.1-1.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"libffi", "3.1-16.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"libunistring", "0.9.10-1.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"fedora-repos", "28-5", "rpm", "binary"}}, + {Feature: database.Feature{"libarchive", "3.3.1-4.fc28", "rpm", "source"}}, + {Feature: database.Feature{"langpacks", "1.0-12.fc28", "rpm", "source"}}, + {Feature: database.Feature{"readline", "7.0-11.fc28", "rpm", "source"}}, + {Feature: database.Feature{"gzip", "1.9-3.fc28", "rpm", "source"}}, + {Feature: database.Feature{"libverto", "0.3.0-5.fc28", "rpm", "source"}}, + {Feature: database.Feature{"ncurses-base", "6.1-5.20180224.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"libfdisk", "2.32.1-1.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"libselinux", "2.8-1.fc28", "rpm", "source"}}, + {Feature: database.Feature{"nss-util", "3.38.0-1.0.fc28", "rpm", "source"}}, + {Feature: database.Feature{"mpfr", "3.1.6-1.fc28", "rpm", "source"}}, + {Feature: database.Feature{"libunistring", "0.9.10-1.fc28", "rpm", "source"}}, + {Feature: database.Feature{"libpcap", "14:1.9.0-1.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"libarchive", "3.3.1-4.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"gmp", "1:6.1.2-7.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"crypto-policies", "20180425-5.git6ad4018.fc28", "rpm", "source"}}, + {Feature: database.Feature{"gzip", "1.9-3.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"fedora-release", "28-2", "rpm", "source"}}, + {Feature: database.Feature{"zlib", "1.2.11-8.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"crypto-policies", "20180425-5.git6ad4018.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"lz4", "1.8.1.2-4.fc28", "rpm", "source"}}, + {Feature: database.Feature{"keyutils", "1.5.10-6.fc28", "rpm", "source"}}, + {Feature: database.Feature{"gpgme", "1.10.0-4.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"libgpg-error", "1.31-1.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"gnutls", "3.6.3-4.fc28", "rpm", "source"}}, + {Feature: database.Feature{"coreutils", "8.29-7.fc28", "rpm", "source"}}, + {Feature: database.Feature{"libsepol", "2.8-1.fc28", "rpm", "source"}}, + {Feature: database.Feature{"libssh", "0.8.2-1.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"libpwquality", "1.4.0-7.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"dnf-conf", "2.7.5-12.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"basesystem", "11-5.fc28", "rpm", "source"}}, + {Feature: database.Feature{"setup", "2.11.4-1.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"libmetalink", "0.1.3-6.fc28", "rpm", "source"}}, + {Feature: database.Feature{"texinfo", "6.5-4.fc28", "rpm", "source"}}, + {Feature: database.Feature{"expat", "2.2.5-3.fc28", "rpm", "source"}}, + {Feature: database.Feature{"ncurses", "6.1-5.20180224.fc28", "rpm", "source"}}, + {Feature: database.Feature{"libpwquality", "1.4.0-7.fc28", "rpm", "source"}}, + {Feature: database.Feature{"pcre", "8.42-3.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"sssd", "1.16.3-2.fc28", "rpm", "source"}}, + {Feature: database.Feature{"basesystem", "11-5.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"systemd-pam", "238-9.git0e0aa59.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"python3-six", "1.11.0-3.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"libcurl", "7.59.0-6.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"qrencode", "3.4.4-5.fc28", "rpm", "source"}}, + {Feature: database.Feature{"xz", "5.2.4-2.fc28", "rpm", "source"}}, + {Feature: database.Feature{"libpkgconf", "1.4.2-1.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"libzstd", "1.3.5-1.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"bash", "4.4.23-1.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"cyrus-sasl", "2.1.27-0.2rc7.fc28", "rpm", "source"}}, + {Feature: database.Feature{"ncurses-libs", "6.1-5.20180224.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"xz-libs", "5.2.4-2.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"dbus", "1.12.10-1.fc28", "rpm", "source"}}, + {Feature: database.Feature{"grep", "3.1-5.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"libusbx", "1.0.22-1.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"audit", "2.8.4-2.fc28", "rpm", "source"}}, + {Feature: database.Feature{"sed", "4.5-1.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"sqlite", "3.22.0-4.fc28", "rpm", "source"}}, + {Feature: database.Feature{"openldap", "2.4.46-3.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"gawk", "4.2.1-1.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"gpgme", "1.10.0-4.fc28", "rpm", "source"}}, + {Feature: database.Feature{"lvm2", "2.02.177-5.fc28", "rpm", "source"}}, + {Feature: database.Feature{"nspr", "4.19.0-1.fc28", "rpm", "source"}}, + {Feature: database.Feature{"libsolv", "0.6.35-1.fc28", "rpm", "source"}}, + {Feature: database.Feature{"info", "6.5-4.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"openssl-libs", "1:1.1.0h-3.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"libxcrypt", "4.1.2-1.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"libselinux", "2.8-1.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"libgcc", "8.1.1-5.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"cracklib", "2.9.6-13.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"python3-libs", "3.6.6-1.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"glibc-langpack-en", "2.27-32.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"json-c", "0.13.1-2.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"gnupg2", "2.2.8-1.fc28", "rpm", "source"}}, + {Feature: database.Feature{"openssl", "1:1.1.0h-3.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"glibc-common", "2.27-32.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"p11-kit-trust", "0.23.12-1.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"zstd", "1.3.5-1.fc28", "rpm", "source"}}, + {Feature: database.Feature{"libxml2", "2.9.8-4.fc28", "rpm", "source"}}, + {Feature: database.Feature{"dbus", "1:1.12.10-1.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"ca-certificates", "2018.2.24-1.0.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"libcomps", "0.1.8-11.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"nss", "3.38.0-1.0.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"libcom_err", "1.44.2-0.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"keyutils-libs", "1.5.10-6.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"libseccomp", "2.3.3-2.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"elfutils-libs", "0.173-1.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"libuuid", "2.32.1-1.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"pkgconf", "1.4.2-1.fc28", "rpm", "source"}}, + {Feature: database.Feature{"grep", "3.1-5.fc28", "rpm", "source"}}, + {Feature: database.Feature{"libpcap", "1.9.0-1.fc28", "rpm", "source"}}, + {Feature: database.Feature{"deltarpm", "3.6-25.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"krb5-libs", "1.16.1-13.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"glibc", "2.27-32.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"libseccomp", "2.3.3-2.fc28", "rpm", "source"}}, + {Feature: database.Feature{"libsemanage", "2.8-2.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"openssl-pkcs11", "0.4.8-1.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"libxml2", "2.9.8-4.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"e2fsprogs", "1.44.2-0.fc28", "rpm", "source"}}, + {Feature: database.Feature{"file-libs", "5.33-7.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"elfutils-default-yama-scope", "0.173-1.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"glibc", "2.27-32.fc28", "rpm", "source"}}, + {Feature: database.Feature{"publicsuffix-list-dafsa", "20180514-1.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"popt", "1.16-14.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"libnsl2", "1.2.0-2.20180605git4a062cf.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"lua-libs", "5.3.4-10.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"libsemanage", "2.8-2.fc28", "rpm", "source"}}, + {Feature: database.Feature{"glibc-minimal-langpack", "2.27-32.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"attr", "2.4.48-3.fc28", "rpm", "source"}}, + {Feature: database.Feature{"gdbm", "1.14.1-4.fc28", "rpm", "source"}}, + {Feature: database.Feature{"pkgconf", "1.4.2-1.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"acl", "2.2.53-1.fc28", "rpm", "source"}}, + {Feature: database.Feature{"gnutls", "3.6.3-4.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"fedora-repos", "28-5", "rpm", "source"}}, + {Feature: database.Feature{"python3-pip", "9.0.3-2.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"libnsl2", "1.2.0-2.20180605git4a062cf.fc28", "rpm", "source"}}, + {Feature: database.Feature{"rpm", "4.14.1-9.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"libutempter", "1.1.6-14.fc28", "rpm", "source"}}, + {Feature: database.Feature{"libdnf", "0.11.1-3.fc28", "rpm", "source"}}, + {Feature: database.Feature{"vim-minimal", "2:8.1.328-1.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"tzdata", "2018e-1.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"nettle", "3.4-2.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"python-pip", "9.0.3-2.fc28", "rpm", "source"}}, + {Feature: database.Feature{"python-six", "1.11.0-3.fc28", "rpm", "source"}}, + {Feature: database.Feature{"diffutils", "3.6-4.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"rpm-plugin-selinux", "4.14.1-9.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"shadow-utils", "2:4.6-1.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"pkgconf-pkg-config", "1.4.2-1.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"cracklib-dicts", "2.9.6-13.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"libblkid", "2.32.1-1.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"python-setuptools", "39.2.0-6.fc28", "rpm", "source"}}, + {Feature: database.Feature{"libsss_idmap", "1.16.3-2.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"libksba", "1.3.5-7.fc28", "rpm", "source"}}, + {Feature: database.Feature{"sssd-client", "1.16.3-2.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"curl", "7.59.0-6.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"pam", "1.3.1-1.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"libsigsegv", "2.11-5.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"langpacks-en", "1.0-12.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"nss-softokn-freebl", "3.38.0-1.0.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"glib2", "2.56.1-4.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"python3-gobject-base", "3.28.3-1.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"libffi", "3.1-16.fc28", "rpm", "source"}}, + {Feature: database.Feature{"libmodulemd", "1.6.2-2.fc28", "rpm", "source"}}, + {Feature: database.Feature{"openssl", "1.1.0h-3.fc28", "rpm", "source"}}, + {Feature: database.Feature{"libyaml", "0.1.7-5.fc28", "rpm", "source"}}, + {Feature: database.Feature{"pam", "1.3.1-1.fc28", "rpm", "source"}}, + {Feature: database.Feature{"iptables", "1.6.2-3.fc28", "rpm", "source"}}, + {Feature: database.Feature{"util-linux", "2.32.1-1.fc28", "rpm", "source"}}, + {Feature: database.Feature{"libsmartcols", "2.32.1-1.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"dnf", "2.7.5-12.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"glib2", "2.56.1-4.fc28", "rpm", "source"}}, + {Feature: database.Feature{"lua", "5.3.4-10.fc28", "rpm", "source"}}, + {Feature: database.Feature{"nss-softokn", "3.38.0-1.0.fc28", "rpm", "source"}}, + {Feature: database.Feature{"python3-dnf", "2.7.5-12.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"filesystem", "3.8-2.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"libsss_nss_idmap", "1.16.3-2.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"pcre2", "10.31-10.fc28", "rpm", "source"}}, + {Feature: database.Feature{"libyaml", "0.1.7-5.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"python3-rpm", "4.14.1-9.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"zlib", "1.2.11-8.fc28", "rpm", "source"}}, + {Feature: database.Feature{"libutempter", "1.1.6-14.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"pcre2", "10.31-10.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"libtirpc", "1.0.3-3.rc2.fc28", "rpm", "source"}}, + {Feature: database.Feature{"pkgconf-m4", "1.4.2-1.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"libreport", "2.9.5-1.fc28", "rpm", "source"}}, + {Feature: database.Feature{"vim", "8.1.328-1.fc28", "rpm", "source"}}, + {Feature: database.Feature{"file", "5.33-7.fc28", "rpm", "source"}}, + {Feature: database.Feature{"shadow-utils", "4.6-1.fc28", "rpm", "source"}}, + {Feature: database.Feature{"sqlite-libs", "3.22.0-4.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"setup", "2.11.4-1.fc28", "rpm", "source"}}, + {Feature: database.Feature{"gcc", "8.1.1-5.fc28", "rpm", "source"}}, + {Feature: database.Feature{"mpfr", "3.1.6-1.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"device-mapper", "1.02.146-5.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"p11-kit", "0.23.12-1.fc28", "rpm", "source"}}, + {Feature: database.Feature{"fedora-release", "28-2", "rpm", "binary"}}, + {Feature: database.Feature{"libnghttp2", "1.32.1-1.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"libcap-ng", "0.7.9-4.fc28", "rpm", "source"}}, + {Feature: database.Feature{"iptables-libs", "1.6.2-3.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"audit-libs", "2.8.4-2.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"libsigsegv", "2.11-5.fc28", "rpm", "source"}}, + {Feature: database.Feature{"rootfiles", "8.1-22.fc28", "rpm", "source"}}, + {Feature: database.Feature{"kmod-libs", "25-2.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"lz4-libs", "1.8.1.2-4.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"libassuan", "2.5.1-3.fc28", "rpm", "source"}}, + {Feature: database.Feature{"p11-kit", "0.23.12-1.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"nss-sysinit", "3.38.0-1.0.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"libcap-ng", "0.7.9-4.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"bash", "4.4.23-1.fc28", "rpm", "source"}}, + {Feature: database.Feature{"pygobject3", "3.28.3-1.fc28", "rpm", "source"}}, + {Feature: database.Feature{"dnf-yum", "2.7.5-12.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"nss-softokn", "3.38.0-1.0.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"expat", "2.2.5-3.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"libassuan", "2.5.1-3.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"libdb", "5.3.28-30.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"tar", "2:1.30-3.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"sed", "4.5-1.fc28", "rpm", "source"}}, + {Feature: database.Feature{"libmetalink", "0.1.3-6.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"python-smartcols", "0.3.0-2.fc28", "rpm", "source"}}, + {Feature: database.Feature{"systemd", "238-9.git0e0aa59.fc28", "rpm", "source"}}, + {Feature: database.Feature{"python-iniparse", "0.4-30.fc28", "rpm", "source"}}, + {Feature: database.Feature{"libsepol", "2.8-1.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"libattr", "2.4.48-3.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"python3-smartcols", "0.3.0-2.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"libdb", "5.3.28-30.fc28", "rpm", "source"}}, + {Feature: database.Feature{"libmodulemd", "1.6.2-2.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"python3-hawkey", "0.11.1-3.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"dbus-libs", "1:1.12.10-1.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"chkconfig", "1.10-4.fc28", "rpm", "source"}}, + {Feature: database.Feature{"libargon2", "20161029-5.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"openssl-pkcs11", "0.4.8-1.fc28", "rpm", "source"}}, + {Feature: database.Feature{"libusbx", "1.0.22-1.fc28", "rpm", "source"}}, + {Feature: database.Feature{"python3-setuptools", "39.2.0-6.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"chkconfig", "1.10-4.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"openldap", "2.4.46-3.fc28", "rpm", "source"}}, + {Feature: database.Feature{"bzip2", "1.0.6-26.fc28", "rpm", "source"}}, + {Feature: database.Feature{"npth", "1.5-4.fc28", "rpm", "source"}}, + {Feature: database.Feature{"libtirpc", "1.0.3-3.rc2.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"util-linux", "2.32.1-1.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"nss", "3.38.0-1.0.fc28", "rpm", "source"}}, + {Feature: database.Feature{"elfutils", "0.173-1.fc28", "rpm", "source"}}, + {Feature: database.Feature{"libcomps", "0.1.8-11.fc28", "rpm", "source"}}, + {Feature: database.Feature{"libxcrypt", "4.1.2-1.fc28", "rpm", "source"}}, + {Feature: database.Feature{"gnupg2", "2.2.8-1.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"libdnf", "0.11.1-3.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"cracklib", "2.9.6-13.fc28", "rpm", "source"}}, + {Feature: database.Feature{"libidn2", "2.0.5-1.fc28", "rpm", "source"}}, + {Feature: database.Feature{"bzip2-libs", "1.0.6-26.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"json-c", "0.13.1-2.fc28", "rpm", "source"}}, + {Feature: database.Feature{"gdbm", "1:1.14.1-4.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"pcre", "8.42-3.fc28", "rpm", "source"}}, + {Feature: database.Feature{"systemd", "238-9.git0e0aa59.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"cryptsetup-libs", "2.0.4-1.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"dnf", "2.7.5-12.fc28", "rpm", "source"}}, + {Feature: database.Feature{"ca-certificates", "2018.2.24-1.0.fc28", "rpm", "source"}}, + {Feature: database.Feature{"libidn2", "2.0.5-1.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"libpsl", "0.20.2-2.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"gdbm-libs", "1:1.14.1-4.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"kmod", "25-2.fc28", "rpm", "source"}}, + {Feature: database.Feature{"libreport-filesystem", "2.9.5-1.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"ima-evm-utils", "1.1-2.fc28", "rpm", "source"}}, + {Feature: database.Feature{"nghttp2", "1.32.1-1.fc28", "rpm", "source"}}, + {Feature: database.Feature{"cyrus-sasl-lib", "2.1.27-0.2rc7.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"libsolv", "0.6.35-1.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"cryptsetup", "2.0.4-1.fc28", "rpm", "source"}}, + {Feature: database.Feature{"filesystem", "3.8-2.fc28", "rpm", "source"}}, + {Feature: database.Feature{"libcap", "2.25-9.fc28", "rpm", "source"}}, + {Feature: database.Feature{"libpsl", "0.20.2-2.fc28", "rpm", "source"}}, + {Feature: database.Feature{"deltarpm", "3.6-25.fc28", "rpm", "source"}}, + {Feature: database.Feature{"fedora-gpg-keys", "28-5", "rpm", "binary"}}, + {Feature: database.Feature{"ima-evm-utils", "1.1-2.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"nss-tools", "3.38.0-1.0.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"libtasn1", "4.13-2.fc28", "rpm", "source"}}, + {Feature: database.Feature{"elfutils-libelf", "0.173-1.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"device-mapper-libs", "1.02.146-5.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"gobject-introspection", "1.56.1-1.fc28", "rpm", "source"}}, + {Feature: database.Feature{"publicsuffix-list", "20180514-1.fc28", "rpm", "source"}}, + {Feature: database.Feature{"libcap", "2.25-9.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"librepo", "1.8.1-7.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"rpm-sign-libs", "4.14.1-9.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"coreutils-single", "8.29-7.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"libacl", "2.2.53-1.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"popt", "1.16-14.fc28", "rpm", "source"}}, + {Feature: database.Feature{"libtasn1", "4.13-2.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"gawk", "4.2.1-1.fc28", "rpm", "source"}}, + {Feature: database.Feature{"diffutils", "3.6-4.fc28", "rpm", "source"}}, + {Feature: database.Feature{"libgpg-error", "1.31-1.fc28", "rpm", "source"}}, + {Feature: database.Feature{"libdb-utils", "5.3.28-30.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"python3-iniparse", "0.4-30.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"acl", "2.2.53-1.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"libssh", "0.8.2-1.fc28", "rpm", "source"}}, + {Feature: database.Feature{"python3-librepo", "1.8.1-7.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"gobject-introspection", "1.56.1-1.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"rpm", "4.14.1-9.fc28", "rpm", "source"}}, + {Feature: database.Feature{"libgcrypt", "1.8.3-1.fc28", "rpm", "source"}}, + {Feature: database.Feature{"curl", "7.59.0-6.fc28", "rpm", "source"}}, + {Feature: database.Feature{"tzdata", "2018e-1.fc28", "rpm", "source"}}, + {Feature: database.Feature{"krb5", "1.16.1-13.fc28", "rpm", "source"}}, + {Feature: database.Feature{"librepo", "1.8.1-7.fc28", "rpm", "source"}}, + {Feature: database.Feature{"python3-gpg", "1.10.0-4.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"nettle", "3.4-2.fc28", "rpm", "source"}}, + {Feature: database.Feature{"libgcrypt", "1.8.3-1.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"python3", "3.6.6-1.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"python3-libcomps", "0.1.8-11.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"rpm-libs", "4.14.1-9.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"nspr", "4.19.0-1.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"argon2", "20161029-5.fc28", "rpm", "source"}}, + {Feature: database.Feature{"tar", "1.30-3.fc28", "rpm", "source"}}, + {Feature: database.Feature{"qrencode-libs", "3.4.4-5.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"gmp", "6.1.2-7.fc28", "rpm", "source"}}, + {Feature: database.Feature{"libverto", "0.3.0-5.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"python3", "3.6.6-1.fc28", "rpm", "source"}}, + {Feature: database.Feature{"libksba", "1.3.5-7.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"readline", "7.0-11.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"rpm-build-libs", "4.14.1-9.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"npth", "1.5-4.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"rootfiles", "8.1-22.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"rpm-plugin-systemd-inhibit", "4.14.1-9.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"systemd-libs", "238-9.git0e0aa59.fc28", "rpm", "binary"}}, + {Feature: database.Feature{"nss-util", "3.38.0-1.0.fc28", "rpm", "binary"}}, } func TestRpmFeatureDetection(t *testing.T) { @@ -333,11 +333,11 @@ func TestRpmFeatureDetection(t *testing.T) { { "valid small case", map[string]string{"var/lib/rpm/Packages": "rpm/testdata/valid"}, - []database.Feature{ - {"centos-release", "7-1.1503.el7.centos.2.8", "rpm", "binary", database.Namespace{}}, - {"filesystem", "3.2-18.el7", "rpm", "binary", database.Namespace{}}, - {"centos-release", "7-1.1503.el7.centos.2.8", "rpm", "source", database.Namespace{}}, - {"filesystem", "3.2-18.el7", "rpm", "source", database.Namespace{}}, + []database.LayerFeature{ + {Feature: database.Feature{"centos-release", "7-1.1503.el7.centos.2.8", "rpm", "binary"}}, + {Feature: database.Feature{"filesystem", "3.2-18.el7", "rpm", "binary"}}, + {Feature: database.Feature{"centos-release", "7-1.1503.el7.centos.2.8", "rpm", "source"}}, + {Feature: database.Feature{"filesystem", "3.2-18.el7", "rpm", "source"}}, }, }, { diff --git a/ext/featurefmt/testutil.go b/ext/featurefmt/testutil.go index d9cebb64..1716baf0 100644 --- a/ext/featurefmt/testutil.go +++ b/ext/featurefmt/testutil.go @@ -54,7 +54,7 @@ func loadTestFiles(testFilePaths map[string]string) tarutil.FilesMap { type TestCase struct { Name string FilePaths map[string]string - ExpectedResult []database.Feature + ExpectedResult []database.LayerFeature } // RunTest runs a featurefmt test by loading the package info database files and @@ -65,7 +65,7 @@ func RunTest(t *testing.T, test TestCase, lister Lister, expectedVersionFormat s expected := test.ExpectedResult features, err := lister.ListFeatures(filesMap) require.Nil(t, err) - visited := map[database.Feature]bool{} + visited := map[database.LayerFeature]bool{} // we only enforce the unique packages to match, the result features // should be always deduplicated. for _, pkg := range expected { @@ -84,7 +84,7 @@ func RunTest(t *testing.T, test TestCase, lister Lister, expectedVersionFormat s visited[f] = true } - missingPackages := []database.Feature{} + missingPackages := []database.LayerFeature{} for pkg, ok := range visited { if !ok { missingPackages = append(missingPackages, pkg) From 60b0bd27fa3e6125dd8a2dd24445f41c5955aa46 Mon Sep 17 00:00:00 2001 From: Ales Raszka Date: Wed, 6 Mar 2019 13:57:11 +0100 Subject: [PATCH 4/6] Add namespace_id as constraints to layer_feature If layer contains more than one potential namespace, features will be created for each namespace. Layer_feature table now has to contains one more constrains (namespace_id). --- database/pgsql/migrations/00001_initial_schema.go | 2 +- database/pgsql/queries.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/database/pgsql/migrations/00001_initial_schema.go b/database/pgsql/migrations/00001_initial_schema.go index 85b2b49c..180a1a15 100644 --- a/database/pgsql/migrations/00001_initial_schema.go +++ b/database/pgsql/migrations/00001_initial_schema.go @@ -90,7 +90,7 @@ var ( feature_id INT REFERENCES feature ON DELETE CASCADE, detector_id INT REFERENCES detector ON DELETE CASCADE, namespace_id INT REFERENCES namespace ON DELETE CASCADE, - UNIQUE (layer_id, feature_id));`, + UNIQUE (layer_id, feature_id, namespace_id));`, `CREATE INDEX ON layer_feature(layer_id);`, `CREATE TABLE IF NOT EXISTS layer_namespace ( diff --git a/database/pgsql/queries.go b/database/pgsql/queries.go index 111dc30e..e19f466a 100644 --- a/database/pgsql/queries.go +++ b/database/pgsql/queries.go @@ -121,7 +121,7 @@ func queryPersistFeature(count int) string { func queryPersistLayerFeature(count int) string { return queryPersist(count, "layer_feature", - "layer_feature_layer_id_feature_id_key", + "layer_feature_layer_id_feature_id_namespace_id_key", "layer_id", "feature_id", "detector_id", From a8a91379d9c51a04e178dba02660416180ba9046 Mon Sep 17 00:00:00 2001 From: Ales Raszka Date: Thu, 7 Mar 2019 13:53:58 +0100 Subject: [PATCH 5/6] Add test for potential namespace Test verifies that potential namespace is stored in database and it can be loaded back to structure. The commit also fixes few typos and bugs. --- database/dbutil.go | 2 +- database/pgsql/layer.go | 20 +++++++++++------ database/pgsql/layer_test.go | 22 +++++++++++++++++++ .../pgsql/migrations/00001_initial_schema.go | 2 +- database/pgsql/testdata/data.sql | 3 ++- database/pgsql/testutil.go | 1 + ext/featurefmt/apk/apk.go | 2 +- ext/featurefmt/dpkg/dpkg.go | 2 +- ext/featurefmt/rpm/rpm.go | 2 +- 9 files changed, 43 insertions(+), 13 deletions(-) diff --git a/database/dbutil.go b/database/dbutil.go index 6581e252..94528266 100644 --- a/database/dbutil.go +++ b/database/dbutil.go @@ -60,7 +60,7 @@ func ConvertFeatureSetToFeatures(features mapset.Set) []Feature { return uniqueFeatures } -func ConvertFeatureSerToLayerFeatures(features mapset.Set) []LayerFeature { +func ConvertFeatureSetToLayerFeatures(features mapset.Set) []LayerFeature { uniqueLayerFeatures := make([]LayerFeature, 0, features.Cardinality()) for f := range features.Iter() { feature := f.(Feature) diff --git a/database/pgsql/layer.go b/database/pgsql/layer.go index 4c1497fb..bce1ef06 100644 --- a/database/pgsql/layer.go +++ b/database/pgsql/layer.go @@ -37,12 +37,15 @@ const ( SELECT id FROM layer WHERE hash = $1` findLayerFeatures = ` - SELECT f.name, f.version, f.version_format, t.name, lf.detector_id, ns.name, ns.version_format - FROM layer_feature AS lf, feature AS f, feature_type AS t, namespace AS ns - WHERE lf.feature_id = f.id - AND t.id = f.type - AND lf.namespace_id = ns.id - AND lf.layer_id = $1` + SELECT + f.name, f.version, f.version_format, ft.name, lf.detector_id, ns.name, ns.version_format + FROM + layer_feature AS lf + LEFT JOIN feature f on f.id = lf.feature_id + LEFT JOIN feature_type ft on ft.id = f.type + LEFT JOIN namespace ns ON ns.id = lf.namespace_id + + WHERE lf.layer_id = $1` findLayerNamespaces = ` SELECT ns.name, ns.version_format, ln.detector_id @@ -320,9 +323,12 @@ func (tx *pgSession) findLayerFeatures(layerID int64, detectors detectorMap) ([] detectorID int64 feature database.LayerFeature ) - if err := rows.Scan(&feature.Name, &feature.Version, &feature.VersionFormat, &feature.Type, &detectorID, &feature.PotentialNamespace.Name, &feature.PotentialNamespace.VersionFormat); err != nil { + var namespaceName, namespaceVersion sql.NullString + if err := rows.Scan(&feature.Name, &feature.Version, &feature.VersionFormat, &feature.Type, &detectorID, &namespaceName, &namespaceVersion); err != nil { return nil, handleError("findLayerFeatures", err) } + feature.PotentialNamespace.Name = namespaceName.String + feature.PotentialNamespace.VersionFormat = namespaceVersion.String feature.By = detectors.byID[detectorID] features = append(features, feature) diff --git a/database/pgsql/layer_test.go b/database/pgsql/layer_test.go index 86ada23e..9b2be2bb 100644 --- a/database/pgsql/layer_test.go +++ b/database/pgsql/layer_test.go @@ -116,6 +116,28 @@ var persistLayerTests = []struct { }, }, }, + + { + title: "layer with potential namespace", + name: "layer-potential-namespace", + by: []database.Detector{realDetectors[3]}, + features: []database.LayerFeature{ + {realFeatures[4], realDetectors[3], realNamespaces[4]}, + }, + namespaces: []database.LayerNamespace{ + {realNamespaces[3], realDetectors[3]}, + }, + layer: &database.Layer{ + Hash: "layer-potential-namespace", + By: []database.Detector{realDetectors[3]}, + Features: []database.LayerFeature{ + {realFeatures[4], realDetectors[3], realNamespaces[4]}, + }, + Namespaces: []database.LayerNamespace{ + {realNamespaces[3], realDetectors[3]}, + }, + }, + }, } func TestPersistLayer(t *testing.T) { diff --git a/database/pgsql/migrations/00001_initial_schema.go b/database/pgsql/migrations/00001_initial_schema.go index 180a1a15..0072857c 100644 --- a/database/pgsql/migrations/00001_initial_schema.go +++ b/database/pgsql/migrations/00001_initial_schema.go @@ -89,7 +89,7 @@ var ( layer_id INT REFERENCES layer ON DELETE CASCADE, feature_id INT REFERENCES feature ON DELETE CASCADE, detector_id INT REFERENCES detector ON DELETE CASCADE, - namespace_id INT REFERENCES namespace ON DELETE CASCADE, + namespace_id INT NULL REFERENCES namespace ON DELETE CASCADE, UNIQUE (layer_id, feature_id, namespace_id));`, `CREATE INDEX ON layer_feature(layer_id);`, diff --git a/database/pgsql/testdata/data.sql b/database/pgsql/testdata/data.sql index 4c90ae0d..58d4c8bf 100644 --- a/database/pgsql/testdata/data.sql +++ b/database/pgsql/testdata/data.sql @@ -2,7 +2,8 @@ INSERT INTO namespace (id, name, version_format) VALUES (1, 'debian:7', 'dpkg'), (2, 'debian:8', 'dpkg'), - (3, 'fake:1.0', 'rpm'); + (3, 'fake:1.0', 'rpm'), + (4, 'cpe:/o:redhat:enterprise_linux:7::server', 'rpm'); INSERT INTO feature (id, name, version, version_format, type) VALUES (1, 'ourchat', '0.5', 'dpkg', 1), diff --git a/database/pgsql/testutil.go b/database/pgsql/testutil.go index d6ceb145..b1bfabf7 100644 --- a/database/pgsql/testutil.go +++ b/database/pgsql/testutil.go @@ -49,6 +49,7 @@ var ( 1: {"debian:7", "dpkg"}, 2: {"debian:8", "dpkg"}, 3: {"fake:1.0", "rpm"}, + 4: {"cpe:/o:redhat:enterprise_linux:7::server", "rpm"}, } realNamespacedFeatures = map[int]database.NamespacedFeature{ diff --git a/ext/featurefmt/apk/apk.go b/ext/featurefmt/apk/apk.go index dcc9f5eb..d245de5d 100644 --- a/ext/featurefmt/apk/apk.go +++ b/ext/featurefmt/apk/apk.go @@ -86,7 +86,7 @@ func (l lister) ListFeatures(files tarutil.FilesMap) ([]database.LayerFeature, e packages.Add(pkg) } - return database.ConvertFeatureSerToLayerFeatures(packages), nil + return database.ConvertFeatureSetToLayerFeatures(packages), nil } func (l lister) RequiredFilenames() []string { diff --git a/ext/featurefmt/dpkg/dpkg.go b/ext/featurefmt/dpkg/dpkg.go index 2b5fd876..ea88c372 100644 --- a/ext/featurefmt/dpkg/dpkg.go +++ b/ext/featurefmt/dpkg/dpkg.go @@ -69,7 +69,7 @@ func (l lister) ListFeatures(files tarutil.FilesMap) ([]database.LayerFeature, e } } - return database.ConvertFeatureSerToLayerFeatures(packages), nil + return database.ConvertFeatureSetToLayerFeatures(packages), nil } // parseDpkgDB consumes the status file scanner exactly one package info, until diff --git a/ext/featurefmt/rpm/rpm.go b/ext/featurefmt/rpm/rpm.go index b85bc81f..f8d91055 100644 --- a/ext/featurefmt/rpm/rpm.go +++ b/ext/featurefmt/rpm/rpm.go @@ -101,7 +101,7 @@ func (l lister) ListFeatures(files tarutil.FilesMap) ([]database.LayerFeature, e } } - return database.ConvertFeatureSerToLayerFeatures(packages), nil + return database.ConvertFeatureSetToLayerFeatures(packages), nil } func parseRPMOutput(raw string) (rpmPackage *database.Feature, srpmPackage *database.Feature) { From d77dc0f0aeee2cfdacae02347c807eaa2e17ca0b Mon Sep 17 00:00:00 2001 From: Ales Raszka Date: Fri, 8 Mar 2019 09:51:40 +0100 Subject: [PATCH 6/6] Use struct as a map key instead of string String was used when Feature contains PotentialNamespace. Since it was moved to LayerFeature we can use struct as map key instead of string. --- database/pgsql/feature.go | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/database/pgsql/feature.go b/database/pgsql/feature.go index 58f12dbd..66b47c50 100644 --- a/database/pgsql/feature.go +++ b/database/pgsql/feature.go @@ -17,7 +17,6 @@ package pgsql import ( "database/sql" "sort" - "strconv" "github.com/lib/pq" log "github.com/sirupsen/logrus" @@ -312,7 +311,7 @@ func (tx *pgSession) findNamespacedFeatureIDs(nfs []database.NamespacedFeature) return nil, nil } - nfsMap := map[string]int64{} + nfsMap := map[database.NamespacedFeature]int64{} keys := make([]interface{}, 0, len(nfs)*5) for _, nf := range nfs { keys = append(keys, nf.Name, nf.Version, nf.VersionFormat, nf.Type, nf.Namespace.Name) @@ -335,12 +334,12 @@ func (tx *pgSession) findNamespacedFeatureIDs(nfs []database.NamespacedFeature) if err != nil { return nil, handleError("searchNamespacedFeature", err) } - nfsMap[nf.Key()] = id + nfsMap[nf] = id } ids := make([]sql.NullInt64, len(nfs)) for i, nf := range nfs { - if id, ok := nfsMap[nf.Key()]; ok { + if id, ok := nfsMap[nf]; ok { ids[i] = sql.NullInt64{id, true} } else { ids[i] = sql.NullInt64{} @@ -360,14 +359,13 @@ func (tx *pgSession) findFeatureIDs(fs []database.Feature) ([]sql.NullInt64, err return nil, err } - fMap := map[string]sql.NullInt64{} + fMap := map[database.Feature]sql.NullInt64{} keys := make([]interface{}, 0, len(fs)*4) for _, f := range fs { typeID := types.byName[f.Type] keys = append(keys, f.Name, f.Version, f.VersionFormat, typeID) - mapKey := f.Name + f.Version + f.VersionFormat + strconv.Itoa(typeID) - fMap[mapKey] = sql.NullInt64{} + fMap[f] = sql.NullInt64{} } rows, err := tx.Query(querySearchFeatureID(len(fs)), keys...) @@ -388,15 +386,12 @@ func (tx *pgSession) findFeatureIDs(fs []database.Feature) ([]sql.NullInt64, err } f.Type = types.byID[typeID] - mapKey := f.Name + f.Version + f.VersionFormat + strconv.Itoa(typeID) - fMap[mapKey] = id + fMap[f] = id } ids := make([]sql.NullInt64, len(fs)) for i, f := range fs { - typeID := types.byName[f.Type] - mapKey := f.Name + f.Version + f.VersionFormat + strconv.Itoa(typeID) - ids[i] = fMap[mapKey] + ids[i] = fMap[f] } return ids, nil