Skip to content

Commit

Permalink
feat: use docker for cleanup (#92)
Browse files Browse the repository at this point in the history
Fixes #91
  • Loading branch information
agaffney authored Mar 7, 2024
1 parent 4d6ca97 commit ff64c33
Show file tree
Hide file tree
Showing 2 changed files with 98 additions and 3 deletions.
71 changes: 71 additions & 0 deletions pkgmgr/docker.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,21 +16,26 @@ package pkgmgr

import (
"bufio"
"bytes"
"context"
"encoding/json"
"errors"
"fmt"
"io"
"log/slog"
"sort"
"strings"

"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/client"
"github.com/docker/docker/pkg/stdcopy"
"github.com/docker/go-connections/nat"
)

const (
dockerUtilityImage = `alpine:3.19.1`

dockerInstallError = `could not contact Docker daemon
Docker is required to be already installed and running. Please refer to the following pages for more information
Expand Down Expand Up @@ -368,3 +373,69 @@ func RemoveDockerImage(image string) error {
}
return nil
}

func RunCommandInDocker(image string, cmd []string, binds []string) (string, string, error) {
client, err := NewDockerClient()
if err != nil {
return "", "", err
}
ctx := context.Background()
pullOut, err := client.ImagePull(context.Background(), image, types.ImagePullOptions{})
if err != nil {
return "", "", err
}
defer pullOut.Close()
// Discard the pull output
if _, err := io.Copy(io.Discard, pullOut); err != nil {
return "", "", err
}
resp, err := client.ContainerCreate(
ctx,
&container.Config{
Image: image,
Cmd: cmd,
Tty: false,
},
&container.HostConfig{
Binds: binds,
},
nil,
nil,
"",
)
if err != nil {
return "", "", err
}
// Start container and wait for it to exit
if err := client.ContainerStart(ctx, resp.ID, container.StartOptions{}); err != nil {
return "", "", err
}
statusCh, errCh := client.ContainerWait(ctx, resp.ID, container.WaitConditionNotRunning)
select {
case err := <-errCh:
if err != nil {
return "", "", err
}
case <-statusCh:
}
// Get container stdout/stderr
logsOut, err := client.ContainerLogs(ctx, resp.ID, container.LogsOptions{ShowStdout: true})
if err != nil {
return "", "", err
}
defer logsOut.Close()
cmdStdout := bytes.NewBuffer(nil)
cmdStderr := bytes.NewBuffer(nil)
if _, err := stdcopy.StdCopy(cmdStdout, cmdStderr, logsOut); err != nil {
return "", "", err
}
// Remove container
if err := client.ContainerRemove(
context.Background(),
resp.ID,
container.RemoveOptions{},
); err != nil {
return "", "", err
}
return cmdStdout.String(), cmdStderr.String(), nil
}
30 changes: 27 additions & 3 deletions pkgmgr/package.go
Original file line number Diff line number Diff line change
Expand Up @@ -146,11 +146,23 @@ func (p Package) uninstall(cfg Config, context string, keepData bool) error {
)
} else {
// Remove package cache dir
// We use Docker to deal with root-owned files from containers
pkgCacheDir := filepath.Join(
cfg.CacheDir,
pkgName,
)
if err := os.RemoveAll(pkgCacheDir); err != nil {
_, _, err := RunCommandInDocker(
dockerUtilityImage,
[]string{
"rm",
"-rf",
fmt.Sprintf("%s/%s", cfg.CacheDir, pkgName),
},
[]string{
fmt.Sprintf("%s:%s", cfg.CacheDir, cfg.CacheDir),
},
)
if err != nil {
cfg.Logger.Warn(
fmt.Sprintf(
"failed to remove package cache directory %q: %s",
Expand All @@ -167,11 +179,23 @@ func (p Package) uninstall(cfg Config, context string, keepData bool) error {
)
}
// Remove package data dir
// We use Docker to deal with root-owned files from containers
pkgDataDir := filepath.Join(
cfg.DataDir,
pkgName,
)
if err := os.RemoveAll(pkgDataDir); err != nil {
_, _, err = RunCommandInDocker(
dockerUtilityImage,
[]string{
"rm",
"-rf",
fmt.Sprintf("%s/%s", cfg.DataDir, pkgName),
},
[]string{
fmt.Sprintf("%s:%s", cfg.DataDir, cfg.DataDir),
},
)
if err != nil {
cfg.Logger.Warn(
fmt.Sprintf(
"failed to remove package data directory %q: %s",
Expand All @@ -183,7 +207,7 @@ func (p Package) uninstall(cfg Config, context string, keepData bool) error {
cfg.Logger.Debug(
fmt.Sprintf(
"removed package data directory %q",
pkgCacheDir,
pkgDataDir,
),
)
}
Expand Down

0 comments on commit ff64c33

Please sign in to comment.