diff --git a/runconfig/compare.go b/runconfig/compare.go index 6ed7405246..122687f669 100644 --- a/runconfig/compare.go +++ b/runconfig/compare.go @@ -19,8 +19,6 @@ func Compare(a, b *Config) bool { return false } if len(a.Cmd) != len(b.Cmd) || - len(a.Dns) != len(b.Dns) || - len(a.DnsSearch) != len(b.DnsSearch) || len(a.Env) != len(b.Env) || len(a.PortSpecs) != len(b.PortSpecs) || len(a.ExposedPorts) != len(b.ExposedPorts) || @@ -34,16 +32,6 @@ func Compare(a, b *Config) bool { return false } } - for i := 0; i < len(a.Dns); i++ { - if a.Dns[i] != b.Dns[i] { - return false - } - } - for i := 0; i < len(a.DnsSearch); i++ { - if a.DnsSearch[i] != b.DnsSearch[i] { - return false - } - } for i := 0; i < len(a.Env); i++ { if a.Env[i] != b.Env[i] { return false diff --git a/runconfig/config.go b/runconfig/config.go index 4b334c6848..9db545976b 100644 --- a/runconfig/config.go +++ b/runconfig/config.go @@ -25,8 +25,6 @@ type Config struct { StdinOnce bool // If true, close stdin after the 1 attached client disconnects. Env []string Cmd []string - Dns []string - DnsSearch []string Image string // Name of the image as it was passed by the operator (eg. could be symbolic) Volumes map[string]struct{} VolumesFrom string @@ -66,12 +64,6 @@ func ContainerConfigFromJob(job *engine.Job) *Config { if Cmd := job.GetenvList("Cmd"); Cmd != nil { config.Cmd = Cmd } - if Dns := job.GetenvList("Dns"); Dns != nil { - config.Dns = Dns - } - if DnsSearch := job.GetenvList("DnsSearch"); DnsSearch != nil { - config.DnsSearch = DnsSearch - } if Entrypoint := job.GetenvList("Entrypoint"); Entrypoint != nil { config.Entrypoint = Entrypoint } diff --git a/runconfig/config_test.go b/runconfig/config_test.go index 784341b08c..d5ab75b3b9 100644 --- a/runconfig/config_test.go +++ b/runconfig/config_test.go @@ -163,32 +163,18 @@ func TestCompare(t *testing.T) { volumes1 := make(map[string]struct{}) volumes1["/test1"] = struct{}{} config1 := Config{ - Dns: []string{"1.1.1.1", "2.2.2.2"}, - DnsSearch: []string{"foo", "bar"}, - PortSpecs: []string{"1111:1111", "2222:2222"}, - Env: []string{"VAR1=1", "VAR2=2"}, - VolumesFrom: "11111111", - Volumes: volumes1, - } - config2 := Config{ - Dns: []string{"0.0.0.0", "2.2.2.2"}, - DnsSearch: []string{"foo", "bar"}, PortSpecs: []string{"1111:1111", "2222:2222"}, Env: []string{"VAR1=1", "VAR2=2"}, VolumesFrom: "11111111", Volumes: volumes1, } config3 := Config{ - Dns: []string{"1.1.1.1", "2.2.2.2"}, - DnsSearch: []string{"foo", "bar"}, PortSpecs: []string{"0000:0000", "2222:2222"}, Env: []string{"VAR1=1", "VAR2=2"}, VolumesFrom: "11111111", Volumes: volumes1, } config4 := Config{ - Dns: []string{"1.1.1.1", "2.2.2.2"}, - DnsSearch: []string{"foo", "bar"}, PortSpecs: []string{"0000:0000", "2222:2222"}, Env: []string{"VAR1=1", "VAR2=2"}, VolumesFrom: "22222222", @@ -197,24 +183,11 @@ func TestCompare(t *testing.T) { volumes2 := make(map[string]struct{}) volumes2["/test2"] = struct{}{} config5 := Config{ - Dns: []string{"1.1.1.1", "2.2.2.2"}, - DnsSearch: []string{"foo", "bar"}, PortSpecs: []string{"0000:0000", "2222:2222"}, Env: []string{"VAR1=1", "VAR2=2"}, VolumesFrom: "11111111", Volumes: volumes2, } - config6 := Config{ - Dns: []string{"1.1.1.1", "2.2.2.2"}, - DnsSearch: []string{"foos", "bars"}, - PortSpecs: []string{"1111:1111", "2222:2222"}, - Env: []string{"VAR1=1", "VAR2=2"}, - VolumesFrom: "11111111", - Volumes: volumes1, - } - if Compare(&config1, &config2) { - t.Fatalf("Compare should return false, Dns are different") - } if Compare(&config1, &config3) { t.Fatalf("Compare should return false, PortSpecs are different") } @@ -224,9 +197,6 @@ func TestCompare(t *testing.T) { if Compare(&config1, &config5) { t.Fatalf("Compare should return false, Volumes are different") } - if Compare(&config1, &config6) { - t.Fatalf("Compare should return false, DnsSearch are different") - } if !Compare(&config1, &config1) { t.Fatalf("Compare should return true") } @@ -237,7 +207,6 @@ func TestMerge(t *testing.T) { volumesImage["/test1"] = struct{}{} volumesImage["/test2"] = struct{}{} configImage := &Config{ - Dns: []string{"1.1.1.1", "2.2.2.2"}, PortSpecs: []string{"1111:1111", "2222:2222"}, Env: []string{"VAR1=1", "VAR2=2"}, VolumesFrom: "1111", @@ -247,7 +216,6 @@ func TestMerge(t *testing.T) { volumesUser := make(map[string]struct{}) volumesUser["/test3"] = struct{}{} configUser := &Config{ - Dns: []string{"2.2.2.2", "3.3.3.3"}, PortSpecs: []string{"3333:2222", "3333:3333"}, Env: []string{"VAR2=3", "VAR3=3"}, Volumes: volumesUser, @@ -257,15 +225,6 @@ func TestMerge(t *testing.T) { t.Error(err) } - if len(configUser.Dns) != 3 { - t.Fatalf("Expected 3 dns, 1.1.1.1, 2.2.2.2 and 3.3.3.3, found %d", len(configUser.Dns)) - } - for _, dns := range configUser.Dns { - if dns != "1.1.1.1" && dns != "2.2.2.2" && dns != "3.3.3.3" { - t.Fatalf("Expected 1.1.1.1 or 2.2.2.2 or 3.3.3.3, found %s", dns) - } - } - if len(configUser.ExposedPorts) != 3 { t.Fatalf("Expected 3 ExposedPorts, 1111, 2222 and 3333, found %d", len(configUser.ExposedPorts)) } diff --git a/runconfig/hostconfig.go b/runconfig/hostconfig.go index 55a308a5b8..5c5e291bad 100644 --- a/runconfig/hostconfig.go +++ b/runconfig/hostconfig.go @@ -14,6 +14,8 @@ type HostConfig struct { PortBindings nat.PortMap Links []string PublishAllPorts bool + Dns []string + DnsSearch []string } func ContainerHostConfigFromJob(job *engine.Job) *HostConfig { @@ -30,6 +32,11 @@ func ContainerHostConfigFromJob(job *engine.Job) *HostConfig { if Links := job.GetenvList("Links"); Links != nil { hostConfig.Links = Links } - + if Dns := job.GetenvList("Dns"); Dns != nil { + hostConfig.Dns = Dns + } + if DnsSearch := job.GetenvList("DnsSearch"); DnsSearch != nil { + hostConfig.DnsSearch = DnsSearch + } return hostConfig } diff --git a/runconfig/merge.go b/runconfig/merge.go index a154d4caf5..7a089855b2 100644 --- a/runconfig/merge.go +++ b/runconfig/merge.go @@ -94,25 +94,6 @@ func Merge(userConf, imageConf *Config) error { if userConf.Cmd == nil || len(userConf.Cmd) == 0 { userConf.Cmd = imageConf.Cmd } - if userConf.Dns == nil || len(userConf.Dns) == 0 { - userConf.Dns = imageConf.Dns - } else { - dnsSet := make(map[string]struct{}, len(userConf.Dns)) - for _, dns := range userConf.Dns { - dnsSet[dns] = struct{}{} - } - for _, dns := range imageConf.Dns { - if _, exists := dnsSet[dns]; !exists { - userConf.Dns = append(userConf.Dns, dns) - } - } - } - if userConf.DnsSearch == nil || len(userConf.DnsSearch) == 0 { - userConf.DnsSearch = imageConf.DnsSearch - } else { - //duplicates aren't an issue here - userConf.DnsSearch = append(userConf.DnsSearch, imageConf.DnsSearch...) - } if userConf.Entrypoint == nil || len(userConf.Entrypoint) == 0 { userConf.Entrypoint = imageConf.Entrypoint } diff --git a/runconfig/parse.go b/runconfig/parse.go index 3ca326fca6..58d6c9ebb9 100644 --- a/runconfig/parse.go +++ b/runconfig/parse.go @@ -213,8 +213,6 @@ func parseRun(cmd *flag.FlagSet, args []string, sysInfo *sysinfo.SysInfo) (*Conf AttachStderr: flAttach.Get("stderr"), Env: envVariables, Cmd: runCmd, - Dns: flDns.GetAll(), - DnsSearch: flDnsSearch.GetAll(), Image: image, Volumes: flVolumes.GetMap(), VolumesFrom: strings.Join(flVolumesFrom.GetAll(), ","), @@ -230,6 +228,8 @@ func parseRun(cmd *flag.FlagSet, args []string, sysInfo *sysinfo.SysInfo) (*Conf PortBindings: portBindings, Links: flLinks.GetAll(), PublishAllPorts: *flPublishAll, + Dns: flDns.GetAll(), + DnsSearch: flDnsSearch.GetAll(), } if sysInfo != nil && flMemory > 0 && !sysInfo.SwapLimit { diff --git a/runtime/container.go b/runtime/container.go index a5a2f25c64..c8053b146c 100644 --- a/runtime/container.go +++ b/runtime/container.go @@ -430,6 +430,12 @@ func (container *Container) Start() (err error) { } }() + if container.ResolvConfPath == "" { + if err := container.setupContainerDns(); err != nil { + return err + } + } + if err := container.Mount(); err != nil { return err } @@ -1174,3 +1180,50 @@ func (container *Container) DisableLink(name string) { } } } + +func (container *Container) setupContainerDns() error { + var ( + config = container.hostConfig + runtime = container.runtime + ) + resolvConf, err := utils.GetResolvConf() + if err != nil { + return err + } + // If custom dns exists, then create a resolv.conf for the container + if len(config.Dns) > 0 || len(runtime.config.Dns) > 0 || len(config.DnsSearch) > 0 || len(runtime.config.DnsSearch) > 0 { + var ( + dns = utils.GetNameservers(resolvConf) + dnsSearch = utils.GetSearchDomains(resolvConf) + ) + if len(config.Dns) > 0 { + dns = config.Dns + } else if len(runtime.config.Dns) > 0 { + dns = runtime.config.Dns + } + if len(config.DnsSearch) > 0 { + dnsSearch = config.DnsSearch + } else if len(runtime.config.DnsSearch) > 0 { + dnsSearch = runtime.config.DnsSearch + } + container.ResolvConfPath = path.Join(container.root, "resolv.conf") + f, err := os.Create(container.ResolvConfPath) + if err != nil { + return err + } + defer f.Close() + for _, dns := range dns { + if _, err := f.Write([]byte("nameserver " + dns + "\n")); err != nil { + return err + } + } + if len(dnsSearch) > 0 { + if _, err := f.Write([]byte("search " + strings.Join(dnsSearch, " ") + "\n")); err != nil { + return err + } + } + } else { + container.ResolvConfPath = "/etc/resolv.conf" + } + return nil +} diff --git a/runtime/runtime.go b/runtime/runtime.go index 864874c8e4..98903cfa08 100644 --- a/runtime/runtime.go +++ b/runtime/runtime.go @@ -24,6 +24,7 @@ import ( "github.com/dotcloud/docker/utils" "io" "io/ioutil" + "log" "os" "path" "regexp" @@ -393,9 +394,6 @@ func (runtime *Runtime) Create(config *runconfig.Config, name string) (*Containe if err := runtime.createRootfs(container, img); err != nil { return nil, nil, err } - if err := runtime.setupContainerDns(container, config); err != nil { - return nil, nil, err - } if err := container.ToDisk(); err != nil { return nil, nil, err } @@ -572,53 +570,6 @@ func (runtime *Runtime) createRootfs(container *Container, img *image.Image) err return nil } -func (runtime *Runtime) setupContainerDns(container *Container, config *runconfig.Config) error { - resolvConf, err := utils.GetResolvConf() - if err != nil { - return err - } - if len(config.Dns) == 0 && len(runtime.config.Dns) == 0 && utils.CheckLocalDns(resolvConf) { - runtime.config.Dns = DefaultDns - } - - // If custom dns exists, then create a resolv.conf for the container - if len(config.Dns) > 0 || len(runtime.config.Dns) > 0 || len(config.DnsSearch) > 0 || len(runtime.config.DnsSearch) > 0 { - var ( - dns = utils.GetNameservers(resolvConf) - dnsSearch = utils.GetSearchDomains(resolvConf) - ) - if len(config.Dns) > 0 { - dns = config.Dns - } else if len(runtime.config.Dns) > 0 { - dns = runtime.config.Dns - } - if len(config.DnsSearch) > 0 { - dnsSearch = config.DnsSearch - } else if len(runtime.config.DnsSearch) > 0 { - dnsSearch = runtime.config.DnsSearch - } - container.ResolvConfPath = path.Join(container.root, "resolv.conf") - f, err := os.Create(container.ResolvConfPath) - if err != nil { - return err - } - defer f.Close() - for _, dns := range dns { - if _, err := f.Write([]byte("nameserver " + dns + "\n")); err != nil { - return err - } - } - if len(dnsSearch) > 0 { - if _, err := f.Write([]byte("search " + strings.Join(dnsSearch, " ") + "\n")); err != nil { - return err - } - } - } else { - container.ResolvConfPath = "/etc/resolv.conf" - } - return nil -} - // Commit creates a new filesystem image from the current state of a container. // The image can optionally be tagged into a repository func (runtime *Runtime) Commit(container *Container, repository, tag, comment, author string, config *runconfig.Config) (*image.Image, error) { @@ -839,6 +790,9 @@ func NewRuntimeFromDirectory(config *daemonconfig.Config, eng *engine.Engine) (* eng: eng, } + if err := runtime.checkLocaldns(); err != nil { + return nil, err + } if err := runtime.restore(); err != nil { return nil, err } @@ -1025,3 +979,15 @@ func (runtime *Runtime) ContainerGraph() *graphdb.Database { func (runtime *Runtime) SetServer(server Server) { runtime.srv = server } + +func (runtime *Runtime) checkLocaldns() error { + resolvConf, err := utils.GetResolvConf() + if err != nil { + return err + } + if len(runtime.config.Dns) == 0 && utils.CheckLocalDns(resolvConf) { + log.Printf("Local (127.0.0.1) DNS resolver found in resolv.conf and containers can't use it. Using default external servers : %v\n", DefaultDns) + runtime.config.Dns = DefaultDns + } + return nil +} diff --git a/server/server.go b/server/server.go index 9cabf17889..0feaff4eac 100644 --- a/server/server.go +++ b/server/server.go @@ -1731,15 +1731,6 @@ func (srv *Server) ContainerCreate(job *engine.Job) engine.Status { job.Errorf("Your kernel does not support swap limit capabilities. Limitation discarded.\n") config.MemorySwap = -1 } - resolvConf, err := utils.GetResolvConf() - if err != nil { - return job.Error(err) - } - if !config.NetworkDisabled && len(config.Dns) == 0 && len(srv.runtime.Config().Dns) == 0 && utils.CheckLocalDns(resolvConf) { - job.Errorf("Local (127.0.0.1) DNS resolver found in resolv.conf and containers can't use it. Using default external servers : %v\n", runtime.DefaultDns) - config.Dns = runtime.DefaultDns - } - container, buildWarnings, err := srv.runtime.Create(config, name) if err != nil { if srv.runtime.Graph().IsNotExist(err) {