From d13eab6947e824692a494225263c6ab2875b8c69 Mon Sep 17 00:00:00 2001 From: Mikhail Klementev Date: Fri, 12 May 2023 20:05:44 +0000 Subject: [PATCH] Match by debian release --- config/config.go | 2 +- distro/debian/debian.go | 110 +++++++++++++++++++++++++++++++++-- distro/debian/debian_test.go | 53 ++++++++++++++++- 3 files changed, 158 insertions(+), 7 deletions(-) diff --git a/config/config.go b/config/config.go index 346f64a..20d8df5 100644 --- a/config/config.go +++ b/config/config.go @@ -27,7 +27,7 @@ type kernel struct { // KernelMask defines the kernel type KernelMask struct { DistroType DistroType - DistroRelease string // 18.04/7.4.1708/9.1 + DistroRelease string // 18.04/7/9 ReleaseMask string // Overrides ReleaseMask diff --git a/distro/debian/debian.go b/distro/debian/debian.go index a89aa33..33d056b 100644 --- a/distro/debian/debian.go +++ b/distro/debian/debian.go @@ -1,8 +1,10 @@ package debian import ( + "errors" "os/user" "regexp" + "strconv" "strings" "github.com/rs/zerolog/log" @@ -10,10 +12,17 @@ import ( "code.dumpstack.io/tools/out-of-tree/config" ) -type CodeName int +type Release int const ( - Wheezy CodeName = iota + None Release = iota + Buzz + Hamm + Woody + Etch + Lenny + Squeeze + Wheezy Jessie Stretch Buster @@ -21,7 +30,14 @@ const ( Bookworm ) -var CodeNameStrings = [...]string{ +var ReleaseStrings = [...]string{ + "", + "Buzz", + "Hamm", + "Woody", + "Etch", + "Lenny", + "Squeeze", "Wheezy", "Jessie", "Stretch", @@ -30,8 +46,79 @@ var CodeNameStrings = [...]string{ "Bookworm", } -func (cn CodeName) String() string { - return CodeNameStrings[cn] +func (cn Release) String() string { + return ReleaseStrings[cn] +} + +func releaseFromString(s string) (r Release) { + switch strings.ToLower(s) { + case "7", "wheezy": + r = Wheezy + case "8", "jessie": + r = Jessie + case "9", "stretch": + r = Stretch + case "10", "buster": + r = Buster + case "11", "bullseye": + r = Bullseye + default: + r = None + } + return +} + +func parseKernelMajorMinor(deb string) (major, minor int, err error) { + // linux-image-4.17.0-2-amd64 -> 4.17 + re := regexp.MustCompile(`([0-9]*\.[0-9]*)`) + + s := re.FindString(deb) + if s == "" { + err = errors.New("empty result") + return + } + + split := strings.Split(s, ".") + if len(split) != 2 { + err = errors.New("unexpected input") + return + } + + major, err = strconv.Atoi(split[0]) + if err != nil { + return + } + + minor, err = strconv.Atoi(split[1]) + if err != nil { + return + } + + return +} + +func kernelRelease(deb string) (r Release, err error) { + major, minor, err := parseKernelMajorMinor(deb) + if err != nil { + return + } + + if major < 3 { + err = errors.New("not supported") + return + } else if major <= 3 && minor < 16 { + r = Wheezy // 3.2 + } else if major <= 4 && minor < 9 { + r = Jessie // 3.16 + } else if major <= 4 && minor < 19 { + r = Stretch // 4.9 + } else if major <= 5 && minor < 10 { + r = Buster // 4.19 + } else { + r = Bullseye // 5.10 + } + + return } var ( @@ -66,10 +153,23 @@ func MatchImagePkg(km config.KernelMask) (pkgs []string, err error) { return } + release := releaseFromString(km.DistroRelease) + r := regexp.MustCompile(km.ReleaseMask) for _, dk := range kernels { p := strings.Replace(dk.Image.Deb.Name, ".deb", "", -1) + + var kr Release + kr, err = kernelRelease(p) + if err != nil { + log.Warn().Err(err).Msg("") + continue + } + if kr != release { + continue + } + if r.MatchString(p) { pkgs = append(pkgs, p) } diff --git a/distro/debian/debian_test.go b/distro/debian/debian_test.go index 8ac138e..ae16777 100644 --- a/distro/debian/debian_test.go +++ b/distro/debian/debian_test.go @@ -7,7 +7,10 @@ import ( ) func TestMatchImagePkg(t *testing.T) { - km := config.KernelMask{ReleaseMask: "3.2.0-4"} + km := config.KernelMask{ + ReleaseMask: "3.2.0-4", + DistroRelease: "7", + } pkgs, err := MatchImagePkg(km) if err != nil { @@ -18,3 +21,51 @@ func TestMatchImagePkg(t *testing.T) { t.Fatal("no packages") } } + +func TestParseKernelMajorMinor(t *testing.T) { + type testcase struct { + Deb string + Major, Minor int + } + + for _, tc := range []testcase{ + testcase{"linux-image-4.17.0-2-amd64", 4, 17}, + testcase{"linux-image-6.1.0-8-amd64-unsigned", 6, 1}, + testcase{"linux-image-6.1.0-0.deb11.7-amd64-unsigned", 6, 1}, + testcase{"linux-image-3.2.0-0.bpo.4-amd64_3.2.41-2+deb7u2~bpo60+1_amd64", 3, 2}, + testcase{"linux-image-5.16.0-rc5-amd64-unsigned_5.16~rc5-1~exp1_amd64", 5, 16}, + testcase{"linux-image-3.6-trunk-amd64_3.8.4-1~experimental.1_amd64", 3, 6}, + } { + major, minor, err := parseKernelMajorMinor(tc.Deb) + if err != nil { + t.Fatal(err) + } + if major != tc.Major || minor != tc.Minor { + t.Fatalf("%v -> %v.%v != %v.%v", tc.Deb, major, minor, + tc.Major, tc.Minor) + } + } +} + +func TestKernelRelease(t *testing.T) { + type testcase struct { + Deb string + Release Release + } + + for _, tc := range []testcase{ + testcase{"linux-image-4.17.0-2-amd64", Stretch}, + testcase{"linux-image-6.1.0-8-amd64-unsigned", Bullseye}, + testcase{"linux-image-6.1.0-0.deb11.7-amd64-unsigned", Bullseye}, + testcase{"linux-image-3.2.0-0.bpo.4-amd64_3.2.41-2+deb7u2~bpo60+1_amd64", Wheezy}, + testcase{"linux-image-5.16.0-rc5-amd64-unsigned_5.16~rc5-1~exp1_amd64", Bullseye}, + } { + r, err := kernelRelease(tc.Deb) + if err != nil { + t.Fatal(err) + } + if r != tc.Release { + t.Fatalf("%v -> %v != %v", tc.Deb, r, tc.Release) + } + } +}