From a8066428f87a55a4a5f5a169c5de5505573940d8 Mon Sep 17 00:00:00 2001 From: Mikhail Klementev Date: Wed, 21 Feb 2024 12:11:57 +0000 Subject: [PATCH] feat: save container images --- .github/workflows/e2e.yml | 5 ++++- cmd/container.go | 33 +++++++++++++++++++++++++++++++++ container/container.go | 20 ++++++++++++++++++++ 3 files changed, 57 insertions(+), 1 deletion(-) diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index 40dfd9d..0173553 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -101,7 +101,8 @@ jobs: ssh root@$IP "cloud-init status --wait" - ssh root@$IP "dnf install -y podman qemu-kvm-core" + ssh root@$IP "dnf install -y podman qemu-kvm-core epel-release" + ssh root@$IP "dnf install -y s3cmd" ssh root@$IP "ln -s /usr/libexec/qemu-kvm /usr/bin/qemu-system-x86_64" @@ -133,6 +134,8 @@ jobs: echo 'TimeoutStopSec=1' >> test.service echo 'ExecStart=/usr/local/bin/out-of-tree kernel autogen --threads=4 --max=256 --shuffle' >> test.service echo 'ExecStart=/usr/local/bin/out-of-tree pew --qemu-timeout=10m --threads=4 --include-internal-errors' >> test.service + echo 'ExecStart=/usr/local/bin/out-of-tree container save' >> test.service + echo "ExecStart=/usr/bin/s3cmd put --acl-public *.tar.gz s3://out-of-tree/1.0.0/containers/ --host=fra1.digitaloceanspaces.com --host-bucket='%(bucket)s.fra1.digitaloceanspaces.com' --access_key=${{ secrets.DIGITALOCEAN_SPACES_ACCESS_KEY }} --secret_key=${{ secrets.DIGITALOCEAN_SPACES_SECRET_KEY }}" >> test.service scp test.service root@$IP:/etc/systemd/system/test.service diff --git a/cmd/container.go b/cmd/container.go index 370c020..41def0d 100644 --- a/cmd/container.go +++ b/cmd/container.go @@ -7,6 +7,7 @@ package cmd import ( "fmt" "os/exec" + "path/filepath" "strings" "github.com/rs/zerolog/log" @@ -18,6 +19,7 @@ type ContainerCmd struct { Filter string `help:"filter by name"` List ContainerListCmd `cmd:"" help:"list containers"` + Save ContainerSaveCmd `cmd:"" help:"save containers"` Cleanup ContainerCleanupCmd `cmd:"" help:"cleanup containers"` } @@ -45,6 +47,37 @@ func (cmd ContainerListCmd) Run(containerCmd *ContainerCmd) (err error) { return } +type ContainerSaveCmd struct { + OutDir string `help:"directory to save containers" default:"./" type:"existingdir"` +} + +func (cmd ContainerSaveCmd) Run(containerCmd *ContainerCmd) (err error) { + for _, name := range containerCmd.Containers() { + nlog := log.With().Str("name", name).Logger() + + output := filepath.Join(cmd.OutDir, name+".tar") + nlog.Info().Msgf("saving to %v") + + err = container.Save(name, output) + if err != nil { + return + } + + compressed := output + ".gz" + nlog.Info().Msgf("compressing to %v", compressed) + + var raw []byte + raw, err = exec.Command("gzip", output).CombinedOutput() + if err != nil { + nlog.Error().Err(err).Msg(string(raw)) + return + } + + nlog.Info().Msg("done") + } + return +} + type ContainerCleanupCmd struct{} func (cmd ContainerCleanupCmd) Run(containerCmd *ContainerCmd) (err error) { diff --git a/container/container.go b/container/container.go index 81f5a9c..09c4132 100644 --- a/container/container.go +++ b/container/container.go @@ -95,6 +95,26 @@ func Import(path, name string) (err error) { return } +func Save(name, path string) (err error) { + exist := Container{name: name}.Exist() + if !exist { + err = errors.New("container does not exist") + log.Error().Err(err).Msg("") + return + } + + cmd := exec.Command(Runtime, "save", name, path) + log.Debug().Msgf("%v", cmd) + + raw, err := cmd.CombinedOutput() + if err != nil { + log.Error().Err(err).Msg(string(raw)) + return + } + + return +} + type Volume struct { Src, Dest string }