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) }
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) }
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 } }
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 }
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) }
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) }
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) }
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 }
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) }
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) }
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) }
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) }
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) }
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) }
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) }
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) }
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) }
// 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 }
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 }