summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libpod/boltdb_state.go167
1 files changed, 105 insertions, 62 deletions
diff --git a/libpod/boltdb_state.go b/libpod/boltdb_state.go
index c226a0617..92a7b1538 100644
--- a/libpod/boltdb_state.go
+++ b/libpod/boltdb_state.go
@@ -382,6 +382,11 @@ func (s *BoltState) LookupContainer(idOrName string) (*Container, error) {
return err
}
+ namesBucket, err := getNamesBucket(tx)
+ if err != nil {
+ return err
+ }
+
nsBucket, err := getNSBucket(tx)
if err != nil {
return err
@@ -395,41 +400,59 @@ func (s *BoltState) LookupContainer(idOrName string) (*Container, error) {
// It might not be in our namespace, but
// getContainerFromDB() will handle that case.
id = []byte(idOrName)
- } else {
- // They did not give us a full container ID.
- // Search for partial ID or full name matches
- // Use else-if in case the name is set to a partial ID
- exists := false
- err = idBucket.ForEach(func(checkID, checkName []byte) error {
- // If the container isn't in our namespace, we
- // can't match it
- if s.namespaceBytes != nil {
- ns := nsBucket.Get(checkID)
- if !bytes.Equal(ns, s.namespaceBytes) {
- return nil
- }
+ return s.getContainerFromDB(id, ctr, ctrBucket)
+ }
+
+ // Next, check if the full name was given
+ isPod := false
+ fullID := namesBucket.Get([]byte(idOrName))
+ if fullID != nil {
+ // The name exists and maps to an ID.
+ // However, we are not yet certain the ID is a
+ // container.
+ ctrExists = ctrBucket.Bucket(fullID)
+ if ctrExists != nil {
+ // A container bucket matching the full ID was
+ // found.
+ return s.getContainerFromDB(fullID, ctr, ctrBucket)
+ }
+ // Don't error if we have a name match but it's not a
+ // container - there's a chance we have a container with
+ // an ID starting with those characters.
+ // However, so we can return a good error, note whether
+ // this is a pod.
+ isPod = true
+ }
+
+ // We were not given a full container ID or name.
+ // Search for partial ID matches.
+ exists := false
+ err = idBucket.ForEach(func(checkID, checkName []byte) error {
+ // If the container isn't in our namespace, we
+ // can't match it
+ if s.namespaceBytes != nil {
+ ns := nsBucket.Get(checkID)
+ if !bytes.Equal(ns, s.namespaceBytes) {
+ return nil
}
- if string(checkName) == idOrName {
- if exists {
- return errors.Wrapf(ErrCtrExists, "more than one result for ID or name %s", idOrName)
- }
- id = checkID
- exists = true
- } else if strings.HasPrefix(string(checkID), idOrName) {
- if exists {
- return errors.Wrapf(ErrCtrExists, "more than one result for ID or name %s", idOrName)
- }
- id = checkID
- exists = true
+ }
+ if strings.HasPrefix(string(checkID), idOrName) {
+ if exists {
+ return errors.Wrapf(ErrCtrExists, "more than one result for container ID %s", idOrName)
}
+ id = checkID
+ exists = true
+ }
- return nil
- })
- if err != nil {
- return err
- } else if !exists {
- return errors.Wrapf(ErrNoSuchCtr, "no container with name or ID %s found", idOrName)
+ return nil
+ })
+ if err != nil {
+ return err
+ } else if !exists {
+ if isPod {
+ return errors.Wrapf(ErrNoSuchCtr, "%s is a pod, not a container", idOrName)
}
+ return errors.Wrapf(ErrNoSuchCtr, "no container with name or ID %s found", idOrName)
}
return s.getContainerFromDB(id, ctr, ctrBucket)
@@ -941,6 +964,11 @@ func (s *BoltState) LookupPod(idOrName string) (*Pod, error) {
return err
}
+ namesBkt, err := getNamesBucket(tx)
+ if err != nil {
+ return err
+ }
+
nsBkt, err := getNSBucket(tx)
if err != nil {
return err
@@ -954,41 +982,56 @@ func (s *BoltState) LookupPod(idOrName string) (*Pod, error) {
// It might not be in our namespace, but getPodFromDB()
// will handle that case.
id = []byte(idOrName)
- } else {
- // They did not give us a full pod ID.
- // Search for partial ID or full name matches
- // Use else-if in case the name is set to a partial ID
- exists := false
- err = idBucket.ForEach(func(checkID, checkName []byte) error {
- // If the pod isn't in our namespace, we
- // can't match it
- if s.namespaceBytes != nil {
- ns := nsBkt.Get(checkID)
- if !bytes.Equal(ns, s.namespaceBytes) {
- return nil
- }
+ return s.getPodFromDB(id, pod, podBkt)
+ }
+
+ // Next, check if the full name was given
+ isCtr := false
+ fullID := namesBkt.Get([]byte(idOrName))
+ if fullID != nil {
+ // The name exists and maps to an ID.
+ // However, we aren't yet sure if the ID is a pod.
+ podExists = podBkt.Bucket(fullID)
+ if podExists != nil {
+ // A pod bucket matching the full ID was found.
+ return s.getPodFromDB(fullID, pod, podBkt)
+ }
+ // Don't error if we have a name match but it's not a
+ // pod - there's a chance we have a pod with an ID
+ // starting with those characters.
+ // However, so we can return a good error, note whether
+ // this is a container.
+ isCtr = true
+ }
+ // They did not give us a full pod name or ID.
+ // Search for partial ID matches.
+ exists := false
+ err = idBucket.ForEach(func(checkID, checkName []byte) error {
+ // If the pod isn't in our namespace, we
+ // can't match it
+ if s.namespaceBytes != nil {
+ ns := nsBkt.Get(checkID)
+ if !bytes.Equal(ns, s.namespaceBytes) {
+ return nil
}
- if string(checkName) == idOrName {
- if exists {
- return errors.Wrapf(ErrPodExists, "more than one result for ID or name %s", idOrName)
- }
- id = checkID
- exists = true
- } else if strings.HasPrefix(string(checkID), idOrName) {
- if exists {
- return errors.Wrapf(ErrPodExists, "more than one result for ID or name %s", idOrName)
- }
- id = checkID
- exists = true
+ }
+ if strings.HasPrefix(string(checkID), idOrName) {
+ if exists {
+ return errors.Wrapf(ErrPodExists, "more than one result for ID or name %s", idOrName)
}
+ id = checkID
+ exists = true
+ }
- return nil
- })
- if err != nil {
- return err
- } else if !exists {
- return errors.Wrapf(ErrNoSuchPod, "no pod with name or ID %s found", idOrName)
+ return nil
+ })
+ if err != nil {
+ return err
+ } else if !exists {
+ if isCtr {
+ return errors.Wrapf(ErrNoSuchPod, "%s is a container, not a pod", idOrName)
}
+ return errors.Wrapf(ErrNoSuchPod, "no pod with name or ID %s found", idOrName)
}
// We might have found a container ID, but it's OK