Compare commits
5 Commits
cdfa480479
...
20cd32243d
Author | SHA1 | Date | |
---|---|---|---|
20cd32243d | |||
a7ecc354a9 | |||
cba1abc7f4 | |||
3f0c28014c | |||
c3c97c3828 |
@ -1,39 +1,65 @@
|
|||||||
// Copyright 2023 Mikhail Klementev. All rights reserved.
|
// Copyright 2024 Mikhail Klementev. All rights reserved.
|
||||||
// Use of this source code is governed by a AGPLv3 license
|
// Use of this source code is governed by a AGPLv3 license
|
||||||
// (or later) that can be found in the LICENSE file.
|
// (or later) that can be found in the LICENSE file.
|
||||||
|
|
||||||
package cmd
|
package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/rs/zerolog/log"
|
"github.com/rs/zerolog/log"
|
||||||
|
|
||||||
"code.dumpstack.io/tools/out-of-tree/container"
|
"code.dumpstack.io/tools/out-of-tree/container"
|
||||||
|
"code.dumpstack.io/tools/out-of-tree/distro"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ContainerCmd struct {
|
type ContainerCmd struct {
|
||||||
Filter string `help:"filter by name"`
|
DistroID string `help:"filter by distribution"`
|
||||||
|
DistroRelease string `help:"filter by distribution release"`
|
||||||
|
|
||||||
List ContainerListCmd `cmd:"" help:"list containers"`
|
List ContainerListCmd `cmd:"" help:"list containers"`
|
||||||
|
Update ContainerUpdateCmd `cmd:"" help:"update containers"`
|
||||||
Save ContainerSaveCmd `cmd:"" help:"save containers"`
|
Save ContainerSaveCmd `cmd:"" help:"save containers"`
|
||||||
Cleanup ContainerCleanupCmd `cmd:"" help:"cleanup containers"`
|
Cleanup ContainerCleanupCmd `cmd:"" help:"cleanup containers"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cmd ContainerCmd) Containers() (names []string) {
|
func (cmd ContainerCmd) Containers() (diis []container.Image, err error) {
|
||||||
images, err := container.Images()
|
images, err := container.Images()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal().Err(err).Msg("")
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var dt distro.Distro
|
||||||
|
if cmd.DistroID != "" {
|
||||||
|
dt.ID, err = distro.NewID(cmd.DistroID)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if cmd.DistroRelease != "" {
|
||||||
|
dt.Release = cmd.DistroRelease
|
||||||
|
}
|
||||||
|
} else if cmd.DistroRelease != "" {
|
||||||
|
err = errors.New("--distro-release has no use on its own")
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, img := range images {
|
for _, img := range images {
|
||||||
if cmd.Filter != "" && !strings.Contains(img.Name, cmd.Filter) {
|
if dt.ID != distro.None && dt.ID != img.Distro.ID {
|
||||||
|
log.Debug().Msgf("skip %s", img.Name)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
names = append(names, img.Name)
|
|
||||||
|
if dt.Release != "" && dt.Release != img.Distro.Release {
|
||||||
|
log.Debug().Msgf("skip %s", img.Name)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Debug().Msgf("append %s", img.Name)
|
||||||
|
diis = append(diis, img)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -41,9 +67,40 @@ func (cmd ContainerCmd) Containers() (names []string) {
|
|||||||
type ContainerListCmd struct{}
|
type ContainerListCmd struct{}
|
||||||
|
|
||||||
func (cmd ContainerListCmd) Run(containerCmd *ContainerCmd) (err error) {
|
func (cmd ContainerListCmd) Run(containerCmd *ContainerCmd) (err error) {
|
||||||
for _, name := range containerCmd.Containers() {
|
images, err := containerCmd.Containers()
|
||||||
fmt.Println(name)
|
if err != nil {
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for _, img := range images {
|
||||||
|
fmt.Printf("%s\n", img.Distro.String())
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
type ContainerUpdateCmd struct{}
|
||||||
|
|
||||||
|
func (cmd ContainerUpdateCmd) Run(g *Globals, containerCmd *ContainerCmd) (err error) {
|
||||||
|
images, err := containerCmd.Containers()
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
container.UseCache = false
|
||||||
|
container.UsePrebuilt = false
|
||||||
|
|
||||||
|
// TODO move from all commands to main command line handler
|
||||||
|
container.Commands = g.Config.Docker.Commands
|
||||||
|
container.Registry = g.Config.Docker.Registry
|
||||||
|
container.Timeout = g.Config.Docker.Timeout.Duration
|
||||||
|
|
||||||
|
for _, img := range images {
|
||||||
|
_, err = img.Distro.Packages()
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -52,13 +109,18 @@ type ContainerSaveCmd struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (cmd ContainerSaveCmd) Run(containerCmd *ContainerCmd) (err error) {
|
func (cmd ContainerSaveCmd) Run(containerCmd *ContainerCmd) (err error) {
|
||||||
for _, name := range containerCmd.Containers() {
|
images, err := containerCmd.Containers()
|
||||||
nlog := log.With().Str("name", name).Logger()
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
output := filepath.Join(cmd.OutDir, name+".tar")
|
for _, img := range images {
|
||||||
|
nlog := log.With().Str("name", img.Name).Logger()
|
||||||
|
|
||||||
|
output := filepath.Join(cmd.OutDir, img.Name+".tar")
|
||||||
nlog.Info().Msgf("saving to %v", output)
|
nlog.Info().Msgf("saving to %v", output)
|
||||||
|
|
||||||
err = container.Save(name, output)
|
err = container.Save(img.Name, output)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -81,9 +143,14 @@ func (cmd ContainerSaveCmd) Run(containerCmd *ContainerCmd) (err error) {
|
|||||||
type ContainerCleanupCmd struct{}
|
type ContainerCleanupCmd struct{}
|
||||||
|
|
||||||
func (cmd ContainerCleanupCmd) Run(containerCmd *ContainerCmd) (err error) {
|
func (cmd ContainerCleanupCmd) Run(containerCmd *ContainerCmd) (err error) {
|
||||||
|
images, err := containerCmd.Containers()
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
var output []byte
|
var output []byte
|
||||||
for _, name := range containerCmd.Containers() {
|
for _, img := range images {
|
||||||
output, err = exec.Command(container.Runtime, "image", "rm", name).
|
output, err = exec.Command(container.Runtime, "image", "rm", img.Name).
|
||||||
CombinedOutput()
|
CombinedOutput()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error().Err(err).Str("output", string(output)).Msg("")
|
log.Error().Err(err).Str("output", string(output)).Msg("")
|
||||||
|
@ -35,9 +35,12 @@ type OutOfTree struct {
|
|||||||
Timeout artifact.Duration
|
Timeout artifact.Duration
|
||||||
Registry string
|
Registry string
|
||||||
|
|
||||||
// Commands that will be executed before
|
// Commands that are executed before (prepend) and after (append) the
|
||||||
// the base layer of Dockerfile
|
// base layer of the Dockerfile.
|
||||||
Commands []distro.Command
|
Commands struct {
|
||||||
|
Prepend []distro.Command
|
||||||
|
Append []distro.Command
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,7 +32,12 @@ var Registry = ""
|
|||||||
|
|
||||||
var Timeout time.Duration
|
var Timeout time.Duration
|
||||||
|
|
||||||
var Commands []distro.Command
|
// Commands that are executed before (prepend) and after (append) the
|
||||||
|
// base layer of the Dockerfile.
|
||||||
|
var Commands struct {
|
||||||
|
Prepend []distro.Command
|
||||||
|
Append []distro.Command
|
||||||
|
}
|
||||||
|
|
||||||
var UseCache = true
|
var UseCache = true
|
||||||
|
|
||||||
@ -97,13 +102,23 @@ func Load(localpath string, name string) (err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd = exec.Command(Runtime, "tag", "localhost/"+name, name)
|
if strings.Contains(Runtime, "docker") {
|
||||||
log.Debug().Msgf("%v", cmd)
|
var err2 error
|
||||||
|
cmd = exec.Command(Runtime, "tag", "localhost/"+name, name)
|
||||||
|
log.Debug().Msgf("%v", cmd)
|
||||||
|
|
||||||
raw, err = cmd.CombinedOutput()
|
raw, err2 = cmd.CombinedOutput()
|
||||||
if err != nil {
|
if err2 != nil {
|
||||||
log.Debug().Err(err).Msg(string(raw))
|
log.Debug().Err(err2).Msg(string(raw))
|
||||||
return
|
}
|
||||||
|
|
||||||
|
cmd = exec.Command(Runtime, "rmi", "localhost/"+name)
|
||||||
|
log.Debug().Msgf("%v", cmd)
|
||||||
|
|
||||||
|
raw, err2 = cmd.CombinedOutput()
|
||||||
|
if err2 != nil {
|
||||||
|
log.Debug().Err(err2).Msg(string(raw))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
@ -286,9 +301,15 @@ func (c Container) Build(image string, envs, runs []string) (err error) {
|
|||||||
}
|
}
|
||||||
cf += image + "\n"
|
cf += image + "\n"
|
||||||
|
|
||||||
for _, c := range Commands {
|
for _, cmd := range Commands.Prepend {
|
||||||
// TODO check for distro type
|
if cmd.Distro.ID != distro.None && cmd.Distro.ID != c.dist.ID {
|
||||||
cf += "RUN " + c.Command + "\n"
|
continue
|
||||||
|
}
|
||||||
|
if cmd.Distro.Release != "" && cmd.Distro.Release != c.dist.Release {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
cf += "RUN " + cmd.Command + "\n"
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, e := range envs {
|
for _, e := range envs {
|
||||||
@ -299,6 +320,17 @@ func (c Container) Build(image string, envs, runs []string) (err error) {
|
|||||||
cf += "RUN " + c + "\n"
|
cf += "RUN " + c + "\n"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for _, cmd := range Commands.Append {
|
||||||
|
if cmd.Distro.ID != distro.None && cmd.Distro.ID != c.dist.ID {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if cmd.Distro.Release != "" && cmd.Distro.Release != c.dist.Release {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
cf += "RUN " + cmd.Command + "\n"
|
||||||
|
}
|
||||||
|
|
||||||
buf, err := os.ReadFile(cfile)
|
buf, err := os.ReadFile(cfile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
err = os.WriteFile(cfile, []byte(cf), os.ModePerm)
|
err = os.WriteFile(cfile, []byte(cf), os.ModePerm)
|
||||||
|
6
main.go
6
main.go
@ -35,13 +35,13 @@ type CLI struct {
|
|||||||
cmd.Globals
|
cmd.Globals
|
||||||
|
|
||||||
Pew cmd.PewCmd `cmd:"" help:"build, run, and test module/exploit"`
|
Pew cmd.PewCmd `cmd:"" help:"build, run, and test module/exploit"`
|
||||||
Kernel cmd.KernelCmd `cmd:"" help:"manipulate kernels"`
|
Kernel cmd.KernelCmd `cmd:"" aliases:"kernels" help:"manipulate kernels"`
|
||||||
Debug cmd.DebugCmd `cmd:"" help:"debug environment"`
|
Debug cmd.DebugCmd `cmd:"" help:"debug environment"`
|
||||||
Log cmd.LogCmd `cmd:"" help:"query logs"`
|
Log cmd.LogCmd `cmd:"" help:"query logs"`
|
||||||
Pack cmd.PackCmd `cmd:"" help:"exploit pack test"`
|
Pack cmd.PackCmd `cmd:"" help:"exploit pack test"`
|
||||||
Gen cmd.GenCmd `cmd:"" help:"generate .out-of-tree.toml skeleton"`
|
Gen cmd.GenCmd `cmd:"" help:"generate .out-of-tree.toml skeleton"`
|
||||||
Image cmd.ImageCmd `cmd:"" help:"manage images"`
|
Image cmd.ImageCmd `cmd:"" aliases:"images" help:"manage images"`
|
||||||
Container cmd.ContainerCmd `cmd:"" help:"manage containers"`
|
Container cmd.ContainerCmd `cmd:"" aliases:"containers" help:"manage containers"`
|
||||||
Distro cmd.DistroCmd `cmd:"" help:"distro-related helpers"`
|
Distro cmd.DistroCmd `cmd:"" help:"distro-related helpers"`
|
||||||
|
|
||||||
Daemon cmd.DaemonCmd `cmd:"" help:"run daemon"`
|
Daemon cmd.DaemonCmd `cmd:"" help:"run daemon"`
|
||||||
|
Loading…
Reference in New Issue
Block a user