func (daemon *Daemon) checkLocaldns() error { resolvConf, err := resolvconf.Get() if err != nil { return err } if len(daemon.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) daemon.config.Dns = DefaultDns } return nil }
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 }
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 } resolvConf, err := utils.GetResolvConf() if err != nil { return err } if len(config.Dns) == 0 && len(srv.runtime.Dns) == 0 && utils.CheckLocalDns(resolvConf) { out.Warnings = append(out.Warnings, fmt.Sprintf("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 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.") } if config.Memory > 0 && !srv.runtime.capabilities.SwapLimit { 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.") } if !srv.runtime.capabilities.IPv4Forwarding { log.Println("Warning: IPv4 forwarding is disabled.") out.Warnings = append(out.Warnings, "IPv4 forwarding is disabled.") } b, err := json.Marshal(out) if err != nil { return err } w.WriteHeader(http.StatusCreated) writeJSON(w, b) 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 }
func postContainersCreate(srv *Server, version float64, w http.ResponseWriter, r *http.Request, vars map[string]string) error { if err := parseForm(r); err != nil { return nil } out := &APIRun{} job := srv.Eng.Job("create", r.Form.Get("name")) if err := job.DecodeEnv(r.Body); err != nil { return err } resolvConf, err := utils.GetResolvConf() if err != nil { return err } if !job.GetenvBool("NetworkDisabled") && len(job.Getenv("Dns")) == 0 && len(srv.runtime.config.Dns) == 0 && utils.CheckLocalDns(resolvConf) { out.Warnings = append(out.Warnings, fmt.Sprintf("Docker detected local DNS server on resolv.conf. Using default external servers: %v", defaultDns)) job.SetenvList("Dns", defaultDns) } // Read container ID from the first line of stdout job.StdoutParseString(&out.ID) // Read warnings from stderr job.StderrParseLines(&out.Warnings, 0) if err := job.Run(); err != nil { return err } if job.GetenvInt("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.") } if job.GetenvInt("Memory") > 0 && !srv.runtime.capabilities.SwapLimit { 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.") } if !job.GetenvBool("NetworkDisabled") && srv.runtime.capabilities.IPv4ForwardingDisabled { log.Println("Warning: IPv4 forwarding is disabled.") out.Warnings = append(out.Warnings, "IPv4 forwarding is disabled.") } return writeJSON(w, http.StatusCreated, out) }
// Create creates a new container from the given configuration with a given name. func (runtime *Runtime) Create(config *Config, name string) (*Container, []string, error) { // Lookup image img, err := runtime.repositories.LookupImage(config.Image) if err != nil { return nil, nil, err } checkDeprecatedExpose := func(config *Config) bool { if config != nil { if config.PortSpecs != nil { for _, p := range config.PortSpecs { if strings.Contains(p, ":") { return true } } } } return false } warnings := []string{} if checkDeprecatedExpose(img.Config) || checkDeprecatedExpose(config) { warnings = append(warnings, "The mapping to public ports on your host has been deprecated. Use -p to publish the ports.") } if img.Config != nil { if err := MergeConfig(config, img.Config); err != nil { return nil, nil, err } } if len(config.Entrypoint) != 0 && config.Cmd == nil { config.Cmd = []string{} } else if config.Cmd == nil || len(config.Cmd) == 0 { return nil, nil, fmt.Errorf("No command specified") } sysInitPath := utils.DockerInitPath() if sysInitPath == "" { return nil, nil, fmt.Errorf("Could not locate dockerinit: This usually means docker was built incorrectly. See http://docs.docker.io/en/latest/contributing/devenvironment for official build instructions.") } // Generate id id := GenerateID() if name == "" { name, err = generateRandomName(runtime) if err != nil { name = utils.TruncateID(id) } } if name[0] != '/' { name = "/" + name } // Set the enitity in the graph using the default name specified if _, err := runtime.containerGraph.Set(name, id); err != nil { if strings.HasSuffix(err.Error(), "name are not unique") { return nil, nil, fmt.Errorf("Conflict, %s already exists.", name) } return nil, nil, err } // Generate default hostname // FIXME: the lxc template no longer needs to set a default hostname if config.Hostname == "" { config.Hostname = id[:12] } var args []string var entrypoint string if len(config.Entrypoint) != 0 { entrypoint = config.Entrypoint[0] args = append(config.Entrypoint[1:], config.Cmd...) } else { entrypoint = config.Cmd[0] args = config.Cmd[1:] } container := &Container{ // FIXME: we should generate the ID here instead of receiving it as an argument ID: id, Created: time.Now(), Path: entrypoint, Args: args, //FIXME: de-duplicate from config Config: config, Image: img.ID, // Always use the resolved image id NetworkSettings: &NetworkSettings{}, // FIXME: do we need to store this in the container? SysInitPath: sysInitPath, Name: name, } container.root = runtime.containerRoot(container.ID) // Step 1: create the container directory. // This doubles as a barrier to avoid race conditions. if err := os.Mkdir(container.root, 0700); err != nil { return nil, nil, err } resolvConf, err := utils.GetResolvConf() if err != nil { return nil, nil, err } if len(config.Dns) == 0 && len(runtime.config.Dns) == 0 && utils.CheckLocalDns(resolvConf) { //"WARNING: Docker detected local DNS server on resolv.conf. Using default external servers: %v", defaultDns 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 { var dns []string if len(config.Dns) > 0 { dns = config.Dns } else { dns = runtime.config.Dns } container.ResolvConfPath = path.Join(container.root, "resolv.conf") f, err := os.Create(container.ResolvConfPath) if err != nil { return nil, nil, err } defer f.Close() for _, dns := range dns { if _, err := f.Write([]byte("nameserver " + dns + "\n")); err != nil { return nil, nil, err } } } else { container.ResolvConfPath = "/etc/resolv.conf" } // Step 2: save the container json if err := container.ToDisk(); err != nil { return nil, nil, err } // Step 3: if hostname, build hostname and hosts files container.HostnamePath = path.Join(container.root, "hostname") ioutil.WriteFile(container.HostnamePath, []byte(container.Config.Hostname+"\n"), 0644) hostsContent := []byte(` 127.0.0.1 localhost ::1 localhost ip6-localhost ip6-loopback fe00::0 ip6-localnet ff00::0 ip6-mcastprefix ff02::1 ip6-allnodes ff02::2 ip6-allrouters `) container.HostsPath = path.Join(container.root, "hosts") if container.Config.Domainname != "" { hostsContent = append([]byte(fmt.Sprintf("::1\t\t%s.%s %s\n", container.Config.Hostname, container.Config.Domainname, container.Config.Hostname)), hostsContent...) hostsContent = append([]byte(fmt.Sprintf("127.0.0.1\t%s.%s %s\n", container.Config.Hostname, container.Config.Domainname, container.Config.Hostname)), hostsContent...) } else { hostsContent = append([]byte(fmt.Sprintf("::1\t\t%s\n", container.Config.Hostname)), hostsContent...) hostsContent = append([]byte(fmt.Sprintf("127.0.0.1\t%s\n", container.Config.Hostname)), hostsContent...) } ioutil.WriteFile(container.HostsPath, hostsContent, 0644) // Step 4: register the container if err := runtime.Register(container); err != nil { return nil, nil, err } return container, warnings, nil }
// Create creates a new container from the given configuration with a given name. func (runtime *Runtime) Create(config *runconfig.Config, name string) (*Container, []string, error) { // Lookup image img, err := runtime.repositories.LookupImage(config.Image) if err != nil { return nil, nil, err } // We add 2 layers to the depth because the container's rw and // init layer add to the restriction depth, err := img.Depth() if err != nil { return nil, nil, err } if depth+2 >= MaxImageDepth { return nil, nil, fmt.Errorf("Cannot create container with more than %d parents", MaxImageDepth) } checkDeprecatedExpose := func(config *runconfig.Config) bool { if config != nil { if config.PortSpecs != nil { for _, p := range config.PortSpecs { if strings.Contains(p, ":") { return true } } } } return false } warnings := []string{} if checkDeprecatedExpose(img.Config) || checkDeprecatedExpose(config) { warnings = append(warnings, "The mapping to public ports on your host via Dockerfile EXPOSE (host:port:port) has been deprecated. Use -p to publish the ports.") } if img.Config != nil { if err := runconfig.Merge(config, img.Config); err != nil { return nil, nil, err } } if len(config.Entrypoint) == 0 && len(config.Cmd) == 0 { return nil, nil, fmt.Errorf("No command specified") } // Generate id id := GenerateID() if name == "" { name, err = generateRandomName(runtime) if err != nil { name = utils.TruncateID(id) } } else { if !validContainerNamePattern.MatchString(name) { return nil, nil, fmt.Errorf("Invalid container name (%s), only %s are allowed", name, validContainerNameChars) } } if name[0] != '/' { name = "/" + name } // Set the enitity in the graph using the default name specified if _, err := runtime.containerGraph.Set(name, id); err != nil { if !graphdb.IsNonUniqueNameError(err) { return nil, nil, err } conflictingContainer, err := runtime.GetByName(name) if err != nil { if strings.Contains(err.Error(), "Could not find entity") { return nil, nil, err } // Remove name and continue starting the container if err := runtime.containerGraph.Delete(name); err != nil { return nil, nil, err } } else { nameAsKnownByUser := strings.TrimPrefix(name, "/") return nil, nil, fmt.Errorf( "Conflict, The name %s is already assigned to %s. You have to delete (or rename) that container to be able to assign %s to a container again.", nameAsKnownByUser, utils.TruncateID(conflictingContainer.ID), nameAsKnownByUser) } } // Generate default hostname // FIXME: the lxc template no longer needs to set a default hostname if config.Hostname == "" { config.Hostname = id[:12] } var args []string var entrypoint string if len(config.Entrypoint) != 0 { entrypoint = config.Entrypoint[0] args = append(config.Entrypoint[1:], config.Cmd...) } else { entrypoint = config.Cmd[0] args = config.Cmd[1:] } container := &Container{ // FIXME: we should generate the ID here instead of receiving it as an argument ID: id, Created: time.Now().UTC(), Path: entrypoint, Args: args, //FIXME: de-duplicate from config Config: config, hostConfig: &runconfig.HostConfig{}, Image: img.ID, // Always use the resolved image id NetworkSettings: &NetworkSettings{}, Name: name, Driver: runtime.driver.String(), ExecDriver: runtime.execDriver.Name(), } container.root = runtime.containerRoot(container.ID) // Step 1: create the container directory. // This doubles as a barrier to avoid race conditions. if err := os.Mkdir(container.root, 0700); err != nil { return nil, nil, err } initID := fmt.Sprintf("%s-init", container.ID) if err := runtime.driver.Create(initID, img.ID); err != nil { return nil, nil, err } initPath, err := runtime.driver.Get(initID) if err != nil { return nil, nil, err } defer runtime.driver.Put(initID) if err := setupInitLayer(initPath); err != nil { return nil, nil, err } if err := runtime.driver.Create(container.ID, initID); err != nil { return nil, nil, err } resolvConf, err := utils.GetResolvConf() if err != nil { return nil, nil, err } if len(config.Dns) == 0 && len(runtime.config.Dns) == 0 && utils.CheckLocalDns(resolvConf) { //"WARNING: Docker detected local DNS server on resolv.conf. Using default external servers: %v", defaultDns 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 { var dns []string if len(config.Dns) > 0 { dns = config.Dns } else { dns = runtime.config.Dns } container.ResolvConfPath = path.Join(container.root, "resolv.conf") f, err := os.Create(container.ResolvConfPath) if err != nil { return nil, nil, err } defer f.Close() for _, dns := range dns { if _, err := f.Write([]byte("nameserver " + dns + "\n")); err != nil { return nil, nil, err } } } else { container.ResolvConfPath = "/etc/resolv.conf" } // Step 2: save the container json if err := container.ToDisk(); err != nil { return nil, nil, err } // Step 3: register the container if err := runtime.Register(container); err != nil { return nil, nil, err } return container, warnings, nil }
// Create creates a new container from the given configuration. func (runtime *Runtime) Create(config *Config) (*Container, error) { // Lookup image img, err := runtime.repositories.LookupImage(config.Image) if err != nil { return nil, err } if img.Config != nil { MergeConfig(config, img.Config) } if len(config.Entrypoint) != 0 && config.Cmd == nil { config.Cmd = []string{} } else if config.Cmd == nil || len(config.Cmd) == 0 { return nil, fmt.Errorf("No command specified") } // Generate id id := GenerateID() // Generate default hostname // FIXME: the lxc template no longer needs to set a default hostname if config.Hostname == "" { config.Hostname = id[:12] } var args []string var entrypoint string if len(config.Entrypoint) != 0 { entrypoint = config.Entrypoint[0] args = append(config.Entrypoint[1:], config.Cmd...) } else { entrypoint = config.Cmd[0] args = config.Cmd[1:] } container := &Container{ // FIXME: we should generate the ID here instead of receiving it as an argument ID: id, Created: time.Now(), Path: entrypoint, Args: args, //FIXME: de-duplicate from config Config: config, Image: img.ID, // Always use the resolved image id NetworkSettings: &NetworkSettings{}, // FIXME: do we need to store this in the container? SysInitPath: sysInitPath, } container.root = runtime.containerRoot(container.ID) // Step 1: create the container directory. // This doubles as a barrier to avoid race conditions. if err := os.Mkdir(container.root, 0700); err != nil { return nil, err } resolvConf, err := utils.GetResolvConf() if err != nil { return nil, err } if len(config.Dns) == 0 && len(runtime.Dns) == 0 && utils.CheckLocalDns(resolvConf) { //"WARNING: Docker detected local DNS server on resolv.conf. Using default external servers: %v", defaultDns runtime.Dns = defaultDns } // If custom dns exists, then create a resolv.conf for the container if len(config.Dns) > 0 || len(runtime.Dns) > 0 { var dns []string if len(config.Dns) > 0 { dns = config.Dns } else { dns = 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 dns { if _, err := f.Write([]byte("nameserver " + dns + "\n")); err != nil { return nil, err } } } else { container.ResolvConfPath = "/etc/resolv.conf" } // Step 2: save the container json if err := container.ToDisk(); err != nil { return nil, err } // Step 3: if hostname, build hostname and hosts files container.HostnamePath = path.Join(container.root, "hostname") ioutil.WriteFile(container.HostnamePath, []byte(container.Config.Hostname+"\n"), 0644) hostsContent := []byte(` 127.0.0.1 localhost ::1 localhost ip6-localhost ip6-loopback fe00::0 ip6-localnet ff00::0 ip6-mcastprefix ff02::1 ip6-allnodes ff02::2 ip6-allrouters `) container.HostsPath = path.Join(container.root, "hosts") if container.Config.Domainname != "" { hostsContent = append([]byte(fmt.Sprintf("::1\t\t%s.%s %s\n", container.Config.Hostname, container.Config.Domainname, container.Config.Hostname)), hostsContent...) hostsContent = append([]byte(fmt.Sprintf("127.0.0.1\t%s.%s %s\n", container.Config.Hostname, container.Config.Domainname, container.Config.Hostname)), hostsContent...) } else { hostsContent = append([]byte(fmt.Sprintf("::1\t\t%s\n", container.Config.Hostname)), hostsContent...) hostsContent = append([]byte(fmt.Sprintf("127.0.0.1\t%s\n", container.Config.Hostname)), hostsContent...) } ioutil.WriteFile(container.HostsPath, hostsContent, 0644) // Step 4: register the container if err := runtime.Register(container); err != nil { return nil, err } return container, nil }
func (builder *Builder) Create(config *Config) (*Container, error) { // Lookup image img, err := builder.repositories.LookupImage(config.Image) if err != nil { return nil, err } if img.Config != nil { MergeConfig(config, img.Config) } if config.Cmd == nil || len(config.Cmd) == 0 { return nil, fmt.Errorf("No command specified") } // Generate id id := GenerateID() // Generate default hostname // FIXME: the lxc template no longer needs to set a default hostname if config.Hostname == "" { config.Hostname = id[:12] } var args []string var entrypoint string if len(config.Entrypoint) != 0 { entrypoint = config.Entrypoint[0] args = append(config.Entrypoint[1:], config.Cmd...) } else { entrypoint = config.Cmd[0] args = config.Cmd[1:] } container := &Container{ // FIXME: we should generate the ID here instead of receiving it as an argument ID: id, Created: time.Now(), Path: entrypoint, Args: args, //FIXME: de-duplicate from config Config: config, Image: img.ID, // Always use the resolved image id NetworkSettings: &NetworkSettings{}, // FIXME: do we need to store this in the container? SysInitPath: sysInitPath, } container.root = builder.runtime.containerRoot(container.ID) // Step 1: create the container directory. // This doubles as a barrier to avoid race conditions. if err := os.Mkdir(container.root, 0700); err != nil { return nil, err } // create the 'rw' directory in case a container is commited without being started if err := os.Mkdir(path.Join(container.root, "rw"), 0755); err != nil { 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 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 dns { if _, err := f.Write([]byte("nameserver " + dns + "\n")); err != nil { return nil, err } } } else { container.ResolvConfPath = "/etc/resolv.conf" } // Step 2: save the container json if err := container.ToDisk(); err != nil { return nil, err } // Step 3: register the container if err := builder.runtime.Register(container); err != nil { return nil, err } return container, nil }