func (s *Server) getImagesGet(version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
if vars == nil {
return fmt.Errorf("Missing parameter")
}
if err := parseForm(r); err != nil {
return err
}
useJSON := version.GreaterThan("1.0")
if useJSON {
w.Header().Set("Content-Type", "application/x-tar")
}
output := utils.NewWriteFlusher(w)
imageExportConfig := &graph.ImageExportConfig{Outstream: output}
if name, ok := vars["name"]; ok {
imageExportConfig.Names = []string{name}
} else {
imageExportConfig.Names = r.Form["names"]
}
if err := s.daemon.Repositories().ImageExport(imageExportConfig); err != nil {
if !output.Flushed() {
return err
}
sf := streamformatter.NewStreamFormatter(useJSON)
output.Write(sf.FormatError(err))
}
return nil
}
开发者ID:pbx0,项目名称:docker,代码行数:31,代码来源:server.go
示例2: postImagesCreate
// Creates an image from Pull or from Import
func postImagesCreate(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
if err := parseForm(r); err != nil {
return err
}
var (
image = r.Form.Get("fromImage")
repo = r.Form.Get("repo")
tag = r.Form.Get("tag")
job *engine.Job
)
authEncoded := r.Header.Get("X-Registry-Auth")
authConfig := ®istry.AuthConfig{}
if authEncoded != "" {
authJson := base64.NewDecoder(base64.URLEncoding, strings.NewReader(authEncoded))
if err := json.NewDecoder(authJson).Decode(authConfig); err != nil {
// for a pull it is not an error if no auth was given
// to increase compatibility with the existing api it is defaulting to be empty
authConfig = ®istry.AuthConfig{}
}
}
if image != "" { //pull
if tag == "" {
image, tag = parsers.ParseRepositoryTag(image)
}
metaHeaders := map[string][]string{}
for k, v := range r.Header {
if strings.HasPrefix(k, "X-Meta-") {
metaHeaders[k] = v
}
}
job = eng.Job("pull", image, tag)
job.SetenvBool("parallel", version.GreaterThan("1.3"))
job.SetenvJson("metaHeaders", metaHeaders)
job.SetenvJson("authConfig", authConfig)
} else { //import
if tag == "" {
repo, tag = parsers.ParseRepositoryTag(repo)
}
job = eng.Job("import", r.Form.Get("fromSrc"), repo, tag)
job.Stdin.Add(r.Body)
job.SetenvList("changes", r.Form["changes"])
}
if version.GreaterThan("1.0") {
job.SetenvBool("json", true)
streamJSON(job, w, true)
} else {
job.Stdout.Add(utils.NewWriteFlusher(w))
}
if err := job.Run(); err != nil {
if !job.Stdout.Used() {
return err
}
sf := streamformatter.NewStreamFormatter(version.GreaterThan("1.0"))
w.Write(sf.FormatError(err))
}
return nil
}
开发者ID:yingmsky,项目名称:docker,代码行数:61,代码来源:server.go
示例3: Push
// FIXME: Allow to interrupt current push when new push of same image is done.
func (s *TagStore) Push(localName string, imagePushConfig *ImagePushConfig) error {
var (
sf = streamformatter.NewStreamFormatter(imagePushConfig.Json)
)
// Resolve the Repository name from fqn to RepositoryInfo
repoInfo, err := s.registryService.ResolveRepository(localName)
if err != nil {
return err
}
if _, err := s.poolAdd("push", repoInfo.LocalName); err != nil {
return err
}
defer s.poolRemove("push", repoInfo.LocalName)
endpoint, err := repoInfo.GetEndpoint()
if err != nil {
return err
}
r, err := registry.NewSession(imagePushConfig.AuthConfig, registry.HTTPRequestFactory(imagePushConfig.MetaHeaders), endpoint, false)
if err != nil {
return err
}
reposLen := 1
if imagePushConfig.Tag == "" {
reposLen = len(s.Repositories[repoInfo.LocalName])
}
imagePushConfig.OutStream.Write(sf.FormatStatus("", "The push refers to a repository [%s] (len: %d)", repoInfo.CanonicalName, reposLen))
// If it fails, try to get the repository
localRepo, exists := s.Repositories[repoInfo.LocalName]
if !exists {
return fmt.Errorf("Repository does not exist: %s", repoInfo.LocalName)
}
if repoInfo.Index.Official || endpoint.Version == registry.APIVersion2 {
err := s.pushV2Repository(r, localRepo, imagePushConfig.OutStream, repoInfo, imagePushConfig.Tag, sf)
if err == nil {
s.eventsService.Log("push", repoInfo.LocalName, "")
return nil
}
if err != ErrV2RegistryUnavailable {
return fmt.Errorf("Error pushing to registry: %s", err)
}
}
if err := s.pushRepository(r, imagePushConfig.OutStream, repoInfo, localRepo, imagePushConfig.Tag, sf); err != nil {
return err
}
s.eventsService.Log("push", repoInfo.LocalName, "")
return nil
}
开发者ID:pbx0,项目名称:docker,代码行数:59,代码来源:push.go
示例4: postImagesPush
func (s *Server) postImagesPush(version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
if vars == nil {
return fmt.Errorf("Missing parameter")
}
metaHeaders := map[string][]string{}
for k, v := range r.Header {
if strings.HasPrefix(k, "X-Meta-") {
metaHeaders[k] = v
}
}
if err := parseForm(r); err != nil {
return err
}
authConfig := &cliconfig.AuthConfig{}
authEncoded := r.Header.Get("X-Registry-Auth")
if authEncoded != "" {
// the new format is to handle the authConfig as a header
authJson := base64.NewDecoder(base64.URLEncoding, strings.NewReader(authEncoded))
if err := json.NewDecoder(authJson).Decode(authConfig); err != nil {
// to increase compatibility to existing api it is defaulting to be empty
authConfig = &cliconfig.AuthConfig{}
}
} else {
// the old format is supported for compatibility if there was no authConfig header
if err := json.NewDecoder(r.Body).Decode(authConfig); err != nil {
return fmt.Errorf("Bad parameters and missing X-Registry-Auth: %v", err)
}
}
useJSON := version.GreaterThan("1.0")
name := vars["name"]
output := utils.NewWriteFlusher(w)
imagePushConfig := &graph.ImagePushConfig{
MetaHeaders: metaHeaders,
AuthConfig: authConfig,
Tag: r.Form.Get("tag"),
OutStream: output,
Json: useJSON,
}
if useJSON {
w.Header().Set("Content-Type", "application/json")
}
if err := s.daemon.Repositories().Push(name, imagePushConfig); err != nil {
if !output.Flushed() {
return err
}
sf := streamformatter.NewStreamFormatter(useJSON)
output.Write(sf.FormatError(err))
}
return nil
}
开发者ID:pbx0,项目名称:docker,代码行数:56,代码来源:server.go
示例5: Import
func (s *TagStore) Import(src string, repo string, tag string, imageImportConfig *ImageImportConfig) error {
var (
sf = streamformatter.NewStreamFormatter(imageImportConfig.Json)
archive archive.ArchiveReader
resp *http.Response
)
if src == "-" {
archive = imageImportConfig.InConfig
} else {
u, err := url.Parse(src)
if err != nil {
return err
}
if u.Scheme == "" {
u.Scheme = "http"
u.Host = src
u.Path = ""
}
imageImportConfig.OutStream.Write(sf.FormatStatus("", "Downloading from %s", u))
resp, err = httputils.Download(u.String())
if err != nil {
return err
}
progressReader := progressreader.New(progressreader.Config{
In: resp.Body,
Out: imageImportConfig.OutStream,
Formatter: sf,
Size: int(resp.ContentLength),
NewLines: true,
ID: "",
Action: "Importing",
})
defer progressReader.Close()
archive = progressReader
}
img, err := s.graph.Create(archive, "", "", "Imported from "+src, "", nil, imageImportConfig.ContainerConfig)
if err != nil {
return err
}
// Optionally register the image at REPO/TAG
if repo != "" {
if err := s.Tag(repo, tag, img.ID, true); err != nil {
return err
}
}
imageImportConfig.OutStream.Write(sf.FormatStatus("", img.ID))
logID := img.ID
if tag != "" {
logID = utils.ImageReference(logID, tag)
}
s.eventsService.Log("import", logID, "")
return nil
}
开发者ID:pbx0,项目名称:docker,代码行数:56,代码来源:import.go
示例6: getContextFromURL
// getContextFromURL uses a remote URL as context for a `docker build`. The
// remote resource is downloaded as either a Dockerfile or a tar archive.
// Returns the tar archive used for the context and a path of the
// dockerfile inside the tar.
func getContextFromURL(out io.Writer, remoteURL, dockerfileName string) (io.ReadCloser, string, error) {
response, err := httputils.Download(remoteURL)
if err != nil {
return nil, "", fmt.Errorf("unable to download remote context %s: %v", remoteURL, err)
}
progressOutput := streamformatter.NewStreamFormatter().NewProgressOutput(out, true)
// Pass the response body through a progress reader.
progReader := progress.NewProgressReader(response.Body, progressOutput, response.ContentLength, "", fmt.Sprintf("Downloading build context from remote url: %s", remoteURL))
return getContextFromReader(ioutils.NewReadCloserWrapper(progReader, func() error { return response.Body.Close() }), dockerfileName)
}
func postImagesPush(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
if vars == nil {
return fmt.Errorf("Missing parameter")
}
metaHeaders := map[string][]string{}
for k, v := range r.Header {
if strings.HasPrefix(k, "X-Meta-") {
metaHeaders[k] = v
}
}
if err := parseForm(r); err != nil {
return err
}
authConfig := ®istry.AuthConfig{}
authEncoded := r.Header.Get("X-Registry-Auth")
if authEncoded != "" {
// the new format is to handle the authConfig as a header
authJson := base64.NewDecoder(base64.URLEncoding, strings.NewReader(authEncoded))
if err := json.NewDecoder(authJson).Decode(authConfig); err != nil {
// to increase compatibility to existing api it is defaulting to be empty
authConfig = ®istry.AuthConfig{}
}
} else {
// the old format is supported for compatibility if there was no authConfig header
if err := json.NewDecoder(r.Body).Decode(authConfig); err != nil {
return fmt.Errorf("Bad parameters and missing X-Registry-Auth: %v", err)
}
}
job := eng.Job("push", vars["name"])
job.SetenvJson("metaHeaders", metaHeaders)
job.SetenvJson("authConfig", authConfig)
job.Setenv("tag", r.Form.Get("tag"))
if version.GreaterThan("1.0") {
job.SetenvBool("json", true)
streamJSON(job, w, true)
} else {
job.Stdout.Add(utils.NewWriteFlusher(w))
}
if err := job.Run(); err != nil {
if !job.Stdout.Used() {
return err
}
sf := streamformatter.NewStreamFormatter(version.GreaterThan("1.0"))
w.Write(sf.FormatError(err))
}
return nil
}
开发者ID:yingmsky,项目名称:docker,代码行数:51,代码来源:server.go
示例8: Build
// Build implements Builder. It consumes the docker build API endpoint and sends
// a tar of the specified service build context.
func (d *DaemonBuilder) Build(imageName string, p *project.Project, service project.Service) error {
if service.Config().Build == "" {
return fmt.Errorf("Specified service does not have a build section")
}
ctx, err := CreateTar(p, service.Name())
if err != nil {
return err
}
defer ctx.Close()
var progBuff io.Writer = os.Stdout
var buildBuff io.Writer = os.Stdout
// Setup an upload progress bar
progressOutput := streamformatter.NewStreamFormatter().NewProgressOutput(progBuff, true)
var body io.Reader = progress.NewProgressReader(ctx, progressOutput, 0, "", "Sending build context to Docker daemon")
client := d.context.ClientFactory.Create(service)
logrus.Infof("Building %s...", imageName)
outFd, isTerminalOut := term.GetFdInfo(os.Stdout)
response, err := client.ImageBuild(context.Background(), types.ImageBuildOptions{
Context: body,
Tags: []string{imageName},
NoCache: d.context.NoCache,
Remove: true,
Dockerfile: service.Config().Dockerfile,
AuthConfigs: d.context.ConfigFile.AuthConfigs,
})
err = jsonmessage.DisplayJSONMessagesStream(response.Body, buildBuff, outFd, isTerminalOut, nil)
if err != nil {
if jerr, ok := err.(*jsonmessage.JSONError); ok {
// If no error code is set, default to 1
if jerr.Code == 0 {
jerr.Code = 1
}
fmt.Fprintf(os.Stderr, "%s%s", progBuff, buildBuff)
return fmt.Errorf("Status: %s, Code: %d", jerr.Message, jerr.Code)
}
}
return err
}
// getContextFromURL uses a remote URL as context for a `docker build`. The
// remote resource is downloaded as either a Dockerfile or a context tar
// archive and stored in a temporary directory used as the context directory.
// Returns the absolute path to the temporary context directory, the relative
// path of the dockerfile in that context directory, and a non-nil error on
// success.
func getContextFromURL(out io.Writer, remoteURL, dockerfileName string) (absContextDir, relDockerfile string, err error) {
response, err := httputils.Download(remoteURL)
if err != nil {
return "", "", fmt.Errorf("unable to download remote context %s: %v", remoteURL, err)
}
defer response.Body.Close()
// Pass the response body through a progress reader.
progReader := &progressreader.Config{
In: response.Body,
Out: out,
Formatter: streamformatter.NewStreamFormatter(),
Size: response.ContentLength,
NewLines: true,
ID: "",
Action: fmt.Sprintf("Downloading build context from remote url: %s", remoteURL),
}
return getContextFromReader(progReader, dockerfileName)
}
//.........这里部分代码省略.........
if err := utils.ValidateContextDirectory(contextDir, excludes); err != nil {
return fmt.Errorf("Error checking context: '%s'.", err)
}
// If .dockerignore mentions .dockerignore or the Dockerfile
// then make sure we send both files over to the daemon
// because Dockerfile is, obviously, needed no matter what, and
// .dockerignore is needed to know if either one needs to be
// removed. The deamon will remove them for us, if needed, after it
// parses the Dockerfile. Ignore errors here, as they will have been
// caught by ValidateContextDirectory above.
var includes = []string{"."}
keepThem1, _ := fileutils.Matches(".dockerignore", excludes)
keepThem2, _ := fileutils.Matches(relDockerfile, excludes)
if keepThem1 || keepThem2 {
includes = append(includes, ".dockerignore", relDockerfile)
}
context, err = archive.TarWithOptions(contextDir, &archive.TarOptions{
Compression: archive.Uncompressed,
ExcludePatterns: excludes,
IncludeFiles: includes,
})
if err != nil {
return err
}
// Wrap the tar archive to replace the Dockerfile entry with the rewritten
// Dockerfile which uses trusted pulls.
context = replaceDockerfileTarWrapper(context, newDockerfile, relDockerfile)
// Setup an upload progress bar
// FIXME: ProgressReader shouldn't be this annoying to use
sf := streamformatter.NewStreamFormatter()
var body io.Reader = progressreader.New(progressreader.Config{
In: context,
Out: cli.out,
Formatter: sf,
NewLines: true,
ID: "",
Action: "Sending build context to Docker daemon",
})
var memory int64
if *flMemoryString != "" {
parsedMemory, err := units.RAMInBytes(*flMemoryString)
if err != nil {
return err
}
memory = parsedMemory
}
var memorySwap int64
if *flMemorySwap != "" {
if *flMemorySwap == "-1" {
memorySwap = -1
} else {
parsedMemorySwap, err := units.RAMInBytes(*flMemorySwap)
if err != nil {
return err
}
memorySwap = parsedMemorySwap
}
}
// Send the build context
开发者ID:maaquib,项目名称:docker,代码行数:67,代码来源:build.go
示例14: runBuild
//.........这里部分代码省略.........
// removed. The daemon will remove them for us, if needed, after it
// parses the Dockerfile. Ignore errors here, as they will have been
// caught by validateContextDirectory above.
var includes = []string{"."}
keepThem1, _ := fileutils.Matches(".dockerignore", excludes)
keepThem2, _ := fileutils.Matches(relDockerfile, excludes)
if keepThem1 || keepThem2 {
includes = append(includes, ".dockerignore", relDockerfile)
}
buildCtx, err = archive.TarWithOptions(contextDir, &archive.TarOptions{
Compression: archive.Uncompressed,
ExcludePatterns: excludes,
IncludeFiles: includes,
})
if err != nil {
return err
}
}
ctx := context.Background()
var resolvedTags []*resolvedTag
if command.IsTrusted() {
translator := func(ctx context.Context, ref reference.NamedTagged) (reference.Canonical, error) {
return TrustedReference(ctx, dockerCli, ref)
}
// Wrap the tar archive to replace the Dockerfile entry with the rewritten
// Dockerfile which uses trusted pulls.
buildCtx = replaceDockerfileTarWrapper(ctx, buildCtx, relDockerfile, translator, &resolvedTags)
}
// Setup an upload progress bar
progressOutput := streamformatter.NewStreamFormatter().NewProgressOutput(progBuff, true)
if !dockerCli.Out().IsTerminal() {
progressOutput = &lastProgressOutput{output: progressOutput}
}
var body io.Reader = progress.NewProgressReader(buildCtx, progressOutput, 0, "", "Sending build context to Docker daemon")
var memory int64
if options.memory != "" {
parsedMemory, err := units.RAMInBytes(options.memory)
if err != nil {
return err
}
memory = parsedMemory
}
var memorySwap int64
if options.memorySwap != "" {
if options.memorySwap == "-1" {
memorySwap = -1
} else {
parsedMemorySwap, err := units.RAMInBytes(options.memorySwap)
if err != nil {
return err
}
memorySwap = parsedMemorySwap
}
}
var shmSize int64
if options.shmSize != "" {
shmSize, err = units.RAMInBytes(options.shmSize)
if err != nil {
开发者ID:vieux,项目名称:docker,代码行数:67,代码来源:build.go
示例15: HyperCmdBuild
//.........这里部分代码省略.........
// Now reset the dockerfileName to be relative to the build context
opts.DockerfileName, err = filepath.Rel(absRoot, filename)
if err != nil {
return err
}
// And canonicalize dockerfile name to a platform-independent one
opts.DockerfileName, err = archive.CanonicalTarNameForPath(opts.DockerfileName)
if err != nil {
return fmt.Errorf("Cannot canonicalize dockerfile path %s: %v", opts.DockerfileName, err)
}
if _, err = os.Lstat(filename); os.IsNotExist(err) {
return fmt.Errorf("Cannot locate Dockerfile: %s", origDockerfile)
}
var includes = []string{"."}
f, err := os.Open(filepath.Join(root, ".dockerignore"))
if err != nil && !os.IsNotExist(err) {
return err
}
defer f.Close()
var excludes []string
if err == nil {
excludes, err = utils.ReadDockerIgnore(f)
if err != nil {
return err
}
}
if err := utils.ValidateContextDirectory(root, excludes); err != nil {
return fmt.Errorf("Error checking context: '%s'.", err)
}
// If .dockerignore mentions .dockerignore or the Dockerfile
// then make sure we send both files over to the daemon
// because Dockerfile is, obviously, needed no matter what, and
// .dockerignore is needed to know if either one needs to be
// removed. The deamon will remove them for us, if needed, after it
// parses the Dockerfile.
keepThem1, _ := fileutils.Matches(".dockerignore", excludes)
keepThem2, _ := fileutils.Matches(opts.DockerfileName, excludes)
if keepThem1 || keepThem2 {
includes = append(includes, ".dockerignore", opts.DockerfileName)
}
if err := utils.ValidateContextDirectory(root, excludes); err != nil {
return fmt.Errorf("Error checking context: '%s'.", err)
}
options := &archive.TarOptions{
Compression: archive.Uncompressed,
ExcludePatterns: excludes,
IncludeFiles: includes,
}
context, err = archive.TarWithOptions(root, options)
if err != nil {
return err
}
var body io.Reader
// Setup an upload progress bar
// FIXME: ProgressReader shouldn't be this annoying to use
if context != nil {
sf := streamformatter.NewStreamFormatter()
body = progressreader.New(progressreader.Config{
In: context,
Out: os.Stdout,
Formatter: sf,
NewLines: true,
ID: "",
Action: "Sending build context to Docker daemon",
})
}
if opts.ImageName == "" {
// set a image name
name = rand.RandStr(10, "alphanum")
} else {
name = opts.ImageName
repository, tag := parsers.ParseRepositoryTag(name)
if err := registry.ValidateRepositoryName(repository); err != nil {
return err
}
if len(tag) > 0 {
if err := tags.ValidateTagName(tag); err != nil {
return err
}
}
}
v := url.Values{}
v.Set("name", name)
headers := http.Header(make(map[string][]string))
if context != nil {
headers.Set("Content-Type", "application/tar")
}
err = cli.stream("POST", "/image/build?"+v.Encode(), body, cli.out, headers)
if err != nil {
return err
}
return nil
}
开发者ID:KnightKu,项目名称:hyper,代码行数:101,代码来源:build.go
示例16: CmdBuild
func (b *BuilderJob) CmdBuild(job *engine.Job) error {
if len(job.Args) != 0 {
return fmt.Errorf("Usage: %s\n", job.Name)
}
var (
dockerfileName = job.Getenv("dockerfile")
remoteURL = job.Getenv("remote")
repoName = job.Getenv("t")
suppressOutput = job.GetenvBool("q")
noCache = job.GetenvBool("nocache")
rm = job.GetenvBool("rm")
forceRm = job.GetenvBool("forcerm")
pull = job.GetenvBool("pull")
memory = job.GetenvInt64("memory")
memorySwap = job.GetenvInt64("memswap")
cpuShares = job.GetenvInt64("cpushares")
cpuSetCpus = job.Getenv("cpusetcpus")
cpuSetMems = job.Getenv("cpusetmems")
authConfig = ®istry.AuthConfig{}
configFile = ®istry.ConfigFile{}
tag string
context io.ReadCloser
)
job.GetenvJson("authConfig", authConfig)
job.GetenvJson("configFile", configFile)
repoName, tag = parsers.ParseRepositoryTag(repoName)
if repoName != "" {
if err := registry.ValidateRepositoryName(repoName); err != nil {
return err
}
if len(tag) > 0 {
if err := graph.ValidateTagName(tag); err != nil {
return err
}
}
}
if remoteURL == "" {
context = ioutil.NopCloser(job.Stdin)
} else if urlutil.IsGitURL(remoteURL) {
if !urlutil.IsGitTransport(remoteURL) {
remoteURL = "https://" + remoteURL
}
root, err := ioutil.TempDir("", "docker-build-git")
if err != nil {
return err
}
defer os.RemoveAll(root)
if output, err := exec.Command("git", "clone", "--recursive", remoteURL, root).CombinedOutput(); err != nil {
return fmt.Errorf("Error trying to use git: %s (%s)", err, output)
}
c, err := archive.Tar(root, archive.Uncompressed)
if err != nil {
return err
}
context = c
} else if urlutil.IsURL(remoteURL) {
f, err := httputils.Download(remoteURL)
if err != nil {
return err
}
defer f.Body.Close()
dockerFile, err := ioutil.ReadAll(f.Body)
if err != nil {
return err
}
// When we're downloading just a Dockerfile put it in
// the default name - don't allow the client to move/specify it
dockerfileName = api.DefaultDockerfileName
c, err := archive.Generate(dockerfileName, string(dockerFile))
if err != nil {
return err
}
context = c
}
defer context.Close()
sf := streamformatter.NewStreamFormatter(job.GetenvBool("json"))
builder := &Builder{
Daemon: b.Daemon,
Engine: b.Engine,
OutStream: &streamformatter.StdoutFormater{
Writer: job.Stdout,
StreamFormatter: sf,
},
ErrStream: &streamformatter.StderrFormater{
Writer: job.Stdout,
StreamFormatter: sf,
},
Verbose: !suppressOutput,
UtilizeCache: !noCache,
Remove: rm,
ForceRemove: forceRm,
//.........这里部分代码省略.........
开发者ID:yingmsky,项目名称:docker,代码行数:101,代码来源:job.go
示例17: postBuild
func (s *Server) postBuild(version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
if version.LessThan("1.3") {
return fmt.Errorf("Multipart upload for build is no longer supported. Please upgrade your docker client.")
}
var (
authEncoded = r.Header.Get("X-Registry-Auth")
authConfig = &cliconfig.AuthConfig{}
configFileEncoded = r.Header.Get("X-Registry-Config")
configFile = &cliconfig.ConfigFile{}
buildConfig = builder.NewBuildConfig()
)
// This block can be removed when API versions prior to 1.9 are deprecated.
// Both headers will be parsed and sent along to the daemon, but if a non-empty
// ConfigFile is present, any value provided as an AuthConfig directly will
// be overridden. See BuildFile::CmdFrom for details.
if version.LessThan("1.9") && authEncoded != "" {
authJson := base64.NewDecoder(base64.URLEncoding, strings.NewReader(authEncoded))
if err := json.NewDecoder(authJson).Decode(authConfig); err != nil {
// for a pull it is not an error if no auth was given
// to increase compatibility with the existing api it is defaulting to be empty
authConfig = &cliconfig.AuthConfig{}
}
}
if configFileEncoded != "" {
configFileJson := base64.NewDecoder(base64.URLEncoding, strings.NewReader(configFileEncoded))
if err := json.NewDecoder(configFileJson).Decode(configFile); err != nil {
// for a pull it is not an error if no auth was given
// to increase compatibility with the existing api it is defaulting to be empty
configFile = &cliconfig.ConfigFile{}
}
}
if version.GreaterThanOrEqualTo("1.8") {
w.Header().Set("Content-Type", "application/json")
buildConfig.JSONFormat = true
}
if boolValue(r, "forcerm") && version.GreaterThanOrEqualTo("1.12") {
buildConfig.Remove = true
} else if r.FormValue("rm") == "" && version.GreaterThanOrEqualTo("1.12") {
buildConfig.Remove = true
} else {
buildConfig.Remove = boolValue(r, "rm")
}
if boolValue(r, "pull") && version.GreaterThanOrEqualTo("1.16") {
buildConfig.Pull = true
}
output := utils.NewWriteFlusher(w)
buildConfig.Stdout = output
buildConfig.Context = r.Body
buildConfig.RemoteURL = r.FormValue("remote")
buildConfig.DockerfileName = r.FormValue("dockerfile")
buildConfig.RepoName = r.FormValue("t")
buildConfig.SuppressOutput = boolValue(r, "q")
buildConfig.NoCache = boolValue(r, "nocache")
buildConfig.ForceRemove = boolValue(r, "forcerm")
buildConfig.AuthConfig = authConfig
buildConfig.ConfigFile = configFile
buildConfig.MemorySwap = int64ValueOrZero(r, "memswap")
buildConfig.Memory = int64ValueOrZero(r, "memory")
buildConfig.CpuShares = int64ValueOrZero(r, "cpushares")
buildConfig.CpuQuota = int64ValueOrZero(r, "cpuquota")
buildConfig.CpuSetCpus = r.FormValue("cpusetcpus")
buildConfig.CpuSetMems = r.FormValue("cpusetmems")
buildConfig.CgroupParent = r.FormValue("cgroupparent")
// Job cancellation. Note: not all job types support this.
if closeNotifier, ok := w.(http.CloseNotifier); ok {
finished := make(chan struct{})
defer close(finished)
go func() {
select {
case <-finished:
case <-closeNotifier.CloseNotify():
logrus.Infof("Client disconnected, cancelling job: build")
buildConfig.Cancel()
}
}()
}
if err := builder.Build(s.daemon, buildConfig); err != nil {
// Do not write the error in the http output if it's still empty.
// This prevents from writing a 200(OK) when there is an interal error.
if !output.Flushed() {
return err
}
sf := streamformatter.NewStreamFormatter(version.GreaterThanOrEqualTo("1.8"))
w.Write(sf.FormatError(err))
}
return nil
}
开发者ID:pbx0,项目名称:docker,代码行数:95,代码来源:server.go
示例18: postBuild
func postBuild(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
if version.LessThan("1.3") {
return fmt.Errorf("Multipart upload for build is no longer supported. Please upgrade your docker client.")
}
var (
authEncoded = r.Header.Get("X-Registry-Auth")
authConfig = ®istry.AuthConfig{}
configFileEncoded = r.Header.Get("X-Registry-Config")
configFile = ®istry.ConfigFile{}
job = eng.Job("build")
)
// This block can be removed when API versions prior to 1.9 are deprecated.
// Both headers will be parsed and sent along to the daemon, but if a non-empty
// ConfigFile is present, any value provided as an AuthConfig directly will
// be overridden. See BuildFile::CmdFrom for details.
if version.LessThan("1.9") && authEncoded != "" {
authJson := base64.NewDecoder(base64.URLEncoding, strings.NewReader(authEncoded))
if err := json.NewDecoder(authJson).Decode(authConfig); err != nil {
// for a pull it is not an error if no auth was given
// to increase compatibility with the existing api it is defaulting to be empty
authConfig = ®istry.AuthConfig{}
}
}
if configFileEncoded != "" {
configFileJson := base64.NewDecoder(base64.URLEncoding, strings.NewReader(configFileEncoded))
if err := json.NewDecoder(configFileJson).Decode(configFile); err != nil {
// for a pull it is not an error if no auth was given
// to increase compatibility with the existing api it is defaulting to be empty
configFile = ®istry.ConfigFile{}
}
}
if version.GreaterThanOrEqualTo("1.8") {
job.SetenvBool("json", true)
streamJSON(job, w, true)
} else {
job.Stdout.Add(utils.NewWriteFlusher(w))
}
if toBool(r.FormValue("forcerm")) && version.GreaterThanOrEqualTo("1.12") {
job.Setenv("rm", "1")
} else if r.FormValue("rm") == "" && version.GreaterThanOrEqualTo("1.12") {
job.Setenv("rm", "1")
} else {
job.Setenv("rm", r.FormValue("rm"))
}
if toBool(r.FormValue("pull")) && version.GreaterThanOrEqualTo("1.16") {
job.Setenv("pull", "1")
}
job.Stdin.Add(r.Body)
job.Setenv("remote", r.FormValue("remote"))
job.Setenv("dockerfile", r.FormValue("dockerfile"))
job.Setenv("t", r.FormValue("t"))
job.Setenv("q", r.FormValue("q"))
job.Setenv("nocache", r.FormValue("nocache"))
job.Setenv("forcerm", r.FormValue("forcerm"))
job.SetenvJson("authConfig", authConfig)
job.SetenvJson("configFile", configFile)
job.Setenv("memswap", r.FormValue("memswap"))
job.Setenv("memory", r.FormValue("memory"))
job.Setenv("cpusetcpus", r.FormValue("cpusetcpus"))
job.Setenv("cpusetmems", r.FormValue("cpusetmems"))
job.Setenv("cpushares", r.FormValue("cpushares"))
// Job cancellation. Note: not all job types support this.
if closeNotifier, ok := w.(http.CloseNotifier); ok {
finished := make(chan struct{})
defer close(finished)
go func() {
select {
case <-finished:
case <-closeNotifier.CloseNotify():
logrus.Infof("Client disconnected, cancelling job: %s", job.Name)
job.Cancel()
}
}()
}
if err := job.Run(); err != nil {
if !job.Stdout.Used() {
return err
}
sf := streamformatter.NewStreamFormatter(version.GreaterThanOrEqualTo("1.8"))
w.Write(sf.FormatError(err))
}
return nil
}
开发者ID:yingmsky,项目名称:docker,代码行数:89,代码来源:server.go
示例19: Build
// Build will build all images in the Parity setup
func (c *DockerCompose) Build() error {
log.Stage("Bulding containers")
base := "Dockerfile"
cwd, _ := os.Getwd()
baseVersion := c.generateContainerVersion(cwd, base)
imageName := fmt.Sprintf("%s:%s", c.ImageName, baseVersion)
client, _ := dockerclient2.NewEnvClient()
log.Step("Checking if image %s exists locally", imageName)
if images, err := client.ImageList(context.Background(), types.ImageListOptions{MatchName: imageName}); err == nil {
for _, i := range images {
log.Info("Found image: %s", i.ID)
return nil
}
}
log.Step("Image %s not found locally, pulling", imageName)
client.ImagePull(context.Background(), types.ImagePullOptions{ImageID: imageName}, nil)
log.Step("Image %s not found anywhere, building", imageName)
ctx, err := c.CreateTar(".", "Dockerfile")
if err != nil {
return err
}
defer ctx.Close()
var progBuff io.Writer = os.Stdout
var buildBuff io.Writer = os.Stdout
// Setup an upload progress bar
progressOutput := streamformatter.NewStreamFormatter().NewProgressOutput(progBuff, true)
var body io.Reader = progress.NewProgressReader(ctx, progressOutput, 0, "", "Sending build context to Docker daemon")
logrus.Infof("Building %s...", imageName)
outFd, isTerminalOut := term.GetFdInfo(os.Stdout)
// Publish latest and specific version
response, err := client.ImageBuild(context.Background(), types.ImageBuildOptions{
Context: body,
Tags: []string{imageName, fmt.Sprintf("%s:latest", c.ImageName)},
NoCache: false,
Remove: true,
Dockerfile: "Dockerfile",
})
if err != nil {
log.Error(err.Error())
return err
}
err = jsonmessage.DisplayJSONMessagesStream(response.Body, buildBuff, outFd, isTerminalOut, nil)
if err != nil {
if jerr, ok := err.(*jsonmessage.JSONError); ok {
// If no error code is set, default to 1
if jerr.Code == 0 {
jerr.Code = 1
}
fmt.Fprintf(os.Stderr, "%s%s", progBuff, buildBuff)
return fmt.Errorf("Status: %s, Code: %d", jerr.Message, jerr.Code)
}
}
return err
}
请发表评论