Skip to content

Commit

Permalink
Merge pull request #17917 from mheon/fix_17905
Browse files Browse the repository at this point in the history
Ensure that SQLite state handles name-ID collisions
  • Loading branch information
openshift-merge-robot authored Mar 27, 2023
2 parents 30619bb + 7daab31 commit 8bd9109
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 32 deletions.
81 changes: 49 additions & 32 deletions libpod/sqlite_state.go
Original file line number Diff line number Diff line change
Expand Up @@ -498,26 +498,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
Expand All @@ -534,26 +537,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)
Expand Down Expand Up @@ -1314,26 +1324,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)
Expand Down
17 changes: 17 additions & 0 deletions test/e2e/create_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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))
})
})
16 changes: 16 additions & 0 deletions test/e2e/pod_create_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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))
})
})

0 comments on commit 8bd9109

Please sign in to comment.