Ejemplo n.º 1
0
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
}
Ejemplo n.º 2
0
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
}
Ejemplo n.º 3
0
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 := &registry.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
}
Ejemplo n.º 4
0
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
}
Ejemplo n.º 5
0
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
}
Ejemplo n.º 6
0
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
}
Ejemplo n.º 7
0
// 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
}