func (s *DockerServer) removeImage(w http.ResponseWriter, r *http.Request) { id := mux.Vars(r)["id"] s.iMut.RLock() var tag string if img, ok := s.imgIDs[id]; ok { id, tag = img, id } var tags []string for tag, taggedID := range s.imgIDs { if taggedID == id { tags = append(tags, tag) } } s.iMut.RUnlock() _, index, err := s.findImageByID(id) if err != nil { http.Error(w, err.Error(), http.StatusNotFound) return } w.WriteHeader(http.StatusNoContent) s.iMut.Lock() defer s.iMut.Unlock() if len(tags) < 2 { s.images[index] = s.images[len(s.images)-1] s.images = s.images[:len(s.images)-1] } if tag != "" { delete(s.imgIDs, tag) } }
func (s *DockerServer) resizeExecContainer(w http.ResponseWriter, r *http.Request) { id := mux.Vars(r)["id"] if _, err := s.getExec(id, false); err == nil { w.WriteHeader(http.StatusOK) return } w.WriteHeader(http.StatusNotFound) }
func (s *DockerServer) inspectExecContainer(w http.ResponseWriter, r *http.Request) { id := mux.Vars(r)["id"] if exec, err := s.getExec(id, true); err == nil { w.WriteHeader(http.StatusOK) w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(exec) return } w.WriteHeader(http.StatusNotFound) }
func (s *DockerServer) inspectContainer(w http.ResponseWriter, r *http.Request) { id := mux.Vars(r)["id"] container, _, err := s.findContainer(id) if err != nil { http.Error(w, err.Error(), http.StatusNotFound) return } w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) json.NewEncoder(w).Encode(container) }
func (s *DockerServer) attachContainer(w http.ResponseWriter, r *http.Request) { id := mux.Vars(r)["id"] container, _, err := s.findContainer(id) if err != nil { http.Error(w, err.Error(), http.StatusNotFound) return } hijacker, ok := w.(http.Hijacker) if !ok { http.Error(w, "cannot hijack connection", http.StatusInternalServerError) return } w.Header().Set("Content-Type", "application/vnd.docker.raw-stream") w.WriteHeader(http.StatusOK) conn, _, err := hijacker.Hijack() if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } wg := sync.WaitGroup{} if r.URL.Query().Get("stdin") == "1" { wg.Add(1) go func() { ioutil.ReadAll(conn) wg.Done() }() } outStream := stdcopy.NewStdWriter(conn, stdcopy.Stdout) if container.State.Running { fmt.Fprintf(outStream, "Container is running\n") } else { fmt.Fprintf(outStream, "Container is not running\n") } fmt.Fprintln(outStream, "What happened?") fmt.Fprintln(outStream, "Something happened") wg.Wait() if r.URL.Query().Get("stream") == "1" { for { time.Sleep(1e6) s.cMut.RLock() if !container.State.Running { s.cMut.RUnlock() break } s.cMut.RUnlock() } } conn.Close() }
func (s *DockerServer) unpauseContainer(w http.ResponseWriter, r *http.Request) { id := mux.Vars(r)["id"] container, _, err := s.findContainer(id) if err != nil { http.Error(w, err.Error(), http.StatusNotFound) return } s.cMut.Lock() defer s.cMut.Unlock() if !container.State.Paused { http.Error(w, "Container not paused", http.StatusBadRequest) return } w.WriteHeader(http.StatusNoContent) container.State.Paused = false }
func (s *DockerServer) renameContainer(w http.ResponseWriter, r *http.Request) { id := mux.Vars(r)["id"] container, index, err := s.findContainer(id) if err != nil { http.Error(w, err.Error(), http.StatusNotFound) return } copy := *container copy.Name = r.URL.Query().Get("name") s.cMut.Lock() defer s.cMut.Unlock() if s.containers[index].ID == copy.ID { s.containers[index] = © } w.WriteHeader(http.StatusNoContent) }
func (s *DockerServer) pushImage(w http.ResponseWriter, r *http.Request) { name := mux.Vars(r)["name"] tag := r.URL.Query().Get("tag") if tag != "" { name += ":" + tag } s.iMut.RLock() if _, ok := s.imgIDs[name]; !ok { s.iMut.RUnlock() http.Error(w, "No such image", http.StatusNotFound) return } s.iMut.RUnlock() fmt.Fprintln(w, "Pushing...") fmt.Fprintln(w, "Pushed") }
func (s *DockerServer) inspectImage(w http.ResponseWriter, r *http.Request) { name := mux.Vars(r)["name"] s.iMut.RLock() defer s.iMut.RUnlock() if id, ok := s.imgIDs[name]; ok { for _, img := range s.images { if img.ID == id { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) json.NewEncoder(w).Encode(img) return } } } http.Error(w, "not found", http.StatusNotFound) }
func (s *DockerServer) stopContainer(w http.ResponseWriter, r *http.Request) { id := mux.Vars(r)["id"] container, _, err := s.findContainer(id) if err != nil { http.Error(w, err.Error(), http.StatusNotFound) return } s.cMut.Lock() defer s.cMut.Unlock() if !container.State.Running { http.Error(w, "Container not running", http.StatusBadRequest) return } w.WriteHeader(http.StatusNoContent) container.State.Running = false s.notify(container) }
func (s *DockerServer) removeContainer(w http.ResponseWriter, r *http.Request) { id := mux.Vars(r)["id"] force := r.URL.Query().Get("force") _, index, err := s.findContainer(id) if err != nil { http.Error(w, err.Error(), http.StatusNotFound) return } if s.containers[index].State.Running && force != "1" { msg := "Error: API error (406): Impossible to remove a running container, please stop it first" http.Error(w, msg, http.StatusInternalServerError) return } w.WriteHeader(http.StatusNoContent) s.cMut.Lock() defer s.cMut.Unlock() s.containers[index] = s.containers[len(s.containers)-1] s.containers = s.containers[:len(s.containers)-1] }
func (s *DockerServer) tagImage(w http.ResponseWriter, r *http.Request) { name := mux.Vars(r)["name"] s.iMut.RLock() if _, ok := s.imgIDs[name]; !ok { s.iMut.RUnlock() http.Error(w, "No such image", http.StatusNotFound) return } s.iMut.RUnlock() s.iMut.Lock() defer s.iMut.Unlock() newRepo := r.URL.Query().Get("repo") newTag := r.URL.Query().Get("tag") if newTag != "" { newRepo += ":" + newTag } s.imgIDs[newRepo] = s.imgIDs[name] w.WriteHeader(http.StatusCreated) }
func (s *DockerServer) waitContainer(w http.ResponseWriter, r *http.Request) { id := mux.Vars(r)["id"] container, _, err := s.findContainer(id) if err != nil { http.Error(w, err.Error(), http.StatusNotFound) return } for { time.Sleep(1e6) s.cMut.RLock() if !container.State.Running { s.cMut.RUnlock() break } s.cMut.RUnlock() } result := map[string]int{"StatusCode": container.State.ExitCode} json.NewEncoder(w).Encode(result) }
func (s *DockerServer) startExecContainer(w http.ResponseWriter, r *http.Request) { id := mux.Vars(r)["id"] if exec, err := s.getExec(id, false); err == nil { s.execMut.Lock() exec.Running = true s.execMut.Unlock() if callback, ok := s.execCallbacks[id]; ok { callback() delete(s.execCallbacks, id) } else if callback, ok := s.execCallbacks["*"]; ok { callback() delete(s.execCallbacks, "*") } s.execMut.Lock() exec.Running = false s.execMut.Unlock() w.WriteHeader(http.StatusOK) return } w.WriteHeader(http.StatusNotFound) }
func (s *DockerServer) createExecContainer(w http.ResponseWriter, r *http.Request) { id := mux.Vars(r)["id"] container, _, err := s.findContainer(id) if err != nil { http.Error(w, err.Error(), http.StatusNotFound) return } execID := s.generateID() container.ExecIDs = append(container.ExecIDs, execID) exec := docker.ExecInspect{ ID: execID, Container: *container, } var params docker.CreateExecOptions err = json.NewDecoder(r.Body).Decode(¶ms) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } if len(params.Cmd) > 0 { exec.ProcessConfig.EntryPoint = params.Cmd[0] if len(params.Cmd) > 1 { exec.ProcessConfig.Arguments = params.Cmd[1:] } } exec.ProcessConfig.User = params.User exec.ProcessConfig.Tty = params.Tty s.execMut.Lock() s.execs = append(s.execs, &exec) s.execMut.Unlock() w.WriteHeader(http.StatusOK) w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(map[string]string{"Id": exec.ID}) }
func (s *DockerServer) topContainer(w http.ResponseWriter, r *http.Request) { id := mux.Vars(r)["id"] container, _, err := s.findContainer(id) if err != nil { http.Error(w, err.Error(), http.StatusNotFound) return } if !container.State.Running { w.WriteHeader(http.StatusInternalServerError) fmt.Fprintf(w, "Container %s is not running", id) return } w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) result := docker.TopResult{ Titles: []string{"UID", "PID", "PPID", "C", "STIME", "TTY", "TIME", "CMD"}, Processes: [][]string{ {"root", "7535", "7516", "0", "03:20", "?", "00:00:00", container.Path + " " + strings.Join(container.Args, " ")}, }, } json.NewEncoder(w).Encode(result) }
func (s *DockerServer) statsContainer(w http.ResponseWriter, r *http.Request) { id := mux.Vars(r)["id"] _, _, err := s.findContainer(id) if err != nil { http.Error(w, err.Error(), http.StatusNotFound) return } stream, _ := strconv.ParseBool(r.URL.Query().Get("stream")) callback := s.statsCallbacks[id] w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) encoder := json.NewEncoder(w) for { var stats docker.Stats if callback != nil { stats = callback(id) } encoder.Encode(stats) if !stream { break } } }
func (s *DockerServer) startContainer(w http.ResponseWriter, r *http.Request) { id := mux.Vars(r)["id"] container, _, err := s.findContainer(id) if err != nil { http.Error(w, err.Error(), http.StatusNotFound) return } s.cMut.Lock() defer s.cMut.Unlock() defer r.Body.Close() var hostConfig docker.HostConfig err = json.NewDecoder(r.Body).Decode(&hostConfig) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } container.HostConfig = &hostConfig if container.State.Running { http.Error(w, "", http.StatusNotModified) return } container.State.Running = true s.notify(container) }