hmdeploy/docker/client.go
2025-04-04 12:22:30 +02:00

58 lines
1.4 KiB
Go

package docker
import (
"errors"
"fmt"
"os"
"os/exec"
"path/filepath"
)
type IClient interface {
Save(imageName, dest string) (string, error)
}
var ErrDockerClientSave = errors.New("unable to save image into tar")
// Client is a simple Docker client wrapping the local Docker daemon.
// It does not use the Docker API but instead shell command and collect the output.
//
// NOTE: for now, it's ok, it only needs one command so, no need to add a fat dedicated
// library with full Docker client API.
type Client struct{}
var _ IClient = (*Client)(nil)
func NewClient() Client {
return Client{}
}
// Save saves the `imageName` (tag included) in tar format in the target directory: `dest`.
// The `dest` directory must exist with correct permissions.
func (c *Client) Save(imageName, dest string) (string, error) {
destInfo, err := os.Stat(dest)
if err != nil {
return "", fmt.Errorf("unable to stat file, dir=%s, err=%v", dest, err)
}
if !destInfo.IsDir() {
return "", fmt.Errorf("dest file must be a directory, dir=%s, err=%v", dest, err)
}
tarFile := fmt.Sprintf("%s.tar", imageName)
cmd := exec.Command("docker", "save", "-o", tarFile, imageName)
cmd.Dir = dest
if _, err := cmd.Output(); err != nil {
return "", fmt.Errorf(
"%w, dir=%s, image=%s, err=%v",
ErrDockerClientSave,
dest,
imageName,
err,
)
}
return filepath.Join(dest, tarFile), nil
}