Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 25 additions & 31 deletions cmd/podman/shared/pod.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,68 +10,62 @@ 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.
// Returns a string representation of the pod status
func GetPodStatus(pod *libpod.Pod) (string, error) {
ctrStatuses, err := pod.Status()
if err != nil {
return PodStateErrored, err
return define.PodStateErrored, err
}
return CreatePodStatusResults(ctrStatuses)
}

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
}
}

Expand Down
19 changes: 19 additions & 0 deletions libpod/define/podstate.go
Original file line number Diff line number Diff line change
@@ -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 changes: 59 additions & 0 deletions libpod/pod_status.go
Original file line number Diff line number Diff line change
@@ -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
}
}
28 changes: 28 additions & 0 deletions libpod/runtime_pod.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
4 changes: 2 additions & 2 deletions pkg/adapter/pods.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
4 changes: 2 additions & 2 deletions pkg/adapter/pods_remote.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package generic
package handlers

import (
"encoding/json"
Expand All @@ -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"
Expand All @@ -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"`
}{
Expand Down Expand Up @@ -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
Expand Down
9 changes: 0 additions & 9 deletions pkg/api/handlers/generic/config.go

This file was deleted.

70 changes: 13 additions & 57 deletions pkg/api/handlers/generic/images.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import (
"io/ioutil"
"net/http"
"os"
"strconv"
"strings"

"github.com/containers/buildah"
Expand All @@ -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) {
Expand Down Expand Up @@ -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)
Expand All @@ -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{}
for k, v := range query.Filters {
for _, val := range v {
filters = append(filters, fmt.Sprintf("%s=%s", k, val))
}
}

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{})
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
Expand Down Expand Up @@ -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"))
Expand Down
Loading