Skip to content
Closed
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
2 changes: 2 additions & 0 deletions cmd/podman/imagefilters/dummy.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
package imagefilters

20 changes: 10 additions & 10 deletions cmd/podman/imagefilters/filters.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// +build refactored_out_code


package imagefilters

import (
Expand All @@ -17,30 +20,30 @@ type ResultFilter func(*adapter.ContainerImage) bool
// return will include the image, a false return will exclude it.
type Filter func(*adapter.ContainerImage, *inspect.ImageData) bool

// CreatedBeforeFilter allows you to filter on images created before
// CreatedBeforeFilter allows you to filterable on images created before
// the given time.Time
func CreatedBeforeFilter(createTime time.Time) ResultFilter {
return func(i *adapter.ContainerImage) bool {
return i.Created().Before(createTime)
}
}

// CreatedAfterFilter allows you to filter on images created after
// CreatedAfterFilter allows you to filterable on images created after
// the given time.Time
func CreatedAfterFilter(createTime time.Time) ResultFilter {
return func(i *adapter.ContainerImage) bool {
return i.Created().After(createTime)
}
}

// DanglingFilter allows you to filter images for dangling images
// DanglingFilter allows you to filterable images for dangling images
func DanglingFilter() ResultFilter {
return func(i *adapter.ContainerImage) bool {
return i.Dangling()
}
}

// LabelFilter allows you to filter by images labels key and/or value
// LabelFilter allows you to filterable by images labels key and/or value
func LabelFilter(ctx context.Context, labelfilter string) ResultFilter {
// We need to handle both label=key and label=key=value
return func(i *adapter.ContainerImage) bool {
Expand All @@ -50,25 +53,22 @@ func LabelFilter(ctx context.Context, labelfilter string) ResultFilter {
if len(splitFilter) > 1 {
value = splitFilter[1]
}
labels, err := i.Labels(ctx)
if err != nil {
return false
}
labels := i.Labels(ctx)
if len(strings.TrimSpace(labels[key])) > 0 && len(strings.TrimSpace(value)) == 0 {
return true
}
return labels[key] == value
}
}

// OutputImageFilter allows you to filter by an a specific image name
// OutputImageFilter allows you to filterable by an a specific image name
func OutputImageFilter(userImage *adapter.ContainerImage) ResultFilter {
return func(i *adapter.ContainerImage) bool {
return userImage.ID() == i.ID()
}
}

// FilterImages filters images using a set of predefined filter funcs
// FilterImages filters images using a set of predefined filterable funcs
func FilterImages(images []*adapter.ContainerImage, filters []ResultFilter) []*adapter.ContainerImage {
var filteredImages []*adapter.ContainerImage
for _, image := range images {
Expand Down
43 changes: 18 additions & 25 deletions libpod/adapter/runtime_remote.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,14 +48,13 @@ func GetRuntime(c *cliconfig.PodmanCommand) (*LocalRuntime, error) {
if err != nil {
return nil, err
}
rr := RemoteRuntime{
Conn: conn,
Remote: true,
}
foo := LocalRuntime{
&rr,
}
return &foo, nil

return &LocalRuntime{
&RemoteRuntime{
Conn: conn,
Remote: true,
},
}, nil
}

// Shutdown is a bogus wrapper for compat with the libpod runtime
Expand Down Expand Up @@ -239,8 +238,8 @@ func (ci *ContainerImage) Digest() digest.Digest {
}

// Labels returns a map of the image's labels
func (ci *ContainerImage) Labels(ctx context.Context) (map[string]string, error) {
return ci.remoteImage.Labels, nil
func (ci *ContainerImage) Labels(ctx context.Context) map[string]string {
return ci.remoteImage.Labels
}

// Dangling returns a bool if the image is "dangling"
Expand Down Expand Up @@ -292,28 +291,22 @@ func (r *LocalRuntime) LookupContainer(idOrName string) (*Container, error) {
return nil, err
}
config := r.Config(idOrName)
if err != nil {
return nil, err
}

rc := remoteContainer{
r,
config,
state,
}

c := Container{
rc,
}
return &c, nil
return &Container{
remoteContainer{
r,
config,
state,
},
}, nil
}

func (r *LocalRuntime) GetLatestContainer() (*Container, error) {
return nil, libpod.ErrNotImplemented
}

// ContainerState returns the "state" of the container.
func (r *LocalRuntime) ContainerState(name string) (*libpod.ContainerState, error) { //no-lint
func (r *LocalRuntime) ContainerState(name string) (*libpod.ContainerState, error) { // no-lint
reply, err := iopodman.ContainerStateData().Call(r.Conn, name)
if err != nil {
return nil, err
Expand Down Expand Up @@ -544,7 +537,7 @@ func (r *LocalRuntime) RemoveVolume(ctx context.Context, v *libpod.Volume, force
// Filters can be provided which will determine what containers are included in
// the output. Multiple filters are handled by ANDing their output, so only
// containers matching all filters are returned
func (r *LocalRuntime) GetContainers(filters ...libpod.ContainerFilter) ([]*libpod.Container, error) {
func (r *LocalRuntime) GetContainers(filters ...libpod.Filter) ([]*Container, error) {
return nil, libpod.ErrNotImplemented
}

Expand Down
39 changes: 31 additions & 8 deletions libpod/container.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import (
"github.com/containers/libpod/pkg/namespaces"
"github.com/containers/storage"
"github.com/cri-o/ocicni/pkg/ocicni"
spec "github.com/opencontainers/runtime-spec/specs-go"
rspec "github.com/opencontainers/runtime-spec/specs-go"
"github.com/pkg/errors"
"github.com/ulule/deepcopier"
)
Expand Down Expand Up @@ -192,7 +192,7 @@ type ContainerState struct {

// ExtensionStageHooks holds hooks which will be executed by libpod
// and not delegated to the OCI runtime.
ExtensionStageHooks map[string][]spec.Hook `json:"extensionStageHooks,omitempty"`
ExtensionStageHooks map[string][]rspec.Hook `json:"extensionStageHooks,omitempty"`

// containerPlatformState holds platform-specific container state.
containerPlatformState
Expand All @@ -211,7 +211,7 @@ type ExecSession struct {
// It is stored, read-only, on disk
// easyjson:json
type ContainerConfig struct {
Spec *spec.Spec `json:"spec"`
Spec *rspec.Spec `json:"spec"`
ID string `json:"id"`
Name string `json:"name"`
// Full ID of the pood the container belongs to
Expand Down Expand Up @@ -403,8 +403,8 @@ func (c *Container) Config() *ContainerConfig {
// Spec returns the container's OCI runtime spec
// The spec returned is the one used to create the container. The running
// spec may differ slightly as mounts are added based on the image
func (c *Container) Spec() *spec.Spec {
returnSpec := new(spec.Spec)
func (c *Container) Spec() *rspec.Spec {
returnSpec := new(rspec.Spec)
deepcopier.Copy(c.config.Spec).To(returnSpec)

return returnSpec
Expand All @@ -413,11 +413,11 @@ func (c *Container) Spec() *spec.Spec {
// specFromState returns the unmarshalled json config of the container. If the
// config does not exist (e.g., because the container was never started) return
// the spec from the config.
func (c *Container) specFromState() (*spec.Spec, error) {
func (c *Container) specFromState() (*rspec.Spec, error) {
returnSpec := c.config.Spec

if f, err := os.Open(c.state.ConfigPath); err == nil {
returnSpec = new(spec.Spec)
returnSpec = new(rspec.Spec)
content, err := ioutil.ReadAll(f)
if err != nil {
return nil, errors.Wrapf(err, "error reading container config")
Expand Down Expand Up @@ -679,6 +679,11 @@ func (c *Container) RuntimeName() string {
return c.runtime.ociRuntime.name
}

// Dangling returns false. Provided to satisfy filterable.
func (c *Container) Dangling() bool {
return false
}

// Runtime spec accessors
// Unlocked

Expand Down Expand Up @@ -1063,7 +1068,7 @@ func networkDisabled(c *Container) (bool, error) {
}
if !c.config.PostConfigureNetNS {
for _, ns := range c.config.Spec.Linux.Namespaces {
if ns.Type == spec.NetworkNamespace {
if ns.Type == rspec.NetworkNamespace {
return ns.Path == "", nil
}
}
Expand All @@ -1085,3 +1090,21 @@ func (c *Container) ContainerState() (*ContainerState, error) {
deepcopier.Copy(c.state).To(returnConfig)
return c.state, nil
}


// Ancestors returns the ImageId and ImageName for the Rootfs of the container
func (c Container) Ancestors() []string {
return []string{
c.config.RootfsImageID,
c.config.RootfsImageName,
}
}

// Mounts returns the mounts for the container
func (c Container) Mounts() []rspec.Mount {
mounts := make([]rspec.Mount, len(c.config.Spec.Mounts))
for _, mount := range c.config.Spec.Mounts {
mounts = append(mounts, mount)
}
return mounts
}
81 changes: 81 additions & 0 deletions libpod/filters.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
package libpod

import (
"strings"
"time"
)

type (
// Filterable defines items to be filtered for CLI and Varlink
Filterable interface{}
)

// Filter defines type of function returned to perform constraint checking
type Filter func(f Filterable) bool

// BeforeFilter used to filter containers created before target time
func BeforeFilter(target time.Time) (Filter, error) {
return func(f Filterable) bool {
if m, ok := f.(interface{ CreatedTime() time.Time }); ok {
return target.After(m.CreatedTime())
} else if m, ok := f.(interface{ Created() time.Time }); ok {
return target.After(m.Created())
} else {
return false
}
}, nil
}

// SinceFilter used to filterable containers created since target time
func SinceFilter(target time.Time) (Filter, error) {
return func(f Filterable) bool {
if m, ok := f.(interface{ CreatedTime() time.Time }); ok {
return m.CreatedTime().Before(target)
} else if m, ok := f.(interface{ Created() time.Time }); ok {
return m.Created().Before(target)
} else {
return false
}
}, nil
}

// IDFilter used to filter on target ID
func IDFilter(target string) (Filter, error) {
return func(f Filterable) bool {
if m, ok := f.(interface{ ID() string }); ok {
return strings.Contains(m.ID(), target)
}
return false
}, nil
}

// LabelFilter allows you to filterable by images labels key and/or value
func LabelFilter(target string) (Filter, error) {
return func(f Filterable) bool {
if m, ok := f.(interface{ Labels() map[string]string }); ok {
var targets = strings.Split(target, "=")
var key = targets[0]
var value = ""
if len(targets) > 1 {
value = targets[1]
}

labels := m.Labels()
if len(strings.TrimSpace(labels[key])) > 0 && len(strings.TrimSpace(value)) == 0 {
return true
}
return labels[key] == value
}
return false
}, nil
}

// NameFilter used to filter on target's name
func NameFilter(target string) (Filter, error) {
return func(f Filterable) bool {
if m, ok := f.(interface{ Name() string }); ok {
return strings.Contains(m.Name(), target)
}
return false
}, nil
}
Loading