first version
This commit is contained in:
@@ -0,0 +1,73 @@
|
||||
package docker
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/client"
|
||||
)
|
||||
|
||||
func SaveImageTar(ctx context.Context, image, path, name string) error {
|
||||
|
||||
cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation())
|
||||
if err != nil {
|
||||
return fmt.Errorf("docker client error: %v", err)
|
||||
}
|
||||
defer cli.Close()
|
||||
|
||||
if err := pullImage(ctx, cli, image); err != nil {
|
||||
return fmt.Errorf("pull image %s failed: %v", image, err)
|
||||
}
|
||||
|
||||
if err := saveToTar(ctx, cli, image, path, name); err != nil {
|
||||
return fmt.Errorf("save image %s failed: %v", image, err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func pullImage(ctx context.Context, cli *client.Client, image string) error {
|
||||
// try pull image
|
||||
r, err := cli.ImagePull(ctx, image, types.ImagePullOptions{})
|
||||
if err != nil {
|
||||
return fmt.Errorf("pull image %s failed: %v", image, err)
|
||||
}
|
||||
defer r.Close()
|
||||
|
||||
io.Copy(os.Stdout, r)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func saveToTar(ctx context.Context, cli *client.Client, image, path, name string) error {
|
||||
out, err := cli.ImageSave(ctx, []string{image})
|
||||
if err != nil {
|
||||
return fmt.Errorf("save image %s failed: %v", image, err)
|
||||
}
|
||||
defer out.Close()
|
||||
|
||||
filename := name
|
||||
if filename == "" {
|
||||
strs := strings.Split(image, "/")
|
||||
filename = fmt.Sprintf("%s.tar", strings.ReplaceAll(strs[len(strs)-1], ":", "_"))
|
||||
}
|
||||
|
||||
filep := filepath.Join(path, filename)
|
||||
|
||||
target, err := os.Create(filep)
|
||||
if err != nil {
|
||||
return fmt.Errorf("create file %s failed: %v", filep, err)
|
||||
}
|
||||
defer target.Close()
|
||||
|
||||
if _, err := io.Copy(target, out); err != nil {
|
||||
return fmt.Errorf("copy file %s failed: %v", filep, err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user