1
0
out-of-tree/distro/debian/kernel.go

157 lines
3.2 KiB
Go
Raw Normal View History

2023-05-11 19:26:54 +00:00
package debian
import (
"errors"
2023-05-11 20:25:34 +00:00
"fmt"
2023-05-11 19:26:54 +00:00
"strings"
2023-05-12 00:07:51 +00:00
"time"
2023-05-11 19:26:54 +00:00
2023-05-12 15:00:50 +00:00
"github.com/rs/zerolog/log"
2023-05-11 19:26:54 +00:00
"code.dumpstack.io/tools/out-of-tree/distro/debian/snapshot"
)
type DebianKernelVersion struct {
// linux-headers-4.17.0-2-amd64_4.17.14-1_amd64.deb
// Package version, e.g. "4.17.14-1"
// See tags in https://salsa.debian.org/kernel-team/linux
Package string
// ABI version, e.g. "4.17.0-2"
ABI string
}
type DebianKernel struct {
Version DebianKernelVersion
Image snapshot.Package
Headers snapshot.Package
2023-05-12 00:07:51 +00:00
// FIXME There is a better way
Internal struct {
Invalid bool
LastFetch time.Time
}
2023-05-11 19:26:54 +00:00
}
2023-05-11 20:25:34 +00:00
var (
ErrNoBinaryPackages = errors.New("no binary packages found")
ErrNoHeadersPackage = errors.New("no headers package found")
ErrNoImagePackage = errors.New("no image package found")
)
2023-05-11 19:26:54 +00:00
func GetDebianKernel(version string) (dk DebianKernel, err error) {
dk.Version.Package = version
2023-05-11 21:47:43 +00:00
regex := `^linux-(image|headers)-[a-z+~0-9\.\-]*-(amd64|amd64-unsigned)$`
2023-05-11 19:26:54 +00:00
2023-05-11 22:17:31 +00:00
filter := []string{
"rt-amd64",
"cloud-amd64",
"all-amd64",
2023-05-11 20:45:53 +00:00
}
2023-05-11 21:47:43 +00:00
2023-05-11 22:17:31 +00:00
packages, err := snapshot.Packages("linux", version, "amd64",
regex, filter)
if err != nil {
return
2023-05-11 21:47:43 +00:00
}
2023-05-11 20:25:34 +00:00
if len(packages) == 0 {
err = ErrNoBinaryPackages
return
} else if len(packages) == 1 {
if strings.Contains(packages[0].Name, "image") {
err = ErrNoHeadersPackage
return
} else if strings.Contains(packages[0].Name, "headers") {
err = ErrNoImagePackage
return
} else {
err = fmt.Errorf("wtf? %v", packages[0].Name)
return
}
} else if len(packages) > 2 {
err = errors.New("more than two binary packages found")
2023-05-11 19:26:54 +00:00
return
}
var imageFound, headersFound bool
for _, p := range packages {
if strings.Contains(p.Name, "image") {
imageFound = true
dk.Image = p
} else if strings.Contains(p.Name, "headers") {
headersFound = true
dk.Headers = p
}
}
if !imageFound {
err = errors.New("image not found")
return
}
if !headersFound {
err = errors.New("headers not found")
return
}
s := strings.Replace(dk.Headers.Name, "linux-headers-", "", -1)
dk.Version.ABI = strings.Replace(s, "-amd64", "", -1)
return
}
2023-05-12 15:00:50 +00:00
func GetKernels(c *Cache, refetchDays int) (kernels []DebianKernel, err error) {
versions, err := snapshot.SourcePackageVersions("linux")
if err != nil {
log.Error().Err(err).Msg("get source package versions")
return
}
for i, version := range versions {
slog := log.With().Str("version", version).Logger()
slog.Debug().Msgf("%03d/%03d", i, len(versions))
var dk DebianKernel
dk, err = c.Get(version)
if err == nil && !dk.Internal.Invalid {
slog.Debug().Msgf("found in cache")
kernels = append(kernels, dk)
continue
}
if dk.Internal.Invalid {
refetch := dk.Internal.LastFetch.AddDate(0, 0, refetchDays)
if refetch.After(time.Now()) {
slog.Debug().Msgf("refetch at %v", refetchDays)
continue
}
}
dk, err = GetDebianKernel(version)
if err != nil {
if err == ErrNoBinaryPackages {
slog.Warn().Err(err).Msg("")
} else {
slog.Error().Err(err).Msg("get debian kernel")
}
dk.Internal.Invalid = true
dk.Internal.LastFetch = time.Now()
}
err = c.Put(dk)
if err != nil {
slog.Error().Err(err).Msg("put to cache")
return
}
slog.Debug().Msgf("%s cached", version)
}
return
}