diff options
Diffstat (limited to 'pkg')
-rw-r--r-- | pkg/api/handlers/generic/config.go | 9 | ||||
-rw-r--r-- | pkg/api/handlers/generic/containers_create.go | 6 | ||||
-rw-r--r-- | pkg/api/handlers/generic/swagger.go | 23 | ||||
-rw-r--r-- | pkg/api/server/register_containers.go | 251 | ||||
-rw-r--r-- | pkg/api/server/register_events.go | 2 | ||||
-rw-r--r-- | pkg/api/server/register_images.go | 241 | ||||
-rw-r--r-- | pkg/api/server/register_info.go | 14 | ||||
-rw-r--r-- | pkg/api/server/register_pods.go | 73 | ||||
-rw-r--r-- | pkg/api/server/register_volumes.go | 16 | ||||
-rw-r--r-- | pkg/api/server/swagger.go | 5 | ||||
-rw-r--r-- | pkg/apparmor/apparmor_linux_test.go | 2 | ||||
-rw-r--r-- | pkg/hooks/1.0.0/when_test.go | 30 | ||||
-rw-r--r-- | pkg/hooks/exec/exec_test.go | 6 | ||||
-rw-r--r-- | pkg/hooks/exec/runtimeconfigfilter_test.go | 5 | ||||
-rw-r--r-- | pkg/network/network_test.go | 5 | ||||
-rw-r--r-- | pkg/network/subnet_test.go | 13 | ||||
-rw-r--r-- | pkg/spec/config_linux_cgo.go | 12 | ||||
-rw-r--r-- | pkg/spec/createconfig.go | 67 | ||||
-rw-r--r-- | pkg/systemdgen/systemdgen_test.go | 18 | ||||
-rw-r--r-- | pkg/tracing/tracing.go | 3 |
20 files changed, 433 insertions, 368 deletions
diff --git a/pkg/api/handlers/generic/config.go b/pkg/api/handlers/generic/config.go new file mode 100644 index 000000000..f715d25eb --- /dev/null +++ b/pkg/api/handlers/generic/config.go @@ -0,0 +1,9 @@ +package generic + +// ContainerCreateResponse is the response struct for creating a container +type ContainerCreateResponse struct { + // ID of the container created + Id string `json:"Id"` + // Warnings during container creation + Warnings []string `json:"Warnings"` +} diff --git a/pkg/api/handlers/generic/containers_create.go b/pkg/api/handlers/generic/containers_create.go index ef5337abd..f98872690 100644 --- a/pkg/api/handlers/generic/containers_create.go +++ b/pkg/api/handlers/generic/containers_create.go @@ -71,11 +71,7 @@ func CreateContainer(w http.ResponseWriter, r *http.Request) { return } - type ctrCreateResponse struct { - Id string `json:"Id"` - Warnings []string `json:"Warnings"` - } - response := ctrCreateResponse{ + response := ContainerCreateResponse{ Id: ctr.ID(), Warnings: []string{}} diff --git a/pkg/api/handlers/generic/swagger.go b/pkg/api/handlers/generic/swagger.go new file mode 100644 index 000000000..27e1fc18d --- /dev/null +++ b/pkg/api/handlers/generic/swagger.go @@ -0,0 +1,23 @@ +package generic + +// Create container +// swagger:response ContainerCreateResponse +type swagCtrCreateResponse struct { + // in:body + Body struct { + ContainerCreateResponse + } +} + +// Wait container +// swagger:response ContainerWaitResponse +type swagCtrWaitResponse struct { + // in:body + Body struct { + // container exit code + StatusCode int + Error struct { + Message string + } + } +} diff --git a/pkg/api/server/register_containers.go b/pkg/api/server/register_containers.go index af1881624..711aecc84 100644 --- a/pkg/api/server/register_containers.go +++ b/pkg/api/server/register_containers.go @@ -11,10 +11,8 @@ import ( func (s *APIServer) RegisterContainersHandlers(r *mux.Router) error { // swagger:operation POST /containers/create containers createContainer - // - // Create a container - // // --- + // summary: Create a container // produces: // - application/json // parameters: @@ -24,44 +22,62 @@ func (s *APIServer) RegisterContainersHandlers(r *mux.Router) error { // description: container name // responses: // '201': - // description: tbd + // $ref: "#/responses/ContainerCreateResponse" // '400': // "$ref": "#/responses/BadParamError" // '404': // "$ref": "#/responses/NoSuchContainer" // '409': - // "$ref": "#/types/ConflictError" + // "$ref": "#/responses/ConflictError" // '500': - // "$ref": "#/types/InternalError" + // "$ref": "#/responses/InternalError" r.HandleFunc(VersionedPath("/containers/create"), APIHandler(s.Context, generic.CreateContainer)).Methods(http.MethodPost) // swagger:operation GET /containers/json containers listContainers - // - // List containers - // // --- + // summary: List containers + // description: Returns a list of containers + // parameters: + // - in: query + // 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>) // produces: // - application/json // responses: // '200': - // schema: - // type: array - // items: - // "$ref": "#/responses/Container" + // "$ref": "#/responses/DocsListContainer" // '400': // "$ref": "#/responses/BadParamError" // '500': // "$ref": "#/responses/InternalError" r.HandleFunc(VersionedPath("/containers/json"), APIHandler(s.Context, generic.ListContainers)).Methods(http.MethodGet) // swagger:operation POST /containers/prune containers pruneContainers - // - // Prune unused containers - // // --- + // summary: Delete stopped containers + // description: Remove containers not in use // parameters: // - in: query // name: filters - // type: map[string][]string - // description: something + // type: string + // description: | + // Filters to process on the prune list, encoded as JSON (a `map[string][]string`). Available filters: + // - `until=<timestamp>` Prune containers created before this timestamp. The `<timestamp>` can be Unix timestamps, date formatted timestamps, or Go duration strings (e.g. `10m`, `1h30m`) computed relative to the daemon machine’s time. + // - `label` (`label=<key>`, `label=<key>=<value>`, `label!=<key>`, or `label!=<key>=<value>`) Prune containers with (or without, in case `label!=...` is used) the specified labels. // produces: // - application/json // responses: @@ -71,10 +87,8 @@ func (s *APIServer) RegisterContainersHandlers(r *mux.Router) error { // "$ref": "#/responses/InternalError" r.HandleFunc(VersionedPath("/containers/prune"), APIHandler(s.Context, generic.PruneContainers)).Methods(http.MethodPost) // swagger:operation DELETE /containers/{nameOrID} containers removeContainer - // - // Delete container - // // --- + // summary: Remove a container // parameters: // - in: path // name: nameOrID @@ -83,11 +97,13 @@ func (s *APIServer) RegisterContainersHandlers(r *mux.Router) error { // - in: query // name: force // type: bool - // description: need something + // default: false + // description: If the container is running, kill it before removing it. // - in: query // name: v // type: bool - // description: need something + // default: false + // description: Remove the volumes associated with the container. // - in: query // name: link // type: bool @@ -107,15 +123,19 @@ func (s *APIServer) RegisterContainersHandlers(r *mux.Router) error { // "$ref": "#/responses/InternalError" r.HandleFunc(VersionedPath("/containers/{name:..*}"), APIHandler(s.Context, generic.RemoveContainer)).Methods(http.MethodDelete) // swagger:operation GET /containers/{nameOrID}/json containers getContainer - // - // Inspect Container - // // --- + // summary: Inspect container + // description: Return low-level information about a container. // parameters: // - in: path // name: nameOrID // required: true - // description: the name or ID of the container + // description: the name or id of the container + // - in: query + // name: size + // type: bool + // default: false + // description: include the size of the container // produces: // - application/json // responses: @@ -126,11 +146,10 @@ func (s *APIServer) RegisterContainersHandlers(r *mux.Router) error { // '500': // "$ref": "#/responses/InternalError" r.HandleFunc(VersionedPath("/containers/{name:..*}/json"), APIHandler(s.Context, generic.GetContainer)).Methods(http.MethodGet) - // swagger:operation POST /containers/{nameOrID}/kill containers killContainer - // - // Kill Container - // + // swagger:operation post /containers/{nameOrID}/kill containers killcontainer // --- + // summary: Kill container + // description: Signal to send to the container as an integer or string (e.g. SIGINT) // parameters: // - in: path // name: nameOrID @@ -153,10 +172,9 @@ func (s *APIServer) RegisterContainersHandlers(r *mux.Router) error { // "$ref": "#/responses/InternalError" r.HandleFunc(VersionedPath("/containers/{name:..*}/kill"), APIHandler(s.Context, generic.KillContainer)).Methods(http.MethodPost) // swagger:operation GET /containers/{nameOrID}/logs containers LogsFromContainer - // - // Get logs from container - // // --- + // summary: Get container logs + // description: Get stdout and stderr logs from a container. // parameters: // - in: path // name: nameOrID @@ -165,46 +183,47 @@ func (s *APIServer) RegisterContainersHandlers(r *mux.Router) error { // - in: query // name: follow // type: bool - // description: needs description + // description: Keep connection after returning logs. // - in: query // name: stdout // type: bool - // description: needs description + // description: not supported // - in: query // name: stderr // type: bool - // description: needs description + // description: not supported? // - in: query // name: since // type: string - // description: needs description + // description: Only return logs since this time, as a UNIX timestamp // - in: query // name: until // type: string - // description: needs description + // description: Only return logs before this time, as a UNIX timestamp // - in: query // name: timestamps // type: bool - // description: needs description + // default: false + // description: Add timestamps to every log line // - in: query // name: tail // type: string - // description: needs description + // description: Only return this number of log lines from the end of the logs + // default: all // produces: // - application/json // responses: // '200': - // description: tbd + // description: logs returned as a stream in response body. // '404': // "$ref": "#/responses/NoSuchContainer" // '500': // "$ref": "#/responses/InternalError" r.HandleFunc(VersionedPath("/containers/{name:..*}/logs"), APIHandler(s.Context, generic.LogsFromContainer)).Methods(http.MethodGet) // swagger:operation POST /containers/{nameOrID}/pause containers pauseContainer - // - // Pause Container - // // --- + // summary: Pause container + // description: Use the cgroups freezer to suspend all processes in a container. // parameters: // - in: path // name: nameOrID @@ -222,10 +241,8 @@ func (s *APIServer) RegisterContainersHandlers(r *mux.Router) error { r.HandleFunc(VersionedPath("/containers/{name:..*}/pause"), APIHandler(s.Context, handlers.PauseContainer)).Methods(http.MethodPost) r.HandleFunc(VersionedPath("/containers/{name:..*}/rename"), APIHandler(s.Context, handlers.UnsupportedHandler)).Methods(http.MethodPost) // swagger:operation POST /containers/{nameOrID}/restart containers restartContainer - // - // Restart Container - // // --- + // summary: Restart container // parameters: // - in: path // name: nameOrID @@ -246,10 +263,8 @@ func (s *APIServer) RegisterContainersHandlers(r *mux.Router) error { // "$ref": "#/responses/InternalError" r.HandleFunc(VersionedPath("/containers/{name:..*}/restart"), APIHandler(s.Context, handlers.RestartContainer)).Methods(http.MethodPost) // swagger:operation POST /containers/{nameOrID}/start containers startContainer - // - // Start a container - // // --- + // summary: Start a container // parameters: // - in: path // name: nameOrID @@ -272,10 +287,9 @@ func (s *APIServer) RegisterContainersHandlers(r *mux.Router) error { // "$ref": "#/responses/InternalError" r.HandleFunc(VersionedPath("/containers/{name:..*}/start"), APIHandler(s.Context, handlers.StartContainer)).Methods(http.MethodPost) // swagger:operation GET /containers/{nameOrID}/stats containers statsContainer - // - // Get stats for a container - // // --- + // summary: Get stats for a container + // description: This returns a live stream of a container’s resource usage statistics. // parameters: // - in: path // name: nameOrID @@ -284,24 +298,21 @@ func (s *APIServer) RegisterContainersHandlers(r *mux.Router) error { // - in: query // name: stream // type: bool - // description: needs description + // default: true + // description: Stream the output // produces: // - application/json // responses: - // '204': - // description: tbd - // '304': - // "$ref": "#/responses/ContainerAlreadyStartedError" + // '200': + // description: no error // '404': // "$ref": "#/responses/NoSuchContainer" // '500': // "$ref": "#/responses/InternalError" r.HandleFunc(VersionedPath("/containers/{name:..*}/stats"), APIHandler(s.Context, generic.StatsContainer)).Methods(http.MethodGet) // swagger:operation POST /containers/{nameOrID}/stop containers stopContainer - // - // Stop a container - // // --- + // summary: Stop a container // parameters: // - in: path // name: nameOrID @@ -324,10 +335,8 @@ func (s *APIServer) RegisterContainersHandlers(r *mux.Router) error { // "$ref": "#/responses/InternalError" r.HandleFunc(VersionedPath("/containers/{name:..*}/stop"), APIHandler(s.Context, handlers.StopContainer)).Methods(http.MethodPost) // swagger:operation GET /containers/{nameOrID}/top containers topContainer - // - // List processes running inside a container - // // --- + // summary: List processes running inside a container // parameters: // - in: path // name: nameOrID @@ -348,10 +357,9 @@ func (s *APIServer) RegisterContainersHandlers(r *mux.Router) error { // "$ref": "#/responses/InternalError" r.HandleFunc(VersionedPath("/containers/{name:..*}/top"), APIHandler(s.Context, handlers.TopContainer)).Methods(http.MethodGet) // swagger:operation POST /containers/{nameOrID}/unpause containers unpauseContainer - // - // Unpause Container - // // --- + // summary: Unpause container + // description: Resume a paused container // parameters: // - in: path // name: nameOrID @@ -362,17 +370,15 @@ func (s *APIServer) RegisterContainersHandlers(r *mux.Router) error { // responses: // '204': // description: no error - // schema: // '404': // "$ref": "#/responses/NoSuchContainer" // '500': // "$ref": "#/responses/InternalError" r.HandleFunc(VersionedPath("/containers/{name:..*}/unpause"), APIHandler(s.Context, handlers.UnpauseContainer)).Methods(http.MethodPost) // swagger:operation POST /containers/{nameOrID}/wait containers waitContainer - // - // Wait on a container to exit - // // --- + // summary: Wait on a container to exit + // description: Block until a container stops, then returns the exit code. // parameters: // - in: path // name: nameOrID @@ -385,8 +391,8 @@ func (s *APIServer) RegisterContainersHandlers(r *mux.Router) error { // produces: // - application/json // responses: - // '204': - // description: no error + // '200': + // $ref: "#/responses/ContainerWaitResponse" // '404': // "$ref": "#/responses/NoSuchContainer" // '500': @@ -398,11 +404,10 @@ func (s *APIServer) RegisterContainersHandlers(r *mux.Router) error { */ r.HandleFunc(VersionedPath("/libpod/containers/create"), APIHandler(s.Context, libpod.CreateContainer)).Methods(http.MethodPost) - // swagger:operation GET /libpod/containers/json containers listContainers - // - // List containers - // + // swagger:operation GET /libpod/containers/json containers libpodListContainers // --- + // summary: List containers + // description: Returns a list of containers // produces: // - application/json // responses: @@ -416,11 +421,10 @@ func (s *APIServer) RegisterContainersHandlers(r *mux.Router) error { // '500': // "$ref": "#/responses/InternalError" r.HandleFunc(VersionedPath("/libpod/containers/json"), APIHandler(s.Context, libpod.ListContainers)).Methods(http.MethodGet) - // swagger:operation POST /libpod/containers/prune containers pruneContainers - // - // Prune unused containers - // + // swagger:operation POST /libpod/containers/prune containers libpodPruneContainers // --- + // summary: Prune unused containers + // description: Remove stopped and exited containers // parameters: // - in: query // name: force @@ -428,21 +432,23 @@ func (s *APIServer) RegisterContainersHandlers(r *mux.Router) error { // description: something // - in: query // name: filters - // type: map[string][]string - // description: something + // type: string + // description: | + // Filters to process on the prune list, encoded as JSON (a `map[string][]string`). Available filters: + // - `until=<timestamp>` Prune containers created before this timestamp. The `<timestamp>` can be Unix timestamps, date formatted timestamps, or Go duration strings (e.g. `10m`, `1h30m`) computed relative to the daemon machine’s time. + // - `label` (`label=<key>`, `label=<key>=<value>`, `label!=<key>`, or `label!=<key>=<value>`) Prune containers with (or without, in case `label!=...` is used) the specified labels. // produces: // - application/json // responses: // '200': - // description: TBD + // description: to be determined // '500': // "$ref": "#/responses/InternalError" r.HandleFunc(VersionedPath("/libpod/containers/prune"), APIHandler(s.Context, libpod.PruneContainers)).Methods(http.MethodPost) // swagger:operation GET /libpod/containers/showmounted containers showMounterContainers - // - // Show mounted containers - // // --- + // summary: Show mounted containers + // description: Lists all mounted containers mount points // produces: // - application/json // responses: @@ -455,11 +461,9 @@ func (s *APIServer) RegisterContainersHandlers(r *mux.Router) error { // '500': // "$ref": "#/responses/InternalError" r.HandleFunc(VersionedPath("/libpod/containers/showmounted"), APIHandler(s.Context, libpod.ShowMountedContainers)).Methods(http.MethodGet) - // swagger:operation DELETE /libpod/containers/json containers removeContainer - // - // Delete container - // + // swagger:operation DELETE /libpod/containers/json containers libpodRemoveContainer // --- + // summary: Delete container // parameters: // - in: path // name: nameOrID @@ -472,7 +476,7 @@ func (s *APIServer) RegisterContainersHandlers(r *mux.Router) error { // - in: query // name: v // type: bool - // description: need something + // description: delete volumes // produces: // - application/json // responses: @@ -487,11 +491,10 @@ func (s *APIServer) RegisterContainersHandlers(r *mux.Router) error { // '500': // "$ref": "#/responses/InternalError" r.HandleFunc(VersionedPath("/libpod/containers/{name:..*}"), APIHandler(s.Context, libpod.RemoveContainer)).Methods(http.MethodDelete) - // swagger:operation GET /libpod/containers/{nameOrID}/json containers getContainer - // - // Inspect Container - // + // swagger:operation GET /libpod/containers/{nameOrID}/json containers libpodGetContainer // --- + // summary: Inspect container + // description: Return low-level information about a container. // parameters: // - in: path // name: nameOrID @@ -511,11 +514,10 @@ func (s *APIServer) RegisterContainersHandlers(r *mux.Router) error { // '500': // "$ref": "#/responses/InternalError" r.HandleFunc(VersionedPath("/libpod/containers/{name:..*}/json"), APIHandler(s.Context, libpod.GetContainer)).Methods(http.MethodGet) - // swagger:operation POST /libpod/containers/{nameOrID}/kill containers killContainer - // - // Kill Container - // + // swagger:operation POST /libpod/containers/{nameOrID}/kill containers libpodKillContainer // --- + // summary: Kill container + // description: send a signal to a container, defaults to killing the container // parameters: // - in: path // name: nameOrID @@ -539,10 +541,9 @@ func (s *APIServer) RegisterContainersHandlers(r *mux.Router) error { // "$ref": "#/responses/InternalError" r.HandleFunc(VersionedPath("/libpod/containers/{name:..*}/kill"), APIHandler(s.Context, libpod.KillContainer)).Methods(http.MethodGet) // swagger:operation GET /libpod/containers/{nameOrID}/mount containers mountContainer - // - // Mount a container - // // --- + // summary: Mount a container + // description: Mount a container to the filesystem // parameters: // - in: path // name: nameOrID @@ -563,11 +564,10 @@ func (s *APIServer) RegisterContainersHandlers(r *mux.Router) error { // "$ref": "#/responses/InternalError" r.HandleFunc(VersionedPath("/libpod/containers/{name:..*}/mount"), APIHandler(s.Context, libpod.MountContainer)).Methods(http.MethodPost) r.HandleFunc(VersionedPath("/libpod/containers/{name:..*}/logs"), APIHandler(s.Context, libpod.LogsFromContainer)).Methods(http.MethodGet) - // swagger:operation POST /libpod/containers/{nameOrID}/pause containers pauseContainer - // - // Pause Container - // + // swagger:operation POST /libpod/containers/{nameOrID}/pause containers libpodPauseContainer // --- + // summary: Pause a container + // description: Use the cgroups freezer to suspend all processes in a container. // parameters: // - in: path // name: nameOrID @@ -583,11 +583,9 @@ func (s *APIServer) RegisterContainersHandlers(r *mux.Router) error { // '500': // "$ref": "#/responses/InternalError" r.HandleFunc(VersionedPath("/libpod/containers/{name:..*}/pause"), APIHandler(s.Context, handlers.PauseContainer)).Methods(http.MethodPost) - // swagger:operation POST /libpod/containers/{nameOrID}/restart containers restartContainer - // - // Restart Container - // + // swagger:operation POST /libpod/containers/{nameOrID}/restart containers libpodRestartContainer // --- + // summary: Restart a container // parameters: // - in: path // name: nameOrID @@ -607,11 +605,9 @@ func (s *APIServer) RegisterContainersHandlers(r *mux.Router) error { // '500': // "$ref": "#/responses/InternalError" r.HandleFunc(VersionedPath("/libpod/containers/{name:..*}/restart"), APIHandler(s.Context, handlers.RestartContainer)).Methods(http.MethodPost) - // swagger:operation POST /libpod/containers/{nameOrID}/start containers startContainer - // - // Start a container - // + // swagger:operation POST /libpod/containers/{nameOrID}/start containers libpodStartContainer // --- + // summary: Start a container // parameters: // - in: path // name: nameOrID @@ -635,11 +631,9 @@ func (s *APIServer) RegisterContainersHandlers(r *mux.Router) error { r.HandleFunc(VersionedPath("/libpod/containers/{name:..*}/start"), APIHandler(s.Context, handlers.StartContainer)).Methods(http.MethodPost) r.HandleFunc(VersionedPath("/libpod/containers/{name:..*}/stats"), APIHandler(s.Context, libpod.StatsContainer)).Methods(http.MethodGet) r.HandleFunc(VersionedPath("/libpod/containers/{name:..*}/top"), APIHandler(s.Context, handlers.TopContainer)).Methods(http.MethodGet) - // swagger:operation POST /libpod/containers/{nameOrID}/unpause containers unpauseContainer - // - // Unpause Container - // + // swagger:operation POST /libpod/containers/{nameOrID}/unpause containers libpodUnpauseContainer // --- + // summary: Unpause Container // parameters: // - in: path // name: nameOrID @@ -655,11 +649,9 @@ func (s *APIServer) RegisterContainersHandlers(r *mux.Router) error { // '500': // "$ref": "#/responses/InternalError" r.HandleFunc(VersionedPath("/libpod/containers/{name:..*}/unpause"), APIHandler(s.Context, handlers.UnpauseContainer)).Methods(http.MethodPost) - // swagger:operation POST /libpod/containers/{nameOrID}/wait containers waitContainer - // - // Wait on a container to exit - // + // swagger:operation POST /libpod/containers/{nameOrID}/wait containers libpodWaitContainer // --- + // summary: Wait on a container to exit // parameters: // - in: path // name: nameOrID @@ -680,10 +672,9 @@ func (s *APIServer) RegisterContainersHandlers(r *mux.Router) error { // "$ref": "#/responses/InternalError" r.HandleFunc(VersionedPath("/libpod/containers/{name:..*}/wait"), APIHandler(s.Context, libpod.WaitContainer)).Methods(http.MethodPost) // swagger:operation POST /libpod/containers/{nameOrID}/exists containers containerExists - // - // Check if container exists - // // --- + // summary: Check if container exists + // description: Quick way to determine if a container exists by name or ID // parameters: // - in: path // name: nameOrID @@ -699,11 +690,9 @@ func (s *APIServer) RegisterContainersHandlers(r *mux.Router) error { // '500': // "$ref": "#/responses/InternalError" r.HandleFunc(VersionedPath("/libpod/containers/{name:..*}/exists"), APIHandler(s.Context, libpod.ContainerExists)).Methods(http.MethodGet) - // swagger:operation POST /libpod/containers/{nameOrID}/stop containers stopContainer - // - // Stop a container - // + // swagger:operation POST /libpod/containers/{nameOrID}/stop containers libpodStopContainer // --- + // summary: Stop a container // parameters: // - in: path // name: nameOrID diff --git a/pkg/api/server/register_events.go b/pkg/api/server/register_events.go index d764fdbb4..56cf96de1 100644 --- a/pkg/api/server/register_events.go +++ b/pkg/api/server/register_events.go @@ -26,7 +26,7 @@ func (s *APIServer) RegisterEventsHandlers(r *mux.Router) error { // description: OK // "500": // description: Failed - // "$ref": "#/types/errorModel" + // "$ref": "#/responses/InternalError" r.Handle(VersionedPath("/events"), APIHandler(s.Context, handlers.GetEvents)) return nil } diff --git a/pkg/api/server/register_images.go b/pkg/api/server/register_images.go index 488427f3c..916534fc7 100644 --- a/pkg/api/server/register_images.go +++ b/pkg/api/server/register_images.go @@ -10,11 +10,11 @@ import ( ) func (s *APIServer) registerImagesHandlers(r *mux.Router) error { - // swagger:operation POST /images/create images createImage - // - // Create an image from an image + // swagger:operation POST /images/create compat_images createImage // // --- + // summary: Create an image from an image + // description: Create an image by either pulling it from a registry or importing it. // produces: // - application/json // parameters: @@ -30,21 +30,20 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error { // '200': // schema: // items: - // $ref: "TBD" + // $ref: "to be determined" // '404': // description: repo or image does not exist // schema: - // $ref: "#/responses/generalError" + // $ref: "#/responses/InternalError" // '500': // description: unexpected error // schema: // $ref: '#/responses/GenericError' r.Handle(VersionedPath("/images/create"), APIHandler(s.Context, generic.CreateImageFromImage)).Methods(http.MethodPost).Queries("fromImage", "{fromImage}") - // swagger:operation POST /images/create images createImage - // - // Create an image from Source - // + // swagger:operation POST /images/create compat_images createImage // --- + // summary: Create an image from Source + // description: Create an image by either pulling it from a registry or importing it. // produces: // - application/json // parameters: @@ -54,27 +53,26 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error { // description: needs description // - in: query // name: changes - // type: TBD + // type: to be determined // description: needs description // responses: // '200': // schema: // items: - // $ref: "TBD" + // $ref: "to be determined" // '404': // description: repo or image does not exist // schema: - // $ref: "#/responses/generalError" + // $ref: "#/responses/InternalError" // '500': // description: unexpected error // schema: // $ref: '#/responses/GenericError' r.Handle(VersionedPath("/images/create"), APIHandler(s.Context, generic.CreateImageFromSrc)).Methods(http.MethodPost).Queries("fromSrc", "{fromSrc}") - // swagger:operation GET /images/json images listImages - // - // List Images - // + // swagger:operation GET /images/json compat_images listImages // --- + // summary: List Images + // description: Returns a list of images on the server. Note that it uses a different, smaller representation of an image than inspecting a single image. // produces: // - application/json // responses: @@ -87,34 +85,43 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error { // '500': // $ref: '#/responses/InternalError' r.Handle(VersionedPath("/images/json"), APIHandler(s.Context, generic.GetImages)).Methods(http.MethodGet) - // swagger:operation POST /images/load images loadImage - // - // Import image + // swagger:operation POST /images/load compat_images loadImage // // --- + // summary: Import image + // description: Load a set of images and tags into a repository. // parameters: // - in: query // name: quiet // type: bool // description: not supported + // - in: body + // description: tarball of container image + // type: string + // format: binary // produces: // - application/json // responses: // '200': - // description: TBD + // description: no error // '500': // $ref: '#/responses/InternalError' r.Handle(VersionedPath("/images/load"), APIHandler(s.Context, handlers.LoadImage)).Methods(http.MethodPost) - // swagger:operation POST /images/prune images pruneImages - // - // Prune unused images - // + // swagger:operation POST /images/prune compat_images pruneImages // --- + // summary: Prune unused images + // description: Remove images from local storage that are not being used by a container // parameters: // - in: query // name: filters - // type: map[string][]string - // description: not supported + // type: string + // description: | + // filters to apply to image pruning, encoded as JSON (map[string][]string). Available filters: + // - `dangling=<boolean>` When set to `true` (or `1`), prune only + // unused *and* untagged images. When set to `false` + // (or `0`), all unused images are pruned. + // - `until=<string>` Prune images created before this timestamp. The `<timestamp>` can be Unix timestamps, date formatted timestamps, or Go duration strings (e.g. `10m`, `1h30m`) computed relative to the daemon machine’s time. + // - `label` (`label=<key>`, `label=<key>=<value>`, `label!=<key>`, or `label!=<key>=<value>`) Prune images with (or without, in case `label!=...` is used) the specified labels. // produces: // - application/json // responses: @@ -125,11 +132,10 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error { // '500': // $ref: '#/responses/InternalError' r.Handle(VersionedPath("/images/prune"), APIHandler(s.Context, generic.PruneImages)).Methods(http.MethodPost) - // swagger:operation GET /images/search images searchImages - // - // Search images - // + // swagger:operation GET /images/search compat_images searchImages // --- + // summary: Search images + // description: Search registries for an image // parameters: // - in: query // name: term @@ -141,8 +147,12 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error { // description: maximum number of results // - in: query // name: filters - // type: map[string][]string - // description: TBD + // type: string + // description: | + // A JSON encoded value of the filters (a `map[string][]string`) to process on the images list. Available filters: + // - `is-automated=(true|false)` + // - `is-official=(true|false)` + // - `stars=<number>` Matches images that has at least 'number' stars. // produces: // - application/json // responses: @@ -151,11 +161,10 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error { // '500': // $ref: '#/responses/InternalError' r.Handle(VersionedPath("/images/search"), APIHandler(s.Context, handlers.SearchImages)).Methods(http.MethodGet) - // swagger:operation DELETE /images/{nameOrID} images removeImage - // - // Remove Image - // + // swagger:operation DELETE /images/{nameOrID} compat_images removeImage // --- + // summary: Remove Image + // description: Delete an image from local storage // parameters: // - in: query // name: force @@ -164,24 +173,23 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error { // - in: query // name: noprune // type: bool - // description: not supported + // description: not supported. will be logged as an invalid parameter if enabled // produces: // - application/json // responses: // '200': // $ref: "#/responses/DocsImageDeleteResponse" - // '404': + // '400': // $ref: '#/responses/BadParamError' // '409': // $ref: '#/responses/ConflictError' // '500': // $ref: '#/responses/InternalError' r.Handle(VersionedPath("/images/{name:..*}"), APIHandler(s.Context, handlers.RemoveImage)).Methods(http.MethodDelete) - // swagger:operation GET /images/{nameOrID}/get images exportImage - // - // Export an image - // + // swagger:operation GET /images/{nameOrID}/get compat_images exportImage // --- + // summary: Export an image + // description: Export an image in tarball format // parameters: // - in: path // name: nameOrID @@ -191,17 +199,17 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error { // - application/json // responses: // '200': + // description: no error // schema: - // $ref: "TBD" - // description: TBD + // type: string + // format: binary // '500': // $ref: '#/responses/InternalError' r.Handle(VersionedPath("/images/{name:..*}/get"), APIHandler(s.Context, generic.ExportImage)).Methods(http.MethodGet) - // swagger:operation GET /images/{nameOrID}/history images imageHistory - // - // History of an image - // + // swagger:operation GET /images/{nameOrID}/history compat_images imageHistory // --- + // summary: History of an image + // description: Return parent layers of an image. // parameters: // - in: path // name: nameOrID @@ -217,11 +225,10 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error { // '500': // $ref: "#/responses/InternalError" r.Handle(VersionedPath("/images/{name:..*}/history"), APIHandler(s.Context, handlers.HistoryImage)).Methods(http.MethodGet) - // swagger:operation GET /images/{nameOrID}/json images inspectImage - // - // Inspect an image - // + // swagger:operation GET /images/{nameOrID}/json compat_images inspectImage // --- + // summary: Inspect an image + // description: Return low-level information about an image. // parameters: // - in: path // name: nameOrID @@ -237,11 +244,10 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error { // '500': // $ref: "#/responses/InternalError" r.Handle(VersionedPath("/images/{name:..*}/json"), APIHandler(s.Context, generic.GetImage)) - // swagger:operation POST /images/{nameOrID}/tag images tagImage - // - // Tag an image - // + // swagger:operation POST /images/{nameOrID}/tag compat_images tagImage // --- + // summary: Tag an image + // description: Tag an image so that it becomes part of a repository. // parameters: // - in: path // name: nameOrID @@ -269,11 +275,9 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error { // 500: // $ref: '#/responses/InternalError' r.Handle(VersionedPath("/images/{name:..*}/tag"), APIHandler(s.Context, handlers.TagImage)).Methods(http.MethodPost) - // swagger:operation POST /commit/ commit commitContainer - // - // Create a new image from a container - // + // swagger:operation POST /commit/ compat_commit commitContainer // --- + // summary: Create a new image from a container // parameters: // - in: query // name: container @@ -318,11 +322,10 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error { libpod endpoints */ - // swagger:operation POST /libpod/images/{nameOrID}/exists images imageExists - // - // Check if image exists in local store - // + // swagger:operation POST /libpod/images/{nameOrID}/exists images libpodImageExists // --- + // summary: Image exists + // description: Check if image exists in local store // parameters: // - in: path // name: nameOrID @@ -330,15 +333,6 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error { // description: the name or ID of the container // produces: // - application/json - // parameters: - // - in: query - // name: fromImage - // type: string - // description: needs description - // - in: query - // name: tag - // type: string - // description: needs description // responses: // '204': // description: image exists @@ -348,11 +342,10 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error { // $ref: '#/responses/InternalError' r.Handle(VersionedPath("/libpod/images/{name:..*}/exists"), APIHandler(s.Context, libpod.ImageExists)) r.Handle(VersionedPath("/libpod/images/{name:..*}/tree"), APIHandler(s.Context, libpod.ImageTree)) - // swagger:operation GET /libpod/images/{nameOrID}/history images imageHistory - // - // History of an image - // + // swagger:operation GET /libpod/images/{nameOrID}/history images libpodImageHistory // --- + // summary: History of an image + // description: Return parent layers of an image. // parameters: // - in: path // name: nameOrID @@ -370,11 +363,10 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error { // '500': // $ref: '#/responses/InternalError' r.Handle(VersionedPath("/libpod/images/history"), APIHandler(s.Context, handlers.HistoryImage)).Methods(http.MethodGet) - // swagger:operation GET /libpod/images/json images listImages - // - // List Images - // + // swagger:operation GET /libpod/images/json images libpodListImages // --- + // summary: List Images + // description: Returns a list of images on the server // produces: // - application/json // responses: @@ -385,34 +377,42 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error { // '500': // $ref: '#/responses/InternalError' r.Handle(VersionedPath("/libpod/images/json"), APIHandler(s.Context, libpod.GetImages)).Methods(http.MethodGet) - // swagger:operation POST /libpod/images/load images loadImage - // - // Import image - // + // swagger:operation POST /libpod/images/load images libpodLoadImage // --- + // summary: Import image + // description: Load a set of images and tags into a repository. // parameters: // - in: query // name: quiet // type: bool // description: not supported + // - in: body + // description: tarball of container image + // type: string + // format: binary // produces: // - application/json // responses: // '200': - // description: TBD + // description: no error // '500': // $ref: '#/responses/InternalError' r.Handle(VersionedPath("/libpod/images/load"), APIHandler(s.Context, handlers.LoadImage)).Methods(http.MethodPost) - // swagger:operation POST /libpod/images/prune images pruneImages - // - // Prune unused images - // + // swagger:operation POST /libpod/images/prune images libpodPruneImages // --- + // summary: Prune unused images + // description: Remove images that are not being used by a container // parameters: // - in: query // name: filters - // type: map[string][]string - // description: image filters + // type: string + // description: | + // filters to apply to image pruning, encoded as JSON (map[string][]string). Available filters: + // - `dangling=<boolean>` When set to `true` (or `1`), prune only + // unused *and* untagged images. When set to `false` + // (or `0`), all unused images are pruned. + // - `until=<string>` Prune images created before this timestamp. The `<timestamp>` can be Unix timestamps, date formatted timestamps, or Go duration strings (e.g. `10m`, `1h30m`) computed relative to the daemon machine’s time. + // - `label` (`label=<key>`, `label=<key>=<value>`, `label!=<key>`, or `label!=<key>=<value>`) Prune images with (or without, in case `label!=...` is used) the specified labels. // - in: query // name: all // type: bool @@ -421,17 +421,15 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error { // - application/json // responses: // '200': - // schema: // items: // $ref: "#/responses/DocsImageDeleteResponse" // '500': // $ref: '#/responses/InternalError' r.Handle(VersionedPath("/libpod/images/prune"), APIHandler(s.Context, libpod.PruneImages)).Methods(http.MethodPost) - // swagger:operation GET /libpod/images/search images searchImages - // - // Search images - // + // swagger:operation GET /libpod/images/search images libpodSearchImages // --- + // summary: Search images + // description: Search registries for images // parameters: // - in: query // name: term @@ -443,8 +441,12 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error { // description: maximum number of results // - in: query // name: filters - // type: map[string][]string - // description: TBD + // type: string + // description: | + // A JSON encoded value of the filters (a `map[string][]string`) to process on the images list. Available filters: + // - `is-automated=(true|false)` + // - `is-official=(true|false)` + // - `stars=<number>` Matches images that has at least 'number' stars. // produces: // - application/json // responses: @@ -455,20 +457,15 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error { // '500': // $ref: '#/responses/InternalError' r.Handle(VersionedPath("/libpod/images/search"), APIHandler(s.Context, handlers.SearchImages)).Methods(http.MethodGet) - // swagger:operation DELETE /libpod/images/{nameOrID} images removeImage - // - // Remove Image - // + // swagger:operation DELETE /libpod/images/{nameOrID} images libpodRemoveImage // --- + // summary: Remove Image + // description: Delete an image from local store // parameters: // - in: query // name: force // type: bool // description: remove the image even if used by containers or has other tags - // - in: query - // name: noprune - // type: bool - // description: not supported // produces: // - application/json // responses: @@ -476,6 +473,8 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error { // schema: // items: // $ref: "#/responses/DocsIageDeleteResponse" + // '400': + // $ref: "#/responses/BadParamError" // '404': // $ref: '#/responses/NoSuchImage' // '409': @@ -483,11 +482,10 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error { // '500': // $ref: '#/responses/InternalError' r.Handle(VersionedPath("/libpod/images/{name:..*}"), APIHandler(s.Context, handlers.RemoveImage)).Methods(http.MethodDelete) - // swagger:operation GET /libpod/images/{nameOrID}/get images exportImage - // - // Export an image - // + // swagger:operation GET /libpod/images/{nameOrID}/get images libpoodExportImage // --- + // summary: Export an image + // description: Export an image as a tarball // parameters: // - in: path // name: nameOrID @@ -505,17 +503,19 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error { // - application/json // responses: // '200': - // description: TBD + // description: no error + // schema: + // type: string + // format: binary // '404': // $ref: '#/responses/NoSuchImage' // '500': // $ref: '#/responses/InternalError' r.Handle(VersionedPath("/libpod/images/{name:..*}/get"), APIHandler(s.Context, libpod.ExportImage)).Methods(http.MethodGet) - // swagger:operation GET /libpod/images/{nameOrID}/json images inspectImage - // - // Inspect an image - // + // swagger:operation GET /libpod/images/{nameOrID}/json images libpodInspectImage // --- + // summary: Inspect an image + // description: Obtain low-level information about an image // parameters: // - in: path // name: nameOrID @@ -525,19 +525,16 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error { // - application/json // responses: // '200': - // schema: - // items: // $ref: "#/responses/DocsLibpodInspectImageResponse" // '404': // $ref: '#/responses/NoSuchImage' // '500': // $ref: '#/responses/InternalError' r.Handle(VersionedPath("/libpod/images/{name:..*}/json"), APIHandler(s.Context, libpod.GetImage)) - // swagger:operation POST /libpod/images/{nameOrID}/tag images tagImage - // - // Tag an image - // + // swagger:operation POST /libpod/images/{nameOrID}/tag images libpodTagImage // --- + // summary: Tag an image + // description: Tag an image so that it becomes part of a repository. // parameters: // - in: path // name: nameOrID diff --git a/pkg/api/server/register_info.go b/pkg/api/server/register_info.go index 797158553..a7fb18721 100644 --- a/pkg/api/server/register_info.go +++ b/pkg/api/server/register_info.go @@ -8,21 +8,17 @@ import ( ) func (s *APIServer) registerInfoHandlers(r *mux.Router) error { - // swagger:operation GET /info libpod getInfo - // - // Returns information on the system and libpod configuration - // + // swagger:operation GET /info libpod libpodGetInfo // --- + // summary: Get info + // description: Returns information on the system and libpod configuration // produces: // - application/json // responses: // '200': - // schema: - // "$ref": "#/types/Info" + // description: to be determined // '500': - // description: unexpected error - // schema: - // "$ref": "#/types/ErrorModel" + // "$ref": "#/responses/InternalError" r.Handle(VersionedPath("/info"), APIHandler(s.Context, generic.GetInfo)).Methods(http.MethodGet) return nil } diff --git a/pkg/api/server/register_pods.go b/pkg/api/server/register_pods.go index c2e10277e..5069326b6 100644 --- a/pkg/api/server/register_pods.go +++ b/pkg/api/server/register_pods.go @@ -9,10 +9,8 @@ import ( func (s *APIServer) registerPodsHandlers(r *mux.Router) error { // swagger:operation GET /libpod/pods/json pods ListPods - // - // List Pods - // // --- + // summary: List pods // produces: // - application/json // parameters: @@ -21,23 +19,25 @@ func (s *APIServer) registerPodsHandlers(r *mux.Router) error { // descriptions: needs description and plumbing for filters // responses: // '200': - // $ref: "#/responses/ListPodsResponse" + // properties: + // items: + // $ref: "#/responses/ListPodsResponse" + // type: array // '400': // $ref: "#/responses/BadParamError" // '500': - // $ref: "#responses/InternalError" + // $ref: "#/responses/InternalError" r.Handle(VersionedPath("/libpod/pods/json"), APIHandler(s.Context, libpod.Pods)).Methods(http.MethodGet) r.Handle(VersionedPath("/libpod/pods/create"), APIHandler(s.Context, libpod.PodCreate)).Methods(http.MethodPost) // swagger:operation POST /libpod/pods/prune pods PrunePods - // - // Prune unused pods - // // --- + // summary: Prune unused pods // parameters: // - in: query // name: force // description: force delete // type: bool + // default: false // produces: // - application/json // responses: @@ -46,13 +46,11 @@ func (s *APIServer) registerPodsHandlers(r *mux.Router) error { // '400': // $ref: "#/responses/BadParamError" // '500': - // $ref: "#responses/InternalError" + // $ref: "#/responses/InternalError" r.Handle(VersionedPath("/libpod/pods/prune"), APIHandler(s.Context, libpod.PodPrune)).Methods(http.MethodPost) // swagger:operation DELETE /libpod/pods/{nameOrID} pods removePod - // - // Remove Pod - // // --- + // summary: Remove pod // produces: // - application/json // parameters: @@ -72,13 +70,11 @@ func (s *APIServer) registerPodsHandlers(r *mux.Router) error { // '404': // $ref: "#/responses/NoSuchPod" // '500': - // $ref: "#responses/InternalError" + // $ref: "#/responses/InternalError" r.Handle(VersionedPath("/libpod/pods/{name:..*}"), APIHandler(s.Context, libpod.PodDelete)).Methods(http.MethodDelete) // swagger:operation GET /libpod/pods/{nameOrID}/json pods inspectPod - // - // Inspect Pod - // // --- + // summary: Inspect pod // produces: // - application/json // parameters: @@ -92,13 +88,12 @@ func (s *APIServer) registerPodsHandlers(r *mux.Router) error { // '404': // $ref: "#/responses/NoSuchPod" // '500': - // $ref: "#responses/InternalError" + // $ref: "#/responses/InternalError" r.Handle(VersionedPath("/libpod/pods/{name:..*}/json"), APIHandler(s.Context, libpod.PodInspect)).Methods(http.MethodGet) // swagger:operation GET /libpod/pods/{nameOrID}/exists pods podExists - // - // Inspect Pod - // // --- + // summary: Pod exists + // description: Check if a pod exists by name or ID // produces: // - application/json // parameters: @@ -112,13 +107,11 @@ func (s *APIServer) registerPodsHandlers(r *mux.Router) error { // '404': // $ref: "#/responses/NoSuchPod" // '500': - // $ref: "#responses/InternalError" + // $ref: "#/responses/InternalError" r.Handle(VersionedPath("/libpod/pods/{name:..*}/exists"), APIHandler(s.Context, libpod.PodExists)).Methods(http.MethodGet) // swagger:operation POST /libpod/pods/{nameOrID}/kill pods killPod - // - // Kill a pod - // // --- + // summary: Kill a pod // produces: // - application/json // parameters: @@ -140,13 +133,11 @@ func (s *APIServer) registerPodsHandlers(r *mux.Router) error { // '409': // $ref: "#/responses/ConflictError" // '500': - // $ref: "#responses/InternalError" + // $ref: "#/responses/InternalError" r.Handle(VersionedPath("/libpod/pods/{name:..*}/kill"), APIHandler(s.Context, libpod.PodKill)).Methods(http.MethodPost) // swagger:operation POST /libpod/pods/{nameOrID}/pause pods pausePod - // - // Pause a pod - // // --- + // summary: Pause a pod // produces: // - application/json // parameters: @@ -160,13 +151,11 @@ func (s *APIServer) registerPodsHandlers(r *mux.Router) error { // '404': // $ref: "#/responses/NoSuchPod" // '500': - // $ref: "#responses/InternalError" + // $ref: "#/responses/InternalError" r.Handle(VersionedPath("/libpod/pods/{name:..*}/pause"), APIHandler(s.Context, libpod.PodPause)).Methods(http.MethodPost) // swagger:operation POST /libpod/pods/{nameOrID}/restart pods restartPod - // - // Restart a pod - // // --- + // summary: Restart a pod // produces: // - application/json // parameters: @@ -180,13 +169,11 @@ func (s *APIServer) registerPodsHandlers(r *mux.Router) error { // '404': // $ref: "#/responses/NoSuchPod" // '500': - // $ref: "#responses/InternalError" + // $ref: "#/responses/InternalError" r.Handle(VersionedPath("/libpod/pods/{name:..*}/restart"), APIHandler(s.Context, libpod.PodRestart)).Methods(http.MethodPost) // swagger:operation POST /libpod/pods/{nameOrID}/start pods startPod - // - // Start a pod - // // --- + // summary: Start a pod // produces: // - application/json // parameters: @@ -202,13 +189,11 @@ func (s *APIServer) registerPodsHandlers(r *mux.Router) error { // '404': // $ref: "#/responses/NoSuchPod" // '500': - // $ref: "#responses/InternalError" + // $ref: "#/responses/InternalError" r.Handle(VersionedPath("/libpod/pods/{name:..*}/start"), APIHandler(s.Context, libpod.PodStart)).Methods(http.MethodPost) // swagger:operation POST /libpod/pods/{nameOrID}/stop pods stopPod - // - // Stop a pod - // // --- + // summary: Stop a pod // produces: // - application/json // parameters: @@ -230,13 +215,11 @@ func (s *APIServer) registerPodsHandlers(r *mux.Router) error { // '404': // $ref: "#/responses/NoSuchPod" // '500': - // $ref: "#responses/InternalError" + // $ref: "#/responses/InternalError" r.Handle(VersionedPath("/libpod/pods/{name:..*}/stop"), APIHandler(s.Context, libpod.PodStop)).Methods(http.MethodPost) // swagger:operation POST /libpod/pods/{nameOrID}/unpause pods unpausePod - // - // Unpause a pod - // // --- + // summary: Unpause a pod // produces: // - application/json // parameters: @@ -250,7 +233,7 @@ func (s *APIServer) registerPodsHandlers(r *mux.Router) error { // '404': // $ref: "#/responses/NoSuchPod" // '500': - // $ref: "#responses/InternalError" + // $ref: "#/responses/InternalError" r.Handle(VersionedPath("/libpod/pods/{name:..*}/unpause"), APIHandler(s.Context, libpod.PodUnpause)).Methods(http.MethodPost) return nil } diff --git a/pkg/api/server/register_volumes.go b/pkg/api/server/register_volumes.go index 8fe5a67e4..34138cfbf 100644 --- a/pkg/api/server/register_volumes.go +++ b/pkg/api/server/register_volumes.go @@ -9,10 +9,8 @@ import ( func (s *APIServer) registerVolumeHandlers(r *mux.Router) error { // swagger:operation POST /libpod/volumes/create volumes createVolume - // - // Create a volume - // // --- + // summary: Create a volume // produces: // - application/json // responses: @@ -23,10 +21,8 @@ func (s *APIServer) registerVolumeHandlers(r *mux.Router) error { r.Handle("/libpod/volumes/create", APIHandler(s.Context, libpod.CreateVolume)).Methods(http.MethodPost) r.Handle("/libpod/volumes/json", APIHandler(s.Context, libpod.ListVolumes)).Methods(http.MethodGet) // swagger:operation POST /volumes/prune volumes pruneVolumes - // - // Prune volumes - // // --- + // summary: Prune volumes // produces: // - application/json // responses: @@ -36,10 +32,8 @@ func (s *APIServer) registerVolumeHandlers(r *mux.Router) error { // "$ref": "#/responses/InternalError" r.Handle("/libpod/volumes/prune", APIHandler(s.Context, libpod.PruneVolumes)).Methods(http.MethodPost) // swagger:operation GET /volumes/{nameOrID}/json volumes inspectVolume - // - // Inspect volume - // // --- + // summary: Inspect volume // parameters: // - in: path // name: nameOrID @@ -56,10 +50,8 @@ func (s *APIServer) registerVolumeHandlers(r *mux.Router) error { // "$ref": "#/responses/InternalError" r.Handle("/libpod/volumes/{name:..*}/json", APIHandler(s.Context, libpod.InspectVolume)).Methods(http.MethodGet) // swagger:operation DELETE /volumes/{nameOrID} volumes removeVolume - // - // Inspect volume - // // --- + // summary: Remove volume // parameters: // - in: path // name: nameOrID diff --git a/pkg/api/server/swagger.go b/pkg/api/server/swagger.go index 0eb57ebab..95129e637 100644 --- a/pkg/api/server/swagger.go +++ b/pkg/api/server/swagger.go @@ -131,3 +131,8 @@ type swagListContainers struct { //handlers.Container } } + +// To be determined +// swagger:response tbd +type swagTBD struct { +} diff --git a/pkg/apparmor/apparmor_linux_test.go b/pkg/apparmor/apparmor_linux_test.go index e94293d87..3ff6e18bc 100644 --- a/pkg/apparmor/apparmor_linux_test.go +++ b/pkg/apparmor/apparmor_linux_test.go @@ -134,7 +134,7 @@ func TestDefaultContent(t *testing.T) { if _, err := os.Stat(aapath); err != nil { t.Skip("AppArmor isn't available in this environment") } - if err := DefaultContent(profile); err != nil { + if _, err := DefaultContent(profile); err != nil { t.Fatalf("Couldn't retrieve default AppArmor profile content '%s': %v", profile, err) } } diff --git a/pkg/hooks/1.0.0/when_test.go b/pkg/hooks/1.0.0/when_test.go index a749063ff..94b0c3830 100644 --- a/pkg/hooks/1.0.0/when_test.go +++ b/pkg/hooks/1.0.0/when_test.go @@ -10,7 +10,8 @@ import ( func TestNoMatch(t *testing.T) { config := &rspec.Spec{} - for _, or := range []bool{true, false} { + for _, o := range []bool{true, false} { + or := o t.Run(fmt.Sprintf("or %t", or), func(t *testing.T) { when := When{Or: or} match, err := when.Match(config, map[string]string{}, false) @@ -27,9 +28,12 @@ func TestAlways(t *testing.T) { processStruct := &rspec.Process{ Args: []string{"/bin/sh", "a", "b"}, } - for _, always := range []bool{true, false} { - for _, or := range []bool{true, false} { - for _, process := range []*rspec.Process{processStruct, nil} { + for _, a := range []bool{true, false} { + always := a + for _, o := range []bool{true, false} { + or := o + for _, p := range []*rspec.Process{processStruct, nil} { + process := p t.Run(fmt.Sprintf("always %t, or %t, has process %t", always, or, process != nil), func(t *testing.T) { config.Process = process when := When{Always: &always, Or: or} @@ -48,7 +52,8 @@ func TestHasBindMountsAnd(t *testing.T) { hasBindMounts := true when := When{HasBindMounts: &hasBindMounts} config := &rspec.Spec{} - for _, containerHasBindMounts := range []bool{false, true} { + for _, b := range []bool{false, true} { + containerHasBindMounts := b t.Run(fmt.Sprintf("%t", containerHasBindMounts), func(t *testing.T) { match, err := when.Match(config, map[string]string{}, containerHasBindMounts) if err != nil { @@ -63,7 +68,8 @@ func TestHasBindMountsOr(t *testing.T) { hasBindMounts := true when := When{HasBindMounts: &hasBindMounts, Or: true} config := &rspec.Spec{} - for _, containerHasBindMounts := range []bool{false, true} { + for _, b := range []bool{false, true} { + containerHasBindMounts := b t.Run(fmt.Sprintf("%t", containerHasBindMounts), func(t *testing.T) { match, err := when.Match(config, map[string]string{}, containerHasBindMounts) if err != nil { @@ -82,7 +88,7 @@ func TestAnnotations(t *testing.T) { }, } config := &rspec.Spec{} - for _, test := range []struct { + for _, tt := range []struct { name string annotations map[string]string or bool @@ -131,6 +137,7 @@ func TestAnnotations(t *testing.T) { match: false, }, } { + test := tt t.Run(test.name, func(t *testing.T) { when.Or = test.or match, err := when.Match(config, test.annotations, false) @@ -149,7 +156,7 @@ func TestCommands(t *testing.T) { }, } config := &rspec.Spec{} - for _, test := range []struct { + for _, tt := range []struct { name string process *rspec.Process match bool @@ -173,6 +180,7 @@ func TestCommands(t *testing.T) { match: false, }, } { + test := tt t.Run(test.name, func(t *testing.T) { config.Process = test.process match, err := when.Match(config, map[string]string{}, false) @@ -209,7 +217,7 @@ func TestHasBindMountsAndCommands(t *testing.T) { }, } config := &rspec.Spec{Process: &rspec.Process{}} - for _, test := range []struct { + for _, tt := range []struct { name string command string hasBindMounts bool @@ -273,6 +281,7 @@ func TestHasBindMountsAndCommands(t *testing.T) { match: false, }, } { + test := tt t.Run(test.name, func(t *testing.T) { config.Process.Args = []string{test.command} when.Or = test.or @@ -287,7 +296,7 @@ func TestHasBindMountsAndCommands(t *testing.T) { func TestInvalidRegexp(t *testing.T) { config := &rspec.Spec{Process: &rspec.Process{Args: []string{"/bin/sh"}}} - for _, test := range []struct { + for _, tt := range []struct { name string when When expected string @@ -308,6 +317,7 @@ func TestInvalidRegexp(t *testing.T) { expected: "^command: error parsing regexp: .*", }, } { + test := tt t.Run(test.name, func(t *testing.T) { _, err := test.when.Match(config, map[string]string{"a": "b"}, false) if err == nil { diff --git a/pkg/hooks/exec/exec_test.go b/pkg/hooks/exec/exec_test.go index 7aac315cb..1e105373d 100644 --- a/pkg/hooks/exec/exec_test.go +++ b/pkg/hooks/exec/exec_test.go @@ -94,7 +94,7 @@ func TestRunEnvironment(t *testing.T) { Path: path, Args: []string{"sh", "-c", "env"}, } - for _, test := range []struct { + for _, tt := range []struct { name string env []string expected map[string]string @@ -120,6 +120,7 @@ func TestRunEnvironment(t *testing.T) { }, }, } { + test := tt t.Run(test.name, func(t *testing.T) { var stderr, stdout bytes.Buffer hook.Env = test.env @@ -147,7 +148,7 @@ func TestRunCancel(t *testing.T) { Args: []string{"sh", "-c", "echo waiting; sleep 2; echo done"}, } one := 1 - for _, test := range []struct { + for _, tt := range []struct { name string contextTimeout time.Duration hookTimeout *int @@ -174,6 +175,7 @@ func TestRunCancel(t *testing.T) { expectedRunError: context.DeadlineExceeded, }, } { + test := tt t.Run(test.name, func(t *testing.T) { ctx := context.Background() var stderr, stdout bytes.Buffer diff --git a/pkg/hooks/exec/runtimeconfigfilter_test.go b/pkg/hooks/exec/runtimeconfigfilter_test.go index 52d590d14..48dd2f998 100644 --- a/pkg/hooks/exec/runtimeconfigfilter_test.go +++ b/pkg/hooks/exec/runtimeconfigfilter_test.go @@ -25,9 +25,9 @@ func pointerFileMode(value os.FileMode) *os.FileMode { } func TestRuntimeConfigFilter(t *testing.T) { - unexpectedEndOfJSONInput := json.Unmarshal([]byte("{\n"), nil) + unexpectedEndOfJSONInput := json.Unmarshal([]byte("{\n"), nil) //nolint - for _, test := range []struct { + for _, tt := range []struct { name string contextTimeout time.Duration hooks []spec.Hook @@ -244,6 +244,7 @@ func TestRuntimeConfigFilter(t *testing.T) { expectedRunError: unexpectedEndOfJSONInput, }, } { + test := tt t.Run(test.name, func(t *testing.T) { ctx := context.Background() if test.contextTimeout > 0 { diff --git a/pkg/network/network_test.go b/pkg/network/network_test.go index dbffc33ad..1969e792c 100644 --- a/pkg/network/network_test.go +++ b/pkg/network/network_test.go @@ -25,9 +25,10 @@ func Test_networkIntersect(t *testing.T) { {"Two 24s", args{n1: parseCIDR("192.168.1.0/24"), n2: parseCIDR("192.168.2.0/24")}, false}, } for _, tt := range tests { + test := tt t.Run(tt.name, func(t *testing.T) { - if got := networkIntersect(tt.args.n1, tt.args.n2); got != tt.want { - t.Errorf("networkIntersect() = %v, want %v", got, tt.want) + if got := networkIntersect(test.args.n1, test.args.n2); got != test.want { + t.Errorf("networkIntersect() = %v, want %v", got, test.want) } }) } diff --git a/pkg/network/subnet_test.go b/pkg/network/subnet_test.go index 6ecfd2d17..917c3be88 100644 --- a/pkg/network/subnet_test.go +++ b/pkg/network/subnet_test.go @@ -20,14 +20,15 @@ func TestNextSubnet(t *testing.T) { {"class c", args{subnet: parseCIDR("192.168.1.0/24")}, parseCIDR("192.168.2.0/24"), false}, } for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - got, err := NextSubnet(tt.args.subnet) - if (err != nil) != tt.wantErr { - t.Errorf("NextSubnet() error = %v, wantErr %v", err, tt.wantErr) + test := tt + t.Run(test.name, func(t *testing.T) { + got, err := NextSubnet(test.args.subnet) + if (err != nil) != test.wantErr { + t.Errorf("NextSubnet() error = %v, wantErr %v", err, test.wantErr) return } - if !reflect.DeepEqual(got, tt.want) { - t.Errorf("NextSubnet() got = %v, want %v", got, tt.want) + if !reflect.DeepEqual(got, test.want) { + t.Errorf("NextSubnet() got = %v, want %v", got, test.want) } }) } diff --git a/pkg/spec/config_linux_cgo.go b/pkg/spec/config_linux_cgo.go index c47156456..ae83c9d52 100644 --- a/pkg/spec/config_linux_cgo.go +++ b/pkg/spec/config_linux_cgo.go @@ -8,13 +8,24 @@ import ( spec "github.com/opencontainers/runtime-spec/specs-go" "github.com/pkg/errors" seccomp "github.com/seccomp/containers-golang" + "github.com/sirupsen/logrus" ) func getSeccompConfig(config *SecurityConfig, configSpec *spec.Spec) (*spec.LinuxSeccomp, error) { var seccompConfig *spec.LinuxSeccomp var err error + if config.SeccompPolicy == SeccompPolicyImage && config.SeccompProfileFromImage != "" { + logrus.Debug("Loading seccomp profile from the security config") + seccompConfig, err = seccomp.LoadProfile(config.SeccompProfileFromImage, configSpec) + if err != nil { + return nil, errors.Wrap(err, "loading seccomp profile failed") + } + return seccompConfig, nil + } + if config.SeccompProfilePath != "" { + logrus.Debugf("Loading seccomp profile from %q", config.SeccompProfilePath) seccompProfile, err := ioutil.ReadFile(config.SeccompProfilePath) if err != nil { return nil, errors.Wrapf(err, "opening seccomp profile (%s) failed", config.SeccompProfilePath) @@ -24,6 +35,7 @@ func getSeccompConfig(config *SecurityConfig, configSpec *spec.Spec) (*spec.Linu return nil, errors.Wrapf(err, "loading seccomp profile (%s) failed", config.SeccompProfilePath) } } else { + logrus.Debug("Loading default seccomp profile") seccompConfig, err = seccomp.GetDefaultProfile(configSpec) if err != nil { return nil, errors.Wrapf(err, "loading seccomp profile (%s) failed", config.SeccompProfilePath) diff --git a/pkg/spec/createconfig.go b/pkg/spec/createconfig.go index 6d058229b..fb222083b 100644 --- a/pkg/spec/createconfig.go +++ b/pkg/spec/createconfig.go @@ -2,6 +2,7 @@ package createconfig import ( "os" + "sort" "strconv" "strings" "syscall" @@ -106,19 +107,63 @@ type NetworkConfig struct { PublishAll bool //publish-all } +// SeccompPolicy determines which seccomp profile gets applied to the container. +type SeccompPolicy int + +const ( + // SeccompPolicyDefault - if set use SecurityConfig.SeccompProfilePath, + // otherwise use the default profile. The SeccompProfilePath might be + // explicitly set by the user. + SeccompPolicyDefault SeccompPolicy = iota + // SeccompPolicyImage - if set use SecurityConfig.SeccompProfileFromImage, + // otherwise follow SeccompPolicyDefault. + SeccompPolicyImage +) + +// Map for easy lookups of supported policies. +var supportedSeccompPolicies = map[string]SeccompPolicy{ + "": SeccompPolicyDefault, + "default": SeccompPolicyDefault, + "image": SeccompPolicyImage, +} + +// LookupSeccompPolicy looksup the corresponding SeccompPolicy for the specified +// string. If none is found, an errors is returned including the list of +// supported policies. +// Note that an empty string resolved to SeccompPolicyDefault. +func LookupSeccompPolicy(s string) (SeccompPolicy, error) { + policy, exists := supportedSeccompPolicies[s] + if exists { + return policy, nil + } + + // Sort the keys first as maps are non-deterministic. + keys := []string{} + for k := range supportedSeccompPolicies { + if k != "" { + keys = append(keys, k) + } + } + sort.Strings(keys) + + return -1, errors.Errorf("invalid seccomp policy %q: valid policies are %+q", s, keys) +} + // SecurityConfig configures the security features for the container type SecurityConfig struct { - CapAdd []string // cap-add - CapDrop []string // cap-drop - LabelOpts []string //SecurityOpts - NoNewPrivs bool //SecurityOpts - ApparmorProfile string //SecurityOpts - SeccompProfilePath string //SecurityOpts - SecurityOpts []string - Privileged bool //privileged - ReadOnlyRootfs bool //read-only - ReadOnlyTmpfs bool //read-only-tmpfs - Sysctl map[string]string //sysctl + CapAdd []string // cap-add + CapDrop []string // cap-drop + LabelOpts []string //SecurityOpts + NoNewPrivs bool //SecurityOpts + ApparmorProfile string //SecurityOpts + SeccompProfilePath string //SecurityOpts + SeccompProfileFromImage string // seccomp profile from the container image + SeccompPolicy SeccompPolicy + SecurityOpts []string + Privileged bool //privileged + ReadOnlyRootfs bool //read-only + ReadOnlyTmpfs bool //read-only-tmpfs + Sysctl map[string]string //sysctl } // CreateConfig is a pre OCI spec structure. It represents user input from varlink or the CLI diff --git a/pkg/systemdgen/systemdgen_test.go b/pkg/systemdgen/systemdgen_test.go index e1da7e8e0..3894a0205 100644 --- a/pkg/systemdgen/systemdgen_test.go +++ b/pkg/systemdgen/systemdgen_test.go @@ -24,9 +24,10 @@ func TestValidateRestartPolicy(t *testing.T) { {"failblank", ContainerInfo{restart: ""}, true}, } for _, tt := range tests { + test := tt t.Run(tt.name, func(t *testing.T) { - if err := validateRestartPolicy(tt.ContainerInfo.restart); (err != nil) != tt.wantErr { - t.Errorf("ValidateRestartPolicy() error = %v, wantErr %v", err, tt.wantErr) + if err := validateRestartPolicy(test.ContainerInfo.restart); (err != nil) != test.wantErr { + t.Errorf("ValidateRestartPolicy() error = %v, wantErr %v", err, test.wantErr) } }) } @@ -221,18 +222,19 @@ WantedBy=multi-user.target` }, } for _, tt := range tests { + test := tt t.Run(tt.name, func(t *testing.T) { opts := Options{ Files: false, - New: tt.info.New, + New: test.info.New, } - got, err := CreateContainerSystemdUnit(&tt.info, opts) - if (err != nil) != tt.wantErr { - t.Errorf("CreateContainerSystemdUnit() error = \n%v, wantErr \n%v", err, tt.wantErr) + got, err := CreateContainerSystemdUnit(&test.info, opts) + if (err != nil) != test.wantErr { + t.Errorf("CreateContainerSystemdUnit() error = \n%v, wantErr \n%v", err, test.wantErr) return } - if got != tt.want { - t.Errorf("CreateContainerSystemdUnit() = \n%v\n---------> want\n%v", got, tt.want) + if got != test.want { + t.Errorf("CreateContainerSystemdUnit() = \n%v\n---------> want\n%v", got, test.want) } }) } diff --git a/pkg/tracing/tracing.go b/pkg/tracing/tracing.go index d028ddf8f..5be24faaa 100644 --- a/pkg/tracing/tracing.go +++ b/pkg/tracing/tracing.go @@ -12,6 +12,7 @@ import ( // Init returns an instance of Jaeger Tracer that samples 100% of traces and logs all spans to stdout. func Init(service string) (opentracing.Tracer, io.Closer) { cfg := &config.Configuration{ + ServiceName: service, Sampler: &config.SamplerConfig{ Type: "const", Param: 1, @@ -20,7 +21,7 @@ func Init(service string) (opentracing.Tracer, io.Closer) { LogSpans: true, }, } - tracer, closer, err := cfg.New(service, config.Logger(jaeger.StdLogger)) + tracer, closer, err := cfg.NewTracer(config.Logger(jaeger.StdLogger)) if err != nil { panic(fmt.Sprintf("ERROR: cannot init Jaeger: %v\n", err)) } |