Skip to content
This repository has been archived by the owner on May 6, 2020. It is now read-only.

Commit

Permalink
oci: Support containers with identical ID prefixes
Browse files Browse the repository at this point in the history
Starting 2 containers with the same ID prefixes is a valid use case.
Although the Docker CLI supports shortened container IDs, italways
call the runtime with the full and complete ID.

Fixes #699

Signed-off-by: Samuel Ortiz <[email protected]>
  • Loading branch information
Samuel Ortiz committed Oct 10, 2017
1 parent 48aad68 commit 89a00f0
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 50 deletions.
29 changes: 4 additions & 25 deletions oci.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ import (
"net"
"os"
"path/filepath"
"strings"
"syscall"

vc "github.com/containers/virtcontainers"
Expand All @@ -43,21 +42,13 @@ const (
cgroupFsType = 0x27e0eb
)

var (
errNeedLinuxResource = errors.New("Linux resource cannot be empty")
errPrefixContIDNotUnique = errors.New("Partial container ID not unique")
)
var errNeedLinuxResource = errors.New("Linux resource cannot be empty")

var cgroupsDirPath = "/sys/fs/cgroup"

// getContainerInfo returns the container status and its pod ID.
// It internally expands the container ID from the prefix provided.
// An error is returned if >1 containers are found with the specified
// prefix.
func getContainerInfo(containerID string) (vc.ContainerStatus, string, error) {
var cStatus vc.ContainerStatus
var podID string

// container ID MUST be provided.
if containerID == "" {
return vc.ContainerStatus{}, "", fmt.Errorf("Missing container ID")
Expand All @@ -68,29 +59,17 @@ func getContainerInfo(containerID string) (vc.ContainerStatus, string, error) {
return vc.ContainerStatus{}, "", err
}

matchFound := false
for _, podStatus := range podStatusList {
for _, containerStatus := range podStatus.ContainersStatus {
if containerStatus.ID == containerID {
return containerStatus, podStatus.ID, nil
}

if strings.HasPrefix(containerStatus.ID, containerID) {
if matchFound {
return vc.ContainerStatus{}, "", errPrefixContIDNotUnique
}

matchFound = true
cStatus = containerStatus
podID = podStatus.ID
}
}
}

if matchFound {
return cStatus, podID, nil
}

// Not finding a container should not trigger an error as
// getContainerInfo is used for checking the existence and
// the absence of a container ID.
return vc.ContainerStatus{}, "", nil
}

Expand Down
44 changes: 19 additions & 25 deletions oci_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,34 +79,27 @@ func TestGetContainerInfoContainerIDEmptyFailure(t *testing.T) {
assert.Empty(status.ID, "Expected blank fullID, but got %v", status.ID)
}

func TestGetContainerInfoDuplicateContainerID(t *testing.T) {
func TestGetContainerInfo(t *testing.T) {
assert := assert.New(t)

pod := &vcMock.Pod{
MockID: testPodID,
}

containerID := testContainerID + testContainerID
containerID := testContainerID

containerStatus := vc.ContainerStatus{
ID: containerID,
Annotations: map[string]string{
oci.ContainerTypeKey: string(vc.PodSandbox),
},
}

testingImpl.ListPodFunc = func() ([]vc.PodStatus, error) {
return []vc.PodStatus{
{
ID: pod.ID(),
ContainersStatus: []vc.ContainerStatus{
// 2 containers with same ID
{
ID: containerID,
Annotations: map[string]string{
oci.ContainerTypeKey: string(vc.PodSandbox),
},
},
{
ID: containerID,
Annotations: map[string]string{
oci.ContainerTypeKey: string(vc.PodSandbox),
},
},
},
ID: pod.ID(),
ContainersStatus: []vc.ContainerStatus{containerStatus},
},
}, nil
}
Expand All @@ -115,12 +108,13 @@ func TestGetContainerInfoDuplicateContainerID(t *testing.T) {
testingImpl.ListPodFunc = nil
}()

_, _, err := getContainerInfo(testContainerID)
assert.Error(err)
assert.Equal(err, errPrefixContIDNotUnique)
status, podID, err := getContainerInfo(testContainerID)
assert.NoError(err)
assert.Equal(podID, pod.ID())
assert.Equal(status, containerStatus)
}

func TestGetContainerInfo(t *testing.T) {
func TestGetContainerInfoMismatch(t *testing.T) {
assert := assert.New(t)

pod := &vcMock.Pod{
Expand Down Expand Up @@ -149,11 +143,11 @@ func TestGetContainerInfo(t *testing.T) {
testingImpl.ListPodFunc = nil
}()

status, podID, err := getContainerInfo(testContainerID)
_, podID, err := getContainerInfo(testContainerID)
assert.NoError(err)
assert.Equal(podID, pod.ID())
assert.Equal(status, containerStatus)
assert.Equal(podID, "")
}

func TestValidCreateParamsContainerIDEmptyFailure(t *testing.T) {
assert := assert.New(t)
_, err := validCreateParams("", "")
Expand Down

0 comments on commit 89a00f0

Please sign in to comment.