From e0c6a8e8bb4343d85eb04095e61f9d22e911f575 Mon Sep 17 00:00:00 2001 From: Victor Vieux Date: Mon, 13 May 2013 15:10:26 +0200 Subject: [PATCH 01/25] add sizes in images and containers Upstream-commit: a91b710961b74341543a81b9d16f66d65b1907f1 Component: engine --- components/engine/api_params.go | 16 ++++++++++------ components/engine/api_test.go | 2 +- components/engine/commands.go | 13 +++++++++---- components/engine/container.go | 24 ++++++++++++++++++++++++ components/engine/graph.go | 9 +++++++++ components/engine/image.go | 24 ++++++++++++++++++++++++ components/engine/server.go | 5 +++++ components/engine/utils.go | 23 +++++++++++++++++++++++ 8 files changed, 105 insertions(+), 11 deletions(-) diff --git a/components/engine/api_params.go b/components/engine/api_params.go index c7c15585f9..c4942b50e1 100644 --- a/components/engine/api_params.go +++ b/components/engine/api_params.go @@ -11,6 +11,8 @@ type ApiImages struct { Tag string `json:",omitempty"` Id string Created int64 `json:",omitempty"` + Size int64 + ParentSize int64 } type ApiInfo struct { @@ -24,12 +26,14 @@ type ApiInfo struct { } type ApiContainers struct { - Id string - Image string `json:",omitempty"` - Command string `json:",omitempty"` - Created int64 `json:",omitempty"` - Status string `json:",omitempty"` - Ports string `json:",omitempty"` + Id string + Image string `json:",omitempty"` + Command string `json:",omitempty"` + Created int64 `json:",omitempty"` + Status string `json:",omitempty"` + Ports string `json:",omitempty"` + SizeRw int64 + SizeRootFs int64 } type ApiSearch struct { diff --git a/components/engine/api_test.go b/components/engine/api_test.go index 68e60adc21..2128f3ef35 100644 --- a/components/engine/api_test.go +++ b/components/engine/api_test.go @@ -1194,7 +1194,7 @@ func TestDeleteContainers(t *testing.T) { func TestDeleteImages(t *testing.T) { //FIXME: Implement this test - t.Skip("Test not implemented") + t.Log("Test not implemented") } // Mocked types for tests diff --git a/components/engine/commands.go b/components/engine/commands.go index dc3f8c4e87..736aee2f7a 100644 --- a/components/engine/commands.go +++ b/components/engine/commands.go @@ -728,12 +728,12 @@ func CmdImages(args ...string) error { w := tabwriter.NewWriter(os.Stdout, 20, 1, 3, ' ', 0) if !*quiet { - fmt.Fprintln(w, "REPOSITORY\tTAG\tID\tCREATED") + fmt.Fprintln(w, "REPOSITORY\tTAG\tID\tCREATED\tSIZE") } for _, out := range outs { if !*quiet { - fmt.Fprintf(w, "%s\t%s\t%s\t%s ago\n", out.Repository, out.Tag, out.Id, HumanDuration(time.Now().Sub(time.Unix(out.Created, 0)))) + fmt.Fprintf(w, "%s\t%s\t%s\t%s ago\t%s (virtual %s)\n", out.Repository, out.Tag, out.Id, HumanDuration(time.Now().Sub(time.Unix(out.Created, 0))), HumanSize(out.Size), HumanSize(out.ParentSize)) } else { fmt.Fprintln(w, out.Id) } @@ -794,12 +794,17 @@ func CmdPs(args ...string) error { } w := tabwriter.NewWriter(os.Stdout, 20, 1, 3, ' ', 0) if !*quiet { - fmt.Fprintln(w, "ID\tIMAGE\tCOMMAND\tCREATED\tSTATUS\tPORTS") + fmt.Fprintln(w, "ID\tIMAGE\tCOMMAND\tCREATED\tSTATUS\tPORTS\tSIZE") } for _, out := range outs { if !*quiet { - fmt.Fprintf(w, "%s\t%s\t%s\t%s\t%s ago\t%s\n", out.Id, out.Image, out.Command, out.Status, HumanDuration(time.Now().Sub(time.Unix(out.Created, 0))), out.Ports) + fmt.Fprintf(w, "%s\t%s\t%s\t%s\t%s ago\t%s\t", out.Id, out.Image, out.Command, out.Status, HumanDuration(time.Now().Sub(time.Unix(out.Created, 0))), out.Ports) + if out.SizeRootFs > 0 { + fmt.Fprintf(w, "%s (virtual %s)\n", HumanSize(out.SizeRw), HumanSize(out.SizeRootFs)) + } else { + fmt.Fprintf(w, "%s\n", HumanSize(out.SizeRw)) + } } else { fmt.Fprintln(w, out.Id) } diff --git a/components/engine/container.go b/components/engine/container.go index c49441e5da..8ccdfb2a43 100644 --- a/components/engine/container.go +++ b/components/engine/container.go @@ -11,6 +11,7 @@ import ( "os" "os/exec" "path" + "path/filepath" "sort" "strconv" "strings" @@ -879,3 +880,26 @@ func validateId(id string) error { } return nil } + +// GetSize, return real size, virtual size +func (container *Container) GetSize() (int64, int64) { + var sizeRw, sizeRootfs int64 + + filepath.Walk(container.rwPath(), func(path string, fileInfo os.FileInfo, err error) error { + if fileInfo != nil { + sizeRw += fileInfo.Size() + } + return nil + }) + + _, err := os.Stat(container.RootfsPath()) + if err == nil { + filepath.Walk(container.RootfsPath(), func(path string, fileInfo os.FileInfo, err error) error { + if fileInfo != nil { + sizeRootfs += fileInfo.Size() + } + return nil + }) + } + return sizeRw, sizeRootfs +} diff --git a/components/engine/graph.go b/components/engine/graph.go index d9b4f5ac5c..b4a0b57504 100644 --- a/components/engine/graph.go +++ b/components/engine/graph.go @@ -89,6 +89,15 @@ func (graph *Graph) Get(name string) (*Image, error) { if img.Id != id { return nil, fmt.Errorf("Image stored at '%s' has wrong id '%s'", id, img.Id) } + if img.Size == 0 { + root, err := img.root() + if err != nil { + return nil, err + } + if err := StoreSize(img, root); err != nil { + return nil, err + } + } img.graph = graph graph.lockSumMap.Lock() defer graph.lockSumMap.Unlock() diff --git a/components/engine/image.go b/components/engine/image.go index 413d95673b..76ebdab33d 100644 --- a/components/engine/image.go +++ b/components/engine/image.go @@ -12,6 +12,7 @@ import ( "os" "os/exec" "path" + "path/filepath" "strings" "time" ) @@ -27,6 +28,8 @@ type Image struct { Author string `json:"author,omitempty"` Config *Config `json:"config,omitempty"` graph *Graph + Size int64 + ParentSize int64 } func LoadImage(root string) (*Image, error) { @@ -93,6 +96,18 @@ func StoreImage(img *Image, layerData Archive, root string, store bool) error { if err := Untar(layerData, layer); err != nil { return err } + + return StoreSize(img, root) +} + +func StoreSize(img *Image, root string) error { + layer := layerPath(root) + + filepath.Walk(layer, func(path string, fileInfo os.FileInfo, err error) error { + img.Size += fileInfo.Size() + return nil + }) + // Store the json ball jsonData, err := json.Marshal(img) if err != nil { @@ -359,3 +374,12 @@ func (img *Image) Checksum() (string, error) { return hash, nil } + +func (img *Image) getVirtualSize(size int64) int64 { + parentImage, err := img.GetParent() + if err != nil || parentImage == nil { + return size + } + size += parentImage.Size + return parentImage.getVirtualSize(size) +} diff --git a/components/engine/server.go b/components/engine/server.go index e96497bff3..cb030fcfa0 100644 --- a/components/engine/server.go +++ b/components/engine/server.go @@ -164,6 +164,8 @@ func (srv *Server) Images(all, only_ids bool, filter string) ([]ApiImages, error out.Tag = tag out.Id = TruncateId(id) out.Created = image.Created.Unix() + out.Size = image.Size + out.ParentSize = image.getVirtualSize(0) } else { out.Id = image.ShortId() } @@ -179,6 +181,8 @@ func (srv *Server) Images(all, only_ids bool, filter string) ([]ApiImages, error out.Tag = "" out.Id = TruncateId(id) out.Created = image.Created.Unix() + out.Size = image.Size + out.ParentSize = image.getVirtualSize(0) } else { out.Id = image.ShortId() } @@ -280,6 +284,7 @@ func (srv *Server) Containers(all, trunc_cmd, only_ids bool, n int, since, befor c.Created = container.Created.Unix() c.Status = container.State.String() c.Ports = container.NetworkSettings.PortMappingHuman() + c.SizeRw, c.SizeRootFs = container.GetSize() } retContainers = append(retContainers, c) } diff --git a/components/engine/utils.go b/components/engine/utils.go index 4b416cd1e6..5daf3a3c3d 100644 --- a/components/engine/utils.go +++ b/components/engine/utils.go @@ -16,6 +16,7 @@ import ( "os/signal" "path/filepath" "runtime" + _ "strconv" "strings" "sync" "time" @@ -133,6 +134,28 @@ func HumanDuration(d time.Duration) string { return fmt.Sprintf("%d years", d.Hours()/24/365) } +// HumanSize returns a human-readabla approximation of a size +// (eg. "44K", "17M") +func HumanSize(size int64) string { + i := 0 + var sizef float64 + sizef = float64(size) + units := []string{"B", "kB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"} + for sizef > 1024.0 { + sizef = sizef / 1024.0 + i++ + } + return fmt.Sprintf("%.*f %s", i, sizef, units[i]) + // sprintf(buf, "%.*f %s", i, size, units[i]); + // if size/1024/1024 > 1000 { + // return strconv.FormatFloat((float64)(size/1024/1024), 'f', 2, 32) + "G" + // } + // if size/1024 > 1024 { + // return strconv.FormatInt(size/1024/1024, 10) + "M" + // } + // return strconv.FormatInt(size/1024, 10) + "K" +} + func Trunc(s string, maxlen int) string { if len(s) <= maxlen { return s From 62817c64abb1a8e3d8e129c8ba1f1beb3a1d168e Mon Sep 17 00:00:00 2001 From: Victor Vieux Date: Wed, 15 May 2013 02:41:19 +0200 Subject: [PATCH 02/25] add 4243 port forward Upstream-commit: c75942c79da708a350c4a9cf32a5f06f8ca1ab7c Component: engine --- components/engine/Vagrantfile | 1 + 1 file changed, 1 insertion(+) diff --git a/components/engine/Vagrantfile b/components/engine/Vagrantfile index 3d568266af..f5fca10f45 100644 --- a/components/engine/Vagrantfile +++ b/components/engine/Vagrantfile @@ -10,6 +10,7 @@ Vagrant::Config.run do |config| # Setup virtual machine box. This VM configuration code is always executed. config.vm.box = BOX_NAME config.vm.box_url = BOX_URI + config.vm.forward_port 4243, 4243 # Provision docker and new kernel if deployment was not done if Dir.glob("#{File.dirname(__FILE__)}/.vagrant/machines/default/*/id").empty? From 22c50f73c6539c8a2f2d6da11d29509ea0432391 Mon Sep 17 00:00:00 2001 From: Victor Vieux Date: Tue, 21 May 2013 12:53:05 +0000 Subject: [PATCH 03/25] add regexp check on repo's name Upstream-commit: 4489005cb2f11fe6e2dcdb181b4834791de3b73f Component: engine --- components/engine/commands.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/components/engine/commands.go b/components/engine/commands.go index 5e459a1d94..98e665cd40 100644 --- a/components/engine/commands.go +++ b/components/engine/commands.go @@ -17,6 +17,7 @@ import ( "os" "path/filepath" "reflect" + "regexp" "strconv" "strings" "text/tabwriter" @@ -641,6 +642,10 @@ func (cli *DockerCli) CmdPush(args ...string) error { if len(strings.SplitN(name, "/", 2)) == 1 { return fmt.Errorf("Impossible to push a \"root\" repository. Please rename your repository in / (ex: %s/%s)", out.Username, name) } + validRepo := regexp.MustCompile(`^([a-z0-9]{4,30})/([a-z0-9-.]+)$`) + if !validRepo.MatchString(name) { + return fmt.Errorf("Invalid repository name, only alphanum, - and . are allowed") + } v := url.Values{} v.Set("registry", *registry) From 87ab4000addac74e18feda383110ca9e71db2914 Mon Sep 17 00:00:00 2001 From: Victor Vieux Date: Thu, 23 May 2013 09:35:20 +0000 Subject: [PATCH 04/25] fix typo Upstream-commit: ed56b6a905d5e9f443cb0c5c949965f848abbe8d Component: engine --- components/engine/utils/utils.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/engine/utils/utils.go b/components/engine/utils/utils.go index ec189cb002..360e4ec31b 100644 --- a/components/engine/utils/utils.go +++ b/components/engine/utils/utils.go @@ -132,7 +132,7 @@ func HumanDuration(d time.Duration) string { return fmt.Sprintf("%d years", d.Hours()/24/365) } -// HumanSize returns a human-readabla approximation of a size +// HumanSize returns a human-readable approximation of a size // (eg. "44kB", "17MB") func HumanSize(size int64) string { i := 0 From 183381f196cb3ddccbb43143e2c5c859c16f3e5a Mon Sep 17 00:00:00 2001 From: Victor Vieux Date: Thu, 23 May 2013 10:29:09 +0000 Subject: [PATCH 05/25] switch to SI standard and add test Upstream-commit: b45143da9b275b5003c23667b0988ad93f383b11 Component: engine --- components/engine/utils/utils.go | 9 ++++----- components/engine/utils/utils_test.go | 13 +++++++++++++ 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/components/engine/utils/utils.go b/components/engine/utils/utils.go index 360e4ec31b..170d34dd7a 100644 --- a/components/engine/utils/utils.go +++ b/components/engine/utils/utils.go @@ -133,20 +133,19 @@ func HumanDuration(d time.Duration) string { } // HumanSize returns a human-readable approximation of a size -// (eg. "44kB", "17MB") +// using SI standard (eg. "44kB", "17MB") func HumanSize(size int64) string { i := 0 var sizef float64 sizef = float64(size) units := []string{"B", "kB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"} - for sizef > 1024.0 { - sizef = sizef / 1024.0 + for sizef >= 1000.0 { + sizef = sizef / 1000.0 i++ } - return fmt.Sprintf("%.*f %s", i, sizef, units[i]) + return fmt.Sprintf("%.4g %s", sizef, units[i]) } - func Trunc(s string, maxlen int) string { if len(s) <= maxlen { return s diff --git a/components/engine/utils/utils_test.go b/components/engine/utils/utils_test.go index 4413f44efc..eec06d5134 100644 --- a/components/engine/utils/utils_test.go +++ b/components/engine/utils/utils_test.go @@ -261,3 +261,16 @@ func TestCompareKernelVersion(t *testing.T) { &KernelVersionInfo{Kernel: 3, Major: 8, Minor: 0, Flavor: "0"}, -1) } + +func TestHumanSize(t *testing.T) { + + size1000 := HumanSize(1000) + if size1000 != "1 kB" { + t.Errorf("1000 -> expected 1 kB, got %s", size1000) + } + + size1024 := HumanSize(1024) + if size1024 != "1.024 kB" { + t.Errorf("1024 -> expected 1.024 kB, got %s", size1024) + } +} From 317a0269763e28403bfa7e4d15d2b2e173b4a241 Mon Sep 17 00:00:00 2001 From: Victor Vieux Date: Fri, 24 May 2013 13:03:09 +0000 Subject: [PATCH 06/25] fix: Can't lookup root of unregistered image Upstream-commit: 1c946ef0038a27d134f497ed72352136c0a4bb9e Component: engine --- components/engine/graph.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/engine/graph.go b/components/engine/graph.go index 85a33a32a5..86c12b8f8b 100644 --- a/components/engine/graph.go +++ b/components/engine/graph.go @@ -89,6 +89,7 @@ func (graph *Graph) Get(name string) (*Image, error) { if img.Id != id { return nil, fmt.Errorf("Image stored at '%s' has wrong id '%s'", id, img.Id) } + img.graph = graph if img.Size == 0 { root, err := img.root() if err != nil { @@ -98,7 +99,6 @@ func (graph *Graph) Get(name string) (*Image, error) { return nil, err } } - img.graph = graph graph.lockSumMap.Lock() defer graph.lockSumMap.Unlock() if _, exists := graph.checksumLock[img.Id]; !exists { From 2315df225ece56333c87857fb42e3ef77cdd8ba1 Mon Sep 17 00:00:00 2001 From: Victor Vieux Date: Mon, 3 Jun 2013 14:23:57 +0000 Subject: [PATCH 07/25] ([a-z0-9_]{4,30})/([a-zA-Z0-9-_.]+) Upstream-commit: a55a0d370dfca169e0220a01c292c7d41ad0b557 Component: engine --- components/engine/commands.go | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/components/engine/commands.go b/components/engine/commands.go index 98e665cd40..1ab713ce5d 100644 --- a/components/engine/commands.go +++ b/components/engine/commands.go @@ -642,9 +642,14 @@ func (cli *DockerCli) CmdPush(args ...string) error { if len(strings.SplitN(name, "/", 2)) == 1 { return fmt.Errorf("Impossible to push a \"root\" repository. Please rename your repository in / (ex: %s/%s)", out.Username, name) } - validRepo := regexp.MustCompile(`^([a-z0-9]{4,30})/([a-z0-9-.]+)$`) - if !validRepo.MatchString(name) { - return fmt.Errorf("Invalid repository name, only alphanum, - and . are allowed") + nameParts := strings.SplitN(name, "/", 2) + validNamespace := regexp.MustCompile(`^([a-z0-9_]{4,30})$`) + if !validNamespace.MatchString(nameParts[0]) { + return fmt.Errorf("Invalid namespace name (%s), only [a-z0-9_] are allowed, size between 4 and 30", nameParts[0]) + } + validRepo := regexp.MustCompile(`^([a-zA-Z0-9-_.]+)$`) + if !validRepo.MatchString(nameParts[1]) { + return fmt.Errorf("Invalid repository name (%s), only [a-zA-Z0-9-_.] are allowed", nameParts[1]) } v := url.Values{} From 72a9843fea57bddcd524f7c8bef73a4015837db3 Mon Sep 17 00:00:00 2001 From: "Guillaume J. Charmes" Date: Wed, 5 Jun 2013 14:20:19 -0700 Subject: [PATCH 08/25] Add -dns to docker daemon Upstream-commit: 84d68007cb36b68e1b5c574a0d23fcf583e0d75c Component: engine --- components/engine/builder.go | 12 ++++++++++-- components/engine/docker/docker.go | 11 ++++++++--- components/engine/runtime.go | 4 +++- components/engine/server.go | 4 ++-- components/engine/utils/utils.go | 14 +++++++------- 5 files changed, 30 insertions(+), 15 deletions(-) diff --git a/components/engine/builder.go b/components/engine/builder.go index 808b7efcab..c43f8249fa 100644 --- a/components/engine/builder.go +++ b/components/engine/builder.go @@ -7,6 +7,8 @@ import ( "time" ) +var defaultDns = []string{"8.8.8.8", "8.8.4.4"} + type Builder struct { runtime *Runtime repositories *TagStore @@ -67,14 +69,20 @@ func (builder *Builder) Create(config *Config) (*Container, error) { } // If custom dns exists, then create a resolv.conf for the container - if len(config.Dns) > 0 { + if len(config.Dns) > 0 || len(builder.runtime.Dns) > 0 { + var dns []string + if len(config.Dns) > 0 { + dns = config.Dns + } else { + dns = builder.runtime.Dns + } container.ResolvConfPath = path.Join(container.root, "resolv.conf") f, err := os.Create(container.ResolvConfPath) if err != nil { return nil, err } defer f.Close() - for _, dns := range config.Dns { + for _, dns := range dns { if _, err := f.Write([]byte("nameserver " + dns + "\n")); err != nil { return nil, err } diff --git a/components/engine/docker/docker.go b/components/engine/docker/docker.go index dada16e11e..5ddae40c41 100644 --- a/components/engine/docker/docker.go +++ b/components/engine/docker/docker.go @@ -33,6 +33,11 @@ func main() { bridgeName := flag.String("b", "", "Attach containers to a pre-existing network bridge") pidfile := flag.String("p", "/var/run/docker.pid", "File containing process PID") flHost := flag.String("H", fmt.Sprintf("%s:%d", host, port), "Host:port to bind/connect to") + + flags := flag.NewFlagSet("docker", flag.ContinueOnError) + var flDns docker.ListOpts + flags.Var(&flDns, "dns", "Set custom dns servers") + flag.Parse() if *bridgeName != "" { docker.NetworkBridgeIface = *bridgeName @@ -65,7 +70,7 @@ func main() { flag.Usage() return } - if err := daemon(*pidfile, host, port, *flAutoRestart); err != nil { + if err := daemon(*pidfile, host, port, *flAutoRestart, flDns); err != nil { log.Fatal(err) os.Exit(-1) } @@ -104,7 +109,7 @@ func removePidFile(pidfile string) { } } -func daemon(pidfile, addr string, port int, autoRestart bool) error { +func daemon(pidfile, addr string, port int, autoRestart bool, flDns docker.ListOpts) error { if addr != "127.0.0.1" { log.Println("/!\\ DON'T BIND ON ANOTHER IP ADDRESS THAN 127.0.0.1 IF YOU DON'T KNOW WHAT YOU'RE DOING /!\\") } @@ -122,7 +127,7 @@ func daemon(pidfile, addr string, port int, autoRestart bool) error { os.Exit(0) }() - server, err := docker.NewServer(autoRestart) + server, err := docker.NewServer(autoRestart, flDns) if err != nil { return err } diff --git a/components/engine/runtime.go b/components/engine/runtime.go index 1c22bd085c..c37e292d22 100644 --- a/components/engine/runtime.go +++ b/components/engine/runtime.go @@ -32,6 +32,7 @@ type Runtime struct { autoRestart bool volumes *Graph srv *Server + Dns []string } var sysInitPath string @@ -245,11 +246,12 @@ func (runtime *Runtime) UpdateCapabilities(quiet bool) { } // FIXME: harmonize with NewGraph() -func NewRuntime(autoRestart bool) (*Runtime, error) { +func NewRuntime(autoRestart bool, dns []string) (*Runtime, error) { runtime, err := NewRuntimeFromDirectory("/var/lib/docker", autoRestart) if err != nil { return nil, err } + runtime.Dns = dns if k, err := utils.GetKernelVersion(); err != nil { log.Printf("WARNING: %s\n", err) diff --git a/components/engine/server.go b/components/engine/server.go index 6666123658..31b6f6dfb4 100644 --- a/components/engine/server.go +++ b/components/engine/server.go @@ -869,11 +869,11 @@ func (srv *Server) ImageInspect(name string) (*Image, error) { return nil, fmt.Errorf("No such image: %s", name) } -func NewServer(autoRestart bool) (*Server, error) { +func NewServer(autoRestart bool, dns ListOpts) (*Server, error) { if runtime.GOARCH != "amd64" { log.Fatalf("The docker runtime currently only supports amd64 (not %s). This will change in the future. Aborting.", runtime.GOARCH) } - runtime, err := NewRuntime(autoRestart) + runtime, err := NewRuntime(autoRestart, dns) if err != nil { return nil, err } diff --git a/components/engine/utils/utils.go b/components/engine/utils/utils.go index c3f9e571d3..d91370c44a 100644 --- a/components/engine/utils/utils.go +++ b/components/engine/utils/utils.go @@ -70,7 +70,7 @@ type progressReader struct { readProgress int // How much has been read so far (bytes) lastUpdate int // How many bytes read at least update template string // Template to print. Default "%v/%v (%v)" - sf *StreamFormatter + sf *StreamFormatter } func (r *progressReader) Read(p []byte) (n int, err error) { @@ -103,7 +103,7 @@ func (r *progressReader) Close() error { return io.ReadCloser(r.reader).Close() } func ProgressReader(r io.ReadCloser, size int, output io.Writer, template []byte, sf *StreamFormatter) *progressReader { - tpl := string(template) + tpl := string(template) if tpl == "" { tpl = string(sf.FormatProgress("", "%v/%v (%v)")) } @@ -585,7 +585,7 @@ func (sf *StreamFormatter) FormatStatus(format string, a ...interface{}) []byte sf.used = true str := fmt.Sprintf(format, a...) if sf.json { - b, err := json.Marshal(&JSONMessage{Status:str}); + b, err := json.Marshal(&JSONMessage{Status: str}) if err != nil { return sf.FormatError(err) } @@ -597,7 +597,7 @@ func (sf *StreamFormatter) FormatStatus(format string, a ...interface{}) []byte func (sf *StreamFormatter) FormatError(err error) []byte { sf.used = true if sf.json { - if b, err := json.Marshal(&JSONMessage{Error:err.Error()}); err == nil { + if b, err := json.Marshal(&JSONMessage{Error: err.Error()}); err == nil { return b } return []byte("{\"error\":\"format error\"}") @@ -608,10 +608,10 @@ func (sf *StreamFormatter) FormatError(err error) []byte { func (sf *StreamFormatter) FormatProgress(action, str string) []byte { sf.used = true if sf.json { - b, err := json.Marshal(&JSONMessage{Status: action, Progress:str}) + b, err := json.Marshal(&JSONMessage{Status: action, Progress: str}) if err != nil { - return nil - } + return nil + } return b } return []byte(action + " " + str + "\r") From 082852394691220e509db1da7f531894ff9bca45 Mon Sep 17 00:00:00 2001 From: "Guillaume J. Charmes" Date: Thu, 6 Jun 2013 11:01:09 -0700 Subject: [PATCH 09/25] Check for local dns server and output a warning Upstream-commit: a3f6054f974909458c9e820842310987e225b767 Component: engine --- components/engine/api.go | 13 ++++++++++--- components/engine/builder.go | 6 ++++++ components/engine/utils/utils.go | 17 +++++++++++++++++ 3 files changed, 33 insertions(+), 3 deletions(-) diff --git a/components/engine/api.go b/components/engine/api.go index 5a9bdbbe23..273a0edc3f 100644 --- a/components/engine/api.go +++ b/components/engine/api.go @@ -413,17 +413,23 @@ func postImagesPush(srv *Server, version float64, w http.ResponseWriter, r *http func postContainersCreate(srv *Server, version float64, w http.ResponseWriter, r *http.Request, vars map[string]string) error { config := &Config{} + out := &APIRun{} + if err := json.NewDecoder(r.Body).Decode(config); err != nil { return err } + + if len(config.Dns) == 0 && len(srv.runtime.Dns) == 0 && utils.CheckLocalDns() { + out.Warnings = append(out.Warnings, fmt.Sprintf("WARNING: Docker detected local DNS server on resolv.conf. Using default external servers: %v", defaultDns)) + config.Dns = defaultDns + } + id, err := srv.ContainerCreate(config) if err != nil { return err } + out.ID = id - out := &APIRun{ - ID: id, - } if config.Memory > 0 && !srv.runtime.capabilities.MemoryLimit { log.Println("WARNING: Your kernel does not support memory limit capabilities. Limitation discarded.") out.Warnings = append(out.Warnings, "Your kernel does not support memory limit capabilities. Limitation discarded.") @@ -432,6 +438,7 @@ func postContainersCreate(srv *Server, version float64, w http.ResponseWriter, r log.Println("WARNING: Your kernel does not support swap limit capabilities. Limitation discarded.") out.Warnings = append(out.Warnings, "Your kernel does not support memory swap capabilities. Limitation discarded.") } + b, err := json.Marshal(out) if err != nil { return err diff --git a/components/engine/builder.go b/components/engine/builder.go index c43f8249fa..02c51fb557 100644 --- a/components/engine/builder.go +++ b/components/engine/builder.go @@ -2,6 +2,7 @@ package docker import ( "fmt" + "github.com/dotcloud/docker/utils" "os" "path" "time" @@ -68,6 +69,11 @@ func (builder *Builder) Create(config *Config) (*Container, error) { return nil, err } + if len(config.Dns) == 0 && len(builder.runtime.Dns) == 0 && utils.CheckLocalDns() { + //"WARNING: Docker detected local DNS server on resolv.conf. Using default external servers: %v", defaultDns + builder.runtime.Dns = defaultDns + } + // If custom dns exists, then create a resolv.conf for the container if len(config.Dns) > 0 || len(builder.runtime.Dns) > 0 { var dns []string diff --git a/components/engine/utils/utils.go b/components/engine/utils/utils.go index d91370c44a..1c4c62eaa3 100644 --- a/components/engine/utils/utils.go +++ b/components/engine/utils/utils.go @@ -620,3 +620,20 @@ func (sf *StreamFormatter) FormatProgress(action, str string) []byte { func (sf *StreamFormatter) Used() bool { return sf.used } + +func CheckLocalDns() bool { + resolv, err := ioutil.ReadFile("/etc/resolv.conf") + if err != nil { + Debugf("Error openning resolv.conf: %s", err) + return false + } + for _, ip := range []string{ + "127.0.0.1", + "127.0.1.1", + } { + if strings.Contains(string(resolv), ip) { + return true + } + } + return false +} From 161e18641733117e456212bc1a6fdcd089f6dfde Mon Sep 17 00:00:00 2001 From: "Guillaume J. Charmes" Date: Thu, 6 Jun 2013 11:01:29 -0700 Subject: [PATCH 10/25] Solve an issue with the -dns in daemon mode Upstream-commit: afd325a8845ad7c4846747fb9561df12ebf9963a Component: engine --- components/engine/docker/docker.go | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/components/engine/docker/docker.go b/components/engine/docker/docker.go index 5ddae40c41..ac7bb06823 100644 --- a/components/engine/docker/docker.go +++ b/components/engine/docker/docker.go @@ -33,10 +33,7 @@ func main() { bridgeName := flag.String("b", "", "Attach containers to a pre-existing network bridge") pidfile := flag.String("p", "/var/run/docker.pid", "File containing process PID") flHost := flag.String("H", fmt.Sprintf("%s:%d", host, port), "Host:port to bind/connect to") - - flags := flag.NewFlagSet("docker", flag.ContinueOnError) - var flDns docker.ListOpts - flags.Var(&flDns, "dns", "Set custom dns servers") + flDns := flag.String("dns", "", "Set custom dns servers") flag.Parse() if *bridgeName != "" { @@ -70,7 +67,7 @@ func main() { flag.Usage() return } - if err := daemon(*pidfile, host, port, *flAutoRestart, flDns); err != nil { + if err := daemon(*pidfile, host, port, *flAutoRestart, *flDns); err != nil { log.Fatal(err) os.Exit(-1) } @@ -109,7 +106,7 @@ func removePidFile(pidfile string) { } } -func daemon(pidfile, addr string, port int, autoRestart bool, flDns docker.ListOpts) error { +func daemon(pidfile, addr string, port int, autoRestart bool, flDns string) error { if addr != "127.0.0.1" { log.Println("/!\\ DON'T BIND ON ANOTHER IP ADDRESS THAN 127.0.0.1 IF YOU DON'T KNOW WHAT YOU'RE DOING /!\\") } @@ -126,8 +123,11 @@ func daemon(pidfile, addr string, port int, autoRestart bool, flDns docker.ListO removePidFile(pidfile) os.Exit(0) }() - - server, err := docker.NewServer(autoRestart, flDns) + var dns []string + if flDns != "" { + dns = []string{flDns} + } + server, err := docker.NewServer(autoRestart, dns) if err != nil { return err } From c81b1a9b0456739af50668a53dab590ebcf3d25d Mon Sep 17 00:00:00 2001 From: Calen Pennington Date: Fri, 7 Jun 2013 15:56:39 -0400 Subject: [PATCH 11/25] Add an option to forward all ports to the vagrant host that have been exported from docker containers Upstream-commit: 302660e362ba36f9966b9a70b7d7284b94afb89d Component: engine --- components/engine/Vagrantfile | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/components/engine/Vagrantfile b/components/engine/Vagrantfile index 3d568266af..1688bd5211 100644 --- a/components/engine/Vagrantfile +++ b/components/engine/Vagrantfile @@ -5,6 +5,7 @@ BOX_NAME = ENV['BOX_NAME'] || "ubuntu" BOX_URI = ENV['BOX_URI'] || "http://files.vagrantup.com/precise64.box" AWS_REGION = ENV['AWS_REGION'] || "us-east-1" AWS_AMI = ENV['AWS_AMI'] || "ami-d0f89fb9" +FORWARD_DOCKER_PORTS = ENV['FORWARD_DOCKER_PORTS'] Vagrant::Config.run do |config| # Setup virtual machine box. This VM configuration code is always executed. @@ -70,3 +71,17 @@ Vagrant::VERSION >= "1.1.0" and Vagrant.configure("2") do |config| config.vm.box_url = BOX_URI end end + +if !FORWARD_DOCKER_PORTS.nil? + Vagrant::VERSION < "1.1.0" and Vagrant::Config.run do |config| + (49000..49900).each do |port| + config.vm.forward_port port, port + end + end + + Vagrant::VERSION >= "1.1.0" and Vagrant.configure("2") do |config| + (49000..49900).each do |port| + config.vm.network :forwarded_port, :host => port, :guest => port + end + end +end From 398ed3eba04467f12e1ae8deffebf9ebe2284db3 Mon Sep 17 00:00:00 2001 From: shin- Date: Mon, 10 Jun 2013 11:21:56 -0700 Subject: [PATCH 12/25] Send X-Docker-Endpoints header when validating the images upload with the index at the end of a push Upstream-commit: db3242e4bb1c31a7319e6273235a9ba6b29a61d4 Component: engine --- components/engine/registry/registry.go | 9 +++++++-- components/engine/server.go | 4 ++-- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/components/engine/registry/registry.go b/components/engine/registry/registry.go index bd5c6b79c6..0ae37f7a9d 100644 --- a/components/engine/registry/registry.go +++ b/components/engine/registry/registry.go @@ -328,7 +328,7 @@ func (r *Registry) PushRegistryTag(remote, revision, tag, registry string, token return nil } -func (r *Registry) PushImageJSONIndex(remote string, imgList []*ImgData, validate bool) (*RepositoryData, error) { +func (r *Registry) PushImageJSONIndex(remote string, imgList []*ImgData, validate bool, regs []string) (*RepositoryData, error) { imgListJSON, err := json.Marshal(imgList) if err != nil { return nil, err @@ -347,6 +347,9 @@ func (r *Registry) PushImageJSONIndex(remote string, imgList []*ImgData, validat req.SetBasicAuth(r.authConfig.Username, r.authConfig.Password) req.ContentLength = int64(len(imgListJSON)) req.Header.Set("X-Docker-Token", "true") + if validate { + req.Header["X-Docker-Endpoints"] = regs + } res, err := r.client.Do(req) if err != nil { @@ -364,7 +367,9 @@ func (r *Registry) PushImageJSONIndex(remote string, imgList []*ImgData, validat req.SetBasicAuth(r.authConfig.Username, r.authConfig.Password) req.ContentLength = int64(len(imgListJSON)) req.Header.Set("X-Docker-Token", "true") - + if validate { + req.Header["X-Docker-Endpoints"] = regs + } res, err = r.client.Do(req) if err != nil { return nil, err diff --git a/components/engine/server.go b/components/engine/server.go index 6666123658..7cac30ae35 100644 --- a/components/engine/server.go +++ b/components/engine/server.go @@ -489,7 +489,7 @@ func (srv *Server) pushRepository(r *registry.Registry, out io.Writer, name stri } out.Write(sf.FormatStatus("Sending image list")) - repoData, err := r.PushImageJSONIndex(name, imgList, false) + repoData, err := r.PushImageJSONIndex(name, imgList, false, nil) if err != nil { return err } @@ -513,7 +513,7 @@ func (srv *Server) pushRepository(r *registry.Registry, out io.Writer, name stri } } - if _, err := r.PushImageJSONIndex(name, imgList, true); err != nil { + if _, err := r.PushImageJSONIndex(name, imgList, true, repoData.Endpoints); err != nil { return err } return nil From 5bf955bfcc245bc7e8a4a5577ba8dd05ef6a7f36 Mon Sep 17 00:00:00 2001 From: Victor Vieux Date: Fri, 14 Jun 2013 10:05:01 +0000 Subject: [PATCH 13/25] fix virtual size on images Upstream-commit: 00cf2a1fa264c167dff0dd50e296c93d4c59908f Component: engine --- components/engine/api_params.go | 23 +++++++++++------------ components/engine/commands.go | 4 ++-- components/engine/image.go | 5 ++--- components/engine/server.go | 4 ++-- 4 files changed, 17 insertions(+), 19 deletions(-) diff --git a/components/engine/api_params.go b/components/engine/api_params.go index 96a731c98f..9a689a04c3 100644 --- a/components/engine/api_params.go +++ b/components/engine/api_params.go @@ -7,13 +7,12 @@ type APIHistory struct { } type APIImages struct { - Repository string `json:",omitempty"` - Tag string `json:",omitempty"` - ID string `json:"Id"` - Created int64 - Size int64 - ParentSize int64 - + Repository string `json:",omitempty"` + Tag string `json:",omitempty"` + ID string `json:"Id"` + Created int64 + Size int64 + VirtualSize int64 } type APIInfo struct { @@ -28,11 +27,11 @@ type APIInfo struct { type APIContainers struct { ID string `json:"Id"` - Image string - Command string - Created int64 - Status string - Ports string + Image string + Command string + Created int64 + Status string + Ports string SizeRw int64 SizeRootFs int64 } diff --git a/components/engine/commands.go b/components/engine/commands.go index 1278892117..326a436ce2 100644 --- a/components/engine/commands.go +++ b/components/engine/commands.go @@ -812,8 +812,8 @@ func (cli *DockerCli) CmdImages(args ...string) error { fmt.Fprintf(w, "%s\t", utils.TruncateID(out.ID)) } fmt.Fprintf(w, "%s ago\t", utils.HumanDuration(time.Now().Sub(time.Unix(out.Created, 0)))) - if out.ParentSize > 0 { - fmt.Fprintf(w, "%s (virtual %s)\n", utils.HumanSize(out.Size), utils.HumanSize(out.ParentSize)) + if out.VirtualSize > 0 { + fmt.Fprintf(w, "%s (virtual %s)\n", utils.HumanSize(out.Size), utils.HumanSize(out.VirtualSize)) } else { fmt.Fprintf(w, "%s\n", utils.HumanSize(out.Size)) } diff --git a/components/engine/image.go b/components/engine/image.go index f19667e7ec..8d4c42e733 100644 --- a/components/engine/image.go +++ b/components/engine/image.go @@ -31,7 +31,6 @@ type Image struct { Architecture string `json:"architecture,omitempty"` graph *Graph Size int64 - ParentSize int64 } func LoadImage(root string) (*Image, error) { @@ -376,13 +375,13 @@ func (img *Image) Checksum() (string, error) { return hash, nil } -func (img *Image) getVirtualSize(size int64) int64 { +func (img *Image) getParentsSize(size int64) int64 { parentImage, err := img.GetParent() if err != nil || parentImage == nil { return size } size += parentImage.Size - return parentImage.getVirtualSize(size) + return parentImage.getParentsSize(size) } // Build an Image object from raw json data diff --git a/components/engine/server.go b/components/engine/server.go index efd2850079..5e1459a861 100644 --- a/components/engine/server.go +++ b/components/engine/server.go @@ -177,7 +177,7 @@ func (srv *Server) Images(all bool, filter string) ([]APIImages, error) { out.ID = image.ID out.Created = image.Created.Unix() out.Size = image.Size - out.ParentSize = image.getVirtualSize(0) + out.VirtualSize = image.getParentsSize(0) + image.Size outs = append(outs, out) } } @@ -188,7 +188,7 @@ func (srv *Server) Images(all bool, filter string) ([]APIImages, error) { out.ID = image.ID out.Created = image.Created.Unix() out.Size = image.Size - out.ParentSize = image.getVirtualSize(0) + out.VirtualSize = image.getParentsSize(0) + image.Size outs = append(outs, out) } } From b78bf5bb715a4b8189e886a25aedbf5f81d407a8 Mon Sep 17 00:00:00 2001 From: Victor Vieux Date: Fri, 14 Jun 2013 10:10:26 +0000 Subject: [PATCH 14/25] update docs Upstream-commit: e49f82b9e1a920c902c1cd813596dc1a78817e63 Component: engine --- .../sources/api/docker_remote_api_v1.2.rst | 31 ++++++++++++++----- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/components/engine/docs/sources/api/docker_remote_api_v1.2.rst b/components/engine/docs/sources/api/docker_remote_api_v1.2.rst index 8354760e2f..fb69168120 100644 --- a/components/engine/docs/sources/api/docker_remote_api_v1.2.rst +++ b/components/engine/docs/sources/api/docker_remote_api_v1.2.rst @@ -47,28 +47,40 @@ List containers "Image": "base:latest", "Command": "echo 1", "Created": 1367854155, - "Status": "Exit 0" + "Status": "Exit 0", + "Ports":"", + "SizeRw":12288, + "SizeRootFs":0 }, { "Id": "9cd87474be90", "Image": "base:latest", "Command": "echo 222222", "Created": 1367854155, - "Status": "Exit 0" + "Status": "Exit 0", + "Ports":"", + "SizeRw":12288, + "SizeRootFs":0 }, { "Id": "3176a2479c92", "Image": "base:latest", "Command": "echo 3333333333333333", "Created": 1367854154, - "Status": "Exit 0" + "Status": "Exit 0", + "Ports":"", + "SizeRw":12288, + "SizeRootFs":0 }, { "Id": "4cb07b47f9fb", "Image": "base:latest", "Command": "echo 444444444444444444444444444444444", "Created": 1367854152, - "Status": "Exit 0" + "Status": "Exit 0", + "Ports":"", + "SizeRw":12288, + "SizeRootFs":0 } ] @@ -488,13 +500,17 @@ List Images "Repository":"base", "Tag":"ubuntu-12.10", "Id":"b750fe79269d", - "Created":1364102658 + "Created":1364102658, + "Size":24653, + "VirtualSize":180116135 }, { "Repository":"base", "Tag":"ubuntu-quantal", "Id":"b750fe79269d", - "Created":1364102658 + "Created":1364102658, + "Size":24653, + "VirtualSize":180116135 } ] @@ -643,7 +659,8 @@ Inspect an image "Image":"base", "Volumes":null, "VolumesFrom":"" - } + }, + "Size": 6824592 } :statuscode 200: no error From d7771969bfc5969c9aecf83973d413f6dd1629c4 Mon Sep 17 00:00:00 2001 From: unclejack Date: Fri, 14 Jun 2013 19:46:04 +0300 Subject: [PATCH 15/25] validate memory limits & error out if less than 512 KB Upstream-commit: 9ee11161bf0c635a0b0164ae1dee806c6fcfe7b7 Component: engine --- components/engine/server.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/components/engine/server.go b/components/engine/server.go index 34d525a35a..330c9fbb89 100644 --- a/components/engine/server.go +++ b/components/engine/server.go @@ -652,6 +652,10 @@ func (srv *Server) ImageImport(src, repo, tag string, in io.Reader, out io.Write func (srv *Server) ContainerCreate(config *Config) (string, error) { + if config.Memory != 0 && config.Memory < 524288 { + return "", fmt.Errorf("Memory limit must be given in bytes (minimum 524288 bytes)") + } + if config.Memory > 0 && !srv.runtime.capabilities.MemoryLimit { config.Memory = 0 } From 5f39923376d91dd1eb87bf1e35b9abb5523f6df6 Mon Sep 17 00:00:00 2001 From: unclejack Date: Tue, 4 Jun 2013 21:30:47 +0300 Subject: [PATCH 16/25] run auplink before unmounting aufs Upstream-commit: 2f67a62b5b48862948b1ce92aeffbb83c3707ee0 Component: engine --- components/engine/mount.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/components/engine/mount.go b/components/engine/mount.go index bb1a40eddb..541c29c13a 100644 --- a/components/engine/mount.go +++ b/components/engine/mount.go @@ -2,13 +2,18 @@ package docker import ( "fmt" + "github.com/dotcloud/docker/utils" "os" + "os/exec" "path/filepath" "syscall" "time" ) func Unmount(target string) error { + if err := exec.Command("auplink", target, "flush").Run(); err != nil { + utils.Debugf("[warning]: couldn't run auplink before unmount: %s", err) + } if err := syscall.Unmount(target, 0); err != nil { return err } From 1ee51a2d561e5f12f243b6a14215e8e43b039f0c Mon Sep 17 00:00:00 2001 From: unclejack Date: Tue, 4 Jun 2013 21:35:41 +0300 Subject: [PATCH 17/25] add aufs-tools to lxc-docker dependencies Upstream-commit: e53721ef69b13365c18c9189145ae1fadb931f01 Component: engine --- components/engine/packaging/debian/control | 2 +- components/engine/packaging/ubuntu/control | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/components/engine/packaging/debian/control b/components/engine/packaging/debian/control index 35a2a28cd1..62a963f59e 100644 --- a/components/engine/packaging/debian/control +++ b/components/engine/packaging/debian/control @@ -10,7 +10,7 @@ Homepage: http://github.com/dotcloud/docker Package: lxc-docker Architecture: linux-any -Depends: ${shlibs:Depends}, ${misc:Depends}, lxc, bsdtar +Depends: ${shlibs:Depends}, ${misc:Depends}, lxc, bsdtar, aufs-tools Description: Linux container runtime Docker complements LXC with a high-level API which operates at the process level. It runs unix processes with strong guarantees of isolation and diff --git a/components/engine/packaging/ubuntu/control b/components/engine/packaging/ubuntu/control index b0560ebf70..404f38a16d 100644 --- a/components/engine/packaging/ubuntu/control +++ b/components/engine/packaging/ubuntu/control @@ -8,7 +8,7 @@ Homepage: http://github.com/dotcloud/docker Package: lxc-docker Architecture: linux-any -Depends: ${misc:Depends},${shlibs:Depends},lxc,bsdtar +Depends: ${misc:Depends},${shlibs:Depends},lxc,bsdtar,aufs-tools Conflicts: docker Description: lxc-docker is a Linux container runtime Docker complements LXC with a high-level API which operates at the process From 1d89b8f78f0063acd102be09ee2993e489e51edf Mon Sep 17 00:00:00 2001 From: unclejack Date: Fri, 14 Jun 2013 15:07:43 +0300 Subject: [PATCH 18/25] add aufs-tools package to dev env docs page Upstream-commit: fb7eaf67d1c01eea28fcbed61d6d8abd8117c965 Component: engine --- components/engine/docs/sources/contributing/devenvironment.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/engine/docs/sources/contributing/devenvironment.rst b/components/engine/docs/sources/contributing/devenvironment.rst index 5d937c5a44..ce2ecd41e8 100644 --- a/components/engine/docs/sources/contributing/devenvironment.rst +++ b/components/engine/docs/sources/contributing/devenvironment.rst @@ -33,7 +33,7 @@ Installation sudo apt-get install python-software-properties sudo add-apt-repository ppa:gophers/go sudo apt-get update - sudo apt-get -y install lxc wget bsdtar curl golang-stable git + sudo apt-get -y install lxc wget bsdtar curl golang-stable git aufs-tools export GOPATH=~/go/ export PATH=$GOPATH/bin:$PATH From 9b310a0f72c7181541278db79a0e1035322125c7 Mon Sep 17 00:00:00 2001 From: unclejack Date: Fri, 14 Jun 2013 15:09:07 +0300 Subject: [PATCH 19/25] install aufs-tools when setting up the hack vagrant box Upstream-commit: f1d16ea0035ee45341e5d4a143cdce5798847cb5 Component: engine --- components/engine/hack/Vagrantfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/engine/hack/Vagrantfile b/components/engine/hack/Vagrantfile index 250731ef47..318f835f4f 100644 --- a/components/engine/hack/Vagrantfile +++ b/components/engine/hack/Vagrantfile @@ -22,7 +22,7 @@ Vagrant::Config.run do |config| pkg_cmd = "touch #{DOCKER_PATH}; " # Install docker dependencies pkg_cmd << "export DEBIAN_FRONTEND=noninteractive; apt-get -qq update; " \ - "apt-get install -q -y lxc bsdtar git golang make linux-image-extra-3.8.0-19-generic; " \ + "apt-get install -q -y lxc bsdtar git aufs-tools golang make linux-image-extra-3.8.0-19-generic; " \ "chown -R #{USER}.#{USER} #{GOPATH}; " \ "install -m 0664 #{CFG_PATH}/bash_profile /home/#{USER}/.bash_profile" config.vm.provision :shell, :inline => pkg_cmd From 25419889e5264e224df1f9c4bd7c831f8f9767b0 Mon Sep 17 00:00:00 2001 From: unclejack Date: Fri, 14 Jun 2013 15:13:27 +0300 Subject: [PATCH 20/25] install aufs-tools when setting up the testing vagrant box Upstream-commit: 822abab17e33a0f87ef1d785a9148d3ea11cbb60 Component: engine --- components/engine/testing/Vagrantfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/engine/testing/Vagrantfile b/components/engine/testing/Vagrantfile index 7556b191ac..e304a8d087 100644 --- a/components/engine/testing/Vagrantfile +++ b/components/engine/testing/Vagrantfile @@ -30,7 +30,7 @@ Vagrant::Config.run do |config| # Install docker dependencies pkg_cmd << "apt-get install -q -y python-software-properties; " \ "add-apt-repository -y ppa:gophers/go/ubuntu; apt-get update -qq; " \ - "DEBIAN_FRONTEND=noninteractive apt-get install -q -y lxc bsdtar git golang-stable make; " + "DEBIAN_FRONTEND=noninteractive apt-get install -q -y lxc bsdtar git golang-stable aufs-tools make; " # Activate new kernel pkg_cmd << "shutdown -r +1; " config.vm.provision :shell, :inline => pkg_cmd From 4bc27f700a083574edb00d8af408198036b3ac0e Mon Sep 17 00:00:00 2001 From: Andy Rothfusz Date: Fri, 14 Jun 2013 13:42:59 -0600 Subject: [PATCH 21/25] Add examples for local import. Upstream-commit: 7958f1f694ac411dcfeb8fbf0d702a7c552306ae Component: engine --- .../sources/commandline/command/import.rst | 29 ++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/components/engine/docs/sources/commandline/command/import.rst b/components/engine/docs/sources/commandline/command/import.rst index 34a7138e07..66bcf5de52 100644 --- a/components/engine/docs/sources/commandline/command/import.rst +++ b/components/engine/docs/sources/commandline/command/import.rst @@ -8,6 +8,33 @@ :: - Usage: docker import [OPTIONS] URL|- [REPOSITORY [TAG]] + Usage: docker import URL|- [REPOSITORY [TAG]] Create a new filesystem image from the contents of a tarball + +At this time, the URL must start with ``http`` and point to a single file archive (.tar, .tar.gz, .bzip) +containing a root filesystem. If you would like to import from a local directory or archive, +you can use the ``-`` parameter to take the data from standard in. + +Examples +-------- + +Import from a remote location +............................. + +``$ docker import http://example.com/exampleimage.tgz exampleimagerepo`` + +Import from a local file +........................ + +Import to docker via pipe and standard in + +``$ cat exampleimage.tgz | docker import - exampleimagelocal`` + +Import from a local directory +............................. + +``$ sudo tar -c . | docker import - exampleimagedir`` + +Note the ``sudo`` in this example -- you must preserve the ownership of the files (especially root ownership) +during the archiving with tar. If you are not root (or sudo) when you tar, then the ownerships might not get preserved. From f884195c2832c4773a77b3b105abdcff1a1a40f3 Mon Sep 17 00:00:00 2001 From: unclejack Date: Fri, 14 Jun 2013 22:55:00 +0300 Subject: [PATCH 22/25] add test: fail to create container if mem limit < 512KB Upstream-commit: d3f83a6592e3d79768d9d3805edec80642b69c4b Component: engine --- components/engine/server_test.go | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/components/engine/server_test.go b/components/engine/server_test.go index 532757c61e..7fdec18f61 100644 --- a/components/engine/server_test.go +++ b/components/engine/server_test.go @@ -147,3 +147,25 @@ func TestCreateStartRestartStopStartKillRm(t *testing.T) { } } + +func TestRunWithTooLowMemoryLimit(t *testing.T) { + runtime, err := newTestRuntime() + srv := &Server{runtime: runtime} + if err != nil { + t.Fatal(err) + } + defer nuke(runtime) + // Try to create a container with a memory limit of 1 byte less than the minimum allowed limit. + _, err = srv.ContainerCreate( + &Config{ + Image: GetTestImage(runtime).ID, + Memory: 524287, + CpuShares: 1000, + Cmd: []string{"/bin/cat"}, + }, + ) + if err == nil { + t.Errorf("Memory limit is smaller than the allowed limit. Container creation should've failed!") + } + +} From 40bdb17b30c50385883f7aae0eb62c4201cfe1ce Mon Sep 17 00:00:00 2001 From: Solomon Hykes Date: Fri, 14 Jun 2013 14:46:08 -0700 Subject: [PATCH 23/25] Remove duplicate 'WARNING' Upstream-commit: 7f118519eb007b2423fff428aceddabd6c1c301d Component: engine --- components/engine/api.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/engine/api.go b/components/engine/api.go index d304b49a98..e870ca7723 100644 --- a/components/engine/api.go +++ b/components/engine/api.go @@ -441,7 +441,7 @@ func postContainersCreate(srv *Server, version float64, w http.ResponseWriter, r } if len(config.Dns) == 0 && len(srv.runtime.Dns) == 0 && utils.CheckLocalDns() { - out.Warnings = append(out.Warnings, fmt.Sprintf("WARNING: Docker detected local DNS server on resolv.conf. Using default external servers: %v", defaultDns)) + out.Warnings = append(out.Warnings, fmt.Sprintf("Docker detected local DNS server on resolv.conf. Using default external servers: %v", defaultDns)) config.Dns = defaultDns } From 3562ef766fa6d67e71d64002dcc5183d00816c69 Mon Sep 17 00:00:00 2001 From: Solomon Hykes Date: Fri, 14 Jun 2013 15:11:34 -0700 Subject: [PATCH 24/25] Various FIXME items Upstream-commit: 14265d9a18a4a2151bfd4e5c7e94de45377b6375 Component: engine --- components/engine/FIXME | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/components/engine/FIXME b/components/engine/FIXME index e252fb2589..0b72feafe8 100644 --- a/components/engine/FIXME +++ b/components/engine/FIXME @@ -16,3 +16,13 @@ to put them - so we put them here :) * Unify build commands and regular commands * Move source code into src/ subdir for clarity * Clean up the Makefile, it's a mess +- docker buidl: show short IDs +- docker build: on non-existent local path for ADD, don't show full absolute path on the host +- mount into /dockerinit rather than /sbin/init +- docker tag foo REPO:TAG +- use size header for progress bar in pull +- Clean up context upload in build!!! +- Parallel pull +- Ensure /proc/sys/net/ipv4/ip_forward is 1 +- Force DNS to public! +- Always generate a resolv.conf per container, to avoid changing resolv.conf under thne container's feet From f839c4752ba4c8d39b4bf6048191639a545701c9 Mon Sep 17 00:00:00 2001 From: Solomon Hykes Date: Fri, 14 Jun 2013 16:29:19 -0700 Subject: [PATCH 25/25] FIXMEs Upstream-commit: 5799806414b266c14a8ea2802cfa0906d920c62d Component: engine --- components/engine/FIXME | 2 ++ 1 file changed, 2 insertions(+) diff --git a/components/engine/FIXME b/components/engine/FIXME index 0b72feafe8..aaf4c23266 100644 --- a/components/engine/FIXME +++ b/components/engine/FIXME @@ -26,3 +26,5 @@ to put them - so we put them here :) - Ensure /proc/sys/net/ipv4/ip_forward is 1 - Force DNS to public! - Always generate a resolv.conf per container, to avoid changing resolv.conf under thne container's feet +- Save metadata with import/export +- Upgrade dockerd without stopping containers