diff --git a/cmd/d2vm/build.go b/cmd/d2vm/build.go index fcf5bad..521d035 100644 --- a/cmd/d2vm/build.go +++ b/cmd/d2vm/build.go @@ -39,15 +39,9 @@ var ( if err != nil { return err } - if debug { - exec.Run = exec.RunStdout - } + exec.SetDebug(debug) logrus.Infof("building docker image from %s", file) - dargs := []string{"build", "-t", tag, "-f", file, args[0]} - for _, v := range buildArgs { - dargs = append(dargs, "--build-arg", v) - } - if err := docker.Cmd(cmd.Context(), dargs...); err != nil { + if err := docker.Build(cmd.Context(), tag, file, args[0], buildArgs...); err != nil { return err } return d2vm.Convert(cmd.Context(), tag, size, password, output, format) diff --git a/cmd/d2vm/convert.go b/cmd/d2vm/convert.go index d3b8781..9d309ea 100644 --- a/cmd/d2vm/convert.go +++ b/cmd/d2vm/convert.go @@ -51,9 +51,7 @@ var ( return fmt.Errorf("%s already exists", output) } } - if debug { - exec.Run = exec.RunStdout - } + exec.SetDebug(debug) if _, err := os.Stat(output); err == nil || !os.IsNotExist(err) { if !force { return fmt.Errorf("%s already exists", output) @@ -61,18 +59,18 @@ var ( } found := false if !pull { - o, _, err := docker.CmdOut(cmd.Context(), "image", "ls", "--format={{ .Repository }}:{{ .Tag }}", img) + imgs, err := docker.ImageList(cmd.Context(), img) if err != nil { return err } - found = strings.TrimSuffix(o, "\n") == fmt.Sprintf("%s:%s", img, tag) + found = len(imgs) == 1 && imgs[0] == fmt.Sprintf("%s:%s", img, tag) if found { logrus.Infof("using local image %s:%s", img, tag) } } if pull || !found { logrus.Infof("pulling image %s", img) - if err := docker.Cmd(cmd.Context(), "image", "pull", img); err != nil { + if err := docker.Pull(cmd.Context(), img); err != nil { return err } } diff --git a/convert.go b/convert.go index 8ecad8a..8852979 100644 --- a/convert.go +++ b/convert.go @@ -56,10 +56,10 @@ func Convert(ctx context.Context, img string, size int64, password string, outpu return err } logrus.Infof("building kernel enabled image") - if err := docker.Cmd(ctx, "image", "build", "-t", imgUUID, "-f", p, dir); err != nil { + if err := docker.Build(ctx, imgUUID, p, dir); err != nil { return err } - defer docker.Cmd(ctx, "image", "rm", imgUUID) + defer docker.Remove(ctx, imgUUID) logrus.Infof("creating vm image") b, err := NewBuilder(ctx, tmpPath, imgUUID, "", size, r, format) diff --git a/docker_image_test.go b/docker_image_test.go index 4a7d5da..e8a6265 100644 --- a/docker_image_test.go +++ b/docker_image_test.go @@ -132,7 +132,7 @@ COPY hostname /etc/ RUN rm -rf /etc/apk ` ) - exec.Run = exec.RunStdout + exec.SetDebug(true) tmp := filepath.Join(os.TempDir(), "d2vm-tests", "image-flatten") require.NoError(t, os.MkdirAll(tmp, perm)) defer os.RemoveAll(tmp) @@ -140,12 +140,9 @@ RUN rm -rf /etc/apk require.NoError(t, os.WriteFile(filepath.Join(tmp, "hostname"), []byte("d2vm-flatten-test"), perm)) require.NoError(t, os.WriteFile(filepath.Join(tmp, "resolv.conf"), []byte("nameserver 8.8.8.8"), perm)) require.NoError(t, os.WriteFile(filepath.Join(tmp, "Dockerfile"), []byte(dockerfile), perm)) - require.NoError(t, docker.Cmd(ctx, "image", "build", "-t", img, tmp)) - defer docker.Cmd(ctx, "image", "rm", img) + require.NoError(t, docker.Build(ctx, img, "", tmp)) + defer docker.Remove(ctx, img) - // imgTar := filepath.Join(tmp, img+".tar") - // require.NoError(t, docker.Cmd(ctx, "image", "save", img, "-o", imgTar)) - // imgTmp := filepath.Join(tmp, "image") i, err := NewImage(ctx, img, imgTmp) diff --git a/pkg/docker/docker.go b/pkg/docker/docker.go index 1ea32ee..6b44a62 100644 --- a/pkg/docker/docker.go +++ b/pkg/docker/docker.go @@ -15,8 +15,10 @@ package docker import ( + "bufio" "context" _ "embed" + "path/filepath" "strings" "go.linka.cloud/d2vm/pkg/exec" @@ -35,3 +37,36 @@ func Cmd(ctx context.Context, args ...string) error { func CmdOut(ctx context.Context, args ...string) (string, string, error) { return exec.RunOut(ctx, "docker", args...) } + +func Build(ctx context.Context, tag, dockerfile, dir string, buildArgs ...string) error { + if dockerfile == "" { + dockerfile = filepath.Join(dir, "Dockerfile") + } + args := []string{"image", "build", "-t", tag, "-f", dockerfile} + for _, v := range buildArgs { + args = append(args, "--build-arg", v) + } + args = append(args, dir) + return Cmd(ctx, args...) +} + +func Remove(ctx context.Context, tag string) error { + return Cmd(ctx, "image", "rm", tag) +} + +func ImageList(ctx context.Context, tag string) ([]string, error) { + o, _, err := CmdOut(ctx, "image", "ls", "--format={{ .Repository }}:{{ .Tag }}", tag) + if err != nil { + return nil, err + } + s := bufio.NewScanner(strings.NewReader(o)) + var imgs []string + for s.Scan() { + imgs = append(imgs, s.Text()) + } + return imgs, s.Err() +} + +func Pull(ctx context.Context, tag string) error { + return Cmd(ctx, "image", "pull", tag) +} diff --git a/pkg/exec/exec.go b/pkg/exec/exec.go index 5231cb9..35b33fb 100644 --- a/pkg/exec/exec.go +++ b/pkg/exec/exec.go @@ -29,6 +29,14 @@ var ( CommandContext = exec.CommandContext ) +func SetDebug(debug bool) { + if debug { + Run = RunStdout + } else { + Run = RunNoOut + } +} + func RunStdout(ctx context.Context, c string, args ...string) error { cmd := exec.CommandContext(ctx, c, args...) cmd.Stdout = os.Stdout