mirror of https://github.com/containers/podman.git
Ensure that SQLite state handles name-ID collisions
If a container with an ID starting with "db1" exists, and a container named "db1" also exists, and they are different containers - if I run `podman inspect db1` the container named "db1" should be inspected, and there should not be an error that multiple containers matched the name or id "db1". This was already handled by BoltDB, and now is properly managed by SQLite. Fixes #17905 Signed-off-by: Matt Heon <mheon@redhat.com>
This commit is contained in:
parent
f9beb0db09
commit
7daab31f1f
|
|
@ -487,26 +487,29 @@ func (s *SQLiteState) LookupContainerID(idOrName string) (string, error) {
|
|||
return "", define.ErrDBClosed
|
||||
}
|
||||
|
||||
rows, err := s.conn.Query("SELECT ID FROM ContainerConfig WHERE ContainerConfig.Name=? OR (ContainerConfig.ID LIKE ?);", idOrName, idOrName+"%")
|
||||
rows, err := s.conn.Query("SELECT ID, Name FROM ContainerConfig WHERE ContainerConfig.Name=? OR (ContainerConfig.ID LIKE ?);", idOrName, idOrName+"%")
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("looking up container %q in database: %w", idOrName, err)
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
var id string
|
||||
foundResult := false
|
||||
var (
|
||||
id, name string
|
||||
resCount uint
|
||||
)
|
||||
for rows.Next() {
|
||||
if foundResult {
|
||||
return "", fmt.Errorf("more than one result for container %q: %w", idOrName, define.ErrCtrExists)
|
||||
}
|
||||
|
||||
if err := rows.Scan(&id); err != nil {
|
||||
if err := rows.Scan(&id, &name); err != nil {
|
||||
return "", fmt.Errorf("retrieving container %q ID from database: %w", idOrName, err)
|
||||
}
|
||||
foundResult = true
|
||||
if name == idOrName {
|
||||
return id, nil
|
||||
}
|
||||
resCount++
|
||||
}
|
||||
if !foundResult {
|
||||
if resCount == 0 {
|
||||
return "", define.ErrNoSuchCtr
|
||||
} else if resCount > 1 {
|
||||
return "", fmt.Errorf("more than one result for container %q: %w", idOrName, define.ErrCtrExists)
|
||||
}
|
||||
|
||||
return id, nil
|
||||
|
|
@ -523,26 +526,33 @@ func (s *SQLiteState) LookupContainer(idOrName string) (*Container, error) {
|
|||
return nil, define.ErrDBClosed
|
||||
}
|
||||
|
||||
rows, err := s.conn.Query("SELECT JSON FROM ContainerConfig WHERE ContainerConfig.Name=? OR (ContainerConfig.ID LIKE ?);", idOrName, idOrName+"%")
|
||||
rows, err := s.conn.Query("SELECT JSON, Name FROM ContainerConfig WHERE ContainerConfig.Name=? OR (ContainerConfig.ID LIKE ?);", idOrName, idOrName+"%")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("looking up container %q in database: %w", idOrName, err)
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
var rawJSON string
|
||||
foundResult := false
|
||||
var (
|
||||
rawJSON, name string
|
||||
exactName bool
|
||||
resCount uint
|
||||
)
|
||||
for rows.Next() {
|
||||
if foundResult {
|
||||
return nil, fmt.Errorf("more than one result for container %q: %w", idOrName, define.ErrCtrExists)
|
||||
}
|
||||
|
||||
if err := rows.Scan(&rawJSON); err != nil {
|
||||
if err := rows.Scan(&rawJSON, &name); err != nil {
|
||||
return nil, fmt.Errorf("retrieving container %q ID from database: %w", idOrName, err)
|
||||
}
|
||||
foundResult = true
|
||||
if name == idOrName {
|
||||
exactName = true
|
||||
break
|
||||
}
|
||||
resCount++
|
||||
}
|
||||
if !foundResult {
|
||||
return nil, fmt.Errorf("no container with name or ID %q found: %w", idOrName, define.ErrNoSuchCtr)
|
||||
if !exactName {
|
||||
if resCount == 0 {
|
||||
return nil, fmt.Errorf("no container with name or ID %q found: %w", idOrName, define.ErrNoSuchCtr)
|
||||
} else if resCount > 1 {
|
||||
return nil, fmt.Errorf("more than one result for container %q: %w", idOrName, define.ErrCtrExists)
|
||||
}
|
||||
}
|
||||
|
||||
ctr := new(Container)
|
||||
|
|
@ -1303,26 +1313,33 @@ func (s *SQLiteState) LookupPod(idOrName string) (*Pod, error) {
|
|||
return nil, define.ErrDBClosed
|
||||
}
|
||||
|
||||
rows, err := s.conn.Query("SELECT JSON FROM PodConfig WHERE PodConfig.Name=? OR (PodConfig.ID LIKE ?);", idOrName, idOrName+"%")
|
||||
rows, err := s.conn.Query("SELECT JSON, Name FROM PodConfig WHERE PodConfig.Name=? OR (PodConfig.ID LIKE ?);", idOrName, idOrName+"%")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("looking up pod %q in database: %w", idOrName, err)
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
var rawJSON string
|
||||
foundResult := false
|
||||
var (
|
||||
rawJSON, name string
|
||||
exactName bool
|
||||
resCount uint
|
||||
)
|
||||
for rows.Next() {
|
||||
if foundResult {
|
||||
return nil, fmt.Errorf("more than one result for pod %q: %w", idOrName, define.ErrCtrExists)
|
||||
}
|
||||
|
||||
if err := rows.Scan(&rawJSON); err != nil {
|
||||
if err := rows.Scan(&rawJSON, &name); err != nil {
|
||||
return nil, fmt.Errorf("error retrieving pod %q ID from database: %w", idOrName, err)
|
||||
}
|
||||
foundResult = true
|
||||
if name == idOrName {
|
||||
exactName = true
|
||||
break
|
||||
}
|
||||
resCount++
|
||||
}
|
||||
if !foundResult {
|
||||
return nil, fmt.Errorf("no pod with name or ID %s found: %w", idOrName, define.ErrNoSuchPod)
|
||||
if !exactName {
|
||||
if resCount == 0 {
|
||||
return nil, fmt.Errorf("no pod with name or ID %s found: %w", idOrName, define.ErrNoSuchPod)
|
||||
} else if resCount > 1 {
|
||||
return nil, fmt.Errorf("more than one result for pod %q: %w", idOrName, define.ErrCtrExists)
|
||||
}
|
||||
}
|
||||
|
||||
return s.createPod(rawJSON)
|
||||
|
|
|
|||
|
|
@ -718,4 +718,21 @@ var _ = Describe("Podman create", func() {
|
|||
setup.WaitWithDefaultTimeout()
|
||||
Expect(setup).Should(Exit(0))
|
||||
})
|
||||
|
||||
It("create container with name subset of existing ID", func() {
|
||||
create1 := podmanTest.Podman([]string{"create", "-t", ALPINE, "top"})
|
||||
create1.WaitWithDefaultTimeout()
|
||||
Expect(create1).Should(Exit(0))
|
||||
ctr1ID := create1.OutputToString()
|
||||
|
||||
ctr2Name := ctr1ID[:5]
|
||||
create2 := podmanTest.Podman([]string{"create", "-t", "--name", ctr2Name, ALPINE, "top"})
|
||||
create2.WaitWithDefaultTimeout()
|
||||
Expect(create2).Should(Exit(0))
|
||||
|
||||
inspect := podmanTest.Podman([]string{"inspect", "--format", "{{.Name}}", ctr2Name})
|
||||
inspect.WaitWithDefaultTimeout()
|
||||
Expect(inspect).Should(Exit(0))
|
||||
Expect(inspect.OutputToString()).Should(Equal(ctr2Name))
|
||||
})
|
||||
})
|
||||
|
|
|
|||
|
|
@ -1199,4 +1199,20 @@ ENTRYPOINT ["sleep","99999"]
|
|||
Expect(strings[0]).Should(ContainSubstring("size=10240k"))
|
||||
})
|
||||
|
||||
It("create pod with name subset of existing ID", func() {
|
||||
create1 := podmanTest.Podman([]string{"pod", "create"})
|
||||
create1.WaitWithDefaultTimeout()
|
||||
Expect(create1).Should(Exit(0))
|
||||
pod1ID := create1.OutputToString()
|
||||
|
||||
pod2Name := pod1ID[:5]
|
||||
create2 := podmanTest.Podman([]string{"pod", "create", pod2Name})
|
||||
create2.WaitWithDefaultTimeout()
|
||||
Expect(create2).Should(Exit(0))
|
||||
|
||||
inspect := podmanTest.Podman([]string{"pod", "inspect", "--format", "{{.Name}}", pod2Name})
|
||||
inspect.WaitWithDefaultTimeout()
|
||||
Expect(inspect).Should(Exit(0))
|
||||
Expect(inspect.OutputToString()).Should(Equal(pod2Name))
|
||||
})
|
||||
})
|
||||
|
|
|
|||
Loading…
Reference in New Issue