aboutsummaryrefslogtreecommitdiff
path: root/pkg
diff options
context:
space:
mode:
Diffstat (limited to 'pkg')
-rw-r--r--pkg/api/handlers/libpod/manifests.go16
-rw-r--r--pkg/api/server/register_networks.go1
-rw-r--r--pkg/api/server/register_pods.go2
-rw-r--r--pkg/api/server/register_volumes.go12
-rw-r--r--pkg/bindings/network/network.go10
-rw-r--r--pkg/bindings/network/types.go3
-rw-r--r--pkg/bindings/network/types_prune_options.go16
-rw-r--r--pkg/bindings/test/networks_test.go47
-rw-r--r--pkg/domain/infra/tunnel/network.go3
-rw-r--r--pkg/registrar/registrar.go127
-rw-r--r--pkg/registrar/registrar_test.go213
11 files changed, 103 insertions, 347 deletions
diff --git a/pkg/api/handlers/libpod/manifests.go b/pkg/api/handlers/libpod/manifests.go
index 5ababc36b..6a491ae48 100644
--- a/pkg/api/handlers/libpod/manifests.go
+++ b/pkg/api/handlers/libpod/manifests.go
@@ -5,6 +5,7 @@ import (
"encoding/json"
"net/http"
+ "github.com/containers/image/v5/docker/reference"
"github.com/containers/image/v5/manifest"
"github.com/containers/image/v5/types"
"github.com/containers/podman/v3/libpod"
@@ -34,6 +35,16 @@ func ManifestCreate(w http.ResponseWriter, r *http.Request) {
errors.Wrapf(err, "failed to parse parameters for %s", r.URL.String()))
return
}
+
+ // TODO: (jhonce) When c/image is refactored the roadmap calls for this check to be pushed into that library.
+ for _, n := range query.Name {
+ if _, err := reference.ParseNormalizedNamed(n); err != nil {
+ utils.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest,
+ errors.Wrapf(err, "invalid image name %s", n))
+ return
+ }
+ }
+
rtc, err := runtime.GetConfig()
if err != nil {
utils.InternalServerError(w, err)
@@ -75,11 +86,16 @@ func ManifestInspect(w http.ResponseWriter, r *http.Request) {
utils.Error(w, "Something went wrong.", http.StatusNotFound, inspectError)
return
}
+
var list manifest.Schema2List
if err := json.Unmarshal(inspectReport, &list); err != nil {
utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "Unmarshal()"))
return
}
+ if list.Manifests == nil {
+ list.Manifests = make([]manifest.Schema2ManifestDescriptor, 0)
+ }
+
utils.WriteResponse(w, http.StatusOK, &list)
}
diff --git a/pkg/api/server/register_networks.go b/pkg/api/server/register_networks.go
index e25fd071c..dcec61bef 100644
--- a/pkg/api/server/register_networks.go
+++ b/pkg/api/server/register_networks.go
@@ -377,7 +377,6 @@ func (s *APIServer) registerNetworkHandlers(r *mux.Router) error {
// name: filters
// type: string
// description: |
- // NOT IMPLEMENTED
// Filters to process on the prune list, encoded as JSON (a map[string][]string).
// Available filters:
// - until=<timestamp> Prune networks 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.
diff --git a/pkg/api/server/register_pods.go b/pkg/api/server/register_pods.go
index 5944b98fd..3bcc50ba4 100644
--- a/pkg/api/server/register_pods.go
+++ b/pkg/api/server/register_pods.go
@@ -38,7 +38,7 @@ func (s *APIServer) registerPodsHandlers(r *mux.Router) error {
// schema:
// $ref: "#/definitions/PodSpecGenerator"
// responses:
- // 200:
+ // 201:
// schema:
// $ref: "#/definitions/IdResponse"
// 400:
diff --git a/pkg/api/server/register_volumes.go b/pkg/api/server/register_volumes.go
index 58f056626..e5d6cf195 100644
--- a/pkg/api/server/register_volumes.go
+++ b/pkg/api/server/register_volumes.go
@@ -81,6 +81,14 @@ func (s *APIServer) registerVolumeHandlers(r *mux.Router) error {
// summary: Prune volumes
// produces:
// - application/json
+ // parameters:
+ // - in: query
+ // name: filters
+ // type: string
+ // description: |
+ // JSON encoded value of filters (a map[string][]string) to match volumes against before pruning.
+ // Available filters:
+ // - label (label=<key>, label=<key>=<value>, label!=<key>, or label!=<key>=<value>) Prune volumes with (or without, in case label!=... is used) the specified labels.
// responses:
// '200':
// "$ref": "#/responses/VolumePruneResponse"
@@ -259,8 +267,8 @@ func (s *APIServer) registerVolumeHandlers(r *mux.Router) error {
// type: string
// description: |
// JSON encoded value of filters (a map[string][]string) to match volumes against before pruning.
- //
- // Note: No filters are currently supported and any filters specified will cause an error response.
+ // Available filters:
+ // - label (label=<key>, label=<key>=<value>, label!=<key>, or label!=<key>=<value>) Prune volumes with (or without, in case label!=... is used) the specified labels.
// responses:
// '200':
// "$ref": "#/responses/DockerVolumePruneResponse"
diff --git a/pkg/bindings/network/network.go b/pkg/bindings/network/network.go
index 6f3aa8594..17451c273 100644
--- a/pkg/bindings/network/network.go
+++ b/pkg/bindings/network/network.go
@@ -184,7 +184,13 @@ func Exists(ctx context.Context, nameOrID string, options *ExistsOptions) (bool,
// Prune removes unused CNI networks
func Prune(ctx context.Context, options *PruneOptions) ([]*entities.NetworkPruneReport, error) {
- // TODO Filters is not implemented
+ if options == nil {
+ options = new(PruneOptions)
+ }
+ params, err := options.ToParams()
+ if err != nil {
+ return nil, err
+ }
var (
prunedNetworks []*entities.NetworkPruneReport
)
@@ -193,7 +199,7 @@ func Prune(ctx context.Context, options *PruneOptions) ([]*entities.NetworkPrune
return nil, err
}
- response, err := conn.DoRequest(nil, http.MethodPost, "/networks/prune", nil, nil)
+ response, err := conn.DoRequest(nil, http.MethodPost, "/networks/prune", params, nil)
if err != nil {
return nil, err
}
diff --git a/pkg/bindings/network/types.go b/pkg/bindings/network/types.go
index 47dce67c7..e62ae8f52 100644
--- a/pkg/bindings/network/types.go
+++ b/pkg/bindings/network/types.go
@@ -79,4 +79,7 @@ type ExistsOptions struct {
// PruneOptions are optional options for removing unused
// CNI networks
type PruneOptions struct {
+ // Filters are applied to the prune of networks to be more
+ // specific on choosing
+ Filters map[string][]string
}
diff --git a/pkg/bindings/network/types_prune_options.go b/pkg/bindings/network/types_prune_options.go
index 84e1a8b32..f17e09d69 100644
--- a/pkg/bindings/network/types_prune_options.go
+++ b/pkg/bindings/network/types_prune_options.go
@@ -19,3 +19,19 @@ func (o *PruneOptions) Changed(fieldName string) bool {
func (o *PruneOptions) ToParams() (url.Values, error) {
return util.ToParams(o)
}
+
+// WithFilters
+func (o *PruneOptions) WithFilters(value map[string][]string) *PruneOptions {
+ v := value
+ o.Filters = v
+ return o
+}
+
+// GetFilters
+func (o *PruneOptions) GetFilters() map[string][]string {
+ var filters map[string][]string
+ if o.Filters == nil {
+ return filters
+ }
+ return o.Filters
+}
diff --git a/pkg/bindings/test/networks_test.go b/pkg/bindings/test/networks_test.go
index ef20235ae..df7d7cd1c 100644
--- a/pkg/bindings/test/networks_test.go
+++ b/pkg/bindings/test/networks_test.go
@@ -37,6 +37,53 @@ var _ = Describe("Podman networks", func() {
bt.cleanup()
})
+ It("podman prune unused networks with filters", func() {
+ name := "foobar"
+ opts := network.CreateOptions{
+ Name: &name,
+ }
+ _, err = network.Create(connText, &opts)
+ Expect(err).To(BeNil())
+
+ // Invalid filters should return error
+ filtersIncorrect := map[string][]string{
+ "status": {"dummy"},
+ }
+ _, err = network.Prune(connText, new(network.PruneOptions).WithFilters(filtersIncorrect))
+ Expect(err).ToNot(BeNil())
+
+ // List filter params should not work with prune.
+ filtersIncorrect = map[string][]string{
+ "name": {name},
+ }
+ _, err = network.Prune(connText, new(network.PruneOptions).WithFilters(filtersIncorrect))
+ Expect(err).ToNot(BeNil())
+
+ // Mismatched label, correct filter params => no network should be pruned.
+ filtersIncorrect = map[string][]string{
+ "label": {"xyz"},
+ }
+ pruneResponse, err := network.Prune(connText, new(network.PruneOptions).WithFilters(filtersIncorrect))
+ Expect(err).To(BeNil())
+ Expect(len(pruneResponse)).To(Equal(0))
+
+ // Mismatched until, correct filter params => no network should be pruned.
+ filters := map[string][]string{
+ "until": {"50"}, // January 1, 1970
+ }
+ pruneResponse, err = network.Prune(connText, new(network.PruneOptions).WithFilters(filters))
+ Expect(err).To(BeNil())
+ Expect(len(pruneResponse)).To(Equal(0))
+
+ // Valid filter params => network should be pruned now.
+ filters = map[string][]string{
+ "until": {"5000000000"}, //June 11, 2128
+ }
+ pruneResponse, err = network.Prune(connText, new(network.PruneOptions).WithFilters(filters))
+ Expect(err).To(BeNil())
+ Expect(len(pruneResponse)).To(Equal(1))
+ })
+
It("create network", func() {
// create a network with blank config should work
_, err = network.Create(connText, &network.CreateOptions{})
diff --git a/pkg/domain/infra/tunnel/network.go b/pkg/domain/infra/tunnel/network.go
index adf34460c..7e59e44c2 100644
--- a/pkg/domain/infra/tunnel/network.go
+++ b/pkg/domain/infra/tunnel/network.go
@@ -92,5 +92,6 @@ func (ic *ContainerEngine) NetworkExists(ctx context.Context, networkname string
// Network prune removes unused cni networks
func (ic *ContainerEngine) NetworkPrune(ctx context.Context, options entities.NetworkPruneOptions) ([]*entities.NetworkPruneReport, error) {
- return network.Prune(ic.ClientCtx, nil)
+ opts := new(network.PruneOptions).WithFilters(options.Filters)
+ return network.Prune(ic.ClientCtx, opts)
}
diff --git a/pkg/registrar/registrar.go b/pkg/registrar/registrar.go
deleted file mode 100644
index 1e75ee995..000000000
--- a/pkg/registrar/registrar.go
+++ /dev/null
@@ -1,127 +0,0 @@
-// Package registrar provides name registration. It reserves a name to a given key.
-package registrar
-
-import (
- "errors"
- "sync"
-)
-
-var (
- // ErrNameReserved is an error which is returned when a name is requested to be reserved that already is reserved
- ErrNameReserved = errors.New("name is reserved")
- // ErrNameNotReserved is an error which is returned when trying to find a name that is not reserved
- ErrNameNotReserved = errors.New("name is not reserved")
- // ErrNoSuchKey is returned when trying to find the names for a key which is not known
- ErrNoSuchKey = errors.New("provided key does not exist")
-)
-
-// Registrar stores indexes a list of keys and their registered names as well as indexes names and the key that they are registered to
-// Names must be unique.
-// Registrar is safe for concurrent access.
-type Registrar struct {
- idx map[string][]string
- names map[string]string
- mu sync.Mutex
-}
-
-// NewRegistrar creates a new Registrar with the an empty index
-func NewRegistrar() *Registrar {
- return &Registrar{
- idx: make(map[string][]string),
- names: make(map[string]string),
- }
-}
-
-// Reserve registers a key to a name
-// Reserve is idempotent
-// Attempting to reserve a key to a name that already exists results in an `ErrNameReserved`
-// A name reservation is globally unique
-func (r *Registrar) Reserve(name, key string) error {
- r.mu.Lock()
- defer r.mu.Unlock()
-
- if k, exists := r.names[name]; exists {
- if k != key {
- return ErrNameReserved
- }
- return nil
- }
-
- r.idx[key] = append(r.idx[key], name)
- r.names[name] = key
- return nil
-}
-
-// Release releases the reserved name
-// Once released, a name can be reserved again
-func (r *Registrar) Release(name string) {
- r.mu.Lock()
- defer r.mu.Unlock()
-
- key, exists := r.names[name]
- if !exists {
- return
- }
-
- for i, n := range r.idx[key] {
- if n != name {
- continue
- }
- r.idx[key] = append(r.idx[key][:i], r.idx[key][i+1:]...)
- break
- }
-
- delete(r.names, name)
-
- if len(r.idx[key]) == 0 {
- delete(r.idx, key)
- }
-}
-
-// Delete removes all reservations for the passed in key.
-// All names reserved to this key are released.
-func (r *Registrar) Delete(key string) {
- r.mu.Lock()
- for _, name := range r.idx[key] {
- delete(r.names, name)
- }
- delete(r.idx, key)
- r.mu.Unlock()
-}
-
-// GetNames lists all the reserved names for the given key
-func (r *Registrar) GetNames(key string) ([]string, error) {
- r.mu.Lock()
- defer r.mu.Unlock()
-
- names, exists := r.idx[key]
- if !exists {
- return nil, ErrNoSuchKey
- }
- return names, nil
-}
-
-// Get returns the key that the passed in name is reserved to
-func (r *Registrar) Get(name string) (string, error) {
- r.mu.Lock()
- key, exists := r.names[name]
- r.mu.Unlock()
-
- if !exists {
- return "", ErrNameNotReserved
- }
- return key, nil
-}
-
-// GetAll returns all registered names
-func (r *Registrar) GetAll() map[string][]string {
- out := make(map[string][]string)
-
- r.mu.Lock()
- // copy index into out
- for id, names := range r.idx {
- out[id] = names
- }
- r.mu.Unlock()
- return out
-}
diff --git a/pkg/registrar/registrar_test.go b/pkg/registrar/registrar_test.go
deleted file mode 100644
index dc9942e80..000000000
--- a/pkg/registrar/registrar_test.go
+++ /dev/null
@@ -1,213 +0,0 @@
-package registrar_test
-
-import (
- "testing"
-
- "github.com/containers/podman/v3/pkg/registrar"
- . "github.com/containers/podman/v3/test/framework"
- . "github.com/onsi/ginkgo"
- . "github.com/onsi/gomega"
-)
-
-// TestRegistrar runs the created specs
-func TestRegistrar(t *testing.T) {
- RegisterFailHandler(Fail)
- RunSpecs(t, "Registrar")
-}
-
-// nolint: gochecknoglobals
-var t *TestFramework
-
-var _ = BeforeSuite(func() {
- t = NewTestFramework(NilFunc, NilFunc)
- t.Setup()
-})
-
-var _ = AfterSuite(func() {
- t.Teardown()
-})
-
-// The actual test suite
-var _ = t.Describe("Registrar", func() {
- // Constant test data needed by some tests
- const (
- testKey = "testKey"
- testName = "testName"
- anotherKey = "anotherKey"
- )
-
- // The system under test
- var sut *registrar.Registrar
-
- // Prepare the system under test and register a test name and key before
- // each test
- BeforeEach(func() {
- sut = registrar.NewRegistrar()
- Expect(sut.Reserve(testName, testKey)).To(BeNil())
- })
-
- t.Describe("Reserve", func() {
- It("should succeed to reserve a new registrar", func() {
- // Given
- // When
- err := sut.Reserve("name", "key")
-
- // Then
- Expect(err).To(BeNil())
- })
-
- It("should succeed to reserve a registrar twice", func() {
- // Given
- // When
- err := sut.Reserve(testName, testKey)
-
- // Then
- Expect(err).To(BeNil())
- })
-
- It("should fail to reserve an already reserved registrar", func() {
- // Given
- // When
- err := sut.Reserve(testName, anotherKey)
-
- // Then
- Expect(err).NotTo(BeNil())
- Expect(err).To(Equal(registrar.ErrNameReserved))
- })
- })
-
- t.Describe("Release", func() {
- It("should succeed to release a registered registrar multiple times", func() {
- // Given
- // When
- // Then
- sut.Release(testName)
- sut.Release(testName)
- })
-
- It("should succeed to release a unknown registrar multiple times", func() {
- // Given
- // When
- // Then
- sut.Release(anotherKey)
- sut.Release(anotherKey)
- })
-
- It("should succeed to release and re-register a registrar", func() {
- // Given
- // When
- sut.Release(testName)
- err := sut.Reserve(testName, testKey)
-
- // Then
- Expect(err).To(BeNil())
- })
- })
-
- t.Describe("GetNames", func() {
- It("should succeed to retrieve a single name for a registrar", func() {
- // Given
- // When
- names, err := sut.GetNames(testKey)
-
- // Then
- Expect(err).To(BeNil())
- Expect(len(names)).To(Equal(1))
- Expect(names[0]).To(Equal(testName))
- })
-
- It("should succeed to retrieve all names for a registrar", func() {
- // Given
- testNames := []string{"test1", "test2"}
- for _, name := range testNames {
- Expect(sut.Reserve(name, anotherKey)).To(BeNil())
- }
-
- // When
- names, err := sut.GetNames(anotherKey)
-
- // Then
- Expect(err).To(BeNil())
- Expect(len(names)).To(Equal(2))
- Expect(names).To(Equal(testNames))
- })
- })
-
- t.Describe("GetNames", func() {
- It("should succeed to retrieve a single name for a registrar", func() {
- // Given
- // When
- names, err := sut.GetNames(testKey)
-
- // Then
- Expect(err).To(BeNil())
- Expect(len(names)).To(Equal(1))
- Expect(names[0]).To(Equal(testName))
- })
-
- It("should succeed to retrieve all names for a registrar", func() {
- // Given
- anotherKey := "anotherKey"
- testNames := []string{"test1", "test2"}
- for _, name := range testNames {
- Expect(sut.Reserve(name, anotherKey)).To(BeNil())
- }
-
- // When
- names, err := sut.GetNames(anotherKey)
-
- // Then
- Expect(err).To(BeNil())
- Expect(len(names)).To(Equal(2))
- Expect(names).To(Equal(testNames))
- })
- })
-
- t.Describe("Delete", func() {
- It("should succeed to delete a registrar", func() {
- // Given
- // When
- sut.Delete(testKey)
-
- // Then
- names, err := sut.GetNames(testKey)
- Expect(len(names)).To(BeZero())
- Expect(err).To(Equal(registrar.ErrNoSuchKey))
- })
- })
-
- t.Describe("Get", func() {
- It("should succeed to get a key for a registrar", func() {
- // Given
- // When
- key, err := sut.Get(testName)
-
- // Then
- Expect(err).To(BeNil())
- Expect(key).To(Equal(testKey))
- })
-
- It("should fail to get a key for a not existing registrar", func() {
- // Given
- // When
- key, err := sut.Get("notExistingName")
-
- // Then
- Expect(key).To(BeEmpty())
- Expect(err).To(Equal(registrar.ErrNameNotReserved))
- })
- })
-
- t.Describe("GetAll", func() {
- It("should succeed to get all names", func() {
- // Given
- // When
- names := sut.GetAll()
-
- // Then
- Expect(len(names)).To(Equal(1))
- Expect(len(names[testKey])).To(Equal(1))
- Expect(names[testKey][0]).To(Equal(testName))
- })
- })
-})