summaryrefslogtreecommitdiff
path: root/pkg/api
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/api')
-rw-r--r--pkg/api/handlers/decoder.go13
-rw-r--r--pkg/api/handlers/generic/containers_stats.go16
-rw-r--r--pkg/api/handlers/generic/types.go55
-rw-r--r--pkg/api/handlers/images.go1
-rw-r--r--pkg/api/handlers/libpod/images.go39
-rw-r--r--pkg/api/handlers/types.go8
-rw-r--r--pkg/api/server/register_containers.go42
-rw-r--r--pkg/api/server/register_images.go1
8 files changed, 125 insertions, 50 deletions
diff --git a/pkg/api/handlers/decoder.go b/pkg/api/handlers/decoder.go
index 890d77ecc..03b86275d 100644
--- a/pkg/api/handlers/decoder.go
+++ b/pkg/api/handlers/decoder.go
@@ -3,8 +3,10 @@ package handlers
import (
"encoding/json"
"reflect"
+ "syscall"
"time"
+ "github.com/containers/libpod/pkg/util"
"github.com/gorilla/schema"
"github.com/sirupsen/logrus"
)
@@ -17,6 +19,9 @@ func NewAPIDecoder() *schema.Decoder {
d.IgnoreUnknownKeys(true)
d.RegisterConverter(map[string][]string{}, convertUrlValuesString)
d.RegisterConverter(time.Time{}, convertTimeString)
+
+ var Signal syscall.Signal
+ d.RegisterConverter(Signal, convertSignal)
return d
}
@@ -89,3 +94,11 @@ func convertTimeString(query string) reflect.Value {
func ParseDateTime(query string) time.Time {
return convertTimeString(query).Interface().(time.Time)
}
+
+func convertSignal(query string) reflect.Value {
+ signal, err := util.ParseSignal(query)
+ if err != nil {
+ logrus.Infof("convertSignal: Failed to parse %s: %s", query, err.Error())
+ }
+ return reflect.ValueOf(signal)
+}
diff --git a/pkg/api/handlers/generic/containers_stats.go b/pkg/api/handlers/generic/containers_stats.go
index 19e2cc882..977979741 100644
--- a/pkg/api/handlers/generic/containers_stats.go
+++ b/pkg/api/handlers/generic/containers_stats.go
@@ -7,7 +7,6 @@ import (
"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/containers/libpod/pkg/cgroups"
docker "github.com/docker/docker/api/types"
@@ -58,17 +57,18 @@ func StatsContainer(w http.ResponseWriter, r *http.Request) {
}
var preRead time.Time
- var preCPUStats docker.CPUStats
+ var preCPUStats CPUStats
if query.Stream {
preRead = time.Now()
systemUsage, _ := cgroups.GetSystemCPUUsage()
- preCPUStats = docker.CPUStats{
+ preCPUStats = CPUStats{
CPUUsage: docker.CPUUsage{
TotalUsage: stats.CPUNano,
PercpuUsage: stats.PerCPU,
UsageInKernelmode: stats.CPUSystemNano,
UsageInUsermode: stats.CPUNano - stats.CPUSystemNano,
},
+ CPU: stats.CPU,
SystemUsage: systemUsage,
OnlineCPUs: 0,
ThrottlingData: docker.ThrottlingData{},
@@ -124,9 +124,8 @@ func StatsContainer(w http.ResponseWriter, r *http.Request) {
}
systemUsage, _ := cgroups.GetSystemCPUUsage()
-
- s := handlers.Stats{StatsJSON: docker.StatsJSON{
- Stats: docker.Stats{
+ s := StatsJSON{
+ Stats: Stats{
Read: time.Now(),
PreRead: preRead,
PidsStats: docker.PidsStats{
@@ -143,13 +142,14 @@ func StatsContainer(w http.ResponseWriter, r *http.Request) {
IoTimeRecursive: nil,
SectorsRecursive: nil,
},
- CPUStats: docker.CPUStats{
+ CPUStats: CPUStats{
CPUUsage: docker.CPUUsage{
TotalUsage: cgroupStat.CPU.Usage.Total,
PercpuUsage: cgroupStat.CPU.Usage.PerCPU,
UsageInKernelmode: cgroupStat.CPU.Usage.Kernel,
UsageInUsermode: cgroupStat.CPU.Usage.Total - cgroupStat.CPU.Usage.Kernel,
},
+ CPU: stats.CPU,
SystemUsage: systemUsage,
OnlineCPUs: uint32(len(cgroupStat.CPU.Usage.PerCPU)),
ThrottlingData: docker.ThrottlingData{
@@ -173,7 +173,7 @@ func StatsContainer(w http.ResponseWriter, r *http.Request) {
Name: stats.Name,
ID: stats.ContainerID,
Networks: net,
- }}
+ }
utils.WriteJSON(w, http.StatusOK, s)
if flusher, ok := w.(http.Flusher); ok {
diff --git a/pkg/api/handlers/generic/types.go b/pkg/api/handlers/generic/types.go
new file mode 100644
index 000000000..f068ac011
--- /dev/null
+++ b/pkg/api/handlers/generic/types.go
@@ -0,0 +1,55 @@
+package generic
+
+import (
+ "time"
+
+ docker "github.com/docker/docker/api/types"
+)
+
+// CPUStats aggregates and wraps all CPU related info of container
+type CPUStats struct {
+ // CPU Usage. Linux and Windows.
+ CPUUsage docker.CPUUsage `json:"cpu_usage"`
+
+ // System Usage. Linux only.
+ SystemUsage uint64 `json:"system_cpu_usage,omitempty"`
+
+ // Online CPUs. Linux only.
+ OnlineCPUs uint32 `json:"online_cpus,omitempty"`
+
+ // Usage of CPU in %. Linux only.
+ CPU float64 `json:"cpu"`
+
+ // Throttling Data. Linux only.
+ ThrottlingData docker.ThrottlingData `json:"throttling_data,omitempty"`
+}
+
+// Stats is Ultimate struct aggregating all types of stats of one container
+type Stats struct {
+ // Common stats
+ Read time.Time `json:"read"`
+ PreRead time.Time `json:"preread"`
+
+ // Linux specific stats, not populated on Windows.
+ PidsStats docker.PidsStats `json:"pids_stats,omitempty"`
+ BlkioStats docker.BlkioStats `json:"blkio_stats,omitempty"`
+
+ // Windows specific stats, not populated on Linux.
+ NumProcs uint32 `json:"num_procs"`
+ StorageStats docker.StorageStats `json:"storage_stats,omitempty"`
+
+ // Shared stats
+ CPUStats CPUStats `json:"cpu_stats,omitempty"`
+ PreCPUStats CPUStats `json:"precpu_stats,omitempty"` // "Pre"="Previous"
+ MemoryStats docker.MemoryStats `json:"memory_stats,omitempty"`
+}
+
+type StatsJSON struct {
+ Stats
+
+ Name string `json:"name,omitempty"`
+ ID string `json:"id,omitempty"`
+
+ // Networks request version >=1.21
+ Networks map[string]docker.NetworkStats `json:"networks,omitempty"`
+}
diff --git a/pkg/api/handlers/images.go b/pkg/api/handlers/images.go
index e4e394d68..96bcbdc96 100644
--- a/pkg/api/handlers/images.go
+++ b/pkg/api/handlers/images.go
@@ -156,6 +156,7 @@ func SearchImages(w http.ResponseWriter, r *http.Request) {
results, err := image.SearchImages(query.Term, options)
if err != nil {
utils.BadRequest(w, "term", query.Term, err)
+ return
}
utils.WriteResponse(w, http.StatusOK, results)
}
diff --git a/pkg/api/handlers/libpod/images.go b/pkg/api/handlers/libpod/images.go
index eac0e4dad..71603e6cc 100644
--- a/pkg/api/handlers/libpod/images.go
+++ b/pkg/api/handlers/libpod/images.go
@@ -8,6 +8,7 @@ import (
"net/http"
"os"
"strconv"
+ "strings"
"github.com/containers/image/v5/docker"
"github.com/containers/image/v5/docker/reference"
@@ -133,11 +134,16 @@ func PruneImages(w http.ResponseWriter, r *http.Request) {
var libpodFilters = []string{}
if _, found := r.URL.Query()["filters"]; found {
- all, err = strconv.ParseBool(query.Filters["all"][0])
- if err != nil {
- utils.InternalServerError(w, err)
- return
+ dangling := query.Filters["all"]
+ if len(dangling) > 0 {
+ all, err = strconv.ParseBool(query.Filters["all"][0])
+ if err != nil {
+ utils.InternalServerError(w, err)
+ return
+ }
}
+ // dangling is special and not implemented in the libpod side of things
+ delete(query.Filters, "dangling")
for k, v := range query.Filters {
libpodFilters = append(libpodFilters, fmt.Sprintf("%s=%s", k, v[0]))
}
@@ -157,7 +163,7 @@ func ExportImage(w http.ResponseWriter, r *http.Request) {
Compress bool `schema:"compress"`
Format string `schema:"format"`
}{
- // override any golang type defaults
+ Format: "docker-archive",
}
if err := decoder.Decode(&query, r.URL.Query()); err != nil {
@@ -166,11 +172,6 @@ func ExportImage(w http.ResponseWriter, r *http.Request) {
return
}
- if len(query.Format) < 1 {
- utils.InternalServerError(w, errors.New("format parameter cannot be empty."))
- return
- }
-
tmpfile, err := ioutil.TempFile("", "api.tar")
if err != nil {
utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "unable to create tempfile"))
@@ -186,6 +187,7 @@ func ExportImage(w http.ResponseWriter, r *http.Request) {
utils.ImageNotFound(w, name, err)
return
}
+
if err := newImage.Save(r.Context(), name, query.Format, tmpfile.Name(), []string{}, false, query.Compress); err != nil {
utils.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest, err)
return
@@ -234,8 +236,20 @@ func ImagesLoad(w http.ResponseWriter, r *http.Request) {
utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "unable to load image"))
return
}
-
- utils.WriteResponse(w, http.StatusOK, []handlers.LibpodImagesLoadReport{{ID: loadedImage}})
+ split := strings.Split(loadedImage, ",")
+ newImage, err := runtime.ImageRuntime().NewFromLocal(split[0])
+ if err != nil {
+ utils.InternalServerError(w, err)
+ return
+ }
+ // TODO this should go into libpod proper at some point.
+ if len(query.Reference) > 0 {
+ if err := newImage.TagImage(query.Reference); err != nil {
+ utils.InternalServerError(w, err)
+ return
+ }
+ }
+ utils.WriteResponse(w, http.StatusOK, handlers.LibpodImagesLoadReport{ID: loadedImage})
}
func ImagesImport(w http.ResponseWriter, r *http.Request) {
@@ -275,7 +289,6 @@ func ImagesImport(w http.ResponseWriter, r *http.Request) {
tmpfile.Close()
source = tmpfile.Name()
}
-
importedImage, err := runtime.Import(context.Background(), source, query.Reference, query.Changes, query.Message, true)
if err != nil {
utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "unable to import image"))
diff --git a/pkg/api/handlers/types.go b/pkg/api/handlers/types.go
index 6268028f5..c72b0f817 100644
--- a/pkg/api/handlers/types.go
+++ b/pkg/api/handlers/types.go
@@ -78,10 +78,6 @@ type Container struct {
docker.ContainerCreateConfig
}
-type ContainerStats struct {
- docker.ContainerStats
-}
-
type Version struct {
docker.Version
}
@@ -143,10 +139,6 @@ type IDResponse struct {
ID string `json:"id"`
}
-type Stats struct {
- docker.StatsJSON
-}
-
type ContainerTopOKBody struct {
dockerContainer.ContainerTopOKBody
}
diff --git a/pkg/api/server/register_containers.go b/pkg/api/server/register_containers.go
index 6007a2d00..6a2ba4b1e 100644
--- a/pkg/api/server/register_containers.go
+++ b/pkg/api/server/register_containers.go
@@ -550,7 +550,7 @@ func (s *APIServer) registerContainersHandlers(r *mux.Router) error {
libpod endpoints
*/
- // swagger:operation POST /containers/create libpod libpodContainerCreate
+ // swagger:operation POST /libpod/containers/create libpod libpodCreateContainer
// ---
// summary: Create a container
// tags:
@@ -615,21 +615,21 @@ func (s *APIServer) registerContainersHandlers(r *mux.Router) error {
// name: filters
// type: string
// description: |
- // Returns a list of containers.
- // - ancestor=(<image-name>[:<tag>], <image id>, or <image@digest>)
- // - before=(<container id> or <container name>)
- // - expose=(<port>[/<proto>]|<startport-endport>/[<proto>])
- // - exited=<int> containers with exit code of <int>
- // - health=(starting|healthy|unhealthy|none)
- // - id=<ID> a container's ID
- // - is-task=(true|false)
- // - label=key or label="key=value" of a container label
- // - name=<name> a container's name
- // - network=(<network id> or <network name>)
- // - publish=(<port>[/<proto>]|<startport-endport>/[<proto>])
- // - since=(<container id> or <container name>)
- // - status=(created|restarting|running|removing|paused|exited|dead)
- // - volume=(<volume name> or <mount point destination>)
+ // A JSON encoded value of the filters (a `map[string][]string`) to process on the containers list. Available filters:
+ // - `ancestor`=(`<image-name>[:<tag>]`, `<image id>`, or `<image@digest>`)
+ // - `before`=(`<container id>` or `<container name>`)
+ // - `expose`=(`<port>[/<proto>]` or `<startport-endport>/[<proto>]`)
+ // - `exited=<int>` containers with exit code of `<int>`
+ // - `health`=(`starting`, `healthy`, `unhealthy` or `none`)
+ // - `id=<ID>` a container's ID
+ // - `is-task`=(`true` or `false`)
+ // - `label`=(`key` or `"key=value"`) of an container label
+ // - `name=<name>` a container's name
+ // - `network`=(`<network id>` or `<network name>`)
+ // - `publish`=(`<port>[/<proto>]` or `<startport-endport>/[<proto>]`)
+ // - `since`=(`<container id>` or `<container name>`)
+ // - `status`=(`created`, `restarting`, `running`, `removing`, `paused`, `exited` or `dead`)
+ // - `volume`=(`<volume name>` or `<mount point destination>`)
// produces:
// - application/json
// responses:
@@ -662,7 +662,7 @@ func (s *APIServer) registerContainersHandlers(r *mux.Router) error {
// 500:
// $ref: "#/responses/InternalError"
r.HandleFunc(VersionedPath("/libpod/containers/prune"), s.APIHandler(handlers.PruneContainers)).Methods(http.MethodPost)
- // swagger:operation GET /libpod/containers/showmounted libpod showMountedContainers
+ // swagger:operation GET /libpod/containers/showmounted libpod libpodShowMountedContainers
// ---
// tags:
// - containers
@@ -769,7 +769,7 @@ func (s *APIServer) registerContainersHandlers(r *mux.Router) error {
// 500:
// $ref: "#/responses/InternalError"
r.HandleFunc(VersionedPath("/libpod/containers/{name}/kill"), s.APIHandler(libpod.KillContainer)).Methods(http.MethodPost)
- // swagger:operation POST /libpod/containers/{name}/mount libpod mountContainer
+ // swagger:operation POST /libpod/containers/{name}/mount libpod libpodMountContainer
// ---
// tags:
// - containers
@@ -1047,7 +1047,7 @@ func (s *APIServer) registerContainersHandlers(r *mux.Router) error {
// 500:
// $ref: "#/responses/InternalError"
r.HandleFunc(VersionedPath("/libpod/containers/{name}/wait"), s.APIHandler(libpod.WaitContainer)).Methods(http.MethodPost)
- // swagger:operation GET /libpod/containers/{name}/exists libpod containerExists
+ // swagger:operation GET /libpod/containers/{name}/exists libpod libpodContainerExists
// ---
// tags:
// - containers
@@ -1096,7 +1096,7 @@ func (s *APIServer) registerContainersHandlers(r *mux.Router) error {
// 500:
// $ref: "#/responses/InternalError"
r.HandleFunc(VersionedPath("/libpod/containers/{name}/stop"), s.APIHandler(handlers.StopContainer)).Methods(http.MethodPost)
- // swagger:operation POST /libpod/containers/{name}/attach libpod libpodAttach
+ // swagger:operation POST /libpod/containers/{name}/attach libpod libpodAttachContainer
// ---
// tags:
// - containers
@@ -1151,7 +1151,7 @@ func (s *APIServer) registerContainersHandlers(r *mux.Router) error {
// 500:
// $ref: "#/responses/InternalError"
r.HandleFunc(VersionedPath("/libpod/containers/{name}/attach"), s.APIHandler(handlers.AttachContainer)).Methods(http.MethodPost)
- // swagger:operation POST /libpod/containers/{name}/resize libpod libpodResize
+ // swagger:operation POST /libpod/containers/{name}/resize libpod libpodResizeContainer
// ---
// tags:
// - containers
diff --git a/pkg/api/server/register_images.go b/pkg/api/server/register_images.go
index 4c8f05385..db04ecdc9 100644
--- a/pkg/api/server/register_images.go
+++ b/pkg/api/server/register_images.go
@@ -648,6 +648,7 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error {
// - `dangling=true`
// - `label=key` or `label="key=value"` of an image label
// - `reference`=(`<image-name>[:<tag>]`)
+ // - `id`=(`<image-id>`)
// - `since`=(`<image-name>[:<tag>]`, `<image id>` or `<image@digest>`)
// type: string
// produces: