diff --git a/container/container.go b/container/container.go index 0bb33b3..792e080 100644 --- a/container/container.go +++ b/container/container.go @@ -147,6 +147,10 @@ func NewFromKernelInfo(ki distro.KernelInfo) ( return } +func (c Container) Name() string { + return c.name +} + func (c Container) Exist() (yes bool) { cmd := exec.Command(Runtime, "images", "-q", c.name) @@ -329,6 +333,10 @@ func (c Container) Run(workdir string, cmds []string) (out string, err error) { } func (c Container) Kernels() (kernels []distro.KernelInfo, err error) { + if !c.Exist() { + return + } + var libmodules, boot string for _, volume := range c.Volumes { switch volume.Dest { diff --git a/distro/centos/centos.go b/distro/centos/centos.go index beb87ca..d40d438 100644 --- a/distro/centos/centos.go +++ b/distro/centos/centos.go @@ -58,6 +58,15 @@ func (centos CentOS) Packages() (pkgs []string, err error) { return } +func (centos CentOS) Kernels() (kernels []distro.KernelInfo, err error) { + c, err := container.New(centos.Distro()) + if err != nil { + return + } + + return c.Kernels() +} + func (centos CentOS) envs() (envs []string) { return } diff --git a/distro/debian/debian.go b/distro/debian/debian.go index eb60db8..6b19633 100644 --- a/distro/debian/debian.go +++ b/distro/debian/debian.go @@ -276,9 +276,18 @@ func (d Debian) runs() (commands []string) { return } -func ContainerKernels(d container.Image, kcfg *config.KernelConfig) (err error) { - cpath := config.Dir("volumes", d.Name) - rootfs := config.File("images", d.Name+".img") +func (d Debian) Kernels() (kernels []distro.KernelInfo, err error) { + c, err := container.New(d.Distro()) + if err != nil { + return + } + + if !c.Exist() { + return + } + + cpath := config.Dir("volumes", c.Name()) + rootfs := config.File("images", c.Name()+".img") files, err := os.ReadDir(cpath) if err != nil { @@ -321,10 +330,10 @@ func ContainerKernels(d container.Image, kcfg *config.KernelConfig) (err error) release := strings.Replace(pkgname, "linux-image-", "", -1) ki := distro.KernelInfo{ - Distro: d.Distro, + Distro: d.Distro(), KernelVersion: path.Base(modules), KernelRelease: release, - ContainerName: d.Name, + ContainerName: c.Name(), KernelPath: vmlinuz, InitrdPath: initrd, @@ -333,7 +342,7 @@ func ContainerKernels(d container.Image, kcfg *config.KernelConfig) (err error) RootFS: rootfs, } - kcfg.Kernels = append(kcfg.Kernels, ki) + kernels = append(kernels, ki) } return diff --git a/distro/distro.go b/distro/distro.go index 45d8d23..80c1f58 100644 --- a/distro/distro.go +++ b/distro/distro.go @@ -11,6 +11,7 @@ type distribution interface { Distro() Distro Equal(Distro) bool Packages() (packages []string, err error) + Kernels() (kernels []KernelInfo, err error) } func Register(d distribution) { @@ -52,3 +53,12 @@ func (d Distro) Packages() (packages []string, err error) { } return } + +func (d Distro) Kernels() (kernels []KernelInfo, err error) { + for _, dd := range distros { + if dd.Equal(d) { + return dd.Kernels() + } + } + return +} diff --git a/distro/oraclelinux/oraclelinux.go b/distro/oraclelinux/oraclelinux.go index f41a7ca..e6f0b0f 100644 --- a/distro/oraclelinux/oraclelinux.go +++ b/distro/oraclelinux/oraclelinux.go @@ -59,6 +59,15 @@ func (ol OracleLinux) Packages() (pkgs []string, err error) { return } +func (ol OracleLinux) Kernels() (kernels []distro.KernelInfo, err error) { + c, err := container.New(ol.Distro()) + if err != nil { + return + } + + return c.Kernels() +} + func (ol OracleLinux) envs() (envs []string) { return } diff --git a/distro/ubuntu/ubuntu.go b/distro/ubuntu/ubuntu.go index 007e223..055493a 100644 --- a/distro/ubuntu/ubuntu.go +++ b/distro/ubuntu/ubuntu.go @@ -63,6 +63,15 @@ func (u Ubuntu) Packages() (pkgs []string, err error) { return } +func (u Ubuntu) Kernels() (kernels []distro.KernelInfo, err error) { + c, err := container.New(u.Distro()) + if err != nil { + return + } + + return c.Kernels() +} + func (u Ubuntu) envs() (envs []string) { envs = append(envs, "DEBIAN_FRONTEND=noninteractive") return diff --git a/kernel.go b/kernel.go index 58d9b5d..cfd669d 100644 --- a/kernel.go +++ b/kernel.go @@ -8,8 +8,10 @@ import ( "errors" "fmt" "math" + "os" "time" + "github.com/naoina/toml" "github.com/remeh/sizedwaitgroup" "github.com/rs/zerolog/log" @@ -37,6 +39,41 @@ type KernelCmd struct { ConfigRegen KernelConfigRegenCmd `cmd:"" help:"regenerate config"` } +func (cmd KernelCmd) UpdateConfig() (err error) { + kcfg := config.KernelConfig{} + + if cmd.UseHost { + // Get host kernels + kcfg.Kernels, err = kernel.GenHostKernels(!cmd.NoDownload) + if err != nil { + return + } + } + + for _, dist := range distro.List() { + var kernels []distro.KernelInfo + kernels, err = dist.Kernels() + if err != nil { + return + } + + kcfg.Kernels = append(kcfg.Kernels, kernels...) + } + + buf, err := toml.Marshal(&kcfg) + if err != nil { + return + } + + err = os.WriteFile(config.File("kernels.toml"), buf, os.ModePerm) + if err != nil { + return + } + + log.Info().Msgf("kernels.toml successfully updated") + return +} + func (cmd KernelCmd) Generate(g *Globals, km config.Target, max int, shutdown *bool) (err error) { @@ -194,7 +231,7 @@ func (cmd KernelAutogenCmd) Run(kernelCmd *KernelCmd, g *Globals) (err error) { } } - return kernel.UpdateKernelsCfg(kernelCmd.UseHost, !kernelCmd.NoDownload) + return kernelCmd.UpdateConfig() } type KernelGenallCmd struct { @@ -220,7 +257,7 @@ func (cmd *KernelGenallCmd) Run(kernelCmd *KernelCmd, g *Globals) (err error) { return } - return kernel.UpdateKernelsCfg(kernelCmd.UseHost, !kernelCmd.NoDownload) + return kernelCmd.UpdateConfig() } type KernelInstallCmd struct { @@ -247,11 +284,11 @@ func (cmd *KernelInstallCmd) Run(kernelCmd *KernelCmd, g *Globals) (err error) { return } - return kernel.UpdateKernelsCfg(kernelCmd.UseHost, !kernelCmd.NoDownload) + return kernelCmd.UpdateConfig() } type KernelConfigRegenCmd struct{} func (cmd *KernelConfigRegenCmd) Run(kernelCmd *KernelCmd, g *Globals) (err error) { - return kernel.UpdateKernelsCfg(kernelCmd.UseHost, !kernelCmd.NoDownload) + return kernelCmd.UpdateConfig() } diff --git a/kernel/kernel.go b/kernel/kernel.go index 3803c12..2172a69 100644 --- a/kernel/kernel.go +++ b/kernel/kernel.go @@ -15,7 +15,6 @@ import ( "runtime" "strings" - "github.com/naoina/toml" "github.com/rs/zerolog/log" "code.dumpstack.io/tools/out-of-tree/cache" @@ -193,92 +192,6 @@ func GenRootfsImage(d container.Image, download bool) (rootfs string, err error) return } -func UpdateKernelsCfg(host, download bool) (err error) { - newkcfg := config.KernelConfig{} - - if host { - // Get host kernels - newkcfg, err = genHostKernels(download) - if err != nil { - return - } - } - - // Get docker kernels - dockerImages, err := container.Images() - if err != nil { - return - } - - for _, d := range dockerImages { - // TODO Requires changing the idea of how we list - // kernels from containers to distro/-related - // functions. - if strings.Contains(d.Name, "debian") { - err = debian.ContainerKernels(d, &newkcfg) - if err != nil { - log.Print("gen kernels", d.Name, ":", err) - } - continue - } - - err = listContainersKernels(d, &newkcfg, download) - if err != nil { - log.Print("gen kernels", d.Name, ":", err) - continue - } - } - - stripkcfg := config.KernelConfig{} - for _, nk := range newkcfg.Kernels { - if !hasKernel(nk, stripkcfg) { - stripkcfg.Kernels = append(stripkcfg.Kernels, nk) - } - } - - buf, err := toml.Marshal(&stripkcfg) - if err != nil { - return - } - - buf = append([]byte("# Autogenerated\n# DO NOT EDIT\n\n"), buf...) - - kernelsCfgPath := config.File("kernels.toml") - err = ioutil.WriteFile(kernelsCfgPath, buf, 0644) - if err != nil { - return - } - - log.Info().Msgf("%s is successfully updated", kernelsCfgPath) - return -} - -func listContainersKernels(dii container.Image, newkcfg *config.KernelConfig, - download bool) (err error) { - - c, err := container.New(dii.Distro) - if err != nil { - return - } - - kernels, err := c.Kernels() - if err != nil { - return - } - - newkcfg.Kernels = append(newkcfg.Kernels, kernels...) - return -} - -func hasKernel(ki distro.KernelInfo, kcfg config.KernelConfig) bool { - for _, sk := range kcfg.Kernels { - if sk == ki { - return true - } - } - return false -} - func ShuffleStrings(a []string) []string { // Fisher–Yates shuffle for i := len(a) - 1; i > 0; i-- { diff --git a/kernel/kernel_linux.go b/kernel/kernel_linux.go index 9f6efe7..5a31d9c 100644 --- a/kernel/kernel_linux.go +++ b/kernel/kernel_linux.go @@ -21,7 +21,7 @@ import ( "code.dumpstack.io/tools/out-of-tree/fs" ) -func genHostKernels(download bool) (kcfg config.KernelConfig, err error) { +func GenHostKernels(download bool) (kernels []distro.KernelInfo, err error) { si := sysinfo.SysInfo{} si.GetSysInfo() @@ -97,7 +97,7 @@ func genHostKernels(download bool) (kcfg config.KernelConfig, err error) { ki.VmlinuxPath = vmlinux } - kcfg.Kernels = append(kcfg.Kernels, ki) + kernels = append(kernels, ki) } return