| 
									
										
										
										
											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" | 
					
						
							| 
									
										
										
										
											2023-05-13 19:51:57 +00:00
										 |  |  | 	"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" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-13 11:04:35 +00:00
										 |  |  | 	"code.dumpstack.io/tools/out-of-tree/cache" | 
					
						
							| 
									
										
										
										
											2023-05-12 17:26:53 +00:00
										 |  |  | 	"code.dumpstack.io/tools/out-of-tree/config" | 
					
						
							| 
									
										
										
										
											2023-05-14 07:19:35 +00:00
										 |  |  | 	"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 11:04:35 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											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-13 11:04:35 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											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-13 19:51:57 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-14 07:00:00 +00:00
										 |  |  | func ContainerEnvs(km config.KernelMask) (envs []string) { | 
					
						
							| 
									
										
										
										
											2023-05-13 19:51:57 +00:00
										 |  |  | 	envs = append(envs, "DEBIAN_FRONTEND=noninteractive") | 
					
						
							|  |  |  | 	return | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-14 09:53:59 +00:00
										 |  |  | func ContainerImage(km config.KernelMask) (image string) { | 
					
						
							|  |  |  | 	image += "debian:" | 
					
						
							| 
									
										
										
										
											2023-05-13 19:51:57 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-14 09:53:59 +00:00
										 |  |  | 	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) { | 
					
						
							| 
									
										
										
										
											2023-05-13 19:51:57 +00:00
										 |  |  | 	var snapshot string | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	switch release { | 
					
						
							| 
									
										
										
										
											2023-05-14 09:53:59 +00:00
										 |  |  | 	// Latest snapshots that include release | 
					
						
							| 
									
										
										
										
											2023-05-13 19:51:57 +00:00
										 |  |  | 	case Wheezy: | 
					
						
							| 
									
										
										
										
											2023-05-14 09:53:59 +00:00
										 |  |  | 		// doesn't include snapshot repos in /etc/apt/source.list | 
					
						
							|  |  |  | 		snapshot = "20190321T212815Z" | 
					
						
							|  |  |  | 	// case Jessie: | 
					
						
							|  |  |  | 	// 	snapshot = "20230322T152120Z" | 
					
						
							|  |  |  | 	// case Stretch: | 
					
						
							|  |  |  | 	// 	snapshot = "20230423T032533Z" | 
					
						
							| 
									
										
										
										
											2023-05-13 19:51:57 +00:00
										 |  |  | 	default: | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-14 09:53:59 +00:00
										 |  |  | 	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) | 
					
						
							| 
									
										
										
										
											2023-05-13 19:51:57 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	cmdf := func(f string, s ...interface{}) { | 
					
						
							|  |  |  | 		commands = append(commands, fmt.Sprintf(f, s...)) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-14 09:53:59 +00:00
										 |  |  | 	repos := repositories(release) | 
					
						
							| 
									
										
										
										
											2023-05-13 19:51:57 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-14 09:53:59 +00:00
										 |  |  | 	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") | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2023-05-13 19:51:57 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	cmdf("apt-get update") | 
					
						
							| 
									
										
										
										
											2023-05-14 09:53:59 +00:00
										 |  |  | 	cmdf("apt-get install -y wget build-essential libelf-dev git") | 
					
						
							| 
									
										
										
										
											2023-05-13 19:51:57 +00:00
										 |  |  | 	cmdf("mkdir -p /lib/modules") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2023-05-14 07:19:35 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | func ContainerKernels(d container.Image, kcfg *config.KernelConfig) (err error) { | 
					
						
							|  |  |  | 	err = errors.New("TODO not implemented") | 
					
						
							|  |  |  | 	return | 
					
						
							|  |  |  | } |