1
0

feat: use distro info to create the container

This commit is contained in:
dump_stack() 2023-05-23 16:54:34 +00:00
parent f2ce20e53b
commit 7ca989fd8d
Signed by: dump_stack
GPG Key ID: BE44DA8C062D87DC
12 changed files with 130 additions and 150 deletions

View File

@ -8,6 +8,7 @@ import (
"bufio" "bufio"
"errors" "errors"
"fmt" "fmt"
"io/ioutil"
"os" "os"
"os/exec" "os/exec"
"path" "path"
@ -21,6 +22,7 @@ import (
"code.dumpstack.io/tools/out-of-tree/config" "code.dumpstack.io/tools/out-of-tree/config"
"code.dumpstack.io/tools/out-of-tree/distro" "code.dumpstack.io/tools/out-of-tree/distro"
"code.dumpstack.io/tools/out-of-tree/fs"
) )
var Runtime = "docker" var Runtime = "docker"
@ -73,16 +75,13 @@ func Images() (diis []Image, err error) {
return return
} }
func ImagePath(sk config.Target) string {
return config.Dir("containers", sk.Distro.ID.String(), sk.Distro.Release)
}
type Volume struct { type Volume struct {
Src, Dest string Src, Dest string
} }
type Container struct { type Container struct {
name string name string
dist distro.Distro
Volumes []Volume Volumes []Volume
@ -92,25 +91,29 @@ type Container struct {
Log zerolog.Logger Log zerolog.Logger
} }
func New(name string) (c Container, err error) { func New(dist distro.Distro) (c Container, err error) {
distro := strings.ToLower(dist.ID.String())
release := strings.Replace(dist.Release, ".", "__", -1)
c.name = fmt.Sprintf("out_of_tree_%s_%s", distro, release)
c.Log = log.With(). c.Log = log.With().
Str("container", name). Str("container", c.name).
Logger() Logger()
c.name = name c.dist = dist
c.Volumes = append(c.Volumes, Volume{ c.Volumes = append(c.Volumes, Volume{
Src: config.Dir("volumes", name, "lib", "modules"), Src: config.Dir("volumes", c.name, "lib", "modules"),
Dest: "/lib/modules", Dest: "/lib/modules",
}) })
c.Volumes = append(c.Volumes, Volume{ c.Volumes = append(c.Volumes, Volume{
Src: config.Dir("volumes", name, "usr", "src"), Src: config.Dir("volumes", c.name, "usr", "src"),
Dest: "/usr/src", Dest: "/usr/src",
}) })
c.Volumes = append(c.Volumes, Volume{ c.Volumes = append(c.Volumes, Volume{
Src: config.Dir("volumes", name, "boot"), Src: config.Dir("volumes", c.name, "boot"),
Dest: "/boot", Dest: "/boot",
}) })
@ -319,3 +322,68 @@ func (c Container) Run(workdir string, command string) (output string, err error
return return
} }
func (c Container) Kernels() (kernels []config.KernelInfo, err error) {
var libmodules, boot string
for _, volume := range c.Volumes {
switch volume.Dest {
case "/lib/modules":
libmodules = volume.Src
case "/boot":
boot = volume.Src
}
}
moddirs, err := ioutil.ReadDir(libmodules)
if err != nil {
return
}
bootfiles, err := ioutil.ReadDir(boot)
if err != nil {
return
}
for _, krel := range moddirs {
c.Log.Debug().Msgf("generate config entry for %s", krel.Name())
var kernelFile, initrdFile string
kernelFile, err = fs.FindKernel(bootfiles, krel.Name())
if err != nil {
c.Log.Warn().Msgf("cannot find kernel %s", krel.Name())
continue
}
initrdFile, err = fs.FindInitrd(bootfiles, krel.Name())
if err != nil {
c.Log.Warn().Msgf("cannot find initrd %s", krel.Name())
continue
}
ki := config.KernelInfo{
Distro: c.dist,
KernelVersion: krel.Name(),
KernelRelease: krel.Name(),
ContainerName: c.name,
KernelPath: filepath.Join(boot, kernelFile),
InitrdPath: filepath.Join(boot, initrdFile),
ModulesPath: filepath.Join(libmodules, krel.Name()),
RootFS: config.File("images", c.name+".img"),
}
kernels = append(kernels, ki)
}
for _, cmd := range []string{
"find /boot -type f -exec chmod a+r {} \\;",
} {
_, err = c.Run(config.Dir("tmp"), cmd)
if err != nil {
return
}
}
return
}

View File

@ -15,18 +15,12 @@ func init() {
releases := []string{"6", "7", "8"} releases := []string{"6", "7", "8"}
for _, release := range releases { for _, release := range releases {
container := "out_of_tree_centos_" + release distro.Register(CentOS{release: release})
distro.Register(CentOS{
release: release,
container: container,
})
} }
} }
type CentOS struct { type CentOS struct {
release string release string
container string
} }
func (centos CentOS) Equal(d distro.Distro) bool { func (centos CentOS) Equal(d distro.Distro) bool {
@ -38,7 +32,7 @@ func (centos CentOS) Distro() distro.Distro {
} }
func (centos CentOS) Packages() (pkgs []string, err error) { func (centos CentOS) Packages() (pkgs []string, err error) {
c, err := container.New(centos.container) c, err := container.New(centos.Distro())
if err != nil { if err != nil {
return return
} }

View File

@ -11,8 +11,7 @@ import (
func TestCentOS(t *testing.T) { func TestCentOS(t *testing.T) {
assert := assert.New(t) assert := assert.New(t)
u := CentOS{release: "7", container: "out_of_tree_centos_7"} u := CentOS{release: "7"}
assert.True(u.Equal(distro.Distro{Release: "7", ID: distro.CentOS})) assert.True(u.Equal(distro.Distro{Release: "7", ID: distro.CentOS}))

View File

@ -29,18 +29,12 @@ func init() {
} }
for _, release := range releases { for _, release := range releases {
container := fmt.Sprintf("out_of_tree_debian_%d", release) distro.Register(Debian{release: release})
distro.Register(Debian{
release: release,
container: container,
})
} }
} }
type Debian struct { type Debian struct {
release Release release Release
container string
} }
func (d Debian) Equal(dd distro.Distro) bool { func (d Debian) Equal(dd distro.Distro) bool {
@ -56,7 +50,7 @@ func (d Debian) Distro() distro.Distro {
} }
func (d Debian) Packages() (packages []string, err error) { func (d Debian) Packages() (packages []string, err error) {
c, err := container.New(d.container) c, err := container.New(d.Distro())
if err != nil { if err != nil {
return return
} }

View File

@ -46,8 +46,7 @@ func TestKernelRelease(t *testing.T) {
func TestDebian(t *testing.T) { func TestDebian(t *testing.T) {
assert := assert.New(t) assert := assert.New(t)
u := Debian{release: Wheezy, container: "out_of_tree_debian_7"} u := Debian{release: Wheezy}
assert.True(u.Equal(distro.Distro{Release: "wheezy", ID: distro.Debian})) assert.True(u.Equal(distro.Distro{Release: "wheezy", ID: distro.Debian}))

View File

@ -15,18 +15,12 @@ func init() {
releases := []string{"6", "7", "8", "9"} releases := []string{"6", "7", "8", "9"}
for _, release := range releases { for _, release := range releases {
container := "out_of_tree_oraclelinux_" + release distro.Register(OracleLinux{release: release})
distro.Register(OracleLinux{
release: release,
container: container,
})
} }
} }
type OracleLinux struct { type OracleLinux struct {
release string release string
container string
} }
func (ol OracleLinux) Equal(d distro.Distro) bool { func (ol OracleLinux) Equal(d distro.Distro) bool {
@ -38,7 +32,7 @@ func (ol OracleLinux) Distro() distro.Distro {
} }
func (ol OracleLinux) Packages() (pkgs []string, err error) { func (ol OracleLinux) Packages() (pkgs []string, err error) {
c, err := container.New(ol.container) c, err := container.New(ol.Distro())
if err != nil { if err != nil {
return return
} }

View File

@ -11,8 +11,7 @@ import (
func TestOracleLinux(t *testing.T) { func TestOracleLinux(t *testing.T) {
assert := assert.New(t) assert := assert.New(t)
u := OracleLinux{release: "9", container: "out_of_tree_oraclelinux_9"} u := OracleLinux{release: "9"}
assert.True(u.Equal(distro.Distro{Release: "9", ID: distro.OracleLinux})) assert.True(u.Equal(distro.Distro{Release: "9", ID: distro.OracleLinux}))

View File

@ -20,19 +20,12 @@ func init() {
} }
for _, release := range releases { for _, release := range releases {
container := "out_of_tree_ubuntu_" + release distro.Register(Ubuntu{release: release})
container = strings.Replace(container, ".", "__", -1)
distro.Register(Ubuntu{
release: release,
container: container,
})
} }
} }
type Ubuntu struct { type Ubuntu struct {
release string release string
container string
} }
func (u Ubuntu) Equal(d distro.Distro) bool { func (u Ubuntu) Equal(d distro.Distro) bool {
@ -44,7 +37,7 @@ func (u Ubuntu) Distro() distro.Distro {
} }
func (u Ubuntu) Packages() (pkgs []string, err error) { func (u Ubuntu) Packages() (pkgs []string, err error) {
c, err := container.New(u.container) c, err := container.New(u.Distro())
if err != nil { if err != nil {
return return
} }

View File

@ -11,7 +11,7 @@ import (
func TestUbuntu(t *testing.T) { func TestUbuntu(t *testing.T) {
assert := assert.New(t) assert := assert.New(t)
u := Ubuntu{release: "22.04", container: "out_of_tree_ubuntu_22__04"} u := Ubuntu{release: "22.04"}
assert.True(u.Equal(distro.Distro{Release: "22.04", ID: distro.Ubuntu})) assert.True(u.Equal(distro.Distro{Release: "22.04", ID: distro.Ubuntu}))

View File

@ -70,3 +70,33 @@ func FindBySubstring(dir, substring string) (k string, err error) {
err = errors.New("not found") err = errors.New("not found")
return return
} }
func FindKernel(files []os.FileInfo, kname string) (name string, err error) {
for _, file := range files {
if strings.HasPrefix(file.Name(), "vmlinuz") {
if strings.Contains(file.Name(), kname) {
name = file.Name()
return
}
}
}
err = errors.New("cannot find kernel")
return
}
func FindInitrd(files []os.FileInfo, kname string) (name string, err error) {
for _, file := range files {
if strings.HasPrefix(file.Name(), "initrd") ||
strings.HasPrefix(file.Name(), "initramfs") {
if strings.Contains(file.Name(), kname) {
name = file.Name()
return
}
}
}
err = errors.New("cannot find kernel")
return
}

View File

@ -5,7 +5,6 @@
package kernel package kernel
import ( import (
"errors"
"fmt" "fmt"
"io/ioutil" "io/ioutil"
"math/rand" "math/rand"
@ -76,7 +75,7 @@ func installKernel(sk config.Target, pkgname string, force, headers bool) (err e
Str("pkg", pkgname). Str("pkg", pkgname).
Logger() Logger()
c, err := container.New(sk.DockerName()) // TODO conf c, err := container.New(sk.Distro) // TODO conf
if err != nil { if err != nil {
return return
} }
@ -182,36 +181,6 @@ func installKernel(sk config.Target, pkgname string, force, headers bool) (err e
return return
} }
func findKernelFile(files []os.FileInfo, kname string) (name string, err error) {
for _, file := range files {
if strings.HasPrefix(file.Name(), "vmlinuz") {
if strings.Contains(file.Name(), kname) {
name = file.Name()
return
}
}
}
err = errors.New("cannot find kernel")
return
}
func findInitrdFile(files []os.FileInfo, kname string) (name string, err error) {
for _, file := range files {
if strings.HasPrefix(file.Name(), "initrd") ||
strings.HasPrefix(file.Name(), "initramfs") {
if strings.Contains(file.Name(), kname) {
name = file.Name()
return
}
}
}
err = errors.New("cannot find kernel")
return
}
func GenRootfsImage(d container.Image, download bool) (rootfs string, err error) { func GenRootfsImage(d container.Image, download bool) (rootfs string, err error) {
imagesPath := config.Dir("images") imagesPath := config.Dir("images")
imageFile := d.Name + ".img" imageFile := d.Name + ".img"
@ -289,76 +258,17 @@ func UpdateKernelsCfg(host, download bool) (err error) {
func listContainersKernels(dii container.Image, newkcfg *config.KernelConfig, func listContainersKernels(dii container.Image, newkcfg *config.KernelConfig,
download bool) (err error) { download bool) (err error) {
rootfs, err := GenRootfsImage(dii, download) c, err := container.New(dii.Distro)
if err != nil { if err != nil {
return return
} }
c, err := container.New(dii.Name) kernels, err := c.Kernels()
if err != nil { if err != nil {
return return
} }
var libmodules, boot string newkcfg.Kernels = append(newkcfg.Kernels, kernels...)
for _, volume := range c.Volumes {
switch volume.Dest {
case "/lib/modules":
libmodules = volume.Src
case "/boot":
boot = volume.Src
}
}
moddirs, err := ioutil.ReadDir(libmodules)
if err != nil {
return
}
bootfiles, err := ioutil.ReadDir(boot)
if err != nil {
return
}
for _, krel := range moddirs {
log.Debug().Msgf("generate config entry for %s", krel.Name())
var kernelFile, initrdFile string
kernelFile, err = findKernelFile(bootfiles, krel.Name())
if err != nil {
log.Warn().Msgf("cannot find kernel %s", krel.Name())
continue
}
initrdFile, err = findInitrdFile(bootfiles, krel.Name())
if err != nil {
log.Warn().Msgf("cannot find initrd %s", krel.Name())
continue
}
ki := config.KernelInfo{
Distro: dii.Distro,
KernelVersion: krel.Name(),
KernelRelease: krel.Name(),
ContainerName: dii.Name,
KernelPath: filepath.Join(boot, kernelFile),
InitrdPath: filepath.Join(boot, initrdFile),
ModulesPath: filepath.Join(libmodules, krel.Name()),
RootFS: rootfs,
}
newkcfg.Kernels = append(newkcfg.Kernels, ki)
}
for _, cmd := range []string{
"find /boot -type f -exec chmod a+r {} \\;",
} {
_, err = c.Run(config.Dir("tmp"), cmd)
if err != nil {
return
}
}
return return
} }

View File

@ -64,13 +64,13 @@ func genHostKernels(download bool) (kcfg config.KernelConfig, err error) {
log.Debug().Msgf("generate config entry for %s", krel) log.Debug().Msgf("generate config entry for %s", krel)
var kernelFile, initrdFile string var kernelFile, initrdFile string
kernelFile, err = findKernelFile(bootfiles, krel) kernelFile, err = fs.FindKernel(bootfiles, krel)
if err != nil { if err != nil {
log.Warn().Msgf("cannot find kernel %s", krel) log.Warn().Msgf("cannot find kernel %s", krel)
continue continue
} }
initrdFile, err = findInitrdFile(bootfiles, krel) initrdFile, err = fs.FindInitrd(bootfiles, krel)
if err != nil { if err != nil {
log.Warn().Msgf("cannot find initrd %s", krel) log.Warn().Msgf("cannot find initrd %s", krel)
continue continue