From c07ca04b62c45409fd4e4d66eeeae39b7f0e381e Mon Sep 17 00:00:00 2001 From: unclejack Date: Sat, 20 Jul 2013 13:47:13 +0300 Subject: [PATCH 01/55] make docker run handle SIGINT/SIGTERM Upstream-commit: df86cb9a5c949530336b43100b303876f07c69ba Component: engine --- components/engine/commands.go | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/components/engine/commands.go b/components/engine/commands.go index f0e1695b3f..db8a126696 100644 --- a/components/engine/commands.go +++ b/components/engine/commands.go @@ -1393,6 +1393,21 @@ func (cli *DockerCli) CmdRun(args ...string) error { v.Set("stderr", "1") } + signals := make(chan os.Signal, 1) + signal.Notify(signals, syscall.SIGINT, syscall.SIGTERM) + go func() { + for { + sig := <-signals + if sig == syscall.SIGINT || sig == syscall.SIGTERM { + fmt.Printf("\nReceived signal: %s; cleaning up\n", sig) + if err := cli.CmdStop("-t", "4", runResult.ID); err != nil { + fmt.Printf("failed to stop container:", err) + } + return + } + } + }() + if err := cli.hijack("POST", "/containers/"+runResult.ID+"/attach?"+v.Encode(), config.Tty, cli.in, cli.out); err != nil { utils.Debugf("Error hijack: %s", err) return err From 86120a1f50180e5c42a09484dc57451419025f9e Mon Sep 17 00:00:00 2001 From: David Calavera Date: Sat, 3 Aug 2013 15:33:51 -0700 Subject: [PATCH 02/55] Sort APIImages by most recent creation date. Fixes #985. Upstream-commit: cd6aeaf97912a0c18994c978a4b58678e671d9ee Component: engine --- components/engine/server.go | 2 ++ components/engine/sorter.go | 36 ++++++++++++++++++++++++++++++++ components/engine/sorter_test.go | 30 ++++++++++++++++++++++++++ 3 files changed, 68 insertions(+) create mode 100644 components/engine/sorter.go create mode 100644 components/engine/sorter_test.go diff --git a/components/engine/server.go b/components/engine/server.go index cb7b2cf1be..5e30dd0118 100644 --- a/components/engine/server.go +++ b/components/engine/server.go @@ -241,6 +241,8 @@ func (srv *Server) Images(all bool, filter string) ([]APIImages, error) { outs = append(outs, out) } } + + sortImagesByCreation(outs) return outs, nil } diff --git a/components/engine/sorter.go b/components/engine/sorter.go new file mode 100644 index 0000000000..a61be0ef75 --- /dev/null +++ b/components/engine/sorter.go @@ -0,0 +1,36 @@ +package docker + +import "sort" + +type imageSorter struct { + images []APIImages + by func(i1, i2 *APIImages) bool // Closure used in the Less method. +} + +// Len is part of sort.Interface. +func (s *imageSorter) Len() int { + return len(s.images) +} + +// Swap is part of sort.Interface. +func (s *imageSorter) Swap(i, j int) { + s.images[i], s.images[j] = s.images[j], s.images[i] +} + +// Less is part of sort.Interface. It is implemented by calling the "by" closure in the sorter. +func (s *imageSorter) Less(i, j int) bool { + return s.by(&s.images[i], &s.images[j]) +} + +// Sort []ApiImages by most recent creation date. +func sortImagesByCreation(images []APIImages) { + creation := func(i1, i2 *APIImages) bool { + return i1.Created > i2.Created + } + + sorter := &imageSorter{ + images: images, + by: creation} + + sort.Sort(sorter) +} diff --git a/components/engine/sorter_test.go b/components/engine/sorter_test.go new file mode 100644 index 0000000000..3c4b3b4874 --- /dev/null +++ b/components/engine/sorter_test.go @@ -0,0 +1,30 @@ +package docker + +import ( + "testing" +) + +func TestServerListOrderedImages(t *testing.T) { + runtime := mkRuntime(t) + defer nuke(runtime) + + archive, err := fakeTar() + if err != nil { + t.Fatal(err) + } + _, err = runtime.graph.Create(archive, nil, "Testing", "", nil) + if err != nil { + t.Fatal(err) + } + + srv := &Server{runtime: runtime} + + images, err := srv.Images(true, "") + if err != nil { + t.Fatal(err) + } + + if images[0].Created < images[1].Created { + t.Error("Expected []APIImges to be ordered by most recent creation date.") + } +} From ad0bdfec4cf76e779de621ad9b5167d64e2b662e Mon Sep 17 00:00:00 2001 From: unclejack Date: Fri, 9 Aug 2013 20:33:17 +0300 Subject: [PATCH 03/55] keep processing signals after the first one Upstream-commit: 88cb9f3116e41b00b00fdccf6359a555e87061bd Component: engine --- components/engine/commands.go | 1 - 1 file changed, 1 deletion(-) diff --git a/components/engine/commands.go b/components/engine/commands.go index db8a126696..d045625c73 100644 --- a/components/engine/commands.go +++ b/components/engine/commands.go @@ -1403,7 +1403,6 @@ func (cli *DockerCli) CmdRun(args ...string) error { if err := cli.CmdStop("-t", "4", runResult.ID); err != nil { fmt.Printf("failed to stop container:", err) } - return } } }() From 7d76874bcb54eb4e2259efb8f7c74dcb7797afde Mon Sep 17 00:00:00 2001 From: unclejack Date: Fri, 9 Aug 2013 23:23:27 +0300 Subject: [PATCH 04/55] minor cleanup for signal handling Upstream-commit: 2ba5c915473ce6fe769fb059db4120e2a21fb42e Component: engine --- components/engine/commands.go | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/components/engine/commands.go b/components/engine/commands.go index d045625c73..ffe4ce230e 100644 --- a/components/engine/commands.go +++ b/components/engine/commands.go @@ -1396,13 +1396,10 @@ func (cli *DockerCli) CmdRun(args ...string) error { signals := make(chan os.Signal, 1) signal.Notify(signals, syscall.SIGINT, syscall.SIGTERM) go func() { - for { - sig := <-signals - if sig == syscall.SIGINT || sig == syscall.SIGTERM { - fmt.Printf("\nReceived signal: %s; cleaning up\n", sig) - if err := cli.CmdStop("-t", "4", runResult.ID); err != nil { - fmt.Printf("failed to stop container:", err) - } + for sig := range signals { + fmt.Printf("\nReceived signal: %s; cleaning up\n", sig) + if err := cli.CmdStop("-t", "4", runResult.ID); err != nil { + fmt.Printf("failed to stop container:", err) } } }() From 71d8c537210de054b8479708e53749fee4a814ea Mon Sep 17 00:00:00 2001 From: unclejack Date: Fri, 9 Aug 2013 23:27:34 +0300 Subject: [PATCH 05/55] add formatting directive to failure to stop container error Upstream-commit: 641ddaeb03f8b8eee5c1ca11e3024976378ceb6d Component: engine --- components/engine/commands.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/engine/commands.go b/components/engine/commands.go index ffe4ce230e..85b5c9abe9 100644 --- a/components/engine/commands.go +++ b/components/engine/commands.go @@ -1399,7 +1399,7 @@ func (cli *DockerCli) CmdRun(args ...string) error { for sig := range signals { fmt.Printf("\nReceived signal: %s; cleaning up\n", sig) if err := cli.CmdStop("-t", "4", runResult.ID); err != nil { - fmt.Printf("failed to stop container:", err) + fmt.Printf("failed to stop container: %v", err) } } }() From 9d2142818e9a88c48c5335c4b6d025a5c39cc08c Mon Sep 17 00:00:00 2001 From: Greg Thornton Date: Sat, 10 Aug 2013 04:55:23 +0000 Subject: [PATCH 06/55] Apply volumes-from before creating volumes Copies the volumes from the container specified in `Config.VolumesFrom` before creating volumes from `Config.Volumes`. Skips any preexisting volumes when processing `Config.Volumes`. Fixes #1351 Upstream-commit: 3bd73a96333e011738136f6a9eda23642cc204ab Component: engine --- components/engine/container.go | 60 +++++++++++++++-------------- components/engine/container_test.go | 59 ++++++++++++++++++++++++++++ 2 files changed, 90 insertions(+), 29 deletions(-) diff --git a/components/engine/container.go b/components/engine/container.go index 8721d45a55..44797e6724 100644 --- a/components/engine/container.go +++ b/components/engine/container.go @@ -574,40 +574,12 @@ func (container *Container) Start(hostConfig *HostConfig) error { binds[path.Clean(dst)] = bindMap } - // FIXME: evaluate volumes-from before individual volumes, so that the latter can override the former. - // Create the requested volumes volumes if container.Volumes == nil || len(container.Volumes) == 0 { container.Volumes = make(map[string]string) container.VolumesRW = make(map[string]bool) - - for volPath := range container.Config.Volumes { - volPath = path.Clean(volPath) - // If an external bind is defined for this volume, use that as a source - if bindMap, exists := binds[volPath]; exists { - container.Volumes[volPath] = bindMap.SrcPath - if strings.ToLower(bindMap.Mode) == "rw" { - container.VolumesRW[volPath] = true - } - // Otherwise create an directory in $ROOT/volumes/ and use that - } else { - c, err := container.runtime.volumes.Create(nil, container, "", "", nil) - if err != nil { - return err - } - srcPath, err := c.layer() - if err != nil { - return err - } - container.Volumes[volPath] = srcPath - container.VolumesRW[volPath] = true // RW by default - } - // Create the mountpoint - if err := os.MkdirAll(path.Join(container.RootfsPath(), volPath), 0755); err != nil { - return nil - } - } } + // Apply volumes from another container if requested if container.Config.VolumesFrom != "" { c := container.runtime.Get(container.Config.VolumesFrom) if c == nil { @@ -627,6 +599,36 @@ func (container *Container) Start(hostConfig *HostConfig) error { } } + // Create the requested volumes if they don't exist + for volPath := range container.Config.Volumes { + volPath = path.Clean(volPath) + // If an external bind is defined for this volume, use that as a source + if _, exists := container.Volumes[volPath]; exists { + // Skip existing mounts + } else if bindMap, exists := binds[volPath]; exists { + container.Volumes[volPath] = bindMap.SrcPath + if strings.ToLower(bindMap.Mode) == "rw" { + container.VolumesRW[volPath] = true + } + // Otherwise create an directory in $ROOT/volumes/ and use that + } else { + c, err := container.runtime.volumes.Create(nil, container, "", "", nil) + if err != nil { + return err + } + srcPath, err := c.layer() + if err != nil { + return err + } + container.Volumes[volPath] = srcPath + container.VolumesRW[volPath] = true // RW by default + } + // Create the mountpoint + if err := os.MkdirAll(path.Join(container.RootfsPath(), volPath), 0755); err != nil { + return nil + } + } + if err := container.generateLXCConfig(); err != nil { return err } diff --git a/components/engine/container_test.go b/components/engine/container_test.go index aca53e5eb3..c4f2193733 100644 --- a/components/engine/container_test.go +++ b/components/engine/container_test.go @@ -1276,6 +1276,65 @@ func TestRestartWithVolumes(t *testing.T) { } } +// Test for #1351 +func TestVolumesFromWithVolumes(t *testing.T) { + runtime := mkRuntime(t) + defer nuke(runtime) + + container, err := NewBuilder(runtime).Create(&Config{ + Image: GetTestImage(runtime).ID, + Cmd: []string{"sh", "-c", "echo -n bar > /test/foo"}, + Volumes: map[string]struct{}{"/test": {}}, + }, + ) + if err != nil { + t.Fatal(err) + } + defer runtime.Destroy(container) + + for key := range container.Config.Volumes { + if key != "/test" { + t.Fail() + } + } + + _, err = container.Output() + if err != nil { + t.Fatal(err) + } + + expected := container.Volumes["/test"] + if expected == "" { + t.Fail() + } + + container2, err := NewBuilder(runtime).Create( + &Config{ + Image: GetTestImage(runtime).ID, + Cmd: []string{"cat", "/test/foo"}, + VolumesFrom: container.ID, + Volumes: map[string]struct{}{"/test": {}}, + }, + ) + if err != nil { + t.Fatal(err) + } + defer runtime.Destroy(container2) + + output, err := container2.Output() + if err != nil { + t.Fatal(err) + } + + if string(output) != "bar" { + t.Fail() + } + + if container.Volumes["/test"] != container2.Volumes["/test"] { + t.Fail() + } +} + func TestOnlyLoopbackExistsWhenUsingDisableNetworkOption(t *testing.T) { runtime := mkRuntime(t) defer nuke(runtime) From 35109f92441b7ab39679a5119ab132a850094da0 Mon Sep 17 00:00:00 2001 From: Greg Thornton Date: Sat, 10 Aug 2013 06:37:57 +0000 Subject: [PATCH 07/55] Skip existing volumes in volumes-from Removes the error when a container already has a volume that would otherwise be created by `Config.VolumesFrom`. Allows restarting containers with a `Config.VolumesFrom` set. Upstream-commit: 57b49efc98d2f4605c95d5579a6cd952dfd6f124 Component: engine --- components/engine/container.go | 10 ++++++---- components/engine/container_test.go | 6 ++++++ 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/components/engine/container.go b/components/engine/container.go index 44797e6724..326c0c55fe 100644 --- a/components/engine/container.go +++ b/components/engine/container.go @@ -587,7 +587,7 @@ func (container *Container) Start(hostConfig *HostConfig) error { } for volPath, id := range c.Volumes { if _, exists := container.Volumes[volPath]; exists { - return fmt.Errorf("The requested volume %s overlap one of the volume of the container %s", volPath, c.ID) + continue } if err := os.MkdirAll(path.Join(container.RootfsPath(), volPath), 0755); err != nil { return nil @@ -602,10 +602,12 @@ func (container *Container) Start(hostConfig *HostConfig) error { // Create the requested volumes if they don't exist for volPath := range container.Config.Volumes { volPath = path.Clean(volPath) - // If an external bind is defined for this volume, use that as a source + // Skip existing volumes if _, exists := container.Volumes[volPath]; exists { - // Skip existing mounts - } else if bindMap, exists := binds[volPath]; exists { + continue + } + // If an external bind is defined for this volume, use that as a source + if bindMap, exists := binds[volPath]; exists { container.Volumes[volPath] = bindMap.SrcPath if strings.ToLower(bindMap.Mode) == "rw" { container.VolumesRW[volPath] = true diff --git a/components/engine/container_test.go b/components/engine/container_test.go index c4f2193733..644e1c058c 100644 --- a/components/engine/container_test.go +++ b/components/engine/container_test.go @@ -1333,6 +1333,12 @@ func TestVolumesFromWithVolumes(t *testing.T) { if container.Volumes["/test"] != container2.Volumes["/test"] { t.Fail() } + + // Ensure it restarts successfully + _, err = container2.Output() + if err != nil { + t.Fatal(err) + } } func TestOnlyLoopbackExistsWhenUsingDisableNetworkOption(t *testing.T) { From c53567b672b085c50cc3b33b0fa681be03649743 Mon Sep 17 00:00:00 2001 From: Brandon Liu Date: Sun, 11 Aug 2013 00:37:16 -0700 Subject: [PATCH 08/55] Fix Graph ByParent() to generate list of child images per parent image. Upstream-commit: 025c759e443cc4eb43fc20b1f7da5520956b3b30 Component: engine --- components/engine/graph.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/components/engine/graph.go b/components/engine/graph.go index 606a6833ee..c54725fdb4 100644 --- a/components/engine/graph.go +++ b/components/engine/graph.go @@ -323,9 +323,9 @@ func (graph *Graph) ByParent() (map[string][]*Image, error) { return } if children, exists := byParent[parent.ID]; exists { - byParent[parent.ID] = []*Image{image} - } else { byParent[parent.ID] = append(children, image) + } else { + byParent[parent.ID] = []*Image{image} } }) return byParent, err From 4ac27c53b9170bc25b95aeb6d053b9d0f716f7a9 Mon Sep 17 00:00:00 2001 From: Brandon Liu Date: Sun, 11 Aug 2013 01:24:21 -0700 Subject: [PATCH 09/55] Add test case for Graph ByParent(). Upstream-commit: 02b8d14bdd1837aad5b8fb667d1f4e7eace59687 Component: engine --- components/engine/graph_test.go | 39 +++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/components/engine/graph_test.go b/components/engine/graph_test.go index 2898fccf99..32fb0ef441 100644 --- a/components/engine/graph_test.go +++ b/components/engine/graph_test.go @@ -234,6 +234,45 @@ func TestDelete(t *testing.T) { assertNImages(graph, t, 1) } +func TestByParent(t *testing.T) { + archive1, _ := fakeTar() + archive2, _ := fakeTar() + archive3, _ := fakeTar() + + graph := tempGraph(t) + defer os.RemoveAll(graph.Root) + parentImage := &Image{ + ID: GenerateID(), + Comment: "parent", + Created: time.Now(), + Parent: "", + } + childImage1 := &Image{ + ID: GenerateID(), + Comment: "child1", + Created: time.Now(), + Parent: parentImage.ID, + } + childImage2 := &Image{ + ID: GenerateID(), + Comment: "child2", + Created: time.Now(), + Parent: parentImage.ID, + } + _ = graph.Register(nil, archive1, parentImage) + _ = graph.Register(nil, archive2, childImage1) + _ = graph.Register(nil, archive3, childImage2) + + byParent, err := graph.ByParent() + if err != nil { + t.Fatal(err) + } + numChildren := len(byParent[parentImage.ID]) + if numChildren != 2 { + t.Fatalf("Expected 2 children, found %d", numChildren) + } +} + func assertNImages(graph *Graph, t *testing.T, n int) { if images, err := graph.All(); err != nil { t.Fatal(err) From c5aa8d03ec3463279154827692c6444f711f35bb Mon Sep 17 00:00:00 2001 From: Kawsar Saiyeed Date: Mon, 12 Aug 2013 05:22:33 +0100 Subject: [PATCH 10/55] Install websocket library before building docker Upstream-commit: def9598ed968eac934699db1b8717f852652b1ef Component: engine --- components/engine/Dockerfile | 3 +++ 1 file changed, 3 insertions(+) diff --git a/components/engine/Dockerfile b/components/engine/Dockerfile index 46f9b585c8..7430ec6c0f 100644 --- a/components/engine/Dockerfile +++ b/components/engine/Dockerfile @@ -22,6 +22,9 @@ run echo 'deb http://archive.ubuntu.com/ubuntu precise main universe' > /etc/apt run apt-get update run apt-get install -y lxc run apt-get install -y aufs-tools +# Docker requires code.google.com/p/go.net/websocket +run apt-get install -y -q mercurial +run PKG=code.google.com/p/go.net REV=78ad7f42aa2e; hg clone https://$PKG /go/src/$PKG && cd /go/src/$PKG && hg checkout -r $REV # Upload docker source add . /go/src/github.com/dotcloud/docker # Build the binary From 2037ff0102228f2a64d35bed5f7443069728dcca Mon Sep 17 00:00:00 2001 From: Victor Vieux Date: Mon, 12 Aug 2013 11:50:03 +0000 Subject: [PATCH 11/55] ensure the use oh IDs and add image's name in /events Upstream-commit: 703905d7ece5b4a71ae1faf2743341ace98c4fbb Component: engine --- components/engine/container.go | 2 +- components/engine/server.go | 22 +++++++++++----------- components/engine/utils/utils.go | 4 ++++ 3 files changed, 16 insertions(+), 12 deletions(-) diff --git a/components/engine/container.go b/components/engine/container.go index 8721d45a55..18c56c8349 100644 --- a/components/engine/container.go +++ b/components/engine/container.go @@ -813,7 +813,7 @@ func (container *Container) monitor() { } utils.Debugf("Process finished") if container.runtime != nil && container.runtime.srv != nil { - container.runtime.srv.LogEvent("die", container.ShortID()) + container.runtime.srv.LogEvent("die", container.ShortID(), container.runtime.repositories.ImageName(container.Image)) } exitCode := -1 if container.cmd != nil { diff --git a/components/engine/server.go b/components/engine/server.go index f06b5ce68e..663b9683b8 100644 --- a/components/engine/server.go +++ b/components/engine/server.go @@ -76,7 +76,7 @@ func (srv *Server) ContainerKill(name string) error { if err := container.Kill(); err != nil { return fmt.Errorf("Error killing container %s: %s", name, err) } - srv.LogEvent("kill", name) + srv.LogEvent("kill", container.ShortID(), srv.runtime.repositories.ImageName(container.Image)) } else { return fmt.Errorf("No such container: %s", name) } @@ -95,7 +95,7 @@ func (srv *Server) ContainerExport(name string, out io.Writer) error { if _, err := io.Copy(out, data); err != nil { return err } - srv.LogEvent("export", name) + srv.LogEvent("export", container.ShortID(), srv.runtime.repositories.ImageName(container.Image)) return nil } return fmt.Errorf("No such container: %s", name) @@ -832,7 +832,7 @@ func (srv *Server) ContainerCreate(config *Config) (string, error) { } return "", err } - srv.LogEvent("create", container.ShortID()) + srv.LogEvent("create", container.ShortID(), srv.runtime.repositories.ImageName(container.Image)) return container.ShortID(), nil } @@ -841,7 +841,7 @@ func (srv *Server) ContainerRestart(name string, t int) error { if err := container.Restart(t); err != nil { return fmt.Errorf("Error restarting container %s: %s", name, err) } - srv.LogEvent("restart", name) + srv.LogEvent("restart", container.ShortID(), srv.runtime.repositories.ImageName(container.Image)) } else { return fmt.Errorf("No such container: %s", name) } @@ -861,7 +861,7 @@ func (srv *Server) ContainerDestroy(name string, removeVolume bool) error { if err := srv.runtime.Destroy(container); err != nil { return fmt.Errorf("Error destroying container %s: %s", name, err) } - srv.LogEvent("destroy", name) + srv.LogEvent("destroy", container.ShortID(), srv.runtime.repositories.ImageName(container.Image)) if removeVolume { // Retrieve all volumes from all remaining containers @@ -928,7 +928,7 @@ func (srv *Server) deleteImageAndChildren(id string, imgs *[]APIRmi) error { return err } *imgs = append(*imgs, APIRmi{Deleted: utils.TruncateID(id)}) - srv.LogEvent("delete", utils.TruncateID(id)) + srv.LogEvent("delete", utils.TruncateID(id), "") return nil } return nil @@ -975,7 +975,7 @@ func (srv *Server) deleteImage(img *Image, repoName, tag string) ([]APIRmi, erro } if tagDeleted { imgs = append(imgs, APIRmi{Untagged: img.ShortID()}) - srv.LogEvent("untag", img.ShortID()) + srv.LogEvent("untag", img.ShortID(), "") } if len(srv.runtime.repositories.ByID()[img.ID]) == 0 { if err := srv.deleteImageAndChildren(img.ID, &imgs); err != nil { @@ -1042,7 +1042,7 @@ func (srv *Server) ContainerStart(name string, hostConfig *HostConfig) error { if err := container.Start(hostConfig); err != nil { return fmt.Errorf("Error starting container %s: %s", name, err) } - srv.LogEvent("start", name) + srv.LogEvent("start", container.ShortID(), srv.runtime.repositories.ImageName(container.Image)) } else { return fmt.Errorf("No such container: %s", name) } @@ -1054,7 +1054,7 @@ func (srv *Server) ContainerStop(name string, t int) error { if err := container.Stop(t); err != nil { return fmt.Errorf("Error stopping container %s: %s", name, err) } - srv.LogEvent("stop", name) + srv.LogEvent("stop", container.ShortID(), srv.runtime.repositories.ImageName(container.Image)) } else { return fmt.Errorf("No such container: %s", name) } @@ -1222,9 +1222,9 @@ func (srv *Server) HTTPRequestFactory() *utils.HTTPRequestFactory { return srv.reqFactory } -func (srv *Server) LogEvent(action, id string) { +func (srv *Server) LogEvent(action, id, from string) { now := time.Now().Unix() - jm := utils.JSONMessage{Status: action, ID: id, Time: now} + jm := utils.JSONMessage{Status: action, ID: id, From: from, Time: now} srv.events = append(srv.events, jm) for _, c := range srv.listeners { select { // non blocking channel diff --git a/components/engine/utils/utils.go b/components/engine/utils/utils.go index df21e75ae4..497d7f4e42 100644 --- a/components/engine/utils/utils.go +++ b/components/engine/utils/utils.go @@ -622,6 +622,7 @@ type JSONMessage struct { Progress string `json:"progress,omitempty"` ErrorMessage string `json:"error,omitempty"` //deprecated ID string `json:"id,omitempty"` + From string `json:"from,omitempty"` Time int64 `json:"time,omitempty"` Error *JSONError `json:"errorDetail,omitempty"` } @@ -650,6 +651,9 @@ func (jm *JSONMessage) Display(out io.Writer) error { if jm.ID != "" { fmt.Fprintf(out, "%s: ", jm.ID) } + if jm.From != "" { + fmt.Fprintf(out, "(from %s) ", jm.From) + } if jm.Progress != "" { fmt.Fprintf(out, "%c[2K", 27) fmt.Fprintf(out, "%s %s\r", jm.Status, jm.Progress) From 97b43448be70d8387fbedec1d192064bf380544a Mon Sep 17 00:00:00 2001 From: Victor Vieux Date: Mon, 12 Aug 2013 11:55:23 +0000 Subject: [PATCH 12/55] Added docs Upstream-commit: 123c80467bb6e7bef22827b55640a4789e42558d Component: engine --- .../docs/sources/api/docker_remote_api.rst | 4 +++ .../sources/api/docker_remote_api_v1.4.rst | 31 +++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/components/engine/docs/sources/api/docker_remote_api.rst b/components/engine/docs/sources/api/docker_remote_api.rst index 7e4b674348..ec19fed48e 100644 --- a/components/engine/docs/sources/api/docker_remote_api.rst +++ b/components/engine/docs/sources/api/docker_remote_api.rst @@ -48,6 +48,10 @@ What's new **New!** You can now use ps args with docker top, like `docker top aux` +.. http:get:: /events: + + **New!** Image's name added in the events + :doc:`docker_remote_api_v1.3` ***************************** diff --git a/components/engine/docs/sources/api/docker_remote_api_v1.4.rst b/components/engine/docs/sources/api/docker_remote_api_v1.4.rst index 06e8f46f99..1073ddcd6e 100644 --- a/components/engine/docs/sources/api/docker_remote_api_v1.4.rst +++ b/components/engine/docs/sources/api/docker_remote_api_v1.4.rst @@ -1095,6 +1095,37 @@ Create a new image from a container's changes :statuscode 404: no such container :statuscode 500: server error + +Monitor Docker's events +*********************** + +.. http:get:: /events + + Get events from docker, either in real time via streaming, or via polling (using `since`) + + **Example request**: + + .. sourcecode:: http + + POST /events?since=1374067924 + + **Example response**: + + .. sourcecode:: http + + HTTP/1.1 200 OK + Content-Type: application/json + + {"status":"create","id":"dfdf82bd3881","from":"base:latest","time":1374067924} + {"status":"start","id":"dfdf82bd3881","from":"base:latest","time":1374067924} + {"status":"stop","id":"dfdf82bd3881","from":"base:latest","time":1374067966} + {"status":"destroy","id":"dfdf82bd3881","from":"base:latest","time":1374067970} + + :query since: timestamp used for polling + :statuscode 200: no error + :statuscode 500: server error + + 3. Going further ================ From a74f9e3dd33aa859fcd55daa13590c1ecb7c3bbd Mon Sep 17 00:00:00 2001 From: Michael Crosby Date: Mon, 12 Aug 2013 22:42:29 +0000 Subject: [PATCH 13/55] Add import for dotcloud/tar to replace std tar pkg Upstream-commit: ec61c46bf73b8c727fe8de1982d86a1417a8a0c4 Component: engine --- components/engine/Dockerfile | 1 + components/engine/utils/tarsum.go | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/components/engine/Dockerfile b/components/engine/Dockerfile index 46f9b585c8..2e4953fb1f 100644 --- a/components/engine/Dockerfile +++ b/components/engine/Dockerfile @@ -15,6 +15,7 @@ run cd /tmp && echo 'package main' > t.go && go test -a -i -v run PKG=github.com/kr/pty REV=27435c699; git clone http://$PKG /go/src/$PKG && cd /go/src/$PKG && git checkout -f $REV run PKG=github.com/gorilla/context/ REV=708054d61e5; git clone http://$PKG /go/src/$PKG && cd /go/src/$PKG && git checkout -f $REV run PKG=github.com/gorilla/mux/ REV=9b36453141c; git clone http://$PKG /go/src/$PKG && cd /go/src/$PKG && git checkout -f $REV +run PKG=github.com/dotcloud/tar/ REV=d06045a6d9; git clone http://$PKG /go/src/$PKG && cd /go/src/$PKG && git checkout -f $REV # Run dependencies run apt-get install -y iptables # lxc requires updating ubuntu sources diff --git a/components/engine/utils/tarsum.go b/components/engine/utils/tarsum.go index d3e1db61f1..290be241a9 100644 --- a/components/engine/utils/tarsum.go +++ b/components/engine/utils/tarsum.go @@ -1,11 +1,11 @@ package utils import ( - "archive/tar" "bytes" "compress/gzip" "crypto/sha256" "encoding/hex" + "github.com/dotcloud/tar" "hash" "io" "sort" From bd75d9f1365fc446140ac480db28befe31d99503 Mon Sep 17 00:00:00 2001 From: Daniel Mizyrycki Date: Mon, 12 Aug 2013 11:07:58 -0700 Subject: [PATCH 14/55] API, issue 1471: Allow users belonging to the docker group to use the docker client Upstream-commit: c015d26e96e1f6ebee2a577468c747bf3d2aeeb9 Component: engine --- components/engine/api.go | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/components/engine/api.go b/components/engine/api.go index 221cabed56..6b692ed984 100644 --- a/components/engine/api.go +++ b/components/engine/api.go @@ -13,6 +13,7 @@ import ( "net/http" "os" "os/exec" + "regexp" "strconv" "strings" ) @@ -974,7 +975,20 @@ func ListenAndServe(proto, addr string, srv *Server, logging bool) error { return e } if proto == "unix" { - os.Chmod(addr, 0700) + os.Chmod(addr, 0660) + groups, err := ioutil.ReadFile("/etc/group") + if err != nil { + return err + } + re := regexp.MustCompile("(^|\n)docker:.*?:([0-9]+)") + if gidMatch := re.FindStringSubmatch(string(groups)); gidMatch != nil { + gid, err := strconv.Atoi(gidMatch[2]) + if err != nil { + return err + } + utils.Debugf("docker group found. gid: %d", gid) + os.Chown(addr, 0, gid) + } } httpSrv := http.Server{Addr: addr, Handler: r} return httpSrv.Serve(l) From daa3c2ba789892d887056eb18162560c7df551f5 Mon Sep 17 00:00:00 2001 From: Michael Crosby Date: Sat, 10 Aug 2013 03:06:08 +0000 Subject: [PATCH 15/55] Revert "docker.upstart: avoid spawning a `sh` process" This reverts commit 24dd50490a027f01ea086eb90663d53348fa770e. Upstream-commit: ef1d1aefa73f71296911b0f5593e46a81c1f5c55 Component: engine --- components/engine/packaging/ubuntu/docker.upstart | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/components/engine/packaging/ubuntu/docker.upstart b/components/engine/packaging/ubuntu/docker.upstart index f4d2fbe922..143be03402 100644 --- a/components/engine/packaging/ubuntu/docker.upstart +++ b/components/engine/packaging/ubuntu/docker.upstart @@ -5,4 +5,6 @@ stop on runlevel [!2345] respawn -exec /usr/bin/docker -d +script + /usr/bin/docker -d +end script From 8e0a4e36d7dfead4e51e37129b6d3f1772f82de5 Mon Sep 17 00:00:00 2001 From: "Guillaume J. Charmes" Date: Wed, 7 Aug 2013 17:23:49 -0700 Subject: [PATCH 16/55] Make sure ENV instruction within build perform a commit each time Upstream-commit: 68934878f1e707b126ab754d48ff6c6eb858b37e Component: engine --- components/engine/buildfile.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/components/engine/buildfile.go b/components/engine/buildfile.go index 33e68c6211..b13643fd8e 100644 --- a/components/engine/buildfile.go +++ b/components/engine/buildfile.go @@ -167,9 +167,9 @@ func (b *buildFile) CmdEnv(args string) error { if envKey >= 0 { b.config.Env[envKey] = replacedVar - return nil + } else { + b.config.Env = append(b.config.Env, replacedVar) } - b.config.Env = append(b.config.Env, replacedVar) return b.commit("", b.config.Cmd, fmt.Sprintf("ENV %s", replacedVar)) } From cc86282cc7456a84876f9de9743c30c99a6ca11a Mon Sep 17 00:00:00 2001 From: Steeve Morin Date: Thu, 1 Aug 2013 02:42:22 +0200 Subject: [PATCH 17/55] Handle ip route showing mask-less IP addresses Sometimes `ip route` will show mask-less IPs, so net.ParseCIDR will fail. If it does we check if we can net.ParseIP, and fail only if we can't. Fixes #1214 Fixes #362 Upstream-commit: 0ca133dd7681bb3af1d1de18a5ea6ed42142a11e Component: engine --- components/engine/network.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/components/engine/network.go b/components/engine/network.go index 4e3c7456a0..02268314af 100644 --- a/components/engine/network.go +++ b/components/engine/network.go @@ -104,7 +104,11 @@ func checkRouteOverlaps(dockerNetwork *net.IPNet) error { continue } if _, network, err := net.ParseCIDR(strings.Split(line, " ")[0]); err != nil { - return fmt.Errorf("Unexpected ip route output: %s (%s)", err, line) + // is this a mask-less IP address? + if ip := net.ParseIP(strings.Split(line, " ")[0]); ip == nil { + // fail only if it's neither a network nor a mask-less IP address + return fmt.Errorf("Unexpected ip route output: %s (%s)", err, line) + } } else if networkOverlaps(dockerNetwork, network) { return fmt.Errorf("Network %s is already routed: '%s'", dockerNetwork.String(), line) } From 7847f341c48bd041a9a6cbcff40c5ca66c649856 Mon Sep 17 00:00:00 2001 From: Michael Crosby Date: Mon, 12 Aug 2013 23:55:42 +0000 Subject: [PATCH 18/55] Bump to 0.5.3 Upstream-commit: c3773740d982d62c5c478d3fb27aa4494383b11b Component: engine --- components/engine/CHANGELOG.md | 6 ++++++ components/engine/commands.go | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/components/engine/CHANGELOG.md b/components/engine/CHANGELOG.md index ab145e595e..7a8122416c 100644 --- a/components/engine/CHANGELOG.md +++ b/components/engine/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## 0.5.3 (2013-08-13) +* Runtime: Use docker group for socket permissions +- Runtime: Spawn shell within upstart script +- Builder: Make sure ENV instruction within build perform a commit each time +- Runtime: Handle ip route showing mask-less IP addresses + ## 0.5.2 (2013-08-08) * Builder: Forbid certain paths within docker build ADD - Runtime: Change network range to avoid conflict with EC2 DNS diff --git a/components/engine/commands.go b/components/engine/commands.go index 7f70c8c09b..e1246d588e 100644 --- a/components/engine/commands.go +++ b/components/engine/commands.go @@ -27,7 +27,7 @@ import ( "unicode" ) -const VERSION = "0.5.2" +const VERSION = "0.5.3" var ( GITCOMMIT string From eb493ee13be73b58a256bea05f05d31bb9e4b395 Mon Sep 17 00:00:00 2001 From: Victor Vieux Date: Tue, 13 Aug 2013 13:35:34 +0000 Subject: [PATCH 19/55] fix merge issue Upstream-commit: 6cb908bb823409661bfedab806da924d232bf200 Component: engine --- components/engine/commands.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/engine/commands.go b/components/engine/commands.go index 9b9dd51e75..d9d4f1b620 100644 --- a/components/engine/commands.go +++ b/components/engine/commands.go @@ -857,7 +857,7 @@ func (cli *DockerCli) CmdPush(args ...string) error { } if err := push(); err != nil { - if err == fmt.Errorf("Authentication is required.") { + if err.Error() == "Authentication is required." { if err = cli.checkIfLogged("push"); err == nil { return push() } From 15696699da10a3ab01d289036ac0056987eb7c95 Mon Sep 17 00:00:00 2001 From: Victor Vieux Date: Tue, 13 Aug 2013 13:51:49 +0000 Subject: [PATCH 20/55] remove checkIfLogged Upstream-commit: 2ba1300773857273585288c79aa65f011b045b4c Component: engine --- components/engine/commands.go | 19 ++++--------------- 1 file changed, 4 insertions(+), 15 deletions(-) diff --git a/components/engine/commands.go b/components/engine/commands.go index d9d4f1b620..8cefe3408f 100644 --- a/components/engine/commands.go +++ b/components/engine/commands.go @@ -858,9 +858,11 @@ func (cli *DockerCli) CmdPush(args ...string) error { if err := push(); err != nil { if err.Error() == "Authentication is required." { - if err = cli.checkIfLogged("push"); err == nil { - return push() + fmt.Fprintln(cli.out, "\nPlease login prior to push:") + if err := cli.CmdLogin(""); err != nil { + return err } + return push() } return err } @@ -1512,19 +1514,6 @@ func (cli *DockerCli) CmdCp(args ...string) error { return nil } -func (cli *DockerCli) checkIfLogged(action string) error { - // If condition AND the login failed - if cli.configFile.Configs[auth.IndexServerAddress()].Username == "" { - if err := cli.CmdLogin(""); err != nil { - return err - } - if cli.configFile.Configs[auth.IndexServerAddress()].Username == "" { - return fmt.Errorf("Please login prior to %s. ('docker login')", action) - } - } - return nil -} - func (cli *DockerCli) call(method, path string, data interface{}) ([]byte, int, error) { var params io.Reader if data != nil { From 1a2d40b29bb82864c151955e5341ba49ae0b2975 Mon Sep 17 00:00:00 2001 From: unclejack Date: Tue, 13 Aug 2013 19:48:30 +0300 Subject: [PATCH 21/55] use Go 1.1.2 for dockerbuilder Upstream-commit: e09863fedb1b2fec4672d2d1ebad29ecdb8eed1a Component: engine --- components/engine/hack/dockerbuilder/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/engine/hack/dockerbuilder/Dockerfile b/components/engine/hack/dockerbuilder/Dockerfile index 60cd93b17a..496ee45e7a 100644 --- a/components/engine/hack/dockerbuilder/Dockerfile +++ b/components/engine/hack/dockerbuilder/Dockerfile @@ -23,7 +23,7 @@ run add-apt-repository -y ppa:dotcloud/docker-golang/ubuntu run apt-get update # Packages required to checkout, build and upload docker run DEBIAN_FRONTEND=noninteractive apt-get install -y -q s3cmd curl -run curl -s -o /go.tar.gz https://go.googlecode.com/files/go1.1.1.linux-amd64.tar.gz +run curl -s -o /go.tar.gz https://go.googlecode.com/files/go1.1.2.linux-amd64.tar.gz run tar -C /usr/local -xzf /go.tar.gz run echo "export PATH=/usr/local/go/bin:$PATH" > /.bashrc run echo "export PATH=/usr/local/go/bin:$PATH" > /.bash_profile From 8a3b7335fe3ae63d1dd13f027b17049c7bdfcb31 Mon Sep 17 00:00:00 2001 From: Nolan Date: Tue, 30 Jul 2013 13:23:34 -0500 Subject: [PATCH 22/55] Add hostname to the container environment. Upstream-commit: 05219d6b52d8448fdad72f89b192d61480483aff Component: engine --- components/engine/container.go | 1 + 1 file changed, 1 insertion(+) diff --git a/components/engine/container.go b/components/engine/container.go index d610c3c7d4..ccc7ab3e9f 100644 --- a/components/engine/container.go +++ b/components/engine/container.go @@ -652,6 +652,7 @@ func (container *Container) Start(hostConfig *HostConfig) error { "-e", "HOME=/", "-e", "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", "-e", "container=lxc", + "-e", "HOSTNAME="+container.Config.Hostname, ) for _, elem := range container.Config.Env { From 8b4336e30f7ec7cd309762ba5e600094c44ee256 Mon Sep 17 00:00:00 2001 From: "Guillaume J. Charmes" Date: Fri, 2 Aug 2013 15:58:10 -0700 Subject: [PATCH 23/55] Fix TestEnv Upstream-commit: 1a1c89556f3869baded68eb56ae20f8a7e90a708 Component: engine --- components/engine/container_test.go | 1 + 1 file changed, 1 insertion(+) diff --git a/components/engine/container_test.go b/components/engine/container_test.go index a1ac0bd33a..f29ae9e4ea 100644 --- a/components/engine/container_test.go +++ b/components/engine/container_test.go @@ -960,6 +960,7 @@ func TestEnv(t *testing.T) { "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", "HOME=/", "container=lxc", + "HOSTNAME=" + container.ShortID(), } sort.Strings(goodEnv) if len(goodEnv) != len(actualEnv) { From 28a5a06a8d78e1ca17f5038abf9df6fcc17d80a3 Mon Sep 17 00:00:00 2001 From: Michael Crosby Date: Tue, 13 Aug 2013 17:36:24 +0000 Subject: [PATCH 24/55] Update changelog to include hostname commit Upstream-commit: 5d25f3232c38d6a7ed31860948058b8ec1d95656 Component: engine --- components/engine/CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/components/engine/CHANGELOG.md b/components/engine/CHANGELOG.md index 7a8122416c..cfbd86cd75 100644 --- a/components/engine/CHANGELOG.md +++ b/components/engine/CHANGELOG.md @@ -5,6 +5,7 @@ - Runtime: Spawn shell within upstart script - Builder: Make sure ENV instruction within build perform a commit each time - Runtime: Handle ip route showing mask-less IP addresses +- Runtime: Add hostname to environment ## 0.5.2 (2013-08-08) * Builder: Forbid certain paths within docker build ADD From 6e12795b0e04309baa98e9cbf07464c75e72d348 Mon Sep 17 00:00:00 2001 From: shin- Date: Mon, 12 Aug 2013 19:45:12 +0200 Subject: [PATCH 25/55] brew: Reuse repositories when possible Upstream-commit: fb7c4214ced3b0533316e3eebd90ac07fe7b2933 Component: engine --- components/engine/contrib/brew/brew/brew.py | 12 ++++++++++-- components/engine/contrib/brew/brew/git.py | 17 ++++++++++++++++- 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/components/engine/contrib/brew/brew/brew.py b/components/engine/contrib/brew/brew/brew.py index 8cbbaca06a..352d20c779 100644 --- a/components/engine/contrib/brew/brew/brew.py +++ b/components/engine/contrib/brew/brew/brew.py @@ -14,6 +14,7 @@ logging.basicConfig(format='%(asctime)s %(levelname)s %(message)s', level='INFO') client = docker.Client() processed = {} +processed_folders = [] def build_library(repository=None, branch=None, namespace=None, push=False, @@ -92,20 +93,27 @@ def build_library(repository=None, branch=None, namespace=None, push=False, f.close() if dst_folder != repository: rmtree(dst_folder, True) + for d in processed_folders: + rmtree(d, True) summary.print_summary(logger) def build_repo(repository, ref, docker_repo, docker_tag, namespace, push, registry): docker_repo = '{0}/{1}'.format(namespace or 'library', docker_repo) img_id = None + dst_folder = None if '{0}@{1}'.format(repository, ref) not in processed.keys(): logger.info('Cloning {0} (ref: {1})'.format(repository, ref)) - dst_folder = git.clone(repository, ref) + if repository not in processed: + rep, dst_folder = git.clone(repository, ref) + processed[repository] = rep + processed_folders.append(dst_folder) + else: + dst_folder = git.checkout(processed[repository], ref) if not 'Dockerfile' in os.listdir(dst_folder): raise RuntimeError('Dockerfile not found in cloned repository') logger.info('Building using dockerfile...') img_id, logs = client.build(path=dst_folder, quiet=True) - rmtree(dst_folder, True) else: img_id = processed['{0}@{1}'.format(repository, ref)] logger.info('Committing to {0}:{1}'.format(docker_repo, diff --git a/components/engine/contrib/brew/brew/git.py b/components/engine/contrib/brew/brew/git.py index 40cae8753b..e45e995458 100644 --- a/components/engine/contrib/brew/brew/git.py +++ b/components/engine/contrib/brew/brew/git.py @@ -16,6 +16,21 @@ def clone_tag(repo_url, tag, folder=None): return clone(repo_url, 'refs/tags/' + tag, folder) +def checkout(rep, ref=None): + is_commit = False + if ref is None: + ref = 'refs/heads/master' + elif not ref.startswith('refs/'): + is_commit = True + if is_commit: + rep['HEAD'] = rep.commit(ref) + else: + rep['HEAD'] = rep.refs[ref] + indexfile = rep.index_path() + tree = rep["HEAD"].tree + index.build_index_from_tree(rep.path, indexfile, rep.object_store, tree) + return rep.path + def clone(repo_url, ref=None, folder=None): is_commit = False if ref is None: @@ -45,4 +60,4 @@ def clone(repo_url, ref=None, folder=None): tree = rep["HEAD"].tree index.build_index_from_tree(rep.path, indexfile, rep.object_store, tree) logger.debug("done") - return folder + return rep, folder From 1b1b67104d7c83d01822748a4a6dfb43f5c04131 Mon Sep 17 00:00:00 2001 From: shin- Date: Mon, 12 Aug 2013 19:52:09 +0200 Subject: [PATCH 26/55] brew: Don't build if docker daemon can't be reached Upstream-commit: 79fc90b6463d9b20391b4edd1540bc0a8e84da6f Component: engine --- components/engine/contrib/brew/brew/brew.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/components/engine/contrib/brew/brew/brew.py b/components/engine/contrib/brew/brew/brew.py index 352d20c779..e07fdfdbbb 100644 --- a/components/engine/contrib/brew/brew/brew.py +++ b/components/engine/contrib/brew/brew/brew.py @@ -32,6 +32,15 @@ def build_library(repository=None, branch=None, namespace=None, push=False, logger.info('Repository provided assumed to be a local path') dst_folder = repository + try: + client.version() + except Exception as e: + logger.error('Could not reach the docker daemon. Please make sure it ' + 'is running.') + logger.warning('Also make sure you have access to the docker UNIX ' + 'socket (use sudo)') + return + #FIXME: set destination folder and only pull latest changes instead of # cloning the whole repo everytime if not dst_folder: From 3d705fcda8ea64cbd1d09e70fdd50ada97392d88 Mon Sep 17 00:00:00 2001 From: shin- Date: Tue, 13 Aug 2013 20:12:44 +0200 Subject: [PATCH 27/55] brew: Updated requirements Upstream-commit: e5f1b6b9a4b934eab9c42d6534fe52672c018405 Component: engine --- components/engine/contrib/brew/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/engine/contrib/brew/requirements.txt b/components/engine/contrib/brew/requirements.txt index 78a574953d..6100b01d01 100644 --- a/components/engine/contrib/brew/requirements.txt +++ b/components/engine/contrib/brew/requirements.txt @@ -1,2 +1,2 @@ dulwich==0.9.0 -docker-py==0.1.3 \ No newline at end of file +docker-py==0.1.4 \ No newline at end of file From 49824271a4a68fa113be27947b5a5f8b88cb5bb4 Mon Sep 17 00:00:00 2001 From: shin- Date: Tue, 13 Aug 2013 20:28:06 +0200 Subject: [PATCH 28/55] brew: Display a clear error message when the path is invalid Upstream-commit: 2cebe09924c9afea47bb1f2444ba1cd8fc423669 Component: engine --- components/engine/contrib/brew/brew/brew.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/components/engine/contrib/brew/brew/brew.py b/components/engine/contrib/brew/brew/brew.py index e07fdfdbbb..22fe5b7b40 100644 --- a/components/engine/contrib/brew/brew/brew.py +++ b/components/engine/contrib/brew/brew/brew.py @@ -53,7 +53,13 @@ def build_library(repository=None, branch=None, namespace=None, push=False, logger.error('Source repository could not be fetched. Check ' 'that the address is correct and the branch exists.') return - for buildfile in os.listdir(os.path.join(dst_folder, 'library')): + try: + dirlist = os.listdir(os.path.join(dst_folder, 'library')) + except OSError as e: + logger.error('The path provided ({0}) could not be found or didn\'t' + 'contain a library/ folder.'.format(dst_folder)) + return + for buildfile in dirlist: if buildfile == 'MAINTAINERS': continue f = open(os.path.join(dst_folder, 'library', buildfile)) From fe8b556e8db25d842139acb06a1f1e9d2dfe7f16 Mon Sep 17 00:00:00 2001 From: Michael Crosby Date: Tue, 13 Aug 2013 12:02:20 -0700 Subject: [PATCH 29/55] Update docs for docker group Upstream-commit: e4f35dd4cf81a7f2d19a61cc8b1084c3adcc5253 Component: engine --- components/engine/docs/sources/api/docker_remote_api.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/components/engine/docs/sources/api/docker_remote_api.rst b/components/engine/docs/sources/api/docker_remote_api.rst index 9113d8e155..aa11ba50a2 100644 --- a/components/engine/docs/sources/api/docker_remote_api.rst +++ b/components/engine/docs/sources/api/docker_remote_api.rst @@ -16,6 +16,7 @@ Docker Remote API - The Remote API is replacing rcli - By default the Docker daemon listens on unix:///var/run/docker.sock and the client must have root access to interact with the daemon +- If a group named *docker* exists on your system, docker will apply ownership of the socket to the group - The API tends to be REST, but for some complex commands, like attach or pull, the HTTP connection is hijacked to transport stdout stdin and stderr From abcb5a75542d6e830c80a7b3243f8eef6965aa36 Mon Sep 17 00:00:00 2001 From: Andy Rothfusz Date: Tue, 13 Aug 2013 13:45:07 -0700 Subject: [PATCH 30/55] Added information about Docker's high level tools over LXC. Formatting cleanup. Mailing list cleanup. Upstream-commit: e2409ad3376baeb36d1011732f7d7b1a239320ae Component: engine --- .../docs/sources/api/registry_index_spec.rst | 3 +- components/engine/docs/sources/faq.rst | 124 ++++++++++++++++-- .../engine/docs/sources/use/builder.rst | 2 + 3 files changed, 116 insertions(+), 13 deletions(-) diff --git a/components/engine/docs/sources/api/registry_index_spec.rst b/components/engine/docs/sources/api/registry_index_spec.rst index a41523e813..4ea0c687db 100644 --- a/components/engine/docs/sources/api/registry_index_spec.rst +++ b/components/engine/docs/sources/api/registry_index_spec.rst @@ -2,9 +2,10 @@ :description: Documentation for docker Registry and Registry API :keywords: docker, registry, api, index +.. _registryindexspec: ===================== -Registry & index Spec +Registry & Index Spec ===================== .. contents:: Table of Contents diff --git a/components/engine/docs/sources/faq.rst b/components/engine/docs/sources/faq.rst index 3cc0086c5d..dd5fd11fd5 100644 --- a/components/engine/docs/sources/faq.rst +++ b/components/engine/docs/sources/faq.rst @@ -9,40 +9,140 @@ FAQ Most frequently asked questions. -------------------------------- -1. **How much does Docker cost?** +How much does Docker cost? +.......................... Docker is 100% free, it is open source, so you can use it without paying. -2. **What open source license are you using?** +What open source license are you using? +....................................... - We are using the Apache License Version 2.0, see it here: https://github.com/dotcloud/docker/blob/master/LICENSE + We are using the Apache License Version 2.0, see it here: + https://github.com/dotcloud/docker/blob/master/LICENSE -3. **Does Docker run on Mac OS X or Windows?** +Does Docker run on Mac OS X or Windows? +....................................... - Not at this time, Docker currently only runs on Linux, but you can use VirtualBox to run Docker in a - virtual machine on your box, and get the best of both worlds. Check out the :ref:`install_using_vagrant` and :ref:`windows` installation guides. + Not at this time, Docker currently only runs on Linux, but you can + use VirtualBox to run Docker in a virtual machine on your box, and + get the best of both worlds. Check out the + :ref:`install_using_vagrant` and :ref:`windows` installation + guides. -4. **How do containers compare to virtual machines?** +How do containers compare to virtual machines? +.............................................. - They are complementary. VMs are best used to allocate chunks of hardware resources. Containers operate at the process level, which makes them very lightweight and perfect as a unit of software delivery. + They are complementary. VMs are best used to allocate chunks of + hardware resources. Containers operate at the process level, which + makes them very lightweight and perfect as a unit of software + delivery. -5. **Can I help by adding some questions and answers?** +What does Docker add to just plain LXC? +....................................... + + Docker is not a replacement for LXC. "LXC" refers to capabilities + of the Linux kernel (specifically namespaces and control groups) + which allow sandboxing processes from one another, and controlling + their resource allocations. On top of this low-level foundation of + kernel features, Docker offers a high-level tool with several + powerful functionalities: + + * *Portable deployment across machines.* + Docker defines a format for bundling an application and all its + dependencies into a single object which can be transferred to + any Docker-enabled machine, and executed there with the + guarantee that the execution environment exposed to the + application will be the same. LXC implements process sandboxing, + which is an important pre-requisite for portable deployment, but + that alone is not enough for portable deployment. If you sent me + a copy of your application installed in a custom LXC + configuration, it would almost certainly not run on my machine + the way it does on yours, because it is tied to your machine's + specific configuration: networking, storage, logging, distro, + etc. Docker defines an abstraction for these machine-specific + settings, so that the exact same Docker container can run - + unchanged - on many different machines, with many different + configurations. + + * *Application-centric.* + Docker is optimized for the deployment of applications, as + opposed to machines. This is reflected in its API, user + interface, design philosophy and documentation. By contrast, the + ``lxc`` helper scripts focus on containers as lightweight + machines - basically servers that boot faster and need less + RAM. We think there's more to containers than just that. + + * *Automatic build.* + Docker includes :ref:`a tool for developers to automatically + assemble a container from their source code `, + with full control over application dependencies, build tools, + packaging etc. They are free to use ``make, maven, chef, puppet, + salt,`` Debian packages, RPMs, source tarballs, or any + combination of the above, regardless of the configuration of the + machines. + + * *Versioning.* + Docker includes git-like capabilities for tracking successive + versions of a container, inspecting the diff between versions, + committing new versions, rolling back etc. The history also + includes how a container was assembled and by whom, so you get + full traceability from the production server all the way back to + the upstream developer. Docker also implements incremental + uploads and downloads, similar to ``git pull``, so new versions + of a container can be transferred by only sending diffs. + + * *Component re-use.* + Any container can be used as a :ref:`"base image" + ` to create more specialized components. This + can be done manually or as part of an automated build. For + example you can prepare the ideal Python environment, and use it + as a base for 10 different applications. Your ideal Postgresql + setup can be re-used for all your future projects. And so on. + + * *Sharing.* + Docker has access to a `public registry + `_ where thousands of people have + uploaded useful containers: anything from Redis, CouchDB, + Postgres to IRC bouncers to Rails app servers to Hadoop to base + images for various Linux distros. The :ref:`registry + ` also includes an official "standard + library" of useful containers maintained by the Docker team. The + registry itself is open-source, so anyone can deploy their own + registry to store and transfer private containers, for internal + server deployments for example. + + * *Tool ecosystem.* + Docker defines an API for automating and customizing the + creation and deployment of containers. There are a huge number + of tools integrating with Docker to extend its + capabilities. PaaS-like deployment (Dokku, Deis, Flynn), + multi-node orchestration (Maestro, Salt, Mesos, Openstack Nova), + management dashboards (docker-ui, Openstack Horizon, Shipyard), + configuration management (Chef, Puppet), continuous integration + (Jenkins, Strider, Travis), etc. Docker is rapidly establishing + itself as the standard for container-based tooling. + +Can I help by adding some questions and answers? +................................................ Definitely! You can fork `the repo`_ and edit the documentation sources. -42. **Where can I find more answers?** +Where can I find more answers? +.............................. You can find more answers on: - * `Docker club mailinglist`_ + * `Docker user mailinglist`_ + * `Docker developer mailinglist`_ * `IRC, docker on freenode`_ * `Github`_ * `Ask questions on Stackoverflow`_ * `Join the conversation on Twitter`_ - .. _Docker club mailinglist: https://groups.google.com/d/forum/docker-club + .. _Docker user mailinglist: https://groups.google.com/d/forum/docker-user + .. _Docker developer mailinglist: https://groups.google.com/d/forum/docker-dev .. _the repo: http://www.github.com/dotcloud/docker .. _IRC, docker on freenode: irc://chat.freenode.net#docker .. _Github: http://www.github.com/dotcloud/docker diff --git a/components/engine/docs/sources/use/builder.rst b/components/engine/docs/sources/use/builder.rst index d111e335ab..293ad32063 100644 --- a/components/engine/docs/sources/use/builder.rst +++ b/components/engine/docs/sources/use/builder.rst @@ -2,6 +2,8 @@ :description: Dockerfiles use a simple DSL which allows you to automate the steps you would normally manually take to create an image. :keywords: builder, docker, Dockerfile, automation, image creation +.. _dockerbuilder: + ================== Dockerfile Builder ================== From f97e8fc164cc8ad43f595ef3c8649806c7757d2b Mon Sep 17 00:00:00 2001 From: Thatcher Peskens Date: Tue, 13 Aug 2013 16:18:32 -0700 Subject: [PATCH 31/55] [docs] Some user-friendly changes to the documentation. - Added parmalinks (closes #1527) - Changed the 'fork us on github' button to 'Edit this page on github', so people can edit quickly (closes #1532) - Changed the favicon Upstream-commit: f14db4934605235bd77e9d1dc22377ca710e4c7b Component: engine --- components/engine/docs/sources/conf.py | 5 ++--- .../engine/docs/theme/docker/layout.html | 4 ++-- .../docs/theme/docker/static/css/main.css | 16 ++++++++++++++++ .../docs/theme/docker/static/css/main.less | 18 ++++++++++++++++++ .../docs/theme/docker/static/favicon.png | Bin 404 -> 1475 bytes 5 files changed, 38 insertions(+), 5 deletions(-) diff --git a/components/engine/docs/sources/conf.py b/components/engine/docs/sources/conf.py index b4c23f0c58..9342ab503a 100644 --- a/components/engine/docs/sources/conf.py +++ b/components/engine/docs/sources/conf.py @@ -18,7 +18,7 @@ import sys, os # documentation root, use os.path.abspath to make it absolute, like shown here. #sys.path.insert(0, os.path.abspath('.')) -# -- General configuration ----------------------------------------------------- +# -- General configuratiofn ----------------------------------------------------- @@ -52,8 +52,7 @@ source_suffix = '.rst' #source_encoding = 'utf-8-sig' #disable the parmalinks on headers, I find them really annoying -html_add_permalinks = None - +html_add_permalinks = u'¶' # The master toctree document. master_doc = 'toctree' diff --git a/components/engine/docs/theme/docker/layout.html b/components/engine/docs/theme/docker/layout.html index d6bfff79ba..2b7796628f 100755 --- a/components/engine/docs/theme/docker/layout.html +++ b/components/engine/docs/theme/docker/layout.html @@ -70,8 +70,8 @@