From ead0d2f2a37852d2e4b50c1306869495857f8f2a Mon Sep 17 00:00:00 2001 From: Justin Cormack Date: Fri, 24 Mar 2017 15:34:19 +0000 Subject: [PATCH] Add a moby build --pull option to force pulling images Signed-off-by: Justin Cormack --- src/cmd/moby/build.go | 26 +++- src/cmd/moby/docker.go | 262 +++++++++++++++++++++++++++++++++++++++++ src/cmd/moby/image.go | 127 -------------------- src/cmd/moby/main.go | 92 +-------------- 4 files changed, 289 insertions(+), 218 deletions(-) create mode 100644 src/cmd/moby/docker.go diff --git a/src/cmd/moby/build.go b/src/cmd/moby/build.go index f94b7f9a6..f84e6a5c4 100644 --- a/src/cmd/moby/build.go +++ b/src/cmd/moby/build.go @@ -65,7 +65,7 @@ func containersInitrd(containers []*bytes.Buffer) (*bytes.Buffer, error) { return w, nil } -func build(name string, args []string) { +func build(name string, pull bool, args []string) { conf := "moby.yaml" if len(args) > 0 { conf = args[0] @@ -91,6 +91,12 @@ func build(name string, args []string) { containers := []*bytes.Buffer{} + if pull { + err := dockerPull(m.Kernel.Image) + if err != nil { + log.Fatalf("Could not pull image %s: %v", m.Kernel.Image, err) + } + } // get kernel bzImage and initrd tarball from container // TODO examine contents to see what names they might have const ( @@ -109,6 +115,12 @@ func build(name string, args []string) { containers = append(containers, ktar) // convert init image to tarball + if pull { + err := dockerPull(m.Init) + if err != nil { + log.Fatalf("Could not pull image %s: %v", m.Init, err) + } + } init, err := ImageExtract(m.Init, "") if err != nil { log.Fatalf("Failed to build init tarball: %v", err) @@ -117,6 +129,12 @@ func build(name string, args []string) { containers = append(containers, buffer) for i, image := range m.System { + if pull { + err := dockerPull(image.Image) + if err != nil { + log.Fatalf("Could not pull image %s: %v", image.Image, err) + } + } config, err := ConfigToOCI(&image) if err != nil { log.Fatalf("Failed to run riddler to get config.json for %s: %v", image.Image, err) @@ -132,6 +150,12 @@ func build(name string, args []string) { } for _, image := range m.Daemon { + if pull { + err := dockerPull(image.Image) + if err != nil { + log.Fatalf("Could not pull image %s: %v", image.Image, err) + } + } config, err := ConfigToOCI(&image) if err != nil { log.Fatalf("Failed to run riddler to get config.json for %s: %v", image.Image, err) diff --git a/src/cmd/moby/docker.go b/src/cmd/moby/docker.go new file mode 100644 index 000000000..4e574dbf3 --- /dev/null +++ b/src/cmd/moby/docker.go @@ -0,0 +1,262 @@ +package main + +// We want to replace much of this with use of containerd tools +// and also using the Docker API not shelling out + +import ( + "errors" + "fmt" + "io" + "io/ioutil" + "os/exec" + "strings" +) + +func dockerRun(args ...string) ([]byte, error) { + docker, err := exec.LookPath("docker") + if err != nil { + return []byte{}, errors.New("Docker does not seem to be installed") + } + args = append([]string{"run", "--rm"}, args...) + cmd := exec.Command(docker, args...) + + stderrPipe, err := cmd.StderrPipe() + if err != nil { + return []byte{}, err + } + + stdoutPipe, err := cmd.StdoutPipe() + if err != nil { + return []byte{}, err + } + + err = cmd.Start() + if err != nil { + return []byte{}, err + } + + stdout, err := ioutil.ReadAll(stdoutPipe) + if err != nil { + return []byte{}, err + } + + stderr, err := ioutil.ReadAll(stderrPipe) + if err != nil { + return []byte{}, err + } + + err = cmd.Wait() + if err != nil { + return []byte{}, fmt.Errorf("%v: %s", err, stderr) + } + + return stdout, nil +} + +func dockerRunInput(input io.Reader, args ...string) ([]byte, error) { + docker, err := exec.LookPath("docker") + if err != nil { + return []byte{}, errors.New("Docker does not seem to be installed") + } + args = append([]string{"run", "--rm", "-i"}, args...) + cmd := exec.Command(docker, args...) + cmd.Stdin = input + + stderrPipe, err := cmd.StderrPipe() + if err != nil { + return []byte{}, err + } + + stdoutPipe, err := cmd.StdoutPipe() + if err != nil { + return []byte{}, err + } + + err = cmd.Start() + if err != nil { + return []byte{}, err + } + + stdout, err := ioutil.ReadAll(stdoutPipe) + if err != nil { + return []byte{}, err + } + + stderr, err := ioutil.ReadAll(stderrPipe) + if err != nil { + return []byte{}, err + } + + err = cmd.Wait() + if err != nil { + return []byte{}, fmt.Errorf("%v: %s", err, stderr) + } + + return stdout, nil +} + +func dockerCreate(image string) (string, error) { + docker, err := exec.LookPath("docker") + if err != nil { + return "", errors.New("Docker does not seem to be installed") + } + // we do not ever run the container, so /dev/null is used as command + args := []string{"create", image, "/dev/null"} + cmd := exec.Command(docker, args...) + + stderrPipe, err := cmd.StderrPipe() + if err != nil { + return "", err + } + + stdoutPipe, err := cmd.StdoutPipe() + if err != nil { + return "", err + } + + err = cmd.Start() + if err != nil { + return "", err + } + + stdout, err := ioutil.ReadAll(stdoutPipe) + if err != nil { + return "", err + } + + stderr, err := ioutil.ReadAll(stderrPipe) + if err != nil { + return "", err + } + + err = cmd.Wait() + if err != nil { + return "", fmt.Errorf("%s: %s", err, stderr) + } + + container := strings.TrimSpace(string(stdout)) + return container, nil +} + +func dockerExport(container string) ([]byte, error) { + docker, err := exec.LookPath("docker") + if err != nil { + return []byte{}, errors.New("Docker does not seem to be installed") + } + args := []string{"export", container} + cmd := exec.Command(docker, args...) + + stderrPipe, err := cmd.StderrPipe() + if err != nil { + return []byte{}, err + } + + stdoutPipe, err := cmd.StdoutPipe() + if err != nil { + return []byte{}, err + } + + err = cmd.Start() + if err != nil { + return []byte{}, err + } + + stdout, err := ioutil.ReadAll(stdoutPipe) + if err != nil { + return []byte{}, err + } + + stderr, err := ioutil.ReadAll(stderrPipe) + if err != nil { + return []byte{}, err + } + + err = cmd.Wait() + if err != nil { + return []byte{}, fmt.Errorf("%v: %s", err, stderr) + } + + return stdout, nil +} + +func dockerRm(container string) error { + docker, err := exec.LookPath("docker") + if err != nil { + return errors.New("Docker does not seem to be installed") + } + args := []string{"rm", container} + cmd := exec.Command(docker, args...) + + stderrPipe, err := cmd.StderrPipe() + if err != nil { + return err + } + + stdoutPipe, err := cmd.StdoutPipe() + if err != nil { + return err + } + + err = cmd.Start() + if err != nil { + return err + } + + _, err = ioutil.ReadAll(stdoutPipe) + if err != nil { + return err + } + + stderr, err := ioutil.ReadAll(stderrPipe) + if err != nil { + return err + } + + err = cmd.Wait() + if err != nil { + return fmt.Errorf("%s: %s", err, stderr) + } + + return nil +} + +func dockerPull(image string) error { + docker, err := exec.LookPath("docker") + if err != nil { + return errors.New("Docker does not seem to be installed") + } + args := []string{"pull", image} + cmd := exec.Command(docker, args...) + + stderrPipe, err := cmd.StderrPipe() + if err != nil { + return err + } + + stdoutPipe, err := cmd.StdoutPipe() + if err != nil { + return err + } + + err = cmd.Start() + if err != nil { + return err + } + + _, err = ioutil.ReadAll(stdoutPipe) + if err != nil { + return err + } + + stderr, err := ioutil.ReadAll(stderrPipe) + if err != nil { + return err + } + + err = cmd.Wait() + if err != nil { + return fmt.Errorf("%s: %s", err, stderr) + } + + return nil +} diff --git a/src/cmd/moby/image.go b/src/cmd/moby/image.go index 6a8b3d938..ea95c929c 100644 --- a/src/cmd/moby/image.go +++ b/src/cmd/moby/image.go @@ -3,11 +3,9 @@ package main import ( "archive/tar" "bytes" - "errors" "fmt" "io" "io/ioutil" - "os/exec" "strings" ) @@ -15,131 +13,6 @@ import ( // used the containerd libraries to do this instead locally direct from a local image // cache as it would be much simpler. -func dockerCreate(image string) (string, error) { - docker, err := exec.LookPath("docker") - if err != nil { - return "", errors.New("Docker does not seem to be installed") - } - // we do not ever run the container, so /dev/null is used as command - args := []string{"create", image, "/dev/null"} - cmd := exec.Command(docker, args...) - - stderrPipe, err := cmd.StderrPipe() - if err != nil { - return "", err - } - - stdoutPipe, err := cmd.StdoutPipe() - if err != nil { - return "", err - } - - err = cmd.Start() - if err != nil { - return "", err - } - - stdout, err := ioutil.ReadAll(stdoutPipe) - if err != nil { - return "", err - } - - stderr, err := ioutil.ReadAll(stderrPipe) - if err != nil { - return "", err - } - - err = cmd.Wait() - if err != nil { - return "", fmt.Errorf("%s: %s", err, stderr) - } - - container := strings.TrimSpace(string(stdout)) - return container, nil -} - -func dockerExport(container string) ([]byte, error) { - docker, err := exec.LookPath("docker") - if err != nil { - return []byte{}, errors.New("Docker does not seem to be installed") - } - args := []string{"export", container} - cmd := exec.Command(docker, args...) - - stderrPipe, err := cmd.StderrPipe() - if err != nil { - return []byte{}, err - } - - stdoutPipe, err := cmd.StdoutPipe() - if err != nil { - return []byte{}, err - } - - err = cmd.Start() - if err != nil { - return []byte{}, err - } - - stdout, err := ioutil.ReadAll(stdoutPipe) - if err != nil { - return []byte{}, err - } - - stderr, err := ioutil.ReadAll(stderrPipe) - if err != nil { - return []byte{}, err - } - - err = cmd.Wait() - if err != nil { - return []byte{}, fmt.Errorf("%s: %s", err, stderr) - } - - return stdout, nil -} - -func dockerRm(container string) error { - docker, err := exec.LookPath("docker") - if err != nil { - return errors.New("Docker does not seem to be installed") - } - args := []string{"rm", container} - cmd := exec.Command(docker, args...) - - stderrPipe, err := cmd.StderrPipe() - if err != nil { - return err - } - - stdoutPipe, err := cmd.StdoutPipe() - if err != nil { - return err - } - - err = cmd.Start() - if err != nil { - return err - } - - _, err = ioutil.ReadAll(stdoutPipe) - if err != nil { - return err - } - - stderr, err := ioutil.ReadAll(stderrPipe) - if err != nil { - return err - } - - err = cmd.Wait() - if err != nil { - return fmt.Errorf("%s: %s", err, stderr) - } - - return nil -} - var exclude = map[string]bool{ ".dockerenv": true, "Dockerfile": true, diff --git a/src/cmd/moby/main.go b/src/cmd/moby/main.go index 6a050202a..e0a99a1f3 100644 --- a/src/cmd/moby/main.go +++ b/src/cmd/moby/main.go @@ -1,100 +1,11 @@ package main import ( - "errors" "flag" "fmt" - "io" - "io/ioutil" "os" - "os/exec" ) -func dockerRun(args ...string) ([]byte, error) { - // TODO switch to using Docker client API not exec - just a quick prototype - docker, err := exec.LookPath("docker") - if err != nil { - return []byte{}, errors.New("Docker does not seem to be installed") - } - args = append([]string{"run", "--rm"}, args...) - cmd := exec.Command(docker, args...) - - stderrPipe, err := cmd.StderrPipe() - if err != nil { - return []byte{}, err - } - - stdoutPipe, err := cmd.StdoutPipe() - if err != nil { - return []byte{}, err - } - - err = cmd.Start() - if err != nil { - return []byte{}, err - } - - stdout, err := ioutil.ReadAll(stdoutPipe) - if err != nil { - return []byte{}, err - } - - stderr, err := ioutil.ReadAll(stderrPipe) - if err != nil { - return []byte{}, err - } - - err = cmd.Wait() - if err != nil { - return []byte{}, fmt.Errorf("%s: %s", err, stderr) - } - - return stdout, nil -} - -func dockerRunInput(input io.Reader, args ...string) ([]byte, error) { - // TODO switch to using Docker client API not exec - just a quick prototype - docker, err := exec.LookPath("docker") - if err != nil { - return []byte{}, errors.New("Docker does not seem to be installed") - } - args = append([]string{"run", "--rm", "-i"}, args...) - cmd := exec.Command(docker, args...) - cmd.Stdin = input - - stderrPipe, err := cmd.StderrPipe() - if err != nil { - return []byte{}, err - } - - stdoutPipe, err := cmd.StdoutPipe() - if err != nil { - return []byte{}, err - } - - err = cmd.Start() - if err != nil { - return []byte{}, err - } - - stdout, err := ioutil.ReadAll(stdoutPipe) - if err != nil { - return []byte{}, err - } - - stderr, err := ioutil.ReadAll(stderrPipe) - if err != nil { - return []byte{}, err - } - - err = cmd.Wait() - if err != nil { - return []byte{}, fmt.Errorf("%s: %s", err, stderr) - } - - return stdout, nil -} - func main() { flag.Usage = func() { fmt.Printf("USAGE: %s COMMAND\n\n", os.Args[0]) @@ -114,6 +25,7 @@ func main() { buildCmd.PrintDefaults() } buildName := buildCmd.String("name", "", "Name to use for output files") + buildPull := buildCmd.Bool("pull", false, "Always pull images") runCmd := flag.NewFlagSet("run", flag.ExitOnError) runCmd.Usage = func() { @@ -141,7 +53,7 @@ func main() { switch os.Args[1] { case "build": buildCmd.Parse(os.Args[2:]) - build(*buildName, buildCmd.Args()) + build(*buildName, *buildPull, buildCmd.Args()) case "run": runCmd.Parse(os.Args[2:]) run(*runCPUs, *runMem, *runDiskSz, *runDisk, runCmd.Args())