diff --git a/Godeps/Godeps.json b/Godeps/Godeps.json index 1b1bc91ed8c..75dbc74b314 100644 --- a/Godeps/Godeps.json +++ b/Godeps/Godeps.json @@ -462,47 +462,47 @@ }, { "ImportPath": "github.com/containerd/containerd/api/services/containers/v1", - "Comment": "v1.0.0-beta.2-159-g27d450a0", + "Comment": "v1.0.0-beta.2-159-g27d450a", "Rev": "27d450a01bb533d7ebc5701eb52792565396b084" }, { "ImportPath": "github.com/containerd/containerd/api/services/tasks/v1", - "Comment": "v1.0.0-beta.2-159-g27d450a0", + "Comment": "v1.0.0-beta.2-159-g27d450a", "Rev": "27d450a01bb533d7ebc5701eb52792565396b084" }, { "ImportPath": "github.com/containerd/containerd/api/services/version/v1", - "Comment": "v1.0.0-beta.2-159-g27d450a0", + "Comment": "v1.0.0-beta.2-159-g27d450a", "Rev": "27d450a01bb533d7ebc5701eb52792565396b084" }, { "ImportPath": "github.com/containerd/containerd/api/types", - "Comment": "v1.0.0-beta.2-159-g27d450a0", + "Comment": "v1.0.0-beta.2-159-g27d450a", "Rev": "27d450a01bb533d7ebc5701eb52792565396b084" }, { "ImportPath": "github.com/containerd/containerd/api/types/task", - "Comment": "v1.0.0-beta.2-159-g27d450a0", + "Comment": "v1.0.0-beta.2-159-g27d450a", "Rev": "27d450a01bb533d7ebc5701eb52792565396b084" }, { "ImportPath": "github.com/containerd/containerd/containers", - "Comment": "v1.0.0-beta.2-159-g27d450a0", + "Comment": "v1.0.0-beta.2-159-g27d450a", "Rev": "27d450a01bb533d7ebc5701eb52792565396b084" }, { "ImportPath": "github.com/containerd/containerd/dialer", - "Comment": "v1.0.0-beta.2-159-g27d450a0", + "Comment": "v1.0.0-beta.2-159-g27d450a", "Rev": "27d450a01bb533d7ebc5701eb52792565396b084" }, { "ImportPath": "github.com/containerd/containerd/errdefs", - "Comment": "v1.0.0-beta.2-159-g27d450a0", + "Comment": "v1.0.0-beta.2-159-g27d450a", "Rev": "27d450a01bb533d7ebc5701eb52792565396b084" }, { "ImportPath": "github.com/containerd/containerd/namespaces", - "Comment": "v1.0.0-beta.2-159-g27d450a0", + "Comment": "v1.0.0-beta.2-159-g27d450a", "Rev": "27d450a01bb533d7ebc5701eb52792565396b084" }, { @@ -991,147 +991,157 @@ }, { "ImportPath": "github.com/docker/distribution/digestset", - "Comment": "v2.6.0-rc.1-209-gedc3ab29", + "Comment": "v2.6.0-rc.1-209-gedc3ab2", "Rev": "edc3ab29cdff8694dd6feb85cfeb4b5f1b38ed9c" }, { "ImportPath": "github.com/docker/distribution/reference", - "Comment": "v2.6.0-rc.1-209-gedc3ab29", + "Comment": "v2.6.0-rc.1-209-gedc3ab2", "Rev": "edc3ab29cdff8694dd6feb85cfeb4b5f1b38ed9c" }, { "ImportPath": "github.com/docker/docker/api", - "Comment": "docs-v1.12.0-rc4-2016-07-15-7401-g4f3616fb1", + "Comment": "docs-v1.12.0-rc4-2016-07-15-7401-g4f3616f", "Rev": "4f3616fb1c112e206b88cb7a9922bf49067a7756" }, { "ImportPath": "github.com/docker/docker/api/types", - "Comment": "docs-v1.12.0-rc4-2016-07-15-7401-g4f3616fb1", + "Comment": "docs-v1.12.0-rc4-2016-07-15-7401-g4f3616f", "Rev": "4f3616fb1c112e206b88cb7a9922bf49067a7756" }, { "ImportPath": "github.com/docker/docker/api/types/blkiodev", - "Comment": "docs-v1.12.0-rc4-2016-07-15-7401-g4f3616fb1", + "Comment": "docs-v1.12.0-rc4-2016-07-15-7401-g4f3616f", "Rev": "4f3616fb1c112e206b88cb7a9922bf49067a7756" }, { "ImportPath": "github.com/docker/docker/api/types/container", - "Comment": "docs-v1.12.0-rc4-2016-07-15-7401-g4f3616fb1", + "Comment": "docs-v1.12.0-rc4-2016-07-15-7401-g4f3616f", "Rev": "4f3616fb1c112e206b88cb7a9922bf49067a7756" }, { "ImportPath": "github.com/docker/docker/api/types/events", - "Comment": "docs-v1.12.0-rc4-2016-07-15-7401-g4f3616fb1", + "Comment": "docs-v1.12.0-rc4-2016-07-15-7401-g4f3616f", "Rev": "4f3616fb1c112e206b88cb7a9922bf49067a7756" }, { "ImportPath": "github.com/docker/docker/api/types/filters", - "Comment": "docs-v1.12.0-rc4-2016-07-15-7401-g4f3616fb1", + "Comment": "docs-v1.12.0-rc4-2016-07-15-7401-g4f3616f", "Rev": "4f3616fb1c112e206b88cb7a9922bf49067a7756" }, { "ImportPath": "github.com/docker/docker/api/types/image", - "Comment": "docs-v1.12.0-rc4-2016-07-15-7401-g4f3616fb1", + "Comment": "docs-v1.12.0-rc4-2016-07-15-7401-g4f3616f", "Rev": "4f3616fb1c112e206b88cb7a9922bf49067a7756" }, { "ImportPath": "github.com/docker/docker/api/types/mount", - "Comment": "docs-v1.12.0-rc4-2016-07-15-7401-g4f3616fb1", + "Comment": "docs-v1.12.0-rc4-2016-07-15-7401-g4f3616f", "Rev": "4f3616fb1c112e206b88cb7a9922bf49067a7756" }, { "ImportPath": "github.com/docker/docker/api/types/network", - "Comment": "docs-v1.12.0-rc4-2016-07-15-7401-g4f3616fb1", + "Comment": "docs-v1.12.0-rc4-2016-07-15-7401-g4f3616f", "Rev": "4f3616fb1c112e206b88cb7a9922bf49067a7756" }, { "ImportPath": "github.com/docker/docker/api/types/registry", - "Comment": "docs-v1.12.0-rc4-2016-07-15-7401-g4f3616fb1", + "Comment": "docs-v1.12.0-rc4-2016-07-15-7401-g4f3616f", "Rev": "4f3616fb1c112e206b88cb7a9922bf49067a7756" }, { "ImportPath": "github.com/docker/docker/api/types/strslice", - "Comment": "docs-v1.12.0-rc4-2016-07-15-7401-g4f3616fb1", + "Comment": "docs-v1.12.0-rc4-2016-07-15-7401-g4f3616f", "Rev": "4f3616fb1c112e206b88cb7a9922bf49067a7756" }, { "ImportPath": "github.com/docker/docker/api/types/swarm", - "Comment": "docs-v1.12.0-rc4-2016-07-15-7401-g4f3616fb1", + "Comment": "docs-v1.12.0-rc4-2016-07-15-7401-g4f3616f", "Rev": "4f3616fb1c112e206b88cb7a9922bf49067a7756" }, { "ImportPath": "github.com/docker/docker/api/types/swarm/runtime", - "Comment": "docs-v1.12.0-rc4-2016-07-15-7401-g4f3616fb1", + "Comment": "docs-v1.12.0-rc4-2016-07-15-7401-g4f3616f", "Rev": "4f3616fb1c112e206b88cb7a9922bf49067a7756" }, { "ImportPath": "github.com/docker/docker/api/types/time", - "Comment": "docs-v1.12.0-rc4-2016-07-15-7401-g4f3616fb1", + "Comment": "docs-v1.12.0-rc4-2016-07-15-7401-g4f3616f", "Rev": "4f3616fb1c112e206b88cb7a9922bf49067a7756" }, { "ImportPath": "github.com/docker/docker/api/types/versions", - "Comment": "docs-v1.12.0-rc4-2016-07-15-7401-g4f3616fb1", + "Comment": "docs-v1.12.0-rc4-2016-07-15-7401-g4f3616f", "Rev": "4f3616fb1c112e206b88cb7a9922bf49067a7756" }, { "ImportPath": "github.com/docker/docker/api/types/volume", - "Comment": "docs-v1.12.0-rc4-2016-07-15-7401-g4f3616fb1", + "Comment": "docs-v1.12.0-rc4-2016-07-15-7401-g4f3616f", "Rev": "4f3616fb1c112e206b88cb7a9922bf49067a7756" }, { "ImportPath": "github.com/docker/docker/client", - "Comment": "docs-v1.12.0-rc4-2016-07-15-7401-g4f3616fb1", + "Comment": "docs-v1.12.0-rc4-2016-07-15-7401-g4f3616f", "Rev": "4f3616fb1c112e206b88cb7a9922bf49067a7756" }, { "ImportPath": "github.com/docker/docker/pkg/ioutils", - "Comment": "docs-v1.12.0-rc4-2016-07-15-7401-g4f3616fb1", + "Comment": "docs-v1.12.0-rc4-2016-07-15-7401-g4f3616f", "Rev": "4f3616fb1c112e206b88cb7a9922bf49067a7756" }, { "ImportPath": "github.com/docker/docker/pkg/jsonlog", - "Comment": "docs-v1.12.0-rc4-2016-07-15-7401-g4f3616fb1", + "Comment": "docs-v1.12.0-rc4-2016-07-15-7401-g4f3616f", "Rev": "4f3616fb1c112e206b88cb7a9922bf49067a7756" }, { "ImportPath": "github.com/docker/docker/pkg/jsonmessage", - "Comment": "docs-v1.12.0-rc4-2016-07-15-7401-g4f3616fb1", + "Comment": "docs-v1.12.0-rc4-2016-07-15-7401-g4f3616f", "Rev": "4f3616fb1c112e206b88cb7a9922bf49067a7756" }, { "ImportPath": "github.com/docker/docker/pkg/longpath", - "Comment": "docs-v1.12.0-rc4-2016-07-15-7401-g4f3616fb1", + "Comment": "docs-v1.12.0-rc4-2016-07-15-7401-g4f3616f", "Rev": "4f3616fb1c112e206b88cb7a9922bf49067a7756" }, { "ImportPath": "github.com/docker/docker/pkg/mount", - "Comment": "docs-v1.12.0-rc4-2016-07-15-7401-g4f3616fb1", + "Comment": "docs-v1.12.0-rc4-2016-07-15-7401-g4f3616f", + "Rev": "4f3616fb1c112e206b88cb7a9922bf49067a7756" + }, + { + "ImportPath": "github.com/docker/docker/pkg/parsers", + "Comment": "docs-v1.12.0-rc4-2016-07-15-7401-g4f3616f", "Rev": "4f3616fb1c112e206b88cb7a9922bf49067a7756" }, { "ImportPath": "github.com/docker/docker/pkg/stdcopy", - "Comment": "docs-v1.12.0-rc4-2016-07-15-7401-g4f3616fb1", + "Comment": "docs-v1.12.0-rc4-2016-07-15-7401-g4f3616f", + "Rev": "4f3616fb1c112e206b88cb7a9922bf49067a7756" + }, + { + "ImportPath": "github.com/docker/docker/pkg/sysinfo", + "Comment": "docs-v1.12.0-rc4-2016-07-15-7401-g4f3616f", "Rev": "4f3616fb1c112e206b88cb7a9922bf49067a7756" }, { "ImportPath": "github.com/docker/docker/pkg/system", - "Comment": "docs-v1.12.0-rc4-2016-07-15-7401-g4f3616fb1", + "Comment": "docs-v1.12.0-rc4-2016-07-15-7401-g4f3616f", "Rev": "4f3616fb1c112e206b88cb7a9922bf49067a7756" }, { "ImportPath": "github.com/docker/docker/pkg/term", - "Comment": "docs-v1.12.0-rc4-2016-07-15-7401-g4f3616fb1", + "Comment": "docs-v1.12.0-rc4-2016-07-15-7401-g4f3616f", "Rev": "4f3616fb1c112e206b88cb7a9922bf49067a7756" }, { "ImportPath": "github.com/docker/docker/pkg/term/windows", - "Comment": "docs-v1.12.0-rc4-2016-07-15-7401-g4f3616fb1", + "Comment": "docs-v1.12.0-rc4-2016-07-15-7401-g4f3616f", "Rev": "4f3616fb1c112e206b88cb7a9922bf49067a7756" }, { "ImportPath": "github.com/docker/docker/pkg/tlsconfig", - "Comment": "docs-v1.12.0-rc4-2016-07-15-7401-g4f3616fb1", + "Comment": "docs-v1.12.0-rc4-2016-07-15-7401-g4f3616f", "Rev": "4f3616fb1c112e206b88cb7a9922bf49067a7756" }, { @@ -1156,7 +1166,7 @@ }, { "ImportPath": "github.com/docker/libnetwork/ipvs", - "Comment": "v0.8.0-dev.2-910-gba46b928", + "Comment": "v0.8.0-dev.2-910-gba46b92", "Rev": "ba46b928444931e6865d8618dc03622cac79aa6f" }, { @@ -1283,132 +1293,132 @@ }, { "ImportPath": "github.com/gogo/protobuf/gogoproto", - "Comment": "v0.4-3-gc0656edd", + "Comment": "v0.4-3-gc0656ed", "Rev": "c0656edd0d9eab7c66d1eb0c568f9039345796f7" }, { "ImportPath": "github.com/gogo/protobuf/plugin/compare", - "Comment": "v0.4-3-gc0656edd", + "Comment": "v0.4-3-gc0656ed", "Rev": "c0656edd0d9eab7c66d1eb0c568f9039345796f7" }, { "ImportPath": "github.com/gogo/protobuf/plugin/defaultcheck", - "Comment": "v0.4-3-gc0656edd", + "Comment": "v0.4-3-gc0656ed", "Rev": "c0656edd0d9eab7c66d1eb0c568f9039345796f7" }, { "ImportPath": "github.com/gogo/protobuf/plugin/description", - "Comment": "v0.4-3-gc0656edd", + "Comment": "v0.4-3-gc0656ed", "Rev": "c0656edd0d9eab7c66d1eb0c568f9039345796f7" }, { "ImportPath": "github.com/gogo/protobuf/plugin/embedcheck", - "Comment": "v0.4-3-gc0656edd", + "Comment": "v0.4-3-gc0656ed", "Rev": "c0656edd0d9eab7c66d1eb0c568f9039345796f7" }, { "ImportPath": "github.com/gogo/protobuf/plugin/enumstringer", - "Comment": "v0.4-3-gc0656edd", + "Comment": "v0.4-3-gc0656ed", "Rev": "c0656edd0d9eab7c66d1eb0c568f9039345796f7" }, { "ImportPath": "github.com/gogo/protobuf/plugin/equal", - "Comment": "v0.4-3-gc0656edd", + "Comment": "v0.4-3-gc0656ed", "Rev": "c0656edd0d9eab7c66d1eb0c568f9039345796f7" }, { "ImportPath": "github.com/gogo/protobuf/plugin/face", - "Comment": "v0.4-3-gc0656edd", + "Comment": "v0.4-3-gc0656ed", "Rev": "c0656edd0d9eab7c66d1eb0c568f9039345796f7" }, { "ImportPath": "github.com/gogo/protobuf/plugin/gostring", - "Comment": "v0.4-3-gc0656edd", + "Comment": "v0.4-3-gc0656ed", "Rev": "c0656edd0d9eab7c66d1eb0c568f9039345796f7" }, { "ImportPath": "github.com/gogo/protobuf/plugin/marshalto", - "Comment": "v0.4-3-gc0656edd", + "Comment": "v0.4-3-gc0656ed", "Rev": "c0656edd0d9eab7c66d1eb0c568f9039345796f7" }, { "ImportPath": "github.com/gogo/protobuf/plugin/oneofcheck", - "Comment": "v0.4-3-gc0656edd", + "Comment": "v0.4-3-gc0656ed", "Rev": "c0656edd0d9eab7c66d1eb0c568f9039345796f7" }, { "ImportPath": "github.com/gogo/protobuf/plugin/populate", - "Comment": "v0.4-3-gc0656edd", + "Comment": "v0.4-3-gc0656ed", "Rev": "c0656edd0d9eab7c66d1eb0c568f9039345796f7" }, { "ImportPath": "github.com/gogo/protobuf/plugin/size", - "Comment": "v0.4-3-gc0656edd", + "Comment": "v0.4-3-gc0656ed", "Rev": "c0656edd0d9eab7c66d1eb0c568f9039345796f7" }, { "ImportPath": "github.com/gogo/protobuf/plugin/stringer", - "Comment": "v0.4-3-gc0656edd", + "Comment": "v0.4-3-gc0656ed", "Rev": "c0656edd0d9eab7c66d1eb0c568f9039345796f7" }, { "ImportPath": "github.com/gogo/protobuf/plugin/testgen", - "Comment": "v0.4-3-gc0656edd", + "Comment": "v0.4-3-gc0656ed", "Rev": "c0656edd0d9eab7c66d1eb0c568f9039345796f7" }, { "ImportPath": "github.com/gogo/protobuf/plugin/union", - "Comment": "v0.4-3-gc0656edd", + "Comment": "v0.4-3-gc0656ed", "Rev": "c0656edd0d9eab7c66d1eb0c568f9039345796f7" }, { "ImportPath": "github.com/gogo/protobuf/plugin/unmarshal", - "Comment": "v0.4-3-gc0656edd", + "Comment": "v0.4-3-gc0656ed", "Rev": "c0656edd0d9eab7c66d1eb0c568f9039345796f7" }, { "ImportPath": "github.com/gogo/protobuf/proto", - "Comment": "v0.4-3-gc0656edd", + "Comment": "v0.4-3-gc0656ed", "Rev": "c0656edd0d9eab7c66d1eb0c568f9039345796f7" }, { "ImportPath": "github.com/gogo/protobuf/protoc-gen-gogo/descriptor", - "Comment": "v0.4-3-gc0656edd", + "Comment": "v0.4-3-gc0656ed", "Rev": "c0656edd0d9eab7c66d1eb0c568f9039345796f7" }, { "ImportPath": "github.com/gogo/protobuf/protoc-gen-gogo/generator", - "Comment": "v0.4-3-gc0656edd", + "Comment": "v0.4-3-gc0656ed", "Rev": "c0656edd0d9eab7c66d1eb0c568f9039345796f7" }, { "ImportPath": "github.com/gogo/protobuf/protoc-gen-gogo/grpc", - "Comment": "v0.4-3-gc0656edd", + "Comment": "v0.4-3-gc0656ed", "Rev": "c0656edd0d9eab7c66d1eb0c568f9039345796f7" }, { "ImportPath": "github.com/gogo/protobuf/protoc-gen-gogo/plugin", - "Comment": "v0.4-3-gc0656edd", + "Comment": "v0.4-3-gc0656ed", "Rev": "c0656edd0d9eab7c66d1eb0c568f9039345796f7" }, { "ImportPath": "github.com/gogo/protobuf/sortkeys", - "Comment": "v0.4-3-gc0656edd", + "Comment": "v0.4-3-gc0656ed", "Rev": "c0656edd0d9eab7c66d1eb0c568f9039345796f7" }, { "ImportPath": "github.com/gogo/protobuf/types", - "Comment": "v0.4-3-gc0656edd", + "Comment": "v0.4-3-gc0656ed", "Rev": "c0656edd0d9eab7c66d1eb0c568f9039345796f7" }, { "ImportPath": "github.com/gogo/protobuf/vanity", - "Comment": "v0.4-3-gc0656edd", + "Comment": "v0.4-3-gc0656ed", "Rev": "c0656edd0d9eab7c66d1eb0c568f9039345796f7" }, { "ImportPath": "github.com/gogo/protobuf/vanity/command", - "Comment": "v0.4-3-gc0656edd", + "Comment": "v0.4-3-gc0656ed", "Rev": "c0656edd0d9eab7c66d1eb0c568f9039345796f7" }, { @@ -2335,82 +2345,82 @@ }, { "ImportPath": "github.com/opencontainers/runc/libcontainer", - "Comment": "v1.0.0-rc4-221-g595bea02", + "Comment": "v1.0.0-rc4-221-g595bea0", "Rev": "595bea022f077a9e17d7473b34fbaf1adaed9e43" }, { "ImportPath": "github.com/opencontainers/runc/libcontainer/apparmor", - "Comment": "v1.0.0-rc4-221-g595bea02", + "Comment": "v1.0.0-rc4-221-g595bea0", "Rev": "595bea022f077a9e17d7473b34fbaf1adaed9e43" }, { "ImportPath": "github.com/opencontainers/runc/libcontainer/cgroups", - "Comment": "v1.0.0-rc4-221-g595bea02", + "Comment": "v1.0.0-rc4-221-g595bea0", "Rev": "595bea022f077a9e17d7473b34fbaf1adaed9e43" }, { "ImportPath": "github.com/opencontainers/runc/libcontainer/cgroups/fs", - "Comment": "v1.0.0-rc4-221-g595bea02", + "Comment": "v1.0.0-rc4-221-g595bea0", "Rev": "595bea022f077a9e17d7473b34fbaf1adaed9e43" }, { "ImportPath": "github.com/opencontainers/runc/libcontainer/cgroups/systemd", - "Comment": "v1.0.0-rc4-221-g595bea02", + "Comment": "v1.0.0-rc4-221-g595bea0", "Rev": "595bea022f077a9e17d7473b34fbaf1adaed9e43" }, { "ImportPath": "github.com/opencontainers/runc/libcontainer/configs", - "Comment": "v1.0.0-rc4-221-g595bea02", + "Comment": "v1.0.0-rc4-221-g595bea0", "Rev": "595bea022f077a9e17d7473b34fbaf1adaed9e43" }, { "ImportPath": "github.com/opencontainers/runc/libcontainer/configs/validate", - "Comment": "v1.0.0-rc4-221-g595bea02", + "Comment": "v1.0.0-rc4-221-g595bea0", "Rev": "595bea022f077a9e17d7473b34fbaf1adaed9e43" }, { "ImportPath": "github.com/opencontainers/runc/libcontainer/criurpc", - "Comment": "v1.0.0-rc4-221-g595bea02", + "Comment": "v1.0.0-rc4-221-g595bea0", "Rev": "595bea022f077a9e17d7473b34fbaf1adaed9e43" }, { "ImportPath": "github.com/opencontainers/runc/libcontainer/intelrdt", - "Comment": "v1.0.0-rc4-221-g595bea02", + "Comment": "v1.0.0-rc4-221-g595bea0", "Rev": "595bea022f077a9e17d7473b34fbaf1adaed9e43" }, { "ImportPath": "github.com/opencontainers/runc/libcontainer/keys", - "Comment": "v1.0.0-rc4-221-g595bea02", + "Comment": "v1.0.0-rc4-221-g595bea0", "Rev": "595bea022f077a9e17d7473b34fbaf1adaed9e43" }, { "ImportPath": "github.com/opencontainers/runc/libcontainer/mount", - "Comment": "v1.0.0-rc4-221-g595bea02", + "Comment": "v1.0.0-rc4-221-g595bea0", "Rev": "595bea022f077a9e17d7473b34fbaf1adaed9e43" }, { "ImportPath": "github.com/opencontainers/runc/libcontainer/seccomp", - "Comment": "v1.0.0-rc4-221-g595bea02", + "Comment": "v1.0.0-rc4-221-g595bea0", "Rev": "595bea022f077a9e17d7473b34fbaf1adaed9e43" }, { "ImportPath": "github.com/opencontainers/runc/libcontainer/stacktrace", - "Comment": "v1.0.0-rc4-221-g595bea02", + "Comment": "v1.0.0-rc4-221-g595bea0", "Rev": "595bea022f077a9e17d7473b34fbaf1adaed9e43" }, { "ImportPath": "github.com/opencontainers/runc/libcontainer/system", - "Comment": "v1.0.0-rc4-221-g595bea02", + "Comment": "v1.0.0-rc4-221-g595bea0", "Rev": "595bea022f077a9e17d7473b34fbaf1adaed9e43" }, { "ImportPath": "github.com/opencontainers/runc/libcontainer/user", - "Comment": "v1.0.0-rc4-221-g595bea02", + "Comment": "v1.0.0-rc4-221-g595bea0", "Rev": "595bea022f077a9e17d7473b34fbaf1adaed9e43" }, { "ImportPath": "github.com/opencontainers/runc/libcontainer/utils", - "Comment": "v1.0.0-rc4-221-g595bea02", + "Comment": "v1.0.0-rc4-221-g595bea0", "Rev": "595bea022f077a9e17d7473b34fbaf1adaed9e43" }, { diff --git a/Godeps/LICENSES b/Godeps/LICENSES index a1f330d6d62..6b70cc52f63 100644 --- a/Godeps/LICENSES +++ b/Godeps/LICENSES @@ -39050,6 +39050,205 @@ Apache License ================================================================================ +================================================================================ += vendor/github.com/docker/docker/pkg/parsers licensed under: = + + + Apache License + Version 2.0, January 2004 + https://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + Copyright 2013-2017 Docker, Inc. + + 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 + + https://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. + += vendor/github.com/docker/docker/LICENSE 9740d093a080530b5c5c6573df9af45a +================================================================================ + + ================================================================================ = vendor/github.com/docker/docker/pkg/stdcopy licensed under: = @@ -39249,6 +39448,205 @@ Apache License ================================================================================ +================================================================================ += vendor/github.com/docker/docker/pkg/sysinfo licensed under: = + + + Apache License + Version 2.0, January 2004 + https://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + Copyright 2013-2017 Docker, Inc. + + 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 + + https://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. + += vendor/github.com/docker/docker/LICENSE 9740d093a080530b5c5c6573df9af45a +================================================================================ + + ================================================================================ = vendor/github.com/docker/docker/pkg/system licensed under: = diff --git a/pkg/kubelet/apis/BUILD b/pkg/kubelet/apis/BUILD index a371d20f496..47cb8184ccb 100644 --- a/pkg/kubelet/apis/BUILD +++ b/pkg/kubelet/apis/BUILD @@ -10,8 +10,20 @@ go_library( srcs = [ "well_known_annotations.go", "well_known_labels.go", - ], + ] + select({ + "@io_bazel_rules_go//go/platform:windows": [ + "well_known_annotations_windows.go", + ], + "//conditions:default": [], + }), importpath = "k8s.io/kubernetes/pkg/kubelet/apis", + deps = select({ + "@io_bazel_rules_go//go/platform:windows": [ + "//pkg/features:go_default_library", + "//vendor/k8s.io/apiserver/pkg/util/feature:go_default_library", + ], + "//conditions:default": [], + }), ) filegroup( diff --git a/pkg/kubelet/apis/well_known_annotations_windows.go b/pkg/kubelet/apis/well_known_annotations_windows.go new file mode 100644 index 00000000000..0e738895ee0 --- /dev/null +++ b/pkg/kubelet/apis/well_known_annotations_windows.go @@ -0,0 +1,41 @@ +// +build windows + +/* +Copyright 2018 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 apis + +import ( + utilfeature "k8s.io/apiserver/pkg/util/feature" + "k8s.io/kubernetes/pkg/features" +) + +const ( + // HypervIsolationAnnotationKey and HypervIsolationValue are used to run windows containers with hyperv isolation. + // Refer https://aka.ms/hyperv-container. + HypervIsolationAnnotationKey = "experimental.windows.kubernetes.io/isolation-type" + HypervIsolationValue = "hyperv" +) + +// ShouldIsolatedByHyperV returns true if a windows container should be run with hyperv isolation. +func ShouldIsolatedByHyperV(annotations map[string]string) bool { + if !utilfeature.DefaultFeatureGate.Enabled(features.HyperVContainer) { + return false + } + + v, ok := annotations[HypervIsolationAnnotationKey] + return ok && v == HypervIsolationValue +} diff --git a/pkg/kubelet/dockershim/BUILD b/pkg/kubelet/dockershim/BUILD index eec1a3adc17..2429b526375 100644 --- a/pkg/kubelet/dockershim/BUILD +++ b/pkg/kubelet/dockershim/BUILD @@ -1,10 +1,4 @@ -package(default_visibility = ["//visibility:public"]) - -load( - "@io_bazel_rules_go//go:def.bzl", - "go_library", - "go_test", -) +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") go_library( name = "go_default_library", @@ -83,6 +77,7 @@ go_library( "//conditions:default": [], }), importpath = "k8s.io/kubernetes/pkg/kubelet/dockershim", + visibility = ["//visibility:public"], deps = [ "//pkg/credentialprovider:go_default_library", "//pkg/kubelet/apis/cri/runtime/v1alpha2:go_default_library", @@ -126,9 +121,8 @@ go_library( "//vendor/k8s.io/utils/exec:go_default_library", ] + select({ "@io_bazel_rules_go//go/platform:windows": [ - "//pkg/features:go_default_library", + "//pkg/kubelet/apis:go_default_library", "//pkg/kubelet/winstats:go_default_library", - "//vendor/k8s.io/apiserver/pkg/util/feature:go_default_library", ], "//conditions:default": [], }), @@ -153,8 +147,6 @@ go_test( ], "//conditions:default": [], }), - data = [ - ], embed = [":go_default_library"], deps = [ "//pkg/kubelet/apis/cri/runtime/v1alpha2:go_default_library", @@ -198,4 +190,5 @@ filegroup( "//pkg/kubelet/dockershim/testing:all-srcs", ], tags = ["automanaged"], + visibility = ["//visibility:public"], ) diff --git a/pkg/kubelet/dockershim/helpers_windows.go b/pkg/kubelet/dockershim/helpers_windows.go index 4636800b5f9..e614eed851b 100644 --- a/pkg/kubelet/dockershim/helpers_windows.go +++ b/pkg/kubelet/dockershim/helpers_windows.go @@ -27,18 +27,10 @@ import ( dockerfilters "github.com/docker/docker/api/types/filters" "github.com/golang/glog" - utilfeature "k8s.io/apiserver/pkg/util/feature" - "k8s.io/kubernetes/pkg/features" + kubeletapis "k8s.io/kubernetes/pkg/kubelet/apis" runtimeapi "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2" ) -const ( - hypervIsolationAnnotationKey = "experimental.windows.kubernetes.io/isolation-type" - - // Refer https://aka.ms/hyperv-container. - hypervIsolation = "hyperv" -) - func DefaultMemorySwap() int64 { return 0 } @@ -50,19 +42,10 @@ func (ds *dockerService) getSecurityOpts(seccompProfile string, separator rune) return nil, nil } -func shouldIsolatedByHyperV(annotations map[string]string) bool { - if !utilfeature.DefaultFeatureGate.Enabled(features.HyperVContainer) { - return false - } - - v, ok := annotations[hypervIsolationAnnotationKey] - return ok && v == hypervIsolation -} - // applyExperimentalCreateConfig applys experimental configures from sandbox annotations. func applyExperimentalCreateConfig(createConfig *dockertypes.ContainerCreateConfig, annotations map[string]string) { - if shouldIsolatedByHyperV(annotations) { - createConfig.HostConfig.Isolation = hypervIsolation + if kubeletapis.ShouldIsolatedByHyperV(annotations) { + createConfig.HostConfig.Isolation = kubeletapis.HypervIsolationValue if networkMode := os.Getenv("CONTAINER_NETWORK"); networkMode == "" { createConfig.HostConfig.NetworkMode = dockercontainer.NetworkMode("none") @@ -77,11 +60,24 @@ func (ds *dockerService) updateCreateConfig( podSandboxID string, securityOptSep rune, apiVersion *semver.Version) error { if networkMode := os.Getenv("CONTAINER_NETWORK"); networkMode != "" { createConfig.HostConfig.NetworkMode = dockercontainer.NetworkMode(networkMode) - } else if !shouldIsolatedByHyperV(sandboxConfig.Annotations) { + } else if !kubeletapis.ShouldIsolatedByHyperV(sandboxConfig.Annotations) { // Todo: Refactor this call in future for calling methods directly in security_context.go modifyHostOptionsForContainer(nil, podSandboxID, createConfig.HostConfig) } + // Apply Windows-specific options if applicable. + if wc := config.GetWindows(); wc != nil { + rOpts := wc.GetResources() + if rOpts != nil { + createConfig.HostConfig.Resources = dockercontainer.Resources{ + Memory: rOpts.MemoryLimitInBytes, + CPUShares: rOpts.CpuShares, + CPUCount: rOpts.CpuCount, + CPUPercent: rOpts.CpuMaximum, + } + } + } + applyExperimentalCreateConfig(createConfig, sandboxConfig.Annotations) return nil @@ -119,7 +115,7 @@ func (ds *dockerService) determinePodIPBySandboxID(sandboxID string) string { // Todo: Add a kernel version check for more validation if networkMode := os.Getenv("CONTAINER_NETWORK"); networkMode == "" { - if r.HostConfig.Isolation == hypervIsolation { + if r.HostConfig.Isolation == kubeletapis.HypervIsolationValue { // Hyper-V only supports one container per Pod yet and the container will have a different // IP address from sandbox. Return the first non-sandbox container IP as POD IP. // TODO(feiskyer): remove this workaround after Hyper-V supports multiple containers per Pod. diff --git a/pkg/kubelet/kuberuntime/BUILD b/pkg/kubelet/kuberuntime/BUILD index b52b1ffaebb..7fc904d311a 100644 --- a/pkg/kubelet/kuberuntime/BUILD +++ b/pkg/kubelet/kuberuntime/BUILD @@ -22,7 +22,53 @@ go_library( "labels.go", "legacy.go", "security_context.go", - ], + ] + select({ + "@io_bazel_rules_go//go/platform:android": [ + "helpers_unsupported.go", + "kuberuntime_container_unsupported.go", + ], + "@io_bazel_rules_go//go/platform:darwin": [ + "helpers_unsupported.go", + "kuberuntime_container_unsupported.go", + ], + "@io_bazel_rules_go//go/platform:dragonfly": [ + "helpers_unsupported.go", + "kuberuntime_container_unsupported.go", + ], + "@io_bazel_rules_go//go/platform:freebsd": [ + "helpers_unsupported.go", + "kuberuntime_container_unsupported.go", + ], + "@io_bazel_rules_go//go/platform:linux": [ + "helpers_linux.go", + "kuberuntime_container_linux.go", + ], + "@io_bazel_rules_go//go/platform:nacl": [ + "helpers_unsupported.go", + "kuberuntime_container_unsupported.go", + ], + "@io_bazel_rules_go//go/platform:netbsd": [ + "helpers_unsupported.go", + "kuberuntime_container_unsupported.go", + ], + "@io_bazel_rules_go//go/platform:openbsd": [ + "helpers_unsupported.go", + "kuberuntime_container_unsupported.go", + ], + "@io_bazel_rules_go//go/platform:plan9": [ + "helpers_unsupported.go", + "kuberuntime_container_unsupported.go", + ], + "@io_bazel_rules_go//go/platform:solaris": [ + "helpers_unsupported.go", + "kuberuntime_container_unsupported.go", + ], + "@io_bazel_rules_go//go/platform:windows": [ + "helpers_windows.go", + "kuberuntime_container_windows.go", + ], + "//conditions:default": [], + }), importpath = "k8s.io/kubernetes/pkg/kubelet/kuberuntime", deps = [ "//pkg/api/legacyscheme:go_default_library", @@ -40,7 +86,6 @@ go_library( "//pkg/kubelet/lifecycle:go_default_library", "//pkg/kubelet/metrics:go_default_library", "//pkg/kubelet/prober/results:go_default_library", - "//pkg/kubelet/qos:go_default_library", "//pkg/kubelet/types:go_default_library", "//pkg/kubelet/util/cache:go_default_library", "//pkg/kubelet/util/format:go_default_library", @@ -64,7 +109,16 @@ go_library( "//vendor/k8s.io/client-go/tools/record:go_default_library", "//vendor/k8s.io/client-go/tools/reference:go_default_library", "//vendor/k8s.io/client-go/util/flowcontrol:go_default_library", - ], + ] + select({ + "@io_bazel_rules_go//go/platform:linux": [ + "//pkg/kubelet/qos:go_default_library", + ], + "@io_bazel_rules_go//go/platform:windows": [ + "//pkg/kubelet/apis:go_default_library", + "//vendor/github.com/docker/docker/pkg/sysinfo:go_default_library", + ], + "//conditions:default": [], + }), ) go_test( @@ -80,7 +134,12 @@ go_test( "labels_test.go", "legacy_test.go", "security_context_test.go", - ], + ] + select({ + "@io_bazel_rules_go//go/platform:linux": [ + "kuberuntime_container_linux_test.go", + ], + "//conditions:default": [], + }), embed = [":go_default_library"], deps = [ "//pkg/credentialprovider:go_default_library", diff --git a/pkg/kubelet/kuberuntime/helpers.go b/pkg/kubelet/kuberuntime/helpers.go index e66440447aa..a1e6119a2a9 100644 --- a/pkg/kubelet/kuberuntime/helpers.go +++ b/pkg/kubelet/kuberuntime/helpers.go @@ -32,17 +32,6 @@ import ( kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" ) -const ( - // Taken from lmctfy https://github.com/google/lmctfy/blob/master/lmctfy/controllers/cpu_controller.cc - minShares = 2 - sharesPerCPU = 1024 - milliCPUToCPU = 1000 - - // 100000 is equivalent to 100ms - quotaPeriod = 100 * minQuotaPeriod - minQuotaPeriod = 1000 -) - type podsByID []*kubecontainer.Pod func (b podsByID) Len() int { return len(b) } @@ -160,45 +149,6 @@ func isContainerFailed(status *kubecontainer.ContainerStatus) bool { return false } -// milliCPUToShares converts milliCPU to CPU shares -func milliCPUToShares(milliCPU int64) int64 { - if milliCPU == 0 { - // Return 2 here to really match kernel default for zero milliCPU. - return minShares - } - // Conceptually (milliCPU / milliCPUToCPU) * sharesPerCPU, but factored to improve rounding. - shares := (milliCPU * sharesPerCPU) / milliCPUToCPU - if shares < minShares { - return minShares - } - return shares -} - -// milliCPUToQuota converts milliCPU to CFS quota and period values -func milliCPUToQuota(milliCPU int64) (quota int64, period int64) { - // CFS quota is measured in two values: - // - cfs_period_us=100ms (the amount of time to measure usage across) - // - cfs_quota=20ms (the amount of cpu time allowed to be used across a period) - // so in the above example, you are limited to 20% of a single CPU - // for multi-cpu environments, you just scale equivalent amounts - if milliCPU == 0 { - return - } - - // we set the period to 100ms by default - period = quotaPeriod - - // we then convert your milliCPU to a value normalized over a period - quota = (milliCPU * quotaPeriod) / milliCPUToCPU - - // quota needs to be a minimum of 1ms. - if quota < minQuotaPeriod { - quota = minQuotaPeriod - } - - return -} - // getStableKey generates a key (string) to uniquely identify a // (pod, container) tuple. The key should include the content of the // container, so that any change to the container generates a new key. diff --git a/pkg/kubelet/kuberuntime/helpers_linux.go b/pkg/kubelet/kuberuntime/helpers_linux.go new file mode 100644 index 00000000000..15abb4a0889 --- /dev/null +++ b/pkg/kubelet/kuberuntime/helpers_linux.go @@ -0,0 +1,69 @@ +// +build linux + +/* +Copyright 2018 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 kuberuntime + +const ( + // Taken from lmctfy https://github.com/google/lmctfy/blob/master/lmctfy/controllers/cpu_controller.cc + minShares = 2 + sharesPerCPU = 1024 + milliCPUToCPU = 1000 + + // 100000 is equivalent to 100ms + quotaPeriod = 100 * minQuotaPeriod + minQuotaPeriod = 1000 +) + +// milliCPUToShares converts milliCPU to CPU shares +func milliCPUToShares(milliCPU int64) int64 { + if milliCPU == 0 { + // Return 2 here to really match kernel default for zero milliCPU. + return minShares + } + // Conceptually (milliCPU / milliCPUToCPU) * sharesPerCPU, but factored to improve rounding. + shares := (milliCPU * sharesPerCPU) / milliCPUToCPU + if shares < minShares { + return minShares + } + return shares +} + +// milliCPUToQuota converts milliCPU to CFS quota and period values +func milliCPUToQuota(milliCPU int64) (quota int64, period int64) { + // CFS quota is measured in two values: + // - cfs_period_us=100ms (the amount of time to measure usage across) + // - cfs_quota=20ms (the amount of cpu time allowed to be used across a period) + // so in the above example, you are limited to 20% of a single CPU + // for multi-cpu environments, you just scale equivalent amounts + if milliCPU == 0 { + return + } + + // we set the period to 100ms by default + period = quotaPeriod + + // we then convert your milliCPU to a value normalized over a period + quota = (milliCPU * quotaPeriod) / milliCPUToCPU + + // quota needs to be a minimum of 1ms. + if quota < minQuotaPeriod { + quota = minQuotaPeriod + } + + return +} diff --git a/pkg/kubelet/kuberuntime/helpers_unsupported.go b/pkg/kubelet/kuberuntime/helpers_unsupported.go new file mode 100644 index 00000000000..1e99c4f9317 --- /dev/null +++ b/pkg/kubelet/kuberuntime/helpers_unsupported.go @@ -0,0 +1,24 @@ +// +build !linux,!windows + +/* +Copyright 2018 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 kuberuntime + +// milliCPUToShares converts milliCPU to CPU shares +func milliCPUToShares(milliCPU int64) int64 { + return 0 +} diff --git a/pkg/kubelet/kuberuntime/helpers_windows.go b/pkg/kubelet/kuberuntime/helpers_windows.go new file mode 100644 index 00000000000..2009fad8d0f --- /dev/null +++ b/pkg/kubelet/kuberuntime/helpers_windows.go @@ -0,0 +1,55 @@ +// +build windows + +/* +Copyright 2018 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 kuberuntime + +import ( + "github.com/docker/docker/pkg/sysinfo" +) + +const ( + // Taken from https://docs.microsoft.com/en-us/virtualization/windowscontainers/manage-containers/resource-controls + minSharesProcess = 5000 + minSharesHyperV = 10 + maxShares = 10000 + milliCPUToCPU = 1000 +) + +// milliCPUToShares converts milliCPU to CPU shares +func milliCPUToShares(milliCPU int64, hyperv bool) int64 { + var minShares int64 = minSharesProcess + if hyperv { + minShares = minSharesHyperV + } + + if milliCPU == 0 { + // Return here to really match kernel default for zero milliCPU. + return minShares + } + + // Conceptually (milliCPU / milliCPUToCPU) * sharesPerCPU, but factored to improve rounding. + totalCPU := sysinfo.NumCPU() + shares := (milliCPU * (maxShares - minShares)) / int64(totalCPU) / milliCPUToCPU + if shares < minShares { + return minShares + } + if shares > maxShares { + return maxShares + } + return shares +} diff --git a/pkg/kubelet/kuberuntime/kuberuntime_container.go b/pkg/kubelet/kuberuntime/kuberuntime_container.go index 650bfaa790d..2dadd7a66e6 100644 --- a/pkg/kubelet/kuberuntime/kuberuntime_container.go +++ b/pkg/kubelet/kuberuntime/kuberuntime_container.go @@ -42,7 +42,6 @@ import ( runtimeapi "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2" kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" "k8s.io/kubernetes/pkg/kubelet/events" - "k8s.io/kubernetes/pkg/kubelet/qos" "k8s.io/kubernetes/pkg/kubelet/types" "k8s.io/kubernetes/pkg/kubelet/util/format" "k8s.io/kubernetes/pkg/util/selinux" @@ -214,7 +213,11 @@ func (m *kubeGenericRuntimeManager) generateContainerConfig(container *v1.Contai Stdin: container.Stdin, StdinOnce: container.StdinOnce, Tty: container.TTY, - Linux: m.generateLinuxContainerConfig(container, pod, uid, username), + } + + // set platform specific configurations. + if err := m.applyPlatformSpecificContainerConfig(config, container, pod, uid, username); err != nil { + return nil, err } // set environment variables @@ -231,49 +234,6 @@ func (m *kubeGenericRuntimeManager) generateContainerConfig(container *v1.Contai return config, nil } -// generateLinuxContainerConfig generates linux container config for kubelet runtime v1. -func (m *kubeGenericRuntimeManager) generateLinuxContainerConfig(container *v1.Container, pod *v1.Pod, uid *int64, username string) *runtimeapi.LinuxContainerConfig { - lc := &runtimeapi.LinuxContainerConfig{ - Resources: &runtimeapi.LinuxContainerResources{}, - SecurityContext: m.determineEffectiveSecurityContext(pod, container, uid, username), - } - - // set linux container resources - var cpuShares int64 - cpuRequest := container.Resources.Requests.Cpu() - cpuLimit := container.Resources.Limits.Cpu() - memoryLimit := container.Resources.Limits.Memory().Value() - oomScoreAdj := int64(qos.GetContainerOOMScoreAdjust(pod, container, - int64(m.machineInfo.MemoryCapacity))) - // If request is not specified, but limit is, we want request to default to limit. - // API server does this for new containers, but we repeat this logic in Kubelet - // for containers running on existing Kubernetes clusters. - if cpuRequest.IsZero() && !cpuLimit.IsZero() { - cpuShares = milliCPUToShares(cpuLimit.MilliValue()) - } else { - // if cpuRequest.Amount is nil, then milliCPUToShares will return the minimal number - // of CPU shares. - cpuShares = milliCPUToShares(cpuRequest.MilliValue()) - } - lc.Resources.CpuShares = cpuShares - if memoryLimit != 0 { - lc.Resources.MemoryLimitInBytes = memoryLimit - } - // Set OOM score of the container based on qos policy. Processes in lower-priority pods should - // be killed first if the system runs out of memory. - lc.Resources.OomScoreAdj = oomScoreAdj - - if m.cpuCFSQuota { - // if cpuLimit.Amount is nil, then the appropriate default value is returned - // to allow full usage of cpu resource. - cpuQuota, cpuPeriod := milliCPUToQuota(cpuLimit.MilliValue()) - lc.Resources.CpuQuota = cpuQuota - lc.Resources.CpuPeriod = cpuPeriod - } - - return lc -} - // makeDevices generates container devices for kubelet runtime v1. func makeDevices(opts *kubecontainer.RunContainerOptions) []*runtimeapi.Device { devices := make([]*runtimeapi.Device, len(opts.Devices)) diff --git a/pkg/kubelet/kuberuntime/kuberuntime_container_linux.go b/pkg/kubelet/kuberuntime/kuberuntime_container_linux.go new file mode 100644 index 00000000000..cdac02ffb53 --- /dev/null +++ b/pkg/kubelet/kuberuntime/kuberuntime_container_linux.go @@ -0,0 +1,74 @@ +// +build linux + +/* +Copyright 2018 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 kuberuntime + +import ( + "k8s.io/api/core/v1" + runtimeapi "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2" + "k8s.io/kubernetes/pkg/kubelet/qos" +) + +// applyPlatformSpecificContainerConfig applies platform specific configurations to runtimeapi.ContainerConfig. +func (m *kubeGenericRuntimeManager) applyPlatformSpecificContainerConfig(config *runtimeapi.ContainerConfig, container *v1.Container, pod *v1.Pod, uid *int64, username string) error { + config.Linux = m.generateLinuxContainerConfig(container, pod, uid, username) + return nil +} + +// generateLinuxContainerConfig generates linux container config for kubelet runtime v1. +func (m *kubeGenericRuntimeManager) generateLinuxContainerConfig(container *v1.Container, pod *v1.Pod, uid *int64, username string) *runtimeapi.LinuxContainerConfig { + lc := &runtimeapi.LinuxContainerConfig{ + Resources: &runtimeapi.LinuxContainerResources{}, + SecurityContext: m.determineEffectiveSecurityContext(pod, container, uid, username), + } + + // set linux container resources + var cpuShares int64 + cpuRequest := container.Resources.Requests.Cpu() + cpuLimit := container.Resources.Limits.Cpu() + memoryLimit := container.Resources.Limits.Memory().Value() + oomScoreAdj := int64(qos.GetContainerOOMScoreAdjust(pod, container, + int64(m.machineInfo.MemoryCapacity))) + // If request is not specified, but limit is, we want request to default to limit. + // API server does this for new containers, but we repeat this logic in Kubelet + // for containers running on existing Kubernetes clusters. + if cpuRequest.IsZero() && !cpuLimit.IsZero() { + cpuShares = milliCPUToShares(cpuLimit.MilliValue()) + } else { + // if cpuRequest.Amount is nil, then milliCPUToShares will return the minimal number + // of CPU shares. + cpuShares = milliCPUToShares(cpuRequest.MilliValue()) + } + lc.Resources.CpuShares = cpuShares + if memoryLimit != 0 { + lc.Resources.MemoryLimitInBytes = memoryLimit + } + // Set OOM score of the container based on qos policy. Processes in lower-priority pods should + // be killed first if the system runs out of memory. + lc.Resources.OomScoreAdj = oomScoreAdj + + if m.cpuCFSQuota { + // if cpuLimit.Amount is nil, then the appropriate default value is returned + // to allow full usage of cpu resource. + cpuQuota, cpuPeriod := milliCPUToQuota(cpuLimit.MilliValue()) + lc.Resources.CpuQuota = cpuQuota + lc.Resources.CpuPeriod = cpuPeriod + } + + return lc +} diff --git a/pkg/kubelet/kuberuntime/kuberuntime_container_linux_test.go b/pkg/kubelet/kuberuntime/kuberuntime_container_linux_test.go new file mode 100644 index 00000000000..7bd9aafac83 --- /dev/null +++ b/pkg/kubelet/kuberuntime/kuberuntime_container_linux_test.go @@ -0,0 +1,130 @@ +// +build linux + +/* +Copyright 2018 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 kuberuntime + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtimeapi "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2" + kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" +) + +func makeExpectedConfig(m *kubeGenericRuntimeManager, pod *v1.Pod, containerIndex int) *runtimeapi.ContainerConfig { + container := &pod.Spec.Containers[containerIndex] + podIP := "" + restartCount := 0 + opts, _ := m.runtimeHelper.GenerateRunContainerOptions(pod, container, podIP) + containerLogsPath := buildContainerLogsPath(container.Name, restartCount) + restartCountUint32 := uint32(restartCount) + envs := make([]*runtimeapi.KeyValue, len(opts.Envs)) + + expectedConfig := &runtimeapi.ContainerConfig{ + Metadata: &runtimeapi.ContainerMetadata{ + Name: container.Name, + Attempt: restartCountUint32, + }, + Image: &runtimeapi.ImageSpec{Image: container.Image}, + Command: container.Command, + Args: []string(nil), + WorkingDir: container.WorkingDir, + Labels: newContainerLabels(container, pod, kubecontainer.ContainerTypeRegular), + Annotations: newContainerAnnotations(container, pod, restartCount, opts), + Devices: makeDevices(opts), + Mounts: m.makeMounts(opts, container), + LogPath: containerLogsPath, + Stdin: container.Stdin, + StdinOnce: container.StdinOnce, + Tty: container.TTY, + Linux: m.generateLinuxContainerConfig(container, pod, new(int64), ""), + Envs: envs, + } + return expectedConfig +} + +func TestGenerateContainerConfig(t *testing.T) { + _, imageService, m, err := createTestRuntimeManager() + assert.NoError(t, err) + + pod := &v1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + UID: "12345678", + Name: "bar", + Namespace: "new", + }, + Spec: v1.PodSpec{ + Containers: []v1.Container{ + { + Name: "foo", + Image: "busybox", + ImagePullPolicy: v1.PullIfNotPresent, + Command: []string{"testCommand"}, + WorkingDir: "testWorkingDir", + }, + }, + }, + } + + expectedConfig := makeExpectedConfig(m, pod, 0) + containerConfig, err := m.generateContainerConfig(&pod.Spec.Containers[0], pod, 0, "", pod.Spec.Containers[0].Image, kubecontainer.ContainerTypeRegular) + assert.NoError(t, err) + assert.Equal(t, expectedConfig, containerConfig, "generate container config for kubelet runtime v1.") + + runAsUser := int64(0) + runAsNonRootTrue := true + podWithContainerSecurityContext := &v1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + UID: "12345678", + Name: "bar", + Namespace: "new", + }, + Spec: v1.PodSpec{ + Containers: []v1.Container{ + { + Name: "foo", + Image: "busybox", + ImagePullPolicy: v1.PullIfNotPresent, + Command: []string{"testCommand"}, + WorkingDir: "testWorkingDir", + SecurityContext: &v1.SecurityContext{ + RunAsNonRoot: &runAsNonRootTrue, + RunAsUser: &runAsUser, + }, + }, + }, + }, + } + + _, err = m.generateContainerConfig(&podWithContainerSecurityContext.Spec.Containers[0], podWithContainerSecurityContext, 0, "", podWithContainerSecurityContext.Spec.Containers[0].Image, kubecontainer.ContainerTypeRegular) + assert.Error(t, err) + + imageId, _ := imageService.PullImage(&runtimeapi.ImageSpec{Image: "busybox"}, nil) + image, _ := imageService.ImageStatus(&runtimeapi.ImageSpec{Image: imageId}) + + image.Uid = nil + image.Username = "test" + + podWithContainerSecurityContext.Spec.Containers[0].SecurityContext.RunAsUser = nil + podWithContainerSecurityContext.Spec.Containers[0].SecurityContext.RunAsNonRoot = &runAsNonRootTrue + + _, err = m.generateContainerConfig(&podWithContainerSecurityContext.Spec.Containers[0], podWithContainerSecurityContext, 0, "", podWithContainerSecurityContext.Spec.Containers[0].Image, kubecontainer.ContainerTypeRegular) + assert.Error(t, err, "RunAsNonRoot should fail for non-numeric username") +} diff --git a/pkg/kubelet/kuberuntime/kuberuntime_container_test.go b/pkg/kubelet/kuberuntime/kuberuntime_container_test.go index b0ab9a70ccc..64845b8c9ad 100644 --- a/pkg/kubelet/kuberuntime/kuberuntime_container_test.go +++ b/pkg/kubelet/kuberuntime/kuberuntime_container_test.go @@ -203,107 +203,6 @@ func TestToKubeContainerStatus(t *testing.T) { } } -func makeExpectedConfig(m *kubeGenericRuntimeManager, pod *v1.Pod, containerIndex int) *runtimeapi.ContainerConfig { - container := &pod.Spec.Containers[containerIndex] - podIP := "" - restartCount := 0 - opts, _ := m.runtimeHelper.GenerateRunContainerOptions(pod, container, podIP) - containerLogsPath := buildContainerLogsPath(container.Name, restartCount) - restartCountUint32 := uint32(restartCount) - envs := make([]*runtimeapi.KeyValue, len(opts.Envs)) - - expectedConfig := &runtimeapi.ContainerConfig{ - Metadata: &runtimeapi.ContainerMetadata{ - Name: container.Name, - Attempt: restartCountUint32, - }, - Image: &runtimeapi.ImageSpec{Image: container.Image}, - Command: container.Command, - Args: []string(nil), - WorkingDir: container.WorkingDir, - Labels: newContainerLabels(container, pod, kubecontainer.ContainerTypeRegular), - Annotations: newContainerAnnotations(container, pod, restartCount, opts), - Devices: makeDevices(opts), - Mounts: m.makeMounts(opts, container), - LogPath: containerLogsPath, - Stdin: container.Stdin, - StdinOnce: container.StdinOnce, - Tty: container.TTY, - Linux: m.generateLinuxContainerConfig(container, pod, new(int64), ""), - Envs: envs, - } - return expectedConfig -} - -func TestGenerateContainerConfig(t *testing.T) { - _, imageService, m, err := createTestRuntimeManager() - assert.NoError(t, err) - - pod := &v1.Pod{ - ObjectMeta: metav1.ObjectMeta{ - UID: "12345678", - Name: "bar", - Namespace: "new", - }, - Spec: v1.PodSpec{ - Containers: []v1.Container{ - { - Name: "foo", - Image: "busybox", - ImagePullPolicy: v1.PullIfNotPresent, - Command: []string{"testCommand"}, - WorkingDir: "testWorkingDir", - }, - }, - }, - } - - expectedConfig := makeExpectedConfig(m, pod, 0) - containerConfig, err := m.generateContainerConfig(&pod.Spec.Containers[0], pod, 0, "", pod.Spec.Containers[0].Image, kubecontainer.ContainerTypeRegular) - assert.NoError(t, err) - assert.Equal(t, expectedConfig, containerConfig, "generate container config for kubelet runtime v1.") - - runAsUser := int64(0) - runAsNonRootTrue := true - podWithContainerSecurityContext := &v1.Pod{ - ObjectMeta: metav1.ObjectMeta{ - UID: "12345678", - Name: "bar", - Namespace: "new", - }, - Spec: v1.PodSpec{ - Containers: []v1.Container{ - { - Name: "foo", - Image: "busybox", - ImagePullPolicy: v1.PullIfNotPresent, - Command: []string{"testCommand"}, - WorkingDir: "testWorkingDir", - SecurityContext: &v1.SecurityContext{ - RunAsNonRoot: &runAsNonRootTrue, - RunAsUser: &runAsUser, - }, - }, - }, - }, - } - - _, err = m.generateContainerConfig(&podWithContainerSecurityContext.Spec.Containers[0], podWithContainerSecurityContext, 0, "", podWithContainerSecurityContext.Spec.Containers[0].Image, kubecontainer.ContainerTypeRegular) - assert.Error(t, err) - - imageId, _ := imageService.PullImage(&runtimeapi.ImageSpec{Image: "busybox"}, nil) - image, _ := imageService.ImageStatus(&runtimeapi.ImageSpec{Image: imageId}) - - image.Uid = nil - image.Username = "test" - - podWithContainerSecurityContext.Spec.Containers[0].SecurityContext.RunAsUser = nil - podWithContainerSecurityContext.Spec.Containers[0].SecurityContext.RunAsNonRoot = &runAsNonRootTrue - - _, err = m.generateContainerConfig(&podWithContainerSecurityContext.Spec.Containers[0], podWithContainerSecurityContext, 0, "", podWithContainerSecurityContext.Spec.Containers[0].Image, kubecontainer.ContainerTypeRegular) - assert.Error(t, err, "RunAsNonRoot should fail for non-numeric username") -} - func TestLifeCycleHook(t *testing.T) { // Setup diff --git a/pkg/kubelet/kuberuntime/kuberuntime_container_unsupported.go b/pkg/kubelet/kuberuntime/kuberuntime_container_unsupported.go new file mode 100644 index 00000000000..0344b7d9e93 --- /dev/null +++ b/pkg/kubelet/kuberuntime/kuberuntime_container_unsupported.go @@ -0,0 +1,29 @@ +// +build !linux,!windows + +/* +Copyright 2018 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 kuberuntime + +import ( + "k8s.io/api/core/v1" + runtimeapi "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2" +) + +// applyPlatformSpecificContainerConfig applies platform specific configurations to runtimeapi.ContainerConfig. +func (m *kubeGenericRuntimeManager) applyPlatformSpecificContainerConfig(config *runtimeapi.ContainerConfig, container *v1.Container, pod *v1.Pod, uid *int64, username string) error { + return nil +} diff --git a/pkg/kubelet/kuberuntime/kuberuntime_container_windows.go b/pkg/kubelet/kuberuntime/kuberuntime_container_windows.go new file mode 100644 index 00000000000..6ea1928cf93 --- /dev/null +++ b/pkg/kubelet/kuberuntime/kuberuntime_container_windows.go @@ -0,0 +1,81 @@ +// +build windows + +/* +Copyright 2018 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 kuberuntime + +import ( + "github.com/docker/docker/pkg/sysinfo" + + "k8s.io/api/core/v1" + kubeletapis "k8s.io/kubernetes/pkg/kubelet/apis" + runtimeapi "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2" +) + +// applyPlatformSpecificContainerConfig applies platform specific configurations to runtimeapi.ContainerConfig. +func (m *kubeGenericRuntimeManager) applyPlatformSpecificContainerConfig(config *runtimeapi.ContainerConfig, container *v1.Container, pod *v1.Pod, uid *int64, username string) error { + config.Windows = m.generateWindowsContainerConfig(container, pod, uid, username) + return nil +} + +// generateWindowsContainerConfig generates windows container config for kubelet runtime v1. +// Refer https://github.com/kubernetes/community/blob/master/contributors/design-proposals/node/cri-windows.md. +func (m *kubeGenericRuntimeManager) generateWindowsContainerConfig(container *v1.Container, pod *v1.Pod, uid *int64, username string) *runtimeapi.WindowsContainerConfig { + wc := &runtimeapi.WindowsContainerConfig{ + Resources: &runtimeapi.WindowsContainerResources{}, + } + + cpuRequest := container.Resources.Requests.Cpu() + cpuLimit := container.Resources.Limits.Cpu() + isolatedByHyperv := kubeletapis.ShouldIsolatedByHyperV(pod.Annotations) + if !cpuLimit.IsZero() { + // Note that sysinfo.NumCPU() is limited to 64 CPUs on Windows due to Processor Groups, + // as only 64 processors are available for execution by a given process. This causes + // some oddities on systems with more than 64 processors. + // Refer https://msdn.microsoft.com/en-us/library/windows/desktop/dd405503(v=vs.85).aspx. + cpuMaximum := 10000 * cpuLimit.MilliValue() / int64(sysinfo.NumCPU()) / 1000 + if isolatedByHyperv { + cpuCount := int64(cpuLimit.MilliValue()+999) / 1000 + wc.Resources.CpuCount = cpuCount + + if cpuCount != 0 { + cpuMaximum = cpuLimit.MilliValue() / cpuCount * 10000 / 1000 + } + } + // ensure cpuMaximum is in range [1, 10000]. + if cpuMaximum < 1 { + cpuMaximum = 1 + } else if cpuMaximum > 10000 { + cpuMaximum = 10000 + } + + wc.Resources.CpuMaximum = cpuMaximum + } + + cpuShares := milliCPUToShares(cpuLimit.MilliValue(), isolatedByHyperv) + if cpuShares == 0 { + cpuShares = milliCPUToShares(cpuRequest.MilliValue(), isolatedByHyperv) + } + wc.Resources.CpuShares = cpuShares + + memoryLimit := container.Resources.Limits.Memory().Value() + if memoryLimit != 0 { + wc.Resources.MemoryLimitInBytes = memoryLimit + } + + return wc +} diff --git a/vendor/BUILD b/vendor/BUILD index aa0ec195547..507cc456ab1 100644 --- a/vendor/BUILD +++ b/vendor/BUILD @@ -147,7 +147,9 @@ filegroup( "//vendor/github.com/docker/docker/pkg/jsonmessage:all-srcs", "//vendor/github.com/docker/docker/pkg/longpath:all-srcs", "//vendor/github.com/docker/docker/pkg/mount:all-srcs", + "//vendor/github.com/docker/docker/pkg/parsers:all-srcs", "//vendor/github.com/docker/docker/pkg/stdcopy:all-srcs", + "//vendor/github.com/docker/docker/pkg/sysinfo:all-srcs", "//vendor/github.com/docker/docker/pkg/system:all-srcs", "//vendor/github.com/docker/docker/pkg/term:all-srcs", "//vendor/github.com/docker/docker/pkg/tlsconfig:all-srcs", diff --git a/vendor/github.com/docker/docker/pkg/parsers/BUILD b/vendor/github.com/docker/docker/pkg/parsers/BUILD new file mode 100644 index 00000000000..2ff1ce1c226 --- /dev/null +++ b/vendor/github.com/docker/docker/pkg/parsers/BUILD @@ -0,0 +1,22 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") + +go_library( + name = "go_default_library", + srcs = ["parsers.go"], + importpath = "github.com/docker/docker/pkg/parsers", + visibility = ["//visibility:public"], +) + +filegroup( + name = "package-srcs", + srcs = glob(["**"]), + tags = ["automanaged"], + visibility = ["//visibility:private"], +) + +filegroup( + name = "all-srcs", + srcs = [":package-srcs"], + tags = ["automanaged"], + visibility = ["//visibility:public"], +) diff --git a/vendor/github.com/docker/docker/pkg/parsers/parsers.go b/vendor/github.com/docker/docker/pkg/parsers/parsers.go new file mode 100644 index 00000000000..acc897168f3 --- /dev/null +++ b/vendor/github.com/docker/docker/pkg/parsers/parsers.go @@ -0,0 +1,69 @@ +// Package parsers provides helper functions to parse and validate different type +// of string. It can be hosts, unix addresses, tcp addresses, filters, kernel +// operating system versions. +package parsers + +import ( + "fmt" + "strconv" + "strings" +) + +// ParseKeyValueOpt parses and validates the specified string as a key/value pair (key=value) +func ParseKeyValueOpt(opt string) (string, string, error) { + parts := strings.SplitN(opt, "=", 2) + if len(parts) != 2 { + return "", "", fmt.Errorf("Unable to parse key/value option: %s", opt) + } + return strings.TrimSpace(parts[0]), strings.TrimSpace(parts[1]), nil +} + +// ParseUintList parses and validates the specified string as the value +// found in some cgroup file (e.g. `cpuset.cpus`, `cpuset.mems`), which could be +// one of the formats below. Note that duplicates are actually allowed in the +// input string. It returns a `map[int]bool` with available elements from `val` +// set to `true`. +// Supported formats: +// 7 +// 1-6 +// 0,3-4,7,8-10 +// 0-0,0,1-7 +// 03,1-3 <- this is gonna get parsed as [1,2,3] +// 3,2,1 +// 0-2,3,1 +func ParseUintList(val string) (map[int]bool, error) { + if val == "" { + return map[int]bool{}, nil + } + + availableInts := make(map[int]bool) + split := strings.Split(val, ",") + errInvalidFormat := fmt.Errorf("invalid format: %s", val) + + for _, r := range split { + if !strings.Contains(r, "-") { + v, err := strconv.Atoi(r) + if err != nil { + return nil, errInvalidFormat + } + availableInts[v] = true + } else { + split := strings.SplitN(r, "-", 2) + min, err := strconv.Atoi(split[0]) + if err != nil { + return nil, errInvalidFormat + } + max, err := strconv.Atoi(split[1]) + if err != nil { + return nil, errInvalidFormat + } + if max < min { + return nil, errInvalidFormat + } + for i := min; i <= max; i++ { + availableInts[i] = true + } + } + } + return availableInts, nil +} diff --git a/vendor/github.com/docker/docker/pkg/sysinfo/BUILD b/vendor/github.com/docker/docker/pkg/sysinfo/BUILD new file mode 100644 index 00000000000..78243c5199c --- /dev/null +++ b/vendor/github.com/docker/docker/pkg/sysinfo/BUILD @@ -0,0 +1,90 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") + +go_library( + name = "go_default_library", + srcs = [ + "sysinfo.go", + ] + select({ + "@io_bazel_rules_go//go/platform:android": [ + "numcpu.go", + "sysinfo_unix.go", + ], + "@io_bazel_rules_go//go/platform:darwin": [ + "numcpu.go", + "sysinfo_unix.go", + ], + "@io_bazel_rules_go//go/platform:dragonfly": [ + "numcpu.go", + "sysinfo_unix.go", + ], + "@io_bazel_rules_go//go/platform:freebsd": [ + "numcpu.go", + "sysinfo_unix.go", + ], + "@io_bazel_rules_go//go/platform:linux": [ + "numcpu_linux.go", + "sysinfo_linux.go", + ], + "@io_bazel_rules_go//go/platform:nacl": [ + "numcpu.go", + "sysinfo_unix.go", + ], + "@io_bazel_rules_go//go/platform:netbsd": [ + "numcpu.go", + "sysinfo_unix.go", + ], + "@io_bazel_rules_go//go/platform:openbsd": [ + "numcpu.go", + "sysinfo_unix.go", + ], + "@io_bazel_rules_go//go/platform:plan9": [ + "numcpu.go", + "sysinfo_unix.go", + ], + "@io_bazel_rules_go//go/platform:solaris": [ + "numcpu.go", + "sysinfo_solaris.go", + ], + "@io_bazel_rules_go//go/platform:windows": [ + "numcpu_windows.go", + "sysinfo_windows.go", + ], + "//conditions:default": [], + }), + cgo = True, + clinkopts = select({ + "@io_bazel_rules_go//go/platform:solaris": [ + "-llgrp", + ], + "//conditions:default": [], + }), + importpath = "github.com/docker/docker/pkg/sysinfo", + visibility = ["//visibility:public"], + deps = [ + "//vendor/github.com/docker/docker/pkg/parsers:go_default_library", + ] + select({ + "@io_bazel_rules_go//go/platform:linux": [ + "//vendor/github.com/opencontainers/runc/libcontainer/cgroups:go_default_library", + "//vendor/github.com/sirupsen/logrus:go_default_library", + "//vendor/golang.org/x/sys/unix:go_default_library", + ], + "@io_bazel_rules_go//go/platform:windows": [ + "//vendor/golang.org/x/sys/windows:go_default_library", + ], + "//conditions:default": [], + }), +) + +filegroup( + name = "package-srcs", + srcs = glob(["**"]), + tags = ["automanaged"], + visibility = ["//visibility:private"], +) + +filegroup( + name = "all-srcs", + srcs = [":package-srcs"], + tags = ["automanaged"], + visibility = ["//visibility:public"], +) diff --git a/vendor/github.com/docker/docker/pkg/sysinfo/README.md b/vendor/github.com/docker/docker/pkg/sysinfo/README.md new file mode 100644 index 00000000000..c1530cef0da --- /dev/null +++ b/vendor/github.com/docker/docker/pkg/sysinfo/README.md @@ -0,0 +1 @@ +SysInfo stores information about which features a kernel supports. diff --git a/vendor/github.com/docker/docker/pkg/sysinfo/numcpu.go b/vendor/github.com/docker/docker/pkg/sysinfo/numcpu.go new file mode 100644 index 00000000000..aeb1a3a8040 --- /dev/null +++ b/vendor/github.com/docker/docker/pkg/sysinfo/numcpu.go @@ -0,0 +1,12 @@ +// +build !linux,!windows + +package sysinfo + +import ( + "runtime" +) + +// NumCPU returns the number of CPUs +func NumCPU() int { + return runtime.NumCPU() +} diff --git a/vendor/github.com/docker/docker/pkg/sysinfo/numcpu_linux.go b/vendor/github.com/docker/docker/pkg/sysinfo/numcpu_linux.go new file mode 100644 index 00000000000..f1d2d9db30b --- /dev/null +++ b/vendor/github.com/docker/docker/pkg/sysinfo/numcpu_linux.go @@ -0,0 +1,44 @@ +// +build linux + +package sysinfo + +import ( + "runtime" + "unsafe" + + "golang.org/x/sys/unix" +) + +// numCPU queries the system for the count of threads available +// for use to this process. +// +// Issues two syscalls. +// Returns 0 on errors. Use |runtime.NumCPU| in that case. +func numCPU() int { + // Gets the affinity mask for a process: The very one invoking this function. + pid, _, _ := unix.RawSyscall(unix.SYS_GETPID, 0, 0, 0) + + var mask [1024 / 64]uintptr + _, _, err := unix.RawSyscall(unix.SYS_SCHED_GETAFFINITY, pid, uintptr(len(mask)*8), uintptr(unsafe.Pointer(&mask[0]))) + if err != 0 { + return 0 + } + + // For every available thread a bit is set in the mask. + ncpu := 0 + for _, e := range mask { + if e == 0 { + continue + } + ncpu += int(popcnt(uint64(e))) + } + return ncpu +} + +// NumCPU returns the number of CPUs which are currently online +func NumCPU() int { + if ncpu := numCPU(); ncpu > 0 { + return ncpu + } + return runtime.NumCPU() +} diff --git a/vendor/github.com/docker/docker/pkg/sysinfo/numcpu_windows.go b/vendor/github.com/docker/docker/pkg/sysinfo/numcpu_windows.go new file mode 100644 index 00000000000..1d89dd55030 --- /dev/null +++ b/vendor/github.com/docker/docker/pkg/sysinfo/numcpu_windows.go @@ -0,0 +1,37 @@ +// +build windows + +package sysinfo + +import ( + "runtime" + "unsafe" + + "golang.org/x/sys/windows" +) + +var ( + kernel32 = windows.NewLazySystemDLL("kernel32.dll") + getCurrentProcess = kernel32.NewProc("GetCurrentProcess") + getProcessAffinityMask = kernel32.NewProc("GetProcessAffinityMask") +) + +func numCPU() int { + // Gets the affinity mask for a process + var mask, sysmask uintptr + currentProcess, _, _ := getCurrentProcess.Call() + ret, _, _ := getProcessAffinityMask.Call(currentProcess, uintptr(unsafe.Pointer(&mask)), uintptr(unsafe.Pointer(&sysmask))) + if ret == 0 { + return 0 + } + // For every available thread a bit is set in the mask. + ncpu := int(popcnt(uint64(mask))) + return ncpu +} + +// NumCPU returns the number of CPUs which are currently online +func NumCPU() int { + if ncpu := numCPU(); ncpu > 0 { + return ncpu + } + return runtime.NumCPU() +} diff --git a/vendor/github.com/docker/docker/pkg/sysinfo/sysinfo.go b/vendor/github.com/docker/docker/pkg/sysinfo/sysinfo.go new file mode 100644 index 00000000000..f046de4b169 --- /dev/null +++ b/vendor/github.com/docker/docker/pkg/sysinfo/sysinfo.go @@ -0,0 +1,144 @@ +package sysinfo + +import "github.com/docker/docker/pkg/parsers" + +// SysInfo stores information about which features a kernel supports. +// TODO Windows: Factor out platform specific capabilities. +type SysInfo struct { + // Whether the kernel supports AppArmor or not + AppArmor bool + // Whether the kernel supports Seccomp or not + Seccomp bool + + cgroupMemInfo + cgroupCPUInfo + cgroupBlkioInfo + cgroupCpusetInfo + cgroupPids + + // Whether IPv4 forwarding is supported or not, if this was disabled, networking will not work + IPv4ForwardingDisabled bool + + // Whether bridge-nf-call-iptables is supported or not + BridgeNFCallIPTablesDisabled bool + + // Whether bridge-nf-call-ip6tables is supported or not + BridgeNFCallIP6TablesDisabled bool + + // Whether the cgroup has the mountpoint of "devices" or not + CgroupDevicesEnabled bool +} + +type cgroupMemInfo struct { + // Whether memory limit is supported or not + MemoryLimit bool + + // Whether swap limit is supported or not + SwapLimit bool + + // Whether soft limit is supported or not + MemoryReservation bool + + // Whether OOM killer disable is supported or not + OomKillDisable bool + + // Whether memory swappiness is supported or not + MemorySwappiness bool + + // Whether kernel memory limit is supported or not + KernelMemory bool +} + +type cgroupCPUInfo struct { + // Whether CPU shares is supported or not + CPUShares bool + + // Whether CPU CFS(Completely Fair Scheduler) period is supported or not + CPUCfsPeriod bool + + // Whether CPU CFS(Completely Fair Scheduler) quota is supported or not + CPUCfsQuota bool + + // Whether CPU real-time period is supported or not + CPURealtimePeriod bool + + // Whether CPU real-time runtime is supported or not + CPURealtimeRuntime bool +} + +type cgroupBlkioInfo struct { + // Whether Block IO weight is supported or not + BlkioWeight bool + + // Whether Block IO weight_device is supported or not + BlkioWeightDevice bool + + // Whether Block IO read limit in bytes per second is supported or not + BlkioReadBpsDevice bool + + // Whether Block IO write limit in bytes per second is supported or not + BlkioWriteBpsDevice bool + + // Whether Block IO read limit in IO per second is supported or not + BlkioReadIOpsDevice bool + + // Whether Block IO write limit in IO per second is supported or not + BlkioWriteIOpsDevice bool +} + +type cgroupCpusetInfo struct { + // Whether Cpuset is supported or not + Cpuset bool + + // Available Cpuset's cpus + Cpus string + + // Available Cpuset's memory nodes + Mems string +} + +type cgroupPids struct { + // Whether Pids Limit is supported or not + PidsLimit bool +} + +// IsCpusetCpusAvailable returns `true` if the provided string set is contained +// in cgroup's cpuset.cpus set, `false` otherwise. +// If error is not nil a parsing error occurred. +func (c cgroupCpusetInfo) IsCpusetCpusAvailable(provided string) (bool, error) { + return isCpusetListAvailable(provided, c.Cpus) +} + +// IsCpusetMemsAvailable returns `true` if the provided string set is contained +// in cgroup's cpuset.mems set, `false` otherwise. +// If error is not nil a parsing error occurred. +func (c cgroupCpusetInfo) IsCpusetMemsAvailable(provided string) (bool, error) { + return isCpusetListAvailable(provided, c.Mems) +} + +func isCpusetListAvailable(provided, available string) (bool, error) { + parsedProvided, err := parsers.ParseUintList(provided) + if err != nil { + return false, err + } + parsedAvailable, err := parsers.ParseUintList(available) + if err != nil { + return false, err + } + for k := range parsedProvided { + if !parsedAvailable[k] { + return false, nil + } + } + return true, nil +} + +// Returns bit count of 1, used by NumCPU +func popcnt(x uint64) (n byte) { + x -= (x >> 1) & 0x5555555555555555 + x = (x>>2)&0x3333333333333333 + x&0x3333333333333333 + x += x >> 4 + x &= 0x0f0f0f0f0f0f0f0f + x *= 0x0101010101010101 + return byte(x >> 56) +} diff --git a/vendor/github.com/docker/docker/pkg/sysinfo/sysinfo_linux.go b/vendor/github.com/docker/docker/pkg/sysinfo/sysinfo_linux.go new file mode 100644 index 00000000000..471f786a70a --- /dev/null +++ b/vendor/github.com/docker/docker/pkg/sysinfo/sysinfo_linux.go @@ -0,0 +1,254 @@ +package sysinfo + +import ( + "fmt" + "io/ioutil" + "os" + "path" + "strings" + + "github.com/opencontainers/runc/libcontainer/cgroups" + "github.com/sirupsen/logrus" + "golang.org/x/sys/unix" +) + +func findCgroupMountpoints() (map[string]string, error) { + cgMounts, err := cgroups.GetCgroupMounts(false) + if err != nil { + return nil, fmt.Errorf("Failed to parse cgroup information: %v", err) + } + mps := make(map[string]string) + for _, m := range cgMounts { + for _, ss := range m.Subsystems { + mps[ss] = m.Mountpoint + } + } + return mps, nil +} + +// New returns a new SysInfo, using the filesystem to detect which features +// the kernel supports. If `quiet` is `false` warnings are printed in logs +// whenever an error occurs or misconfigurations are present. +func New(quiet bool) *SysInfo { + sysInfo := &SysInfo{} + cgMounts, err := findCgroupMountpoints() + if err != nil { + logrus.Warnf("Failed to parse cgroup information: %v", err) + } else { + sysInfo.cgroupMemInfo = checkCgroupMem(cgMounts, quiet) + sysInfo.cgroupCPUInfo = checkCgroupCPU(cgMounts, quiet) + sysInfo.cgroupBlkioInfo = checkCgroupBlkioInfo(cgMounts, quiet) + sysInfo.cgroupCpusetInfo = checkCgroupCpusetInfo(cgMounts, quiet) + sysInfo.cgroupPids = checkCgroupPids(quiet) + } + + _, ok := cgMounts["devices"] + sysInfo.CgroupDevicesEnabled = ok + + sysInfo.IPv4ForwardingDisabled = !readProcBool("/proc/sys/net/ipv4/ip_forward") + sysInfo.BridgeNFCallIPTablesDisabled = !readProcBool("/proc/sys/net/bridge/bridge-nf-call-iptables") + sysInfo.BridgeNFCallIP6TablesDisabled = !readProcBool("/proc/sys/net/bridge/bridge-nf-call-ip6tables") + + // Check if AppArmor is supported. + if _, err := os.Stat("/sys/kernel/security/apparmor"); !os.IsNotExist(err) { + sysInfo.AppArmor = true + } + + // Check if Seccomp is supported, via CONFIG_SECCOMP. + if err := unix.Prctl(unix.PR_GET_SECCOMP, 0, 0, 0, 0); err != unix.EINVAL { + // Make sure the kernel has CONFIG_SECCOMP_FILTER. + if err := unix.Prctl(unix.PR_SET_SECCOMP, unix.SECCOMP_MODE_FILTER, 0, 0, 0); err != unix.EINVAL { + sysInfo.Seccomp = true + } + } + + return sysInfo +} + +// checkCgroupMem reads the memory information from the memory cgroup mount point. +func checkCgroupMem(cgMounts map[string]string, quiet bool) cgroupMemInfo { + mountPoint, ok := cgMounts["memory"] + if !ok { + if !quiet { + logrus.Warn("Your kernel does not support cgroup memory limit") + } + return cgroupMemInfo{} + } + + swapLimit := cgroupEnabled(mountPoint, "memory.memsw.limit_in_bytes") + if !quiet && !swapLimit { + logrus.Warn("Your kernel does not support swap memory limit") + } + memoryReservation := cgroupEnabled(mountPoint, "memory.soft_limit_in_bytes") + if !quiet && !memoryReservation { + logrus.Warn("Your kernel does not support memory reservation") + } + oomKillDisable := cgroupEnabled(mountPoint, "memory.oom_control") + if !quiet && !oomKillDisable { + logrus.Warn("Your kernel does not support oom control") + } + memorySwappiness := cgroupEnabled(mountPoint, "memory.swappiness") + if !quiet && !memorySwappiness { + logrus.Warn("Your kernel does not support memory swappiness") + } + kernelMemory := cgroupEnabled(mountPoint, "memory.kmem.limit_in_bytes") + if !quiet && !kernelMemory { + logrus.Warn("Your kernel does not support kernel memory limit") + } + + return cgroupMemInfo{ + MemoryLimit: true, + SwapLimit: swapLimit, + MemoryReservation: memoryReservation, + OomKillDisable: oomKillDisable, + MemorySwappiness: memorySwappiness, + KernelMemory: kernelMemory, + } +} + +// checkCgroupCPU reads the cpu information from the cpu cgroup mount point. +func checkCgroupCPU(cgMounts map[string]string, quiet bool) cgroupCPUInfo { + mountPoint, ok := cgMounts["cpu"] + if !ok { + if !quiet { + logrus.Warn("Unable to find cpu cgroup in mounts") + } + return cgroupCPUInfo{} + } + + cpuShares := cgroupEnabled(mountPoint, "cpu.shares") + if !quiet && !cpuShares { + logrus.Warn("Your kernel does not support cgroup cpu shares") + } + + cpuCfsPeriod := cgroupEnabled(mountPoint, "cpu.cfs_period_us") + if !quiet && !cpuCfsPeriod { + logrus.Warn("Your kernel does not support cgroup cfs period") + } + + cpuCfsQuota := cgroupEnabled(mountPoint, "cpu.cfs_quota_us") + if !quiet && !cpuCfsQuota { + logrus.Warn("Your kernel does not support cgroup cfs quotas") + } + + cpuRealtimePeriod := cgroupEnabled(mountPoint, "cpu.rt_period_us") + if !quiet && !cpuRealtimePeriod { + logrus.Warn("Your kernel does not support cgroup rt period") + } + + cpuRealtimeRuntime := cgroupEnabled(mountPoint, "cpu.rt_runtime_us") + if !quiet && !cpuRealtimeRuntime { + logrus.Warn("Your kernel does not support cgroup rt runtime") + } + + return cgroupCPUInfo{ + CPUShares: cpuShares, + CPUCfsPeriod: cpuCfsPeriod, + CPUCfsQuota: cpuCfsQuota, + CPURealtimePeriod: cpuRealtimePeriod, + CPURealtimeRuntime: cpuRealtimeRuntime, + } +} + +// checkCgroupBlkioInfo reads the blkio information from the blkio cgroup mount point. +func checkCgroupBlkioInfo(cgMounts map[string]string, quiet bool) cgroupBlkioInfo { + mountPoint, ok := cgMounts["blkio"] + if !ok { + if !quiet { + logrus.Warn("Unable to find blkio cgroup in mounts") + } + return cgroupBlkioInfo{} + } + + weight := cgroupEnabled(mountPoint, "blkio.weight") + if !quiet && !weight { + logrus.Warn("Your kernel does not support cgroup blkio weight") + } + + weightDevice := cgroupEnabled(mountPoint, "blkio.weight_device") + if !quiet && !weightDevice { + logrus.Warn("Your kernel does not support cgroup blkio weight_device") + } + + readBpsDevice := cgroupEnabled(mountPoint, "blkio.throttle.read_bps_device") + if !quiet && !readBpsDevice { + logrus.Warn("Your kernel does not support cgroup blkio throttle.read_bps_device") + } + + writeBpsDevice := cgroupEnabled(mountPoint, "blkio.throttle.write_bps_device") + if !quiet && !writeBpsDevice { + logrus.Warn("Your kernel does not support cgroup blkio throttle.write_bps_device") + } + readIOpsDevice := cgroupEnabled(mountPoint, "blkio.throttle.read_iops_device") + if !quiet && !readIOpsDevice { + logrus.Warn("Your kernel does not support cgroup blkio throttle.read_iops_device") + } + + writeIOpsDevice := cgroupEnabled(mountPoint, "blkio.throttle.write_iops_device") + if !quiet && !writeIOpsDevice { + logrus.Warn("Your kernel does not support cgroup blkio throttle.write_iops_device") + } + return cgroupBlkioInfo{ + BlkioWeight: weight, + BlkioWeightDevice: weightDevice, + BlkioReadBpsDevice: readBpsDevice, + BlkioWriteBpsDevice: writeBpsDevice, + BlkioReadIOpsDevice: readIOpsDevice, + BlkioWriteIOpsDevice: writeIOpsDevice, + } +} + +// checkCgroupCpusetInfo reads the cpuset information from the cpuset cgroup mount point. +func checkCgroupCpusetInfo(cgMounts map[string]string, quiet bool) cgroupCpusetInfo { + mountPoint, ok := cgMounts["cpuset"] + if !ok { + if !quiet { + logrus.Warn("Unable to find cpuset cgroup in mounts") + } + return cgroupCpusetInfo{} + } + + cpus, err := ioutil.ReadFile(path.Join(mountPoint, "cpuset.cpus")) + if err != nil { + return cgroupCpusetInfo{} + } + + mems, err := ioutil.ReadFile(path.Join(mountPoint, "cpuset.mems")) + if err != nil { + return cgroupCpusetInfo{} + } + + return cgroupCpusetInfo{ + Cpuset: true, + Cpus: strings.TrimSpace(string(cpus)), + Mems: strings.TrimSpace(string(mems)), + } +} + +// checkCgroupPids reads the pids information from the pids cgroup mount point. +func checkCgroupPids(quiet bool) cgroupPids { + _, err := cgroups.FindCgroupMountpoint("pids") + if err != nil { + if !quiet { + logrus.Warn(err) + } + return cgroupPids{} + } + + return cgroupPids{ + PidsLimit: true, + } +} + +func cgroupEnabled(mountPoint, name string) bool { + _, err := os.Stat(path.Join(mountPoint, name)) + return err == nil +} + +func readProcBool(path string) bool { + val, err := ioutil.ReadFile(path) + if err != nil { + return false + } + return strings.TrimSpace(string(val)) == "1" +} diff --git a/vendor/github.com/docker/docker/pkg/sysinfo/sysinfo_solaris.go b/vendor/github.com/docker/docker/pkg/sysinfo/sysinfo_solaris.go new file mode 100644 index 00000000000..c858d57e089 --- /dev/null +++ b/vendor/github.com/docker/docker/pkg/sysinfo/sysinfo_solaris.go @@ -0,0 +1,121 @@ +// +build solaris,cgo + +package sysinfo + +import ( + "bytes" + "os/exec" + "strconv" + "strings" +) + +/* +#cgo LDFLAGS: -llgrp +#include +#include +#include +int getLgrpCount() { + lgrp_cookie_t lgrpcookie = LGRP_COOKIE_NONE; + uint_t nlgrps; + + if ((lgrpcookie = lgrp_init(LGRP_VIEW_OS)) == LGRP_COOKIE_NONE) { + return -1; + } + nlgrps = lgrp_nlgrps(lgrpcookie); + return nlgrps; +} +*/ +import "C" + +// IsCPUSharesAvailable returns whether CPUShares setting is supported. +// We need FSS to be set as default scheduling class to support CPU Shares +func IsCPUSharesAvailable() bool { + cmd := exec.Command("/usr/sbin/dispadmin", "-d") + outBuf := new(bytes.Buffer) + errBuf := new(bytes.Buffer) + cmd.Stderr = errBuf + cmd.Stdout = outBuf + + if err := cmd.Run(); err != nil { + return false + } + return (strings.Contains(outBuf.String(), "FSS")) +} + +// New returns a new SysInfo, using the filesystem to detect which features +// the kernel supports. +//NOTE Solaris: If we change the below capabilities be sure +// to update verifyPlatformContainerSettings() in daemon_solaris.go +func New(quiet bool) *SysInfo { + sysInfo := &SysInfo{} + sysInfo.cgroupMemInfo = setCgroupMem(quiet) + sysInfo.cgroupCPUInfo = setCgroupCPU(quiet) + sysInfo.cgroupBlkioInfo = setCgroupBlkioInfo(quiet) + sysInfo.cgroupCpusetInfo = setCgroupCPUsetInfo(quiet) + + sysInfo.IPv4ForwardingDisabled = false + + sysInfo.AppArmor = false + + return sysInfo +} + +// setCgroupMem reads the memory information for Solaris. +func setCgroupMem(quiet bool) cgroupMemInfo { + + return cgroupMemInfo{ + MemoryLimit: true, + SwapLimit: true, + MemoryReservation: false, + OomKillDisable: false, + MemorySwappiness: false, + KernelMemory: false, + } +} + +// setCgroupCPU reads the cpu information for Solaris. +func setCgroupCPU(quiet bool) cgroupCPUInfo { + + return cgroupCPUInfo{ + CPUShares: true, + CPUCfsPeriod: false, + CPUCfsQuota: true, + CPURealtimePeriod: false, + CPURealtimeRuntime: false, + } +} + +// blkio switches are not supported in Solaris. +func setCgroupBlkioInfo(quiet bool) cgroupBlkioInfo { + + return cgroupBlkioInfo{ + BlkioWeight: false, + BlkioWeightDevice: false, + } +} + +// setCgroupCPUsetInfo reads the cpuset information for Solaris. +func setCgroupCPUsetInfo(quiet bool) cgroupCpusetInfo { + + return cgroupCpusetInfo{ + Cpuset: true, + Cpus: getCPUCount(), + Mems: getLgrpCount(), + } +} + +func getCPUCount() string { + ncpus := C.sysconf(C._SC_NPROCESSORS_ONLN) + if ncpus <= 0 { + return "" + } + return strconv.FormatInt(int64(ncpus), 16) +} + +func getLgrpCount() string { + nlgrps := C.getLgrpCount() + if nlgrps <= 0 { + return "" + } + return strconv.FormatInt(int64(nlgrps), 16) +} diff --git a/vendor/github.com/docker/docker/pkg/sysinfo/sysinfo_unix.go b/vendor/github.com/docker/docker/pkg/sysinfo/sysinfo_unix.go new file mode 100644 index 00000000000..45f3ef1c65f --- /dev/null +++ b/vendor/github.com/docker/docker/pkg/sysinfo/sysinfo_unix.go @@ -0,0 +1,9 @@ +// +build !linux,!solaris,!windows + +package sysinfo + +// New returns an empty SysInfo for non linux nor solaris for now. +func New(quiet bool) *SysInfo { + sysInfo := &SysInfo{} + return sysInfo +} diff --git a/vendor/github.com/docker/docker/pkg/sysinfo/sysinfo_windows.go b/vendor/github.com/docker/docker/pkg/sysinfo/sysinfo_windows.go new file mode 100644 index 00000000000..4e6255bc592 --- /dev/null +++ b/vendor/github.com/docker/docker/pkg/sysinfo/sysinfo_windows.go @@ -0,0 +1,9 @@ +// +build windows + +package sysinfo + +// New returns an empty SysInfo for windows for now. +func New(quiet bool) *SysInfo { + sysInfo := &SysInfo{} + return sysInfo +}