func getContainerLogs(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 args []string = []string{r.Form.Get("container"), r.Form.Get("tail"), r.Form.Get("since")} boolVals := []string{"follow", "timestamps", "stdout", "stderr"} for _, k := range boolVals { if v := r.Form.Get(k); v == "yes" { args = append(args, k) } } glog.V(1).Infof("Log for %s", r.Form.Get("container")) job := eng.Job("containerLogs", args...) w.Header().Set("Content-Type", "plain/text") outStream := ioutils.NewWriteFlusher(w) job.Stdout.Add(outStream) output := ioutils.NewWriteFlusher(w) if err := job.Run(); err != nil { output.Write([]byte(err.Error())) return err } return nil }
func postImagePush(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 := &cliconfig.AuthConfig{} output := ioutils.NewWriteFlusher(w) 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 { err = fmt.Errorf("Bad parameters and missing X-Registry-Auth: %v", err) sf := streamformatter.NewJSONStreamFormatter() output.Write(sf.FormatError(err)) return nil } } imagePushConfig := &types.ImagePushConfig{ MetaHeaders: metaHeaders, AuthConfig: authConfig, Tag: r.Form.Get("tag"), } w.Header().Set("Content-Type", "application/json") job := eng.Job("push", r.Form.Get("remote")) job.Stdout.Add(output) if err := job.SetenvJson("ImagePushConfig", imagePushConfig); err != nil { sf := streamformatter.NewJSONStreamFormatter() output.Write(sf.FormatError(err)) return nil } if err := job.Run(); err != nil { sf := streamformatter.NewJSONStreamFormatter() output.Write(sf.FormatError(err)) } return nil }
func (s *TagStore) pushImage(r *registry.Session, out io.Writer, imgID, ep string, token []string, sf *streamformatter.StreamFormatter) (checksum string, err error) { out = ioutils.NewWriteFlusher(out) jsonRaw, err := ioutil.ReadFile(filepath.Join(s.graph.Root, imgID, "json")) if err != nil { return "", fmt.Errorf("Cannot retrieve the path for {%s}: %s", imgID, err) } out.Write(sf.FormatProgress(stringid.TruncateID(imgID), "Pushing", nil)) imgData := ®istry.ImgData{ ID: imgID, } // Send the json if err := r.PushImageJSONRegistry(imgData, jsonRaw, ep); err != nil { if err == registry.ErrAlreadyExists { out.Write(sf.FormatProgress(stringid.TruncateID(imgData.ID), "Image already pushed, skipping", nil)) return "", nil } return "", err } layerData, err := s.graph.TempLayerArchive(imgID, sf, out) if err != nil { return "", fmt.Errorf("Failed to generate layer archive: %s", err) } defer os.RemoveAll(layerData.Name()) // Send the layer glog.V(1).Infof("rendered layer for %s of [%d] size", imgData.ID, layerData.Size) checksum, checksumPayload, err := r.PushImageLayerRegistry(imgData.ID, progressreader.New(progressreader.Config{ In: layerData, Out: out, Formatter: sf, Size: int(layerData.Size), NewLines: false, ID: stringid.TruncateID(imgData.ID), Action: "Pushing", }), ep, jsonRaw) if err != nil { return "", err } imgData.Checksum = checksum imgData.ChecksumPayload = checksumPayload // Send the checksum if err := r.PushImageChecksumRegistry(imgData, ep); err != nil { return "", err } out.Write(sf.FormatProgress(stringid.TruncateID(imgData.ID), "Image successfully pushed", nil)) return imgData.Checksum, nil }
func postImageBuild(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error { if err := r.ParseForm(); err != nil { return nil } w.Header().Set("Content-Type", "application/json") glog.V(1).Infof("Image name is %s", r.Form.Get("name")) job := eng.Job("build", r.Form.Get("name")) stdoutBuf := bytes.NewBuffer(nil) job.Stdout.Add(stdoutBuf) job.Stdin.Add(r.Body) output := ioutils.NewWriteFlusher(w) if err := job.Run(); err != nil { sf := streamformatter.NewJSONStreamFormatter() output.Write(sf.FormatError(err)) } return nil }
func (cli Docker) SendImageBuild(name string, context io.ReadCloser) ([]byte, int, error) { var ( authConfig = &cliconfig.AuthConfig{} configFile = &cliconfig.ConfigFile{} buildConfig = builder.NewBuildConfig() ) buildConfig.Remove = true buildConfig.Pull = true output := ioutils.NewWriteFlusher(os.Stdout) buildConfig.Stdout = output buildConfig.Context = context buildConfig.RemoteURL = "" //r.FormValue("remote") buildConfig.DockerfileName = "" // r.FormValue("dockerfile") buildConfig.RepoName = name //r.FormValue("t") buildConfig.SuppressOutput = false //boolValue(r, "q") buildConfig.NoCache = false //boolValue(r, "nocache") buildConfig.ForceRemove = true //boolValue(r, "forcerm") buildConfig.AuthConfig = authConfig buildConfig.ConfigFile = configFile buildConfig.MemorySwap = 0 //int64ValueOrZero(r, "memswap") buildConfig.Memory = 0 //int64ValueOrZero(r, "memory") buildConfig.CpuShares = 0 //int64ValueOrZero(r, "cpushares") buildConfig.CpuPeriod = 0 //int64ValueOrZero(r, "cpuperiod") buildConfig.CpuQuota = 0 //int64ValueOrZero(r, "cpuquota") buildConfig.CpuSetCpus = "" //r.FormValue("cpusetcpus") buildConfig.CpuSetMems = "" //r.FormValue("cpusetmems") buildConfig.CgroupParent = "" //r.FormValue("cgroupparent") if err := builder.Build(cli.daemon, buildConfig); err != nil { glog.Error(err.Error()) // 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. return nil, -1, err } return nil, 0, nil }
func postImageCreate(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 } authEncoded := r.Header.Get("X-Registry-Auth") authConfig := &cliconfig.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 = &cliconfig.AuthConfig{} } } w.Header().Set("Content-Type", "application/json") glog.V(1).Infof("Image name is %s", r.Form.Get("imageName")) job := eng.Job("pull", r.Form.Get("imageName")) output := ioutils.NewWriteFlusher(w) metaHeaders := map[string][]string{} for k, v := range r.Header { if strings.HasPrefix(k, "X-Meta-") { metaHeaders[k] = v } } job.Stdout.Add(output) imagePullConfig := &types.ImagePullConfig{ MetaHeaders: metaHeaders, AuthConfig: authConfig, } job.SetenvJson("ImagePullConfig", imagePullConfig) if err := job.Run(); err != nil { sf := streamformatter.NewJSONStreamFormatter() output.Write(sf.FormatError(err)) } return nil }
// pushRepository pushes layers that do not already exist on the registry. func (s *TagStore) pushRepository(r *registry.Session, out io.Writer, repoInfo *registry.RepositoryInfo, localRepo map[string]string, tag string, sf *streamformatter.StreamFormatter) error { glog.V(1).Infof("Local repo: %s", localRepo) out = ioutils.NewWriteFlusher(out) imgList, tags, err := s.getImageList(localRepo, tag) if err != nil { return err } out.Write(sf.FormatStatus("", "Sending image list")) imageIndex := s.createImageIndex(imgList, tags) glog.V(1).Infof("Preparing to push %s with the following images and tags", localRepo) for _, data := range imageIndex { glog.V(1).Infof("Pushing ID: %s with Tag: %s", data.ID, data.Tag) } // Register all the images in a repository with the registry // If an image is not in this list it will not be associated with the repository repoData, err := r.PushImageJSONIndex(repoInfo.RemoteName, imageIndex, false, nil) if err != nil { return err } nTag := 1 if tag == "" { nTag = len(localRepo) } out.Write(sf.FormatStatus("", "Pushing repository %s (%d tags)", repoInfo.CanonicalName, nTag)) // push the repository to each of the endpoints only if it does not exist. for _, endpoint := range repoData.Endpoints { if err := s.pushImageToEndpoint(endpoint, out, repoInfo.RemoteName, imgList, tags, repoData, sf, r); err != nil { return err } } _, err = r.PushImageJSONIndex(repoInfo.RemoteName, imageIndex, true, repoData.Endpoints) return err }