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

290 lines
5.1 KiB
Go
Raw Normal View History

2023-05-11 22:17:46 +00:00
package debian
2023-05-12 17:26:53 +00:00
import (
2023-05-12 20:05:44 +00:00
"errors"
"fmt"
2023-05-12 17:26:53 +00:00
"regexp"
2023-05-12 20:05:44 +00:00
"strconv"
2023-05-12 17:26:53 +00:00
"strings"
"github.com/rs/zerolog/log"
"code.dumpstack.io/tools/out-of-tree/cache"
2023-05-12 17:26:53 +00:00
"code.dumpstack.io/tools/out-of-tree/config"
"code.dumpstack.io/tools/out-of-tree/container"
2023-05-13 16:08:59 +00:00
"code.dumpstack.io/tools/out-of-tree/fs"
2023-05-12 17:26:53 +00:00
)
2023-05-12 20:05:44 +00:00
type Release int
2023-05-11 22:17:46 +00:00
const (
2023-05-12 20:05:44 +00:00
None Release = iota
Buzz
Hamm
Woody
Etch
Lenny
Squeeze
Wheezy
2023-05-11 22:17:46 +00:00
Jessie
Stretch
Buster
Bullseye
Bookworm
)
2023-05-12 20:05:44 +00:00
var ReleaseStrings = [...]string{
"",
2023-05-13 19:08:46 +00:00
"buzz",
"hamm",
"woody",
"etch",
"lenny",
"squeeze",
"wheezy",
"jessie",
"stretch",
"buster",
"bullseye",
"bookworm",
2023-05-11 22:17:46 +00:00
}
2023-05-12 20:05:44 +00:00
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
}
2023-05-13 17:42:25 +00:00
// Wheezy 3.2
// Jessie 3.16
// Stretch 4.9
// Buster 4.19
// Bullseye 5.10
2023-05-12 20:05:44 +00:00
if major < 3 {
err = errors.New("not supported")
return
2023-05-13 17:42:25 +00:00
}
switch major {
case 3:
if minor < 16 {
r = Wheezy
} else {
r = Jessie
}
case 4:
if minor < 9 {
r = Jessie
} else if minor < 19 {
r = Stretch
} else {
r = Buster
}
case 5:
if minor < 10 {
r = Buster
} else {
r = Bullseye
}
default:
r = Bullseye // latest release
2023-05-12 20:05:44 +00:00
}
return
2023-05-11 22:17:46 +00:00
}
2023-05-12 17:26:53 +00:00
var (
CachePath string
RefetchDays int = 7
)
func MatchImagePkg(km config.KernelMask) (pkgs []string, err error) {
if CachePath == "" {
2023-05-13 09:09:29 +00:00
CachePath = config.File("debian.cache")
2023-05-12 17:26:53 +00:00
log.Debug().Msgf("Use default kernels cache path: %s", CachePath)
2023-05-13 16:08:59 +00:00
if !fs.PathExists(CachePath) {
log.Debug().Msgf("No cache, download")
err = cache.DownloadDebianCache(CachePath)
if err != nil {
log.Debug().Err(err).Msg(
"No remote cache, will take some time")
}
}
2023-05-12 17:26:53 +00:00
} else {
log.Debug().Msgf("Debian kernels cache path: %s", CachePath)
}
c, err := NewCache(CachePath)
if err != nil {
log.Error().Err(err).Msg("cache")
return
}
defer c.Close()
kernels, err := GetKernels(c, RefetchDays)
if err != nil {
log.Error().Err(err).Msg("get kernels")
return
}
2023-05-12 20:05:44 +00:00
release := releaseFromString(km.DistroRelease)
2023-05-12 17:26:53 +00:00
r := regexp.MustCompile(km.ReleaseMask)
for _, dk := range kernels {
p := strings.Replace(dk.Image.Deb.Name, ".deb", "", -1)
2023-05-12 20:05:44 +00:00
var kr Release
kr, err = kernelRelease(p)
if err != nil {
log.Warn().Err(err).Msg("")
continue
}
if kr != release {
continue
}
2023-05-12 17:26:53 +00:00
if r.MatchString(p) {
pkgs = append(pkgs, p)
}
}
return
}
2023-05-14 07:00:00 +00:00
func ContainerEnvs(km config.KernelMask) (envs []string) {
envs = append(envs, "DEBIAN_FRONTEND=noninteractive")
return
}
func ContainerImage(km config.KernelMask) (image string) {
image += "debian:"
switch releaseFromString(km.DistroRelease) {
case Wheezy:
image += "wheezy-20190228"
case Jessie:
image += "jessie-20210326"
case Stretch:
image += "stretch-20220622"
default:
image += km.DistroType.String()
}
return
}
func repositories(release Release) (repos []string) {
var snapshot string
switch release {
// Latest snapshots that include release
case Wheezy:
// doesn't include snapshot repos in /etc/apt/source.list
snapshot = "20190321T212815Z"
// case Jessie:
// snapshot = "20230322T152120Z"
// case Stretch:
// snapshot = "20230423T032533Z"
default:
return
}
repo := func(archive, s string) {
format := "deb [check-valid-until=no trusted=yes] " +
"http://snapshot.debian.org/archive/%s/%s " +
"%s%s main"
r := fmt.Sprintf(format, archive, snapshot, release, s)
repos = append(repos, r)
}
repo("debian", "")
repo("debian", "-updates")
repo("debian-security", "/updates")
return
}
func ContainerCommands(km config.KernelMask) (commands []string) {
release := releaseFromString(km.DistroRelease)
cmdf := func(f string, s ...interface{}) {
commands = append(commands, fmt.Sprintf(f, s...))
}
repos := repositories(release)
if len(repos) != 0 {
cmdf("rm /etc/apt/sources.list")
for _, repo := range repos {
cmdf("echo '%s' >> /etc/apt/sources.list", repo)
}
} else {
cmdf("sed -e '/snapshot/!d' -e 's/# deb/deb [check-valid-until=no trusted=yes]/' /etc/apt/sources.list")
}
cmdf("apt-get update")
cmdf("apt-get install -y wget build-essential libelf-dev git")
cmdf("mkdir -p /lib/modules")
return
}
func ContainerKernels(d container.Image, kcfg *config.KernelConfig) (err error) {
err = errors.New("TODO not implemented")
return
}