Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cherry-pick 57af35d2 to release/0.3: support RuntimeClass.handler #387

Open
wants to merge 1 commit into
base: release/0.3
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions core/container_create.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,11 @@ func (ds *dockerService) CreateContainer(
}
containerName := makeContainerName(sandboxConfig, config)
terminationMessagePath, _ := config.Annotations["io.kubernetes.container.terminationMessagePath"]

sandboxInfo, err := ds.client.InspectContainer(r.GetPodSandboxId())
if err != nil {
return nil, fmt.Errorf("unable to get container's sandbox ID: %v", err)
}
createConfig := types.ContainerCreateConfig{
Name: containerName,
Config: &container.Config{
Expand All @@ -89,6 +94,7 @@ func (ds *dockerService) CreateContainer(
RestartPolicy: container.RestartPolicy{
Name: "no",
},
Runtime: sandboxInfo.HostConfig.Runtime,
},
}

Expand Down
111 changes: 87 additions & 24 deletions core/container_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,15 @@ func TestConcurrentlyCreateAndDeleteContainers(t *testing.T) {
podName, namespace := "foo", "bar"
containerName, image := "sidecar", "logger"

type podInfo struct {
ContainerId string
SandboxID string
}

const count = 20
configs := make([]*runtimeapi.ContainerConfig, 0, count)
sConfigs := make([]*runtimeapi.PodSandboxConfig, 0, count)

for i := 0; i < count; i++ {
s := makeSandboxConfig(fmt.Sprintf("%s%d", podName, i),
fmt.Sprintf("%s%d", namespace, i), fmt.Sprintf("%d", i), 0)
Expand All @@ -80,8 +86,8 @@ func TestConcurrentlyCreateAndDeleteContainers(t *testing.T) {
configs = append(configs, c)
}

containerIDs := make(
chan string,
podInfos := make(
chan podInfo,
len(configs),
) // make channel non-blocking to simulate concurrent containers creation

Expand All @@ -94,39 +100,64 @@ func TestConcurrentlyCreateAndDeleteContainers(t *testing.T) {

go func() {
creationWg.Wait()
close(containerIDs)
close(podInfos)
}()
for i := range configs {
go func(i int) {
defer creationWg.Done()
// We don't care about the sandbox id; pass a bogus one.
sandboxID := fmt.Sprintf("sandboxid%d", i)

runSandboxResp, err := ds.RunPodSandbox(getTestCTX(), &runtimeapi.RunPodSandboxRequest{
Config: sConfigs[i],
})
if err != nil {
t.Errorf("RunPodSandbox: %v", err)
return
}

req := &runtimeapi.CreateContainerRequest{
PodSandboxId: sandboxID,
PodSandboxId: runSandboxResp.PodSandboxId,
Config: configs[i],
SandboxConfig: sConfigs[i],
}

createResp, err := ds.CreateContainer(getTestCTX(), req)
if err != nil {
t.Errorf("CreateContainer: %v", err)
return
}
containerIDs <- createResp.ContainerId
podInfos <- podInfo{
ContainerId: createResp.ContainerId,
SandboxID: runSandboxResp.PodSandboxId,
}
}(i)
}

for containerID := range containerIDs {
for pod := range podInfos {
deletionWg.Add(1)
go func(id string) {
go func(i podInfo) {
defer deletionWg.Done()
_, err := ds.RemoveContainer(
getTestCTX(),
&runtimeapi.RemoveContainerRequest{ContainerId: id},
&runtimeapi.RemoveContainerRequest{ContainerId: i.ContainerId},
)
if err != nil {
t.Errorf("RemoveContainer: %v", err)
}
}(containerID)
_, err = ds.StopPodSandbox(
getTestCTX(),
&runtimeapi.StopPodSandboxRequest{PodSandboxId: i.SandboxID},
)
if err != nil {
t.Errorf("StopPodSandbox: %v", err)
}
_, err = ds.RemovePodSandbox(
getTestCTX(),
&runtimeapi.RemovePodSandboxRequest{PodSandboxId: i.SandboxID},
)
if err != nil {
t.Errorf("RemovePodSandbox: %v", err)
}
}(pod)
}
deletionWg.Wait()
}
Expand Down Expand Up @@ -155,10 +186,15 @@ func TestListContainers(t *testing.T) {
state := runtimeapi.ContainerState_CONTAINER_RUNNING
var createdAt int64 = fakeClock.Now().UnixNano()
for i := range configs {
// We don't care about the sandbox id; pass a bogus one.
sandboxID := fmt.Sprintf("sandboxid%d", i)
runSandboxResp, err := ds.RunPodSandbox(getTestCTX(), &runtimeapi.RunPodSandboxRequest{
Config: sConfigs[i],
})
if err != nil {
t.Errorf("RunPodSandbox: %v", err)
return
}
req := &runtimeapi.CreateContainerRequest{
PodSandboxId: sandboxID,
PodSandboxId: runSandboxResp.PodSandboxId,
Config: configs[i],
SandboxConfig: sConfigs[i],
}
Expand All @@ -174,7 +210,7 @@ func TestListContainers(t *testing.T) {
expected = append([]*runtimeapi.Container{{
Metadata: configs[i].Metadata,
Id: id,
PodSandboxId: sandboxID,
PodSandboxId: runSandboxResp.PodSandboxId,
State: state,
CreatedAt: createdAt,
Image: configs[i].Image,
Expand Down Expand Up @@ -226,12 +262,20 @@ func TestContainerStatus(t *testing.T) {

fDocker.InjectImages([]dockertypes.ImageSummary{{ID: imageName}})

runSandboxResp, err := ds.RunPodSandbox(getTestCTX(), &runtimeapi.RunPodSandboxRequest{
Config: sConfig,
})
if err != nil {
t.Errorf("RunPodSandbox: %v", err)
return
}

// Create the container.
fClock.SetTime(time.Now().Add(-1 * time.Hour))
expected.CreatedAt = fClock.Now().UnixNano()

req := &runtimeapi.CreateContainerRequest{
PodSandboxId: sandboxID,
PodSandboxId: runSandboxResp.PodSandboxId,
Config: config,
SandboxConfig: sConfig,
}
Expand All @@ -243,7 +287,7 @@ func TestContainerStatus(t *testing.T) {
c, err := fDocker.InspectContainer(id)
require.NoError(t, err)
assert.Equal(t, c.Config.Labels[containerTypeLabelKey], containerTypeLabelContainer)
assert.Equal(t, c.Config.Labels[sandboxIDLabelKey], sandboxID)
assert.Equal(t, c.Config.Labels[sandboxIDLabelKey], runSandboxResp.PodSandboxId)

// Set the id manually since we don't know the id until it's created.
expected.Id = id
Expand Down Expand Up @@ -309,8 +353,16 @@ func TestContainerLogPath(t *testing.T) {
config := makeContainerConfig(sConfig, "pause", "iamimage", 0, nil, nil)
config.LogPath = containerLogPath

runSandboxResp, err := ds.RunPodSandbox(getTestCTX(), &runtimeapi.RunPodSandboxRequest{
Config: sConfig,
})
if err != nil {
t.Errorf("RunPodSandbox: %v", err)
return
}

req := &runtimeapi.CreateContainerRequest{
PodSandboxId: sandboxID,
PodSandboxId: runSandboxResp.PodSandboxId,
Config: config,
SandboxConfig: sConfig,
}
Expand Down Expand Up @@ -371,43 +423,54 @@ func TestContainerCreationConflict(t *testing.T) {
noContainerError := fmt.Errorf("Error response from daemon: No such container: %s", containerID)
randomError := fmt.Errorf("random error")

// sandBox run called "inspect_image", "pull", "create", "start", "inspect_container",
sandBoxCalls := []string{"inspect_image", "pull", "create", "start", "inspect_container"}
for desc, test := range map[string]struct {
createError error
removeError error
expectError error
expectCalls []string
expectFields int
}{
// sandBox run called "inspect_image", "pull", "create", "start", "inspect_container",
"no create error": {
expectCalls: []string{"create"},
expectCalls: append(sandBoxCalls, []string{"create"}...),
expectFields: 6,
},
"random create error": {
createError: randomError,
expectError: randomError,
expectCalls: []string{"create"},
expectCalls: append(sandBoxCalls, []string{"create"}...),
},
"conflict create error with successful remove": {
createError: conflictError,
expectError: conflictError,
expectCalls: []string{"create", "remove"},
expectCalls: append(sandBoxCalls, []string{"create", "remove"}...),
},
"conflict create error with random remove error": {
createError: conflictError,
removeError: randomError,
expectError: conflictError,
expectCalls: []string{"create", "remove"},
expectCalls: append(sandBoxCalls, []string{"create", "remove"}...),
},
"conflict create error with no such container remove error": {
createError: conflictError,
removeError: noContainerError,
expectCalls: []string{"create", "remove", "create"},
expectCalls: append(sandBoxCalls, []string{"create", "remove", "create"}...),
expectFields: 7,
},
} {
t.Logf("TestCase: %s", desc)
ds, fDocker, _ := newTestDockerService()

runSandboxResp, err := ds.RunPodSandbox(getTestCTX(), &runtimeapi.RunPodSandboxRequest{
Config: sConfig,
})
if err != nil {
require.EqualError(t, err, test.expectError.Error())
continue
}

if test.createError != nil {
fDocker.InjectError("create", test.createError)
}
Expand All @@ -416,7 +479,7 @@ func TestContainerCreationConflict(t *testing.T) {
}

req := &runtimeapi.CreateContainerRequest{
PodSandboxId: sandboxID,
PodSandboxId: runSandboxResp.PodSandboxId,
Config: config,
SandboxConfig: sConfig,
}
Expand Down
2 changes: 2 additions & 0 deletions core/docker_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,8 @@ type dockerService struct {
// methods for more info).
containerCleanupInfos map[string]*containerCleanupInfo
cleanupInfosLock sync.RWMutex

// runtimeInfoLock sync.RWMutex
}

type dockerServiceAlpha struct {
Expand Down
15 changes: 14 additions & 1 deletion core/docker_service_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package core
import (
"errors"
"math/rand"
"sync"
"testing"
"time"

Expand All @@ -45,26 +46,33 @@ func newTestNetworkPlugin(t *testing.T) *nettest.MockNetworkPlugin {
}

type mockCheckpointManager struct {
lock sync.Mutex
checkpoint map[string]*PodSandboxCheckpoint
}

func (ckm *mockCheckpointManager) CreateCheckpoint(
checkpointKey string,
checkpoint store.Checkpoint,
) error {
ckm.lock.Lock()
ckm.checkpoint[checkpointKey] = checkpoint.(*PodSandboxCheckpoint)
ckm.lock.Unlock()
return nil
}

func (ckm *mockCheckpointManager) GetCheckpoint(
checkpointKey string,
checkpoint store.Checkpoint,
) error {
ckm.lock.Lock()
defer ckm.lock.Unlock()
*(checkpoint.(*PodSandboxCheckpoint)) = *(ckm.checkpoint[checkpointKey])
return nil
}

func (ckm *mockCheckpointManager) RemoveCheckpoint(checkpointKey string) error {
ckm.lock.Lock()
defer ckm.lock.Unlock()
_, ok := ckm.checkpoint[checkpointKey]
if ok {
delete(ckm.checkpoint, "moo")
Expand All @@ -74,14 +82,19 @@ func (ckm *mockCheckpointManager) RemoveCheckpoint(checkpointKey string) error {

func (ckm *mockCheckpointManager) ListCheckpoints() ([]string, error) {
var keys []string
ckm.lock.Lock()
defer ckm.lock.Unlock()
for key := range ckm.checkpoint {
keys = append(keys, key)
}
return keys, nil
}

func newMockCheckpointManager() store.CheckpointManager {
return &mockCheckpointManager{checkpoint: make(map[string]*PodSandboxCheckpoint)}
return &mockCheckpointManager{
checkpoint: make(map[string]*PodSandboxCheckpoint),
lock: sync.Mutex{},
}
}

func newTestDockerService() (*dockerService, *libdocker.FakeDockerClient, *clock.FakeClock) {
Expand Down
18 changes: 18 additions & 0 deletions core/sandbox_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,24 @@ var (
defaultSandboxGracePeriod = time.Duration(10) * time.Second
)

// check Runtime correct
func (ds *dockerService) IsRuntimeConfigured(runtime string) error {
info, err := ds.getDockerInfo()
if err != nil {
return fmt.Errorf("failed to get docker info: %v", err)
}

// ds.runtimeInfoLock.RLock()
for r := range info.Runtimes {
if r == runtime {
return nil
}
}
// ds.runtimeInfoLock.RUnlock()

return fmt.Errorf("no runtime for %q is configured", runtime)
}

// Returns whether the sandbox network is ready, and whether the sandbox is known
func (ds *dockerService) getNetworkReady(podSandboxID string) (bool, bool) {
ds.networkReadyLock.Lock()
Expand Down
Loading
Loading