diff options
Diffstat (limited to 'pkg/api')
-rw-r--r-- | pkg/api/handlers/compat/containers.go | 14 | ||||
-rw-r--r-- | pkg/api/handlers/compat/containers_restart.go | 16 | ||||
-rw-r--r-- | pkg/api/handlers/compat/images.go | 3 | ||||
-rw-r--r-- | pkg/api/handlers/compat/images_remove.go | 22 | ||||
-rw-r--r-- | pkg/api/handlers/libpod/images.go | 5 | ||||
-rw-r--r-- | pkg/api/handlers/libpod/volumes.go | 140 | ||||
-rw-r--r-- | pkg/api/handlers/types.go | 70 | ||||
-rw-r--r-- | pkg/api/server/register_images.go | 2 | ||||
-rw-r--r-- | pkg/api/server/register_volumes.go | 10 | ||||
-rw-r--r-- | pkg/api/server/swagger.go | 10 |
10 files changed, 124 insertions, 168 deletions
diff --git a/pkg/api/handlers/compat/containers.go b/pkg/api/handlers/compat/containers.go index 3a269fe50..2ce113d30 100644 --- a/pkg/api/handlers/compat/containers.go +++ b/pkg/api/handlers/compat/containers.go @@ -7,7 +7,6 @@ import ( "strconv" "strings" "sync" - "syscall" "time" "github.com/containers/libpod/libpod" @@ -15,6 +14,7 @@ import ( "github.com/containers/libpod/libpod/logs" "github.com/containers/libpod/pkg/api/handlers" "github.com/containers/libpod/pkg/api/handlers/utils" + "github.com/containers/libpod/pkg/signal" "github.com/containers/libpod/pkg/util" "github.com/gorilla/schema" "github.com/pkg/errors" @@ -145,14 +145,20 @@ func KillContainer(w http.ResponseWriter, r *http.Request) { runtime := r.Context().Value("runtime").(*libpod.Runtime) decoder := r.Context().Value("decoder").(*schema.Decoder) query := struct { - Signal syscall.Signal `schema:"signal"` + Signal string `schema:"signal"` }{ - Signal: syscall.SIGKILL, + Signal: "KILL", } 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 } + + sig, err := signal.ParseSignalNameOrNumber(query.Signal) + if err != nil { + utils.InternalServerError(w, err) + return + } name := utils.GetName(r) con, err := runtime.LookupContainer(name) if err != nil { @@ -172,7 +178,7 @@ func KillContainer(w http.ResponseWriter, r *http.Request) { return } - err = con.Kill(uint(query.Signal)) + err = con.Kill(uint(sig)) if err != nil { utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrapf(err, "unable to kill Container %s", name)) } diff --git a/pkg/api/handlers/compat/containers_restart.go b/pkg/api/handlers/compat/containers_restart.go index 5b8fafaa4..343bf96d2 100644 --- a/pkg/api/handlers/compat/containers_restart.go +++ b/pkg/api/handlers/compat/containers_restart.go @@ -1,11 +1,9 @@ package compat import ( - "fmt" "net/http" "github.com/containers/libpod/libpod" - "github.com/containers/libpod/libpod/define" "github.com/containers/libpod/pkg/api/handlers/utils" "github.com/gorilla/schema" "github.com/pkg/errors" @@ -32,20 +30,6 @@ func RestartContainer(w http.ResponseWriter, r *http.Request) { return } - state, err := con.State() - if err != nil { - utils.InternalServerError(w, err) - return - } - - // FIXME: This is not in the swagger.yml... - // If the Container is stopped already, send a 409 - if state == define.ContainerStateStopped || state == define.ContainerStateExited { - msg := fmt.Sprintf("Container %s is not running", name) - utils.Error(w, msg, http.StatusConflict, errors.New(msg)) - return - } - timeout := con.StopTimeout() if _, found := r.URL.Query()["t"]; found { timeout = uint(query.Timeout) diff --git a/pkg/api/handlers/compat/images.go b/pkg/api/handlers/compat/images.go index b18687bf9..cce718f54 100644 --- a/pkg/api/handlers/compat/images.go +++ b/pkg/api/handlers/compat/images.go @@ -15,6 +15,7 @@ import ( 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/domain/entities" "github.com/containers/libpod/pkg/util" "github.com/docker/docker/api/types" "github.com/gorilla/schema" @@ -305,7 +306,7 @@ func GetImages(w http.ResponseWriter, r *http.Request) { utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "Failed get images")) return } - var summaries = make([]*handlers.ImageSummary, len(images)) + var summaries = make([]*entities.ImageSummary, len(images)) for j, img := range images { is, err := handlers.ImageToImageSummary(img) if err != nil { diff --git a/pkg/api/handlers/compat/images_remove.go b/pkg/api/handlers/compat/images_remove.go index 3d346543e..ed0153529 100644 --- a/pkg/api/handlers/compat/images_remove.go +++ b/pkg/api/handlers/compat/images_remove.go @@ -36,17 +36,23 @@ func RemoveImage(w http.ResponseWriter, r *http.Request) { return } - _, err = runtime.RemoveImage(r.Context(), newImage, query.Force) + results, err := runtime.RemoveImage(r.Context(), newImage, query.Force) if err != nil { utils.Error(w, "Something went wrong.", http.StatusInternalServerError, err) return } - // TODO - // This will need to be fixed for proper response, like Deleted: and Untagged: - m := make(map[string]string) - m["Deleted"] = newImage.ID() - foo := []map[string]string{} - foo = append(foo, m) - utils.WriteResponse(w, http.StatusOK, foo) + + response := make([]map[string]string, 0, len(results.Untagged)+1) + deleted := make(map[string]string, 1) + deleted["Deleted"] = results.Deleted + response = append(response, deleted) + + for _, u := range results.Untagged { + untagged := make(map[string]string, 1) + untagged["Untagged"] = u + response = append(response, untagged) + } + + utils.WriteResponse(w, http.StatusOK, response) } diff --git a/pkg/api/handlers/libpod/images.go b/pkg/api/handlers/libpod/images.go index b6f2f58e8..f8e666451 100644 --- a/pkg/api/handlers/libpod/images.go +++ b/pkg/api/handlers/libpod/images.go @@ -21,6 +21,7 @@ import ( 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/domain/entities" "github.com/containers/libpod/pkg/util" "github.com/gorilla/schema" "github.com/pkg/errors" @@ -101,7 +102,7 @@ func GetImages(w http.ResponseWriter, r *http.Request) { utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "Failed get images")) return } - var summaries = make([]*handlers.ImageSummary, len(images)) + var summaries = make([]*entities.ImageSummary, len(images)) for j, img := range images { is, err := handlers.ImageToImageSummary(img) if err != nil { @@ -109,7 +110,7 @@ func GetImages(w http.ResponseWriter, r *http.Request) { return } // libpod has additional fields that we need to populate. - is.CreatedTime = img.Created() + is.Created = img.Created().Unix() is.ReadOnly = img.IsReadOnly() summaries[j] = is } diff --git a/pkg/api/handlers/libpod/volumes.go b/pkg/api/handlers/libpod/volumes.go index 06ca1d225..e61d272f4 100644 --- a/pkg/api/handlers/libpod/volumes.go +++ b/pkg/api/handlers/libpod/volumes.go @@ -3,16 +3,15 @@ package libpod import ( "encoding/json" "net/http" - "strings" "github.com/containers/libpod/cmd/podman/shared" "github.com/containers/libpod/libpod" "github.com/containers/libpod/libpod/define" "github.com/containers/libpod/pkg/api/handlers/utils" "github.com/containers/libpod/pkg/domain/entities" + "github.com/containers/libpod/pkg/domain/filters" "github.com/gorilla/schema" "github.com/pkg/errors" - log "github.com/sirupsen/logrus" ) func CreateVolume(w http.ResponseWriter, r *http.Request) { @@ -65,14 +64,14 @@ func CreateVolume(w http.ResponseWriter, r *http.Request) { return } volResponse := entities.VolumeConfigResponse{ - Name: config.Name, - Labels: config.Labels, - Driver: config.Driver, - MountPoint: config.MountPoint, - CreatedTime: config.CreatedTime, - Options: config.Options, - UID: config.UID, - GID: config.GID, + Name: config.Name, + Driver: config.Driver, + Mountpoint: config.MountPoint, + CreatedAt: config.CreatedTime, + Labels: config.Labels, + Options: config.Options, + UID: config.UID, + GID: config.GID, } utils.WriteResponse(w, http.StatusOK, volResponse) } @@ -85,21 +84,27 @@ func InspectVolume(w http.ResponseWriter, r *http.Request) { vol, err := runtime.GetVolume(name) if err != nil { utils.VolumeNotFound(w, name, err) + return } - inspect, err := vol.Inspect() - if err != nil { - utils.InternalServerError(w, err) + volResponse := entities.VolumeConfigResponse{ + Name: vol.Name(), + Driver: vol.Driver(), + Mountpoint: vol.MountPoint(), + CreatedAt: vol.CreatedTime(), + Labels: vol.Labels(), + Scope: vol.Scope(), + Options: vol.Options(), + UID: vol.UID(), + GID: vol.GID(), } - utils.WriteResponse(w, http.StatusOK, inspect) + utils.WriteResponse(w, http.StatusOK, volResponse) } func ListVolumes(w http.ResponseWriter, r *http.Request) { var ( decoder = r.Context().Value("decoder").(*schema.Decoder) - err error runtime = r.Context().Value("runtime").(*libpod.Runtime) - volumeConfigs []*libpod.VolumeConfig - volumeFilters []libpod.VolumeFilter + volumeConfigs []*entities.VolumeListReport ) query := struct { Filters map[string][]string `schema:"filters"` @@ -113,25 +118,30 @@ func ListVolumes(w http.ResponseWriter, r *http.Request) { return } - if len(query.Filters) > 0 { - volumeFilters, err = generateVolumeFilters(query.Filters) - if err != nil { - utils.InternalServerError(w, err) - return - } + volumeFilters, err := filters.GenerateVolumeFilters(query.Filters) + if err != nil { + utils.InternalServerError(w, err) + return } + vols, err := runtime.Volumes(volumeFilters...) if err != nil { utils.InternalServerError(w, err) return } for _, v := range vols { - config, err := v.Config() - if err != nil { - utils.InternalServerError(w, err) - return + config := entities.VolumeConfigResponse{ + Name: v.Name(), + Driver: v.Driver(), + Mountpoint: v.MountPoint(), + CreatedAt: v.CreatedTime(), + Labels: v.Labels(), + Scope: v.Scope(), + Options: v.Options(), + UID: v.UID(), + GID: v.GID(), } - volumeConfigs = append(volumeConfigs, config) + volumeConfigs = append(volumeConfigs, &entities.VolumeListReport{VolumeConfigResponse: config}) } utils.WriteResponse(w, http.StatusOK, volumeConfigs) } @@ -140,14 +150,10 @@ func PruneVolumes(w http.ResponseWriter, r *http.Request) { var ( runtime = r.Context().Value("runtime").(*libpod.Runtime) ) - pruned, errs := runtime.PruneVolumes(r.Context()) - if errs != nil { - if len(errs) > 1 { - for _, err := range errs { - log.Infof("Request Failed(%s): %s", http.StatusText(http.StatusInternalServerError), err.Error()) - } - } - utils.InternalServerError(w, errs[len(errs)-1]) + pruned, err := runtime.PruneVolumes(r.Context()) + if err != nil { + utils.InternalServerError(w, err) + return } utils.WriteResponse(w, http.StatusOK, pruned) } @@ -184,65 +190,3 @@ func RemoveVolume(w http.ResponseWriter, r *http.Request) { } utils.WriteResponse(w, http.StatusNoContent, "") } - -func generateVolumeFilters(filters map[string][]string) ([]libpod.VolumeFilter, error) { - var vf []libpod.VolumeFilter - for filter, v := range filters { - for _, val := range v { - switch filter { - case "name": - nameVal := val - vf = append(vf, func(v *libpod.Volume) bool { - return nameVal == v.Name() - }) - case "driver": - driverVal := val - vf = append(vf, func(v *libpod.Volume) bool { - return v.Driver() == driverVal - }) - case "scope": - scopeVal := val - vf = append(vf, func(v *libpod.Volume) bool { - return v.Scope() == scopeVal - }) - case "label": - filterArray := strings.SplitN(val, "=", 2) - filterKey := filterArray[0] - var filterVal string - if len(filterArray) > 1 { - filterVal = filterArray[1] - } else { - filterVal = "" - } - vf = append(vf, func(v *libpod.Volume) bool { - for labelKey, labelValue := range v.Labels() { - if labelKey == filterKey && ("" == filterVal || labelValue == filterVal) { - return true - } - } - return false - }) - case "opt": - filterArray := strings.SplitN(val, "=", 2) - filterKey := filterArray[0] - var filterVal string - if len(filterArray) > 1 { - filterVal = filterArray[1] - } else { - filterVal = "" - } - vf = append(vf, func(v *libpod.Volume) bool { - for labelKey, labelValue := range v.Options() { - if labelKey == filterKey && ("" == filterVal || labelValue == filterVal) { - return true - } - } - return false - }) - default: - return nil, errors.Errorf("%q is in an invalid volume filter", filter) - } - } - } - return vf, nil -} diff --git a/pkg/api/handlers/types.go b/pkg/api/handlers/types.go index 6fa776d0f..fe4198c37 100644 --- a/pkg/api/handlers/types.go +++ b/pkg/api/handlers/types.go @@ -13,6 +13,7 @@ import ( "github.com/containers/libpod/libpod/define" "github.com/containers/libpod/libpod/events" libpodImage "github.com/containers/libpod/libpod/image" + "github.com/containers/libpod/pkg/domain/entities" docker "github.com/docker/docker/api/types" dockerContainer "github.com/docker/docker/api/types/container" dockerEvents "github.com/docker/docker/api/types/events" @@ -45,12 +46,6 @@ type LibpodImagesPullReport struct { ID string `json:"id"` } -type ImageSummary struct { - docker.ImageSummary - CreatedTime time.Time `json:"CreatedTime,omitempty"` - ReadOnly bool `json:"ReadOnly,omitempty"` -} - type ContainersPruneReport struct { docker.ContainersPruneReport } @@ -203,23 +198,13 @@ func EventToApiEvent(e *events.Event) *Event { }} } -func ImageToImageSummary(l *libpodImage.Image) (*ImageSummary, error) { +func ImageToImageSummary(l *libpodImage.Image) (*entities.ImageSummary, error) { containers, err := l.Containers() if err != nil { return nil, errors.Wrapf(err, "Failed to obtain Containers for image %s", l.ID()) } containerCount := len(containers) - var digests []string - for _, d := range l.Digests() { - digests = append(digests, string(d)) - } - - tags, err := l.RepoTags() - if err != nil { - return nil, errors.Wrapf(err, "Failed to obtain RepoTags for image %s", l.ID()) - } - // FIXME: GetParent() panics // parent, err := l.GetParent(context.TODO()) // if err != nil { @@ -235,20 +220,43 @@ func ImageToImageSummary(l *libpodImage.Image) (*ImageSummary, error) { if err != nil { return nil, errors.Wrapf(err, "Failed to obtain Size for image %s", l.ID()) } - dockerSummary := docker.ImageSummary{ - Containers: int64(containerCount), - Created: l.Created().Unix(), - ID: l.ID(), - Labels: labels, - ParentID: l.Parent, - RepoDigests: digests, - RepoTags: tags, - SharedSize: 0, - Size: int64(*size), - VirtualSize: int64(*size), - } - is := ImageSummary{ - ImageSummary: dockerSummary, + + repoTags, err := l.RepoTags() + if err != nil { + return nil, errors.Wrapf(err, "Failed to obtain RepoTags for image %s", l.ID()) + } + + history, err := l.History(context.TODO()) + if err != nil { + return nil, errors.Wrapf(err, "Failed to obtain History for image %s", l.ID()) + } + historyIds := make([]string, len(history)) + for i, h := range history { + historyIds[i] = h.ID + } + + digests := make([]string, len(l.Digests())) + for i, d := range l.Digests() { + digests[i] = string(d) + } + + is := entities.ImageSummary{ + ID: l.ID(), + ParentId: l.Parent, + RepoTags: repoTags, + Created: l.Created().Unix(), + Size: int64(*size), + SharedSize: 0, + VirtualSize: l.VirtualSize, + Labels: labels, + Containers: containerCount, + ReadOnly: l.IsReadOnly(), + Dangling: l.Dangling(), + Names: l.Names(), + Digest: string(l.Digest()), + Digests: digests, + ConfigDigest: string(l.ConfigDigest), + History: historyIds, } return &is, nil } diff --git a/pkg/api/server/register_images.go b/pkg/api/server/register_images.go index 87ddf5add..e8dfe2fa8 100644 --- a/pkg/api/server/register_images.go +++ b/pkg/api/server/register_images.go @@ -967,7 +967,7 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error { // 500: // $ref: '#/responses/InternalError' r.Handle(VersionedPath("/libpod/images/{name:.*}/tag"), s.APIHandler(compat.TagImage)).Methods(http.MethodPost) - // swagger:operation POST /commit libpod libpodCommitContainer + // swagger:operation POST /libpod/commit libpod libpodCommitContainer // --- // tags: // - containers diff --git a/pkg/api/server/register_volumes.go b/pkg/api/server/register_volumes.go index 2cf249cc3..93b972b6b 100644 --- a/pkg/api/server/register_volumes.go +++ b/pkg/api/server/register_volumes.go @@ -53,8 +53,8 @@ func (s *APIServer) registerVolumeHandlers(r *mux.Router) error { // produces: // - application/json // responses: - // '204': - // description: no error + // '200': + // "$ref": "#/responses/VolumePruneResponse" // '500': // "$ref": "#/responses/InternalError" r.Handle(VersionedPath("/libpod/volumes/prune"), s.APIHandler(libpod.PruneVolumes)).Methods(http.MethodPost) @@ -71,11 +71,11 @@ func (s *APIServer) registerVolumeHandlers(r *mux.Router) error { // - application/json // responses: // '200': - // "$ref": "#/responses/InspectVolumeResponse" + // "$ref": "#/responses/VolumeCreateResponse" // '404': - // "$ref": "#/responses/NoSuchVolume" + // "$ref": "#/responses/NoSuchVolume" // '500': - // "$ref": "#/responses/InternalError" + // "$ref": "#/responses/InternalError" r.Handle(VersionedPath("/libpod/volumes/{name}/json"), s.APIHandler(libpod.InspectVolume)).Methods(http.MethodGet) // swagger:operation DELETE /libpod/volumes/{name} volumes removeVolume // --- diff --git a/pkg/api/server/swagger.go b/pkg/api/server/swagger.go index 2e1a269f2..9156f3f8a 100644 --- a/pkg/api/server/swagger.go +++ b/pkg/api/server/swagger.go @@ -2,7 +2,6 @@ package server import ( "github.com/containers/libpod/libpod" - "github.com/containers/libpod/pkg/api/handlers" "github.com/containers/libpod/pkg/api/handlers/utils" "github.com/containers/libpod/pkg/domain/entities" ) @@ -128,7 +127,7 @@ type swagPodAlreadyStopped struct { // swagger:response DockerImageSummary type swagImageSummary struct { // in:body - Body []handlers.ImageSummary + Body []entities.ImageSummary } // List Containers @@ -151,6 +150,13 @@ type ok struct { } } +// Volume prune response +// swagger:response VolumePruneResponse +type swagVolumePruneResponse struct { + // in:body + Body []entities.VolumePruneReport +} + // Volume create response // swagger:response VolumeCreateResponse type swagVolumeCreateResponse struct { |