Merge pull request #7867 from vrothberg/fix-7837

remote: fix name and ID collisions of containers and pods
This commit is contained in:
OpenShift Merge Robot 2020-10-02 07:29:46 -04:00 committed by GitHub
commit ff3aa2b3d1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 68 additions and 24 deletions

View File

@ -2,74 +2,118 @@ package tunnel
import ( import (
"context" "context"
"strings"
"github.com/containers/podman/v2/libpod/define" "github.com/containers/podman/v2/libpod/define"
"github.com/containers/podman/v2/pkg/bindings" "github.com/containers/podman/v2/pkg/bindings"
"github.com/containers/podman/v2/pkg/bindings/containers" "github.com/containers/podman/v2/pkg/bindings/containers"
"github.com/containers/podman/v2/pkg/bindings/pods" "github.com/containers/podman/v2/pkg/bindings/pods"
"github.com/containers/podman/v2/pkg/domain/entities" "github.com/containers/podman/v2/pkg/domain/entities"
"github.com/containers/podman/v2/pkg/util" "github.com/containers/podman/v2/pkg/errorhandling"
"github.com/pkg/errors" "github.com/pkg/errors"
) )
// FIXME: the `ignore` parameter is very likely wrong here as it should rather
// be used on *errors* from operations such as remove.
func getContainersByContext(contextWithConnection context.Context, all, ignore bool, namesOrIDs []string) ([]entities.ListContainer, error) { func getContainersByContext(contextWithConnection context.Context, all, ignore bool, namesOrIDs []string) ([]entities.ListContainer, error) {
var (
cons []entities.ListContainer
)
if all && len(namesOrIDs) > 0 { if all && len(namesOrIDs) > 0 {
return nil, errors.New("cannot lookup containers and all") return nil, errors.New("cannot lookup containers and all")
} }
c, err := containers.List(contextWithConnection, nil, bindings.PTrue, nil, nil, bindings.PTrue)
allContainers, err := containers.List(contextWithConnection, nil, bindings.PTrue, nil, nil, bindings.PTrue)
if err != nil { if err != nil {
return nil, err return nil, err
} }
if all { if all {
return c, err return allContainers, err
} }
for _, id := range namesOrIDs {
var found bool // Note: it would be nicer if the lists endpoint would support that as
for _, con := range c { // we could use the libpod backend for looking up containers rather
if id == con.ID || strings.HasPrefix(con.ID, id) || util.StringInSlice(id, con.Names) { // than risking diverging the local and remote lookups.
cons = append(cons, con) //
// A `--filter nameOrId=abc` that can be specified multiple times would
// be awesome to have.
filtered := []entities.ListContainer{}
for _, nameOrID := range namesOrIDs {
// First determine if the container exists by doing an inspect.
// Inspect takes supports names and IDs and let's us determine
// a containers full ID.
inspectData, err := containers.Inspect(contextWithConnection, nameOrID, bindings.PFalse)
if err != nil {
if ignore && errorhandling.Contains(err, define.ErrNoSuchCtr) {
continue
}
return nil, err
}
// Now we can do a full match of the ID to find the right
// container. Note that we *really* need a full ID match to
// prevent any ambiguities between IDs and names (see #7837).
found := false
for _, ctr := range allContainers {
if ctr.ID == inspectData.ID {
filtered = append(filtered, ctr)
found = true found = true
break break
} }
} }
if !found && !ignore { if !found && !ignore {
return nil, errors.Wrapf(define.ErrNoSuchCtr, "unable to find container %q", id) return nil, errors.Wrapf(define.ErrNoSuchCtr, "unable to find container %q", nameOrID)
} }
} }
return cons, nil return filtered, nil
} }
func getPodsByContext(contextWithConnection context.Context, all bool, namesOrIDs []string) ([]*entities.ListPodsReport, error) { func getPodsByContext(contextWithConnection context.Context, all bool, namesOrIDs []string) ([]*entities.ListPodsReport, error) {
var (
sPods []*entities.ListPodsReport
)
if all && len(namesOrIDs) > 0 { if all && len(namesOrIDs) > 0 {
return nil, errors.New("cannot lookup specific pods and all") return nil, errors.New("cannot lookup specific pods and all")
} }
fPods, err := pods.List(contextWithConnection, nil) allPods, err := pods.List(contextWithConnection, nil)
if err != nil { if err != nil {
return nil, err return nil, err
} }
if all { if all {
return fPods, nil return allPods, nil
} }
filtered := []*entities.ListPodsReport{}
// Note: it would be nicer if the lists endpoint would support that as
// we could use the libpod backend for looking up pods rather than
// risking diverging the local and remote lookups.
//
// A `--filter nameOrId=abc` that can be specified multiple times would
// be awesome to have.
for _, nameOrID := range namesOrIDs { for _, nameOrID := range namesOrIDs {
var found bool // First determine if the pod exists by doing an inspect.
for _, f := range fPods { // Inspect takes supports names and IDs and let's us determine
if f.Name == nameOrID || strings.HasPrefix(f.Id, nameOrID) { // a containers full ID.
sPods = append(sPods, f) inspectData, err := pods.Inspect(contextWithConnection, nameOrID)
if err != nil {
if errorhandling.Contains(err, define.ErrNoSuchPod) {
return nil, errors.Wrapf(define.ErrNoSuchPod, "unable to find pod %q", nameOrID)
}
return nil, err
}
// Now we can do a full match of the ID to find the right pod.
// Note that we *really* need a full ID match to prevent any
// ambiguities between IDs and names (see #7837).
found := false
for _, pod := range allPods {
if pod.Id == inspectData.ID {
filtered = append(filtered, pod)
found = true found = true
break break
} }
} }
if !found { if !found {
return nil, errors.Wrapf(define.ErrNoSuchPod, "unable to find pod %q", nameOrID) return nil, errors.Wrapf(define.ErrNoSuchPod, "unable to find pod %q", nameOrID)
} }
} }
return sPods, nil return filtered, nil
} }