github.com/walkingsparrow/docker@v1.4.2-0.20151218153551-b708a2249bfa/api/client/create.go (about) 1 package client 2 3 import ( 4 "fmt" 5 "io" 6 "os" 7 8 "github.com/docker/docker/api/client/lib" 9 "github.com/docker/docker/api/types" 10 Cli "github.com/docker/docker/cli" 11 "github.com/docker/docker/pkg/jsonmessage" 12 "github.com/docker/docker/reference" 13 "github.com/docker/docker/registry" 14 "github.com/docker/docker/runconfig" 15 ) 16 17 func (cli *DockerCli) pullImage(image string) error { 18 return cli.pullImageCustomOut(image, cli.out) 19 } 20 21 func (cli *DockerCli) pullImageCustomOut(image string, out io.Writer) error { 22 ref, err := reference.ParseNamed(image) 23 if err != nil { 24 return err 25 } 26 27 var tag string 28 switch x := reference.WithDefaultTag(ref).(type) { 29 case reference.Canonical: 30 tag = x.Digest().String() 31 case reference.NamedTagged: 32 tag = x.Tag() 33 } 34 35 // Resolve the Repository name from fqn to RepositoryInfo 36 repoInfo, err := registry.ParseRepositoryInfo(ref) 37 if err != nil { 38 return err 39 } 40 41 // Resolve the Auth config relevant for this server 42 encodedAuth, err := cli.encodeRegistryAuth(repoInfo.Index) 43 if err != nil { 44 return err 45 } 46 47 options := types.ImageCreateOptions{ 48 Parent: ref.Name(), 49 Tag: tag, 50 RegistryAuth: encodedAuth, 51 } 52 53 responseBody, err := cli.client.ImageCreate(options) 54 if err != nil { 55 return err 56 } 57 defer responseBody.Close() 58 59 return jsonmessage.DisplayJSONMessagesStream(responseBody, out, cli.outFd, cli.isTerminalOut) 60 } 61 62 type cidFile struct { 63 path string 64 file *os.File 65 written bool 66 } 67 68 func newCIDFile(path string) (*cidFile, error) { 69 if _, err := os.Stat(path); err == nil { 70 return nil, fmt.Errorf("Container ID file found, make sure the other container isn't running or delete %s", path) 71 } 72 73 f, err := os.Create(path) 74 if err != nil { 75 return nil, fmt.Errorf("Failed to create the container ID file: %s", err) 76 } 77 78 return &cidFile{path: path, file: f}, nil 79 } 80 81 func (cli *DockerCli) createContainer(config *runconfig.Config, hostConfig *runconfig.HostConfig, cidfile, name string) (*types.ContainerCreateResponse, error) { 82 mergedConfig := runconfig.MergeConfigs(config, hostConfig) 83 84 var containerIDFile *cidFile 85 if cidfile != "" { 86 var err error 87 if containerIDFile, err = newCIDFile(cidfile); err != nil { 88 return nil, err 89 } 90 defer containerIDFile.Close() 91 } 92 93 ref, err := reference.ParseNamed(config.Image) 94 if err != nil { 95 return nil, err 96 } 97 ref = reference.WithDefaultTag(ref) 98 99 var trustedRef reference.Canonical 100 101 if ref, ok := ref.(reference.NamedTagged); ok && isTrusted() { 102 var err error 103 trustedRef, err = cli.trustedReference(ref) 104 if err != nil { 105 return nil, err 106 } 107 config.Image = trustedRef.String() 108 } 109 110 //create the container 111 response, err := cli.client.ContainerCreate(mergedConfig, name) 112 //if image not found try to pull it 113 if err != nil { 114 if lib.IsErrImageNotFound(err) { 115 fmt.Fprintf(cli.err, "Unable to find image '%s' locally\n", ref.String()) 116 117 // we don't want to write to stdout anything apart from container.ID 118 if err = cli.pullImageCustomOut(config.Image, cli.err); err != nil { 119 return nil, err 120 } 121 if ref, ok := ref.(reference.NamedTagged); ok && trustedRef != nil { 122 if err := cli.tagTrusted(trustedRef, ref); err != nil { 123 return nil, err 124 } 125 } 126 // Retry 127 var retryErr error 128 response, retryErr = cli.client.ContainerCreate(mergedConfig, name) 129 if retryErr != nil { 130 return nil, retryErr 131 } 132 } else { 133 return nil, err 134 } 135 } 136 137 for _, warning := range response.Warnings { 138 fmt.Fprintf(cli.err, "WARNING: %s\n", warning) 139 } 140 if containerIDFile != nil { 141 if err = containerIDFile.Write(response.ID); err != nil { 142 return nil, err 143 } 144 } 145 return &response, nil 146 } 147 148 // CmdCreate creates a new container from a given image. 149 // 150 // Usage: docker create [OPTIONS] IMAGE [COMMAND] [ARG...] 151 func (cli *DockerCli) CmdCreate(args ...string) error { 152 cmd := Cli.Subcmd("create", []string{"IMAGE [COMMAND] [ARG...]"}, Cli.DockerCommands["create"].Description, true) 153 addTrustedFlags(cmd, true) 154 155 // These are flags not stored in Config/HostConfig 156 var ( 157 flName = cmd.String([]string{"-name"}, "", "Assign a name to the container") 158 ) 159 160 config, hostConfig, cmd, err := runconfig.Parse(cmd, args) 161 if err != nil { 162 cmd.ReportError(err.Error(), true) 163 os.Exit(1) 164 } 165 if config.Image == "" { 166 cmd.Usage() 167 return nil 168 } 169 response, err := cli.createContainer(config, hostConfig, hostConfig.ContainerIDFile, *flName) 170 if err != nil { 171 return err 172 } 173 fmt.Fprintf(cli.out, "%s\n", response.ID) 174 return nil 175 }