Add a dockershim package

Add a new docker integration with kubelet using the new runtime API.
This change adds the package with some skeletons, and implements some
of the basic operations.
This commit is contained in:
Yu-Ju Hong 2016-07-22 14:24:05 -07:00
parent 0ac247c6a7
commit 03d11bcf4e
12 changed files with 708 additions and 22 deletions

View File

@ -22,9 +22,8 @@ import (
runtimeApi "k8s.io/kubernetes/pkg/kubelet/api/v1alpha1/runtime"
)
// RuntimeService interface defines the interfaces that should be implemented
// by a container runtime.
// Thread safety is required from implementations of this interface.
// RuntimeService interface should be implemented by a container runtime.
// The methods should be thread-safe.
type RuntimeService interface {
// Version returns the runtime name, runtime version and runtime API version
Version(apiVersion string) (*runtimeApi.VersionResponse, error)
@ -33,40 +32,39 @@ type RuntimeService interface {
CreatePodSandbox(config *runtimeApi.PodSandboxConfig) (string, error)
// StopPodSandbox stops the sandbox. If there are any running containers in the
// sandbox, they should be force terminated.
StopPodSandbox(podSandBoxID string) error
// DeletePodSandbox deletes the sandbox. If there are any running containers in the
// sandbox, they should be force deleted.
DeletePodSandbox(podSandBoxID string) error
StopPodSandbox(podSandboxID string) error
// DeletePodSandbox deletes the sandbox. If there are running containers in the
// sandbox, they should be forcibly deleted.
DeletePodSandbox(podSandboxID string) error
// PodSandboxStatus returns the Status of the PodSandbox.
PodSandboxStatus(podSandBoxID string) (*runtimeApi.PodSandboxStatus, error)
// ListPodSandbox returns a list of SandBox.
PodSandboxStatus(podSandboxID string) (*runtimeApi.PodSandboxStatus, error)
// ListPodSandbox returns a list of Sandbox.
ListPodSandbox(filter *runtimeApi.PodSandboxFilter) ([]*runtimeApi.PodSandbox, error)
// CreateContainer creates a new container in specified PodSandbox
CreateContainer(podSandBoxID string, config *runtimeApi.ContainerConfig, sandboxConfig *runtimeApi.PodSandboxConfig) (string, error)
// CreateContainer creates a new container in specified PodSandbox.
CreateContainer(podSandboxID string, config *runtimeApi.ContainerConfig, sandboxConfig *runtimeApi.PodSandboxConfig) (string, error)
// StartContainer starts the container.
StartContainer(rawContainerID string) error
// StopContainer stops a running container with a grace period (i.e., timeout).
StopContainer(rawContainerID string, timeout int64) error
// RemoveContainer removes the container. If the container is running, the container
// should be force removed.
// RemoveContainer removes the container.
RemoveContainer(rawContainerID string) error
// ListContainers lists all containers by filters.
ListContainers(filter *runtimeApi.ContainerFilter) ([]*runtimeApi.Container, error)
// ContainerStatus returns the container status.
// ContainerStatus returns the status of the container.
ContainerStatus(rawContainerID string) (*runtimeApi.ContainerStatus, error)
// Exec execute a command in the container.
// Exec executes a command in the container.
Exec(rawContainerID string, cmd []string, tty bool, stdin io.Reader, stdout, stderr io.WriteCloser) error
}
// ImageManagerService interface defines the interfaces that should be implemented
// by a container image manager.
// Thread safety is required from implementations of this interface.
// ImageManagerService interface should be implemented by a container image
// manager.
// The methods should be thread-safe.
type ImageManagerService interface {
// ListImages lists existing images.
// ListImages lists the existing images.
ListImages(filter *runtimeApi.ImageFilter) ([]*runtimeApi.Image, error)
// ImageStatus returns the status of the image.
ImageStatus(image *runtimeApi.ImageSpec) (*runtimeApi.Image, error)
// PullImage pulls a image with authentication config.
// PullImage pulls an image with the authentication config.
PullImage(image *runtimeApi.ImageSpec, auth *runtimeApi.AuthConfig) error
// RemoveImage removes the image.
RemoveImage(image *runtimeApi.ImageSpec) error

View File

@ -0,0 +1,91 @@
/*
Copyright 2016 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package dockershim
import (
"fmt"
"strings"
dockertypes "github.com/docker/engine-api/types"
runtimeApi "k8s.io/kubernetes/pkg/kubelet/api/v1alpha1/runtime"
)
// This file contains helper functions to convert docker API types to runtime
// API types, or vice versa.
const (
// Status of a container returned by docker ListContainers
statusRunningPrefix = "Up"
statusCreatedPrefix = "Created"
statusExitedPrefix = "Exited"
)
func toRuntimeAPIImage(image *dockertypes.Image) (*runtimeApi.Image, error) {
if image == nil {
return nil, fmt.Errorf("unable to convert a nil pointer to a runtime API image")
}
size := uint64(image.VirtualSize)
return &runtimeApi.Image{
Id: &image.ID,
RepoTags: image.RepoTags,
RepoDigests: image.RepoDigests,
Size_: &size,
}, nil
}
func toRuntimeAPIContainer(c *dockertypes.Container) *runtimeApi.Container {
state := toRuntimeAPIContainerState(c.Status)
return &runtimeApi.Container{
Id: &c.ID,
Name: &c.Names[0],
Image: &runtimeApi.ImageSpec{Image: &c.Image},
ImageRef: &c.ImageID,
State: &state,
Labels: c.Labels,
}
}
func toDockerContainerStatus(state runtimeApi.ContainerState) string {
switch state {
case runtimeApi.ContainerState_CREATED:
return "created"
case runtimeApi.ContainerState_RUNNING:
return "running"
case runtimeApi.ContainerState_EXITED:
return "exited"
case runtimeApi.ContainerState_UNKNOWN:
fallthrough
default:
return "unknown"
}
}
func toRuntimeAPIContainerState(state string) runtimeApi.ContainerState {
// Parse the state string in dockertypes.Container. This could break when
// we upgrade docker.
switch {
case strings.HasPrefix(state, statusRunningPrefix):
return runtimeApi.ContainerState_RUNNING
case strings.HasPrefix(state, statusExitedPrefix):
return runtimeApi.ContainerState_EXITED
case strings.HasPrefix(state, statusCreatedPrefix):
return runtimeApi.ContainerState_CREATED
default:
return runtimeApi.ContainerState_UNKNOWN
}
}

View File

@ -0,0 +1,41 @@
/*
Copyright 2016 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package dockershim
import (
"testing"
runtimeApi "k8s.io/kubernetes/pkg/kubelet/api/v1alpha1/runtime"
)
func TestConvertDockerStatusToRuntimeAPIState(t *testing.T) {
testCases := []struct {
input string
expected runtimeApi.ContainerState
}{
{input: "Up 5 hours", expected: runtimeApi.ContainerState_RUNNING},
{input: "Exited (0) 2 hours ago", expected: runtimeApi.ContainerState_EXITED},
{input: "Created", expected: runtimeApi.ContainerState_CREATED},
{input: "Random string", expected: runtimeApi.ContainerState_UNKNOWN},
}
for i, test := range testCases {
if actual := toRuntimeAPIContainerState(test.input); actual != test.expected {
t.Errorf("Test[%d]: expected %q, got %q", i, test.expected, actual)
}
}
}

View File

@ -0,0 +1,18 @@
/*
Copyright 2016 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Docker integration using pkg/kubelet/api/v1alpha1/runtime/api.pb.go.
package dockershim

View File

@ -0,0 +1,203 @@
/*
Copyright 2016 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package dockershim
import (
"fmt"
"io"
dockertypes "github.com/docker/engine-api/types"
dockercontainer "github.com/docker/engine-api/types/container"
dockerfilters "github.com/docker/engine-api/types/filters"
dockerstrslice "github.com/docker/engine-api/types/strslice"
runtimeApi "k8s.io/kubernetes/pkg/kubelet/api/v1alpha1/runtime"
)
// ListContainers lists all containers matching the filter.
func (ds *dockerService) ListContainers(filter *runtimeApi.ContainerFilter) ([]*runtimeApi.Container, error) {
opts := dockertypes.ContainerListOptions{All: true}
opts.Filter = dockerfilters.NewArgs()
if filter != nil {
if filter.Name != nil {
opts.Filter.Add("name", filter.GetName())
}
if filter.Id != nil {
opts.Filter.Add("id", filter.GetId())
}
if filter.State != nil {
opts.Filter.Add("status", toDockerContainerStatus(filter.GetState()))
}
if filter.PodSandboxId != nil {
// TODO: implement this after sandbox functions are implemented.
}
if filter.LabelSelector != nil {
for k, v := range filter.LabelSelector {
opts.Filter.Add("label", fmt.Sprintf("%s=%s", k, v))
}
}
}
containers, err := ds.client.ListContainers(opts)
if err != nil {
return nil, err
}
// Convert docker to runtime api containers.
result := []*runtimeApi.Container{}
for _, c := range containers {
result = append(result, toRuntimeAPIContainer(&c))
}
return result, nil
}
// CreateContainer creates a new container in the given PodSandbox
// Note: docker doesn't use LogPath yet.
// TODO: check if the default values returned by the runtime API are ok.
func (ds *dockerService) CreateContainer(podSandboxID string, config *runtimeApi.ContainerConfig, sandboxConfig *runtimeApi.PodSandboxConfig) (string, error) {
if config == nil {
return "", fmt.Errorf("container config is nil")
}
if sandboxConfig == nil {
return "", fmt.Errorf("sandbox config is nil for container %q", config.GetName())
}
// Merge annotations and labels because docker supports only labels.
// TODO: add a prefix to annotations so that we can distinguish labels and
// annotations when reading back them from the docker container.
// TODO: should we apply docker-specific labels?
labels := config.GetLabels()
for k, v := range config.GetAnnotations() {
if _, ok := labels[k]; !ok {
// Only write to labels if the key doesn't exist.
labels[k] = v
}
}
image := ""
if iSpec := config.GetImage(); iSpec != nil {
image = iSpec.GetImage()
}
createConfig := dockertypes.ContainerCreateConfig{
Name: config.GetName(),
Config: &dockercontainer.Config{
// TODO: set User.
Hostname: sandboxConfig.GetHostname(),
Entrypoint: dockerstrslice.StrSlice(config.GetCommand()),
Cmd: dockerstrslice.StrSlice(config.GetArgs()),
Env: generateEnvList(config.GetEnvs()),
Image: image,
WorkingDir: config.GetWorkingDir(),
Labels: labels,
// Interactive containers:
OpenStdin: config.GetStdin(),
StdinOnce: config.GetStdinOnce(),
Tty: config.GetTty(),
},
}
// Fill the HostConfig.
hc := &dockercontainer.HostConfig{
Binds: generateMountBindings(config.GetMounts()),
ReadonlyRootfs: config.GetReadonlyRootfs(),
Privileged: config.GetPrivileged(),
}
// Apply options derived from the sandbox config.
if lc := sandboxConfig.GetLinux(); lc != nil {
// Apply Cgroup options.
// TODO: Check if this works with per-pod cgroups.
hc.CgroupParent = lc.GetCgroupParent()
// Apply namespace options.
sandboxNSMode := fmt.Sprintf("container:%v", podSandboxID)
hc.NetworkMode = dockercontainer.NetworkMode(sandboxNSMode)
hc.IpcMode = dockercontainer.IpcMode(sandboxNSMode)
hc.UTSMode = ""
hc.PidMode = ""
nsOpts := lc.GetNamespaceOptions()
if nsOpts != nil {
if nsOpts.GetHostNetwork() {
hc.UTSMode = namespaceModeHost
}
if nsOpts.GetHostPid() {
hc.PidMode = namespaceModeHost
}
}
}
// Apply Linux-specific options if applicable.
if lc := config.GetLinux(); lc != nil {
// Apply resource options.
// TODO: Check if the units are correct.
// TODO: Can we assume the defaults are sane?
rOpts := lc.GetResources()
if rOpts != nil {
hc.Resources = dockercontainer.Resources{
Memory: rOpts.GetMemoryLimitInBytes(),
MemorySwap: -1, // Always disable memory swap.
CPUShares: rOpts.GetCpuShares(),
CPUQuota: rOpts.GetCpuQuota(),
CPUPeriod: rOpts.GetCpuPeriod(),
// TODO: Need to set devices.
}
hc.OomScoreAdj = int(rOpts.GetOomScoreAdj())
}
// Note: ShmSize is handled in kube_docker_client.go
}
// TODO: Seccomp support. Need to figure out how to pass seccomp options
// through the runtime API (annotations?).See dockerManager.getSecurityOpts()
// for the details. Always set the default seccomp profile for now.
hc.SecurityOpt = []string{fmt.Sprintf("%s=%s", "seccomp", defaultSeccompProfile)}
// TODO: Add or drop capabilities.
createConfig.HostConfig = hc
createResp, err := ds.client.CreateContainer(createConfig)
if createResp != nil {
return createResp.ID, err
}
return "", err
}
// StartContainer starts the container.
func (ds *dockerService) StartContainer(rawContainerID string) error {
return ds.client.StartContainer(rawContainerID)
}
// StopContainer stops a running container with a grace period (i.e., timeout).
func (ds *dockerService) StopContainer(rawContainerID string, timeout int64) error {
return ds.client.StopContainer(rawContainerID, int(timeout))
}
// RemoveContainer removes the container.
// TODO: If a container is still running, should we forcibly remove it?
func (ds *dockerService) RemoveContainer(rawContainerID string) error {
return ds.client.RemoveContainer(rawContainerID, dockertypes.ContainerRemoveOptions{RemoveVolumes: true})
}
// ContainerStatus returns the container status.
// TODO: Implement the function.
func (ds *dockerService) ContainerStatus(rawContainerID string) (*runtimeApi.ContainerStatus, error) {
return nil, fmt.Errorf("not implemented")
}
// Exec execute a command in the container.
// TODO: Implement the function.
func (ds *dockerService) Exec(rawContainerID string, cmd []string, tty bool, stdin io.Reader, stdout, stderr io.WriteCloser) error {
return fmt.Errorf("not implemented")
}

View File

@ -0,0 +1,85 @@
/*
Copyright 2016 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package dockershim
import (
"fmt"
dockertypes "github.com/docker/engine-api/types"
runtimeApi "k8s.io/kubernetes/pkg/kubelet/api/v1alpha1/runtime"
)
// This file implements methods in ImageManagerService.
// ListImages lists existing images.
func (ds *dockerService) ListImages(filter *runtimeApi.ImageFilter) ([]*runtimeApi.Image, error) {
opts := dockertypes.ImageListOptions{}
if filter != nil {
if imgSpec := filter.GetImage(); imgSpec != nil {
opts.MatchName = imgSpec.GetImage()
}
}
images, err := ds.client.ListImages(opts)
if err != nil {
return nil, err
}
result := []*runtimeApi.Image{}
for _, i := range images {
apiImage, err := toRuntimeAPIImage(&i)
if err != nil {
// TODO: log an error message?
continue
}
result = append(result, apiImage)
}
return result, nil
}
// ImageStatus returns the status of the image.
func (ds *dockerService) ImageStatus(image *runtimeApi.ImageSpec) (*runtimeApi.Image, error) {
images, err := ds.ListImages(&runtimeApi.ImageFilter{Image: image})
if err != nil {
return nil, err
}
if len(images) != 1 {
return nil, fmt.Errorf("ImageStatus returned more than one image: %+v", images)
}
return images[0], nil
}
// PullImage pulls a image with authentication config.
func (ds *dockerService) PullImage(image *runtimeApi.ImageSpec, auth *runtimeApi.AuthConfig) error {
// TODO: add default tags for images or should this be done by kubelet?
return ds.client.PullImage(image.GetImage(),
dockertypes.AuthConfig{
Username: auth.GetUsername(),
Password: auth.GetPassword(),
ServerAddress: auth.GetServerAddress(),
IdentityToken: auth.GetIdentityToken(),
RegistryToken: auth.GetRegistryToken(),
},
dockertypes.ImagePullOptions{},
)
}
// RemoveImage removes the image.
func (ds *dockerService) RemoveImage(image *runtimeApi.ImageSpec) error {
_, err := ds.client.RemoveImage(image.GetImage(), dockertypes.ImageRemoveOptions{PruneChildren: true})
return err
}

View File

@ -0,0 +1,51 @@
/*
Copyright 2016 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package dockershim
import (
"fmt"
runtimeApi "k8s.io/kubernetes/pkg/kubelet/api/v1alpha1/runtime"
)
// CreatePodSandbox creates a pod-level sandbox.
// The definition of PodSandbox is at https://github.com/kubernetes/kubernetes/pull/25899
func (ds *dockerService) CreatePodSandbox(config *runtimeApi.PodSandboxConfig) (string, error) {
return "", fmt.Errorf("Not implemented")
}
// StopPodSandbox stops the sandbox. If there are any running containers in the
// sandbox, they should be force terminated.
func (ds *dockerService) StopPodSandbox(podSandboxID string) error {
return fmt.Errorf("Not implemented")
}
// DeletePodSandbox deletes the sandbox. If there are running containers in the
// sandbox, they should be forcibly deleted.
func (ds *dockerService) DeletePodSandbox(podSandboxID string) error {
return fmt.Errorf("Not implemented")
}
// PodSandboxStatus returns the Status of the PodSandbox.
func (ds *dockerService) PodSandboxStatus(podSandboxID string) (*runtimeApi.PodSandboxStatus, error) {
return nil, fmt.Errorf("Not implemented")
}
// ListPodSandbox returns a list of Sandbox.
func (ds *dockerService) ListPodSandbox(filter *runtimeApi.PodSandboxFilter) ([]*runtimeApi.PodSandbox, error) {
return nil, fmt.Errorf("Not implemented")
}

View File

@ -0,0 +1,78 @@
/*
Copyright 2016 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package dockershim
import (
"fmt"
"io"
"k8s.io/kubernetes/pkg/api"
runtimeApi "k8s.io/kubernetes/pkg/kubelet/api/v1alpha1/runtime"
kubecontainer "k8s.io/kubernetes/pkg/kubelet/container"
"k8s.io/kubernetes/pkg/kubelet/dockertools"
)
const (
dockerRuntimeName = "docker"
kubeAPIVersion = "0.1.0"
// String used to detect docker host mode for various namespaces (e.g.
// networking). Must match the value returned by docker inspect -f
// '{{.HostConfig.NetworkMode}}'.
namespaceModeHost = "host"
defaultSeccompProfile = "unconfined"
)
func NewDockerSevice(client dockertools.DockerInterface) DockerLegacyService {
return &dockerService{
client: dockertools.NewInstrumentedDockerInterface(client),
}
}
// DockerLegacyService is an interface that embeds both the new
// RuntimeService and ImageService interfaces, while including legacy methods
// for backward compatibility.
type DockerLegacyService interface {
kubecontainer.RuntimeService
kubecontainer.ImageManagerService
// Supporting legacy methods for docker.
GetContainerLogs(pod *api.Pod, containerID kubecontainer.ContainerID, logOptions *api.PodLogOptions, stdout, stderr io.Writer) (err error)
kubecontainer.ContainerAttacher
PortForward(pod *kubecontainer.Pod, port uint16, stream io.ReadWriteCloser) error
}
type dockerService struct {
client dockertools.DockerInterface
}
// Version returns the runtime name, runtime version and runtime API version
func (ds *dockerService) Version(apiVersion string) (*runtimeApi.VersionResponse, error) {
v, err := ds.client.Version()
if err != nil {
return nil, fmt.Errorf("docker: failed to get docker version: %v", err)
}
runtimeAPIVersion := kubeAPIVersion
name := dockerRuntimeName
return &runtimeApi.VersionResponse{
Version: &runtimeAPIVersion,
RuntimeName: &name,
RuntimeVersion: &v.Version,
RuntimeApiVersion: &v.APIVersion,
}, nil
}

View File

@ -0,0 +1,78 @@
/*
Copyright 2016 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package dockershim
import (
"fmt"
dockerapiversion "github.com/docker/engine-api/types/versions"
runtimeApi "k8s.io/kubernetes/pkg/kubelet/api/v1alpha1/runtime"
)
// apiVersion implements kubecontainer.Version interface by implementing
// Compare() and String(). It uses the compare function of engine-api to
// compare docker apiversions.
type apiVersion string
func (v apiVersion) String() string {
return string(v)
}
func (v apiVersion) Compare(other string) (int, error) {
if dockerapiversion.LessThan(string(v), other) {
return -1, nil
} else if dockerapiversion.GreaterThan(string(v), other) {
return 1, nil
}
return 0, nil
}
// generateEnvList converts KeyValue list to a list of strings, in the form of
// '<key>=<value>', which can be understood by docker.
func generateEnvList(envs []*runtimeApi.KeyValue) (result []string) {
for _, env := range envs {
result = append(result, fmt.Sprintf("%s=%s", env.GetKey(), env.GetValue()))
}
return
}
// generateMountBindings converts the mount list to a list of strings that
// can be understood by docker.
// Each element in the string is in the form of:
// '<HostPath>:<ContainerPath>', or
// '<HostPath>:<ContainerPath>:ro', if the path is read only, or
// '<HostPath>:<ContainerPath>:Z', if the volume requires SELinux
// relabeling and the pod provides an SELinux label
func generateMountBindings(mounts []*runtimeApi.Mount) (result []string) {
// TODO: resolve podHasSELinuxLabel
for _, m := range mounts {
bind := fmt.Sprintf("%s:%s", m.GetHostPath(), m.GetContainerPath())
readOnly := m.GetReadonly()
if readOnly {
bind += ":ro"
}
if m.GetSelinuxRelabel() {
if readOnly {
bind += ",Z"
} else {
bind += ":Z"
}
}
result = append(result, bind)
}
return
}

View File

@ -0,0 +1,43 @@
/*
Copyright 2016 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package dockershim
import (
"fmt"
"io"
"k8s.io/kubernetes/pkg/api"
kubecontainer "k8s.io/kubernetes/pkg/kubelet/container"
"k8s.io/kubernetes/pkg/util/term"
)
// This file implements the functions that are needed for backward
// compatibility. Therefore, it imports various kubernetes packages
// directly.
// TODO: implement the methods in this file.
func (ds *dockerService) AttachContainer(id kubecontainer.ContainerID, stdin io.Reader, stdout, stderr io.WriteCloser, tty bool, resize <-chan term.Size) (err error) {
return fmt.Errorf("not implemented")
}
func (ds *dockerService) GetContainerLogs(pod *api.Pod, containerID kubecontainer.ContainerID, logOptions *api.PodLogOptions, stdout, stderr io.Writer) (err error) {
return fmt.Errorf("not implemented")
}
func (ds *dockerService) PortForward(pod *kubecontainer.Pod, port uint16, stream io.ReadWriteCloser) error {
return fmt.Errorf("not implemented")
}

View File

@ -225,7 +225,7 @@ func NewDockerManager(
seccompProfileRoot string,
options ...kubecontainer.Option) *DockerManager {
// Wrap the docker client with instrumentedDockerInterface
client = newInstrumentedDockerInterface(client)
client = NewInstrumentedDockerInterface(client)
// Work out the location of the Docker runtime, defaulting to /var/lib/docker
// if there are any problems.

View File

@ -30,7 +30,7 @@ type instrumentedDockerInterface struct {
}
// Creates an instrumented DockerInterface from an existing DockerInterface.
func newInstrumentedDockerInterface(dockerClient DockerInterface) DockerInterface {
func NewInstrumentedDockerInterface(dockerClient DockerInterface) DockerInterface {
return instrumentedDockerInterface{
client: dockerClient,
}