From 161259a33b0c1b0c0b131b8dac84c1273a902d19 Mon Sep 17 00:00:00 2001 From: Kieran Muller Date: Thu, 27 Jul 2023 14:29:28 +0100 Subject: [PATCH] debian:distroless dist parsing support and tests Signed-off-by: Kieran Muller --- debian/distributionscanner.go | 8 ++- debian/distributionscanner_test.go | 51 ++++++++++++------- .../distroless_dist/10/etc/os-release | 8 +++ .../distroless_dist/11/etc/os-release | 8 +++ .../testdata/distroless_dist/9/etc/os-release | 8 +++ osrelease/scanner_test.go | 22 ++++++++ osrelease/testdata/distroless_corrupt_layer | 8 +++ osrelease/testdata/distroless_valid_layer | 9 ++++ 8 files changed, 101 insertions(+), 21 deletions(-) create mode 100644 debian/testdata/distroless_dist/10/etc/os-release create mode 100644 debian/testdata/distroless_dist/11/etc/os-release create mode 100644 debian/testdata/distroless_dist/9/etc/os-release create mode 100644 osrelease/testdata/distroless_corrupt_layer create mode 100644 osrelease/testdata/distroless_valid_layer diff --git a/debian/distributionscanner.go b/debian/distributionscanner.go index 6d51d591d..e4d84fd8e 100644 --- a/debian/distributionscanner.go +++ b/debian/distributionscanner.go @@ -5,6 +5,7 @@ import ( "errors" "fmt" "io/fs" + "regexp" "runtime/trace" "strconv" "strings" @@ -31,7 +32,7 @@ type DistributionScanner struct{} func (*DistributionScanner) Name() string { return "debian" } // Version implements [indexer.VersionedScanner]. -func (*DistributionScanner) Version() string { return "2" } +func (*DistributionScanner) Version() string { return "3" } // Kind implements [indexer.VersionedScanner]. func (*DistributionScanner) Kind() string { return "distribution" } @@ -85,10 +86,13 @@ func findDist(ctx context.Context, sys fs.FS) (*claircore.Distribution, error) { return nil, nil } + // Regex pattern matches item within string that appear as so: (bookworm), (buster), (bullseye) + ver := regexp.MustCompile(`\(\w+\)$`) + name, nameok := kv[`VERSION_CODENAME`] idstr := kv[`VERSION_ID`] if !nameok { - name = strings.TrimFunc(kv[`VERSION`], func(r rune) bool { return !unicode.IsLetter(r) }) + name = strings.TrimFunc(ver.FindString(kv[`VERSION`]), func(r rune) bool { return !unicode.IsLetter(r) }) } if name == "" || idstr == "" { zlog.Info(ctx). diff --git a/debian/distributionscanner_test.go b/debian/distributionscanner_test.go index 531a39a69..5a2241da4 100644 --- a/debian/distributionscanner_test.go +++ b/debian/distributionscanner_test.go @@ -2,6 +2,7 @@ package debian import ( "context" + "io/fs" "os" "path/filepath" "regexp" @@ -17,24 +18,36 @@ func TestDistributionScanner(t *testing.T) { if err != nil { t.Fatal(err) } - for _, e := range ents { - t.Run(e.Name(), func(t *testing.T) { - sys := os.DirFS(filepath.Join(`testdata/dist`, e.Name())) - d, err := findDist(ctx, sys) - if err != nil { - t.Error(err) - } - if d == nil { - t.Fatalf("%s does not represent a Debian dist", e.Name()) - } - got, want := d.VersionID, e.Name() - t.Logf("got: %q, want: %q", got, want) - if got != want { - t.Fail() - } - if !ver.MatchString(d.Version) { - t.Fatalf("weird version: %q", d.Version) - } - }) + dEnts, err := os.ReadDir(`testdata/distroless_dist`) + if err != nil { + t.Fatal(err) + } + + testCase := map[string][]fs.DirEntry{ + "testdata/dist": ents, + "testdata/distroless_dist": dEnts, + } + + for tcDir, tcEnts := range testCase { + for _, e := range tcEnts { + t.Run(e.Name(), func(t *testing.T) { + sys := os.DirFS(filepath.Join(tcDir, e.Name())) + d, err := findDist(ctx, sys) + if err != nil { + t.Error(err) + } + if d == nil { + t.Fatalf("tc: %v | %s does not represent a Debian dist", tcDir, e.Name()) + } + got, want := d.VersionID, e.Name() + t.Logf("tc: %v | got: %q, want: %q", tcDir, got, want) + if got != want { + t.Fail() + } + if !ver.MatchString(d.Version) { + t.Fatalf("tc: %v | weird version: %q", tcDir, d.Version) + } + }) + } } } diff --git a/debian/testdata/distroless_dist/10/etc/os-release b/debian/testdata/distroless_dist/10/etc/os-release new file mode 100644 index 000000000..19a0e0d49 --- /dev/null +++ b/debian/testdata/distroless_dist/10/etc/os-release @@ -0,0 +1,8 @@ +PRETTY_NAME="Distroless" +NAME="Debian GNU/Linux" +ID="debian" +VERSION_ID="10" +VERSION="Debian GNU/Linux 10 (buster)" +HOME_URL="https://github.com/GoogleContainerTools/distroless" +SUPPORT_URL="https://github.com/GoogleContainerTools/distroless/blob/master/README.md" +BUG_REPORT_URL="https://github.com/GoogleContainerTools/distroless/issues/new" diff --git a/debian/testdata/distroless_dist/11/etc/os-release b/debian/testdata/distroless_dist/11/etc/os-release new file mode 100644 index 000000000..129cbf639 --- /dev/null +++ b/debian/testdata/distroless_dist/11/etc/os-release @@ -0,0 +1,8 @@ +PRETTY_NAME="Distroless" +NAME="Debian GNU/Linux" +ID="debian" +VERSION_ID="11" +VERSION="Debian GNU/Linux 11 (bullseye)" +HOME_URL="https://github.com/GoogleContainerTools/distroless" +SUPPORT_URL="https://github.com/GoogleContainerTools/distroless/blob/master/README.md" +BUG_REPORT_URL="https://github.com/GoogleContainerTools/distroless/issues/new" diff --git a/debian/testdata/distroless_dist/9/etc/os-release b/debian/testdata/distroless_dist/9/etc/os-release new file mode 100644 index 000000000..c34cc402f --- /dev/null +++ b/debian/testdata/distroless_dist/9/etc/os-release @@ -0,0 +1,8 @@ +PRETTY_NAME="Distroless" +NAME="Debian GNU/Linux" +ID="debian" +VERSION_ID="9" +VERSION="Debian GNU/Linux 9 (stretch)" +HOME_URL="https://github.com/GoogleContainerTools/distroless" +SUPPORT_URL="https://github.com/GoogleContainerTools/distroless/blob/master/README.md" +BUG_REPORT_URL="https://github.com/GoogleContainerTools/distroless/issues/new" diff --git a/osrelease/scanner_test.go b/osrelease/scanner_test.go index 657392044..6ccf4f5ed 100644 --- a/osrelease/scanner_test.go +++ b/osrelease/scanner_test.go @@ -122,6 +122,28 @@ func TestParse(t *testing.T) { PrettyName: "Red Hat Enterprise Linux 8", }, }, + { + File: "distroless_corrupt_layer", + Want: claircore.Distribution{ + DID: "debian", + Name: "Debian GNU/Linux", + Version: "Debian GNU/Linux 12 (bookworm)", + VersionCodeName: "", + VersionID: "12", + PrettyName: "Distroless", + }, + }, + { + File: "distroless_valid_layer", + Want: claircore.Distribution{ + DID: "debian", + Name: "Debian GNU/Linux", + Version: "12 (bookworm)", + VersionCodeName: "bookworm", + VersionID: "12", + PrettyName: "Debian GNU/Linux 12 (bookworm)", + }, + }, } for _, tc := range tt { t.Run(tc.File, tc.Test) diff --git a/osrelease/testdata/distroless_corrupt_layer b/osrelease/testdata/distroless_corrupt_layer new file mode 100644 index 000000000..d286ebe17 --- /dev/null +++ b/osrelease/testdata/distroless_corrupt_layer @@ -0,0 +1,8 @@ +PRETTY_NAME="Distroless" +NAME="Debian GNU/Linux" +ID="debian" +VERSION_ID="12" +VERSION="Debian GNU/Linux 12 (bookworm)" +HOME_URL="https://github.com/GoogleContainerTools/distroless" +SUPPORT_URL="https://github.com/GoogleContainerTools/distroless/blob/master/README.md" +BUG_REPORT_URL="https://github.com/GoogleContainerTools/distroless/issues/new" diff --git a/osrelease/testdata/distroless_valid_layer b/osrelease/testdata/distroless_valid_layer new file mode 100644 index 000000000..332086217 --- /dev/null +++ b/osrelease/testdata/distroless_valid_layer @@ -0,0 +1,9 @@ +PRETTY_NAME="Debian GNU/Linux 12 (bookworm)" +NAME="Debian GNU/Linux" +VERSION_ID="12" +VERSION="12 (bookworm)" +VERSION_CODENAME=bookworm +ID=debian +HOME_URL="https://www.debian.org/" +SUPPORT_URL="https://www.debian.org/support" +BUG_REPORT_URL="https://bugs.debian.org/"