diff options
Diffstat (limited to 'pkg/api/handlers/compat')
-rw-r--r-- | pkg/api/handlers/compat/containers.go | 18 | ||||
-rw-r--r-- | pkg/api/handlers/compat/containers_create.go | 13 | ||||
-rw-r--r-- | pkg/api/handlers/compat/containers_restart.go | 16 | ||||
-rw-r--r-- | pkg/api/handlers/compat/exec.go | 107 | ||||
-rw-r--r-- | pkg/api/handlers/compat/images.go | 10 | ||||
-rw-r--r-- | pkg/api/handlers/compat/images_history.go | 2 | ||||
-rw-r--r-- | pkg/api/handlers/compat/images_remove.go | 22 | ||||
-rw-r--r-- | pkg/api/handlers/compat/info.go | 8 |
8 files changed, 152 insertions, 44 deletions
diff --git a/pkg/api/handlers/compat/containers.go b/pkg/api/handlers/compat/containers.go index 1298e7fa4..2ce113d30 100644 --- a/pkg/api/handlers/compat/containers.go +++ b/pkg/api/handlers/compat/containers.go @@ -7,7 +7,6 @@ import ( "strconv" "strings" "sync" - "syscall" "time" "github.com/containers/libpod/libpod" @@ -15,6 +14,7 @@ import ( "github.com/containers/libpod/libpod/logs" "github.com/containers/libpod/pkg/api/handlers" "github.com/containers/libpod/pkg/api/handlers/utils" + "github.com/containers/libpod/pkg/signal" "github.com/containers/libpod/pkg/util" "github.com/gorilla/schema" "github.com/pkg/errors" @@ -87,7 +87,7 @@ func ListContainers(w http.ResponseWriter, r *http.Request) { utils.InternalServerError(w, err) return } - if _, found := r.URL.Query()["limit"]; found { + if _, found := r.URL.Query()["limit"]; found && query.Limit != -1 { last := query.Limit if len(containers) > last { containers = containers[len(containers)-last:] @@ -145,14 +145,20 @@ func KillContainer(w http.ResponseWriter, r *http.Request) { runtime := r.Context().Value("runtime").(*libpod.Runtime) decoder := r.Context().Value("decoder").(*schema.Decoder) query := struct { - Signal syscall.Signal `schema:"signal"` + Signal string `schema:"signal"` }{ - Signal: syscall.SIGKILL, + Signal: "KILL", } if err := decoder.Decode(&query, r.URL.Query()); err != nil { utils.Error(w, "Something went wrong.", http.StatusBadRequest, errors.Wrapf(err, "Failed to parse parameters for %s", r.URL.String())) return } + + sig, err := signal.ParseSignalNameOrNumber(query.Signal) + if err != nil { + utils.InternalServerError(w, err) + return + } name := utils.GetName(r) con, err := runtime.LookupContainer(name) if err != nil { @@ -172,7 +178,7 @@ func KillContainer(w http.ResponseWriter, r *http.Request) { return } - err = con.Kill(uint(query.Signal)) + err = con.Kill(uint(sig)) if err != nil { utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrapf(err, "unable to kill Container %s", name)) } @@ -326,7 +332,6 @@ func LogsFromContainer(w http.ResponseWriter, r *http.Request) { builder.WriteRune(' ') } builder.WriteString(line.Msg) - // Build header and output entry binary.BigEndian.PutUint32(header[4:], uint32(len(header)+builder.Len())) if _, err := w.Write(header[:]); err != nil { @@ -335,7 +340,6 @@ func LogsFromContainer(w http.ResponseWriter, r *http.Request) { if _, err := fmt.Fprint(w, builder.String()); err != nil { log.Errorf("unable to write builder string: %q", err) } - if flusher, ok := w.(http.Flusher); ok { flusher.Flush() } diff --git a/pkg/api/handlers/compat/containers_create.go b/pkg/api/handlers/compat/containers_create.go index 6b8440fc2..12af40876 100644 --- a/pkg/api/handlers/compat/containers_create.go +++ b/pkg/api/handlers/compat/containers_create.go @@ -6,8 +6,8 @@ import ( "net/http" "strings" + "github.com/containers/common/pkg/config" "github.com/containers/libpod/libpod" - "github.com/containers/libpod/libpod/define" image2 "github.com/containers/libpod/libpod/image" "github.com/containers/libpod/pkg/api/handlers" "github.com/containers/libpod/pkg/api/handlers/utils" @@ -46,7 +46,12 @@ func CreateContainer(w http.ResponseWriter, r *http.Request) { utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "NewFromLocal()")) return } - cc, err := makeCreateConfig(input, newImage) + defaultContainerConfig, err := runtime.GetConfig() + if err != nil { + utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "GetConfig()")) + return + } + cc, err := makeCreateConfig(defaultContainerConfig, input, newImage) if err != nil { utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "makeCreatConfig()")) return @@ -55,7 +60,7 @@ func CreateContainer(w http.ResponseWriter, r *http.Request) { utils.CreateContainer(r.Context(), w, runtime, &cc) } -func makeCreateConfig(input handlers.CreateContainerConfig, newImage *image2.Image) (createconfig.CreateConfig, error) { +func makeCreateConfig(defaultContainerConfig *config.Config, input handlers.CreateContainerConfig, newImage *image2.Image) (createconfig.CreateConfig, error) { var ( err error init bool @@ -76,7 +81,7 @@ func makeCreateConfig(input handlers.CreateContainerConfig, newImage *image2.Ima workDir = input.WorkingDir } - stopTimeout := uint(define.CtrRemoveTimeout) + stopTimeout := defaultContainerConfig.Engine.StopTimeout if input.StopTimeout != nil { stopTimeout = uint(*input.StopTimeout) } diff --git a/pkg/api/handlers/compat/containers_restart.go b/pkg/api/handlers/compat/containers_restart.go index 5b8fafaa4..343bf96d2 100644 --- a/pkg/api/handlers/compat/containers_restart.go +++ b/pkg/api/handlers/compat/containers_restart.go @@ -1,11 +1,9 @@ package compat import ( - "fmt" "net/http" "github.com/containers/libpod/libpod" - "github.com/containers/libpod/libpod/define" "github.com/containers/libpod/pkg/api/handlers/utils" "github.com/gorilla/schema" "github.com/pkg/errors" @@ -32,20 +30,6 @@ func RestartContainer(w http.ResponseWriter, r *http.Request) { return } - state, err := con.State() - if err != nil { - utils.InternalServerError(w, err) - return - } - - // FIXME: This is not in the swagger.yml... - // If the Container is stopped already, send a 409 - if state == define.ContainerStateStopped || state == define.ContainerStateExited { - msg := fmt.Sprintf("Container %s is not running", name) - utils.Error(w, msg, http.StatusConflict, errors.New(msg)) - return - } - timeout := con.StopTimeout() if _, found := r.URL.Query()["t"]; found { timeout = uint(query.Timeout) diff --git a/pkg/api/handlers/compat/exec.go b/pkg/api/handlers/compat/exec.go new file mode 100644 index 000000000..ec1a8ac96 --- /dev/null +++ b/pkg/api/handlers/compat/exec.go @@ -0,0 +1,107 @@ +package compat + +import ( + "encoding/json" + "fmt" + "net/http" + "strings" + + "github.com/containers/libpod/libpod" + "github.com/containers/libpod/libpod/define" + "github.com/containers/libpod/pkg/api/handlers" + "github.com/containers/libpod/pkg/api/handlers/utils" + "github.com/gorilla/mux" + "github.com/pkg/errors" + "github.com/sirupsen/logrus" +) + +// ExecCreateHandler creates an exec session for a given container. +func ExecCreateHandler(w http.ResponseWriter, r *http.Request) { + runtime := r.Context().Value("runtime").(*libpod.Runtime) + + input := new(handlers.ExecCreateConfig) + if err := json.NewDecoder(r.Body).Decode(&input); err != nil { + utils.InternalServerError(w, errors.Wrapf(err, "error decoding request body as JSON")) + return + } + + ctrName := utils.GetName(r) + ctr, err := runtime.LookupContainer(ctrName) + if err != nil { + utils.ContainerNotFound(w, ctrName, err) + return + } + + libpodConfig := new(libpod.ExecConfig) + libpodConfig.Command = input.Cmd + libpodConfig.Terminal = input.Tty + libpodConfig.AttachStdin = input.AttachStdin + libpodConfig.AttachStderr = input.AttachStderr + libpodConfig.AttachStdout = input.AttachStdout + if input.DetachKeys != "" { + libpodConfig.DetachKeys = &input.DetachKeys + } + libpodConfig.Environment = make(map[string]string) + for _, envStr := range input.Env { + split := strings.SplitN(envStr, "=", 2) + if len(split) != 2 { + utils.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest, errors.Errorf("environment variable %q badly formed, must be key=value", envStr)) + return + } + libpodConfig.Environment[split[0]] = split[1] + } + libpodConfig.WorkDir = input.WorkingDir + libpodConfig.Privileged = input.Privileged + libpodConfig.User = input.User + + sessID, err := ctr.ExecCreate(libpodConfig) + if err != nil { + if errors.Cause(err) == define.ErrCtrStateInvalid { + // Check if the container is paused. If so, return a 409 + state, err := ctr.State() + if err == nil { + // Ignore the error != nil case. We're already + // throwing an InternalServerError below. + if state == define.ContainerStatePaused { + utils.Error(w, "Container is paused", http.StatusConflict, errors.Errorf("cannot create exec session as container %s is paused", ctr.ID())) + return + } + } + } + utils.InternalServerError(w, err) + return + } + + resp := new(handlers.ExecCreateResponse) + resp.ID = sessID + + utils.WriteResponse(w, http.StatusCreated, resp) +} + +// ExecInspectHandler inspects a given exec session. +func ExecInspectHandler(w http.ResponseWriter, r *http.Request) { + runtime := r.Context().Value("runtime").(*libpod.Runtime) + + sessionID := mux.Vars(r)["id"] + sessionCtr, err := runtime.GetExecSessionContainer(sessionID) + if err != nil { + utils.Error(w, fmt.Sprintf("No such exec session: %s", sessionID), http.StatusNotFound, err) + return + } + + logrus.Debugf("Inspecting exec session %s of container %s", sessionID, sessionCtr.ID()) + + session, err := sessionCtr.ExecSession(sessionID) + if err != nil { + utils.InternalServerError(w, errors.Wrapf(err, "error retrieving exec session %s from container %s", sessionID, sessionCtr.ID())) + return + } + + inspectOut, err := session.Inspect() + if err != nil { + utils.InternalServerError(w, err) + return + } + + utils.WriteResponse(w, http.StatusOK, inspectOut) +} diff --git a/pkg/api/handlers/compat/images.go b/pkg/api/handlers/compat/images.go index b18687bf9..ea9cbd691 100644 --- a/pkg/api/handlers/compat/images.go +++ b/pkg/api/handlers/compat/images.go @@ -15,6 +15,7 @@ import ( image2 "github.com/containers/libpod/libpod/image" "github.com/containers/libpod/pkg/api/handlers" "github.com/containers/libpod/pkg/api/handlers/utils" + "github.com/containers/libpod/pkg/domain/entities" "github.com/containers/libpod/pkg/util" "github.com/docker/docker/api/types" "github.com/gorilla/schema" @@ -63,6 +64,7 @@ func PruneImages(w http.ResponseWriter, r *http.Request) { runtime := r.Context().Value("runtime").(*libpod.Runtime) query := struct { + All bool Filters map[string][]string `schema:"filters"` }{ // This is where you can override the golang default value for one of fields @@ -79,7 +81,7 @@ func PruneImages(w http.ResponseWriter, r *http.Request) { filters = append(filters, fmt.Sprintf("%s=%s", k, val)) } } - pruneCids, err := runtime.ImageRuntime().PruneImages(r.Context(), false, filters) + pruneCids, err := runtime.ImageRuntime().PruneImages(r.Context(), query.All, filters) if err != nil { utils.InternalServerError(w, err) return @@ -127,13 +129,13 @@ func CommitContainer(w http.ResponseWriter, r *http.Request) { utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "Decode()")) return } - sc := image2.GetSystemContext(rtc.SignaturePolicyPath, "", false) + sc := image2.GetSystemContext(rtc.Engine.SignaturePolicyPath, "", false) tag := "latest" options := libpod.ContainerCommitOptions{ Pause: true, } options.CommitOptions = buildah.CommitOptions{ - SignaturePolicyPath: rtc.SignaturePolicyPath, + SignaturePolicyPath: rtc.Engine.SignaturePolicyPath, ReportWriter: os.Stderr, SystemContext: sc, PreferredManifestType: manifest.DockerV2Schema2MediaType, @@ -305,7 +307,7 @@ func GetImages(w http.ResponseWriter, r *http.Request) { utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "Failed get images")) return } - var summaries = make([]*handlers.ImageSummary, len(images)) + var summaries = make([]*entities.ImageSummary, len(images)) for j, img := range images { is, err := handlers.ImageToImageSummary(img) if err != nil { diff --git a/pkg/api/handlers/compat/images_history.go b/pkg/api/handlers/compat/images_history.go index 04304caa4..afadf4c48 100644 --- a/pkg/api/handlers/compat/images_history.go +++ b/pkg/api/handlers/compat/images_history.go @@ -28,7 +28,7 @@ func HistoryImage(w http.ResponseWriter, r *http.Request) { for _, h := range history { l := handlers.HistoryResponse{ ID: h.ID, - Created: h.Created.UnixNano(), + Created: h.Created.Unix(), CreatedBy: h.CreatedBy, Tags: h.Tags, Size: h.Size, diff --git a/pkg/api/handlers/compat/images_remove.go b/pkg/api/handlers/compat/images_remove.go index 3d346543e..ed0153529 100644 --- a/pkg/api/handlers/compat/images_remove.go +++ b/pkg/api/handlers/compat/images_remove.go @@ -36,17 +36,23 @@ func RemoveImage(w http.ResponseWriter, r *http.Request) { return } - _, err = runtime.RemoveImage(r.Context(), newImage, query.Force) + results, err := runtime.RemoveImage(r.Context(), newImage, query.Force) if err != nil { utils.Error(w, "Something went wrong.", http.StatusInternalServerError, err) return } - // TODO - // This will need to be fixed for proper response, like Deleted: and Untagged: - m := make(map[string]string) - m["Deleted"] = newImage.ID() - foo := []map[string]string{} - foo = append(foo, m) - utils.WriteResponse(w, http.StatusOK, foo) + + response := make([]map[string]string, 0, len(results.Untagged)+1) + deleted := make(map[string]string, 1) + deleted["Deleted"] = results.Deleted + response = append(response, deleted) + + for _, u := range results.Untagged { + untagged := make(map[string]string, 1) + untagged["Untagged"] = u + response = append(response, untagged) + } + + utils.WriteResponse(w, http.StatusOK, response) } diff --git a/pkg/api/handlers/compat/info.go b/pkg/api/handlers/compat/info.go index 30b49948d..104d0793b 100644 --- a/pkg/api/handlers/compat/info.go +++ b/pkg/api/handlers/compat/info.go @@ -9,8 +9,8 @@ import ( "strings" "time" + "github.com/containers/common/pkg/config" "github.com/containers/libpod/libpod" - "github.com/containers/libpod/libpod/config" "github.com/containers/libpod/libpod/define" "github.com/containers/libpod/pkg/api/handlers" "github.com/containers/libpod/pkg/api/handlers/utils" @@ -60,7 +60,7 @@ func GetInfo(w http.ResponseWriter, r *http.Request) { CPUCfsQuota: sysInfo.CPUCfsQuota, CPUSet: sysInfo.Cpuset, CPUShares: sysInfo.CPUShares, - CgroupDriver: configInfo.CgroupManager, + CgroupDriver: configInfo.Engine.CgroupManager, ClusterAdvertise: "", ClusterStore: "", ContainerdCommit: docker.Commit{}, @@ -69,7 +69,7 @@ func GetInfo(w http.ResponseWriter, r *http.Request) { ContainersRunning: stateInfo[define.ContainerStateRunning], ContainersStopped: stateInfo[define.ContainerStateStopped] + stateInfo[define.ContainerStateExited], Debug: log.IsLevelEnabled(log.DebugLevel), - DefaultRuntime: configInfo.OCIRuntime, + DefaultRuntime: configInfo.Engine.OCIRuntime, DockerRootDir: storeInfo["GraphRoot"].(string), Driver: storeInfo["GraphDriverName"].(string), DriverStatus: getGraphStatus(storeInfo), @@ -152,7 +152,7 @@ func getSecOpts(sysInfo *sysinfo.SysInfo) []string { func getRuntimes(configInfo *config.Config) map[string]docker.Runtime { var runtimes = map[string]docker.Runtime{} - for name, paths := range configInfo.OCIRuntimes { + for name, paths := range configInfo.Engine.OCIRuntimes { runtimes[name] = docker.Runtime{ Path: paths[0], Args: nil, |