Merge pull request from mheon/fix_7214

Unconditionally retrieve pod names via API
This commit is contained in:
OpenShift Merge Robot
2020-08-10 12:59:06 -04:00
committed by GitHub
11 changed files with 134 additions and 14 deletions

@ -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 == "" {

@ -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 == "" {

@ -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 {

@ -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.

@ -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)

@ -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

@ -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))
}

@ -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))
})
})

@ -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) {

@ -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
}

@ -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 {