APIv2 review corrections #3

The third pass of corrections for the APIv2.

Signed-off-by: Brent Baude <bbaude@redhat.com>
This commit is contained in:
Brent Baude
2020-01-24 08:59:20 -06:00
parent 81e59a742b
commit 5da70b04dd
20 changed files with 300 additions and 217 deletions

View File

@ -10,14 +10,8 @@ import (
"github.com/pkg/errors"
)
const (
PodStateStopped = "Stopped"
PodStateRunning = "Running"
PodStatePaused = "Paused"
PodStateExited = "Exited"
PodStateErrored = "Error"
PodStateCreated = "Created"
)
// TODO GetPodStatus and CreatePodStatusResults should removed once the adapter
// and shared packages are reworked. It has now been duplicated in libpod proper.
// GetPodStatus determines the status of the pod based on the
// statuses of the containers in the pod.
@ -25,7 +19,7 @@ const (
func GetPodStatus(pod *libpod.Pod) (string, error) {
ctrStatuses, err := pod.Status()
if err != nil {
return PodStateErrored, err
return define.PodStateErrored, err
}
return CreatePodStatusResults(ctrStatuses)
}
@ -33,45 +27,45 @@ func GetPodStatus(pod *libpod.Pod) (string, error) {
func CreatePodStatusResults(ctrStatuses map[string]define.ContainerStatus) (string, error) {
ctrNum := len(ctrStatuses)
if ctrNum == 0 {
return PodStateCreated, nil
return define.PodStateCreated, nil
}
statuses := map[string]int{
PodStateStopped: 0,
PodStateRunning: 0,
PodStatePaused: 0,
PodStateCreated: 0,
PodStateErrored: 0,
define.PodStateStopped: 0,
define.PodStateRunning: 0,
define.PodStatePaused: 0,
define.PodStateCreated: 0,
define.PodStateErrored: 0,
}
for _, ctrStatus := range ctrStatuses {
switch ctrStatus {
case define.ContainerStateExited:
fallthrough
case define.ContainerStateStopped:
statuses[PodStateStopped]++
statuses[define.PodStateStopped]++
case define.ContainerStateRunning:
statuses[PodStateRunning]++
statuses[define.PodStateRunning]++
case define.ContainerStatePaused:
statuses[PodStatePaused]++
statuses[define.PodStatePaused]++
case define.ContainerStateCreated, define.ContainerStateConfigured:
statuses[PodStateCreated]++
statuses[define.PodStateCreated]++
default:
statuses[PodStateErrored]++
statuses[define.PodStateErrored]++
}
}
switch {
case statuses[PodStateRunning] > 0:
return PodStateRunning, nil
case statuses[PodStatePaused] == ctrNum:
return PodStatePaused, nil
case statuses[PodStateStopped] == ctrNum:
return PodStateExited, nil
case statuses[PodStateStopped] > 0:
return PodStateStopped, nil
case statuses[PodStateErrored] > 0:
return PodStateErrored, nil
case statuses[define.PodStateRunning] > 0:
return define.PodStateRunning, nil
case statuses[define.PodStatePaused] == ctrNum:
return define.PodStatePaused, nil
case statuses[define.PodStateStopped] == ctrNum:
return define.PodStateExited, nil
case statuses[define.PodStateStopped] > 0:
return define.PodStateStopped, nil
case statuses[define.PodStateErrored] > 0:
return define.PodStateErrored, nil
default:
return PodStateCreated, nil
return define.PodStateCreated, nil
}
}

19
libpod/define/podstate.go Normal file
View File

@ -0,0 +1,19 @@
package define
const (
// PodStateCreated indicates the pod is created but has not been started
PodStateCreated = "Created"
// PodStateErrored indicates the pod is in an errored state where
// information about it can no longer be retrieved
PodStateErrored = "Error"
// PodStateExited indicates the pod ran but has been stopped
PodStateExited = "Exited"
// PodStatePaused indicates the pod has been paused
PodStatePaused = "Paused"
// PodStateRunning indicates that one or more of the containers in
// the pod is running
PodStateRunning = "Running"
// PodStateStopped indicates all of the containers belonging to the pod
// are stopped.
PodStateStopped = "Stopped"
)

59
libpod/pod_status.go Normal file
View File

@ -0,0 +1,59 @@
package libpod
import "github.com/containers/libpod/libpod/define"
// GetPodStatus determines the status of the pod based on the
// statuses of the containers in the pod.
// Returns a string representation of the pod status
func (p *Pod) GetPodStatus() (string, error) {
ctrStatuses, err := p.Status()
if err != nil {
return define.PodStateErrored, err
}
return CreatePodStatusResults(ctrStatuses)
}
func CreatePodStatusResults(ctrStatuses map[string]define.ContainerStatus) (string, error) {
ctrNum := len(ctrStatuses)
if ctrNum == 0 {
return define.PodStateCreated, nil
}
statuses := map[string]int{
define.PodStateStopped: 0,
define.PodStateRunning: 0,
define.PodStatePaused: 0,
define.PodStateCreated: 0,
define.PodStateErrored: 0,
}
for _, ctrStatus := range ctrStatuses {
switch ctrStatus {
case define.ContainerStateExited:
fallthrough
case define.ContainerStateStopped:
statuses[define.PodStateStopped]++
case define.ContainerStateRunning:
statuses[define.PodStateRunning]++
case define.ContainerStatePaused:
statuses[define.PodStatePaused]++
case define.ContainerStateCreated, define.ContainerStateConfigured:
statuses[define.PodStateCreated]++
default:
statuses[define.PodStateErrored]++
}
}
switch {
case statuses[define.PodStateRunning] > 0:
return define.PodStateRunning, nil
case statuses[define.PodStatePaused] == ctrNum:
return define.PodStatePaused, nil
case statuses[define.PodStateStopped] == ctrNum:
return define.PodStateExited, nil
case statuses[define.PodStateStopped] > 0:
return define.PodStateStopped, nil
case statuses[define.PodStateErrored] > 0:
return define.PodStateErrored, nil
default:
return define.PodStateCreated, nil
}
}

View File

@ -182,3 +182,31 @@ func (r *Runtime) GetRunningPods() ([]*Pod, error) {
}
return runningPods, nil
}
// PrunePods removes unused pods and their containers from local storage.
// If force is given, then running pods are also included in the pruning.
func (r *Runtime) PrunePods() (map[string]error, error) {
response := make(map[string]error)
states := []string{define.PodStateStopped, define.PodStateExited}
filterFunc := func(p *Pod) bool {
state, _ := p.GetPodStatus()
for _, status := range states {
if state == status {
return true
}
}
return false
}
pods, err := r.Pods(filterFunc)
if err != nil {
return nil, err
}
if len(pods) < 1 {
return response, nil
}
for _, pod := range pods {
err := r.removePod(context.TODO(), pod, true, false)
response[pod.ID()] = err
}
return response, nil
}

View File

@ -58,9 +58,9 @@ func (r *LocalRuntime) PrunePods(ctx context.Context, cli *cliconfig.PodPruneVal
}
logrus.Debugf("Setting maximum rm workers to %d", maxWorkers)
states := []string{shared.PodStateStopped, shared.PodStateExited}
states := []string{define.PodStateStopped, define.PodStateExited}
if cli.Force {
states = append(states, shared.PodStateRunning)
states = append(states, define.PodStateRunning)
}
pods, err := r.GetPodsByStatus(states)

View File

@ -540,9 +540,9 @@ func (r *LocalRuntime) PrunePods(ctx context.Context, cli *cliconfig.PodPruneVal
ok = []string{}
failures = map[string]error{}
)
states := []string{shared.PodStateStopped, shared.PodStateExited}
states := []string{define.PodStateStopped, define.PodStateExited}
if cli.Force {
states = append(states, shared.PodStateRunning)
states = append(states, define.PodStateRunning)
}
ids, err := iopodman.GetPodsByStatus().Call(r.Conn, states)

View File

@ -1,4 +1,4 @@
package generic
package handlers
import (
"encoding/json"
@ -10,7 +10,6 @@ import (
"github.com/containers/libpod/libpod"
"github.com/containers/libpod/libpod/define"
image2 "github.com/containers/libpod/libpod/image"
"github.com/containers/libpod/pkg/api/handlers"
"github.com/containers/libpod/pkg/api/handlers/utils"
"github.com/containers/libpod/pkg/namespaces"
createconfig "github.com/containers/libpod/pkg/spec"
@ -25,7 +24,7 @@ import (
func CreateContainer(w http.ResponseWriter, r *http.Request) {
runtime := r.Context().Value("runtime").(*libpod.Runtime)
decoder := r.Context().Value("decoder").(*schema.Decoder)
input := handlers.CreateContainerConfig{}
input := CreateContainerConfig{}
query := struct {
Name string `schema:"name"`
}{
@ -74,13 +73,13 @@ func CreateContainer(w http.ResponseWriter, r *http.Request) {
}
response := ContainerCreateResponse{
Id: ctr.ID(),
ID: ctr.ID(),
Warnings: []string{}}
utils.WriteResponse(w, http.StatusCreated, response)
}
func makeCreateConfig(input handlers.CreateContainerConfig, newImage *image2.Image) (createconfig.CreateConfig, error) {
func makeCreateConfig(input CreateContainerConfig, newImage *image2.Image) (createconfig.CreateConfig, error) {
var (
err error
init bool

View File

@ -1,9 +0,0 @@
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"`
}

View File

@ -6,7 +6,6 @@ import (
"io/ioutil"
"net/http"
"os"
"strconv"
"strings"
"github.com/containers/buildah"
@ -16,12 +15,10 @@ import (
"github.com/containers/libpod/pkg/api/handlers"
"github.com/containers/libpod/pkg/api/handlers/utils"
"github.com/containers/libpod/pkg/util"
"github.com/containers/storage"
"github.com/docker/docker/api/types"
"github.com/gorilla/mux"
"github.com/gorilla/schema"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
)
func ExportImage(w http.ResponseWriter, r *http.Request) {
@ -59,11 +56,8 @@ func ExportImage(w http.ResponseWriter, r *http.Request) {
}
func PruneImages(w http.ResponseWriter, r *http.Request) {
// 200 no error
// 500 internal
var (
dangling = true
err error
filters []string
)
decoder := r.Context().Value("decoder").(*schema.Decoder)
runtime := r.Context().Value("runtime").(*libpod.Runtime)
@ -79,60 +73,24 @@ func PruneImages(w http.ResponseWriter, r *http.Request) {
return
}
// until ts is not supported on podman prune
if v, found := query.Filters["until"]; found {
utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrapf(err, "until=%s is not supported yet", v))
return
}
// labels are not supported on podman prune
if _, found := query.Filters["since"]; found {
utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "labelis not supported yet"))
return
}
if v, found := query.Filters["dangling"]; found {
dangling, err = strconv.ParseBool(v[0])
if err != nil {
utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "processing dangling filter"))
return
}
}
idr := []types.ImageDeleteResponseItem{}
//
// This code needs to be migrated to libpod to work correctly. I could not
// work my around the information docker needs with the existing prune in libpod.
//
pruneImages, err := runtime.ImageRuntime().GetPruneImages(!dangling, []image2.ImageFilter{})
for k, v := range query.Filters {
for _, val := range v {
filters = append(filters, fmt.Sprintf("%s=%s", k, val))
}
}
pruneCids, err := runtime.ImageRuntime().PruneImages(r.Context(), false, filters)
if err != nil {
utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "unable to get images to prune"))
utils.InternalServerError(w, err)
return
}
for _, p := range pruneImages {
repotags, err := p.RepoTags()
if err != nil {
utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "unable to get repotags for image"))
return
}
if err := p.Remove(r.Context(), true); err != nil {
if errors.Cause(err) == storage.ErrImageUsedByContainer {
logrus.Warnf("Failed to prune image %s as it is in use: %v", p.ID(), err)
continue
}
utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "failed to prune image"))
return
}
// newimageevent is not export therefore we cannot record the event. this will be fixed
// when the prune is fixed in libpod
// defer p.newImageEvent(events.Prune)
response := types.ImageDeleteResponseItem{
Deleted: fmt.Sprintf("sha256:%s", p.ID()), // I ack this is not ideal
}
if len(repotags) > 0 {
response.Untagged = repotags[0]
}
idr = append(idr, response)
for _, p := range pruneCids {
idr = append(idr, types.ImageDeleteResponseItem{
Deleted: p,
})
}
//FIXME/TODO to do this exacty correct, pruneimages needs to return idrs and space-reclaimed, then we are golden
ipr := types.ImagesPruneReport{
ImagesDeleted: idr,
SpaceReclaimed: 1, // TODO we cannot supply this right now
@ -342,8 +300,6 @@ func GetImage(w http.ResponseWriter, r *http.Request) {
}
func GetImages(w http.ResponseWriter, r *http.Request) {
// 200 ok
// 500 internal
images, err := utils.GetImages(w, r)
if err != nil {
utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "Failed get images"))

View File

@ -1,11 +1,13 @@
package generic
import "github.com/containers/libpod/pkg/api/handlers"
// Create container
// swagger:response ContainerCreateResponse
type swagCtrCreateResponse struct {
// in:body
Body struct {
ContainerCreateResponse
handlers.ContainerCreateResponse
}
}

View File

@ -3,7 +3,6 @@ package handlers
import (
"fmt"
"io"
"io/ioutil"
"net/http"
"os"
"strconv"
@ -127,46 +126,6 @@ func GetImage(r *http.Request, name string) (*image.Image, error) {
return runtime.ImageRuntime().NewFromLocal(name)
}
func LoadImage(w http.ResponseWriter, r *http.Request) {
decoder := r.Context().Value("decoder").(*schema.Decoder)
runtime := r.Context().Value("runtime").(*libpod.Runtime)
query := struct {
//quiet bool # quiet is currently unused
}{
// This is where you can override the golang default value for one of fields
}
if err := decoder.Decode(&query, r.URL.Query()); err != nil {
utils.Error(w, "Something went wrong.", http.StatusBadRequest, errors.Wrapf(err, "Failed to parse parameters for %s", r.URL.String()))
return
}
var (
err error
writer io.Writer
)
f, err := ioutil.TempFile("", "api_load.tar")
if err != nil {
utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "failed to create tempfile"))
return
}
if err := SaveFromBody(f, r); err != nil {
utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "failed to write temporary file"))
return
}
id, err := runtime.LoadImage(r.Context(), "", f.Name(), writer, "")
if err != nil {
utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "failed to load image"))
return
}
utils.WriteResponse(w, http.StatusOK, struct {
Stream string `json:"stream"`
}{
Stream: fmt.Sprintf("Loaded image: %s\n", id),
})
}
func SaveFromBody(f *os.File, r *http.Request) error { // nolint
if _, err := io.Copy(f, r.Body); err != nil {
return err

View File

@ -19,8 +19,6 @@ func StopContainer(w http.ResponseWriter, r *http.Request) {
}
func ContainerExists(w http.ResponseWriter, r *http.Request) {
// 404 no such container
// 200 ok
runtime := r.Context().Value("runtime").(*libpod.Runtime)
name := mux.Vars(r)["name"]
_, err := runtime.LookupContainer(name)
@ -147,10 +145,6 @@ func LogsFromContainer(w http.ResponseWriter, r *http.Request) {
// tail string
}
func CreateContainer(w http.ResponseWriter, r *http.Request) {
}
func UnmountContainer(w http.ResponseWriter, r *http.Request) {
runtime := r.Context().Value("runtime").(*libpod.Runtime)
name := mux.Vars(r)["name"]

View File

@ -2,9 +2,11 @@ package libpod
import (
"fmt"
"io"
"io/ioutil"
"net/http"
"os"
"strconv"
"github.com/containers/libpod/libpod"
"github.com/containers/libpod/pkg/api/handlers"
@ -91,12 +93,13 @@ func GetImages(w http.ResponseWriter, r *http.Request) {
}
func PruneImages(w http.ResponseWriter, r *http.Request) {
// 200 ok
// 500 internal
var (
all bool
err error
)
runtime := r.Context().Value("runtime").(*libpod.Runtime)
decoder := r.Context().Value("decoder").(*schema.Decoder)
query := struct {
All bool `schema:"all"`
Filters map[string][]string `schema:"filters"`
}{
// override any golang type defaults
@ -110,11 +113,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
}
for k, v := range query.Filters {
libpodFilters = append(libpodFilters, fmt.Sprintf("%s=%s", k, v[0]))
}
}
cids, err := runtime.ImageRuntime().PruneImages(r.Context(), query.All, libpodFilters)
cids, err := runtime.ImageRuntime().PruneImages(r.Context(), all, libpodFilters)
if err != nil {
utils.Error(w, "Something went wrong.", http.StatusInternalServerError, err)
return
@ -171,3 +179,47 @@ func ExportImage(w http.ResponseWriter, r *http.Request) {
defer os.Remove(tmpfile.Name())
utils.WriteResponse(w, http.StatusOK, rdr)
}
func ImportImage(w http.ResponseWriter, r *http.Request) {
// TODO this is basically wrong
decoder := r.Context().Value("decoder").(*schema.Decoder)
runtime := r.Context().Value("runtime").(*libpod.Runtime)
query := struct {
Changes map[string]string `json:"changes"`
Message string `json:"message"`
Quiet bool `json:"quiet"`
}{
// This is where you can override the golang default value for one of fields
}
if err := decoder.Decode(&query, r.URL.Query()); err != nil {
utils.Error(w, "Something went wrong.", http.StatusBadRequest, errors.Wrapf(err, "Failed to parse parameters for %s", r.URL.String()))
return
}
var (
err error
writer io.Writer
)
f, err := ioutil.TempFile("", "api_load.tar")
if err != nil {
utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "failed to create tempfile"))
return
}
if err := handlers.SaveFromBody(f, r); err != nil {
utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "failed to write temporary file"))
return
}
id, err := runtime.LoadImage(r.Context(), "", f.Name(), writer, "")
//id, err := runtime.Import(r.Context())
if err != nil {
utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "failed to load image"))
return
}
utils.WriteResponse(w, http.StatusOK, struct {
Stream string `json:"stream"`
}{
Stream: fmt.Sprintf("Loaded image: %s\n", id),
})
}

View File

@ -268,7 +268,7 @@ func PodDelete(w http.ResponseWriter, r *http.Request) {
decoder = r.Context().Value("decoder").(*schema.Decoder)
)
query := struct {
force bool `schema:"force"`
Force bool `schema:"force"`
}{
// override any golang type defaults
}
@ -284,7 +284,7 @@ func PodDelete(w http.ResponseWriter, r *http.Request) {
utils.PodNotFound(w, name, err)
return
}
if err := runtime.RemovePod(r.Context(), pod, true, query.force); err != nil {
if err := runtime.RemovePod(r.Context(), pod, true, query.Force); err != nil {
utils.Error(w, "Something went wrong", http.StatusInternalServerError, err)
return
}
@ -309,43 +309,14 @@ func PodRestart(w http.ResponseWriter, r *http.Request) {
func PodPrune(w http.ResponseWriter, r *http.Request) {
var (
err error
pods []*libpod.Pod
runtime = r.Context().Value("runtime").(*libpod.Runtime)
decoder = r.Context().Value("decoder").(*schema.Decoder)
)
query := struct {
force bool `schema:"force"`
}{
// override any golang type defaults
}
if err := decoder.Decode(&query, r.URL.Query()); err != nil {
utils.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest,
errors.Wrapf(err, "Failed to parse parameters for %s", r.URL.String()))
pruned, err := runtime.PrunePods()
if err != nil {
utils.InternalServerError(w, err)
return
}
if query.force {
pods, err = runtime.GetAllPods()
if err != nil {
utils.Error(w, "Something went wrong", http.StatusInternalServerError, err)
return
}
} else {
// TODO We need to make a libpod.PruneVolumes or this code will be a mess. Volumes
// already does this right. It will also help clean this code path up with less
// conditionals. We do this when we integrate with libpod again.
utils.Error(w, "not implemented", http.StatusInternalServerError, errors.New("not implemented"))
return
}
for _, p := range pods {
if err := runtime.RemovePod(r.Context(), p, true, query.force); err != nil {
utils.Error(w, "Something went wrong", http.StatusInternalServerError, err)
return
}
}
utils.WriteResponse(w, http.StatusNoContent, "")
utils.WriteResponse(w, http.StatusOK, pruned)
}
func PodPause(w http.ResponseWriter, r *http.Request) {

View File

@ -537,3 +537,11 @@ func portsToPortSet(input map[string]struct{}) (nat.PortSet, error) {
}
return ports, nil
}
// 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"`
}

View File

@ -6,6 +6,7 @@ import (
"github.com/containers/libpod/libpod"
"github.com/containers/libpod/libpod/image"
"github.com/gorilla/mux"
"github.com/gorilla/schema"
)
@ -15,17 +16,22 @@ func GetImages(w http.ResponseWriter, r *http.Request) ([]*image.Image, error) {
decoder := r.Context().Value("decoder").(*schema.Decoder)
runtime := r.Context().Value("runtime").(*libpod.Runtime)
query := struct {
// all bool # all is currently unused
All bool
Filters map[string][]string `schema:"filters"`
// digests bool # digests is currently unused
Digests bool
}{
// 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
}
var filters = []string{}
if _, found := mux.Vars(r)["digests"]; found && query.Digests {
UnSupportedParameter("digests")
}
if _, found := r.URL.Query()["filters"]; found {
filters = append(filters, fmt.Sprintf("reference=%s", ""))
}

View File

@ -12,7 +12,8 @@
// Version: 0.0.1
// License: Apache-2.0 https://opensource.org/licenses/Apache-2.0
// Contact: Podman <podman@lists.podman.io> https://podman.io/community/
// Extensions:
//
// InfoExtensions:
// x-logo:
// - url: https://raw.githubusercontent.com/containers/libpod/master/logo/podman-logo.png
// - altText: "Podman logo"

View File

@ -33,7 +33,7 @@ func (s *APIServer) RegisterContainersHandlers(r *mux.Router) error {
// $ref: "#/responses/ConflictError"
// 500:
// $ref: "#/responses/InternalError"
r.HandleFunc(VersionedPath("/containers/create"), APIHandler(s.Context, generic.CreateContainer)).Methods(http.MethodPost)
r.HandleFunc(VersionedPath("/containers/create"), APIHandler(s.Context, handlers.CreateContainer)).Methods(http.MethodPost)
// swagger:operation GET /containers/json compat listContainers
// ---
// tags:
@ -550,7 +550,7 @@ func (s *APIServer) RegisterContainersHandlers(r *mux.Router) error {
libpod endpoints
*/
r.HandleFunc(VersionedPath("/libpod/containers/create"), APIHandler(s.Context, libpod.CreateContainer)).Methods(http.MethodPost)
r.HandleFunc(VersionedPath("/libpod/containers/create"), APIHandler(s.Context, handlers.CreateContainer)).Methods(http.MethodPost)
// swagger:operation GET /libpod/containers/json libpod libpodListContainers
// ---
// tags:

View File

@ -55,6 +55,27 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error {
// - images (compat)
// 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.
// parameters:
// - name: all
// in: query
// description: "Show all images. Only images from a final layer (no children) are shown by default."
// type: boolean
// default: false
// - name: filters
// in: query
// description: |
// A JSON encoded value of the filters (a `map[string][]string`) to process on the images list. Available filters:
// - `before`=(`<image-name>[:<tag>]`, `<image id>` or `<image@digest>`)
// - `dangling=true`
// - `label=key` or `label="key=value"` of an image label
// - `reference`=(`<image-name>[:<tag>]`)
// - `since`=(`<image-name>[:<tag>]`, `<image id>` or `<image@digest>`)
// type: string
// - name: digests
// in: query
// description: Not supported
// type: boolean
// default: false
// produces:
// - application/json
// responses:
@ -63,7 +84,7 @@ 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 compat loadImage
// swagger:operation POST /images/load compat importImage
// ---
// tags:
// - images (compat)
@ -86,7 +107,7 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error {
// description: no error
// 500:
// $ref: '#/responses/InternalError'
r.Handle(VersionedPath("/images/load"), APIHandler(s.Context, handlers.LoadImage)).Methods(http.MethodPost)
r.Handle(VersionedPath("/images/load"), APIHandler(s.Context, libpod.ImportImage)).Methods(http.MethodPost)
// swagger:operation POST /images/prune compat pruneImages
// ---
// tags:
@ -585,6 +606,27 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error {
// - images
// summary: List Images
// description: Returns a list of images on the server
// parameters:
// - name: "all"
// in: "query"
// description: "Show all images. Only images from a final layer (no children) are shown by default."
// type: "boolean"
// default: false
// - name: "filters"
// in: "query"
// description: |
// A JSON encoded value of the filters (a `map[string][]string`) to process on the images list. Available filters:
// - `before`=(`<image-name>[:<tag>]`, `<image id>` or `<image@digest>`)
// - `dangling=true`
// - `label=key` or `label="key=value"` of an image label
// - `reference`=(`<image-name>[:<tag>]`)
// - `since`=(`<image-name>[:<tag>]`, `<image id>` or `<image@digest>`)
// type: "string"
// - name: "digests"
// in: "query"
// description: Not supported
// type: "boolean"
// default: false
// produces:
// - application/json
// responses:
@ -593,7 +635,7 @@ 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 libpod libpodLoadImage
// swagger:operation POST /libpod/images/load libpod libpodImportImage
// ---
// tags:
// - images
@ -604,6 +646,14 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error {
// name: quiet
// type: boolean
// description: not supported
// - in: query
// name: change
// description: "Apply the following possible instructions to the created image (default []): CMD | ENTRYPOINT | ENV | EXPOSE | LABEL | STOPSIGNAL | USER | VOLUME | WORKDIR. JSON encoded string"
// type: string
// - in: query
// name: message
// description: Set commit message for imported image
// type: string
// - in: body
// name: request
// description: tarball of container image
@ -617,7 +667,7 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error {
// description: no error
// 500:
// $ref: '#/responses/InternalError'
r.Handle(VersionedPath("/libpod/images/load"), APIHandler(s.Context, handlers.LoadImage)).Methods(http.MethodPost)
r.Handle(VersionedPath("/libpod/images/load"), APIHandler(s.Context, libpod.ImportImage)).Methods(http.MethodPost)
// swagger:operation POST /libpod/images/prune libpod libpodPruneImages
// ---
// tags:
@ -635,10 +685,6 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error {
// (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 machines 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: boolean
// description: prune all images
// produces:
// - application/json
// responses:

View File

@ -30,17 +30,15 @@ func (s *APIServer) registerPodsHandlers(r *mux.Router) error {
// swagger:operation POST /libpod/pods/prune pods PrunePods
// ---
// summary: Prune unused pods
// parameters:
// - in: query
// name: force
// description: force delete
// type: boolean
// default: false
// produces:
// - application/json
// responses:
// 204:
// description: no error
// 200:
// description: tbd
// schema:
// type: object
// additionalProperties:
// type: string
// 400:
// $ref: "#/responses/BadParamError"
// 500:
@ -60,7 +58,7 @@ func (s *APIServer) registerPodsHandlers(r *mux.Router) error {
// - in: query
// name: force
// type: boolean
// description: force delete
// description : force removal of a running pod by first stopping all containers, then removing all containers in the pod
// responses:
// 204:
// description: no error