feat: add kernel install to distro interface
This commit is contained in:
parent
daaef89050
commit
e2d66db16f
@ -158,3 +158,48 @@ func (centos CentOS) runs() (commands []string) {
|
|||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (centos CentOS) Install(pkgname string, headers bool) (err error) {
|
||||||
|
var headerspkg string
|
||||||
|
if headers {
|
||||||
|
headerspkg = strings.Replace(pkgname, "kernel", "kernel-devel", -1)
|
||||||
|
}
|
||||||
|
|
||||||
|
var commands []string
|
||||||
|
cmdf := func(f string, s ...interface{}) {
|
||||||
|
commands = append(commands, fmt.Sprintf(f, s...))
|
||||||
|
}
|
||||||
|
|
||||||
|
cmdf("yum -y install %s %s", pkgname, headerspkg)
|
||||||
|
|
||||||
|
version := strings.Replace(pkgname, "kernel-", "", -1)
|
||||||
|
|
||||||
|
if centos.release <= "7" {
|
||||||
|
cmdf("dracut -v --add-drivers 'e1000 ext4' -f "+
|
||||||
|
"/boot/initramfs-%s.img %s", version, version)
|
||||||
|
} else {
|
||||||
|
cmdf("dracut -v --add-drivers 'ata_piix libata' "+
|
||||||
|
"--force-drivers 'e1000 ext4 sd_mod' -f "+
|
||||||
|
"/boot/initramfs-%s.img %s", version, version)
|
||||||
|
}
|
||||||
|
|
||||||
|
cmdf("cp -r /boot /target/")
|
||||||
|
cmdf("cp -r /lib/modules /target/lib/")
|
||||||
|
cmdf("cp -r /usr/src /target/usr/")
|
||||||
|
|
||||||
|
c, err := container.New(centos.Distro())
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := range c.Volumes {
|
||||||
|
c.Volumes[i].Dest = "/target" + c.Volumes[i].Dest
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = c.Run("", commands)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
@ -348,8 +348,13 @@ func (d Debian) Kernels() (kernels []distro.KernelInfo, err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func Volumes(km config.Target, pkgname string) (volumes []container.Volume) {
|
func (d Debian) volumes(pkgname string) (volumes []container.Volume) {
|
||||||
pkgdir := filepath.Join("volumes", km.DockerName(), pkgname)
|
c, err := container.New(d.Distro())
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
pkgdir := filepath.Join("volumes", c.Name(), pkgname)
|
||||||
|
|
||||||
volumes = append(volumes, container.Volume{
|
volumes = append(volumes, container.Volume{
|
||||||
Src: config.Dir(pkgdir, "/lib/modules"),
|
Src: config.Dir(pkgdir, "/lib/modules"),
|
||||||
@ -369,7 +374,13 @@ func Volumes(km config.Target, pkgname string) (volumes []container.Volume) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func Install(km config.Target, pkgname string, headers bool) (cmds []string, err error) {
|
func (d Debian) Install(pkgname string, headers bool) (err error) {
|
||||||
|
defer func() {
|
||||||
|
if err != nil {
|
||||||
|
d.cleanup(pkgname)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
dk, err := getCachedKernel(pkgname + ".deb")
|
dk, err := getCachedKernel(pkgname + ".deb")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
@ -382,9 +393,11 @@ func Install(km config.Target, pkgname string, headers bool) (cmds []string, err
|
|||||||
pkgs = []snapshot.Package{dk.Image}
|
pkgs = []snapshot.Package{dk.Image}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var cmds []string
|
||||||
|
|
||||||
for _, pkg := range pkgs {
|
for _, pkg := range pkgs {
|
||||||
found, newurl := cache.PackageURL(
|
found, newurl := cache.PackageURL(
|
||||||
km.Distro.ID,
|
distro.Debian,
|
||||||
pkg.Deb.URL,
|
pkg.Deb.URL,
|
||||||
)
|
)
|
||||||
if found {
|
if found {
|
||||||
@ -402,15 +415,39 @@ func Install(km config.Target, pkgname string, headers bool) (cmds []string, err
|
|||||||
|
|
||||||
cmds = append(cmds, "dpkg -i ./*.deb")
|
cmds = append(cmds, "dpkg -i ./*.deb")
|
||||||
|
|
||||||
|
c, err := container.New(d.Distro())
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c.Volumes = d.volumes(pkgname)
|
||||||
|
for i := range c.Volumes {
|
||||||
|
c.Volumes[i].Dest = "/target" + c.Volumes[i].Dest
|
||||||
|
}
|
||||||
|
|
||||||
|
cmds = append(cmds, "cp -r /boot /target/")
|
||||||
|
cmds = append(cmds, "cp -r /lib/modules /target/lib/")
|
||||||
|
cmds = append(cmds, "cp -r /usr/src /target/usr/")
|
||||||
|
|
||||||
|
_, err = c.Run("", cmds)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func Cleanup(km config.Target, pkgname string) {
|
func (d Debian) cleanup(pkgname string) {
|
||||||
pkgdir := config.Dir(filepath.Join("volumes", km.DockerName(), pkgname))
|
c, err := container.New(d.Distro())
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
pkgdir := config.Dir(filepath.Join("volumes", c.Name(), pkgname))
|
||||||
|
|
||||||
log.Debug().Msgf("cleanup %s", pkgdir)
|
log.Debug().Msgf("cleanup %s", pkgdir)
|
||||||
|
|
||||||
err := os.RemoveAll(pkgdir)
|
err = os.RemoveAll(pkgdir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Warn().Err(err).Msg("cleanup")
|
log.Warn().Err(err).Msg("cleanup")
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package distro
|
package distro
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"sync"
|
"sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -11,6 +12,7 @@ type distribution interface {
|
|||||||
Distro() Distro
|
Distro() Distro
|
||||||
Equal(Distro) bool
|
Equal(Distro) bool
|
||||||
Packages() (packages []string, err error)
|
Packages() (packages []string, err error)
|
||||||
|
Install(pkg string, headers bool) (err error)
|
||||||
Kernels() (kernels []KernelInfo, err error)
|
Kernels() (kernels []KernelInfo, err error)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -54,6 +56,17 @@ func (d Distro) Packages() (packages []string, err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (d Distro) Install(pkg string, headers bool) (err error) {
|
||||||
|
for _, dd := range distros {
|
||||||
|
if !dd.Equal(d) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
return dd.Install(pkg, headers)
|
||||||
|
}
|
||||||
|
return errors.New("not found")
|
||||||
|
}
|
||||||
|
|
||||||
func (d Distro) Kernels() (kernels []KernelInfo, err error) {
|
func (d Distro) Kernels() (kernels []KernelInfo, err error) {
|
||||||
for _, dd := range distros {
|
for _, dd := range distros {
|
||||||
if dd.Equal(d) {
|
if dd.Equal(d) {
|
||||||
|
@ -96,7 +96,7 @@ func (ol OracleLinux) runs() (commands []string) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func Install(km config.Target, pkgname string, headers bool) (commands []string, err error) {
|
func (ol OracleLinux) Install(pkgname string, headers bool) (err error) {
|
||||||
var headerspkg string
|
var headerspkg string
|
||||||
if headers {
|
if headers {
|
||||||
if strings.Contains(pkgname, "uek") {
|
if strings.Contains(pkgname, "uek") {
|
||||||
@ -108,6 +108,7 @@ func Install(km config.Target, pkgname string, headers bool) (commands []string,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var commands []string
|
||||||
cmdf := func(f string, s ...interface{}) {
|
cmdf := func(f string, s ...interface{}) {
|
||||||
commands = append(commands, fmt.Sprintf(f, s...))
|
commands = append(commands, fmt.Sprintf(f, s...))
|
||||||
}
|
}
|
||||||
@ -121,7 +122,7 @@ func Install(km config.Target, pkgname string, headers bool) (commands []string,
|
|||||||
version = strings.Replace(pkgname, "kernel-", "", -1)
|
version = strings.Replace(pkgname, "kernel-", "", -1)
|
||||||
}
|
}
|
||||||
|
|
||||||
if km.Distro.Release <= "7" {
|
if ol.release <= "7" {
|
||||||
cmdf("dracut -v --add-drivers 'e1000 ext4' -f "+
|
cmdf("dracut -v --add-drivers 'e1000 ext4' -f "+
|
||||||
"/boot/initramfs-%s.img %s", version, version)
|
"/boot/initramfs-%s.img %s", version, version)
|
||||||
} else {
|
} else {
|
||||||
@ -130,9 +131,23 @@ func Install(km config.Target, pkgname string, headers bool) (commands []string,
|
|||||||
"/boot/initramfs-%s.img %s", version, version)
|
"/boot/initramfs-%s.img %s", version, version)
|
||||||
}
|
}
|
||||||
|
|
||||||
return
|
cmdf("cp -r /boot /target/")
|
||||||
}
|
cmdf("cp -r /lib/modules /target/lib/")
|
||||||
|
cmdf("cp -r /usr/src /target/usr/")
|
||||||
|
|
||||||
|
c, err := container.New(ol.Distro())
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := range c.Volumes {
|
||||||
|
c.Volumes[i].Dest = "/target" + c.Volumes[i].Dest
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = c.Run("", commands)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
func Cleanup(km config.Target, pkgname string) {
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -122,22 +122,35 @@ func (u Ubuntu) runs() (commands []string) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func Install(km config.Target, pkgname string, headers bool) (commands []string, err error) {
|
func (u Ubuntu) Install(pkgname string, headers bool) (err error) {
|
||||||
|
|
||||||
var headerspkg string
|
var headerspkg string
|
||||||
if headers {
|
if headers {
|
||||||
headerspkg = strings.Replace(pkgname, "image", "headers", -1)
|
headerspkg = strings.Replace(pkgname, "image", "headers", -1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var commands []string
|
||||||
cmdf := func(f string, s ...interface{}) {
|
cmdf := func(f string, s ...interface{}) {
|
||||||
commands = append(commands, fmt.Sprintf(f, s...))
|
commands = append(commands, fmt.Sprintf(f, s...))
|
||||||
}
|
}
|
||||||
|
|
||||||
cmdf("apt-get install -y %s %s", pkgname, headerspkg)
|
cmdf("apt-get install -y %s %s", pkgname, headerspkg)
|
||||||
|
cmdf("cp -r /boot /target/")
|
||||||
|
cmdf("cp -r /lib/modules /target/lib/")
|
||||||
|
cmdf("cp -r /usr/src /target/usr/")
|
||||||
|
|
||||||
|
c, err := container.New(u.Distro())
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := range c.Volumes {
|
||||||
|
c.Volumes[i].Dest = "/target" + c.Volumes[i].Dest
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = c.Run("", commands)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func Cleanup(km config.Target, pkgname string) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
@ -129,7 +129,8 @@ func (cmd KernelCmd) Generate(g *Globals, km config.Target, max int,
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
err = kernel.InstallKernel(km, p, cmd.Force, !cmd.NoHeaders)
|
// TODO cmd.Force
|
||||||
|
err = km.Distro.Install(p, !cmd.NoHeaders)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
max--
|
max--
|
||||||
break
|
break
|
||||||
|
118
kernel/kernel.go
118
kernel/kernel.go
@ -5,7 +5,6 @@
|
|||||||
package kernel
|
package kernel
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"os"
|
"os"
|
||||||
@ -20,10 +19,6 @@ import (
|
|||||||
"code.dumpstack.io/tools/out-of-tree/cache"
|
"code.dumpstack.io/tools/out-of-tree/cache"
|
||||||
"code.dumpstack.io/tools/out-of-tree/config"
|
"code.dumpstack.io/tools/out-of-tree/config"
|
||||||
"code.dumpstack.io/tools/out-of-tree/container"
|
"code.dumpstack.io/tools/out-of-tree/container"
|
||||||
"code.dumpstack.io/tools/out-of-tree/distro"
|
|
||||||
"code.dumpstack.io/tools/out-of-tree/distro/debian"
|
|
||||||
"code.dumpstack.io/tools/out-of-tree/distro/oraclelinux"
|
|
||||||
"code.dumpstack.io/tools/out-of-tree/distro/ubuntu"
|
|
||||||
"code.dumpstack.io/tools/out-of-tree/fs"
|
"code.dumpstack.io/tools/out-of-tree/fs"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -65,119 +60,6 @@ func vsyscallAvailable() (available bool, err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func InstallKernel(sk config.Target, pkgname string, force, headers bool) (err error) {
|
|
||||||
slog := log.With().
|
|
||||||
Str("distro_type", sk.Distro.ID.String()).
|
|
||||||
Str("distro_release", sk.Distro.Release).
|
|
||||||
Str("pkg", pkgname).
|
|
||||||
Logger()
|
|
||||||
|
|
||||||
c, err := container.New(sk.Distro) // TODO conf
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
searchdir := ""
|
|
||||||
for _, volume := range c.Volumes {
|
|
||||||
if volume.Dest == "/lib/modules" {
|
|
||||||
searchdir = volume.Src
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if sk.Distro.ID == distro.Debian {
|
|
||||||
// TODO We need some kind of API for that
|
|
||||||
searchdir = config.Dir("volumes", sk.DockerName())
|
|
||||||
}
|
|
||||||
|
|
||||||
moddirs, err := ioutil.ReadDir(searchdir)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, krel := range moddirs {
|
|
||||||
if strings.Contains(pkgname, krel.Name()) {
|
|
||||||
if force {
|
|
||||||
slog.Info().Msg("Reinstall")
|
|
||||||
} else {
|
|
||||||
slog.Info().Msg("Already installed")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if sk.Distro.ID == distro.Debian {
|
|
||||||
// Debian has different kernels (package version) by the
|
|
||||||
// same name (ABI), so we need to separate /boot
|
|
||||||
c.Volumes = debian.Volumes(sk, pkgname)
|
|
||||||
}
|
|
||||||
|
|
||||||
slog.Debug().Msgf("Installing kernel")
|
|
||||||
|
|
||||||
var commands []string
|
|
||||||
|
|
||||||
// TODO install/cleanup kernel interface
|
|
||||||
switch sk.Distro.ID {
|
|
||||||
case distro.Ubuntu:
|
|
||||||
commands, err = ubuntu.Install(sk, pkgname, headers)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
defer func() {
|
|
||||||
if err != nil {
|
|
||||||
ubuntu.Cleanup(sk, pkgname)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
case distro.OracleLinux, distro.CentOS:
|
|
||||||
commands, err = oraclelinux.Install(sk, pkgname, headers)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
defer func() {
|
|
||||||
if err != nil {
|
|
||||||
oraclelinux.Cleanup(sk, pkgname)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
case distro.Debian:
|
|
||||||
commands, err = debian.Install(sk, pkgname, headers)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
defer func() {
|
|
||||||
if err != nil {
|
|
||||||
debian.Cleanup(sk, pkgname)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
default:
|
|
||||||
err = fmt.Errorf("%s not yet supported", sk.Distro.ID.String())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
cmd := "true"
|
|
||||||
for _, command := range commands {
|
|
||||||
cmd += fmt.Sprintf(" && %s", command)
|
|
||||||
}
|
|
||||||
|
|
||||||
for i := range c.Volumes {
|
|
||||||
c.Volumes[i].Dest = "/target" + c.Volumes[i].Dest
|
|
||||||
}
|
|
||||||
|
|
||||||
cmd += " && cp -r /boot /target/"
|
|
||||||
cmd += " && cp -r /lib/modules /target/lib/"
|
|
||||||
if sk.Distro.ID == distro.Debian {
|
|
||||||
cmd += " && cp -rL /usr/src /target/usr/"
|
|
||||||
} else {
|
|
||||||
cmd += " && cp -r /usr/src /target/usr/"
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err = c.Run("", []string{cmd})
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
slog.Debug().Msgf("Success")
|
|
||||||
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"
|
||||||
|
Loading…
Reference in New Issue
Block a user