aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOpenShift Merge Robot <openshift-merge-robot@users.noreply.github.com>2020-08-10 12:59:06 -0400
committerGitHub <noreply@github.com>2020-08-10 12:59:06 -0400
commit68fd9aa2cf67a749258ccdc6fa8fd89c2557ebfc (patch)
treec3b6d5d3f767326407e80f54324acb45daa0fa45
parent5ba21849a517659203a5879553f5dfb20963b7b5 (diff)
parent569854d6348e1cd74e8d654c88720e5517898f1a (diff)
downloadpodman-68fd9aa2cf67a749258ccdc6fa8fd89c2557ebfc.tar.gz
podman-68fd9aa2cf67a749258ccdc6fa8fd89c2557ebfc.tar.bz2
podman-68fd9aa2cf67a749258ccdc6fa8fd89c2557ebfc.zip
Merge pull request #7223 from mheon/fix_7214
Unconditionally retrieve pod names via API
-rw-r--r--libpod/boltdb_state.go55
-rw-r--r--libpod/in_memory_state.go30
-rw-r--r--libpod/runtime.go16
-rw-r--r--libpod/state.go6
-rw-r--r--pkg/api/handlers/libpod/containers.go3
-rw-r--r--pkg/api/server/register_containers.go3
-rw-r--r--pkg/bindings/containers/containers.go5
-rw-r--r--pkg/bindings/test/containers_test.go19
-rw-r--r--pkg/domain/infra/tunnel/containers.go2
-rw-r--r--pkg/domain/infra/tunnel/helpers.go2
-rw-r--r--pkg/ps/ps.go7
11 files changed, 134 insertions, 14 deletions
diff --git a/libpod/boltdb_state.go b/libpod/boltdb_state.go
index 2575f0e86..9dd5ca465 100644
--- a/libpod/boltdb_state.go
+++ b/libpod/boltdb_state.go
@@ -424,6 +424,61 @@ func (s *BoltState) SetNamespace(ns string) error {
return nil
}
+// GetName returns the name associated with a given ID. Since IDs are globally
+// unique, it works for both containers and pods.
+// Returns ErrNoSuchCtr if the ID does not exist.
+func (s *BoltState) GetName(id string) (string, error) {
+ if id == "" {
+ return "", define.ErrEmptyID
+ }
+
+ if !s.valid {
+ return "", define.ErrDBClosed
+ }
+
+ idBytes := []byte(id)
+
+ db, err := s.getDBCon()
+ if err != nil {
+ return "", err
+ }
+ defer s.deferredCloseDBCon(db)
+
+ name := ""
+
+ err = db.View(func(tx *bolt.Tx) error {
+ idBkt, err := getIDBucket(tx)
+ if err != nil {
+ return err
+ }
+
+ nameBytes := idBkt.Get(idBytes)
+ if nameBytes == nil {
+ return define.ErrNoSuchCtr
+ }
+
+ if s.namespaceBytes != nil {
+ nsBkt, err := getNSBucket(tx)
+ if err != nil {
+ return err
+ }
+
+ idNs := nsBkt.Get(idBytes)
+ if !bytes.Equal(idNs, s.namespaceBytes) {
+ return define.ErrNoSuchCtr
+ }
+ }
+
+ name = string(nameBytes)
+ return nil
+ })
+ if err != nil {
+ return "", err
+ }
+
+ return name, nil
+}
+
// Container retrieves a single container from the state by its full ID
func (s *BoltState) Container(id string) (*Container, error) {
if id == "" {
diff --git a/libpod/in_memory_state.go b/libpod/in_memory_state.go
index 2ac05e88d..0de25a6ef 100644
--- a/libpod/in_memory_state.go
+++ b/libpod/in_memory_state.go
@@ -106,6 +106,36 @@ func (s *InMemoryState) SetNamespace(ns string) error {
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 == "" {
diff --git a/libpod/runtime.go b/libpod/runtime.go
index 3021ef3f4..8a7053e33 100644
--- a/libpod/runtime.go
+++ b/libpod/runtime.go
@@ -732,6 +732,22 @@ func (r *Runtime) GetStore() storage.Store {
return r.store
}
+// GetName retrieves the name associated with a given full ID.
+// This works for both containers and pods, and does not distinguish between the
+// two.
+// If the given ID does not correspond to any existing Pod or Container,
+// ErrNoSuchCtr is returned.
+func (r *Runtime) GetName(id string) (string, error) {
+ r.lock.RLock()
+ defer r.lock.RUnlock()
+
+ if !r.valid {
+ return "", define.ErrRuntimeStopped
+ }
+
+ return r.state.GetName(id)
+}
+
// DBConfig is a set of Libpod runtime configuration settings that are saved in
// a State when it is first created, and can subsequently be retrieved.
type DBConfig struct {
diff --git a/libpod/state.go b/libpod/state.go
index 6206a2994..44632b02f 100644
--- a/libpod/state.go
+++ b/libpod/state.go
@@ -43,6 +43,12 @@ type State interface {
// containers and pods in all namespaces will be returned.
SetNamespace(ns string) error
+ // Resolve an ID into a Name. Since Podman names and IDs are globally
+ // unique between Pods and Containers, the ID may belong to either a pod
+ // or container. Despite this, we will always return ErrNoSuchCtr if the
+ // ID does not exist.
+ GetName(id string) (string, error)
+
// Return a container from the database from its full ID.
// If the container is not in the set namespace, an error will be
// returned.
diff --git a/pkg/api/handlers/libpod/containers.go b/pkg/api/handlers/libpod/containers.go
index 47ea6c40d..e343a9e0c 100644
--- a/pkg/api/handlers/libpod/containers.go
+++ b/pkg/api/handlers/libpod/containers.go
@@ -41,7 +41,6 @@ func ListContainers(w http.ResponseWriter, r *http.Request) {
Last int `schema:"last"` // alias for limit
Limit int `schema:"limit"`
Namespace bool `schema:"namespace"`
- Pod bool `schema:"pod"`
Size bool `schema:"size"`
Sync bool `schema:"sync"`
}{
@@ -72,7 +71,7 @@ func ListContainers(w http.ResponseWriter, r *http.Request) {
Size: query.Size,
Sort: "",
Namespace: query.Namespace,
- Pod: query.Pod,
+ Pod: true,
Sync: query.Sync,
}
pss, err := ps.GetContainerLists(runtime, opts)
diff --git a/pkg/api/server/register_containers.go b/pkg/api/server/register_containers.go
index edc1ee3c8..0ad5d29ea 100644
--- a/pkg/api/server/register_containers.go
+++ b/pkg/api/server/register_containers.go
@@ -661,11 +661,10 @@ func (s *APIServer) registerContainersHandlers(r *mux.Router) error {
// type: boolean
// description: Include namespace information
// default: false
- // - in: query
// name: pod
// type: boolean
// default: false
- // description: Include Pod ID and Name if applicable
+ // description: Ignored. Previously included details on pod name and ID that are currently included by default.
// - in: query
// name: size
// type: boolean
diff --git a/pkg/bindings/containers/containers.go b/pkg/bindings/containers/containers.go
index 9913b773b..c1eb23233 100644
--- a/pkg/bindings/containers/containers.go
+++ b/pkg/bindings/containers/containers.go
@@ -24,7 +24,7 @@ var (
// the most recent number of containers. The pod and size booleans indicate that pod information and rootfs
// size information should also be included. Finally, the sync bool synchronizes the OCI runtime and
// container state.
-func List(ctx context.Context, filters map[string][]string, all *bool, last *int, pod, size, sync *bool) ([]entities.ListContainer, error) { // nolint:typecheck
+func List(ctx context.Context, filters map[string][]string, all *bool, last *int, size, sync *bool) ([]entities.ListContainer, error) { // nolint:typecheck
conn, err := bindings.GetClient(ctx)
if err != nil {
return nil, err
@@ -37,9 +37,6 @@ func List(ctx context.Context, filters map[string][]string, all *bool, last *int
if last != nil {
params.Set("limit", strconv.Itoa(*last))
}
- if pod != nil {
- params.Set("pod", strconv.FormatBool(*pod))
- }
if size != nil {
params.Set("size", strconv.FormatBool(*size))
}
diff --git a/pkg/bindings/test/containers_test.go b/pkg/bindings/test/containers_test.go
index 9a188e5da..db5be4909 100644
--- a/pkg/bindings/test/containers_test.go
+++ b/pkg/bindings/test/containers_test.go
@@ -510,7 +510,7 @@ var _ = Describe("Podman containers ", func() {
Expect(err).To(BeNil())
_, err = bt.RunTopContainer(&name2, bindings.PFalse, nil)
Expect(err).To(BeNil())
- containerLatestList, err := containers.List(bt.conn, nil, nil, &latestContainers, nil, nil, nil)
+ containerLatestList, err := containers.List(bt.conn, nil, nil, &latestContainers, nil, nil)
Expect(err).To(BeNil())
err = containers.Kill(bt.conn, containerLatestList[0].Names[0], "SIGTERM")
Expect(err).To(BeNil())
@@ -755,8 +755,23 @@ var _ = Describe("Podman containers ", func() {
// Validate list container with id filter
filters := make(map[string][]string)
filters["id"] = []string{cid}
- c, err := containers.List(bt.conn, filters, bindings.PTrue, nil, nil, nil, nil)
+ c, err := containers.List(bt.conn, filters, bindings.PTrue, nil, nil, nil)
Expect(err).To(BeNil())
Expect(len(c)).To(Equal(1))
})
+
+ It("List containers always includes pod information", func() {
+ podName := "testpod"
+ ctrName := "testctr"
+ bt.Podcreate(&podName)
+ _, err := bt.RunTopContainer(&ctrName, bindings.PTrue, &podName)
+ Expect(err).To(BeNil())
+
+ lastNum := 1
+
+ c, err := containers.List(bt.conn, nil, bindings.PTrue, &lastNum, nil, nil)
+ Expect(err).To(BeNil())
+ Expect(len(c)).To(Equal(1))
+ Expect(c[0].PodName).To(Equal(podName))
+ })
})
diff --git a/pkg/domain/infra/tunnel/containers.go b/pkg/domain/infra/tunnel/containers.go
index d2221ab7b..cc919561f 100644
--- a/pkg/domain/infra/tunnel/containers.go
+++ b/pkg/domain/infra/tunnel/containers.go
@@ -496,7 +496,7 @@ func (ic *ContainerEngine) ContainerStart(ctx context.Context, namesOrIds []stri
}
func (ic *ContainerEngine) ContainerList(ctx context.Context, options entities.ContainerListOptions) ([]entities.ListContainer, error) {
- return containers.List(ic.ClientCxt, options.Filters, &options.All, &options.Last, &options.Pod, &options.Size, &options.Sync)
+ return containers.List(ic.ClientCxt, options.Filters, &options.All, &options.Last, &options.Size, &options.Sync)
}
func (ic *ContainerEngine) ContainerRun(ctx context.Context, opts entities.ContainerRunOptions) (*entities.ContainerRunReport, error) {
diff --git a/pkg/domain/infra/tunnel/helpers.go b/pkg/domain/infra/tunnel/helpers.go
index 91a49cd02..0c38a3326 100644
--- a/pkg/domain/infra/tunnel/helpers.go
+++ b/pkg/domain/infra/tunnel/helpers.go
@@ -20,7 +20,7 @@ func getContainersByContext(contextWithConnection context.Context, all bool, nam
if all && len(namesOrIDs) > 0 {
return nil, errors.New("cannot lookup containers and all")
}
- c, err := containers.List(contextWithConnection, nil, bindings.PTrue, nil, nil, nil, bindings.PTrue)
+ c, err := containers.List(contextWithConnection, nil, bindings.PTrue, nil, nil, bindings.PTrue)
if err != nil {
return nil, err
}
diff --git a/pkg/ps/ps.go b/pkg/ps/ps.go
index 8163d7247..4c5f60844 100644
--- a/pkg/ps/ps.go
+++ b/pkg/ps/ps.go
@@ -175,11 +175,14 @@ func ListContainerBatch(rt *libpod.Runtime, ctr *libpod.Container, opts entities
State: conState.String(),
}
if opts.Pod && len(conConfig.Pod) > 0 {
- pod, err := rt.GetPod(conConfig.Pod)
+ podName, err := rt.GetName(conConfig.Pod)
if err != nil {
+ if errors.Cause(err) == define.ErrNoSuchCtr {
+ return entities.ListContainer{}, errors.Wrapf(define.ErrNoSuchPod, "could not find container %s pod (id %s) in state", conConfig.ID, conConfig.Pod)
+ }
return entities.ListContainer{}, err
}
- ps.PodName = pod.Name()
+ ps.PodName = podName
}
if opts.Namespace {