Skip to content

Commit

Permalink
rpm: change RepositoryHint to use URL formatting
Browse files Browse the repository at this point in the history
This makes things easier to reason about and removes the ad-hoc parsing
that used to happen.

Signed-off-by: Hank Donnay <hdonnay@redhat.com>
  • Loading branch information
hdonnay committed Jan 12, 2024
1 parent 5980074 commit cb74edd
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 47 deletions.
26 changes: 8 additions & 18 deletions rpm/native_db.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"context"
"fmt"
"io"
"net/url"
"runtime/trace"
"strings"

Expand Down Expand Up @@ -76,7 +77,7 @@ func packagesFromDB(ctx context.Context, pkgdb string, db nativeDB) ([]*claircor
}
p.Module = modStream
p.Version = constructEVR(&b, &info)
p.RepositoryHint = constructHint(&b, &info)
p.RepositoryHint = constructHint(&info)

if s, ok := src[info.SourceNEVR]; ok {
p.Source = s
Expand Down Expand Up @@ -185,14 +186,12 @@ func constructEVR(b *strings.Builder, info *Info) string {
return b.String()
}

func constructHint(b *strings.Builder, info *Info) string {
b.Reset()
func constructHint(info *Info) string {
v := url.Values{}
if info.Digest != "" {
b.WriteString("hash:")
switch info.DigestAlgo {
case 8:
b.WriteString("sha256:")
b.WriteString(info.Digest)
v.Add("hash", fmt.Sprintf("sha256:%s", info.Digest))
}
}
if len(info.Signature) != 0 {
Expand All @@ -204,20 +203,11 @@ func constructHint(b *strings.Builder, info *Info) string {
if p.SigType != 0 {
continue
}
if b.Len() != 0 {
b.WriteByte('|')
}
fmt.Fprintf(b, "key:%016x", p.IssuerKeyId)
v.Add("key", fmt.Sprintf("%016x", p.IssuerKeyId))
case *packet.Signature:
if p.SigType != 0 || p.IssuerKeyId == nil {
continue
}
if b.Len() != 0 {
b.WriteByte('|')
}
fmt.Fprintf(b, "key:%016x", *p.IssuerKeyId)
v.Add("key", fmt.Sprintf("%016x", p.IssuerKeyId))

Check warning on line 208 in rpm/native_db.go

View check run for this annotation

Codecov / codecov/patch

rpm/native_db.go#L208

Added line #L208 was not covered by tests
}
}
}
return b.String()
return v.Encode()
}
31 changes: 31 additions & 0 deletions rpm/packagescanner.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@ package rpm

import (
"context"
"errors"
"fmt"
"io"
"io/fs"
"net/url"
"os"
"path"
"runtime/trace"
Expand Down Expand Up @@ -167,6 +169,35 @@ func (ps *Scanner) Scan(ctx context.Context, layer *claircore.Layer) ([]*clairco
}
pkgs = append(pkgs, ps...)
}
rm, err := repoMap(ctx, sys)
switch {
case errors.Is(err, nil) && len(rm) != 0: // OK
for _, pkg := range pkgs {
nerva := fmt.Sprintf("%s-%s.%s", pkg.Name, pkg.Version, pkg.Arch)
repoid, ok := rm[nerva]
if !ok {
// Packages not installed via dnf, which may happen during
// bootstrapping, aren't present in the dnf history database.
// This means the process shouldn't bail if the package is
// missing.
continue

Check warning on line 183 in rpm/packagescanner.go

View check run for this annotation

Codecov / codecov/patch

rpm/packagescanner.go#L174-L183

Added lines #L174 - L183 were not covered by tests
}
v, err := url.ParseQuery(pkg.RepositoryHint)
if err != nil { // Shouldn't happen:
zlog.Warn(ctx).
AnErr("url.ParseQuery", err).
Msg("malformed RepositoryHint")
continue

Check warning on line 190 in rpm/packagescanner.go

View check run for this annotation

Codecov / codecov/patch

rpm/packagescanner.go#L185-L190

Added lines #L185 - L190 were not covered by tests
}
v.Add("repoid", repoid)
pkg.RepositoryHint = v.Encode()

Check warning on line 193 in rpm/packagescanner.go

View check run for this annotation

Codecov / codecov/patch

rpm/packagescanner.go#L192-L193

Added lines #L192 - L193 were not covered by tests
}
case errors.Is(err, nil) && len(rm) == 0: // nothing found
default: // some error
zlog.Warn(ctx).
AnErr("repoMap", err).
Msg("unable to open dnf history database")

Check warning on line 199 in rpm/packagescanner.go

View check run for this annotation

Codecov / codecov/patch

rpm/packagescanner.go#L196-L199

Added lines #L196 - L199 were not covered by tests
}

return pkgs, nil
}
Expand Down
41 changes: 12 additions & 29 deletions test/rpmtest/manifest.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package rpmtest
import (
"encoding/json"
"io"
"sort"
"net/url"
"strings"
"testing"

Expand Down Expand Up @@ -41,7 +41,7 @@ func PackagesFromRPMManifest(t *testing.T, r io.Reader) []*claircore.Package {
Version: rpm.Version + "-" + rpm.Release,
Kind: "binary",
Arch: rpm.Arch,
RepositoryHint: "key:" + rpm.GPG,
RepositoryHint: url.Values{"key": {rpm.GPG}}.Encode(),
Module: rpm.Module,
}
if s, ok := src[rpm.Source]; ok {
Expand Down Expand Up @@ -82,35 +82,18 @@ var Options = cmp.Options{
// so cook up a comparison function that understands the rpm package's packed format.
var HintCompare = cmp.FilterPath(
func(p cmp.Path) bool { return p.Last().String() == ".RepositoryHint" },
cmpopts.AcyclicTransformer("NormalizeHint", func(h string) string {
n := [][2]string{}
for _, s := range strings.Split(h, "|") {
if s == "" {
continue
}
k, v, ok := strings.Cut(s, ":")
if !ok {
panic("odd format: " + s)
}
if k == "hash" {
continue
}
i := len(n)
n = append(n, [2]string{})
n[i][0] = k
n[i][1] = v
cmp.Comparer(func(a, b string) bool {
av, err := url.ParseQuery(a)
if err != nil {
panic(err)
}
sort.Slice(n, func(i, j int) bool { return n[i][0] < n[i][1] })
var b strings.Builder
for i, s := range n {
if i != 0 {
b.WriteByte('|')
}
b.WriteString(s[0])
b.WriteByte(':')
b.WriteString(s[1])
bv, err := url.ParseQuery(b)
if err != nil {
panic(err)
}
return b.String()
av.Del("hash")
bv.Del("hash")
return cmp.Equal(av.Encode(), bv.Encode())
}),
)

Expand Down

0 comments on commit cb74edd

Please sign in to comment.