func DockerLogin(username, password, email string) (string, error) { if username == "" && password == "" && email == "" { // Attempt login with .dockercfg file. configFile, err := registry.LoadConfig(os.Getenv("HOME")) if err != nil { return "", err } authconfig, ok := configFile.Configs[registry.IndexServerAddress()] if !ok { return "", fmt.Errorf("Error: Unable to login, no data for index server.") } status, err := registry.Login(&authconfig, registry.HTTPRequestFactory(nil)) if err != nil { return "", err } return status, nil } else { // Attempt login with this function's auth params. authconfig := registry.AuthConfig{ Username: username, Email: email, Password: password, ServerAddress: registry.IndexServerAddress(), } status, err := registry.Login(&authconfig, registry.HTTPRequestFactory(nil)) if err != nil { return "", err } return status, nil } return "", fmt.Errorf("Auth params don't make sense.") }
func (daemon *Daemon) CmdInfo(job *engine.Job) engine.Status { images, _ := daemon.Graph().Map() var imgcount int if images == nil { imgcount = 0 } else { imgcount = len(images) } kernelVersion := "<unknown>" if kv, err := kernel.GetKernelVersion(); err == nil { kernelVersion = kv.String() } operatingSystem := "<unknown>" if s, err := operatingsystem.GetOperatingSystem(); err == nil { operatingSystem = s } if inContainer, err := operatingsystem.IsContainerized(); err != nil { utils.Errorf("Could not determine if daemon is containerized: %v", err) operatingSystem += " (error determining if containerized)" } else if inContainer { operatingSystem += " (containerized)" } // if we still have the original dockerinit binary from before we copied it locally, let's return the path to that, since that's more intuitive (the copied path is trivial to derive by hand given VERSION) initPath := utils.DockerInitPath("") if initPath == "" { // if that fails, we'll just return the path from the daemon initPath = daemon.SystemInitPath() } cjob := job.Eng.Job("subscribers_count") env, _ := cjob.Stdout.AddEnv() if err := cjob.Run(); err != nil { return job.Error(err) } v := &engine.Env{} v.SetInt("Containers", len(daemon.List())) v.SetInt("Images", imgcount) v.Set("Driver", daemon.GraphDriver().String()) v.SetJson("DriverStatus", daemon.GraphDriver().Status()) v.SetBool("MemoryLimit", daemon.SystemConfig().MemoryLimit) v.SetBool("SwapLimit", daemon.SystemConfig().SwapLimit) v.SetBool("IPv4Forwarding", !daemon.SystemConfig().IPv4ForwardingDisabled) v.SetBool("Debug", os.Getenv("DEBUG") != "") v.SetInt("NFd", utils.GetTotalUsedFds()) v.SetInt("NGoroutines", runtime.NumGoroutine()) v.Set("ExecutionDriver", daemon.ExecutionDriver().Name()) v.SetInt("NEventsListener", env.GetInt("count")) v.Set("KernelVersion", kernelVersion) v.Set("OperatingSystem", operatingSystem) v.Set("IndexServerAddress", registry.IndexServerAddress()) v.Set("InitSha1", dockerversion.INITSHA1) v.Set("InitPath", initPath) v.SetList("Sockets", daemon.Sockets) if _, err := v.WriteTo(job.Stdout); err != nil { return job.Error(err) } return engine.StatusOK }
func (cli *DockerCli) call(method, path string, data interface{}, passAuthInfo bool) (io.ReadCloser, int, error) { params, err := cli.encodeData(data) if err != nil { return nil, -1, err } req, err := http.NewRequest(method, fmt.Sprintf("/v%s%s", api.APIVERSION, path), params) if err != nil { return nil, -1, err } if passAuthInfo { cli.LoadConfigFile() // Resolve the Auth config relevant for this server authConfig := cli.configFile.ResolveAuthConfig(registry.IndexServerAddress()) getHeaders := func(authConfig registry.AuthConfig) (map[string][]string, error) { buf, err := json.Marshal(authConfig) if err != nil { return nil, err } registryAuthHeader := []string{ base64.URLEncoding.EncodeToString(buf), } return map[string][]string{"X-Registry-Auth": registryAuthHeader}, nil } if headers, err := getHeaders(authConfig); err == nil && headers != nil { for k, v := range headers { req.Header[k] = v } } } req.Header.Set("User-Agent", "Docker-Client/"+dockerversion.VERSION) req.URL.Host = cli.addr req.URL.Scheme = cli.scheme if data != nil { req.Header.Set("Content-Type", "application/json") } else if method == "POST" { req.Header.Set("Content-Type", "plain/text") } resp, err := cli.HTTPClient().Do(req) if err != nil { if strings.Contains(err.Error(), "connection refused") { return nil, -1, ErrConnectionRefused } return nil, -1, err } if resp.StatusCode < 200 || resp.StatusCode >= 400 { body, err := ioutil.ReadAll(resp.Body) if err != nil { return nil, -1, err } if len(body) == 0 { return nil, resp.StatusCode, fmt.Errorf("Error: request returned %s for API route and version %s, check if the server supports the requested API version", http.StatusText(resp.StatusCode), req.URL) } return nil, resp.StatusCode, fmt.Errorf("Error response from daemon: %s", bytes.TrimSpace(body)) } return resp.Body, resp.StatusCode, nil }
func (s *TagStore) CmdPull(job *engine.Job) engine.Status { if n := len(job.Args); n != 1 && n != 2 { return job.Errorf("Usage: %s IMAGE [TAG]", job.Name) } var ( localName = job.Args[0] tag string sf = utils.NewStreamFormatter(job.GetenvBool("json")) authConfig = ®istry.AuthConfig{} metaHeaders map[string][]string ) if len(job.Args) > 1 { tag = job.Args[1] } job.GetenvJson("authConfig", authConfig) job.GetenvJson("metaHeaders", &metaHeaders) c, err := s.poolAdd("pull", localName+":"+tag) if err != nil { if c != nil { // Another pull of the same repository is already taking place; just wait for it to finish job.Stdout.Write(sf.FormatStatus("", "Repository %s already being pulled by another client. Waiting.", localName)) <-c return engine.StatusOK } return job.Error(err) } defer s.poolRemove("pull", localName+":"+tag) // Resolve the Repository name from fqn to endpoint + name hostname, remoteName, err := registry.ResolveRepositoryName(localName) if err != nil { return job.Error(err) } endpoint, err := registry.ExpandAndVerifyRegistryUrl(hostname) if err != nil { return job.Error(err) } r, err := registry.NewSession(authConfig, registry.HTTPRequestFactory(metaHeaders), endpoint, true) if err != nil { return job.Error(err) } if endpoint == registry.IndexServerAddress() { // If pull "index.docker.io/foo/bar", it's stored locally under "foo/bar" localName = remoteName } if err = s.pullRepository(r, job.Stdout, localName, remoteName, tag, sf, job.GetenvBool("parallel")); err != nil { return job.Error(err) } return engine.StatusOK }
// CmdLogout logs a user out from a Docker registry. // // If no server is specified, the user will be logged out from the registry's index server. // // Usage: docker logout [SERVER] func (cli *DockerCli) CmdLogout(args ...string) error { cmd := cli.Subcmd("logout", "[SERVER]", "Log out from a Docker registry, if no server is\nspecified \""+registry.IndexServerAddress()+"\" is the default.", true) cmd.Require(flag.Max, 1) cmd.ParseFlags(args, true) serverAddress := registry.IndexServerAddress() if len(cmd.Args()) > 0 { serverAddress = cmd.Arg(0) } if _, ok := cli.configFile.AuthConfigs[serverAddress]; !ok { fmt.Fprintf(cli.out, "Not logged in to %s\n", serverAddress) } else { fmt.Fprintf(cli.out, "Remove login credentials for %s\n", serverAddress) delete(cli.configFile.AuthConfigs, serverAddress) if err := cli.configFile.Save(); err != nil { return fmt.Errorf("Failed to save docker config: %v", err) } } return nil }
func (daemon *Daemon) CmdInfo(job *engine.Job) error { images, _ := daemon.Graph().Map() var imgcount int if images == nil { imgcount = 0 } else { imgcount = len(images) } kernelVersion := "<unknown>" if kv, err := kernel.GetKernelVersion(); err == nil { kernelVersion = kv.String() } operatingSystem := "<unknown>" if s, err := operatingsystem.GetOperatingSystem(); err == nil { operatingSystem = s } if inContainer, err := operatingsystem.IsContainerized(); err != nil { logrus.Errorf("Could not determine if daemon is containerized: %v", err) operatingSystem += " (error determining if containerized)" } else if inContainer { operatingSystem += " (containerized)" } meminfo, err := system.ReadMemInfo() if err != nil { logrus.Errorf("Could not read system memory info: %v", err) } // if we still have the original dockerinit binary from before we copied it locally, let's return the path to that, since that's more intuitive (the copied path is trivial to derive by hand given VERSION) initPath := utils.DockerInitPath("") if initPath == "" { // if that fails, we'll just return the path from the daemon initPath = daemon.SystemInitPath() } cjob := job.Eng.Job("subscribers_count") env, _ := cjob.Stdout.AddEnv() if err := cjob.Run(); err != nil { return err } registryJob := job.Eng.Job("registry_config") registryEnv, _ := registryJob.Stdout.AddEnv() if err := registryJob.Run(); err != nil { return err } registryConfig := registry.ServiceConfig{} if err := registryEnv.GetJson("config", ®istryConfig); err != nil { return err } v := &engine.Env{} v.SetJson("ID", daemon.ID) v.SetInt("Containers", len(daemon.List())) v.SetInt("Images", imgcount) v.Set("Driver", daemon.GraphDriver().String()) v.SetJson("DriverStatus", daemon.GraphDriver().Status()) v.SetBool("MemoryLimit", daemon.SystemConfig().MemoryLimit) v.SetBool("SwapLimit", daemon.SystemConfig().SwapLimit) v.SetBool("IPv4Forwarding", !daemon.SystemConfig().IPv4ForwardingDisabled) v.SetBool("Debug", os.Getenv("DEBUG") != "") v.SetInt("NFd", utils.GetTotalUsedFds()) v.SetInt("NGoroutines", runtime.NumGoroutine()) v.Set("SystemTime", time.Now().Format(time.RFC3339Nano)) v.Set("ExecutionDriver", daemon.ExecutionDriver().Name()) v.SetInt("NEventsListener", env.GetInt("count")) v.Set("KernelVersion", kernelVersion) v.Set("OperatingSystem", operatingSystem) v.Set("IndexServerAddress", registry.IndexServerAddress()) v.SetJson("RegistryConfig", registryConfig) v.Set("InitSha1", dockerversion.INITSHA1) v.Set("InitPath", initPath) v.SetInt("NCPU", runtime.NumCPU()) v.SetInt64("MemTotal", meminfo.MemTotal) v.Set("DockerRootDir", daemon.Config().Root) if http_proxy := os.Getenv("http_proxy"); http_proxy != "" { v.Set("HttpProxy", http_proxy) } if https_proxy := os.Getenv("https_proxy"); https_proxy != "" { v.Set("HttpsProxy", https_proxy) } if no_proxy := os.Getenv("no_proxy"); no_proxy != "" { v.Set("NoProxy", no_proxy) } if hostname, err := os.Hostname(); err == nil { v.SetJson("Name", hostname) } v.SetList("Labels", daemon.Config().Labels) if _, err := v.WriteTo(job.Stdout); err != nil { return err } return nil }
func (s *TagStore) CmdPull(job *engine.Job) engine.Status { if n := len(job.Args); n != 1 && n != 2 { return job.Errorf("Usage: %s IMAGE [TAG]", job.Name) } var ( localName = job.Args[0] tag string sf = utils.NewStreamFormatter(job.GetenvBool("json")) authConfig = ®istry.AuthConfig{} metaHeaders map[string][]string mirrors []string ) if len(job.Args) > 1 { tag = job.Args[1] } job.GetenvJson("authConfig", authConfig) job.GetenvJson("metaHeaders", &metaHeaders) c, err := s.poolAdd("pull", localName+":"+tag) if err != nil { if c != nil { // Another pull of the same repository is already taking place; just wait for it to finish job.Stdout.Write(sf.FormatStatus("", "Repository %s already being pulled by another client. Waiting.", localName)) <-c return engine.StatusOK } return job.Error(err) } defer s.poolRemove("pull", localName+":"+tag) // Resolve the Repository name from fqn to endpoint + name hostname, remoteName, err := registry.ResolveRepositoryName(localName) if err != nil { return job.Error(err) } endpoint, err := registry.NewEndpoint(hostname, s.insecureRegistries) if err != nil { return job.Error(err) } r, err := registry.NewSession(authConfig, registry.HTTPRequestFactory(metaHeaders), endpoint, true) if err != nil { return job.Error(err) } var isOfficial bool if endpoint.VersionString(1) == registry.IndexServerAddress() { // If pull "index.docker.io/foo/bar", it's stored locally under "foo/bar" localName = remoteName isOfficial = isOfficialName(remoteName) if isOfficial && strings.IndexRune(remoteName, '/') == -1 { remoteName = "library/" + remoteName } } // Use provided mirrors, if any mirrors = s.mirrors if len(mirrors) == 0 && (isOfficial || endpoint.Version == registry.APIVersion2) { j := job.Eng.Job("trust_update_base") if err = j.Run(); err != nil { return job.Errorf("error updating trust base graph: %s", err) } if err := s.pullV2Repository(job.Eng, r, job.Stdout, localName, remoteName, tag, sf, job.GetenvBool("parallel")); err == nil { return engine.StatusOK } else if err != registry.ErrDoesNotExist { log.Errorf("Error from V2 registry: %s", err) } } if err = s.pullRepository(r, job.Stdout, localName, remoteName, tag, sf, job.GetenvBool("parallel"), mirrors); err != nil { return job.Error(err) } return engine.StatusOK }
// CmdLogin logs in or registers a user to a Docker registry service. // // If no server is specified, the user will be logged into or registered to the registry's index server. // // Usage: docker login SERVER func (cli *DockerCli) CmdLogin(args ...string) error { cmd := cli.Subcmd("login", []string{"[SERVER]"}, "Register or log in to a Docker registry server, if no server is\nspecified \""+registry.IndexServerAddress()+"\" is the default.", true) cmd.Require(flag.Max, 1) var username, password, email string cmd.StringVar(&username, []string{"u", "-username"}, "", "Username") cmd.StringVar(&password, []string{"p", "-password"}, "", "Password") cmd.StringVar(&email, []string{"e", "-email"}, "", "Email") cmd.ParseFlags(args, true) serverAddress := registry.IndexServerAddress() if len(cmd.Args()) > 0 { serverAddress = cmd.Arg(0) } promptDefault := func(prompt string, configDefault string) { if configDefault == "" { fmt.Fprintf(cli.out, "%s: ", prompt) } else { fmt.Fprintf(cli.out, "%s (%s): ", prompt, configDefault) } } readInput := func(in io.Reader, out io.Writer) string { reader := bufio.NewReader(in) line, _, err := reader.ReadLine() if err != nil { fmt.Fprintln(out, err.Error()) os.Exit(1) } return string(line) } authconfig, ok := cli.configFile.AuthConfigs[serverAddress] if !ok { authconfig = cliconfig.AuthConfig{} } if username == "" { promptDefault("Username", authconfig.Username) username = readInput(cli.in, cli.out) username = strings.Trim(username, " ") if username == "" { username = authconfig.Username } } // Assume that a different username means they may not want to use // the password or email from the config file, so prompt them if username != authconfig.Username { if password == "" { oldState, err := term.SaveState(cli.inFd) if err != nil { return err } fmt.Fprintf(cli.out, "Password: "******"\n") term.RestoreTerminal(cli.inFd, oldState) if password == "" { return fmt.Errorf("Error : Password Required") } } if email == "" { promptDefault("Email", authconfig.Email) email = readInput(cli.in, cli.out) if email == "" { email = authconfig.Email } } } else { // However, if they don't override the username use the // password or email from the cmd line if specified. IOW, allow // then to change/override them. And if not specified, just // use what's in the config file if password == "" { password = authconfig.Password } if email == "" { email = authconfig.Email } } authconfig.Username = username authconfig.Password = password authconfig.Email = email authconfig.ServerAddress = serverAddress cli.configFile.AuthConfigs[serverAddress] = authconfig serverResp, err := cli.call("POST", "/auth", cli.configFile.AuthConfigs[serverAddress], nil) if serverResp.statusCode == 401 { delete(cli.configFile.AuthConfigs, serverAddress) if err2 := cli.configFile.Save(); err2 != nil { fmt.Fprintf(cli.out, "WARNING: could not save config file: %v\n", err2) } return err } if err != nil { return err } defer serverResp.body.Close() var response types.AuthResponse if err := json.NewDecoder(serverResp.body).Decode(&response); err != nil { // Upon error, remove entry delete(cli.configFile.AuthConfigs, serverAddress) return err } if err := cli.configFile.Save(); err != nil { return fmt.Errorf("Error saving config file: %v", err) } fmt.Fprintf(cli.out, "WARNING: login credentials saved in %s\n", cli.configFile.Filename()) if response.Status != "" { fmt.Fprintf(cli.out, "%s\n", response.Status) } return nil }
func (s *TagStore) CmdPullAndApply(job *engine.Job) engine.Status { if n := len(job.Args); n != 4 { return job.Errorf("Usage: %s CONTAINERID CONTAINERIMAGE IMAGE TAG", job.Name) } var ( containerID = job.Args[0] containerImage = job.Args[1] localName = job.Args[2] tag = job.Args[3] sf = utils.NewStreamFormatter(job.GetenvBool("json")) authConfig = ®istry.AuthConfig{} metaHeaders map[string][]string mirrors []string ) job.GetenvJson("authConfig", authConfig) job.GetenvJson("metaHeaders", &metaHeaders) for { c, err := s.poolAdd("pull", localName+":"+tag) if err != nil { if c != nil { // Another pull of the same repository is already taking place; just wait for it to finish job.Stdout.Write(sf.FormatStatus("", "Repository %s already being pulled by another client. Waiting.", localName)) <-c continue } else { return job.Error(err) } } break } defer s.poolRemove("pull", localName+":"+tag) // Resolve the Repository name from fqn to endpoint + name hostname, remoteName, err := registry.ResolveRepositoryName(localName) if err != nil { return job.Error(err) } endpoint, err := registry.NewEndpoint(hostname, s.insecureRegistries) if err != nil { return job.Error(err) } r, err := registry.NewSession(authConfig, registry.HTTPRequestFactory(metaHeaders), endpoint, true) if err != nil { return job.Error(err) } if endpoint.VersionString(1) == registry.IndexServerAddress() { // If pull "index.docker.io/foo/bar", it's stored locally under "foo/bar" localName = remoteName isOfficial := isOfficialName(remoteName) if isOfficial && strings.IndexRune(remoteName, '/') == -1 { remoteName = "library/" + remoteName } } // Use provided mirrors, if any mirrors = s.mirrors if err = s.pullMRepository(r, job.Stdout, containerID, containerImage, localName, remoteName, tag, sf, job.GetenvBool("parallel"), mirrors); err != nil { return job.Error(err) } return engine.StatusOK }
func (daemon *Daemon) SystemInfo() (*types.Info, error) { images := daemon.Graph().Map() var imgcount int if images == nil { imgcount = 0 } else { imgcount = len(images) } kernelVersion := "<unknown>" if kv, err := kernel.GetKernelVersion(); err == nil { kernelVersion = kv.String() } operatingSystem := "<unknown>" if s, err := operatingsystem.GetOperatingSystem(); err == nil { operatingSystem = s } // Don't do containerized check on Windows if runtime.GOOS != "windows" { if inContainer, err := operatingsystem.IsContainerized(); err != nil { logrus.Errorf("Could not determine if daemon is containerized: %v", err) operatingSystem += " (error determining if containerized)" } else if inContainer { operatingSystem += " (containerized)" } } meminfo, err := system.ReadMemInfo() if err != nil { logrus.Errorf("Could not read system memory info: %v", err) } // if we still have the original dockerinit binary from before we copied it locally, let's return the path to that, since that's more intuitive (the copied path is trivial to derive by hand given VERSION) initPath := utils.DockerInitPath("") if initPath == "" { // if that fails, we'll just return the path from the daemon initPath = daemon.SystemInitPath() } v := &types.Info{ ID: daemon.ID, Containers: len(daemon.List()), Images: imgcount, Driver: daemon.GraphDriver().String(), DriverStatus: daemon.GraphDriver().Status(), IPv4Forwarding: !daemon.SystemConfig().IPv4ForwardingDisabled, BridgeNfIptables: !daemon.SystemConfig().BridgeNfCallIptablesDisabled, BridgeNfIp6tables: !daemon.SystemConfig().BridgeNfCallIp6tablesDisabled, Debug: os.Getenv("DEBUG") != "", NFd: fileutils.GetTotalUsedFds(), NGoroutines: runtime.NumGoroutine(), SystemTime: time.Now().Format(time.RFC3339Nano), ExecutionDriver: daemon.ExecutionDriver().Name(), LoggingDriver: daemon.defaultLogConfig.Type, NEventsListener: daemon.EventsService.SubscribersCount(), KernelVersion: kernelVersion, OperatingSystem: operatingSystem, IndexServerAddress: registry.IndexServerAddress(), RegistryConfig: daemon.RegistryService.Config, InitSha1: dockerversion.INITSHA1, InitPath: initPath, NCPU: runtime.NumCPU(), MemTotal: meminfo.MemTotal, DockerRootDir: daemon.Config().Root, Labels: daemon.Config().Labels, ExperimentalBuild: utils.ExperimentalBuild(), } // TODO Windows. Refactor this more once sysinfo is refactored into // platform specific code. On Windows, sysinfo.cgroupMemInfo and // sysinfo.cgroupCpuInfo will be nil otherwise and cause a SIGSEGV if // an attempt is made to access through them. if runtime.GOOS != "windows" { v.MemoryLimit = daemon.SystemConfig().MemoryLimit v.SwapLimit = daemon.SystemConfig().SwapLimit v.OomKillDisable = daemon.SystemConfig().OomKillDisable v.CpuCfsPeriod = daemon.SystemConfig().CpuCfsPeriod v.CpuCfsQuota = daemon.SystemConfig().CpuCfsQuota } if httpProxy := os.Getenv("http_proxy"); httpProxy != "" { v.HttpProxy = httpProxy } if httpsProxy := os.Getenv("https_proxy"); httpsProxy != "" { v.HttpsProxy = httpsProxy } if noProxy := os.Getenv("no_proxy"); noProxy != "" { v.NoProxy = noProxy } if hostname, err := os.Hostname(); err == nil { v.Name = hostname } return v, nil }
var allowNetworks = flag.String( "allowNetworks", "", "CIDR blocks representing IPs to whitelist", ) var graphRoot = flag.String( "graph", "/var/lib/garden-docker-graph", "docker image graph", ) var dockerRegistry = flag.String( "registry", registry.IndexServerAddress(), "docker registry API endpoint", ) var insecureRegistries = flag.String( "insecureDockerRegistryList", "", "comma-separated list of docker registries to allow connection to even if they are not secure", ) var tag = flag.String( "tag", "", "server-wide identifier used for 'global' configuration, must be less than 3 character long", )