From 90a8e45604f42d60d58b4cefa37a5e5d3112b64a Mon Sep 17 00:00:00 2001 From: Gosuke Miyashita Date: Sat, 21 Mar 2015 01:52:05 +0900 Subject: [PATCH 01/58] Append icc related iptables rules, not INSERT Signed-off-by: Gosuke Miyashita --- daemon/networkdriver/bridge/driver.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/daemon/networkdriver/bridge/driver.go b/daemon/networkdriver/bridge/driver.go index 8f240ef59..0ea4d5dca 100644 --- a/daemon/networkdriver/bridge/driver.go +++ b/daemon/networkdriver/bridge/driver.go @@ -340,7 +340,7 @@ func setupIPTables(addr net.Addr, icc, ipmasq bool) error { if !iptables.Exists(iptables.Filter, "FORWARD", dropArgs...) { logrus.Debugf("Disable inter-container communication") - if output, err := iptables.Raw(append([]string{"-I", "FORWARD"}, dropArgs...)...); err != nil { + if output, err := iptables.Raw(append([]string{"-A", "FORWARD"}, dropArgs...)...); err != nil { return fmt.Errorf("Unable to prevent intercontainer communication: %s", err) } else if len(output) != 0 { return fmt.Errorf("Error disabling intercontainer communication: %s", output) @@ -351,7 +351,7 @@ func setupIPTables(addr net.Addr, icc, ipmasq bool) error { if !iptables.Exists(iptables.Filter, "FORWARD", acceptArgs...) { logrus.Debugf("Enable inter-container communication") - if output, err := iptables.Raw(append([]string{"-I", "FORWARD"}, acceptArgs...)...); err != nil { + if output, err := iptables.Raw(append([]string{"-A", "FORWARD"}, acceptArgs...)...); err != nil { return fmt.Errorf("Unable to allow intercontainer communication: %s", err) } else if len(output) != 0 { return fmt.Errorf("Error enabling intercontainer communication: %s", output) From 1f7ba6f80914cc663b3b38ffc0b2c8e1add2547a Mon Sep 17 00:00:00 2001 From: Vincent Demeester Date: Thu, 23 Apr 2015 09:43:04 +0200 Subject: [PATCH 02/58] Fix the design proposal link in advanced contribution page Signed-off-by: Vincent Demeester --- docs/sources/project/advanced-contributing.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/sources/project/advanced-contributing.md b/docs/sources/project/advanced-contributing.md index f20cbfff9..7ee7a86cb 100644 --- a/docs/sources/project/advanced-contributing.md +++ b/docs/sources/project/advanced-contributing.md @@ -67,7 +67,7 @@ The following provides greater detail on the process: The design proposals are all online in our GitHub pull requests. + 3Akind%2Fproposal" target="_blank">all online in our GitHub pull requests. 3. Talk to the community about your idea. From b6569b6b82df4c5e29ee8f5ebd9db7e36919cefd Mon Sep 17 00:00:00 2001 From: Vincent Batts Date: Thu, 23 Apr 2015 08:21:39 -0400 Subject: [PATCH 03/58] contrib/init: unshare mount namespace for inits * openrc * sysvinit-debian * upstart Signed-off-by: Vincent Batts --- contrib/init/openrc/docker.initd | 6 ++++-- contrib/init/sysvinit-debian/docker | 7 ++++--- contrib/init/upstart/docker.conf | 2 +- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/contrib/init/openrc/docker.initd b/contrib/init/openrc/docker.initd index a9d21b170..f251e9af5 100755 --- a/contrib/init/openrc/docker.initd +++ b/contrib/init/openrc/docker.initd @@ -7,6 +7,7 @@ DOCKER_LOGFILE=${DOCKER_LOGFILE:-/var/log/${SVCNAME}.log} DOCKER_PIDFILE=${DOCKER_PIDFILE:-/run/${SVCNAME}.pid} DOCKER_BINARY=${DOCKER_BINARY:-/usr/bin/docker} DOCKER_OPTS=${DOCKER_OPTS:-} +UNSHARE_BINARY=${UNSHARE_BINARY:-/usr/bin/unshare} start() { checkpath -f -m 0644 -o root:docker "$DOCKER_LOGFILE" @@ -16,11 +17,12 @@ start() { ebegin "Starting docker daemon" start-stop-daemon --start --background \ - --exec "$DOCKER_BINARY" \ + --exec "$UNSHARE_BINARY" \ --pidfile "$DOCKER_PIDFILE" \ --stdout "$DOCKER_LOGFILE" \ --stderr "$DOCKER_LOGFILE" \ - -- -d -p "$DOCKER_PIDFILE" \ + -- --mount \ + -- "$DOCKER_BINARY" -d -p "$DOCKER_PIDFILE" \ $DOCKER_OPTS eend $? } diff --git a/contrib/init/sysvinit-debian/docker b/contrib/init/sysvinit-debian/docker index cf33c8377..35fd71f13 100755 --- a/contrib/init/sysvinit-debian/docker +++ b/contrib/init/sysvinit-debian/docker @@ -30,6 +30,7 @@ DOCKER_SSD_PIDFILE=/var/run/$BASE-ssd.pid DOCKER_LOGFILE=/var/log/$BASE.log DOCKER_OPTS= DOCKER_DESC="Docker" +UNSHARE=${UNSHARE:-/usr/bin/unshare} # Get lsb functions . /lib/lsb/init-functions @@ -99,11 +100,11 @@ case "$1" in log_begin_msg "Starting $DOCKER_DESC: $BASE" start-stop-daemon --start --background \ --no-close \ - --exec "$DOCKER" \ + --exec "$UNSHARE" \ --pidfile "$DOCKER_SSD_PIDFILE" \ --make-pidfile \ - -- \ - -d -p "$DOCKER_PIDFILE" \ + -- --mount \ + -- "$DOCKER" -d -p "$DOCKER_PIDFILE" \ $DOCKER_OPTS \ >> "$DOCKER_LOGFILE" 2>&1 log_end_msg $? diff --git a/contrib/init/upstart/docker.conf b/contrib/init/upstart/docker.conf index 4ad6058ed..5e8df6e3c 100644 --- a/contrib/init/upstart/docker.conf +++ b/contrib/init/upstart/docker.conf @@ -37,7 +37,7 @@ script if [ -f /etc/default/$UPSTART_JOB ]; then . /etc/default/$UPSTART_JOB fi - exec "$DOCKER" -d $DOCKER_OPTS + exec unshare -m -- "$DOCKER" -d $DOCKER_OPTS end script # Don't emit "started" event until docker.sock is ready. From 47e5acfbaefc45e536b953af6bf8a3993669c816 Mon Sep 17 00:00:00 2001 From: Qiang Huang Date: Tue, 14 Apr 2015 08:38:34 +0800 Subject: [PATCH 04/58] add devices cgroup check and errors Signed-off-by: Qiang Huang --- pkg/sysinfo/sysinfo.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/pkg/sysinfo/sysinfo.go b/pkg/sysinfo/sysinfo.go index 76a61fa95..0c1ae8743 100644 --- a/pkg/sysinfo/sysinfo.go +++ b/pkg/sysinfo/sysinfo.go @@ -58,5 +58,11 @@ func New(quiet bool) *SysInfo { } else { sysInfo.AppArmor = true } + + // Check if Devices cgroup is mounted, it is hard requirement for container security. + if _, err := cgroups.FindCgroupMountpoint("devices"); err != nil { + logrus.Fatalf("Error mounting devices cgroup: %v", err) + } + return sysInfo } From 66acef865d7504605572b0d9566d9e250cf19bc2 Mon Sep 17 00:00:00 2001 From: Ma Shimiao Date: Mon, 13 Apr 2015 22:33:52 +0800 Subject: [PATCH 05/58] clean up viz code Signed-off-by: Ma Shimiao --- api/client/images.go | 261 ++++++++++--------------------------------- api/server/server.go | 10 -- 2 files changed, 57 insertions(+), 214 deletions(-) diff --git a/api/client/images.go b/api/client/images.go index 32440d48d..e39c47374 100644 --- a/api/client/images.go +++ b/api/client/images.go @@ -4,7 +4,6 @@ import ( "encoding/json" "fmt" "net/url" - "strings" "text/tabwriter" "time" @@ -18,74 +17,6 @@ import ( "github.com/docker/docker/utils" ) -// FIXME: --viz and --tree are deprecated. Remove them in a future version. -func (cli *DockerCli) walkTree(noTrunc bool, images []*types.Image, byParent map[string][]*types.Image, prefix string, printNode func(cli *DockerCli, noTrunc bool, image *types.Image, prefix string)) { - length := len(images) - if length > 1 { - for index, image := range images { - if index+1 == length { - printNode(cli, noTrunc, image, prefix+"└─") - if subimages, exists := byParent[image.ID]; exists { - cli.walkTree(noTrunc, subimages, byParent, prefix+" ", printNode) - } - } else { - printNode(cli, noTrunc, image, prefix+"\u251C─") - if subimages, exists := byParent[image.ID]; exists { - cli.walkTree(noTrunc, subimages, byParent, prefix+"\u2502 ", printNode) - } - } - } - } else { - for _, image := range images { - printNode(cli, noTrunc, image, prefix+"└─") - if subimages, exists := byParent[image.ID]; exists { - cli.walkTree(noTrunc, subimages, byParent, prefix+" ", printNode) - } - } - } -} - -// FIXME: --viz and --tree are deprecated. Remove them in a future version. -func (cli *DockerCli) printVizNode(noTrunc bool, image *types.Image, prefix string) { - var ( - imageID string - parentID string - ) - if noTrunc { - imageID = image.ID - parentID = image.ParentId - } else { - imageID = stringid.TruncateID(image.ID) - parentID = stringid.TruncateID(image.ParentId) - } - if parentID == "" { - fmt.Fprintf(cli.out, " base -> \"%s\" [style=invis]\n", imageID) - } else { - fmt.Fprintf(cli.out, " \"%s\" -> \"%s\"\n", parentID, imageID) - } - if image.RepoTags[0] != ":" { - fmt.Fprintf(cli.out, " \"%s\" [label=\"%s\\n%s\",shape=box,fillcolor=\"paleturquoise\",style=\"filled,rounded\"];\n", - imageID, imageID, strings.Join(image.RepoTags, "\\n")) - } -} - -// FIXME: --viz and --tree are deprecated. Remove them in a future version. -func (cli *DockerCli) printTreeNode(noTrunc bool, image *types.Image, prefix string) { - var imageID string - if noTrunc { - imageID = image.ID - } else { - imageID = stringid.TruncateID(image.ID) - } - - fmt.Fprintf(cli.out, "%s%s Virtual Size: %s", prefix, imageID, units.HumanSize(float64(image.VirtualSize))) - if image.RepoTags[0] != ":" { - fmt.Fprintf(cli.out, " Tags: %s\n", strings.Join(image.RepoTags, ", ")) - } else { - fmt.Fprint(cli.out, "\n") - } -} - // CmdImages lists the images in a specified repository, or all top-level images if no repository is specified. // // Usage: docker images [OPTIONS] [REPOSITORY] @@ -95,9 +26,6 @@ func (cli *DockerCli) CmdImages(args ...string) error { all := cmd.Bool([]string{"a", "-all"}, false, "Show all images (default hides intermediate images)") noTrunc := cmd.Bool([]string{"#notrunc", "-no-trunc"}, false, "Don't truncate output") showDigests := cmd.Bool([]string{"-digests"}, false, "Show digests") - // FIXME: --viz and --tree are deprecated. Remove them in a future version. - flViz := cmd.Bool([]string{"#v", "#viz", "#-viz"}, false, "Output graph in graphviz format") - flTree := cmd.Bool([]string{"#t", "#tree", "#-tree"}, false, "Output graph in tree format") flFilter := opts.NewListOpts(nil) cmd.Var(&flFilter, []string{"f", "-filter"}, "Filter output based on conditions provided") @@ -116,158 +44,83 @@ func (cli *DockerCli) CmdImages(args ...string) error { } matchName := cmd.Arg(0) - // FIXME: --viz and --tree are deprecated. Remove them in a future version. - if *flViz || *flTree { - v := url.Values{ - "all": []string{"1"}, - } - if len(imageFilterArgs) > 0 { - filterJSON, err := filters.ToParam(imageFilterArgs) - if err != nil { - return err - } - v.Set("filters", filterJSON) - } - - rdr, _, err := cli.call("GET", "/images/json?"+v.Encode(), nil, nil) + v := url.Values{} + if len(imageFilterArgs) > 0 { + filterJSON, err := filters.ToParam(imageFilterArgs) if err != nil { return err } + v.Set("filters", filterJSON) + } - images := []types.Image{} - err = json.NewDecoder(rdr).Decode(&images) - if err != nil { - return err - } + if cmd.NArg() == 1 { + // FIXME rename this parameter, to not be confused with the filters flag + v.Set("filter", matchName) + } + if *all { + v.Set("all", "1") + } - var ( - printNode func(cli *DockerCli, noTrunc bool, image *types.Image, prefix string) - startImage *types.Image + rdr, _, err := cli.call("GET", "/images/json?"+v.Encode(), nil, nil) + if err != nil { + return err + } - roots = []*types.Image{} - byParent = make(map[string][]*types.Image) - ) + images := []types.Image{} + if err := json.NewDecoder(rdr).Decode(&images); err != nil { + return err + } - for _, image := range images { - if image.ParentId == "" { - roots = append(roots, &image) - } else { - if children, exists := byParent[image.ParentId]; exists { - children = append(children, &image) - } else { - byParent[image.ParentId] = []*types.Image{&image} - } - } - - if matchName != "" { - if matchName == image.ID || matchName == stringid.TruncateID(image.ID) { - startImage = &image - } - - for _, repotag := range image.RepoTags { - if repotag == matchName { - startImage = &image - } - } - } - } - - if *flViz { - fmt.Fprintf(cli.out, "digraph docker {\n") - printNode = (*DockerCli).printVizNode + w := tabwriter.NewWriter(cli.out, 20, 1, 3, ' ', 0) + if !*quiet { + if *showDigests { + fmt.Fprintln(w, "REPOSITORY\tTAG\tDIGEST\tIMAGE ID\tCREATED\tVIRTUAL SIZE") } else { - printNode = (*DockerCli).printTreeNode + fmt.Fprintln(w, "REPOSITORY\tTAG\tIMAGE ID\tCREATED\tVIRTUAL SIZE") + } + } + + for _, image := range images { + ID := image.ID + if !*noTrunc { + ID = stringid.TruncateID(ID) } - if startImage != nil { - root := []*types.Image{startImage} - cli.walkTree(*noTrunc, root, byParent, "", printNode) - } else if matchName == "" { - cli.walkTree(*noTrunc, roots, byParent, "", printNode) - } - if *flViz { - fmt.Fprintf(cli.out, " base [style=invisible]\n}\n") - } - } else { - v := url.Values{} - if len(imageFilterArgs) > 0 { - filterJSON, err := filters.ToParam(imageFilterArgs) - if err != nil { - return err - } - v.Set("filters", filterJSON) + repoTags := image.RepoTags + repoDigests := image.RepoDigests + + if len(repoTags) == 1 && repoTags[0] == ":" && len(repoDigests) == 1 && repoDigests[0] == "@" { + // dangling image - clear out either repoTags or repoDigsts so we only show it once below + repoDigests = []string{} } - if cmd.NArg() == 1 { - // FIXME rename this parameter, to not be confused with the filters flag - v.Set("filter", matchName) - } - if *all { - v.Set("all", "1") - } - - rdr, _, err := cli.call("GET", "/images/json?"+v.Encode(), nil, nil) - if err != nil { - return err - } - - images := []types.Image{} - err = json.NewDecoder(rdr).Decode(&images) - if err != nil { - return err - } - - w := tabwriter.NewWriter(cli.out, 20, 1, 3, ' ', 0) - if !*quiet { - if *showDigests { - fmt.Fprintln(w, "REPOSITORY\tTAG\tDIGEST\tIMAGE ID\tCREATED\tVIRTUAL SIZE") + // combine the tags and digests lists + tagsAndDigests := append(repoTags, repoDigests...) + for _, repoAndRef := range tagsAndDigests { + repo, ref := parsers.ParseRepositoryTag(repoAndRef) + // default tag and digest to none - if there's a value, it'll be set below + tag := "" + digest := "" + if utils.DigestReference(ref) { + digest = ref } else { - fmt.Fprintln(w, "REPOSITORY\tTAG\tIMAGE ID\tCREATED\tVIRTUAL SIZE") - } - } - - for _, image := range images { - ID := image.ID - if !*noTrunc { - ID = stringid.TruncateID(ID) + tag = ref } - repoTags := image.RepoTags - repoDigests := image.RepoDigests - - if len(repoTags) == 1 && repoTags[0] == ":" && len(repoDigests) == 1 && repoDigests[0] == "@" { - // dangling image - clear out either repoTags or repoDigsts so we only show it once below - repoDigests = []string{} - } - - // combine the tags and digests lists - tagsAndDigests := append(repoTags, repoDigests...) - for _, repoAndRef := range tagsAndDigests { - repo, ref := parsers.ParseRepositoryTag(repoAndRef) - // default tag and digest to none - if there's a value, it'll be set below - tag := "" - digest := "" - if utils.DigestReference(ref) { - digest = ref + if !*quiet { + if *showDigests { + fmt.Fprintf(w, "%s\t%s\t%s\t%s\t%s ago\t%s\n", repo, tag, digest, ID, units.HumanDuration(time.Now().UTC().Sub(time.Unix(int64(image.Created), 0))), units.HumanSize(float64(image.VirtualSize))) } else { - tag = ref - } - - if !*quiet { - if *showDigests { - fmt.Fprintf(w, "%s\t%s\t%s\t%s\t%s ago\t%s\n", repo, tag, digest, ID, units.HumanDuration(time.Now().UTC().Sub(time.Unix(int64(image.Created), 0))), units.HumanSize(float64(image.VirtualSize))) - } else { - fmt.Fprintf(w, "%s\t%s\t%s\t%s ago\t%s\n", repo, tag, ID, units.HumanDuration(time.Now().UTC().Sub(time.Unix(int64(image.Created), 0))), units.HumanSize(float64(image.VirtualSize))) - } - } else { - fmt.Fprintln(w, ID) + fmt.Fprintf(w, "%s\t%s\t%s\t%s ago\t%s\n", repo, tag, ID, units.HumanDuration(time.Now().UTC().Sub(time.Unix(int64(image.Created), 0))), units.HumanSize(float64(image.VirtualSize))) } + } else { + fmt.Fprintln(w, ID) } } + } - if !*quiet { - w.Flush() - } + if !*quiet { + w.Flush() } return nil } diff --git a/api/server/server.go b/api/server/server.go index 830e731a7..b5f978e84 100644 --- a/api/server/server.go +++ b/api/server/server.go @@ -406,15 +406,6 @@ func (s *Server) getImagesJSON(eng *engine.Engine, version version.Version, w ht return writeJSON(w, http.StatusOK, legacyImages) } -func (s *Server) getImagesViz(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error { - if version.GreaterThan("1.6") { - w.WriteHeader(http.StatusNotFound) - return fmt.Errorf("This is now implemented in the client.") - } - eng.ServeHTTP(w, r) - return nil -} - func (s *Server) getInfo(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error { w.Header().Set("Content-Type", "application/json") @@ -1588,7 +1579,6 @@ func createRouter(s *Server, eng *engine.Engine) *mux.Router { "/info": s.getInfo, "/version": s.getVersion, "/images/json": s.getImagesJSON, - "/images/viz": s.getImagesViz, "/images/search": s.getImagesSearch, "/images/get": s.getImagesGet, "/images/{name:.*}/get": s.getImagesGet, From 667b1e220cf82fb77fd776426a4b712ae5fee0ae Mon Sep 17 00:00:00 2001 From: Qiang Huang Date: Wed, 15 Apr 2015 08:16:00 +0800 Subject: [PATCH 06/58] simplify memory limit check If memory cgroup is mounted, memory limit is always supported, no need to check if these files are exist. Signed-off-by: Qiang Huang --- pkg/sysinfo/sysinfo.go | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/pkg/sysinfo/sysinfo.go b/pkg/sysinfo/sysinfo.go index 0c1ae8743..195a03e9a 100644 --- a/pkg/sysinfo/sysinfo.go +++ b/pkg/sysinfo/sysinfo.go @@ -23,20 +23,16 @@ func New(quiet bool) *SysInfo { sysInfo := &SysInfo{} if cgroupMemoryMountpoint, err := cgroups.FindCgroupMountpoint("memory"); err != nil { if !quiet { - logrus.Warnf("%v", err) + logrus.Warnf("Your kernel does not support cgroup memory limit: %v", err) } } else { - _, err1 := ioutil.ReadFile(path.Join(cgroupMemoryMountpoint, "memory.limit_in_bytes")) - _, err2 := ioutil.ReadFile(path.Join(cgroupMemoryMountpoint, "memory.soft_limit_in_bytes")) - sysInfo.MemoryLimit = err1 == nil && err2 == nil - if !sysInfo.MemoryLimit && !quiet { - logrus.Warn("Your kernel does not support cgroup memory limit.") - } + // If memory cgroup is mounted, MemoryLimit is always enabled. + sysInfo.MemoryLimit = true - _, err = ioutil.ReadFile(path.Join(cgroupMemoryMountpoint, "memory.memsw.limit_in_bytes")) - sysInfo.SwapLimit = err == nil + _, err1 := ioutil.ReadFile(path.Join(cgroupMemoryMountpoint, "memory.memsw.limit_in_bytes")) + sysInfo.SwapLimit = err1 == nil if !sysInfo.SwapLimit && !quiet { - logrus.Warn("Your kernel does not support cgroup swap limit.") + logrus.Warn("Your kernel does not support swap memory limit.") } } From 4377ebd6a758278c1766006c7eb8b777fa175719 Mon Sep 17 00:00:00 2001 From: Aleksa Sarai Date: Fri, 6 Mar 2015 12:53:06 +1100 Subject: [PATCH 07/58] *: expose getResourcePath and getRootResourcePath wrappers Due to the importance of path safety, the internal sanitisation wrappers for volumes and containers should be exposed so other parts of Docker can benefit from proper path sanitisation. Signed-off-by: Aleksa Sarai (github: cyphar) --- daemon/container.go | 47 ++++++++++++++++++++++++++++++++++----------- daemon/volumes.go | 10 +++++----- volumes/volume.go | 36 ++++++++++++++++++++++++++++------ 3 files changed, 71 insertions(+), 22 deletions(-) diff --git a/daemon/container.go b/daemon/container.go index bdfcbf447..8eb35c9f5 100644 --- a/daemon/container.go +++ b/daemon/container.go @@ -211,12 +211,37 @@ func (container *Container) LogEvent(action string) { ) } -func (container *Container) getResourcePath(path string) (string, error) { +// Evaluates `path` in the scope of the container's basefs, with proper path +// sanitisation. Symlinks are all scoped to the basefs of the container, as +// though the container's basefs was `/`. +// +// The basefs of a container is the host-facing path which is bind-mounted as +// `/` inside the container. This method is essentially used to access a +// particular path inside the container as though you were a process in that +// container. +// +// NOTE: The returned path is *only* safely scoped inside the container's basefs +// if no component of the returned path changes (such as a component +// symlinking to a different path) between using this method and using the +// path. See symlink.FollowSymlinkInScope for more details. +func (container *Container) GetResourcePath(path string) (string, error) { cleanPath := filepath.Join("/", path) return symlink.FollowSymlinkInScope(filepath.Join(container.basefs, cleanPath), container.basefs) } -func (container *Container) getRootResourcePath(path string) (string, error) { +// Evaluates `path` in the scope of the container's root, with proper path +// sanitisation. Symlinks are all scoped to the root of the container, as +// though the container's root was `/`. +// +// The root of a container is the host-facing configuration metadata directory. +// Only use this method to safely access the container's `container.json` or +// other metadata files. If in doubt, use container.GetResourcePath. +// +// NOTE: The returned path is *only* safely scoped inside the container's root +// if no component of the returned path changes (such as a component +// symlinking to a different path) between using this method and using the +// path. See symlink.FollowSymlinkInScope for more details. +func (container *Container) GetRootResourcePath(path string) (string, error) { cleanPath := filepath.Join("/", path) return symlink.FollowSymlinkInScope(filepath.Join(container.root, cleanPath), container.root) } @@ -515,7 +540,7 @@ func (streamConfig *StreamConfig) StderrLogPipe() io.ReadCloser { } func (container *Container) buildHostnameFile() error { - hostnamePath, err := container.getRootResourcePath("hostname") + hostnamePath, err := container.GetRootResourcePath("hostname") if err != nil { return err } @@ -529,7 +554,7 @@ func (container *Container) buildHostnameFile() error { func (container *Container) buildHostsFiles(IP string) error { - hostsPath, err := container.getRootResourcePath("hosts") + hostsPath, err := container.GetRootResourcePath("hosts") if err != nil { return err } @@ -895,7 +920,7 @@ func (container *Container) Unmount() error { } func (container *Container) logPath(name string) (string, error) { - return container.getRootResourcePath(fmt.Sprintf("%s-%s.log", container.ID, name)) + return container.GetRootResourcePath(fmt.Sprintf("%s-%s.log", container.ID, name)) } func (container *Container) ReadLog(name string) (io.Reader, error) { @@ -907,11 +932,11 @@ func (container *Container) ReadLog(name string) (io.Reader, error) { } func (container *Container) hostConfigPath() (string, error) { - return container.getRootResourcePath("hostconfig.json") + return container.GetRootResourcePath("hostconfig.json") } func (container *Container) jsonPath() (string, error) { - return container.getRootResourcePath("config.json") + return container.GetRootResourcePath("config.json") } // This method must be exported to be used from the lxc template @@ -981,7 +1006,7 @@ func (container *Container) Copy(resource string) (io.ReadCloser, error) { } }() - basePath, err := container.getResourcePath(resource) + basePath, err := container.GetResourcePath(resource) if err != nil { return nil, err } @@ -1083,7 +1108,7 @@ func (container *Container) setupContainerDns() error { if err != nil { return err } - container.ResolvConfPath, err = container.getRootResourcePath("resolv.conf") + container.ResolvConfPath, err = container.GetRootResourcePath("resolv.conf") if err != nil { return err } @@ -1244,7 +1269,7 @@ func (container *Container) initializeNetworking() error { return err } - hostsPath, err := container.getRootResourcePath("hosts") + hostsPath, err := container.GetRootResourcePath("hosts") if err != nil { return err } @@ -1375,7 +1400,7 @@ func (container *Container) setupWorkingDirectory() error { if container.Config.WorkingDir != "" { container.Config.WorkingDir = path.Clean(container.Config.WorkingDir) - pth, err := container.getResourcePath(container.Config.WorkingDir) + pth, err := container.GetResourcePath(container.Config.WorkingDir) if err != nil { return err } diff --git a/daemon/volumes.go b/daemon/volumes.go index 4d15023ba..79d83504a 100644 --- a/daemon/volumes.go +++ b/daemon/volumes.go @@ -47,7 +47,7 @@ func (container *Container) createVolumes() error { continue } - realPath, err := container.getResourcePath(path) + realPath, err := container.GetResourcePath(path) if err != nil { return err } @@ -336,7 +336,7 @@ func (container *Container) mountVolumes() error { return fmt.Errorf("could not find volume for %s:%s, impossible to mount", source, dest) } - destPath, err := container.getResourcePath(dest) + destPath, err := container.GetResourcePath(dest) if err != nil { return err } @@ -347,7 +347,7 @@ func (container *Container) mountVolumes() error { } for _, mnt := range container.specialMounts() { - destPath, err := container.getResourcePath(mnt.Destination) + destPath, err := container.GetResourcePath(mnt.Destination) if err != nil { return err } @@ -360,7 +360,7 @@ func (container *Container) mountVolumes() error { func (container *Container) unmountVolumes() { for dest := range container.Volumes { - destPath, err := container.getResourcePath(dest) + destPath, err := container.GetResourcePath(dest) if err != nil { logrus.Errorf("error while unmounting volumes %s: %v", destPath, err) continue @@ -372,7 +372,7 @@ func (container *Container) unmountVolumes() { } for _, mnt := range container.specialMounts() { - destPath, err := container.getResourcePath(mnt.Destination) + destPath, err := container.GetResourcePath(mnt.Destination) if err != nil { logrus.Errorf("error while unmounting volumes %s: %v", destPath, err) continue diff --git a/volumes/volume.go b/volumes/volume.go index 87aa4ad25..283bc9bca 100644 --- a/volumes/volume.go +++ b/volumes/volume.go @@ -114,14 +114,38 @@ func (v *Volume) FromDisk() error { } func (v *Volume) jsonPath() (string, error) { - return v.getRootResourcePath("config.json") -} -func (v *Volume) getRootResourcePath(path string) (string, error) { - cleanPath := filepath.Join("/", path) - return symlink.FollowSymlinkInScope(filepath.Join(v.configPath, cleanPath), v.configPath) + return v.GetRootResourcePath("config.json") } -func (v *Volume) getResourcePath(path string) (string, error) { +// Evalutes `path` in the scope of the volume's root path, with proper path +// sanitisation. Symlinks are all scoped to the root of the volume, as +// though the volume's root was `/`. +// +// The volume's root path is the host-facing path of the root of the volume's +// mountpoint inside a container. +// +// NOTE: The returned path is *only* safely scoped inside the volume's root +// if no component of the returned path changes (such as a component +// symlinking to a different path) between using this method and using the +// path. See symlink.FollowSymlinkInScope for more details. +func (v *Volume) GetResourcePath(path string) (string, error) { cleanPath := filepath.Join("/", path) return symlink.FollowSymlinkInScope(filepath.Join(v.Path, cleanPath), v.Path) } + +// Evalutes `path` in the scope of the volume's config path, with proper path +// sanitisation. Symlinks are all scoped to the root of the config path, as +// though the config path was `/`. +// +// The config path of a volume is not exposed to the container and is just used +// to store volume configuration options and other internal information. If in +// doubt, you probably want to just use v.GetResourcePath. +// +// NOTE: The returned path is *only* safely scoped inside the volume's config +// path if no component of the returned path changes (such as a component +// symlinking to a different path) between using this method and using the +// path. See symlink.FollowSymlinkInScope for more details. +func (v *Volume) GetRootResourcePath(path string) (string, error) { + cleanPath := filepath.Join("/", path) + return symlink.FollowSymlinkInScope(filepath.Join(v.configPath, cleanPath), v.configPath) +} From b7c3c0cb6988c9a7864649bfe458217336c5fc51 Mon Sep 17 00:00:00 2001 From: Aleksa Sarai Date: Fri, 20 Mar 2015 19:59:15 +1100 Subject: [PATCH 08/58] *: switch to Get(Root)?ResourcePath where appropriate Several parts of the codebase didn't use the correct path sanitisation wrappers. Now that the wrappers have been exposed, use those. Signed-off-by: Aleksa Sarai (github: cyphar) --- builder/internals.go | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/builder/internals.go b/builder/internals.go index ba7d45bcb..2fe7ca8ba 100644 --- a/builder/internals.go +++ b/builder/internals.go @@ -32,7 +32,6 @@ import ( "github.com/docker/docker/pkg/parsers" "github.com/docker/docker/pkg/progressreader" "github.com/docker/docker/pkg/stringid" - "github.com/docker/docker/pkg/symlink" "github.com/docker/docker/pkg/system" "github.com/docker/docker/pkg/tarsum" "github.com/docker/docker/pkg/urlutil" @@ -646,14 +645,12 @@ func (b *Builder) addContext(container *daemon.Container, orig, dest string, dec err error destExists = true origPath = path.Join(b.contextPath, orig) - destPath = path.Join(container.RootfsPath(), dest) + destPath string ) - if destPath != container.RootfsPath() { - destPath, err = symlink.FollowSymlinkInScope(destPath, container.RootfsPath()) - if err != nil { - return err - } + destPath, err = container.GetResourcePath(dest) + if err != nil { + return err } // Preserve the trailing '/' From c21d408ad24cf8e2b5bd761d562fae7e3ae1bc54 Mon Sep 17 00:00:00 2001 From: Vincent Demeester Date: Fri, 24 Apr 2015 17:03:33 +0200 Subject: [PATCH 09/58] Add coverage on pkg/archive Add tests on: - changes.go - archive.go - wrap.go Should fix #11603 as the coverage is now 81.2% on the ``pkg/archive`` package. There is still room for improvement though :). Signed-off-by: Vincent Demeester --- pkg/archive/archive_test.go | 309 ++++++++++++++++++++++++++++++++++++ pkg/archive/changes_test.go | 152 ++++++++++++++++++ pkg/archive/wrap_test.go | 98 ++++++++++++ 3 files changed, 559 insertions(+) create mode 100644 pkg/archive/wrap_test.go diff --git a/pkg/archive/archive_test.go b/pkg/archive/archive_test.go index dabb0d504..ae9b5a8cd 100644 --- a/pkg/archive/archive_test.go +++ b/pkg/archive/archive_test.go @@ -207,6 +207,315 @@ func TestCmdStreamGood(t *testing.T) { } } +func TestUntarPathWithInvalidDest(t *testing.T) { + tempFolder, err := ioutil.TempDir("", "docker-archive-test") + if err != nil { + t.Fatal(err) + } + defer os.RemoveAll(tempFolder) + invalidDestFolder := path.Join(tempFolder, "invalidDest") + // Create a src file + srcFile := path.Join(tempFolder, "src") + _, err = os.Create(srcFile) + if err != nil { + t.Fatalf("Fail to create the source file") + } + err = UntarPath(srcFile, invalidDestFolder) + if err == nil { + t.Fatalf("UntarPath with invalid destination path should throw an error.") + } +} + +func TestUntarPathWithInvalidSrc(t *testing.T) { + dest, err := ioutil.TempDir("", "docker-archive-test") + if err != nil { + t.Fatalf("Fail to create the destination file") + } + defer os.RemoveAll(dest) + err = UntarPath("/invalid/path", dest) + if err == nil { + t.Fatalf("UntarPath with invalid src path should throw an error.") + } +} + +func TestUntarPath(t *testing.T) { + tmpFolder, err := ioutil.TempDir("", "docker-archive-test") + if err != nil { + t.Fatal(err) + } + defer os.RemoveAll(tmpFolder) + srcFile := path.Join(tmpFolder, "src") + tarFile := path.Join(tmpFolder, "src.tar") + os.Create(path.Join(tmpFolder, "src")) + cmd := exec.Command("/bin/sh", "-c", "tar cf "+tarFile+" "+srcFile) + _, err = cmd.CombinedOutput() + if err != nil { + t.Fatal(err) + } + destFolder := path.Join(tmpFolder, "dest") + err = os.MkdirAll(destFolder, 0740) + if err != nil { + t.Fatalf("Fail to create the destination file") + } + err = UntarPath(tarFile, destFolder) + if err != nil { + t.Fatalf("UntarPath shouldn't throw an error, %s.", err) + } + expectedFile := path.Join(destFolder, srcFile) + _, err = os.Stat(expectedFile) + if err != nil { + t.Fatalf("Destination folder should contain the source file but did not.") + } +} + +// Do the same test as above but with the destination as file, it should fail +func TestUntarPathWithDestinationFile(t *testing.T) { + tmpFolder, err := ioutil.TempDir("", "docker-archive-test") + if err != nil { + t.Fatal(err) + } + defer os.RemoveAll(tmpFolder) + srcFile := path.Join(tmpFolder, "src") + tarFile := path.Join(tmpFolder, "src.tar") + os.Create(path.Join(tmpFolder, "src")) + cmd := exec.Command("/bin/sh", "-c", "tar cf "+tarFile+" "+srcFile) + _, err = cmd.CombinedOutput() + if err != nil { + t.Fatal(err) + } + destFile := path.Join(tmpFolder, "dest") + _, err = os.Create(destFile) + if err != nil { + t.Fatalf("Fail to create the destination file") + } + err = UntarPath(tarFile, destFile) + if err == nil { + t.Fatalf("UntarPath should throw an error if the destination if a file") + } +} + +// Do the same test as above but with the destination folder already exists +// and the destination file is a directory +// It's working, see https://github.com/docker/docker/issues/10040 +func TestUntarPathWithDestinationSrcFileAsFolder(t *testing.T) { + tmpFolder, err := ioutil.TempDir("", "docker-archive-test") + if err != nil { + t.Fatal(err) + } + defer os.RemoveAll(tmpFolder) + srcFile := path.Join(tmpFolder, "src") + tarFile := path.Join(tmpFolder, "src.tar") + os.Create(srcFile) + cmd := exec.Command("/bin/sh", "-c", "tar cf "+tarFile+" "+srcFile) + _, err = cmd.CombinedOutput() + if err != nil { + t.Fatal(err) + } + destFolder := path.Join(tmpFolder, "dest") + err = os.MkdirAll(destFolder, 0740) + if err != nil { + t.Fatalf("Fail to create the destination folder") + } + // Let's create a folder that will has the same path as the extracted file (from tar) + destSrcFileAsFolder := path.Join(destFolder, srcFile) + err = os.MkdirAll(destSrcFileAsFolder, 0740) + if err != nil { + t.Fatal(err) + } + err = UntarPath(tarFile, destFolder) + if err != nil { + t.Fatalf("UntarPath should throw not throw an error if the extracted file already exists and is a folder") + } +} + +func TestCopyWithTarInvalidSrc(t *testing.T) { + tempFolder, err := ioutil.TempDir("", "docker-archive-test") + if err != nil { + t.Fatal(nil) + } + destFolder := path.Join(tempFolder, "dest") + invalidSrc := path.Join(tempFolder, "doesnotexists") + err = os.MkdirAll(destFolder, 0740) + if err != nil { + t.Fatal(err) + } + err = CopyWithTar(invalidSrc, destFolder) + if err == nil { + t.Fatalf("archiver.CopyWithTar with invalid src path should throw an error.") + } +} + +func TestCopyWithTarInexistentDestWillCreateIt(t *testing.T) { + tempFolder, err := ioutil.TempDir("", "docker-archive-test") + if err != nil { + t.Fatal(nil) + } + srcFolder := path.Join(tempFolder, "src") + inexistentDestFolder := path.Join(tempFolder, "doesnotexists") + err = os.MkdirAll(srcFolder, 0740) + if err != nil { + t.Fatal(err) + } + err = CopyWithTar(srcFolder, inexistentDestFolder) + if err != nil { + t.Fatalf("CopyWithTar with an inexistent folder shouldn't fail.") + } + _, err = os.Stat(inexistentDestFolder) + if err != nil { + t.Fatalf("CopyWithTar with an inexistent folder should create it.") + } +} + +// Test CopyWithTar with a file as src +func TestCopyWithTarSrcFile(t *testing.T) { + folder, err := ioutil.TempDir("", "docker-archive-test") + if err != nil { + t.Fatal(err) + } + defer os.RemoveAll(folder) + dest := path.Join(folder, "dest") + srcFolder := path.Join(folder, "src") + src := path.Join(folder, path.Join("src", "src")) + err = os.MkdirAll(srcFolder, 0740) + if err != nil { + t.Fatal(err) + } + err = os.MkdirAll(dest, 0740) + if err != nil { + t.Fatal(err) + } + ioutil.WriteFile(src, []byte("content"), 0777) + err = CopyWithTar(src, dest) + if err != nil { + t.Fatalf("archiver.CopyWithTar shouldn't throw an error, %s.", err) + } + _, err = os.Stat(dest) + // FIXME Check the content + if err != nil { + t.Fatalf("Destination file should be the same as the source.") + } +} + +// Test CopyWithTar with a folder as src +func TestCopyWithTarSrcFolder(t *testing.T) { + folder, err := ioutil.TempDir("", "docker-archive-test") + if err != nil { + t.Fatal(err) + } + defer os.RemoveAll(folder) + dest := path.Join(folder, "dest") + src := path.Join(folder, path.Join("src", "folder")) + err = os.MkdirAll(src, 0740) + if err != nil { + t.Fatal(err) + } + err = os.MkdirAll(dest, 0740) + if err != nil { + t.Fatal(err) + } + ioutil.WriteFile(path.Join(src, "file"), []byte("content"), 0777) + err = CopyWithTar(src, dest) + if err != nil { + t.Fatalf("archiver.CopyWithTar shouldn't throw an error, %s.", err) + } + _, err = os.Stat(dest) + // FIXME Check the content (the file inside) + if err != nil { + t.Fatalf("Destination folder should contain the source file but did not.") + } +} + +func TestCopyFileWithTarInvalidSrc(t *testing.T) { + tempFolder, err := ioutil.TempDir("", "docker-archive-test") + if err != nil { + t.Fatal(err) + } + defer os.RemoveAll(tempFolder) + destFolder := path.Join(tempFolder, "dest") + err = os.MkdirAll(destFolder, 0740) + if err != nil { + t.Fatal(err) + } + invalidFile := path.Join(tempFolder, "doesnotexists") + err = CopyFileWithTar(invalidFile, destFolder) + if err == nil { + t.Fatalf("archiver.CopyWithTar with invalid src path should throw an error.") + } +} + +func TestCopyFileWithTarInexistentDestWillCreateIt(t *testing.T) { + tempFolder, err := ioutil.TempDir("", "docker-archive-test") + if err != nil { + t.Fatal(nil) + } + defer os.RemoveAll(tempFolder) + srcFile := path.Join(tempFolder, "src") + inexistentDestFolder := path.Join(tempFolder, "doesnotexists") + _, err = os.Create(srcFile) + if err != nil { + t.Fatal(err) + } + err = CopyFileWithTar(srcFile, inexistentDestFolder) + if err != nil { + t.Fatalf("CopyWithTar with an inexistent folder shouldn't fail.") + } + _, err = os.Stat(inexistentDestFolder) + if err != nil { + t.Fatalf("CopyWithTar with an inexistent folder should create it.") + } + // FIXME Test the src file and content +} + +func TestCopyFileWithTarSrcFolder(t *testing.T) { + folder, err := ioutil.TempDir("", "docker-archive-copyfilewithtar-test") + if err != nil { + t.Fatal(err) + } + defer os.RemoveAll(folder) + dest := path.Join(folder, "dest") + src := path.Join(folder, "srcfolder") + err = os.MkdirAll(src, 0740) + if err != nil { + t.Fatal(err) + } + err = os.MkdirAll(dest, 0740) + if err != nil { + t.Fatal(err) + } + err = CopyFileWithTar(src, dest) + if err == nil { + t.Fatalf("CopyFileWithTar should throw an error with a folder.") + } +} + +func TestCopyFileWithTarSrcFile(t *testing.T) { + folder, err := ioutil.TempDir("", "docker-archive-test") + if err != nil { + t.Fatal(err) + } + defer os.RemoveAll(folder) + dest := path.Join(folder, "dest") + srcFolder := path.Join(folder, "src") + src := path.Join(folder, path.Join("src", "src")) + err = os.MkdirAll(srcFolder, 0740) + if err != nil { + t.Fatal(err) + } + err = os.MkdirAll(dest, 0740) + if err != nil { + t.Fatal(err) + } + ioutil.WriteFile(src, []byte("content"), 0777) + err = CopyWithTar(src, dest+"/") + if err != nil { + t.Fatalf("archiver.CopyFileWithTar shouldn't throw an error, %s.", err) + } + _, err = os.Stat(dest) + if err != nil { + t.Fatalf("Destination folder should contain the source file but did not.") + } +} + func TestTarFiles(t *testing.T) { // try without hardlinks if err := checkNoChanges(1000, false); err != nil { diff --git a/pkg/archive/changes_test.go b/pkg/archive/changes_test.go index 53ec575b6..290b2dd40 100644 --- a/pkg/archive/changes_test.go +++ b/pkg/archive/changes_test.go @@ -6,6 +6,7 @@ import ( "os/exec" "path" "sort" + "syscall" "testing" "time" ) @@ -91,17 +92,130 @@ func createSampleDir(t *testing.T, root string) { } } +func TestChangeString(t *testing.T) { + modifiyChange := Change{"change", ChangeModify} + toString := modifiyChange.String() + if toString != "C change" { + t.Fatalf("String() of a change with ChangeModifiy Kind should have been %s but was %s", "C change", toString) + } + addChange := Change{"change", ChangeAdd} + toString = addChange.String() + if toString != "A change" { + t.Fatalf("String() of a change with ChangeAdd Kind should have been %s but was %s", "A change", toString) + } + deleteChange := Change{"change", ChangeDelete} + toString = deleteChange.String() + if toString != "D change" { + t.Fatalf("String() of a change with ChangeDelete Kind should have been %s but was %s", "D change", toString) + } +} + +func TestChangesWithNoChanges(t *testing.T) { + rwLayer, err := ioutil.TempDir("", "docker-changes-test") + if err != nil { + t.Fatal(err) + } + defer os.RemoveAll(rwLayer) + layer, err := ioutil.TempDir("", "docker-changes-test-layer") + if err != nil { + t.Fatal(err) + } + defer os.RemoveAll(layer) + createSampleDir(t, layer) + changes, err := Changes([]string{layer}, rwLayer) + if err != nil { + t.Fatal(err) + } + if len(changes) != 0 { + t.Fatalf("Changes with no difference should have detect no changes, but detected %d", len(changes)) + } +} + +func TestChangesWithChanges(t *testing.T) { + rwLayer, err := ioutil.TempDir("", "docker-changes-test") + if err != nil { + t.Fatal(err) + } + defer os.RemoveAll(rwLayer) + // Create a folder + dir1 := path.Join(rwLayer, "dir1") + os.MkdirAll(dir1, 0740) + deletedFile := path.Join(dir1, ".wh.file1-2") + ioutil.WriteFile(deletedFile, []byte{}, 0600) + modifiedFile := path.Join(dir1, "file1-1") + ioutil.WriteFile(modifiedFile, []byte{0x00}, 01444) + // Let's add a subfolder for a newFile + subfolder := path.Join(dir1, "subfolder") + os.MkdirAll(subfolder, 0740) + newFile := path.Join(subfolder, "newFile") + ioutil.WriteFile(newFile, []byte{}, 0740) + // Let's create folders that with have the role of layers with the same data + layer, err := ioutil.TempDir("", "docker-changes-test-layer") + if err != nil { + t.Fatal(err) + } + defer os.RemoveAll(layer) + createSampleDir(t, layer) + os.MkdirAll(path.Join(layer, "dir1/subfolder"), 0740) + + // Let's modify modtime for dir1 to be sure it's the same for the two layer (to not having false positive) + fi, err := os.Stat(dir1) + if err != nil { + return + } + mtime := fi.ModTime() + stat := fi.Sys().(*syscall.Stat_t) + atime := time.Unix(int64(stat.Atim.Sec), int64(stat.Atim.Nsec)) + + layerDir1 := path.Join(layer, "dir1") + os.Chtimes(layerDir1, atime, mtime) + + changes, err := Changes([]string{layer}, rwLayer) + if err != nil { + t.Fatal(err) + } + + sort.Sort(changesByPath(changes)) + + expectedChanges := []Change{ + {"/dir1/file1-1", ChangeModify}, + {"/dir1/file1-2", ChangeDelete}, + {"/dir1/subfolder", ChangeModify}, + {"/dir1/subfolder/newFile", ChangeAdd}, + } + + for i := 0; i < max(len(changes), len(expectedChanges)); i++ { + if i >= len(expectedChanges) { + t.Fatalf("unexpected change %s\n", changes[i].String()) + } + if i >= len(changes) { + t.Fatalf("no change for expected change %s\n", expectedChanges[i].String()) + } + if changes[i].Path == expectedChanges[i].Path { + if changes[i] != expectedChanges[i] { + t.Fatalf("Wrong change for %s, expected %s, got %s\n", changes[i].Path, changes[i].String(), expectedChanges[i].String()) + } + } else if changes[i].Path < expectedChanges[i].Path { + t.Fatalf("unexpected change %s\n", changes[i].String()) + } else { + t.Fatalf("no change for expected change %s != %s\n", expectedChanges[i].String(), changes[i].String()) + } + } +} + // Create an directory, copy it, make sure we report no changes between the two func TestChangesDirsEmpty(t *testing.T) { src, err := ioutil.TempDir("", "docker-changes-test") if err != nil { t.Fatal(err) } + defer os.RemoveAll(src) createSampleDir(t, src) dst := src + "-copy" if err := copyDir(src, dst); err != nil { t.Fatal(err) } + defer os.RemoveAll(dst) changes, err := ChangesDirs(dst, src) if err != nil { t.Fatal(err) @@ -291,3 +405,41 @@ func TestApplyLayer(t *testing.T) { t.Fatalf("Unexpected differences after reapplying mutation: %v", changes2) } } + +func TestChangesSizeWithNoChanges(t *testing.T) { + size := ChangesSize("/tmp", nil) + if size != 0 { + t.Fatalf("ChangesSizes with no changes should be 0, was %d", size) + } +} + +func TestChangesSizeWithOnlyDeleteChanges(t *testing.T) { + changes := []Change{ + {Path: "deletedPath", Kind: ChangeDelete}, + } + size := ChangesSize("/tmp", changes) + if size != 0 { + t.Fatalf("ChangesSizes with only delete changes should be 0, was %d", size) + } +} + +func TestChangesSize(t *testing.T) { + parentPath, err := ioutil.TempDir("", "docker-changes-test") + defer os.RemoveAll(parentPath) + addition := path.Join(parentPath, "addition") + if err := ioutil.WriteFile(addition, []byte{0x01, 0x01, 0x01}, 0744); err != nil { + t.Fatal(err) + } + modification := path.Join(parentPath, "modification") + if err = ioutil.WriteFile(modification, []byte{0x01, 0x01, 0x01}, 0744); err != nil { + t.Fatal(err) + } + changes := []Change{ + {Path: "addition", Kind: ChangeAdd}, + {Path: "modification", Kind: ChangeModify}, + } + size := ChangesSize(parentPath, changes) + if size != 6 { + t.Fatalf("ChangesSizes with only delete changes should be 0, was %d", size) + } +} diff --git a/pkg/archive/wrap_test.go b/pkg/archive/wrap_test.go new file mode 100644 index 000000000..46ab36697 --- /dev/null +++ b/pkg/archive/wrap_test.go @@ -0,0 +1,98 @@ +package archive + +import ( + "archive/tar" + "bytes" + "io" + "testing" +) + +func TestGenerateEmptyFile(t *testing.T) { + archive, err := Generate("emptyFile") + if err != nil { + t.Fatal(err) + } + if archive == nil { + t.Fatal("The generated archive should not be nil.") + } + + expectedFiles := [][]string{ + {"emptyFile", ""}, + } + + tr := tar.NewReader(archive) + actualFiles := make([][]string, 0, 10) + i := 0 + for { + hdr, err := tr.Next() + if err == io.EOF { + break + } + if err != nil { + t.Fatal(err) + } + buf := new(bytes.Buffer) + buf.ReadFrom(tr) + content := buf.String() + actualFiles = append(actualFiles, []string{hdr.Name, content}) + i++ + } + if len(actualFiles) != len(expectedFiles) { + t.Fatalf("Number of expected file %d, got %d.", len(expectedFiles), len(actualFiles)) + } + for i := 0; i < len(expectedFiles); i++ { + actual := actualFiles[i] + expected := expectedFiles[i] + if actual[0] != expected[0] { + t.Fatalf("Expected name '%s', Actual name '%s'", expected[0], actual[0]) + } + if actual[1] != expected[1] { + t.Fatalf("Expected content '%s', Actual content '%s'", expected[1], actual[1]) + } + } +} + +func TestGenerateWithContent(t *testing.T) { + archive, err := Generate("file", "content") + if err != nil { + t.Fatal(err) + } + if archive == nil { + t.Fatal("The generated archive should not be nil.") + } + + expectedFiles := [][]string{ + {"file", "content"}, + } + + tr := tar.NewReader(archive) + actualFiles := make([][]string, 0, 10) + i := 0 + for { + hdr, err := tr.Next() + if err == io.EOF { + break + } + if err != nil { + t.Fatal(err) + } + buf := new(bytes.Buffer) + buf.ReadFrom(tr) + content := buf.String() + actualFiles = append(actualFiles, []string{hdr.Name, content}) + i++ + } + if len(actualFiles) != len(expectedFiles) { + t.Fatalf("Number of expected file %d, got %d.", len(expectedFiles), len(actualFiles)) + } + for i := 0; i < len(expectedFiles); i++ { + actual := actualFiles[i] + expected := expectedFiles[i] + if actual[0] != expected[0] { + t.Fatalf("Expected name '%s', Actual name '%s'", expected[0], actual[0]) + } + if actual[1] != expected[1] { + t.Fatalf("Expected content '%s', Actual content '%s'", expected[1], actual[1]) + } + } +} From 36fbf4b86469ca6fe3677d47c9a1976bcdd111e4 Mon Sep 17 00:00:00 2001 From: David Calavera Date: Fri, 17 Apr 2015 15:30:22 -0700 Subject: [PATCH 10/58] Shallow clone using git to build images. Signed-off-by: David Calavera --- builder/job.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/builder/job.go b/builder/job.go index 115d89a4b..7ea1ae30b 100644 --- a/builder/job.go +++ b/builder/job.go @@ -114,7 +114,7 @@ func Build(d *daemon.Daemon, buildConfig *Config) error { } defer os.RemoveAll(root) - if output, err := exec.Command("git", "clone", "--recursive", buildConfig.RemoteURL, root).CombinedOutput(); err != nil { + if output, err := exec.Command("git", "clone", "--depth", "1", "--recursive", buildConfig.RemoteURL, root).CombinedOutput(); err != nil { return fmt.Errorf("Error trying to use git: %s (%s)", err, output) } From 9fb7204a41804131c2492f9d50d7451e123a05e5 Mon Sep 17 00:00:00 2001 From: David Calavera Date: Tue, 21 Apr 2015 10:58:38 -0700 Subject: [PATCH 11/58] Do not try to shallow git history when the protocol doesn't allow it. This only happens with the old git http dumb protocol, but that's what we use in our integration tests. We check the Content-Type header advertised in http requests to make sure the http transport is the git smart transport: See this commit as a reference: https://github.com/git/git/commit/4656bf47fca857df51b5d6f4b7b052192b3b2317 Signed-off-by: David Calavera --- builder/job.go | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/builder/job.go b/builder/job.go index 7ea1ae30b..8c031a8bd 100644 --- a/builder/job.go +++ b/builder/job.go @@ -5,6 +5,7 @@ import ( "fmt" "io" "io/ioutil" + "net/http" "os" "os/exec" "strings" @@ -114,7 +115,9 @@ func Build(d *daemon.Daemon, buildConfig *Config) error { } defer os.RemoveAll(root) - if output, err := exec.Command("git", "clone", "--depth", "1", "--recursive", buildConfig.RemoteURL, root).CombinedOutput(); err != nil { + clone := cloneArgs(buildConfig.RemoteURL, root) + + if output, err := exec.Command("git", clone...).CombinedOutput(); err != nil { return fmt.Errorf("Error trying to use git: %s (%s)", err, output) } @@ -239,3 +242,21 @@ func Commit(d *daemon.Daemon, name string, c *daemon.ContainerCommitConfig) (str return img.ID, nil } + +func cloneArgs(remoteURL, root string) []string { + args := []string{"clone", "--recursive"} + shallow := true + + if strings.HasPrefix(remoteURL, "http") { + res, err := http.Head(fmt.Sprintf("%s/info/refs?service=git-upload-pack", remoteURL)) + if err != nil || res.Header.Get("Content-Type") != "application/x-git-upload-pack-advertisement" { + shallow = false + } + } + + if shallow { + args = append(args, "--depth", "1") + } + + return append(args, remoteURL, root) +} From 3117bf3ef562bc43ef007d8afe3815c58aac6e85 Mon Sep 17 00:00:00 2001 From: David Calavera Date: Tue, 21 Apr 2015 14:24:29 -0700 Subject: [PATCH 12/58] Test that we set the right arguments for git cloning depending on the transport. Signed-off-by: David Calavera --- builder/job_test.go | 56 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 builder/job_test.go diff --git a/builder/job_test.go b/builder/job_test.go new file mode 100644 index 000000000..79421a068 --- /dev/null +++ b/builder/job_test.go @@ -0,0 +1,56 @@ +package builder + +import ( + "fmt" + "net/http" + "net/http/httptest" + "net/url" + "reflect" + "testing" +) + +func TestCloneArgsSmartHttp(t *testing.T) { + mux := http.NewServeMux() + server := httptest.NewServer(mux) + serverURL, _ := url.Parse(server.URL) + + serverURL.Path = "/repo.git" + gitURL := serverURL.String() + + mux.HandleFunc("/repo.git/info/refs", func(w http.ResponseWriter, r *http.Request) { + q := r.URL.Query().Get("service") + w.Header().Set("Content-Type", fmt.Sprintf("application/x-%s-advertisement", q)) + }) + + args := cloneArgs(gitURL, "/tmp") + exp := []string{"clone", "--recursive", "--depth", "1", gitURL, "/tmp"} + if !reflect.DeepEqual(args, exp) { + t.Fatalf("Expected %v, got %v", exp, args) + } +} + +func TestCloneArgsDumbHttp(t *testing.T) { + mux := http.NewServeMux() + server := httptest.NewServer(mux) + serverURL, _ := url.Parse(server.URL) + + serverURL.Path = "/repo.git" + gitURL := serverURL.String() + + mux.HandleFunc("/repo.git/info/refs", func(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "text/plain") + }) + + args := cloneArgs(gitURL, "/tmp") + exp := []string{"clone", "--recursive", gitURL, "/tmp"} + if !reflect.DeepEqual(args, exp) { + t.Fatalf("Expected %v, got %v", exp, args) + } +} +func TestCloneArgsGit(t *testing.T) { + args := cloneArgs("git://github.com/docker/docker", "/tmp") + exp := []string{"clone", "--recursive", "--depth", "1", "git://github.com/docker/docker", "/tmp"} + if !reflect.DeepEqual(args, exp) { + t.Fatalf("Expected %v, got %v", exp, args) + } +} From 8bd5a95e1e39541dfc5dc635c5c8e7604fe10028 Mon Sep 17 00:00:00 2001 From: David Calavera Date: Thu, 23 Apr 2015 09:35:19 -0700 Subject: [PATCH 13/58] Document the extra `depth` argument in git contexts. Signed-off-by: David Calavera --- docs/sources/reference/commandline/cli.md | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/docs/sources/reference/commandline/cli.md b/docs/sources/reference/commandline/cli.md index a87116204..26659c8ff 100644 --- a/docs/sources/reference/commandline/cli.md +++ b/docs/sources/reference/commandline/cli.md @@ -636,12 +636,13 @@ refer to any of the files in the context. For example, your build can use an [*ADD*](/reference/builder/#add) instruction to reference a file in the context. -The `URL` parameter can specify the location of a Git repository; in this -case, the repository is the context. The Git repository is recursively -cloned with its submodules. The system does a fresh `git clone -recursive` -in a temporary directory on your local host. Then, this clone is sent to -the Docker daemon as the context. Local clones give you the ability to -access private repositories using local user credentials, VPN's, and so forth. +The `URL` parameter can specify the location of a Git repository; +the repository acts as the build context. The system recursively clones the repository +and its submodules using a `git clone --depth 1 --recursive` command. +This command runs in a temporary directory on your local host. +After the command succeeds, the directory is sent to the Docker daemon as the context. +Local clones give you the ability to access private repositories using +local user credentials, VPN's, and so forth. Instead of specifying a context, you can pass a single Dockerfile in the `URL` or pipe the file in via `STDIN`. To pipe a Dockerfile from `STDIN`: From 1cfb307d70558110e8e88a7391ae0e6cf6ebf174 Mon Sep 17 00:00:00 2001 From: David Calavera Date: Thu, 23 Apr 2015 10:19:34 -0700 Subject: [PATCH 14/58] Remove duplicated git clone logic. Signed-off-by: David Calavera --- api/client/build.go | 11 +----- builder/job.go | 32 +--------------- utils/git.go | 47 ++++++++++++++++++++++++ builder/job_test.go => utils/git_test.go | 2 +- 4 files changed, 51 insertions(+), 41 deletions(-) create mode 100644 utils/git.go rename builder/job_test.go => utils/git_test.go (98%) diff --git a/api/client/build.go b/api/client/build.go index 63cc63bc9..eb39058b6 100644 --- a/api/client/build.go +++ b/api/client/build.go @@ -95,20 +95,11 @@ func (cli *DockerCli) CmdBuild(args ...string) error { } else { root := cmd.Arg(0) if urlutil.IsGitURL(root) { - remoteURL := cmd.Arg(0) - if !urlutil.IsGitTransport(remoteURL) { - remoteURL = "https://" + remoteURL - } - - root, err = ioutil.TempDir("", "docker-build-git") + root, err = utils.GitClone(root) if err != nil { return err } defer os.RemoveAll(root) - - if output, err := exec.Command("git", "clone", "--recursive", remoteURL, root).CombinedOutput(); err != nil { - return fmt.Errorf("Error trying to use git: %s (%s)", err, output) - } } if _, err := os.Stat(root); err != nil { return err diff --git a/builder/job.go b/builder/job.go index 8c031a8bd..7991cba21 100644 --- a/builder/job.go +++ b/builder/job.go @@ -5,9 +5,7 @@ import ( "fmt" "io" "io/ioutil" - "net/http" "os" - "os/exec" "strings" "sync" @@ -23,6 +21,7 @@ import ( "github.com/docker/docker/pkg/urlutil" "github.com/docker/docker/registry" "github.com/docker/docker/runconfig" + "github.com/docker/docker/utils" ) // whitelist of commands allowed for a commit/import @@ -106,21 +105,12 @@ func Build(d *daemon.Daemon, buildConfig *Config) error { if buildConfig.RemoteURL == "" { context = ioutil.NopCloser(buildConfig.Context) } else if urlutil.IsGitURL(buildConfig.RemoteURL) { - if !urlutil.IsGitTransport(buildConfig.RemoteURL) { - buildConfig.RemoteURL = "https://" + buildConfig.RemoteURL - } - root, err := ioutil.TempDir("", "docker-build-git") + root, err := utils.GitClone(buildConfig.RemoteURL) if err != nil { return err } defer os.RemoveAll(root) - clone := cloneArgs(buildConfig.RemoteURL, root) - - if output, err := exec.Command("git", clone...).CombinedOutput(); err != nil { - return fmt.Errorf("Error trying to use git: %s (%s)", err, output) - } - c, err := archive.Tar(root, archive.Uncompressed) if err != nil { return err @@ -242,21 +232,3 @@ func Commit(d *daemon.Daemon, name string, c *daemon.ContainerCommitConfig) (str return img.ID, nil } - -func cloneArgs(remoteURL, root string) []string { - args := []string{"clone", "--recursive"} - shallow := true - - if strings.HasPrefix(remoteURL, "http") { - res, err := http.Head(fmt.Sprintf("%s/info/refs?service=git-upload-pack", remoteURL)) - if err != nil || res.Header.Get("Content-Type") != "application/x-git-upload-pack-advertisement" { - shallow = false - } - } - - if shallow { - args = append(args, "--depth", "1") - } - - return append(args, remoteURL, root) -} diff --git a/utils/git.go b/utils/git.go new file mode 100644 index 000000000..18e002d18 --- /dev/null +++ b/utils/git.go @@ -0,0 +1,47 @@ +package utils + +import ( + "fmt" + "io/ioutil" + "net/http" + "os/exec" + "strings" + + "github.com/docker/docker/pkg/urlutil" +) + +func GitClone(remoteURL string) (string, error) { + if !urlutil.IsGitTransport(remoteURL) { + remoteURL = "https://" + remoteURL + } + root, err := ioutil.TempDir("", "docker-build-git") + if err != nil { + return "", err + } + + clone := cloneArgs(remoteURL, root) + + if output, err := exec.Command("git", clone...).CombinedOutput(); err != nil { + return "", fmt.Errorf("Error trying to use git: %s (%s)", err, output) + } + + return root, nil +} + +func cloneArgs(remoteURL, root string) []string { + args := []string{"clone", "--recursive"} + shallow := true + + if strings.HasPrefix(remoteURL, "http") { + res, err := http.Head(fmt.Sprintf("%s/info/refs?service=git-upload-pack", remoteURL)) + if err != nil || res.Header.Get("Content-Type") != "application/x-git-upload-pack-advertisement" { + shallow = false + } + } + + if shallow { + args = append(args, "--depth", "1") + } + + return append(args, remoteURL, root) +} diff --git a/builder/job_test.go b/utils/git_test.go similarity index 98% rename from builder/job_test.go rename to utils/git_test.go index 79421a068..a82841ae1 100644 --- a/builder/job_test.go +++ b/utils/git_test.go @@ -1,4 +1,4 @@ -package builder +package utils import ( "fmt" From a9688cdca5577d6db65d76f38bcbe4c1e6f5994f Mon Sep 17 00:00:00 2001 From: Alexander Morozov Date: Thu, 23 Apr 2015 14:39:31 -0700 Subject: [PATCH 15/58] Implement teardown removeAllImages Signed-off-by: Alexander Morozov --- integration-cli/check_test.go | 1 + integration-cli/docker_api_containers_test.go | 1 - integration-cli/docker_api_images_test.go | 2 - integration-cli/docker_cli_build_test.go | 186 ------------------ integration-cli/docker_cli_by_digest_test.go | 8 - integration-cli/docker_cli_commit_test.go | 16 -- integration-cli/docker_cli_create_test.go | 1 - integration-cli/docker_cli_events_test.go | 3 - .../docker_cli_export_import_test.go | 4 - integration-cli/docker_cli_history_test.go | 2 - integration-cli/docker_cli_images_test.go | 9 - integration-cli/docker_cli_import_test.go | 1 - integration-cli/docker_cli_ps_test.go | 1 - integration-cli/docker_cli_pull_test.go | 5 - integration-cli/docker_cli_push_test.go | 4 - integration-cli/docker_cli_rm_test.go | 1 - integration-cli/docker_cli_run_test.go | 8 - integration-cli/docker_cli_save_load_test.go | 7 - integration-cli/docker_cli_tag_test.go | 10 - integration-cli/docker_utils.go | 49 +++++ 20 files changed, 50 insertions(+), 269 deletions(-) diff --git a/integration-cli/check_test.go b/integration-cli/check_test.go index 07bb93159..f6dbdb8a9 100644 --- a/integration-cli/check_test.go +++ b/integration-cli/check_test.go @@ -30,6 +30,7 @@ type DockerSuite struct { func (s *DockerSuite) TearDownTest(c *check.C) { deleteAllContainers() + deleteAllImages() s.TimerSuite.TearDownTest(c) } diff --git a/integration-cli/docker_api_containers_test.go b/integration-cli/docker_api_containers_test.go index 24efbb7a2..f14bd91c1 100644 --- a/integration-cli/docker_api_containers_test.go +++ b/integration-cli/docker_api_containers_test.go @@ -632,7 +632,6 @@ func (s *DockerSuite) TestContainerApiCommit(c *check.C) { if err := json.Unmarshal(b, &img); err != nil { c.Fatal(err) } - defer deleteImages(img.Id) cmd, err := inspectField(img.Id, "Config.Cmd") if err != nil { diff --git a/integration-cli/docker_api_images_test.go b/integration-cli/docker_api_images_test.go index a0f029d40..ac3ad55d7 100644 --- a/integration-cli/docker_api_images_test.go +++ b/integration-cli/docker_api_images_test.go @@ -30,7 +30,6 @@ func (s *DockerSuite) TestApiImagesFilter(c *check.C) { name := "utest:tag1" name2 := "utest/docker:tag2" name3 := "utest:5000/docker:tag3" - defer deleteImages(name, name2, name3) for _, n := range []string{name, name2, name3} { if out, err := exec.Command(dockerBinary, "tag", "busybox", n).CombinedOutput(); err != nil { c.Fatal(err, out) @@ -74,7 +73,6 @@ func (s *DockerSuite) TestApiImagesSaveAndLoad(c *check.C) { c.Fatal(err) } id := strings.TrimSpace(out) - defer deleteImages("saveandload") status, body, err := sockRequestRaw("GET", "/images/"+id+"/get", nil, "") c.Assert(status, check.Equals, http.StatusOK) diff --git a/integration-cli/docker_cli_build_test.go b/integration-cli/docker_cli_build_test.go index 72d15c177..6d6805aef 100644 --- a/integration-cli/docker_cli_build_test.go +++ b/integration-cli/docker_cli_build_test.go @@ -27,7 +27,6 @@ import ( func (s *DockerSuite) TestBuildJSONEmptyRun(c *check.C) { name := "testbuildjsonemptyrun" - defer deleteImages(name) _, err := buildImage( name, @@ -45,7 +44,6 @@ func (s *DockerSuite) TestBuildJSONEmptyRun(c *check.C) { func (s *DockerSuite) TestBuildEmptyWhitespace(c *check.C) { name := "testbuildemptywhitespace" - defer deleteImages(name) _, err := buildImage( name, @@ -65,7 +63,6 @@ func (s *DockerSuite) TestBuildEmptyWhitespace(c *check.C) { func (s *DockerSuite) TestBuildShCmdJSONEntrypoint(c *check.C) { name := "testbuildshcmdjsonentrypoint" - defer deleteImages(name) _, err := buildImage( name, @@ -99,7 +96,6 @@ func (s *DockerSuite) TestBuildShCmdJSONEntrypoint(c *check.C) { func (s *DockerSuite) TestBuildEnvironmentReplacementUser(c *check.C) { name := "testbuildenvironmentreplacement" - defer deleteImages(name) _, err := buildImage(name, ` FROM scratch @@ -123,7 +119,6 @@ func (s *DockerSuite) TestBuildEnvironmentReplacementUser(c *check.C) { func (s *DockerSuite) TestBuildEnvironmentReplacementVolume(c *check.C) { name := "testbuildenvironmentreplacement" - defer deleteImages(name) _, err := buildImage(name, ` FROM scratch @@ -153,7 +148,6 @@ func (s *DockerSuite) TestBuildEnvironmentReplacementVolume(c *check.C) { func (s *DockerSuite) TestBuildEnvironmentReplacementExpose(c *check.C) { name := "testbuildenvironmentreplacement" - defer deleteImages(name) _, err := buildImage(name, ` FROM scratch @@ -183,7 +177,6 @@ func (s *DockerSuite) TestBuildEnvironmentReplacementExpose(c *check.C) { func (s *DockerSuite) TestBuildEnvironmentReplacementWorkdir(c *check.C) { name := "testbuildenvironmentreplacement" - defer deleteImages(name) _, err := buildImage(name, ` FROM busybox @@ -200,7 +193,6 @@ func (s *DockerSuite) TestBuildEnvironmentReplacementWorkdir(c *check.C) { func (s *DockerSuite) TestBuildEnvironmentReplacementAddCopy(c *check.C) { name := "testbuildenvironmentreplacement" - defer deleteImages(name) ctx, err := fakeContext(` FROM scratch @@ -236,8 +228,6 @@ func (s *DockerSuite) TestBuildEnvironmentReplacementAddCopy(c *check.C) { func (s *DockerSuite) TestBuildEnvironmentReplacementEnv(c *check.C) { name := "testbuildenvironmentreplacement" - defer deleteImages(name) - _, err := buildImage(name, ` FROM busybox @@ -305,8 +295,6 @@ func (s *DockerSuite) TestBuildEnvironmentReplacementEnv(c *check.C) { func (s *DockerSuite) TestBuildHandleEscapes(c *check.C) { name := "testbuildhandleescapes" - defer deleteImages(name) - _, err := buildImage(name, ` FROM scratch @@ -395,8 +383,6 @@ func (s *DockerSuite) TestBuildOnBuildLowercase(c *check.C) { name := "testbuildonbuildlowercase" name2 := "testbuildonbuildlowercase2" - defer deleteImages(name, name2) - _, err := buildImage(name, ` FROM busybox @@ -427,7 +413,6 @@ func (s *DockerSuite) TestBuildOnBuildLowercase(c *check.C) { func (s *DockerSuite) TestBuildEnvEscapes(c *check.C) { name := "testbuildenvescapes" - defer deleteImages(name) _, err := buildImage(name, ` FROM busybox @@ -450,7 +435,6 @@ func (s *DockerSuite) TestBuildEnvEscapes(c *check.C) { func (s *DockerSuite) TestBuildEnvOverwrite(c *check.C) { name := "testbuildenvoverwrite" - defer deleteImages(name) _, err := buildImage(name, ` @@ -478,8 +462,6 @@ func (s *DockerSuite) TestBuildEnvOverwrite(c *check.C) { func (s *DockerSuite) TestBuildOnBuildForbiddenMaintainerInSourceImage(c *check.C) { name := "testbuildonbuildforbiddenmaintainerinsourceimage" - defer deleteImages("onbuild") - defer deleteImages(name) createCmd := exec.Command(dockerBinary, "create", "busybox", "true") out, _, _, err := runCommandWithStdoutStderr(createCmd) @@ -510,8 +492,6 @@ func (s *DockerSuite) TestBuildOnBuildForbiddenMaintainerInSourceImage(c *check. func (s *DockerSuite) TestBuildOnBuildForbiddenFromInSourceImage(c *check.C) { name := "testbuildonbuildforbiddenfrominsourceimage" - defer deleteImages("onbuild") - defer deleteImages(name) createCmd := exec.Command(dockerBinary, "create", "busybox", "true") out, _, _, err := runCommandWithStdoutStderr(createCmd) @@ -542,8 +522,6 @@ func (s *DockerSuite) TestBuildOnBuildForbiddenFromInSourceImage(c *check.C) { func (s *DockerSuite) TestBuildOnBuildForbiddenChainedInSourceImage(c *check.C) { name := "testbuildonbuildforbiddenchainedinsourceimage" - defer deleteImages("onbuild") - defer deleteImages(name) createCmd := exec.Command(dockerBinary, "create", "busybox", "true") out, _, _, err := runCommandWithStdoutStderr(createCmd) @@ -576,9 +554,6 @@ func (s *DockerSuite) TestBuildOnBuildCmdEntrypointJSON(c *check.C) { name1 := "onbuildcmd" name2 := "onbuildgenerated" - defer deleteImages(name2) - defer deleteImages(name1) - _, err := buildImage(name1, ` FROM busybox ONBUILD CMD ["hello world"] @@ -611,9 +586,6 @@ func (s *DockerSuite) TestBuildOnBuildEntrypointJSON(c *check.C) { name1 := "onbuildcmd" name2 := "onbuildgenerated" - defer deleteImages(name2) - defer deleteImages(name1) - _, err := buildImage(name1, ` FROM busybox ONBUILD ENTRYPOINT ["echo"]`, @@ -642,7 +614,6 @@ ONBUILD ENTRYPOINT ["echo"]`, func (s *DockerSuite) TestBuildCacheADD(c *check.C) { name := "testbuildtwoimageswithadd" - defer deleteImages(name) server, err := fakeStorage(map[string]string{ "robots.txt": "hello", "index.html": "world", @@ -677,7 +648,6 @@ func (s *DockerSuite) TestBuildCacheADD(c *check.C) { func (s *DockerSuite) TestBuildLastModified(c *check.C) { name := "testbuildlastmodified" - defer deleteImages(name) server, err := fakeStorage(map[string]string{ "file": "hello", @@ -743,7 +713,6 @@ RUN ls -le /file` func (s *DockerSuite) TestBuildSixtySteps(c *check.C) { name := "foobuildsixtysteps" - defer deleteImages(name) ctx, err := fakeContext("FROM scratch\n"+strings.Repeat("ADD foo /\n", 60), map[string]string{ "foo": "test1", @@ -760,7 +729,6 @@ func (s *DockerSuite) TestBuildSixtySteps(c *check.C) { func (s *DockerSuite) TestBuildAddSingleFileToRoot(c *check.C) { name := "testaddimg" - defer deleteImages(name) ctx, err := fakeContext(fmt.Sprintf(`FROM busybox RUN echo 'dockerio:x:1001:1001::/bin:/bin/false' >> /etc/passwd RUN echo 'dockerio:x:1001:' >> /etc/group @@ -786,7 +754,6 @@ RUN [ $(ls -l /exists | awk '{print $3":"$4}') = 'dockerio:dockerio' ]`, expecte // Issue #3960: "ADD src ." hangs func (s *DockerSuite) TestBuildAddSingleFileToWorkdir(c *check.C) { name := "testaddsinglefiletoworkdir" - defer deleteImages(name) ctx, err := fakeContext(`FROM busybox ADD test_file .`, map[string]string{ @@ -813,7 +780,6 @@ ADD test_file .`, func (s *DockerSuite) TestBuildAddSingleFileToExistDir(c *check.C) { name := "testaddsinglefiletoexistdir" - defer deleteImages(name) ctx, err := fakeContext(`FROM busybox RUN echo 'dockerio:x:1001:1001::/bin:/bin/false' >> /etc/passwd RUN echo 'dockerio:x:1001:' >> /etc/group @@ -847,7 +813,6 @@ func (s *DockerSuite) TestBuildCopyAddMultipleFiles(c *check.C) { defer server.Close() name := "testcopymultiplefilestofile" - defer deleteImages(name) ctx, err := fakeContext(fmt.Sprintf(`FROM busybox RUN echo 'dockerio:x:1001:1001::/bin:/bin/false' >> /etc/passwd RUN echo 'dockerio:x:1001:' >> /etc/group @@ -884,7 +849,6 @@ RUN [ $(ls -l /exists/exists_file | awk '{print $3":"$4}') = 'dockerio:dockerio' func (s *DockerSuite) TestBuildAddMultipleFilesToFile(c *check.C) { name := "testaddmultiplefilestofile" - defer deleteImages(name) ctx, err := fakeContext(`FROM scratch ADD file1.txt file2.txt test `, @@ -906,7 +870,6 @@ func (s *DockerSuite) TestBuildAddMultipleFilesToFile(c *check.C) { func (s *DockerSuite) TestBuildJSONAddMultipleFilesToFile(c *check.C) { name := "testjsonaddmultiplefilestofile" - defer deleteImages(name) ctx, err := fakeContext(`FROM scratch ADD ["file1.txt", "file2.txt", "test"] `, @@ -928,7 +891,6 @@ func (s *DockerSuite) TestBuildJSONAddMultipleFilesToFile(c *check.C) { func (s *DockerSuite) TestBuildAddMultipleFilesToFileWild(c *check.C) { name := "testaddmultiplefilestofilewild" - defer deleteImages(name) ctx, err := fakeContext(`FROM scratch ADD file*.txt test `, @@ -950,7 +912,6 @@ func (s *DockerSuite) TestBuildAddMultipleFilesToFileWild(c *check.C) { func (s *DockerSuite) TestBuildJSONAddMultipleFilesToFileWild(c *check.C) { name := "testjsonaddmultiplefilestofilewild" - defer deleteImages(name) ctx, err := fakeContext(`FROM scratch ADD ["file*.txt", "test"] `, @@ -972,7 +933,6 @@ func (s *DockerSuite) TestBuildJSONAddMultipleFilesToFileWild(c *check.C) { func (s *DockerSuite) TestBuildCopyMultipleFilesToFile(c *check.C) { name := "testcopymultiplefilestofile" - defer deleteImages(name) ctx, err := fakeContext(`FROM scratch COPY file1.txt file2.txt test `, @@ -994,7 +954,6 @@ func (s *DockerSuite) TestBuildCopyMultipleFilesToFile(c *check.C) { func (s *DockerSuite) TestBuildJSONCopyMultipleFilesToFile(c *check.C) { name := "testjsoncopymultiplefilestofile" - defer deleteImages(name) ctx, err := fakeContext(`FROM scratch COPY ["file1.txt", "file2.txt", "test"] `, @@ -1016,7 +975,6 @@ func (s *DockerSuite) TestBuildJSONCopyMultipleFilesToFile(c *check.C) { func (s *DockerSuite) TestBuildAddFileWithWhitespace(c *check.C) { name := "testaddfilewithwhitespace" - defer deleteImages(name) ctx, err := fakeContext(`FROM busybox RUN mkdir "/test dir" RUN mkdir "/test_dir" @@ -1052,7 +1010,6 @@ RUN [ $(cat "/test dir/test_file6") = 'test6' ]`, func (s *DockerSuite) TestBuildCopyFileWithWhitespace(c *check.C) { name := "testcopyfilewithwhitespace" - defer deleteImages(name) ctx, err := fakeContext(`FROM busybox RUN mkdir "/test dir" RUN mkdir "/test_dir" @@ -1088,7 +1045,6 @@ RUN [ $(cat "/test dir/test_file6") = 'test6' ]`, func (s *DockerSuite) TestBuildAddMultipleFilesToFileWithWhitespace(c *check.C) { name := "testaddmultiplefilestofilewithwhitespace" - defer deleteImages(name) ctx, err := fakeContext(`FROM busybox ADD [ "test file1", "test file2", "test" ] `, @@ -1110,7 +1066,6 @@ func (s *DockerSuite) TestBuildAddMultipleFilesToFileWithWhitespace(c *check.C) func (s *DockerSuite) TestBuildCopyMultipleFilesToFileWithWhitespace(c *check.C) { name := "testcopymultiplefilestofilewithwhitespace" - defer deleteImages(name) ctx, err := fakeContext(`FROM busybox COPY [ "test file1", "test file2", "test" ] `, @@ -1132,7 +1087,6 @@ func (s *DockerSuite) TestBuildCopyMultipleFilesToFileWithWhitespace(c *check.C) func (s *DockerSuite) TestBuildCopyWildcard(c *check.C) { name := "testcopywildcard" - defer deleteImages(name) server, err := fakeStorage(map[string]string{ "robots.txt": "hello", "index.html": "world", @@ -1183,7 +1137,6 @@ func (s *DockerSuite) TestBuildCopyWildcard(c *check.C) { func (s *DockerSuite) TestBuildCopyWildcardNoFind(c *check.C) { name := "testcopywildcardnofind" - defer deleteImages(name) ctx, err := fakeContext(`FROM busybox COPY file*.txt /tmp/ `, nil) @@ -1204,7 +1157,6 @@ func (s *DockerSuite) TestBuildCopyWildcardNoFind(c *check.C) { func (s *DockerSuite) TestBuildCopyWildcardCache(c *check.C) { name := "testcopywildcardcache" - defer deleteImages(name) ctx, err := fakeContext(`FROM busybox COPY file1.txt /tmp/`, map[string]string{ @@ -1238,7 +1190,6 @@ func (s *DockerSuite) TestBuildCopyWildcardCache(c *check.C) { func (s *DockerSuite) TestBuildAddSingleFileToNonExistingDir(c *check.C) { name := "testaddsinglefiletononexistingdir" - defer deleteImages(name) ctx, err := fakeContext(`FROM busybox RUN echo 'dockerio:x:1001:1001::/bin:/bin/false' >> /etc/passwd RUN echo 'dockerio:x:1001:' >> /etc/group @@ -1264,7 +1215,6 @@ RUN [ $(ls -l /exists | awk '{print $3":"$4}') = 'dockerio:dockerio' ]`, func (s *DockerSuite) TestBuildAddDirContentToRoot(c *check.C) { name := "testadddircontenttoroot" - defer deleteImages(name) ctx, err := fakeContext(`FROM busybox RUN echo 'dockerio:x:1001:1001::/bin:/bin/false' >> /etc/passwd RUN echo 'dockerio:x:1001:' >> /etc/group @@ -1288,7 +1238,6 @@ RUN [ $(ls -l /exists | awk '{print $3":"$4}') = 'dockerio:dockerio' ]`, func (s *DockerSuite) TestBuildAddDirContentToExistingDir(c *check.C) { name := "testadddircontenttoexistingdir" - defer deleteImages(name) ctx, err := fakeContext(`FROM busybox RUN echo 'dockerio:x:1001:1001::/bin:/bin/false' >> /etc/passwd RUN echo 'dockerio:x:1001:' >> /etc/group @@ -1314,7 +1263,6 @@ RUN [ $(ls -l /exists/test_file | awk '{print $3":"$4}') = 'root:root' ]`, func (s *DockerSuite) TestBuildAddWholeDirToRoot(c *check.C) { name := "testaddwholedirtoroot" - defer deleteImages(name) ctx, err := fakeContext(fmt.Sprintf(`FROM busybox RUN echo 'dockerio:x:1001:1001::/bin:/bin/false' >> /etc/passwd RUN echo 'dockerio:x:1001:' >> /etc/group @@ -1342,7 +1290,6 @@ RUN [ $(ls -l /exists | awk '{print $3":"$4}') = 'dockerio:dockerio' ]`, expecte // Testing #5941 func (s *DockerSuite) TestBuildAddEtcToRoot(c *check.C) { name := "testaddetctoroot" - defer deleteImages(name) ctx, err := fakeContext(`FROM scratch ADD . /`, map[string]string{ @@ -1361,7 +1308,6 @@ ADD . /`, // Testing #9401 func (s *DockerSuite) TestBuildAddPreservesFilesSpecialBits(c *check.C) { name := "testaddpreservesfilesspecialbits" - defer deleteImages(name) ctx, err := fakeContext(`FROM busybox ADD suidbin /usr/bin/suidbin RUN chmod 4755 /usr/bin/suidbin @@ -1384,7 +1330,6 @@ RUN [ $(ls -l /usr/bin/suidbin | awk '{print $1}') = '-rwsr-xr-x' ]`, func (s *DockerSuite) TestBuildCopySingleFileToRoot(c *check.C) { name := "testcopysinglefiletoroot" - defer deleteImages(name) ctx, err := fakeContext(fmt.Sprintf(`FROM busybox RUN echo 'dockerio:x:1001:1001::/bin:/bin/false' >> /etc/passwd RUN echo 'dockerio:x:1001:' >> /etc/group @@ -1410,7 +1355,6 @@ RUN [ $(ls -l /exists | awk '{print $3":"$4}') = 'dockerio:dockerio' ]`, expecte // Issue #3960: "ADD src ." hangs - adapted for COPY func (s *DockerSuite) TestBuildCopySingleFileToWorkdir(c *check.C) { name := "testcopysinglefiletoworkdir" - defer deleteImages(name) ctx, err := fakeContext(`FROM busybox COPY test_file .`, map[string]string{ @@ -1437,7 +1381,6 @@ COPY test_file .`, func (s *DockerSuite) TestBuildCopySingleFileToExistDir(c *check.C) { name := "testcopysinglefiletoexistdir" - defer deleteImages(name) ctx, err := fakeContext(`FROM busybox RUN echo 'dockerio:x:1001:1001::/bin:/bin/false' >> /etc/passwd RUN echo 'dockerio:x:1001:' >> /etc/group @@ -1463,7 +1406,6 @@ RUN [ $(ls -l /exists/exists_file | awk '{print $3":"$4}') = 'dockerio:dockerio' func (s *DockerSuite) TestBuildCopySingleFileToNonExistDir(c *check.C) { name := "testcopysinglefiletononexistdir" - defer deleteImages(name) ctx, err := fakeContext(`FROM busybox RUN echo 'dockerio:x:1001:1001::/bin:/bin/false' >> /etc/passwd RUN echo 'dockerio:x:1001:' >> /etc/group @@ -1488,7 +1430,6 @@ RUN [ $(ls -l /exists | awk '{print $3":"$4}') = 'dockerio:dockerio' ]`, func (s *DockerSuite) TestBuildCopyDirContentToRoot(c *check.C) { name := "testcopydircontenttoroot" - defer deleteImages(name) ctx, err := fakeContext(`FROM busybox RUN echo 'dockerio:x:1001:1001::/bin:/bin/false' >> /etc/passwd RUN echo 'dockerio:x:1001:' >> /etc/group @@ -1512,7 +1453,6 @@ RUN [ $(ls -l /exists | awk '{print $3":"$4}') = 'dockerio:dockerio' ]`, func (s *DockerSuite) TestBuildCopyDirContentToExistDir(c *check.C) { name := "testcopydircontenttoexistdir" - defer deleteImages(name) ctx, err := fakeContext(`FROM busybox RUN echo 'dockerio:x:1001:1001::/bin:/bin/false' >> /etc/passwd RUN echo 'dockerio:x:1001:' >> /etc/group @@ -1538,7 +1478,6 @@ RUN [ $(ls -l /exists/test_file | awk '{print $3":"$4}') = 'root:root' ]`, func (s *DockerSuite) TestBuildCopyWholeDirToRoot(c *check.C) { name := "testcopywholedirtoroot" - defer deleteImages(name) ctx, err := fakeContext(fmt.Sprintf(`FROM busybox RUN echo 'dockerio:x:1001:1001::/bin:/bin/false' >> /etc/passwd RUN echo 'dockerio:x:1001:' >> /etc/group @@ -1565,7 +1504,6 @@ RUN [ $(ls -l /exists | awk '{print $3":"$4}') = 'dockerio:dockerio' ]`, expecte func (s *DockerSuite) TestBuildCopyEtcToRoot(c *check.C) { name := "testcopyetctoroot" - defer deleteImages(name) ctx, err := fakeContext(`FROM scratch COPY . /`, map[string]string{ @@ -1583,7 +1521,6 @@ COPY . /`, func (s *DockerSuite) TestBuildCopyDisallowRemote(c *check.C) { name := "testcopydisallowremote" - defer deleteImages(name) _, out, err := buildImageWithOut(name, `FROM scratch COPY https://index.docker.io/robots.txt /`, true) @@ -1604,7 +1541,6 @@ func (s *DockerSuite) TestBuildAddBadLinks(c *check.C) { var ( name = "test-link-absolute" ) - defer deleteImages(name) ctx, err := fakeContext(dockerfile, nil) if err != nil { c.Fatal(err) @@ -1692,7 +1628,6 @@ func (s *DockerSuite) TestBuildAddBadLinksVolume(c *check.C) { name = "test-link-absolute-volume" dockerfile = "" ) - defer deleteImages(name) tempDir, err := ioutil.TempDir("", "test-link-absolute-volume-temp-") if err != nil { @@ -1737,7 +1672,6 @@ func (s *DockerSuite) TestBuildWithInaccessibleFilesInContext(c *check.C) { { name := "testbuildinaccessiblefiles" - defer deleteImages(name) ctx, err := fakeContext("FROM scratch\nADD . /foo/", map[string]string{"fileWithoutReadAccess": "foo"}) if err != nil { c.Fatal(err) @@ -1770,7 +1704,6 @@ func (s *DockerSuite) TestBuildWithInaccessibleFilesInContext(c *check.C) { } { name := "testbuildinaccessibledirectory" - defer deleteImages(name) ctx, err := fakeContext("FROM scratch\nADD . /foo/", map[string]string{"directoryWeCantStat/bar": "foo"}) if err != nil { c.Fatal(err) @@ -1809,7 +1742,6 @@ func (s *DockerSuite) TestBuildWithInaccessibleFilesInContext(c *check.C) { } { name := "testlinksok" - defer deleteImages(name) ctx, err := fakeContext("FROM scratch\nADD . /foo/", nil) if err != nil { c.Fatal(err) @@ -1829,7 +1761,6 @@ func (s *DockerSuite) TestBuildWithInaccessibleFilesInContext(c *check.C) { } { name := "testbuildignoredinaccessible" - defer deleteImages(name) ctx, err := fakeContext("FROM scratch\nADD . /foo/", map[string]string{ "directoryWeCantStat/bar": "foo", @@ -1867,7 +1798,6 @@ func (s *DockerSuite) TestBuildForceRm(c *check.C) { c.Fatalf("failed to get the container count: %s", err) } name := "testbuildforcerm" - defer deleteImages(name) ctx, err := fakeContext("FROM scratch\nRUN true\nRUN thiswillfail", nil) if err != nil { c.Fatal(err) @@ -1903,7 +1833,6 @@ func (s *DockerSuite) TestBuildCancelationKillsSleep(c *check.C) { defer wg.Wait() name := "testbuildcancelation" - defer deleteImages(name) // (Note: one year, will never finish) ctx, err := fakeContext("FROM busybox\nRUN sleep 31536000", nil) @@ -2018,7 +1947,6 @@ func (s *DockerSuite) TestBuildCancelationKillsSleep(c *check.C) { func (s *DockerSuite) TestBuildRm(c *check.C) { name := "testbuildrm" - defer deleteImages(name) ctx, err := fakeContext("FROM scratch\nADD foo /\nADD foo /", map[string]string{"foo": "bar"}) if err != nil { c.Fatal(err) @@ -2112,7 +2040,6 @@ func (s *DockerSuite) TestBuildWithVolumes(c *check.C) { "/test8]": emptyMap, } ) - defer deleteImages(name) _, err := buildImage(name, `FROM scratch VOLUME /test1 @@ -2146,7 +2073,6 @@ func (s *DockerSuite) TestBuildWithVolumes(c *check.C) { func (s *DockerSuite) TestBuildMaintainer(c *check.C) { name := "testbuildmaintainer" expected := "dockerio" - defer deleteImages(name) _, err := buildImage(name, `FROM scratch MAINTAINER dockerio`, @@ -2166,7 +2092,6 @@ func (s *DockerSuite) TestBuildMaintainer(c *check.C) { func (s *DockerSuite) TestBuildUser(c *check.C) { name := "testbuilduser" expected := "dockerio" - defer deleteImages(name) _, err := buildImage(name, `FROM busybox RUN echo 'dockerio:x:1001:1001::/bin:/bin/false' >> /etc/passwd @@ -2188,7 +2113,6 @@ func (s *DockerSuite) TestBuildUser(c *check.C) { func (s *DockerSuite) TestBuildRelativeWorkdir(c *check.C) { name := "testbuildrelativeworkdir" expected := "/test2/test3" - defer deleteImages(name) _, err := buildImage(name, `FROM busybox RUN [ "$PWD" = '/' ] @@ -2214,7 +2138,6 @@ func (s *DockerSuite) TestBuildRelativeWorkdir(c *check.C) { func (s *DockerSuite) TestBuildWorkdirWithEnvVariables(c *check.C) { name := "testbuildworkdirwithenvvariables" expected := "/test1/test2" - defer deleteImages(name) _, err := buildImage(name, `FROM busybox ENV DIRPATH /test1 @@ -2236,7 +2159,6 @@ func (s *DockerSuite) TestBuildWorkdirWithEnvVariables(c *check.C) { func (s *DockerSuite) TestBuildRelativeCopy(c *check.C) { name := "testbuildrelativecopy" - defer deleteImages(name) dockerfile := ` FROM busybox WORKDIR /test1 @@ -2276,7 +2198,6 @@ func (s *DockerSuite) TestBuildRelativeCopy(c *check.C) { func (s *DockerSuite) TestBuildEnv(c *check.C) { name := "testbuildenv" expected := "[PATH=/test:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin PORT=2375]" - defer deleteImages(name) _, err := buildImage(name, `FROM busybox ENV PATH /test:$PATH @@ -2299,7 +2220,6 @@ func (s *DockerSuite) TestBuildContextCleanup(c *check.C) { testRequires(c, SameHostDaemon) name := "testbuildcontextcleanup" - defer deleteImages(name) entries, err := ioutil.ReadDir("/var/lib/docker/tmp") if err != nil { c.Fatalf("failed to list contents of tmp dir: %s", err) @@ -2325,7 +2245,6 @@ func (s *DockerSuite) TestBuildContextCleanupFailedBuild(c *check.C) { testRequires(c, SameHostDaemon) name := "testbuildcontextcleanup" - defer deleteImages(name) entries, err := ioutil.ReadDir("/var/lib/docker/tmp") if err != nil { c.Fatalf("failed to list contents of tmp dir: %s", err) @@ -2350,7 +2269,6 @@ func (s *DockerSuite) TestBuildContextCleanupFailedBuild(c *check.C) { func (s *DockerSuite) TestBuildCmd(c *check.C) { name := "testbuildcmd" expected := "{[/bin/echo Hello World]}" - defer deleteImages(name) _, err := buildImage(name, `FROM scratch CMD ["/bin/echo", "Hello World"]`, @@ -2370,7 +2288,6 @@ func (s *DockerSuite) TestBuildCmd(c *check.C) { func (s *DockerSuite) TestBuildExpose(c *check.C) { name := "testbuildexpose" expected := "map[2375/tcp:{}]" - defer deleteImages(name) _, err := buildImage(name, `FROM scratch EXPOSE 2375`, @@ -2413,7 +2330,6 @@ func (s *DockerSuite) TestBuildExposeMorePorts(c *check.C) { tmpl.Execute(buf, portList) name := "testbuildexpose" - defer deleteImages(name) _, err := buildImage(name, buf.String(), true) if err != nil { c.Fatal(err) @@ -2458,7 +2374,6 @@ func (s *DockerSuite) TestBuildExposeOrder(c *check.C) { id1 := buildID("testbuildexpose1", "80 2375") id2 := buildID("testbuildexpose2", "2375 80") - defer deleteImages("testbuildexpose1", "testbuildexpose2") if id1 != id2 { c.Errorf("EXPOSE should invalidate the cache only when ports actually changed") } @@ -2467,7 +2382,6 @@ func (s *DockerSuite) TestBuildExposeOrder(c *check.C) { func (s *DockerSuite) TestBuildExposeUpperCaseProto(c *check.C) { name := "testbuildexposeuppercaseproto" expected := "map[5678/udp:{}]" - defer deleteImages(name) _, err := buildImage(name, `FROM scratch EXPOSE 5678/UDP`, @@ -2488,7 +2402,6 @@ func (s *DockerSuite) TestBuildExposeHostPort(c *check.C) { // start building docker file with ip:hostPort:containerPort name := "testbuildexpose" expected := "map[5678/tcp:{}]" - defer deleteImages(name) _, out, err := buildImageWithOut(name, `FROM scratch EXPOSE 192.168.1.2:2375:5678`, @@ -2513,7 +2426,6 @@ func (s *DockerSuite) TestBuildExposeHostPort(c *check.C) { func (s *DockerSuite) TestBuildEmptyEntrypointInheritance(c *check.C) { name := "testbuildentrypointinheritance" name2 := "testbuildentrypointinheritance2" - defer deleteImages(name, name2) _, err := buildImage(name, `FROM busybox @@ -2554,7 +2466,6 @@ func (s *DockerSuite) TestBuildEmptyEntrypointInheritance(c *check.C) { func (s *DockerSuite) TestBuildEmptyEntrypoint(c *check.C) { name := "testbuildentrypoint" - defer deleteImages(name) expected := "{[]}" _, err := buildImage(name, @@ -2577,7 +2488,6 @@ func (s *DockerSuite) TestBuildEmptyEntrypoint(c *check.C) { func (s *DockerSuite) TestBuildEntrypoint(c *check.C) { name := "testbuildentrypoint" expected := "{[/bin/echo]}" - defer deleteImages(name) _, err := buildImage(name, `FROM scratch ENTRYPOINT ["/bin/echo"]`, @@ -2617,7 +2527,6 @@ func (s *DockerSuite) TestBuildOnBuildLimitedInheritence(c *check.C) { if err != nil { c.Fatalf("build failed to complete: %s, %v", out1, err) } - defer deleteImages(name1) } { name2 := "testonbuildtrigger2" @@ -2634,7 +2543,6 @@ func (s *DockerSuite) TestBuildOnBuildLimitedInheritence(c *check.C) { if err != nil { c.Fatalf("build failed to complete: %s, %v", out2, err) } - defer deleteImages(name2) } { name3 := "testonbuildtrigger3" @@ -2652,7 +2560,6 @@ func (s *DockerSuite) TestBuildOnBuildLimitedInheritence(c *check.C) { c.Fatalf("build failed to complete: %s, %v", out3, err) } - defer deleteImages(name3) } // ONBUILD should be run in second build. @@ -2669,7 +2576,6 @@ func (s *DockerSuite) TestBuildOnBuildLimitedInheritence(c *check.C) { func (s *DockerSuite) TestBuildWithCache(c *check.C) { name := "testbuildwithcache" - defer deleteImages(name) id1, err := buildImage(name, `FROM scratch MAINTAINER dockerio @@ -2696,7 +2602,6 @@ func (s *DockerSuite) TestBuildWithCache(c *check.C) { func (s *DockerSuite) TestBuildWithoutCache(c *check.C) { name := "testbuildwithoutcache" name2 := "testbuildwithoutcache2" - defer deleteImages(name, name2) id1, err := buildImage(name, `FROM scratch MAINTAINER dockerio @@ -2723,8 +2628,6 @@ func (s *DockerSuite) TestBuildWithoutCache(c *check.C) { func (s *DockerSuite) TestBuildConditionalCache(c *check.C) { name := "testbuildconditionalcache" - name2 := "testbuildconditionalcache2" - defer deleteImages(name, name2) dockerfile := ` FROM busybox @@ -2761,13 +2664,11 @@ func (s *DockerSuite) TestBuildConditionalCache(c *check.C) { if id3 != id2 { c.Fatal("Should have used the cache") } - } func (s *DockerSuite) TestBuildADDLocalFileWithCache(c *check.C) { name := "testbuildaddlocalfilewithcache" name2 := "testbuildaddlocalfilewithcache2" - defer deleteImages(name, name2) dockerfile := ` FROM busybox MAINTAINER dockerio @@ -2796,7 +2697,6 @@ func (s *DockerSuite) TestBuildADDLocalFileWithCache(c *check.C) { func (s *DockerSuite) TestBuildADDMultipleLocalFileWithCache(c *check.C) { name := "testbuildaddmultiplelocalfilewithcache" name2 := "testbuildaddmultiplelocalfilewithcache2" - defer deleteImages(name, name2) dockerfile := ` FROM busybox MAINTAINER dockerio @@ -2825,7 +2725,6 @@ func (s *DockerSuite) TestBuildADDMultipleLocalFileWithCache(c *check.C) { func (s *DockerSuite) TestBuildADDLocalFileWithoutCache(c *check.C) { name := "testbuildaddlocalfilewithoutcache" name2 := "testbuildaddlocalfilewithoutcache2" - defer deleteImages(name, name2) dockerfile := ` FROM busybox MAINTAINER dockerio @@ -2854,7 +2753,6 @@ func (s *DockerSuite) TestBuildADDLocalFileWithoutCache(c *check.C) { func (s *DockerSuite) TestBuildCopyDirButNotFile(c *check.C) { name := "testbuildcopydirbutnotfile" name2 := "testbuildcopydirbutnotfile2" - defer deleteImages(name, name2) dockerfile := ` FROM scratch COPY dir /tmp/` @@ -2888,7 +2786,6 @@ func (s *DockerSuite) TestBuildADDCurrentDirWithCache(c *check.C) { name3 := name + "3" name4 := name + "4" name5 := name + "5" - defer deleteImages(name, name2, name3, name4, name5) dockerfile := ` FROM scratch MAINTAINER dockerio @@ -2950,7 +2847,6 @@ func (s *DockerSuite) TestBuildADDCurrentDirWithCache(c *check.C) { func (s *DockerSuite) TestBuildADDCurrentDirWithoutCache(c *check.C) { name := "testbuildaddcurrentdirwithoutcache" name2 := "testbuildaddcurrentdirwithoutcache2" - defer deleteImages(name, name2) dockerfile := ` FROM scratch MAINTAINER dockerio @@ -2977,7 +2873,6 @@ func (s *DockerSuite) TestBuildADDCurrentDirWithoutCache(c *check.C) { func (s *DockerSuite) TestBuildADDRemoteFileWithCache(c *check.C) { name := "testbuildaddremotefilewithcache" - defer deleteImages(name) server, err := fakeStorage(map[string]string{ "baz": "hello", }) @@ -3010,7 +2905,6 @@ func (s *DockerSuite) TestBuildADDRemoteFileWithCache(c *check.C) { func (s *DockerSuite) TestBuildADDRemoteFileWithoutCache(c *check.C) { name := "testbuildaddremotefilewithoutcache" name2 := "testbuildaddremotefilewithoutcache2" - defer deleteImages(name, name2) server, err := fakeStorage(map[string]string{ "baz": "hello", }) @@ -3046,8 +2940,6 @@ func (s *DockerSuite) TestBuildADDRemoteFileMTime(c *check.C) { name3 := name + "3" name4 := name + "4" - defer deleteImages(name, name2, name3, name4) - files := map[string]string{"baz": "hello"} server, err := fakeStorage(files) if err != nil { @@ -3115,7 +3007,6 @@ func (s *DockerSuite) TestBuildADDRemoteFileMTime(c *check.C) { func (s *DockerSuite) TestBuildADDLocalAndRemoteFilesWithCache(c *check.C) { name := "testbuildaddlocalandremotefilewithcache" - defer deleteImages(name) server, err := fakeStorage(map[string]string{ "baz": "hello", }) @@ -3167,7 +3058,6 @@ CMD ["cat", "/foo"]`, } name := "contexttar" buildCmd := exec.Command(dockerBinary, "build", "-t", name, "-") - defer deleteImages(name) buildCmd.Stdin = context if out, _, err := runCommandWithOutput(buildCmd); err != nil { @@ -3194,15 +3084,12 @@ func (s *DockerSuite) TestBuildNoContext(c *check.C) { if out, _ := dockerCmd(c, "run", "--rm", "nocontext"); out != "ok\n" { c.Fatalf("run produced invalid output: %q, expected %q", out, "ok") } - - deleteImages("nocontext") } // TODO: TestCaching func (s *DockerSuite) TestBuildADDLocalAndRemoteFilesWithoutCache(c *check.C) { name := "testbuildaddlocalandremotefilewithoutcache" name2 := "testbuildaddlocalandremotefilewithoutcache2" - defer deleteImages(name, name2) server, err := fakeStorage(map[string]string{ "baz": "hello", }) @@ -3237,7 +3124,6 @@ func (s *DockerSuite) TestBuildADDLocalAndRemoteFilesWithoutCache(c *check.C) { func (s *DockerSuite) TestBuildWithVolumeOwnership(c *check.C) { name := "testbuildimg" - defer deleteImages(name) _, err := buildImage(name, `FROM busybox:latest @@ -3269,7 +3155,6 @@ func (s *DockerSuite) TestBuildWithVolumeOwnership(c *check.C) { // utilizing cache func (s *DockerSuite) TestBuildEntrypointRunCleanup(c *check.C) { name := "testbuildcmdcleanup" - defer deleteImages(name) if _, err := buildImage(name, `FROM busybox RUN echo "hello"`, @@ -3303,7 +3188,6 @@ func (s *DockerSuite) TestBuildEntrypointRunCleanup(c *check.C) { func (s *DockerSuite) TestBuildForbiddenContextPath(c *check.C) { name := "testbuildforbidpath" - defer deleteImages(name) ctx, err := fakeContext(`FROM scratch ADD ../../ test/ `, @@ -3325,7 +3209,6 @@ func (s *DockerSuite) TestBuildForbiddenContextPath(c *check.C) { func (s *DockerSuite) TestBuildADDFileNotFound(c *check.C) { name := "testbuildaddnotfound" - defer deleteImages(name) ctx, err := fakeContext(`FROM scratch ADD foo /usr/local/bar`, map[string]string{"bar": "hello"}) @@ -3344,7 +3227,6 @@ func (s *DockerSuite) TestBuildADDFileNotFound(c *check.C) { func (s *DockerSuite) TestBuildInheritance(c *check.C) { name := "testbuildinheritance" - defer deleteImages(name) _, err := buildImage(name, `FROM scratch @@ -3384,7 +3266,6 @@ func (s *DockerSuite) TestBuildInheritance(c *check.C) { func (s *DockerSuite) TestBuildFails(c *check.C) { name := "testbuildfails" - defer deleteImages(name) _, err := buildImage(name, `FROM busybox RUN sh -c "exit 23"`, @@ -3400,7 +3281,6 @@ func (s *DockerSuite) TestBuildFails(c *check.C) { func (s *DockerSuite) TestBuildFailsDockerfileEmpty(c *check.C) { name := "testbuildfails" - defer deleteImages(name) _, err := buildImage(name, ``, true) if err != nil { if !strings.Contains(err.Error(), "The Dockerfile (Dockerfile) cannot be empty") { @@ -3413,7 +3293,6 @@ func (s *DockerSuite) TestBuildFailsDockerfileEmpty(c *check.C) { func (s *DockerSuite) TestBuildOnBuild(c *check.C) { name := "testbuildonbuild" - defer deleteImages(name) _, err := buildImage(name, `FROM busybox ONBUILD RUN touch foobar`, @@ -3432,7 +3311,6 @@ func (s *DockerSuite) TestBuildOnBuild(c *check.C) { func (s *DockerSuite) TestBuildOnBuildForbiddenChained(c *check.C) { name := "testbuildonbuildforbiddenchained" - defer deleteImages(name) _, err := buildImage(name, `FROM busybox ONBUILD ONBUILD RUN touch foobar`, @@ -3448,7 +3326,6 @@ func (s *DockerSuite) TestBuildOnBuildForbiddenChained(c *check.C) { func (s *DockerSuite) TestBuildOnBuildForbiddenFrom(c *check.C) { name := "testbuildonbuildforbiddenfrom" - defer deleteImages(name) _, err := buildImage(name, `FROM busybox ONBUILD FROM scratch`, @@ -3464,7 +3341,6 @@ func (s *DockerSuite) TestBuildOnBuildForbiddenFrom(c *check.C) { func (s *DockerSuite) TestBuildOnBuildForbiddenMaintainer(c *check.C) { name := "testbuildonbuildforbiddenmaintainer" - defer deleteImages(name) _, err := buildImage(name, `FROM busybox ONBUILD MAINTAINER docker.io`, @@ -3481,7 +3357,6 @@ func (s *DockerSuite) TestBuildOnBuildForbiddenMaintainer(c *check.C) { // gh #2446 func (s *DockerSuite) TestBuildAddToSymlinkDest(c *check.C) { name := "testbuildaddtosymlinkdest" - defer deleteImages(name) ctx, err := fakeContext(`FROM busybox RUN mkdir /foo RUN ln -s /foo /bar @@ -3502,7 +3377,6 @@ func (s *DockerSuite) TestBuildAddToSymlinkDest(c *check.C) { func (s *DockerSuite) TestBuildEscapeWhitespace(c *check.C) { name := "testbuildescaping" - defer deleteImages(name) _, err := buildImage(name, ` FROM busybox @@ -3526,7 +3400,6 @@ docker.com>" func (s *DockerSuite) TestBuildVerifyIntString(c *check.C) { // Verify that strings that look like ints are still passed as strings name := "testbuildstringing" - defer deleteImages(name) _, err := buildImage(name, ` FROM busybox @@ -3546,7 +3419,6 @@ func (s *DockerSuite) TestBuildVerifyIntString(c *check.C) { func (s *DockerSuite) TestBuildDockerignore(c *check.C) { name := "testbuilddockerignore" - defer deleteImages(name) dockerfile := ` FROM busybox ADD . /bla @@ -3576,7 +3448,6 @@ func (s *DockerSuite) TestBuildDockerignore(c *check.C) { func (s *DockerSuite) TestBuildDockerignoreCleanPaths(c *check.C) { name := "testbuilddockerignorecleanpaths" - defer deleteImages(name) dockerfile := ` FROM busybox ADD . /tmp/ @@ -3598,7 +3469,6 @@ func (s *DockerSuite) TestBuildDockerignoreCleanPaths(c *check.C) { func (s *DockerSuite) TestBuildDockerignoringDockerfile(c *check.C) { name := "testbuilddockerignoredockerfile" - defer deleteImages(name) dockerfile := ` FROM busybox ADD . /tmp/ @@ -3627,7 +3497,6 @@ func (s *DockerSuite) TestBuildDockerignoringDockerfile(c *check.C) { func (s *DockerSuite) TestBuildDockerignoringRenamedDockerfile(c *check.C) { name := "testbuilddockerignoredockerfile" - defer deleteImages(name) dockerfile := ` FROM busybox ADD . /tmp/ @@ -3658,7 +3527,6 @@ func (s *DockerSuite) TestBuildDockerignoringRenamedDockerfile(c *check.C) { func (s *DockerSuite) TestBuildDockerignoringDockerignore(c *check.C) { name := "testbuilddockerignoredockerignore" - defer deleteImages(name) dockerfile := ` FROM busybox ADD . /tmp/ @@ -3682,7 +3550,6 @@ func (s *DockerSuite) TestBuildDockerignoreTouchDockerfile(c *check.C) { var id2 string name := "testbuilddockerignoretouchdockerfile" - defer deleteImages(name) dockerfile := ` FROM busybox ADD . /tmp/` @@ -3732,7 +3599,6 @@ func (s *DockerSuite) TestBuildDockerignoreTouchDockerfile(c *check.C) { func (s *DockerSuite) TestBuildDockerignoringWholeDir(c *check.C) { name := "testbuilddockerignorewholedir" - defer deleteImages(name) dockerfile := ` FROM busybox COPY . / @@ -3754,7 +3620,6 @@ func (s *DockerSuite) TestBuildDockerignoringWholeDir(c *check.C) { func (s *DockerSuite) TestBuildLineBreak(c *check.C) { name := "testbuildlinebreak" - defer deleteImages(name) _, err := buildImage(name, `FROM busybox RUN sh -c 'echo root:testpass \ @@ -3770,7 +3635,6 @@ RUN [ "$(ls -d /var/run/sshd)" = "/var/run/sshd" ]`, func (s *DockerSuite) TestBuildEOLInLine(c *check.C) { name := "testbuildeolinline" - defer deleteImages(name) _, err := buildImage(name, `FROM busybox RUN sh -c 'echo root:testpass > /tmp/passwd' @@ -3786,7 +3650,6 @@ RUN [ "$(ls -d /var/run/sshd)" = "/var/run/sshd" ]`, func (s *DockerSuite) TestBuildCommentsShebangs(c *check.C) { name := "testbuildcomments" - defer deleteImages(name) _, err := buildImage(name, `FROM busybox # This is an ordinary comment. @@ -3805,7 +3668,6 @@ RUN [ "$(/hello.sh)" = "hello world" ]`, func (s *DockerSuite) TestBuildUsersAndGroups(c *check.C) { name := "testbuildusers" - defer deleteImages(name) _, err := buildImage(name, `FROM busybox @@ -3868,7 +3730,6 @@ RUN [ "$(id -u):$(id -g)/$(id -un):$(id -gn)/$(id -G):$(id -Gn)" = '1042:1043/10 func (s *DockerSuite) TestBuildEnvUsage(c *check.C) { name := "testbuildenvusage" - defer deleteImages(name) dockerfile := `FROM busybox ENV HOME /root ENV PATH $HOME/bin:$PATH @@ -3904,7 +3765,6 @@ RUN [ "$ghi" = "def" ] func (s *DockerSuite) TestBuildEnvUsage2(c *check.C) { name := "testbuildenvusage2" - defer deleteImages(name) dockerfile := `FROM busybox ENV abc=def RUN [ "$abc" = "def" ] @@ -4007,7 +3867,6 @@ RUN [ "$eee1,$eee2,$eee3,$eee4" = 'foo,foo,foo,foo' ] func (s *DockerSuite) TestBuildAddScript(c *check.C) { name := "testbuildaddscript" - defer deleteImages(name) dockerfile := ` FROM busybox ADD test /test @@ -4030,7 +3889,6 @@ RUN [ "$(cat /testfile)" = 'test!' ]` func (s *DockerSuite) TestBuildAddTar(c *check.C) { name := "testbuildaddtar" - defer deleteImages(name) ctx := func() *FakeContext { dockerfile := ` @@ -4085,7 +3943,6 @@ RUN cat /existing-directory-trailing-slash/test/foo | grep Hi` func (s *DockerSuite) TestBuildAddTarXz(c *check.C) { name := "testbuildaddtarxz" - defer deleteImages(name) ctx := func() *FakeContext { dockerfile := ` @@ -4136,7 +3993,6 @@ func (s *DockerSuite) TestBuildAddTarXz(c *check.C) { func (s *DockerSuite) TestBuildAddTarXzGz(c *check.C) { name := "testbuildaddtarxzgz" - defer deleteImages(name) ctx := func() *FakeContext { dockerfile := ` @@ -4195,7 +4051,6 @@ func (s *DockerSuite) TestBuildAddTarXzGz(c *check.C) { func (s *DockerSuite) TestBuildFromGIT(c *check.C) { name := "testbuildfromgit" - defer deleteImages(name) git, err := fakeGIT("repo", map[string]string{ "Dockerfile": `FROM busybox ADD first /first @@ -4223,7 +4078,6 @@ func (s *DockerSuite) TestBuildFromGIT(c *check.C) { func (s *DockerSuite) TestBuildCleanupCmdOnEntrypoint(c *check.C) { name := "testbuildcmdcleanuponentrypoint" - defer deleteImages(name) if _, err := buildImage(name, `FROM scratch CMD ["test"] @@ -4256,7 +4110,6 @@ func (s *DockerSuite) TestBuildCleanupCmdOnEntrypoint(c *check.C) { func (s *DockerSuite) TestBuildClearCmd(c *check.C) { name := "testbuildclearcmd" - defer deleteImages(name) _, err := buildImage(name, `From scratch ENTRYPOINT ["/bin/bash"] @@ -4276,7 +4129,6 @@ func (s *DockerSuite) TestBuildClearCmd(c *check.C) { func (s *DockerSuite) TestBuildEmptyCmd(c *check.C) { name := "testbuildemptycmd" - defer deleteImages(name) if _, err := buildImage(name, "FROM scratch\nMAINTAINER quux\n", true); err != nil { c.Fatal(err) } @@ -4291,14 +4143,10 @@ func (s *DockerSuite) TestBuildEmptyCmd(c *check.C) { func (s *DockerSuite) TestBuildOnBuildOutput(c *check.C) { name := "testbuildonbuildparent" - defer deleteImages(name) if _, err := buildImage(name, "FROM busybox\nONBUILD RUN echo foo\n", true); err != nil { c.Fatal(err) } - childname := "testbuildonbuildchild" - defer deleteImages(childname) - _, out, err := buildImageWithOut(name, "FROM "+name+"\nMAINTAINER quux\n", true) if err != nil { c.Fatal(err) @@ -4312,7 +4160,6 @@ func (s *DockerSuite) TestBuildOnBuildOutput(c *check.C) { func (s *DockerSuite) TestBuildInvalidTag(c *check.C) { name := "abcd:" + stringutils.GenerateRandomAlphaOnlyString(200) - defer deleteImages(name) _, out, err := buildImageWithOut(name, "FROM scratch\nMAINTAINER quux\n", true) // if the error doesnt check for illegal tag name, or the image is built // then this should fail @@ -4323,7 +4170,6 @@ func (s *DockerSuite) TestBuildInvalidTag(c *check.C) { func (s *DockerSuite) TestBuildCmdShDashC(c *check.C) { name := "testbuildcmdshc" - defer deleteImages(name) if _, err := buildImage(name, "FROM busybox\nCMD echo cmd\n", true); err != nil { c.Fatal(err) } @@ -4346,7 +4192,6 @@ func (s *DockerSuite) TestBuildCmdSpaces(c *check.C) { // the arg separator to make sure ["echo","hi"] and ["echo hi"] don't // look the same name := "testbuildcmdspaces" - defer deleteImages(name) var id1 string var id2 string var err error @@ -4380,7 +4225,6 @@ func (s *DockerSuite) TestBuildCmdSpaces(c *check.C) { func (s *DockerSuite) TestBuildCmdJSONNoShDashC(c *check.C) { name := "testbuildcmdjson" - defer deleteImages(name) if _, err := buildImage(name, "FROM busybox\nCMD [\"echo\", \"cmd\"]", true); err != nil { c.Fatal(err) } @@ -4400,7 +4244,6 @@ func (s *DockerSuite) TestBuildCmdJSONNoShDashC(c *check.C) { func (s *DockerSuite) TestBuildErrorInvalidInstruction(c *check.C) { name := "testbuildignoreinvalidinstruction" - defer deleteImages(name) out, _, err := buildImageWithOut(name, "FROM busybox\nfoo bar", true) if err == nil { @@ -4410,7 +4253,6 @@ func (s *DockerSuite) TestBuildErrorInvalidInstruction(c *check.C) { } func (s *DockerSuite) TestBuildEntrypointInheritance(c *check.C) { - defer deleteImages("parent", "child") if _, err := buildImage("parent", ` FROM busybox @@ -4447,8 +4289,6 @@ func (s *DockerSuite) TestBuildEntrypointInheritanceInspect(c *check.C) { expected = `["/bin/sh","-c","echo quux"]` ) - defer deleteImages(name, name2) - if _, err := buildImage(name, "FROM busybox\nENTRYPOINT /foo/bar", true); err != nil { c.Fatal(err) } @@ -4481,7 +4321,6 @@ func (s *DockerSuite) TestBuildEntrypointInheritanceInspect(c *check.C) { func (s *DockerSuite) TestBuildRunShEntrypoint(c *check.C) { name := "testbuildentrypoint" - defer deleteImages(name) _, err := buildImage(name, `FROM busybox ENTRYPOINT /bin/echo`, @@ -4500,7 +4339,6 @@ func (s *DockerSuite) TestBuildRunShEntrypoint(c *check.C) { func (s *DockerSuite) TestBuildExoticShellInterpolation(c *check.C) { name := "testbuildexoticshellinterpolation" - defer deleteImages(name) _, err := buildImage(name, ` FROM busybox @@ -4534,7 +4372,6 @@ func (s *DockerSuite) TestBuildVerifySingleQuoteFails(c *check.C) { // as a "string" insead of "JSON array" and pass it on to "sh -c" and // it should barf on it. name := "testbuildsinglequotefails" - defer deleteImages(name) _, err := buildImage(name, `FROM busybox @@ -4550,7 +4387,6 @@ func (s *DockerSuite) TestBuildVerifySingleQuoteFails(c *check.C) { func (s *DockerSuite) TestBuildVerboseOut(c *check.C) { name := "testbuildverboseout" - defer deleteImages(name) _, out, err := buildImageWithOut(name, `FROM busybox @@ -4568,7 +4404,6 @@ RUN echo 123`, func (s *DockerSuite) TestBuildWithTabs(c *check.C) { name := "testbuildwithtabs" - defer deleteImages(name) _, err := buildImage(name, "FROM busybox\nRUN echo\tone\t\ttwo", true) if err != nil { @@ -4588,7 +4423,6 @@ func (s *DockerSuite) TestBuildWithTabs(c *check.C) { func (s *DockerSuite) TestBuildLabels(c *check.C) { name := "testbuildlabel" expected := `{"License":"GPL","Vendor":"Acme"}` - defer deleteImages(name) _, err := buildImage(name, `FROM busybox LABEL Vendor=Acme @@ -4608,7 +4442,6 @@ func (s *DockerSuite) TestBuildLabels(c *check.C) { func (s *DockerSuite) TestBuildLabelsCache(c *check.C) { name := "testbuildlabelcache" - defer deleteImages(name) id1, err := buildImage(name, `FROM busybox @@ -4659,7 +4492,6 @@ func (s *DockerSuite) TestBuildStderr(c *check.C) { // This test just makes sure that no non-error output goes // to stderr name := "testbuildstderr" - defer deleteImages(name) _, _, stderr, err := buildImageWithStdoutStderr(name, "FROM busybox\nRUN echo one", true) if err != nil { @@ -4685,7 +4517,6 @@ func (s *DockerSuite) TestBuildChownSingleFile(c *check.C) { testRequires(c, UnixCli) // test uses chown: not available on windows name := "testbuildchownsinglefile" - defer deleteImages(name) ctx, err := fakeContext(` FROM busybox @@ -4765,7 +4596,6 @@ func (s *DockerSuite) TestBuildSymlinkBreakout(c *check.C) { func (s *DockerSuite) TestBuildXZHost(c *check.C) { name := "testbuildxzhost" - defer deleteImages(name) ctx, err := fakeContext(` FROM busybox @@ -4796,7 +4626,6 @@ func (s *DockerSuite) TestBuildVolumesRetainContents(c *check.C) { name = "testbuildvolumescontent" expected = "some text" ) - defer deleteImages(name) ctx, err := fakeContext(` FROM busybox COPY content /foo/file @@ -4929,7 +4758,6 @@ func (s *DockerSuite) TestBuildRenamedDockerfile(c *check.C) { func (s *DockerSuite) TestBuildFromMixedcaseDockerfile(c *check.C) { testRequires(c, UnixCli) // Dockerfile overwrites dockerfile on windows - defer deleteImages("test1") ctx, err := fakeContext(`FROM busybox RUN echo from dockerfile`, @@ -4954,7 +4782,6 @@ func (s *DockerSuite) TestBuildFromMixedcaseDockerfile(c *check.C) { func (s *DockerSuite) TestBuildWithTwoDockerfiles(c *check.C) { testRequires(c, UnixCli) // Dockerfile overwrites dockerfile on windows - defer deleteImages("test1") ctx, err := fakeContext(`FROM busybox RUN echo from Dockerfile`, @@ -4978,7 +4805,6 @@ RUN echo from Dockerfile`, } func (s *DockerSuite) TestBuildFromURLWithF(c *check.C) { - defer deleteImages("test1") server, err := fakeStorage(map[string]string{"baz": `FROM busybox RUN echo from baz @@ -5013,7 +4839,6 @@ RUN echo from Dockerfile`, } func (s *DockerSuite) TestBuildFromStdinWithF(c *check.C) { - defer deleteImages("test1") ctx, err := fakeContext(`FROM busybox RUN echo from Dockerfile`, @@ -5121,8 +4946,6 @@ func (s *DockerSuite) TestBuildDockerfileOutsideContext(c *check.C) { if err == nil { c.Fatalf("Expected error. Out: %s", out) } - deleteImages(name) - } func (s *DockerSuite) TestBuildSpaces(c *check.C) { @@ -5134,7 +4957,6 @@ func (s *DockerSuite) TestBuildSpaces(c *check.C) { ) name := "testspaces" - defer deleteImages(name) ctx, err := fakeContext("FROM busybox\nCOPY\n", map[string]string{ "Dockerfile": "FROM busybox\nCOPY\n", @@ -5199,7 +5021,6 @@ func (s *DockerSuite) TestBuildSpaces(c *check.C) { func (s *DockerSuite) TestBuildSpacesWithQuotes(c *check.C) { // Test to make sure that spaces in quotes aren't lost name := "testspacesquotes" - defer deleteImages(name) dockerfile := `FROM busybox RUN echo " \ @@ -5275,7 +5096,6 @@ func (s *DockerSuite) TestBuildMissingArgs(c *check.C) { } func (s *DockerSuite) TestBuildEmptyScratch(c *check.C) { - defer deleteImages("sc") _, out, err := buildImageWithOut("sc", "FROM scratch", true) if err == nil { c.Fatalf("Build was supposed to fail") @@ -5286,7 +5106,6 @@ func (s *DockerSuite) TestBuildEmptyScratch(c *check.C) { } func (s *DockerSuite) TestBuildDotDotFile(c *check.C) { - defer deleteImages("sc") ctx, err := fakeContext("FROM busybox\n", map[string]string{ "..gitme": "", @@ -5302,7 +5121,6 @@ func (s *DockerSuite) TestBuildDotDotFile(c *check.C) { } func (s *DockerSuite) TestBuildNotVerbose(c *check.C) { - defer deleteImages("verbose") ctx, err := fakeContext("FROM busybox\nENV abc=hi\nRUN echo $abc there", map[string]string{}) if err != nil { @@ -5337,8 +5155,6 @@ func (s *DockerSuite) TestBuildNotVerbose(c *check.C) { func (s *DockerSuite) TestBuildRUNoneJSON(c *check.C) { name := "testbuildrunonejson" - defer deleteImages(name, "hello-world") - ctx, err := fakeContext(`FROM hello-world:frozen RUN [ "/hello" ]`, map[string]string{}) if err != nil { @@ -5361,7 +5177,6 @@ RUN [ "/hello" ]`, map[string]string{}) func (s *DockerSuite) TestBuildResourceConstraintsAreUsed(c *check.C) { name := "testbuildresourceconstraints" - defer deleteImages(name, "hello-world") ctx, err := fakeContext(` FROM hello-world:frozen @@ -5425,7 +5240,6 @@ func (s *DockerSuite) TestBuildResourceConstraintsAreUsed(c *check.C) { func (s *DockerSuite) TestBuildEmptyStringVolume(c *check.C) { name := "testbuildemptystringvolume" - defer deleteImages(name) _, err := buildImage(name, ` FROM busybox diff --git a/integration-cli/docker_cli_by_digest_test.go b/integration-cli/docker_cli_by_digest_test.go index bd4518434..6470d974c 100644 --- a/integration-cli/docker_cli_by_digest_test.go +++ b/integration-cli/docker_cli_by_digest_test.go @@ -33,7 +33,6 @@ func setupImageWithTag(tag string) (string, error) { if out, _, err := runCommandWithOutput(cmd); err != nil { return "", fmt.Errorf("image tagging failed: %s, %v", out, err) } - defer deleteImages(repoAndTag) // delete the container as we don't need it any more if err := deleteContainer(containerName); err != nil { @@ -77,7 +76,6 @@ func (s *DockerSuite) TestPullByTagDisplaysDigest(c *check.C) { if err != nil { c.Fatalf("error pulling by tag: %s, %v", out, err) } - defer deleteImages(repoName) // the pull output includes "Digest: ", so find that matches := digestRegex.FindStringSubmatch(out) @@ -108,7 +106,6 @@ func (s *DockerSuite) TestPullByDigest(c *check.C) { if err != nil { c.Fatalf("error pulling by digest: %s, %v", out, err) } - defer deleteImages(imageReference) // the pull output includes "Digest: ", so find that matches := digestRegex.FindStringSubmatch(out) @@ -248,7 +245,6 @@ func (s *DockerSuite) TestBuildByDigest(c *check.C) { // do the build name := "buildbydigest" - defer deleteImages(name) _, err = buildImage(name, fmt.Sprintf( `FROM %s CMD ["/bin/echo", "Hello World"]`, imageReference), @@ -340,7 +336,6 @@ func (s *DockerSuite) TestListImagesWithoutDigests(c *check.C) { func (s *DockerSuite) TestListImagesWithDigests(c *check.C) { defer setupRegistry(c)() - defer deleteImages(repoName+":tag1", repoName+":tag2") // setup image1 digest1, err := setupImageWithTag("tag1") @@ -348,7 +343,6 @@ func (s *DockerSuite) TestListImagesWithDigests(c *check.C) { c.Fatalf("error setting up image: %v", err) } imageReference1 := fmt.Sprintf("%s@%s", repoName, digest1) - defer deleteImages(imageReference1) c.Logf("imageReference1 = %s", imageReference1) // pull image1 by digest @@ -377,7 +371,6 @@ func (s *DockerSuite) TestListImagesWithDigests(c *check.C) { c.Fatalf("error setting up image: %v", err) } imageReference2 := fmt.Sprintf("%s@%s", repoName, digest2) - defer deleteImages(imageReference2) c.Logf("imageReference2 = %s", imageReference2) // pull image1 by digest @@ -508,7 +501,6 @@ func (s *DockerSuite) TestDeleteImageByIDOnlyPulledByDigest(c *check.C) { c.Fatalf("error pulling by digest: %s, %v", out, err) } // just in case... - defer deleteImages(imageReference) imageID, err := inspectField(imageReference, ".Id") if err != nil { diff --git a/integration-cli/docker_cli_commit_test.go b/integration-cli/docker_cli_commit_test.go index a75621f3a..1544b3aac 100644 --- a/integration-cli/docker_cli_commit_test.go +++ b/integration-cli/docker_cli_commit_test.go @@ -33,10 +33,6 @@ func (s *DockerSuite) TestCommitAfterContainerIsDone(c *check.C) { if out, _, err = runCommandWithOutput(inspectCmd); err != nil { c.Fatalf("failed to inspect image: %s, %v", out, err) } - - deleteContainer(cleanedContainerID) - deleteImages(cleanedImageID) - } func (s *DockerSuite) TestCommitWithoutPause(c *check.C) { @@ -65,10 +61,6 @@ func (s *DockerSuite) TestCommitWithoutPause(c *check.C) { if out, _, err = runCommandWithOutput(inspectCmd); err != nil { c.Fatalf("failed to inspect image: %s, %v", out, err) } - - deleteContainer(cleanedContainerID) - deleteImages(cleanedImageID) - } //test commit a paused container should not unpause it after commit @@ -92,8 +84,6 @@ func (s *DockerSuite) TestCommitPausedContainer(c *check.C) { if err != nil { c.Fatalf("failed to commit container to image: %s, %v", out, err) } - cleanedImageID := strings.TrimSpace(out) - defer deleteImages(cleanedImageID) cmd = exec.Command(dockerBinary, "inspect", "-f", "{{.State.Paused}}", cleanedContainerID) out, _, _, err = runCommandWithStdoutStderr(cmd) @@ -120,7 +110,6 @@ func (s *DockerSuite) TestCommitNewFile(c *check.C) { c.Fatal(err) } imageID = strings.Trim(imageID, "\r\n") - defer deleteImages(imageID) cmd = exec.Command(dockerBinary, "run", imageID, "cat", "/foo") @@ -161,7 +150,6 @@ func (s *DockerSuite) TestCommitHardlink(c *check.C) { c.Fatal(imageID, err) } imageID = strings.Trim(imageID, "\r\n") - defer deleteImages(imageID) cmd = exec.Command(dockerBinary, "run", "-t", "hardlinks", "ls", "-di", "file1", "file2") secondOuput, _, err := runCommandWithOutput(cmd) @@ -185,7 +173,6 @@ func (s *DockerSuite) TestCommitHardlink(c *check.C) { } func (s *DockerSuite) TestCommitTTY(c *check.C) { - defer deleteImages("ttytest") cmd := exec.Command(dockerBinary, "run", "-t", "--name", "tty", "busybox", "/bin/ls") if _, err := runCommand(cmd); err != nil { @@ -220,7 +207,6 @@ func (s *DockerSuite) TestCommitWithHostBindMount(c *check.C) { } imageID = strings.Trim(imageID, "\r\n") - defer deleteImages(imageID) cmd = exec.Command(dockerBinary, "run", "bindtest", "true") @@ -248,7 +234,6 @@ func (s *DockerSuite) TestCommitChange(c *check.C) { c.Fatal(imageId, err) } imageId = strings.Trim(imageId, "\r\n") - defer deleteImages(imageId) expected := map[string]string{ "Config.ExposedPorts": "map[8080/tcp:{}]", @@ -274,7 +259,6 @@ func (s *DockerSuite) TestCommitMergeConfigRun(c *check.C) { id := strings.TrimSpace(out) dockerCmd(c, "commit", `--run={"Cmd": ["cat", "/tmp/foo"]}`, id, "commit-test") - defer deleteImages("commit-test") out, _ = dockerCmd(c, "run", "--name", name, "commit-test") if strings.TrimSpace(out) != "testing" { diff --git a/integration-cli/docker_cli_create_test.go b/integration-cli/docker_cli_create_test.go index 10c499982..646a8eafe 100644 --- a/integration-cli/docker_cli_create_test.go +++ b/integration-cli/docker_cli_create_test.go @@ -259,7 +259,6 @@ func (s *DockerSuite) TestCreateLabels(c *check.C) { func (s *DockerSuite) TestCreateLabelFromImage(c *check.C) { imageName := "testcreatebuildlabel" - defer deleteImages(imageName) _, err := buildImage(imageName, `FROM busybox LABEL k1=v1 k2=v2`, diff --git a/integration-cli/docker_cli_events_test.go b/integration-cli/docker_cli_events_test.go index 35a9c0a21..dfe35b14c 100644 --- a/integration-cli/docker_cli_events_test.go +++ b/integration-cli/docker_cli_events_test.go @@ -144,7 +144,6 @@ func (s *DockerSuite) TestEventsContainerEventsSinceUnixEpoch(c *check.C) { func (s *DockerSuite) TestEventsImageUntagDelete(c *check.C) { name := "testimageevents" - defer deleteImages(name) _, err := buildImage(name, `FROM scratch MAINTAINER "docker"`, @@ -180,8 +179,6 @@ func (s *DockerSuite) TestEventsImagePull(c *check.C) { since := daemonTime(c).Unix() testRequires(c, Network) - defer deleteImages("hello-world") - pullCmd := exec.Command(dockerBinary, "pull", "hello-world") if out, _, err := runCommandWithOutput(pullCmd); err != nil { c.Fatalf("pulling the hello-world image from has failed: %s, %v", out, err) diff --git a/integration-cli/docker_cli_export_import_test.go b/integration-cli/docker_cli_export_import_test.go index bc7b16356..3370a9676 100644 --- a/integration-cli/docker_cli_export_import_test.go +++ b/integration-cli/docker_cli_export_import_test.go @@ -12,8 +12,6 @@ import ( func (s *DockerSuite) TestExportContainerAndImportImage(c *check.C) { containerID := "testexportcontainerandimportimage" - defer deleteImages("repo/testexp:v1") - runCmd := exec.Command(dockerBinary, "run", "-d", "--name", containerID, "busybox", "true") out, _, err := runCommandWithOutput(runCmd) if err != nil { @@ -51,8 +49,6 @@ func (s *DockerSuite) TestExportContainerAndImportImage(c *check.C) { func (s *DockerSuite) TestExportContainerWithOutputAndImportImage(c *check.C) { containerID := "testexportcontainerwithoutputandimportimage" - defer deleteImages("repo/testexp:v1") - runCmd := exec.Command(dockerBinary, "run", "-d", "--name", containerID, "busybox", "true") out, _, err := runCommandWithOutput(runCmd) if err != nil { diff --git a/integration-cli/docker_cli_history_test.go b/integration-cli/docker_cli_history_test.go index 8de400831..d229f1a8c 100644 --- a/integration-cli/docker_cli_history_test.go +++ b/integration-cli/docker_cli_history_test.go @@ -14,7 +14,6 @@ import ( // sort is not predictable it doesn't always fail. func (s *DockerSuite) TestBuildHistory(c *check.C) { name := "testbuildhistory" - defer deleteImages(name) _, err := buildImage(name, `FROM busybox RUN echo "A" RUN echo "B" @@ -85,7 +84,6 @@ func (s *DockerSuite) TestHistoryNonExistentImage(c *check.C) { func (s *DockerSuite) TestHistoryImageWithComment(c *check.C) { name := "testhistoryimagewithcomment" - defer deleteImages(name) // make a image through docker commit [ -m messages ] //runCmd := exec.Command(dockerBinary, "run", "-i", "-a", "stdin", "busybox", "echo", "foo") diff --git a/integration-cli/docker_cli_images_test.go b/integration-cli/docker_cli_images_test.go index cf219e88b..0ab646250 100644 --- a/integration-cli/docker_cli_images_test.go +++ b/integration-cli/docker_cli_images_test.go @@ -26,9 +26,6 @@ func (s *DockerSuite) TestImagesEnsureImageIsListed(c *check.C) { } func (s *DockerSuite) TestImagesOrderedByCreationDate(c *check.C) { - defer deleteImages("order:test_a") - defer deleteImages("order:test_c") - defer deleteImages("order:test_b") id1, err := buildImage("order:test_a", `FROM scratch MAINTAINER dockerio1`, true) @@ -80,9 +77,6 @@ func (s *DockerSuite) TestImagesFilterLabel(c *check.C) { imageName1 := "images_filter_test1" imageName2 := "images_filter_test2" imageName3 := "images_filter_test3" - defer deleteImages(imageName1) - defer deleteImages(imageName2) - defer deleteImages(imageName3) image1ID, err := buildImage(imageName1, `FROM scratch LABEL match me`, true) @@ -130,7 +124,6 @@ func (s *DockerSuite) TestImagesFilterLabel(c *check.C) { func (s *DockerSuite) TestImagesFilterSpaceTrimCase(c *check.C) { imageName := "images_filter_test" - defer deleteImages(imageName) buildImage(imageName, `FROM scratch RUN touch /test/foo @@ -189,7 +182,6 @@ func (s *DockerSuite) TestImagesEnsureDanglingImageOnlyListedOnce(c *check.C) { c.Fatalf("error tagging foobox: %s", err) } imageId := stringid.TruncateID(strings.TrimSpace(out)) - defer deleteImages(imageId) // overwrite the tag, making the previous image dangling cmd = exec.Command(dockerBinary, "tag", "-f", "busybox", "foobox") @@ -197,7 +189,6 @@ func (s *DockerSuite) TestImagesEnsureDanglingImageOnlyListedOnce(c *check.C) { if err != nil { c.Fatalf("error tagging foobox: %s", err) } - defer deleteImages("foobox") cmd = exec.Command(dockerBinary, "images", "-q", "-f", "dangling=true") out, _, err = runCommandWithOutput(cmd) diff --git a/integration-cli/docker_cli_import_test.go b/integration-cli/docker_cli_import_test.go index 02b857bfd..201dbaa58 100644 --- a/integration-cli/docker_cli_import_test.go +++ b/integration-cli/docker_cli_import_test.go @@ -27,7 +27,6 @@ func (s *DockerSuite) TestImportDisplay(c *check.C) { c.Fatalf("display is messed up: %d '\\n' instead of 1:\n%s", n, out) } image := strings.TrimSpace(out) - defer deleteImages(image) runCmd = exec.Command(dockerBinary, "run", "--rm", image, "true") out, _, err = runCommandWithOutput(runCmd) diff --git a/integration-cli/docker_cli_ps_test.go b/integration-cli/docker_cli_ps_test.go index ca2d67bc9..881f02d4f 100644 --- a/integration-cli/docker_cli_ps_test.go +++ b/integration-cli/docker_cli_ps_test.go @@ -560,7 +560,6 @@ func (s *DockerSuite) TestPsListContainersFilterExited(c *check.C) { func (s *DockerSuite) TestPsRightTagName(c *check.C) { tag := "asybox:shmatest" - defer deleteImages(tag) if out, err := exec.Command(dockerBinary, "tag", "busybox", tag).CombinedOutput(); err != nil { c.Fatalf("Failed to tag image: %s, out: %q", err, out) } diff --git a/integration-cli/docker_cli_pull_test.go b/integration-cli/docker_cli_pull_test.go index 9dc9920ca..bdb55f35d 100644 --- a/integration-cli/docker_cli_pull_test.go +++ b/integration-cli/docker_cli_pull_test.go @@ -13,7 +13,6 @@ func (s *DockerSuite) TestPullImageWithAliases(c *check.C) { defer setupRegistry(c)() repoName := fmt.Sprintf("%v/dockercli/busybox", privateRegistryURL) - defer deleteImages(repoName) repos := []string{} for _, tag := range []string{"recent", "fresh"} { @@ -25,7 +24,6 @@ func (s *DockerSuite) TestPullImageWithAliases(c *check.C) { if out, _, err := runCommandWithOutput(exec.Command(dockerBinary, "tag", "busybox", repo)); err != nil { c.Fatalf("Failed to tag image %v: error %v, output %q", repos, err, out) } - defer deleteImages(repo) if out, err := exec.Command(dockerBinary, "push", repo).CombinedOutput(); err != nil { c.Fatalf("Failed to push image %v: error %v, output %q", repo, err, string(out)) } @@ -61,7 +59,6 @@ func (s *DockerSuite) TestPullVerified(c *check.C) { // unless keychain is manually updated to contain the daemon's sign key. verifiedName := "hello-world" - defer deleteImages(verifiedName) // pull it expected := "The image you are pulling has been verified" @@ -88,8 +85,6 @@ func (s *DockerSuite) TestPullVerified(c *check.C) { func (s *DockerSuite) TestPullImageFromCentralRegistry(c *check.C) { testRequires(c, Network) - defer deleteImages("hello-world") - pullCmd := exec.Command(dockerBinary, "pull", "hello-world") if out, _, err := runCommandWithOutput(pullCmd); err != nil { c.Fatalf("pulling the hello-world image from the registry has failed: %s, %v", out, err) diff --git a/integration-cli/docker_cli_push_test.go b/integration-cli/docker_cli_push_test.go index 3fc1ae3a0..44d34dd63 100644 --- a/integration-cli/docker_cli_push_test.go +++ b/integration-cli/docker_cli_push_test.go @@ -22,7 +22,6 @@ func (s *DockerSuite) TestPushBusyboxImage(c *check.C) { if out, _, err := runCommandWithOutput(tagCmd); err != nil { c.Fatalf("image tagging failed: %s, %v", out, err) } - defer deleteImages(repoName) pushCmd := exec.Command(dockerBinary, "push", repoName) if out, _, err := runCommandWithOutput(pushCmd); err != nil { @@ -77,12 +76,10 @@ func (s *DockerSuite) TestPushMultipleTags(c *check.C) { if out, _, err := runCommandWithOutput(tagCmd1); err != nil { c.Fatalf("image tagging failed: %s, %v", out, err) } - defer deleteImages(repoTag1) tagCmd2 := exec.Command(dockerBinary, "tag", "busybox", repoTag2) if out, _, err := runCommandWithOutput(tagCmd2); err != nil { c.Fatalf("image tagging failed: %s, %v", out, err) } - defer deleteImages(repoTag2) pushCmd := exec.Command(dockerBinary, "push", repoName) if out, _, err := runCommandWithOutput(pushCmd); err != nil { @@ -97,7 +94,6 @@ func (s *DockerSuite) TestPushInterrupt(c *check.C) { if out, _, err := runCommandWithOutput(exec.Command(dockerBinary, "tag", "busybox", repoName)); err != nil { c.Fatalf("image tagging failed: %s, %v", out, err) } - defer deleteImages(repoName) pushCmd := exec.Command(dockerBinary, "push", repoName) if err := pushCmd.Start(); err != nil { diff --git a/integration-cli/docker_cli_rm_test.go b/integration-cli/docker_cli_rm_test.go index c330bb76a..b8d1b843d 100644 --- a/integration-cli/docker_cli_rm_test.go +++ b/integration-cli/docker_cli_rm_test.go @@ -87,7 +87,6 @@ func (s *DockerSuite) TestRmContainerOrphaning(c *check.C) { // build first dockerfile img1, err := buildImage(img, dockerfile1, true) - defer deleteImages(img1) if err != nil { c.Fatalf("Could not build image %s: %v", img, err) } diff --git a/integration-cli/docker_cli_run_test.go b/integration-cli/docker_cli_run_test.go index 8da6f3b87..342137c47 100644 --- a/integration-cli/docker_cli_run_test.go +++ b/integration-cli/docker_cli_run_test.go @@ -447,7 +447,6 @@ func (s *DockerSuite) TestRunCreateVolumesInSymlinkDir(c *check.C) { if _, err := buildImage(name, dockerFile, false); err != nil { c.Fatal(err) } - defer deleteImages(name) out, _, err := runCommandWithOutput(exec.Command(dockerBinary, "run", "-v", "/test/test", name)) if err != nil { @@ -604,7 +603,6 @@ func (s *DockerSuite) TestRunCreateVolume(c *check.C) { // Note that this bug happens only with symlinks with a target that starts with '/'. func (s *DockerSuite) TestRunCreateVolumeWithSymlink(c *check.C) { image := "docker-test-createvolumewithsymlink" - defer deleteImages(image) buildCmd := exec.Command(dockerBinary, "build", "-t", image, "-") buildCmd.Stdin = strings.NewReader(`FROM busybox @@ -644,7 +642,6 @@ func (s *DockerSuite) TestRunCreateVolumeWithSymlink(c *check.C) { // Tests that a volume path that has a symlink exists in a container mounting it with `--volumes-from`. func (s *DockerSuite) TestRunVolumesFromSymlinkPath(c *check.C) { name := "docker-test-volumesfromsymlinkpath" - defer deleteImages(name) buildCmd := exec.Command(dockerBinary, "build", "-t", name, "-") buildCmd.Stdin = strings.NewReader(`FROM busybox @@ -1746,7 +1743,6 @@ func (s *DockerSuite) TestRunState(c *check.C) { // Test for #1737 func (s *DockerSuite) TestRunCopyVolumeUidGid(c *check.C) { name := "testrunvolumesuidgid" - defer deleteImages(name) _, err := buildImage(name, `FROM busybox RUN echo 'dockerio:x:1001:1001::/bin:/bin/false' >> /etc/passwd @@ -1772,7 +1768,6 @@ func (s *DockerSuite) TestRunCopyVolumeUidGid(c *check.C) { // Test for #1582 func (s *DockerSuite) TestRunCopyVolumeContent(c *check.C) { name := "testruncopyvolumecontent" - defer deleteImages(name) _, err := buildImage(name, `FROM busybox RUN mkdir -p /hello/local && echo hello > /hello/local/world`, @@ -1794,7 +1789,6 @@ func (s *DockerSuite) TestRunCopyVolumeContent(c *check.C) { func (s *DockerSuite) TestRunCleanupCmdOnEntrypoint(c *check.C) { name := "testrunmdcleanuponentrypoint" - defer deleteImages(name) if _, err := buildImage(name, `FROM busybox ENTRYPOINT ["echo"] @@ -2349,7 +2343,6 @@ func (s *DockerSuite) TestRunCreateVolumeEtc(c *check.C) { } func (s *DockerSuite) TestVolumesNoCopyData(c *check.C) { - defer deleteImages("dataimage") if _, err := buildImage("dataimage", `FROM busybox RUN mkdir -p /foo @@ -2430,7 +2423,6 @@ func (s *DockerSuite) TestRunVolumesCleanPaths(c *check.C) { true); err != nil { c.Fatal(err) } - defer deleteImages("run_volumes_clean_paths") cmd := exec.Command(dockerBinary, "run", "-v", "/foo", "-v", "/bar/", "--name", "dark_helmet", "run_volumes_clean_paths") if out, _, err := runCommandWithOutput(cmd); err != nil { diff --git a/integration-cli/docker_cli_save_load_test.go b/integration-cli/docker_cli_save_load_test.go index f74f69fcc..fe6bf2bfc 100644 --- a/integration-cli/docker_cli_save_load_test.go +++ b/integration-cli/docker_cli_save_load_test.go @@ -131,7 +131,6 @@ func (s *DockerSuite) TestSaveSingleTag(c *check.C) { repoName := "foobar-save-single-tag-test" tagCmd := exec.Command(dockerBinary, "tag", "busybox:latest", fmt.Sprintf("%v:latest", repoName)) - defer deleteImages(repoName) if out, _, err := runCommandWithOutput(tagCmd); err != nil { c.Fatalf("failed to tag repo: %s, %v", out, err) } @@ -157,7 +156,6 @@ func (s *DockerSuite) TestSaveImageId(c *check.C) { repoName := "foobar-save-image-id-test" tagCmd := exec.Command(dockerBinary, "tag", "emptyfs:latest", fmt.Sprintf("%v:latest", repoName)) - defer deleteImages(repoName) if out, _, err := runCommandWithOutput(tagCmd); err != nil { c.Fatalf("failed to tag repo: %s, %v", out, err) } @@ -264,7 +262,6 @@ func (s *DockerSuite) TestSaveMultipleNames(c *check.C) { if out, _, err := runCommandWithOutput(tagCmd); err != nil { c.Fatalf("failed to tag repo: %s, %v", out, err) } - defer deleteImages(repoName + "-one") // Make two images tagCmd = exec.Command(dockerBinary, "tag", "emptyfs:latest", fmt.Sprintf("%v-two:latest", repoName)) @@ -272,7 +269,6 @@ func (s *DockerSuite) TestSaveMultipleNames(c *check.C) { if err != nil { c.Fatalf("failed to tag repo: %s, %v", out, err) } - defer deleteImages(repoName + "-two") out, _, err = runCommandPipelineWithOutput( exec.Command(dockerBinary, "save", fmt.Sprintf("%v-one", repoName), fmt.Sprintf("%v-two:latest", repoName)), @@ -311,9 +307,7 @@ func (s *DockerSuite) TestSaveRepoWithMultipleImages(c *check.C) { tagBar := repoName + ":bar" idFoo := makeImage("busybox:latest", tagFoo) - defer deleteImages(idFoo) idBar := makeImage("busybox:latest", tagBar) - defer deleteImages(idBar) deleteImages(repoName) @@ -358,7 +352,6 @@ func (s *DockerSuite) TestSaveDirectoryPermissions(c *check.C) { os.Mkdir(extractionDirectory, 0777) defer os.RemoveAll(tmpDir) - defer deleteImages(name) _, err = buildImage(name, `FROM busybox RUN adduser -D user && mkdir -p /opt/a/b && chown -R user:user /opt/a diff --git a/integration-cli/docker_cli_tag_test.go b/integration-cli/docker_cli_tag_test.go index 1b4d36b7b..35225f9c1 100644 --- a/integration-cli/docker_cli_tag_test.go +++ b/integration-cli/docker_cli_tag_test.go @@ -18,9 +18,6 @@ func (s *DockerSuite) TestTagUnprefixedRepoByName(c *check.C) { if out, _, err := runCommandWithOutput(tagCmd); err != nil { c.Fatal(out, err) } - - deleteImages("testfoobarbaz") - } // tagging an image by ID in a new unprefixed repo should work @@ -36,9 +33,6 @@ func (s *DockerSuite) TestTagUnprefixedRepoByID(c *check.C) { if out, _, err = runCommandWithOutput(tagCmd); err != nil { c.Fatal(out, err) } - - deleteImages("testfoobarbaz") - } // ensure we don't allow the use of invalid repository names; these tag operations should fail @@ -104,8 +98,6 @@ func (s *DockerSuite) TestTagExistedNameWithoutForce(c *check.C) { if err == nil || !strings.Contains(out, "Conflict: Tag test is already set to image") { c.Fatal("tag busybox busybox:test should have failed,because busybox:test is existed") } - deleteImages("busybox:test") - } // tag an image with an existed tag name with -f option should work @@ -122,8 +114,6 @@ func (s *DockerSuite) TestTagExistedNameWithForce(c *check.C) { if out, _, err := runCommandWithOutput(tagCmd); err != nil { c.Fatal(out, err) } - deleteImages("busybox:test") - } // ensure tagging using official names works diff --git a/integration-cli/docker_utils.go b/integration-cli/docker_utils.go index 20e87244e..688de68a1 100644 --- a/integration-cli/docker_utils.go +++ b/integration-cli/docker_utils.go @@ -396,6 +396,55 @@ func deleteAllContainers() error { return nil } +var protectedImages = map[string]struct{}{} + +func init() { + out, err := exec.Command(dockerBinary, "images").CombinedOutput() + if err != nil { + panic(err) + } + lines := strings.Split(string(out), "\n")[1:] + for _, l := range lines { + if l == "" { + continue + } + fields := strings.Fields(l) + imgTag := fields[0] + ":" + fields[1] + protectedImages[imgTag] = struct{}{} + } +} + +func deleteAllImages() error { + out, err := exec.Command(dockerBinary, "images").CombinedOutput() + if err != nil { + return err + } + lines := strings.Split(string(out), "\n")[1:] + var imgs []string + for _, l := range lines { + if l == "" { + continue + } + fields := strings.Fields(l) + imgTag := fields[0] + ":" + fields[1] + if _, ok := protectedImages[imgTag]; !ok { + if fields[0] == "" { + imgs = append(imgs, fields[2]) + continue + } + imgs = append(imgs, imgTag) + } + } + if len(imgs) == 0 { + return nil + } + args := append([]string{"rmi", "-f"}, imgs...) + if err := exec.Command(dockerBinary, args...).Run(); err != nil { + return err + } + return nil +} + func getPausedContainers() (string, error) { getPausedContainersCmd := exec.Command(dockerBinary, "ps", "-f", "status=paused", "-q", "-a") out, exitCode, err := runCommandWithOutput(getPausedContainersCmd) From 07795c3f5db3aa8ff592b0606ab76d32db4c6d25 Mon Sep 17 00:00:00 2001 From: Daniel Antlinger Date: Thu, 23 Apr 2015 11:43:08 -0700 Subject: [PATCH 16/58] fix runtime issue for TestEventsFilterContainer Signed-off-by: Daniel Antlinger Signed-off-by: Alexander Morozov --- integration-cli/docker_cli_events_test.go | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/integration-cli/docker_cli_events_test.go b/integration-cli/docker_cli_events_test.go index b8e24260a..16e03bfe3 100644 --- a/integration-cli/docker_cli_events_test.go +++ b/integration-cli/docker_cli_events_test.go @@ -322,12 +322,15 @@ func (s *DockerSuite) TestEventsFilterContainer(c *check.C) { nameID := make(map[string]string) for _, name := range []string{"container_1", "container_2"} { - out, _, err := runCommandWithOutput(exec.Command(dockerBinary, "run", "-d", "--name", name, "busybox", "true")) + out, _, err := runCommandWithOutput(exec.Command(dockerBinary, "run", "--name", name, "busybox", "true")) + if err != nil { + c.Fatalf("Error: %v, Output: %s", err, out) + } + id, err := inspectField(name, "Id") if err != nil { c.Fatal(err) } - nameID[name] = strings.TrimSpace(out) - waitInspect(name, "{{.State.Runing }}", "false", 5) + nameID[name] = id } until := fmt.Sprintf("%d", daemonTime(c).Unix()) From 11a5f1af01842acf9a25ccebb59f36472ae51170 Mon Sep 17 00:00:00 2001 From: Anton Tiurin Date: Fri, 24 Apr 2015 00:39:05 +0300 Subject: [PATCH 17/58] statsCollector: fix data race in run() statsCollector.publishers must be protected to prevent modifications during the iteration in run(). Being locked for a long time is bad, so pairs of containers & publishers (pointers) are copied to release the lock fast. Signed-off-by: Anton Tiurin --- daemon/stats_collector.go | 36 ++++++++++++++++++++++++++++-------- 1 file changed, 28 insertions(+), 8 deletions(-) diff --git a/daemon/stats_collector.go b/daemon/stats_collector.go index 5677a8634..22239743a 100644 --- a/daemon/stats_collector.go +++ b/daemon/stats_collector.go @@ -76,22 +76,42 @@ func (s *statsCollector) unsubscribe(c *Container, ch chan interface{}) { } func (s *statsCollector) run() { + type publishersPair struct { + container *Container + publisher *pubsub.Publisher + } + // we cannot determine the capacity here. + // it will grow enough in first iteration + var pairs []publishersPair + for range time.Tick(s.interval) { + systemUsage, err := s.getSystemCpuUsage() + if err != nil { + logrus.Errorf("collecting system cpu usage: %v", err) + continue + } + + // it does not make sense in the first iteration, + // but saves allocations in further iterations + pairs = pairs[:0] + + s.m.Lock() for container, publisher := range s.publishers { - systemUsage, err := s.getSystemCpuUsage() - if err != nil { - logrus.Errorf("collecting system cpu usage for %s: %v", container.ID, err) - continue - } - stats, err := container.Stats() + // copy pointers here to release the lock ASAP + pairs = append(pairs, publishersPair{container, publisher}) + } + s.m.Unlock() + + for _, pair := range pairs { + stats, err := pair.container.Stats() if err != nil { if err != execdriver.ErrNotRunning { - logrus.Errorf("collecting stats for %s: %v", container.ID, err) + logrus.Errorf("collecting stats for %s: %v", pair.container.ID, err) } continue } stats.SystemUsage = systemUsage - publisher.Publish(stats) + pair.publisher.Publish(stats) } } } From 887ad57cfa46df542001a1bb4e3ab052ce5f5ed9 Mon Sep 17 00:00:00 2001 From: Alexander Morozov Date: Fri, 24 Apr 2015 11:05:17 -0700 Subject: [PATCH 18/58] Use -f for rm instead of kill before Signed-off-by: Alexander Morozov --- integration-cli/docker_utils.go | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/integration-cli/docker_utils.go b/integration-cli/docker_utils.go index 20e87244e..907be173c 100644 --- a/integration-cli/docker_utils.go +++ b/integration-cli/docker_utils.go @@ -361,9 +361,7 @@ func readBody(b io.ReadCloser) ([]byte, error) { func deleteContainer(container string) error { container = strings.TrimSpace(strings.Replace(container, "\n", " ", -1)) - killArgs := strings.Split(fmt.Sprintf("kill %v", container), " ") - runCommand(exec.Command(dockerBinary, killArgs...)) - rmArgs := strings.Split(fmt.Sprintf("rm -v %v", container), " ") + rmArgs := strings.Split(fmt.Sprintf("rm -fv %v", container), " ") exitCode, err := runCommand(exec.Command(dockerBinary, rmArgs...)) // set error manually if not set if exitCode != 0 && err == nil { From 366ee6bdfa9d2c87d006a162fc951ecc0f68051a Mon Sep 17 00:00:00 2001 From: Darren Shepherd Date: Fri, 24 Apr 2015 12:23:54 -0700 Subject: [PATCH 19/58] Expose ParseRestartPolicy ParseRestartPolicy is useful function for third party go programs to use so that they can parse the restart policy in the same way that Docker does Signed-off-by: Darren Shepherd --- runconfig/parse.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/runconfig/parse.go b/runconfig/parse.go index 2cdb2d331..47feac866 100644 --- a/runconfig/parse.go +++ b/runconfig/parse.go @@ -277,7 +277,7 @@ func Parse(cmd *flag.FlagSet, args []string) (*Config, *HostConfig, *flag.FlagSe return nil, nil, cmd, fmt.Errorf("--net: invalid net mode: %v", err) } - restartPolicy, err := parseRestartPolicy(*flRestartPolicy) + restartPolicy, err := ParseRestartPolicy(*flRestartPolicy) if err != nil { return nil, nil, cmd, err } @@ -374,8 +374,8 @@ func convertKVStringsToMap(values []string) map[string]string { return result } -// parseRestartPolicy returns the parsed policy or an error indicating what is incorrect -func parseRestartPolicy(policy string) (RestartPolicy, error) { +// ParseRestartPolicy returns the parsed policy or an error indicating what is incorrect +func ParseRestartPolicy(policy string) (RestartPolicy, error) { p := RestartPolicy{} if policy == "" { From 9bea123bddb9d2ce8b2aa517c2a2a4b269ed39bc Mon Sep 17 00:00:00 2001 From: Alexander Morozov Date: Fri, 24 Apr 2015 13:16:51 -0700 Subject: [PATCH 20/58] Not protect dangling images for integration-cli Signed-off-by: Alexander Morozov --- integration-cli/docker_utils.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/integration-cli/docker_utils.go b/integration-cli/docker_utils.go index 929426b4f..51ecacb33 100644 --- a/integration-cli/docker_utils.go +++ b/integration-cli/docker_utils.go @@ -408,7 +408,10 @@ func init() { } fields := strings.Fields(l) imgTag := fields[0] + ":" + fields[1] - protectedImages[imgTag] = struct{}{} + // just for case if we have dangling images in tested daemon + if imgTag != ":" { + protectedImages[imgTag] = struct{}{} + } } } From f696b1071a296bee1f4ac7cafa807ce337fb9f2c Mon Sep 17 00:00:00 2001 From: Alexander Morozov Date: Fri, 24 Apr 2015 14:16:56 -0700 Subject: [PATCH 21/58] Implement DockerRegistrySuite in integration-cli To avoid manually creating and destroying registrys in tests. Signed-off-by: Alexander Morozov --- integration-cli/check_test.go | 25 +++++++++- integration-cli/docker_cli_by_digest_test.go | 48 ++++---------------- integration-cli/docker_cli_pull_test.go | 5 +- integration-cli/docker_cli_push_test.go | 22 +++------ integration-cli/docker_utils.go | 5 +- 5 files changed, 43 insertions(+), 62 deletions(-) diff --git a/integration-cli/check_test.go b/integration-cli/check_test.go index f6dbdb8a9..533ac127c 100644 --- a/integration-cli/check_test.go +++ b/integration-cli/check_test.go @@ -24,6 +24,10 @@ func (s *TimerSuite) TearDownTest(c *check.C) { fmt.Printf("%-60s%.2f\n", c.TestName(), time.Since(s.start).Seconds()) } +func init() { + check.Suite(&DockerSuite{}) +} + type DockerSuite struct { TimerSuite } @@ -34,4 +38,23 @@ func (s *DockerSuite) TearDownTest(c *check.C) { s.TimerSuite.TearDownTest(c) } -var _ = check.Suite(&DockerSuite{}) +func init() { + check.Suite(&DockerRegistrySuite{ + ds: &DockerSuite{}, + }) +} + +type DockerRegistrySuite struct { + ds *DockerSuite + reg *testRegistryV2 +} + +func (s *DockerRegistrySuite) SetUpTest(c *check.C) { + s.reg = setupRegistry(c) + s.ds.SetUpTest(c) +} + +func (s *DockerRegistrySuite) TearDownTest(c *check.C) { + s.reg.Close() + s.ds.TearDownTest(c) +} diff --git a/integration-cli/docker_cli_by_digest_test.go b/integration-cli/docker_cli_by_digest_test.go index 6470d974c..b9b319cf9 100644 --- a/integration-cli/docker_cli_by_digest_test.go +++ b/integration-cli/docker_cli_by_digest_test.go @@ -62,9 +62,7 @@ func setupImageWithTag(tag string) (string, error) { return pushDigest, nil } -func (s *DockerSuite) TestPullByTagDisplaysDigest(c *check.C) { - defer setupRegistry(c)() - +func (s *DockerRegistrySuite) TestPullByTagDisplaysDigest(c *check.C) { pushDigest, err := setupImage() if err != nil { c.Fatalf("error setting up image: %v", err) @@ -88,12 +86,9 @@ func (s *DockerSuite) TestPullByTagDisplaysDigest(c *check.C) { if pushDigest != pullDigest { c.Fatalf("push digest %q didn't match pull digest %q", pushDigest, pullDigest) } - } -func (s *DockerSuite) TestPullByDigest(c *check.C) { - defer setupRegistry(c)() - +func (s *DockerRegistrySuite) TestPullByDigest(c *check.C) { pushDigest, err := setupImage() if err != nil { c.Fatalf("error setting up image: %v", err) @@ -118,12 +113,9 @@ func (s *DockerSuite) TestPullByDigest(c *check.C) { if pushDigest != pullDigest { c.Fatalf("push digest %q didn't match pull digest %q", pushDigest, pullDigest) } - } -func (s *DockerSuite) TestCreateByDigest(c *check.C) { - defer setupRegistry(c)() - +func (s *DockerRegistrySuite) TestCreateByDigest(c *check.C) { pushDigest, err := setupImage() if err != nil { c.Fatalf("error setting up image: %v", err) @@ -145,12 +137,9 @@ func (s *DockerSuite) TestCreateByDigest(c *check.C) { if res != imageReference { c.Fatalf("unexpected Config.Image: %s (expected %s)", res, imageReference) } - } -func (s *DockerSuite) TestRunByDigest(c *check.C) { - defer setupRegistry(c)() - +func (s *DockerRegistrySuite) TestRunByDigest(c *check.C) { pushDigest, err := setupImage() if err != nil { c.Fatalf("error setting up image: %v", err) @@ -181,12 +170,9 @@ func (s *DockerSuite) TestRunByDigest(c *check.C) { if res != imageReference { c.Fatalf("unexpected Config.Image: %s (expected %s)", res, imageReference) } - } -func (s *DockerSuite) TestRemoveImageByDigest(c *check.C) { - defer setupRegistry(c)() - +func (s *DockerRegistrySuite) TestRemoveImageByDigest(c *check.C) { digest, err := setupImage() if err != nil { c.Fatalf("error setting up image: %v", err) @@ -217,12 +203,9 @@ func (s *DockerSuite) TestRemoveImageByDigest(c *check.C) { } else if !strings.Contains(err.Error(), "No such image") { c.Fatalf("expected 'No such image' output, got %v", err) } - } -func (s *DockerSuite) TestBuildByDigest(c *check.C) { - defer setupRegistry(c)() - +func (s *DockerRegistrySuite) TestBuildByDigest(c *check.C) { digest, err := setupImage() if err != nil { c.Fatalf("error setting up image: %v", err) @@ -262,12 +245,9 @@ func (s *DockerSuite) TestBuildByDigest(c *check.C) { if res != imageID { c.Fatalf("Image %s, expected %s", res, imageID) } - } -func (s *DockerSuite) TestTagByDigest(c *check.C) { - defer setupRegistry(c)() - +func (s *DockerRegistrySuite) TestTagByDigest(c *check.C) { digest, err := setupImage() if err != nil { c.Fatalf("error setting up image: %v", err) @@ -302,12 +282,9 @@ func (s *DockerSuite) TestTagByDigest(c *check.C) { if tagID != expectedID { c.Fatalf("expected image id %q, got %q", expectedID, tagID) } - } -func (s *DockerSuite) TestListImagesWithoutDigests(c *check.C) { - defer setupRegistry(c)() - +func (s *DockerRegistrySuite) TestListImagesWithoutDigests(c *check.C) { digest, err := setupImage() if err != nil { c.Fatalf("error setting up image: %v", err) @@ -334,8 +311,7 @@ func (s *DockerSuite) TestListImagesWithoutDigests(c *check.C) { } -func (s *DockerSuite) TestListImagesWithDigests(c *check.C) { - defer setupRegistry(c)() +func (s *DockerRegistrySuite) TestListImagesWithDigests(c *check.C) { // setup image1 digest1, err := setupImageWithTag("tag1") @@ -482,12 +458,9 @@ func (s *DockerSuite) TestListImagesWithDigests(c *check.C) { if !busyboxRe.MatchString(out) { c.Fatalf("expected %q: %s", busyboxRe.String(), out) } - } -func (s *DockerSuite) TestDeleteImageByIDOnlyPulledByDigest(c *check.C) { - defer setupRegistry(c)() - +func (s *DockerRegistrySuite) TestDeleteImageByIDOnlyPulledByDigest(c *check.C) { pushDigest, err := setupImage() if err != nil { c.Fatalf("error setting up image: %v", err) @@ -511,5 +484,4 @@ func (s *DockerSuite) TestDeleteImageByIDOnlyPulledByDigest(c *check.C) { if _, err := runCommand(cmd); err != nil { c.Fatalf("error deleting image by id: %v", err) } - } diff --git a/integration-cli/docker_cli_pull_test.go b/integration-cli/docker_cli_pull_test.go index bdb55f35d..a3ded8f03 100644 --- a/integration-cli/docker_cli_pull_test.go +++ b/integration-cli/docker_cli_pull_test.go @@ -9,9 +9,7 @@ import ( ) // See issue docker/docker#8141 -func (s *DockerSuite) TestPullImageWithAliases(c *check.C) { - defer setupRegistry(c)() - +func (s *DockerRegistrySuite) TestPullImageWithAliases(c *check.C) { repoName := fmt.Sprintf("%v/dockercli/busybox", privateRegistryURL) repos := []string{} @@ -48,7 +46,6 @@ func (s *DockerSuite) TestPullImageWithAliases(c *check.C) { c.Fatalf("Image %v shouldn't have been pulled down", repo) } } - } // pulling library/hello-world should show verified message diff --git a/integration-cli/docker_cli_push_test.go b/integration-cli/docker_cli_push_test.go index 44d34dd63..8f7ee3158 100644 --- a/integration-cli/docker_cli_push_test.go +++ b/integration-cli/docker_cli_push_test.go @@ -13,9 +13,7 @@ import ( ) // pulling an image from the central registry should work -func (s *DockerSuite) TestPushBusyboxImage(c *check.C) { - defer setupRegistry(c)() - +func (s *DockerRegistrySuite) TestPushBusyboxImage(c *check.C) { repoName := fmt.Sprintf("%v/dockercli/busybox", privateRegistryURL) // tag the image to upload it to the private registry tagCmd := exec.Command(dockerBinary, "tag", "busybox", repoName) @@ -37,9 +35,7 @@ func (s *DockerSuite) TestPushUnprefixedRepo(c *check.C) { } } -func (s *DockerSuite) TestPushUntagged(c *check.C) { - defer setupRegistry(c)() - +func (s *DockerRegistrySuite) TestPushUntagged(c *check.C) { repoName := fmt.Sprintf("%v/dockercli/busybox", privateRegistryURL) expected := "Repository does not exist" @@ -51,9 +47,7 @@ func (s *DockerSuite) TestPushUntagged(c *check.C) { } } -func (s *DockerSuite) TestPushBadTag(c *check.C) { - defer setupRegistry(c)() - +func (s *DockerRegistrySuite) TestPushBadTag(c *check.C) { repoName := fmt.Sprintf("%v/dockercli/busybox:latest", privateRegistryURL) expected := "does not exist" @@ -65,9 +59,7 @@ func (s *DockerSuite) TestPushBadTag(c *check.C) { } } -func (s *DockerSuite) TestPushMultipleTags(c *check.C) { - defer setupRegistry(c)() - +func (s *DockerRegistrySuite) TestPushMultipleTags(c *check.C) { repoName := fmt.Sprintf("%v/dockercli/busybox", privateRegistryURL) repoTag1 := fmt.Sprintf("%v/dockercli/busybox:t1", privateRegistryURL) repoTag2 := fmt.Sprintf("%v/dockercli/busybox:t2", privateRegistryURL) @@ -87,8 +79,7 @@ func (s *DockerSuite) TestPushMultipleTags(c *check.C) { } } -func (s *DockerSuite) TestPushInterrupt(c *check.C) { - defer setupRegistry(c)() +func (s *DockerRegistrySuite) TestPushInterrupt(c *check.C) { repoName := fmt.Sprintf("%v/dockercli/busybox", privateRegistryURL) // tag the image and upload it to the private registry if out, _, err := runCommandWithOutput(exec.Command(dockerBinary, "tag", "busybox", repoName)); err != nil { @@ -118,8 +109,7 @@ func (s *DockerSuite) TestPushInterrupt(c *check.C) { } } -func (s *DockerSuite) TestPushEmptyLayer(c *check.C) { - defer setupRegistry(c)() +func (s *DockerRegistrySuite) TestPushEmptyLayer(c *check.C) { repoName := fmt.Sprintf("%v/dockercli/emptylayer", privateRegistryURL) emptyTarball, err := ioutil.TempFile("", "empty_tarball") if err != nil { diff --git a/integration-cli/docker_utils.go b/integration-cli/docker_utils.go index 929426b4f..931f3e269 100644 --- a/integration-cli/docker_utils.go +++ b/integration-cli/docker_utils.go @@ -1125,7 +1125,7 @@ func daemonTime(c *check.C) time.Time { return dt } -func setupRegistry(c *check.C) func() { +func setupRegistry(c *check.C) *testRegistryV2 { testRequires(c, RegistryHosting) reg, err := newTestRegistryV2(c) if err != nil { @@ -1143,8 +1143,7 @@ func setupRegistry(c *check.C) func() { if err != nil { c.Fatal("Timeout waiting for test registry to become available") } - - return func() { reg.Close() } + return reg } // appendBaseEnv appends the minimum set of environment variables to exec the From 29a3bbf2b375111b9494df1ce5ee457508f7acad Mon Sep 17 00:00:00 2001 From: Ankush Agarwal Date: Mon, 20 Apr 2015 13:05:48 -0700 Subject: [PATCH 22/58] Eliminate json.Marshal from graph/export.go and volumes/volume.go Fixes #12531 Fixes #12530 Signed-off-by: Ankush Agarwal --- graph/export.go | 11 +++++++++-- volumes/volume.go | 13 +++++++------ 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/graph/export.go b/graph/export.go index 00cfa8975..91382c60e 100644 --- a/graph/export.go +++ b/graph/export.go @@ -85,8 +85,15 @@ func (s *TagStore) ImageExport(imageExportConfig *ImageExportConfig) error { } // write repositories, if there is something to write if len(rootRepoMap) > 0 { - rootRepoJson, _ := json.Marshal(rootRepoMap) - if err := ioutil.WriteFile(path.Join(tempdir, "repositories"), rootRepoJson, os.FileMode(0644)); err != nil { + f, err := os.OpenFile(path.Join(tempdir, "repositories"), os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0644) + if err != nil { + f.Close() + return err + } + if err := json.NewEncoder(f).Encode(rootRepoMap); err != nil { + return err + } + if err := f.Close(); err != nil { return err } } else { diff --git a/volumes/volume.go b/volumes/volume.go index 87aa4ad25..164469265 100644 --- a/volumes/volume.go +++ b/volumes/volume.go @@ -2,7 +2,6 @@ package volumes import ( "encoding/json" - "io/ioutil" "os" "path/filepath" "sync" @@ -81,17 +80,19 @@ func (v *Volume) ToDisk() error { } func (v *Volume) toDisk() error { - data, err := json.Marshal(v) + jsonPath, err := v.jsonPath() if err != nil { return err } - - pth, err := v.jsonPath() + f, err := os.OpenFile(jsonPath, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0644) if err != nil { return err } - - return ioutil.WriteFile(pth, data, 0666) + if err := json.NewEncoder(f).Encode(v); err != nil { + f.Close() + return err + } + return f.Close() } func (v *Volume) FromDisk() error { From ae9905ef9c5e8fe793e6a6269bb720618f4fcaed Mon Sep 17 00:00:00 2001 From: John Howard Date: Fri, 24 Apr 2015 16:52:32 -0700 Subject: [PATCH 23/58] Fixed typo 'configuring' Signed-off-by: John Howard --- daemon/networkdriver/bridge/driver.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/daemon/networkdriver/bridge/driver.go b/daemon/networkdriver/bridge/driver.go index f1397dc32..04e3737dc 100644 --- a/daemon/networkdriver/bridge/driver.go +++ b/daemon/networkdriver/bridge/driver.go @@ -233,7 +233,7 @@ func InitDriver(config *Config) error { // Configure iptables for link support if config.EnableIptables { if err := setupIPTables(addrv4, config.InterContainerCommunication, config.EnableIpMasq); err != nil { - logrus.Errorf("Error configuing iptables: %s", err) + logrus.Errorf("Error configuring iptables: %s", err) return err } // call this on Firewalld reload From 2188c8d2f41f4905411a40c30f4c703d7f4e0fcf Mon Sep 17 00:00:00 2001 From: Sergey Alekseev Date: Sat, 25 Apr 2015 11:28:39 +0300 Subject: [PATCH 24/58] Fix documentation typo in articles/basics.md Signed-off-by: Sergey Alekseev --- docs/sources/articles/basics.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/sources/articles/basics.md b/docs/sources/articles/basics.md index 94264ece6..7d7c15409 100644 --- a/docs/sources/articles/basics.md +++ b/docs/sources/articles/basics.md @@ -172,7 +172,7 @@ will be stored (as a diff). See which images you already have using the # Commit your container to a new named image $ docker commit - # List your containers + # List your images $ docker images You now have an image state from which you can create new instances. From 8f752ffeafd2f8c08035a5e39220fe17c9309fd7 Mon Sep 17 00:00:00 2001 From: Hu Keping Date: Fri, 24 Apr 2015 19:57:04 +0800 Subject: [PATCH 25/58] Add test for REST API container rename Signed-off-by: Hu Keping --- integration-cli/docker_api_containers_test.go | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/integration-cli/docker_api_containers_test.go b/integration-cli/docker_api_containers_test.go index 24efbb7a2..172e3e993 100644 --- a/integration-cli/docker_api_containers_test.go +++ b/integration-cli/docker_api_containers_test.go @@ -841,3 +841,22 @@ func (s *DockerSuite) TestStartWithTooLowMemoryLimit(c *check.C) { c.Assert(status, check.Equals, http.StatusInternalServerError) c.Assert(strings.Contains(string(b), "Minimum memory limit allowed is 4MB"), check.Equals, true) } + +func (s *DockerSuite) TestContainerApiRename(c *check.C) { + runCmd := exec.Command(dockerBinary, "run", "--name", "first_name", "-d", "busybox", "sh") + out, _, err := runCommandWithOutput(runCmd) + c.Assert(err, check.IsNil) + + containerID := strings.TrimSpace(out) + newName := "new_name" + stringid.GenerateRandomID() + statusCode, _, err := sockRequest("POST", "/containers/"+containerID+"/rename?name="+newName, nil) + + // 204 No Content is expected, not 200 + c.Assert(statusCode, check.Equals, http.StatusNoContent) + c.Assert(err, check.IsNil) + + name, err := inspectField(containerID, "Name") + if name != "/"+newName { + c.Fatalf("Failed to rename container, expected %v, got %v. Container rename API failed", newName, name) + } +} From bc149be69c5ad22f82269427dd4b4aed9df4fa40 Mon Sep 17 00:00:00 2001 From: Doug Davis Date: Sat, 25 Apr 2015 04:42:43 -0700 Subject: [PATCH 26/58] A fix for = in env values in linked containers Closes: #12763 Signed-off-by: Doug Davis --- integration-cli/docker_cli_links_test.go | 21 +++++++++++++++++++++ links/links.go | 4 ++-- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/integration-cli/docker_cli_links_test.go b/integration-cli/docker_cli_links_test.go index 95b340be2..6bb173c10 100644 --- a/integration-cli/docker_cli_links_test.go +++ b/integration-cli/docker_cli_links_test.go @@ -310,3 +310,24 @@ func (s *DockerSuite) TestLinksUpdateOnRestart(c *check.C) { c.Fatalf("For 'onetwo' alias expected IP: %s, got: %s", realIP, ip) } } + +func (s *DockerSuite) TestLinksEnvs(c *check.C) { + runCmd := exec.Command(dockerBinary, "run", "-d", "-e", "e1=", "-e", "e2=v2", "-e", "e3=v3=v3", "--name=first", "busybox", "top") + out, _, _, err := runCommandWithStdoutStderr(runCmd) + if err != nil { + c.Fatalf("Run of first failed: %s\n%s", out, err) + } + + runCmd = exec.Command(dockerBinary, "run", "--name=second", "--link=first:first", "busybox", "env") + + out, stde, rc, err := runCommandWithStdoutStderr(runCmd) + if err != nil || rc != 0 { + c.Fatalf("run of 2nd failed: rc: %d, out: %s\n err: %s", rc, out, stde) + } + + if !strings.Contains(out, "FIRST_ENV_e1=\n") || + !strings.Contains(out, "FIRST_ENV_e2=v2") || + !strings.Contains(out, "FIRST_ENV_e3=v3=v3") { + c.Fatalf("Incorrect output: %s", out) + } +} diff --git a/links/links.go b/links/links.go index 8bbacdd3d..935bff4ae 100644 --- a/links/links.go +++ b/links/links.go @@ -107,8 +107,8 @@ func (l *Link) ToEnv() []string { if l.ChildEnvironment != nil { for _, v := range l.ChildEnvironment { - parts := strings.Split(v, "=") - if len(parts) != 2 { + parts := strings.SplitN(v, "=", 2) + if len(parts) < 2 { continue } // Ignore a few variables that are added during docker build (and not really relevant to linked containers) From cd4f507b42e800d148b211ca2c780d01192a9041 Mon Sep 17 00:00:00 2001 From: Doug Davis Date: Sat, 25 Apr 2015 05:46:47 -0700 Subject: [PATCH 27/58] Fix race condition in API commit test Signed-off-by: Doug Davis --- integration-cli/docker_api_containers_test.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/integration-cli/docker_api_containers_test.go b/integration-cli/docker_api_containers_test.go index f14bd91c1..50958a6cd 100644 --- a/integration-cli/docker_api_containers_test.go +++ b/integration-cli/docker_api_containers_test.go @@ -614,14 +614,14 @@ func (s *DockerSuite) TestContainerApiTop(c *check.C) { } func (s *DockerSuite) TestContainerApiCommit(c *check.C) { - out, err := exec.Command(dockerBinary, "run", "-d", "busybox", "/bin/sh", "-c", "touch /test").CombinedOutput() + cName := "testapicommit" + out, err := exec.Command(dockerBinary, "run", "--name="+cName, "busybox", "/bin/sh", "-c", "touch /test").CombinedOutput() if err != nil { c.Fatal(err, out) } - id := strings.TrimSpace(string(out)) name := "testcommit" + stringid.GenerateRandomID() - status, b, err := sockRequest("POST", "/commit?repo="+name+"&testtag=tag&container="+id, nil) + status, b, err := sockRequest("POST", "/commit?repo="+name+"&testtag=tag&container="+cName, nil) c.Assert(status, check.Equals, http.StatusCreated) c.Assert(err, check.IsNil) From fa9299f4c03cf097887db26dadcc63c711c925f1 Mon Sep 17 00:00:00 2001 From: Ed Costello Date: Sat, 25 Apr 2015 14:57:01 -0400 Subject: [PATCH 28/58] Copy edits for typos Signed-off-by: Ed Costello --- docs/sources/articles/b2d_volume_resize.md | 2 +- docs/sources/articles/networking.md | 2 +- docs/sources/articles/puppet.md | 2 +- docs/sources/articles/security.md | 2 +- docs/sources/installation/SUSE.md | 2 +- docs/sources/project/create-pr.md | 2 +- docs/sources/project/review-pr.md | 2 +- docs/sources/project/test-and-docs.md | 2 +- docs/sources/reference/api/docker_remote_api_v1.10.md | 2 +- docs/sources/reference/api/docker_remote_api_v1.11.md | 2 +- docs/sources/reference/api/docker_remote_api_v1.12.md | 2 +- docs/sources/reference/api/docker_remote_api_v1.13.md | 2 +- docs/sources/reference/api/docker_remote_api_v1.14.md | 2 +- docs/sources/reference/api/docker_remote_api_v1.15.md | 4 ++-- docs/sources/reference/api/docker_remote_api_v1.16.md | 4 ++-- docs/sources/reference/api/docker_remote_api_v1.17.md | 4 ++-- docs/sources/reference/api/docker_remote_api_v1.18.md | 4 ++-- docs/sources/reference/api/docker_remote_api_v1.19.md | 4 ++-- docs/sources/reference/api/docker_remote_api_v1.9.md | 2 +- docs/sources/reference/builder.md | 8 ++++---- docs/sources/reference/run.md | 2 +- 21 files changed, 29 insertions(+), 29 deletions(-) diff --git a/docs/sources/articles/b2d_volume_resize.md b/docs/sources/articles/b2d_volume_resize.md index 65238c669..53c859095 100644 --- a/docs/sources/articles/b2d_volume_resize.md +++ b/docs/sources/articles/b2d_volume_resize.md @@ -60,7 +60,7 @@ You might need to create the bus before you can add the ISO. ## 5. Add the new VDI image In the settings for the Boot2Docker image in VirtualBox, remove the VMDK image -from the SATA contoller and add the VDI image. +from the SATA controller and add the VDI image. diff --git a/docs/sources/articles/networking.md b/docs/sources/articles/networking.md index 18529a086..823b450c7 100644 --- a/docs/sources/articles/networking.md +++ b/docs/sources/articles/networking.md @@ -576,7 +576,7 @@ As soon as the router wants to send an IPv6 packet to the first container it will transmit a neighbor solicitation request, asking, who has `2001:db8::c009`? But it will get no answer because noone on this subnet has this address. The container with this address is hidden behind the Docker host. -The Docker host has to listen to neighbor solication requests for the container +The Docker host has to listen to neighbor solicitation requests for the container address and send a response that itself is the device that is responsible for the address. This is done by a Kernel feature called `NDP Proxy`. You can enable it by executing diff --git a/docs/sources/articles/puppet.md b/docs/sources/articles/puppet.md index 50504cd47..a1b3d273a 100644 --- a/docs/sources/articles/puppet.md +++ b/docs/sources/articles/puppet.md @@ -1,5 +1,5 @@ page_title: Using Puppet -page_description: Installating and using Puppet +page_description: Installing and using Puppet page_keywords: puppet, installation, usage, docker, documentation # Using Puppet diff --git a/docs/sources/articles/security.md b/docs/sources/articles/security.md index 39a247c38..42d15e88c 100644 --- a/docs/sources/articles/security.md +++ b/docs/sources/articles/security.md @@ -249,7 +249,7 @@ may still be utilized by Docker containers on supported kernels, by directly using the clone syscall, or utilizing the 'unshare' utility. Using this, some users may find it possible to drop more capabilities from their process as user namespaces provide -an artifical capabilities set. Likewise, however, this artifical +an artificial capabilities set. Likewise, however, this artificial capabilities set may require use of 'capsh' to restrict the user-namespace capabilities set when using 'unshare'. diff --git a/docs/sources/installation/SUSE.md b/docs/sources/installation/SUSE.md index 2a0aa91d9..756ed6b5c 100644 --- a/docs/sources/installation/SUSE.md +++ b/docs/sources/installation/SUSE.md @@ -8,7 +8,7 @@ Docker is available in **openSUSE 12.3 and later**. Please note that due to its current limitations Docker is able to run only **64 bit** architecture. Docker is not part of the official repositories of openSUSE 12.3 and -openSUSE 13.1. Hence it is neccessary to add the [Virtualization +openSUSE 13.1. Hence it is necessary to add the [Virtualization repository](https://build.opensuse.org/project/show/Virtualization) from [OBS](https://build.opensuse.org/) to install the `docker` package. diff --git a/docs/sources/project/create-pr.md b/docs/sources/project/create-pr.md index e9123c463..613ab6911 100644 --- a/docs/sources/project/create-pr.md +++ b/docs/sources/project/create-pr.md @@ -77,7 +77,7 @@ Always rebase and squash your commits before making a pull request. `git commit -s` - Make sure your message includes Date: Wed, 22 Apr 2015 00:47:51 +0200 Subject: [PATCH 29/58] Replace json.Unmarshal with json.Decoder().Decode() Signed-off-by: Antonio Murdaca --- builder/parser/line_parsers.go | 2 +- daemon/execdriver/lxc/init.go | 8 ++++---- graph/load.go | 26 +++++++++++++++----------- graph/tags.go | 5 +++-- pkg/parsers/filters/parse.go | 3 +-- 5 files changed, 24 insertions(+), 20 deletions(-) diff --git a/builder/parser/line_parsers.go b/builder/parser/line_parsers.go index 5f65a8762..8db360ca3 100644 --- a/builder/parser/line_parsers.go +++ b/builder/parser/line_parsers.go @@ -233,7 +233,7 @@ func parseString(rest string) (*Node, map[string]bool, error) { // parseJSON converts JSON arrays to an AST. func parseJSON(rest string) (*Node, map[string]bool, error) { var myJson []interface{} - if err := json.Unmarshal([]byte(rest), &myJson); err != nil { + if err := json.NewDecoder(strings.NewReader(rest)).Decode(&myJson); err != nil { return nil, nil, err } diff --git a/daemon/execdriver/lxc/init.go b/daemon/execdriver/lxc/init.go index 6cdbf775e..eca1c02e2 100644 --- a/daemon/execdriver/lxc/init.go +++ b/daemon/execdriver/lxc/init.go @@ -4,7 +4,6 @@ import ( "encoding/json" "flag" "fmt" - "io/ioutil" "log" "os" "os/exec" @@ -107,12 +106,13 @@ func getArgs() *InitArgs { func setupEnv(args *InitArgs) error { // Get env var env []string - content, err := ioutil.ReadFile(".dockerenv") + dockerenv, err := os.Open(".dockerenv") if err != nil { return fmt.Errorf("Unable to load environment variables: %v", err) } - if err := json.Unmarshal(content, &env); err != nil { - return fmt.Errorf("Unable to unmarshal environment variables: %v", err) + defer dockerenv.Close() + if err := json.NewDecoder(dockerenv).Decode(&env); err != nil { + return fmt.Errorf("Unable to decode environment variables: %v", err) } // Propagate the plugin-specific container env variable env = append(env, "container="+os.Getenv("container")) diff --git a/graph/load.go b/graph/load.go index be968bab5..d978b1ee8 100644 --- a/graph/load.go +++ b/graph/load.go @@ -58,22 +58,26 @@ func (s *TagStore) Load(inTar io.ReadCloser, outStream io.Writer) error { } } - repositoriesJson, err := ioutil.ReadFile(path.Join(tmpImageDir, "repo", "repositories")) - if err == nil { - repositories := map[string]Repository{} - if err := json.Unmarshal(repositoriesJson, &repositories); err != nil { + reposJSONFile, err := os.Open(path.Join(tmpImageDir, "repo", "repositories")) + if err != nil { + if !os.IsNotExist(err) { return err } + return nil + } + defer reposJSONFile.Close() - for imageName, tagMap := range repositories { - for tag, address := range tagMap { - if err := s.SetLoad(imageName, tag, address, true, outStream); err != nil { - return err - } + repositories := map[string]Repository{} + if err := json.NewDecoder(reposJSONFile).Decode(&repositories); err != nil { + return err + } + + for imageName, tagMap := range repositories { + for tag, address := range tagMap { + if err := s.SetLoad(imageName, tag, address, true, outStream); err != nil { + return err } } - } else if !os.IsNotExist(err) { - return err } return nil diff --git a/graph/tags.go b/graph/tags.go index 39f0ffc29..abffe2f56 100644 --- a/graph/tags.go +++ b/graph/tags.go @@ -115,11 +115,12 @@ func (store *TagStore) save() error { } func (store *TagStore) reload() error { - jsonData, err := ioutil.ReadFile(store.path) + f, err := os.Open(store.path) if err != nil { return err } - if err := json.Unmarshal(jsonData, store); err != nil { + defer f.Close() + if err := json.NewDecoder(f).Decode(&store); err != nil { return err } return nil diff --git a/pkg/parsers/filters/parse.go b/pkg/parsers/filters/parse.go index 9c056bb3c..df5486d51 100644 --- a/pkg/parsers/filters/parse.go +++ b/pkg/parsers/filters/parse.go @@ -58,8 +58,7 @@ func FromParam(p string) (Args, error) { if len(p) == 0 { return args, nil } - err := json.Unmarshal([]byte(p), &args) - if err != nil { + if err := json.NewDecoder(strings.NewReader(p)).Decode(&args); err != nil { return nil, err } return args, nil From ba79f0ca1f389e3c87c19b2c326b3b6afbebc8ef Mon Sep 17 00:00:00 2001 From: Mary Anthony Date: Sun, 26 Apr 2015 10:32:43 -0700 Subject: [PATCH 30/58] Adding James and theJeztah to the list Signed-off-by: Mary Anthony --- MAINTAINERS | 2 ++ 1 file changed, 2 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index b708af774..5c02fa671 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -409,6 +409,8 @@ made through a pull request. "fredlf", "james", "moxiegirl", + "thaJeztah", + "jamtur01", "spf13", "sven" ] From cfd0f53b03d26c370e37abf651d7f481ee8c6912 Mon Sep 17 00:00:00 2001 From: Daniel Nephin Date: Sun, 26 Apr 2015 15:36:01 -0400 Subject: [PATCH 31/58] Add missing API docs about filtering by label. Signed-off-by: Daniel Nephin --- docs/sources/reference/api/docker_remote_api_v1.18.md | 2 ++ docs/sources/reference/api/docker_remote_api_v1.19.md | 2 ++ 2 files changed, 4 insertions(+) diff --git a/docs/sources/reference/api/docker_remote_api_v1.18.md b/docs/sources/reference/api/docker_remote_api_v1.18.md index c97fe9c61..a91ca8417 100644 --- a/docs/sources/reference/api/docker_remote_api_v1.18.md +++ b/docs/sources/reference/api/docker_remote_api_v1.18.md @@ -91,6 +91,7 @@ Query Parameters: - **filters** - a json encoded value of the filters (a map[string][]string) to process on the containers list. Available filters: - exited=<int> -- containers with exit code of <int> - status=(restarting|running|paused|exited) + - label=`key` or `key=value` of a container label Status Codes: @@ -1191,6 +1192,7 @@ Query Parameters: - **all** – 1/True/true or 0/False/false, default false - **filters** – a json encoded value of the filters (a map[string][]string) to process on the images list. Available filters: - dangling=true + - label=`key` or `key=value` of an image label ### Build image from a Dockerfile diff --git a/docs/sources/reference/api/docker_remote_api_v1.19.md b/docs/sources/reference/api/docker_remote_api_v1.19.md index 8c27de159..cede2e107 100644 --- a/docs/sources/reference/api/docker_remote_api_v1.19.md +++ b/docs/sources/reference/api/docker_remote_api_v1.19.md @@ -91,6 +91,7 @@ Query Parameters: - **filters** - a json encoded value of the filters (a map[string][]string) to process on the containers list. Available filters: - exited=<int> -- containers with exit code of <int> - status=(restarting|running|paused|exited) + - label=`key` or `key=value` of a container label Status Codes: @@ -1194,6 +1195,7 @@ Query Parameters: - **all** – 1/True/true or 0/False/false, default false - **filters** – a json encoded value of the filters (a map[string][]string) to process on the images list. Available filters: - dangling=true + - label=`key` or `key=value` of an image label ### Build image from a Dockerfile From 6d9439c627e36349679249d991400da45eb75587 Mon Sep 17 00:00:00 2001 From: He Simei Date: Mon, 27 Apr 2015 12:41:03 +0800 Subject: [PATCH 32/58] remove useless http call from export Signed-off-by: He Simei --- api/client/export.go | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) diff --git a/api/client/export.go b/api/client/export.go index 8f1642f60..1ff46f9b5 100644 --- a/api/client/export.go +++ b/api/client/export.go @@ -3,7 +3,6 @@ package client import ( "errors" "io" - "net/url" "os" flag "github.com/docker/docker/pkg/mflag" @@ -34,19 +33,9 @@ func (cli *DockerCli) CmdExport(args ...string) error { return errors.New("Cowardly refusing to save to a terminal. Use the -o flag or redirect.") } - if len(cmd.Args()) == 1 { - image := cmd.Arg(0) - if err := cli.stream("GET", "/containers/"+image+"/export", nil, output, nil); err != nil { - return err - } - } else { - v := url.Values{} - for _, arg := range cmd.Args() { - v.Add("names", arg) - } - if err := cli.stream("GET", "/containers/get?"+v.Encode(), nil, output, nil); err != nil { - return err - } + image := cmd.Arg(0) + if err := cli.stream("GET", "/containers/"+image+"/export", nil, output, nil); err != nil { + return err } return nil From accbbfeae4c2f3ceb68060e08e46e382cdefc975 Mon Sep 17 00:00:00 2001 From: jmzwcn Date: Mon, 27 Apr 2015 15:50:47 +0800 Subject: [PATCH 33/58] Remove dead code from daemon/daemon.go fix #12492 Signed-off-by: Daniel Zhang --- daemon/daemon.go | 6 ------ 1 file changed, 6 deletions(-) diff --git a/daemon/daemon.go b/daemon/daemon.go index d186854ad..99f5ae636 100644 --- a/daemon/daemon.go +++ b/daemon/daemon.go @@ -225,7 +225,6 @@ func (daemon *Daemon) register(container *Container, updateSuffixarray bool) err if container.IsRunning() { logrus.Debugf("killing old running container %s", container.ID) - existingPid := container.Pid container.SetStopped(&execdriver.ExitStatus{ExitCode: 0}) // We only have to handle this for lxc because the other drivers will ensure that @@ -237,11 +236,6 @@ func (daemon *Daemon) register(container *Container, updateSuffixarray bool) err cmd := &execdriver.Command{ ID: container.ID, } - var err error - cmd.ProcessConfig.Process, err = os.FindProcess(existingPid) - if err != nil { - logrus.Debugf("cannot find existing process for %d", existingPid) - } daemon.execDriver.Terminate(cmd) } From c7b2632dc8550c8aa80ebd8b229809ac37fa53e1 Mon Sep 17 00:00:00 2001 From: Antonio Murdaca Date: Mon, 27 Apr 2015 13:56:55 +0200 Subject: [PATCH 34/58] Remove c.Fatal from goroutine in TestGetContainersAttachWebsocket Signed-off-by: Antonio Murdaca --- integration-cli/docker_api_attach_test.go | 38 ++++++++++++++++------- 1 file changed, 26 insertions(+), 12 deletions(-) diff --git a/integration-cli/docker_api_attach_test.go b/integration-cli/docker_api_attach_test.go index ce7f85d30..c784d5c36 100644 --- a/integration-cli/docker_api_attach_test.go +++ b/integration-cli/docker_api_attach_test.go @@ -40,24 +40,38 @@ func (s *DockerSuite) TestGetContainersAttachWebsocket(c *check.C) { expected := []byte("hello") actual := make([]byte, len(expected)) - outChan := make(chan string) + + outChan := make(chan error) go func() { - if _, err := ws.Read(actual); err != nil { - c.Fatal(err) - } - outChan <- "done" + _, err := ws.Read(actual) + outChan <- err + close(outChan) }() - inChan := make(chan string) + inChan := make(chan error) go func() { - if _, err := ws.Write(expected); err != nil { - c.Fatal(err) - } - inChan <- "done" + _, err := ws.Write(expected) + inChan <- err + close(inChan) }() - <-inChan - <-outChan + select { + case err := <-inChan: + if err != nil { + c.Fatal(err) + } + case <-time.After(5 * time.Second): + c.Fatal("Timeout writing to ws") + } + + select { + case err := <-outChan: + if err != nil { + c.Fatal(err) + } + case <-time.After(5 * time.Second): + c.Fatal("Timeout reading from ws") + } if !bytes.Equal(expected, actual) { c.Fatal("Expected output on websocket to match input") From f30d1c1835618eadea5d0a68d1301dffd9f09b22 Mon Sep 17 00:00:00 2001 From: Aidan Hobson Sayers Date: Mon, 27 Apr 2015 01:07:30 +0100 Subject: [PATCH 35/58] Prevent deadlock on attempt to use own net Signed-off-by: Aidan Hobson Sayers --- daemon/container.go | 3 +++ integration-cli/docker_cli_run_test.go | 8 ++++++++ 2 files changed, 11 insertions(+) diff --git a/daemon/container.go b/daemon/container.go index bdfcbf447..01eef4d31 100644 --- a/daemon/container.go +++ b/daemon/container.go @@ -1515,6 +1515,9 @@ func (container *Container) getNetworkedContainer() (*Container, error) { if err != nil { return nil, err } + if container == nc { + return nil, fmt.Errorf("cannot join own network") + } if !nc.IsRunning() { return nil, fmt.Errorf("cannot join network of a non running container: %s", parts[1]) } diff --git a/integration-cli/docker_cli_run_test.go b/integration-cli/docker_cli_run_test.go index 342137c47..b7961126c 100644 --- a/integration-cli/docker_cli_run_test.go +++ b/integration-cli/docker_cli_run_test.go @@ -2657,6 +2657,14 @@ func (s *DockerSuite) TestContainerNetworkMode(c *check.C) { } } +func (s *DockerSuite) TestContainerNetworkModeToSelf(c *check.C) { + cmd := exec.Command(dockerBinary, "run", "--name=me", "--net=container:me", "busybox", "true") + out, _, err := runCommandWithOutput(cmd) + if err == nil || !strings.Contains(out, "cannot join own network") { + c.Fatalf("using container net mode to self should result in an error") + } +} + func (s *DockerSuite) TestRunModePidHost(c *check.C) { testRequires(c, NativeExecDriver, SameHostDaemon) From 9e0ffae864d6679084e84e2e27cbb9d350f6dbae Mon Sep 17 00:00:00 2001 From: Brian Goff Date: Tue, 21 Apr 2015 21:51:41 -0400 Subject: [PATCH 36/58] remove some uneeded sleeps in tests Signed-off-by: Brian Goff --- integration-cli/docker_api_logs_test.go | 38 +++++++++++---- integration-cli/docker_cli_wait_test.go | 65 ++++++++++++++++--------- 2 files changed, 71 insertions(+), 32 deletions(-) diff --git a/integration-cli/docker_api_logs_test.go b/integration-cli/docker_api_logs_test.go index bf0e1fbf4..a1723ef21 100644 --- a/integration-cli/docker_api_logs_test.go +++ b/integration-cli/docker_api_logs_test.go @@ -1,28 +1,46 @@ package main import ( + "bufio" "bytes" "fmt" "net/http" "os/exec" + "strings" + "time" "github.com/go-check/check" ) func (s *DockerSuite) TestLogsApiWithStdout(c *check.C) { - name := "logs_test" - - runCmd := exec.Command(dockerBinary, "run", "-d", "-t", "--name", name, "busybox", "bin/sh", "-c", "sleep 10 && echo "+name) - if out, _, err := runCommandWithOutput(runCmd); err != nil { - c.Fatal(out, err) + out, _ := dockerCmd(c, "run", "-d", "-t", "busybox", "/bin/sh", "-c", "while true; do echo hello; sleep 1; done") + id := strings.TrimSpace(out) + if err := waitRun(id); err != nil { + c.Fatal(err) } - status, body, err := sockRequest("GET", fmt.Sprintf("/containers/%s/logs?follow=1&stdout=1×tamps=1", name), nil) - c.Assert(status, check.Equals, http.StatusOK) - c.Assert(err, check.IsNil) + type logOut struct { + out string + status int + err error + } + chLog := make(chan logOut) - if !bytes.Contains(body, []byte(name)) { - c.Fatalf("Expected %s, got %s", name, string(body[:])) + go func() { + statusCode, body, err := sockRequestRaw("GET", fmt.Sprintf("/containers/%s/logs?follow=1&stdout=1×tamps=1", id), nil, "") + out, _ := bufio.NewReader(body).ReadString('\n') + chLog <- logOut{strings.TrimSpace(out), statusCode, err} + }() + + select { + case l := <-chLog: + c.Assert(l.status, check.Equals, http.StatusOK) + c.Assert(l.err, check.IsNil) + if !strings.HasSuffix(l.out, "hello") { + c.Fatalf("expected log output to container 'hello', but it does not") + } + case <-time.After(2 * time.Second): + c.Fatal("timeout waiting for logs to exit") } } diff --git a/integration-cli/docker_cli_wait_test.go b/integration-cli/docker_cli_wait_test.go index 09d0272bc..21f04faf0 100644 --- a/integration-cli/docker_cli_wait_test.go +++ b/integration-cli/docker_cli_wait_test.go @@ -44,19 +44,29 @@ func (s *DockerSuite) TestWaitNonBlockedExitZero(c *check.C) { // blocking wait with 0 exit code func (s *DockerSuite) TestWaitBlockedExitZero(c *check.C) { - - runCmd := exec.Command(dockerBinary, "run", "-d", "busybox", "sh", "-c", "sleep 10") - out, _, err := runCommandWithOutput(runCmd) - if err != nil { - c.Fatal(out, err) - } + out, _ := dockerCmd(c, "run", "-d", "busybox", "/bin/sh", "-c", "trap 'exit 0' SIGTERM; while true; do sleep 0.01; done") containerID := strings.TrimSpace(out) - runCmd = exec.Command(dockerBinary, "wait", containerID) - out, _, err = runCommandWithOutput(runCmd) + if err := waitRun(containerID); err != nil { + c.Fatal(err) + } - if err != nil || strings.TrimSpace(out) != "0" { - c.Fatal("failed to set up container", out, err) + chWait := make(chan string) + go func() { + out, _, _ := runCommandWithOutput(exec.Command(dockerBinary, "wait", containerID)) + chWait <- out + }() + + time.Sleep(100 * time.Millisecond) + dockerCmd(c, "stop", containerID) + + select { + case status := <-chWait: + if strings.TrimSpace(status) != "0" { + c.Fatalf("expected exit 0, got %s", status) + } + case <-time.After(2 * time.Second): + c.Fatal("timeout waiting for `docker wait` to exit") } } @@ -97,19 +107,30 @@ func (s *DockerSuite) TestWaitNonBlockedExitRandom(c *check.C) { // blocking wait with random exit code func (s *DockerSuite) TestWaitBlockedExitRandom(c *check.C) { - - runCmd := exec.Command(dockerBinary, "run", "-d", "busybox", "sh", "-c", "sleep 10; exit 99") - out, _, err := runCommandWithOutput(runCmd) - if err != nil { - c.Fatal(out, err) - } + out, _ := dockerCmd(c, "run", "-d", "busybox", "sh", "-c", "trap 'exit 99' SIGTERM; while true; do sleep 0.01; done") containerID := strings.TrimSpace(out) - - runCmd = exec.Command(dockerBinary, "wait", containerID) - out, _, err = runCommandWithOutput(runCmd) - - if err != nil || strings.TrimSpace(out) != "99" { - c.Fatal("failed to set up container", out, err) + if err := waitRun(containerID); err != nil { + c.Fatal(err) + } + if err := waitRun(containerID); err != nil { + c.Fatal(err) } + chWait := make(chan string) + go func() { + out, _, _ := runCommandWithOutput(exec.Command(dockerBinary, "wait", containerID)) + chWait <- out + }() + + time.Sleep(100 * time.Millisecond) + dockerCmd(c, "stop", containerID) + + select { + case status := <-chWait: + if strings.TrimSpace(status) != "99" { + c.Fatalf("expected exit 99, got %s", status) + } + case <-time.After(2 * time.Second): + c.Fatal("timeout waiting for `docker wait` to exit") + } } From 29f379ea6e2a68d8ac4bf41d3559a52066a275a0 Mon Sep 17 00:00:00 2001 From: Zhang Wei Date: Mon, 27 Apr 2015 20:54:51 +0800 Subject: [PATCH 37/58] improve docker man page fix issue #12708: "docker man page is misleading about format of commands" Signed-off-by: Zhang Wei --- docs/man/docker.1.md | 114 ++++++++++++++++++++++++++++--------------- 1 file changed, 76 insertions(+), 38 deletions(-) diff --git a/docs/man/docker.1.md b/docs/man/docker.1.md index 0196b6364..75b9b80cc 100644 --- a/docs/man/docker.1.md +++ b/docs/man/docker.1.md @@ -128,120 +128,158 @@ unix://[/path/to/socket] to use. Enable selinux support. Default is false. SELinux does not presently support the BTRFS storage driver. # COMMANDS -**docker-attach(1)** +**attach** Attach to a running container + See **docker-attach(1)** for full documentation on the **attach** command. -**docker-build(1)** +**build** Build an image from a Dockerfile + See **docker-build(1)** for full documentation on the **build** command. -**docker-commit(1)** +**commit** Create a new image from a container's changes + See **docker-commit(1)** for full documentation on the **commit** command. -**docker-cp(1)** +**cp** Copy files/folders from a container's filesystem to the host + See **docker-cp(1)** for full documentation on the **cp** command. -**docker-create(1)** +**create** Create a new container + See **docker-create(1)** for full documentation on the **create** command. -**docker-diff(1)** +**diff** Inspect changes on a container's filesystem + See **docker-diff(1)** for full documentation on the **diff** command. -**docker-events(1)** +**events** Get real time events from the server + See **docker-events(1)** for full documentation on the **events** command. -**docker-exec(1)** +**exec** Run a command in a running container + See **docker-exec(1)** for full documentation on the **exec** command. -**docker-export(1)** +**export** Stream the contents of a container as a tar archive + See **docker-export(1)** for full documentation on the **export** command. -**docker-history(1)** +**history** Show the history of an image + See **docker-history(1)** for full documentation on the **history** command. -**docker-images(1)** +**images** List images + See **docker-images(1)** for full documentation on the **images** command. -**docker-import(1)** +**import** Create a new filesystem image from the contents of a tarball + See **docker-import(1)** for full documentation on the **import** command. -**docker-info(1)** +**info** Display system-wide information + See **docker-info(1)** for full documentation on the **info** command. -**docker-inspect(1)** +**inspect** Return low-level information on a container or image + See **docker-inspect(1)** for full documentation on the **inspect** command. -**docker-kill(1)** +**kill** Kill a running container (which includes the wrapper process and everything inside it) + See **docker-kill(1)** for full documentation on the **kill** command. -**docker-load(1)** +**load** Load an image from a tar archive + See **docker-load(1)** for full documentation on the **load** command. -**docker-login(1)** +**login** Register or login to a Docker Registry + See **docker-login(1)** for full documentation on the **login** command. -**docker-logout(1)** +**logout** Log the user out of a Docker Registry + See **docker-logout(1)** for full documentation on the **logout** command. -**docker-logs(1)** +**logs** Fetch the logs of a container + See **docker-logs(1)** for full documentation on the **logs** command. -**docker-pause(1)** +**pause** Pause all processes within a container + See **docker-pause(1)** for full documentation on the **pause** command. -**docker-port(1)** +**port** Lookup the public-facing port which is NAT-ed to PRIVATE_PORT + See **docker-port(1)** for full documentation on the **port** command. -**docker-ps(1)** +**ps** List containers + See **docker-ps(1)** for full documentation on the **ps** command. -**docker-pull(1)** +**pull** Pull an image or a repository from a Docker Registry + See **docker-pull(1)** for full documentation on the **pull** command. -**docker-push(1)** +**push** Push an image or a repository to a Docker Registry + See **docker-push(1)** for full documentation on the **push** command. -**docker-restart(1)** +**restart** Restart a running container + See **docker-restart(1)** for full documentation on the **restart** command. -**docker-rm(1)** +**rm** Remove one or more containers + See **docker-rm(1)** for full documentation on the **rm** command. -**docker-rmi(1)** +**rmi** Remove one or more images + See **docker-rmi(1)** for full documentation on the **rmi** command. -**docker-run(1)** +**run** Run a command in a new container + See **docker-run(1)** for full documentation on the **run** command. -**docker-save(1)** +**save** Save an image to a tar archive + See **docker-save(1)** for full documentation on the **save** command. -**docker-search(1)** +**search** Search for an image in the Docker index + See **docker-search(1)** for full documentation on the **search** command. -**docker-start(1)** +**start** Start a stopped container + See **docker-start(1)** for full documentation on the **start** command. -**docker-stats(1)** +**stats** Display a live stream of one or more containers' resource usage statistics + See **docker-stats(1)** for full documentation on the **stats** command. -**docker-stop(1)** +**stop** Stop a running container + See **docker-stop(1)** for full documentation on the **stop** command. -**docker-tag(1)** +**tag** Tag an image into a repository + See **docker-tag(1)** for full documentation on the **tag** command. -**docker-top(1)** +**top** Lookup the running processes of a container + See **docker-top(1)** for full documentation on the **top** command. -**docker-unpause(1)** +**unpause** Unpause all processes within a container + See **docker-unpause(1)** for full documentation on the **unpause** command. -**docker-version(1)** +**version** Show the Docker version information + See **docker-version(1)** for full documentation on the **version** command. -**docker-wait(1)** +**wait** Block until a container stops, then print its exit code + See **docker-wait(1)** for full documentation on the **wait** command. # STORAGE DRIVER OPTIONS From ab97303caed2a7be474e2c4ff7a55af9d6c8c3cc Mon Sep 17 00:00:00 2001 From: John Howard Date: Mon, 27 Apr 2015 08:38:01 -0700 Subject: [PATCH 38/58] Windows: Info no containerized check Signed-off-by: John Howard --- daemon/info.go | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/daemon/info.go b/daemon/info.go index 270abda59..df1c0530c 100644 --- a/daemon/info.go +++ b/daemon/info.go @@ -33,11 +33,15 @@ func (daemon *Daemon) SystemInfo() (*types.Info, error) { if s, err := operatingsystem.GetOperatingSystem(); err == nil { operatingSystem = s } - if inContainer, err := operatingsystem.IsContainerized(); err != nil { - logrus.Errorf("Could not determine if daemon is containerized: %v", err) - operatingSystem += " (error determining if containerized)" - } else if inContainer { - operatingSystem += " (containerized)" + + // Don't do containerized check on Windows + if runtime.GOOS != "windows" { + if inContainer, err := operatingsystem.IsContainerized(); err != nil { + logrus.Errorf("Could not determine if daemon is containerized: %v", err) + operatingSystem += " (error determining if containerized)" + } else if inContainer { + operatingSystem += " (containerized)" + } } meminfo, err := system.ReadMemInfo() From ba1725a94ee75603d3a21e0580be3954fc689137 Mon Sep 17 00:00:00 2001 From: John Howard Date: Mon, 27 Apr 2015 09:25:38 -0700 Subject: [PATCH 39/58] Windows: Refactor volumes Signed-off-by: John Howard --- daemon/volumes.go | 16 ---------------- daemon/volumes_linux.go | 24 ++++++++++++++++++++++++ daemon/volumes_windows.go | 8 ++++++++ 3 files changed, 32 insertions(+), 16 deletions(-) create mode 100644 daemon/volumes_linux.go create mode 100644 daemon/volumes_windows.go diff --git a/daemon/volumes.go b/daemon/volumes.go index 4d15023ba..ede1eef73 100644 --- a/daemon/volumes.go +++ b/daemon/volumes.go @@ -13,7 +13,6 @@ import ( "github.com/docker/docker/pkg/chrootarchive" "github.com/docker/docker/pkg/mount" "github.com/docker/docker/pkg/symlink" - "github.com/docker/docker/pkg/system" ) type volumeMount struct { @@ -314,21 +313,6 @@ func copyExistingContents(source, destination string) error { return copyOwnership(source, destination) } -// copyOwnership copies the permissions and uid:gid of the source file -// into the destination file -func copyOwnership(source, destination string) error { - stat, err := system.Stat(source) - if err != nil { - return err - } - - if err := os.Chown(destination, int(stat.Uid()), int(stat.Gid())); err != nil { - return err - } - - return os.Chmod(destination, os.FileMode(stat.Mode())) -} - func (container *Container) mountVolumes() error { for dest, source := range container.Volumes { v := container.daemon.volumes.Get(source) diff --git a/daemon/volumes_linux.go b/daemon/volumes_linux.go new file mode 100644 index 000000000..93fea8165 --- /dev/null +++ b/daemon/volumes_linux.go @@ -0,0 +1,24 @@ +// +build !windows + +package daemon + +import ( + "os" + + "github.com/docker/docker/pkg/system" +) + +// copyOwnership copies the permissions and uid:gid of the source file +// into the destination file +func copyOwnership(source, destination string) error { + stat, err := system.Stat(source) + if err != nil { + return err + } + + if err := os.Chown(destination, int(stat.Uid()), int(stat.Gid())); err != nil { + return err + } + + return os.Chmod(destination, os.FileMode(stat.Mode())) +} diff --git a/daemon/volumes_windows.go b/daemon/volumes_windows.go new file mode 100644 index 000000000..ca1199a54 --- /dev/null +++ b/daemon/volumes_windows.go @@ -0,0 +1,8 @@ +// +build windows + +package daemon + +// Not supported on Windows +func copyOwnership(source, destination string) error { + return nil +} From bb1c576eb3024f7fb4242d76dc835b7c4dd85c5b Mon Sep 17 00:00:00 2001 From: Antonio Murdaca Date: Mon, 27 Apr 2015 18:33:08 +0200 Subject: [PATCH 40/58] Expose whole Response struct in sockRequestRaw Signed-off-by: Antonio Murdaca --- integration-cli/docker_api_containers_test.go | 50 +++++++++---------- integration-cli/docker_api_images_test.go | 8 +-- integration-cli/docker_api_logs_test.go | 12 ++--- integration-cli/docker_utils.go | 16 +++--- 4 files changed, 43 insertions(+), 43 deletions(-) diff --git a/integration-cli/docker_api_containers_test.go b/integration-cli/docker_api_containers_test.go index e7ce0f3f5..cd04c38dc 100644 --- a/integration-cli/docker_api_containers_test.go +++ b/integration-cli/docker_api_containers_test.go @@ -339,8 +339,8 @@ func (s *DockerSuite) TestBuildApiDockerfilePath(c *check.C) { c.Fatalf("failed to close tar archive: %v", err) } - status, body, err := sockRequestRaw("POST", "/build?dockerfile=../Dockerfile", buffer, "application/x-tar") - c.Assert(status, check.Equals, http.StatusInternalServerError) + res, body, err := sockRequestRaw("POST", "/build?dockerfile=../Dockerfile", buffer, "application/x-tar") + c.Assert(res.StatusCode, check.Equals, http.StatusInternalServerError) c.Assert(err, check.IsNil) out, err := readBody(body) @@ -365,8 +365,8 @@ RUN find /tmp/`, } defer server.Close() - status, body, err := sockRequestRaw("POST", "/build?dockerfile=baz&remote="+server.URL()+"/testD", nil, "application/json") - c.Assert(status, check.Equals, http.StatusOK) + res, body, err := sockRequestRaw("POST", "/build?dockerfile=baz&remote="+server.URL()+"/testD", nil, "application/json") + c.Assert(res.StatusCode, check.Equals, http.StatusOK) c.Assert(err, check.IsNil) buf, err := readBody(body) @@ -393,8 +393,8 @@ RUN echo from dockerfile`, } defer git.Close() - status, body, err := sockRequestRaw("POST", "/build?remote="+git.RepoURL, nil, "application/json") - c.Assert(status, check.Equals, http.StatusOK) + res, body, err := sockRequestRaw("POST", "/build?remote="+git.RepoURL, nil, "application/json") + c.Assert(res.StatusCode, check.Equals, http.StatusOK) c.Assert(err, check.IsNil) buf, err := readBody(body) @@ -421,8 +421,8 @@ RUN echo from Dockerfile`, defer git.Close() // Make sure it tries to 'dockerfile' query param value - status, body, err := sockRequestRaw("POST", "/build?dockerfile=baz&remote="+git.RepoURL, nil, "application/json") - c.Assert(status, check.Equals, http.StatusOK) + res, body, err := sockRequestRaw("POST", "/build?dockerfile=baz&remote="+git.RepoURL, nil, "application/json") + c.Assert(res.StatusCode, check.Equals, http.StatusOK) c.Assert(err, check.IsNil) buf, err := readBody(body) @@ -450,8 +450,8 @@ RUN echo from dockerfile`, defer git.Close() // Make sure it tries to 'dockerfile' query param value - status, body, err := sockRequestRaw("POST", "/build?remote="+git.RepoURL, nil, "application/json") - c.Assert(status, check.Equals, http.StatusOK) + res, body, err := sockRequestRaw("POST", "/build?remote="+git.RepoURL, nil, "application/json") + c.Assert(res.StatusCode, check.Equals, http.StatusOK) c.Assert(err, check.IsNil) buf, err := readBody(body) @@ -483,8 +483,8 @@ func (s *DockerSuite) TestBuildApiDockerfileSymlink(c *check.C) { c.Fatalf("failed to close tar archive: %v", err) } - status, body, err := sockRequestRaw("POST", "/build", buffer, "application/x-tar") - c.Assert(status, check.Equals, http.StatusInternalServerError) + res, body, err := sockRequestRaw("POST", "/build", buffer, "application/x-tar") + c.Assert(res.StatusCode, check.Equals, http.StatusInternalServerError) c.Assert(err, check.IsNil) out, err := readBody(body) @@ -720,7 +720,7 @@ func (s *DockerSuite) TestContainerApiVerifyHeader(c *check.C) { "Image": "busybox", } - create := func(ct string) (int, io.ReadCloser, error) { + create := func(ct string) (*http.Response, io.ReadCloser, error) { jsonData := bytes.NewBuffer(nil) if err := json.NewEncoder(jsonData).Encode(config); err != nil { c.Fatal(err) @@ -729,21 +729,21 @@ func (s *DockerSuite) TestContainerApiVerifyHeader(c *check.C) { } // Try with no content-type - status, body, err := create("") - c.Assert(status, check.Equals, http.StatusInternalServerError) + res, body, err := create("") c.Assert(err, check.IsNil) + c.Assert(res.StatusCode, check.Equals, http.StatusInternalServerError) body.Close() // Try with wrong content-type - status, body, err = create("application/xml") - c.Assert(status, check.Equals, http.StatusInternalServerError) + res, body, err = create("application/xml") c.Assert(err, check.IsNil) + c.Assert(res.StatusCode, check.Equals, http.StatusInternalServerError) body.Close() // now application/json - status, body, err = create("application/json") - c.Assert(status, check.Equals, http.StatusCreated) + res, body, err = create("application/json") c.Assert(err, check.IsNil) + c.Assert(res.StatusCode, check.Equals, http.StatusCreated) body.Close() } @@ -774,8 +774,8 @@ func (s *DockerSuite) TestContainerApiPostCreateNull(c *check.C) { "NetworkDisabled":false, "OnBuild":null}` - status, body, err := sockRequestRaw("POST", "/containers/create", strings.NewReader(config), "application/json") - c.Assert(status, check.Equals, http.StatusCreated) + res, body, err := sockRequestRaw("POST", "/containers/create", strings.NewReader(config), "application/json") + c.Assert(res.StatusCode, check.Equals, http.StatusCreated) c.Assert(err, check.IsNil) b, err := readBody(body) @@ -808,13 +808,13 @@ func (s *DockerSuite) TestCreateWithTooLowMemoryLimit(c *check.C) { "Memory": 524287 }` - status, body, _ := sockRequestRaw("POST", "/containers/create", strings.NewReader(config), "application/json") + res, body, _ := sockRequestRaw("POST", "/containers/create", strings.NewReader(config), "application/json") b, err2 := readBody(body) if err2 != nil { c.Fatal(err2) } - c.Assert(status, check.Equals, http.StatusInternalServerError) + c.Assert(res.StatusCode, check.Equals, http.StatusInternalServerError) c.Assert(strings.Contains(string(b), "Minimum memory limit allowed is 4MB"), check.Equals, true) } @@ -831,13 +831,13 @@ func (s *DockerSuite) TestStartWithTooLowMemoryLimit(c *check.C) { "Memory": 524287 }` - status, body, _ := sockRequestRaw("POST", "/containers/"+containerID+"/start", strings.NewReader(config), "application/json") + res, body, _ := sockRequestRaw("POST", "/containers/"+containerID+"/start", strings.NewReader(config), "application/json") b, err2 := readBody(body) if err2 != nil { c.Fatal(err2) } - c.Assert(status, check.Equals, http.StatusInternalServerError) + c.Assert(res.StatusCode, check.Equals, http.StatusInternalServerError) c.Assert(strings.Contains(string(b), "Minimum memory limit allowed is 4MB"), check.Equals, true) } diff --git a/integration-cli/docker_api_images_test.go b/integration-cli/docker_api_images_test.go index ac3ad55d7..e88fbaeaa 100644 --- a/integration-cli/docker_api_images_test.go +++ b/integration-cli/docker_api_images_test.go @@ -74,9 +74,9 @@ func (s *DockerSuite) TestApiImagesSaveAndLoad(c *check.C) { } id := strings.TrimSpace(out) - status, body, err := sockRequestRaw("GET", "/images/"+id+"/get", nil, "") - c.Assert(status, check.Equals, http.StatusOK) + res, body, err := sockRequestRaw("GET", "/images/"+id+"/get", nil, "") c.Assert(err, check.IsNil) + c.Assert(res.StatusCode, check.Equals, http.StatusOK) defer body.Close() @@ -84,9 +84,9 @@ func (s *DockerSuite) TestApiImagesSaveAndLoad(c *check.C) { c.Fatal(err, out) } - status, loadBody, err := sockRequestRaw("POST", "/images/load", body, "application/x-tar") - c.Assert(status, check.Equals, http.StatusOK) + res, loadBody, err := sockRequestRaw("POST", "/images/load", body, "application/x-tar") c.Assert(err, check.IsNil) + c.Assert(res.StatusCode, check.Equals, http.StatusOK) defer loadBody.Close() diff --git a/integration-cli/docker_api_logs_test.go b/integration-cli/docker_api_logs_test.go index a1723ef21..f9284494d 100644 --- a/integration-cli/docker_api_logs_test.go +++ b/integration-cli/docker_api_logs_test.go @@ -20,22 +20,22 @@ func (s *DockerSuite) TestLogsApiWithStdout(c *check.C) { } type logOut struct { - out string - status int - err error + out string + res *http.Response + err error } chLog := make(chan logOut) go func() { - statusCode, body, err := sockRequestRaw("GET", fmt.Sprintf("/containers/%s/logs?follow=1&stdout=1×tamps=1", id), nil, "") + res, body, err := sockRequestRaw("GET", fmt.Sprintf("/containers/%s/logs?follow=1&stdout=1×tamps=1", id), nil, "") out, _ := bufio.NewReader(body).ReadString('\n') - chLog <- logOut{strings.TrimSpace(out), statusCode, err} + chLog <- logOut{strings.TrimSpace(out), res, err} }() select { case l := <-chLog: - c.Assert(l.status, check.Equals, http.StatusOK) c.Assert(l.err, check.IsNil) + c.Assert(l.res.StatusCode, check.Equals, http.StatusOK) if !strings.HasSuffix(l.out, "hello") { c.Fatalf("expected log output to container 'hello', but it does not") } diff --git a/integration-cli/docker_utils.go b/integration-cli/docker_utils.go index 5d2a537e1..8386bb59f 100644 --- a/integration-cli/docker_utils.go +++ b/integration-cli/docker_utils.go @@ -313,20 +313,20 @@ func sockRequest(method, endpoint string, data interface{}) (int, []byte, error) return -1, nil, err } - status, body, err := sockRequestRaw(method, endpoint, jsonData, "application/json") + res, body, err := sockRequestRaw(method, endpoint, jsonData, "application/json") if err != nil { b, _ := ioutil.ReadAll(body) - return status, b, err + return -1, b, err } var b []byte b, err = readBody(body) - return status, b, err + return res.StatusCode, b, err } -func sockRequestRaw(method, endpoint string, data io.Reader, ct string) (int, io.ReadCloser, error) { +func sockRequestRaw(method, endpoint string, data io.Reader, ct string) (*http.Response, io.ReadCloser, error) { c, err := sockConn(time.Duration(10 * time.Second)) if err != nil { - return -1, nil, fmt.Errorf("could not dial docker daemon: %v", err) + return nil, nil, fmt.Errorf("could not dial docker daemon: %v", err) } client := httputil.NewClientConn(c, nil) @@ -334,7 +334,7 @@ func sockRequestRaw(method, endpoint string, data io.Reader, ct string) (int, io req, err := http.NewRequest(method, endpoint, data) if err != nil { client.Close() - return -1, nil, fmt.Errorf("could not create new request: %v", err) + return nil, nil, fmt.Errorf("could not create new request: %v", err) } if ct != "" { @@ -344,14 +344,14 @@ func sockRequestRaw(method, endpoint string, data io.Reader, ct string) (int, io resp, err := client.Do(req) if err != nil { client.Close() - return -1, nil, fmt.Errorf("could not perform request: %v", err) + return nil, nil, fmt.Errorf("could not perform request: %v", err) } body := ioutils.NewReadCloserWrapper(resp.Body, func() error { defer client.Close() return resp.Body.Close() }) - return resp.StatusCode, body, err + return resp, body, nil } func readBody(b io.ReadCloser) ([]byte, error) { From b6cfe7ca07722cee22345602595fc8fb928dbe79 Mon Sep 17 00:00:00 2001 From: Matt McCormick Date: Sun, 26 Apr 2015 20:58:31 -0400 Subject: [PATCH 41/58] Do Debian installation verification with hello-world image. The hello-world image is recommended as a verification image and it is smaller than Ubuntu. Signed-off-by: Matt McCormick --- docs/sources/installation/debian.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/sources/installation/debian.md b/docs/sources/installation/debian.md index aeee1ecb1..da9e5f59b 100644 --- a/docs/sources/installation/debian.md +++ b/docs/sources/installation/debian.md @@ -28,9 +28,10 @@ To install the latest Debian package (may not be the latest Docker release): To verify that everything has worked as expected: - $ sudo docker run -i -t ubuntu /bin/bash + $ sudo docker run --rm hello-world -Which should download the `ubuntu` image, and then start `bash` in a container. +This command downloads and runs the `hello-world` image in a container. When the +container runs, it prints an informational message. Then, it exits. > **Note**: > If you want to enable memory and swap accounting see From 40779b28bb04dca6178ba17eaeb93265e2974ee1 Mon Sep 17 00:00:00 2001 From: Lorenzo Fontana Date: Mon, 27 Apr 2015 21:12:23 +0200 Subject: [PATCH 42/58] Parallelize TestEventsLimit Signed-off-by: Lorenzo Fontana --- integration-cli/docker_cli_events_test.go | 25 +++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/integration-cli/docker_cli_events_test.go b/integration-cli/docker_cli_events_test.go index 5f3616b21..b1cc26b9a 100644 --- a/integration-cli/docker_cli_events_test.go +++ b/integration-cli/docker_cli_events_test.go @@ -7,6 +7,7 @@ import ( "regexp" "strconv" "strings" + "sync" "time" "github.com/go-check/check" @@ -65,9 +66,29 @@ func (s *DockerSuite) TestEventsContainerFailStartDie(c *check.C) { } func (s *DockerSuite) TestEventsLimit(c *check.C) { - for i := 0; i < 30; i++ { - dockerCmd(c, "run", "busybox", "echo", strconv.Itoa(i)) + + var waitGroup sync.WaitGroup + errChan := make(chan error, 17) + + args := []string{"run", "--rm", "busybox", "true"} + for i := 0; i < 17; i++ { + waitGroup.Add(1) + go func() { + defer waitGroup.Done() + err := exec.Command(dockerBinary, args...).Run() + errChan <- err + }() } + + waitGroup.Wait() + close(errChan) + + for err := range errChan { + if err != nil { + c.Fatalf("%q failed with error: %v", strings.Join(args, " "), err) + } + } + eventsCmd := exec.Command(dockerBinary, "events", "--since=0", fmt.Sprintf("--until=%d", daemonTime(c).Unix())) out, _, _ := runCommandWithOutput(eventsCmd) events := strings.Split(out, "\n") From 844538142d95c1b7dda1bb2903179510105fe9b5 Mon Sep 17 00:00:00 2001 From: Antonio Murdaca Date: Sun, 26 Apr 2015 18:50:25 +0200 Subject: [PATCH 43/58] Small if err cleaning Signed-off-by: Antonio Murdaca --- api/client/build.go | 2 +- api/client/diff.go | 3 +-- api/client/history.go | 3 +-- api/client/ps.go | 3 +-- api/client/rmi.go | 3 +-- api/client/search.go | 3 +-- api/client/top.go | 3 +-- api/common.go | 3 +-- api/server/server.go | 7 +++---- builder/internals.go | 11 +++++++++-- cliconfig/config.go | 3 +-- daemon/container.go | 3 +-- daemon/daemon.go | 3 +-- daemon/exec.go | 3 +-- daemon/graphdriver/devmapper/deviceset.go | 13 ++++++------- graph/graph.go | 5 ++--- graph/pull.go | 6 ++---- graph/push.go | 3 +-- image/image.go | 3 +-- integration-cli/docker_api_containers_test.go | 8 ++++---- integration-cli/utils.go | 3 +-- pkg/jsonlog/jsonlog_marshalling.go | 3 +-- pkg/mflag/flag.go | 3 +-- pkg/system/lstat.go | 3 +-- pkg/system/stat_linux.go | 3 +-- pkg/timeoutconn/timeoutconn.go | 3 +-- registry/session.go | 3 +-- registry/session_v2.go | 4 +--- trust/trusts.go | 9 +++------ 29 files changed, 51 insertions(+), 74 deletions(-) diff --git a/api/client/build.go b/api/client/build.go index 800e04ac9..e83de976b 100644 --- a/api/client/build.go +++ b/api/client/build.go @@ -173,7 +173,7 @@ func (cli *DockerCli) CmdBuild(args ...string) error { includes = append(includes, ".dockerignore", *dockerfileName) } - if err = utils.ValidateContextDirectory(root, excludes); err != nil { + if err := utils.ValidateContextDirectory(root, excludes); err != nil { return fmt.Errorf("Error checking context is accessible: '%s'. Please check permissions and try again.", err) } options := &archive.TarOptions{ diff --git a/api/client/diff.go b/api/client/diff.go index a22734d04..6000c6b38 100644 --- a/api/client/diff.go +++ b/api/client/diff.go @@ -31,8 +31,7 @@ func (cli *DockerCli) CmdDiff(args ...string) error { } changes := []types.ContainerChange{} - err = json.NewDecoder(rdr).Decode(&changes) - if err != nil { + if err := json.NewDecoder(rdr).Decode(&changes); err != nil { return err } diff --git a/api/client/history.go b/api/client/history.go index 79c6f3f7a..31b853503 100644 --- a/api/client/history.go +++ b/api/client/history.go @@ -30,8 +30,7 @@ func (cli *DockerCli) CmdHistory(args ...string) error { } history := []types.ImageHistory{} - err = json.NewDecoder(rdr).Decode(&history) - if err != nil { + if err := json.NewDecoder(rdr).Decode(&history); err != nil { return err } diff --git a/api/client/ps.go b/api/client/ps.go index 44f5ff0d2..6c40c6867 100644 --- a/api/client/ps.go +++ b/api/client/ps.go @@ -92,8 +92,7 @@ func (cli *DockerCli) CmdPs(args ...string) error { } containers := []types.Container{} - err = json.NewDecoder(rdr).Decode(&containers) - if err != nil { + if err := json.NewDecoder(rdr).Decode(&containers); err != nil { return err } diff --git a/api/client/rmi.go b/api/client/rmi.go index 11c9ff32d..a8590dc82 100644 --- a/api/client/rmi.go +++ b/api/client/rmi.go @@ -37,8 +37,7 @@ func (cli *DockerCli) CmdRmi(args ...string) error { encounteredError = fmt.Errorf("Error: failed to remove one or more images") } else { dels := []types.ImageDelete{} - err = json.NewDecoder(rdr).Decode(&dels) - if err != nil { + if err := json.NewDecoder(rdr).Decode(&dels); err != nil { fmt.Fprintf(cli.err, "%s\n", err) encounteredError = fmt.Errorf("Error: failed to remove one or more images") continue diff --git a/api/client/search.go b/api/client/search.go index 4e493b234..e606d479f 100644 --- a/api/client/search.go +++ b/api/client/search.go @@ -51,8 +51,7 @@ func (cli *DockerCli) CmdSearch(args ...string) error { } results := ByStars{} - err = json.NewDecoder(rdr).Decode(&results) - if err != nil { + if err := json.NewDecoder(rdr).Decode(&results); err != nil { return err } diff --git a/api/client/top.go b/api/client/top.go index 4975f4759..ee16fdbf6 100644 --- a/api/client/top.go +++ b/api/client/top.go @@ -31,8 +31,7 @@ func (cli *DockerCli) CmdTop(args ...string) error { } procList := types.ContainerProcessList{} - err = json.NewDecoder(stream).Decode(&procList) - if err != nil { + if err := json.NewDecoder(stream).Decode(&procList); err != nil { return err } diff --git a/api/common.go b/api/common.go index cb627824e..4a9523cd4 100644 --- a/api/common.go +++ b/api/common.go @@ -107,8 +107,7 @@ func MatchesContentType(contentType, expectedType string) bool { // LoadOrCreateTrustKey attempts to load the libtrust key at the given path, // otherwise generates a new one func LoadOrCreateTrustKey(trustKeyPath string) (libtrust.PrivateKey, error) { - err := os.MkdirAll(filepath.Dir(trustKeyPath), 0700) - if err != nil { + if err := os.MkdirAll(filepath.Dir(trustKeyPath), 0700); err != nil { return nil, err } trustKey, err := libtrust.LoadKeyFile(trustKeyPath) diff --git a/api/server/server.go b/api/server/server.go index 1e951d36c..61e816265 100644 --- a/api/server/server.go +++ b/api/server/server.go @@ -277,8 +277,7 @@ func (s *Server) postContainersKill(eng *engine.Engine, version version.Version, if vars == nil { return fmt.Errorf("Missing parameter") } - err := parseForm(r) - if err != nil { + if err := parseForm(r); err != nil { return err } @@ -289,7 +288,7 @@ func (s *Server) postContainersKill(eng *engine.Engine, version version.Version, if sigStr := vars["signal"]; sigStr != "" { // Check if we passed the signal as a number: // The largest legal signal is 31, so let's parse on 5 bits - sig, err = strconv.ParseUint(sigStr, 10, 5) + sig, err := strconv.ParseUint(sigStr, 10, 5) if err != nil { // The signal is not a number, treat it as a string (either like // "KILL" or like "SIGKILL") @@ -301,7 +300,7 @@ func (s *Server) postContainersKill(eng *engine.Engine, version version.Version, } } - if err = s.daemon.ContainerKill(name, sig); err != nil { + if err := s.daemon.ContainerKill(name, sig); err != nil { return err } diff --git a/builder/internals.go b/builder/internals.go index ba7d45bcb..53542a669 100644 --- a/builder/internals.go +++ b/builder/internals.go @@ -148,8 +148,15 @@ func (b *Builder) runContextCommand(args []string, allowRemote bool, allowDecomp // do the copy (e.g. hash value if cached). Don't actually do // the copy until we've looked at all src files for _, orig := range args[0 : len(args)-1] { - err := calcCopyInfo(b, cmdName, ©Infos, orig, dest, allowRemote, allowDecompression) - if err != nil { + if err := calcCopyInfo( + b, + cmdName, + ©Infos, + orig, + dest, + allowRemote, + allowDecompression, + ); err != nil { return err } } diff --git a/cliconfig/config.go b/cliconfig/config.go index 19a92fbd8..2a27589d2 100644 --- a/cliconfig/config.go +++ b/cliconfig/config.go @@ -166,8 +166,7 @@ func (configFile *ConfigFile) Save() error { return err } - err = ioutil.WriteFile(configFile.filename, data, 0600) - if err != nil { + if err := ioutil.WriteFile(configFile.filename, data, 0600); err != nil { return err } diff --git a/daemon/container.go b/daemon/container.go index 01eef4d31..10d6b4cd8 100644 --- a/daemon/container.go +++ b/daemon/container.go @@ -149,8 +149,7 @@ func (container *Container) toDisk() error { return err } - err = ioutil.WriteFile(pth, data, 0666) - if err != nil { + if err := ioutil.WriteFile(pth, data, 0666); err != nil { return err } diff --git a/daemon/daemon.go b/daemon/daemon.go index 99f5ae636..f12ed2111 100644 --- a/daemon/daemon.go +++ b/daemon/daemon.go @@ -1181,8 +1181,7 @@ func tempDir(rootDir string) (string, error) { if tmpDir = os.Getenv("DOCKER_TMPDIR"); tmpDir == "" { tmpDir = filepath.Join(rootDir, "tmp") } - err := os.MkdirAll(tmpDir, 0700) - return tmpDir, err + return tmpDir, os.MkdirAll(tmpDir, 0700) } func checkKernel() error { diff --git a/daemon/exec.go b/daemon/exec.go index 22872adc4..9aa102690 100644 --- a/daemon/exec.go +++ b/daemon/exec.go @@ -214,8 +214,7 @@ func (d *Daemon) ContainerExecStart(execName string, stdin io.ReadCloser, stdout // the exitStatus) even after the cmd is done running. go func() { - err := container.Exec(execConfig) - if err != nil { + if err := container.Exec(execConfig); err != nil { execErr <- fmt.Errorf("Cannot run exec command %s in container %s: %s", execName, container.ID, err) } }() diff --git a/daemon/graphdriver/devmapper/deviceset.go b/daemon/graphdriver/devmapper/deviceset.go index b5d67fa11..42b9d76be 100644 --- a/daemon/graphdriver/devmapper/deviceset.go +++ b/daemon/graphdriver/devmapper/deviceset.go @@ -218,7 +218,7 @@ func (devices *DeviceSet) ensureImage(name string, size int64) (string, error) { } defer file.Close() - if err = file.Truncate(size); err != nil { + if err := file.Truncate(size); err != nil { return "", err } } @@ -697,7 +697,7 @@ func (devices *DeviceSet) setupBaseImage() error { logrus.Debugf("Creating filesystem on base device-mapper thin volume") - if err = devices.activateDeviceIfNeeded(info); err != nil { + if err := devices.activateDeviceIfNeeded(info); err != nil { return err } @@ -706,7 +706,7 @@ func (devices *DeviceSet) setupBaseImage() error { } info.Initialized = true - if err = devices.saveMetadata(info); err != nil { + if err := devices.saveMetadata(info); err != nil { info.Initialized = false return err } @@ -1099,14 +1099,14 @@ func (devices *DeviceSet) initDevmapper(doInit bool) error { // If we didn't just create the data or metadata image, we need to // load the transaction id and migrate old metadata if !createdLoopback { - if err = devices.initMetaData(); err != nil { + if err := devices.initMetaData(); err != nil { return err } } // Right now this loads only NextDeviceId. If there is more metadata // down the line, we might have to move it earlier. - if err = devices.loadDeviceSetMetaData(); err != nil { + if err := devices.loadDeviceSetMetaData(); err != nil { return err } @@ -1528,8 +1528,7 @@ func (devices *DeviceSet) MetadataDevicePath() string { func (devices *DeviceSet) getUnderlyingAvailableSpace(loopFile string) (uint64, error) { buf := new(syscall.Statfs_t) - err := syscall.Statfs(loopFile, buf) - if err != nil { + if err := syscall.Statfs(loopFile, buf); err != nil { logrus.Warnf("Couldn't stat loopfile filesystem %v: %v", loopFile, err) return 0, err } diff --git a/graph/graph.go b/graph/graph.go index 5159a9322..9b2d7c2ee 100644 --- a/graph/graph.go +++ b/graph/graph.go @@ -348,9 +348,8 @@ func (graph *Graph) Delete(name string) error { tmp, err := graph.Mktemp("") graph.idIndex.Delete(id) if err == nil { - err = os.Rename(graph.ImageRoot(id), tmp) - // On err make tmp point to old dir and cleanup unused tmp dir - if err != nil { + if err := os.Rename(graph.ImageRoot(id), tmp); err != nil { + // On err make tmp point to old dir and cleanup unused tmp dir os.RemoveAll(tmp) tmp = graph.ImageRoot(id) } diff --git a/graph/pull.go b/graph/pull.go index 0ebf75abb..c3c064fc5 100644 --- a/graph/pull.go +++ b/graph/pull.go @@ -537,8 +537,7 @@ func (s *TagStore) pullV2Tag(r *registry.Session, out io.Writer, endpoint *regis di.err <- downloadFunc(di) }(&downloads[i]) } else { - err := downloadFunc(&downloads[i]) - if err != nil { + if err := downloadFunc(&downloads[i]); err != nil { return false, err } } @@ -548,8 +547,7 @@ func (s *TagStore) pullV2Tag(r *registry.Session, out io.Writer, endpoint *regis for i := len(downloads) - 1; i >= 0; i-- { d := &downloads[i] if d.err != nil { - err := <-d.err - if err != nil { + if err := <-d.err; err != nil { return false, err } } diff --git a/graph/push.go b/graph/push.go index 62ff94e0c..1b33288d8 100644 --- a/graph/push.go +++ b/graph/push.go @@ -367,8 +367,7 @@ func (s *TagStore) pushV2Repository(r *registry.Session, localRepo Repository, o logrus.Debugf("Pushing layer: %s", layer.ID) if layer.Config != nil && metadata.Image != layer.ID { - err = runconfig.Merge(&metadata, layer.Config) - if err != nil { + if err := runconfig.Merge(&metadata, layer.Config); err != nil { return err } } diff --git a/image/image.go b/image/image.go index 90714d6db..a34d2b940 100644 --- a/image/image.go +++ b/image/image.go @@ -268,8 +268,7 @@ func NewImgJSON(src []byte) (*Image, error) { func ValidateID(id string) error { validHex := regexp.MustCompile(`^([a-f0-9]{64})$`) if ok := validHex.MatchString(id); !ok { - err := fmt.Errorf("image ID '%s' is invalid", id) - return err + return fmt.Errorf("image ID '%s' is invalid", id) } return nil } diff --git a/integration-cli/docker_api_containers_test.go b/integration-cli/docker_api_containers_test.go index e7ce0f3f5..a26afb162 100644 --- a/integration-cli/docker_api_containers_test.go +++ b/integration-cli/docker_api_containers_test.go @@ -176,7 +176,7 @@ func (s *DockerSuite) TestContainerApiStartVolumesFrom(c *check.C) { c.Fatal(out, err) } - name := "testing" + name := "TestContainerApiStartDupVolumeBinds" config := map[string]interface{}{ "Image": "busybox", "Volumes": map[string]struct{}{volPath: {}}, @@ -620,7 +620,7 @@ func (s *DockerSuite) TestContainerApiCommit(c *check.C) { c.Fatal(err, out) } - name := "testcommit" + stringid.GenerateRandomID() + name := "TestContainerApiCommit" status, b, err := sockRequest("POST", "/commit?repo="+name+"&testtag=tag&container="+cName, nil) c.Assert(status, check.Equals, http.StatusCreated) c.Assert(err, check.IsNil) @@ -842,12 +842,12 @@ func (s *DockerSuite) TestStartWithTooLowMemoryLimit(c *check.C) { } func (s *DockerSuite) TestContainerApiRename(c *check.C) { - runCmd := exec.Command(dockerBinary, "run", "--name", "first_name", "-d", "busybox", "sh") + runCmd := exec.Command(dockerBinary, "run", "--name", "TestContainerApiRename", "-d", "busybox", "sh") out, _, err := runCommandWithOutput(runCmd) c.Assert(err, check.IsNil) containerID := strings.TrimSpace(out) - newName := "new_name" + stringid.GenerateRandomID() + newName := "TestContainerApiRenameNew" statusCode, _, err := sockRequest("POST", "/containers/"+containerID+"/rename?name="+newName, nil) // 204 No Content is expected, not 200 diff --git a/integration-cli/utils.go b/integration-cli/utils.go index 4ca7158ae..f0de79ea8 100644 --- a/integration-cli/utils.go +++ b/integration-cli/utils.go @@ -169,8 +169,7 @@ func runCommandPipelineWithOutput(cmds ...*exec.Cmd) (output string, exitCode in } func unmarshalJSON(data []byte, result interface{}) error { - err := json.Unmarshal(data, result) - if err != nil { + if err := json.Unmarshal(data, result); err != nil { return err } diff --git a/pkg/jsonlog/jsonlog_marshalling.go b/pkg/jsonlog/jsonlog_marshalling.go index 6244eb01a..abaa8a73b 100644 --- a/pkg/jsonlog/jsonlog_marshalling.go +++ b/pkg/jsonlog/jsonlog_marshalling.go @@ -65,8 +65,7 @@ import ( func (mj *JSONLog) MarshalJSON() ([]byte, error) { var buf bytes.Buffer buf.Grow(1024) - err := mj.MarshalJSONBuf(&buf) - if err != nil { + if err := mj.MarshalJSONBuf(&buf); err != nil { return nil, err } return buf.Bytes(), nil diff --git a/pkg/mflag/flag.go b/pkg/mflag/flag.go index f2da1cd1b..f0d20d99b 100644 --- a/pkg/mflag/flag.go +++ b/pkg/mflag/flag.go @@ -486,8 +486,7 @@ func (f *FlagSet) Set(name, value string) error { if !ok { return fmt.Errorf("no such flag -%v", name) } - err := flag.Value.Set(value) - if err != nil { + if err := flag.Value.Set(value); err != nil { return err } if f.actual == nil { diff --git a/pkg/system/lstat.go b/pkg/system/lstat.go index a966cd488..d0e43b370 100644 --- a/pkg/system/lstat.go +++ b/pkg/system/lstat.go @@ -12,8 +12,7 @@ import ( // Throws an error if the file does not exist func Lstat(path string) (*Stat_t, error) { s := &syscall.Stat_t{} - err := syscall.Lstat(path, s) - if err != nil { + if err := syscall.Lstat(path, s); err != nil { return nil, err } return fromStatT(s) diff --git a/pkg/system/stat_linux.go b/pkg/system/stat_linux.go index 928ba89e6..3899b3e0e 100644 --- a/pkg/system/stat_linux.go +++ b/pkg/system/stat_linux.go @@ -20,8 +20,7 @@ func fromStatT(s *syscall.Stat_t) (*Stat_t, error) { // Throws an error if the file does not exist func Stat(path string) (*Stat_t, error) { s := &syscall.Stat_t{} - err := syscall.Stat(path, s) - if err != nil { + if err := syscall.Stat(path, s); err != nil { return nil, err } return fromStatT(s) diff --git a/pkg/timeoutconn/timeoutconn.go b/pkg/timeoutconn/timeoutconn.go index 3a554559a..d9534b5da 100644 --- a/pkg/timeoutconn/timeoutconn.go +++ b/pkg/timeoutconn/timeoutconn.go @@ -17,8 +17,7 @@ type conn struct { func (c *conn) Read(b []byte) (int, error) { if c.timeout > 0 { - err := c.Conn.SetReadDeadline(time.Now().Add(c.timeout)) - if err != nil { + if err := c.Conn.SetReadDeadline(time.Now().Add(c.timeout)); err != nil { return 0, err } } diff --git a/registry/session.go b/registry/session.go index f7358bc10..e65f82cd6 100644 --- a/registry/session.go +++ b/registry/session.go @@ -597,8 +597,7 @@ func (r *Session) SearchRepositories(term string) (*SearchResults, error) { return nil, httputils.NewHTTPRequestError(fmt.Sprintf("Unexpected status code %d", res.StatusCode), res) } result := new(SearchResults) - err = json.NewDecoder(res.Body).Decode(result) - return result, err + return result, json.NewDecoder(res.Body).Decode(result) } func (r *Session) GetAuthConfig(withPasswd bool) *cliconfig.AuthConfig { diff --git a/registry/session_v2.go b/registry/session_v2.go index a14e434ac..4188e505b 100644 --- a/registry/session_v2.go +++ b/registry/session_v2.go @@ -387,10 +387,8 @@ func (r *Session) GetV2RemoteTags(ep *Endpoint, imageName string, auth *RequestA return nil, httputils.NewHTTPRequestError(fmt.Sprintf("Server error: %d trying to fetch for %s", res.StatusCode, imageName), res) } - decoder := json.NewDecoder(res.Body) var remote remoteTags - err = decoder.Decode(&remote) - if err != nil { + if err := json.NewDecoder(res.Body).Decode(&remote); err != nil { return nil, fmt.Errorf("Error while decoding the http response: %s", err) } return remote.Tags, nil diff --git a/trust/trusts.go b/trust/trusts.go index c4a2f4158..885127ee5 100644 --- a/trust/trusts.go +++ b/trust/trusts.go @@ -62,8 +62,7 @@ func NewTrustStore(path string) (*TrustStore, error) { baseEndpoints: endpoints, } - err = t.reload() - if err != nil { + if err := t.reload(); err != nil { return nil, err } @@ -170,8 +169,7 @@ func (t *TrustStore) fetch() { continue } // TODO check if value differs - err = ioutil.WriteFile(path.Join(t.path, bg+".json"), b, 0600) - if err != nil { + if err := ioutil.WriteFile(path.Join(t.path, bg+".json"), b, 0600); err != nil { logrus.Infof("Error writing trust graph statement: %s", err) } fetchCount++ @@ -180,8 +178,7 @@ func (t *TrustStore) fetch() { if fetchCount > 0 { go func() { - err := t.reload() - if err != nil { + if err := t.reload(); err != nil { logrus.Infof("Reload of trust graph failed: %s", err) } }() From 3941623fbc3fa724d61f53121513ffd87d03b61c Mon Sep 17 00:00:00 2001 From: David Mackey Date: Mon, 27 Apr 2015 13:33:30 -0700 Subject: [PATCH 44/58] trivial: typo cleanup Signed-off-by: David Mackey --- builder/internals.go | 2 +- contrib/docker-device-tool/device_tool.go | 2 +- daemon/daemon.go | 2 +- daemon/networkdriver/ipallocator/allocator_test.go | 2 +- engine/streams_test.go | 2 +- integration-cli/docker_api_containers_test.go | 2 +- integration-cli/docker_cli_attach_test.go | 4 ++-- integration-cli/docker_cli_attach_unix_test.go | 8 ++++---- integration-cli/docker_cli_build_test.go | 4 ++-- integration-cli/docker_cli_commit_test.go | 2 +- integration-cli/docker_cli_daemon_test.go | 2 +- integration-cli/docker_cli_ps_test.go | 2 +- integration-cli/docker_cli_push_test.go | 4 ++-- integration-cli/docker_cli_rmi_test.go | 2 +- integration-cli/docker_cli_run_test.go | 4 ++-- integration-cli/docker_cli_run_unix_test.go | 4 ++-- integration-cli/docker_cli_save_load_test.go | 2 +- integration-cli/docker_cli_start_test.go | 2 +- integration/api_test.go | 4 ++-- integration/container_test.go | 2 +- integration/runtime_test.go | 2 +- integration/utils.go | 2 +- pkg/archive/archive_windows_test.go | 2 +- pkg/graphdb/graphdb_test.go | 4 ++-- pkg/term/winconsole/console_windows_test.go | 2 +- registry/registry_test.go | 2 +- runconfig/config_test.go | 2 +- runconfig/merge.go | 2 +- volumes/repository.go | 2 +- 29 files changed, 39 insertions(+), 39 deletions(-) diff --git a/builder/internals.go b/builder/internals.go index ba7d45bcb..d373de6c1 100644 --- a/builder/internals.go +++ b/builder/internals.go @@ -483,7 +483,7 @@ func (b *Builder) processImageFrom(img *imagepkg.Image) error { fmt.Fprintf(b.ErrStream, "# Executing %d build triggers\n", nTriggers) } - // Copy the ONBUILD triggers, and remove them from the config, since the config will be commited. + // Copy the ONBUILD triggers, and remove them from the config, since the config will be committed. onBuildTriggers := b.Config.OnBuild b.Config.OnBuild = []string{} diff --git a/contrib/docker-device-tool/device_tool.go b/contrib/docker-device-tool/device_tool.go index 9ad094a34..0a0b0803d 100644 --- a/contrib/docker-device-tool/device_tool.go +++ b/contrib/docker-device-tool/device_tool.go @@ -125,7 +125,7 @@ func main() { err = devices.ResizePool(size) if err != nil { - fmt.Println("Error resizeing pool: ", err) + fmt.Println("Error resizing pool: ", err) os.Exit(1) } diff --git a/daemon/daemon.go b/daemon/daemon.go index 99f5ae636..45a5af28f 100644 --- a/daemon/daemon.go +++ b/daemon/daemon.go @@ -823,7 +823,7 @@ func NewDaemonFromDirectory(config *Config, eng *engine.Engine, registryService // Load storage driver driver, err := graphdriver.New(config.Root, config.GraphOptions) if err != nil { - return nil, fmt.Errorf("error intializing graphdriver: %v", err) + return nil, fmt.Errorf("error initializing graphdriver: %v", err) } logrus.Debugf("Using graph driver %s", driver) // register cleanup for graph driver diff --git a/daemon/networkdriver/ipallocator/allocator_test.go b/daemon/networkdriver/ipallocator/allocator_test.go index fffe6e338..6c5c0e4db 100644 --- a/daemon/networkdriver/ipallocator/allocator_test.go +++ b/daemon/networkdriver/ipallocator/allocator_test.go @@ -601,7 +601,7 @@ func TestRegisterBadTwice(t *testing.T) { Mask: []byte{255, 255, 255, 248}, } if err := a.RegisterSubnet(network, subnet); err != ErrNetworkAlreadyRegistered { - t.Fatalf("Expecteded ErrNetworkAlreadyRegistered error, got %v", err) + t.Fatalf("Expected ErrNetworkAlreadyRegistered error, got %v", err) } } diff --git a/engine/streams_test.go b/engine/streams_test.go index 476a721ba..c22338a32 100644 --- a/engine/streams_test.go +++ b/engine/streams_test.go @@ -182,7 +182,7 @@ func TestInputAddEmpty(t *testing.T) { t.Fatal(err) } if len(data) > 0 { - t.Fatalf("Read from empty input shoul yield no data") + t.Fatalf("Read from empty input should yield no data") } } diff --git a/integration-cli/docker_api_containers_test.go b/integration-cli/docker_api_containers_test.go index e7ce0f3f5..9a2300270 100644 --- a/integration-cli/docker_api_containers_test.go +++ b/integration-cli/docker_api_containers_test.go @@ -643,7 +643,7 @@ func (s *DockerSuite) TestContainerApiCommit(c *check.C) { // sanity check, make sure the image is what we think it is out, err = exec.Command(dockerBinary, "run", img.Id, "ls", "/test").CombinedOutput() if err != nil { - c.Fatalf("error checking commited image: %v - %q", err, string(out)) + c.Fatalf("error checking committed image: %v - %q", err, string(out)) } } diff --git a/integration-cli/docker_cli_attach_test.go b/integration-cli/docker_cli_attach_test.go index 11ae1584a..4dd45ddff 100644 --- a/integration-cli/docker_cli_attach_test.go +++ b/integration-cli/docker_cli_attach_test.go @@ -161,7 +161,7 @@ func (s *DockerSuite) TestAttachDisconnect(c *check.C) { c.Fatal(err) } if strings.TrimSpace(out) != "hello" { - c.Fatalf("exepected 'hello', got %q", out) + c.Fatalf("expected 'hello', got %q", out) } if err := stdin.Close(); err != nil { @@ -174,7 +174,7 @@ func (s *DockerSuite) TestAttachDisconnect(c *check.C) { c.Fatal(err) } if running != "true" { - c.Fatal("exepected container to still be running") + c.Fatal("expected container to still be running") } } diff --git a/integration-cli/docker_cli_attach_unix_test.go b/integration-cli/docker_cli_attach_unix_test.go index 5567c92a0..bae83d994 100644 --- a/integration-cli/docker_cli_attach_unix_test.go +++ b/integration-cli/docker_cli_attach_unix_test.go @@ -172,7 +172,7 @@ func (s *DockerSuite) TestAttachDetach(c *check.C) { c.Fatal(err) } if strings.TrimSpace(out) != "hello" { - c.Fatalf("exepected 'hello', got %q", out) + c.Fatalf("expected 'hello', got %q", out) } // escape sequence @@ -195,7 +195,7 @@ func (s *DockerSuite) TestAttachDetach(c *check.C) { c.Fatal(err) } if running != "true" { - c.Fatal("exepected container to still be running") + c.Fatal("expected container to still be running") } go func() { @@ -243,7 +243,7 @@ func (s *DockerSuite) TestAttachDetachTruncatedID(c *check.C) { c.Fatal(err) } if strings.TrimSpace(out) != "hello" { - c.Fatalf("exepected 'hello', got %q", out) + c.Fatalf("expected 'hello', got %q", out) } // escape sequence @@ -266,7 +266,7 @@ func (s *DockerSuite) TestAttachDetachTruncatedID(c *check.C) { c.Fatal(err) } if running != "true" { - c.Fatal("exepected container to still be running") + c.Fatal("expected container to still be running") } go func() { diff --git a/integration-cli/docker_cli_build_test.go b/integration-cli/docker_cli_build_test.go index 6d6805aef..695e4cd6e 100644 --- a/integration-cli/docker_cli_build_test.go +++ b/integration-cli/docker_cli_build_test.go @@ -3408,7 +3408,7 @@ func (s *DockerSuite) TestBuildVerifyIntString(c *check.C) { out, rc, err := runCommandWithOutput(exec.Command(dockerBinary, "inspect", name)) if rc != 0 || err != nil { - c.Fatalf("Unexcepted error from inspect: rc: %v err: %v", rc, err) + c.Fatalf("Unexpected error from inspect: rc: %v err: %v", rc, err) } if !strings.Contains(out, "\"123\"") { @@ -5033,7 +5033,7 @@ RUN echo " \ expecting := "\n foo \n" if !strings.Contains(out, expecting) { - c.Fatalf("Bad output: %q expecting to contian %q", out, expecting) + c.Fatalf("Bad output: %q expecting to contain %q", out, expecting) } } diff --git a/integration-cli/docker_cli_commit_test.go b/integration-cli/docker_cli_commit_test.go index 1544b3aac..391cd4ebc 100644 --- a/integration-cli/docker_cli_commit_test.go +++ b/integration-cli/docker_cli_commit_test.go @@ -262,7 +262,7 @@ func (s *DockerSuite) TestCommitMergeConfigRun(c *check.C) { out, _ = dockerCmd(c, "run", "--name", name, "commit-test") if strings.TrimSpace(out) != "testing" { - c.Fatal("run config in commited container was not merged") + c.Fatal("run config in committed container was not merged") } type cfg struct { diff --git a/integration-cli/docker_cli_daemon_test.go b/integration-cli/docker_cli_daemon_test.go index 2a945827e..034c17ebb 100644 --- a/integration-cli/docker_cli_daemon_test.go +++ b/integration-cli/docker_cli_daemon_test.go @@ -860,7 +860,7 @@ func (s *DockerSuite) TestDaemonwithwrongkey(c *check.C) { if err := d1.Start(); err == nil { d1.Stop() - c.Fatalf("It should not be succssful to start daemon with wrong key: %v", err) + c.Fatalf("It should not be successful to start daemon with wrong key: %v", err) } content, _ := ioutil.ReadFile(d1.logFile.Name()) diff --git a/integration-cli/docker_cli_ps_test.go b/integration-cli/docker_cli_ps_test.go index 881f02d4f..271051815 100644 --- a/integration-cli/docker_cli_ps_test.go +++ b/integration-cli/docker_cli_ps_test.go @@ -547,7 +547,7 @@ func (s *DockerSuite) TestPsListContainersFilterExited(c *check.C) { } ids = strings.Split(strings.TrimSpace(out), "\n") if len(ids) != 2 { - c.Fatalf("Should be 2 zero exited containerst got %d", len(ids)) + c.Fatalf("Should be 2 zero exited containers got %d", len(ids)) } if ids[0] != secondNonZero { c.Fatalf("First in list should be %q, got %q", secondNonZero, ids[0]) diff --git a/integration-cli/docker_cli_push_test.go b/integration-cli/docker_cli_push_test.go index 8f7ee3158..69a05ed82 100644 --- a/integration-cli/docker_cli_push_test.go +++ b/integration-cli/docker_cli_push_test.go @@ -41,7 +41,7 @@ func (s *DockerRegistrySuite) TestPushUntagged(c *check.C) { expected := "Repository does not exist" pushCmd := exec.Command(dockerBinary, "push", repoName) if out, _, err := runCommandWithOutput(pushCmd); err == nil { - c.Fatalf("pushing the image to the private registry should have failed: outuput %q", out) + c.Fatalf("pushing the image to the private registry should have failed: output %q", out) } else if !strings.Contains(out, expected) { c.Fatalf("pushing the image failed with an unexpected message: expected %q, got %q", expected, out) } @@ -53,7 +53,7 @@ func (s *DockerRegistrySuite) TestPushBadTag(c *check.C) { expected := "does not exist" pushCmd := exec.Command(dockerBinary, "push", repoName) if out, _, err := runCommandWithOutput(pushCmd); err == nil { - c.Fatalf("pushing the image to the private registry should have failed: outuput %q", out) + c.Fatalf("pushing the image to the private registry should have failed: output %q", out) } else if !strings.Contains(out, expected) { c.Fatalf("pushing the image failed with an unexpected message: expected %q, got %q", expected, out) } diff --git a/integration-cli/docker_cli_rmi_test.go b/integration-cli/docker_cli_rmi_test.go index 234fa22f0..9dc2ee297 100644 --- a/integration-cli/docker_cli_rmi_test.go +++ b/integration-cli/docker_cli_rmi_test.go @@ -108,7 +108,7 @@ func (s *DockerSuite) TestRmiImgIDForce(c *check.C) { runCmd = exec.Command(dockerBinary, "rmi", imgID) out, _, err = runCommandWithOutput(runCmd) if err == nil || !strings.Contains(out, fmt.Sprintf("Conflict, cannot delete image %s because it is tagged in multiple repositories, use -f to force", imgID)) { - c.Fatalf("rmi tagged in mutiple repos should have failed without force:%s, %v", out, err) + c.Fatalf("rmi tagged in multiple repos should have failed without force:%s, %v", out, err) } dockerCmd(c, "rmi", "-f", imgID) diff --git a/integration-cli/docker_cli_run_test.go b/integration-cli/docker_cli_run_test.go index b7961126c..c3b25558d 100644 --- a/integration-cli/docker_cli_run_test.go +++ b/integration-cli/docker_cli_run_test.go @@ -329,7 +329,7 @@ func (s *DockerSuite) TestRunLinksContainerWithContainerId(c *check.C) { cmd = exec.Command(dockerBinary, "inspect", "-f", "{{.NetworkSettings.IPAddress}}", cID) ip, _, _, err := runCommandWithStdoutStderr(cmd) if err != nil { - c.Fatalf("faild to inspect container: %v, output: %q", err, ip) + c.Fatalf("failed to inspect container: %v, output: %q", err, ip) } ip = strings.TrimSpace(ip) cmd = exec.Command(dockerBinary, "run", "--link", cID+":test", "busybox", "/bin/cat", "/etc/hosts") @@ -2067,7 +2067,7 @@ func (s *DockerSuite) TestRunCidFileCleanupIfEmpty(c *check.C) { if err == nil { c.Fatalf("Run without command must fail. out=%s", out) } else if !strings.Contains(out, "No command specified") { - c.Fatalf("Run without command failed with wrong outpuc. out=%s\nerr=%v", out, err) + c.Fatalf("Run without command failed with wrong output. out=%s\nerr=%v", out, err) } if _, err := os.Stat(tmpCidFile); err == nil { diff --git a/integration-cli/docker_cli_run_unix_test.go b/integration-cli/docker_cli_run_unix_test.go index 74fae1735..43fa82150 100644 --- a/integration-cli/docker_cli_run_unix_test.go +++ b/integration-cli/docker_cli_run_unix_test.go @@ -213,7 +213,7 @@ func (s *DockerSuite) TestRunAttachDetach(c *check.C) { c.Fatal(err) } if strings.TrimSpace(out) != "hello" { - c.Fatalf("exepected 'hello', got %q", out) + c.Fatalf("expected 'hello', got %q", out) } // escape sequence @@ -236,7 +236,7 @@ func (s *DockerSuite) TestRunAttachDetach(c *check.C) { c.Fatal(err) } if running != "true" { - c.Fatal("exepected container to still be running") + c.Fatal("expected container to still be running") } go func() { diff --git a/integration-cli/docker_cli_save_load_test.go b/integration-cli/docker_cli_save_load_test.go index fe6bf2bfc..f83f6645a 100644 --- a/integration-cli/docker_cli_save_load_test.go +++ b/integration-cli/docker_cli_save_load_test.go @@ -333,7 +333,7 @@ func (s *DockerSuite) TestSaveRepoWithMultipleImages(c *check.C) { sort.Strings(actual) sort.Strings(expected) if !reflect.DeepEqual(expected, actual) { - c.Fatalf("achive does not contains the right layers: got %v, expected %v", actual, expected) + c.Fatalf("archive does not contains the right layers: got %v, expected %v", actual, expected) } } diff --git a/integration-cli/docker_cli_start_test.go b/integration-cli/docker_cli_start_test.go index 52afac1af..13ecedd57 100644 --- a/integration-cli/docker_cli_start_test.go +++ b/integration-cli/docker_cli_start_test.go @@ -205,7 +205,7 @@ func (s *DockerSuite) TestStartMultipleContainers(c *check.C) { c.Fatal("Container should be stopped") } - // start all the three containers, container `child_first` start first which should be faild + // start all the three containers, container `child_first` start first which should be failed // container 'parent' start second and then start container 'child_second' cmd = exec.Command(dockerBinary, "start", "child_first", "parent", "child_second") out, _, err = runCommandWithOutput(cmd) diff --git a/integration/api_test.go b/integration/api_test.go index 614966f6e..e45fa97e8 100644 --- a/integration/api_test.go +++ b/integration/api_test.go @@ -434,7 +434,7 @@ func TestGetEnabledCors(t *testing.T) { t.Errorf("Expected header Access-Control-Allow-Headers to be \"Origin, X-Requested-With, Content-Type, Accept, X-Registry-Auth\", %s found.", allowHeaders) } if allowMethods != "GET, POST, DELETE, PUT, OPTIONS" { - t.Errorf("Expected hearder Access-Control-Allow-Methods to be \"GET, POST, DELETE, PUT, OPTIONS\", %s found.", allowMethods) + t.Errorf("Expected header Access-Control-Allow-Methods to be \"GET, POST, DELETE, PUT, OPTIONS\", %s found.", allowMethods) } } @@ -648,7 +648,7 @@ func TestConstainersStartChunkedEncodingHostConfig(t *testing.T) { } if c.HostConfig.Binds[0] != "/tmp:/foo" { - t.Fatal("Chunked encoding not properly handled, execpted binds to be /tmp:/foo, got:", c.HostConfig.Binds[0]) + t.Fatal("Chunked encoding not properly handled, expected binds to be /tmp:/foo, got:", c.HostConfig.Binds[0]) } } diff --git a/integration/container_test.go b/integration/container_test.go index 01078734c..9256e9997 100644 --- a/integration/container_test.go +++ b/integration/container_test.go @@ -213,7 +213,7 @@ func BenchmarkRunParallel(b *testing.B) { return } // if string(output) != "foo" { - // complete <- fmt.Errorf("Unexecpted output: %v", string(output)) + // complete <- fmt.Errorf("Unexpected output: %v", string(output)) // } if err := daemon.Rm(container); err != nil { complete <- err diff --git a/integration/runtime_test.go b/integration/runtime_test.go index 82f21b700..a2f22072c 100644 --- a/integration/runtime_test.go +++ b/integration/runtime_test.go @@ -837,7 +837,7 @@ func TestDestroyWithInitLayer(t *testing.T) { // Make sure that the container does not exist in the driver if _, err := driver.Get(container.ID, ""); err == nil { - t.Fatal("Conttainer should not exist in the driver") + t.Fatal("Container should not exist in the driver") } // Make sure that the init layer is removed from the driver diff --git a/integration/utils.go b/integration/utils.go index 1d27cd6e4..62e02e9bb 100644 --- a/integration/utils.go +++ b/integration/utils.go @@ -41,7 +41,7 @@ func waitContainerStart(t *testing.T, timeout time.Duration) *daemon.Container { }) if container == nil { - t.Fatal("An error occured while waiting for the container to start") + t.Fatal("An error occurred while waiting for the container to start") } return container diff --git a/pkg/archive/archive_windows_test.go b/pkg/archive/archive_windows_test.go index b33e0fb00..72bc71e06 100644 --- a/pkg/archive/archive_windows_test.go +++ b/pkg/archive/archive_windows_test.go @@ -20,7 +20,7 @@ func TestCanonicalTarNameForPath(t *testing.T) { if out, err := CanonicalTarNameForPath(v.in); err != nil && !v.shouldFail { t.Fatalf("cannot get canonical name for path: %s: %v", v.in, err) } else if v.shouldFail && err == nil { - t.Fatalf("canonical path call should have pailed with error. in=%s out=%s", v.in, out) + t.Fatalf("canonical path call should have failed with error. in=%s out=%s", v.in, out) } else if !v.shouldFail && out != v.expected { t.Fatalf("wrong canonical tar name. expected:%s got:%s", v.expected, out) } diff --git a/pkg/graphdb/graphdb_test.go b/pkg/graphdb/graphdb_test.go index 12dd524ed..1cd223bd9 100644 --- a/pkg/graphdb/graphdb_test.go +++ b/pkg/graphdb/graphdb_test.go @@ -52,7 +52,7 @@ func TestGetRootEntity(t *testing.T) { t.Fatal("Entity should not be nil") } if e.ID() != "0" { - t.Fatalf("Enity id should be 0, got %s", e.ID()) + t.Fatalf("Entity id should be 0, got %s", e.ID()) } } @@ -74,7 +74,7 @@ func TestSetDuplicateEntity(t *testing.T) { t.Fatal(err) } if _, err := db.Set("/foo", "43"); err == nil { - t.Fatalf("Creating an entry with a duplciate path did not cause an error") + t.Fatalf("Creating an entry with a duplicate path did not cause an error") } } diff --git a/pkg/term/winconsole/console_windows_test.go b/pkg/term/winconsole/console_windows_test.go index ee9d96834..edb5d6f66 100644 --- a/pkg/term/winconsole/console_windows_test.go +++ b/pkg/term/winconsole/console_windows_test.go @@ -18,7 +18,7 @@ func helpsTestParseInt16OrDefault(t *testing.T, expectedValue int16, shouldFail t.Errorf(format, args) } if expectedValue != value { - t.Errorf("The value returned does not macth expected\n\tExpected:%v\n\t:Actual%v", expectedValue, value) + t.Errorf("The value returned does not match expected\n\tExpected:%v\n\t:Actual%v", expectedValue, value) t.Errorf(format, args) } } diff --git a/registry/registry_test.go b/registry/registry_test.go index b4bd4ee72..3f63eb6e2 100644 --- a/registry/registry_test.go +++ b/registry/registry_test.go @@ -736,7 +736,7 @@ func TestSearchRepositories(t *testing.T) { } assertEqual(t, results.NumResults, 1, "Expected 1 search results") assertEqual(t, results.Query, "fakequery", "Expected 'fakequery' as query") - assertEqual(t, results.Results[0].StarCount, 42, "Expected 'fakeimage' a ot hae 42 stars") + assertEqual(t, results.Results[0].StarCount, 42, "Expected 'fakeimage' to have 42 stars") } func TestValidRemoteName(t *testing.T) { diff --git a/runconfig/config_test.go b/runconfig/config_test.go index e36dacbf4..87fc6c6aa 100644 --- a/runconfig/config_test.go +++ b/runconfig/config_test.go @@ -104,7 +104,7 @@ func TestParseRunVolumes(t *testing.T) { if config, hostConfig := mustParse(t, "-v /tmp -v /var"); hostConfig.Binds != nil { t.Fatalf("Error parsing volume flags, `-v /tmp -v /var` should not mount-bind anything. Received %v", hostConfig.Binds) } else if _, exists := config.Volumes["/tmp"]; !exists { - t.Fatalf("Error parsing volume flags, `-v /tmp` is missing from volumes. Recevied %v", config.Volumes) + t.Fatalf("Error parsing volume flags, `-v /tmp` is missing from volumes. Received %v", config.Volumes) } else if _, exists := config.Volumes["/var"]; !exists { t.Fatalf("Error parsing volume flags, `-v /var` is missing from volumes. Received %v", config.Volumes) } diff --git a/runconfig/merge.go b/runconfig/merge.go index ce6697dbf..9c9a3b436 100644 --- a/runconfig/merge.go +++ b/runconfig/merge.go @@ -41,7 +41,7 @@ func Merge(userConf, imageConf *Config) error { } if len(imageConf.PortSpecs) > 0 { // FIXME: I think we can safely remove this. Leaving it for now for the sake of reverse-compat paranoia. - logrus.Debugf("Migrating image port specs to containter: %s", strings.Join(imageConf.PortSpecs, ", ")) + logrus.Debugf("Migrating image port specs to container: %s", strings.Join(imageConf.PortSpecs, ", ")) if userConf.ExposedPorts == nil { userConf.ExposedPorts = make(nat.PortSet) } diff --git a/volumes/repository.go b/volumes/repository.go index 0dac3753d..71d6c0ad6 100644 --- a/volumes/repository.go +++ b/volumes/repository.go @@ -58,7 +58,7 @@ func (r *Repository) newVolume(path string, writable bool) (*Volume, error) { path = filepath.Clean(path) // Ignore the error here since the path may not exist - // Really just want to make sure the path we are using is real(or non-existant) + // Really just want to make sure the path we are using is real(or nonexistent) if cleanPath, err := filepath.EvalSymlinks(path); err == nil { path = cleanPath } From c3c08f76bec023218b632e4c688ff9fcda11fcef Mon Sep 17 00:00:00 2001 From: Brian Goff Date: Mon, 27 Apr 2015 16:10:59 -0400 Subject: [PATCH 45/58] Fix undead containers When a container has errors on removal, it gets flagged as dead. If you `docker rm -f` a dead container the container is dereffed from the daemon and doesn't show up on `docker ps` anymore... except that the container JSON file may still be lingering around and becomes undead when you restart the daemon. Signed-off-by: Brian Goff --- daemon/delete.go | 1 + 1 file changed, 1 insertion(+) diff --git a/daemon/delete.go b/daemon/delete.go index d398741d7..464193b28 100644 --- a/daemon/delete.go +++ b/daemon/delete.go @@ -129,6 +129,7 @@ func (daemon *Daemon) commonRm(container *Container, forceRemove bool) (err erro if err != nil && forceRemove { daemon.idIndex.Delete(container.ID) daemon.containers.Delete(container.ID) + os.RemoveAll(container.root) } }() From 57464c32b99b36a2963fb37da86b9870c9a56145 Mon Sep 17 00:00:00 2001 From: Alexander Morozov Date: Sat, 25 Apr 2015 19:47:42 -0700 Subject: [PATCH 46/58] Implement daemon suite for integration-cli For creating and stopping test daemons automatically. Signed-off-by: Alexander Morozov --- integration-cli/check_test.go | 21 ++ integration-cli/docker_cli_daemon_test.go | 403 +++++++++------------- integration-cli/docker_cli_exec_test.go | 15 +- integration-cli/docker_cli_proxy_test.go | 5 +- 4 files changed, 186 insertions(+), 258 deletions(-) diff --git a/integration-cli/check_test.go b/integration-cli/check_test.go index 533ac127c..202799cbf 100644 --- a/integration-cli/check_test.go +++ b/integration-cli/check_test.go @@ -58,3 +58,24 @@ func (s *DockerRegistrySuite) TearDownTest(c *check.C) { s.reg.Close() s.ds.TearDownTest(c) } + +func init() { + check.Suite(&DockerDaemonSuite{ + ds: &DockerSuite{}, + }) +} + +type DockerDaemonSuite struct { + ds *DockerSuite + d *Daemon +} + +func (s *DockerDaemonSuite) SetUpTest(c *check.C) { + s.d = NewDaemon(c) + s.ds.SetUpTest(c) +} + +func (s *DockerDaemonSuite) TearDownTest(c *check.C) { + s.d.Stop() + s.ds.TearDownTest(c) +} diff --git a/integration-cli/docker_cli_daemon_test.go b/integration-cli/docker_cli_daemon_test.go index 034c17ebb..e099995ad 100644 --- a/integration-cli/docker_cli_daemon_test.go +++ b/integration-cli/docker_cli_daemon_test.go @@ -16,25 +16,23 @@ import ( "github.com/go-check/check" ) -func (s *DockerSuite) TestDaemonRestartWithRunningContainersPorts(c *check.C) { - d := NewDaemon(c) - if err := d.StartWithBusybox(); err != nil { +func (s *DockerDaemonSuite) TestDaemonRestartWithRunningContainersPorts(c *check.C) { + if err := s.d.StartWithBusybox(); err != nil { c.Fatalf("Could not start daemon with busybox: %v", err) } - defer d.Stop() - if out, err := d.Cmd("run", "-d", "--name", "top1", "-p", "1234:80", "--restart", "always", "busybox:latest", "top"); err != nil { + if out, err := s.d.Cmd("run", "-d", "--name", "top1", "-p", "1234:80", "--restart", "always", "busybox:latest", "top"); err != nil { c.Fatalf("Could not run top1: err=%v\n%s", err, out) } // --restart=no by default - if out, err := d.Cmd("run", "-d", "--name", "top2", "-p", "80", "busybox:latest", "top"); err != nil { + if out, err := s.d.Cmd("run", "-d", "--name", "top2", "-p", "80", "busybox:latest", "top"); err != nil { c.Fatalf("Could not run top2: err=%v\n%s", err, out) } testRun := func(m map[string]bool, prefix string) { var format string for cont, shouldRun := range m { - out, err := d.Cmd("ps") + out, err := s.d.Cmd("ps") if err != nil { c.Fatalf("Could not run ps: err=%v\n%q", err, out) } @@ -51,34 +49,30 @@ func (s *DockerSuite) TestDaemonRestartWithRunningContainersPorts(c *check.C) { testRun(map[string]bool{"top1": true, "top2": true}, "") - if err := d.Restart(); err != nil { + if err := s.d.Restart(); err != nil { c.Fatalf("Could not restart daemon: %v", err) } - testRun(map[string]bool{"top1": true, "top2": false}, "After daemon restart: ") - } -func (s *DockerSuite) TestDaemonRestartWithVolumesRefs(c *check.C) { - d := NewDaemon(c) - if err := d.StartWithBusybox(); err != nil { +func (s *DockerDaemonSuite) TestDaemonRestartWithVolumesRefs(c *check.C) { + if err := s.d.StartWithBusybox(); err != nil { c.Fatal(err) } - defer d.Stop() - if out, err := d.Cmd("run", "-d", "--name", "volrestarttest1", "-v", "/foo", "busybox"); err != nil { + if out, err := s.d.Cmd("run", "-d", "--name", "volrestarttest1", "-v", "/foo", "busybox"); err != nil { c.Fatal(err, out) } - if err := d.Restart(); err != nil { + if err := s.d.Restart(); err != nil { c.Fatal(err) } - if _, err := d.Cmd("run", "-d", "--volumes-from", "volrestarttest1", "--name", "volrestarttest2", "busybox", "top"); err != nil { + if _, err := s.d.Cmd("run", "-d", "--volumes-from", "volrestarttest1", "--name", "volrestarttest2", "busybox", "top"); err != nil { c.Fatal(err) } - if out, err := d.Cmd("rm", "-fv", "volrestarttest2"); err != nil { + if out, err := s.d.Cmd("rm", "-fv", "volrestarttest2"); err != nil { c.Fatal(err, out) } - v, err := d.Cmd("inspect", "--format", "{{ json .Volumes }}", "volrestarttest1") + v, err := s.d.Cmd("inspect", "--format", "{{ json .Volumes }}", "volrestarttest1") if err != nil { c.Fatal(err) } @@ -87,30 +81,25 @@ func (s *DockerSuite) TestDaemonRestartWithVolumesRefs(c *check.C) { if _, err := os.Stat(volumes["/foo"]); err != nil { c.Fatalf("Expected volume to exist: %s - %s", volumes["/foo"], err) } - } -func (s *DockerSuite) TestDaemonStartIptablesFalse(c *check.C) { - d := NewDaemon(c) - if err := d.Start("--iptables=false"); err != nil { +func (s *DockerDaemonSuite) TestDaemonStartIptablesFalse(c *check.C) { + if err := s.d.Start("--iptables=false"); err != nil { c.Fatalf("we should have been able to start the daemon with passing iptables=false: %v", err) } - d.Stop() - } // Issue #8444: If docker0 bridge is modified (intentionally or unintentionally) and // no longer has an IP associated, we should gracefully handle that case and associate // an IP with it rather than fail daemon start -func (s *DockerSuite) TestDaemonStartBridgeWithoutIPAssociation(c *check.C) { - d := NewDaemon(c) +func (s *DockerDaemonSuite) TestDaemonStartBridgeWithoutIPAssociation(c *check.C) { // rather than depending on brctl commands to verify docker0 is created and up // let's start the daemon and stop it, and then make a modification to run the // actual test - if err := d.Start(); err != nil { + if err := s.d.Start(); err != nil { c.Fatalf("Could not start daemon: %v", err) } - if err := d.Stop(); err != nil { + if err := s.d.Stop(); err != nil { c.Fatalf("Could not stop daemon: %v", err) } @@ -121,27 +110,18 @@ func (s *DockerSuite) TestDaemonStartBridgeWithoutIPAssociation(c *check.C) { c.Fatalf("failed to remove docker0 IP association: %v, stdout: %q, stderr: %q", err, stdout, stderr) } - if err := d.Start(); err != nil { + if err := s.d.Start(); err != nil { warning := "**WARNING: Docker bridge network in bad state--delete docker0 bridge interface to fix" c.Fatalf("Could not start daemon when docker0 has no IP address: %v\n%s", err, warning) } - - // cleanup - stop the daemon if test passed - if err := d.Stop(); err != nil { - c.Fatalf("Could not stop daemon: %v", err) - } - } -func (s *DockerSuite) TestDaemonIptablesClean(c *check.C) { - - d := NewDaemon(c) - if err := d.StartWithBusybox(); err != nil { +func (s *DockerDaemonSuite) TestDaemonIptablesClean(c *check.C) { + if err := s.d.StartWithBusybox(); err != nil { c.Fatalf("Could not start daemon with busybox: %v", err) } - defer d.Stop() - if out, err := d.Cmd("run", "-d", "--name", "top", "-p", "80", "busybox:latest", "top"); err != nil { + if out, err := s.d.Cmd("run", "-d", "--name", "top", "-p", "80", "busybox:latest", "top"); err != nil { c.Fatalf("Could not run top: %s, %v", out, err) } @@ -157,7 +137,7 @@ func (s *DockerSuite) TestDaemonIptablesClean(c *check.C) { c.Fatalf("iptables output should have contained %q, but was %q", ipTablesSearchString, out) } - if err := d.Stop(); err != nil { + if err := s.d.Stop(); err != nil { c.Fatalf("Could not stop daemon: %v", err) } @@ -171,18 +151,14 @@ func (s *DockerSuite) TestDaemonIptablesClean(c *check.C) { if strings.Contains(out, ipTablesSearchString) { c.Fatalf("iptables output should not have contained %q, but was %q", ipTablesSearchString, out) } - } -func (s *DockerSuite) TestDaemonIptablesCreate(c *check.C) { - - d := NewDaemon(c) - if err := d.StartWithBusybox(); err != nil { +func (s *DockerDaemonSuite) TestDaemonIptablesCreate(c *check.C) { + if err := s.d.StartWithBusybox(); err != nil { c.Fatalf("Could not start daemon with busybox: %v", err) } - defer d.Stop() - if out, err := d.Cmd("run", "-d", "--name", "top", "--restart=always", "-p", "80", "busybox:latest", "top"); err != nil { + if out, err := s.d.Cmd("run", "-d", "--name", "top", "--restart=always", "-p", "80", "busybox:latest", "top"); err != nil { c.Fatalf("Could not run top: %s, %v", out, err) } @@ -198,12 +174,12 @@ func (s *DockerSuite) TestDaemonIptablesCreate(c *check.C) { c.Fatalf("iptables output should have contained %q, but was %q", ipTablesSearchString, out) } - if err := d.Restart(); err != nil { + if err := s.d.Restart(); err != nil { c.Fatalf("Could not restart daemon: %v", err) } // make sure the container is not running - runningOut, err := d.Cmd("inspect", "--format='{{.State.Running}}'", "top") + runningOut, err := s.d.Cmd("inspect", "--format='{{.State.Running}}'", "top") if err != nil { c.Fatalf("Could not inspect on container: %s, %v", out, err) } @@ -221,69 +197,64 @@ func (s *DockerSuite) TestDaemonIptablesCreate(c *check.C) { if !strings.Contains(out, ipTablesSearchString) { c.Fatalf("iptables output after restart should have contained %q, but was %q", ipTablesSearchString, out) } - } -func (s *DockerSuite) TestDaemonLoggingLevel(c *check.C) { - d := NewDaemon(c) +func (s *DockerDaemonSuite) TestDaemonLogLevelWrong(c *check.C) { + c.Assert(s.d.Start("--log-level=bogus"), check.NotNil, check.Commentf("Daemon shouldn't start with wrong log level")) +} - if err := d.Start("--log-level=bogus"); err == nil { - c.Fatal("Daemon should not have been able to start") - } - - d = NewDaemon(c) - if err := d.Start("--log-level=debug"); err != nil { +func (s *DockerDaemonSuite) TestDaemonLogLevelDebug(c *check.C) { + if err := s.d.Start("--log-level=debug"); err != nil { c.Fatal(err) } - d.Stop() - content, _ := ioutil.ReadFile(d.logFile.Name()) + content, _ := ioutil.ReadFile(s.d.logFile.Name()) if !strings.Contains(string(content), `level=debug`) { c.Fatalf(`Missing level="debug" in log file:\n%s`, string(content)) } +} - d = NewDaemon(c) - if err := d.Start("--log-level=fatal"); err != nil { +func (s *DockerDaemonSuite) TestDaemonLogLevelFatal(c *check.C) { + // we creating new daemons to create new logFile + if err := s.d.Start("--log-level=fatal"); err != nil { c.Fatal(err) } - d.Stop() - content, _ = ioutil.ReadFile(d.logFile.Name()) + content, _ := ioutil.ReadFile(s.d.logFile.Name()) if strings.Contains(string(content), `level=debug`) { c.Fatalf(`Should not have level="debug" in log file:\n%s`, string(content)) } +} - d = NewDaemon(c) - if err := d.Start("-D"); err != nil { +func (s *DockerDaemonSuite) TestDaemonFlagD(c *check.C) { + if err := s.d.Start("-D"); err != nil { c.Fatal(err) } - d.Stop() - content, _ = ioutil.ReadFile(d.logFile.Name()) + content, _ := ioutil.ReadFile(s.d.logFile.Name()) if !strings.Contains(string(content), `level=debug`) { c.Fatalf(`Missing level="debug" in log file using -D:\n%s`, string(content)) } +} - d = NewDaemon(c) - if err := d.Start("--debug"); err != nil { +func (s *DockerDaemonSuite) TestDaemonFlagDebug(c *check.C) { + if err := s.d.Start("--debug"); err != nil { c.Fatal(err) } - d.Stop() - content, _ = ioutil.ReadFile(d.logFile.Name()) + content, _ := ioutil.ReadFile(s.d.logFile.Name()) if !strings.Contains(string(content), `level=debug`) { c.Fatalf(`Missing level="debug" in log file using --debug:\n%s`, string(content)) } +} - d = NewDaemon(c) - if err := d.Start("--debug", "--log-level=fatal"); err != nil { +func (s *DockerDaemonSuite) TestDaemonFlagDebugLogLevelFatal(c *check.C) { + if err := s.d.Start("--debug", "--log-level=fatal"); err != nil { c.Fatal(err) } - d.Stop() - content, _ = ioutil.ReadFile(d.logFile.Name()) + content, _ := ioutil.ReadFile(s.d.logFile.Name()) if !strings.Contains(string(content), `level=debug`) { c.Fatalf(`Missing level="debug" in log file when using both --debug and --log-level=fatal:\n%s`, string(content)) } - } -func (s *DockerSuite) TestDaemonAllocatesListeningPort(c *check.C) { +func (s *DockerDaemonSuite) TestDaemonAllocatesListeningPort(c *check.C) { listeningPorts := [][]string{ {"0.0.0.0", "0.0.0.0", "5678"}, {"127.0.0.1", "127.0.0.1", "1234"}, @@ -295,31 +266,25 @@ func (s *DockerSuite) TestDaemonAllocatesListeningPort(c *check.C) { cmdArgs = append(cmdArgs, "--host", fmt.Sprintf("tcp://%s:%s", hostDirective[0], hostDirective[2])) } - d := NewDaemon(c) - if err := d.StartWithBusybox(cmdArgs...); err != nil { + if err := s.d.StartWithBusybox(cmdArgs...); err != nil { c.Fatalf("Could not start daemon with busybox: %v", err) } - defer d.Stop() for _, hostDirective := range listeningPorts { - output, err := d.Cmd("run", "-p", fmt.Sprintf("%s:%s:80", hostDirective[1], hostDirective[2]), "busybox", "true") + output, err := s.d.Cmd("run", "-p", fmt.Sprintf("%s:%s:80", hostDirective[1], hostDirective[2]), "busybox", "true") if err == nil { c.Fatalf("Container should not start, expected port already allocated error: %q", output) } else if !strings.Contains(output, "port is already allocated") { c.Fatalf("Expected port is already allocated error: %q", output) } } - } // #9629 -func (s *DockerSuite) TestDaemonVolumesBindsRefs(c *check.C) { - d := NewDaemon(c) - - if err := d.StartWithBusybox(); err != nil { +func (s *DockerDaemonSuite) TestDaemonVolumesBindsRefs(c *check.C) { + if err := s.d.StartWithBusybox(); err != nil { c.Fatal(err) } - defer d.Stop() tmp, err := ioutil.TempDir(os.TempDir(), "") if err != nil { @@ -331,28 +296,26 @@ func (s *DockerSuite) TestDaemonVolumesBindsRefs(c *check.C) { c.Fatal(err) } - if out, err := d.Cmd("create", "-v", tmp+":/foo", "--name=voltest", "busybox"); err != nil { + if out, err := s.d.Cmd("create", "-v", tmp+":/foo", "--name=voltest", "busybox"); err != nil { c.Fatal(err, out) } - if err := d.Restart(); err != nil { + if err := s.d.Restart(); err != nil { c.Fatal(err) } - if out, err := d.Cmd("run", "--volumes-from=voltest", "--name=consumer", "busybox", "/bin/sh", "-c", "[ -f /foo/test ]"); err != nil { + if out, err := s.d.Cmd("run", "--volumes-from=voltest", "--name=consumer", "busybox", "/bin/sh", "-c", "[ -f /foo/test ]"); err != nil { c.Fatal(err, out) } - } -func (s *DockerSuite) TestDaemonKeyGeneration(c *check.C) { +func (s *DockerDaemonSuite) TestDaemonKeyGeneration(c *check.C) { // TODO: skip or update for Windows daemon os.Remove("/etc/docker/key.json") - d := NewDaemon(c) - if err := d.Start(); err != nil { + if err := s.d.Start(); err != nil { c.Fatalf("Could not start daemon: %v", err) } - d.Stop() + s.d.Stop() k, err := libtrust.LoadKeyFile("/etc/docker/key.json") if err != nil { @@ -363,10 +326,9 @@ func (s *DockerSuite) TestDaemonKeyGeneration(c *check.C) { if len(kid) != 59 { c.Fatalf("Bad key ID: %s", kid) } - } -func (s *DockerSuite) TestDaemonKeyMigration(c *check.C) { +func (s *DockerDaemonSuite) TestDaemonKeyMigration(c *check.C) { // TODO: skip or update for Windows daemon os.Remove("/etc/docker/key.json") k1, err := libtrust.GenerateECP256PrivateKey() @@ -380,11 +342,10 @@ func (s *DockerSuite) TestDaemonKeyMigration(c *check.C) { c.Fatalf("Error saving private key: %s", err) } - d := NewDaemon(c) - if err := d.Start(); err != nil { + if err := s.d.Start(); err != nil { c.Fatalf("Could not start daemon: %v", err) } - d.Stop() + s.d.Stop() k2, err := libtrust.LoadKeyFile("/etc/docker/key.json") if err != nil { @@ -393,29 +354,25 @@ func (s *DockerSuite) TestDaemonKeyMigration(c *check.C) { if k1.KeyID() != k2.KeyID() { c.Fatalf("Key not migrated") } - } // Simulate an older daemon (pre 1.3) coming up with volumes specified in containers // without corresponding volume json -func (s *DockerSuite) TestDaemonUpgradeWithVolumes(c *check.C) { - d := NewDaemon(c) - +func (s *DockerDaemonSuite) TestDaemonUpgradeWithVolumes(c *check.C) { graphDir := filepath.Join(os.TempDir(), "docker-test") defer os.RemoveAll(graphDir) - if err := d.StartWithBusybox("-g", graphDir); err != nil { + if err := s.d.StartWithBusybox("-g", graphDir); err != nil { c.Fatal(err) } - defer d.Stop() tmpDir := filepath.Join(os.TempDir(), "test") defer os.RemoveAll(tmpDir) - if out, err := d.Cmd("create", "-v", tmpDir+":/foo", "--name=test", "busybox"); err != nil { + if out, err := s.d.Cmd("create", "-v", tmpDir+":/foo", "--name=test", "busybox"); err != nil { c.Fatal(err, out) } - if err := d.Stop(); err != nil { + if err := s.d.Stop(); err != nil { c.Fatal(err) } @@ -430,7 +387,7 @@ func (s *DockerSuite) TestDaemonUpgradeWithVolumes(c *check.C) { c.Fatal(err) } - if err := d.Start("-g", graphDir); err != nil { + if err := s.d.Start("-g", graphDir); err != nil { c.Fatal(err) } @@ -447,7 +404,7 @@ func (s *DockerSuite) TestDaemonUpgradeWithVolumes(c *check.C) { } // Now with just removing the volume config and not the volume data - if err := d.Stop(); err != nil { + if err := s.d.Stop(); err != nil { c.Fatal(err) } @@ -455,7 +412,7 @@ func (s *DockerSuite) TestDaemonUpgradeWithVolumes(c *check.C) { c.Fatal(err) } - if err := d.Start("-g", graphDir); err != nil { + if err := s.d.Start("-g", graphDir); err != nil { c.Fatal(err) } @@ -467,45 +424,37 @@ func (s *DockerSuite) TestDaemonUpgradeWithVolumes(c *check.C) { if len(dir) == 0 { c.Fatalf("expected volumes config dir to contain data for new volume") } - } // GH#11320 - verify that the daemon exits on failure properly // Note that this explicitly tests the conflict of {-b,--bridge} and {--bip} options as the means // to get a daemon init failure; no other tests for -b/--bip conflict are therefore required -func (s *DockerSuite) TestDaemonExitOnFailure(c *check.C) { - d := NewDaemon(c) - defer d.Stop() - +func (s *DockerDaemonSuite) TestDaemonExitOnFailure(c *check.C) { //attempt to start daemon with incorrect flags (we know -b and --bip conflict) - if err := d.Start("--bridge", "nosuchbridge", "--bip", "1.1.1.1"); err != nil { + if err := s.d.Start("--bridge", "nosuchbridge", "--bip", "1.1.1.1"); err != nil { //verify we got the right error if !strings.Contains(err.Error(), "Daemon exited and never started") { c.Fatalf("Expected daemon not to start, got %v", err) } // look in the log and make sure we got the message that daemon is shutting down - runCmd := exec.Command("grep", "Error starting daemon", d.LogfileName()) + runCmd := exec.Command("grep", "Error starting daemon", s.d.LogfileName()) if out, _, err := runCommandWithOutput(runCmd); err != nil { c.Fatalf("Expected 'Error starting daemon' message; but doesn't exist in log: %q, err: %v", out, err) } } else { //if we didn't get an error and the daemon is running, this is a failure - d.Stop() c.Fatal("Conflicting options should cause the daemon to error out with a failure") } - } -func (s *DockerSuite) TestDaemonUlimitDefaults(c *check.C) { +func (s *DockerDaemonSuite) TestDaemonUlimitDefaults(c *check.C) { testRequires(c, NativeExecDriver) - d := NewDaemon(c) - if err := d.StartWithBusybox("--default-ulimit", "nofile=42:42", "--default-ulimit", "nproc=1024:1024"); err != nil { + if err := s.d.StartWithBusybox("--default-ulimit", "nofile=42:42", "--default-ulimit", "nproc=1024:1024"); err != nil { c.Fatal(err) } - defer d.Stop() - out, err := d.Cmd("run", "--ulimit", "nproc=2048", "--name=test", "busybox", "/bin/sh", "-c", "echo $(ulimit -n); echo $(ulimit -p)") + out, err := s.d.Cmd("run", "--ulimit", "nproc=2048", "--name=test", "busybox", "/bin/sh", "-c", "echo $(ulimit -n); echo $(ulimit -p)") if err != nil { c.Fatal(out, err) } @@ -525,11 +474,11 @@ func (s *DockerSuite) TestDaemonUlimitDefaults(c *check.C) { } // Now restart daemon with a new default - if err := d.Restart("--default-ulimit", "nofile=43"); err != nil { + if err := s.d.Restart("--default-ulimit", "nofile=43"); err != nil { c.Fatal(err) } - out, err = d.Cmd("start", "-a", "test") + out, err = s.d.Cmd("start", "-a", "test") if err != nil { c.Fatal(err) } @@ -547,53 +496,46 @@ func (s *DockerSuite) TestDaemonUlimitDefaults(c *check.C) { if nproc != "2048" { c.Fatalf("exepcted `ulimit -p` to be 2048, got: %s", nproc) } - } // #11315 -func (s *DockerSuite) TestDaemonRestartRenameContainer(c *check.C) { - d := NewDaemon(c) - if err := d.StartWithBusybox(); err != nil { - c.Fatal(err) - } - defer d.Stop() - - if out, err := d.Cmd("run", "--name=test", "busybox"); err != nil { - c.Fatal(err, out) - } - - if out, err := d.Cmd("rename", "test", "test2"); err != nil { - c.Fatal(err, out) - } - - if err := d.Restart(); err != nil { +func (s *DockerDaemonSuite) TestDaemonRestartRenameContainer(c *check.C) { + if err := s.d.StartWithBusybox(); err != nil { c.Fatal(err) } - if out, err := d.Cmd("start", "test2"); err != nil { + if out, err := s.d.Cmd("run", "--name=test", "busybox"); err != nil { c.Fatal(err, out) } + if out, err := s.d.Cmd("rename", "test", "test2"); err != nil { + c.Fatal(err, out) + } + + if err := s.d.Restart(); err != nil { + c.Fatal(err) + } + + if out, err := s.d.Cmd("start", "test2"); err != nil { + c.Fatal(err, out) + } } -func (s *DockerSuite) TestDaemonLoggingDriverDefault(c *check.C) { - d := NewDaemon(c) - - if err := d.StartWithBusybox(); err != nil { +func (s *DockerDaemonSuite) TestDaemonLoggingDriverDefault(c *check.C) { + if err := s.d.StartWithBusybox(); err != nil { c.Fatal(err) } - defer d.Stop() - out, err := d.Cmd("run", "-d", "busybox", "echo", "testline") + out, err := s.d.Cmd("run", "-d", "busybox", "echo", "testline") if err != nil { c.Fatal(out, err) } id := strings.TrimSpace(out) - if out, err := d.Cmd("wait", id); err != nil { + if out, err := s.d.Cmd("wait", id); err != nil { c.Fatal(out, err) } - logPath := filepath.Join(d.folder, "graph", "containers", id, id+"-json.log") + logPath := filepath.Join(s.d.folder, "graph", "containers", id, id+"-json.log") if _, err := os.Stat(logPath); err != nil { c.Fatal(err) @@ -621,72 +563,63 @@ func (s *DockerSuite) TestDaemonLoggingDriverDefault(c *check.C) { } } -func (s *DockerSuite) TestDaemonLoggingDriverDefaultOverride(c *check.C) { - d := NewDaemon(c) - - if err := d.StartWithBusybox(); err != nil { +func (s *DockerDaemonSuite) TestDaemonLoggingDriverDefaultOverride(c *check.C) { + if err := s.d.StartWithBusybox(); err != nil { c.Fatal(err) } - defer d.Stop() - out, err := d.Cmd("run", "-d", "--log-driver=none", "busybox", "echo", "testline") + out, err := s.d.Cmd("run", "-d", "--log-driver=none", "busybox", "echo", "testline") if err != nil { c.Fatal(out, err) } id := strings.TrimSpace(out) - if out, err := d.Cmd("wait", id); err != nil { + if out, err := s.d.Cmd("wait", id); err != nil { c.Fatal(out, err) } - logPath := filepath.Join(d.folder, "graph", "containers", id, id+"-json.log") + logPath := filepath.Join(s.d.folder, "graph", "containers", id, id+"-json.log") if _, err := os.Stat(logPath); err == nil || !os.IsNotExist(err) { c.Fatalf("%s shouldn't exits, error on Stat: %s", logPath, err) } } -func (s *DockerSuite) TestDaemonLoggingDriverNone(c *check.C) { - d := NewDaemon(c) - - if err := d.StartWithBusybox("--log-driver=none"); err != nil { +func (s *DockerDaemonSuite) TestDaemonLoggingDriverNone(c *check.C) { + if err := s.d.StartWithBusybox("--log-driver=none"); err != nil { c.Fatal(err) } - defer d.Stop() - out, err := d.Cmd("run", "-d", "busybox", "echo", "testline") + out, err := s.d.Cmd("run", "-d", "busybox", "echo", "testline") if err != nil { c.Fatal(out, err) } id := strings.TrimSpace(out) - if out, err := d.Cmd("wait", id); err != nil { + if out, err := s.d.Cmd("wait", id); err != nil { c.Fatal(out, err) } - logPath := filepath.Join(d.folder, "graph", "containers", id, id+"-json.log") + logPath := filepath.Join(s.d.folder, "graph", "containers", id, id+"-json.log") if _, err := os.Stat(logPath); err == nil || !os.IsNotExist(err) { c.Fatalf("%s shouldn't exits, error on Stat: %s", logPath, err) } } -func (s *DockerSuite) TestDaemonLoggingDriverNoneOverride(c *check.C) { - d := NewDaemon(c) - - if err := d.StartWithBusybox("--log-driver=none"); err != nil { +func (s *DockerDaemonSuite) TestDaemonLoggingDriverNoneOverride(c *check.C) { + if err := s.d.StartWithBusybox("--log-driver=none"); err != nil { c.Fatal(err) } - defer d.Stop() - out, err := d.Cmd("run", "-d", "--log-driver=json-file", "busybox", "echo", "testline") + out, err := s.d.Cmd("run", "-d", "--log-driver=json-file", "busybox", "echo", "testline") if err != nil { c.Fatal(out, err) } id := strings.TrimSpace(out) - if out, err := d.Cmd("wait", id); err != nil { + if out, err := s.d.Cmd("wait", id); err != nil { c.Fatal(out, err) } - logPath := filepath.Join(d.folder, "graph", "containers", id, id+"-json.log") + logPath := filepath.Join(s.d.folder, "graph", "containers", id, id+"-json.log") if _, err := os.Stat(logPath); err != nil { c.Fatal(err) @@ -714,20 +647,17 @@ func (s *DockerSuite) TestDaemonLoggingDriverNoneOverride(c *check.C) { } } -func (s *DockerSuite) TestDaemonLoggingDriverNoneLogsError(c *check.C) { - d := NewDaemon(c) - - if err := d.StartWithBusybox("--log-driver=none"); err != nil { +func (s *DockerDaemonSuite) TestDaemonLoggingDriverNoneLogsError(c *check.C) { + if err := s.d.StartWithBusybox("--log-driver=none"); err != nil { c.Fatal(err) } - defer d.Stop() - out, err := d.Cmd("run", "-d", "busybox", "echo", "testline") + out, err := s.d.Cmd("run", "-d", "busybox", "echo", "testline") if err != nil { c.Fatal(out, err) } id := strings.TrimSpace(out) - out, err = d.Cmd("logs", id) + out, err = s.d.Cmd("logs", id) if err == nil { c.Fatalf("Logs should fail with \"none\" driver") } @@ -736,54 +666,50 @@ func (s *DockerSuite) TestDaemonLoggingDriverNoneLogsError(c *check.C) { } } -func (s *DockerSuite) TestDaemonDots(c *check.C) { - d := NewDaemon(c) - if err := d.StartWithBusybox(); err != nil { +func (s *DockerDaemonSuite) TestDaemonDots(c *check.C) { + if err := s.d.StartWithBusybox(); err != nil { c.Fatal(err) } - defer d.Stop() // Now create 4 containers - if _, err := d.Cmd("create", "busybox"); err != nil { + if _, err := s.d.Cmd("create", "busybox"); err != nil { c.Fatalf("Error creating container: %q", err) } - if _, err := d.Cmd("create", "busybox"); err != nil { + if _, err := s.d.Cmd("create", "busybox"); err != nil { c.Fatalf("Error creating container: %q", err) } - if _, err := d.Cmd("create", "busybox"); err != nil { + if _, err := s.d.Cmd("create", "busybox"); err != nil { c.Fatalf("Error creating container: %q", err) } - if _, err := d.Cmd("create", "busybox"); err != nil { + if _, err := s.d.Cmd("create", "busybox"); err != nil { c.Fatalf("Error creating container: %q", err) } - d.Stop() + s.d.Stop() - d.Start("--log-level=debug") - d.Stop() - content, _ := ioutil.ReadFile(d.logFile.Name()) + s.d.Start("--log-level=debug") + s.d.Stop() + content, _ := ioutil.ReadFile(s.d.logFile.Name()) if strings.Contains(string(content), "....") { c.Fatalf("Debug level should not have ....\n%s", string(content)) } - d.Start("--log-level=error") - d.Stop() - content, _ = ioutil.ReadFile(d.logFile.Name()) + s.d.Start("--log-level=error") + s.d.Stop() + content, _ = ioutil.ReadFile(s.d.logFile.Name()) if strings.Contains(string(content), "....") { c.Fatalf("Error level should not have ....\n%s", string(content)) } - d.Start("--log-level=info") - d.Stop() - content, _ = ioutil.ReadFile(d.logFile.Name()) + s.d.Start("--log-level=info") + s.d.Stop() + content, _ = ioutil.ReadFile(s.d.logFile.Name()) if !strings.Contains(string(content), "....") { c.Fatalf("Info level should have ....\n%s", string(content)) } - } -func (s *DockerSuite) TestDaemonUnixSockCleanedUp(c *check.C) { - d := NewDaemon(c) +func (s *DockerDaemonSuite) TestDaemonUnixSockCleanedUp(c *check.C) { dir, err := ioutil.TempDir("", "socket-cleanup-test") if err != nil { c.Fatal(err) @@ -791,26 +717,24 @@ func (s *DockerSuite) TestDaemonUnixSockCleanedUp(c *check.C) { defer os.RemoveAll(dir) sockPath := filepath.Join(dir, "docker.sock") - if err := d.Start("--host", "unix://"+sockPath); err != nil { + if err := s.d.Start("--host", "unix://"+sockPath); err != nil { c.Fatal(err) } - defer d.Stop() if _, err := os.Stat(sockPath); err != nil { c.Fatal("socket does not exist") } - if err := d.Stop(); err != nil { + if err := s.d.Stop(); err != nil { c.Fatal(err) } if _, err := os.Stat(sockPath); err == nil || !os.IsNotExist(err) { c.Fatal("unix socket is not cleaned up") } - } -func (s *DockerSuite) TestDaemonwithwrongkey(c *check.C) { +func (s *DockerDaemonSuite) TestDaemonwithwrongkey(c *check.C) { type Config struct { Crv string `json:"crv"` D string `json:"d"` @@ -821,12 +745,11 @@ func (s *DockerSuite) TestDaemonwithwrongkey(c *check.C) { } os.Remove("/etc/docker/key.json") - d := NewDaemon(c) - if err := d.Start(); err != nil { + if err := s.d.Start(); err != nil { c.Fatalf("Failed to start daemon: %v", err) } - if err := d.Stop(); err != nil { + if err := s.d.Stop(); err != nil { c.Fatalf("Could not stop daemon: %v", err) } @@ -855,46 +778,41 @@ func (s *DockerSuite) TestDaemonwithwrongkey(c *check.C) { c.Fatalf("Error ioutil.WriteFile: %s", err) } - d1 := NewDaemon(c) defer os.Remove("/etc/docker/key.json") - if err := d1.Start(); err == nil { - d1.Stop() + if err := s.d.Start(); err == nil { c.Fatalf("It should not be successful to start daemon with wrong key: %v", err) } - content, _ := ioutil.ReadFile(d1.logFile.Name()) + content, _ := ioutil.ReadFile(s.d.logFile.Name()) if !strings.Contains(string(content), "Public Key ID does not match") { c.Fatal("Missing KeyID message from daemon logs") } - } -func (s *DockerSuite) TestDaemonRestartKillWait(c *check.C) { - d := NewDaemon(c) - if err := d.StartWithBusybox(); err != nil { +func (s *DockerDaemonSuite) TestDaemonRestartKillWait(c *check.C) { + if err := s.d.StartWithBusybox(); err != nil { c.Fatalf("Could not start daemon with busybox: %v", err) } - defer d.Stop() - out, err := d.Cmd("run", "-id", "busybox", "/bin/cat") + out, err := s.d.Cmd("run", "-id", "busybox", "/bin/cat") if err != nil { c.Fatalf("Could not run /bin/cat: err=%v\n%s", err, out) } containerID := strings.TrimSpace(out) - if out, err := d.Cmd("kill", containerID); err != nil { + if out, err := s.d.Cmd("kill", containerID); err != nil { c.Fatalf("Could not kill %s: err=%v\n%s", containerID, err, out) } - if err := d.Restart(); err != nil { + if err := s.d.Restart(); err != nil { c.Fatalf("Could not restart daemon: %v", err) } errchan := make(chan error) go func() { - if out, err := d.Cmd("wait", containerID); err != nil { + if out, err := s.d.Cmd("wait", containerID); err != nil { errchan <- fmt.Errorf("%v:\n%s", err, out) } close(errchan) @@ -908,26 +826,23 @@ func (s *DockerSuite) TestDaemonRestartKillWait(c *check.C) { c.Fatal(err) } } - } // TestHttpsInfo connects via two-way authenticated HTTPS to the info endpoint -func (s *DockerSuite) TestHttpsInfo(c *check.C) { +func (s *DockerDaemonSuite) TestHttpsInfo(c *check.C) { const ( testDaemonHttpsAddr = "localhost:4271" ) - d := NewDaemon(c) - if err := d.Start("--tlsverify", "--tlscacert", "fixtures/https/ca.pem", "--tlscert", "fixtures/https/server-cert.pem", + if err := s.d.Start("--tlsverify", "--tlscacert", "fixtures/https/ca.pem", "--tlscert", "fixtures/https/server-cert.pem", "--tlskey", "fixtures/https/server-key.pem", "-H", testDaemonHttpsAddr); err != nil { c.Fatalf("Could not start daemon with busybox: %v", err) } - defer d.Stop() //force tcp protocol host := fmt.Sprintf("tcp://%s", testDaemonHttpsAddr) daemonArgs := []string{"--host", host, "--tlsverify", "--tlscacert", "fixtures/https/ca.pem", "--tlscert", "fixtures/https/client-cert.pem", "--tlskey", "fixtures/https/client-key.pem"} - out, err := d.CmdWithArgs(daemonArgs, "info") + out, err := s.d.CmdWithArgs(daemonArgs, "info") if err != nil { c.Fatalf("Error Occurred: %s and output: %s", err, out) } @@ -935,22 +850,20 @@ func (s *DockerSuite) TestHttpsInfo(c *check.C) { // TestHttpsInfoRogueCert connects via two-way authenticated HTTPS to the info endpoint // by using a rogue client certificate and checks that it fails with the expected error. -func (s *DockerSuite) TestHttpsInfoRogueCert(c *check.C) { +func (s *DockerDaemonSuite) TestHttpsInfoRogueCert(c *check.C) { const ( errBadCertificate = "remote error: bad certificate" testDaemonHttpsAddr = "localhost:4271" ) - d := NewDaemon(c) - if err := d.Start("--tlsverify", "--tlscacert", "fixtures/https/ca.pem", "--tlscert", "fixtures/https/server-cert.pem", + if err := s.d.Start("--tlsverify", "--tlscacert", "fixtures/https/ca.pem", "--tlscert", "fixtures/https/server-cert.pem", "--tlskey", "fixtures/https/server-key.pem", "-H", testDaemonHttpsAddr); err != nil { c.Fatalf("Could not start daemon with busybox: %v", err) } - defer d.Stop() //force tcp protocol host := fmt.Sprintf("tcp://%s", testDaemonHttpsAddr) daemonArgs := []string{"--host", host, "--tlsverify", "--tlscacert", "fixtures/https/ca.pem", "--tlscert", "fixtures/https/client-rogue-cert.pem", "--tlskey", "fixtures/https/client-rogue-key.pem"} - out, err := d.CmdWithArgs(daemonArgs, "info") + out, err := s.d.CmdWithArgs(daemonArgs, "info") if err == nil || !strings.Contains(out, errBadCertificate) { c.Fatalf("Expected err: %s, got instead: %s and output: %s", errBadCertificate, err, out) } @@ -958,22 +871,20 @@ func (s *DockerSuite) TestHttpsInfoRogueCert(c *check.C) { // TestHttpsInfoRogueServerCert connects via two-way authenticated HTTPS to the info endpoint // which provides a rogue server certificate and checks that it fails with the expected error -func (s *DockerSuite) TestHttpsInfoRogueServerCert(c *check.C) { +func (s *DockerDaemonSuite) TestHttpsInfoRogueServerCert(c *check.C) { const ( errCaUnknown = "x509: certificate signed by unknown authority" testDaemonRogueHttpsAddr = "localhost:4272" ) - d := NewDaemon(c) - if err := d.Start("--tlsverify", "--tlscacert", "fixtures/https/ca.pem", "--tlscert", "fixtures/https/server-rogue-cert.pem", + if err := s.d.Start("--tlsverify", "--tlscacert", "fixtures/https/ca.pem", "--tlscert", "fixtures/https/server-rogue-cert.pem", "--tlskey", "fixtures/https/server-rogue-key.pem", "-H", testDaemonRogueHttpsAddr); err != nil { c.Fatalf("Could not start daemon with busybox: %v", err) } - defer d.Stop() //force tcp protocol host := fmt.Sprintf("tcp://%s", testDaemonRogueHttpsAddr) daemonArgs := []string{"--host", host, "--tlsverify", "--tlscacert", "fixtures/https/ca.pem", "--tlscert", "fixtures/https/client-rogue-cert.pem", "--tlskey", "fixtures/https/client-rogue-key.pem"} - out, err := d.CmdWithArgs(daemonArgs, "info") + out, err := s.d.CmdWithArgs(daemonArgs, "info") if err == nil || !strings.Contains(out, errCaUnknown) { c.Fatalf("Expected err: %s, got instead: %s and output: %s", errCaUnknown, err, out) } diff --git a/integration-cli/docker_cli_exec_test.go b/integration-cli/docker_cli_exec_test.go index c6910d432..cbdd59756 100644 --- a/integration-cli/docker_cli_exec_test.go +++ b/integration-cli/docker_cli_exec_test.go @@ -117,28 +117,26 @@ func (s *DockerSuite) TestExecAfterContainerRestart(c *check.C) { } -func (s *DockerSuite) TestExecAfterDaemonRestart(c *check.C) { +func (s *DockerDaemonSuite) TestExecAfterDaemonRestart(c *check.C) { testRequires(c, SameHostDaemon) - d := NewDaemon(c) - if err := d.StartWithBusybox(); err != nil { + if err := s.d.StartWithBusybox(); err != nil { c.Fatalf("Could not start daemon with busybox: %v", err) } - defer d.Stop() - if out, err := d.Cmd("run", "-d", "--name", "top", "-p", "80", "busybox:latest", "top"); err != nil { + if out, err := s.d.Cmd("run", "-d", "--name", "top", "-p", "80", "busybox:latest", "top"); err != nil { c.Fatalf("Could not run top: err=%v\n%s", err, out) } - if err := d.Restart(); err != nil { + if err := s.d.Restart(); err != nil { c.Fatalf("Could not restart daemon: %v", err) } - if out, err := d.Cmd("start", "top"); err != nil { + if out, err := s.d.Cmd("start", "top"); err != nil { c.Fatalf("Could not start top after daemon restart: err=%v\n%s", err, out) } - out, err := d.Cmd("exec", "top", "echo", "hello") + out, err := s.d.Cmd("exec", "top", "echo", "hello") if err != nil { c.Fatalf("Could not exec on container top: err=%v\n%s", err, out) } @@ -147,7 +145,6 @@ func (s *DockerSuite) TestExecAfterDaemonRestart(c *check.C) { if outStr != "hello" { c.Errorf("container should've printed hello, instead printed %q", outStr) } - } // Regression test for #9155, #9044 diff --git a/integration-cli/docker_cli_proxy_test.go b/integration-cli/docker_cli_proxy_test.go index c07ed6406..8b55c67d8 100644 --- a/integration-cli/docker_cli_proxy_test.go +++ b/integration-cli/docker_cli_proxy_test.go @@ -22,7 +22,7 @@ func (s *DockerSuite) TestCliProxyDisableProxyUnixSock(c *check.C) { // Can't use localhost here since go has a special case to not use proxy if connecting to localhost // See https://golang.org/pkg/net/http/#ProxyFromEnvironment -func (s *DockerSuite) TestCliProxyProxyTCPSock(c *check.C) { +func (s *DockerDaemonSuite) TestCliProxyProxyTCPSock(c *check.C) { testRequires(c, SameHostDaemon) // get the IP to use to connect since we can't use localhost addrs, err := net.InterfaceAddrs() @@ -43,8 +43,7 @@ func (s *DockerSuite) TestCliProxyProxyTCPSock(c *check.C) { c.Fatal("could not find ip to connect to") } - d := NewDaemon(c) - if err := d.Start("-H", "tcp://"+ip+":2375"); err != nil { + if err := s.d.Start("-H", "tcp://"+ip+":2375"); err != nil { c.Fatal(err) } From d4bbbe58ddd5916c5f7d253a90fd97e3a4fd59bf Mon Sep 17 00:00:00 2001 From: Jessica Frazelle Date: Wed, 28 Jan 2015 14:54:25 -0800 Subject: [PATCH 47/58] Add docs for `--exec-opt` and setting `native.cgroupdriver`. update man pages. update bash completion. Docker-DCO-1.1-Signed-off-by: Jessica Frazelle (github: jfrazelle) Docker-DCO-1.1-Signed-off-by: Jessie Frazelle (github: jfrazelle) --- contrib/completion/bash/docker | 1 + contrib/completion/fish/docker.fish | 1 + docs/man/docker.1.md | 15 +++++++++++++++ docs/sources/reference/commandline/cli.md | 21 +++++++++++++++++++++ 4 files changed, 38 insertions(+) diff --git a/contrib/completion/bash/docker b/contrib/completion/bash/docker index f3b833158..5b7a102a6 100755 --- a/contrib/completion/bash/docker +++ b/contrib/completion/bash/docker @@ -1151,6 +1151,7 @@ _docker() { --dns --dns-search --exec-driver -e + --exec-opt --fixed-cidr --fixed-cidr-v6 --graph -g diff --git a/contrib/completion/fish/docker.fish b/contrib/completion/fish/docker.fish index d3237588e..c53591185 100644 --- a/contrib/completion/fish/docker.fish +++ b/contrib/completion/fish/docker.fish @@ -51,6 +51,7 @@ complete -c docker -f -n '__fish_docker_no_subcommand' -s d -l daemon -d 'Enable complete -c docker -f -n '__fish_docker_no_subcommand' -l dns -d 'Force Docker to use specific DNS servers' complete -c docker -f -n '__fish_docker_no_subcommand' -l dns-search -d 'Force Docker to use specific DNS search domains' complete -c docker -f -n '__fish_docker_no_subcommand' -s e -l exec-driver -d 'Force the Docker runtime to use a specific exec driver' +complete -c docker -f -n '__fish_docker_no_subcommand' -l exec-opt -d 'Set exec driver options' complete -c docker -f -n '__fish_docker_no_subcommand' -l fixed-cidr -d 'IPv4 subnet for fixed IPs (e.g. 10.20.0.0/16)' complete -c docker -f -n '__fish_docker_no_subcommand' -l fixed-cidr-v6 -d 'IPv6 subnet for fixed IPs (e.g.: 2001:a02b/48)' complete -c docker -f -n '__fish_docker_no_subcommand' -s G -l group -d 'Group to assign the unix socket specified by -H when running in daemon mode' diff --git a/docs/man/docker.1.md b/docs/man/docker.1.md index 0196b6364..8ee5bc3cf 100644 --- a/docs/man/docker.1.md +++ b/docs/man/docker.1.md @@ -124,6 +124,9 @@ unix://[/path/to/socket] to use. **-v**, **--version**=*true*|*false* Print version information and quit. Default is false. +**--exec-opt**=[] + Set exec driver options. See EXEC DRIVER OPTIONS. + **--selinux-enabled**=*true*|*false* Enable selinux support. Default is false. SELinux does not presently support the BTRFS storage driver. @@ -319,6 +322,18 @@ for data and metadata: --storage-opt dm.metadatadev=/dev/vdc \ --storage-opt dm.basesize=20G +# EXEC DRIVER OPTIONS + +Options to the exec-driver can be specified with the **--exec-opt** flags. The +only driver accepting options is the *native* (libcontainer) driver. Therefore +use these flags with **-s=**native. + +The following is the only *native* option: + +#### native.cgroupdriver +Specifies the management of the container's cgroups. As of now the only viable +options are `cgroupfs` and `systemd`. The option will always fallback to `cgroupfs`. + #### Client For specific client examples please see the man page for the specific Docker command. For example: diff --git a/docs/sources/reference/commandline/cli.md b/docs/sources/reference/commandline/cli.md index 26659c8ff..e2d073a42 100644 --- a/docs/sources/reference/commandline/cli.md +++ b/docs/sources/reference/commandline/cli.md @@ -452,6 +452,27 @@ https://linuxcontainers.org/) via the `lxc` execution driver, however, this is not where the primary development of new functionality is taking place. Add `-e lxc` to the daemon flags to use the `lxc` execution driver. +#### Exec driver options + +Particular exec-driver can be configured with options specified with +`--exec-opt` flags. The only driver accepting options is `native` +(libcontainer) as of now. All its options are prefixed with `native`. + +Currently supported options are: + + * `native.cgroupdriver` + + Specifies the management of the container's cgroups. As of now the only + viable options are `cgroupfs` and `systemd`. The option will always + fallback to `cgroupfs`. By default, if no option is specified, the + execdriver will try `systemd` and fallback to `cgroupfs`. Same applies if + `systemd` is passed as the `cgroupdriver` but is not capable of being used. + + Example use: + + $ sudo docker -d --exec-opt native.cgroupdriver=cgroupfs + + ### Daemon DNS options From 2afcd10202283478cbafb21e8c5f90f1236acccc Mon Sep 17 00:00:00 2001 From: Jessica Frazelle Date: Mon, 6 Apr 2015 11:47:55 -0700 Subject: [PATCH 48/58] option to configure cgroups Signed-off-by: Jessica Frazelle --- daemon/config.go | 2 ++ daemon/daemon.go | 2 +- daemon/execdriver/execdrivers/execdrivers.go | 4 +-- daemon/execdriver/native/driver.go | 38 +++++++++++++++++++- docs/man/docker.1.md | 14 ++++---- docs/sources/reference/commandline/cli.md | 32 +++++++---------- 6 files changed, 62 insertions(+), 30 deletions(-) diff --git a/daemon/config.go b/daemon/config.go index 952fb5f74..43b08531b 100644 --- a/daemon/config.go +++ b/daemon/config.go @@ -29,6 +29,7 @@ type Config struct { GraphDriver string GraphOptions []string ExecDriver string + ExecOptions []string Mtu int SocketGroup string EnableCors bool @@ -70,6 +71,7 @@ func (config *Config) InstallFlags() { flag.StringVar(&config.CorsHeaders, []string{"-api-cors-header"}, "", "Set CORS headers in the remote API") opts.IPVar(&config.Bridge.DefaultIp, []string{"#ip", "-ip"}, "0.0.0.0", "Default IP when binding container ports") opts.ListVar(&config.GraphOptions, []string{"-storage-opt"}, "Set storage driver options") + opts.ListVar(&config.ExecOptions, []string{"-exec-opt"}, "Set exec driver options") // FIXME: why the inconsistency between "hosts" and "sockets"? opts.IPListVar(&config.Dns, []string{"#dns", "-dns"}, "DNS server to use") opts.DnsSearchListVar(&config.DnsSearch, []string{"-dns-search"}, "DNS search domains to use") diff --git a/daemon/daemon.go b/daemon/daemon.go index 109ee35cb..05de40217 100644 --- a/daemon/daemon.go +++ b/daemon/daemon.go @@ -942,7 +942,7 @@ func NewDaemonFromDirectory(config *Config, eng *engine.Engine, registryService sysInfo := sysinfo.New(false) const runDir = "/var/run/docker" - ed, err := execdrivers.NewDriver(config.ExecDriver, runDir, config.Root, sysInitPath, sysInfo) + ed, err := execdrivers.NewDriver(config.ExecDriver, config.ExecOptions, runDir, config.Root, sysInitPath, sysInfo) if err != nil { return nil, err } diff --git a/daemon/execdriver/execdrivers/execdrivers.go b/daemon/execdriver/execdrivers/execdrivers.go index f6f97c930..dde0be1f0 100644 --- a/daemon/execdriver/execdrivers/execdrivers.go +++ b/daemon/execdriver/execdrivers/execdrivers.go @@ -10,7 +10,7 @@ import ( "github.com/docker/docker/pkg/sysinfo" ) -func NewDriver(name, root, libPath, initPath string, sysInfo *sysinfo.SysInfo) (execdriver.Driver, error) { +func NewDriver(name string, options []string, root, libPath, initPath string, sysInfo *sysinfo.SysInfo) (execdriver.Driver, error) { switch name { case "lxc": // we want to give the lxc driver the full docker root because it needs @@ -18,7 +18,7 @@ func NewDriver(name, root, libPath, initPath string, sysInfo *sysinfo.SysInfo) ( // to be backwards compatible return lxc.NewDriver(root, libPath, initPath, sysInfo.AppArmor) case "native": - return native.NewDriver(path.Join(root, "execdriver", "native"), initPath) + return native.NewDriver(path.Join(root, "execdriver", "native"), initPath, options) } return nil, fmt.Errorf("unknown exec driver %s", name) } diff --git a/daemon/execdriver/native/driver.go b/daemon/execdriver/native/driver.go index ad13e1c1e..afc3f1e45 100644 --- a/daemon/execdriver/native/driver.go +++ b/daemon/execdriver/native/driver.go @@ -8,12 +8,14 @@ import ( "os" "os/exec" "path/filepath" + "strings" "sync" "syscall" "time" "github.com/Sirupsen/logrus" "github.com/docker/docker/daemon/execdriver" + "github.com/docker/docker/pkg/parsers" "github.com/docker/docker/pkg/reexec" sysinfo "github.com/docker/docker/pkg/system" "github.com/docker/docker/pkg/term" @@ -39,7 +41,7 @@ type driver struct { sync.Mutex } -func NewDriver(root, initPath string) (*driver, error) { +func NewDriver(root, initPath string, options []string) (*driver, error) { meminfo, err := sysinfo.ReadMemInfo() if err != nil { return nil, err @@ -52,11 +54,45 @@ func NewDriver(root, initPath string) (*driver, error) { if err := apparmor.InstallDefaultProfile(); err != nil { return nil, err } + + // choose cgroup manager + // this makes sure there are no breaking changes to people + // who upgrade from versions without native.cgroupdriver opt cgm := libcontainer.Cgroupfs if systemd.UseSystemd() { cgm = libcontainer.SystemdCgroups } + // parse the options + for _, option := range options { + key, val, err := parsers.ParseKeyValueOpt(option) + if err != nil { + return nil, err + } + key = strings.ToLower(key) + switch key { + case "native.cgroupdriver": + // override the default if they set options + switch val { + case "systemd": + if systemd.UseSystemd() { + cgm = libcontainer.SystemdCgroups + } else { + // warn them that they chose the wrong driver + logrus.Warn("You cannot use systemd as native.cgroupdriver, using cgroupfs instead") + } + case "cgroupfs": + cgm = libcontainer.Cgroupfs + default: + return nil, fmt.Errorf("Unknown native.cgroupdriver given %q. try cgroupfs or systemd", val) + } + default: + return nil, fmt.Errorf("Unknown option %s\n", key) + } + } + + logrus.Debugf("Using %v as native.cgroupdriver", cgm) + f, err := libcontainer.New( root, cgm, diff --git a/docs/man/docker.1.md b/docs/man/docker.1.md index 8ee5bc3cf..794fb1688 100644 --- a/docs/man/docker.1.md +++ b/docs/man/docker.1.md @@ -324,15 +324,15 @@ for data and metadata: # EXEC DRIVER OPTIONS -Options to the exec-driver can be specified with the **--exec-opt** flags. The -only driver accepting options is the *native* (libcontainer) driver. Therefore -use these flags with **-s=**native. - -The following is the only *native* option: +Use the **--exec-opt** flags to specify options to the exec-driver. The only +driver that accepts this flag is the *native* (libcontainer) driver. As a +result, you must also specify **-s=**native for this option to have effect. The +following is the only *native* option: #### native.cgroupdriver -Specifies the management of the container's cgroups. As of now the only viable -options are `cgroupfs` and `systemd`. The option will always fallback to `cgroupfs`. +Specifies the management of the container's `cgroups`. You can specify +`cgroupfs` or `systemd`. If you specify `systemd` and it is not available, the +system uses `cgroupfs`. #### Client For specific client examples please see the man page for the specific Docker diff --git a/docs/sources/reference/commandline/cli.md b/docs/sources/reference/commandline/cli.md index e2d073a42..2348ff549 100644 --- a/docs/sources/reference/commandline/cli.md +++ b/docs/sources/reference/commandline/cli.md @@ -442,7 +442,7 @@ Currently supported options are: > Otherwise, set this flag for migrating existing Docker daemons to a > daemon with a supported environment. -### Docker exec-driver option +### Docker execdriver option The Docker daemon uses a specifically built `libcontainer` execution driver as its interface to the Linux kernel `namespaces`, `cgroups`, and `SELinux`. @@ -452,27 +452,21 @@ https://linuxcontainers.org/) via the `lxc` execution driver, however, this is not where the primary development of new functionality is taking place. Add `-e lxc` to the daemon flags to use the `lxc` execution driver. -#### Exec driver options +#### Options for the native execdriver -Particular exec-driver can be configured with options specified with -`--exec-opt` flags. The only driver accepting options is `native` -(libcontainer) as of now. All its options are prefixed with `native`. - -Currently supported options are: - - * `native.cgroupdriver` - - Specifies the management of the container's cgroups. As of now the only - viable options are `cgroupfs` and `systemd`. The option will always - fallback to `cgroupfs`. By default, if no option is specified, the - execdriver will try `systemd` and fallback to `cgroupfs`. Same applies if - `systemd` is passed as the `cgroupdriver` but is not capable of being used. - - Example use: - - $ sudo docker -d --exec-opt native.cgroupdriver=cgroupfs +You can configure the `native` (libcontainer) execdriver using options specified +with the `--exec-opt` flag. All the flag's options have the `native` prefix. A +single `native.cgroupdriver` option is available. +The `native.cgroupdriver` option specifies the management of the container's +cgroups. You can specify `cgroupfs` or `systemd`. If you specify `systemd` and +it is not available, the system uses `cgroupfs`. By default, if no option is +specified, the execdriver first tries `systemd` and falls back to `cgroupfs`. +This example sets the execdriver to `cgroupfs`: + $ sudo docker -d --exec-opt native.cgroupdriver=cgroupfs + +Setting this option applies to all containers the daemon launches. ### Daemon DNS options From af8efab7561484debffa3f6782eaea199fa22506 Mon Sep 17 00:00:00 2001 From: Jessica Frazelle Date: Tue, 10 Mar 2015 11:21:09 -0700 Subject: [PATCH 49/58] add initial docs for windows client testing Docker-DCO-1.1-Signed-off-by: Jessie Frazelle (github: jfrazelle) Docker-DCO-1.1-Signed-off-by: Jessie Frazelle (github: jfrazelle) docs: crop and optimize images Cropped and optimized images. Signed-off-by: Sebastiaan van Stijn Docker-DCO-1.1-Signed-off-by: Jessie Frazelle (github: jfrazelle) Testing and updating the Windows material Signed-off-by: Mary Anthony checkpoint Signed-off-by: Mary Anthony Fitting the Windows specific material into the contributor guide Signed-off-by: Mary Anthony Entering James comments Signed-off-by: Mary Anthony --- docs/mkdocs.yml | 33 +-- docs/sources/project/images/git_bash.png | Bin 0 -> 39522 bytes docs/sources/project/images/include_gcc.png | Bin 0 -> 16446 bytes docs/sources/project/images/path_variable.png | Bin 0 -> 59864 bytes .../project/images/windows-env-vars.png | Bin 0 -> 120562 bytes docs/sources/project/images/windows-mingw.png | Bin 0 -> 230524 bytes docs/sources/project/set-up-git.md | 5 +- docs/sources/project/software-req-win.md | 258 ++++++++++++++++++ docs/sources/project/software-required.md | 5 +- docs/sources/project/test-and-docs.md | 40 +++ 10 files changed, 322 insertions(+), 19 deletions(-) create mode 100644 docs/sources/project/images/git_bash.png create mode 100644 docs/sources/project/images/include_gcc.png create mode 100644 docs/sources/project/images/path_variable.png create mode 100644 docs/sources/project/images/windows-env-vars.png create mode 100644 docs/sources/project/images/windows-mingw.png create mode 100644 docs/sources/project/software-req-win.md diff --git a/docs/mkdocs.yml b/docs/mkdocs.yml index e425175f6..a67910b21 100644 --- a/docs/mkdocs.yml +++ b/docs/mkdocs.yml @@ -34,6 +34,7 @@ pages: - ['installation/ubuntulinux.md', 'Installation', 'Ubuntu'] - ['installation/mac.md', 'Installation', 'Mac OS X'] - ['installation/windows.md', 'Installation', 'Microsoft Windows'] +- ['installation/testing-windows-docker-client.md', 'Installation', 'Building and testing the Windows Docker client'] - ['installation/amazon.md', 'Installation', 'Amazon EC2'] - ['installation/archlinux.md', 'Installation', 'Arch Linux'] - ['installation/binaries.md', 'Installation', 'Binaries'] @@ -195,21 +196,21 @@ pages: - ['terms/image.md', '**HIDDEN**'] - - # Project: - ['project/index.md', '**HIDDEN**'] -- ['project/who-written-for.md', 'Contribute', 'README first'] -- ['project/software-required.md', 'Contribute', 'Get required software'] -- ['project/set-up-git.md', 'Contribute', 'Configure Git for contributing'] -- ['project/set-up-dev-env.md', 'Contribute', 'Work with a development container'] -- ['project/test-and-docs.md', 'Contribute', 'Run tests and test documentation'] -- ['project/make-a-contribution.md', 'Contribute', 'Understand contribution workflow'] -- ['project/find-an-issue.md', 'Contribute', 'Find an issue'] -- ['project/work-issue.md', 'Contribute', 'Work on an issue'] -- ['project/create-pr.md', 'Contribute', 'Create a pull request'] -- ['project/review-pr.md', 'Contribute', 'Participate in the PR review'] -- ['project/advanced-contributing.md', 'Contribute', 'Advanced contributing'] -- ['project/get-help.md', 'Contribute', 'Where to get help'] -- ['project/coding-style.md', 'Contribute', 'Coding style guide'] -- ['project/doc-style.md', 'Contribute', 'Documentation style guide'] +- ['project/who-written-for.md', 'Contributor', 'README first'] +- ['project/software-required.md', 'Contributor', 'Get required software for Linux or OS X'] +- ['project/software-req-win.md', 'Contributor', 'Get required software for Windows'] +- ['project/set-up-git.md', 'Contributor', 'Configure Git for contributing'] +- ['project/set-up-dev-env.md', 'Contributor', 'Work with a development container'] +- ['project/test-and-docs.md', 'Contributor', 'Run tests and test documentation'] +- ['project/make-a-contribution.md', 'Contributor', 'Understand contribution workflow'] +- ['project/find-an-issue.md', 'Contributor', 'Find an issue'] +- ['project/work-issue.md', 'Contributor', 'Work on an issue'] +- ['project/create-pr.md', 'Contributor', 'Create a pull request'] +- ['project/review-pr.md', 'Contributor', 'Participate in the PR review'] +- ['project/advanced-contributing.md', 'Contributor', 'Advanced contributing'] +- ['project/get-help.md', 'Contributor', 'Where to get help'] +- ['project/coding-style.md', 'Contributor', 'Coding style guide'] +- ['project/doc-style.md', 'Contributor', 'Documentation style guide'] + diff --git a/docs/sources/project/images/git_bash.png b/docs/sources/project/images/git_bash.png new file mode 100644 index 0000000000000000000000000000000000000000..153fd2fbb92c9b10f120eb38041ede9ce96f570a GIT binary patch literal 39522 zcmZ6TV_+oF5~yR_wr$(CZJV1+Y}>Y-jW^lY8{4++yuEtw-uGwD^z=+u)#*9iRrOVM zq>_RpJPZyD5D*Z&w3L_%5D-Y;-}i4&5Px5VlCxO<4#2J|k|IELQ+TI;KLU~#6IS~H ze31+3qb9yQoPSBa`d}bc8nz|u%{V74EPg>kvxEt_1{X(G_WA@vR&JaDFiHo6AW0E* zKX+Ppt$yXMnu(%FK|P}9zBZaYZ*{1CJzs5FPVu`+Fj@55MK_Nlm_&l5%TOdkFRG_D zG&hHIf({|knq2Z zm40X0$b(uhTzx_qeN1X2Y3h_X>EFP_gz2PxCXMB}#~Gcj!^AjrK0P!k9S%p!pb3e* z!$|3U2iGk|dyjECfpF#my^BCIehqIvc-+8zdw_*J6jK(z*Ug$hpblNAi#;3VaRp|} z2k1weoVQ5zAMiv00ce)put_)nT%EHoO4_mX_<;t(Zj&i2Bc>=(NS^N2B1Mop;jkfK z;2;^gCeaprzrxB*#e{VQ4{Z1MQX|7ObQPd=zzPPe{D~fP%0Nie=-t10 z-cgn{Nh>hlI0VhBK_lF8tLsZ!_1>SVG5aup<@R`7n?|L2%-N{J|Dnka7}q}(_&WsZ zCI_sVh4d8t`g``o5_mgw=zr5&+Po7`c-UI|iKK2B!QW% zn*@;~4Ro+h%xE#C4n#2?C^>dws9+4?BubHtwhX%df7blNsP-$cU+?gtrb2*>SP0uy zkwh%(uJ6vP`w_T<;`ND5ct*sNz~}gpy;M?4Cx8=gH4wqhWn6stlOx8?#hb_DxEK?( z5pV}zS7r3Behx4o7UzjwyxnwN^2Pm5RtoAu9K+Z}{0L+B9FX?II;ZzL2xzF{r(e1} zTVsLrryF6xEN}Lgk+HGmsAKf2t2QO!41Up=z`8S9PeiKupXt^`Leq8q=k&{R{Te%1 zez0cs@w+B_w$Yx3T4k@LCdL%Chjf#<_+eoE0pL$9ICcc@XnQ>Ip}N`_7FPyg4A!$~d?BdPCUeGQ3w?f-;w3ll$%g z=aV+7BpDN1f%{7Jm9HHwyADS*4!(B`7nbUZv#>ZlA@U^Aq(*{w!54@j8~#l<-A;dK zB9?UG=X6ddD_1xe&F$b5&{Meg-#@loxT%VC zWJoBKo0;Dx=O2;@iOTZC0SvQ}Hi1HP!A~>iE3HRJA(#qQ=k}()^GBq&xzrI`$w0{> z-eZ2yr5;RW4ugG?n54~8s+6PIDRLxBb_MeW;*EOt8Uk8IOLHKw?A~XC@P%tK zn?9J7H_xQKSIRA^hcjttKVM8>_w**7hvfPf0vZ;mBZ7b-_~p zeg%)K7leaM%^5yp+YO>H(HhN_rK^<~Cd?*={ecyyK(l5MqE$#%DCJ9P8zrs#$H8)m z5KUAW?k=vZ|G8VZp~f3Q=eZ14LCeiXO><%4^98Cjfy#=g_swxZS=YAGj$$wMrwC=& zY;%*X5zE{>Yvd#khf&}LI0k5p4yo7@$Bc+L8G*b`E&EcJkd?5!H&>Ji3^H36KbQnP z*c%9%<)BaoZhXzk{S6|XR-1~-Cple8WrYBb>cMbXExoundGmo%t_epwv23f9jPQPC zECfA$mY5hCjKu^|z92kv(U4|J&&kJ=!?|DdlF)Jhen-!#v=42C74rs#$-hlH#I>?H^?8lk!jvXm+T=nuxwSL{HKSL0O~|>as;qad+Rex!3Z$7@RDu;-AH>OvsL9 zghn>;aZ})tA4Pu%_pQDzGd}OIuqJ4%>k}YMWpol#4#{De57`@9=N?DT&@*BmG+|J& zZ6_f(oU=V{2cbVip`=otR=Qsh4nnSN8zoKCzCsFaSx*g$teF*UdB>CX5`5h}gAX;y zQiba)JFL)mmd35l1+X`>@2c5<92t=<{LIo#DCSSgjcR)X-d=7YwUJKPrea^EK%Ts+ zFt%3CXg#+5kwP&*meSYLgtVCyPuhC#G#C~eX6laY6OGF3e(j<)%rNYQGQw%IFr(4H zNBH-~tH%$Vn2VVM3R1w^Ns!w18-iCDey~ggZIH58E={noUxNd>#v2wN6;Lz@Z4(d37ALuIhqsWRl}sj9^lJ&%K|k2~QN~8~(97(wE%^QhAz@5f%$hc# z+Zs#ktI!cx(u;d7C>bsFp zCl)%&BN&g*FNnF0337UXj5B43!ezuSdt0R} zL-0mbtdHT?AQ_opq-5aKvGPKXObAU+eybQDeFwTI5_l+p7t0>UrRZV%mQxaIqI{Ar ziKP3WOG$op;A$f$UnF}o2<)g#z2a7=UNCLR>4>sYO}OuKCDa+6*qbA+vUNl7dqU++ zfva&Pjri$lF%qPFk#G>i+34j=m#2jM3x`^^?=Gtsjb6?n6Go1NLn0CZey0d=sgE*l zq89}&h&bRS_9S$V^js-3E$XMCMuEox-do`WBykuw2Z4Ii6jas{wEFrosbGCd9uH4{ z<+T}@+kFx6Oq-Md4!pfOd(k&i(Lk?XgX)=*#{;Dq`3#*0jvdw8q(r&H6%!VF1z!(1 zI|A^GL{7l`&Z(32wXk2TJS46B6!v#7^o9-CiGXQ)j4nv@ofCVpU^egS>9-%qlTF@5 z_h+_aXW2B#nXGVZ*alI5qWt!47f<+3okHJ_AIr=>*sfEZDz`xlm(mJbSlB+=$Tj8J z=HWS58!e~yTpH-TQd6^Z(vvMW4C5h#KcHB2T)YnT^Nk0`1ZR&g4BNBs`~=^9$zGoW z7ToaD4!S4?KaBq2J(+;G4KPRJ?eLs=aFu+8*08=pogV_5;%En|vhJ|{po*d$-SeFF zjr{PaM!)eppdI~oWQcP(4<2iV=sQ!Fi0>F|(H>m`fOvpn^rsHyht|Yu1j@nxRFcAL zUcs*GhA24l0kIixX~4t~(NBw=awQx-MZK+HRtzOO=7YggJHbB@zk;TyjCxZa>*D8r1SDVF|R^6-vEJ( z?2u~viLBq#3W>#(CWRcCtD79Jg}*#WLbK>;l18j)el*Cl)c7 z%^fkWZnQrk-5@Z%07*N0JJ95cti8Q5vBiZr>EO9|Bqy`_ZI#m}N^f?2$s|bRj?L5jz z6+TFbR)i<@6ShLK7_VvM{5EhNZ;z?G5UMcnIO}ucQ zW_n`R6b3W?59{0@u;F-}F$dyE2Tq!M&uwPTXUk#8afKFqhXLad)(qF`R({S4;3Fn9L_C?lfD zYuJUd7Q{{y>r@Oh;3%ZV^-#gZ<+R#7W9a*XHez(&=!*=WvyZbQyVWRj@{4D`g(O6< zV~+iY8n5q>Zca#*)_6tyM#8ad(u8F!)B?-k$RjO@&Of;Ha=>QD>_o?VKz@x`RH%YEWpV}3_4*Pms3&S6N={Zu zacw*^_zdt7UF<+z-%uv_c@Xzg9d)i+V)0C7LK;qkl+e?MFF4|Tluw1pXhP6;IAjn7 zQ~UAG<%S!ZP-z>SHWI_7QVHNfr$bMRGCYKRzYtyUdEj-w%Y`Z7h3CL`kgcT`PuO3M zx|@(F{e&l5RY%Ytq$ufl7TYO#b*h4rc*;IkN>T;+>y1My zr1@7L19#+e&7cMm-_IJW2o{Jkz+jGu+OrL$!cmw|cep}P_gFe(zrG}b|CqyT#~Kl~ zRZ7wwx1wsz9%~YSzYI#H;#E8z^W@^$V#d5upvYhoIAJM=bz^^EBVLHB8U79rdhh{@ z%YoajlT1|R%BkxTU^2548*jA<@q2*p{Hd9=Edh@QKNPXmfVqfjDNN=WP%=_ak8@i5+xskfXRj4;Ynx0^oZb-v_ zAH!8|6@emPGZjY1VfAei$vX;r(rzWt>;%fWq>r!La@|3#a{>RCwEkpL_Qf_nuOuHr z>;}3?6W;`eA*uJ@^|um<16Q@XKac1u*B( zyp(t6wWWbS^52=y!ud14=Ah7O^+Jk&QzmU!Wq>sxEsiYjtjrxcdF|Lg5MWD)B>a-T z%pulHgepHep@C6KRDqf{$R#4_Gvks+-O8cp zE+1p*bNEAt0-EhJM+Lo-%yQPHj3ct7iHPP4Kt%BC#vbD4kz!FKs-*&b{oNBF%D5E| zTHhT`B2A?x!;EeoG$)9~HVqFEjH)LI2OQTE2dJ zoGQ%gwcfF6m*&{JfpsJ~wIZNn2@{tT9EZrD?x~2J3JxU+pjrnPmGSGgc*|v8Iv{x- zS$4iT1T=nkdnOX-fA?V{BNXku4hmpeK@8HOQ;(5o|Fu@SRLX+h0t6ABc z{7UvOq#;W2DIFusfZdVMr1XDRB0XK%q|^Yc*5^wyREtHpbrs zU9J8CCfE#~T$<)o0cw8Jri0YwWq8#Tie-%?<67~=c|tS*ik%E4kj0h);@$HZ6(Van zhpnAN_B%ivw)iH%Vx9sv(L~~J316Ii*8)L zQTPHLPP`%ONT(|lh{UP94_^SO=RVjkph^?byz@gPg*l-Ny=Nb1L`@N!Fg#nLyo_I| z1*&+N(PjY^w#Yc6QofjqjN;Gh^+*ntZTf?7nMQh97??A+LK4R;g4+qWA$LZ9;D z$C6m-hId>H1x8?SuJW3eY?=$Odn1iXs3@aDE6WLk z_(3gA&od~MYRL@wWa&R(laa)}yijlw)mC4P)+;C*TyOMFYCzg&W0y2=zbF1CD%%i% zDacO7;*l?BUay2o>fbTc^~(lCB{Ymsj4?lc;`}bZT7*TS2rKFHEIJ+#P3SmOR7*{G zoD)-wv)}`&zsPU+UQDehS`T6O22quGRQNSXW3_AwQbM`Bs~3V6$iJSLFfY1gii9`d zFXHV7`Qm;{IYHE+uQpsn)EOj}l9HF1D>7GR)h>^xc#lbf^gQN0YT+N&1Ij1mluVv@ z7yeZyQU{?XdZL^U?uegkyp8jw|S zSpf|j7~Guv=x4=|FpAHKe-}}okRXSQPSqJqwT~$Fkr@8e79Z4fLY72oTF^)s-!r`p z$?1$nb9pUPel_C!_IRx@b6_qW`kV$>yhW_o?Z@`n2$J z;i=S%HRJ=DjY86Id}aSc#fG@W0kA{zDc$1yVA$j5e(n~7U-DoU`z$Mfe!D6$^#vZX zlJ??H)$0P+dOS6Y`G9bK;86yW?UT3iNIF(PV=EJ_Pbqeu>F8NKTVV>_i?e@jUZ2r{0 z_$%|u{Q{2WyBZv~{KpcE0(=H_vE-lSY6k;-ZZo1GI&hV&*i6@eL;O2q=#~N|YOa~s z4)7E{wm|VMLxtrWNI{TO{cjM_x}F9KfS8BiO1W{D7+?xd*f8qG9hFi_C66fuC0C=P z8}{qanIPpQRuZHuP}Wc#X+(FyxT}*xn@XSwNgyd)R z4_f6SGkDt*VL<_kks=|ZdO6l4u%9>57ZrR*f^>mBY#7G^dVyS($R4Hwg9$w>3p4-{ zyB!&^-#n0^us!`ksjQEg{WY_hEYLo?yk0CSg1!jr9Le8K&$m#S?EN;iZ4qcro%VD- zPd)K}7}ZTK_8@1@YaNlEH?vp#jsXjLusMIHrjK=Po|`IE>JWiioOm}9wLKMjfu9_e z}>gm;A_cd6`a?lUbE!R#;{e|5O$YB@(vEzQ!N-2++;Nv#p&8$m)T>S*8yG6A3# z9l1u2#qkL&dy?%IY`4!dgTaF>a(9U1`+*oE_yFI{X|mifGAhG2LX(uam_ezqb1n2Y zRo*wxj#PjfvZ!K7AJjpob*TI)pDds?r0V+`d(YvweWGr}NK>3+)U1Cm#ij(L)7h3A-1zTe3 zM7Y0e);IcdXNEs6l{!I28DPV1vUDwWlVrGiDHFemThzA9YW)1`?QONn9&=4rz0sqI z$6hY$IeXEZKjX0Q*OJRwmd;4tN8;(N|DP{KBxGW-e98R4=BN*w^V%c$!zDtM=kU~_ zD06qtJvsXZolR}>CGV_7Yun=5n&Et1@98^^3tNr6OT5{g5sSperRgbX-m<#H)-{F{ zQ(I1RYa{FG;y}w{zebb_g!9M2H}eTVq1jg)YCAi0gKftv|AqI%;M-?$klps|xmwvG ziCuS_UOY&BH=HeJ_M@_p^Qo*!`~dxjBH!CyHQLxQ%(*eivK;5qfUiS%o(N)Nq|1o6 z!V$;|4ENmyXQ0r$69s2s|8HS*IVt`6g@YsI=ZbfcSvAG|Dx72ck1cPZdsA!DP05<@ zb%$X(!{q(5aYwz-mi{u_no`{%w0SkU)$x{|^2ykVHVdP_>98~ssEy-d(|jcF?HVNt z8*Ks)I&GgnDvUooeiO#kku~FhG0~1JF{Y*ameI?<3E|p3uD7nQS*~vZC9ciXV7rf~ z^ik-T%S)hMzJ(_ZuD)3vYAVfsQaZ_^8f`5DwA}U<8f5?l}dcv&+5q*G6f8HsR9` z1CsBVf9?NnlpI?O-eApwS|1KiLL&7M` z;8x;l8{6PCzwT6OfAsoK82Ivz!j$Z;Z!Sr^5=6!EvB>e)3(RbMvOzo^asCI$y!lOP zq<@v3Mr$kDq$TRw7{jRxw9FY-Wlp=d2=DkMX>SEenHTymTp0)iAR$j3+qpOsnR4d) z=g{QMUK{UQg`d4$GDs@0N{ zwNx?6rS0vLoBVlTH6SA>VvGG#=j=D5@`W;gr~!(K6hh;P3|4DQ)R5BRJP8&Ed>4`_F+MOFDwT{NBD9~mtKF`Y0@-5B5*s<{y16S2xv+C@KlozLVlqAd> zl`||dv#u3UDamPc1Z6Z%#5=I?!2EJxQsvXd$)G;8YXp~J)0)@OG&Yq-5~9#lnz@r$ zrX9kpU&OIuhFNo{4ntsFSP~k^qDL8sTcaykq}&t%6oymbk4%~M$>rmkw`mN0@Ba&R zzgVIq%-Iy^ce$5R3E0Q`45|smZXjeb_%S6SH?_>z(?=P3BxLy!EqAxvM2)R=gb+Kb z0jTueOpc_OpZvZ^JkkuDncF^q5lAsiA8CslY#&8Fe6H5I_BVY=jszJ*hra1Y@&Rq6 zff&V|*3zf(;$rUB>7DlL!2^!n@vlE^VJznG|ACr{#mf8;o=ki+9DB z`ut+M2i;fmx4Aoq_bF57 z?H2+inNw~B2e6*kLn@lHYvS>pzV`bk@n839d+%8+FSQoY;tEaJA9keZ1SZxOF-*LM)4aq_k z(*tSWb&@%qw?Z?Rs8<)^{rb4b^Cvu4e((DkcovYdPsl!Bt|5;+_XUds1i9>3e&X-9 zf2u?qTB@XrUm^cpW8jYmoT?Hz6pq-pK2rY2m({wek@Po2q#0XcQ)s-76dD6oQGi1C zmK!#6CWcg%;dHmM1+jKQCl_#@_(+1oJ3j_j!FoIPNiB`2jqp67;(8&3J#*3&`Ho&8 ztVHZX@#Ez)(d(SHefY-D-%U@+x09lvh1{+X;LE}_M6IuNzk{ud z6Sp!QvwYsjEW1#nQC_1y(|u)p^uUS(Ig_;Ljee99DWLct2jr75 zRfAWg)+ZdM0wCHry2zZJT=E5`z6lcr_b)i^S36YLVsLx?aCaniFwgel;IWVHuED#V0PH%wz}WcA`~~G-@lX9f7up zm(Bfn@28cD0_A4mq7Hxw1_j{_6|UN{q}Qo%3vGkFWcr&2)La@Ap;D5nr7h&3q%CdP z+{8E6@Rx+8|EX-C2KNMDZ1fDwPR3_n19CS;u7bCaN{uu7!y-ziE>h0`il;}!xg?~o z3=jG!U*Qy%UX4$`Z6~DdN6Z!*D=$xjA#!+xaE-7z(^k*h1oB)|l4DcFAY9m~pd6K= z;N;m_jxHuQQz5IoRG^oQruHoiwcQxM8w)8xdbvz_yAN#>Q%cJddP1yGv2%0;#mt{H zH7z5l&dv)xDL)85bvZCoZfKcueJjzU0#{sy7J5jQm7P~!hCb)Lkt;bJs{b*q^(6Zv zmt2l4G`bi?$DRD=lLAJ0Ns5*hW|PFAj1DFX3lj~M z5xJreRBfQgpJ;8}&5&dkJR?KmORjeGA4T6**t*3imTf)Z#SU%zn?nOeofkHaC@)}J z2#jJo>-4;dwVpwZ+anok^k9}r3WaY)Ja)KrGn!^3CeIFodQ(=D2#w718X_kLz^N-S zQF|h4r>9wDTQrqdXOhTmlN4r4`AA+B;W$=Ui~K=A%ENE!V$=hfQMO)C*|8UL|uxj!Sk zlfZ*iZAcKgJFdT?Y9GWQh$oxw*^en}VSG_&bure0Kl1$_S0EXhP5<=nj=wwSJS4^E z24#NnhoiaMIY|ck--Jdm0S2~6+3%=$%d?x^=JQ<{5X#ziER$uVjn9h-ENes1=-()j z+qHw5UD5$;220J_fXg++KGW!YF->EE@zW7q!^D`_2~8q}1| zXW$a^Rrt(S!@(JBKN)lILNZ=XP~cc16Z{WweeT}5rPKqpZq8`2cC11aBzlsDoL^4< zI3{=t8?(_X5CnBJOZNKQkox?hZu2`_kdl6_ojH$Ry>IP%o8@XLC z5EQ8r?sSyy&U7O5URVA_P!lyeyteBztmVgkb+=Ni7qaZ}1hO*=yn|UP z!flGl1SIUuzO_xdC)N?8AA#s)#mE=Tpl=7<1Su_({q6Zri&w}O7f+sCR%8(gfv9h| zsS&_L64OLrGG@BHIRzAKXgLF6$77hbzK#GJ zYY@^2JlTQv4$=y0chEXx%*Y*(^}r9t|I|{>Sb(5p5hd$s$-fmgxg$?nETh}F zA4D^w<(8UZt9cg$BXTQe&?u*zM@826L=vlS@AhcM0r3+IW-VWdd=E6P)OW136xF%o z-}J&x6Wu(N|2U|Is!pg{zY5~r_JZ4#;WQds*HvbK??2yW7%C>KLP%(@`V%*l&)m^& zDMEQ+&`NM;c|5Q@f+-65JMMJ+&ySr3m8DCJ}O1vg!og~7B^9Zk@>Fmb94^w$M?M(&?S~us=`fMC!K+-w* zO(-9_IN;_M6%dfX{qnZ?W#m9k^y>Lzvz*Jvj6>tsI;4O19m-P`Bi{TPZ{z~uB|rJX z))|Dg6}4=?BIMo8!Km;HzXd4`THncGO7tJWt6&X2AlbCZV2?}IA7-}1K1cp>=FyaU zGtG%+rft28q(A@zAB>4VekYfX!tkevn)O>)+qyy5$AZDZ@;=VVHxrQcJD7pE!@ph; z!Z;>PnnbafacKlXmNDu?(}vKSw+$l2?-6!3rQo$wF9XKKe!YKjGAaDPK0n$FooOK? zDQk&q@{JwRtoD*0QoT!7EzGXJ(J%3KSw!-X`Es7le}Z)oeLBq_ z(lMg3^VtHaWTRHFJSoY{F9&WRgq~%K{2M_2#U+oS%rXxvCjRo8TAz3-fJB?dIQ&3b z-WZ=}veM-q@;1n;^)}}6^V}J?gu6zGmS)c)ua8mxU!XZ~HF&Rb^PvsD3Q4Wr;Cd}MmAEwL9a3;n(+h4ye1Zk{W@GWON zy93)I#+}2GX;YIWL4kQOe*gfzf#Q}j_g=obk1ykz5sY9s$SwT+VU@OxY$+&X4EjdzP=d`v)SDa7- zs;W*L^jQ319umJeP)n`iy$Ts_2K8Sa?lY07_;%~&lDWuX^~X!2(O#ZJJTd7>NN`|{ z#%+(ogbV>Gc5&k5ylRGF?P~bL;JhLV$jA%g+Ge?T!M^egDAi(E)*QV?$KeKr4o>$u zQHTPB;_<2YJBoE^0zC`W{j$r`t>e~DJgB8C+gjmSCk0@;H5Y@f{Ag^ zpn67A`#im z)B3bW>uXq;kppD;`U~67^g)o}#R(s-tk1~yU`iK)?i2`wH)rZZtUU``B4VDDcSlT1 z&PzYRh1KxD3OG=pxPg!n>c@heUlifxm@Em(h)e(8&0TJ0vYsu^*jMm+@`*RkKJ#pX zb17BNU>~J4Ia=Dv�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 literal 0 HcmV?d00001 diff --git a/docs/sources/project/images/include_gcc.png b/docs/sources/project/images/include_gcc.png new file mode 100644 index 0000000000000000000000000000000000000000..e48f50cdf99f2d77733ea50235feab3003c58a5e GIT binary patch literal 16446 zcmc&+<8vinw2jS)ZB2}ceZz^JiEZ2FBsZSeHYO9>wr%sq&daafm-ipMFWr4=*Ew}g z*RI}sueEkZD#}YDBj6)|fq@}QONl9ifq@f$J$u2yd|fTq_?f-scYL~U%7{h?OG(i>9u847jc4-QZlpO+Wu|$@m<>&4 zZ7z%@11dnh7W0N1t2+B@nW-*j-=kv?Oc*l5--~;=kH$^9FGbs^f!Gq5#w+eohCmWv zU2y)6tH+z#jo!tF_>)T~p2j8zA$AD?J`i!`?8q3D?V;nV=6`%{=aFF==L)61{c0{0 zWIK-aG?6OST(#if#WBsHp9~w}^q)3_FK+3q&A;p8K%AfJsgP!#mt17DPuIs<6LEI$ znW^DF$S`y0PiCI@`dk|IBMTwgg%iO*vV)3)Av2l`S@84jc|9k4rq74@C#lgO%jPWD z5~OJ|foJ;yz)86J8N`eQ_?qipYu;dZi7Wzjg3w*on$3WYd7`=*t)&#b5p(_boqr_bF zodPaleOqTzPG8&v8eIq+*ulEMXnZLJ71w}Rav%ZgS47fX5+(6PXuP+_s5 zW!nDT2SJmVV7{uFEbFgP+r?0K%Vj8Kg=mU!E;dlK9_^Vg%{&u-Resn_og~Xv=;QO!~5Z#6%%M}v2FSWviKnR?}1Si76u+4JXy?d$( zhmp^t^ep`mc{o2?2&Eu{uJVip(M1jgap%?EZijJrH3m?YV$mby!z4HVXf~j7Dlcad zqyzUSoQGX(rJJu4Er6P;BX{M0Zl15^a>fFV?cI;;{p}mDw40;)0qj8{%5>n-nZ|`| z0qf>*s=C0j%sB=fbe}5V+>9%#_a|x7OBan8SnIc3p51Z}_+vzLyaI zM)NktR+J4r%$nf!)fx11ah%OHS2=LayQ8r%Ixcuv>~X7I^9--jxl=+MG=6l{)%=A) zbiM&yCo~8WYwTkg=op!=uXdS7g~p&M29

{0NO1)Qesh-^#1Zg(2RWErK}|tEP;> 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

{{VD31C$dDSwVl{n2aBK7$F@ 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⁢~Guti;Ek` zINQHMt|NsN*nK(EVKu=sV-tr*k{TJQgWj1n4aW_t!O@Wb0J+ejAxi0+qL4C_yvZ=| z{x%fc_TI!p_l#ftNw6i?7iDnvcNG|(2}tceZP16Yczu)Om`qMu@B&yXP)bl~yGB$w zn5{+ofkRj*8n|*e3WEvx0_DUhLfPme2|B4_XlzH|0=PHW@??rLSccruTkTjEEZ5_;OpInzTqDOcq4(E$&*0%-`3=8CFQ?gwD9angX`dlhjL!;iC53o137vpC4#JU* zXkeDr;4s8o?~^p%PDh~e6e2mhNlGeRsCm`UfvV0>g*>E+r%MW46u%?L=QH=Ru(gTm zy(6!$!Lev!hi^T6cFa?U7E|vfDm4H~9N2Us{QJ_HWY+v+tYWXK8(dwu5daf^JH>qO z`Bbv)x!&%ZH)L-fB$a)cBD2*xsy|*rS@86^dRw97GNK6%cXaps?Y(g?f9Eq$^d)00 z;LoFBwp6b7v8jKxV28hrbc-8g?Y1_W0G4pGXKK}Xx+)xb(c;gOq0796c*?h~!9TSc zaN^!O6`L&O(y>t;c25xby2ecw9?R#u1;{LyZ^k)g?2|fk0+S|`%2F^Vn$iGH#!#u= z=nxy+amn(N$mQqqej0v+fC9|5 z0D^BI*)pG?1b!z4AQ+n&9)CJXE_3eXN4wI zwFarVeYhT9d@DZ@%5JtSfQ^VJ-x;0SPSCStdz?Cp&f13W-(&m~N;Kd-@WI@*-#(3> z`3MP>#7bgy;N^oKnbzq`keM1Rh%_vA;+P^pBPB*rQetLWF&UaOolZ&M`(bSR71E?H zC=|1bZ-D86Cdlv(@mpAACFL@7aUQ~A`HHRGdOezD`%mAH_PsSW-po_h_KcPb_K)Aw zeOv1>%!Tc!56y#DH<8n>pDDmt3T=8vkvIoJW1YBqO|?chCYJ+zPw1{0=UUD&p~)E| zU(0vkNV=?q$YYXg^AeL4E2ME&T38^#ikoN)(2*twB2z&t?vcz3j`tZMmH%IWd}vX+ zy)2O;yZrT_AS3}9$sYc6WI0aga_72 zKP#M@3$nP~HWaUy%;1(ls8@zAQ%5}<%QOIxFyFj91&c8$VE`N#0-o!O5W`>W+CGBN zs$<<8nv(qetH?FP*ZZ+!!bX2ABwLG|*owvH&;%4i5lcQ}LfED&NNzo^D~8gI_YQ&9 zjdjCV->M&dr@O3NG6-d{DckEXy^wo|DGrb?uxb50$>n{Q3!b?W^=$UYXtC9Vl3K$X z`MV^?;WJM2x~c;X;nZ0?gpgzBz=l$Xw+S29?qV3@4lOuz#qg@+SG;FhSWiqqvNDUK zS5sJaJp|T9WxqlKWX=Rm%6SZQgmEPI65%6pGb1&@*e46$S}n96K6<`7sy-JlHz_eQ zsHI7B+44M`JZ{W<)=$F+YT{Ei1plN4IGugecxgwCuwVE)Etc%^GJpHR+#yO0&=WSD zVY{CHsy+ruC(E}&^WkC_^|A-8aU zGX?(ywu@pIB>sq)k;{Cec`bXg)$bk#`FiL`d+F!900$TeMt%x%J#Yp>o)}638era< zKeqn)a1j|cjeA@F+&Tse#>?q0{)VqT6sO&`#NfU~@wm@St&jf1hY^Ps_0xWm8Wge= zQgMbCzO!+9OAVOJt+bNWQ04#;uO47c)$H?@`{t^sAHjAYAWo#z9RsVQyp?aNkB1rO+V3-YW zEQ!`x%<6d0$Zzs-rtUc2M>|2Oi{jmXNzg#OwrJM4`CXk&D2xmR0L~|Pg1N$eybE(S+!}iZZeinXVG+gijB&c@qcVHxFvAZrz?dyN;oifTWIa6j)67$I{2gd1hw<=rk z8U+{}1FvA3xZlU!d;4<1P~Wr?rDSmCq&hTjIdS~-J4jd{Jn;yAXh(r8AUX%8IEgO2 z7-59wGK4VaO^XImgfY1ehCOFIqZBz=(dn&0=-p7(x;=Q`erG*JP?=86esJgiaVs7YUOcsjQE_8gQFQ7t{v zY6NM2cb>MjVGe9cMG^+B8JqOghJxV_gSf0q0Gl_Q_~W(_n2@0g9IE=1u+Lt0<12VD zc-H>@Q>EyYVHk1$YC69aVV8ZGQMm*UixjhRwK#wD`vJRp?koHcpJ(h1r z;Cw;a%^_u2Z7Legp;q)jAO|&9lRILmPitNvBv1ZGc8J9lL9mL|PouqFK`Et+V7`0PZsla=*q4WqCJz&-55Df4J9@$ z0S8@;N0rUOD>^K0u)G02SqQbRS7D64SYZ@tWd_6H_+)OEu@DWv3U%f*vT>gv#Qj=v zI0EFDTmSGjS7n9cZ&UAT)*-aFuZZYH9tlbBq12;R&NQ-%V1$y?C*dqjZP{beMg%Pm zES15DM|(v|k#7BvYBtpVLm0|-BksTTw|IpHSMpYqlsbE(tKcUE$;T2>`t7d3Xbj>B zw;OThvu0m<1^cf4+!rbypYz}|6$ckHY8n>j+oeDhOa)y z0t>(OAOyAurWHz*dQFD|>gn5LDFOn{QC#j7VaBGE4C^sX)c(at))Vk|Q9r1raQwUh~17E&Z;u^p6QyM37?eEwo~$I-48@D+m?P9wPi`d$OYz_ zO8m7JVQ=$oXctFWHJMwHO|@|rjff`kv1GAaSEv^&!DC5`YG^7ib?FQDb{yoc%5nyI zXz`BB%xL^m!V#?Oq=Ch-_YvS%Fl}x;GbmwNzq}A)4cs1+(zrhxxh7p#4lP)cd~6Li zO#K}-EdQ^P9SEPXS*AnGX*q+f=Xr{$9YvCXec((#5E~;yHqk%d`znV8BlV7g-$;o2 zbBhd&56-u-yUDZOg?p;sclgZ??oNY+lk=-3E#tIiy%yU>o4u4>SbUlhy;RijB2;{6U`t0_ z^1Z8;-UD7!YyxJ<99xjDvVVfg&X*nGu7f=+6704(35&cVd`#fu@&T73LFuv1=q8OG z5+Osw1k-FGNBp+B6VA(^fg)w;l2<>v(Z)DCHzF_tepbcFuu#nN*VOoebKs)Xv~E~z z;zSHuZw)mNJEM~)2TiSp>fF%mJ_(?x?ws*!O{-o6YQ=kw(v7)WH7~~)$QUEADwdVm zK(SJn=4ZZK6q}((aNgoys9`zgK=j0v?iAYQgMP1PfC#FId9unXrH~^mS_l$E8ye$< z6ng{-o7{Izv|8ulBbzQsAvkDBDTs@tQd+J*9G}2U68S5Uy<73brl72OzP=+bDuH>i zh$F(Rzf_g~KKBw)%$w#A%6R>zO1)8*@2*ogu@B`k$liw(3vKzhV+DEk3nzVNn-SI* zLV^evG_kVhcjq3H6fbN!)z+NP=NBj%9;6*i;Ma;Z^TO2ENW$$n7Z@IBY_GPEKk94? z2#sALX)nOt4Vj8#-GhT%mY0x#0F=3{lQ|B~Y^I9n41{0orLLiQ)Ula3#?f0D)=~m} zRF;g?{D_x6zJGQSB9hMKUk7W4A1<|6vnNgj7eYp>26wMIxnU;g;D~wRb~7xBC`F?3 zeR7a=Mu{fJ2SpsA3`7PM`3}sB5-v4U1iJ?cwe#4)Yx=uvtT+a0GMgfG>F9xpM_)9_ z0SzzLYCLBW1Ag7CLopYzDRc>i!%b}%Fe&gP9axV^orOr_?QCSl{MNFL*@;9N(!+eGz6FTwc zK)@xjbflQ7G7h-17mMr9M6GZZN?@6gbx~nAT!FwFIR(Uvk>^)zKAU!FpzoJG1e1G4yA9nV=ha>Lpeq~okuMFTp3K9DuAP!R^h)l5b4e>1l>5Qc`WF) z&>D>5)1GpbHG_mxjg(Hv$-QY znEgkfp82PhL-Vrc45l0!a@k zLEFunWu8C+DP{PyW-SxLd13YNWX20M*~EP8Br(J0$Ha#v9fLf6C?P}qTSXrdE8@HV z(mz}#mr;J_XImbv*7OA5L5R5JP~vtg3V@RMw@0p}qd8r>3SrNcez?EisAKV_Uf9$h zb>SU_U~OE8j#t(?6LH3P%kyoSSAZ-YZs_V+Xz$CFx#8|*V3?qQ$guw$SHlf2IIru7 z1pbG<(j6fI$#G=*37O}30yTQcAR>%M@EKH3@BL)U*as^ZwTO1>dRDi9(UJ=UASiCk3OKfA9UtfzT=he63CRp!C%9YD*U*=r1jUc1 zyMeJ{mr*O>B{&;=%~0kw%L5Tb1L0Ks!#7>TlF-x=NT0u)|789-fgTPfmZsBZMRd{i zN6nia-okg=UHyxvXLD?PaXJ-Wd?`L1n`LjCj&S;*AAx>{19G#@T)YLzcgluZsOD75 zQ$_8HhY!trI$UD)-sF0=~7=VzgG@r5{4c5D)5r52Oxa_ z#5=D~=vDWn5Z(uW)w?}ecRuD~8o$^|_X}rmVoSo`0-W|o8~^(TbNk~{cDgUE0K|ha zG~7nqC!_n?+L~y2AKZby4s=g)`N4u~vxCuVmdf7)Og-xUkDGl% zWab!v#a*(kTti5~%V{8$2m#DK5(tDe+5~ zFo^FZamFFOH0!d}FAnS_Q zlN;Gh9z(4OSO_*GXjaW4{|V4hvC(D}5JNMZK``?5r4muX<8CYgg;v{s7g6TxX<&)W zkvM#Y8Cv|k6w9;yu}qrSya%ZTHPNf{lPZ|c;@QSv0@}jcizlP7o<@G>q1x;L5-P?xJ2IIyM^hbMoCc(lwoeQ&L zU~=b@t~Y~yyw>xr=GhSiKv+Pz@n`?~-}Us3ggwb>uo=lXNh4Y)Jr3OL@C7u0dgtU6 zRKZOGsQZCE|LF;fJ%py1t~oF^21rF?TF-6%%)OKk?`VdZ|MZr9au%ONq~>xE$c(;r zLRI1?z}JfwvzihWq3#kz^oy;4>bLj1v#8?7fZ_e=*2)v_mWXXy>+%px38B~RaQgEc zUfLg9taHxlFqwQAefE`!kK`!3bF+Zrr~DDdgtX%zvp4SxGFoo#wenW~-=TH;%;vAC z9xiyXQ;6ty1BT0l@T2o)!kf3791Z4OTJQ+|9b5FM7g0<@3602#9Jk#bqoIgyM-h1J zZ(6?ix)$lI)!>il^;XPOUSHC&Snvq4{a-3~xRLJr0Z)SZ!4%asYYJWUi-{hJY6wp1 zRT3KY&@>)+>fWDd^sk$PP=}CvnS&4?6iY$s|FTK5NEz8lyP~UpXd65dc3j`T3fx~U zfX7Zs6o&nU;un9ENNcwRwvZ{V78?$w9%9{WO~;>!U0<@n;jXz0d-@5AxcUf#GIbaB zLa;O2yiihMzOr}g2*R=>&Et)&8*felYMBHAGsSW#r|Yvt3ZALDm+1jVPHM4Uv*OB$LtQs! zuM9Czt>)qWl2IU&c4V)#JrF6@vlq9nBpD+Y_-7AvX7$HbQ-@H;Jz0OHihs(vxaIrP zWrb47vVHV9fxp4xj|r`29NNF_MYFv~Gfg-zTq;Tu1pRe+96J_3J|p82`#+~a(dIl5 z0p^-3;=06~D`n;X%00JO-U?xOqvYONgaA%~KoqnZp(61eEc0YLWh5VoQiG=#s1v?M z%5#<_Vr~Wq4D`$*g{#YJ3U~sQ-ZQTjNs}FUO|I>LL{`cn_gXDSze<5?RCsGXY@5^Y zQPPlfVn^Y|-|Ud<)7gC)D%wnqxp8A%HCRY@G0wXGPNG2k5*zUOg?7Q#`zcQ`E@M_B z?#|YU?g;>KZ#RnOtbEuvgI<;iIG7Q@3dZ*=-{7uqcj~)Xl~#rZU<60)f8Wden9*eDGwGm3y*yLjGvUe9GKbRsf0u)$)2 zp1N0trH#U@M=#fCH{K=wK`*9gB-UtFqKT-`V3NXnY?Oe6k*&TfZf8frSr*9WEk6r$ zcwL6MyhSSEaBqUlkoy&Vi=v2tT_7v18-h*k_|L^u8b%bazIOwMqjbE1dGv#2!m@?T zmo_w;s;vp&R>=M`loVH&>g}l+4&LCI{;A8KS!4jqAadM9ayw+!J=3pmLmhP~22^~5n=>`J z!|S(RwSap3!K5Q@`vMSY1Pd$}ZgJHkd*s4Ep%0}tXTD4P7tlP$HtRi|k|SS>%^K2o zjdUnu6!{Mk2TpB2`GmvifrnWRI(=9Cv1EC(dr^=0_g)s=-oiOJ@aw{UIt(EJq;`YI%8vSzS9)#i-=?yl0W^&{xtCDe*kq0Jz-pdV5TVkDF6dSkgw8Dgf0LWFcuwDo5*H8KU-pHxw%k!0wwWjaOB1 zu@5}i>_0&@5N-XhszJO%l?E@(>3&_A;mlD7e*@D`;DJ+w=j89ChH_XNRkJuJyVxkTKK3SxP=?AD#q>e=h}tQ5>w; zGPNI3pyp>rk_^`VJfVfP3KP3xrbH#fP>zCt8r2;nYw7g4BHqx+F|_%hAx9Q#q&}3H zO~*5o7pAPr?%cgPgQS%XidQ@7%;S_!qmRQ`{2O07yN4Z?_{MPc=!Va~*8Q1+d}0Gt zVhr-Td~{*7jDV-bBI*^NMkFIyHh`LLSG9yy+^tIdmWL5lX;DQ-QDVFOWVI6DO-)dm zA`Qw4$HH0PSonbIPeFfL7!5V{Oy$?=^`Ld#g4{b?$&F;I`iR5>WRX^T6XnF(7!{}Zuc17~HmJ;$RoA9g$QdUybaUm8>H4vVqI|^1V zg#{N%lnO_oKh2_wlQEVD!cv#;D_<^PuhsA1rgRNUEiq7H$4}_H3l)m3s#I|LZh~yT z<{=P#jIYAEJ&7m3%PvpAc z_?RuKMk?vN0WOACBcGlt{SiiuRFfulJyx(kazh{@0s0%KWjZ>If$549YC zZfI+K9PtZ5yGR_QgoD^YIt0>(sl1xD3Jj+pnZD!*nbttmX}#J-ElDggdCrH;dKpTN zHchnTcfhqn9rMM+1Qo?;1_Y(yRuv>o3XR+}N|W$(VsLH6RwqR;5O)GvR9k{jl{mXH z`7Ssohga<4DF`k^%*pXCAWs+X@iI#MMI3!s7OPV*pY%O%*9@!?e<4-{h-?8kCG{W4VB$4}O`^4<@PTa}q0!_0juwFfUIh^hxmEK&% zIrQY`MgDMuaK73O)ik0oL2l!N`ZT})o><|&;ELj@Jlg-Ix(6N9Mx9<)Mfok`{QB42 z#<-`H?O4>;;{*5q#NJtObo+J~K=N(VN{~G}sg#wia-hqba z9YOzx&FDeg8)2b$a_#gT2_iv62+jqVgd+0I{EqzQjD~;stmk?*Q2d z{huwrBmGI^F~PFKk3tXyN4_KN!Ec4XVJ2^oy|VxR)Bjh~E0!8AU6R=OI{DxEKmKlW z7I?f3_ZrojZ}+Tl)pE7tprNh(Ie*$o@STurL{em2T%>}0d-r}431E{J{pnIw9%v9Tk(>xVcF%02G85CZ=1V?qfFQ<%iwkv2br``z|GM(McqesV#AjO@5n?oZ+$1MepdHOaJ$ zF70q)AR{6om=YBH2~2(6}HT@6^B zjt-r>LD}KmhC)%&PUoOT>)emj5g|6KcZp&3%ueuJkPvl`+Xxq;!bD?NH?hP-{^5g= zB!;^o2DH-taKT2BD7JT@@ zL9m>^EJ4`2O@jXv7)wGmhk(D95~^54`_h=ar~DV3y0!bwt7_E)LW@5`2?l6ixdI^c zS;0}C5w?vUY4hRDcYPe%RpoU)*MlUMU=X@cgkb->(pOHK9WG*L4VuLyIb2}ZGf0RT zSTKugc&P{aAt5VdIu0~Bb&@1U{X-_m6JFz2Kh%$&W0+DfsYx1~#dHYEVJ$6uciChh z3Vc*Ed5(GLK*ph|U*MvH6}D;2L|N+Nyq_}skz)A~v2KbRiv^+aNz-AwKIa27ipOcFk^q4+11P*qawI)-QiM$VrhtQ+koNcpxVmQFi{1Qwg{Rktp(1y_t|0|qJE z03J#LfJX~Tt3P0}U6Cw6hoQ80l&o^;Ox6l0!AJ<2Q2;X+t01!$N-dTCR(wsH*!CC~QH z0@}TLjBb561ij| zmMW-(6ZjAfJ&${*L%3M{uLO`?g2>o@e}?t@ZsN7o`+EQF&km{yZTK$1wQ}v;Iud>_ zb8Nt8mTEipsI!g#|6=Q#qAOjxc00E1WW}~^+qT`YZQHilv2EM7la4z%+24PAE^CZc zOK**u4<^O~F7F3xe`Hju0GW5t%d+giQdeqNht>U~T&FdkK`c8+FJe`0EJQF8#01 zAG>?3TS0owLfJb{IQV1K`Rab=JX{{X_`MxbtUE=rjOl!I{oG`Qr%5 z}Dful9&RH+)FaIX1EV~*A7zK<)XozrA5lzboi8SN; z{=qIZJJ%}TVF5O$8wF_2BdMa;6SAD)Dzsu(hc_WkmLO&|uaa1&@F;g64icfFD3Xb$ zs!TIifk+;}t2aU_(B3iCP{-M^GOI4Le@JU4;ZYK62n_<9wB2yHf z!IZob%(TwX0VXoGm*fGE>O|(@YeOPk(<~H=js1-6*)syt)FBx_Nj_WZZMl3BM z)+`PZC=?cQM!r_VE;KJ&U?^v0s2`V;6h@ZNqgo~=qC!gjnJRwS&GgImG3r5S>~{S? zgoQtNr~lCgXEZ!O?jVpXXJT)~%@44&fqt_=UQf3SB^(MryeGJ=u)Yk7-@^yV-w4s~ zdp$o)4VFc4QyfY9J79kN8L6&iDTU?I`MnXVF?gDw3goKs`StAe?_Q7`0 zvm+&QY#g3b85NPCfrR4&Aos!{&Eg%vB?54EfE;j(=SG!>QIh#mW7SP6QB;6 z1C7KbhJ}~HN;L-Pl=`HR{nO#1xo&Cor>l89WB%Six}wX2y~h1BRzswlLKYrXs z0t}CQ&nAJbEfz3lcD=9>mJ!&4K8q(3d`T$@@(`4m)%1YmR}~9PWvwCg1jTayrdK*P zI_!|z>rTTJGB_@p^iV0f6b5%CpR3O{R;?Dhs1<_hp=)Q(YMSl2{L5c!TbeO9wpj(T zodM~+=Ty=B~efy<>*QOj^`=7O2wNcOV&9SW2s+=6c5n?Vt1woEc&K>v#^Y&~?S^w37{yj%KL zMlIuVDRtv8PH{KJe5#&&uk7Vz$)hIm`^)!FzC@d&vAb6x!F`lT+~j5YLpKcwrKPE2i|6M&Pnnq%?4Z= zlJ}4Jqo47gFWNrwKw?cGIUwn9LJmQOPFwQ%&J<(i>sye&Da+&1PnJF++m63C@5Y7R zm(ADqIf`f%Q@@WCLvL1_rc!?m_d>6N(EAvdZ}38O74vBWcQ|2x*%ne}}ESSmsvV*MUYZ-fvc zru8G{$CQt<4``h^u;}RMFrvsHLR%@MDi>_3p;Auos?IjSY-?}tX2vuz`_dJh9Qf5p zID9+7<&Fjp_6MF5iI$=m=8iAA+~jBhfWB7~HC4j_uDNyA*#i%4Bxts2g*w#z%KHPy zf9PL?@DFH3W-sv;_-`c$_~Cnkh10kH0sUl-AG$~Ds5}8N^s_=G`5|=ZBpaW4|G#Yt z6e7v%^e3l{>hXkkUjGq7(w~w$`<>Kn=YY)!rVn0mYqWzT<%0Y({?hbrQm?Pqv;XM8 zfQY{kjfhgVI)pV$B-``Jc0NpYcw?I(O<~lZc3eiub5t@~?h9GN!l~Qo|Gtq5sK%5H zgf#O6jHo8W&Hy1yZukPB1v>(5`(^t^rAB&2D+A3A$^S7~L4g`IWtzp-!Fn`kq-lID zDzNdrkpB_aE?dx@QutDZh_g-Hwar}A9lrnVFn~mjbj=l>{rMmVP$}r2pPQPTadi0K z3L5N(7Q=wK`YQjB+x%ie1(FDgN!W3w^M+aeR^pPW;C3cO^f6FHPvKOwzqh2+k~qvY zW0W)z+V?YcIn3x^G5=9(vHUS4#fCNiwYkkUhc6yFou1e-%Vh6oRc9(M(9&KN!L;bR zJ9iWET<`rS?Ki=SfW@MF1`_!9Ej(1I{3ZTA^F_78wSOYY9fpu4@#J_T$&UO7f*r9i zg}W2pcVe8tAwdEKR;T*-jS4iP?}t?ytj73s#mceP##|FF8Uc0U$w6$yco#BwBFI=I z0N!R##$@OWN&-)@Q1tgT;&f(ixIBAo;Lc`P$Yba+iraRy&n2$P`l|bH!!?=BNTA56b2izao&OGQvBg<`2e6q{TH$O_e6Z<=)zo z0P=fthESexE`dQJb`yiP6Aih=;-OkF1yi`_C+NvhS-tqatwDeO6q&C;j{)g>qq zI`OTf8cP@>^I4dS921BG)nZgGZee7uCI#+y|2umLg84s>ZqoG`IpY@w{D`oc5AL(9 zCA9H{@s^K8-&+hbVzEt_o$UnC!_+MY(m@DUiM`=`;g9B$L$f^9!@JCQk zgTZfvt#?DxmhI>OT>)~L>@8Gtzm2f)%T7mqO)Og+m7#>cI7qMa(6H5pl1B+G$C73B z&SD&y)8~PWW|ABXZv4r*m;LTml&SyFIht6#dUa_z!J%`3qO@`U|u7|4i{R3A3pECaqg0sbq60F~|O89%$Zmroq&L5|DZ}Bhkl;xR! z`=wi<=pQ}@By0ng$1o;G=&z1-6xA+!V_6AIF(_I@g)$g$j$#34H;B|vM{Flvg#Fc; zdCVRMI^Ylp26KB{Ef>oew%fnL%R?+%Jbt*+&mH}L$3cphuA=w9tZe?d{LBzNz)q zwe1E3Bql&>c{=J^%DHqh9n+-{PC=YMj>Xlsp`Fyl941m+wP>i`j?}a6_^U$QSFCOa zZ-3qh$Twpi<2sdgw7*j?ycZ>~az4F3` zk`ob2!tg6%rMIgHCZW^Ll|~|Aso(A&T#rhia00H!O|QC|3DEQMz?hix9UOmYX%JqN zMY%7PV`Kk4gZ^oXdnrMEY+?&lP(Kz?v%7V1Nb3j+{R>EpqXSKwx`(Yu9%mo2uda%rU{M5j3L=kkFerDnQ1B zBMBpA^jE?R(Y2NX6z%h5W9gxp`(}qPr@1glppqb{CUOf?B|2BcYjz6D^{X`_GbdX! zz*eYyG5nokx1d>37?Jy%m21C)FTR%}>>twS)S^iA zYKe=RUV8{ftgt7N{5KD&R(<#xMe;bj+XoTmlrD5?J`j@?4Lddu;=}nsVN*Wfwj;vf z%L*+Ul)T=12^uuvx8&79NJ~I&JqvxvgGE%WFoCg+55eajS5z$<6(KT5p`w{T`NY7} zH{$>aOBNbLAj)(J#S}OSV~Lbhcn8O&{goXV@3wKg%5w1XvpYsIw{~#tCg)&Ml`^)q zznTwHMS?*rHMA2eY6okH5oh)4P~8&XIBw*SfUkjQ!?1cOy3hg{Y8p%PF!|ZAzD_BW zCB8e#jXxaVIGm1$aGv>pq!HDgy5Xb|h$ft`f%ySe&9?dBDmtSUu5wK*9PinQC+RAfc#?$7Tn> zK_=Q}hz)mzT?Rf(Lvsq~jSw8DE80)}&8!2t5KKrn3KFlihBlT$Q426|<1dAG=e}l2 zrZz522E$1HgJm&|cK1O+$}pmC^bHF%icyHvL^NPX1(}jbpWAN@3J(9yCV{>tZ zI@cRj>MGk{zwai?6w_Y6k}n&0%{Co6S|%m@U_+sk z%+Y@Ue+R!>H(#ixnh(cv((a%U4Bi1@?81LOU$|5coSq=%+_(N-uv^Txly4p=Nm6w> zRIhYbjF&inop+*g;QRCknncn8i$;bsrDGy3bWep^E>W!d@lwsHX_d_a7{DVHWScKT z23js=&q$Hf$eO%G3!a-|nT6h89>vhxSk(vXI%XfMG_+?oUbXWo-00cs{8rpnByC;A z^H`rBZcktK^#3~~fEa-U;=(%N$^6C77>k}-I{umefh1_?0QS0D`tsbzkN;DD0sjAq zy#~nc82@cMi26_Lb-Qt&{h!$DFOZNN(HQRv49z?W^FPG(S_XMGCRN5D_4DpZ5ul^; zIip2;qwy2PApuamhm++Gq0STLO5S+7p9IBoC4IM*--vy&!lxxG4cXM z;4XVNCr>L2+2}M=U|#G%n(Ius>jOsL?msco1#~UbRJ3TEr1R3R)ogld`fl>%+T=?j zfQl1oI@3z*S1}Wm66FdRLSI72IRC#q!!q*2<>+YGv16K%3W~|s?>x4?%b!aV2&l#G z@bC}`1qDP}T3IE+Zz+l;^8WJnRvbSn(NE>uR)y+!_SvK0!eltoFK+J6)3DdHPb7mV z#vCKK@@1<Er%rJUlEHr9M?_m&Tg(5^gumO^=jZ1&bHl%1BiZ#E&XDKL zji>RBBhG>%m`&-@Xrd$HLwo?W)M-KUyNJjN#boHB3f~Xt0Rz*P&0-Q1Qa&qUfhLSc zxfP^t3Q(dR6MWCD;8CwX?Ji{P%9iAx)ArN;Wl>%=`l5K2LaJSTM*Vov{(?w(fSqo2 z!uW2nrthA@32KA}U3Ej7eJ8h4jfy^IN(xB__e#kfh=+nW1dm{jiM@NSKye&x649{z z{zH<=E!P{k>^XzX?%Ly-V1$mnvCtu_BR@+%Q&$G&0c^eyK1%-iU;&|pO_)X0i4 z8UiMiqI(v)48)245JN;a7hW;ht(Ya`@P6z3{V-18Zw%n!P&G)(KVmW(EPOflD9D&@ z6+My1hkT=?tVlebd+RH^Pli|=c|I7CB;nlz!ATecvLZ|$93@NuwwS;`M8#C*+9V`c zF%wEL3$kNSoTN| z_P==zXM()A>qvM!uKd${(Y6HKxa%zVz0ujQgCaxy{a6if<`7Qgz@9<>8@#y!V{;je zMvMwn-1T%v3~KS_B4gf$X9hLk$CYi&lxdx0LUTo+b4Y`2QLx+Psc-(GuVNmrrud?qUw=8?* z#NH|mo;HZ(+wg|Ge-R>!lV$m0eYcNv#Px2sI{@xaBViG&K;#tUR5~^HCk`}(nX3RV zO}9wSi$Jw)zM(mUu>6WmADS&!q?hmX5PqSF!r47^#4X;iAaa8KfjX!kn-*8ti&ao- zND;R?<(HxcC@#0mPjid_jb0<#8IfXP!-T*l?bZYQVVZviXAtGp9YKF4w`qvkQZ7?_7D9NA6=l50Y2!fZLke4?l0-^DZxnUAS%T6LSmm;;F`=mElNNnubYqbSpcp4DAD(X`Dnd?(;TUMY^-n>oD zfmt>QBfcjK$S=_t5dSGHZ+ALnFdP82*=j@j(Vs^4`h#RoyzC$JzU8%t!%Z<_^YYvR(T2}iAWf5V)9>|AH8d$gl)OL|$+HEj z>=E|Y8gkMXiddSHLG%cjgCYycWQB`KOa8_y(76+VxumWY>?Y?qCU5ZgJX83-Hq)Y3 zZ+}Ca3-zX2&Q%s@HgUfien44Nwgjqfxyoo_MroSI?XTUtSRC5}(T)p)p*CxYXGpW6 zo)ZLnXvu&cm;xkdfEoU776tD^Wp~%Z6lJ{%NwhftYn>%&1Go{<(L;Z{H>0Ps`Mam5 zp>oBdKAFr~opz<-5p8b{#lRTRc=ngS{%qkKqkQo3l(c*LP4I=MvLd6zRAV$_dn;Y= z&010tFH_E=`KrpP(^3}mJdl_Cc451!o;IltmYsW0uU6u5_pL=5M?X9!z^>S z`gUZZtmP{U@mM6-JPY;Uq-DOVAzZ7Q^V7nRT~)J;U;8AY@iy>ruEy}x4`K`-%?f3) zvHL?jUs0B*Z;S?3IhKOs%O9+<~ z;$dLnWPLSO;!|3CA?Yl{DsuSs#PoO@RYG=#q6n>+DVuPibt}-WN`CIE5oC1A@Y0*# zf86jKRMqTX+ta-0y@&zYBH0uNJKBph%+sM-nJH|x>FX;@wj2wgY+vh2lZqK9JME6e z2l#|kg@j&C?JwWi2y}XgaInEur=LR~G0Z!U*-p8)yqCN^cP>prAMbdMjHEDPG0Z}P zKN-@9!IJiO-lTryGOq&&=0jMrbN$o1trj(=tW=%9ql}KihFNV$d^J*G%yEpM{Gz?x zxU|Gfg^X_@+06;uJC2J?sl8rTmG+6#JSE0{>2v|RE95bES-bSHw1R|B?u6-_v4Q4>#3$nX}WgF!o$+-CPeO;7e$qWuViS<6DM)n3?IBwNb}MU$+)i zk8EnHPWHjlMUICf?kqy|wOEmS_hj$Rf${WU;zgzX=alGQwJY3Q2Deg%W(45No})d| z*pmRW2MBmvD!Hto>(xlA;4+Xu&q}Mif{Ku$ZsRpP3fp|6p7c+2!W3UsNai62M2ZS5 zt^dFPCh^Sd?C4C^5G7TY+Kt3=LJ-4nfjWARE$!t1Q%XvhLE=*0$3TI}50}ce_>{kw%pf*<9#7NF%)Q}4UOboAE)@Ad^o zp>X5xASMm_lQ91*Nc#I`igqv}2(ZYR~^WNv8fZwUQi`aHpnZWdBWCnK{5a@RvU-Op!_2IZfT zJD5~&YJj^sNDb5ovm@(zmt$9smR-nRBHe^E2Uu>mqrP!U4Dj1KA>`>k{!T!`a8su1 z6*t6cc3pkbrb+X-PV6}hz~J~W4#Y6RV(F4{YjFewf}M8QewSA00!#eK;{dJs$#L%; zpLNR?!Qjg622)I!r02qkMdE=q^(}VT-*Xi^f-P4!Zj{_!Xe~eOEu+o9$_&3<-I>dv_Pr7D7N+}u?9Aq(+6mW7QcV*1}I#w_m?r>!$@773lp=_OWm=C z8A8};+(^*vweTX5@_g%5L9uv5UyY!^8U$LE^aN8oNynGbUrE(Xls^>6)9f2Xx~+U| z-geY%1UA9&T-qAiIQfU**fB=Ca;VK5S|X!fv|T~m`Idv2Hd=0AZ|1!r=2>)oXgC(E zTA9RXAt@2gH!FQFgzgA8Yn(5}K7oC7@9QY#cNZ>R5>L zwE~dMRFB)66VtYgcy!Uiv033zacY^17T_dbeVAUkRsHW;nrp|35cKIwgLUnf!=O}o z!%tmHjjn93_@@Sqzn5}X`sQ$dY*Aou4`XxGpN;#oi8YKzYl_(Z-fh9a#k=j>d-HKa z?2M>nUvI&_yh8dk7EAY=cH>>J!l*&2cvRH}{{Qn93iW_APHKD25gilLE~h# zP#jTc_?6`_P+GI5Pe0a5m1CMfk-%h9Hc<693$yLomWKBXh8lZ(PfB8=n*|A_?tFHP zw(yNpYsnfV6w=O6#&Ruu6BVI9-485-?eG1?lVw|P3QFOMZ&-U0#(~lpq4)EMMR0_n z>VD$akWM#r>;~$URy|6LepZNsykUG%v6DYD6QaihpwaWK$UsqzjBdGEI6nsbYkRk^ zHE-8zyFmphYmeCwRI6w{fACHcbFF6xy)aR7!YiWBHqu|g7c?W)bVb*q@Hl6>4tA|l z4x%SwE1WaWo33Y;*wzJa8z-$NHx8tQF1s&cB*BLqX><`dDVAW6Pna!xD<|K~jdzp_ zQ{KBBlz?Xm5qsy7(*wi@oo-m{(YZe=JenugssE2bR&KZxqj?Gn1d4}=lbI*_l3vaI z7|P+@vD>WC?5OhHbZ%2V<0tYA(sg->n9U~`HT=Scq7ks98(GTLUt+hWbFd9114GvCV*_i6TmR$|Lb(y{kv%X^$mskmBkyK z`NVmIpeS$T$UGGT7iA#!ty_KzCeMH%k#1BQq{Db6>*IdugJAHbihgc%5;X5swZHV9 z(EIxUjEC_CNJjo}CJH=<@!zDm0{vh5CHSR-k+AlT!8EfTCe9Y^t@+ZjKcShf{mL<^ ztC20V@Mnt-Q|dm-#+l?_>4B2Fw?aLRAUm38Q3#=|WuzYml#|>M{v!ETkmV~iyB0i2 z@zG-Y`*TjC{^Jqgo8_h4k`;RqYgi69-ZZg!;RF6(ZiaVrqxm?jP+Z#F%7~)U*4M=Y z6a>_C1XP|nS3=o`D0!)1^ls|#jwd=rE!s}0XRW4H^QER7fmRg+k-M*ek9O7TSh>9s4cv;0lvzGN5Vbpw4UM0HLA>_!JXpk^T=0xBdd zJjp}m`St1X`u1-0_}qQA+zkR({}`T!Ea&`&hl}g*tOT&)&`8_(K=u^jk^j!YOwliH z3%97Yxps6P$x43`kmm>q1~7AXQn)gHx_&Ag!G&E!@=QimK^`eLEhnB0izJLk5T{OF zS+Mq)xZCLnTRwi7#wvRzLrQ>F!U9EI%&22YnL%wXTSRw?F9oqw&H7?uEqTJ7&ekar| zP`ns*R`IFF=@6$`uSX^+!K9fa1LP+fMAILtP)iTkeknOFlK@3y zd}M$}@CA-CQcgJl>TLe#%QF4hi2CT}6W>@bD~y7!c^2OH*RG5w(!OtMO7{faRjb%{ zKmfs$XlEvr#=}a~8tNT5pI0qdY~3ePFMS8>C49`B{oJ-ipYUhxsm(H0IPd7T!Rn)f z@~m=$%Zvrjw>qM4Hb0Uf{`p#$1=|Vjdg$b*fnIcHbejqe=qp#z%^-o{471Jz;6s5u z#MuR&M1ql=Tzvfw02}q0g|f-FxUg_mW5r*AKFq|KHhb9A+ABQzqHd&@&K%!?Weg!Z zsP8iZcwXLabK5b4g$Hf?VeG9ocet&x6z6;>V`;V3TC81@5kj0?xPKhpHePWNrB1YxJUP z%If;Id&$B7KK6fYE8f|o!rBg4;_?{>wdjI47_K6%&HD;2)biIq3otbU;oUjpk=4_S z1$vCR!ibVDn|ZgqBYv@yAg)`2H+z3dNB3+JoVNM~Af&F2ULka19E<90`9eY}p<2@` zE7^68&hnfZ?RKe+?nJH4Xo$`fN<96pq@CG>9pVtoAK-N9yEBh9xNhNjeUTVwHhJaZ@D7y8Z?za%8)83-$|+`$X^H=kLjFfV}=NF&OFO zo_G3G0M*fm#3<$3zueDw_1zNU*!lj|wYJ^rGB!9LqkMm#&Cz_Z{VNMyZlnTRe(2Bu1zQ`M9Q`NQx3j(fGuz2Wo5cdnBy^2f zcMSC?U;k|wUnoecRm3#rfT`*6Z(@nq#?&8k+=lV#c)FK}kY&EZ<+4yPsF5BhIxfz< z`M5Rw+rBaR)Q8b0p9iRFpsrsEBB(QKeFi@he;>1)Pcsa^PIfd~@^JpF&lbw@@Ki|a#)a}JT8F}>o=jc_F%F_=0lyE93{=6G^}&D^#X`Ak7A zHisy5w8xvVT@OAJi&2~F7fF@p?&7((4F3Ib!#Yzg9x96{hH&8@vr8+CYf3r1 z%G!SvvKyqS7#^1gUi(H~Ua~HtwAqgTsAk=L zfDH!XMSN0MfYd6EtDf_s_5;RmG)H{eA(wr3JY0B`80m5j-=#U*!YFR6d|_atU%7$x zm)y?!VjF7>gg_PDnp~RWaiWoesO{A0N>^Zax0v23mJQ<829n~anz8UZFQ(2SNQ3rw zpi7m5dl+w|2Mg4i`-?NI#RpYOadHp&TKR0S?U+ThMGMj{Z98bnA5qm=WQ)m7Zm^#_ z6R-W9v*24ne9G4i@C@NW$Zg90j8_q~D*nr>oYvI=Ri+`A&>iDd|Up4%x^q;TSKe5=WxnyM%V~Z z3Dteo*5OKt*V!~LHP#YC#D)QDnlbQZ`NPMvp)kn;ez4vUw7*{>w(aQ(mRT-s-t{1b zKalBFbVB|!LdFsQCTK^L9>R|W{&7hA?FvnVykI{Z>TFYR4=QJzO_z(n95-9N=$)U=1o==W`HbUsJ%(Ulvp)fSgI zTZ4!VgU>D};bu;3U|nEi!f0gAKg)c=#9^fN=hEu-N=whM9b=2Q*nVSCdN4L2p;y#mAVD)nf$SV4Jf~uhy%g)aP; zAyq@H9lEGo5#J%L;K<6f!mX#z#T_Gmk<0_gtnZC35uU=B$I*i=+R)G5ePSvpYy<~+ z+RskU^zlFUk!XyC_gwc=u?G0yb&W#{?QGiLZ%_z=v;*`Zm?^=-85+w(X28|~1?5|X z0Y{Ea-e&uu9)iD`O$)c8Uf6$Q`@UW{9q7H#f7zjirKi4}WT)ZaWC)eAKk2+rdY^oF zimxQ&A6zWjsIipH+^dh%KN?krS(X@32w{h(ROCYQ590#W?1O?nSZE{=1T+z<1T^)r zN^i|UWjKM}gxtd9>V5S3ucSIIA2v2bR-X#t6J=4}7Jd#hCl&p}er?jpe*MsoTt&?* z`O=Cet5iX)9rDP>Ps3EQLZe=Lm+-E}*HeU!X`wAKkT)G*XvmjM_Mv($m6 zYFV&Tw{qla4@>b^vazCz6_#Cx4udMNs02h2&g6IWISoDM`uY2Q4Y31-j{{jbRc^(7 zJ>Tuj0PT4MAi~6hjvV+@#NMyZ?`lu`vwt0Al#mQQ`2InIixSzY`x!z9{K|&zV8(Oo zcm(wNyTG6O(S;=9jV287plGoHsWX%37j@p74&HEsN2nhOs>888)xCyX#t_7|O6%{4 zq$mi6rMOHo#xavjm|6Yl&fJGq!|d(E^DvK&SqKhKq_(MMtp=MV%09l(3dt)TO$9!Z zv40ru;E20f3kc0Vjl;`$`9UcX=q?nO&s1nlde-#t$Y1F&1MZdE>yY;AG7w%zPNu&9Z(6 zlesfeT*+{)_&EA()Xn8fMouvglP_+CC@DLO1nE0LnPznHW4aB0)&({m2T69IK0#Sd zXONg{J*`9r&Sbs06{*oaY`p&b8VRYN9L848it!~`Wix%8IP|n9k=EMAZaGwH z?ZiJth5ZWT#;E^h!kth`*%hx|{8R2)Yz|HB`}kIZIn-;i(vHn4nH!KCM3CH5?U%;n zk6+^-hFJ$CjN~Q(VqhiS7j>Hy?jr2_s*TK!)S8HI8r~rzWWu4}LokPLLAI9A?LWGC zPdvhM2DUFq15%nInC*mBhn(w}epo#wS58fGB6E4h?kFx(N?_oY5 z)P+2Y2Fud7ZR=n54-?|CpBKYo@WFn_J)|^S-lIwKnf$eu?b!9CX`o#6$t{^!CG}8* zm)q}$9P)Q6+bHmY*AL)>hSneaF%X27yjQG-sr#Q*_9KpuI& z?mPXgyremKRAf9R#+Jfh3v4dxI}#=V3v363evXOZjvy>9^7WAzxg`X<1XgO#V)tns zECsGD1Jo*PXew;hpPzBlR)8A3)#GBeQjZx^NfN}aaFjN=hud~J5 zjs_=$56-V;KV;@1X3( zj60?E0O>QZ>s`?3^F7ADO_U(JsZn+DSHW}0Y+ez~H@f8e<2z#3)MGz=d7~+J^Cs_3 z1nh$%K@9Q1GHAe`iw=o0F@R8thT3 zd0ML_{v59;_+Q_LyVz<|L=$Ts9 zY=J>TqO)SRL%p9iR>hz~v!S#judp_Enj{gAmP=~u{(uO3pW8qvUU9b6e=SQQnBvTd zn^4FJam<}HHq|b=>*>!4Pc04{`D|gppZ?;KB)9YsxoaW=gb6OS>iOF}UC}X#_x#Jr zmP(-pY@WT?G{h5#WA4H>5>qmdf&>ODc_hJ$VB145=OiLMRieE`IQJm+3Bhj&5jp$M zimA^svold1CR%0Z_7cDNvwyS;C}dF9cG^!}F)aQ4UFB<-qa2@fg7`aNt*B!hQFVizE`B%L8lbDqTt(P%BCrfYTR=00cSo}B~&e52+p zjw)vrx(x9IU+7D^YiZ&jKVb8D6p4I4dve#~3^fYID#33kk|N`wCSJ#iLATTJ6#hjQ zqwK$LSEF!!ciS>Wbc~fCET(TUq@{;$N@S_`XKXgajzd0R4*tJ)m6INrs?QR=7;?>$ zXR~?*fu&PbeNK!g2uNfnF2&j{7^D;C=kXv3Tf`~a@FEsxB4;DOqJXyWsx68F=ZqyD zcw#VTl65Vf+zN@OQV)mL;&7hZm^W3E79xYPWq>*~v8)K%{51H#3!C#O)5ha+m6(l!5`QrxX+v1#zBHYw)F7#xx( zRLmq5OW3%q-|4LTw>0cSAiFUp)TaqV))ykUC48|X8P8vLPI-y5Rg$nB3ETLyq}Ro_ zaN}IpVj|;8?n6qBuET^I54xCpfHeS#>6jeC8@-VwqDrdZc=*Y~Shb=)10T!Cm!?iS zUow9!n@d0&l3<^Z#)6_rH^vo2*EPat7vs)PjbV?>r~NI28q7l(8s-Sj*_A<#L>R6W zSMqCPJ2dmmAc=J!AsCKx0QMt(%@S(aL$LUrqE;a>5*5HHbLzOli@~?}5X4kTdbuol zFv^2RDv6*!*c_2p06JrYDJ)*ib_J%#C7@Ka;1LQ;7&2MaFaBg_Qje|L-Zuro0> z*>8p>)ND+IH6+dRjD*YL+&3;?i|2i#9w`?wR!2XN(vKRm9EKV9j5W0(CEjQXXcR1M z5M!@KXf__SmZ&ik6SpFJA|83BYXmBduLp)&Ap-X7W$$crB$GQnOTh&Vyqg{lrg zS<6hlfLs_SJ74QiY$_y>_dViSzf+Qc-;W**3dTB{`fZ47El~*XyHqI={0LT1-}hU> zYGCB%D`+V`mRSZSk@9dsX~%~o-t#HX1KHgS<=6ri_RxnZ@78Pw|KP9LNXE~D;RW>; zV1gtSgf)2e9yyulPpYevA8!0 z_FDzdNX#2Hx(?@3n$Xm*hnrQm4!96?kQB*sik-2NV5$H&H4P;XDthOpkI8hW5p%Y! z7EFuV-kw{0jCK@C2z8@`7)Ip^85NH20e93D)8Zwg$322WCNc1Quo1jJ6N5k-VLoFp?{*Ju#R zfe5Ps=-C`(eHxs;N5G10BZ{O|Mvr=OY>EMG(s~FvN0>w>hQ2c#Az=?wo$7Eyq!H>I z%$q;lcWtd#tN)ZF0JYTTi*T{P>}0(8&)$)Em6c48TxTGej|-Aj~TW%_-i1?KaVmB z)9=Yj7jRB$zS6mERxs0Wy4Xjm*i7(W_ zlA*gmIcrq~x;XH9d__A(x?0m5L@md|%y?%UrJx_mHum(0au#$wlZAg@e2BPN zGo;U*mW=64SJR%-tW*>mFl7x=A!|bQCJB*ElxP1 z5K7(2Rw^T*M4hrds=AnK%n&&sGu+jPm|l@y3$gCVk2O=q;;8h~4+=3v@#jm_n+?Ar z+k#OXyC;8h)<=uTcvrjAXG2LlTKm>?(cI^S6HBB;&T^0B%XN>C?&y6#9}GwFC=EeV zui6OS=H?g}PfsWeU_r%#K-kUdNr}K!o`oEsJ&K-j&e$G_llKz(h1l1)pB?XG*&8i@ z@b04`N6O4kQ#l_{BprqU1R-fBGpI7!myC>pP2FNp4joB#E%&A0+ih>xDMW%OBcc|5 zO*7dJYB@$@XE!NiXmpAgqwNQyz%3rhXk@BOEix-AgYBnhTa1w*BhLFt|LIot-5`iYDduJ*lQeSmR&ty;Ao0_E0|i z{A0q`SI3|}i4|s0cO(DzNE|8`+1IA2>~XjCXHu%|9fcX6AS4fd*h#jy{A{M}wx?yS zecB(x*Mndi?||{UUEg3)Hzb7M%bz)W0JAu1x`@O-2fBWWDBgfslMrUn!?w&JcXX=lrd{}QJsky9oM+@E> zo9hCno3MG_Y!KHzQesp$F=Oq&F>kw{saEg~Ht?y*o82E&c@jGz%sNj9wt4wN#&%53@;Yv>K0o#>5s`lH6&szVCwzx>lWxYCeIfaW)S2i&rJ z?q_he4O37;z;35RvU`brKX$3KsFj5;4}#LlW&|g`#SWcn;g%>a6Isq4o?yE;yU^M) zD^%R>P95E?SFne|x+9nK+y)CB>G!kn6m@Lu<2pxa`#S$wrDE3t@UKzpL=x%a@*nRH?s%LM5oIdR_@6AFR^L6?+XZ%5L)T5l(GQcj-X!>*@J75(!ZY-Fe__z&qg+DJE}M$djm+Ic+&y(2 zpPib9y>@>frnuow?&byNRqOR_(CRpqafN0C=?&q?q0DXWAQ&=I*WZmf+(?a&?rx$V zPK}4^XiOtWe~M-wt7YVe_Doz=2SyNqoi67v*zP}`X>~f#GGfTsI2qi`U4fcgY!Cxo}|rz|bI--HZe-j6p~C=RBIBt|kr(D${tGFU~( zUWd%Yy8t=q;|E>oDL33ih1N^SiXUx!8%7cRnx3T_3?wFI=+OjkvH8YhBp--RON9?x zIcy00JHcp5z2kXc>Aly5db?{KcP4C}e-9H_H@S=uHPgiBja+JEtK-L$za6PcDR^d_ z7t8gpbboSOw}77qCvNH=T8vztsM6SvbSVoll)D`m4k?%7H1WQ)&%v==10m0?JgNxC zE>FOrqY*k*eFGWwfs@sEQBdUr9V(*{Ty_g5@-$-U{v9@4UUKaZwHw{XJKg5lJBQVD z=y;`p%!3m`!KNiUJ8XX#MsDo*LFR7t8`_oT14=P=u)%XxcaB`a&ME=7V<$v=qq?BN z5JBC}`{V*yXHQ7`|F!j%L2*4#v}m#c7PnwQLvRT0wk!mK26qXtxJz&e?rwn)+!l9t zcXxMp3-UIr;q9lbx_$55>8d+(PEYsgv^<@OeA4r!A}WQLbw@sn7qdSzhnYAp zHJaP7yd({FQ^UObv{u4=$kY%xJ@OmBch9g!6|2Q8L2}y*u6C+mFhwJK^5rV-u>(n< zFK~EkivHrDzP;{{ADbK1`Qxo6kFOj{L~jdxY57N?)|167BN573tMguBmYbjKzcr3h zH&ZmmM5;{K3k5F|7yZTL?BrihL zHoW@Fv#^KzJwvWVK~BUQwTQmBwG7cK{0)Hf2zYV=57}$~>`Kp>d?ne>O0PAvf}M;0 zZ$nrXo~q9l6|2j~tuz7R3C?G%uSX=0-GsmRGJGlIgN)YJu!6Hag@8kPmdoRn%T7;t zPNL~8q-WQ}kv4a@zgwhuaeSu^tj?FCO_qVCz$T(o$W1@%^k}(6pMgQ}gC{LI>0$^@ z{!IbF?iko2r&n76qeQUDXtTuB?je6iD);tzqFs{ho8=R?10TO066X%lT+2c~Z}a=c zS%U)Th=g)CW$x-oauqRi%VK6}7y~njwx0$EIws-xdknOqF64qVw$eK(Mjn$^qIe4< zi#P2x&Rmq)_3r!oCOl53QvMY0=AZWJP!iW(oZqy1YIO+GV0#b$&4ODS^A-VpYT5mMl_>YPr7binrZ)<@v907&oR-E;kW^)NF7W8wLTbCN&y~vM>>nEDJyZSn zW4YQ31Ya6z4?5~w>v5NN@fn%{{OFmSobOCo4Ap`Qp%X++F*Bq?q~d7hJrLO6&AvOCyt;{b8Ll@Pc*#dcj43`mSu zYEW;v-(z2!eSf;g93$4kw)>ZbwFvP}B9%V^_=G4mZlP*;;tX8mwD-rWvp%pSNpRa! zTq3Zp9^71YCl3@DC$g4olZf)AVl@^VnEyk%s>6YEH`h|MK(EN}O4-i_2#IMbcP=Jv ztaZ*KRbWV^cT}`3+1Wy#+gGQ?VWFkn%w0c1Ag+*~D#plr5kl5k9u8piN|#>>fG2%4 z=s%ALF?PJ13RAWgqPtH&EKeY4CFI+ zE??n>Ns=$*JJpI@%;pH|f5;^feTZ?~JJ~PG9y1aV%F$(3ad9*z} z3T<6;I7Nh58Pj_P3=T`) zl8LQ`zKcGPh2zo2&+N8fybY4Jnn`@14j`PF^PQNim&b}G*Dk*N#0ckPqB#Ct#F4%X zVu>%s$@t~jyL&Dp9+P`F3c*o)_>rc{)tVizAw1W{Bk(UbYm&z0zpRa!EKh>1?XfI# zlnsBg0lB~~fr_a3+q%zYu%6jfB9_&okV$IXzFO}9IM7XX%=WvRKo%JhBw-e-0Koo@=CHFax@Vzmtt4BZb5HPEaw{%&VEGytKnD9g#D{qCYwg8S`_~E8BtE>}Nu_N#0L$1oyvAlZRM`WbI z2+zK|k|3ErwF=82XUmn^cU2iBVKv2+@lacOt|vya=$Tl_~2kP4WEJTXqrQPXK){QZ>tKY+hf#$J5AT0j^*M=&fI?_(PNL+HKPwV>q zJ2^i$F{fsD&!$sZ78mq;&g6ZLw2{d4;{f3*tQ%;TXvtM~}ttx$n1r=ZY`SXKxB;iK{M`OB+VzbG;CiVwX)r6Ruk?{x{jWS|x;! z5sz0!Xh*MzpVLcX91MgLnKS|tWOfbX_7$gjB*mA^ziKtSP2;xdYvnB4da{wR`?|oD zoqzL8Vy(rQFmK?ooQo=?&hS`Kk!*j4nq2Wjt$ny0kU?s6v3fLB5pU0^b^rE-`-rxC zJS$X)o1lgVz0GxI=$JX5GUCVR-ULcgq*d2viCr5uheKyaHxu$@yZ2S6hkJ;`wq*B&2H}Kld>IcLXV% zDP)S z%(CQ0XZII)$HTiX^=(nQJfF2POUpkGn=i-ip0Y<4L=W)0mwnuynNe8?eY=EteVA_N zq&mq=DCnlhUPwHI*rmGux8W_J81T0yaDx~>Jd#AaOoE}-U$W(AZj;=l`w39%4!pn8 zl_!N*__SHLjtg0Ao>L(10g*p7Zlu{TZ}voa_h`ebLSf`rhae)&%Ll_=w@1=p58IUU z(c|+6s!oUUw@m94jDRUR>6i}EbhnzHW$9Q+V|x@;KfHU!S+vC`Ol_HKz^$eP4jsKT zJSB{9jv{x~vUbZ}ti3_zkctDvYn?lSN=Q|?6X~cr!$AcS2Zd`Sekcw$Db_NVHd}r^ zx_M;NsngE5KS5*dxPDLPSvj&b;q@hG83)_{Ug*q7LEJg2u#PD0rq2R8CrT(4=mghz zYp7W(_B*!;Cbk~w$p({rvYCebkSBonb^E}pp?`hCP5Kzo*WAEw_Q${KDoQZwZ}ncx zF?9a``3IL<=C`rkg1#%2P79`XN{Xrpf~b*S7+yH_YZn5PmQ7oKW;tE6#T1rq$EPp# zr5!b0s)>1!TW324u^4oHfj@jUKa{w{j4$4F(yj?3)EO~U7)@vougHdYxa%KJ;~$$n z`w4QM_T<=3DC>+n>zncr3?gai2?!bDm$)IHr=xcO#WL4wu^je@)(`IhLO=d+I}e9< zNAbUOFQ@ypmyADR3I8NCv@N+sBvea^vVR`m>0kzIbQmAx-?GbxVV0HpbDILimzGcF zAC4G@SH`SrnW5*CCFlZX`rOXE*S&E}$kq)2>pA#HQA2H!fYgYk%=}&%GaFS)cTci$ z@s!cZLVq&x@N>HS!HJ!cIs7UkkO{(V&ni5tupRmUVCl50h7NPpGk(tw5@9?|+U#92Z`gy({ z;H#e|ms-9ee@J)kybpS`HG!$XL9i+5=-v@9Ym034M#x4%(zuAH^5xY&rcUy_JU?BH zbqyUI-jDZ$O@@BMQoro{jK!+SpLO>s735e0Xv*k8qLLhI^v3)DNKCt#x#&#u^hRA+eQ^*ZtCEv%db$wNC>wwBsTtd)C{u z!8fnM>Z>b{O&qDwcE1^x%x;RV>vlln>Z;uKjtQ2ZtA_!3XglnYlOs|sud*w==NXZhp65-p*z6WKzA3e;_shykPfy#El`O2;D@sg5_jG_iIX*7Z zAy^fl-66?k#h@?y7k+}}?~240lpy~1Z(W$2yy@x{Uf{hlERa>8j&v;$OD;*$sRE`o zIqSI~S2-wR3OOvAFkCERBu}XYt;>nF4}=&EQg^fG{{Vk^pPqqw*3t~Y&9&b}8KRb` zp;n}t!#m~244LQ2P^3uzSK?zz-cD+$x``{oyv!2CZ@W)es{Q3-lqxVzl^=T~n{O>o zh21YU$5Mh3BYCn6c7uKgz*bnK_2EnKPQP^Bs1+U+`wl?KK)0AQB($Z1Q*cGG*aTRW z{sk{l?|sa_0n#YRd%qQTs_q*`e~kq(5O2^2 z>-`dq>(~+~sx({)wG6|dI5|1N^KYSFKQ*5+)yt8^20pLoI(6lY1E~YM$eM# zALrQ9c_6`6@&f>a;Pe;WIw8(Vg0^+eQP3^N@|e7 zQ4wzhE2}>L;nvoAXFp{Gt2hxSkCLxditOhS7s>UFs6lC15ZGKkzBsY}Q4_e#%p3b~ zFApeCc|%RM6b$XV*&nZB5P&+^vK_*W=G9XPgiFpG+Vq(yV1LFgpnuEum&;%!W2zrV z4|~+PY0f%eb)`#Ro~Wh+&r+)uDdlBkV{1DAAKDUw`944(Uu61rL*oWtJ_o_y5>)z% z$}itbkwiHE)v8b2m)UdRwLeTORzQa|II915e=!l!sE7Dt06{bI4n@z{ScMBw>ST5RIbY$4<4PuIDc`S9#@a|Htg4c+Y5+`r-Su|pPr_K_p!wCGw|MrhnQfqyg3>;ee zq2X!LPzC!X+G26tW(%E+?E)kqQGBgEQ-n#lfJoi=S4W-A*WT1*(7d~IH|*rq$9cj2 zsfqzRTk=B(PIiXK=%t3b+a}7fz~XwLi=J2z5!k#IX<00tS`n40eh_ylImut()tXSv zh8h1!g`maau)w%`^RJo`9WC65!SKQ6@bHxTu2{+6A4Ies*`hEIGtr@frS#v(of5VS=? zT-FpgP!6Ly1kL@Q*9IB0v?JR-7&Yu z1a6nInJ+JE^;|XlRbk`1k!?<4KBVb!H}KIz=mox7a2~$Q!;5=#^ns|YxbuAelW@1C zPQ(Y367ZG$U(uutql(`oU$W}T`81W39vT)3mfX=iXkUH;WUc1E=TMEZ0VlAC?HJ3+Y(En5IZK>W8wH0o`}`_@vCTCxsICd5pjCSh#*1TC{gvE5!d~7~ z>@Q~ol2auMpQ+(D?U$(40c3c4Baj^*V)$poG14`iKQ*4#w;|KYm&87pBDWB>Dg?5j z1aZWd(wFhR&z~WT9ulzc4f#NEX>P)dmbGNjWvkJEpO@=U5VW0dG3trd$aXrVf5fJ+R-dvCk?Pm07<7yqZd0rT^ijNq6NX!P^2uq&3+2b4fnZ~RwxQ=mCIvCpd0%>47vZ=Ri1^t-!voewu* z=YQo)1#V4Pc-|Q{s65b{@_{q%;^NW+hKIirUMl|zaREVxB<(gm@HH1`s2+#ecz$v- z^PqkWNB)?%DILMcY}zk5y%?Z=5k*Vp+47bnNKJnhBc>i7?t(eC*&OJb$x-DYMNi+R13{YHT zHtS1nhOHPr?M}VijW);SsCGAvg%*!yG1lVCm*$5-9b454LE+hyEOcD2;I9XolV!iu zD|03rX)25U)Y$oCBdX*-k?_1h>kj?{jLyF8+bY9oFXWZaa<41hpSYuA6!buz?bs+t z&yi4X5Mq0oa^)ltju z$afdi1{BldueA!JJfF3`MLcaH7?WL%@*U&oo22VvJ70J=pY|Tk#+{#sS5v&~Lee4f z{prJ67~$(P{P&MKy$w|%tm<~(IgVhRyFw*v`^zZs_T;p4z+j1zC&QIVOmGd*obaV% z?o2SitL3y~-X?DR=wuG_bdH2d576a@wKCpdf#FEZg&0$)-TVD0Le8Ho@Fv5oK3_}H z@#une^}$RyT*!00ZpS2?lnra|2>7#aLZiN}$yJ!p=E)V4UQ4H@Zxh^J{Qp+7rJYz~ zg#{DOIGU>ElGo2u*#G~k*_yKM9n{%0`3qSG`%o6<6j{2DwLLWPo0oNB#wzN(mza1a)IquF7+H5;pSa~SE^O27#ly8SSon-%$Qj5psZF;eMgnTy)V=4#E9r>0 z6H-~V3tuMh#4}WVY5}-9jQ$jzE7ehKaz26KAVXZI@s197Qx=-6HwlP}&NS%-n-@R8 zU&9CYP{NCCp#Qh54vzCETH(8iDM8CLgoDTH6LuvmA|BGrD!FbhVTAbE6Eh)DQ3O-% z`SMw1%tL#Ay<4S%phqA9;J{gH?qWZ+AjI{n!bxrwzU;Vkn>*tP&dzZEHK6!Y-o@(KIYf5H(T!BI|8@ zZf&PKI0=w_V1cD^A^IRB(dc3O53*>$@M6>jle{S8-NC_ul(clC6)-yZ)La#x)~>q%n!+Pc&gXD98SkCPWpzR0Y2n!o$qWEF~q?9tb2Z`WmSfQ%)FX@94FbF!kry{etJ4T zt{PL-$Zb?HCO^zfW~JlhrDMeehn_j2As`@}LeQ*L1Q`iJLRq|(uQeDoD@g_h3JWwW z&+k=37^fb%k&p_vx3{0t>Xsf`x_waTzYEsWI5iI+fh2sV&uzOh;XNlRJY`OEYnhx1 z+nHiCKT^WrI;?c@9m38eNJ4ED*4b>9WV&vX(hycx2?O@+>5(E0DGF$-sxxq>>ALEl zU;m-~8}ZC#YR%_La+?1Ee3c*{>WQK*-8{yB2lQ`XT%ZMrqG%%ekNof<75xPDBo}F$ zYB~ile@g@`n*jh_k_nti4ntp*)om^uox}{y-(2H+C(os;;u(936P2m1S2bq4kRM@Y;7%DW_A6JjC8 zCMA>7;^2R?kU|>9tlzCt|2YgB#&A?ZTEA++9$xMWV>Fr` zSc7Q)*p5obKWBjS@|ga;od7~Ch^ZA|{N_K!1sF$!sAREBCBmN1NajngLu-DqKY#|a zGMuZJcP**B{}rDBAH#jq_Pw+c%^{vyaYg_-%y|$CD$e_AT%;22lP>30A zWLB)6Iw+%iZYu38B=lhsEwYwK^K)ZrVoeQaBC}3twq#W2=;-NT*wQ&YKRhgw!osqc(X>I5~-9<^L-t$)=Y%G1~X@AOxzo6(O9R+-7kXfqKHo z#031e1W8E&F0UB61SH=hLqRs0Q2eXik)~b9NvO0^EJT8WZmWU^2`L8UP`UBCjy8z? zN0Xw>>huVn&f`*z7R#mapsBI45^sg_`+`9p7-9BB5fzF4eLt^aO3OKMsLiLuH3SyP z4U{8cVK#9Nf3v-_OFq_as>yl%!;SD>mqa-7NqhUS?8I8@>+THEyluF~#4V(Xot8Gq z+3&UKnw~H^A;Z^$L2G`=etFSD%!oW8lW&E7xGxo&m?_N4frkp zMpQ9k_4GWndN$yWYh1xst*}^_i+dW>qYg6L!papaF7b=KkVawz!ZQ?mbc0K~dY!=G z_ot+eC57PA9q0SY?4Eh2e)QT=O;Fh@ybJ;DMj_pY%PJ!ZTlBU~%radJW=lmAqHTsj&{&n|~EBQ9I*UJG9$75UhPB|W5WNHYT zr=YFWn@#=sO+jKxLLfBVZMeal2Y2>~-VNJ$U-*A#ycJG$TOe{iLyCTo8+Y0RAK z`!+r>hq5qJo#xiHT-gL2X$kIn)duT_jh;_`r{d%#D6jEP8$=mBA?qgmd#lj%q5W;z z3z*&Mqq9{=yHBC;dU2_qLHC)(#A+A1#VcR9B&}z}n^Lo2;Y#c_=Kjw0Bwe4Ii<@L& zr}v9B)0upZNe)++rA?s2M(WhQjtxXpL+KvHlBU7Y5r6SQn;r3xcG5_=CUbMnq?w!x zkd_i$ex$1u5gta73ca(D)ug~gP8;{^Yb~zeAyAY_Xso8&sYp!5ak4W*#};^%G{&aD z*>sZHjC8DXfx62mgqEO#9~+xSUQxx}tc4CfQzbjE9|r)vgu|{(C!;m5C>+gq;brqk zV=1#Rv50*O7W(wZwK{~$@hd|z+so+F@q%#Wbn3&$+bs)9N^`F*e&b487z#KYmLC~n)_?(Fmc%I2dY%<8Mstp$yrL12Gz-@raY}(Y`;cJv1$pv_K8o1zX*}KR&bg?qr zah{#1JEH{$DqEVJz~Wn)bm7-g!@=`!9WLdyl$fhz&_fDnjs|G^`}qFcz+5J!`W@QW zUH74V%#E~00mz4z>SuiuWwf&S{X3D)_`{!=`Mc{S*E4>#=2usTNNB?9YU!6uO#xO| zeA-X#Z_tJEwpKDnmT;b#WipG6!0YW)ecgZ-p}Wo7`g(N=iYiXaLM!5tR-6YC2B7)u zn}a4=qwSU!eR%}Z>t%IEs30kZlhs>(X2jwZGfd3}m8jF^&L49cR<@qlP<&*X0N8Fo zjxaq5;$AJA(f3epLan@fD?gQsWkPcMTDj;6Yeyme}|ovgtRarq?F0D!b#5B7ROUaMoDbM zmwTJ)H%PPVs0bd1ieR~`^o_ZWXU?{~sZM=Oyv`4tH>zB)PKwTq!7=27DkgUx^tM<> zro}`bI)3<3^~5s7O+h#?$2jRnD^HfI-%rrWX}jDG;Pziz^mJ@h$K#H6rX1|$C0(lh z+rh;$tN*ZEneNU>_%fbm;l|?pRHyu~3sR3ii+zz^Wsi)#h!3uvw1G+`E^%9flpVja zQ8Ag@?-?^6Ojbiy(KrQ`QIF{o{c-Ljj<;u-shTKYvMY=@@Dl}Byb}hGRm0lL>gF-r z6LMvHNGb2@O(w2g1icfVp4xV0%jUAR@>LOmi_eRrsY}Z9X z>gwj8>%?c+y$bHGcI!aT#-N@I5=gN?~vcDE|peEdYW^&os8>(meRLHLi{eV)=2b z;p78i3(BWRiYrCGqDOHj$o==S>X-&e^%>%}XAVdj64 za2WieMza21vg7tppn%OJ1tLMTZQ0&-_z$$%x>Jyw?%9-G#y9+v+kh2ib3;Q=ikIEU zsETHl^{Srh2xU^1ftakov*m&~%BO<*#%yI&12os{a&9Tj)>yzY2Lc!*`! zpoCjCs|M2laQv$-TBdjmHtiRn@6(eDm$aC@3^G%I9b3?E2+Q|p`CUz2-aIoJO2{}-yn7-ft0f}YW AeEX$+}+)+MT=W;D_&UKo#O7r-QC@P`aJLZe)DH$ zXU@&ZBZJpx zJr0Jg`Y1w*04vh(>LdzpApi4chGs?^w@p@hn{z=3F^p(BL1n{-e-I@`mvuy49IDWY4Q%_rhoYUfT^*Dc zCT1HHIjuua^>(xyCeuL0bJV?#X#dhv*!GpJ;}>h%EqKvBZ}*}1Ph0dUw)FZ`IarCj zvYw*iXuSW2P~-i71~H%*&_9^}4fKso0J^m~V#<89jg`;a)riknL@|ko@hOSQz2^BP zotmEb!(-!VeujLRlXY$^iOmrsBu@XZprC<7xMk^cbsuhRL%QNXNA6bc;vkTtj6q{D7-wO*2>EsI9>6DDR#7V#AGmFQX zOu5y53VNwH6@O-mCoq|2mDj>Cy6hu-TjrPa;-; z9HZ@wj4^FYT*&!$gpWafEjH7*d;S&BVOlNYIaGC*L-vRZ--K&!#j>k#m2R@hH6kHzI7 zVtoXtWxkS?DGZ*!Ic@2{d|=WPSqvh#P#yNPttDr8 z+$!4&*djs5W=HhTTLHQ?Wku1 zjxFY>>Xi|ecZgS_!9p}+{5W=&0P9y2+rLmxS<3`p-9qB&XSl|MgB0P-s5fnBVEvN( zclQ_9RVD<+3``Y}yuLW<6~203 ze(6gYUE$77Y62|&;4jvlEQn%X$2p4)vIfm~ZBS~6BE7jc$;wiRa`uc<-i7c)$;*aD z5F;^xWzD*0n~X+AFshU+hMGCubnC`0M0FaXPDBrom5(f`(B9hsZ?P(@aq2S9)_YgA z4;sYH8_3i@4@V)XUFZMfkY}GvWNAWCV)aUe+>U3Qs>0&qokn|FgsTT*m!`J7k8#!1 z20J=pO#y24l|GB{@eRiJzIxJ==v9dNHmxZ9^_ixC-~_OYhQOk+Wln^=MDB#X_4v)i zeoeC4-%XY6jnPnbDyV-NK|E3l9=^ORqyk_NTiDs@Q6@ffLAraXka1Bo-v13*o}eP! z;0akECC~@P;tyRypmy2EP_ZRL#-uKW^>c1*!NNeMnEq*ZY|1w!KSA2&C*AJh?$avm z2dZ|B0fVQTJprZwRt6O#b1Iw4na_zk6cDH?#HvBeX&HHOllLJ*rCcuK#50pd=4@(V zz{|^vMiGOIY>mZgzjQo=R_%@w}p`6IIoz`hH$_N2JZO+Cy_X zwqSn;WqR{MR{$*$Nz#ogsI@3FK`l4Mk&TwJpBZ!uV7o5b}bpQ@M}YV!;y z^nutWM{%6dA1t00sELa~hPB?w9{MZjy9F169d{^ON>OgMd4a|k8D*p%S=EII*{S`j zLQIiw**Z1pyM5K%PPnEHEo(!uMiB3*39c_1AdrqvtKHEe7|)jz`-Q%QW;xzmeyJ2< zXWN=Ye0>N7bvHU9=6KrnY_*XFtUQ^(X?8sgjo$3@?m0zJ{186YU2oW#LeZxfxH(Cm zV3jqsG*8e@#{bd!c*I~Vy}Y62=HhpU=>D0T?1~@49aG(4##Wb5P63_L7xk;hEX>SK zHFa-JLhGb1$!MFMl%7@?j{1`&TXT;qZ*svYF7_op_NCYpE9nAFm7=;wv`LCOM5qcS zGZ~q#+}015FT9`krw8L?)$TfYwWv6HcN9%YA}S#7Jm*8r7(t+*7M&!w zxAr$WTG~;+mcAY7bAKb}8z(6Jx5gywPg6@ z<0z#U;w1DG7lCi1IBURPL>1_5NICxx#u)O{mA{|@1;q#2F{0KiJWtvzYH1g=4lAvi zPDn_UZ%c)Rn)9$MpB^0@l{ox!|FgOo;>CJejzOU6o9&%eC&M_%Xu4~*yKB0$W46PF zlw!Z*_DHx5b{x{vdal9OeM!^#)QtNk?zkJD0N<|-)LEJ!wV)2z1}s*93JMAj4iBt~ ztriv*;s%Vpyu7BC3kYhtsCDH^K9!5Lk6Zp2G3`R@?R*Sk{^sA~7H$B~V3O$Am|pt! zV#W|}gHyS$)xYZaN55)DQ3z%k6$RvOgAW>hfGze_I)r@&omTrC(^5Tn1(V?XzyGWv zfcFx?Nc{M2o;2|2u?@ZIqZBD685sh?$EtYPDjHZ%-yOMYZ(nI%8*GfL7YMz}=IG*Z1loIg*3Q?g+a~Z^obZGq2%yj`elKK z+7e}u5`Y-vWT(j~E&R5ww7IVF{_gHQ9Go~ToMdot-;uP8tc={oCw8iTA^(k<-Wi@A ztc0J_@pSn`Tn)#s4-w+*;%ZW0CJ`uJQ&)44f-`=fg)@{KAD{uJ5~r-0s`=ri);YuO zmksx-&x&J+2+~u`Cx`r&mX>CxZioER(vj6!p-+@0t*t&EOB_#O=r*abBb&=!NNlaW zJYO246S4g&Z}ytQWs_`qQn9j}i@kr9I6hqM8wrqSN)kYGaB(@o52a($DDv`K#l|PZh}Xxu5-{dT^A^@03magvYCAvrvP;C5zG6 z*oZ7;N%8aG;GicQM>fOlXpV)nj8M=Umw)OXzwB+PAl!@0(TcQaa~F8CL?kRkUp^=> zxJ0)(m5Ptg>w80$!R7~;O9Ur$QH>~&s z^T*N79wZCiPqH?N5`mKG0!}l@pi%bB(6F$T{o|4Rub_ffe2=O2d!nH&iy0vADgM+i#`4%-VcgIM?!90#z{eOy7sE)U{ z->jOC5>M>+bY4|erN_~wEAJw&pfLLNJ(ukgJVeTKrNsk=mr?NPtcySMpG})z$*{8H z(deO@sjCpBK%ZD%pkKHv>A|fI!EiLPV*beYM{QS&e!_%L+mDV8%q=G8;_J8lEl1;jMxSw>!X3{|}VA5*)#6vfq3{n6k zFr7c$l;4zxbl*t?i?>|+cEc!A=j9VUm*WAT*AooR`}AI}_QL%bbXyp?sDV|t+)!;! z=Pc*(g>s{FN!fUohcl(Cey=`R3RYU4SR^D&JYF|P(ANI`{{2`&ohCzx%MN`+B^OL( z2wfCd*pHK4T>;+1=9eY@&kT}(mYbHAmm4Lwm=|*Gl4E0qQO9uDN+u^3pab2H^YCHz z!kOC6E-xv_jF1xb*N%@Fc8479JM3$PUhX!N^n6o5ODVK#hljG7r=g+Wztb`@Qtysu zi*AWYNW|G%SX4UdP+)HF?#hmyEH_&~wwQN*;sikF%{||)+G$WpylcPTNo#1}9ufHy z8TU|u`^;NqV`@qbK|nxg+E*;N^9c$Gfl0Tpu=qju=~F~hRNM2-qK%CWU4_r1tIyc` z_wV6Q3HQc0QfRBpGCfRRzdfgB$Hm3z10a_P&N@0oYSKchIXUEIWDLgF2h$~kOsTND z5H9f(f8VwxB8(b2dFeN>sMv7%4Oy*POe(BQfdc4yT%GgSxkg1tt~MA@bo(E(V3hd3 zCqc(E*p`V&O-)V6pxQ4!0D@yrTovTcYS&Syd~PoER)TpUN2~2wgbZ3hH`jcwtkW>r?V;*vv2;S+t#PZ71)=N0>}UifWmxxQU$bq@ z#E9bgh_0+{**`M6fTb0rbuXskmbw~i=q&;-aYoG?*OW{F3o2jqV}8E7AvB`CIXwF2 z7_r>lAm-0v46P3Y(o^=Y%=XpS3V(c0ABpR;jBNRmUlBtq3cZYXBr+ScV3}K4 z*BvNUoX3Rhkjd>U!bUS|QzqOYtggzQ0f2zlX11#r&FWWejle~}7~O`n4`T$l7%6C} zc@KK(MNi#ny?a}H#CuGd0~A`%g;LO3bzN8KX$qJIBH_`x&W=Zb!ysmZ&cLEE1^F>4 z5?ILG+}zV#ZV(dA;COdomTy>On|{YT)_bNTbhn~3yS5Y%{M{Scb2~weHsXG?0w#q# zQ;%BXJ&oEtY$5e|MbpiKRX#o;mOd$sfPl|Lj`$Wcwpe`#9yrDQx;xY_d9NzL5;wH2 z?@Oq?e?|rou7rs5qD}qzRcxyDN()|r=YD=trsn}2*ki-q(pt*%{$d*|nD(UUkWt|q zp`24)9DVO~CE;GcVgC=-7$~0GC8y}4koK~&GQ);TJ-QE=Rc7=H>z1N8c|l26T3x_P zXQxnOExOANIFh}(mj;K;?tz0*zSF#7InzdbJVGbg(;=A|k`J;=UPy$ELo$J~T~{opoxK z<#V$hLUQotuNWjGB>#Hqmy4BkA^;v$tJD=VI@{X%Nj6GeLA5-0{pAOqIKMz?ZI6jF zWV1{3Ff|@!dsyv>j1pYa4*E~*pRh1RK6!yPXem0N0vu7H?AdgVkl6DF7K^F`;e={8V_SitwBk z0l7Q5Au<7XY+N~C{+Pp%@NQ{s`SxvP$n){KsdQ)eP)%Dsf@cM7)2f!E_FWRjkEK;g zeSHi!RrPJ-d#H6dFO?e^`MM@+Ko))chKQ_5AV`Wm(;^SEGZ}PtZH)a*K-x=LCC<<= z=jEzqRcICCDtb2L`Pi;fMR)PC?-8lYu@i{NQU?6HN8F?YD?bE}gjs83$T`I#J5->&7nxB0Yf2(`Rn0};$a zyZ+g8;6;7=r1>;)Bnb4$=l7O(J}wOs6@Eon4f}8R&)U**a(S&2j%zt7Y-Tc&v*|oe zxRmP_L+E&~l^4*PZQ5?jF6sC-P$c3808NV0aCW&Mx0DLTO2yQ-5F0nCukoG&PAj!d z|16*e54^4 z!Es^tvIm0fSIC4(XzdNRVS;mU%1!A^hk+Xr6_(dPX~{k@QR+_Ml_b*I$g^)*0vc|K zKi9~7L3N(lNM^np2d|yO36pNnV0DG!FF97cdor^Xw96|MZ00UEqogrLjE^|kL_gL) zea(?g0#(qS8EIByLumwEzCXb@B$_SPZoM#{n0Sk%Cq7d4-@Eh2+wOh)3sBPTg4R04 zR@vmi*e5=sMldF4aF@&5T42rIx$hGVGO`2+^M0F5?~^;(6OnK7xwqx2Tb<4lm1G9i&lIw#Fy*`l45+wYl|->9os zXJ075ctQsJ5(kxWMqQmi4BurE2sbx(4D%S!m{n7xux*Rk6NW4%ps}PH(XUkfJ@ZfG z4RESig7hmd9V6$c+|z9;ht-)tm#dkWRQ+;3w0-Gb%jpQvTExfoc!8?qq7#WJ<|7zg z5l9b4?@CQZsq=if-*o}6M+{eoMbT@slfr^K#*^rcGC`SMCp;KFRfrj)5lu1r^v z!bV4jqQo7+&C6~0_5ShxGD#zOn13=Q)cLY^1mPS3d@l?we0LcQ3nAt1_DbSHMaMmX zt3s{7B4)r+qm|%S*J(B7FmZ<8j|O$;5RgMYUdrVNfqBxsk^`l|2HN5ZlDBPLUXjpv zj@S&klqDC(ZmSowVW6j{XX7qg$`VHee?({zT>Yh_(lV`c`wq0Fo@pu}E)rzoWA}ta z)0p~S6;hJ^IsW8**HMgVItRsv543)Dc(3jObkrYJ17Z;&{iy3Y=n8tt0pqA0z<0oh zVGNrQn>fx)Ee#0(BQ@k`OiJiShCGS)MW%6%ws{qLcD4Z-nK1u{x0K}h-S0-`zh=xzjj<)u`7@&E=WkiMOH*59i8o9>nd-r|?nK!30I+ZwHla%$MkGdDv z*ROcW3h6yOo*Pq;Zq1uz{+0fI1S4=mDH584;Xam zf{}6TK7}ZPpOuN|P$9N2e!JoFinQ%mYkIgd{Dzc&2zKcm?KQiq%*F%QSG0FD-t!lXeJ%YO^P(OE zq77n|qa9ADF$TEyoc&TwUdKAB{`KcdL_-s64O5O7Xd%w+CUy}>tVcfPZ> zM35Vr8-k6QcF^>^lc`oEVr{3a2BOh3L3LQ5kEf@HjK_ZHrhN++Rfy%66hV#mQ|5LD zx`StG>f+IlNjCKj*60V!UBEl;ujJP66R!J!>R7sbEyla*5lQ3_D4G-7leeTqR#x81 z&Wa>_wbaa2M-aom(qsS-Sx9i7Y^0@d6x2bpu*hJ<22t_Wo(Q5Oe(_I0L)Yj+`$xph{~f_X~X{{zL9yRWW5m zdkqC2%bQJ+Ak5JzgyN`ywKgCSvaK-Ae4QJJ=lo?fX{d+#L1B*PeIE7E_yz4zppRx{ zy|#xKo)6e@V1g;NL>c9IU2Ao!^Ol@kd&wDMYG0~~Ju6=+ zl_G|(%B~?tEeyzVp-}o;rom6$sx{PA|0FkVSw9oSC`;{N5=^;hQYTh3MIm@3sJ}sB zbf3+yvAt{n`rPEeK(kIM`7%8}O=o8?9|~eIwrEnvk6hkurji`aesS%5lo~uMj&pPK z10~dFn|u>2o-j~~)FTdhJ_OY=I!Pm(GD)Z^t0-?r^pZpD)2geh0-gfSPFbUHJIGkc zI6JT$U94it*wHC6ri?cl!$}KtjNr#8As-DyQauJ!8sr`KKIs3BMTMC?E?ZpIcJs7V zRFt3nA+b|kR3oiU#m=t!*eX+y{WsW2+P>}$(wG1Fr(DA5;8Np4$ZsE01i4${&cyO$ zz9Q8Sm$oRWM0_U{hZ)x;+J$EX&0Hda^w}Ui1AgUqd8pl~)edaMg~`iF)QKRRK|ieM zeMkD~yYGF$fuJ7}THYm_1!=Z%_u+o^8;EQDg^|f;mYW~{y^`1|y@fJgs}k~f2NP3c zjMtci6mcmOR0e@{+{kXT%||RkTtWbPzTe3*e;IRAr!McJFR?iVXK+4}i!=J8lAg-y z^1M7t5Ady|@ejOl!-61_3f}cERp}DziZQT-GL+8vH1l1`{=iE5ez;B==*Bmp#xc!d zMlf3SaYso_MKZ9}J6pUm?C%xnFBk%-dVr?WD+{O!XAJiXshLdq$RUi*dV3-Qx%5rZ zDR1-tsYJ4L0=@aNq;zV3^$b@{x^7ogg~cJD%Vou8W@Fd>5@)bf3fKH|v8Z)dPzMdc z!p7?D?JgE)*um)m;%F6lsZ8hmkLo2U6Lq&f)h)GU3Ebl}*l}C>z%sPItaS zuN`SjW0&otqjo3jBol8{_pg6DqvQV!{`XiD_7_?6R*wH?_V3`gp3mYZzhP@+dF&5y z_x8bsh($*`3t)}E<$8{IUB+eK1io3m>Oz-|@#!@w$uFzK?PqIKt@VxbZ`S^N-rmS{YwRO&BFulamm8?INhu217`3LyjiXP& zO;M0&jO&)kIhxVrVo|Xdj3yD#MHITiHPoa0kMQYBULF1^0is|TZj_0;&{0))ZchrH zWMISyj-o4d=i&Y1{+SB)-zBIjj_pmZ(DOwD6P%vFhMe`&I9l^KDe&cw6z4Dcpue)G zr+DI?DO97D%0Fdtn){0KApoWKu5*V~pBcAr zr>a9gZ3yli>~|H?KuTB)sdNmCch0LAO-#=1K8hm9Yu&C@x^~5rdaXivtB1bJ&kyt0 zj|VPDZ!hNVODliEU9+_GIunI>lv74Ow7*CmsDqP~&0yL!kl(2Og-j+Gk;4_l z6?$l$^`eY;nZ-du>ZkkZKj+`^Cjt#opBSY6O9^%M3I#G3(52D!NqB!+C3Z$A4rYe5C9iaTT#mq=jzm4VFqRcFs9qvPbf&FcV9`2Pxr z;*ZVx0ZD#DszxnbH}@4f=l=AecEf_r>%Pm0Dv3S?@iE#yA?h;w*0VN7l+A(T#FW@n zV)tFy|1Dol<1-&&J4?MXb3MOpY+WKK@I(G7yiEI2b_MtP$J?Fks^XAZd&;}c0O~~V zikEdRNK}csm#Zu%$Y3imc$Ka}!*vhVcF@A`mRs#Oxz!5B>u~rX4IKRw`9G+MxVFkEY2z26B$~-E-}eFIc5ST770Mlx@dGIiR4{U8I7hBnF*ZPv$MTqEj%B6e-by-L!rI6~L?REGWbu!dhgw zE4h_9+xBVi)M`63~$ecA!C!hN~*)K*EIyEV;`W`X!zJ?4{GgE&QFwwK{^b z(vvJ)xziXSI7F*Uh^cc#vzO1RzI;TgMX1+Y{B&8xGo-9W_^G9wjm_a*@1C*See0*H zt!8bijbo1UEbn!pjTJo~Z-NbAb;c}`VqT5gm-i8waD1~mkOZ%5N9D6LrB&^2rBDG2 z8s(Wj!Cz!@YzOp$^Un36HkTslLwcq=n6StPABz!H1WmvF&llE!W78l(h93MQS$}K? z9anJ)be#hUa1c71VwTO6XG<=NT_#h8gD^2gDYTDZnMHqtI|}aM9|E(B0{)oA!Hyhq zG|s5zwI)XD0|oGV51HFv5O!NHn^y>Zr=B0pxpvR5?)96_^^PV0gknVH!( zy8_S)nQvTmr)p+kgl)aNy!Ytd9RYnDvUG~pdH7G}qdG4x@!S(9ka%dAY=?n_ES}vX zhko^sfQC{)i0(5#L$(s)+llZm{03!i`U2!#-2a4P55*;G1P&Gte!>HNhOdDXDsWMh zVLXB_eCQlK8}eD`>b@1|?En#|MBp7YXcn!=MK$L?b~;ZjABE{g-6*M92$3j@t2XN} zM)w_x8#-=upoK4vxTa}*vHyJv90{Fpf#JPN-%?QR09-|Y$7`RD3AmFM-;>xzFB*9- zaOl5t)g4|Yu+eU1l4-JMt|M?rP&q8CrCtAu?RKfVU_#!9?6;%)vY|}8yob(i{UWO2 z_md$S=l^$K;T6-C$CnNxdFs;9JkWqTg-@U~(YdX~5uNjGo-|*O(8KmJXTmg+zyWY@ zp*!wMD}q>qo~6d0p2{JZzGADEk3(>d`p1?nl)e%`!+z~b6I*q=T_=j%#H+Gsrs zlx?KTJWj1&-)rYVJi{#%UjICTenjp!vfyjFKra z)W`n~ZEJ<6K%{;IGAl!&uhH@Yl1LKH-=pEJ94|S^JFZ%M^O+ir%xvk*#aX@R!^bnS zLXA>M1?#B26_4N$1TcvB%r0y3Q-ogGBWhLcL=UJl+vIWPV!SWF>J9)aGSMm|3D5E@ zJ7U();p0Y(c~2HPM}6qGj9JaoMRoGm*IW5UeUWE$RJ^4RoC?PFWaWAy&pOMg*eYG7 z&MpA$eS?&2sHZ1^_qTyajlW!~aI*Z0!VLnMgfyIQF7Wegcb4gl?OK%t(lIrK$A9-A z{|I5=lC|)rpPZhgpaS*35cUsSET7t0+4JV^~A0%KDw4MK)QT1JO7i0d0u)kMT}x_hj2J{$@Z1`wv%pz#8!DZkP|2>?*;m8jq>Nh-7+;*YT^TzV*8o<7!3beD)%r zw!ISURhrK(7fKm%cm!Jxjg4|FENAp{)cH~Dd0YGGzWYiQu;z)|Z`&}RzG>hkoOb(L zkhx|`6Hydth_fmu*Xl}oHry`KMj&@00;*KqCpIP-~!G03SxYBbaOfS^B*O$%}}=AIH$?86%%rSaImMurv0O>rcwRr!*ZuW*@)1H zXJaCZO|rNIHtuQQd!BXY(8BFjIfihCAd*spN*mjvH4T%&`xT5lQS#NR5lgQJ*h}G^ zCk6-g9bCEjwI8m={anUPU?Z0~uIqN>{CoE#9FNirwoj9+k{So2`lB%K zYn*0_SmuA&G&4_RSYpQAYkbi9wT?q)fA+hwY>gEaQ+k!bXF9NaBW7*llcn}R&0xD8 z6`r5bIDAK;_~hWz3Ch5;)HgY0DQw9~>voxo@n7$xM;BF2+gyS({oI(T(^~k5A3=lM z(w6n`l;YwI^|OL^Z;5Eeh=E6o+|yl3^_;-GeYlTToKz)Xi7u;5D$SvNC0M>yF?xVl zs+EFpV_>v5cZTYw5P;HceCv%bE(IiJDl6#Q`I5tikmVQ9x-ryF1O(Y|P_e@7zm~<+ zoq-#BOsEo7T;H$0?v^j2>XFbLPP48*0|x>x(Al(gN4IpOyL}TPe?&KkEv2w52}YX# zb{?}o(>NMPT&#dq&}h(~C#sB04SuM; zTS-GvS#D$jLwxcDV;S#7*Syk~nDFkH7KE@l)JJhO1G6R36n0Y4E5~7yux`)BV*Wy_ zX@x&w-%t7tQN{Up{dckx{lZZID zHu*ZVxTh*2zTJB_Ny_fuw{S;(LFDZuK4RE*II#!gPcRW@M{&f*e_Q?$HZ1!^+0QjV zj#L@EjTta09ozr$yOp7rY>1q_G>Ts4$7oHjY@z25tQ=Y5m>72CDo*4fj-TQy3?wBv zSveFq4X)N=6VL1{r0@Hk8rXhOkT%I~S;Sj3FF?Fxw_D8}#W|ZE=<+BJPjv)}$-Fk(AMkuiAaz z_)0JxA8cb_*HOTP4i2yBvFz+u9y2PI$J1lR#33@=`t*)a-bJTctC_uv#=*Y505O3r zQJ7|#t7pY2yZ|5$tOh}OP3sdn5HY&N)_#5jAngJvLmakGs-e!5DtG+Mto&(T2n`K6 zReNaW>p6~gPw|M5&h2@lblp&RLx_@=N2!w7*CZEOE zME!Ux9!It%5U#MzVt8{%qo5j3<>^Xs_@*kJqXo-yI|a2^K~t1u8&AW>l^cSoHsMq=*>KOzp&*gSGRmU$DK<ui?n`9IYae!1@LWt7pQeRbJ{$zyB`}ODYp0A zHDgyB$3U3Ek3V(K(8C>qrEIFVCv&7~l`g2JG5=AN<$nhZXozvXAu%SF4ZTOJ(vXbd#(Ir)$Yg zWcEq2RF!mDz9JtOPYL-ffsE{Z%OPj#S$0+5U2ziq2P8*8+mQDO-(EI?yWxd3Ihpo7Um2R_skW?F7ZZ8SQ!f=GXQ^NO2b!#iQwS3(@;oPyP5x z_OX5G(%vZcv-QRAvWxH$7`gvkaDh<2*?KHub_?PhwG!|nX-#qJ#5VjB8^gqKab_!@ z57a@?6)g5&@)VLLRMo;3bq7hvsxE*U?AW(^=WQ~H#bm9%DjDa}UWeia^rziuo~HSo zKe)Z;reiJdsyJW{UERpb-U%Pz(FK$8lSIF4c%OQt+lE3a@Uo7&S25Hx##I^zsZ~i$ zvOoasPLfZ6?}<%erEsr{OplM*@2}9D_`1rR<~_3@fs^;)I#i8RWj?xAKLmcb<^F25 zgfqmm<*JWda{@fV1`%OOayyyjd>~f!7(1QWc)OWm8lBqosL|pK5Ag`FVqh=mjEHM* zyRS0~W8u;!Tn&L>`D<{kNKCKn3F(M>iUJm!rq7YOLBz{iLR!uknBaWnc)Iq7kI_1+ z8B23GuEA09&-!ZTo&x;50<_*gSB(qnqjeitXUcCr#}9KfpY`y|{_L}52|=%`-@N%_ zq(jwiGv(6u!4np^pO2OprAE#Rh!&b|x_g!Moy#hY5Ai9BTOypoPsV@eV#1!V*A5}B z|Cv#-22_&v;W&Cf8{1n7L8K7MfDF$+K>ccI?? zX`aba_AO*9*MyKY_~`~Oxcfxo1jy^*YIyh!qoW2-)4xwp0-pz4R<2bbH6+oJuon(* zF0d{XQ!BMf<3v)&#K@Z@)dq!ftmK;BD%_NCcxMGIpojsH&swV2Vdg}?WEJ#e4to)d zKe_WuxY%I8D`CxN&%9(}$CtCr&?2h6HqF!C>O zYgz{ewyoN^mq7XpT~B|7?^iapyj-n}{zg0ETUagfMO0JjI>l>3Ti%h^TDG?_aoP=s zRtrUwgyVv}@QY{XX?pfflNcj%{;T- zOP6($`0hT#r5uT)w~});GVD?NS!Q!t_7*6n+J^gmg?M9zw+kcvnN>K|4j5f0FN*_c zxTTt3hIj<7GchSAHiu0KE=XwlC4W!+JOuS`C2Q?%H@yN-v8~JyS!j>eeQQQ{{ND)s z1pbWIpQJ^#7zFer<%0Fh2D~k5zjyGozP_XyFX$Kt_^bU9Mh&%lxwbusnZEo5@vbYn zI8-JZ3#9yAyZhzUKGmp-k4M1g@Wu_)!Kpu?>KpEJ4}-h`#MgCA8{Pht=M8Dx;sEyv&Y(CwHJ{CM{?PL2%v|I+~%lb z(a0rMnc)|0S&L<@{xtT^+)bhd-_szsU7hXjn`S#g3N8xKS{0HjUo6SvodteIxC8I) zaxSzlK2tOX3X;99={8Dy{JPS&ziGVAw)yENaWgI!IY7Q@=d^%T(>1iDaN}{u7BKxf z^vUtr=-yFVDqi$y9OF`C;;J1P`y=Q09CC39?iCJ|VOk#qZ&!@4M|baw#X9EE`7Nhf zTTH)?Kcs;WKy%vCWM|%g8#JW+QJU3IrPEj^l41S=HanIupQFyYpeY+d3@6=DQ`z+G%(jy zXZM~sv~dM2sAA~wPVN5fy9b7XA~vYCyDnYACyPG@T*-3`u; z9=YK!Dbz#BXh5!c?2IO398ozFGJ>$0kG}vPYv4B*un9>^5_D;~$Pf`>dPMU37BX+N znAjXf<*LG!Ze9hhvUj(v+MPy4UwQP<{WrfM@GO}cd^UE#2)4I_Ha(F@ zU|N#zU~vh09D170=0=I$8$jSPT0ldYUy)j+<5gxf^$G4f%Bno;s|AN3BYhTgpN3_^+kvuPVUCt zEBX)rgQ>7_&A~cVs{8`otB`pDl!f8N85b3L$9z$yv@IihGk@Ff;P(0t!>4ZXcD5vq0@yS zchBv0F1>#0>|FLG7@Ej^1Se^JJ}Byr`v>J(nBWh65mJ^j$r)8lPmilp=b{?!1&Wla zr!3sdRYKfxNBmWfcP+Rk#`;rbY{5%m_7M2?MfLeMYmJvBP~_k!U428WcXsn@Zs26# zQZlW$SNEqItKTAMqh)G8g4>Vd zrBQg=8;r}n%g$AY4|2}(8))sGWcISV*z6Lb*{tH(ta6ir%eojc0+PByX1O@IlUrE* zZ1v{?n`(SU&R2tHzP|5A705eS%Z{F?!pZ~Ua{t9`6e;Ql=!9e}( z4!vQr|C#yQ3;Qqa-D_>w>|p}sz_#OiT@wxLzccoITH8A^4%~#)@zOdaU}ELsY0Ksj zK@J{(yWZdV-x+oZ`}_OrmtCA`^5s)jQ6P(}LYLCWLM`@%u&!&A>pI58y}e&U+Zg|F zqtOyCoJvSY0wh`8z8WuU7-%?-KY(;4>_%iwbu2^H^(|5~wTh+*t~O@UXPQ(@w&kg| zc`GScOx39o&D`s7AjwaA4JVEs9a%eA`82Q2J&f)w4QF^*=pD(+ zOo26NdTex@)SXB2rv-9tS&Wt!^%Q(veJV%j%A9UzK_xmZ9-^*`q;5WMlD^K*0yQ41 z7D@vYO|leAnrbAxEIM9RN}imHZUr11rW4wB<%;ib7-j1=m^4k2I>`~%+j%)+k}A1a zs!imc4m(RP?o(ap_8;iUhk3lWK96pwDXYBM`7W}R56$wh35Q$Iht0>wSa-Mal6T5A z&eXEdV(F8@MxL}0Uzz9;x9t%nCG?^`-wFaMZZ#8Y?fA>F@1lsja{Y_>Sw<=Q`G+eM3XJ{3Ur7iyd2`D>dq7~2FrO2yY~ z)iwsFhg*YZE<|q*m__7Hoy4Nj002`o@+I*S5ce^xq#ebLvrr>A#vxHWJLrR{7u<~7 z;ExjjwC#5Uoykcwb3~2u{(_u^Wwz?JBJg+(#xmx#uEwt0@FJYyajWRZ+_CP}9**Z} zr5KCqE-$!7hz4LYIPQ51kKHkop0e6O_FP`V-3F=8wXj~!!u;A9$||Z7JtvLIop@<_ z!tnAOYOtm9fsh2U;V{=^7d~=kzMNm#q|abB$!slga|>Dy%052kTgOf!7FO9im~Jsg zLrc+JHP(MCiBNa#)(H_;$fIX}6mww}dr^cU4}E%16=Ys|=A%ZObjIk^$1dQbzym`A zUiJ{u!zVFCe>J(3&s<+tlRtt$Gr#jU5jr?>pE|c}&M~7@mFN!Q%6r(vBGU38u?+7r zzR3bFBXhtU_IssE>+hRwzh#}Iq-c)h$EUH$ENJ!Ycxh3|=F#yHeI*g^ull2-mh}Ua zMWEHP0>qy%_u@-h(cEt0i*MA&c1YuQ4fIQy5~l%Y@+M?WGfq?FWn$H^HrC@B-#*`s ziiiK`i#TsW*Bi9S`#~avORUYqYnF)4xYQuGm%aMZ#GA_=noDR+?e`+=EytrrK23HO zt&zHC`D<{Sc03h9MqgxPt+SYjZ1G@8&E3!N7QXe$li%bDx_zSOTa%-RL0b2jxu3eP z3Kg`URtYY!HBNnnOjB3fO+$W?FTo-EeSqb^>LgZ##0*NqJPQ=1ge++4@HL~k`MGe% z;ogF^kIU`~+>}$7$%lg7yHpXcNvsmSA-|^Y(9vT7uy86{R zL-BoH$ikl?W&g!Dqb1Ip?#xTmDqm8)fZl7HaY%9Mb8|U+1IO3yb`H2r_pUogD>Y22 z!^vnKMh}&wpQ=U>Fx2c^1`GRhMjN4z!uiw*66jL*Xa=1e#))ET#CQ}?!upl|D6b&x z&TVd3Pe=2#^Wq7koVl4QB8wfiz|_>q>~D*~52y_*Iovul(_0`odJ-NlyL}Suy@X4% z@*h>JFg3V*xvgOB8kKAJYz6r<1B1t`n0#ZFY_uyE)kdBhvxpeb4|elaFdd(PO-wwS z62@Ym_badkWCm~2&C?avV`ONE(qf8`!Crb{)i|KAm}OJVIK_xzbG46u10$3>f9Yh; z!G<%l1klau!3}TwF=DdbAz@#rgU%Pb{L$p*g3Y02#ud!f{Mb=y$RS^+)XuLlG&>rz z8Pje7L*iJ0 znUg%7te`6VIN#{OQs}Ap&V6*SchqN1IMnG0O*;5%EHB}OhqIO^}3}; zSI;W;;OOZn)rcj+dbaHd1d0Xytl||nW}Msi6X$n&TH+Afh%mwQKMb>)u>m$pgZ$5? zpT&mi3l_}*#w_q*7{1js{K1vRk_4rb%QdIQCP|L-f+~J%ji=@S*JG`dJi*c)K^>>P z1lqVI?n$L%AMRXNLWXP3EPkxLLvv z=luDYHK(m2zy080a8X_XDOEe($f#`hHoG14*PnXs9T{6TJC(RU?VoqQy<_}YESk^{ zM~=3}xAVKwO~TrnK8_U9&=C&-rgc(l#`=9oK6f$5anIlA%Jf-c0avs=d&MbuQ}FeC zgD&_%A1g3tfY#2K#vT60n`G&1s>|J(>+jH98mdTB$Jf(F$#6kz%ja>zX2b9QzL;)N z2h6q&eSIx~VY6%d7Rz5bIO1}s+?yd3E?HaR#}`DRy;;`TW`&bbP_R+SdwuORhl2vRT{QxOTT_~JSPmPGPDFq zR;iED?*=svtNxl4|21tZe?F1K(z#wQcJuJH0Z-KR2|?`3(y1K;$VkdS36Z}Kvv`jX zm5wN!@q!nr#Y#<$J*$dy zK5GMQQbcOPMhf0NrmY~OynVmc%|LT44bDwc@TE=_k)tq+Ua-T=2M?QGv0mTJ@6Dtf zz}8+L;*d49T@now5xM!1!%yCK=P@d(TkBn6yf|?k=izR zGIi;SReX3=vM+xHKt+Ma;0USz2n36*=^>%+qmX#Xqd37OQRVG%|3qy3|f=C}gVz!S6DLe4nytgeeU=;(Jp zS_AGz(P`|9=@e_1xA&OC(l3_#b~6gO>z~A?*Q| zxwiw>Sm0AaqG+7Km7Z8yaxy0Ce>k|iD^YTjMjhy8Y57}C`t;J$RGDFj?B9!Nlg5TI zDs2BujdI&YtbgG7q1gmkKy)8rLD7+yE|o2g)-U;a!BXGGbSF zxOM-)La`?Y%m<~-c+nAG{#rcB(wWXrP2g`{C!eWemS5iZBE>7~Qyi4{I@l6xHv-{| zMHtwq%jNC1U;^i=RmQPmCN6w69Ktg@EQ>tclcLL$3xeZS3`HM z!{%rUd6&0kl@FPfRMi=y!nLc5tch#`&@x-HV5W>VVhMb*=-n?~ ziX-(EMr~q(?HeZDu9Z9=mL9z5v$RAox0`Bx;iceTxWH6o>=SxrXJ>ydRhk_D76BW| zX(+STW5&H*_x=4IlT}R(?(HG!xdECHhn zQQ0;!(D4f_YoQ+FXy}RQik0Lw2NK-0RY{va*)?ZiUJ{P5^?%I&SU|{3sD0#Tf`Y9( zmk6Y!NEpnl(S; z|Jrl^+5Mj__r3EUi}Ano9I!~^-nP*Q+7|PF-)!GBMow7k=<5^hBchGMKt6+!##0es z;vq^rNB-Yg-FsG;i6iyZ)l3Wo7LCl*4KecPJ(v2AB>!p}!}=}Fq7|bV8R#=6%)fCX z!02kSAfpovGFH)Ikku!Z)xG%6e6=QP(JZCWonT12p&;L_qHVDP5*4+V=C{l;EQu@( zuLz70A{i)HZ7BIKKXjO1D2pg0KYoGyATu?%e1ohX_>Ly0JDuN8eEcO)^ylP!O8xr` zZQv|T0u%hbWm^E**f^9*lFr+~NJ9u+yM{(79e_8*3e=*%u1<;S$4oIW+7WB7Gw7^EXs-6Dmw0?GI zor&2fd}{XN|N5tHm6y$vGo}KTo9xb7*2i?RiQ`S^pbuU=R&XK@ehwk$t>kJXzh!Hq z+{sD7|95^eYZ3I<-&FL>vnc5&#F6|syuw6&R1SeQ4=?SZdGZh##T4frr{y>Z&RUd=JzuD zy(+d|i5MlACIiZ5;zfYr4N=w%O;UOxs^=GJH9@)8j>GKU>RX0%C*g6%->f;LdAUBW zL_+_2s3`aCPk{|io{UiUA3VR_!aR=FDl1Su|DC*YlE>ipBVOH`rt6S1|8Pp?H^fTe z;$6}_vXrn|OM)wr$guf2bE1qZhsH406iBP)IIVO3v_3pGS`pp0XJeF!mNH1PF;?B! z5>Ahw2rlg<)z4m)5Up!&uG@d)UXMq_*oW+Kdc7f}y%nfAA2@Y`OfNTKlmK?s!enN+ zvWxJOaf+EFN6bv!Euzp`T8oK@P<$$%sSXTn2Ekt6^E`qdRA9dGw#>Tgt`nPJZVz{l z1#ng2!N2!nXw=&Cs&_PonoQ=4bn2}O;$})T&XR9(!4I!0JzlJSN0y66`?nJpFTlukRP9 zEiOmdpW{ff6kP&p+}ZaLc-Qz-fRYg^o6ENAXTlx3Pj_>icF~NHkD*8$nq|Luyw&ma zs}b|sR>YqqauJ407^s&$hch4;RAQD-P%X1v%cH+SC2gCARCfo`7F(53F zS%@-YPL?@9-IMz*7i~2RIz#!*Nf~g?a92O`Nxky5NF#3_(1#TP>I^2K(kNIQHg?s# zmuhH8Zwq)eV^w6qYub<>1YdW;5sY+x7U>RS+iFH}N_TjT!rxR$u$yl?_3L5+%B17*Qx=q4dL@}Lp7uMilJB0Nwv$eZ;zb#Z=PPES>4O`H&DVH+%0NCM=X z{vAZ5UQ_-eEg|OWDW(pvNLeGoH_q%g%owj6fqvlV`xHk3Kw2QL4GQV-2n4)ICjIrO2GZUvf6p|41~U=hV}i@!S*lubgb$5sw*` zw?Yc|u#EB`_l#7|z@~WcziLO~`)T({tcj%n_TMGM5cp15L5eDUOFbWiR952N=Dn-> z&`;#5a4#F=(xsqO^@JZqvvc@oq>i-?*aQbsoUS|=qnKDmR%`COS`_7prvXcJYES{# z@5>unw^!=72A_^i(tpL-D$$#v8H~V4`qKJ>`fMlS>nWLwUfAD~F1Our5s6*r!dQh~T6TZRv#HOj%K@KvcRPkEr}J#tO=8&VfE@N|IknRpN6o0qb!TF%4@ zAnM6&G1LWV5>`HvWoEYk!?0@LJ*qsyc9)!h_VP+zX4*}u@)xL=!KXXT%;++XYP zc)1D*(3o^O0D=Baon-S*B@T&VlT)z0w%Q(t-%2cZ4*j`y1t5u{AouXr9cWO=dk1{* z_-!JA4#N5u`WXG+l7DcUhM*lrQ)`x^r=J&l6GOEe4IRv_sKnyuVqfAsCG(FcCWiNg zTkPS#O^o)imx(vfB9mF)c{bbI&ND*(qw#SHRUhq+O6v~|75PlKyq8y-Ze|y)tXL7I z(1n1oLmhO{@qd~}wo!KI-F7TfK@r$>#3Kk5+rm!mX8>YXS5wDQkZO~-d{!MV8l|)A zSt7nElAU7;P_3n(<2DZG>rW$-O96M2(ymGy&Lj*1hc~A^>Z|??!b$lZw=} zA}~AO)D^Z0vG`_a-bdH$H+RT&$)C|SE-|5tPpm3}ndHeX{9e2vm1H4n{w<|_e0E<1 zvz$)Moprr!T=`wS*-Z9FnPxb@5mySgzbqzkmk^0lP#qTl0T4a@h zTR$0;KZ{?KH043a?ZaAL}^3UYh zno$-oa9UoOkc!x>8z7Ok?>i@CSbAPcTIO2_E-QTbdRv?}BpY;vi@!B6?f!J&us6CIzd|o9bwIm;7uWbO?L`?E57%PeSvJh84{|B3zNl@K+(#xg|mtOIL(< zq5W4YU#3xH!a>;B*jUk8v5P5U=f1R*TL$RL>x+x>FlWsTF{jIIe+d>Co0}(565yel zuWH-7m8FACa|)^KwyyjL$#x&(Nd#_B_wMGSiP*PNU?54=(`u8CS=Gsx!lVl*6L=0S zh4b*qH8n-r;AFA-wm{o@7RTT?U!Y~fk9+@4u{5R*$bFvOQCiHWdpey-^9}xB2P>fA z9pz17pQLCu;JH8(bvVJCwE42Arn`k>PE}k9TWm;fJ72$DY~8Y3wrr#?RPUGfknnfs z{4zjQUmuVlSC5gw^+&SeCvAyHt-lCO-CAxoebQp9Xk}ZT!_MNRf~Gw#<~qnrfo2Av z?F;o3Ly7NM+NN`-o%wRE)A{BDqODgn%?dk2rOb0YTYeA)7=&_q3*zh%s-NZ z?tI#{abTG0!cb!s8nWfb)S?Y81^bU(Qw_*g04|WWsAwvEw@g`{UY=Ik`lC2;j1TQMuZ z_BU2KQEOoJA16=TcE!Qd&2&} z!fxPooYbh#{H95$aq4#tf-A3gMqb`kf@R>NYZ5Mruc_fc;^wcD^7ius(p}4f#o5DJ zvEvq(g&COx<5$2G|WthX`pa%S8obS8AWJl@YZnKu1v)1bii$`~uAk__-h zU{nbSFV?WZ%&Mp5>_7FCDv(1a@&?g?{LdO|2rOTufeG0p!9iC8sLxok?Hj}knX=)4 zLhwuCX$f9VJAAoPRofA9XH+6})xJ~|C@+9V87`So!m)0c_C8WsaD{O zC^KRm?d)OY;Q3J8kmWb-kGI&C-I0Ehe`k-AQb3qH2hFuMNc7V%fZmNxqYkB#b3#oM z!?|d7m3e#m@t!I6?+Kw4OM<@(I9$|}g6m%F{wL{4oJh!g6@X;{hl(cILcqN|jMfSf zr9#2GDm4s+ESb%(ivN>>6m7`h&lp@c8GA2Zh!#nt@%{~QrxmqE#}`YcCCDW%6SeVr zRnb~*_~GC6P3ngY? zZRZd`ppvT#exYcv6@m!$PRhdwrIWKoVj~!)+uQ%e4cA7Ct~#6q`4yc-6zDFJ?zQh^ zs#-D6#Nq);r;G$Z3xOGE$0gUy$6i<$r@w(4vp#U7xlCQZ`nwp&II$>^OLWtmsma<7 zQ>>-s^f|oKf%lnzIkpjzRS)yZ1!AqN=pT%I8o&Ma5!Z<)&WOo&WK=p9P*=6TuoLl8 z6zVC+s4WH!S zemH&{9hev+($Wl_j0C>Hmm1X0ChItSHb#xy#~OweT@CoJGSCS3Ur!6l{R9(OjabDJ zI81N_*#D%45*+2uQ{y*~83O-jN%LdF z75V!b=QRpTjS}}$JaPFfk;*$ilU@{4I90t2MpZ(7r^{X;({ZBReJ??Ao< zvs*przt`d27%ef^U)b7V!owTDMb$djQ`eYhH#-pCvO>C-g{*4uMPfytK<*&HXfcwA zy-b5*i~0R=zjdAkt*QO=`n1M9_iUX>q>)GIfw4yb&NEwx_JCZu7A;9mxmH^#- zCp~*4(xxg>QZS?Vn0R=r3RbDoW+o=rZ23(8qc4wAJ41Ux+#*}Nt{mVtT-&?INa5h; z$qjZY<-oqHcz@HQ%fK9q;B6#LiUU>pa=#H%xNFV4`O;DlR6sl|tK z+10)Y!fUmG=ibjTQn!$GUWt~HKi*hA&jCfQe|Sk^6>M1R=`}dJ(|MAQQd~z&3#QM8 z4@~BfvRB}%6)ra@Ur=x6fAk#RzX{Xe%a7z{&vjEl-u;o{)7BoTe=470o19~2jEMXf z9X)IjeK6<9mV;8Ocs-^;)rz~-ZR*r-c%}NN5_;4Oh0@bw$xkaZ#5sd2;z;T+4=7YA z6(Y%Xo4$4Qf*mP^1Ryp%us^UvN=MXiFaP~+Etr@0qZ$bU{QszJ^y-ABk;pCQ<5&AD ziHXcG%<$-$+6wk(k4Rj8rbWW~YFZ}mT{m}1Zl_mb4 zbcyWuKzEsaBH?~Ub%@~GUP%0pqw<><&xoTu0~M)?_J}B?^)NvyE2}+ypEOYW!WW&8 zTn#qmW(^{9zn0mfOhC!Y*~ekob6}5F18-TGd)S!AzV~h0R*Qe@_}LidFk{Nkug8L= zaCkm!2c!oiGDoQIh8!T0-eb8S(T__&rMtzq3FVuYwYbf**#6=@o*tuiZjI9NaK;QTTu7VBdUU8-pmw#wmP*{Or7BFnIWwscTw`@iH*|Ig{D$&VA6lX|uS=0>Bpv zJLEg)ZoX8oEamv77o~^;*-`$>{ZQ`7PPbzxQ5?|YTLg4yBmcx&89JZ47$2av+-}k{ zSg9*c!Tp`Dok@enPcAV9o=P60NF(|kbo9x)3g7xdv*9_RGk7&Lc31i-^d>$5{Np!LJRgl3JAMb% za=8nPwc3%4;`7LkJVKN*cg57`3QLNP?XQ14(*Jd~x_q_t;`fR^x&ST6oZVAH4}AP} zl9r5-JhP$;JG`pJ1Msc;F5X-y45OILbiq_aR`dlQftB3AoA#ovd=l}EQ%%eJQ(x9) zFE2Vc_3WGT3Kg8%gv|y|iY0Tmc{#+@ijx8LFo4SYWc_*dC3dPFb&--iF&nVt!c*$k z8?Su)Bs_X?Vq

Cpt}Nwl-z6!Ma5V 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

mQC}VKu+7F>Yf$5kX)xe7RcM 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%0A=aq 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

    w^*@oxBDMMj0#l7z9L?-RgwoeU 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 LFIp*V81TOU7pe6i literal 0 HcmV?d00001 diff --git a/docs/sources/project/set-up-git.md b/docs/sources/project/set-up-git.md index 1c8b511d0..d67ff817c 100644 --- a/docs/sources/project/set-up-git.md +++ b/docs/sources/project/set-up-git.md @@ -46,9 +46,12 @@ target="_blank">docker/docker repository. that instead. You'll need to convert what you see in the guide to what is appropriate to your tool. -5. Open a terminal window on your local host and change to your home directory. In Windows, you'll work in your Boot2Docker window instead of Powershell or cmd. +5. Open a terminal window on your local host and change to your home directory. $ cd ~ + + In Windows, you'll work in your Boot2Docker window instead of Powershell or + a `cmd` window. 6. Create a `repos` directory. diff --git a/docs/sources/project/software-req-win.md b/docs/sources/project/software-req-win.md new file mode 100644 index 000000000..a7f137892 --- /dev/null +++ b/docs/sources/project/software-req-win.md @@ -0,0 +1,258 @@ +page_title: Set up for development on Windows +page_description: How to set up a server to test Docker Windows client +page_keywords: development, inception, container, image Dockerfile, dependencies, Go, artifacts, windows + + +# Get the required software for Windows + +This page explains how to get the software you need to use a a Windows Server +2012 or Windows 8 machine for Docker development. Before you begin contributing +you must have: + +- a GitHub account +- Git for Windows (msysGit) +- TDM-GCC, a compiler suite for Windows +- MinGW (tar and xz) +- Go language + +> **Note**: This installation prcedure refers to the `C:\` drive. If you system's main drive +is `D:\` you'll need to substitute that in where appropriate in these +instructions. + +### Get a GitHub account + +To contribute to the Docker project, you will need a GitHub account. A free account is +fine. All the Docker project repositories are public and visible to everyone. + +You should also have some experience using both the GitHub application and `git` +on the command line. + +## Install Git for Windows + +Git for Windows includes several tools including msysGit, which is a build +environment. The environment contains the tools you need for development such as +Git and a Git Bash shell. + +1. Browse to the [Git for Windows](https://msysgit.github.io/) download page. + +2. Click **Download**. + + Windows prompts you to save the file to your machine. + +3. Run the saved file. + + The system displays the **Git Setup** wizard. + +4. Click the **Next** button to move through the wizard and accept all the defaults. + +5. Click **Finish** when you are done. + +## Installing TDM-GCC + +TDM-GCC is a compiler suite for Windows. You'll use this suite to compile the +Docker Go code as you develop. + +1. Browse to + [tdm-gcc download page](http://tdm-gcc.tdragon.net/download). + +2. Click on the lastest 64-bit version of the package. + + Windows prompts you to save the file to your machine + +3. Set up the suite by running the downloaded file. + + The system opens the **TDM-GCC Setup** wizard. + +4. Click **Create**. + +5. Click the **Next** button to move through the wizard and accept all the defaults. + +6. Click **Finish** when you are done. + + +## Installing MinGW (tar and xz) + +MinGW is a minimalist port of the GNU Compiler Collection (GCC). In this +procedure, you first download and install the MinGW installation manager. Then, +you use the manager to install the `tar` and `xz` tools from the collection. + +1. Browse to MinGW + [SourceForge](http://sourceforge.net/projects/mingw/). + +2. Click **Download**. + + Windows prompts you to save the file to your machine + +3. Run the downloaded file. + + The system opens the **MinGW Installation Manager Setup Tool** + +4. Choose **Install** install the MinGW Installation Manager. + +5. Press **Continue**. + + The system installs and then opens the MinGW Installation Manager. + +6. Press **Continue** after the install completes to open the manager. + +7. Select **All Packages > MSYS Base System** from the left hand menu. + + The system displays the available packages. + +8. Click on the the **msys-tar bin** package and choose **Mark for Installation**. + +9. Click on the **msys-xz bin** package and choose **Mark for Installation**. + +10. Select **Installation > Apply Changes**, to install the selected packages. + + The system displays the **Schedule of Pending Actions Dialog**. + + ![windows-mingw](/project/images/windows-mingw.png) + +11. Press **Apply** + + MingGW installs the packages for you. + +12. Close the dialog and the MinGW Installation Manager. + + +## Set up your environment variables + +You'll need to add the compiler to your `Path` environment variable. + +1. Open the **Control Panel**. + +2. Choose **System and Security > System**. + +3. Click the **Advanced system settings** link in the sidebar. + + The system opens the **System Properties** dialog. + +3. Select the **Advanced** tab. + +4. Click **Environment Variables**. + + The system opens the **Environment Variables dialog** dialog. + +5. Locate the **System variables** area and scroll to the **Path** + variable. + + ![windows-mingw](/project/images/path_variable.png) + +6. Click **Edit** to edit the variable (you can also double-click it). + + The system opens the **Edit System Variable** dialog. + +7. Make sure the `Path` includes `C:\TDM-GCC64\bin` + + ![include gcc](/project/images/include_gcc.png) + + If you don't see `C:\TDM-GCC64\bin`, add it. + +8. Press **OK** to close this dialog. + +9. Press **OK** twice to close out of the remaining dialogs. + +## Install Go and cross-compile it + +In this section, you install the Go language. Then, you build the source so that it can cross-compile for `linux/amd64` architectures. + +1. Open [Go Language download](http://golang.org/dl/) page in your browser. + +2. Locate and click the latest `.msi` installer. + + The system prompts you to save the file. + +3. Run the installer. + + The system opens the **Go Programming Langauge Setup** dialog. + +4. Select all the defaults to install. + +5. Press **Finish** to close the installation dialog. + +6. Start a command prompt. + +7. Change to the Go `src` directory. + + cd c:\Go\src + +8. Set the following Go variables + + c:\Go\src> set GOOS=linux + c:\Go\src> set GOARCH=amd64 + +9. Compile the source. + + c:\Go\src> make.bat + + Compiling the source also adds a number of variables to your Windows environment. + +## Get the Docker repository + +In this step, you start a Git `bash` terminal and get the Docker source code from +Github. + +1. Locate the **Git Bash** program and start it. + + Recall that **Git Bash** came with the Git for Windows installation. **Git + Bash** just as it sounds allows you to run a Bash terminal on Windows. + + ![Git Bash](/project/images/git_bash.png) + +2. Change to the root directory. + + $ cd /c/ + +3. Make a `gopath` directory. + + $ mkdir gopath + +4. Go get the `docker/docker` repository. + + $ go.exe get github.com/docker/docker package github.com/docker/docker + imports github.com/docker/docker + imports github.com/docker/docker: no buildable Go source files in C:\gopath\src\github.com\docker\docker + + In the next steps, you create environment variables for you Go paths. + +5. Open the **Control Panel** on your system. + +6. Choose **System and Security > System**. + +7. Click the **Advanced system settings** link in the sidebar. + + The system opens the **System Properties** dialog. + +8. Select the **Advanced** tab. + +9. Click **Environment Variables**. + + The system opens the **Environment Variables dialog** dialog. + +10. Locate the **System variables** area and scroll to the **Path** + variable. + +11. Click **New**. + + Now you are going to create some new variables. These paths you'll create in the next procedure; but you can set them now. + +12. Enter `GOPATH` for the **Variable Name**. + +13. For the **Variable Value** enter the following: + + C:\gopath;C:\gopath\src\github.com\docker\docker\vendor + + +14. Press **OK** to close this dialog. + + The system adds `GOPATH` to the list of **System Variables**. + +15. Press **OK** twice to close out of the remaining dialogs. + + +## Where to go next + +In the next section, you'll [learn how to set up and configure Git for +contributing to Docker](/project/set-up-git/). \ No newline at end of file diff --git a/docs/sources/project/software-required.md b/docs/sources/project/software-required.md index 08a4243ae..15b9a6935 100644 --- a/docs/sources/project/software-required.md +++ b/docs/sources/project/software-required.md @@ -2,9 +2,10 @@ page_title: Get the required software page_description: Describes the software required to contribute to Docker page_keywords: GitHub account, repository, Docker, Git, Go, make, -# Get the required software +# Get the required software for Linux or OS X -Before you begin contributing you must have: +This page explains how to get the software you need to use a Linux or OS X +machine for Docker development. Before you begin contributing you must have: * a GitHub account * `git` diff --git a/docs/sources/project/test-and-docs.md b/docs/sources/project/test-and-docs.md index f11049047..23b6b0914 100644 --- a/docs/sources/project/test-and-docs.md +++ b/docs/sources/project/test-and-docs.md @@ -230,6 +230,46 @@ with new memory settings. 6. Restart your container and try your test again. +## Testing just the Windows client + +This explains how to test the Windows client on a Windows server set up as a +development environment. You'll use the **Git Bash** came with the Git for +Windows installation. **Git Bash** just as it sounds allows you to run a Bash +terminal on Windows. + +1. If you don't have one, start a Git Bash terminal. + + ![Git Bash](/project/images/git_bash.png) + +2. Change to the `docker` source directory. + + $ cd /c/gopath/src/github.com/docker/docker + +3. Set `DOCKER_CLIENTONLY` as follows: + + $ export DOCKER_CLIENTONLY=1 + + This ensures you are building only the client binary instead of both the + binary and the daemon. + +4. Set `DOCKER_TEST_HOST` to the `tcp://IP_ADDRESS:2376` value; substitute your +machine's actual IP address, for example: + + $ export DOCKER_TEST_HOST=tcp://263.124.23.200:2376 + +5. Make the binary and the test: + + $ hack/make.sh binary test-integration-cli + + Many tests are skipped on Windows for various reasons. You see which tests + were skipped by re-running the make and passing in the + `TESTFLAGS='-test.v'` value. + + +You can now choose to make changes to the Docker source or the tests. If you +make any changes just run these commands again. + + ## Build and test the documentation The Docker documentation source files are under `docs/sources`. The content is From 8f52eb7b827d658d6974056460afd722a5cb040f Mon Sep 17 00:00:00 2001 From: Peter Salvatore Date: Tue, 21 Apr 2015 23:36:27 -0400 Subject: [PATCH 50/58] Rewrite Official Repositories page. The existing page is focused on listing a set of requirements for proposing a new repository. This information has become outdated and is duplicated in the `docker-library/official-images` and `docker-library/docs` GitHub repositories. This PR rewrites the Official Repositories page to describe what they actually are, and defers to GitHub/IRC for the subset of users that are interested in contributing. I also removed the requirement to contact partners@docker.com and made it optional to reduce the barrier to entry. Signed-off-by: Peter Salvatore --- docs/mkdocs.yml | 2 +- docs/sources/articles/baseimages.md | 2 +- .../articles/dockerfile_best-practices.md | 4 +- docs/sources/docker-hub/official_repos.md | 245 ++++++------------ docs/sources/docker-hub/repos.md | 12 +- docs/sources/terms/repository.md | 2 +- docs/sources/userguide/dockerimages.md | 10 +- docs/sources/userguide/dockerrepos.md | 12 +- 8 files changed, 103 insertions(+), 186 deletions(-) diff --git a/docs/mkdocs.yml b/docs/mkdocs.yml index e425175f6..a83f281e5 100644 --- a/docs/mkdocs.yml +++ b/docs/mkdocs.yml @@ -76,7 +76,7 @@ pages: - ['docker-hub/accounts.md', 'Docker Hub', 'Accounts'] - ['docker-hub/repos.md', 'Docker Hub', 'Repositories'] - ['docker-hub/builds.md', 'Docker Hub', 'Automated Builds'] -- ['docker-hub/official_repos.md', 'Docker Hub', 'Official repo guidelines'] +- ['docker-hub/official_repos.md', 'Docker Hub', 'Official Repositories'] # Docker Hub Enterprise: - ['docker-hub-enterprise/index.md', 'Docker Hub Enterprise', 'Overview' ] diff --git a/docs/sources/articles/baseimages.md b/docs/sources/articles/baseimages.md index a54f5307a..a1a7665b7 100644 --- a/docs/sources/articles/baseimages.md +++ b/docs/sources/articles/baseimages.md @@ -65,4 +65,4 @@ There are lots more resources available to help you write your 'Dockerfile`. * There's a [complete guide to all the instructions](/reference/builder/) available for use in a `Dockerfile` in the reference section. * To help you write a clear, readable, maintainable `Dockerfile`, we've also written a [`Dockerfile` Best Practices guide](/articles/dockerfile_best-practices). -* If you're working on an Official Repo, be sure to check out the [Official Repo Guidelines](/docker-hub/official_repos/). +* If your goal is to create a new Official Repository, be sure to read up on Docker's [Official Repositories](/docker-hub/official_repos/). diff --git a/docs/sources/articles/dockerfile_best-practices.md b/docs/sources/articles/dockerfile_best-practices.md index 425eb8658..04e77fd62 100644 --- a/docs/sources/articles/dockerfile_best-practices.md +++ b/docs/sources/articles/dockerfile_best-practices.md @@ -419,9 +419,9 @@ fail catastrophically if the new build's context is missing the resource being added. Adding a separate tag, as recommended above, will help mitigate this by allowing the `Dockerfile` author to make a choice. -## Examples for official repositories +## Examples for Official Repositories -These Official Repos have exemplary `Dockerfile`s: +These Official Repositories have exemplary `Dockerfile`s: * [Go](https://registry.hub.docker.com/_/golang/) * [Perl](https://registry.hub.docker.com/_/perl/) diff --git a/docs/sources/docker-hub/official_repos.md b/docs/sources/docker-hub/official_repos.md index a101d88c1..eb73b4bc2 100644 --- a/docs/sources/docker-hub/official_repos.md +++ b/docs/sources/docker-hub/official_repos.md @@ -1,189 +1,106 @@ -page_title: Guidelines for official repositories on Docker Hub +page_title: Official Repositories on Docker Hub page_description: Guidelines for Official Repositories on Docker Hub page_keywords: Docker, docker, registry, accounts, plans, Dockerfile, Docker Hub, docs, official, image, documentation -# Guidelines for creating and documenting official repositories +# Official Repositories on Docker Hub -## Introduction +The Docker [Official Repositories](http://registry.hub.docker.com/official) are +a curated set of Docker repositories that are promoted on Docker Hub and +supported by Docker, Inc. They are designed to: -You’ve been given the job of creating an image for an Official Repository -hosted on [Docker Hub Registry](https://registry.hub.docker.com/). These are -our guidelines for getting that task done. Even if you’re not -planning to create an Official Repo, you can think of these guidelines as best -practices for image creation generally. +* Provide essential base OS repositories (for example, + [`ubuntu`](https://registry.hub.docker.com/_/ubuntu/), + [`centos`](https://registry.hub.docker.com/_/centos/)) that serve as the + starting point for the majority of users. -This document consists of two major sections: +* Provide drop-in solutions for popular programming language runtimes, data + stores, and other services, similar to what a Platform-as-a-Service (PAAS) + would offer. -* A list of expected files, resources and supporting items for your image, -along with best practices for creating those items -* Examples embodying those practices +* Exemplify [`Dockerfile` best practices](/articles/dockerfile_best-practices) + and provide clear documentation to serve as a reference for other `Dockerfile` + authors. -## Expected files and resources +* Ensure that security updates are applied in a timely manner. This is + particularly important as many Official Repositories are some of the most + popular on Docker Hub. -### A Git repository +* Provide a channel for software vendors to redistribute up-to-date and + supported versions of their products. Organization accounts on Docker Hub can + also serve this purpose, without the careful review or restrictions on what + can be published. -Your image needs to live in a Git repository, preferably on GitHub. (If you’d -like to use a different provider, please [contact us](mailto:feedback@docker.com) -directly.) Docker **strongly** recommends that this repo be publicly -accessible. +Docker, Inc. sponsors a dedicated team that is responsible for reviewing and +publishing all Official Repositories content. This team works in collaboration +with upstream software maintainers, security experts, and the broader Docker +community. -If the repo is private or has otherwise limited access, you must provide a -means of at least “read-only” access for both general users and for the -docker-library maintainers, who need access for review and building purposes. +While it is preferrable to have upstream software authors maintaining their +corresponding Official Repositories, this is not a strict requirement. Creating +and maintaining images for Official Repositories is a public process. It takes +place openly on GitHub where participation is encouraged. Anyone can provide +feedback, contribute code, suggest process changes, or even propose a new +Official Repository. -### A Dockerfile +## Should I use Official Repositories? -Complete information on `Dockerfile`s can be found in the [Reference section](https://docs.docker.com/reference/builder/). -We also have a page discussing [best practices for writing `Dockerfile`s](/articles/dockerfile_best-practices). -Your `Dockerfile` should adhere to the following: +New Docker users are encouraged to use the Official Repositories in their +projects. These repositories have clear documentation, promote best practices, +and are designed for the most common use cases. Advanced users are encouraged to +review the Official Repositories as part of their `Dockerfile` learning process. -* It must be written either by using `FROM scratch` or be based on another, -established Official Image. -* It must follow `Dockerfile` best practices. These are discussed on the -[best practices page](/articles/dockerfile_best-practices). In addition, -Docker engineer Michael Crosby has some good tips for `Dockerfiles` in -this [blog post](http://crosbymichael.com/dockerfile-best-practices-take-2.html). +A common rationale for diverging from Official Repositories is to optimize for +image size. For instance, many of the programming language stack images contain +a complete build toolchain to support installation of modules that depend on +optimized code. An advanced user could build a custom image with just the +necessary pre-compiled libraries to save space. -While [`ONBUILD` triggers](https://docs.docker.com/reference/builder/#onbuild) -are not required, if you choose to use them you should: +A number of language stacks such as +[`python`](https://registry.hub.docker.com/_/python/) and +[`ruby`](https://registry.hub.docker.com/_/ruby/) have `-slim` tag variants +designed to fill the need for optimization. Even when these "slim" variants are +insufficient, it is still recommended to inherit from an Official Repository +base OS image to leverage the ongoing maintenance work, rather than duplicating +these efforts. -* Build both `ONBUILD` and non-`ONBUILD` images, with the `ONBUILD` image -built `FROM` the non-`ONBUILD` image. -* The `ONBUILD` image should be specifically tagged, for example, `ruby: -latest`and `ruby:onbuild`, or `ruby:2` and `ruby:2-onbuild` +## How can I get involved? -### A short description +All Official Repositories contain a **User Feedback** section in their +documentation which covers the details for that specific repository. In most +cases, the GitHub repository which contains the Dockerfiles for an Official +Repository also has an active issue tracker. General feedback and support +questions should be directed to `#docker-library` on Freenode IRC. -Include a brief description of your image (in plaintext). Only one description -is required; you don’t need additional descriptions for each tag. The file -should also: +## How do I create a new Official Repository? -* Be named `README-short.txt` -* Reside in the repo for the “latest” tag -* Not exceed 100 characters +From a high level, an Official Repository starts out as a proposal in the form +of a set of GitHub pull requests. You'll find detailed and objective proposal +requirements in the following GitHub repositories: -### A logo +* [docker-library/official-images](https://github.com/docker-library/official-images) -Include a logo of your company or the product (png format preferred). Only one -logo is required; you don’t need additional logo files for each tag. The logo -file should have the following characteristics: +* [docker-library/docs](https://github.com/docker-library/docs) -* Be named `logo.png` -* Should reside in the repo for the “latest” tag -* Should fit inside a 200px square, maximized in one dimension (preferably the -width) -* Square or wide (landscape) is preferred over tall (portrait), but exceptions -can be made based on the logo needed +The Official Repositories team, with help from community contributors, formally +review each proposal and provide feedback to the author. This initial review +process may require a bit of back and forth before the proposal is accepted. -### A long description +There are also subjective considerations during the review process. These +subjective concerns boil down to the basic question: "is this image generally +useful?" For example, the [`python`](https://registry.hub.docker.com/_/python/) +Official Repository is "generally useful" to the large Python developer +community, whereas an obscure text adventure game written in Python last week is +not. -Include a comprehensive description of your image (in Markdown format, GitHub -flavor preferred). Only one description is required; you don’t need additional -descriptions for each tag. The file should also: +When a new proposal is accepted, the author becomes responsibile for keeping +their images up-to-date and responding to user feedback. The Official +Repositories team becomes responsibile for publishing the images and +documentation on Docker Hub. Updates to the Official Repository follow the same +pull request process, though with less review. The Official Repositories team +ultimately acts as a gatekeeper for all changes, which helps mitigate the risk +of quality and security issues from being introduced. -* Be named `README.md` -* Reside in the repo for the “latest” tag -* Be no longer than absolutely necessary, while still addressing all the -content requirements - -In terms of content, the long description must include the following sections: - -* Overview & links -* How-to/usage -* Issues & contributions - -#### Overview and links - -This section should provide: - -* an overview of the software contained in the image, similar to the -introduction in a Wikipedia entry - -* a selection of links to outside resources that help to describe the software - -* a *mandatory* link to the `Dockerfile` - -#### How-to/usage - -A section that describes how to run and use the image, including common use -cases and example `Dockerfile`s (if applicable). Try to provide clear, step-by- -step instructions wherever possible. - -##### Issues and contributions - -In this section, point users to any resources that can help them contribute to -the project. Include contribution guidelines and any specific instructions -related to your development practices. Include a link to -[Docker’s resources for contributors](https://docs.docker.com/contributing/contributing/). -Be sure to include contact info, handles, etc. for official maintainers. - -Also include information letting users know where they can go for help and how -they can file issues with the repo. Point them to any specific IRC channels, -issue trackers, contacts, additional “how-to” information or other resources. - -### License - -Include a file, `LICENSE`, of any applicable license. Docker recommends using -the license of the software contained in the image, provided it allows Docker, -Inc. to legally build and distribute the image. Otherwise, Docker recommends -adopting the [Expat license](http://directory.fsf.org/wiki/License:Expat) -(a.k.a., the MIT or X11 license). - -## Examples - -Below are sample short and long description files for an imaginary image -containing Ruby on Rails. - -### Short description - -`README-short.txt` - -`Ruby on Rails is an open-source application framework written in Ruby. It emphasizes best practices such as convention over configuration, active record pattern, and the model-view-controller pattern.` - -### Long description - -`README.md` - -```markdown -# What is Ruby on Rails - -Ruby on Rails, often simply referred to as Rails, is an open source web application framework which runs via the Ruby programming language. It is a full-stack framework: it allows creating pages and applications that gather information from the web server, talk to or query the database, and render templates out of the box. As a result, Rails features a routing system that is independent of the web server. - -> [wikipedia.org/wiki/Ruby_on_Rails](https://en.wikipedia.org/wiki/Ruby_on_Rails) - -# How to use this image - -## Create a `Dockerfile` in your rails app project - - FROM rails:onbuild - -Put this file in the root of your app, next to the `Gemfile`. - -This image includes multiple `ONBUILD` triggers so that should be all that you need for most applications. The build will `ADD . /usr/src/app`, `RUN bundle install`, `EXPOSE 3000`, and set the default command to `rails server`. - -Then build and run the Docker image. - - docker build -t my-rails-app . - docker run --name some-rails-app -d my-rails-app - -Test it by visiting `http://container-ip:3000` in a browser. On the other hand, if you need access outside the host on port 8080: - - docker run --name some-rails-app -p 8080:3000 -d my-rails-app - -Then go to `http://localhost:8080` or `http://host-ip:8080` in a browser. -``` - -For more examples, take a look at these repos: - -* [Go](https://github.com/docker-library/golang) -* [PostgreSQL](https://github.com/docker-library/postgres) -* [Buildpack-deps](https://github.com/docker-library/buildpack-deps) -* ["Hello World" minimal container](https://github.com/docker-library/hello-world) -* [Node](https://github.com/docker-library/node) - -## Submit your repo - -Once you've checked off everything in these guidelines, and are confident your -image is ready for primetime, please contact us at -[partners@docker.com](mailto:partners@docker.com) to have your project -considered for the Official Repos program. +> **Note**: If you are interested in proposing an Official Repository, but would +> like to discuss it with Docker, Inc. privately first, please send your +> inquiries to partners@docker.com. There is no fast-track or pay-for-status +> option. diff --git a/docs/sources/docker-hub/repos.md b/docs/sources/docker-hub/repos.md index 0a2fa6550..a48040fb5 100644 --- a/docs/sources/docker-hub/repos.md +++ b/docs/sources/docker-hub/repos.md @@ -51,10 +51,10 @@ private to public. You can also collaborate on Docker Hub with organizations and groups. You can read more about that [here](accounts/). -## Official repositories +## Official Repositories -The Docker Hub contains a number of [official -repositories](http://registry.hub.docker.com/official). These are +The Docker Hub contains a number of [Official +Repositories](http://registry.hub.docker.com/official). These are certified repositories from vendors and contributors to Docker. They contain Docker images from vendors like Canonical, Oracle, and Red Hat that you can use to build applications and services. @@ -63,9 +63,9 @@ If you use Official Repositories you know you're using a supported, optimized and up-to-date image to power your applications. > **Note:** -> If you would like to contribute an official repository for your -> organization, product or team you can see more information -> [here](https://github.com/docker/stackbrew). +> If you would like to contribute an Official Repository for your +> organization, see [Official Repositories on Docker +> Hub](/docker-hub/official_repos) for more information. ## Private repositories diff --git a/docs/sources/terms/repository.md b/docs/sources/terms/repository.md index 84963b4bf..4b8579924 100644 --- a/docs/sources/terms/repository.md +++ b/docs/sources/terms/repository.md @@ -29,7 +29,7 @@ A Fully Qualified Image Name (FQIN) can be made up of 3 parts: If you create a new repository which you want to share, you will need to set at least the `user_name`, as the `default` blank `user_name` prefix is -reserved for official Docker images. +reserved for [Official Repositories](/docker-hub/official_repos). For more information see [*Working with Repositories*](/userguide/dockerrepos/#working-with-the-repository) diff --git a/docs/sources/userguide/dockerimages.md b/docs/sources/userguide/dockerimages.md index 621946654..c29b01032 100644 --- a/docs/sources/userguide/dockerimages.md +++ b/docs/sources/userguide/dockerimages.md @@ -131,11 +131,11 @@ term `sinatra`. We can see we've returned a lot of images that use the term `sinatra`. We've returned a list of image names, descriptions, Stars (which measure the social popularity of images - if a user likes an image then they can "star" it), and -the Official and Automated build statuses. Official repositories are built and -maintained by the [Stackbrew](https://github.com/docker/stackbrew) project, -and Automated repositories are [Automated Builds]( -/userguide/dockerrepos/#automated-builds) that allow you to validate the source -and content of an image. +the Official and Automated build statuses. +[Official Repositories](/docker-hub/official_repos) are a carefully curated set +of Docker repositories supported by Docker, Inc. Automated repositories are +[Automated Builds](/userguide/dockerrepos/#automated-builds) that allow you to +validate the source and content of an image. We've reviewed the images available to use and we decided to use the `training/sinatra` image. So far we've seen two types of images repositories, diff --git a/docs/sources/userguide/dockerrepos.md b/docs/sources/userguide/dockerrepos.md index efa6ca3d0..8fc2ba637 100644 --- a/docs/sources/userguide/dockerrepos.md +++ b/docs/sources/userguide/dockerrepos.md @@ -51,12 +51,12 @@ name, user name, or description: tianon/centos CentOS 5 and 6, created using rinse instea... 21 ... -There you can see two example results: `centos` and -`tianon/centos`. The second result shows that it comes from -the public repository of a user, named `tianon/`, while the first result, -`centos`, doesn't explicitly list a repository which means that it comes from the -trusted top-level namespace. The `/` character separates a user's -repository from the image name. +There you can see two example results: `centos` and `tianon/centos`. The second +result shows that it comes from the public repository of a user, named +`tianon/`, while the first result, `centos`, doesn't explicitly list a +repository which means that it comes from the trusted top-level namespace for +[Official Repositories](/docker-hub/official_repos). The `/` character separates +a user's repository from the image name. Once you've found the image you want, you can download it with `docker pull `: From c7812f01c7269c713c2243fe8a69b55cdb77b72a Mon Sep 17 00:00:00 2001 From: Qiang Huang Date: Tue, 28 Apr 2015 18:51:04 +0800 Subject: [PATCH 51/58] fix a minor inspect format issue Before, inspect cont1 cont2 shows: [{ xxx } ,{ xxx } ] After, it shows: [ { xxx } ,{ xxx } ] Because `func (*Encoder) Encode` always followed by a newline character, so it's difficult to put '}' and ']' one the same line. To get symmetry, above is our choice. Signed-off-by: Qiang Huang --- api/client/inspect.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/client/inspect.go b/api/client/inspect.go index db281795c..0f327cb4d 100644 --- a/api/client/inspect.go +++ b/api/client/inspect.go @@ -34,7 +34,7 @@ func (cli *DockerCli) CmdInspect(args ...string) error { } indented := new(bytes.Buffer) - indented.WriteByte('[') + indented.WriteString("[\n") status := 0 isImage := false From ed40c0a9a48e54dbe341ad718d9362a268467378 Mon Sep 17 00:00:00 2001 From: Vincent Batts Date: Mon, 27 Apr 2015 11:03:05 -0400 Subject: [PATCH 52/58] rhel.md: update RHEL6 from 6.5 to 6.6 Signed-off-by: Vincent Batts --- docs/sources/installation/rhel.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/sources/installation/rhel.md b/docs/sources/installation/rhel.md index 7be8debce..b312d57d1 100644 --- a/docs/sources/installation/rhel.md +++ b/docs/sources/installation/rhel.md @@ -7,7 +7,7 @@ page_keywords: Docker, Docker documentation, requirements, linux, rhel Docker is supported on the following versions of RHEL: - [*Red Hat Enterprise Linux 7 (64-bit)*](#red-hat-enterprise-linux-7-installation) -- [*Red Hat Enterprise Linux 6.5 (64-bit)*](#red-hat-enterprise-linux-6.5-installation) or later +- [*Red Hat Enterprise Linux 6.6 (64-bit)*](#red-hat-enterprise-linux-66-installation) or later ## Kernel support @@ -41,14 +41,14 @@ Portal](https://access.redhat.com/). Please continue with the [Starting the Docker daemon](#starting-the-docker-daemon). -## Red Hat Enterprise Linux 6.5 installation +## Red Hat Enterprise Linux 6.6 installation You will need **64 bit** [RHEL -6.5](https://access.redhat.com/site/articles/3078#RHEL6) or later, with +6.6](https://access.redhat.com/site/articles/3078#RHEL6) or later, with a RHEL 6 kernel version 2.6.32-431 or higher as this has specific kernel fixes to allow Docker to work. -Docker is available for **RHEL6.5** on EPEL. Please note that +Docker is available for **RHEL6.6** on EPEL. Please note that this package is part of [Extra Packages for Enterprise Linux (EPEL)](https://fedoraproject.org/wiki/EPEL), a community effort to create and maintain additional packages for the RHEL distribution. From 179b6ddc353fd766125df19bf61b00a39a13cd04 Mon Sep 17 00:00:00 2001 From: Vincent Batts Date: Mon, 27 Apr 2015 11:04:32 -0400 Subject: [PATCH 53/58] rhel.md: bump the kernel version for RHEL6 Closes #9856 Signed-off-by: Vincent Batts --- docs/sources/installation/rhel.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/sources/installation/rhel.md b/docs/sources/installation/rhel.md index b312d57d1..610a300c5 100644 --- a/docs/sources/installation/rhel.md +++ b/docs/sources/installation/rhel.md @@ -45,7 +45,7 @@ Please continue with the [Starting the Docker daemon](#starting-the-docker-daemo You will need **64 bit** [RHEL 6.6](https://access.redhat.com/site/articles/3078#RHEL6) or later, with -a RHEL 6 kernel version 2.6.32-431 or higher as this has specific kernel +a RHEL 6 kernel version 2.6.32-504.16.2 or higher as this has specific kernel fixes to allow Docker to work. Docker is available for **RHEL6.6** on EPEL. Please note that From 9b365e0845bf8e74cef23db2233e721b90ae4339 Mon Sep 17 00:00:00 2001 From: Vincent Batts Date: Mon, 27 Apr 2015 14:44:56 -0400 Subject: [PATCH 54/58] rhel.md: adding link to most recent issue Signed-off-by: Vincent Batts --- docs/sources/installation/rhel.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/sources/installation/rhel.md b/docs/sources/installation/rhel.md index 610a300c5..b3bd7aa1d 100644 --- a/docs/sources/installation/rhel.md +++ b/docs/sources/installation/rhel.md @@ -46,7 +46,7 @@ Please continue with the [Starting the Docker daemon](#starting-the-docker-daemo You will need **64 bit** [RHEL 6.6](https://access.redhat.com/site/articles/3078#RHEL6) or later, with a RHEL 6 kernel version 2.6.32-504.16.2 or higher as this has specific kernel -fixes to allow Docker to work. +fixes to allow Docker to work. Related issues: [#9856](https://github.com/docker/docker/issues/9856). Docker is available for **RHEL6.6** on EPEL. Please note that this package is part of [Extra Packages for Enterprise Linux From 6fd8e485c85c4f8ca62578d0840bdeddc4cba151 Mon Sep 17 00:00:00 2001 From: buddhamagnet Date: Thu, 9 Apr 2015 20:07:06 +0100 Subject: [PATCH 55/58] add support for exclusion rules in dockerignore Signed-off-by: Dave Goodchild --- .../articles/dockerfile_best-practices.md | 13 +- docs/sources/reference/builder.md | 97 +++++++----- docs/sources/reference/commandline/cli.md | 69 +++------ integration-cli/docker_cli_build_test.go | 63 +++++++- pkg/archive/archive.go | 11 +- pkg/fileutils/fileutils.go | 111 ++++++++++++-- pkg/fileutils/fileutils_test.go | 139 ++++++++++++++++++ 7 files changed, 399 insertions(+), 104 deletions(-) diff --git a/docs/sources/articles/dockerfile_best-practices.md b/docs/sources/articles/dockerfile_best-practices.md index 425eb8658..dfb265c68 100644 --- a/docs/sources/articles/dockerfile_best-practices.md +++ b/docs/sources/articles/dockerfile_best-practices.md @@ -32,13 +32,14 @@ ephemeral as possible. By “ephemeral,” we mean that it can be stopped and destroyed and a new one built and put in place with an absolute minimum of set-up and configuration. -### Use [a .dockerignore file](https://docs.docker.com/reference/builder/#the-dockerignore-file) +### Use a .dockerignore file -For faster uploading and efficiency during `docker build`, you should use -a `.dockerignore` file to exclude files or directories from the build -context and final image. For example, unless`.git` is needed by your build -process or scripts, you should add it to `.dockerignore`, which can save many -megabytes worth of upload time. +In most cases, it's best to put each Dockerfile in an empty directory. Then, +add to that directory only the files needed for building the Dockerfile. To +increase the build's performance, you can exclude files and directories by +adding a `.dockerignore` file to that directory as well. This file supports +exclusion patterns similar to `.gitignore` files. For information on creating one, +see the [.dockerignore file](../../reference/builder/#dockerignore-file). ### Avoid installing unnecessary packages diff --git a/docs/sources/reference/builder.md b/docs/sources/reference/builder.md index c5392f847..7dbe54923 100644 --- a/docs/sources/reference/builder.md +++ b/docs/sources/reference/builder.md @@ -41,10 +41,11 @@ whole context must be transferred to the daemon. The Docker CLI reports > repository, the entire contents of your hard drive will get sent to the daemon (and > thus to the machine running the daemon). You probably don't want that. -In most cases, it's best to put each Dockerfile in an empty directory, and then add only -the files needed for building that Dockerfile to that directory. To further speed up the -build, you can exclude files and directories by adding a `.dockerignore` file to the same -directory. +In most cases, it's best to put each Dockerfile in an empty directory. Then, +only add the files needed for building the Dockerfile to the directory. To +increase the build's performance, you can exclude files and directories by +adding a `.dockerignore` file to the directory. For information about how to +[create a `.dockerignore` file](#the-dockerignore-file) on this page. You can specify a repository and tag at which to save the new image if the build succeeds: @@ -169,43 +170,67 @@ will result in `def` having a value of `hello`, not `bye`. However, `ghi` will have a value of `bye` because it is not part of the same command that set `abc` to `bye`. -## The `.dockerignore` file +### .dockerignore file -If a file named `.dockerignore` exists in the source repository, then it -is interpreted as a newline-separated list of exclusion patterns. -Exclusion patterns match files or directories relative to the source repository -that will be excluded from the context. Globbing is done using Go's +If a file named `.dockerignore` exists in the root of `PATH`, then Docker +interprets it as a newline-separated list of exclusion patterns. Docker excludes +files or directories relative to `PATH` that match these exclusion patterns. If +there are any `.dockerignore` files in `PATH` subdirectories, Docker treats +them as normal files. + +Filepaths in `.dockerignore` are absolute with the current directory as the +root. Wildcards are allowed but the search is not recursive. Globbing (file name +expansion) is done using Go's [filepath.Match](http://golang.org/pkg/path/filepath#Match) rules. -> **Note**: -> The `.dockerignore` file can even be used to ignore the `Dockerfile` and -> `.dockerignore` files. This might be useful if you are copying files from -> the root of the build context into your new container but do not want to -> include the `Dockerfile` or `.dockerignore` files (e.g. `ADD . /someDir/`). +You can specify exceptions to exclusion rules. To do this, simply prefix a +pattern with an `!` (exclamation mark) in the same way you would in a +`.gitignore` file. Currently there is no support for regular expressions. +Formats like `[^temp*]` are ignored. -The following example shows the use of the `.dockerignore` file to exclude the -`.git` directory from the context. Its effect can be seen in the changed size of -the uploaded context. +The following is an example `.dockerignore` file: + +``` + */temp* + */*/temp* + temp? + *.md + !LICENCSE.md +``` + +This file causes the following build behavior: + +| Rule | Behavior | +|----------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `*/temp*` | Exclude all files with names starting with`temp` in any subdirectory below the root directory. For example, a file named`/somedir/temporary.txt` is ignored. | +| `*/*/temp*` | Exclude files starting with name `temp` from any subdirectory that is two levels below the root directory. For example, the file `/somedir/subdir/temporary.txt` is ignored. | +| `temp?` | Exclude the files that match the pattern in the root directory. For example, the files `tempa`, `tempb` in the root directory are ignored. | +| `*.md ` | Exclude all markdown files. | +| `!LICENSE.md` | Exception to the exclude all Markdown files is this file, `LICENSE.md`, include this file in the build. | + +The placement of `!` exception rules influences the matching algorithm; the +last line of the `.dockerignore` that matches a particular file determines +whether it is included or excluded. In the above example, the `LICENSE.md` file +matches both the `*.md` and `!LICENSE.md` rule. If you reverse the lines in the +example: + +``` + */temp* + */*/temp* + temp? + !LICENCSE.md + *.md +``` + +The build would exclude `LICENSE.md` because the last `*.md` rule adds all +Markdown files back onto the ignore list. The `!LICENSE.md` rule has no effect +because the subsequent `*.md` rule overrides it. + +You can even use the `.dockerignore` file to ignore the `Dockerfile` and +`.dockerignore` files. This is useful if you are copying files from the root of +the build context into your new container but do not want to include the +`Dockerfile` or `.dockerignore` files (e.g. `ADD . /someDir/`). - $ docker build . - Uploading context 18.829 MB - Uploading context - Step 0 : FROM busybox - ---> 769b9341d937 - Step 1 : CMD echo Hello World - ---> Using cache - ---> 99cc1ad10469 - Successfully built 99cc1ad10469 - $ echo ".git" > .dockerignore - $ docker build . - Uploading context 6.76 MB - Uploading context - Step 0 : FROM busybox - ---> 769b9341d937 - Step 1 : CMD echo Hello World - ---> Using cache - ---> 99cc1ad10469 - Successfully built 99cc1ad10469 ## FROM diff --git a/docs/sources/reference/commandline/cli.md b/docs/sources/reference/commandline/cli.md index 26659c8ff..597324eae 100644 --- a/docs/sources/reference/commandline/cli.md +++ b/docs/sources/reference/commandline/cli.md @@ -653,6 +653,26 @@ If you use STDIN or specify a `URL`, the system places the contents into a file called `Dockerfile`, and any `-f`, `--file` option is ignored. In this scenario, there is no context. +By default the `docker build` command will look for a `Dockerfile` at the +root of the build context. The `-f`, `--file`, option lets you specify +the path to an alternative file to use instead. This is useful +in cases where the same set of files are used for multiple builds. The path +must be to a file within the build context. If a relative path is specified +then it must to be relative to the current directory. + +In most cases, it's best to put each Dockerfile in an empty directory. Then, add +to that directory only the files needed for building the Dockerfile. To increase +the build's performance, you can exclude files and directories by adding a +`.dockerignore` file to that directory as well. For information on creating one, +see the [.dockerignore file](../../reference/builder/#dockerignore-file). + +If the Docker client loses connection to the daemon, the build is canceled. +This happens if you interrupt the Docker client with `ctrl-c` or if the Docker +client is killed for any reason. + +> **Note:** Currently only the "run" phase of the build can be canceled until +> pull cancelation is implemented). + ### Return code On a successful build, a return code of success `0` will be returned. @@ -673,55 +693,11 @@ INFO[0000] The command [/bin/sh -c exit 13] returned a non-zero code: 13 $ echo $? 1 ``` - -### .dockerignore file - -If a file named `.dockerignore` exists in the root of `PATH` then it -is interpreted as a newline-separated list of exclusion patterns. -Exclusion patterns match files or directories relative to `PATH` that -will be excluded from the context. Globbing is done using Go's -[filepath.Match](http://golang.org/pkg/path/filepath#Match) rules. - -Please note that `.dockerignore` files in other subdirectories are -considered as normal files. Filepaths in `.dockerignore` are absolute with -the current directory as the root. Wildcards are allowed but the search -is not recursive. - -#### Example .dockerignore file - */temp* - */*/temp* - temp? - -The first line above `*/temp*`, would ignore all files with names starting with -`temp` from any subdirectory below the root directory. For example, a file named -`/somedir/temporary.txt` would be ignored. The second line `*/*/temp*`, will -ignore files starting with name `temp` from any subdirectory that is two levels -below the root directory. For example, the file `/somedir/subdir/temporary.txt` -would get ignored in this case. The last line in the above example `temp?` -will ignore the files that match the pattern from the root directory. -For example, the files `tempa`, `tempb` are ignored from the root directory. -Currently there is no support for regular expressions. Formats -like `[^temp*]` are ignored. - -By default the `docker build` command will look for a `Dockerfile` at the -root of the build context. The `-f`, `--file`, option lets you specify -the path to an alternative file to use instead. This is useful -in cases where the same set of files are used for multiple builds. The path -must be to a file within the build context. If a relative path is specified -then it must to be relative to the current directory. - -If the Docker client loses connection to the daemon, the build is canceled. -This happens if you interrupt the Docker client with `ctrl-c` or if the Docker -client is killed for any reason. - -> **Note:** Currently only the "run" phase of the build can be canceled until -> pull cancelation is implemented). - See also: [*Dockerfile Reference*](/reference/builder). -#### Examples +### Examples $ docker build . Uploading context 10240 bytes @@ -790,7 +766,8 @@ affect the build cache. This example shows the use of the `.dockerignore` file to exclude the `.git` directory from the context. Its effect can be seen in the changed size of the -uploaded context. +uploaded context. The builder reference contains detailed information on +[creating a .dockerignore file](../../builder/#dockerignore-file) $ docker build -t vieux/apache:2.0 . diff --git a/integration-cli/docker_cli_build_test.go b/integration-cli/docker_cli_build_test.go index 695e4cd6e..334342783 100644 --- a/integration-cli/docker_cli_build_test.go +++ b/integration-cli/docker_cli_build_test.go @@ -3427,20 +3427,29 @@ func (s *DockerSuite) TestBuildDockerignore(c *check.C) { RUN [[ ! -e /bla/src/_vendor ]] RUN [[ ! -e /bla/.gitignore ]] RUN [[ ! -e /bla/README.md ]] + RUN [[ ! -e /bla/dir/foo ]] + RUN [[ ! -e /bla/foo ]] RUN [[ ! -e /bla/.git ]]` ctx, err := fakeContext(dockerfile, map[string]string{ "Makefile": "all:", ".git/HEAD": "ref: foo", "src/x.go": "package main", "src/_vendor/v.go": "package main", + "dir/foo": "", ".gitignore": "", "README.md": "readme", - ".dockerignore": ".git\npkg\n.gitignore\nsrc/_vendor\n*.md", + ".dockerignore": ` +.git +pkg +.gitignore +src/_vendor +*.md +dir`, }) - defer ctx.Close() if err != nil { c.Fatal(err) } + defer ctx.Close() if _, err := buildImageFromContext(name, ctx, true); err != nil { c.Fatal(err) } @@ -3467,6 +3476,55 @@ func (s *DockerSuite) TestBuildDockerignoreCleanPaths(c *check.C) { } } +func (s *DockerSuite) TestBuildDockerignoreExceptions(c *check.C) { + name := "testbuilddockerignoreexceptions" + defer deleteImages(name) + dockerfile := ` + FROM busybox + ADD . /bla + RUN [[ -f /bla/src/x.go ]] + RUN [[ -f /bla/Makefile ]] + RUN [[ ! -e /bla/src/_vendor ]] + RUN [[ ! -e /bla/.gitignore ]] + RUN [[ ! -e /bla/README.md ]] + RUN [[ -e /bla/dir/dir/foo ]] + RUN [[ ! -e /bla/dir/foo1 ]] + RUN [[ -f /bla/dir/e ]] + RUN [[ -f /bla/dir/e-dir/foo ]] + RUN [[ ! -e /bla/foo ]] + RUN [[ ! -e /bla/.git ]]` + ctx, err := fakeContext(dockerfile, map[string]string{ + "Makefile": "all:", + ".git/HEAD": "ref: foo", + "src/x.go": "package main", + "src/_vendor/v.go": "package main", + "dir/foo": "", + "dir/foo1": "", + "dir/dir/f1": "", + "dir/dir/foo": "", + "dir/e": "", + "dir/e-dir/foo": "", + ".gitignore": "", + "README.md": "readme", + ".dockerignore": ` +.git +pkg +.gitignore +src/_vendor +*.md +dir +!dir/e* +!dir/dir/foo`, + }) + if err != nil { + c.Fatal(err) + } + defer ctx.Close() + if _, err := buildImageFromContext(name, ctx, true); err != nil { + c.Fatal(err) + } +} + func (s *DockerSuite) TestBuildDockerignoringDockerfile(c *check.C) { name := "testbuilddockerignoredockerfile" dockerfile := ` @@ -3607,6 +3665,7 @@ func (s *DockerSuite) TestBuildDockerignoringWholeDir(c *check.C) { ctx, err := fakeContext(dockerfile, map[string]string{ "Dockerfile": "FROM scratch", "Makefile": "all:", + ".gitignore": "", ".dockerignore": ".*\n", }) defer ctx.Close() diff --git a/pkg/archive/archive.go b/pkg/archive/archive.go index 7f1889750..4d8d26008 100644 --- a/pkg/archive/archive.go +++ b/pkg/archive/archive.go @@ -391,6 +391,13 @@ func Tar(path string, compression Compression) (io.ReadCloser, error) { // TarWithOptions creates an archive from the directory at `path`, only including files whose relative // paths are included in `options.IncludeFiles` (if non-nil) or not in `options.ExcludePatterns`. func TarWithOptions(srcPath string, options *TarOptions) (io.ReadCloser, error) { + + patterns, patDirs, exceptions, err := fileutils.CleanPatterns(options.ExcludePatterns) + + if err != nil { + return nil, err + } + pipeReader, pipeWriter := io.Pipe() compressWriter, err := CompressStream(pipeWriter, options.Compression) @@ -441,7 +448,7 @@ func TarWithOptions(srcPath string, options *TarOptions) (io.ReadCloser, error) // is asking for that file no matter what - which is true // for some files, like .dockerignore and Dockerfile (sometimes) if include != relFilePath { - skip, err = fileutils.Matches(relFilePath, options.ExcludePatterns) + skip, err = fileutils.OptimizedMatches(relFilePath, patterns, patDirs) if err != nil { logrus.Debugf("Error matching %s", relFilePath, err) return err @@ -449,7 +456,7 @@ func TarWithOptions(srcPath string, options *TarOptions) (io.ReadCloser, error) } if skip { - if f.IsDir() { + if !exceptions && f.IsDir() { return filepath.SkipDir } return nil diff --git a/pkg/fileutils/fileutils.go b/pkg/fileutils/fileutils.go index ef2a6523d..d1e130d0a 100644 --- a/pkg/fileutils/fileutils.go +++ b/pkg/fileutils/fileutils.go @@ -1,33 +1,120 @@ package fileutils import ( + "errors" "fmt" "io" "io/ioutil" "os" "path/filepath" + "strings" "github.com/Sirupsen/logrus" ) -// Matches returns true if relFilePath matches any of the patterns -func Matches(relFilePath string, patterns []string) (bool, error) { - for _, exclude := range patterns { - matched, err := filepath.Match(exclude, relFilePath) +func Exclusion(pattern string) bool { + return pattern[0] == '!' +} + +func Empty(pattern string) bool { + return pattern == "" +} + +// Cleanpatterns takes a slice of patterns returns a new +// slice of patterns cleaned with filepath.Clean, stripped +// of any empty patterns and lets the caller know whether the +// slice contains any exception patterns (prefixed with !). +func CleanPatterns(patterns []string) ([]string, [][]string, bool, error) { + // Loop over exclusion patterns and: + // 1. Clean them up. + // 2. Indicate whether we are dealing with any exception rules. + // 3. Error if we see a single exclusion marker on it's own (!). + cleanedPatterns := []string{} + patternDirs := [][]string{} + exceptions := false + for _, pattern := range patterns { + // Eliminate leading and trailing whitespace. + pattern = strings.TrimSpace(pattern) + if Empty(pattern) { + continue + } + if Exclusion(pattern) { + if len(pattern) == 1 { + logrus.Errorf("Illegal exclusion pattern: %s", pattern) + return nil, nil, false, errors.New("Illegal exclusion pattern: !") + } + exceptions = true + } + pattern = filepath.Clean(pattern) + cleanedPatterns = append(cleanedPatterns, pattern) + if Exclusion(pattern) { + pattern = pattern[1:] + } + patternDirs = append(patternDirs, strings.Split(pattern, "/")) + } + + return cleanedPatterns, patternDirs, exceptions, nil +} + +// Matches returns true if file matches any of the patterns +// and isn't excluded by any of the subsequent patterns. +func Matches(file string, patterns []string) (bool, error) { + file = filepath.Clean(file) + + if file == "." { + // Don't let them exclude everything, kind of silly. + return false, nil + } + + patterns, patDirs, _, err := CleanPatterns(patterns) + if err != nil { + return false, err + } + + return OptimizedMatches(file, patterns, patDirs) +} + +// Matches is basically the same as fileutils.Matches() but optimized for archive.go. +// It will assume that the inputs have been preprocessed and therefore the function +// doen't need to do as much error checking and clean-up. This was done to avoid +// repeating these steps on each file being checked during the archive process. +// The more generic fileutils.Matches() can't make these assumptions. +func OptimizedMatches(file string, patterns []string, patDirs [][]string) (bool, error) { + matched := false + parentPath := filepath.Dir(file) + parentPathDirs := strings.Split(parentPath, "/") + + for i, pattern := range patterns { + negative := false + + if Exclusion(pattern) { + negative = true + pattern = pattern[1:] + } + + match, err := filepath.Match(pattern, file) if err != nil { - logrus.Errorf("Error matching: %s (pattern: %s)", relFilePath, exclude) + logrus.Errorf("Error matching: %s (pattern: %s)", file, pattern) return false, err } - if matched { - if filepath.Clean(relFilePath) == "." { - logrus.Errorf("Can't exclude whole path, excluding pattern: %s", exclude) - continue + + if !match && parentPath != "." { + // Check to see if the pattern matches one of our parent dirs. + if len(patDirs[i]) <= len(parentPathDirs) { + match, _ = filepath.Match(strings.Join(patDirs[i], "/"), + strings.Join(parentPathDirs[:len(patDirs[i])], "/")) } - logrus.Debugf("Skipping excluded path: %s", relFilePath) - return true, nil + } + + if match { + matched = !negative } } - return false, nil + + if matched { + logrus.Debugf("Skipping excluded path: %s", file) + } + return matched, nil } func CopyFile(src, dst string) (int64, error) { diff --git a/pkg/fileutils/fileutils_test.go b/pkg/fileutils/fileutils_test.go index 16d00d7b9..ce19ffce4 100644 --- a/pkg/fileutils/fileutils_test.go +++ b/pkg/fileutils/fileutils_test.go @@ -79,3 +79,142 @@ func TestReadSymlinkedDirectoryToFile(t *testing.T) { t.Errorf("failed to remove symlink: %s", err) } } + +func TestWildcardMatches(t *testing.T) { + match, _ := Matches("fileutils.go", []string{"*"}) + if match != true { + t.Errorf("failed to get a wildcard match, got %v", match) + } +} + +// A simple pattern match should return true. +func TestPatternMatches(t *testing.T) { + match, _ := Matches("fileutils.go", []string{"*.go"}) + if match != true { + t.Errorf("failed to get a match, got %v", match) + } +} + +// An exclusion followed by an inclusion should return true. +func TestExclusionPatternMatchesPatternBefore(t *testing.T) { + match, _ := Matches("fileutils.go", []string{"!fileutils.go", "*.go"}) + if match != true { + t.Errorf("failed to get true match on exclusion pattern, got %v", match) + } +} + +// A folder pattern followed by an exception should return false. +func TestPatternMatchesFolderExclusions(t *testing.T) { + match, _ := Matches("docs/README.md", []string{"docs", "!docs/README.md"}) + if match != false { + t.Errorf("failed to get a false match on exclusion pattern, got %v", match) + } +} + +// A folder pattern followed by an exception should return false. +func TestPatternMatchesFolderWithSlashExclusions(t *testing.T) { + match, _ := Matches("docs/README.md", []string{"docs/", "!docs/README.md"}) + if match != false { + t.Errorf("failed to get a false match on exclusion pattern, got %v", match) + } +} + +// A folder pattern followed by an exception should return false. +func TestPatternMatchesFolderWildcardExclusions(t *testing.T) { + match, _ := Matches("docs/README.md", []string{"docs/*", "!docs/README.md"}) + if match != false { + t.Errorf("failed to get a false match on exclusion pattern, got %v", match) + } +} + +// A pattern followed by an exclusion should return false. +func TestExclusionPatternMatchesPatternAfter(t *testing.T) { + match, _ := Matches("fileutils.go", []string{"*.go", "!fileutils.go"}) + if match != false { + t.Errorf("failed to get false match on exclusion pattern, got %v", match) + } +} + +// A filename evaluating to . should return false. +func TestExclusionPatternMatchesWholeDirectory(t *testing.T) { + match, _ := Matches(".", []string{"*.go"}) + if match != false { + t.Errorf("failed to get false match on ., got %v", match) + } +} + +// A single ! pattern should return an error. +func TestSingleExclamationError(t *testing.T) { + _, err := Matches("fileutils.go", []string{"!"}) + if err == nil { + t.Errorf("failed to get an error for a single exclamation point, got %v", err) + } +} + +// A string preceded with a ! should return true from Exclusion. +func TestExclusion(t *testing.T) { + exclusion := Exclusion("!") + if !exclusion { + t.Errorf("failed to get true for a single !, got %v", exclusion) + } +} + +// An empty string should return true from Empty. +func TestEmpty(t *testing.T) { + empty := Empty("") + if !empty { + t.Errorf("failed to get true for an empty string, got %v", empty) + } +} + +func TestCleanPatterns(t *testing.T) { + cleaned, _, _, _ := CleanPatterns([]string{"docs", "config"}) + if len(cleaned) != 2 { + t.Errorf("expected 2 element slice, got %v", len(cleaned)) + } +} + +func TestCleanPatternsStripEmptyPatterns(t *testing.T) { + cleaned, _, _, _ := CleanPatterns([]string{"docs", "config", ""}) + if len(cleaned) != 2 { + t.Errorf("expected 2 element slice, got %v", len(cleaned)) + } +} + +func TestCleanPatternsExceptionFlag(t *testing.T) { + _, _, exceptions, _ := CleanPatterns([]string{"docs", "!docs/README.md"}) + if !exceptions { + t.Errorf("expected exceptions to be true, got %v", exceptions) + } +} + +func TestCleanPatternsLeadingSpaceTrimmed(t *testing.T) { + _, _, exceptions, _ := CleanPatterns([]string{"docs", " !docs/README.md"}) + if !exceptions { + t.Errorf("expected exceptions to be true, got %v", exceptions) + } +} + +func TestCleanPatternsTrailingSpaceTrimmed(t *testing.T) { + _, _, exceptions, _ := CleanPatterns([]string{"docs", "!docs/README.md "}) + if !exceptions { + t.Errorf("expected exceptions to be true, got %v", exceptions) + } +} + +func TestCleanPatternsErrorSingleException(t *testing.T) { + _, _, _, err := CleanPatterns([]string{"!"}) + if err == nil { + t.Errorf("expected error on single exclamation point, got %v", err) + } +} + +func TestCleanPatternsFolderSplit(t *testing.T) { + _, dirs, _, _ := CleanPatterns([]string{"docs/config/CONFIG.md"}) + if dirs[0][0] != "docs" { + t.Errorf("expected first element in dirs slice to be docs, got %v", dirs[0][1]) + } + if dirs[0][1] != "config" { + t.Errorf("expected first element in dirs slice to be config, got %v", dirs[0][1]) + } +} From 0e752adf550ef4891e40889ea92e12ec3d775a00 Mon Sep 17 00:00:00 2001 From: Lei Jitang Date: Wed, 29 Apr 2015 19:37:20 +0800 Subject: [PATCH 56/58] Fix docker rename help not consistent with other commands Signed-off-by: Lei Jitang --- api/client/rename.go | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/api/client/rename.go b/api/client/rename.go index 278f471f2..ebe16963d 100644 --- a/api/client/rename.go +++ b/api/client/rename.go @@ -1,20 +1,19 @@ package client -import "fmt" +import ( + "fmt" + + flag "github.com/docker/docker/pkg/mflag" +) // CmdRename renames a container. // // Usage: docker rename OLD_NAME NEW_NAME func (cli *DockerCli) CmdRename(args ...string) error { cmd := cli.Subcmd("rename", "OLD_NAME NEW_NAME", "Rename a container", true) - if err := cmd.Parse(args); err != nil { - return nil - } + cmd.Require(flag.Exact, 2) + cmd.ParseFlags(args, true) - if cmd.NArg() != 2 { - cmd.Usage() - return nil - } oldName := cmd.Arg(0) newName := cmd.Arg(1) From 8454e1a3b24e2e076bb08a2a6b1fcb56efe2924e Mon Sep 17 00:00:00 2001 From: Vincent Demeester Date: Wed, 29 Apr 2015 16:27:12 +0200 Subject: [PATCH 57/58] Add coverage on pkg/fileutils Should fix #11598 Signed-off-by: Vincent Demeester --- pkg/fileutils/fileutils.go | 10 ++- pkg/fileutils/fileutils_test.go | 137 ++++++++++++++++++++++++++++++++ 2 files changed, 143 insertions(+), 4 deletions(-) diff --git a/pkg/fileutils/fileutils.go b/pkg/fileutils/fileutils.go index d1e130d0a..fdafb53c7 100644 --- a/pkg/fileutils/fileutils.go +++ b/pkg/fileutils/fileutils.go @@ -118,18 +118,20 @@ func OptimizedMatches(file string, patterns []string, patDirs [][]string) (bool, } func CopyFile(src, dst string) (int64, error) { - if src == dst { + cleanSrc := filepath.Clean(src) + cleanDst := filepath.Clean(dst) + if cleanSrc == cleanDst { return 0, nil } - sf, err := os.Open(src) + sf, err := os.Open(cleanSrc) if err != nil { return 0, err } defer sf.Close() - if err := os.Remove(dst); err != nil && !os.IsNotExist(err) { + if err := os.Remove(cleanDst); err != nil && !os.IsNotExist(err) { return 0, err } - df, err := os.Create(dst) + df, err := os.Create(cleanDst) if err != nil { return 0, err } diff --git a/pkg/fileutils/fileutils_test.go b/pkg/fileutils/fileutils_test.go index ce19ffce4..ef931684c 100644 --- a/pkg/fileutils/fileutils_test.go +++ b/pkg/fileutils/fileutils_test.go @@ -1,10 +1,125 @@ package fileutils import ( + "io/ioutil" "os" + "path" "testing" ) +// CopyFile with invalid src +func TestCopyFileWithInvalidSrc(t *testing.T) { + tempFolder, err := ioutil.TempDir("", "docker-fileutils-test") + defer os.RemoveAll(tempFolder) + if err != nil { + t.Fatal(err) + } + bytes, err := CopyFile("/invalid/file/path", path.Join(tempFolder, "dest")) + if err == nil { + t.Fatal("Should have fail to copy an invalid src file") + } + if bytes != 0 { + t.Fatal("Should have written 0 bytes") + } + +} + +// CopyFile with invalid dest +func TestCopyFileWithInvalidDest(t *testing.T) { + tempFolder, err := ioutil.TempDir("", "docker-fileutils-test") + defer os.RemoveAll(tempFolder) + if err != nil { + t.Fatal(err) + } + src := path.Join(tempFolder, "file") + err = ioutil.WriteFile(src, []byte("content"), 0740) + if err != nil { + t.Fatal(err) + } + bytes, err := CopyFile(src, path.Join(tempFolder, "/invalid/dest/path")) + if err == nil { + t.Fatal("Should have fail to copy an invalid src file") + } + if bytes != 0 { + t.Fatal("Should have written 0 bytes") + } + +} + +// CopyFile with same src and dest +func TestCopyFileWithSameSrcAndDest(t *testing.T) { + tempFolder, err := ioutil.TempDir("", "docker-fileutils-test") + defer os.RemoveAll(tempFolder) + if err != nil { + t.Fatal(err) + } + file := path.Join(tempFolder, "file") + err = ioutil.WriteFile(file, []byte("content"), 0740) + if err != nil { + t.Fatal(err) + } + bytes, err := CopyFile(file, file) + if err != nil { + t.Fatal(err) + } + if bytes != 0 { + t.Fatal("Should have written 0 bytes as it is the same file.") + } +} + +// CopyFile with same src and dest but path is different and not clean +func TestCopyFileWithSameSrcAndDestWithPathNameDifferent(t *testing.T) { + tempFolder, err := ioutil.TempDir("", "docker-fileutils-test") + defer os.RemoveAll(tempFolder) + if err != nil { + t.Fatal(err) + } + testFolder := path.Join(tempFolder, "test") + err = os.MkdirAll(testFolder, 0740) + if err != nil { + t.Fatal(err) + } + file := path.Join(testFolder, "file") + sameFile := testFolder + "/../test/file" + err = ioutil.WriteFile(file, []byte("content"), 0740) + if err != nil { + t.Fatal(err) + } + bytes, err := CopyFile(file, sameFile) + if err != nil { + t.Fatal(err) + } + if bytes != 0 { + t.Fatal("Should have written 0 bytes as it is the same file.") + } +} + +func TestCopyFile(t *testing.T) { + tempFolder, err := ioutil.TempDir("", "docker-fileutils-test") + defer os.RemoveAll(tempFolder) + if err != nil { + t.Fatal(err) + } + src := path.Join(tempFolder, "src") + dest := path.Join(tempFolder, "dest") + ioutil.WriteFile(src, []byte("content"), 0777) + ioutil.WriteFile(dest, []byte("destContent"), 0777) + bytes, err := CopyFile(src, dest) + if err != nil { + t.Fatal(err) + } + if bytes != 7 { + t.Fatalf("Should have written %d bytes but wrote %d", 7, bytes) + } + actual, err := ioutil.ReadFile(dest) + if err != nil { + t.Fatal(err) + } + if string(actual) != "content" { + t.Fatalf("Dest content was '%s', expected '%s'", string(actual), "content") + } +} + // Reading a symlink to a directory must return the directory func TestReadSymlinkedDirectoryExistingDirectory(t *testing.T) { var err error @@ -159,6 +274,28 @@ func TestExclusion(t *testing.T) { } } +// Matches with no patterns +func TestMatchesWithNoPatterns(t *testing.T) { + matches, err := Matches("/any/path/there", []string{}) + if err != nil { + t.Fatal(err) + } + if matches { + t.Fatalf("Should not have match anything") + } +} + +// Matches with malformed patterns +func TestMatchesWithMalformedPatterns(t *testing.T) { + matches, err := Matches("/any/path/there", []string{"["}) + if err == nil { + t.Fatal("Should have failed because of a malformed syntax in the pattern") + } + if matches { + t.Fatalf("Should not have match anything") + } +} + // An empty string should return true from Empty. func TestEmpty(t *testing.T) { empty := Empty("") From 4203230cbbf46238e38099c9073bdcad5f69a63f Mon Sep 17 00:00:00 2001 From: Antonio Murdaca Date: Mon, 27 Apr 2015 19:29:48 +0200 Subject: [PATCH 58/58] c.Fatal won't fail and exit test inside a goroutine, errors should be handled outside with a channel Signed-off-by: Antonio Murdaca --- integration-cli/docker_api_containers_test.go | 15 ++-- integration-cli/docker_cli_attach_test.go | 17 +++-- .../docker_cli_attach_unix_test.go | 33 +++++---- integration-cli/docker_cli_build_test.go | 71 +++++++------------ integration-cli/docker_cli_events_test.go | 39 ++++------ integration-cli/docker_cli_exec_test.go | 53 +++++++++----- integration-cli/docker_cli_logs_test.go | 23 +++--- integration-cli/docker_cli_ps_test.go | 1 - integration-cli/docker_cli_run_test.go | 55 +++++++------- integration-cli/docker_cli_run_unix_test.go | 11 +-- integration-cli/docker_cli_start_test.go | 7 +- 11 files changed, 156 insertions(+), 169 deletions(-) diff --git a/integration-cli/docker_api_containers_test.go b/integration-cli/docker_api_containers_test.go index 6cf2f9975..1fec3912e 100644 --- a/integration-cli/docker_api_containers_test.go +++ b/integration-cli/docker_api_containers_test.go @@ -260,15 +260,14 @@ func (s *DockerSuite) TestGetContainerStats(c *check.C) { c.Fatalf("Error on container creation: %v, output: %q", err, out) } type b struct { - body []byte - err error + status int + body []byte + err error } bc := make(chan b, 1) go func() { status, body, err := sockRequest("GET", "/containers/"+name+"/stats", nil) - c.Assert(status, check.Equals, http.StatusOK) - c.Assert(err, check.IsNil) - bc <- b{body, err} + bc <- b{status, body, err} }() // allow some time to stream the stats from the container @@ -283,9 +282,8 @@ func (s *DockerSuite) TestGetContainerStats(c *check.C) { case <-time.After(2 * time.Second): c.Fatal("stream was not closed after container was removed") case sr := <-bc: - if sr.err != nil { - c.Fatal(sr.err) - } + c.Assert(sr.err, check.IsNil) + c.Assert(sr.status, check.Equals, http.StatusOK) dec := json.NewDecoder(bytes.NewBuffer(sr.body)) var s *types.Stats @@ -297,6 +295,7 @@ func (s *DockerSuite) TestGetContainerStats(c *check.C) { } func (s *DockerSuite) TestGetStoppedContainerStats(c *check.C) { + // TODO: this test does nothing because we are c.Assert'ing in goroutine var ( name = "statscontainer" runCmd = exec.Command(dockerBinary, "create", "--name", name, "busybox", "top") diff --git a/integration-cli/docker_cli_attach_test.go b/integration-cli/docker_cli_attach_test.go index 4dd45ddff..fc2ea1a1d 100644 --- a/integration-cli/docker_cli_attach_test.go +++ b/integration-cli/docker_cli_attach_test.go @@ -2,6 +2,7 @@ package main import ( "bufio" + "fmt" "io" "os/exec" "strings" @@ -89,7 +90,6 @@ func (s *DockerSuite) TestAttachMultipleAndRestart(c *check.C) { } func (s *DockerSuite) TestAttachTtyWithoutStdin(c *check.C) { - cmd := exec.Command(dockerBinary, "run", "-d", "-ti", "busybox") out, _, err := runCommandWithOutput(cmd) if err != nil { @@ -108,29 +108,32 @@ func (s *DockerSuite) TestAttachTtyWithoutStdin(c *check.C) { } }() - done := make(chan struct{}) + done := make(chan error) go func() { defer close(done) cmd := exec.Command(dockerBinary, "attach", id) if _, err := cmd.StdinPipe(); err != nil { - c.Fatal(err) + done <- err + return } expected := "cannot enable tty mode" if out, _, err := runCommandWithOutput(cmd); err == nil { - c.Fatal("attach should have failed") + done <- fmt.Errorf("attach should have failed") + return } else if !strings.Contains(out, expected) { - c.Fatalf("attach failed with error %q: expected %q", out, expected) + done <- fmt.Errorf("attach failed with error %q: expected %q", out, expected) + return } }() select { - case <-done: + case err := <-done: + c.Assert(err, check.IsNil) case <-time.After(attachWait): c.Fatal("attach is running but should have failed") } - } func (s *DockerSuite) TestAttachDisconnect(c *check.C) { diff --git a/integration-cli/docker_cli_attach_unix_test.go b/integration-cli/docker_cli_attach_unix_test.go index bae83d994..82808a5b0 100644 --- a/integration-cli/docker_cli_attach_unix_test.go +++ b/integration-cli/docker_cli_attach_unix_test.go @@ -27,14 +27,14 @@ func (s *DockerSuite) TestAttachClosedOnContainerStop(c *check.C) { c.Fatal(err) } - done := make(chan struct{}) - + errChan := make(chan error) go func() { - defer close(done) + defer close(errChan) _, tty, err := pty.Open() if err != nil { - c.Fatalf("could not open pty: %v", err) + errChan <- err + return } attachCmd := exec.Command(dockerBinary, "attach", id) attachCmd.Stdin = tty @@ -42,7 +42,8 @@ func (s *DockerSuite) TestAttachClosedOnContainerStop(c *check.C) { attachCmd.Stderr = tty if err := attachCmd.Run(); err != nil { - c.Fatalf("attach returned error %s", err) + errChan <- err + return } }() @@ -51,7 +52,8 @@ func (s *DockerSuite) TestAttachClosedOnContainerStop(c *check.C) { c.Fatalf("error thrown while waiting for container: %s, %v", out, err) } select { - case <-done: + case err := <-errChan: + c.Assert(err, check.IsNil) case <-time.After(attachWait): c.Fatal("timed out without attach returning") } @@ -71,12 +73,10 @@ func (s *DockerSuite) TestAttachAfterDetach(c *check.C) { cmd.Stdout = tty cmd.Stderr = tty - detached := make(chan struct{}) + errChan := make(chan error) go func() { - if err := cmd.Run(); err != nil { - c.Fatalf("attach returned error %s", err) - } - close(detached) + errChan <- cmd.Run() + close(errChan) }() time.Sleep(500 * time.Millisecond) @@ -87,7 +87,12 @@ func (s *DockerSuite) TestAttachAfterDetach(c *check.C) { time.Sleep(100 * time.Millisecond) cpty.Write([]byte{17}) - <-detached + select { + case err := <-errChan: + c.Assert(err, check.IsNil) + case <-time.After(5 * time.Second): + c.Fatal("timeout while detaching") + } cpty, tty, err = pty.Open() if err != nil { @@ -119,9 +124,7 @@ func (s *DockerSuite) TestAttachAfterDetach(c *check.C) { select { case err := <-readErr: - if err != nil { - c.Fatal(err) - } + c.Assert(err, check.IsNil) case <-time.After(2 * time.Second): c.Fatal("timeout waiting for attach read") } diff --git a/integration-cli/docker_cli_build_test.go b/integration-cli/docker_cli_build_test.go index 334342783..b74dce2cf 100644 --- a/integration-cli/docker_cli_build_test.go +++ b/integration-cli/docker_cli_build_test.go @@ -15,7 +15,6 @@ import ( "runtime" "strconv" "strings" - "sync" "text/template" "time" @@ -764,17 +763,17 @@ ADD test_file .`, } defer ctx.Close() - done := make(chan struct{}) + errChan := make(chan error) go func() { - if _, err := buildImageFromContext(name, ctx, true); err != nil { - c.Fatal(err) - } - close(done) + _, err := buildImageFromContext(name, ctx, true) + errChan <- err + close(errChan) }() select { case <-time.After(5 * time.Second): c.Fatal("Build with adding to workdir timed out") - case <-done: + case err := <-errChan: + c.Assert(err, check.IsNil) } } @@ -1365,17 +1364,17 @@ COPY test_file .`, } defer ctx.Close() - done := make(chan struct{}) + errChan := make(chan error) go func() { - if _, err := buildImageFromContext(name, ctx, true); err != nil { - c.Fatal(err) - } - close(done) + _, err := buildImageFromContext(name, ctx, true) + errChan <- err + close(errChan) }() select { case <-time.After(5 * time.Second): c.Fatal("Build with adding to workdir timed out") - case <-done: + case err := <-errChan: + c.Assert(err, check.IsNil) } } @@ -1829,9 +1828,6 @@ func (s *DockerSuite) TestBuildForceRm(c *check.C) { // * When docker events sees container start, close the "docker build" command // * Wait for docker events to emit a dying event. func (s *DockerSuite) TestBuildCancelationKillsSleep(c *check.C) { - var wg sync.WaitGroup - defer wg.Wait() - name := "testbuildcancelation" // (Note: one year, will never finish) @@ -1849,26 +1845,21 @@ func (s *DockerSuite) TestBuildCancelationKillsSleep(c *check.C) { containerID := make(chan string) startEpoch := daemonTime(c).Unix() + // Watch for events since epoch. + eventsCmd := exec.Command( + dockerBinary, "events", + "--since", strconv.FormatInt(startEpoch, 10)) + stdout, err := eventsCmd.StdoutPipe() + if err != nil { + c.Fatal(err) + } + if err := eventsCmd.Start(); err != nil { + c.Fatal(err) + } + defer eventsCmd.Process.Kill() - wg.Add(1) // Goroutine responsible for watching start/die events from `docker events` go func() { - defer wg.Done() - // Watch for events since epoch. - eventsCmd := exec.Command( - dockerBinary, "events", - "--since", strconv.FormatInt(startEpoch, 10)) - stdout, err := eventsCmd.StdoutPipe() - err = eventsCmd.Start() - if err != nil { - c.Fatalf("failed to start 'docker events': %s", err) - } - - go func() { - <-finish - eventsCmd.Process.Kill() - }() - cid := <-containerID matchStart := regexp.MustCompile(cid + `(.*) start$`) @@ -1886,19 +1877,13 @@ func (s *DockerSuite) TestBuildCancelationKillsSleep(c *check.C) { close(eventDie) } } - - err = eventsCmd.Wait() - if err != nil && !IsKilled(err) { - c.Fatalf("docker events had bad exit status: %s", err) - } }() buildCmd := exec.Command(dockerBinary, "build", "-t", name, ".") buildCmd.Dir = ctx.Dir stdoutBuild, err := buildCmd.StdoutPipe() - err = buildCmd.Start() - if err != nil { + if err := buildCmd.Start(); err != nil { c.Fatalf("failed to run build: %s", err) } @@ -1923,14 +1908,12 @@ func (s *DockerSuite) TestBuildCancelationKillsSleep(c *check.C) { // Send a kill to the `docker build` command. // Causes the underlying build to be cancelled due to socket close. - err = buildCmd.Process.Kill() - if err != nil { + if err := buildCmd.Process.Kill(); err != nil { c.Fatalf("error killing build command: %s", err) } // Get the exit status of `docker build`, check it exited because killed. - err = buildCmd.Wait() - if err != nil && !IsKilled(err) { + if err := buildCmd.Wait(); err != nil && !IsKilled(err) { c.Fatalf("wait failed during build run: %T %s", err, err) } diff --git a/integration-cli/docker_cli_events_test.go b/integration-cli/docker_cli_events_test.go index b1cc26b9a..80cc0c69d 100644 --- a/integration-cli/docker_cli_events_test.go +++ b/integration-cli/docker_cli_events_test.go @@ -75,8 +75,7 @@ func (s *DockerSuite) TestEventsLimit(c *check.C) { waitGroup.Add(1) go func() { defer waitGroup.Done() - err := exec.Command(dockerBinary, args...).Run() - errChan <- err + errChan <- exec.Command(dockerBinary, args...).Run() }() } @@ -229,8 +228,7 @@ func (s *DockerSuite) TestEventsImageImport(c *check.C) { if err != nil { c.Fatal(err) } - err = eventsCmd.Start() - if err != nil { + if err := eventsCmd.Start(); err != nil { c.Fatal(err) } defer eventsCmd.Process.Kill() @@ -424,30 +422,23 @@ func (s *DockerSuite) TestEventsFilterContainer(c *check.C) { func (s *DockerSuite) TestEventsStreaming(c *check.C) { start := daemonTime(c).Unix() - finish := make(chan struct{}) - defer close(finish) id := make(chan string) eventCreate := make(chan struct{}) eventStart := make(chan struct{}) eventDie := make(chan struct{}) eventDestroy := make(chan struct{}) + eventsCmd := exec.Command(dockerBinary, "events", "--since", strconv.FormatInt(start, 10)) + stdout, err := eventsCmd.StdoutPipe() + if err != nil { + c.Fatal(err) + } + if err := eventsCmd.Start(); err != nil { + c.Fatalf("failed to start 'docker events': %s", err) + } + defer eventsCmd.Process.Kill() + go func() { - eventsCmd := exec.Command(dockerBinary, "events", "--since", strconv.FormatInt(start, 10)) - stdout, err := eventsCmd.StdoutPipe() - if err != nil { - c.Fatal(err) - } - err = eventsCmd.Start() - if err != nil { - c.Fatalf("failed to start 'docker events': %s", err) - } - - go func() { - <-finish - eventsCmd.Process.Kill() - }() - containerID := <-id matchCreate := regexp.MustCompile(containerID + `: \(from busybox:latest\) create$`) @@ -468,11 +459,6 @@ func (s *DockerSuite) TestEventsStreaming(c *check.C) { close(eventDestroy) } } - - err = eventsCmd.Wait() - if err != nil && !IsKilled(err) { - c.Fatalf("docker events had bad exit status: %s", err) - } }() runCmd := exec.Command(dockerBinary, "run", "-d", "busybox:latest", "true") @@ -516,5 +502,4 @@ func (s *DockerSuite) TestEventsStreaming(c *check.C) { case <-eventDestroy: // ignore, done } - } diff --git a/integration-cli/docker_cli_exec_test.go b/integration-cli/docker_cli_exec_test.go index cbdd59756..4b36d7b53 100644 --- a/integration-cli/docker_cli_exec_test.go +++ b/integration-cli/docker_cli_exec_test.go @@ -74,15 +74,14 @@ func (s *DockerSuite) TestExecInteractive(c *check.C) { if err := stdin.Close(); err != nil { c.Fatal(err) } - finish := make(chan struct{}) + errChan := make(chan error) go func() { - if err := execCmd.Wait(); err != nil { - c.Fatal(err) - } - close(finish) + errChan <- execCmd.Wait() + close(errChan) }() select { - case <-finish: + case err := <-errChan: + c.Assert(err, check.IsNil) case <-time.After(1 * time.Second): c.Fatal("docker exec failed to exit on stdin close") } @@ -278,25 +277,29 @@ func (s *DockerSuite) TestExecTtyWithoutStdin(c *check.C) { } }() - done := make(chan struct{}) + errChan := make(chan error) go func() { - defer close(done) + defer close(errChan) cmd := exec.Command(dockerBinary, "exec", "-ti", id, "true") if _, err := cmd.StdinPipe(); err != nil { - c.Fatal(err) + errChan <- err + return } expected := "cannot enable tty mode" if out, _, err := runCommandWithOutput(cmd); err == nil { - c.Fatal("exec should have failed") + errChan <- fmt.Errorf("exec should have failed") + return } else if !strings.Contains(out, expected) { - c.Fatalf("exec failed with error %q: expected %q", out, expected) + errChan <- fmt.Errorf("exec failed with error %q: expected %q", out, expected) + return } }() select { - case <-done: + case err := <-errChan: + c.Assert(err, check.IsNil) case <-time.After(3 * time.Second): c.Fatal("exec is running but should have failed") } @@ -326,17 +329,22 @@ func (s *DockerSuite) TestExecStopNotHanging(c *check.C) { c.Fatal(err) } - wait := make(chan struct{}) + type dstop struct { + out []byte + err error + } + + ch := make(chan dstop) go func() { - if out, err := exec.Command(dockerBinary, "stop", "testing").CombinedOutput(); err != nil { - c.Fatal(out, err) - } - close(wait) + out, err := exec.Command(dockerBinary, "stop", "testing").CombinedOutput() + ch <- dstop{out, err} + close(ch) }() select { case <-time.After(3 * time.Second): c.Fatal("Container stop timed out") - case <-wait: + case s := <-ch: + c.Assert(s.err, check.IsNil) } } @@ -359,6 +367,7 @@ func (s *DockerSuite) TestExecCgroup(c *check.C) { var wg sync.WaitGroup var mu sync.Mutex execCgroups := []sort.StringSlice{} + errChan := make(chan error) // exec a few times concurrently to get consistent failure for i := 0; i < 5; i++ { wg.Add(1) @@ -366,7 +375,8 @@ func (s *DockerSuite) TestExecCgroup(c *check.C) { cmd := exec.Command(dockerBinary, "exec", "testing", "cat", "/proc/self/cgroup") out, _, err := runCommandWithOutput(cmd) if err != nil { - c.Fatal(out, err) + errChan <- err + return } cg := sort.StringSlice(strings.Split(string(out), "\n")) @@ -377,6 +387,11 @@ func (s *DockerSuite) TestExecCgroup(c *check.C) { }() } wg.Wait() + close(errChan) + + for err := range errChan { + c.Assert(err, check.IsNil) + } for _, cg := range execCgroups { if !reflect.DeepEqual(cg, containerCgroups) { diff --git a/integration-cli/docker_cli_logs_test.go b/integration-cli/docker_cli_logs_test.go index a7c891622..0a3e1af98 100644 --- a/integration-cli/docker_cli_logs_test.go +++ b/integration-cli/docker_cli_logs_test.go @@ -260,16 +260,15 @@ func (s *DockerSuite) TestLogsFollowStopped(c *check.C) { c.Fatal(err) } - ch := make(chan struct{}) + errChan := make(chan error) go func() { - if err := logsCmd.Wait(); err != nil { - c.Fatal(err) - } - close(ch) + errChan <- logsCmd.Wait() + close(errChan) }() select { - case <-ch: + case err := <-errChan: + c.Assert(err, check.IsNil) case <-time.After(1 * time.Second): c.Fatal("Following logs is hanged") } @@ -298,9 +297,7 @@ func (s *DockerSuite) TestLogsFollowSlowStdoutConsumer(c *check.C) { logCmd := exec.Command(dockerBinary, "logs", "-f", cleanedContainerID) stdout, err := logCmd.StdoutPipe() - if err != nil { - c.Fatal(err) - } + c.Assert(err, check.IsNil) if err := logCmd.Start(); err != nil { c.Fatal(err) @@ -308,15 +305,11 @@ func (s *DockerSuite) TestLogsFollowSlowStdoutConsumer(c *check.C) { // First read slowly bytes1, err := consumeWithSpeed(stdout, 10, 50*time.Millisecond, stopSlowRead) - if err != nil { - c.Fatal(err) - } + c.Assert(err, check.IsNil) // After the container has finished we can continue reading fast bytes2, err := consumeWithSpeed(stdout, 32*1024, 0, nil) - if err != nil { - c.Fatal(err) - } + c.Assert(err, check.IsNil) actual := bytes1 + bytes2 expected := 200000 diff --git a/integration-cli/docker_cli_ps_test.go b/integration-cli/docker_cli_ps_test.go index 271051815..bb34575fb 100644 --- a/integration-cli/docker_cli_ps_test.go +++ b/integration-cli/docker_cli_ps_test.go @@ -255,7 +255,6 @@ func assertContainerList(out string, expected []string) bool { } func (s *DockerSuite) TestPsListContainersSize(c *check.C) { - cmd := exec.Command(dockerBinary, "run", "-d", "busybox", "echo", "hello") runCommandWithOutput(cmd) cmd = exec.Command(dockerBinary, "ps", "-s", "-n=1") diff --git a/integration-cli/docker_cli_run_test.go b/integration-cli/docker_cli_run_test.go index c3b25558d..0cf5c31ee 100644 --- a/integration-cli/docker_cli_run_test.go +++ b/integration-cli/docker_cli_run_test.go @@ -756,17 +756,22 @@ func (s *DockerSuite) TestRunTwoConcurrentContainers(c *check.C) { group := sync.WaitGroup{} group.Add(2) + errChan := make(chan error, 2) for i := 0; i < 2; i++ { go func() { defer group.Done() cmd := exec.Command(dockerBinary, "run", "busybox", "sleep", "2") - if _, err := runCommand(cmd); err != nil { - c.Fatal(err) - } + _, err := runCommand(cmd) + errChan <- err }() } group.Wait() + close(errChan) + + for err := range errChan { + c.Assert(err, check.IsNil) + } } func (s *DockerSuite) TestRunEnvironment(c *check.C) { @@ -1851,22 +1856,20 @@ func (s *DockerSuite) TestRunExitOnStdinClose(c *check.C) { if err := stdin.Close(); err != nil { c.Fatal(err) } - finish := make(chan struct{}) + finish := make(chan error) go func() { - if err := runCmd.Wait(); err != nil { - c.Fatal(err) - } + finish <- runCmd.Wait() close(finish) }() select { - case <-finish: + case err := <-finish: + c.Assert(err, check.IsNil) case <-time.After(1 * time.Second): c.Fatal("docker run failed to exit on stdin close") } state, err := inspectField(name, "State.Running") - if err != nil { - c.Fatal(err) - } + c.Assert(err, check.IsNil) + if state != "false" { c.Fatal("Container must be stopped after stdin closing") } @@ -2762,25 +2765,29 @@ func (s *DockerSuite) TestRunPortFromDockerRangeInUse(c *check.C) { } func (s *DockerSuite) TestRunTtyWithPipe(c *check.C) { - done := make(chan struct{}) + errChan := make(chan error) go func() { - defer close(done) + defer close(errChan) cmd := exec.Command(dockerBinary, "run", "-ti", "busybox", "true") if _, err := cmd.StdinPipe(); err != nil { - c.Fatal(err) + errChan <- err + return } expected := "cannot enable tty mode" if out, _, err := runCommandWithOutput(cmd); err == nil { - c.Fatal("run should have failed") + errChan <- fmt.Errorf("run should have failed") + return } else if !strings.Contains(out, expected) { - c.Fatalf("run failed with error %q: expected %q", out, expected) + errChan <- fmt.Errorf("run failed with error %q: expected %q", out, expected) + return } }() select { - case <-done: + case err := <-errChan: + c.Assert(err, check.IsNil) case <-time.After(3 * time.Second): c.Fatal("container is running but should have failed") } @@ -2875,19 +2882,19 @@ func (s *DockerSuite) TestRunAllowPortRangeThroughPublish(c *check.C) { } func (s *DockerSuite) TestRunOOMExitCode(c *check.C) { - done := make(chan struct{}) + errChan := make(chan error) go func() { - defer close(done) - + defer close(errChan) runCmd := exec.Command(dockerBinary, "run", "-m", "4MB", "busybox", "sh", "-c", "x=a; while true; do x=$x$x$x$x; done") out, exitCode, _ := runCommandWithOutput(runCmd) if expected := 137; exitCode != expected { - c.Fatalf("wrong exit code for OOM container: expected %d, got %d (output: %q)", expected, exitCode, out) + errChan <- fmt.Errorf("wrong exit code for OOM container: expected %d, got %d (output: %q)", expected, exitCode, out) } }() select { - case <-done: + case err := <-errChan: + c.Assert(err, check.IsNil) case <-time.After(30 * time.Second): c.Fatal("Timeout waiting for container to die on OOM") } @@ -3030,9 +3037,7 @@ func (s *DockerSuite) TestRunPidHostWithChildIsKillable(c *check.C) { }() select { case err := <-errchan: - if err != nil { - c.Fatal(err) - } + c.Assert(err, check.IsNil) case <-time.After(5 * time.Second): c.Fatal("Kill container timed out") } diff --git a/integration-cli/docker_cli_run_unix_test.go b/integration-cli/docker_cli_run_unix_test.go index 43fa82150..59b623162 100644 --- a/integration-cli/docker_cli_run_unix_test.go +++ b/integration-cli/docker_cli_run_unix_test.go @@ -29,21 +29,22 @@ func (s *DockerSuite) TestRunRedirectStdout(c *check.C) { cmd.Stdin = tty cmd.Stdout = tty cmd.Stderr = tty - ch := make(chan struct{}) if err := cmd.Start(); err != nil { c.Fatalf("start err: %v", err) } + ch := make(chan error) go func() { - if err := cmd.Wait(); err != nil { - c.Fatalf("wait err=%v", err) - } + ch <- cmd.Wait() close(ch) }() select { case <-time.After(10 * time.Second): c.Fatal("command timeout") - case <-ch: + case err := <-ch: + if err != nil { + c.Fatalf("wait err=%v", err) + } } } diff --git a/integration-cli/docker_cli_start_test.go b/integration-cli/docker_cli_start_test.go index 13ecedd57..fddc8c97b 100644 --- a/integration-cli/docker_cli_start_test.go +++ b/integration-cli/docker_cli_start_test.go @@ -20,18 +20,19 @@ func (s *DockerSuite) TestStartAttachReturnsOnError(c *check.C) { c.Fatal("Expected error but got none") } - ch := make(chan struct{}) + ch := make(chan error) go func() { // Attempt to start attached to the container that won't start // This should return an error immediately since the container can't be started if _, err := runCommand(exec.Command(dockerBinary, "start", "-a", "test2")); err == nil { - c.Fatal("Expected error but got none") + ch <- fmt.Errorf("Expected error but got none") } close(ch) }() select { - case <-ch: + case err := <-ch: + c.Assert(err, check.IsNil) case <-time.After(time.Second): c.Fatalf("Attach did not exit properly") }

tp3@! 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⪯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
7i@!(6dY;9m^s$c!uGTQy%^FYud$zDQM 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
dPu1mzW>&42AO9WM2>O7A=FYBr(B;XH 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 literal 0 HcmV?d00001 diff --git a/docs/sources/project/images/windows-mingw.png b/docs/sources/project/images/windows-mingw.png new file mode 100644 index 0000000000000000000000000000000000000000..09f53ba9ebf11ad1ef9790b5a5752b2480f3de7d GIT binary patch literal 230524 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