1
0

Implements kernels config autogeneration

This commit is contained in:
dump_stack() 2018-12-01 14:23:01 +00:00
parent 4956fdc4a2
commit b350e9c45b
2 changed files with 99 additions and 38 deletions

View File

@ -23,16 +23,10 @@ type KernelMask struct {
func (km KernelMask) DockerName() string { func (km KernelMask) DockerName() string {
distro := strings.ToLower(km.DistroType.String()) distro := strings.ToLower(km.DistroType.String())
release := strings.Replace(km.DistroRelease, ".", "", -1) release := strings.Replace(km.DistroRelease, ".", "__", -1)
return fmt.Sprintf("out_of_tree_%s_%s", distro, release) return fmt.Sprintf("out_of_tree_%s_%s", distro, release)
} }
func (km KernelMask) ImageName() string {
distro := strings.ToLower(km.DistroType.String())
release := strings.Replace(km.DistroRelease, ".", "", -1)
return fmt.Sprintf("%s_%s.img", distro, release)
}
type ArtifactType int type ArtifactType int
const ( const (

129
kernel.go
View File

@ -97,7 +97,7 @@ func generateBaseDockerImage(sk config.KernelMask) (err error) {
d += "ENV DEBIAN_FRONTEND=noninteractive\n" d += "ENV DEBIAN_FRONTEND=noninteractive\n"
d += "RUN apt-get update\n" d += "RUN apt-get update\n"
d += "RUN apt-get install -y build-essential libelf-dev\n" d += "RUN apt-get install -y build-essential libelf-dev\n"
d += "RUN apt-get install -y wget git libelf-dev\n" d += "RUN apt-get install -y wget git\n"
default: default:
s := fmt.Sprintf("%s not yet supported", sk.DistroType.String()) s := fmt.Sprintf("%s not yet supported", sk.DistroType.String())
err = errors.New(s) err = errors.New(s)
@ -246,21 +246,110 @@ func genInitrdPath(files []os.FileInfo, kname string) string {
return "unknown" return "unknown"
} }
func genRootfsImage(km config.KernelMask) string { func genRootfsImage(d dockerImageInfo) string {
usr, err := user.Current() usr, err := user.Current()
if err != nil { if err != nil {
return fmt.Sprintln(err) return fmt.Sprintln(err)
} }
return usr.HomeDir + "/.out-of-tree/images/" + km.ImageName() imageFile := d.ContainerName + ".img"
return usr.HomeDir + "/.out-of-tree/images/" + imageFile
} }
func genKernels(km config.KernelMask, newkcfg *config.KernelConfig) ( type dockerImageInfo struct {
ContainerName string
DistroType config.DistroType
DistroRelease string // 18.04/7.4.1708/9.1
}
func listDockerImages() (diis []dockerImageInfo, err error) {
cmd := exec.Command("docker", "images")
rawOutput, err := cmd.CombinedOutput()
if err != nil {
return
}
r, err := regexp.Compile("out_of_tree_.*")
if err != nil {
return
}
containers := r.FindAll(rawOutput, -1)
for _, c := range containers {
container := strings.Fields(string(c))[0]
s := strings.Replace(container, "__", ".", -1)
values := strings.Split(s, "_")
distro, ver := values[3], values[4]
dii := dockerImageInfo{
ContainerName: container,
DistroRelease: ver,
}
dii.DistroType, err = config.NewDistroType(distro)
if err != nil {
return
}
diis = append(diis, dii)
}
return
}
func updateKernelsCfg() (err error) {
dockerImages, err := listDockerImages()
if err != nil {
return
}
newkcfg := config.KernelConfig{}
for _, d := range dockerImages {
err = genKernels(d, &newkcfg)
if err != nil {
log.Println("gen kernels", d.ContainerName, ":", 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...)
usr, err := user.Current()
if err != nil {
return
}
// TODO move all cfg path values to one provider
kernelsCfgPath := usr.HomeDir + "/.out-of-tree/kernels.toml"
err = ioutil.WriteFile(kernelsCfgPath, buf, 0644)
if err != nil {
return
}
log.Println(kernelsCfgPath, "is successfully updated")
return
}
func genKernels(dii dockerImageInfo, newkcfg *config.KernelConfig) (
err error) { err error) {
name := km.DockerName() name := dii.ContainerName
cmd := exec.Command("docker", "run", name, "ls", "/lib/modules") cmd := exec.Command("docker", "run", name, "ls", "/lib/modules")
rawOutput, err := cmd.CombinedOutput() rawOutput, err := cmd.CombinedOutput()
if err != nil { if err != nil {
log.Println(string(rawOutput), err)
return return
} }
@ -276,14 +365,14 @@ func genKernels(km config.KernelMask, newkcfg *config.KernelConfig) (
for _, k := range strings.Fields(string(rawOutput)) { for _, k := range strings.Fields(string(rawOutput)) {
ki := config.KernelInfo{ ki := config.KernelInfo{
DistroType: km.DistroType, DistroType: dii.DistroType,
DistroRelease: km.DistroRelease, DistroRelease: dii.DistroRelease,
KernelRelease: k, KernelRelease: k,
ContainerName: name, ContainerName: name,
KernelPath: kernelsBase + genKernelPath(files, k), KernelPath: kernelsBase + genKernelPath(files, k),
InitrdPath: kernelsBase + genInitrdPath(files, k), InitrdPath: kernelsBase + genInitrdPath(files, k),
RootFS: genRootfsImage(km), RootFS: genRootfsImage(dii),
} }
newkcfg.Kernels = append(newkcfg.Kernels, ki) newkcfg.Kernels = append(newkcfg.Kernels, ki)
} }
@ -298,7 +387,6 @@ func hasKernel(ki config.KernelInfo, kcfg config.KernelConfig) bool {
} }
} }
return false return false
} }
func kernelAutogenHandler(kcfg config.KernelConfig, workPath string) (err error) { func kernelAutogenHandler(kcfg config.KernelConfig, workPath string) (err error) {
@ -307,8 +395,6 @@ func kernelAutogenHandler(kcfg config.KernelConfig, workPath string) (err error)
return return
} }
newkcfg := config.KernelConfig{}
for _, sk := range ka.SupportedKernels { for _, sk := range ka.SupportedKernels {
if sk.DistroRelease == "" { if sk.DistroRelease == "" {
err = errors.New("Please set distro_release") err = errors.New("Please set distro_release")
@ -342,27 +428,8 @@ func kernelAutogenHandler(kcfg config.KernelConfig, workPath string) (err error)
log.Println("copy kernels", sk.DockerName(), ":", err) log.Println("copy kernels", sk.DockerName(), ":", err)
continue continue
} }
err = genKernels(sk, &newkcfg)
if err != nil {
log.Println("gen kernels", sk.DockerName(), ":", err)
continue
}
} }
stripkcfg := config.KernelConfig{} err = updateKernelsCfg()
for _, nk := range newkcfg.Kernels {
if !hasKernel(nk, stripkcfg) {
stripkcfg.Kernels = append(stripkcfg.Kernels, nk)
}
}
buf, err := toml.Marshal(&stripkcfg)
if err != nil {
return
}
fmt.Println()
fmt.Println(string(buf)) // TODO auto-save to some path
return return
} }