diff --git a/config/config.go b/config/config.go index 5af72c7..7e7c3d5 100644 --- a/config/config.go +++ b/config/config.go @@ -23,16 +23,10 @@ type KernelMask struct { func (km KernelMask) DockerName() 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) } -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 const ( diff --git a/kernel.go b/kernel.go index 9cffdac..bd10428 100644 --- a/kernel.go +++ b/kernel.go @@ -97,7 +97,7 @@ func generateBaseDockerImage(sk config.KernelMask) (err error) { d += "ENV DEBIAN_FRONTEND=noninteractive\n" d += "RUN apt-get update\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: s := fmt.Sprintf("%s not yet supported", sk.DistroType.String()) err = errors.New(s) @@ -246,21 +246,110 @@ func genInitrdPath(files []os.FileInfo, kname string) string { return "unknown" } -func genRootfsImage(km config.KernelMask) string { +func genRootfsImage(d dockerImageInfo) string { usr, err := user.Current() if err != nil { 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) { - name := km.DockerName() + name := dii.ContainerName cmd := exec.Command("docker", "run", name, "ls", "/lib/modules") rawOutput, err := cmd.CombinedOutput() if err != nil { + log.Println(string(rawOutput), err) return } @@ -276,14 +365,14 @@ func genKernels(km config.KernelMask, newkcfg *config.KernelConfig) ( for _, k := range strings.Fields(string(rawOutput)) { ki := config.KernelInfo{ - DistroType: km.DistroType, - DistroRelease: km.DistroRelease, + DistroType: dii.DistroType, + DistroRelease: dii.DistroRelease, KernelRelease: k, ContainerName: name, KernelPath: kernelsBase + genKernelPath(files, k), InitrdPath: kernelsBase + genInitrdPath(files, k), - RootFS: genRootfsImage(km), + RootFS: genRootfsImage(dii), } newkcfg.Kernels = append(newkcfg.Kernels, ki) } @@ -298,7 +387,6 @@ func hasKernel(ki config.KernelInfo, kcfg config.KernelConfig) bool { } } return false - } func kernelAutogenHandler(kcfg config.KernelConfig, workPath string) (err error) { @@ -307,8 +395,6 @@ func kernelAutogenHandler(kcfg config.KernelConfig, workPath string) (err error) return } - newkcfg := config.KernelConfig{} - for _, sk := range ka.SupportedKernels { if sk.DistroRelease == "" { 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) continue } - - err = genKernels(sk, &newkcfg) - if err != nil { - log.Println("gen kernels", sk.DockerName(), ":", 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 - } - fmt.Println() - fmt.Println(string(buf)) // TODO auto-save to some path - + err = updateKernelsCfg() return }