mirror of
https://github.com/containers/podman.git
synced 2025-05-21 09:05:56 +08:00
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:
@ -10,14 +10,8 @@ import (
|
|||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
// TODO GetPodStatus and CreatePodStatusResults should removed once the adapter
|
||||||
PodStateStopped = "Stopped"
|
// and shared packages are reworked. It has now been duplicated in libpod proper.
|
||||||
PodStateRunning = "Running"
|
|
||||||
PodStatePaused = "Paused"
|
|
||||||
PodStateExited = "Exited"
|
|
||||||
PodStateErrored = "Error"
|
|
||||||
PodStateCreated = "Created"
|
|
||||||
)
|
|
||||||
|
|
||||||
// GetPodStatus determines the status of the pod based on the
|
// GetPodStatus determines the status of the pod based on the
|
||||||
// statuses of the containers in the pod.
|
// statuses of the containers in the pod.
|
||||||
@ -25,7 +19,7 @@ const (
|
|||||||
func GetPodStatus(pod *libpod.Pod) (string, error) {
|
func GetPodStatus(pod *libpod.Pod) (string, error) {
|
||||||
ctrStatuses, err := pod.Status()
|
ctrStatuses, err := pod.Status()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return PodStateErrored, err
|
return define.PodStateErrored, err
|
||||||
}
|
}
|
||||||
return CreatePodStatusResults(ctrStatuses)
|
return CreatePodStatusResults(ctrStatuses)
|
||||||
}
|
}
|
||||||
@ -33,45 +27,45 @@ func GetPodStatus(pod *libpod.Pod) (string, error) {
|
|||||||
func CreatePodStatusResults(ctrStatuses map[string]define.ContainerStatus) (string, error) {
|
func CreatePodStatusResults(ctrStatuses map[string]define.ContainerStatus) (string, error) {
|
||||||
ctrNum := len(ctrStatuses)
|
ctrNum := len(ctrStatuses)
|
||||||
if ctrNum == 0 {
|
if ctrNum == 0 {
|
||||||
return PodStateCreated, nil
|
return define.PodStateCreated, nil
|
||||||
}
|
}
|
||||||
statuses := map[string]int{
|
statuses := map[string]int{
|
||||||
PodStateStopped: 0,
|
define.PodStateStopped: 0,
|
||||||
PodStateRunning: 0,
|
define.PodStateRunning: 0,
|
||||||
PodStatePaused: 0,
|
define.PodStatePaused: 0,
|
||||||
PodStateCreated: 0,
|
define.PodStateCreated: 0,
|
||||||
PodStateErrored: 0,
|
define.PodStateErrored: 0,
|
||||||
}
|
}
|
||||||
for _, ctrStatus := range ctrStatuses {
|
for _, ctrStatus := range ctrStatuses {
|
||||||
switch ctrStatus {
|
switch ctrStatus {
|
||||||
case define.ContainerStateExited:
|
case define.ContainerStateExited:
|
||||||
fallthrough
|
fallthrough
|
||||||
case define.ContainerStateStopped:
|
case define.ContainerStateStopped:
|
||||||
statuses[PodStateStopped]++
|
statuses[define.PodStateStopped]++
|
||||||
case define.ContainerStateRunning:
|
case define.ContainerStateRunning:
|
||||||
statuses[PodStateRunning]++
|
statuses[define.PodStateRunning]++
|
||||||
case define.ContainerStatePaused:
|
case define.ContainerStatePaused:
|
||||||
statuses[PodStatePaused]++
|
statuses[define.PodStatePaused]++
|
||||||
case define.ContainerStateCreated, define.ContainerStateConfigured:
|
case define.ContainerStateCreated, define.ContainerStateConfigured:
|
||||||
statuses[PodStateCreated]++
|
statuses[define.PodStateCreated]++
|
||||||
default:
|
default:
|
||||||
statuses[PodStateErrored]++
|
statuses[define.PodStateErrored]++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
case statuses[PodStateRunning] > 0:
|
case statuses[define.PodStateRunning] > 0:
|
||||||
return PodStateRunning, nil
|
return define.PodStateRunning, nil
|
||||||
case statuses[PodStatePaused] == ctrNum:
|
case statuses[define.PodStatePaused] == ctrNum:
|
||||||
return PodStatePaused, nil
|
return define.PodStatePaused, nil
|
||||||
case statuses[PodStateStopped] == ctrNum:
|
case statuses[define.PodStateStopped] == ctrNum:
|
||||||
return PodStateExited, nil
|
return define.PodStateExited, nil
|
||||||
case statuses[PodStateStopped] > 0:
|
case statuses[define.PodStateStopped] > 0:
|
||||||
return PodStateStopped, nil
|
return define.PodStateStopped, nil
|
||||||
case statuses[PodStateErrored] > 0:
|
case statuses[define.PodStateErrored] > 0:
|
||||||
return PodStateErrored, nil
|
return define.PodStateErrored, nil
|
||||||
default:
|
default:
|
||||||
return PodStateCreated, nil
|
return define.PodStateCreated, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
19
libpod/define/podstate.go
Normal file
19
libpod/define/podstate.go
Normal 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
59
libpod/pod_status.go
Normal 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
|
||||||
|
}
|
||||||
|
}
|
@ -182,3 +182,31 @@ func (r *Runtime) GetRunningPods() ([]*Pod, error) {
|
|||||||
}
|
}
|
||||||
return runningPods, nil
|
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
|
||||||
|
}
|
||||||
|
@ -58,9 +58,9 @@ func (r *LocalRuntime) PrunePods(ctx context.Context, cli *cliconfig.PodPruneVal
|
|||||||
}
|
}
|
||||||
logrus.Debugf("Setting maximum rm workers to %d", maxWorkers)
|
logrus.Debugf("Setting maximum rm workers to %d", maxWorkers)
|
||||||
|
|
||||||
states := []string{shared.PodStateStopped, shared.PodStateExited}
|
states := []string{define.PodStateStopped, define.PodStateExited}
|
||||||
if cli.Force {
|
if cli.Force {
|
||||||
states = append(states, shared.PodStateRunning)
|
states = append(states, define.PodStateRunning)
|
||||||
}
|
}
|
||||||
|
|
||||||
pods, err := r.GetPodsByStatus(states)
|
pods, err := r.GetPodsByStatus(states)
|
||||||
|
@ -540,9 +540,9 @@ func (r *LocalRuntime) PrunePods(ctx context.Context, cli *cliconfig.PodPruneVal
|
|||||||
ok = []string{}
|
ok = []string{}
|
||||||
failures = map[string]error{}
|
failures = map[string]error{}
|
||||||
)
|
)
|
||||||
states := []string{shared.PodStateStopped, shared.PodStateExited}
|
states := []string{define.PodStateStopped, define.PodStateExited}
|
||||||
if cli.Force {
|
if cli.Force {
|
||||||
states = append(states, shared.PodStateRunning)
|
states = append(states, define.PodStateRunning)
|
||||||
}
|
}
|
||||||
|
|
||||||
ids, err := iopodman.GetPodsByStatus().Call(r.Conn, states)
|
ids, err := iopodman.GetPodsByStatus().Call(r.Conn, states)
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package generic
|
package handlers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
@ -10,7 +10,6 @@ import (
|
|||||||
"github.com/containers/libpod/libpod"
|
"github.com/containers/libpod/libpod"
|
||||||
"github.com/containers/libpod/libpod/define"
|
"github.com/containers/libpod/libpod/define"
|
||||||
image2 "github.com/containers/libpod/libpod/image"
|
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/api/handlers/utils"
|
||||||
"github.com/containers/libpod/pkg/namespaces"
|
"github.com/containers/libpod/pkg/namespaces"
|
||||||
createconfig "github.com/containers/libpod/pkg/spec"
|
createconfig "github.com/containers/libpod/pkg/spec"
|
||||||
@ -25,7 +24,7 @@ import (
|
|||||||
func CreateContainer(w http.ResponseWriter, r *http.Request) {
|
func CreateContainer(w http.ResponseWriter, r *http.Request) {
|
||||||
runtime := r.Context().Value("runtime").(*libpod.Runtime)
|
runtime := r.Context().Value("runtime").(*libpod.Runtime)
|
||||||
decoder := r.Context().Value("decoder").(*schema.Decoder)
|
decoder := r.Context().Value("decoder").(*schema.Decoder)
|
||||||
input := handlers.CreateContainerConfig{}
|
input := CreateContainerConfig{}
|
||||||
query := struct {
|
query := struct {
|
||||||
Name string `schema:"name"`
|
Name string `schema:"name"`
|
||||||
}{
|
}{
|
||||||
@ -74,13 +73,13 @@ func CreateContainer(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
response := ContainerCreateResponse{
|
response := ContainerCreateResponse{
|
||||||
Id: ctr.ID(),
|
ID: ctr.ID(),
|
||||||
Warnings: []string{}}
|
Warnings: []string{}}
|
||||||
|
|
||||||
utils.WriteResponse(w, http.StatusCreated, response)
|
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 (
|
var (
|
||||||
err error
|
err error
|
||||||
init bool
|
init bool
|
@ -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"`
|
|
||||||
}
|
|
@ -6,7 +6,6 @@ import (
|
|||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"strconv"
|
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/containers/buildah"
|
"github.com/containers/buildah"
|
||||||
@ -16,12 +15,10 @@ import (
|
|||||||
"github.com/containers/libpod/pkg/api/handlers"
|
"github.com/containers/libpod/pkg/api/handlers"
|
||||||
"github.com/containers/libpod/pkg/api/handlers/utils"
|
"github.com/containers/libpod/pkg/api/handlers/utils"
|
||||||
"github.com/containers/libpod/pkg/util"
|
"github.com/containers/libpod/pkg/util"
|
||||||
"github.com/containers/storage"
|
|
||||||
"github.com/docker/docker/api/types"
|
"github.com/docker/docker/api/types"
|
||||||
"github.com/gorilla/mux"
|
"github.com/gorilla/mux"
|
||||||
"github.com/gorilla/schema"
|
"github.com/gorilla/schema"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/sirupsen/logrus"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func ExportImage(w http.ResponseWriter, r *http.Request) {
|
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) {
|
func PruneImages(w http.ResponseWriter, r *http.Request) {
|
||||||
// 200 no error
|
|
||||||
// 500 internal
|
|
||||||
var (
|
var (
|
||||||
dangling = true
|
filters []string
|
||||||
err error
|
|
||||||
)
|
)
|
||||||
decoder := r.Context().Value("decoder").(*schema.Decoder)
|
decoder := r.Context().Value("decoder").(*schema.Decoder)
|
||||||
runtime := r.Context().Value("runtime").(*libpod.Runtime)
|
runtime := r.Context().Value("runtime").(*libpod.Runtime)
|
||||||
@ -79,60 +73,24 @@ func PruneImages(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
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{}
|
idr := []types.ImageDeleteResponseItem{}
|
||||||
//
|
for k, v := range query.Filters {
|
||||||
// This code needs to be migrated to libpod to work correctly. I could not
|
for _, val := range v {
|
||||||
// work my around the information docker needs with the existing prune in libpod.
|
filters = append(filters, fmt.Sprintf("%s=%s", k, val))
|
||||||
//
|
}
|
||||||
pruneImages, err := runtime.ImageRuntime().GetPruneImages(!dangling, []image2.ImageFilter{})
|
}
|
||||||
|
pruneCids, err := runtime.ImageRuntime().PruneImages(r.Context(), false, filters)
|
||||||
if err != nil {
|
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
|
return
|
||||||
}
|
}
|
||||||
for _, p := range pruneImages {
|
for _, p := range pruneCids {
|
||||||
repotags, err := p.RepoTags()
|
idr = append(idr, types.ImageDeleteResponseItem{
|
||||||
if err != nil {
|
Deleted: p,
|
||||||
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)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//FIXME/TODO to do this exacty correct, pruneimages needs to return idrs and space-reclaimed, then we are golden
|
||||||
ipr := types.ImagesPruneReport{
|
ipr := types.ImagesPruneReport{
|
||||||
ImagesDeleted: idr,
|
ImagesDeleted: idr,
|
||||||
SpaceReclaimed: 1, // TODO we cannot supply this right now
|
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) {
|
func GetImages(w http.ResponseWriter, r *http.Request) {
|
||||||
// 200 ok
|
|
||||||
// 500 internal
|
|
||||||
images, err := utils.GetImages(w, r)
|
images, err := utils.GetImages(w, r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "Failed get images"))
|
utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "Failed get images"))
|
||||||
|
@ -1,11 +1,13 @@
|
|||||||
package generic
|
package generic
|
||||||
|
|
||||||
|
import "github.com/containers/libpod/pkg/api/handlers"
|
||||||
|
|
||||||
// Create container
|
// Create container
|
||||||
// swagger:response ContainerCreateResponse
|
// swagger:response ContainerCreateResponse
|
||||||
type swagCtrCreateResponse struct {
|
type swagCtrCreateResponse struct {
|
||||||
// in:body
|
// in:body
|
||||||
Body struct {
|
Body struct {
|
||||||
ContainerCreateResponse
|
handlers.ContainerCreateResponse
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,7 +3,6 @@ package handlers
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"strconv"
|
"strconv"
|
||||||
@ -127,46 +126,6 @@ func GetImage(r *http.Request, name string) (*image.Image, error) {
|
|||||||
return runtime.ImageRuntime().NewFromLocal(name)
|
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
|
func SaveFromBody(f *os.File, r *http.Request) error { // nolint
|
||||||
if _, err := io.Copy(f, r.Body); err != nil {
|
if _, err := io.Copy(f, r.Body); err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -19,8 +19,6 @@ func StopContainer(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func ContainerExists(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)
|
runtime := r.Context().Value("runtime").(*libpod.Runtime)
|
||||||
name := mux.Vars(r)["name"]
|
name := mux.Vars(r)["name"]
|
||||||
_, err := runtime.LookupContainer(name)
|
_, err := runtime.LookupContainer(name)
|
||||||
@ -147,10 +145,6 @@ func LogsFromContainer(w http.ResponseWriter, r *http.Request) {
|
|||||||
// tail string
|
// tail string
|
||||||
}
|
}
|
||||||
|
|
||||||
func CreateContainer(w http.ResponseWriter, r *http.Request) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func UnmountContainer(w http.ResponseWriter, r *http.Request) {
|
func UnmountContainer(w http.ResponseWriter, r *http.Request) {
|
||||||
runtime := r.Context().Value("runtime").(*libpod.Runtime)
|
runtime := r.Context().Value("runtime").(*libpod.Runtime)
|
||||||
name := mux.Vars(r)["name"]
|
name := mux.Vars(r)["name"]
|
||||||
|
@ -2,9 +2,11 @@ package libpod
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
"github.com/containers/libpod/libpod"
|
"github.com/containers/libpod/libpod"
|
||||||
"github.com/containers/libpod/pkg/api/handlers"
|
"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) {
|
func PruneImages(w http.ResponseWriter, r *http.Request) {
|
||||||
// 200 ok
|
var (
|
||||||
// 500 internal
|
all bool
|
||||||
|
err error
|
||||||
|
)
|
||||||
runtime := r.Context().Value("runtime").(*libpod.Runtime)
|
runtime := r.Context().Value("runtime").(*libpod.Runtime)
|
||||||
decoder := r.Context().Value("decoder").(*schema.Decoder)
|
decoder := r.Context().Value("decoder").(*schema.Decoder)
|
||||||
query := struct {
|
query := struct {
|
||||||
All bool `schema:"all"`
|
|
||||||
Filters map[string][]string `schema:"filters"`
|
Filters map[string][]string `schema:"filters"`
|
||||||
}{
|
}{
|
||||||
// override any golang type defaults
|
// override any golang type defaults
|
||||||
@ -110,11 +113,16 @@ func PruneImages(w http.ResponseWriter, r *http.Request) {
|
|||||||
|
|
||||||
var libpodFilters = []string{}
|
var libpodFilters = []string{}
|
||||||
if _, found := r.URL.Query()["filters"]; found {
|
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 {
|
for k, v := range query.Filters {
|
||||||
libpodFilters = append(libpodFilters, fmt.Sprintf("%s=%s", k, v[0]))
|
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 {
|
if err != nil {
|
||||||
utils.Error(w, "Something went wrong.", http.StatusInternalServerError, err)
|
utils.Error(w, "Something went wrong.", http.StatusInternalServerError, err)
|
||||||
return
|
return
|
||||||
@ -171,3 +179,47 @@ func ExportImage(w http.ResponseWriter, r *http.Request) {
|
|||||||
defer os.Remove(tmpfile.Name())
|
defer os.Remove(tmpfile.Name())
|
||||||
utils.WriteResponse(w, http.StatusOK, rdr)
|
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),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
@ -268,7 +268,7 @@ func PodDelete(w http.ResponseWriter, r *http.Request) {
|
|||||||
decoder = r.Context().Value("decoder").(*schema.Decoder)
|
decoder = r.Context().Value("decoder").(*schema.Decoder)
|
||||||
)
|
)
|
||||||
query := struct {
|
query := struct {
|
||||||
force bool `schema:"force"`
|
Force bool `schema:"force"`
|
||||||
}{
|
}{
|
||||||
// override any golang type defaults
|
// override any golang type defaults
|
||||||
}
|
}
|
||||||
@ -284,7 +284,7 @@ func PodDelete(w http.ResponseWriter, r *http.Request) {
|
|||||||
utils.PodNotFound(w, name, err)
|
utils.PodNotFound(w, name, err)
|
||||||
return
|
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)
|
utils.Error(w, "Something went wrong", http.StatusInternalServerError, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -309,43 +309,14 @@ func PodRestart(w http.ResponseWriter, r *http.Request) {
|
|||||||
|
|
||||||
func PodPrune(w http.ResponseWriter, r *http.Request) {
|
func PodPrune(w http.ResponseWriter, r *http.Request) {
|
||||||
var (
|
var (
|
||||||
err error
|
|
||||||
pods []*libpod.Pod
|
|
||||||
runtime = r.Context().Value("runtime").(*libpod.Runtime)
|
runtime = r.Context().Value("runtime").(*libpod.Runtime)
|
||||||
decoder = r.Context().Value("decoder").(*schema.Decoder)
|
|
||||||
)
|
)
|
||||||
query := struct {
|
pruned, err := runtime.PrunePods()
|
||||||
force bool `schema:"force"`
|
if err != nil {
|
||||||
}{
|
utils.InternalServerError(w, err)
|
||||||
// override any golang type defaults
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := decoder.Decode(&query, r.URL.Query()); err != nil {
|
|
||||||
utils.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest,
|
|
||||||
errors.Wrapf(err, "Failed to parse parameters for %s", r.URL.String()))
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
utils.WriteResponse(w, http.StatusOK, pruned)
|
||||||
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, "")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func PodPause(w http.ResponseWriter, r *http.Request) {
|
func PodPause(w http.ResponseWriter, r *http.Request) {
|
||||||
|
@ -537,3 +537,11 @@ func portsToPortSet(input map[string]struct{}) (nat.PortSet, error) {
|
|||||||
}
|
}
|
||||||
return ports, nil
|
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"`
|
||||||
|
}
|
||||||
|
@ -6,6 +6,7 @@ import (
|
|||||||
|
|
||||||
"github.com/containers/libpod/libpod"
|
"github.com/containers/libpod/libpod"
|
||||||
"github.com/containers/libpod/libpod/image"
|
"github.com/containers/libpod/libpod/image"
|
||||||
|
"github.com/gorilla/mux"
|
||||||
"github.com/gorilla/schema"
|
"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)
|
decoder := r.Context().Value("decoder").(*schema.Decoder)
|
||||||
runtime := r.Context().Value("runtime").(*libpod.Runtime)
|
runtime := r.Context().Value("runtime").(*libpod.Runtime)
|
||||||
query := struct {
|
query := struct {
|
||||||
// all bool # all is currently unused
|
All bool
|
||||||
Filters map[string][]string `schema:"filters"`
|
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
|
// 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 {
|
if err := decoder.Decode(&query, r.URL.Query()); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var filters = []string{}
|
var filters = []string{}
|
||||||
|
if _, found := mux.Vars(r)["digests"]; found && query.Digests {
|
||||||
|
UnSupportedParameter("digests")
|
||||||
|
}
|
||||||
|
|
||||||
if _, found := r.URL.Query()["filters"]; found {
|
if _, found := r.URL.Query()["filters"]; found {
|
||||||
filters = append(filters, fmt.Sprintf("reference=%s", ""))
|
filters = append(filters, fmt.Sprintf("reference=%s", ""))
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,8 @@
|
|||||||
// Version: 0.0.1
|
// Version: 0.0.1
|
||||||
// License: Apache-2.0 https://opensource.org/licenses/Apache-2.0
|
// License: Apache-2.0 https://opensource.org/licenses/Apache-2.0
|
||||||
// Contact: Podman <podman@lists.podman.io> https://podman.io/community/
|
// Contact: Podman <podman@lists.podman.io> https://podman.io/community/
|
||||||
// Extensions:
|
//
|
||||||
|
// InfoExtensions:
|
||||||
// x-logo:
|
// x-logo:
|
||||||
// - url: https://raw.githubusercontent.com/containers/libpod/master/logo/podman-logo.png
|
// - url: https://raw.githubusercontent.com/containers/libpod/master/logo/podman-logo.png
|
||||||
// - altText: "Podman logo"
|
// - altText: "Podman logo"
|
||||||
|
@ -33,7 +33,7 @@ func (s *APIServer) RegisterContainersHandlers(r *mux.Router) error {
|
|||||||
// $ref: "#/responses/ConflictError"
|
// $ref: "#/responses/ConflictError"
|
||||||
// 500:
|
// 500:
|
||||||
// $ref: "#/responses/InternalError"
|
// $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
|
// swagger:operation GET /containers/json compat listContainers
|
||||||
// ---
|
// ---
|
||||||
// tags:
|
// tags:
|
||||||
@ -550,7 +550,7 @@ func (s *APIServer) RegisterContainersHandlers(r *mux.Router) error {
|
|||||||
libpod endpoints
|
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
|
// swagger:operation GET /libpod/containers/json libpod libpodListContainers
|
||||||
// ---
|
// ---
|
||||||
// tags:
|
// tags:
|
||||||
|
@ -55,6 +55,27 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error {
|
|||||||
// - images (compat)
|
// - images (compat)
|
||||||
// summary: List Images
|
// 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.
|
// 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:
|
// produces:
|
||||||
// - application/json
|
// - application/json
|
||||||
// responses:
|
// responses:
|
||||||
@ -63,7 +84,7 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error {
|
|||||||
// 500:
|
// 500:
|
||||||
// $ref: '#/responses/InternalError'
|
// $ref: '#/responses/InternalError'
|
||||||
r.Handle(VersionedPath("/images/json"), APIHandler(s.Context, generic.GetImages)).Methods(http.MethodGet)
|
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:
|
// tags:
|
||||||
// - images (compat)
|
// - images (compat)
|
||||||
@ -86,7 +107,7 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error {
|
|||||||
// description: no error
|
// description: no error
|
||||||
// 500:
|
// 500:
|
||||||
// $ref: '#/responses/InternalError'
|
// $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
|
// swagger:operation POST /images/prune compat pruneImages
|
||||||
// ---
|
// ---
|
||||||
// tags:
|
// tags:
|
||||||
@ -585,6 +606,27 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error {
|
|||||||
// - images
|
// - images
|
||||||
// summary: List Images
|
// summary: List Images
|
||||||
// description: Returns a list of images on the server
|
// 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:
|
// produces:
|
||||||
// - application/json
|
// - application/json
|
||||||
// responses:
|
// responses:
|
||||||
@ -593,7 +635,7 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error {
|
|||||||
// 500:
|
// 500:
|
||||||
// $ref: '#/responses/InternalError'
|
// $ref: '#/responses/InternalError'
|
||||||
r.Handle(VersionedPath("/libpod/images/json"), APIHandler(s.Context, libpod.GetImages)).Methods(http.MethodGet)
|
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:
|
// tags:
|
||||||
// - images
|
// - images
|
||||||
@ -604,6 +646,14 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error {
|
|||||||
// name: quiet
|
// name: quiet
|
||||||
// type: boolean
|
// type: boolean
|
||||||
// description: not supported
|
// 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
|
// - in: body
|
||||||
// name: request
|
// name: request
|
||||||
// description: tarball of container image
|
// description: tarball of container image
|
||||||
@ -617,7 +667,7 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error {
|
|||||||
// description: no error
|
// description: no error
|
||||||
// 500:
|
// 500:
|
||||||
// $ref: '#/responses/InternalError'
|
// $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
|
// swagger:operation POST /libpod/images/prune libpod libpodPruneImages
|
||||||
// ---
|
// ---
|
||||||
// tags:
|
// tags:
|
||||||
@ -635,10 +685,6 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error {
|
|||||||
// (or `0`), all unused images are pruned.
|
// (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.
|
// - `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.
|
// - `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:
|
// produces:
|
||||||
// - application/json
|
// - application/json
|
||||||
// responses:
|
// responses:
|
||||||
|
@ -30,17 +30,15 @@ func (s *APIServer) registerPodsHandlers(r *mux.Router) error {
|
|||||||
// swagger:operation POST /libpod/pods/prune pods PrunePods
|
// swagger:operation POST /libpod/pods/prune pods PrunePods
|
||||||
// ---
|
// ---
|
||||||
// summary: Prune unused pods
|
// summary: Prune unused pods
|
||||||
// parameters:
|
|
||||||
// - in: query
|
|
||||||
// name: force
|
|
||||||
// description: force delete
|
|
||||||
// type: boolean
|
|
||||||
// default: false
|
|
||||||
// produces:
|
// produces:
|
||||||
// - application/json
|
// - application/json
|
||||||
// responses:
|
// responses:
|
||||||
// 204:
|
// 200:
|
||||||
// description: no error
|
// description: tbd
|
||||||
|
// schema:
|
||||||
|
// type: object
|
||||||
|
// additionalProperties:
|
||||||
|
// type: string
|
||||||
// 400:
|
// 400:
|
||||||
// $ref: "#/responses/BadParamError"
|
// $ref: "#/responses/BadParamError"
|
||||||
// 500:
|
// 500:
|
||||||
@ -60,7 +58,7 @@ func (s *APIServer) registerPodsHandlers(r *mux.Router) error {
|
|||||||
// - in: query
|
// - in: query
|
||||||
// name: force
|
// name: force
|
||||||
// type: boolean
|
// 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:
|
// responses:
|
||||||
// 204:
|
// 204:
|
||||||
// description: no error
|
// description: no error
|
||||||
|
Reference in New Issue
Block a user