diff options
author | Jhon Honce <jhonce@redhat.com> | 2020-03-09 14:18:44 +0100 |
---|---|---|
committer | Jhon Honce <jhonce@redhat.com> | 2020-03-10 08:03:41 -0700 |
commit | 31112e4b087612f7d63e83d770263b8b9fa4f206 (patch) | |
tree | e27af2df4e9c2c24f6a245e245ccc96d5fe1706b /pkg/api/handlers/generic/containers.go | |
parent | 684813fb3effbd7a483e44233ed395eb49c7fded (diff) | |
download | podman-31112e4b087612f7d63e83d770263b8b9fa4f206.tar.gz podman-31112e4b087612f7d63e83d770263b8b9fa4f206.tar.bz2 podman-31112e4b087612f7d63e83d770263b8b9fa4f206.zip |
Refactor handler packages
To help with packaging, the handlers in pkg/api/handlers are now found
in pkg/api/handler/compat.
Signed-off-by: Jhon Honce <jhonce@redhat.com>
Diffstat (limited to 'pkg/api/handlers/generic/containers.go')
-rw-r--r-- | pkg/api/handlers/generic/containers.go | 295 |
1 files changed, 0 insertions, 295 deletions
diff --git a/pkg/api/handlers/generic/containers.go b/pkg/api/handlers/generic/containers.go deleted file mode 100644 index b8460702c..000000000 --- a/pkg/api/handlers/generic/containers.go +++ /dev/null @@ -1,295 +0,0 @@ -package generic - -import ( - "encoding/binary" - "fmt" - "net/http" - "strconv" - "strings" - "sync" - "time" - - "github.com/containers/libpod/libpod" - "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/util" - "github.com/gorilla/schema" - "github.com/pkg/errors" - log "github.com/sirupsen/logrus" -) - -func RemoveContainer(w http.ResponseWriter, r *http.Request) { - decoder := r.Context().Value("decoder").(*schema.Decoder) - query := struct { - Force bool `schema:"force"` - Vols bool `schema:"v"` - Link bool `schema:"link"` - }{ - // override any golang type defaults - } - - if err := decoder.Decode(&query, r.URL.Query()); err != nil { - utils.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest, - errors.Wrapf(err, "Failed to parse parameters for %s", r.URL.String())) - return - } - if query.Link { - utils.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest, - utils.ErrLinkNotSupport) - return - } - utils.RemoveContainer(w, r, query.Force, query.Vols) -} - -func ListContainers(w http.ResponseWriter, r *http.Request) { - var ( - containers []*libpod.Container - err error - ) - runtime := r.Context().Value("runtime").(*libpod.Runtime) - decoder := r.Context().Value("decoder").(*schema.Decoder) - query := struct { - All bool `schema:"all"` - Limit int `schema:"limit"` - Size bool `schema:"size"` - Filters map[string][]string `schema:"filters"` - }{ - // override any golang type defaults - } - - 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 - } - if query.All { - containers, err = runtime.GetAllContainers() - } else { - containers, err = runtime.GetRunningContainers() - } - if err != nil { - utils.InternalServerError(w, err) - return - } - if _, found := r.URL.Query()["limit"]; found { - last := query.Limit - if len(containers) > last { - containers = containers[len(containers)-last:] - } - } - // TODO filters still need to be applied - infoData, err := runtime.Info() - if err != nil { - utils.InternalServerError(w, errors.Wrapf(err, "Failed to obtain system info")) - return - } - - var list = make([]*handlers.Container, len(containers)) - for i, ctnr := range containers { - api, err := handlers.LibpodToContainer(ctnr, infoData, query.Size) - if err != nil { - utils.InternalServerError(w, err) - return - } - list[i] = api - } - utils.WriteResponse(w, http.StatusOK, list) -} - -func GetContainer(w http.ResponseWriter, r *http.Request) { - runtime := r.Context().Value("runtime").(*libpod.Runtime) - decoder := r.Context().Value("decoder").(*schema.Decoder) - query := struct { - Size bool `schema:"size"` - }{ - // override any golang type defaults - } - - 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 - } - - name := utils.GetName(r) - ctnr, err := runtime.LookupContainer(name) - if err != nil { - utils.ContainerNotFound(w, name, err) - return - } - api, err := handlers.LibpodToContainerJSON(ctnr, query.Size) - if err != nil { - utils.InternalServerError(w, err) - return - } - utils.WriteResponse(w, http.StatusOK, api) -} - -func KillContainer(w http.ResponseWriter, r *http.Request) { - // /{version}/containers/(name)/kill - con, err := utils.KillContainer(w, r) - if err != nil { - return - } - // the kill behavior for docker differs from podman in that they appear to wait - // for the Container to croak so the exit code is accurate immediately after the - // kill is sent. libpod does not. but we can add a wait here only for the docker - // side of things and mimic that behavior - if _, err = con.Wait(); err != nil { - utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrapf(err, "failed to wait for Container %s", con.ID())) - return - } - // Success - utils.WriteResponse(w, http.StatusNoContent, "") -} - -func WaitContainer(w http.ResponseWriter, r *http.Request) { - var msg string - // /{version}/containers/(name)/wait - exitCode, err := utils.WaitContainer(w, r) - if err != nil { - return - } - utils.WriteResponse(w, http.StatusOK, handlers.ContainerWaitOKBody{ - StatusCode: int(exitCode), - Error: struct { - Message string - }{ - Message: msg, - }, - }) -} - -func LogsFromContainer(w http.ResponseWriter, r *http.Request) { - decoder := r.Context().Value("decoder").(*schema.Decoder) - runtime := r.Context().Value("runtime").(*libpod.Runtime) - - query := struct { - Follow bool `schema:"follow"` - Stdout bool `schema:"stdout"` - Stderr bool `schema:"stderr"` - Since string `schema:"since"` - Until string `schema:"until"` - Timestamps bool `schema:"timestamps"` - Tail string `schema:"tail"` - }{ - Tail: "all", - } - 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 - } - - if !(query.Stdout || query.Stderr) { - msg := fmt.Sprintf("%s: you must choose at least one stream", http.StatusText(http.StatusBadRequest)) - utils.Error(w, msg, http.StatusBadRequest, errors.Errorf("%s for %s", msg, r.URL.String())) - return - } - - name := utils.GetName(r) - ctnr, err := runtime.LookupContainer(name) - if err != nil { - utils.ContainerNotFound(w, name, err) - return - } - - var tail int64 = -1 - if query.Tail != "all" { - tail, err = strconv.ParseInt(query.Tail, 0, 64) - if err != nil { - utils.BadRequest(w, "tail", query.Tail, err) - return - } - } - - var since time.Time - if _, found := r.URL.Query()["since"]; found { - since, err = util.ParseInputTime(query.Since) - if err != nil { - utils.BadRequest(w, "since", query.Since, err) - return - } - } - - var until time.Time - if _, found := r.URL.Query()["until"]; found { - since, err = util.ParseInputTime(query.Until) - if err != nil { - utils.BadRequest(w, "until", query.Until, err) - return - } - } - - options := &logs.LogOptions{ - Details: true, - Follow: query.Follow, - Since: since, - Tail: tail, - Timestamps: query.Timestamps, - } - - var wg sync.WaitGroup - options.WaitGroup = &wg - - logChannel := make(chan *logs.LogLine, tail+1) - if err := runtime.Log([]*libpod.Container{ctnr}, options, logChannel); err != nil { - utils.InternalServerError(w, errors.Wrapf(err, "Failed to obtain logs for Container '%s'", name)) - return - } - go func() { - wg.Wait() - close(logChannel) - }() - - w.WriteHeader(http.StatusOK) - var builder strings.Builder - for ok := true; ok; ok = query.Follow { - for line := range logChannel { - if _, found := r.URL.Query()["until"]; found { - if line.Time.After(until) { - break - } - } - - // Reset variables we're ready to loop again - builder.Reset() - header := [8]byte{} - - switch line.Device { - case "stdout": - if !query.Stdout { - continue - } - header[0] = 1 - case "stderr": - if !query.Stderr { - continue - } - header[0] = 2 - default: - // Logging and moving on is the best we can do here. We may have already sent - // a Status and Content-Type to client therefore we can no longer report an error. - log.Infof("unknown Device type '%s' in log file from Container %s", line.Device, ctnr.ID()) - continue - } - - if query.Timestamps { - builder.WriteString(line.Time.Format(time.RFC3339)) - 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 { - log.Errorf("unable to write log output header: %q", err) - } - 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() - } - } - } -} |