From 0d3a075d7626ba0daeaee406103aacd0b9b5e70e Mon Sep 17 00:00:00 2001 From: Mikhail Klementev Date: Thu, 6 Apr 2023 19:05:21 +0000 Subject: [PATCH] Add commands to manage containers --- container.go | 92 +++++++++++++++++++++++++++++++++++++++++++++++++ kernel.go | 59 +++++-------------------------- kernel_linux.go | 4 +-- main.go | 15 ++++---- 4 files changed, 110 insertions(+), 60 deletions(-) diff --git a/container.go b/container.go index a35d324..e85b2e7 100644 --- a/container.go +++ b/container.go @@ -11,11 +11,103 @@ import ( "os" "os/exec" "os/user" + "regexp" + "strings" "time" "github.com/rs/zerolog/log" + + "code.dumpstack.io/tools/out-of-tree/config" ) +type ContainerCmd struct { + Filter string `help:"filter by name"` + + List ContainerListCmd `cmd:"" help:"list containers"` + Cleanup ContainerCleanupCmd `cmd:"" help:"cleanup containers"` +} + +func (cmd ContainerCmd) Containers() (names []string) { + images, err := listContainerImages() + if err != nil { + log.Fatal().Err(err).Msg("") + } + + for _, img := range images { + if cmd.Filter != "" && !strings.Contains(img.Name, cmd.Filter) { + continue + } + names = append(names, img.Name) + } + return +} + +type ContainerListCmd struct{} + +func (cmd ContainerListCmd) Run(containerCmd *ContainerCmd) (err error) { + for _, name := range containerCmd.Containers() { + fmt.Println(name) + } + return +} + +type ContainerCleanupCmd struct{} + +func (cmd ContainerCleanupCmd) Run(containerCmd *ContainerCmd) (err error) { + var output []byte + for _, name := range containerCmd.Containers() { + output, err = exec.Command("docker", "image", "rm", name).CombinedOutput() + if err != nil { + log.Error().Err(err).Str("output", string(output)).Msg("") + return + } + } + return +} + +type containerImageInfo struct { + Name string + DistroType config.DistroType + DistroRelease string // 18.04/7.4.1708/9.1 +} + +func listContainerImages() (diis []containerImageInfo, err error) { + cmd := exec.Command("docker", "images") + log.Debug().Msgf("%v", cmd) + + 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 := containerImageInfo{ + Name: container, + DistroRelease: ver, + } + + dii.DistroType, err = config.NewDistroType(distro) + if err != nil { + return + } + + diis = append(diis, dii) + } + return +} + type container struct { name string timeout time.Duration diff --git a/kernel.go b/kernel.go index 944484e..d2bf972 100644 --- a/kernel.go +++ b/kernel.go @@ -513,12 +513,12 @@ func genInitrdPath(files []os.FileInfo, kname string) string { return "" } -func genRootfsImage(d dockerImageInfo, download bool) (rootfs string, err error) { +func genRootfsImage(d containerImageInfo, download bool) (rootfs string, err error) { usr, err := user.Current() if err != nil { return } - imageFile := d.ContainerName + ".img" + imageFile := d.Name + ".img" imagesPath := usr.HomeDir + "/.out-of-tree/images/" os.MkdirAll(imagesPath, os.ModePerm) @@ -533,49 +533,6 @@ func genRootfsImage(d dockerImageInfo, download bool) (rootfs string, err error) return } -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") - log.Debug().Msgf("%v", cmd) - - 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(host, download bool) (err error) { newkcfg := config.KernelConfig{} @@ -588,7 +545,7 @@ func updateKernelsCfg(host, download bool) (err error) { } // Get docker kernels - dockerImages, err := listDockerImages() + dockerImages, err := listContainerImages() if err != nil { return } @@ -596,7 +553,7 @@ func updateKernelsCfg(host, download bool) (err error) { for _, d := range dockerImages { err = listContainersKernels(d, &newkcfg, download) if err != nil { - log.Print("gen kernels", d.ContainerName, ":", err) + log.Print("gen kernels", d.Name, ":", err) continue } } @@ -631,7 +588,7 @@ func updateKernelsCfg(host, download bool) (err error) { return } -func listContainersKernels(dii dockerImageInfo, newkcfg *config.KernelConfig, +func listContainersKernels(dii containerImageInfo, newkcfg *config.KernelConfig, download bool) (err error) { rootfs, err := genRootfsImage(dii, download) @@ -639,7 +596,7 @@ func listContainersKernels(dii dockerImageInfo, newkcfg *config.KernelConfig, return } - c, err := NewContainer(dii.ContainerName, time.Hour) + c, err := NewContainer(dii.Name, time.Hour) if err != nil { return } @@ -659,7 +616,7 @@ func listContainersKernels(dii dockerImageInfo, newkcfg *config.KernelConfig, DistroType: dii.DistroType, DistroRelease: dii.DistroRelease, KernelRelease: krel.Name(), - ContainerName: dii.ContainerName, + ContainerName: dii.Name, KernelPath: c.Volumes.Boot + "/" + genKernelPath(bootfiles, krel.Name()), @@ -708,7 +665,7 @@ func generateKernels(km config.KernelMask, registry string, log.Info().Msgf("Generating for kernel mask %v", km) - _, err = genRootfsImage(dockerImageInfo{ContainerName: km.DockerName()}, + _, err = genRootfsImage(containerImageInfo{Name: km.DockerName()}, download) if err != nil { return diff --git a/kernel_linux.go b/kernel_linux.go index 1dd6287..5c72363 100644 --- a/kernel_linux.go +++ b/kernel_linux.go @@ -43,8 +43,8 @@ func genHostKernels(download bool) (kcfg config.KernelConfig, err error) { } // only for compatibility, docker is not really used - dii := dockerImageInfo{ - ContainerName: config.KernelMask{ + dii := containerImageInfo{ + Name: config.KernelMask{ DistroType: distroType, DistroRelease: si.OS.Version, }.DockerName(), diff --git a/main.go b/main.go index 5decd38..2efcfea 100644 --- a/main.go +++ b/main.go @@ -32,13 +32,14 @@ type Globals struct { type CLI struct { Globals - Pew PewCmd `cmd:"" help:"build, run, and test module/exploit"` - Kernel KernelCmd `cmd:"" help:"manipulate kernels"` - Debug DebugCmd `cmd:"" help:"debug environment"` - Log LogCmd `cmd:"" help:"query logs"` - Pack PackCmd `cmd:"" help:"exploit pack test"` - Gen GenCmd `cmd:"" help:"generate .out-of-tree.toml skeleton"` - Image ImageCmd `cmd:"" help:"manage images"` + Pew PewCmd `cmd:"" help:"build, run, and test module/exploit"` + Kernel KernelCmd `cmd:"" help:"manipulate kernels"` + Debug DebugCmd `cmd:"" help:"debug environment"` + Log LogCmd `cmd:"" help:"query logs"` + Pack PackCmd `cmd:"" help:"exploit pack test"` + Gen GenCmd `cmd:"" help:"generate .out-of-tree.toml skeleton"` + Image ImageCmd `cmd:"" help:"manage images"` + Container ContainerCmd `cmd:"" help:"manage containers"` Version VersionFlag `name:"version" help:"print version information and quit"`