1
0

Add commands to manage containers

This commit is contained in:
dump_stack() 2023-04-06 19:05:21 +00:00
parent bbd6f79443
commit 0d3a075d76
Signed by: dump_stack
GPG Key ID: BE44DA8C062D87DC
4 changed files with 110 additions and 60 deletions

View File

@ -11,11 +11,103 @@ import (
"os" "os"
"os/exec" "os/exec"
"os/user" "os/user"
"regexp"
"strings"
"time" "time"
"github.com/rs/zerolog/log" "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 { type container struct {
name string name string
timeout time.Duration timeout time.Duration

View File

@ -513,12 +513,12 @@ func genInitrdPath(files []os.FileInfo, kname string) string {
return "" 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() usr, err := user.Current()
if err != nil { if err != nil {
return return
} }
imageFile := d.ContainerName + ".img" imageFile := d.Name + ".img"
imagesPath := usr.HomeDir + "/.out-of-tree/images/" imagesPath := usr.HomeDir + "/.out-of-tree/images/"
os.MkdirAll(imagesPath, os.ModePerm) os.MkdirAll(imagesPath, os.ModePerm)
@ -533,49 +533,6 @@ func genRootfsImage(d dockerImageInfo, download bool) (rootfs string, err error)
return 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) { func updateKernelsCfg(host, download bool) (err error) {
newkcfg := config.KernelConfig{} newkcfg := config.KernelConfig{}
@ -588,7 +545,7 @@ func updateKernelsCfg(host, download bool) (err error) {
} }
// Get docker kernels // Get docker kernels
dockerImages, err := listDockerImages() dockerImages, err := listContainerImages()
if err != nil { if err != nil {
return return
} }
@ -596,7 +553,7 @@ func updateKernelsCfg(host, download bool) (err error) {
for _, d := range dockerImages { for _, d := range dockerImages {
err = listContainersKernels(d, &newkcfg, download) err = listContainersKernels(d, &newkcfg, download)
if err != nil { if err != nil {
log.Print("gen kernels", d.ContainerName, ":", err) log.Print("gen kernels", d.Name, ":", err)
continue continue
} }
} }
@ -631,7 +588,7 @@ func updateKernelsCfg(host, download bool) (err error) {
return return
} }
func listContainersKernels(dii dockerImageInfo, newkcfg *config.KernelConfig, func listContainersKernels(dii containerImageInfo, newkcfg *config.KernelConfig,
download bool) (err error) { download bool) (err error) {
rootfs, err := genRootfsImage(dii, download) rootfs, err := genRootfsImage(dii, download)
@ -639,7 +596,7 @@ func listContainersKernels(dii dockerImageInfo, newkcfg *config.KernelConfig,
return return
} }
c, err := NewContainer(dii.ContainerName, time.Hour) c, err := NewContainer(dii.Name, time.Hour)
if err != nil { if err != nil {
return return
} }
@ -659,7 +616,7 @@ func listContainersKernels(dii dockerImageInfo, newkcfg *config.KernelConfig,
DistroType: dii.DistroType, DistroType: dii.DistroType,
DistroRelease: dii.DistroRelease, DistroRelease: dii.DistroRelease,
KernelRelease: krel.Name(), KernelRelease: krel.Name(),
ContainerName: dii.ContainerName, ContainerName: dii.Name,
KernelPath: c.Volumes.Boot + "/" + KernelPath: c.Volumes.Boot + "/" +
genKernelPath(bootfiles, krel.Name()), genKernelPath(bootfiles, krel.Name()),
@ -708,7 +665,7 @@ func generateKernels(km config.KernelMask, registry string,
log.Info().Msgf("Generating for kernel mask %v", km) log.Info().Msgf("Generating for kernel mask %v", km)
_, err = genRootfsImage(dockerImageInfo{ContainerName: km.DockerName()}, _, err = genRootfsImage(containerImageInfo{Name: km.DockerName()},
download) download)
if err != nil { if err != nil {
return return

View File

@ -43,8 +43,8 @@ func genHostKernels(download bool) (kcfg config.KernelConfig, err error) {
} }
// only for compatibility, docker is not really used // only for compatibility, docker is not really used
dii := dockerImageInfo{ dii := containerImageInfo{
ContainerName: config.KernelMask{ Name: config.KernelMask{
DistroType: distroType, DistroType: distroType,
DistroRelease: si.OS.Version, DistroRelease: si.OS.Version,
}.DockerName(), }.DockerName(),

View File

@ -39,6 +39,7 @@ type CLI struct {
Pack PackCmd `cmd:"" help:"exploit pack test"` Pack PackCmd `cmd:"" help:"exploit pack test"`
Gen GenCmd `cmd:"" help:"generate .out-of-tree.toml skeleton"` Gen GenCmd `cmd:"" help:"generate .out-of-tree.toml skeleton"`
Image ImageCmd `cmd:"" help:"manage images"` Image ImageCmd `cmd:"" help:"manage images"`
Container ContainerCmd `cmd:"" help:"manage containers"`
Version VersionFlag `name:"version" help:"print version information and quit"` Version VersionFlag `name:"version" help:"print version information and quit"`