From a4a80b64a7f6366f7fb94cb8cca042a6324a0e99 Mon Sep 17 00:00:00 2001 From: Alexander Larsson Date: Mon, 17 Mar 2014 17:03:22 +0100 Subject: [PATCH 1/2] server: Break out setHostConfig() from ContainerStart This will be reused for ContainerCreate Docker-DCO-1.1-Signed-off-by: Alexander Larsson (github: alexlarsson) --- server/server.go | 46 +++++++++++++++++++++++++++------------------- 1 file changed, 27 insertions(+), 19 deletions(-) diff --git a/server/server.go b/server/server.go index 3e6de00c1e..b443eba321 100644 --- a/server/server.go +++ b/server/server.go @@ -2035,6 +2035,32 @@ func (srv *Server) ImageGetCached(imgID string, config *runconfig.Config) (*imag return match, nil } +func (srv *Server) setHostConfig(container *daemon.Container, hostConfig *runconfig.HostConfig) error { + // Validate the HostConfig binds. Make sure that: + // the source exists + for _, bind := range hostConfig.Binds { + splitBind := strings.Split(bind, ":") + source := splitBind[0] + + // ensure the source exists on the host + _, err := os.Stat(source) + if err != nil && os.IsNotExist(err) { + err = os.MkdirAll(source, 0755) + if err != nil { + return fmt.Errorf("Could not create local directory '%s' for bind mount: %s!", source, err.Error()) + } + } + } + // Register any links from the host config before starting the container + if err := srv.daemon.RegisterLinks(container, hostConfig); err != nil { + return err + } + container.SetHostConfig(hostConfig) + container.ToDisk() + + return nil +} + func (srv *Server) ContainerStart(job *engine.Job) engine.Status { if len(job.Args) < 1 { return job.Errorf("Usage: %s container_id", job.Name) @@ -2056,27 +2082,9 @@ func (srv *Server) ContainerStart(job *engine.Job) engine.Status { // If no environment was set, then no hostconfig was passed. if len(job.Environ()) > 0 { hostConfig := runconfig.ContainerHostConfigFromJob(job) - // Validate the HostConfig binds. Make sure that: - // the source exists - for _, bind := range hostConfig.Binds { - splitBind := strings.Split(bind, ":") - source := splitBind[0] - - // ensure the source exists on the host - _, err := os.Stat(source) - if err != nil && os.IsNotExist(err) { - err = os.MkdirAll(source, 0755) - if err != nil { - return job.Errorf("Could not create local directory '%s' for bind mount: %s!", source, err.Error()) - } - } - } - // Register any links from the host config before starting the container - if err := srv.daemon.RegisterLinks(container, hostConfig); err != nil { + if err := srv.setHostConfig(container, hostConfig); err != nil { return job.Error(err) } - container.SetHostConfig(hostConfig) - container.ToDisk() } if err := container.Start(); err != nil { return job.Errorf("Cannot start container %s: %s", name, err) From 2b3959c414ffe9403e53617ed1a160c1daabeeaa Mon Sep 17 00:00:00 2001 From: Mrunal Patel Date: Wed, 2 Jul 2014 16:33:14 -0400 Subject: [PATCH 2/2] api.DockerCli: Extract pullImage into separate function This lets us reuse this code later. Docker-DCO-1.1-Signed-off-by: Alexander Larsson (github: alexlarsson) --- api/client/commands.go | 66 +++++++++++++++++++++++------------------- 1 file changed, 37 insertions(+), 29 deletions(-) diff --git a/api/client/commands.go b/api/client/commands.go index 2d9c74f432..93470c2918 100644 --- a/api/client/commands.go +++ b/api/client/commands.go @@ -1894,6 +1894,41 @@ func (cli *DockerCli) CmdTag(args ...string) error { return nil } +func (cli *DockerCli) pullImage(image string) error { + v := url.Values{} + repos, tag := utils.ParseRepositoryTag(image) + // pull only the image tagged 'latest' if no tag was specified + if tag == "" { + tag = "latest" + } + v.Set("fromImage", repos) + v.Set("tag", tag) + + // Resolve the Repository name from fqn to hostname + name + hostname, _, err := registry.ResolveRepositoryName(repos) + if err != nil { + return err + } + + // Load the auth config file, to be able to pull the image + cli.LoadConfigFile() + + // Resolve the Auth config relevant for this server + authConfig := cli.configFile.ResolveAuthConfig(hostname) + buf, err := json.Marshal(authConfig) + if err != nil { + return err + } + + registryAuthHeader := []string{ + base64.URLEncoding.EncodeToString(buf), + } + if err = cli.stream("POST", "/images/create?"+v.Encode(), nil, cli.err, map[string][]string{"X-Registry-Auth": registryAuthHeader}); err != nil { + return err + } + return nil +} + func (cli *DockerCli) CmdRun(args ...string) error { // FIXME: just use runconfig.Parse already config, hostConfig, cmd, err := runconfig.ParseSubcommand(cli.Subcmd("run", "[OPTIONS] IMAGE [COMMAND] [ARG...]", "Run a command in a new container"), args, nil) @@ -1955,37 +1990,10 @@ func (cli *DockerCli) CmdRun(args ...string) error { if statusCode == 404 { fmt.Fprintf(cli.err, "Unable to find image '%s' locally\n", config.Image) - v := url.Values{} - repos, tag := utils.ParseRepositoryTag(config.Image) - // pull only the image tagged 'latest' if no tag was specified - if tag == "" { - tag = "latest" - } - v.Set("fromImage", repos) - v.Set("tag", tag) - - // Resolve the Repository name from fqn to hostname + name - hostname, _, err := registry.ResolveRepositoryName(repos) - if err != nil { - return err - } - - // Load the auth config file, to be able to pull the image - cli.LoadConfigFile() - - // Resolve the Auth config relevant for this server - authConfig := cli.configFile.ResolveAuthConfig(hostname) - buf, err := json.Marshal(authConfig) - if err != nil { - return err - } - - registryAuthHeader := []string{ - base64.URLEncoding.EncodeToString(buf), - } - if err = cli.stream("POST", "/images/create?"+v.Encode(), nil, cli.err, map[string][]string{"X-Registry-Auth": registryAuthHeader}); err != nil { + if err = cli.pullImage(config.Image); err != nil { return err } + // Retry if stream, _, err = cli.call("POST", "/containers/create?"+containerValues.Encode(), config, false); err != nil { return err }