From fd95103a823414cb394b236bc2de9cded8465c89 Mon Sep 17 00:00:00 2001 From: Jan Broer Date: Mon, 9 Nov 2015 05:44:56 +0100 Subject: [PATCH] Adds support for saving/restoring image layers from archive --- DOCS.md | 24 ++++++++++++++++++++++++ main.go | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 81 insertions(+) diff --git a/DOCS.md b/DOCS.md index 6bb5fac..10709cd 100644 --- a/DOCS.md +++ b/DOCS.md @@ -9,6 +9,9 @@ The following parameters are used to configure this plugin: * `tag` - repository tag for the image * `insecure` - enable insecure communication to this registry * `storage_driver` - use `aufs`, `devicemapper`, `btrfs` or `overlay` driver +* `archive` - save and restore image layers to/from a tarred archive + * `file` - absolute or relative path to archive file + * `tag` - limit archiving to these tag(s) (optional) The following is a sample Docker configuration in your .drone.yml file: @@ -53,6 +56,27 @@ publish: Note that in the above example we quote the version numbers. If the yaml parser interprets the value as a number it will cause a parsing error. +You may want to cache Docker image layers between builds to speed up the build process: + +``` +publish: + docker: + username: kevinbacon + password: $$DOCKER_PASSWORD + email: kevin.bacon@mail.com + repo: foo/bar + tag: + - latest + - "1.0.1" + archive: + file: docker/image.tar + tag: latest + +cache: + mount: + - docker/image.tar +``` + ## Troubleshooting For detailed output you can set the `DOCKER_LAUNCH_DEBUG` environment variable in your plugin configuration. This starts Docker with verbose logging enabled. diff --git a/main.go b/main.go index d93f2ff..ced75c4 100644 --- a/main.go +++ b/main.go @@ -5,12 +5,18 @@ import ( "io/ioutil" "os" "os/exec" + "path/filepath" "strings" "time" "github.com/drone/drone-plugin-go/plugin" ) +type Archive struct { + File string `json:"file"` + Tag StrSlice `json:"tag"` +} + type Docker struct { Storage string `json:"storage_driver"` Registry string `json:"registry"` @@ -24,6 +30,7 @@ type Docker struct { File string `json:"file"` Context string `json:"context"` Dns []string `json:"dns"` + Archive Archive `json:"archive"` } func main() { @@ -59,6 +66,12 @@ func main() { if vargs.Tag.Len() == 0 { vargs.Tag = StrSlice{[]string{"latest"}} } + // Archive file can be both a relative or absolute path + if len(vargs.Archive.File) != 0 { + if ! filepath.IsAbs(vargs.Archive.File) { + vargs.Archive.File = filepath.Join(workspace.Path, vargs.Archive.File) + } + } go func() { args := []string{"-d"} @@ -125,6 +138,23 @@ func main() { trace(cmd) cmd.Run() + // Load archived image if exists + if len(vargs.Archive.File) != 0 { + if _, err := os.Stat(vargs.Archive.File); err != nil { + fmt.Printf("Archive %s does not exist. Building from scratch.\n", vargs.Archive.File) + } else { + cmd := exec.Command("/usr/bin/docker", "load", "-i", vargs.Archive.File) + cmd.Dir = workspace.Path + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + trace(cmd) + err := cmd.Run() + if err != nil { + os.Exit(1) + } + } + } + // Build the container name := fmt.Sprintf("%s:%s", vargs.Repo, vargs.Tag.Slice()[0]) cmd = exec.Command("/usr/bin/docker", "build", "--pull=true", "--rm=true", "-f", vargs.File, "-t", name, vargs.Context) @@ -165,6 +195,33 @@ func main() { } } + // Save the image to the archive + if len(vargs.Archive.File) != 0 { + // if the path's directory does not exist, create it + dir := filepath.Dir(vargs.Archive.File) + os.MkdirAll(dir, 0755) + + cmd = exec.Command("/usr/bin/docker", "save", "-o", vargs.Archive.File) + + // Limit save command to the given tag(s) + if vargs.Archive.Tag.Len() != 0 { + for _, tag := range vargs.Archive.Tag.Slice() { + name_ := fmt.Sprintf("%s:%s", vargs.Repo, tag) + cmd.Args = append(cmd.Args, name_) + } + } else { + cmd.Args = append(cmd.Args, vargs.Repo) + } + + cmd.Dir = workspace.Path + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + trace(cmd) + err := cmd.Run() + if err != nil { + os.Exit(1) + } + } } // Trace writes each command to standard error (preceded by a ‘$ ’) before it