Beispiel #1
0
func (p *podRouter) postVmCreate(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
	if err := httputils.ParseForm(r); err != nil {
		return err
	}

	var (
		cpu   = 1
		mem   = 128
		async = false
		err   error
	)
	if value := r.Form.Get("cpu"); value != "" {
		cpu, err = strconv.Atoi(value)
		if err != nil {
			return err
		}
	}
	if value := r.Form.Get("mem"); value != "" {
		mem, err = strconv.Atoi(value)
		if err != nil {
			return err
		}
	}
	if r.Form.Get("async") == "yes" || r.Form.Get("async") == "true" {
		async = true
	}

	env, err := p.backend.CmdCreateVm(cpu, mem, async)
	if err != nil {
		return err
	}

	return env.WriteJSON(w, http.StatusOK)
}
Beispiel #2
0
func (c *containerRouter) postContainerCreate(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
	if err := httputils.ParseForm(r); err != nil {
		return err
	}

	if err := httputils.CheckForJSON(r); err != nil {
		return err
	}

	imageName := r.Form.Get("imageName")
	glog.V(1).Infof("Image name is %s", imageName)

	config, hostConfig, _, err := runconfig.DecodeContainerConfig(r.Body)
	if err != nil {
		return err
	}

	env, err := c.backend.CmdCreateContainer(types.ContainerCreateConfig{
		Name:       imageName,
		Config:     config,
		HostConfig: hostConfig,
	})

	if err != nil {
		return err
	}

	return env.WriteJSON(w, http.StatusCreated)
}
Beispiel #3
0
func (p *podRouter) postPodStart(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
	if err := httputils.ParseForm(r); err != nil {
		return err
	}

	podId := r.Form.Get("podId")
	vmId := r.Form.Get("vmId")
	tag := r.Form.Get("tag")

	if tag == "" {
		env, err := p.backend.CmdStartPod(nil, nil, podId, vmId, tag)
		if err != nil {
			return err
		}

		return env.WriteJSON(w, http.StatusOK)
	} else {
		// Setting up the streaming http interface.
		inStream, outStream, err := httputils.HijackConnection(w)
		if err != nil {
			return err
		}
		defer httputils.CloseStreams(inStream, outStream)

		fmt.Fprintf(outStream, "HTTP/1.1 101 UPGRADED\r\nContent-Type: application/vnd.docker.raw-stream\r\nConnection: Upgrade\r\nUpgrade: tcp\r\n\r\n")

		if _, err = p.backend.CmdStartPod(inStream, outStream.(io.WriteCloser), podId, vmId, tag); err != nil {
			return err
		}
		w.WriteHeader(http.StatusNoContent)
		return nil
	}
}
Beispiel #4
0
func (s *router) postImagesPush(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
	metaHeaders := map[string][]string{}
	for k, v := range r.Header {
		if strings.HasPrefix(k, "X-Meta-") {
			metaHeaders[k] = v
		}
	}
	if err := httputils.ParseForm(r); err != nil {
		return err
	}
	authConfig := &types.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 = &types.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)
		}
	}

	ref, err := reference.ParseNamed(r.Form.Get("remote"))
	if err != nil {
		return err
	}
	tag := r.Form.Get("tag")
	if tag != "" {
		// Push by digest is not supported, so only tags are supported.
		ref, err = reference.WithTag(ref, tag)
		if err != nil {
			return err
		}
	}

	output := ioutils.NewWriteFlusher(w)
	defer output.Close()

	w.Header().Set("Content-Type", "application/json")

	if err := s.daemon.PushImage(ref, metaHeaders, authConfig, output); err != nil {
		if !output.Flushed() {
			return err
		}
		sf := streamformatter.NewJSONStreamFormatter()
		output.Write(sf.FormatError(err))
	}
	return nil
}
Beispiel #5
0
func (s *serviceRouter) getServices(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
	if err := httputils.ParseForm(r); err != nil {
		return err
	}

	data, err := s.backend.CmdGetServices(r.Form.Get("podId"))
	if err != nil {
		return err
	}

	return httputils.WriteJSON(w, http.StatusOK, data)
}
Beispiel #6
0
func (c *containerRouter) getContainerInfo(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
	if err := httputils.ParseForm(r); err != nil {
		return err
	}

	data, err := c.backend.CmdGetContainerInfo(r.Form.Get("container"))
	if err != nil {
		return err
	}

	return httputils.WriteJSON(w, http.StatusOK, data)
}
Beispiel #7
0
func (s *router) getImagesJSON(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
	if err := httputils.ParseForm(r); err != nil {
		return err
	}

	// FIXME: The filter parameter could just be a match filter
	env, err := s.daemon.CmdImages(r.Form.Get("filters"), r.Form.Get("filter"), httputils.BoolValue(r, "all"))
	if err != nil {
		return err
	}

	return env.WriteJSON(w, http.StatusOK)
}
Beispiel #8
0
func (p *podRouter) postPodUnpause(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
	if err := httputils.ParseForm(r); err != nil {
		return err
	}

	podId := r.Form.Get("podId")
	if err := p.backend.CmdUnpausePod(podId); err != nil {
		return err
	}

	w.WriteHeader(http.StatusNoContent)
	return nil
}
Beispiel #9
0
func (p *podRouter) deleteVm(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
	if err := httputils.ParseForm(r); err != nil {
		return err
	}

	vmId := r.Form.Get("vm")
	env, err := p.backend.CmdKillVm(vmId)
	if err != nil {
		return err
	}

	return env.WriteJSON(w, http.StatusOK)
}
Beispiel #10
0
func (c *containerRouter) postContainerRename(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
	if err := httputils.ParseForm(r); err != nil {
		return err
	}

	newName := r.Form.Get("newName")
	oldName := r.Form.Get("oldName")
	env, err := c.backend.CmdContainerRename(oldName, newName)
	if err != nil {
		return err
	}

	return env.WriteJSON(w, http.StatusOK)
}
Beispiel #11
0
func (p *podRouter) postPodStop(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
	if err := httputils.ParseForm(r); err != nil {
		return err
	}

	podId := r.Form.Get("podId")
	stopVm := r.Form.Get("stopVm")

	env, err := p.backend.CmdStopPod(podId, stopVm)
	if err != nil {
		return err
	}

	return env.WriteJSON(w, http.StatusOK)
}
Beispiel #12
0
func (s *serviceRouter) deleteService(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
	if err := httputils.ParseForm(r); err != nil {
		return err
	}

	podId := r.Form.Get("podId")
	services := r.Form.Get("services")

	data, err := s.backend.CmdDeleteService(podId, services)
	if err != nil {
		return err
	}

	return httputils.WriteJSON(w, http.StatusOK, data)
}
Beispiel #13
0
func (p *podRouter) getList(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
	if err := httputils.ParseForm(r); err != nil {
		return err
	}

	item := r.Form.Get("item")
	auxiliary := httputils.BoolValue(r, "auxiliary")
	pod := r.Form.Get("pod")
	vm := r.Form.Get("vm")

	glog.V(1).Infof("List type is %s, specified pod: [%s], specified vm: [%s], list auxiliary pod: %v", item, pod, vm, auxiliary)

	env, err := p.backend.CmdList(item, pod, vm, auxiliary)
	if err != nil {
		return err
	}

	return env.WriteJSON(w, http.StatusCreated)
}
Beispiel #14
0
func (s *router) deleteImages(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
	if err := httputils.ParseForm(r); err != nil {
		return err
	}

	name := r.Form.Get("imageId")

	if strings.TrimSpace(name) == "" {
		return fmt.Errorf("image name cannot be blank")
	}

	force := httputils.BoolValue(r, "force")
	prune := !httputils.BoolValue(r, "noprune")

	env, err := s.daemon.CmdImageDelete(name, force, prune)
	if err != nil {
		return err
	}

	return env.WriteJSON(w, http.StatusOK)
}
Beispiel #15
0
func (c *containerRouter) postContainerCommit(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
	if err := httputils.ParseForm(r); err != nil {
		return err
	}

	cname := r.Form.Get("container")
	pause := httputils.BoolValue(r, "pause")

	config, _, _, err := runconfig.DecodeContainerConfig(r.Body)
	if err != nil && err != io.EOF { //Do not fail if body is empty.
		return err
	}
	if config == nil {
		config = &container.Config{}
	}

	newConfig, err := dockerfile.BuildFromConfig(config, r.Form["changes"])
	if err != nil {
		return err
	}

	commitCfg := &types.ContainerCommitConfig{
		Pause:        pause,
		Repo:         r.Form.Get("repo"),
		Tag:          r.Form.Get("tag"),
		Author:       r.Form.Get("author"),
		Comment:      r.Form.Get("comment"),
		Config:       newConfig,
		MergeConfigs: true,
	}

	env, err := c.backend.CmdCommitImage(cname, commitCfg)
	if err != nil {
		return err
	}

	return env.WriteJSON(w, http.StatusOK)
}
Beispiel #16
0
func (p *podRouter) postPodCreate(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
	if err := httputils.ParseForm(r); err != nil {
		return err
	}

	if err := httputils.CheckForJSON(r); err != nil {
		return err
	}

	podArgs, _ := ioutil.ReadAll(r.Body)
	autoRemove := false
	if r.Form.Get("remove") == "yes" || r.Form.Get("remove") == "true" {
		autoRemove = true
	}
	glog.V(1).Infof("Args string is %s, autoremove %v", string(podArgs), autoRemove)

	env, err := p.backend.CmdCreatePod(string(podArgs), autoRemove)
	if err != nil {
		return err
	}

	return env.WriteJSON(w, http.StatusCreated)
}
Beispiel #17
0
func (p *podRouter) postPodLabels(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
	if err := httputils.ParseForm(r); err != nil {
		return err
	}

	podId := r.Form.Get("podId")
	labels := make(map[string]string)

	if err := json.Unmarshal([]byte(r.Form.Get("labels")), &labels); err != nil {
		return err
	}

	override := false
	if r.Form.Get("override") == "true" || r.Form.Get("override") == "yes" {
		override = true
	}

	env, err := p.backend.CmdSetPodLabels(podId, override, labels)
	if err != nil {
		return err
	}

	return env.WriteJSON(w, http.StatusCreated)
}
Beispiel #18
0
// Creates an image from Pull or from Import
func (s *router) postImagesCreate(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
	if err := httputils.ParseForm(r); err != nil {
		return err
	}

	var (
		image   = r.Form.Get("imageName")
		repo    = r.Form.Get("repo")
		tag     = r.Form.Get("tag")
		message = r.Form.Get("message")
	)
	authEncoded := r.Header.Get("X-Registry-Auth")
	authConfig := &types.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 = &types.AuthConfig{}
		}
	}

	var (
		err    error
		output = ioutils.NewWriteFlusher(w)
	)
	defer output.Close()

	w.Header().Set("Content-Type", "application/json")

	if image != "" { //pull
		// Special case: "pull -a" may send an image name with a
		// trailing :. This is ugly, but let's not break API
		// compatibility.
		image = strings.TrimSuffix(image, ":")

		var ref reference.Named
		ref, err = reference.ParseNamed(image)
		if err == nil {
			if tag != "" {
				// The "tag" could actually be a digest.
				var dgst digest.Digest
				dgst, err = digest.ParseDigest(tag)
				if err == nil {
					ref, err = reference.WithDigest(ref, dgst)
				} else {
					ref, err = reference.WithTag(ref, tag)
				}
			}
			if err == nil {
				metaHeaders := map[string][]string{}
				for k, v := range r.Header {
					if strings.HasPrefix(k, "X-Meta-") {
						metaHeaders[k] = v
					}
				}

				err = s.daemon.PullImage(ref, metaHeaders, authConfig, output)
			}
		}
	} else { //import
		var newRef reference.Named
		if repo != "" {
			var err error
			newRef, err = reference.ParseNamed(repo)
			if err != nil {
				return err
			}

			if _, isCanonical := newRef.(reference.Canonical); isCanonical {
				return errors.New("cannot import digest reference")
			}

			if tag != "" {
				newRef, err = reference.WithTag(newRef, tag)
				if err != nil {
					return err
				}
			}
		}

		src := r.Form.Get("fromSrc")

		// 'err' MUST NOT be defined within this block, we need any error
		// generated from the download to be available to the output
		// stream processing below
		var newConfig *container.Config
		newConfig, err = dockerfile.BuildFromConfig(&container.Config{}, r.Form["changes"])
		if err != nil {
			return err
		}

		err = s.daemon.ImportImage(src, newRef, message, r.Body, output, newConfig)
	}
	if err != nil {
		if !output.Flushed() {
			return err
		}
		sf := streamformatter.NewJSONStreamFormatter()
		output.Write(sf.FormatError(err))
	}

	return nil
}
Beispiel #19
0
func (c *containerRouter) getContainerLogs(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
	if err := httputils.ParseForm(r); err != nil {
		return err
	}

	// Args are validated before the stream starts because when it starts we're
	// sending HTTP 200 by writing an empty chunk of data to tell the client that
	// daemon is going to stream. By sending this initial HTTP 200 we can't report
	// any error after the stream starts (i.e. container not found, wrong parameters)
	// with the appropriate status code.
	stdout, stderr := httputils.BoolValue(r, "stdout"), httputils.BoolValue(r, "stderr")
	if !(stdout || stderr) {
		return fmt.Errorf("Bad parameters: you must choose at least one stream")
	}

	var since time.Time
	if r.Form.Get("since") != "" {
		s, n, err := timetypes.ParseTimestamps(r.Form.Get("since"), 0)
		if err != nil {
			return err
		}
		since = time.Unix(s, n)
	}

	var closeNotifier <-chan bool
	if notifier, ok := w.(http.CloseNotifier); ok {
		closeNotifier = notifier.CloseNotify()
	}

	containerName := r.Form.Get("container")
	/*
		if !s.backend.Exists(containerName) {
			return derr.ErrorCodeNoSuchContainer.WithArgs(containerName)
		}
	*/
	// write an empty chunk of data (this is to ensure that the
	// HTTP Response is sent immediately, even if the container has
	// not yet produced any data)
	w.WriteHeader(http.StatusOK)
	if flusher, ok := w.(http.Flusher); ok {
		flusher.Flush()
	}

	output := ioutils.NewWriteFlusher(w)
	defer output.Close()

	logsConfig := &daemon.ContainerLogsConfig{
		Follow:     httputils.BoolValue(r, "follow"),
		Timestamps: httputils.BoolValue(r, "timestamps"),
		Since:      since,
		Tail:       r.Form.Get("tail"),
		UseStdout:  stdout,
		UseStderr:  stderr,
		OutStream:  output,
		Stop:       closeNotifier,
	}

	if err := c.backend.CmdGetContainerLogs(containerName, logsConfig); err != nil {
		// The client may be expecting all of the data we're sending to
		// be multiplexed, so send it through OutStream, which will
		// have been set up to handle that if needed.
		fmt.Fprintf(logsConfig.OutStream, "Error running logs job: %s\n", utils.GetErrorMessage(err))
	}

	return nil
}