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