diff options
Diffstat (limited to 'pkg/api')
-rw-r--r-- | pkg/api/handlers/compat/containers.go | 27 | ||||
-rw-r--r-- | pkg/api/handlers/compat/containers_start.go | 3 | ||||
-rw-r--r-- | pkg/api/handlers/compat/containers_stop.go (renamed from pkg/api/handlers/compat/container_start.go) | 0 | ||||
-rw-r--r-- | pkg/api/handlers/compat/images_build.go | 1 | ||||
-rw-r--r-- | pkg/api/handlers/libpod/healthcheck.go | 24 | ||||
-rw-r--r-- | pkg/api/handlers/libpod/manifests.go | 1 | ||||
-rw-r--r-- | pkg/api/handlers/libpod/system.go | 10 | ||||
-rw-r--r-- | pkg/api/handlers/utils/images.go | 33 | ||||
-rw-r--r-- | pkg/api/server/register_images.go | 209 | ||||
-rw-r--r-- | pkg/api/server/register_system.go | 14 | ||||
-rw-r--r-- | pkg/api/server/server.go | 8 |
11 files changed, 273 insertions, 57 deletions
diff --git a/pkg/api/handlers/compat/containers.go b/pkg/api/handlers/compat/containers.go index 239e41af4..cea4bd0f6 100644 --- a/pkg/api/handlers/compat/containers.go +++ b/pkg/api/handlers/compat/containers.go @@ -4,6 +4,7 @@ import ( "encoding/binary" "encoding/json" "fmt" + "io" "net/http" "strconv" "strings" @@ -295,7 +296,9 @@ func LogsFromContainer(w http.ResponseWriter, r *http.Request) { }() w.WriteHeader(http.StatusOK) - var builder strings.Builder + + var frame strings.Builder + header := make([]byte, 8) for ok := true; ok; ok = query.Follow { for line := range logChannel { if _, found := r.URL.Query()["until"]; found { @@ -304,10 +307,8 @@ func LogsFromContainer(w http.ResponseWriter, r *http.Request) { } } - // Reset variables we're ready to loop again - builder.Reset() - header := [8]byte{} - + // Reset buffer we're ready to loop again + frame.Reset() switch line.Device { case "stdout": if !query.Stdout { @@ -327,17 +328,17 @@ func LogsFromContainer(w http.ResponseWriter, r *http.Request) { } if query.Timestamps { - builder.WriteString(line.Time.Format(time.RFC3339)) - builder.WriteRune(' ') + frame.WriteString(line.Time.Format(time.RFC3339)) + frame.WriteString(" ") } - 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 { + frame.WriteString(line.Msg) + + binary.BigEndian.PutUint32(header[4:], uint32(frame.Len())) + if _, err := w.Write(header[0:8]); 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 _, err := io.WriteString(w, frame.String()); err != nil { + log.Errorf("unable to write frame string: %q", err) } if flusher, ok := w.(http.Flusher); ok { flusher.Flush() diff --git a/pkg/api/handlers/compat/containers_start.go b/pkg/api/handlers/compat/containers_start.go index 9cb1492fb..cdbc8ff76 100644 --- a/pkg/api/handlers/compat/containers_start.go +++ b/pkg/api/handlers/compat/containers_start.go @@ -33,7 +33,6 @@ func StartContainer(w http.ResponseWriter, r *http.Request) { utils.ContainerNotFound(w, name, err) return } - state, err := con.State() if err != nil { utils.InternalServerError(w, err) @@ -43,7 +42,7 @@ func StartContainer(w http.ResponseWriter, r *http.Request) { utils.WriteResponse(w, http.StatusNotModified, "") return } - if err := con.Start(r.Context(), false); err != nil { + if err := con.Start(r.Context(), len(con.PodID()) > 0); err != nil { utils.InternalServerError(w, err) return } diff --git a/pkg/api/handlers/compat/container_start.go b/pkg/api/handlers/compat/containers_stop.go index d26ef2c82..d26ef2c82 100644 --- a/pkg/api/handlers/compat/container_start.go +++ b/pkg/api/handlers/compat/containers_stop.go diff --git a/pkg/api/handlers/compat/images_build.go b/pkg/api/handlers/compat/images_build.go index e208e6ddc..e9d8fd719 100644 --- a/pkg/api/handlers/compat/images_build.go +++ b/pkg/api/handlers/compat/images_build.go @@ -226,6 +226,7 @@ func BuildImage(w http.ResponseWriter, r *http.Request) { id, _, err := runtime.Build(r.Context(), buildOptions, query.Dockerfile) if err != nil { utils.InternalServerError(w, err) + return } // Find image ID that was built... diff --git a/pkg/api/handlers/libpod/healthcheck.go b/pkg/api/handlers/libpod/healthcheck.go index 6eb2ab0e3..0ca3574b7 100644 --- a/pkg/api/handlers/libpod/healthcheck.go +++ b/pkg/api/handlers/libpod/healthcheck.go @@ -4,6 +4,7 @@ import ( "net/http" "github.com/containers/libpod/libpod" + "github.com/containers/libpod/libpod/define" "github.com/containers/libpod/pkg/api/handlers/utils" ) @@ -12,32 +13,27 @@ func RunHealthCheck(w http.ResponseWriter, r *http.Request) { name := utils.GetName(r) status, err := runtime.HealthCheck(name) if err != nil { - if status == libpod.HealthCheckContainerNotFound { + if status == define.HealthCheckContainerNotFound { utils.ContainerNotFound(w, name, err) return } - if status == libpod.HealthCheckNotDefined { + if status == define.HealthCheckNotDefined { utils.Error(w, "no healthcheck defined", http.StatusConflict, err) return } - if status == libpod.HealthCheckContainerStopped { + if status == define.HealthCheckContainerStopped { utils.Error(w, "container not running", http.StatusConflict, err) return } utils.InternalServerError(w, err) return } - ctr, err := runtime.LookupContainer(name) - if err != nil { - utils.InternalServerError(w, err) - return + hcStatus := define.HealthCheckUnhealthy + if status == define.HealthCheckSuccess { + hcStatus = define.HealthCheckHealthy } - - hcLog, err := ctr.GetHealthCheckLog() - if err != nil { - utils.InternalServerError(w, err) - return + report := define.HealthCheckResults{ + Status: hcStatus, } - - utils.WriteResponse(w, http.StatusOK, hcLog) + utils.WriteResponse(w, http.StatusOK, report) } diff --git a/pkg/api/handlers/libpod/manifests.go b/pkg/api/handlers/libpod/manifests.go index d87ed7eba..93ca367f7 100644 --- a/pkg/api/handlers/libpod/manifests.go +++ b/pkg/api/handlers/libpod/manifests.go @@ -151,6 +151,7 @@ func ManifestPush(w http.ResponseWriter, r *http.Request) { } sc := image.GetSystemContext(rtc.Engine.SignaturePolicyPath, "", false) opts := manifests.PushOptions{ + Store: runtime.GetStore(), ImageListSelection: copy2.CopySpecificImages, SystemContext: sc, } diff --git a/pkg/api/handlers/libpod/system.go b/pkg/api/handlers/libpod/system.go index 81ed37b4a..f575546c9 100644 --- a/pkg/api/handlers/libpod/system.go +++ b/pkg/api/handlers/libpod/system.go @@ -71,16 +71,6 @@ func SystemPrune(w http.ResponseWriter, r *http.Request) { utils.WriteResponse(w, http.StatusOK, systemPruneReport) } -// SystemReset Resets podman storage back to default state -func SystemReset(w http.ResponseWriter, r *http.Request) { - err := r.Context().Value("runtime").(*libpod.Runtime).Reset(r.Context()) - if err != nil { - utils.InternalServerError(w, err) - return - } - utils.WriteResponse(w, http.StatusOK, nil) -} - func DiskUsage(w http.ResponseWriter, r *http.Request) { // Options are only used by the CLI options := entities.SystemDfOptions{} diff --git a/pkg/api/handlers/utils/images.go b/pkg/api/handlers/utils/images.go index 1c67de9db..7fb31a177 100644 --- a/pkg/api/handlers/utils/images.go +++ b/pkg/api/handlers/utils/images.go @@ -62,7 +62,6 @@ func GetImages(w http.ResponseWriter, r *http.Request) ([]*image.Image, error) { }{ // This is where you can override the golang default value for one of fields } - // TODO I think all is implemented with a filter? if err := decoder.Decode(&query, r.URL.Query()); err != nil { return nil, err @@ -71,6 +70,10 @@ func GetImages(w http.ResponseWriter, r *http.Request) ([]*image.Image, error) { if _, found := r.URL.Query()["digests"]; found && query.Digests { UnSupportedParameter("digests") } + var ( + images []*image.Image + err error + ) if len(query.Filters) > 0 { for k, v := range query.Filters { @@ -78,11 +81,33 @@ func GetImages(w http.ResponseWriter, r *http.Request) ([]*image.Image, error) { filters = append(filters, fmt.Sprintf("%s=%s", k, val)) } } - return runtime.ImageRuntime().GetImagesWithFilters(filters) + images, err = runtime.ImageRuntime().GetImagesWithFilters(filters) + if err != nil { + return images, err + } } else { - return runtime.ImageRuntime().GetImages() + images, err = runtime.ImageRuntime().GetImages() + if err != nil { + return images, err + } } - + if query.All { + return images, nil + } + var returnImages []*image.Image + for _, img := range images { + if len(img.Names()) == 0 { + parent, err := img.IsParent(r.Context()) + if err != nil { + return nil, err + } + if parent { + continue + } + } + returnImages = append(returnImages, img) + } + return returnImages, nil } func GetImage(r *http.Request, name string) (*image.Image, error) { diff --git a/pkg/api/server/register_images.go b/pkg/api/server/register_images.go index 01854b9c4..c885dc81a 100644 --- a/pkg/api/server/register_images.go +++ b/pkg/api/server/register_images.go @@ -1188,5 +1188,214 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error { // $ref: "#/responses/InternalError" r.HandleFunc(VersionedPath("/libpod/images/{name}/changes"), s.APIHandler(compat.Changes)).Methods(http.MethodGet) + // swagger:operation POST /libpod/build libpod libpodBuildImage + // --- + // tags: + // - images + // summary: Create image + // description: Build an image from the given Dockerfile(s) + // parameters: + // - in: query + // name: dockerfile + // type: string + // default: Dockerfile + // description: | + // Path within the build context to the `Dockerfile`. + // This is ignored if remote is specified and points to an external `Dockerfile`. + // - in: query + // name: t + // type: string + // default: latest + // description: A name and optional tag to apply to the image in the `name:tag` format. + // - in: query + // name: extrahosts + // type: string + // default: + // description: | + // TBD Extra hosts to add to /etc/hosts + // (As of version 1.xx) + // - in: query + // name: remote + // type: string + // default: + // description: | + // A Git repository URI or HTTP/HTTPS context URI. + // If the URI points to a single text file, the file’s contents are placed + // into a file called Dockerfile and the image is built from that file. If + // the URI points to a tarball, the file is downloaded by the daemon and the + // contents therein used as the context for the build. If the URI points to a + // tarball and the dockerfile parameter is also specified, there must be a file + // with the corresponding path inside the tarball. + // (As of version 1.xx) + // - in: query + // name: q + // type: boolean + // default: false + // description: | + // Suppress verbose build output + // - in: query + // name: nocache + // type: boolean + // default: false + // description: | + // Do not use the cache when building the image + // (As of version 1.xx) + // - in: query + // name: cachefrom + // type: string + // default: + // description: | + // JSON array of images used to build cache resolution + // (As of version 1.xx) + // - in: query + // name: pull + // type: boolean + // default: false + // description: | + // Attempt to pull the image even if an older image exists locally + // (As of version 1.xx) + // - in: query + // name: rm + // type: boolean + // default: true + // description: | + // Remove intermediate containers after a successful build + // (As of version 1.xx) + // - in: query + // name: forcerm + // type: boolean + // default: false + // description: | + // Always remove intermediate containers, even upon failure + // (As of version 1.xx) + // - in: query + // name: memory + // type: integer + // description: | + // Memory is the upper limit (in bytes) on how much memory running containers can use + // (As of version 1.xx) + // - in: query + // name: memswap + // type: integer + // description: | + // MemorySwap limits the amount of memory and swap together + // (As of version 1.xx) + // - in: query + // name: cpushares + // type: integer + // description: | + // CPUShares (relative weight + // (As of version 1.xx) + // - in: query + // name: cpusetcpus + // type: string + // description: | + // CPUSetCPUs in which to allow execution (0-3, 0,1) + // (As of version 1.xx) + // - in: query + // name: cpuperiod + // type: integer + // description: | + // CPUPeriod limits the CPU CFS (Completely Fair Scheduler) period + // (As of version 1.xx) + // - in: query + // name: cpuquota + // type: integer + // description: | + // CPUQuota limits the CPU CFS (Completely Fair Scheduler) quota + // (As of version 1.xx) + // - in: query + // name: buildargs + // type: string + // default: + // description: | + // JSON map of string pairs denoting build-time variables. + // For example, the build argument `Foo` with the value of `bar` would be encoded in JSON as `["Foo":"bar"]`. + // + // For example, buildargs={"Foo":"bar"}. + // + // Note(s): + // * This should not be used to pass secrets. + // * The value of buildargs should be URI component encoded before being passed to the API. + // + // (As of version 1.xx) + // - in: query + // name: shmsize + // type: integer + // default: 67108864 + // description: | + // ShmSize is the "size" value to use when mounting an shmfs on the container's /dev/shm directory. + // Default is 64MB + // (As of version 1.xx) + // - in: query + // name: squash + // type: boolean + // default: false + // description: | + // Silently ignored. + // Squash the resulting images layers into a single layer + // (As of version 1.xx) + // - in: query + // name: labels + // type: string + // default: + // description: | + // JSON map of key, value pairs to set as labels on the new image + // (As of version 1.xx) + // - in: query + // name: networkmode + // type: string + // default: bridge + // description: | + // Sets the networking mode for the run commands during build. + // Supported standard values are: + // * `bridge` limited to containers within a single host, port mapping required for external access + // * `host` no isolation between host and containers on this network + // * `none` disable all networking for this container + // * container:<nameOrID> share networking with given container + // ---All other values are assumed to be a custom network's name + // (As of version 1.xx) + // - in: query + // name: platform + // type: string + // default: + // description: | + // Platform format os[/arch[/variant]] + // (As of version 1.xx) + // - in: query + // name: target + // type: string + // default: + // description: | + // Target build stage + // (As of version 1.xx) + // - in: query + // name: outputs + // type: string + // default: + // description: | + // output configuration TBD + // (As of version 1.xx) + // produces: + // - application/json + // responses: + // 200: + // description: OK (As of version 1.xx) + // schema: + // type: object + // required: + // - stream + // properties: + // stream: + // type: string + // description: output from build process + // example: | + // (build details...) + // Successfully built 8ba084515c724cbf90d447a63600c0a6 + // 400: + // $ref: "#/responses/BadParamError" + // 500: + // $ref: "#/responses/InternalError" + r.Handle(VersionedPath("/libpod/build"), s.APIHandler(compat.BuildImage)).Methods(http.MethodPost) return nil } diff --git a/pkg/api/server/register_system.go b/pkg/api/server/register_system.go index 8a942a888..118ad2d08 100644 --- a/pkg/api/server/register_system.go +++ b/pkg/api/server/register_system.go @@ -27,20 +27,6 @@ func (s *APIServer) registerSystemHandlers(r *mux.Router) error { // 500: // $ref: "#/responses/InternalError" r.Handle(VersionedPath("/libpod/system/prune"), s.APIHandler(libpod.SystemPrune)).Methods(http.MethodPost) - // swagger:operation POST /libpod/system/reset libpod resetSystem - // --- - // tags: - // - system - // summary: Reset podman storage - // description: All containers will be stopped and removed, and all images, volumes and container content will be removed. - // produces: - // - application/json - // responses: - // 200: - // description: no error - // 500: - // $ref: "#/responses/InternalError" - r.Handle(VersionedPath("/libpod/system/reset"), s.APIHandler(libpod.SystemReset)).Methods(http.MethodPost) // swagger:operation GET /libpod/system/df libpod df // --- // tags: diff --git a/pkg/api/server/server.go b/pkg/api/server/server.go index d39528f45..9cbc66e87 100644 --- a/pkg/api/server/server.go +++ b/pkg/api/server/server.go @@ -92,6 +92,14 @@ func newServer(runtime *libpod.Runtime, duration time.Duration, listener *net.Li }, ) + router.MethodNotAllowedHandler = http.HandlerFunc( + func(w http.ResponseWriter, r *http.Request) { + // We can track user errors... + logrus.Infof("Failed Request: (%d:%s) for %s:'%s'", http.StatusMethodNotAllowed, http.StatusText(http.StatusMethodNotAllowed), r.Method, r.URL.String()) + http.Error(w, http.StatusText(http.StatusMethodNotAllowed), http.StatusMethodNotAllowed) + }, + ) + for _, fn := range []func(*mux.Router) error{ server.registerAuthHandlers, server.registerContainersHandlers, |