Refactor CreateContainer.

pull/6/head
Random-Liu 2016-04-14 10:36:13 -07:00
parent da07fa9dd5
commit ba4a5ed39e
11 changed files with 111 additions and 126 deletions

View File

@ -60,7 +60,7 @@ const (
type DockerInterface interface {
ListContainers(options dockertypes.ContainerListOptions) ([]dockertypes.Container, error)
InspectContainer(id string) (*dockertypes.ContainerJSON, error)
CreateContainer(docker.CreateContainerOptions) (*docker.Container, error)
CreateContainer(dockertypes.ContainerCreateConfig) (*dockertypes.ContainerCreateResponse, error)
StartContainer(id string, hostConfig *docker.HostConfig) error
StopContainer(id string, timeout uint) error
RemoveContainer(opts docker.RemoveContainerOptions) error

View File

@ -28,6 +28,7 @@ import (
"github.com/docker/docker/pkg/jsonmessage"
dockertypes "github.com/docker/engine-api/types"
dockernat "github.com/docker/go-connections/nat"
docker "github.com/fsouza/go-dockerclient"
cadvisorapi "github.com/google/cadvisor/info/v1"
"k8s.io/kubernetes/cmd/kubelet/app/options"
@ -744,37 +745,37 @@ func TestMakePortsAndBindings(t *testing.T) {
}
// Construct expected bindings
expectPortBindings := map[string][]docker.PortBinding{
expectPortBindings := map[string][]dockernat.PortBinding{
"80/tcp": {
docker.PortBinding{
dockernat.PortBinding{
HostPort: "8080",
HostIP: "127.0.0.1",
},
},
"443/tcp": {
docker.PortBinding{
dockernat.PortBinding{
HostPort: "443",
HostIP: "",
},
docker.PortBinding{
dockernat.PortBinding{
HostPort: "446",
HostIP: "",
},
},
"443/udp": {
docker.PortBinding{
dockernat.PortBinding{
HostPort: "446",
HostIP: "",
},
},
"444/udp": {
docker.PortBinding{
dockernat.PortBinding{
HostPort: "444",
HostIP: "",
},
},
"445/tcp": {
docker.PortBinding{
dockernat.PortBinding{
HostPort: "445",
HostIP: "",
},

View File

@ -305,7 +305,7 @@ func (f *FakeDockerClient) normalSleep(mean, stdDev, cutOffMillis int) {
// CreateContainer is a test-spy implementation of DockerInterface.CreateContainer.
// It adds an entry "create" to the internal method call record.
func (f *FakeDockerClient) CreateContainer(c docker.CreateContainerOptions) (*docker.Container, error) {
func (f *FakeDockerClient) CreateContainer(c dockertypes.ContainerCreateConfig) (*dockertypes.ContainerCreateResponse, error) {
f.Lock()
defer f.Unlock()
f.called = append(f.called, "create")
@ -315,28 +315,21 @@ func (f *FakeDockerClient) CreateContainer(c docker.CreateContainerOptions) (*do
// This is not a very good fake. We'll just add this container's name to the list.
// Docker likes to add a '/', so copy that behavior.
name := "/" + c.Name
id := name
f.Created = append(f.Created, name)
// The newest container should be in front, because we assume so in GetPodStatus()
f.RunningContainerList = append([]dockertypes.Container{
{ID: name, Names: []string{name}, Image: c.Config.Image, Labels: c.Config.Labels},
}, f.RunningContainerList...)
// TODO(random-liu): Remove this convertion when we refactor CreateContainer
config := &dockercontainer.Config{}
convertType(c.Config, config)
hostConfig := &dockercontainer.HostConfig{}
convertType(c.HostConfig, hostConfig)
container := convertFakeContainer(&FakeContainer{ID: name, Name: name, Config: config, HostConfig: hostConfig})
containerCopy := *container
f.ContainerMap[name] = &containerCopy
f.ContainerMap[name] = convertFakeContainer(&FakeContainer{ID: id, Name: name, Config: c.Config, HostConfig: c.HostConfig})
f.normalSleep(100, 25, 25)
// TODO(random-liu): This will be refactored soon, we could do this because only the returned id is used.
return &docker.Container{ID: container.ID}, nil
return &dockertypes.ContainerCreateResponse{ID: id}, nil
}
// StartContainer is a test-spy implementation of DockerInterface.StartContainer.
// It adds an entry "start" to the internal method call record.
// The HostConfig at StartContainer will be deprecated from docker 1.10. Now in
// docker manager the HostConfig is set when CreateContainer().
// docker manager the HostConfig is set when ContainerCreate().
// TODO(random-liu): Remove the HostConfig here when it is completely removed in
// docker 1.12.
func (f *FakeDockerClient) StartContainer(id string, _ *docker.HostConfig) error {
@ -543,3 +536,8 @@ func (f *FakeDockerPuller) IsImagePresent(name string) (bool, error) {
}
return false, nil
}
// dockerTimestampToString converts the timestamp to string
func dockerTimestampToString(t time.Time) string {
return t.Format(time.RFC3339Nano)
}

View File

@ -67,7 +67,7 @@ func (in instrumentedDockerInterface) InspectContainer(id string) (*dockertypes.
return out, err
}
func (in instrumentedDockerInterface) CreateContainer(opts docker.CreateContainerOptions) (*docker.Container, error) {
func (in instrumentedDockerInterface) CreateContainer(opts dockertypes.ContainerCreateConfig) (*dockertypes.ContainerCreateResponse, error) {
const operation = "create_container"
defer recordOperation(operation, time.Now())

View File

@ -29,7 +29,6 @@ import (
"github.com/docker/docker/pkg/stdcopy"
dockerapi "github.com/docker/engine-api/client"
dockertypes "github.com/docker/engine-api/types"
dockercontainer "github.com/docker/engine-api/types/container"
dockerfilters "github.com/docker/engine-api/types/filters"
docker "github.com/fsouza/go-dockerclient"
"golang.org/x/net/context"
@ -125,24 +124,12 @@ func (d *kubeDockerClient) InspectContainer(id string) (*dockertypes.ContainerJS
return &containerJSON, nil
}
func (d *kubeDockerClient) CreateContainer(opts docker.CreateContainerOptions) (*docker.Container, error) {
config := &dockercontainer.Config{}
if err := convertType(opts.Config, config); err != nil {
return nil, err
}
hostConfig := &dockercontainer.HostConfig{}
if err := convertType(opts.HostConfig, hostConfig); err != nil {
return nil, err
}
resp, err := d.client.ContainerCreate(getDefaultContext(), config, hostConfig, nil, opts.Name)
func (d *kubeDockerClient) CreateContainer(opts dockertypes.ContainerCreateConfig) (*dockertypes.ContainerCreateResponse, error) {
createResp, err := d.client.ContainerCreate(getDefaultContext(), opts.Config, opts.HostConfig, opts.NetworkingConfig, opts.Name)
if err != nil {
return nil, err
}
container := &docker.Container{}
if err := convertType(&resp, container); err != nil {
return nil, err
}
return container, nil
return &createResp, nil
}
// TODO(random-liu): The HostConfig at container start is deprecated, will remove this in the following refactoring.
@ -384,11 +371,6 @@ func parseDockerTimestamp(s string) (time.Time, error) {
return time.Parse(time.RFC3339Nano, s)
}
// dockerTimestampToString converts the timestamp to string
func dockerTimestampToString(t time.Time) string {
return t.Format(time.RFC3339Nano)
}
// containerNotFoundError is the error returned by InspectContainer when container not found. We
// add this error type for testability. We don't use the original error returned by engine-api
// because dockertypes.containerNotFoundError is private, we can't create and inject it in our test.

View File

@ -33,6 +33,9 @@ import (
"github.com/coreos/go-semver/semver"
dockertypes "github.com/docker/engine-api/types"
dockercontainer "github.com/docker/engine-api/types/container"
dockerstrslice "github.com/docker/engine-api/types/strslice"
dockernat "github.com/docker/go-connections/nat"
docker "github.com/fsouza/go-dockerclient"
"github.com/golang/glog"
cadvisorapi "github.com/google/cadvisor/info/v1"
@ -477,9 +480,9 @@ func makeMountBindings(mounts []kubecontainer.Mount, podHasSELinuxLabel bool) (r
return
}
func makePortsAndBindings(portMappings []kubecontainer.PortMapping) (map[docker.Port]struct{}, map[docker.Port][]docker.PortBinding) {
exposedPorts := map[docker.Port]struct{}{}
portBindings := map[docker.Port][]docker.PortBinding{}
func makePortsAndBindings(portMappings []kubecontainer.PortMapping) (map[dockernat.Port]struct{}, map[dockernat.Port][]dockernat.PortBinding) {
exposedPorts := map[dockernat.Port]struct{}{}
portBindings := map[dockernat.Port][]dockernat.PortBinding{}
for _, port := range portMappings {
exteriorPort := port.HostPort
if exteriorPort == 0 {
@ -500,10 +503,10 @@ func makePortsAndBindings(portMappings []kubecontainer.PortMapping) (map[docker.
protocol = "/tcp"
}
dockerPort := docker.Port(strconv.Itoa(interiorPort) + protocol)
dockerPort := dockernat.Port(strconv.Itoa(interiorPort) + protocol)
exposedPorts[dockerPort] = struct{}{}
hostBinding := docker.PortBinding{
hostBinding := dockernat.PortBinding{
HostPort: strconv.Itoa(exteriorPort),
HostIP: port.HostIP,
}
@ -514,7 +517,7 @@ func makePortsAndBindings(portMappings []kubecontainer.PortMapping) (map[docker.
portBindings[dockerPort] = append(existedBindings, hostBinding)
} else {
// Otherwise, it's fresh new port binding
portBindings[dockerPort] = []docker.PortBinding{
portBindings[dockerPort] = []dockernat.PortBinding{
hostBinding,
}
}
@ -599,17 +602,18 @@ func (dm *DockerManager) runContainer(
}
}
hc := &docker.HostConfig{
hc := &dockercontainer.HostConfig{
Binds: binds,
NetworkMode: netMode,
IpcMode: ipcMode,
UTSMode: utsMode,
PidMode: pidMode,
NetworkMode: dockercontainer.NetworkMode(netMode),
IpcMode: dockercontainer.IpcMode(ipcMode),
UTSMode: dockercontainer.UTSMode(utsMode),
PidMode: dockercontainer.PidMode(pidMode),
ReadonlyRootfs: readOnlyRootFilesystem(container),
// Memory and CPU are set here for newer versions of Docker (1.6+).
Memory: memoryLimit,
MemorySwap: -1,
CPUShares: cpuShares,
Resources: dockercontainer.Resources{
Memory: memoryLimit,
MemorySwap: -1,
CPUShares: cpuShares,
},
SecurityOpt: securityOpts,
}
@ -633,15 +637,11 @@ func (dm *DockerManager) runContainer(
hc.CgroupParent = opts.CgroupParent
}
dockerOpts := docker.CreateContainerOptions{
dockerOpts := dockertypes.ContainerCreateConfig{
Name: containerName,
Config: &docker.Config{
Env: makeEnvList(opts.Envs),
Image: container.Image,
// Memory and CPU are set here for older versions of Docker (pre-1.6).
Memory: memoryLimit,
MemorySwap: -1,
CPUShares: cpuShares,
Config: &dockercontainer.Config{
Env: makeEnvList(opts.Envs),
Image: container.Image,
WorkingDir: container.WorkingDir,
Labels: labels,
// Interactive containers:
@ -657,36 +657,39 @@ func (dm *DockerManager) runContainer(
setInfraContainerNetworkConfig(pod, netMode, opts, dockerOpts)
}
setEntrypointAndCommand(container, opts, &dockerOpts)
setEntrypointAndCommand(container, opts, dockerOpts)
glog.V(3).Infof("Container %v/%v/%v: setting entrypoint \"%v\" and command \"%v\"", pod.Namespace, pod.Name, container.Name, dockerOpts.Config.Entrypoint, dockerOpts.Config.Cmd)
securityContextProvider := securitycontext.NewSimpleSecurityContextProvider()
securityContextProvider.ModifyContainerConfig(pod, container, dockerOpts.Config)
securityContextProvider.ModifyHostConfig(pod, container, dockerOpts.HostConfig)
dockerContainer, err := dm.client.CreateContainer(dockerOpts)
createResp, err := dm.client.CreateContainer(dockerOpts)
if err != nil {
dm.recorder.Eventf(ref, api.EventTypeWarning, kubecontainer.FailedToCreateContainer, "Failed to create docker container with error: %v", err)
return kubecontainer.ContainerID{}, err
}
dm.recorder.Eventf(ref, api.EventTypeNormal, kubecontainer.CreatedContainer, "Created container with docker id %v", utilstrings.ShortenString(dockerContainer.ID, 12))
if len(createResp.Warnings) != 0 {
glog.V(2).Infof("Container %q of pod %q created with warnings: %v", container.Name, format.Pod(pod), createResp.Warnings)
}
dm.recorder.Eventf(ref, api.EventTypeNormal, kubecontainer.CreatedContainer, "Created container with docker id %v", utilstrings.ShortenString(createResp.ID, 12))
if err = dm.client.StartContainer(dockerContainer.ID, nil); err != nil {
if err = dm.client.StartContainer(createResp.ID, nil); err != nil {
dm.recorder.Eventf(ref, api.EventTypeWarning, kubecontainer.FailedToStartContainer,
"Failed to start container with docker id %v with error: %v", utilstrings.ShortenString(dockerContainer.ID, 12), err)
"Failed to start container with docker id %v with error: %v", utilstrings.ShortenString(createResp.ID, 12), err)
return kubecontainer.ContainerID{}, err
}
dm.recorder.Eventf(ref, api.EventTypeNormal, kubecontainer.StartedContainer, "Started container with docker id %v", utilstrings.ShortenString(dockerContainer.ID, 12))
dm.recorder.Eventf(ref, api.EventTypeNormal, kubecontainer.StartedContainer, "Started container with docker id %v", utilstrings.ShortenString(createResp.ID, 12))
return kubecontainer.DockerID(dockerContainer.ID).ContainerID(), nil
return kubecontainer.DockerID(createResp.ID).ContainerID(), nil
}
// setInfraContainerNetworkConfig sets the network configuration for the infra-container. We only set network configuration for infra-container, all
// the user containers will share the same network namespace with infra-container.
func setInfraContainerNetworkConfig(pod *api.Pod, netMode string, opts *kubecontainer.RunContainerOptions, dockerOpts docker.CreateContainerOptions) {
func setInfraContainerNetworkConfig(pod *api.Pod, netMode string, opts *kubecontainer.RunContainerOptions, dockerOpts dockertypes.ContainerCreateConfig) {
exposedPorts, portBindings := makePortsAndBindings(opts.PortMappings)
dockerOpts.Config.ExposedPorts = exposedPorts
dockerOpts.HostConfig.PortBindings = portBindings
dockerOpts.HostConfig.PortBindings = dockernat.PortMap(portBindings)
if netMode != namespaceModeHost {
dockerOpts.Config.Hostname = opts.Hostname
@ -699,11 +702,11 @@ func setInfraContainerNetworkConfig(pod *api.Pod, netMode string, opts *kubecont
}
}
func setEntrypointAndCommand(container *api.Container, opts *kubecontainer.RunContainerOptions, dockerOpts *docker.CreateContainerOptions) {
func setEntrypointAndCommand(container *api.Container, opts *kubecontainer.RunContainerOptions, dockerOpts dockertypes.ContainerCreateConfig) {
command, args := kubecontainer.ExpandContainerCommandAndArgs(container, opts.Envs)
dockerOpts.Config.Entrypoint = command
dockerOpts.Config.Cmd = args
dockerOpts.Config.Entrypoint = dockerstrslice.StrSlice(command)
dockerOpts.Config.Cmd = dockerstrslice.StrSlice(args)
}
// A helper function to get the KubeletContainerName and hash from a docker

View File

@ -31,6 +31,7 @@ import (
dockertypes "github.com/docker/engine-api/types"
dockercontainer "github.com/docker/engine-api/types/container"
dockerstrslice "github.com/docker/engine-api/types/strslice"
docker "github.com/fsouza/go-dockerclient"
cadvisorapi "github.com/google/cadvisor/info/v1"
"github.com/stretchr/testify/assert"
@ -164,13 +165,13 @@ func TestSetEntrypointAndCommand(t *testing.T) {
name string
container *api.Container
envs []kubecontainer.EnvVar
expected *docker.CreateContainerOptions
expected *dockertypes.ContainerCreateConfig
}{
{
name: "none",
container: &api.Container{},
expected: &docker.CreateContainerOptions{
Config: &docker.Config{},
expected: &dockertypes.ContainerCreateConfig{
Config: &dockercontainer.Config{},
},
},
{
@ -178,9 +179,9 @@ func TestSetEntrypointAndCommand(t *testing.T) {
container: &api.Container{
Command: []string{"foo", "bar"},
},
expected: &docker.CreateContainerOptions{
Config: &docker.Config{
Entrypoint: []string{"foo", "bar"},
expected: &dockertypes.ContainerCreateConfig{
Config: &dockercontainer.Config{
Entrypoint: dockerstrslice.StrSlice([]string{"foo", "bar"}),
},
},
},
@ -199,9 +200,9 @@ func TestSetEntrypointAndCommand(t *testing.T) {
Value: "boo",
},
},
expected: &docker.CreateContainerOptions{
Config: &docker.Config{
Entrypoint: []string{"foo", "zoo", "boo"},
expected: &dockertypes.ContainerCreateConfig{
Config: &dockercontainer.Config{
Entrypoint: dockerstrslice.StrSlice([]string{"foo", "zoo", "boo"}),
},
},
},
@ -210,8 +211,8 @@ func TestSetEntrypointAndCommand(t *testing.T) {
container: &api.Container{
Args: []string{"foo", "bar"},
},
expected: &docker.CreateContainerOptions{
Config: &docker.Config{
expected: &dockertypes.ContainerCreateConfig{
Config: &dockercontainer.Config{
Cmd: []string{"foo", "bar"},
},
},
@ -231,9 +232,9 @@ func TestSetEntrypointAndCommand(t *testing.T) {
Value: "trap",
},
},
expected: &docker.CreateContainerOptions{
Config: &docker.Config{
Cmd: []string{"zap", "hap", "trap"},
expected: &dockertypes.ContainerCreateConfig{
Config: &dockercontainer.Config{
Cmd: dockerstrslice.StrSlice([]string{"zap", "hap", "trap"}),
},
},
},
@ -243,10 +244,10 @@ func TestSetEntrypointAndCommand(t *testing.T) {
Command: []string{"foo"},
Args: []string{"bar", "baz"},
},
expected: &docker.CreateContainerOptions{
Config: &docker.Config{
Entrypoint: []string{"foo"},
Cmd: []string{"bar", "baz"},
expected: &dockertypes.ContainerCreateConfig{
Config: &dockercontainer.Config{
Entrypoint: dockerstrslice.StrSlice([]string{"foo"}),
Cmd: dockerstrslice.StrSlice([]string{"bar", "baz"}),
},
},
},
@ -270,10 +271,10 @@ func TestSetEntrypointAndCommand(t *testing.T) {
Value: "roo",
},
},
expected: &docker.CreateContainerOptions{
Config: &docker.Config{
Entrypoint: []string{"boo--zoo", "foo", "roo"},
Cmd: []string{"foo", "zoo", "boo"},
expected: &dockertypes.ContainerCreateConfig{
Config: &dockercontainer.Config{
Entrypoint: dockerstrslice.StrSlice([]string{"boo--zoo", "foo", "roo"}),
Cmd: dockerstrslice.StrSlice([]string{"foo", "zoo", "boo"}),
},
},
},
@ -284,8 +285,8 @@ func TestSetEntrypointAndCommand(t *testing.T) {
Envs: tc.envs,
}
actualOpts := &docker.CreateContainerOptions{
Config: &docker.Config{},
actualOpts := dockertypes.ContainerCreateConfig{
Config: &dockercontainer.Config{},
}
setEntrypointAndCommand(tc.container, opts, actualOpts)

View File

@ -19,7 +19,7 @@ package securitycontext
import (
"k8s.io/kubernetes/pkg/api"
docker "github.com/fsouza/go-dockerclient"
dockercontainer "github.com/docker/engine-api/types/container"
)
// ValidSecurityContextWithContainerDefaults creates a valid security context provider based on
@ -39,7 +39,7 @@ func NewFakeSecurityContextProvider() SecurityContextProvider {
type FakeSecurityContextProvider struct{}
func (p FakeSecurityContextProvider) ModifyContainerConfig(pod *api.Pod, container *api.Container, config *docker.Config) {
func (p FakeSecurityContextProvider) ModifyContainerConfig(pod *api.Pod, container *api.Container, config *dockercontainer.Config) {
}
func (p FakeSecurityContextProvider) ModifyHostConfig(pod *api.Pod, container *api.Container, hostConfig *docker.HostConfig) {
func (p FakeSecurityContextProvider) ModifyHostConfig(pod *api.Pod, container *api.Container, hostConfig *dockercontainer.HostConfig) {
}

View File

@ -23,7 +23,7 @@ import (
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/kubelet/leaky"
docker "github.com/fsouza/go-dockerclient"
dockercontainer "github.com/docker/engine-api/types/container"
)
// NewSimpleSecurityContextProvider creates a new SimpleSecurityContextProvider.
@ -37,7 +37,7 @@ type SimpleSecurityContextProvider struct{}
// ModifyContainerConfig is called before the Docker createContainer call.
// The security context provider can make changes to the Config with which
// the container is created.
func (p SimpleSecurityContextProvider) ModifyContainerConfig(pod *api.Pod, container *api.Container, config *docker.Config) {
func (p SimpleSecurityContextProvider) ModifyContainerConfig(pod *api.Pod, container *api.Container, config *dockercontainer.Config) {
effectiveSC := DetermineEffectiveSecurityContext(pod, container)
if effectiveSC == nil {
return
@ -50,7 +50,7 @@ func (p SimpleSecurityContextProvider) ModifyContainerConfig(pod *api.Pod, conta
// ModifyHostConfig is called before the Docker runContainer call.
// The security context provider can make changes to the HostConfig, affecting
// security options, whether the container is privileged, volume binds, etc.
func (p SimpleSecurityContextProvider) ModifyHostConfig(pod *api.Pod, container *api.Container, hostConfig *docker.HostConfig) {
func (p SimpleSecurityContextProvider) ModifyHostConfig(pod *api.Pod, container *api.Container, hostConfig *dockercontainer.HostConfig) {
// Apply pod security context
if container.Name != leaky.PodInfraContainerName && pod.Spec.SecurityContext != nil {
// TODO: We skip application of supplemental groups to the

View File

@ -22,7 +22,7 @@ import (
"strconv"
"testing"
docker "github.com/fsouza/go-dockerclient"
dockercontainer "github.com/docker/engine-api/types/container"
"k8s.io/kubernetes/pkg/api"
apitesting "k8s.io/kubernetes/pkg/api/testing"
)
@ -35,28 +35,28 @@ func TestModifyContainerConfig(t *testing.T) {
name string
podSc *api.PodSecurityContext
sc *api.SecurityContext
expected *docker.Config
expected *dockercontainer.Config
}{
{
name: "container.SecurityContext.RunAsUser set",
sc: &api.SecurityContext{
RunAsUser: &uid,
},
expected: &docker.Config{
expected: &dockercontainer.Config{
User: strconv.FormatInt(uid, 10),
},
},
{
name: "no RunAsUser value set",
sc: &api.SecurityContext{},
expected: &docker.Config{},
expected: &dockercontainer.Config{},
},
{
name: "pod.Spec.SecurityContext.RunAsUser set",
podSc: &api.PodSecurityContext{
RunAsUser: &uid,
},
expected: &docker.Config{
expected: &dockercontainer.Config{
User: strconv.FormatInt(uid, 10),
},
},
@ -68,7 +68,7 @@ func TestModifyContainerConfig(t *testing.T) {
sc: &api.SecurityContext{
RunAsUser: &overrideUid,
},
expected: &docker.Config{
expected: &dockercontainer.Config{
User: strconv.FormatInt(overrideUid, 10),
},
},
@ -79,7 +79,7 @@ func TestModifyContainerConfig(t *testing.T) {
for _, tc := range cases {
pod := &api.Pod{Spec: api.PodSpec{SecurityContext: tc.podSc}}
dummyContainer.SecurityContext = tc.sc
dockerCfg := &docker.Config{}
dockerCfg := &dockercontainer.Config{}
provider.ModifyContainerConfig(pod, dummyContainer, dockerCfg)
@ -93,16 +93,16 @@ func TestModifyHostConfig(t *testing.T) {
priv := true
setPrivSC := &api.SecurityContext{}
setPrivSC.Privileged = &priv
setPrivHC := &docker.HostConfig{
setPrivHC := &dockercontainer.HostConfig{
Privileged: true,
}
setCapsHC := &docker.HostConfig{
setCapsHC := &dockercontainer.HostConfig{
CapAdd: []string{"addCapA", "addCapB"},
CapDrop: []string{"dropCapA", "dropCapB"},
}
setSELinuxHC := &docker.HostConfig{}
setSELinuxHC := &dockercontainer.HostConfig{}
setSELinuxHC.SecurityOpt = []string{
fmt.Sprintf("%s:%s", dockerLabelUser, "user"),
fmt.Sprintf("%s:%s", dockerLabelRole, "role"),
@ -117,7 +117,7 @@ func TestModifyHostConfig(t *testing.T) {
name string
podSc *api.PodSecurityContext
sc *api.SecurityContext
expected *docker.HostConfig
expected *dockercontainer.HostConfig
}{
{
name: "fully set container.SecurityContext",
@ -164,7 +164,7 @@ func TestModifyHostConfig(t *testing.T) {
for _, tc := range cases {
pod := &api.Pod{Spec: api.PodSpec{SecurityContext: tc.podSc}}
dummyContainer.SecurityContext = tc.sc
dockerCfg := &docker.HostConfig{}
dockerCfg := &dockercontainer.HostConfig{}
provider.ModifyHostConfig(pod, dummyContainer, dockerCfg)
@ -187,7 +187,7 @@ func TestModifyHostConfigPodSecurityContext(t *testing.T) {
testCases := map[string]struct {
securityContext *api.PodSecurityContext
expected *docker.HostConfig
expected *dockercontainer.HostConfig
}{
"nil": {
securityContext: nil,
@ -219,7 +219,7 @@ func TestModifyHostConfigPodSecurityContext(t *testing.T) {
for k, v := range testCases {
dummyPod.Spec.SecurityContext = v.securityContext
dockerCfg := &docker.HostConfig{}
dockerCfg := &dockercontainer.HostConfig{}
provider.ModifyHostConfig(dummyPod, dummyContainer, dockerCfg)
if !reflect.DeepEqual(v.expected, dockerCfg) {
t.Errorf("unexpected modification of host config for %s. Expected: %#v Got: %#v", k, v.expected, dockerCfg)
@ -301,8 +301,8 @@ func inputSELinuxOptions() *api.SELinuxOptions {
}
}
func fullValidHostConfig() *docker.HostConfig {
return &docker.HostConfig{
func fullValidHostConfig() *dockercontainer.HostConfig {
return &dockercontainer.HostConfig{
Privileged: true,
CapAdd: []string{"addCapA", "addCapB"},
CapDrop: []string{"dropCapA", "dropCapB"},

View File

@ -19,21 +19,21 @@ package securitycontext
import (
"k8s.io/kubernetes/pkg/api"
docker "github.com/fsouza/go-dockerclient"
dockercontainer "github.com/docker/engine-api/types/container"
)
type SecurityContextProvider interface {
// ModifyContainerConfig is called before the Docker createContainer call.
// The security context provider can make changes to the Config with which
// the container is created.
ModifyContainerConfig(pod *api.Pod, container *api.Container, config *docker.Config)
ModifyContainerConfig(pod *api.Pod, container *api.Container, config *dockercontainer.Config)
// ModifyHostConfig is called before the Docker createContainer call.
// The security context provider can make changes to the HostConfig, affecting
// security options, whether the container is privileged, volume binds, etc.
// An error is returned if it's not possible to secure the container as requested
// with a security context.
ModifyHostConfig(pod *api.Pod, container *api.Container, hostConfig *docker.HostConfig)
ModifyHostConfig(pod *api.Pod, container *api.Container, hostConfig *dockercontainer.HostConfig)
}
const (