summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xcontrib/cirrus/logformatter10
-rw-r--r--go.mod6
-rw-r--r--go.sum12
-rw-r--r--libpod/in_memory_state.go1706
-rw-r--r--libpod/runtime.go6
-rw-r--r--libpod/runtime_ctr.go14
-rw-r--r--libpod/state_test.go28
-rw-r--r--pkg/registrar/registrar.go127
-rw-r--r--pkg/registrar/registrar_test.go213
-rwxr-xr-xtest/compose/test-compose23
-rw-r--r--test/system/helpers.bash15
-rw-r--r--vendor/github.com/containers/common/version/version.go2
-rw-r--r--vendor/github.com/containers/ocicrypt/.travis.yml1
-rw-r--r--vendor/github.com/containers/ocicrypt/go.mod6
-rw-r--r--vendor/github.com/containers/ocicrypt/go.sum25
-rw-r--r--vendor/github.com/containers/ocicrypt/gpg.go4
-rw-r--r--vendor/github.com/containers/ocicrypt/utils/testing.go2
-rw-r--r--vendor/github.com/containers/ocicrypt/utils/utils.go4
-rw-r--r--vendor/golang.org/x/crypto/chacha20/chacha_arm64.go1
-rw-r--r--vendor/golang.org/x/crypto/chacha20/chacha_noasm.go1
-rw-r--r--vendor/golang.org/x/crypto/chacha20/chacha_ppc64le.go1
-rw-r--r--vendor/golang.org/x/crypto/chacha20/chacha_s390x.go1
-rw-r--r--vendor/golang.org/x/crypto/curve25519/curve25519_amd64.go1
-rw-r--r--vendor/golang.org/x/crypto/curve25519/curve25519_noasm.go1
-rw-r--r--vendor/golang.org/x/crypto/ed25519/ed25519.go1
-rw-r--r--vendor/golang.org/x/crypto/ed25519/ed25519_go113.go1
-rw-r--r--vendor/golang.org/x/crypto/internal/subtle/aliasing.go1
-rw-r--r--vendor/golang.org/x/crypto/internal/subtle/aliasing_purego.go1
-rw-r--r--vendor/golang.org/x/crypto/poly1305/bits_compat.go1
-rw-r--r--vendor/golang.org/x/crypto/poly1305/bits_go1.13.go1
-rw-r--r--vendor/golang.org/x/crypto/poly1305/mac_noasm.go1
-rw-r--r--vendor/golang.org/x/crypto/poly1305/sum_amd64.go1
-rw-r--r--vendor/golang.org/x/crypto/poly1305/sum_ppc64le.go1
-rw-r--r--vendor/golang.org/x/crypto/poly1305/sum_s390x.go1
-rw-r--r--vendor/golang.org/x/net/http2/server.go30
-rw-r--r--vendor/modules.txt8
36 files changed, 115 insertions, 2143 deletions
diff --git a/contrib/cirrus/logformatter b/contrib/cirrus/logformatter
index 3fa0e5618..5156f9f8a 100755
--- a/contrib/cirrus/logformatter
+++ b/contrib/cirrus/logformatter
@@ -243,11 +243,17 @@ END_HTML
$cirrus_task = $1;
}
- # BATS handling (used also for apiv2 tests, which emit TAP output)
- if ($line =~ /^1\.\.(\d+)$/ || $line =~ m!/test-apiv2!) {
+ # BATS handling. This will recognize num_tests both at start and end
+ if ($line =~ /^1\.\.(\d+)$/) {
$looks_like_bats = 1;
$bats_count{expected_total} = $1;
}
+ # Since the number of tests can't always be predicted, recognize
+ # some leading text strings that indicate BATS output to come.
+ elsif ($line =~ /^TAP\s+version\s/ || $line =~ m!/test-apiv2!) {
+ $looks_like_bats = 1;
+ $bats_count{expected_total} = -1; # Expect to be overridden at end!
+ }
if ($looks_like_bats) {
my $css;
diff --git a/go.mod b/go.mod
index 446056d4e..f92419519 100644
--- a/go.mod
+++ b/go.mod
@@ -11,10 +11,10 @@ require (
github.com/containernetworking/cni v0.8.1
github.com/containernetworking/plugins v0.9.1
github.com/containers/buildah v1.20.1-0.20210402144408-36a37402d0c8
- github.com/containers/common v0.35.4
+ github.com/containers/common v0.36.0
github.com/containers/conmon v2.0.20+incompatible
github.com/containers/image/v5 v5.11.0
- github.com/containers/ocicrypt v1.1.0
+ github.com/containers/ocicrypt v1.1.1
github.com/containers/psgo v1.5.2
github.com/containers/storage v1.29.0
github.com/coreos/go-systemd/v22 v22.3.1
@@ -61,7 +61,7 @@ require (
github.com/vbauerster/mpb/v6 v6.0.3
github.com/vishvananda/netlink v1.1.1-0.20201029203352-d40f9887b852
go.etcd.io/bbolt v1.3.5
- golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad
+ golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a
golang.org/x/sys v0.0.0-20210324051608-47abb6519492
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776
diff --git a/go.sum b/go.sum
index a0133b6d0..60347f84d 100644
--- a/go.sum
+++ b/go.sum
@@ -192,8 +192,9 @@ github.com/containernetworking/plugins v0.9.1 h1:FD1tADPls2EEi3flPc2OegIY1M9pUa9
github.com/containernetworking/plugins v0.9.1/go.mod h1:xP/idU2ldlzN6m4p5LmGiwRDjeJr6FLK6vuiUwoH7P8=
github.com/containers/buildah v1.20.1-0.20210402144408-36a37402d0c8 h1:RlqbDlfE3+qrq4bNTZG7NVPqCDzfZrgE/yicu0VAykQ=
github.com/containers/buildah v1.20.1-0.20210402144408-36a37402d0c8/go.mod h1:iowyscoAC5jwNDhs3c5CLGdBZ9FJk5UOoN2I5TdmXFs=
-github.com/containers/common v0.35.4 h1:szyWRncsHkBwCVpu1dkEOXUjkwCetlfcLmKJTwo1Sp8=
github.com/containers/common v0.35.4/go.mod h1:rMzxgD7nMGw++cEbsp+NZv0UJO4rgXbm7F7IbJPTwIE=
+github.com/containers/common v0.36.0 h1:7/0GM3oi2ROmKAg/8pDWJ8BU2BXdbmy7Gk2/SFCTV38=
+github.com/containers/common v0.36.0/go.mod h1:rMzxgD7nMGw++cEbsp+NZv0UJO4rgXbm7F7IbJPTwIE=
github.com/containers/conmon v2.0.20+incompatible h1:YbCVSFSCqFjjVwHTPINGdMX1F6JXHGTUje2ZYobNrkg=
github.com/containers/conmon v2.0.20+incompatible/go.mod h1:hgwZ2mtuDrppv78a/cOBNiCm6O0UMWGx1mu7P00nu5I=
github.com/containers/image/v5 v5.10.5/go.mod h1:SgIbWEedCNBbn2FI5cH0/jed1Ecy2s8XK5zTxvJTzII=
@@ -203,8 +204,9 @@ github.com/containers/libtrust v0.0.0-20190913040956-14b96171aa3b h1:Q8ePgVfHDpl
github.com/containers/libtrust v0.0.0-20190913040956-14b96171aa3b/go.mod h1:9rfv8iPl1ZP7aqh9YA68wnZv2NUDbXdcdPHVz0pFbPY=
github.com/containers/ocicrypt v1.0.1/go.mod h1:MeJDzk1RJHv89LjsH0Sp5KTY3ZYkjXO/C+bKAeWFIrc=
github.com/containers/ocicrypt v1.0.3/go.mod h1:CUBa+8MRNL/VkpxYIpaMtgn1WgXGyvPQj8jcy0EVG6g=
-github.com/containers/ocicrypt v1.1.0 h1:A6UzSUFMla92uxO43O6lm86i7evMGjTY7wTKB2DyGPY=
github.com/containers/ocicrypt v1.1.0/go.mod h1:b8AOe0YR67uU8OqfVNcznfFpAzu3rdgUV4GP9qXPfu4=
+github.com/containers/ocicrypt v1.1.1 h1:prL8l9w3ntVqXvNH1CiNn5ENjcCnr38JqpSyvKKB4GI=
+github.com/containers/ocicrypt v1.1.1/go.mod h1:Dm55fwWm1YZAjYRaJ94z2mfZikIyIN4B0oB3dj3jFxY=
github.com/containers/psgo v1.5.2 h1:3aoozst/GIwsrr/5jnFy3FrJay98uujPCu9lTuSZ/Cw=
github.com/containers/psgo v1.5.2/go.mod h1:2ubh0SsreMZjSXW1Hif58JrEcFudQyIy9EzPUWfawVU=
github.com/containers/storage v1.23.5/go.mod h1:ha26Q6ngehFNhf3AWoXldvAvwI4jFe3ETQAf/CeZPyM=
@@ -852,8 +854,9 @@ golang.org/x/crypto v0.0.0-20200423211502-4bdfaf469ed5/go.mod h1:LzIPMQfyMNhhGPh
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
-golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad h1:DN0cp81fZ3njFcrLCytUHRSUkqBjfTo4Tx9RJTWs0EY=
golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
+golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2 h1:It14KIkyBFYkHkwZ7k45minvA9aorojkyjGk9KJ5B/w=
+golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
@@ -926,8 +929,9 @@ golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwY
golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
-golang.org/x/net v0.0.0-20210224082022-3d97a244fca7 h1:OgUuv8lsRpBibGNbSizVwKWlysjaNzmC9gYMhPVfqFM=
golang.org/x/net v0.0.0-20210224082022-3d97a244fca7/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
+golang.org/x/net v0.0.0-20210226172049-e18ecbb05110 h1:qWPm9rbaAMKs8Bq/9LRpbMqxWRVUAQwMI9fVrssnTfw=
+golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
diff --git a/libpod/in_memory_state.go b/libpod/in_memory_state.go
deleted file mode 100644
index df45f8e73..000000000
--- a/libpod/in_memory_state.go
+++ /dev/null
@@ -1,1706 +0,0 @@
-package libpod
-
-import (
- "strings"
-
- "github.com/containers/podman/v3/libpod/define"
- "github.com/containers/podman/v3/pkg/registrar"
- "github.com/containers/storage/pkg/truncindex"
- "github.com/pkg/errors"
-)
-
-// TODO: Maybe separate idIndex for pod/containers
-// As of right now, partial IDs used in Lookup... need to be unique as well
-// This may be undesirable?
-
-// An InMemoryState is a purely in-memory state store
-type InMemoryState struct {
- // Maps pod ID to pod struct.
- pods map[string]*Pod
- // Maps container ID to container struct.
- containers map[string]*Container
- // Maps volume ID to volume struct
- volumes map[string]*Volume
- // Maps exec session ID to ID of associated container
- execSessions map[string]string
- // Maps container ID to a list of IDs of dependencies.
- ctrDepends map[string][]string
- // Maps volume ID to IDs of dependencies
- volumeDepends map[string][]string
- // Maps container ID to IDs of associated exec sessions.
- ctrExecSessions map[string][]string
- // Maps pod ID to a map of container ID to container struct.
- podContainers map[string]map[string]*Container
- ctrNetworks map[string][]string
- // Maps container ID to network name to list of aliases.
- ctrNetworkAliases map[string]map[string][]string
- // Global name registry - ensures name uniqueness and performs lookups.
- nameIndex *registrar.Registrar
- // Global ID registry - ensures ID uniqueness and performs lookups.
- idIndex *truncindex.TruncIndex
- // Namespace the state is joined to.
- namespace string
- // Maps namespace name to local ID and name registries for looking up
- // pods and containers in a specific namespace.
- namespaceIndexes map[string]*namespaceIndex
-}
-
-// namespaceIndex contains name and ID registries for a specific namespace.
-// This is used for namespaces lookup operations.
-type namespaceIndex struct {
- nameIndex *registrar.Registrar
- idIndex *truncindex.TruncIndex
-}
-
-// NewInMemoryState initializes a new, empty in-memory state
-func NewInMemoryState() (State, error) {
- state := new(InMemoryState)
-
- state.pods = make(map[string]*Pod)
- state.containers = make(map[string]*Container)
- state.volumes = make(map[string]*Volume)
- state.execSessions = make(map[string]string)
-
- state.ctrDepends = make(map[string][]string)
- state.volumeDepends = make(map[string][]string)
-
- state.ctrExecSessions = make(map[string][]string)
-
- state.podContainers = make(map[string]map[string]*Container)
-
- state.ctrNetworks = make(map[string][]string)
- state.ctrNetworkAliases = make(map[string]map[string][]string)
-
- state.nameIndex = registrar.NewRegistrar()
- state.idIndex = truncindex.NewTruncIndex([]string{})
-
- state.namespace = ""
-
- state.namespaceIndexes = make(map[string]*namespaceIndex)
-
- return state, nil
-}
-
-// Close the state before shutdown
-// This is a no-op as we have no backing disk
-func (s *InMemoryState) Close() error {
- return nil
-}
-
-// Refresh clears container and pod stats after a reboot
-// In-memory state won't survive a reboot so this is a no-op
-func (s *InMemoryState) Refresh() error {
- return nil
-}
-
-// GetDBConfig is not implemented for in-memory state.
-// As we do not store a config, return an empty one.
-func (s *InMemoryState) GetDBConfig() (*DBConfig, error) {
- return &DBConfig{}, nil
-}
-
-// ValidateDBConfig is not implemented for the in-memory state.
-// Since we do nothing just return no error.
-func (s *InMemoryState) ValidateDBConfig(runtime *Runtime) error {
- return nil
-}
-
-// SetNamespace sets the namespace for container and pod retrieval.
-func (s *InMemoryState) SetNamespace(ns string) error {
- s.namespace = ns
-
- return nil
-}
-
-// GetName retrieves the name associated with a given ID.
-// Works with both Container and Pod IDs.
-func (s *InMemoryState) GetName(id string) (string, error) {
- if id == "" {
- return "", define.ErrEmptyID
- }
-
- var idIndex *truncindex.TruncIndex
- if s.namespace != "" {
- nsIndex, ok := s.namespaceIndexes[s.namespace]
- if !ok {
- // We have no containers in the namespace
- // Return false
- return "", define.ErrNoSuchCtr
- }
- idIndex = nsIndex.idIndex
- } else {
- idIndex = s.idIndex
- }
-
- fullID, err := idIndex.Get(id)
- if err != nil {
- if err == truncindex.ErrNotExist {
- return "", define.ErrNoSuchCtr
- }
- return "", errors.Wrapf(err, "error performing truncindex lookup for ID %s", id)
- }
- return fullID, nil
-}
-
-// Container retrieves a container from its full ID
-func (s *InMemoryState) Container(id string) (*Container, error) {
- if id == "" {
- return nil, define.ErrEmptyID
- }
-
- ctr, ok := s.containers[id]
- if !ok {
- return nil, errors.Wrapf(define.ErrNoSuchCtr, "no container with ID %s found", id)
- }
-
- if err := s.checkNSMatch(ctr.ID(), ctr.Namespace()); err != nil {
- return nil, err
- }
-
- return ctr, nil
-}
-
-// lookupID retrieves a container or pod ID by full ID, unique partial ID, or
-// name
-func (s *InMemoryState) lookupID(idOrName string) (string, error) {
- var (
- nameIndex *registrar.Registrar
- idIndex *truncindex.TruncIndex
- )
-
- if idOrName == "" {
- return "", define.ErrEmptyID
- }
-
- if s.namespace != "" {
- nsIndex, ok := s.namespaceIndexes[s.namespace]
- if !ok {
- // We have no containers in the namespace
- // Return false
- return "", define.ErrNoSuchCtr
- }
- nameIndex = nsIndex.nameIndex
- idIndex = nsIndex.idIndex
- } else {
- nameIndex = s.nameIndex
- idIndex = s.idIndex
- }
-
- fullID, err := nameIndex.Get(idOrName)
- if err != nil {
- if err == registrar.ErrNameNotReserved {
- // What was passed is not a name, assume it's an ID
- fullID, err = idIndex.Get(idOrName)
- if err != nil {
- if err == truncindex.ErrNotExist {
- return "", define.ErrNoSuchCtr
- }
- return "", errors.Wrapf(err, "error performing truncindex lookup for ID %s", idOrName)
- }
- } else {
- return "", errors.Wrapf(err, "error performing registry lookup for ID %s", idOrName)
- }
- }
-
- return fullID, nil
-}
-
-// LookupContainerID retrieves a container ID by full ID, unique partial ID, or
-// name
-func (s *InMemoryState) LookupContainerID(idOrName string) (string, error) {
- fullID, err := s.lookupID(idOrName)
-
- switch err {
- case nil:
- _, ok := s.containers[fullID]
- if !ok {
- // It's a pod, not a container
- return "", errors.Wrapf(define.ErrNoSuchCtr, "name or ID %s is a pod, not a container", idOrName)
- }
-
- case define.ErrNoSuchCtr:
- return "", errors.Wrapf(define.ErrNoSuchCtr, "no container found with name or ID %s", idOrName)
-
- default:
- return "", err
- }
-
- return fullID, nil
-}
-
-// LookupContainer retrieves a container by full ID, unique partial ID, or name
-func (s *InMemoryState) LookupContainer(idOrName string) (*Container, error) {
- fullID, err := s.lookupID(idOrName)
-
- switch err {
- case nil:
-
- case define.ErrNoSuchCtr:
- return nil, errors.Wrapf(define.ErrNoSuchCtr, "no container found with name or ID %s", idOrName)
-
- default:
- return nil, err
- }
-
- ctr, ok := s.containers[fullID]
- if !ok {
- // It's a pod, not a container
- return nil, errors.Wrapf(define.ErrNoSuchCtr, "name or ID %s is a pod, not a container", idOrName)
- }
-
- return ctr, nil
-}
-
-// HasContainer checks if a container with the given ID is present in the state
-func (s *InMemoryState) HasContainer(id string) (bool, error) {
- if id == "" {
- return false, define.ErrEmptyID
- }
-
- ctr, ok := s.containers[id]
- if !ok || (s.namespace != "" && s.namespace != ctr.config.Namespace) {
- return false, nil
- }
-
- return true, nil
-}
-
-// AddContainer adds a container to the state
-// Containers in a pod cannot be added to the state
-func (s *InMemoryState) AddContainer(ctr *Container) error {
- if !ctr.valid {
- return errors.Wrapf(define.ErrCtrRemoved, "container with ID %s is not valid", ctr.ID())
- }
-
- if _, ok := s.containers[ctr.ID()]; ok {
- return errors.Wrapf(define.ErrCtrExists, "container with ID %s already exists in state", ctr.ID())
- }
-
- if ctr.config.Pod != "" {
- return errors.Wrapf(define.ErrInvalidArg, "cannot add a container that is in a pod with AddContainer, use AddContainerToPod")
- }
-
- if err := s.checkNSMatch(ctr.ID(), ctr.Namespace()); err != nil {
- return err
- }
-
- // Check networks
- for _, net := range ctr.config.Networks {
- if net == "" {
- return errors.Wrapf(define.ErrInvalidArg, "network names cannot be empty")
- }
- }
-
- // Check network aliases
- for network := range ctr.config.NetworkAliases {
- inNet := false
- for _, net := range ctr.config.Networks {
- if net == network {
- inNet = true
- break
- }
- }
- if !inNet {
- return errors.Wrapf(define.ErrInvalidArg, "container %s has network aliases for network %q but is not joined to network", ctr.ID(), network)
- }
- }
-
- // There are potential race conditions with this
- // But in-memory state is intended purely for testing and not production
- // use, so this should be fine.
- depCtrs := ctr.Dependencies()
- for _, depID := range depCtrs {
- depCtr, ok := s.containers[depID]
- if !ok {
- return errors.Wrapf(define.ErrNoSuchCtr, "cannot depend on nonexistent container %s", depID)
- } else if depCtr.config.Pod != "" {
- return errors.Wrapf(define.ErrInvalidArg, "cannot depend on container in a pod if not part of same pod")
- }
- if depCtr.config.Namespace != ctr.config.Namespace {
- return errors.Wrapf(define.ErrNSMismatch, "container %s is in namespace %s and cannot depend on container %s in namespace %s", ctr.ID(), ctr.config.Namespace, depID, depCtr.config.Namespace)
- }
- }
-
- if err := s.nameIndex.Reserve(ctr.Name(), ctr.ID()); err != nil {
- return errors.Wrapf(err, "error registering container name %s", ctr.Name())
- }
-
- if err := s.idIndex.Add(ctr.ID()); err != nil {
- s.nameIndex.Release(ctr.Name())
- return errors.Wrapf(err, "error registering container ID %s", ctr.ID())
- }
-
- s.containers[ctr.ID()] = ctr
-
- // If we're in a namespace, add us to that namespace's indexes
- if ctr.config.Namespace != "" {
- var nsIndex *namespaceIndex
- nsIndex, ok := s.namespaceIndexes[ctr.config.Namespace]
- if !ok {
- nsIndex = new(namespaceIndex)
- nsIndex.nameIndex = registrar.NewRegistrar()
- nsIndex.idIndex = truncindex.NewTruncIndex([]string{})
- s.namespaceIndexes[ctr.config.Namespace] = nsIndex
- }
- // Should be no errors here, the previous index adds should have caught that
- if err := nsIndex.nameIndex.Reserve(ctr.Name(), ctr.ID()); err != nil {
- return errors.Wrapf(err, "error registering container name %s", ctr.Name())
- }
- if err := nsIndex.idIndex.Add(ctr.ID()); err != nil {
- return errors.Wrapf(err, "error registering container ID %s", ctr.ID())
- }
- }
-
- // Add containers this container depends on
- for _, depCtr := range depCtrs {
- s.addCtrToDependsMap(ctr.ID(), depCtr)
- }
-
- // Add container to volume dependencies
- for _, vol := range ctr.config.NamedVolumes {
- s.addCtrToVolDependsMap(ctr.ID(), vol.Name)
- }
-
- // Add networks
- newNets := make([]string, 0, len(ctr.config.Networks))
- for _, net := range ctr.config.Networks {
- if net == "" {
- return define.ErrInvalidArg
- }
- newNets = append(newNets, net)
- }
- s.ctrNetworks[ctr.ID()] = newNets
-
- // Add network aliases
- s.ctrNetworkAliases[ctr.ID()] = ctr.config.NetworkAliases
-
- return nil
-}
-
-// RemoveContainer removes a container from the state
-// The container will only be removed from the state, not from the pod the container belongs to
-func (s *InMemoryState) RemoveContainer(ctr *Container) error {
- // Almost no validity checks are performed, to ensure we can kick
- // misbehaving containers out of the state
-
- if err := s.checkNSMatch(ctr.ID(), ctr.Namespace()); err != nil {
- return err
- }
-
- // Ensure we don't remove a container which other containers depend on
- deps, ok := s.ctrDepends[ctr.ID()]
- if ok && len(deps) != 0 {
- depsStr := strings.Join(deps, ", ")
- return errors.Wrapf(define.ErrDepExists, "the following containers depend on container %s: %s", ctr.ID(), depsStr)
- }
-
- // Ensure we don't have active exec sessions
- ctrSessions := s.ctrExecSessions[ctr.ID()]
- if len(ctrSessions) > 0 {
- sessStr := strings.Join(ctrSessions, ", ")
- return errors.Wrapf(define.ErrCtrExists, "the following exec sessions are running for container %s: %s", ctr.ID(), sessStr)
- }
-
- if _, ok := s.containers[ctr.ID()]; !ok {
- ctr.valid = false
- return errors.Wrapf(define.ErrNoSuchCtr, "no container exists in state with ID %s", ctr.ID())
- }
-
- if err := s.idIndex.Delete(ctr.ID()); err != nil {
- return errors.Wrapf(err, "error removing container ID from index")
- }
- delete(s.containers, ctr.ID())
- s.nameIndex.Release(ctr.Name())
-
- delete(s.ctrDepends, ctr.ID())
-
- if ctr.config.Namespace != "" {
- nsIndex, ok := s.namespaceIndexes[ctr.config.Namespace]
- if !ok {
- return errors.Wrapf(define.ErrInternal, "error retrieving index for namespace %q", ctr.config.Namespace)
- }
- if err := nsIndex.idIndex.Delete(ctr.ID()); err != nil {
- return errors.Wrapf(err, "error removing container %s from namespace ID index", ctr.ID())
- }
- nsIndex.nameIndex.Release(ctr.Name())
- }
-
- // Remove us from container dependencies
- depCtrs := ctr.Dependencies()
- for _, depCtr := range depCtrs {
- s.removeCtrFromDependsMap(ctr.ID(), depCtr)
- }
-
- // Remove this container from volume dependencies
- for _, vol := range ctr.config.NamedVolumes {
- s.removeCtrFromVolDependsMap(ctr.ID(), vol.Name)
- }
-
- // Remove our network aliases
- delete(s.ctrNetworkAliases, ctr.ID())
- delete(s.ctrNetworks, ctr.ID())
-
- return nil
-}
-
-// UpdateContainer updates a container's state
-// As all state is in-memory, no update will be required
-// As such this is a no-op
-func (s *InMemoryState) UpdateContainer(ctr *Container) error {
- // If the container is invalid, return error
- if !ctr.valid {
- return errors.Wrapf(define.ErrCtrRemoved, "container with ID %s is not valid", ctr.ID())
- }
-
- // If the container does not exist, return error
- if _, ok := s.containers[ctr.ID()]; !ok {
- ctr.valid = false
- return errors.Wrapf(define.ErrNoSuchCtr, "container with ID %s not found in state", ctr.ID())
- }
-
- return s.checkNSMatch(ctr.ID(), ctr.Namespace())
-}
-
-// SaveContainer saves a container's state
-// As all state is in-memory, any changes are always reflected as soon as they
-// are made
-// As such this is a no-op
-func (s *InMemoryState) SaveContainer(ctr *Container) error {
- // If the container is invalid, return error
- if !ctr.valid {
- return errors.Wrapf(define.ErrCtrRemoved, "container with ID %s is not valid", ctr.ID())
- }
-
- // If the container does not exist, return error
- if _, ok := s.containers[ctr.ID()]; !ok {
- ctr.valid = false
- return errors.Wrapf(define.ErrNoSuchCtr, "container with ID %s not found in state", ctr.ID())
- }
-
- return s.checkNSMatch(ctr.ID(), ctr.Namespace())
-}
-
-// ContainerInUse checks if the given container is being used by other containers
-func (s *InMemoryState) ContainerInUse(ctr *Container) ([]string, error) {
- if !ctr.valid {
- return nil, define.ErrCtrRemoved
- }
-
- // If the container does not exist, return error
- if _, ok := s.containers[ctr.ID()]; !ok {
- ctr.valid = false
- return nil, errors.Wrapf(define.ErrNoSuchCtr, "container with ID %s not found in state", ctr.ID())
- }
-
- if err := s.checkNSMatch(ctr.ID(), ctr.Namespace()); err != nil {
- return nil, err
- }
-
- arr, ok := s.ctrDepends[ctr.ID()]
- if !ok {
- return []string{}, nil
- }
-
- return arr, nil
-}
-
-// AllContainers retrieves all containers from the state
-func (s *InMemoryState) AllContainers() ([]*Container, error) {
- ctrs := make([]*Container, 0, len(s.containers))
- for _, ctr := range s.containers {
- if s.namespace == "" || ctr.config.Namespace == s.namespace {
- ctrs = append(ctrs, ctr)
- }
- }
-
- return ctrs, nil
-}
-
-// Get all networks this container is present in.
-func (s *InMemoryState) GetNetworks(ctr *Container) ([]string, error) {
- if !ctr.valid {
- return nil, define.ErrCtrRemoved
- }
-
- ctr, ok := s.containers[ctr.ID()]
- if !ok {
- ctr.valid = false
- return nil, define.ErrNoSuchCtr
- }
-
- ctrNetworks, ok := s.ctrNetworks[ctr.ID()]
- if !ok {
- return nil, define.ErrNoSuchNetwork
- }
-
- return ctrNetworks, nil
-}
-
-// GetNetworkAliases returns network aliases for the given container in the
-// given network.
-func (s *InMemoryState) GetNetworkAliases(ctr *Container, network string) ([]string, error) {
- if !ctr.valid {
- return nil, define.ErrCtrRemoved
- }
-
- if network == "" {
- return nil, errors.Wrapf(define.ErrInvalidArg, "network names must not be empty")
- }
-
- ctr, ok := s.containers[ctr.ID()]
- if !ok {
- ctr.valid = false
- return nil, define.ErrNoSuchCtr
- }
-
- inNet := false
- for _, net := range ctr.config.Networks {
- if net == network {
- inNet = true
- }
- }
- if !inNet {
- return nil, define.ErrInvalidArg
- }
-
- ctrAliases, ok := s.ctrNetworkAliases[ctr.ID()]
- if !ok {
- return []string{}, nil
- }
- netAliases, ok := ctrAliases[network]
- if !ok {
- return []string{}, nil
- }
-
- return netAliases, nil
-}
-
-// GetAllNetworkAliases gets all network aliases for the given container.
-func (s *InMemoryState) GetAllNetworkAliases(ctr *Container) (map[string][]string, error) {
- if !ctr.valid {
- return nil, define.ErrCtrRemoved
- }
-
- ctr, ok := s.containers[ctr.ID()]
- if !ok {
- ctr.valid = false
- return nil, define.ErrNoSuchCtr
- }
-
- ctrAliases, ok := s.ctrNetworkAliases[ctr.ID()]
- if !ok {
- return map[string][]string{}, nil
- }
-
- return ctrAliases, nil
-}
-
-// NetworkConnect connects to the given network
-func (s *InMemoryState) NetworkConnect(ctr *Container, network string, aliases []string) error {
- if !ctr.valid {
- return define.ErrCtrRemoved
- }
-
- if network == "" {
- return errors.Wrapf(define.ErrInvalidArg, "network names must not be empty")
- }
-
- ctr, ok := s.containers[ctr.ID()]
- if !ok {
- ctr.valid = false
- return define.ErrNoSuchCtr
- }
-
- inNet := false
- ctrNetworks, ok := s.ctrNetworks[ctr.ID()]
- if !ok {
- return define.ErrNoSuchNetwork
- }
- for _, net := range ctrNetworks {
- if net == network {
- inNet = true
- }
- }
- if inNet {
- return define.ErrNoSuchNetwork
- }
- s.ctrNetworks[ctr.ID()] = append(ctrNetworks, network)
-
- ctrAliases, ok := s.ctrNetworkAliases[ctr.ID()]
- if !ok {
- ctrAliases = make(map[string][]string)
- s.ctrNetworkAliases[ctr.ID()] = ctrAliases
- }
- ctrAliases[network] = aliases
-
- return nil
-}
-
-// Disconnect from the given network and remove all aliases in it.
-func (s *InMemoryState) NetworkDisconnect(ctr *Container, network string) error {
- if !ctr.valid {
- return define.ErrCtrRemoved
- }
-
- if network == "" {
- return errors.Wrapf(define.ErrInvalidArg, "network names must not be empty")
- }
-
- ctr, ok := s.containers[ctr.ID()]
- if !ok {
- ctr.valid = false
- return define.ErrNoSuchCtr
- }
-
- ctrNetworks, ok := s.ctrNetworks[ctr.ID()]
- if !ok {
- return define.ErrNoSuchNetwork
- }
- inNet := false
- remainingNets := make([]string, 0, len(ctrNetworks))
- for _, net := range ctrNetworks {
- if net == network {
- inNet = true
- break
- } else {
- remainingNets = append(remainingNets, net)
- }
- }
- if !inNet {
- return define.ErrNoSuchNetwork
- }
- s.ctrNetworks[ctr.ID()] = remainingNets
-
- ctrAliases, ok := s.ctrNetworkAliases[ctr.ID()]
- if !ok {
- ctrAliases = make(map[string][]string)
- s.ctrNetworkAliases[ctr.ID()] = ctrAliases
- }
- delete(ctrAliases, network)
-
- return nil
-}
-
-// GetContainerConfig returns a container config from the database by full ID
-func (s *InMemoryState) GetContainerConfig(id string) (*ContainerConfig, error) {
- ctr, err := s.LookupContainer(id)
- if err != nil {
- return nil, err
- }
-
- return ctr.Config(), nil
-}
-
-// Add an exec session to the database
-func (s *InMemoryState) AddExecSession(ctr *Container, session *ExecSession) error {
- if !ctr.valid {
- return define.ErrCtrRemoved
- }
- if session.ContainerID() != ctr.ID() {
- return errors.Wrapf(define.ErrInvalidArg, "container ID and exec session ID must match")
- }
- if _, ok := s.containers[ctr.ID()]; !ok {
- return define.ErrNoSuchCtr
- }
-
- if _, ok := s.execSessions[session.ID()]; ok {
- return define.ErrExecSessionExists
- }
-
- s.execSessions[session.ID()] = ctr.ID()
-
- ctrSessions, ok := s.ctrExecSessions[ctr.ID()]
- if !ok {
- ctrSessions = []string{}
- }
-
- ctrSessions = append(ctrSessions, session.ID())
- s.ctrExecSessions[ctr.ID()] = ctrSessions
-
- return nil
-}
-
-// Get an exec session from the database by full or partial ID.
-func (s *InMemoryState) GetExecSession(id string) (string, error) {
- if id == "" {
- return "", define.ErrEmptyID
- }
-
- session, ok := s.execSessions[id]
- if !ok {
- return "", define.ErrNoSuchExecSession
- }
-
- return session, nil
-}
-
-// RemoveExecSession removes an exec session from the database.
-func (s *InMemoryState) RemoveExecSession(session *ExecSession) error {
- if _, ok := s.execSessions[session.ID()]; !ok {
- return define.ErrNoSuchExecSession
- }
-
- ctrSessions, ok := s.ctrExecSessions[session.ContainerID()]
- // If !ok - internal state seems inconsistent, but the thing we wanted
- // to remove is gone. Continue.
- if ok {
- newSessions := []string{}
- for _, sess := range ctrSessions {
- if sess != session.ID() {
- newSessions = append(newSessions, sess)
- }
- }
- s.ctrExecSessions[session.ContainerID()] = newSessions
- }
-
- delete(s.execSessions, session.ID())
-
- return nil
-}
-
-// GetContainerExecSessions retrieves all exec sessions for the given container.
-func (s *InMemoryState) GetContainerExecSessions(ctr *Container) ([]string, error) {
- if !ctr.valid {
- return nil, define.ErrCtrRemoved
- }
- if _, ok := s.containers[ctr.ID()]; !ok {
- ctr.valid = false
- return nil, define.ErrNoSuchCtr
- }
-
- ctrSessions := s.ctrExecSessions[ctr.ID()]
-
- return ctrSessions, nil
-}
-
-// RemoveContainerExecSessions removes all exec sessions for the given
-// container.
-func (s *InMemoryState) RemoveContainerExecSessions(ctr *Container) error {
- if !ctr.valid {
- return define.ErrCtrRemoved
- }
- if _, ok := s.containers[ctr.ID()]; !ok {
- ctr.valid = false
- return define.ErrNoSuchCtr
- }
-
- ctrSessions, ok := s.ctrExecSessions[ctr.ID()]
- if !ok {
- return nil
- }
-
- for _, sess := range ctrSessions {
- if _, ok := s.execSessions[sess]; !ok {
- // We have an internal state inconsistency
- // Error out
- return errors.Wrapf(define.ErrInternal, "inconsistent database state: exec session %s is missing", sess)
- }
- delete(s.execSessions, sess)
- }
- delete(s.ctrExecSessions, ctr.ID())
-
- return nil
-}
-
-// RewriteContainerConfig rewrites a container's configuration.
-// This function is DANGEROUS, even with an in-memory state.
-// Please read the full comment on it in state.go before using it.
-func (s *InMemoryState) RewriteContainerConfig(ctr *Container, newCfg *ContainerConfig) error {
- if !ctr.valid {
- return define.ErrCtrRemoved
- }
-
- // If the container does not exist, return error
- stateCtr, ok := s.containers[ctr.ID()]
- if !ok {
- ctr.valid = false
- return errors.Wrapf(define.ErrNoSuchCtr, "container with ID %s not found in state", ctr.ID())
- }
-
- stateCtr.config = newCfg
-
- return nil
-}
-
-// SafeRewriteContainerConfig rewrites a container's configuration.
-// It's safer than RewriteContainerConfig, but still has limitations. Please
-// read the comment in state.go before using.
-func (s *InMemoryState) SafeRewriteContainerConfig(ctr *Container, oldName, newName string, newCfg *ContainerConfig) error {
- if !ctr.valid {
- return define.ErrCtrRemoved
- }
-
- if _, err := s.nameIndex.Get(newName); err == nil {
- return errors.Wrapf(define.ErrCtrExists, "name %s is in use", newName)
- }
-
- // If the container does not exist, return error
- stateCtr, ok := s.containers[ctr.ID()]
- if !ok {
- ctr.valid = false
- return errors.Wrapf(define.ErrNoSuchCtr, "container with ID %s not found in state", ctr.ID())
- }
-
- // Change name in registry.
- if s.namespace != "" {
- nsIndex, ok := s.namespaceIndexes[s.namespace]
- if !ok {
- return define.ErrInternal
- }
- nsIndex.nameIndex.Release(oldName)
- if err := nsIndex.nameIndex.Reserve(newName, ctr.ID()); err != nil {
- return errors.Wrapf(err, "error registering name %s", newName)
- }
- }
- s.nameIndex.Release(oldName)
- if err := s.nameIndex.Reserve(newName, ctr.ID()); err != nil {
- return errors.Wrapf(err, "error registering name %s", newName)
- }
-
- stateCtr.config = newCfg
-
- return nil
-}
-
-// RewritePodConfig rewrites a pod's configuration.
-// This function is DANGEROUS, even with in-memory state.
-// Please read the full comment on it in state.go before using it.
-func (s *InMemoryState) RewritePodConfig(pod *Pod, newCfg *PodConfig) error {
- if !pod.valid {
- return define.ErrPodRemoved
- }
-
- // If the pod does not exist, return error
- statePod, ok := s.pods[pod.ID()]
- if !ok {
- pod.valid = false
- return errors.Wrapf(define.ErrNoSuchPod, "pod with ID %s not found in state", pod.ID())
- }
-
- statePod.config = newCfg
-
- return nil
-}
-
-// RewriteVolumeConfig rewrites a volume's configuration.
-// This function is DANGEROUS, even with in-memory state.
-// Please read the full comment in state.go before using it.
-func (s *InMemoryState) RewriteVolumeConfig(volume *Volume, newCfg *VolumeConfig) error {
- if !volume.valid {
- return define.ErrVolumeRemoved
- }
-
- // If the volume does not exist, return error
- stateVol, ok := s.volumes[volume.Name()]
- if !ok {
- volume.valid = false
- return errors.Wrapf(define.ErrNoSuchVolume, "volume with name %q not found in state", volume.Name())
- }
-
- stateVol.config = newCfg
-
- return nil
-}
-
-// Volume retrieves a volume from its full name
-func (s *InMemoryState) Volume(name string) (*Volume, error) {
- if name == "" {
- return nil, define.ErrEmptyID
- }
-
- vol, ok := s.volumes[name]
- if !ok {
- return nil, errors.Wrapf(define.ErrNoSuchCtr, "no volume with name %s found", name)
- }
-
- return vol, nil
-}
-
-// LookupVolume finds a volume from an unambiguous partial ID.
-func (s *InMemoryState) LookupVolume(name string) (*Volume, error) {
- if name == "" {
- return nil, define.ErrEmptyID
- }
-
- vol, ok := s.volumes[name]
- if ok {
- return vol, nil
- }
-
- // Alright, we've failed to find by full name. Now comes the expensive
- // part.
- // Loop through all volumes and look for matches.
- var (
- foundMatch bool
- candidate *Volume
- )
- for volName, vol := range s.volumes {
- if strings.HasPrefix(volName, name) {
- if foundMatch {
- return nil, errors.Wrapf(define.ErrVolumeExists, "more than one result for volume name %q", name)
- }
- candidate = vol
- foundMatch = true
- }
- }
-
- if !foundMatch {
- return nil, errors.Wrapf(define.ErrNoSuchVolume, "no volume with name %q found", name)
- }
-
- return candidate, nil
-}
-
-// HasVolume checks if a volume with the given name is present in the state
-func (s *InMemoryState) HasVolume(name string) (bool, error) {
- if name == "" {
- return false, define.ErrEmptyID
- }
-
- _, ok := s.volumes[name]
- if !ok {
- return false, nil
- }
-
- return true, nil
-}
-
-// AddVolume adds a volume to the state
-func (s *InMemoryState) AddVolume(volume *Volume) error {
- if !volume.valid {
- return errors.Wrapf(define.ErrVolumeRemoved, "volume with name %s is not valid", volume.Name())
- }
-
- if _, ok := s.volumes[volume.Name()]; ok {
- return errors.Wrapf(define.ErrVolumeExists, "volume with name %s already exists in state", volume.Name())
- }
-
- s.volumes[volume.Name()] = volume
-
- return nil
-}
-
-// RemoveVolume removes a volume from the state
-func (s *InMemoryState) RemoveVolume(volume *Volume) error {
- // Ensure we don't remove a volume which containers depend on
- deps, ok := s.volumeDepends[volume.Name()]
- if ok && len(deps) != 0 {
- depsStr := strings.Join(deps, ", ")
- return errors.Wrapf(define.ErrVolumeExists, "the following containers depend on volume %s: %s", volume.Name(), depsStr)
- }
-
- if _, ok := s.volumes[volume.Name()]; !ok {
- volume.valid = false
- return errors.Wrapf(define.ErrVolumeRemoved, "no volume exists in state with name %s", volume.Name())
- }
-
- delete(s.volumes, volume.Name())
-
- return nil
-}
-
-// UpdateVolume updates a volume from the database.
-// For the in-memory state, this is a no-op.
-func (s *InMemoryState) UpdateVolume(volume *Volume) error {
- if !volume.valid {
- return define.ErrVolumeRemoved
- }
-
- if _, ok := s.volumes[volume.Name()]; !ok {
- volume.valid = false
- return errors.Wrapf(define.ErrNoSuchVolume, "volume with name %q not found in state", volume.Name())
- }
-
- return nil
-}
-
-// SaveVolume saves a volume's state to the database.
-// For the in-memory state, this is a no-op.
-func (s *InMemoryState) SaveVolume(volume *Volume) error {
- if !volume.valid {
- return define.ErrVolumeRemoved
- }
-
- if _, ok := s.volumes[volume.Name()]; !ok {
- volume.valid = false
- return errors.Wrapf(define.ErrNoSuchVolume, "volume with name %q not found in state", volume.Name())
- }
-
- return nil
-}
-
-// VolumeInUse checks if the given volume is being used by at least one container
-func (s *InMemoryState) VolumeInUse(volume *Volume) ([]string, error) {
- if !volume.valid {
- return nil, define.ErrVolumeRemoved
- }
-
- // If the volume does not exist, return error
- if _, ok := s.volumes[volume.Name()]; !ok {
- volume.valid = false
- return nil, errors.Wrapf(define.ErrNoSuchVolume, "volume with name %s not found in state", volume.Name())
- }
-
- arr, ok := s.volumeDepends[volume.Name()]
- if !ok {
- return []string{}, nil
- }
-
- return arr, nil
-}
-
-// AllVolumes returns all volumes that exist in the state
-func (s *InMemoryState) AllVolumes() ([]*Volume, error) {
- allVols := make([]*Volume, 0, len(s.volumes))
- for _, v := range s.volumes {
- allVols = append(allVols, v)
- }
-
- return allVols, nil
-}
-
-// Pod retrieves a pod from the state from its full ID
-func (s *InMemoryState) Pod(id string) (*Pod, error) {
- if id == "" {
- return nil, define.ErrEmptyID
- }
-
- pod, ok := s.pods[id]
- if !ok {
- return nil, errors.Wrapf(define.ErrNoSuchPod, "no pod with id %s found", id)
- }
-
- if err := s.checkNSMatch(pod.ID(), pod.Namespace()); err != nil {
- return nil, err
- }
-
- return pod, nil
-}
-
-// LookupPod retrieves a pod from the state from a full or unique partial ID or
-// a full name
-func (s *InMemoryState) LookupPod(idOrName string) (*Pod, error) {
- fullID, err := s.lookupID(idOrName)
-
- switch err {
- case nil:
-
- case define.ErrNoSuchCtr, define.ErrNoSuchPod:
- return nil, errors.Wrapf(define.ErrNoSuchPod, "no pod found with name or ID %s", idOrName)
-
- default:
- return nil, err
- }
-
- pod, ok := s.pods[fullID]
- if !ok {
- // It's a container not a pod
- return nil, errors.Wrapf(define.ErrNoSuchPod, "id or name %s is a container, not a pod", idOrName)
- }
-
- return pod, nil
-}
-
-// HasPod checks if a pod with the given ID is present in the state
-func (s *InMemoryState) HasPod(id string) (bool, error) {
- if id == "" {
- return false, define.ErrEmptyID
- }
-
- pod, ok := s.pods[id]
- if !ok || (s.namespace != "" && s.namespace != pod.config.Namespace) {
- return false, nil
- }
-
- return true, nil
-}
-
-// PodHasContainer checks if the given pod has a container with the given ID
-func (s *InMemoryState) PodHasContainer(pod *Pod, ctrID string) (bool, error) {
- if !pod.valid {
- return false, errors.Wrapf(define.ErrPodRemoved, "pod %s is not valid", pod.ID())
- }
-
- if ctrID == "" {
- return false, define.ErrEmptyID
- }
-
- if err := s.checkNSMatch(pod.ID(), pod.Namespace()); err != nil {
- return false, err
- }
-
- podCtrs, ok := s.podContainers[pod.ID()]
- if !ok {
- pod.valid = false
- return false, errors.Wrapf(define.ErrNoSuchPod, "no pod with ID %s found in state", pod.ID())
- }
-
- _, ok = podCtrs[ctrID]
- return ok, nil
-}
-
-// PodContainersByID returns the IDs of all containers in the given pod
-func (s *InMemoryState) PodContainersByID(pod *Pod) ([]string, error) {
- if !pod.valid {
- return nil, errors.Wrapf(define.ErrPodRemoved, "pod %s is not valid", pod.ID())
- }
-
- if err := s.checkNSMatch(pod.ID(), pod.Namespace()); err != nil {
- return nil, err
- }
-
- podCtrs, ok := s.podContainers[pod.ID()]
- if !ok {
- pod.valid = false
- return nil, errors.Wrapf(define.ErrNoSuchPod, "no pod with ID %s found in state", pod.ID())
- }
-
- length := len(podCtrs)
- if length == 0 {
- return []string{}, nil
- }
-
- ctrs := make([]string, 0, length)
- for _, ctr := range podCtrs {
- ctrs = append(ctrs, ctr.ID())
- }
-
- return ctrs, nil
-}
-
-// PodContainers retrieves the containers from a pod
-func (s *InMemoryState) PodContainers(pod *Pod) ([]*Container, error) {
- if !pod.valid {
- return nil, errors.Wrapf(define.ErrPodRemoved, "pod %s is not valid", pod.ID())
- }
-
- if err := s.checkNSMatch(pod.ID(), pod.Namespace()); err != nil {
- return nil, err
- }
-
- podCtrs, ok := s.podContainers[pod.ID()]
- if !ok {
- pod.valid = false
- return nil, errors.Wrapf(define.ErrNoSuchPod, "no pod with ID %s found in state", pod.ID())
- }
-
- length := len(podCtrs)
- if length == 0 {
- return []*Container{}, nil
- }
-
- ctrs := make([]*Container, 0, length)
- for _, ctr := range podCtrs {
- ctrs = append(ctrs, ctr)
- }
-
- return ctrs, nil
-}
-
-// AddPod adds a given pod to the state
-func (s *InMemoryState) AddPod(pod *Pod) error {
- if !pod.valid {
- return errors.Wrapf(define.ErrPodRemoved, "pod %s is not valid and cannot be added", pod.ID())
- }
-
- if err := s.checkNSMatch(pod.ID(), pod.Namespace()); err != nil {
- return err
- }
-
- if _, ok := s.pods[pod.ID()]; ok {
- return errors.Wrapf(define.ErrPodExists, "pod with ID %s already exists in state", pod.ID())
- }
-
- if _, ok := s.podContainers[pod.ID()]; ok {
- return errors.Wrapf(define.ErrPodExists, "pod with ID %s already exists in state", pod.ID())
- }
-
- if err := s.nameIndex.Reserve(pod.Name(), pod.ID()); err != nil {
- return errors.Wrapf(err, "error registering pod name %s", pod.Name())
- }
-
- if err := s.idIndex.Add(pod.ID()); err != nil {
- s.nameIndex.Release(pod.Name())
- return errors.Wrapf(err, "error registering pod ID %s", pod.ID())
- }
-
- s.pods[pod.ID()] = pod
-
- s.podContainers[pod.ID()] = make(map[string]*Container)
-
- // If we're in a namespace, add us to that namespace's indexes
- if pod.config.Namespace != "" {
- var nsIndex *namespaceIndex
- nsIndex, ok := s.namespaceIndexes[pod.config.Namespace]
- if !ok {
- nsIndex = new(namespaceIndex)
- nsIndex.nameIndex = registrar.NewRegistrar()
- nsIndex.idIndex = truncindex.NewTruncIndex([]string{})
- s.namespaceIndexes[pod.config.Namespace] = nsIndex
- }
- // Should be no errors here, the previous index adds should have caught that
- if err := nsIndex.nameIndex.Reserve(pod.Name(), pod.ID()); err != nil {
- return errors.Wrapf(err, "error registering container name %s", pod.Name())
- }
- if err := nsIndex.idIndex.Add(pod.ID()); err != nil {
- return errors.Wrapf(err, "error registering container ID %s", pod.ID())
- }
- }
-
- return nil
-}
-
-// RemovePod removes a given pod from the state
-// Only empty pods can be removed
-func (s *InMemoryState) RemovePod(pod *Pod) error {
- // Don't make many validity checks to ensure we can kick badly formed
- // pods out of the state
-
- if err := s.checkNSMatch(pod.ID(), pod.Namespace()); err != nil {
- return err
- }
-
- if _, ok := s.pods[pod.ID()]; !ok {
- pod.valid = false
- return errors.Wrapf(define.ErrNoSuchPod, "no pod exists in state with ID %s", pod.ID())
- }
- podCtrs, ok := s.podContainers[pod.ID()]
- if !ok {
- pod.valid = false
- return errors.Wrapf(define.ErrNoSuchPod, "no pod exists in state with ID %s", pod.ID())
- }
- if len(podCtrs) != 0 {
- return errors.Wrapf(define.ErrCtrExists, "pod %s is not empty and cannot be removed", pod.ID())
- }
-
- if err := s.idIndex.Delete(pod.ID()); err != nil {
- return errors.Wrapf(err, "error removing pod ID %s from index", pod.ID())
- }
- delete(s.pods, pod.ID())
- delete(s.podContainers, pod.ID())
- s.nameIndex.Release(pod.Name())
-
- if pod.config.Namespace != "" {
- nsIndex, ok := s.namespaceIndexes[pod.config.Namespace]
- if !ok {
- return errors.Wrapf(define.ErrInternal, "error retrieving index for namespace %q", pod.config.Namespace)
- }
- if err := nsIndex.idIndex.Delete(pod.ID()); err != nil {
- return errors.Wrapf(err, "error removing container %s from namespace ID index", pod.ID())
- }
- nsIndex.nameIndex.Release(pod.Name())
- }
-
- return nil
-}
-
-// RemovePodContainers removes all containers from a pod
-// This is used to simultaneously remove a number of containers with
-// many interdependencies
-// Will only remove containers if no dependencies outside of the pod are present
-func (s *InMemoryState) RemovePodContainers(pod *Pod) error {
- if !pod.valid {
- return errors.Wrapf(define.ErrPodRemoved, "pod %s is not valid", pod.ID())
- }
-
- if err := s.checkNSMatch(pod.ID(), pod.Namespace()); err != nil {
- return err
- }
-
- // Get pod containers
- podCtrs, ok := s.podContainers[pod.ID()]
- if !ok {
- pod.valid = false
- return errors.Wrapf(define.ErrNoSuchPod, "no pod exists in state with ID %s", pod.ID())
- }
-
- // Go through container dependencies. Check to see if any are outside the pod.
- for ctr := range podCtrs {
- ctrDeps, ok := s.ctrDepends[ctr]
- if ok {
- for _, dep := range ctrDeps {
- if _, ok := podCtrs[dep]; !ok {
- return errors.Wrapf(define.ErrCtrExists, "container %s has dependency %s outside of pod %s", ctr, dep, pod.ID())
- }
- }
- }
- }
-
- // All dependencies are OK to remove
- // Remove all containers
- s.podContainers[pod.ID()] = make(map[string]*Container)
- for _, ctr := range podCtrs {
- if err := s.idIndex.Delete(ctr.ID()); err != nil {
- return errors.Wrapf(err, "error removing container ID from index")
- }
- s.nameIndex.Release(ctr.Name())
-
- delete(s.containers, ctr.ID())
- delete(s.ctrDepends, ctr.ID())
- }
-
- return nil
-}
-
-// AddContainerToPod adds a container to the given pod, also adding it to the
-// state
-func (s *InMemoryState) AddContainerToPod(pod *Pod, ctr *Container) error {
- if !pod.valid {
- return errors.Wrapf(define.ErrPodRemoved, "pod %s is not valid", pod.ID())
- }
- if !ctr.valid {
- return errors.Wrapf(define.ErrCtrRemoved, "container %s is not valid", ctr.ID())
- }
-
- if ctr.config.Pod != pod.ID() {
- return errors.Wrapf(define.ErrInvalidArg, "container %s is not in pod %s", ctr.ID(), pod.ID())
- }
-
- if ctr.config.Namespace != pod.config.Namespace {
- return errors.Wrapf(define.ErrNSMismatch, "container %s is in namespace %s and pod %s is in namespace %s",
- ctr.ID(), ctr.config.Namespace, pod.ID(), pod.config.Namespace)
- }
-
- if err := s.checkNSMatch(ctr.ID(), ctr.Namespace()); err != nil {
- return err
- }
-
- // Check networks
- for _, net := range ctr.config.Networks {
- if net == "" {
- return errors.Wrapf(define.ErrInvalidArg, "network names cannot be empty")
- }
- }
-
- // Check network aliases
- for network := range ctr.config.NetworkAliases {
- inNet := false
- for _, net := range ctr.config.Networks {
- if net == network {
- inNet = true
- break
- }
- }
- if !inNet {
- return errors.Wrapf(define.ErrInvalidArg, "container %s has network aliases for network %q but is not joined to network", ctr.ID(), network)
- }
- }
-
- // Retrieve pod containers list
- podCtrs, ok := s.podContainers[pod.ID()]
- if !ok {
- pod.valid = false
- return errors.Wrapf(define.ErrPodRemoved, "pod %s not found in state", pod.ID())
- }
-
- // Is the container already in the pod?
- if _, ok = podCtrs[ctr.ID()]; ok {
- return errors.Wrapf(define.ErrCtrExists, "container with ID %s already exists in pod %s", ctr.ID(), pod.ID())
- }
-
- // There are potential race conditions with this
- // But in-memory state is intended purely for testing and not production
- // use, so this should be fine.
- depCtrs := ctr.Dependencies()
- for _, depCtr := range depCtrs {
- if _, ok = s.containers[depCtr]; !ok {
- return errors.Wrapf(define.ErrNoSuchCtr, "cannot depend on nonexistent container %s", depCtr)
- }
- depCtrStruct, ok := podCtrs[depCtr]
- if !ok {
- return errors.Wrapf(define.ErrInvalidArg, "cannot depend on container %s as it is not in pod %s", depCtr, pod.ID())
- }
- if depCtrStruct.config.Namespace != ctr.config.Namespace {
- return errors.Wrapf(define.ErrNSMismatch, "container %s is in namespace %s and cannot depend on container %s in namespace %s", ctr.ID(), ctr.config.Namespace, depCtr, depCtrStruct.config.Namespace)
- }
- }
-
- // Add container to state
- if _, ok = s.containers[ctr.ID()]; ok {
- return errors.Wrapf(define.ErrCtrExists, "container with ID %s already exists in state", ctr.ID())
- }
-
- if err := s.nameIndex.Reserve(ctr.Name(), ctr.ID()); err != nil {
- return errors.Wrapf(err, "error reserving container name %s", ctr.Name())
- }
-
- if err := s.idIndex.Add(ctr.ID()); err != nil {
- s.nameIndex.Release(ctr.Name())
- return errors.Wrapf(err, "error releasing container ID %s", ctr.ID())
- }
-
- s.containers[ctr.ID()] = ctr
-
- // Add container to pod containers
- podCtrs[ctr.ID()] = ctr
-
- // If we're in a namespace, add us to that namespace's indexes
- if ctr.config.Namespace != "" {
- var nsIndex *namespaceIndex
- nsIndex, ok := s.namespaceIndexes[ctr.config.Namespace]
- if !ok {
- nsIndex = new(namespaceIndex)
- nsIndex.nameIndex = registrar.NewRegistrar()
- nsIndex.idIndex = truncindex.NewTruncIndex([]string{})
- s.namespaceIndexes[ctr.config.Namespace] = nsIndex
- }
- // Should be no errors here, the previous index adds should have caught that
- if err := nsIndex.nameIndex.Reserve(ctr.Name(), ctr.ID()); err != nil {
- return errors.Wrapf(err, "error registering container name %s", ctr.Name())
- }
- if err := nsIndex.idIndex.Add(ctr.ID()); err != nil {
- return errors.Wrapf(err, "error registering container ID %s", ctr.ID())
- }
- }
-
- // Add containers this container depends on
- for _, depCtr := range depCtrs {
- s.addCtrToDependsMap(ctr.ID(), depCtr)
- }
-
- // Add container to volume dependencies
- for _, vol := range ctr.config.NamedVolumes {
- s.addCtrToVolDependsMap(ctr.ID(), vol.Name)
- }
-
- // Add networks
- newNets := make([]string, 0, len(ctr.config.Networks))
- for _, net := range ctr.config.Networks {
- if net == "" {
- return define.ErrInvalidArg
- }
- newNets = append(newNets, net)
- }
- s.ctrNetworks[ctr.ID()] = newNets
-
- // Add network aliases
- s.ctrNetworkAliases[ctr.ID()] = ctr.config.NetworkAliases
-
- return nil
-}
-
-// RemoveContainerFromPod removes the given container from the given pod
-// The container is also removed from the state
-func (s *InMemoryState) RemoveContainerFromPod(pod *Pod, ctr *Container) error {
- if !pod.valid {
- return errors.Wrapf(define.ErrPodRemoved, "pod %s is not valid and containers cannot be removed", pod.ID())
- }
- if !ctr.valid {
- return errors.Wrapf(define.ErrCtrRemoved, "container %s is not valid and cannot be removed from the pod", ctr.ID())
- }
-
- if err := s.checkNSMatch(ctr.ID(), ctr.Namespace()); err != nil {
- return err
- }
-
- // Ensure we don't remove a container which other containers depend on
- deps, ok := s.ctrDepends[ctr.ID()]
- if ok && len(deps) != 0 {
- depsStr := strings.Join(deps, ", ")
- return errors.Wrapf(define.ErrDepExists, "the following containers depend on container %s: %s", ctr.ID(), depsStr)
- }
-
- // Ensure we don't have active exec sessions
- ctrSessions := s.ctrExecSessions[ctr.ID()]
- if len(ctrSessions) > 0 {
- sessStr := strings.Join(ctrSessions, ", ")
- return errors.Wrapf(define.ErrCtrExists, "the following exec sessions are running for container %s: %s", ctr.ID(), sessStr)
- }
-
- // Retrieve pod containers
- podCtrs, ok := s.podContainers[pod.ID()]
- if !ok {
- pod.valid = false
- return errors.Wrapf(define.ErrPodRemoved, "pod %s has been removed", pod.ID())
- }
-
- // Does the container exist?
- if _, ok := s.containers[ctr.ID()]; !ok {
- ctr.valid = false
- return errors.Wrapf(define.ErrNoSuchCtr, "container %s does not exist in state", ctr.ID())
- }
-
- // Is the container in the pod?
- if _, ok := podCtrs[ctr.ID()]; !ok {
- return errors.Wrapf(define.ErrNoSuchCtr, "container with ID %s not found in pod %s", ctr.ID(), pod.ID())
- }
-
- // Remove container from state
- if _, ok := s.containers[ctr.ID()]; !ok {
- return errors.Wrapf(define.ErrNoSuchCtr, "no container exists in state with ID %s", ctr.ID())
- }
-
- if err := s.idIndex.Delete(ctr.ID()); err != nil {
- return errors.Wrapf(err, "error removing container ID from index")
- }
- delete(s.containers, ctr.ID())
- s.nameIndex.Release(ctr.Name())
-
- // Remove the container from the pod
- delete(podCtrs, ctr.ID())
-
- if ctr.config.Namespace != "" {
- nsIndex, ok := s.namespaceIndexes[ctr.config.Namespace]
- if !ok {
- return errors.Wrapf(define.ErrInternal, "error retrieving index for namespace %q", ctr.config.Namespace)
- }
- if err := nsIndex.idIndex.Delete(ctr.ID()); err != nil {
- return errors.Wrapf(err, "error removing container %s from namespace ID index", ctr.ID())
- }
- nsIndex.nameIndex.Release(ctr.Name())
- }
-
- // Remove us from container dependencies
- depCtrs := ctr.Dependencies()
- for _, depCtr := range depCtrs {
- s.removeCtrFromDependsMap(ctr.ID(), depCtr)
- }
-
- // Remove our network aliases
- delete(s.ctrNetworkAliases, ctr.ID())
- delete(s.ctrNetworks, ctr.ID())
-
- return nil
-}
-
-// UpdatePod updates a pod in the state
-// This is a no-op as there is no backing store
-func (s *InMemoryState) UpdatePod(pod *Pod) error {
- if !pod.valid {
- return define.ErrPodRemoved
- }
-
- if err := s.checkNSMatch(pod.ID(), pod.Namespace()); err != nil {
- return err
- }
-
- if _, ok := s.pods[pod.ID()]; !ok {
- pod.valid = false
- return errors.Wrapf(define.ErrNoSuchPod, "no pod exists in state with ID %s", pod.ID())
- }
-
- return nil
-}
-
-// SavePod updates a pod in the state
-// This is a no-op at there is no backing store
-func (s *InMemoryState) SavePod(pod *Pod) error {
- if !pod.valid {
- return define.ErrPodRemoved
- }
-
- if err := s.checkNSMatch(pod.ID(), pod.Namespace()); err != nil {
- return err
- }
-
- if _, ok := s.pods[pod.ID()]; !ok {
- pod.valid = false
- return errors.Wrapf(define.ErrNoSuchPod, "no pod exists in state with ID %s", pod.ID())
- }
-
- return nil
-}
-
-// AllPods retrieves all pods currently in the state
-func (s *InMemoryState) AllPods() ([]*Pod, error) {
- pods := make([]*Pod, 0, len(s.pods))
- for _, pod := range s.pods {
- if s.namespace != "" {
- if s.namespace == pod.config.Namespace {
- pods = append(pods, pod)
- }
- } else {
- pods = append(pods, pod)
- }
- }
-
- return pods, nil
-}
-
-// Internal Functions
-
-// Add a container to the dependency mappings
-func (s *InMemoryState) addCtrToDependsMap(ctrID, dependsID string) {
- if dependsID != "" {
- arr, ok := s.ctrDepends[dependsID]
- if !ok {
- // Do not have a mapping for that container yet
- s.ctrDepends[dependsID] = []string{ctrID}
- } else {
- // Have a mapping for the container
- arr = append(arr, ctrID)
- s.ctrDepends[dependsID] = arr
- }
- }
-}
-
-// Remove a container from dependency mappings
-func (s *InMemoryState) removeCtrFromDependsMap(ctrID, dependsID string) {
- if dependsID != "" {
- arr, ok := s.ctrDepends[dependsID]
- if !ok {
- // Internal state seems inconsistent
- // But the dependency is definitely gone
- // So just return
- return
- }
-
- newArr := make([]string, 0, len(arr))
-
- for _, id := range arr {
- if id != ctrID {
- newArr = append(newArr, id)
- }
- }
-
- s.ctrDepends[dependsID] = newArr
- }
-}
-
-// Add a container to the dependency mappings for the volume
-func (s *InMemoryState) addCtrToVolDependsMap(depCtrID, volName string) {
- if volName != "" {
- arr, ok := s.volumeDepends[volName]
- if !ok {
- // Do not have a mapping for that volume yet
- s.volumeDepends[volName] = []string{depCtrID}
- } else {
- // Have a mapping for the volume
- arr = append(arr, depCtrID)
- s.volumeDepends[volName] = arr
- }
- }
-}
-
-// Remove a container from the dependency mappings for the volume
-func (s *InMemoryState) removeCtrFromVolDependsMap(depCtrID, volName string) {
- if volName != "" {
- arr, ok := s.volumeDepends[volName]
- if !ok {
- // Internal state seems inconsistent
- // But the dependency is definitely gone
- // So just return
- return
- }
-
- newArr := make([]string, 0, len(arr))
-
- for _, id := range arr {
- if id != depCtrID {
- newArr = append(newArr, id)
- }
- }
-
- s.volumeDepends[volName] = newArr
- }
-}
-
-// Check if we can access a pod or container, or if that is blocked by
-// namespaces.
-func (s *InMemoryState) checkNSMatch(id, ns string) error {
- if s.namespace != "" && s.namespace != ns {
- return errors.Wrapf(define.ErrNSMismatch, "cannot access %s as it is in namespace %q and we are in namespace %q",
- id, ns, s.namespace)
- }
- return nil
-}
diff --git a/libpod/runtime.go b/libpod/runtime.go
index 613651790..98ca2d5a4 100644
--- a/libpod/runtime.go
+++ b/libpod/runtime.go
@@ -282,11 +282,7 @@ func makeRuntime(ctx context.Context, runtime *Runtime) (retErr error) {
// package.
switch runtime.config.Engine.StateType {
case config.InMemoryStateStore:
- state, err := NewInMemoryState()
- if err != nil {
- return err
- }
- runtime.state = state
+ return errors.Wrapf(define.ErrInvalidArg, "in-memory state is currently disabled")
case config.SQLiteStateStore:
return errors.Wrapf(define.ErrInvalidArg, "SQLite state is currently disabled")
case config.BoltDBStateStore:
diff --git a/libpod/runtime_ctr.go b/libpod/runtime_ctr.go
index 537618b65..f9b5c5c51 100644
--- a/libpod/runtime_ctr.go
+++ b/libpod/runtime_ctr.go
@@ -616,20 +616,6 @@ func (r *Runtime) removeContainer(ctx context.Context, c *Container, force, remo
}
}
- // Delete the container.
- // Not needed in Configured and Exited states, where the container
- // doesn't exist in the runtime
- if c.state.State != define.ContainerStateConfigured &&
- c.state.State != define.ContainerStateExited {
- if err := c.delete(ctx); err != nil {
- if cleanupErr == nil {
- cleanupErr = err
- } else {
- logrus.Errorf("delete container: %v", err)
- }
- }
- }
-
// Remove the container from the state
if c.config.Pod != "" {
// If we're removing the pod, the container will be evicted
diff --git a/libpod/state_test.go b/libpod/state_test.go
index 559c84d1e..4799d7b8d 100644
--- a/libpod/state_test.go
+++ b/libpod/state_test.go
@@ -28,8 +28,7 @@ const (
var (
testedStates = map[string]emptyStateFunc{
- "in-memory": getEmptyInMemoryState,
- "boltdb": getEmptyBoltState,
+ "boltdb": getEmptyBoltState,
}
)
@@ -65,31 +64,6 @@ func getEmptyBoltState() (_ State, _ string, _ lock.Manager, retErr error) {
return state, tmpDir, lockManager, nil
}
-// Get an empty in-memory state for use in tests
-func getEmptyInMemoryState() (_ State, _ string, _ lock.Manager, retErr error) {
- tmpDir, err := ioutil.TempDir("", tmpDirPrefix)
- if err != nil {
- return nil, "", nil, err
- }
- defer func() {
- if retErr != nil {
- os.RemoveAll(tmpDir)
- }
- }()
-
- state, err := NewInMemoryState()
- if err != nil {
- return nil, "", nil, err
- }
-
- lockManager, err := lock.NewInMemoryManager(16)
- if err != nil {
- return nil, "", nil, err
- }
-
- return state, tmpDir, lockManager, nil
-}
-
func runForAllStates(t *testing.T, testFunc func(*testing.T, State, lock.Manager)) {
for stateName, stateFunc := range testedStates {
state, path, manager, err := stateFunc()
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))
- })
- })
-})
diff --git a/test/compose/test-compose b/test/compose/test-compose
index 7693041ac..abb957b43 100755
--- a/test/compose/test-compose
+++ b/test/compose/test-compose
@@ -163,18 +163,21 @@ function test_port() {
local op="$2" # '=' or '~'
local expect="$3" # what to expect from curl output
- local actual=$(curl --retry 3 --retry-all-errors -s http://127.0.0.1:$port/)
- # The test is flaking with an empty result. The curl retry doesn't solve this.
- # If the result is empty sleep one second and try again.
- if [[ "$actual" == "" ]]; then
+ # -s -S means "silent, but show errors"
+ local actual=$(curl --retry 3 --retry-all-errors -s -S http://127.0.0.1:$port/)
+ local curl_rc=$?
+
+ # FIXME 2021-04-13: test is flaking, curl succeeds but returns empty result.
+ # Could it be that the container is not actually ready? Wait, and retry.
+ if [[ $curl_rc -eq 0 && -z "$actual" ]]; then
sleep 1
- local actual=$(curl --retry 3 --retry-all-errors -s http://127.0.0.1:$port/)
+ echo "# Retrying curl:"
+ actual=$(curl --retry 3 --retry-all-errors -s -S http://127.0.0.1:$port/)
+ curl_rc=$?
fi
- local curl_rc=$?
+
if [ $curl_rc -ne 0 ]; then
_show_ok 0 "$testname - curl failed with status $curl_rc"
-### docker-compose down >>$logfile 2>&1
-### exit 1
fi
case "$op" in
@@ -285,6 +288,10 @@ fi
# Too hard to precompute the number of tests; just spit it out at the end.
n_tests=0
+
+# We aren't really TAP 13; this helps logformatter recognize our output as BATS
+echo "TAP version 13"
+
for t in ${tests_to_run[@]}; do
testdir="$(dirname $t)"
testname="$(basename $testdir)"
diff --git a/test/system/helpers.bash b/test/system/helpers.bash
index 823dc3376..b9eacfd0b 100644
--- a/test/system/helpers.bash
+++ b/test/system/helpers.bash
@@ -9,6 +9,7 @@ PODMAN_TEST_IMAGE_USER=${PODMAN_TEST_IMAGE_USER:-"libpod"}
PODMAN_TEST_IMAGE_NAME=${PODMAN_TEST_IMAGE_NAME:-"testimage"}
PODMAN_TEST_IMAGE_TAG=${PODMAN_TEST_IMAGE_TAG:-"20210223"}
PODMAN_TEST_IMAGE_FQN="$PODMAN_TEST_IMAGE_REGISTRY/$PODMAN_TEST_IMAGE_USER/$PODMAN_TEST_IMAGE_NAME:$PODMAN_TEST_IMAGE_TAG"
+PODMAN_TEST_IMAGE_ID=
# Remote image that we *DO NOT* fetch or keep by default; used for testing pull
# This changed from 0 to 1 on 2021-02-24 due to multiarch considerations; it
@@ -53,11 +54,21 @@ function basic_setup() {
for line in "${lines[@]}"; do
set $line
if [ "$1" == "$PODMAN_TEST_IMAGE_FQN" ]; then
+ if [[ -z "$PODMAN_TEST_IMAGE_ID" ]]; then
+ # This will probably only trigger the 2nd time through setup
+ PODMAN_TEST_IMAGE_ID=$2
+ fi
found_needed_image=1
else
- echo "# setup(): removing stray images $1 $2" >&3
+ # Always remove image that doesn't match by name
+ echo "# setup(): removing stray image $1" >&3
run_podman rmi --force "$1" >/dev/null 2>&1 || true
- run_podman rmi --force "$2" >/dev/null 2>&1 || true
+
+ # Tagged image will have same IID as our test image; don't rmi it.
+ if [[ $2 != "$PODMAN_TEST_IMAGE_ID" ]]; then
+ echo "# setup(): removing stray image $2" >&3
+ run_podman rmi --force "$2" >/dev/null 2>&1 || true
+ fi
fi
done
diff --git a/vendor/github.com/containers/common/version/version.go b/vendor/github.com/containers/common/version/version.go
index 94f2048f3..67f454c9a 100644
--- a/vendor/github.com/containers/common/version/version.go
+++ b/vendor/github.com/containers/common/version/version.go
@@ -1,4 +1,4 @@
package version
// Version is the version of the build.
-const Version = "0.35.4"
+const Version = "0.36.0"
diff --git a/vendor/github.com/containers/ocicrypt/.travis.yml b/vendor/github.com/containers/ocicrypt/.travis.yml
index 7031d938a..e4dd4a402 100644
--- a/vendor/github.com/containers/ocicrypt/.travis.yml
+++ b/vendor/github.com/containers/ocicrypt/.travis.yml
@@ -6,6 +6,7 @@ os:
go:
- "1.13.x"
+ - "1.16.x"
matrix:
include:
diff --git a/vendor/github.com/containers/ocicrypt/go.mod b/vendor/github.com/containers/ocicrypt/go.mod
index 06a77af95..02be18591 100644
--- a/vendor/github.com/containers/ocicrypt/go.mod
+++ b/vendor/github.com/containers/ocicrypt/go.mod
@@ -13,9 +13,9 @@ require (
github.com/stefanberger/go-pkcs11uri v0.0.0-20201008174630-78d3cae3a980
github.com/stretchr/testify v1.3.0
go.mozilla.org/pkcs7 v0.0.0-20200128120323-432b2356ecb1
- golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de
- golang.org/x/sys v0.0.0-20200817155316-9781c653f443 // indirect
+ golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2
+ golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1
google.golang.org/grpc v1.33.2
gopkg.in/square/go-jose.v2 v2.5.1
- gopkg.in/yaml.v2 v2.3.0
+ gopkg.in/yaml.v2 v2.4.0
)
diff --git a/vendor/github.com/containers/ocicrypt/go.sum b/vendor/github.com/containers/ocicrypt/go.sum
index b014b76ee..7153900da 100644
--- a/vendor/github.com/containers/ocicrypt/go.sum
+++ b/vendor/github.com/containers/ocicrypt/go.sum
@@ -3,7 +3,6 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
-github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@@ -53,8 +52,8 @@ github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UV
go.mozilla.org/pkcs7 v0.0.0-20200128120323-432b2356ecb1 h1:A/5uWzF44DlIgdm/PQFwfMkW0JX+cIcQi/SwLAmZP5M=
go.mozilla.org/pkcs7 v0.0.0-20200128120323-432b2356ecb1/go.mod h1:SNgMg+EgDFwmvSmLRTNKC5fegJjB7v23qTQ0XLGUNHk=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
-golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de h1:ikNHVSjEfnvz6sxdSPCaPt572qowuyMDMJLLm3Db3ig=
-golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
+golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2 h1:It14KIkyBFYkHkwZ7k45minvA9aorojkyjGk9KJ5B/w=
+golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
@@ -63,21 +62,23 @@ golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73r
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
-golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3 h1:0GoQqolDA55aaLxZyTzK/Y2ePZzZTUrRacwib7cNsYQ=
-golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20210226172049-e18ecbb05110 h1:qWPm9rbaAMKs8Bq/9LRpbMqxWRVUAQwMI9fVrssnTfw=
+golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
-golang.org/x/sys v0.0.0-20190412213103-97732733099d h1:+R4KGOnez64A81RvjARKc4UT5/tI9ujCIVX+P5KiHuI=
-golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200817155316-9781c653f443 h1:X18bCaipMcoJGm27Nv7zr4XYPKGUy92GtqboKC2Hxaw=
-golang.org/x/sys v0.0.0-20200817155316-9781c653f443/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
+golang.org/x/sys v0.0.0-20201119102817-f84b799fce68 h1:nxC68pudNYkKU6jWhgrqdreuFiOQWj1Fs7T3VrH4Pjw=
+golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E=
+golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k=
+golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
@@ -110,7 +111,7 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/square/go-jose.v2 v2.5.1 h1:7odma5RETjNHWJnR32wx8t+Io4djHE1PqxCFx3iiZ2w=
gopkg.in/square/go-jose.v2 v2.5.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
-gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
-gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
+gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
diff --git a/vendor/github.com/containers/ocicrypt/gpg.go b/vendor/github.com/containers/ocicrypt/gpg.go
index c4d31e52d..b9d55539a 100644
--- a/vendor/github.com/containers/ocicrypt/gpg.go
+++ b/vendor/github.com/containers/ocicrypt/gpg.go
@@ -27,7 +27,7 @@ import (
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/pkg/errors"
- "golang.org/x/crypto/ssh/terminal"
+ "golang.org/x/term"
)
// GPGVersion enum representing the GPG client version to use.
@@ -387,7 +387,7 @@ func GPGGetPrivateKey(descs []ocispec.Descriptor, gpgClient GPGClient, gpgVault
fmt.Printf("Passphrase required for Key id 0x%x: \n%v", keyid, string(keyinfo))
fmt.Printf("Enter passphrase for key with Id 0x%x: ", keyid)
- password, err := terminal.ReadPassword(int(os.Stdin.Fd()))
+ password, err := term.ReadPassword(int(os.Stdin.Fd()))
fmt.Printf("\n")
if err != nil {
return nil, nil, err
diff --git a/vendor/github.com/containers/ocicrypt/utils/testing.go b/vendor/github.com/containers/ocicrypt/utils/testing.go
index e2ed4b1d8..38633b19b 100644
--- a/vendor/github.com/containers/ocicrypt/utils/testing.go
+++ b/vendor/github.com/containers/ocicrypt/utils/testing.go
@@ -67,7 +67,7 @@ func CreateRSATestKey(bits int, password []byte, pemencode bool) ([]byte, []byte
typ := "RSA PRIVATE KEY"
if len(password) > 0 {
- block, err = x509.EncryptPEMBlock(rand.Reader, typ, privData, password, x509.PEMCipherAES256)
+ block, err = x509.EncryptPEMBlock(rand.Reader, typ, privData, password, x509.PEMCipherAES256) //nolint:staticcheck // ignore SA1019, which is kept for backward compatibility
if err != nil {
return nil, nil, errors.Wrap(err, "x509.EncryptPEMBlock failed")
}
diff --git a/vendor/github.com/containers/ocicrypt/utils/utils.go b/vendor/github.com/containers/ocicrypt/utils/utils.go
index 7bc2aa28d..07fe6d367 100644
--- a/vendor/github.com/containers/ocicrypt/utils/utils.go
+++ b/vendor/github.com/containers/ocicrypt/utils/utils.go
@@ -95,11 +95,11 @@ func ParsePrivateKey(privKey, privKeyPassword []byte, prefix string) (interface{
block, _ := pem.Decode(privKey)
if block != nil {
var der []byte
- if x509.IsEncryptedPEMBlock(block) {
+ if x509.IsEncryptedPEMBlock(block) { //nolint:staticcheck // ignore SA1019, which is kept for backward compatibility
if privKeyPassword == nil {
return nil, errors.Errorf("%s: Missing password for encrypted private key", prefix)
}
- der, err = x509.DecryptPEMBlock(block, privKeyPassword)
+ der, err = x509.DecryptPEMBlock(block, privKeyPassword) //nolint:staticcheck // ignore SA1019, which is kept for backward compatibility
if err != nil {
return nil, errors.Errorf("%s: Wrong password: could not decrypt private key", prefix)
}
diff --git a/vendor/golang.org/x/crypto/chacha20/chacha_arm64.go b/vendor/golang.org/x/crypto/chacha20/chacha_arm64.go
index c474e5a80..94c71ac1a 100644
--- a/vendor/golang.org/x/crypto/chacha20/chacha_arm64.go
+++ b/vendor/golang.org/x/crypto/chacha20/chacha_arm64.go
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+//go:build go1.11 && gc && !purego
// +build go1.11,gc,!purego
package chacha20
diff --git a/vendor/golang.org/x/crypto/chacha20/chacha_noasm.go b/vendor/golang.org/x/crypto/chacha20/chacha_noasm.go
index 3e8a609fb..025b49897 100644
--- a/vendor/golang.org/x/crypto/chacha20/chacha_noasm.go
+++ b/vendor/golang.org/x/crypto/chacha20/chacha_noasm.go
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+//go:build (!arm64 && !s390x && !ppc64le) || (arm64 && !go1.11) || !gc || purego
// +build !arm64,!s390x,!ppc64le arm64,!go1.11 !gc purego
package chacha20
diff --git a/vendor/golang.org/x/crypto/chacha20/chacha_ppc64le.go b/vendor/golang.org/x/crypto/chacha20/chacha_ppc64le.go
index 2806c6325..da420b2e9 100644
--- a/vendor/golang.org/x/crypto/chacha20/chacha_ppc64le.go
+++ b/vendor/golang.org/x/crypto/chacha20/chacha_ppc64le.go
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+//go:build gc && !purego
// +build gc,!purego
package chacha20
diff --git a/vendor/golang.org/x/crypto/chacha20/chacha_s390x.go b/vendor/golang.org/x/crypto/chacha20/chacha_s390x.go
index a0774dde1..c5898db46 100644
--- a/vendor/golang.org/x/crypto/chacha20/chacha_s390x.go
+++ b/vendor/golang.org/x/crypto/chacha20/chacha_s390x.go
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+//go:build gc && !purego
// +build gc,!purego
package chacha20
diff --git a/vendor/golang.org/x/crypto/curve25519/curve25519_amd64.go b/vendor/golang.org/x/crypto/curve25519/curve25519_amd64.go
index 877b6de29..84858480d 100644
--- a/vendor/golang.org/x/crypto/curve25519/curve25519_amd64.go
+++ b/vendor/golang.org/x/crypto/curve25519/curve25519_amd64.go
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+//go:build amd64 && gc && !purego
// +build amd64,gc,!purego
package curve25519
diff --git a/vendor/golang.org/x/crypto/curve25519/curve25519_noasm.go b/vendor/golang.org/x/crypto/curve25519/curve25519_noasm.go
index 80d3300af..259728af7 100644
--- a/vendor/golang.org/x/crypto/curve25519/curve25519_noasm.go
+++ b/vendor/golang.org/x/crypto/curve25519/curve25519_noasm.go
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+//go:build !amd64 || !gc || purego
// +build !amd64 !gc purego
package curve25519
diff --git a/vendor/golang.org/x/crypto/ed25519/ed25519.go b/vendor/golang.org/x/crypto/ed25519/ed25519.go
index c7f8c7e64..71ad917da 100644
--- a/vendor/golang.org/x/crypto/ed25519/ed25519.go
+++ b/vendor/golang.org/x/crypto/ed25519/ed25519.go
@@ -5,6 +5,7 @@
// In Go 1.13, the ed25519 package was promoted to the standard library as
// crypto/ed25519, and this package became a wrapper for the standard library one.
//
+//go:build !go1.13
// +build !go1.13
// Package ed25519 implements the Ed25519 signature algorithm. See
diff --git a/vendor/golang.org/x/crypto/ed25519/ed25519_go113.go b/vendor/golang.org/x/crypto/ed25519/ed25519_go113.go
index d1448d8d2..b5974dc8b 100644
--- a/vendor/golang.org/x/crypto/ed25519/ed25519_go113.go
+++ b/vendor/golang.org/x/crypto/ed25519/ed25519_go113.go
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+//go:build go1.13
// +build go1.13
// Package ed25519 implements the Ed25519 signature algorithm. See
diff --git a/vendor/golang.org/x/crypto/internal/subtle/aliasing.go b/vendor/golang.org/x/crypto/internal/subtle/aliasing.go
index 281c27ef0..4fad24f8d 100644
--- a/vendor/golang.org/x/crypto/internal/subtle/aliasing.go
+++ b/vendor/golang.org/x/crypto/internal/subtle/aliasing.go
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+//go:build !purego
// +build !purego
// Package subtle implements functions that are often useful in cryptographic
diff --git a/vendor/golang.org/x/crypto/internal/subtle/aliasing_purego.go b/vendor/golang.org/x/crypto/internal/subtle/aliasing_purego.go
index e20a29659..80ccbed2c 100644
--- a/vendor/golang.org/x/crypto/internal/subtle/aliasing_purego.go
+++ b/vendor/golang.org/x/crypto/internal/subtle/aliasing_purego.go
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+//go:build purego
// +build purego
// Package subtle implements functions that are often useful in cryptographic
diff --git a/vendor/golang.org/x/crypto/poly1305/bits_compat.go b/vendor/golang.org/x/crypto/poly1305/bits_compat.go
index 157a69f61..45b5c966b 100644
--- a/vendor/golang.org/x/crypto/poly1305/bits_compat.go
+++ b/vendor/golang.org/x/crypto/poly1305/bits_compat.go
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+//go:build !go1.13
// +build !go1.13
package poly1305
diff --git a/vendor/golang.org/x/crypto/poly1305/bits_go1.13.go b/vendor/golang.org/x/crypto/poly1305/bits_go1.13.go
index a0a185f0f..ed52b3418 100644
--- a/vendor/golang.org/x/crypto/poly1305/bits_go1.13.go
+++ b/vendor/golang.org/x/crypto/poly1305/bits_go1.13.go
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+//go:build go1.13
// +build go1.13
package poly1305
diff --git a/vendor/golang.org/x/crypto/poly1305/mac_noasm.go b/vendor/golang.org/x/crypto/poly1305/mac_noasm.go
index af6c94f92..f184b67d9 100644
--- a/vendor/golang.org/x/crypto/poly1305/mac_noasm.go
+++ b/vendor/golang.org/x/crypto/poly1305/mac_noasm.go
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+//go:build (!amd64 && !ppc64le && !s390x) || !gc || purego
// +build !amd64,!ppc64le,!s390x !gc purego
package poly1305
diff --git a/vendor/golang.org/x/crypto/poly1305/sum_amd64.go b/vendor/golang.org/x/crypto/poly1305/sum_amd64.go
index cf3a69ed3..6d522333f 100644
--- a/vendor/golang.org/x/crypto/poly1305/sum_amd64.go
+++ b/vendor/golang.org/x/crypto/poly1305/sum_amd64.go
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+//go:build gc && !purego
// +build gc,!purego
package poly1305
diff --git a/vendor/golang.org/x/crypto/poly1305/sum_ppc64le.go b/vendor/golang.org/x/crypto/poly1305/sum_ppc64le.go
index cb4b7185d..4a069941a 100644
--- a/vendor/golang.org/x/crypto/poly1305/sum_ppc64le.go
+++ b/vendor/golang.org/x/crypto/poly1305/sum_ppc64le.go
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+//go:build gc && !purego
// +build gc,!purego
package poly1305
diff --git a/vendor/golang.org/x/crypto/poly1305/sum_s390x.go b/vendor/golang.org/x/crypto/poly1305/sum_s390x.go
index 188a665e1..62cc9f847 100644
--- a/vendor/golang.org/x/crypto/poly1305/sum_s390x.go
+++ b/vendor/golang.org/x/crypto/poly1305/sum_s390x.go
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+//go:build gc && !purego
// +build gc,!purego
package poly1305
diff --git a/vendor/golang.org/x/net/http2/server.go b/vendor/golang.org/x/net/http2/server.go
index 2aa859f76..e125bbd2a 100644
--- a/vendor/golang.org/x/net/http2/server.go
+++ b/vendor/golang.org/x/net/http2/server.go
@@ -1293,7 +1293,9 @@ func (sc *serverConn) startGracefulShutdown() {
sc.shutdownOnce.Do(func() { sc.sendServeMsg(gracefulShutdownMsg) })
}
-// After sending GOAWAY, the connection will close after goAwayTimeout.
+// After sending GOAWAY with an error code (non-graceful shutdown), the
+// connection will close after goAwayTimeout.
+//
// If we close the connection immediately after sending GOAWAY, there may
// be unsent data in our kernel receive buffer, which will cause the kernel
// to send a TCP RST on close() instead of a FIN. This RST will abort the
@@ -1629,23 +1631,37 @@ func (sc *serverConn) processSettingInitialWindowSize(val uint32) error {
func (sc *serverConn) processData(f *DataFrame) error {
sc.serveG.check()
- if sc.inGoAway && sc.goAwayCode != ErrCodeNo {
+ id := f.Header().StreamID
+ if sc.inGoAway && (sc.goAwayCode != ErrCodeNo || id > sc.maxClientStreamID) {
+ // Discard all DATA frames if the GOAWAY is due to an
+ // error, or:
+ //
+ // Section 6.8: After sending a GOAWAY frame, the sender
+ // can discard frames for streams initiated by the
+ // receiver with identifiers higher than the identified
+ // last stream.
return nil
}
- data := f.Data()
- // "If a DATA frame is received whose stream is not in "open"
- // or "half closed (local)" state, the recipient MUST respond
- // with a stream error (Section 5.4.2) of type STREAM_CLOSED."
- id := f.Header().StreamID
+ data := f.Data()
state, st := sc.state(id)
if id == 0 || state == stateIdle {
+ // Section 6.1: "DATA frames MUST be associated with a
+ // stream. If a DATA frame is received whose stream
+ // identifier field is 0x0, the recipient MUST respond
+ // with a connection error (Section 5.4.1) of type
+ // PROTOCOL_ERROR."
+ //
// Section 5.1: "Receiving any frame other than HEADERS
// or PRIORITY on a stream in this state MUST be
// treated as a connection error (Section 5.4.1) of
// type PROTOCOL_ERROR."
return ConnectionError(ErrCodeProtocol)
}
+
+ // "If a DATA frame is received whose stream is not in "open"
+ // or "half closed (local)" state, the recipient MUST respond
+ // with a stream error (Section 5.4.2) of type STREAM_CLOSED."
if st == nil || state != stateOpen || st.gotTrailerHeader || st.resetQueued {
// This includes sending a RST_STREAM if the stream is
// in stateHalfClosedLocal (which currently means that
diff --git a/vendor/modules.txt b/vendor/modules.txt
index 0f8b515e2..1bf189b86 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -93,7 +93,7 @@ github.com/containers/buildah/pkg/parse
github.com/containers/buildah/pkg/rusage
github.com/containers/buildah/pkg/supplemented
github.com/containers/buildah/util
-# github.com/containers/common v0.35.4
+# github.com/containers/common v0.36.0
github.com/containers/common/pkg/apparmor
github.com/containers/common/pkg/apparmor/internal/supported
github.com/containers/common/pkg/auth
@@ -163,7 +163,7 @@ github.com/containers/image/v5/types
github.com/containers/image/v5/version
# github.com/containers/libtrust v0.0.0-20190913040956-14b96171aa3b
github.com/containers/libtrust
-# github.com/containers/ocicrypt v1.1.0
+# github.com/containers/ocicrypt v1.1.1
github.com/containers/ocicrypt
github.com/containers/ocicrypt/blockcipher
github.com/containers/ocicrypt/config
@@ -619,7 +619,7 @@ go.opencensus.io/internal
go.opencensus.io/trace
go.opencensus.io/trace/internal
go.opencensus.io/trace/tracestate
-# golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad
+# golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2
golang.org/x/crypto/blowfish
golang.org/x/crypto/cast5
golang.org/x/crypto/chacha20
@@ -640,7 +640,7 @@ golang.org/x/crypto/ssh/agent
golang.org/x/crypto/ssh/internal/bcrypt_pbkdf
golang.org/x/crypto/ssh/knownhosts
golang.org/x/crypto/ssh/terminal
-# golang.org/x/net v0.0.0-20210224082022-3d97a244fca7
+# golang.org/x/net v0.0.0-20210226172049-e18ecbb05110
golang.org/x/net/context
golang.org/x/net/html
golang.org/x/net/html/atom