diff --git a/Godeps/Godeps.json b/Godeps/Godeps.json index 775a10c67b..dfec10507d 100644 --- a/Godeps/Godeps.json +++ b/Godeps/Godeps.json @@ -46,18 +46,18 @@ }, { "ImportPath": "github.com/appc/spec/schema", - "Comment": "v0.7.4-43-gd22f52b", - "Rev": "d22f52bfeba06614d37c7aa1ad6fd76d8fdb2ba8" + "Comment": "v0.8.1-10-ge9daa59", + "Rev": "e9daa59a023c1618a60db7563d29c53255d13864" }, { "ImportPath": "github.com/appc/spec/schema/common", - "Comment": "v0.7.4-43-gd22f52b", - "Rev": "d22f52bfeba06614d37c7aa1ad6fd76d8fdb2ba8" + "Comment": "v0.8.1-10-ge9daa59", + "Rev": "e9daa59a023c1618a60db7563d29c53255d13864" }, { "ImportPath": "github.com/appc/spec/schema/types", - "Comment": "v0.7.4-43-gd22f52b", - "Rev": "d22f52bfeba06614d37c7aa1ad6fd76d8fdb2ba8" + "Comment": "v0.8.1-10-ge9daa59", + "Rev": "e9daa59a023c1618a60db7563d29c53255d13864" }, { "ImportPath": "github.com/armon/go-metrics", @@ -459,23 +459,23 @@ }, { "ImportPath": "github.com/coreos/go-oidc/http", - "Rev": "024cdeee09d02fb439eb55bc422e582ac115615b" + "Rev": "5cf2aa52da8c574d3aa4458f471ad6ae2240fe6b" }, { "ImportPath": "github.com/coreos/go-oidc/jose", - "Rev": "024cdeee09d02fb439eb55bc422e582ac115615b" + "Rev": "5cf2aa52da8c574d3aa4458f471ad6ae2240fe6b" }, { "ImportPath": "github.com/coreos/go-oidc/key", - "Rev": "024cdeee09d02fb439eb55bc422e582ac115615b" + "Rev": "5cf2aa52da8c574d3aa4458f471ad6ae2240fe6b" }, { "ImportPath": "github.com/coreos/go-oidc/oauth2", - "Rev": "024cdeee09d02fb439eb55bc422e582ac115615b" + "Rev": "5cf2aa52da8c574d3aa4458f471ad6ae2240fe6b" }, { "ImportPath": "github.com/coreos/go-oidc/oidc", - "Rev": "024cdeee09d02fb439eb55bc422e582ac115615b" + "Rev": "5cf2aa52da8c574d3aa4458f471ad6ae2240fe6b" }, { "ImportPath": "github.com/coreos/go-semver/semver", @@ -1496,6 +1496,11 @@ "Comment": "v1.0.0-665-gf928634", "Rev": "f92863476c034f851073599c09d90cd61ee95b3d" }, + { + "ImportPath": "github.com/robfig/cron", + "Comment": "v1-16-g0f39cf7", + "Rev": "0f39cf7ebc65a602f45692f9894bd6a193faf8fa" + }, { "ImportPath": "github.com/samalba/dockerclient", "Rev": "91d7393ff85980ba3a8966405871a3d446ca28f2" @@ -1584,78 +1589,78 @@ }, { "ImportPath": "github.com/vmware/govmomi", - "Comment": "v0.5.0", - "Rev": "c1b29993f383c32fc3fadb90892909668699810a" + "Comment": "v0.6.2", + "Rev": "9051bd6b44125d9472e0c148b5965692ab283d4a" }, { "ImportPath": "github.com/vmware/govmomi/find", - "Comment": "v0.5.0", - "Rev": "c1b29993f383c32fc3fadb90892909668699810a" + "Comment": "v0.6.2", + "Rev": "9051bd6b44125d9472e0c148b5965692ab283d4a" }, { "ImportPath": "github.com/vmware/govmomi/list", - "Comment": "v0.5.0", - "Rev": "c1b29993f383c32fc3fadb90892909668699810a" + "Comment": "v0.6.2", + "Rev": "9051bd6b44125d9472e0c148b5965692ab283d4a" }, { "ImportPath": "github.com/vmware/govmomi/object", - "Comment": "v0.5.0", - "Rev": "c1b29993f383c32fc3fadb90892909668699810a" + "Comment": "v0.6.2", + "Rev": "9051bd6b44125d9472e0c148b5965692ab283d4a" }, { "ImportPath": "github.com/vmware/govmomi/property", - "Comment": "v0.5.0", - "Rev": "c1b29993f383c32fc3fadb90892909668699810a" + "Comment": "v0.6.2", + "Rev": "9051bd6b44125d9472e0c148b5965692ab283d4a" }, { "ImportPath": "github.com/vmware/govmomi/session", - "Comment": "v0.5.0", - "Rev": "c1b29993f383c32fc3fadb90892909668699810a" + "Comment": "v0.6.2", + "Rev": "9051bd6b44125d9472e0c148b5965692ab283d4a" }, { "ImportPath": "github.com/vmware/govmomi/task", - "Comment": "v0.5.0", - "Rev": "c1b29993f383c32fc3fadb90892909668699810a" + "Comment": "v0.6.2", + "Rev": "9051bd6b44125d9472e0c148b5965692ab283d4a" }, { "ImportPath": "github.com/vmware/govmomi/vim25", - "Comment": "v0.5.0", - "Rev": "c1b29993f383c32fc3fadb90892909668699810a" + "Comment": "v0.6.2", + "Rev": "9051bd6b44125d9472e0c148b5965692ab283d4a" }, { "ImportPath": "github.com/vmware/govmomi/vim25/debug", - "Comment": "v0.5.0", - "Rev": "c1b29993f383c32fc3fadb90892909668699810a" + "Comment": "v0.6.2", + "Rev": "9051bd6b44125d9472e0c148b5965692ab283d4a" }, { "ImportPath": "github.com/vmware/govmomi/vim25/methods", - "Comment": "v0.5.0", - "Rev": "c1b29993f383c32fc3fadb90892909668699810a" + "Comment": "v0.6.2", + "Rev": "9051bd6b44125d9472e0c148b5965692ab283d4a" }, { "ImportPath": "github.com/vmware/govmomi/vim25/mo", - "Comment": "v0.5.0", - "Rev": "c1b29993f383c32fc3fadb90892909668699810a" + "Comment": "v0.6.2", + "Rev": "9051bd6b44125d9472e0c148b5965692ab283d4a" }, { "ImportPath": "github.com/vmware/govmomi/vim25/progress", - "Comment": "v0.5.0", - "Rev": "c1b29993f383c32fc3fadb90892909668699810a" + "Comment": "v0.6.2", + "Rev": "9051bd6b44125d9472e0c148b5965692ab283d4a" }, { "ImportPath": "github.com/vmware/govmomi/vim25/soap", - "Comment": "v0.5.0", - "Rev": "c1b29993f383c32fc3fadb90892909668699810a" + "Comment": "v0.6.2", + "Rev": "9051bd6b44125d9472e0c148b5965692ab283d4a" }, { "ImportPath": "github.com/vmware/govmomi/vim25/types", - "Comment": "v0.5.0", - "Rev": "c1b29993f383c32fc3fadb90892909668699810a" + "Comment": "v0.6.2", + "Rev": "9051bd6b44125d9472e0c148b5965692ab283d4a" }, { "ImportPath": "github.com/vmware/govmomi/vim25/xml", - "Comment": "v0.5.0", - "Rev": "c1b29993f383c32fc3fadb90892909668699810a" + "Comment": "v0.6.2", + "Rev": "9051bd6b44125d9472e0c148b5965692ab283d4a" }, { "ImportPath": "github.com/xiang90/probing", @@ -1847,2003 +1852,2063 @@ }, { "ImportPath": "k8s.io/heapster/metrics/api/v1/types", - "Comment": "v1.1.0-beta1-15-gde510e4", - "Rev": "de510e4bdcdea96722b5bde19ff0b7a142939485" + "Comment": "v1.1.0-beta1-54-g86ef67f", + "Rev": "86ef67f0a4fcf4730d45345f83b7a7e696db8624" + }, + { + "ImportPath": "k8s.io/heapster/metrics/apis/metrics/v1alpha1", + "Comment": "v1.1.0-beta1-54-g86ef67f", + "Rev": "86ef67f0a4fcf4730d45345f83b7a7e696db8624" }, { "ImportPath": "k8s.io/kubernetes/cmd/kube-apiserver/app", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/cmd/kube-apiserver/app/options", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/cmd/kube-controller-manager/app", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/cmd/kube-controller-manager/app/options", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/cmd/kube-proxy/app", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/cmd/kube-proxy/app/options", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/cmd/kubelet/app", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/cmd/kubelet/app/options", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/admission", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/api", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/api/annotations", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/api/endpoints", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/api/errors", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/api/errors/storage", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/api/install", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/api/meta", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" + }, + { + "ImportPath": "k8s.io/kubernetes/pkg/api/meta/metatypes", + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/api/pod", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/api/resource", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/api/rest", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/api/service", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/api/unversioned", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/api/unversioned/validation", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/api/util", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/api/v1", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/api/validation", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/apimachinery", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/apimachinery/registered", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/apis/abac", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/apis/abac/latest", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/apis/abac/v0", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/apis/abac/v1beta1", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/apis/apps", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/apis/apps/install", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/apis/apps/v1alpha1", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/apis/apps/validation", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/apis/authentication.k8s.io", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/apis/authentication.k8s.io/install", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/apis/authentication.k8s.io/v1beta1", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/apis/authorization", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/apis/authorization/install", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/apis/authorization/v1beta1", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/apis/autoscaling", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/apis/autoscaling/install", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/apis/autoscaling/v1", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/apis/autoscaling/validation", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/apis/batch", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/apis/batch/install", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/apis/batch/v1", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/apis/batch/v2alpha1", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/apis/batch/validation", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/apis/componentconfig", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/apis/componentconfig/install", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/apis/componentconfig/v1alpha1", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/apis/extensions", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/apis/extensions/install", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/apis/extensions/v1beta1", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/apis/extensions/validation", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/apis/metrics", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/apis/metrics/install", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/apis/metrics/v1alpha1", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/apis/policy", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/apis/policy/install", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/apis/policy/v1alpha1", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" + }, + { + "ImportPath": "k8s.io/kubernetes/pkg/apis/policy/validation", + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/apiserver", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/apiserver/authenticator", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/apiserver/metrics", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/auth/authenticator", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/auth/authenticator/bearertoken", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/auth/authorizer", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/auth/authorizer/abac", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/auth/authorizer/union", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/auth/handlers", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/auth/user", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/capabilities", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/client/cache", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/client/chaosclient", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/autoscaling/unversioned", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/batch/unversioned", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/core/unversioned", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/extensions/unversioned", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/client/leaderelection", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/client/metrics", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/client/record", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/client/restclient", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/client/transport", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/client/typed/discovery", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/client/typed/dynamic", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/client/unversioned", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/client/unversioned/auth", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/client/unversioned/clientcmd", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/client/unversioned/clientcmd/api", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/client/unversioned/clientcmd/api/latest", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/client/unversioned/clientcmd/api/v1", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/cloudprovider", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/cloudprovider/providers", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/cloudprovider/providers/aws", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/cloudprovider/providers/gce", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/cloudprovider/providers/mesos", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/cloudprovider/providers/openstack", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/cloudprovider/providers/ovirt", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/cloudprovider/providers/rackspace", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/cloudprovider/providers/vsphere", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/controller", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/controller/daemon", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/controller/deployment", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/controller/endpoint", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/controller/framework", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/controller/framework/informers", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/controller/gc", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/controller/job", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/controller/namespace", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/controller/node", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/controller/persistentvolume", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/controller/petset", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/controller/podautoscaler", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/controller/podautoscaler/metrics", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/controller/replicaset", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/controller/replication", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/controller/resourcequota", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/controller/route", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/controller/service", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/controller/serviceaccount", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/controller/volume", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/conversion", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/conversion/queryparams", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/credentialprovider", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/credentialprovider/aws", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/credentialprovider/gcp", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/fieldpath", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/fields", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/genericapiserver", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" + }, + { + "ImportPath": "k8s.io/kubernetes/pkg/genericapiserver/options", + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/healthz", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/httplog", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/kubelet", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/kubelet/api/v1alpha1/stats", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/kubelet/cadvisor", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/kubelet/client", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/kubelet/cm", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/kubelet/config", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/kubelet/container", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/kubelet/custommetrics", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/kubelet/dockertools", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/kubelet/envvars", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/kubelet/eviction", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/kubelet/leaky", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/kubelet/lifecycle", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/kubelet/metrics", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/kubelet/network", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/kubelet/network/cni", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/kubelet/network/exec", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/kubelet/network/hairpin", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/kubelet/network/kubenet", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/kubelet/pleg", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/kubelet/pod", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/kubelet/prober", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/kubelet/prober/results", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/kubelet/qos", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/kubelet/qos/util", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/kubelet/rkt", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/kubelet/server", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/kubelet/server/portforward", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/kubelet/server/remotecommand", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/kubelet/server/stats", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/kubelet/status", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/kubelet/types", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/kubelet/util/cache", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/kubelet/util/format", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" + }, + { + "ImportPath": "k8s.io/kubernetes/pkg/kubelet/util/ioutils", + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/kubelet/util/queue", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/labels", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/master", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/master/ports", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/probe", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/probe/exec", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/probe/http", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/probe/tcp", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/proxy", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/proxy/config", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/proxy/iptables", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/proxy/userspace", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/quota", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/quota/evaluator/core", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/quota/generic", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/quota/install", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/registry/cachesize", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/registry/componentstatus", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/registry/configmap", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/registry/configmap/etcd", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/registry/controller", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/registry/controller/etcd", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/registry/daemonset", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/registry/daemonset/etcd", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/registry/deployment", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/registry/deployment/etcd", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/registry/endpoint", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/registry/endpoint/etcd", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/registry/event", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/registry/event/etcd", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/registry/experimental/controller/etcd", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/registry/generic", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/registry/generic/registry", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/registry/generic/rest", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/registry/horizontalpodautoscaler", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/registry/horizontalpodautoscaler/etcd", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/registry/ingress", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/registry/ingress/etcd", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/registry/job", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/registry/job/etcd", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/registry/limitrange", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/registry/limitrange/etcd", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/registry/namespace", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/registry/namespace/etcd", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" + }, + { + "ImportPath": "k8s.io/kubernetes/pkg/registry/networkpolicy", + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" + }, + { + "ImportPath": "k8s.io/kubernetes/pkg/registry/networkpolicy/etcd", + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/registry/node", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/registry/node/etcd", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/registry/node/rest", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/registry/persistentvolume", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/registry/persistentvolume/etcd", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/registry/persistentvolumeclaim", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/registry/persistentvolumeclaim/etcd", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/registry/petset", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/registry/petset/etcd", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/registry/pod", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/registry/pod/etcd", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/registry/pod/rest", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" + }, + { + "ImportPath": "k8s.io/kubernetes/pkg/registry/poddisruptionbudget", + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" + }, + { + "ImportPath": "k8s.io/kubernetes/pkg/registry/poddisruptionbudget/etcd", + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/registry/podsecuritypolicy", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/registry/podsecuritypolicy/etcd", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/registry/podtemplate", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/registry/podtemplate/etcd", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/registry/replicaset", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/registry/replicaset/etcd", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/registry/resourcequota", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/registry/resourcequota/etcd", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/registry/secret", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/registry/secret/etcd", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/registry/service", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/registry/service/allocator", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/registry/service/allocator/etcd", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/registry/service/etcd", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/registry/service/ipallocator", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/registry/service/ipallocator/controller", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/registry/service/portallocator", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/registry/service/portallocator/controller", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/registry/serviceaccount", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/registry/serviceaccount/etcd", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/registry/thirdpartyresource", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/registry/thirdpartyresource/etcd", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/registry/thirdpartyresourcedata", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/registry/thirdpartyresourcedata/etcd", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/runtime", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/runtime/serializer", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/runtime/serializer/json", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/runtime/serializer/protobuf", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/runtime/serializer/recognizer", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/runtime/serializer/streaming", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/runtime/serializer/versioning", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/security/podsecuritypolicy", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/security/podsecuritypolicy/capabilities", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/security/podsecuritypolicy/group", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/security/podsecuritypolicy/selinux", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/security/podsecuritypolicy/user", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/security/podsecuritypolicy/util", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/securitycontext", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/serviceaccount", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/ssh", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/storage", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/storage/etcd", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/storage/etcd/metrics", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/storage/etcd/util", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/storage/etcd3", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/storage/storagebackend", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" + }, + { + "ImportPath": "k8s.io/kubernetes/pkg/storage/storagebackend/factory", + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/types", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/ui", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/ui/data/swagger", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/util", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/util/bandwidth", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/util/cache", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/util/chmod", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/util/chown", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/util/config", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/util/configz", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/util/crypto", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/util/dbus", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/util/deployment", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/util/diff", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/util/env", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/util/errors", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/util/exec", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/util/flock", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/util/flowcontrol", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/util/flushwriter", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/util/framer", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/util/hash", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/util/homedir", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/util/httpstream", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/util/httpstream/spdy", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/util/integer", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/util/intstr", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/util/io", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/util/iptables", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/util/json", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/util/keymutex", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/util/labels", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/util/limitwriter", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/util/metrics", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/util/mount", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/util/net", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/util/net/sets", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/util/node", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/util/oom", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/util/parsers", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/util/pod", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/util/procfs", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/util/proxy", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/util/rand", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/util/replicaset", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/util/runtime", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/util/selinux", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/util/sets", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/util/slice", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/util/strategicpatch", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/util/strings", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/util/sysctl", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" + }, + { + "ImportPath": "k8s.io/kubernetes/pkg/util/system", + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/util/validation", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/util/validation/field", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/util/wait", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/util/workqueue", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/util/wsstream", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/util/yaml", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/version", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/volume", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/volume/aws_ebs", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/volume/azure_file", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/volume/cephfs", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/volume/cinder", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/volume/configmap", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/volume/downwardapi", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/volume/empty_dir", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/volume/fc", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/volume/flexvolume", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/volume/flocker", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/volume/gce_pd", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/volume/git_repo", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/volume/glusterfs", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/volume/host_path", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/volume/iscsi", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/volume/nfs", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" - }, - { - "ImportPath": "k8s.io/kubernetes/pkg/volume/persistent_claim", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/volume/rbd", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/volume/secret", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/volume/util", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" + }, + { + "ImportPath": "k8s.io/kubernetes/pkg/volume/vsphere_volume", + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/watch", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/pkg/watch/versioned", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/plugin/cmd/kube-scheduler/app", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/plugin/cmd/kube-scheduler/app/options", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/plugin/pkg/admission/admit", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/plugin/pkg/admission/alwayspullimages", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/plugin/pkg/admission/antiaffinity", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/plugin/pkg/admission/deny", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/plugin/pkg/admission/exec", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/plugin/pkg/admission/initialresources", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/plugin/pkg/admission/limitranger", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/plugin/pkg/admission/namespace/autoprovision", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/plugin/pkg/admission/namespace/exists", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/plugin/pkg/admission/namespace/lifecycle", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/plugin/pkg/admission/persistentvolume/label", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/plugin/pkg/admission/resourcequota", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/plugin/pkg/admission/security/podsecuritypolicy", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/plugin/pkg/admission/securitycontext/scdeny", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/plugin/pkg/admission/serviceaccount", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/plugin/pkg/auth/authenticator/password/keystone", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/plugin/pkg/auth/authenticator/password/passwordfile", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/plugin/pkg/auth/authenticator/request/basicauth", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/plugin/pkg/auth/authenticator/request/union", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/plugin/pkg/auth/authenticator/request/x509", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/plugin/pkg/auth/authenticator/token/oidc", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/plugin/pkg/auth/authenticator/token/tokenfile", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/plugin/pkg/auth/authenticator/token/webhook", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/plugin/pkg/auth/authorizer/webhook", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/plugin/pkg/client/auth", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/plugin/pkg/client/auth/gcp", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" + }, + { + "ImportPath": "k8s.io/kubernetes/plugin/pkg/client/auth/oidc", + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/plugin/pkg/scheduler", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/plugin/pkg/scheduler/algorithm", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/plugin/pkg/scheduler/algorithm/predicates", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/plugin/pkg/scheduler/algorithm/priorities", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/plugin/pkg/scheduler/algorithm/priorities/util", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/plugin/pkg/scheduler/algorithmprovider", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/plugin/pkg/scheduler/algorithmprovider/defaults", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/plugin/pkg/scheduler/api", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/plugin/pkg/scheduler/api/latest", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/plugin/pkg/scheduler/api/v1", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/plugin/pkg/scheduler/api/validation", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/plugin/pkg/scheduler/factory", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/plugin/pkg/scheduler/metrics", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/plugin/pkg/scheduler/schedulercache", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/plugin/pkg/webhook", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/third_party/forked/json", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/third_party/forked/reflect", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/third_party/golang/expansion", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" }, { "ImportPath": "k8s.io/kubernetes/third_party/golang/netutil", - "Comment": "v1.3.0-alpha.3-838-gba170aa", - "Rev": "ba170aa191f8c790c53682fc52e299245f94e68c" + "Comment": "v1.3.0-alpha.3-1398-gefc5bbc", + "Rev": "efc5bbc9e8e6162eaf99bc749d58a65d484f823e" } ] } diff --git a/pkg/localkube/kube2sky/kube2sky.go b/pkg/localkube/kube2sky/kube2sky.go index 0222704874..e1047985ae 100644 --- a/pkg/localkube/kube2sky/kube2sky.go +++ b/pkg/localkube/kube2sky/kube2sky.go @@ -200,7 +200,7 @@ func (ks *kube2sky) generateRecordsForHeadlessService(subdomain string, e *kapi. return err } if hostRecord, exists := podHostnames[string(endpointIP)]; exists { - if validation.IsDNS1123Label(hostRecord.HostName) { + if len(validation.IsDNS1123Label(hostRecord.HostName)) == 0 { recordLabel = hostRecord.HostName } } diff --git a/vendor/github.com/appc/spec/schema/pod.go b/vendor/github.com/appc/spec/schema/pod.go index b8699315f0..d4792ff3b4 100644 --- a/vendor/github.com/appc/spec/schema/pod.go +++ b/vendor/github.com/appc/spec/schema/pod.go @@ -152,11 +152,12 @@ func (r Mount) assertValid() error { // RuntimeApp describes an application referenced in a PodManifest type RuntimeApp struct { - Name types.ACName `json:"name"` - Image RuntimeImage `json:"image"` - App *types.App `json:"app,omitempty"` - Mounts []Mount `json:"mounts,omitempty"` - Annotations types.Annotations `json:"annotations,omitempty"` + Name types.ACName `json:"name"` + Image RuntimeImage `json:"image"` + App *types.App `json:"app,omitempty"` + ReadOnlyRootFS bool `json:"readOnlyRootFS,omitempty"` + Mounts []Mount `json:"mounts,omitempty"` + Annotations types.Annotations `json:"annotations,omitempty"` } // RuntimeImage describes an image referenced in a RuntimeApp diff --git a/vendor/github.com/appc/spec/schema/types/isolator_resources.go b/vendor/github.com/appc/spec/schema/types/isolator_resources.go index 2ac5130d1c..d97827b96f 100644 --- a/vendor/github.com/appc/spec/schema/types/isolator_resources.go +++ b/vendor/github.com/appc/spec/schema/types/isolator_resources.go @@ -155,8 +155,8 @@ func NewResourceCPUIsolator(request, limit string) (*ResourceCPU, error) { res := &ResourceCPU{ ResourceBase{ resourceValue{ - Request: req, - Limit: lim, + Request: &req, + Limit: &lim, }, }, } @@ -209,8 +209,8 @@ func NewResourceMemoryIsolator(request, limit string) (*ResourceMemory, error) { res := &ResourceMemory{ ResourceBase{ resourceValue{ - Request: req, - Limit: lim, + Request: &req, + Limit: &lim, }, }, } diff --git a/vendor/github.com/appc/spec/schema/version.go b/vendor/github.com/appc/spec/schema/version.go index 1aa136753a..effd86e376 100644 --- a/vendor/github.com/appc/spec/schema/version.go +++ b/vendor/github.com/appc/spec/schema/version.go @@ -22,7 +22,7 @@ const ( // version represents the canonical version of the appc spec and tooling. // For now, the schema and tooling is coupled with the spec itself, so // this must be kept in sync with the VERSION file in the root of the repo. - version string = "0.7.4+git" + version string = "0.8.2+git" ) var ( diff --git a/vendor/github.com/coreos/go-oidc/http/client.go b/vendor/github.com/coreos/go-oidc/http/client.go index 942e2bb18c..fd079b4950 100644 --- a/vendor/github.com/coreos/go-oidc/http/client.go +++ b/vendor/github.com/coreos/go-oidc/http/client.go @@ -1,51 +1,7 @@ package http -import ( - "io/ioutil" - "net/http" - "net/http/httptest" -) +import "net/http" type Client interface { Do(*http.Request) (*http.Response, error) } - -type HandlerClient struct { - Handler http.Handler -} - -func (hc *HandlerClient) Do(r *http.Request) (*http.Response, error) { - w := httptest.NewRecorder() - hc.Handler.ServeHTTP(w, r) - - resp := http.Response{ - StatusCode: w.Code, - Header: w.Header(), - Body: ioutil.NopCloser(w.Body), - } - - return &resp, nil -} - -type RequestRecorder struct { - Response *http.Response - Error error - - Request *http.Request -} - -func (rr *RequestRecorder) Do(req *http.Request) (*http.Response, error) { - rr.Request = req - - if rr.Response == nil && rr.Error == nil { - panic("RequestRecorder Response and Error cannot both be nil") - } else if rr.Response != nil && rr.Error != nil { - panic("RequestRecorder Response and Error cannot both be non-nil") - } - - return rr.Response, rr.Error -} - -func (rr *RequestRecorder) RoundTrip(req *http.Request) (*http.Response, error) { - return rr.Do(req) -} diff --git a/vendor/github.com/coreos/go-oidc/jose/claims.go b/vendor/github.com/coreos/go-oidc/jose/claims.go index 1695b3ac01..8b48bfd230 100644 --- a/vendor/github.com/coreos/go-oidc/jose/claims.go +++ b/vendor/github.com/coreos/go-oidc/jose/claims.go @@ -3,6 +3,7 @@ package jose import ( "encoding/json" "fmt" + "math" "time" ) @@ -70,13 +71,33 @@ func (c Claims) Int64Claim(name string) (int64, bool, error) { return v, true, nil } +func (c Claims) Float64Claim(name string) (float64, bool, error) { + cl, ok := c[name] + if !ok { + return 0, false, nil + } + + v, ok := cl.(float64) + if !ok { + vi, ok := cl.(int64) + if !ok { + return 0, false, fmt.Errorf("unable to parse claim as float64: %v", name) + } + v = float64(vi) + } + + return v, true, nil +} + func (c Claims) TimeClaim(name string) (time.Time, bool, error) { - v, ok, err := c.Int64Claim(name) + v, ok, err := c.Float64Claim(name) if !ok || err != nil { return time.Time{}, ok, err } - return time.Unix(v, 0).UTC(), true, nil + s := math.Trunc(v) + ns := (v - s) * math.Pow(10, 9) + return time.Unix(int64(s), int64(ns)).UTC(), true, nil } func decodeClaims(payload []byte) (Claims, error) { diff --git a/vendor/github.com/coreos/go-oidc/jose/jose.go b/vendor/github.com/coreos/go-oidc/jose/jose.go index 4f99aeb768..6209926596 100644 --- a/vendor/github.com/coreos/go-oidc/jose/jose.go +++ b/vendor/github.com/coreos/go-oidc/jose/jose.go @@ -13,6 +13,57 @@ const ( HeaderKeyID = "kid" ) +const ( + // Encryption Algorithm Header Parameter Values for JWS + // See: https://tools.ietf.org/html/draft-ietf-jose-json-web-algorithms-40#page-6 + AlgHS256 = "HS256" + AlgHS384 = "HS384" + AlgHS512 = "HS512" + AlgRS256 = "RS256" + AlgRS384 = "RS384" + AlgRS512 = "RS512" + AlgES256 = "ES256" + AlgES384 = "ES384" + AlgES512 = "ES512" + AlgPS256 = "PS256" + AlgPS384 = "PS384" + AlgPS512 = "PS512" + AlgNone = "none" +) + +const ( + // Algorithm Header Parameter Values for JWE + // See: https://tools.ietf.org/html/draft-ietf-jose-json-web-algorithms-40#section-4.1 + AlgRSA15 = "RSA1_5" + AlgRSAOAEP = "RSA-OAEP" + AlgRSAOAEP256 = "RSA-OAEP-256" + AlgA128KW = "A128KW" + AlgA192KW = "A192KW" + AlgA256KW = "A256KW" + AlgDir = "dir" + AlgECDHES = "ECDH-ES" + AlgECDHESA128KW = "ECDH-ES+A128KW" + AlgECDHESA192KW = "ECDH-ES+A192KW" + AlgECDHESA256KW = "ECDH-ES+A256KW" + AlgA128GCMKW = "A128GCMKW" + AlgA192GCMKW = "A192GCMKW" + AlgA256GCMKW = "A256GCMKW" + AlgPBES2HS256A128KW = "PBES2-HS256+A128KW" + AlgPBES2HS384A192KW = "PBES2-HS384+A192KW" + AlgPBES2HS512A256KW = "PBES2-HS512+A256KW" +) + +const ( + // Encryption Algorithm Header Parameter Values for JWE + // See: https://tools.ietf.org/html/draft-ietf-jose-json-web-algorithms-40#page-22 + EncA128CBCHS256 = "A128CBC-HS256" + EncA128CBCHS384 = "A128CBC-HS384" + EncA256CBCHS512 = "A256CBC-HS512" + EncA128GCM = "A128GCM" + EncA192GCM = "A192GCM" + EncA256GCM = "A256GCM" +) + type JOSEHeader map[string]string func (j JOSEHeader) Validate() error { diff --git a/vendor/github.com/coreos/go-oidc/jose/jwk.go b/vendor/github.com/coreos/go-oidc/jose/jwk.go index 045f5fdee2..b7a8e23558 100644 --- a/vendor/github.com/coreos/go-oidc/jose/jwk.go +++ b/vendor/github.com/coreos/go-oidc/jose/jwk.go @@ -70,6 +70,10 @@ func (j *JWK) UnmarshalJSON(data []byte) error { return nil } +type JWKSet struct { + Keys []JWK `json:"keys"` +} + func decodeExponent(e string) (int, error) { decE, err := decodeBase64URLPaddingOptional(e) if err != nil { diff --git a/vendor/github.com/coreos/go-oidc/jose/sig.go b/vendor/github.com/coreos/go-oidc/jose/sig.go index 220681bd75..7b2b253cca 100644 --- a/vendor/github.com/coreos/go-oidc/jose/sig.go +++ b/vendor/github.com/coreos/go-oidc/jose/sig.go @@ -2,7 +2,6 @@ package jose import ( "fmt" - "strings" ) type Verifier interface { @@ -17,7 +16,7 @@ type Signer interface { } func NewVerifier(jwk JWK) (Verifier, error) { - if strings.ToUpper(jwk.Type) != "RSA" { + if jwk.Type != "RSA" { return nil, fmt.Errorf("unsupported key type %q", jwk.Type) } diff --git a/vendor/github.com/coreos/go-oidc/jose/sig_hmac.go b/vendor/github.com/coreos/go-oidc/jose/sig_hmac.go index bcf42b707e..b3ca3ef3d4 100644 --- a/vendor/github.com/coreos/go-oidc/jose/sig_hmac.go +++ b/vendor/github.com/coreos/go-oidc/jose/sig_hmac.go @@ -7,7 +7,6 @@ import ( _ "crypto/sha256" "errors" "fmt" - "strings" ) type VerifierHMAC struct { @@ -21,7 +20,7 @@ type SignerHMAC struct { } func NewVerifierHMAC(jwk JWK) (*VerifierHMAC, error) { - if strings.ToUpper(jwk.Alg) != "HS256" { + if jwk.Alg != "" && jwk.Alg != "HS256" { return nil, fmt.Errorf("unsupported key algorithm %q", jwk.Alg) } diff --git a/vendor/github.com/coreos/go-oidc/jose/sig_rsa.go b/vendor/github.com/coreos/go-oidc/jose/sig_rsa.go index 57066f02f1..004e45dd83 100644 --- a/vendor/github.com/coreos/go-oidc/jose/sig_rsa.go +++ b/vendor/github.com/coreos/go-oidc/jose/sig_rsa.go @@ -5,7 +5,6 @@ import ( "crypto/rand" "crypto/rsa" "fmt" - "strings" ) type VerifierRSA struct { @@ -20,7 +19,7 @@ type SignerRSA struct { } func NewVerifierRSA(jwk JWK) (*VerifierRSA, error) { - if strings.ToUpper(jwk.Alg) != "RS256" { + if jwk.Alg != "" && jwk.Alg != "RS256" { return nil, fmt.Errorf("unsupported key algorithm %q", jwk.Alg) } diff --git a/vendor/github.com/coreos/go-oidc/key/key.go b/vendor/github.com/coreos/go-oidc/key/key.go index 3edae468f8..d0142a9e0e 100644 --- a/vendor/github.com/coreos/go-oidc/key/key.go +++ b/vendor/github.com/coreos/go-oidc/key/key.go @@ -20,7 +20,7 @@ type PublicKey struct { } func (k *PublicKey) MarshalJSON() ([]byte, error) { - return json.Marshal(k.jwk) + return json.Marshal(&k.jwk) } func (k *PublicKey) UnmarshalJSON(data []byte) error { @@ -135,7 +135,7 @@ func (s *PrivateKeySet) Active() *PrivateKey { type GeneratePrivateKeyFunc func() (*PrivateKey, error) func GeneratePrivateKey() (*PrivateKey, error) { - pk, err := rsa.GenerateKey(rand.Reader, 1024) + pk, err := rsa.GenerateKey(rand.Reader, 2048) if err != nil { return nil, err } diff --git a/vendor/github.com/coreos/go-oidc/key/repo.go b/vendor/github.com/coreos/go-oidc/key/repo.go index 1d4ce8d397..1acdeb3614 100644 --- a/vendor/github.com/coreos/go-oidc/key/repo.go +++ b/vendor/github.com/coreos/go-oidc/key/repo.go @@ -1,6 +1,9 @@ package key -import "errors" +import ( + "errors" + "sync" +) var ErrorNoKeys = errors.New("no keys found") @@ -22,6 +25,7 @@ func NewPrivateKeySetRepo() PrivateKeySetRepo { } type memPrivateKeySetRepo struct { + mu sync.RWMutex pks PrivateKeySet } @@ -33,11 +37,17 @@ func (r *memPrivateKeySetRepo) Set(ks KeySet) error { return errors.New("nil KeySet") } + r.mu.Lock() + defer r.mu.Unlock() + r.pks = *pks return nil } func (r *memPrivateKeySetRepo) Get() (KeySet, error) { + r.mu.RLock() + defer r.mu.RUnlock() + if r.pks.keys == nil { return nil, ErrorNoKeys } diff --git a/vendor/github.com/coreos/go-oidc/key/sync.go b/vendor/github.com/coreos/go-oidc/key/sync.go index 076ee462eb..e8d5d03d88 100644 --- a/vendor/github.com/coreos/go-oidc/key/sync.go +++ b/vendor/github.com/coreos/go-oidc/key/sync.go @@ -29,7 +29,7 @@ func (s *KeySetSyncer) Run() chan struct{} { var failing bool var next time.Duration for { - exp, err := sync(s.readable, s.writable, s.clock) + exp, err := syncKeySet(s.readable, s.writable, s.clock) if err != nil || exp == 0 { if !failing { failing = true @@ -62,12 +62,12 @@ func (s *KeySetSyncer) Run() chan struct{} { } func Sync(r ReadableKeySetRepo, w WritableKeySetRepo) (time.Duration, error) { - return sync(r, w, clockwork.NewRealClock()) + return syncKeySet(r, w, clockwork.NewRealClock()) } -// sync copies the keyset from r to the KeySet at w and returns the duration in which the KeySet will expire. +// syncKeySet copies the keyset from r to the KeySet at w and returns the duration in which the KeySet will expire. // If keyset has already expired, returns a zero duration. -func sync(r ReadableKeySetRepo, w WritableKeySetRepo, clock clockwork.Clock) (exp time.Duration, err error) { +func syncKeySet(r ReadableKeySetRepo, w WritableKeySetRepo, clock clockwork.Clock) (exp time.Duration, err error) { var ks KeySet ks, err = r.Get() if err != nil { diff --git a/vendor/github.com/coreos/go-oidc/oauth2/oauth2.go b/vendor/github.com/coreos/go-oidc/oauth2/oauth2.go index c5583e518f..1c68293a0a 100644 --- a/vendor/github.com/coreos/go-oidc/oauth2/oauth2.go +++ b/vendor/github.com/coreos/go-oidc/oauth2/oauth2.go @@ -8,19 +8,55 @@ import ( "mime" "net/http" "net/url" + "sort" "strconv" "strings" phttp "github.com/coreos/go-oidc/http" ) +// ResponseTypesEqual compares two response_type values. If either +// contains a space, it is treated as an unordered list. For example, +// comparing "code id_token" and "id_token code" would evaluate to true. +func ResponseTypesEqual(r1, r2 string) bool { + if !strings.Contains(r1, " ") || !strings.Contains(r2, " ") { + // fast route, no split needed + return r1 == r2 + } + + // split, sort, and compare + r1Fields := strings.Fields(r1) + r2Fields := strings.Fields(r2) + if len(r1Fields) != len(r2Fields) { + return false + } + sort.Strings(r1Fields) + sort.Strings(r2Fields) + for i, r1Field := range r1Fields { + if r1Field != r2Fields[i] { + return false + } + } + return true +} + const ( - ResponseTypeCode = "code" + // OAuth2.0 response types registered by OIDC. + // + // See: https://openid.net/specs/oauth-v2-multiple-response-types-1_0.html#RegistryContents + ResponseTypeCode = "code" + ResponseTypeCodeIDToken = "code id_token" + ResponseTypeCodeIDTokenToken = "code id_token token" + ResponseTypeIDToken = "id_token" + ResponseTypeIDTokenToken = "id_token token" + ResponseTypeToken = "token" + ResponseTypeNone = "none" ) const ( GrantTypeAuthCode = "authorization_code" GrantTypeClientCreds = "client_credentials" + GrantTypeUserCreds = "password" GrantTypeImplicit = "implicit" GrantTypeRefreshToken = "refresh_token" @@ -105,6 +141,11 @@ func NewClient(hc phttp.Client, cfg Config) (c *Client, err error) { return } +// Return the embedded HTTP client +func (c *Client) HttpClient() phttp.Client { + return c.hc +} + // Generate the url for initial redirect to oauth provider. func (c *Client) AuthCodeURL(state, accessType, prompt string) string { v := c.commonURLValues() @@ -136,22 +177,24 @@ func (c *Client) commonURLValues() url.Values { } } -func (c *Client) newAuthenticatedRequest(url string, values url.Values) (*http.Request, error) { +func (c *Client) newAuthenticatedRequest(urlToken string, values url.Values) (*http.Request, error) { var req *http.Request var err error switch c.authMethod { case AuthMethodClientSecretPost: values.Set("client_secret", c.creds.Secret) - req, err = http.NewRequest("POST", url, strings.NewReader(values.Encode())) + req, err = http.NewRequest("POST", urlToken, strings.NewReader(values.Encode())) if err != nil { return nil, err } case AuthMethodClientSecretBasic: - req, err = http.NewRequest("POST", url, strings.NewReader(values.Encode())) + req, err = http.NewRequest("POST", urlToken, strings.NewReader(values.Encode())) if err != nil { return nil, err } - req.SetBasicAuth(c.creds.ID, c.creds.Secret) + encodedID := url.QueryEscape(c.creds.ID) + encodedSecret := url.QueryEscape(c.creds.Secret) + req.SetBasicAuth(encodedID, encodedSecret) default: panic("misconfigured client: auth method not supported") } @@ -183,6 +226,30 @@ func (c *Client) ClientCredsToken(scope []string) (result TokenResponse, err err return parseTokenResponse(resp) } +// UserCredsToken posts the username and password to obtain a token scoped to the OAuth2 client via the "password" grant_type +// May not be supported by all OAuth2 servers. +func (c *Client) UserCredsToken(username, password string) (result TokenResponse, err error) { + v := url.Values{ + "scope": {strings.Join(c.scope, " ")}, + "grant_type": {GrantTypeUserCreds}, + "username": {username}, + "password": {password}, + } + + req, err := c.newAuthenticatedRequest(c.tokenURL.String(), v) + if err != nil { + return + } + + resp, err := c.hc.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + + return parseTokenResponse(resp) +} + // RequestToken requests a token from the Token Endpoint with the specified grantType. // If 'grantType' == GrantTypeAuthCode, then 'value' should be the authorization code. // If 'grantType' == GrantTypeRefreshToken, then 'value' should be the refresh token. diff --git a/vendor/github.com/coreos/go-oidc/oidc/client.go b/vendor/github.com/coreos/go-oidc/oidc/client.go index 76330237f1..7a3cb40f64 100644 --- a/vendor/github.com/coreos/go-oidc/oidc/client.go +++ b/vendor/github.com/coreos/go-oidc/oidc/client.go @@ -1,9 +1,11 @@ package oidc import ( + "encoding/json" "errors" "fmt" "net/http" + "net/mail" "net/url" "sync" "time" @@ -36,23 +38,520 @@ type ClientIdentity struct { Metadata ClientMetadata } -type ClientMetadata struct { - RedirectURLs []url.URL +type JWAOptions struct { + // SigningAlg specifies an JWA alg for signing JWTs. + // + // Specifying this field implies different actions depending on the context. It may + // require objects be serialized and signed as a JWT instead of plain JSON, or + // require an existing JWT object use the specified alg. + // + // See: http://openid.net/specs/openid-connect-registration-1_0.html#ClientMetadata + SigningAlg string + // EncryptionAlg, if provided, specifies that the returned or sent object be stored + // (or nested) within a JWT object and encrypted with the provided JWA alg. + EncryptionAlg string + // EncryptionEnc specifies the JWA enc algorithm to use with EncryptionAlg. If + // EncryptionAlg is provided and EncryptionEnc is omitted, this field defaults + // to A128CBC-HS256. + // + // If EncryptionEnc is provided EncryptionAlg must also be specified. + EncryptionEnc string } +func (opt JWAOptions) valid() error { + if opt.EncryptionEnc != "" && opt.EncryptionAlg == "" { + return errors.New("encryption encoding provided with no encryption algorithm") + } + return nil +} + +func (opt JWAOptions) defaults() JWAOptions { + if opt.EncryptionAlg != "" && opt.EncryptionEnc == "" { + opt.EncryptionEnc = jose.EncA128CBCHS256 + } + return opt +} + +var ( + // Ensure ClientMetadata satisfies these interfaces. + _ json.Marshaler = &ClientMetadata{} + _ json.Unmarshaler = &ClientMetadata{} +) + +// ClientMetadata holds metadata that the authorization server associates +// with a client identifier. The fields range from human-facing display +// strings such as client name, to items that impact the security of the +// protocol, such as the list of valid redirect URIs. +// +// See http://openid.net/specs/openid-connect-registration-1_0.html#ClientMetadata +// +// TODO: support language specific claim representations +// http://openid.net/specs/openid-connect-registration-1_0.html#LanguagesAndScripts +type ClientMetadata struct { + RedirectURIs []url.URL // Required + + // A list of OAuth 2.0 "response_type" values that the client wishes to restrict + // itself to. Either "code", "token", or another registered extension. + // + // If omitted, only "code" will be used. + ResponseTypes []string + // A list of OAuth 2.0 grant types the client wishes to restrict itself to. + // The grant type values used by OIDC are "authorization_code", "implicit", + // and "refresh_token". + // + // If ommitted, only "authorization_code" will be used. + GrantTypes []string + // "native" or "web". If omitted, "web". + ApplicationType string + + // List of email addresses. + Contacts []mail.Address + // Name of client to be presented to the end-user. + ClientName string + // URL that references a logo for the Client application. + LogoURI *url.URL + // URL of the home page of the Client. + ClientURI *url.URL + // Profile data policies and terms of use to be provided to the end user. + PolicyURI *url.URL + TermsOfServiceURI *url.URL + + // URL to or the value of the client's JSON Web Key Set document. + JWKSURI *url.URL + JWKS *jose.JWKSet + + // URL referencing a flie with a single JSON array of redirect URIs. + SectorIdentifierURI *url.URL + + SubjectType string + + // Options to restrict the JWS alg and enc values used for server responses and requests. + IDTokenResponseOptions JWAOptions + UserInfoResponseOptions JWAOptions + RequestObjectOptions JWAOptions + + // Client requested authorization method and signing options for the token endpoint. + // + // Defaults to "client_secret_basic" + TokenEndpointAuthMethod string + TokenEndpointAuthSigningAlg string + + // DefaultMaxAge specifies the maximum amount of time in seconds before an authorized + // user must reauthroize. + // + // If 0, no limitation is placed on the maximum. + DefaultMaxAge int64 + // RequireAuthTime specifies if the auth_time claim in the ID token is required. + RequireAuthTime bool + + // Default Authentication Context Class Reference values for authentication requests. + DefaultACRValues []string + + // URI that a third party can use to initiate a login by the relaying party. + // + // See: http://openid.net/specs/openid-connect-core-1_0.html#ThirdPartyInitiatedLogin + InitiateLoginURI *url.URL + // Pre-registered request_uri values that may be cached by the server. + RequestURIs []url.URL +} + +// Defaults returns a shallow copy of ClientMetadata with default +// values replacing omitted fields. +func (m ClientMetadata) Defaults() ClientMetadata { + if len(m.ResponseTypes) == 0 { + m.ResponseTypes = []string{oauth2.ResponseTypeCode} + } + if len(m.GrantTypes) == 0 { + m.GrantTypes = []string{oauth2.GrantTypeAuthCode} + } + if m.ApplicationType == "" { + m.ApplicationType = "web" + } + if m.TokenEndpointAuthMethod == "" { + m.TokenEndpointAuthMethod = oauth2.AuthMethodClientSecretBasic + } + m.IDTokenResponseOptions = m.IDTokenResponseOptions.defaults() + m.UserInfoResponseOptions = m.UserInfoResponseOptions.defaults() + m.RequestObjectOptions = m.RequestObjectOptions.defaults() + return m +} + +func (m *ClientMetadata) MarshalJSON() ([]byte, error) { + e := m.toEncodableStruct() + return json.Marshal(&e) +} + +func (m *ClientMetadata) UnmarshalJSON(data []byte) error { + var e encodableClientMetadata + if err := json.Unmarshal(data, &e); err != nil { + return err + } + meta, err := e.toStruct() + if err != nil { + return err + } + if err := meta.Valid(); err != nil { + return err + } + *m = meta + return nil +} + +type encodableClientMetadata struct { + RedirectURIs []string `json:"redirect_uris"` // Required + ResponseTypes []string `json:"response_types,omitempty"` + GrantTypes []string `json:"grant_types,omitempty"` + ApplicationType string `json:"application_type,omitempty"` + Contacts []string `json:"contacts,omitempty"` + ClientName string `json:"client_name,omitempty"` + LogoURI string `json:"logo_uri,omitempty"` + ClientURI string `json:"client_uri,omitempty"` + PolicyURI string `json:"policy_uri,omitempty"` + TermsOfServiceURI string `json:"tos_uri,omitempty"` + JWKSURI string `json:"jwks_uri,omitempty"` + JWKS *jose.JWKSet `json:"jwks,omitempty"` + SectorIdentifierURI string `json:"sector_identifier_uri,omitempty"` + SubjectType string `json:"subject_type,omitempty"` + IDTokenSignedResponseAlg string `json:"id_token_signed_response_alg,omitempty"` + IDTokenEncryptedResponseAlg string `json:"id_token_encrypted_response_alg,omitempty"` + IDTokenEncryptedResponseEnc string `json:"id_token_encrypted_response_enc,omitempty"` + UserInfoSignedResponseAlg string `json:"userinfo_signed_response_alg,omitempty"` + UserInfoEncryptedResponseAlg string `json:"userinfo_encrypted_response_alg,omitempty"` + UserInfoEncryptedResponseEnc string `json:"userinfo_encrypted_response_enc,omitempty"` + RequestObjectSigningAlg string `json:"request_object_signing_alg,omitempty"` + RequestObjectEncryptionAlg string `json:"request_object_encryption_alg,omitempty"` + RequestObjectEncryptionEnc string `json:"request_object_encryption_enc,omitempty"` + TokenEndpointAuthMethod string `json:"token_endpoint_auth_method,omitempty"` + TokenEndpointAuthSigningAlg string `json:"token_endpoint_auth_signing_alg,omitempty"` + DefaultMaxAge int64 `json:"default_max_age,omitempty"` + RequireAuthTime bool `json:"require_auth_time,omitempty"` + DefaultACRValues []string `json:"default_acr_values,omitempty"` + InitiateLoginURI string `json:"initiate_login_uri,omitempty"` + RequestURIs []string `json:"request_uris,omitempty"` +} + +func (c *encodableClientMetadata) toStruct() (ClientMetadata, error) { + p := stickyErrParser{} + m := ClientMetadata{ + RedirectURIs: p.parseURIs(c.RedirectURIs, "redirect_uris"), + ResponseTypes: c.ResponseTypes, + GrantTypes: c.GrantTypes, + ApplicationType: c.ApplicationType, + Contacts: p.parseEmails(c.Contacts, "contacts"), + ClientName: c.ClientName, + LogoURI: p.parseURI(c.LogoURI, "logo_uri"), + ClientURI: p.parseURI(c.ClientURI, "client_uri"), + PolicyURI: p.parseURI(c.PolicyURI, "policy_uri"), + TermsOfServiceURI: p.parseURI(c.TermsOfServiceURI, "tos_uri"), + JWKSURI: p.parseURI(c.JWKSURI, "jwks_uri"), + JWKS: c.JWKS, + SectorIdentifierURI: p.parseURI(c.SectorIdentifierURI, "sector_identifier_uri"), + SubjectType: c.SubjectType, + TokenEndpointAuthMethod: c.TokenEndpointAuthMethod, + TokenEndpointAuthSigningAlg: c.TokenEndpointAuthSigningAlg, + DefaultMaxAge: c.DefaultMaxAge, + RequireAuthTime: c.RequireAuthTime, + DefaultACRValues: c.DefaultACRValues, + InitiateLoginURI: p.parseURI(c.InitiateLoginURI, "initiate_login_uri"), + RequestURIs: p.parseURIs(c.RequestURIs, "request_uris"), + IDTokenResponseOptions: JWAOptions{ + c.IDTokenSignedResponseAlg, + c.IDTokenEncryptedResponseAlg, + c.IDTokenEncryptedResponseEnc, + }, + UserInfoResponseOptions: JWAOptions{ + c.UserInfoSignedResponseAlg, + c.UserInfoEncryptedResponseAlg, + c.UserInfoEncryptedResponseEnc, + }, + RequestObjectOptions: JWAOptions{ + c.RequestObjectSigningAlg, + c.RequestObjectEncryptionAlg, + c.RequestObjectEncryptionEnc, + }, + } + if p.firstErr != nil { + return ClientMetadata{}, p.firstErr + } + return m, nil +} + +// stickyErrParser parses URIs and email addresses. Once it encounters +// a parse error, subsequent calls become no-op. +type stickyErrParser struct { + firstErr error +} + +func (p *stickyErrParser) parseURI(s, field string) *url.URL { + if p.firstErr != nil || s == "" { + return nil + } + u, err := url.Parse(s) + if err == nil { + if u.Host == "" { + err = errors.New("no host in URI") + } else if u.Scheme != "http" && u.Scheme != "https" { + err = errors.New("invalid URI scheme") + } + } + if err != nil { + p.firstErr = fmt.Errorf("failed to parse %s: %v", field, err) + return nil + } + return u +} + +func (p *stickyErrParser) parseURIs(s []string, field string) []url.URL { + if p.firstErr != nil || len(s) == 0 { + return nil + } + uris := make([]url.URL, len(s)) + for i, val := range s { + if val == "" { + p.firstErr = fmt.Errorf("invalid URI in field %s", field) + return nil + } + if u := p.parseURI(val, field); u != nil { + uris[i] = *u + } + } + return uris +} + +func (p *stickyErrParser) parseEmails(s []string, field string) []mail.Address { + if p.firstErr != nil || len(s) == 0 { + return nil + } + addrs := make([]mail.Address, len(s)) + for i, addr := range s { + if addr == "" { + p.firstErr = fmt.Errorf("invalid email in field %s", field) + return nil + } + a, err := mail.ParseAddress(addr) + if err != nil { + p.firstErr = fmt.Errorf("invalid email in field %s: %v", field, err) + return nil + } + addrs[i] = *a + } + return addrs +} + +func (m *ClientMetadata) toEncodableStruct() encodableClientMetadata { + return encodableClientMetadata{ + RedirectURIs: urisToStrings(m.RedirectURIs), + ResponseTypes: m.ResponseTypes, + GrantTypes: m.GrantTypes, + ApplicationType: m.ApplicationType, + Contacts: emailsToStrings(m.Contacts), + ClientName: m.ClientName, + LogoURI: uriToString(m.LogoURI), + ClientURI: uriToString(m.ClientURI), + PolicyURI: uriToString(m.PolicyURI), + TermsOfServiceURI: uriToString(m.TermsOfServiceURI), + JWKSURI: uriToString(m.JWKSURI), + JWKS: m.JWKS, + SectorIdentifierURI: uriToString(m.SectorIdentifierURI), + SubjectType: m.SubjectType, + IDTokenSignedResponseAlg: m.IDTokenResponseOptions.SigningAlg, + IDTokenEncryptedResponseAlg: m.IDTokenResponseOptions.EncryptionAlg, + IDTokenEncryptedResponseEnc: m.IDTokenResponseOptions.EncryptionEnc, + UserInfoSignedResponseAlg: m.UserInfoResponseOptions.SigningAlg, + UserInfoEncryptedResponseAlg: m.UserInfoResponseOptions.EncryptionAlg, + UserInfoEncryptedResponseEnc: m.UserInfoResponseOptions.EncryptionEnc, + RequestObjectSigningAlg: m.RequestObjectOptions.SigningAlg, + RequestObjectEncryptionAlg: m.RequestObjectOptions.EncryptionAlg, + RequestObjectEncryptionEnc: m.RequestObjectOptions.EncryptionEnc, + TokenEndpointAuthMethod: m.TokenEndpointAuthMethod, + TokenEndpointAuthSigningAlg: m.TokenEndpointAuthSigningAlg, + DefaultMaxAge: m.DefaultMaxAge, + RequireAuthTime: m.RequireAuthTime, + DefaultACRValues: m.DefaultACRValues, + InitiateLoginURI: uriToString(m.InitiateLoginURI), + RequestURIs: urisToStrings(m.RequestURIs), + } +} + +func uriToString(u *url.URL) string { + if u == nil { + return "" + } + return u.String() +} + +func urisToStrings(urls []url.URL) []string { + if len(urls) == 0 { + return nil + } + sli := make([]string, len(urls)) + for i, u := range urls { + sli[i] = u.String() + } + return sli +} + +func emailsToStrings(addrs []mail.Address) []string { + if len(addrs) == 0 { + return nil + } + sli := make([]string, len(addrs)) + for i, addr := range addrs { + sli[i] = addr.String() + } + return sli +} + +// Valid determines if a ClientMetadata conforms with the OIDC specification. +// +// Valid is called by UnmarshalJSON. +// +// NOTE(ericchiang): For development purposes Valid does not mandate 'https' for +// URLs fields where the OIDC spec requires it. This may change in future releases +// of this package. See: https://github.com/coreos/go-oidc/issues/34 func (m *ClientMetadata) Valid() error { - if len(m.RedirectURLs) == 0 { + if len(m.RedirectURIs) == 0 { return errors.New("zero redirect URLs") } - for _, u := range m.RedirectURLs { + validURI := func(u *url.URL, fieldName string) error { + if u.Host == "" { + return fmt.Errorf("no host for uri field %s", fieldName) + } if u.Scheme != "http" && u.Scheme != "https" { - return errors.New("invalid redirect URL: scheme not http/https") - } else if u.Host == "" { - return errors.New("invalid redirect URL: host empty") + return fmt.Errorf("uri field %s scheme is not http or https", fieldName) + } + return nil + } + + uris := []struct { + val *url.URL + name string + }{ + {m.LogoURI, "logo_uri"}, + {m.ClientURI, "client_uri"}, + {m.PolicyURI, "policy_uri"}, + {m.TermsOfServiceURI, "tos_uri"}, + {m.JWKSURI, "jwks_uri"}, + {m.SectorIdentifierURI, "sector_identifier_uri"}, + {m.InitiateLoginURI, "initiate_login_uri"}, + } + + for _, uri := range uris { + if uri.val == nil { + continue + } + if err := validURI(uri.val, uri.name); err != nil { + return err } } + uriLists := []struct { + vals []url.URL + name string + }{ + {m.RedirectURIs, "redirect_uris"}, + {m.RequestURIs, "request_uris"}, + } + for _, list := range uriLists { + for _, uri := range list.vals { + if err := validURI(&uri, list.name); err != nil { + return err + } + } + } + + options := []struct { + option JWAOptions + name string + }{ + {m.IDTokenResponseOptions, "id_token response"}, + {m.UserInfoResponseOptions, "userinfo response"}, + {m.RequestObjectOptions, "request_object"}, + } + for _, option := range options { + if err := option.option.valid(); err != nil { + return fmt.Errorf("invalid JWA values for %s: %v", option.name, err) + } + } + return nil +} + +type ClientRegistrationResponse struct { + ClientID string // Required + ClientSecret string + RegistrationAccessToken string + RegistrationClientURI string + // If IsZero is true, unspecified. + ClientIDIssuedAt time.Time + // Time at which the client_secret will expire. + // If IsZero is true, it will not expire. + ClientSecretExpiresAt time.Time + + ClientMetadata +} + +type encodableClientRegistrationResponse struct { + ClientID string `json:"client_id"` // Required + ClientSecret string `json:"client_secret,omitempty"` + RegistrationAccessToken string `json:"registration_access_token,omitempty"` + RegistrationClientURI string `json:"registration_client_uri,omitempty"` + ClientIDIssuedAt int64 `json:"client_id_issued_at,omitempty"` + // Time at which the client_secret will expire, in seconds since the epoch. + // If 0 it will not expire. + ClientSecretExpiresAt int64 `json:"client_secret_expires_at"` // Required + + encodableClientMetadata +} + +func unixToSec(t time.Time) int64 { + if t.IsZero() { + return 0 + } + return t.Unix() +} + +func (c *ClientRegistrationResponse) MarshalJSON() ([]byte, error) { + e := encodableClientRegistrationResponse{ + ClientID: c.ClientID, + ClientSecret: c.ClientSecret, + RegistrationAccessToken: c.RegistrationAccessToken, + RegistrationClientURI: c.RegistrationClientURI, + ClientIDIssuedAt: unixToSec(c.ClientIDIssuedAt), + ClientSecretExpiresAt: unixToSec(c.ClientSecretExpiresAt), + encodableClientMetadata: c.ClientMetadata.toEncodableStruct(), + } + return json.Marshal(&e) +} + +func secToUnix(sec int64) time.Time { + if sec == 0 { + return time.Time{} + } + return time.Unix(sec, 0) +} + +func (c *ClientRegistrationResponse) UnmarshalJSON(data []byte) error { + var e encodableClientRegistrationResponse + if err := json.Unmarshal(data, &e); err != nil { + return err + } + if e.ClientID == "" { + return errors.New("no client_id in client registration response") + } + metadata, err := e.encodableClientMetadata.toStruct() + if err != nil { + return err + } + *c = ClientRegistrationResponse{ + ClientID: e.ClientID, + ClientSecret: e.ClientSecret, + RegistrationAccessToken: e.RegistrationAccessToken, + RegistrationClientURI: e.RegistrationClientURI, + ClientIDIssuedAt: secToUnix(e.ClientIDIssuedAt), + ClientSecretExpiresAt: secToUnix(e.ClientSecretExpiresAt), + ClientMetadata: metadata, + } return nil } @@ -101,34 +600,12 @@ type Client struct { redirectURL string scope []string keySet key.PublicKeySet + providerSyncer *ProviderConfigSyncer keySetSyncMutex sync.RWMutex lastKeySetSync time.Time } -type providerConfigRepo struct { - mu sync.RWMutex - config ProviderConfig // do not access directly, use Get() -} - -func newProviderConfigRepo(pc ProviderConfig) *providerConfigRepo { - return &providerConfigRepo{sync.RWMutex{}, pc} -} - -// returns an error to implement ProviderConfigSetter -func (r *providerConfigRepo) Set(cfg ProviderConfig) error { - r.mu.Lock() - defer r.mu.Unlock() - r.config = cfg - return nil -} - -func (r *providerConfigRepo) Get() ProviderConfig { - r.mu.RLock() - defer r.mu.RUnlock() - return r.config -} - func (c *Client) Healthy() error { now := time.Now().UTC() @@ -155,8 +632,8 @@ func (c *Client) OAuthClient() (*oauth2.Client, error) { ocfg := oauth2.Config{ Credentials: oauth2.ClientCredentials(c.credentials), RedirectURL: c.redirectURL, - AuthURL: cfg.AuthEndpoint, - TokenURL: cfg.TokenEndpoint, + AuthURL: cfg.AuthEndpoint.String(), + TokenURL: cfg.TokenEndpoint.String(), Scope: c.scope, AuthMethod: authMethod, } @@ -178,9 +655,13 @@ func chooseAuthMethod(cfg ProviderConfig) (string, error) { return "", errors.New("no supported auth methods") } +// SyncProviderConfig starts the provider config syncer func (c *Client) SyncProviderConfig(discoveryURL string) chan struct{} { r := NewHTTPProviderConfigGetter(c.httpClient, discoveryURL) - return NewProviderConfigSyncer(r, c.providerConfig).Run() + s := NewProviderConfigSyncer(r, c.providerConfig) + stop := s.Run() + s.WaitUntilInitialSync() + return stop } func (c *Client) maybeSyncKeys() error { @@ -204,7 +685,7 @@ func (c *Client) maybeSyncKeys() error { } cfg := c.providerConfig.Get() - r := NewRemotePublicKeyRepo(c.httpClient, cfg.KeysEndpoint) + r := NewRemotePublicKeyRepo(c.httpClient, cfg.KeysEndpoint.String()) w := &clientKeyRepo{client: c} _, err := key.Sync(r, w) c.lastKeySetSync = time.Now().UTC() @@ -299,7 +780,7 @@ func (c *Client) VerifyJWT(jwt jose.JWT) error { } v := NewJWTVerifier( - c.providerConfig.Get().Issuer, + c.providerConfig.Get().Issuer.String(), c.credentials.ID, c.maybeSyncKeys, keysFunc) @@ -340,3 +821,26 @@ func (c *Client) keysFuncAll() func() []key.PublicKey { return c.keySet.Keys() } } + +type providerConfigRepo struct { + mu sync.RWMutex + config ProviderConfig // do not access directly, use Get() +} + +func newProviderConfigRepo(pc ProviderConfig) *providerConfigRepo { + return &providerConfigRepo{sync.RWMutex{}, pc} +} + +// returns an error to implement ProviderConfigSetter +func (r *providerConfigRepo) Set(cfg ProviderConfig) error { + r.mu.Lock() + defer r.mu.Unlock() + r.config = cfg + return nil +} + +func (r *providerConfigRepo) Get() ProviderConfig { + r.mu.RLock() + defer r.mu.RUnlock() + return r.config +} diff --git a/vendor/github.com/coreos/go-oidc/oidc/key.go b/vendor/github.com/coreos/go-oidc/oidc/key.go index 004310d445..82a0f567d5 100644 --- a/vendor/github.com/coreos/go-oidc/oidc/key.go +++ b/vendor/github.com/coreos/go-oidc/oidc/key.go @@ -11,6 +11,11 @@ import ( "github.com/coreos/go-oidc/key" ) +// DefaultPublicKeySetTTL is the default TTL set on the PublicKeySet if no +// Cache-Control header is provided by the JWK Set document endpoint. +const DefaultPublicKeySetTTL = 24 * time.Hour + +// NewRemotePublicKeyRepo is responsible for fetching the JWK Set document. func NewRemotePublicKeyRepo(hc phttp.Client, ep string) *remotePublicKeyRepo { return &remotePublicKeyRepo{hc: hc, ep: ep} } @@ -20,6 +25,11 @@ type remotePublicKeyRepo struct { ep string } +// Get returns a PublicKeySet fetched from the JWK Set document endpoint. A TTL +// is set on the Key Set to avoid it having to be re-retrieved for every +// encryption event. This TTL is typically controlled by the endpoint returning +// a Cache-Control header, but defaults to 24 hours if no Cache-Control header +// is found. func (r *remotePublicKeyRepo) Get() (key.KeySet, error) { req, err := http.NewRequest("GET", r.ep, nil) if err != nil { @@ -48,7 +58,7 @@ func (r *remotePublicKeyRepo) Get() (key.KeySet, error) { return nil, err } if !ok { - return nil, errors.New("HTTP cache headers not set") + ttl = DefaultPublicKeySetTTL } exp := time.Now().UTC().Add(ttl) diff --git a/vendor/github.com/coreos/go-oidc/oidc/provider.go b/vendor/github.com/coreos/go-oidc/oidc/provider.go index f911e39e08..1235890c0c 100644 --- a/vendor/github.com/coreos/go-oidc/oidc/provider.go +++ b/vendor/github.com/coreos/go-oidc/oidc/provider.go @@ -2,8 +2,12 @@ package oidc import ( "encoding/json" + "errors" "fmt" "net/http" + "net/url" + "strings" + "sync" "time" "github.com/coreos/pkg/capnslog" @@ -18,6 +22,26 @@ var ( log = capnslog.NewPackageLogger("github.com/coreos/go-oidc", "http") ) +const ( + // Subject Identifier types defined by the OIDC spec. Specifies if the provider + // should provide the same sub claim value to all clients (public) or a unique + // value for each client (pairwise). + // + // See: http://openid.net/specs/openid-connect-core-1_0.html#SubjectIDTypes + SubjectTypePublic = "public" + SubjectTypePairwise = "pairwise" +) + +var ( + // Default values for omitted provider config fields. + // + // Use ProviderConfig's Defaults method to fill a provider config with these values. + DefaultGrantTypesSupported = []string{oauth2.GrantTypeAuthCode, oauth2.GrantTypeImplicit} + DefaultResponseModesSupported = []string{"query", "fragment"} + DefaultTokenEndpointAuthMethodsSupported = []string{oauth2.AuthMethodClientSecretBasic} + DefaultClaimTypesSupported = []string{"normal"} +) + const ( MaximumProviderConfigSyncInterval = 24 * time.Hour MinimumProviderConfigSyncInterval = time.Minute @@ -28,29 +52,414 @@ const ( // internally configurable for tests var minimumProviderConfigSyncInterval = MinimumProviderConfigSyncInterval +var ( + // Ensure ProviderConfig satisfies these interfaces. + _ json.Marshaler = &ProviderConfig{} + _ json.Unmarshaler = &ProviderConfig{} +) + +// ProviderConfig represents the OpenID Provider Metadata specifying what +// configurations a provider supports. +// +// See: http://openid.net/specs/openid-connect-discovery-1_0.html#ProviderMetadata type ProviderConfig struct { - Issuer string `json:"issuer"` - AuthEndpoint string `json:"authorization_endpoint"` - TokenEndpoint string `json:"token_endpoint"` - KeysEndpoint string `json:"jwks_uri"` - ResponseTypesSupported []string `json:"response_types_supported"` - GrantTypesSupported []string `json:"grant_types_supported"` - SubjectTypesSupported []string `json:"subject_types_supported"` - IDTokenAlgValuesSupported []string `json:"id_token_alg_values_supported"` - TokenEndpointAuthMethodsSupported []string `json:"token_endpoint_auth_methods_supported"` - ExpiresAt time.Time `json:"-"` + Issuer *url.URL // Required + AuthEndpoint *url.URL // Required + TokenEndpoint *url.URL // Required if grant types other than "implicit" are supported + UserInfoEndpoint *url.URL + KeysEndpoint *url.URL // Required + RegistrationEndpoint *url.URL + + // Servers MAY choose not to advertise some supported scope values even when this + // parameter is used, although those defined in OpenID Core SHOULD be listed, if supported. + ScopesSupported []string + // OAuth2.0 response types supported. + ResponseTypesSupported []string // Required + // OAuth2.0 response modes supported. + // + // If omitted, defaults to DefaultResponseModesSupported. + ResponseModesSupported []string + // OAuth2.0 grant types supported. + // + // If omitted, defaults to DefaultGrantTypesSupported. + GrantTypesSupported []string + ACRValuesSupported []string + // SubjectTypesSupported specifies strategies for providing values for the sub claim. + SubjectTypesSupported []string // Required + + // JWA signing and encryption algorith values supported for ID tokens. + IDTokenSigningAlgValues []string // Required + IDTokenEncryptionAlgValues []string + IDTokenEncryptionEncValues []string + + // JWA signing and encryption algorith values supported for user info responses. + UserInfoSigningAlgValues []string + UserInfoEncryptionAlgValues []string + UserInfoEncryptionEncValues []string + + // JWA signing and encryption algorith values supported for request objects. + ReqObjSigningAlgValues []string + ReqObjEncryptionAlgValues []string + ReqObjEncryptionEncValues []string + + TokenEndpointAuthMethodsSupported []string + TokenEndpointAuthSigningAlgValuesSupported []string + DisplayValuesSupported []string + ClaimTypesSupported []string + ClaimsSupported []string + ServiceDocs *url.URL + ClaimsLocalsSupported []string + UILocalsSupported []string + ClaimsParameterSupported bool + RequestParameterSupported bool + RequestURIParamaterSupported bool + RequireRequestURIRegistration bool + + Policy *url.URL + TermsOfService *url.URL + + // Not part of the OpenID Provider Metadata + ExpiresAt time.Time } +// Defaults returns a shallow copy of ProviderConfig with default +// values replacing omitted fields. +// +// var cfg oidc.ProviderConfig +// // Fill provider config with default values for omitted fields. +// cfg = cfg.Defaults() +// +func (p ProviderConfig) Defaults() ProviderConfig { + setDefault := func(val *[]string, defaultVal []string) { + if len(*val) == 0 { + *val = defaultVal + } + } + setDefault(&p.GrantTypesSupported, DefaultGrantTypesSupported) + setDefault(&p.ResponseModesSupported, DefaultResponseModesSupported) + setDefault(&p.TokenEndpointAuthMethodsSupported, DefaultTokenEndpointAuthMethodsSupported) + setDefault(&p.ClaimTypesSupported, DefaultClaimTypesSupported) + return p +} + +func (p *ProviderConfig) MarshalJSON() ([]byte, error) { + e := p.toEncodableStruct() + return json.Marshal(&e) +} + +func (p *ProviderConfig) UnmarshalJSON(data []byte) error { + var e encodableProviderConfig + if err := json.Unmarshal(data, &e); err != nil { + return err + } + conf, err := e.toStruct() + if err != nil { + return err + } + if err := conf.Valid(); err != nil { + return err + } + *p = conf + return nil +} + +type encodableProviderConfig struct { + Issuer string `json:"issuer"` + AuthEndpoint string `json:"authorization_endpoint"` + TokenEndpoint string `json:"token_endpoint"` + UserInfoEndpoint string `json:"userinfo_endpoint,omitempty"` + KeysEndpoint string `json:"jwks_uri"` + RegistrationEndpoint string `json:"registration_endpoint,omitempty"` + + // Use 'omitempty' for all slices as per OIDC spec: + // "Claims that return multiple values are represented as JSON arrays. + // Claims with zero elements MUST be omitted from the response." + // http://openid.net/specs/openid-connect-discovery-1_0.html#ProviderConfigurationResponse + + ScopesSupported []string `json:"scopes_supported,omitempty"` + ResponseTypesSupported []string `json:"response_types_supported,omitempty"` + ResponseModesSupported []string `json:"response_modes_supported,omitempty"` + GrantTypesSupported []string `json:"grant_types_supported,omitempty"` + ACRValuesSupported []string `json:"acr_values_supported,omitempty"` + SubjectTypesSupported []string `json:"subject_types_supported,omitempty"` + + IDTokenSigningAlgValues []string `json:"id_token_signing_alg_values_supported,omitempty"` + IDTokenEncryptionAlgValues []string `json:"id_token_encryption_alg_values_supported,omitempty"` + IDTokenEncryptionEncValues []string `json:"id_token_encryption_enc_values_supported,omitempty"` + UserInfoSigningAlgValues []string `json:"userinfo_signing_alg_values_supported,omitempty"` + UserInfoEncryptionAlgValues []string `json:"userinfo_encryption_alg_values_supported,omitempty"` + UserInfoEncryptionEncValues []string `json:"userinfo_encryption_enc_values_supported,omitempty"` + ReqObjSigningAlgValues []string `json:"request_object_signing_alg_values_supported,omitempty"` + ReqObjEncryptionAlgValues []string `json:"request_object_encryption_alg_values_supported,omitempty"` + ReqObjEncryptionEncValues []string `json:"request_object_encryption_enc_values_supported,omitempty"` + + TokenEndpointAuthMethodsSupported []string `json:"token_endpoint_auth_methods_supported,omitempty"` + TokenEndpointAuthSigningAlgValuesSupported []string `json:"token_endpoint_auth_signing_alg_values_supported,omitempty"` + + DisplayValuesSupported []string `json:"display_values_supported,omitempty"` + ClaimTypesSupported []string `json:"claim_types_supported,omitempty"` + ClaimsSupported []string `json:"claims_supported,omitempty"` + ServiceDocs string `json:"service_documentation,omitempty"` + ClaimsLocalsSupported []string `json:"claims_locales_supported,omitempty"` + UILocalsSupported []string `json:"ui_locales_supported,omitempty"` + ClaimsParameterSupported bool `json:"claims_parameter_supported,omitempty"` + RequestParameterSupported bool `json:"request_parameter_supported,omitempty"` + RequestURIParamaterSupported bool `json:"request_uri_parameter_supported,omitempty"` + RequireRequestURIRegistration bool `json:"require_request_uri_registration,omitempty"` + + Policy string `json:"op_policy_uri,omitempty"` + TermsOfService string `json:"op_tos_uri,omitempty"` +} + +func (cfg ProviderConfig) toEncodableStruct() encodableProviderConfig { + return encodableProviderConfig{ + Issuer: uriToString(cfg.Issuer), + AuthEndpoint: uriToString(cfg.AuthEndpoint), + TokenEndpoint: uriToString(cfg.TokenEndpoint), + UserInfoEndpoint: uriToString(cfg.UserInfoEndpoint), + KeysEndpoint: uriToString(cfg.KeysEndpoint), + RegistrationEndpoint: uriToString(cfg.RegistrationEndpoint), + ScopesSupported: cfg.ScopesSupported, + ResponseTypesSupported: cfg.ResponseTypesSupported, + ResponseModesSupported: cfg.ResponseModesSupported, + GrantTypesSupported: cfg.GrantTypesSupported, + ACRValuesSupported: cfg.ACRValuesSupported, + SubjectTypesSupported: cfg.SubjectTypesSupported, + IDTokenSigningAlgValues: cfg.IDTokenSigningAlgValues, + IDTokenEncryptionAlgValues: cfg.IDTokenEncryptionAlgValues, + IDTokenEncryptionEncValues: cfg.IDTokenEncryptionEncValues, + UserInfoSigningAlgValues: cfg.UserInfoSigningAlgValues, + UserInfoEncryptionAlgValues: cfg.UserInfoEncryptionAlgValues, + UserInfoEncryptionEncValues: cfg.UserInfoEncryptionEncValues, + ReqObjSigningAlgValues: cfg.ReqObjSigningAlgValues, + ReqObjEncryptionAlgValues: cfg.ReqObjEncryptionAlgValues, + ReqObjEncryptionEncValues: cfg.ReqObjEncryptionEncValues, + TokenEndpointAuthMethodsSupported: cfg.TokenEndpointAuthMethodsSupported, + TokenEndpointAuthSigningAlgValuesSupported: cfg.TokenEndpointAuthSigningAlgValuesSupported, + DisplayValuesSupported: cfg.DisplayValuesSupported, + ClaimTypesSupported: cfg.ClaimTypesSupported, + ClaimsSupported: cfg.ClaimsSupported, + ServiceDocs: uriToString(cfg.ServiceDocs), + ClaimsLocalsSupported: cfg.ClaimsLocalsSupported, + UILocalsSupported: cfg.UILocalsSupported, + ClaimsParameterSupported: cfg.ClaimsParameterSupported, + RequestParameterSupported: cfg.RequestParameterSupported, + RequestURIParamaterSupported: cfg.RequestURIParamaterSupported, + RequireRequestURIRegistration: cfg.RequireRequestURIRegistration, + Policy: uriToString(cfg.Policy), + TermsOfService: uriToString(cfg.TermsOfService), + } +} + +func (e encodableProviderConfig) toStruct() (ProviderConfig, error) { + p := stickyErrParser{} + conf := ProviderConfig{ + Issuer: p.parseURI(e.Issuer, "issuer"), + AuthEndpoint: p.parseURI(e.AuthEndpoint, "authorization_endpoint"), + TokenEndpoint: p.parseURI(e.TokenEndpoint, "token_endpoint"), + UserInfoEndpoint: p.parseURI(e.UserInfoEndpoint, "userinfo_endpoint"), + KeysEndpoint: p.parseURI(e.KeysEndpoint, "jwks_uri"), + RegistrationEndpoint: p.parseURI(e.RegistrationEndpoint, "registration_endpoint"), + ScopesSupported: e.ScopesSupported, + ResponseTypesSupported: e.ResponseTypesSupported, + ResponseModesSupported: e.ResponseModesSupported, + GrantTypesSupported: e.GrantTypesSupported, + ACRValuesSupported: e.ACRValuesSupported, + SubjectTypesSupported: e.SubjectTypesSupported, + IDTokenSigningAlgValues: e.IDTokenSigningAlgValues, + IDTokenEncryptionAlgValues: e.IDTokenEncryptionAlgValues, + IDTokenEncryptionEncValues: e.IDTokenEncryptionEncValues, + UserInfoSigningAlgValues: e.UserInfoSigningAlgValues, + UserInfoEncryptionAlgValues: e.UserInfoEncryptionAlgValues, + UserInfoEncryptionEncValues: e.UserInfoEncryptionEncValues, + ReqObjSigningAlgValues: e.ReqObjSigningAlgValues, + ReqObjEncryptionAlgValues: e.ReqObjEncryptionAlgValues, + ReqObjEncryptionEncValues: e.ReqObjEncryptionEncValues, + TokenEndpointAuthMethodsSupported: e.TokenEndpointAuthMethodsSupported, + TokenEndpointAuthSigningAlgValuesSupported: e.TokenEndpointAuthSigningAlgValuesSupported, + DisplayValuesSupported: e.DisplayValuesSupported, + ClaimTypesSupported: e.ClaimTypesSupported, + ClaimsSupported: e.ClaimsSupported, + ServiceDocs: p.parseURI(e.ServiceDocs, "service_documentation"), + ClaimsLocalsSupported: e.ClaimsLocalsSupported, + UILocalsSupported: e.UILocalsSupported, + ClaimsParameterSupported: e.ClaimsParameterSupported, + RequestParameterSupported: e.RequestParameterSupported, + RequestURIParamaterSupported: e.RequestURIParamaterSupported, + RequireRequestURIRegistration: e.RequireRequestURIRegistration, + Policy: p.parseURI(e.Policy, "op_policy-uri"), + TermsOfService: p.parseURI(e.TermsOfService, "op_tos_uri"), + } + if p.firstErr != nil { + return ProviderConfig{}, p.firstErr + } + return conf, nil +} + +// Empty returns if a ProviderConfig holds no information. +// +// This case generally indicates a ProviderConfigGetter has experienced an error +// and has nothing to report. func (p ProviderConfig) Empty() bool { - return p.Issuer == "" + return p.Issuer == nil +} + +func contains(sli []string, ele string) bool { + for _, s := range sli { + if s == ele { + return true + } + } + return false +} + +// Valid determines if a ProviderConfig conforms with the OIDC specification. +// If Valid returns successfully it guarantees required field are non-nil and +// URLs are well formed. +// +// Valid is called by UnmarshalJSON. +// +// NOTE(ericchiang): For development purposes Valid does not mandate 'https' for +// URLs fields where the OIDC spec requires it. This may change in future releases +// of this package. See: https://github.com/coreos/go-oidc/issues/34 +func (p ProviderConfig) Valid() error { + grantTypes := p.GrantTypesSupported + if len(grantTypes) == 0 { + grantTypes = DefaultGrantTypesSupported + } + implicitOnly := true + for _, grantType := range grantTypes { + if grantType != oauth2.GrantTypeImplicit { + implicitOnly = false + break + } + } + + if len(p.SubjectTypesSupported) == 0 { + return errors.New("missing required field subject_types_supported") + } + if len(p.IDTokenSigningAlgValues) == 0 { + return errors.New("missing required field id_token_signing_alg_values_supported") + } + + if len(p.ScopesSupported) != 0 && !contains(p.ScopesSupported, "openid") { + return errors.New("scoped_supported must be unspecified or include 'openid'") + } + + if !contains(p.IDTokenSigningAlgValues, "RS256") { + return errors.New("id_token_signing_alg_values_supported must include 'RS256'") + } + if contains(p.TokenEndpointAuthMethodsSupported, "none") { + return errors.New("token_endpoint_auth_signing_alg_values_supported cannot include 'none'") + } + + uris := []struct { + val *url.URL + name string + required bool + }{ + {p.Issuer, "issuer", true}, + {p.AuthEndpoint, "authorization_endpoint", true}, + {p.TokenEndpoint, "token_endpoint", !implicitOnly}, + {p.UserInfoEndpoint, "userinfo_endpoint", false}, + {p.KeysEndpoint, "jwks_uri", true}, + {p.RegistrationEndpoint, "registration_endpoint", false}, + {p.ServiceDocs, "service_documentation", false}, + {p.Policy, "op_policy_uri", false}, + {p.TermsOfService, "op_tos_uri", false}, + } + + for _, uri := range uris { + if uri.val == nil { + if !uri.required { + continue + } + return fmt.Errorf("empty value for required uri field %s", uri.name) + } + if uri.val.Host == "" { + return fmt.Errorf("no host for uri field %s", uri.name) + } + if uri.val.Scheme != "http" && uri.val.Scheme != "https" { + return fmt.Errorf("uri field %s schemeis not http or https", uri.name) + } + } + return nil +} + +// Supports determines if provider supports a client given their respective metadata. +func (p ProviderConfig) Supports(c ClientMetadata) error { + if err := p.Valid(); err != nil { + return fmt.Errorf("invalid provider config: %v", err) + } + if err := c.Valid(); err != nil { + return fmt.Errorf("invalid client config: %v", err) + } + + // Fill default values for omitted fields + c = c.Defaults() + p = p.Defaults() + + // Do the supported values list the requested one? + supports := []struct { + supported []string + requested string + name string + }{ + {p.IDTokenSigningAlgValues, c.IDTokenResponseOptions.SigningAlg, "id_token_signed_response_alg"}, + {p.IDTokenEncryptionAlgValues, c.IDTokenResponseOptions.EncryptionAlg, "id_token_encryption_response_alg"}, + {p.IDTokenEncryptionEncValues, c.IDTokenResponseOptions.EncryptionEnc, "id_token_encryption_response_enc"}, + {p.UserInfoSigningAlgValues, c.UserInfoResponseOptions.SigningAlg, "userinfo_signed_response_alg"}, + {p.UserInfoEncryptionAlgValues, c.UserInfoResponseOptions.EncryptionAlg, "userinfo_encryption_response_alg"}, + {p.UserInfoEncryptionEncValues, c.UserInfoResponseOptions.EncryptionEnc, "userinfo_encryption_response_enc"}, + {p.ReqObjSigningAlgValues, c.RequestObjectOptions.SigningAlg, "request_object_signing_alg"}, + {p.ReqObjEncryptionAlgValues, c.RequestObjectOptions.EncryptionAlg, "request_object_encryption_alg"}, + {p.ReqObjEncryptionEncValues, c.RequestObjectOptions.EncryptionEnc, "request_object_encryption_enc"}, + } + for _, field := range supports { + if field.requested == "" { + continue + } + if !contains(field.supported, field.requested) { + return fmt.Errorf("provider does not support requested value for field %s", field.name) + } + } + + stringsEqual := func(s1, s2 string) bool { return s1 == s2 } + + // For lists, are the list of requested values a subset of the supported ones? + supportsAll := []struct { + supported []string + requested []string + name string + // OAuth2.0 response_type can be space separated lists where order doesn't matter. + // For example "id_token token" is the same as "token id_token" + // Support a custom compare method. + comp func(s1, s2 string) bool + }{ + {p.GrantTypesSupported, c.GrantTypes, "grant_types", stringsEqual}, + {p.ResponseTypesSupported, c.ResponseTypes, "response_type", oauth2.ResponseTypesEqual}, + } + for _, field := range supportsAll { + requestLoop: + for _, req := range field.requested { + for _, sup := range field.supported { + if field.comp(req, sup) { + continue requestLoop + } + } + return fmt.Errorf("provider does not support requested value for field %s", field.name) + } + } + + // TODO(ericchiang): Are there more checks we feel comfortable with begin strict about? + + return nil } func (p ProviderConfig) SupportsGrantType(grantType string) bool { var supported []string if len(p.GrantTypesSupported) == 0 { - // If omitted, the default value is ["authorization_code", "implicit"]. - // http://openid.net/specs/openid-connect-discovery-1_0.html#ProviderMetadata - supported = []string{oauth2.GrantTypeAuthCode, oauth2.GrantTypeImplicit} + supported = DefaultGrantTypesSupported } else { supported = p.GrantTypesSupported } @@ -75,6 +484,9 @@ type ProviderConfigSyncer struct { from ProviderConfigGetter to ProviderConfigSetter clock clockwork.Clock + + initialSyncDone bool + initialSyncWait sync.WaitGroup } func NewProviderConfigSyncer(from ProviderConfigGetter, to ProviderConfigSetter) *ProviderConfigSyncer { @@ -91,6 +503,7 @@ func (s *ProviderConfigSyncer) Run() chan struct{} { var next pcsStepper next = &pcsStepNext{aft: time.Duration(0)} + s.initialSyncWait.Add(1) go func() { for { select { @@ -105,6 +518,10 @@ func (s *ProviderConfigSyncer) Run() chan struct{} { return stop } +func (s *ProviderConfigSyncer) WaitUntilInitialSync() { + s.initialSyncWait.Wait() +} + func (s *ProviderConfigSyncer) sync() (time.Duration, error) { cfg, err := s.from.Get() if err != nil { @@ -115,6 +532,11 @@ func (s *ProviderConfigSyncer) sync() (time.Duration, error) { return 0, fmt.Errorf("error setting provider config: %v", err) } + if !s.initialSyncDone { + s.initialSyncWait.Done() + s.initialSyncDone = true + } + log.Infof("Updating provider config: config=%#v", cfg) return nextSyncAfter(cfg.ExpiresAt, s.clock), nil @@ -197,7 +619,11 @@ func NewHTTPProviderConfigGetter(hc phttp.Client, issuerURL string) *httpProvide } func (r *httpProviderConfigGetter) Get() (cfg ProviderConfig, err error) { - req, err := http.NewRequest("GET", r.issuerURL+discoveryConfigPath, nil) + // If the Issuer value contains a path component, any terminating / MUST be removed before + // appending /.well-known/openid-configuration. + // https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderConfigurationRequest + discoveryURL := strings.TrimSuffix(r.issuerURL, "/") + discoveryConfigPath + req, err := http.NewRequest("GET", discoveryURL, nil) if err != nil { return } @@ -223,7 +649,7 @@ func (r *httpProviderConfigGetter) Get() (cfg ProviderConfig, err error) { // The issuer value returned MUST be identical to the Issuer URL that was directly used to retrieve the configuration information. // http://openid.net/specs/openid-connect-discovery-1_0.html#ProviderConfigurationValidation - if !urlEqual(cfg.Issuer, r.issuerURL) { + if !urlEqual(cfg.Issuer.String(), r.issuerURL) { err = fmt.Errorf(`"issuer" in config (%v) does not match provided issuer URL (%v)`, cfg.Issuer, r.issuerURL) return } diff --git a/vendor/github.com/coreos/go-oidc/oidc/transport.go b/vendor/github.com/coreos/go-oidc/oidc/transport.go index 93ff9e1f57..61c926d7fe 100644 --- a/vendor/github.com/coreos/go-oidc/oidc/transport.go +++ b/vendor/github.com/coreos/go-oidc/oidc/transport.go @@ -67,6 +67,15 @@ func (t *AuthenticatedTransport) verifiedJWT() (jose.JWT, error) { return t.jwt, nil } +// SetJWT sets the JWT held by the Transport. +// This is useful for cases in which you want to set an initial JWT. +func (t *AuthenticatedTransport) SetJWT(jwt jose.JWT) { + t.mu.Lock() + defer t.mu.Unlock() + + t.jwt = jwt +} + func (t *AuthenticatedTransport) RoundTrip(r *http.Request) (*http.Response, error) { jwt, err := t.verifiedJWT() if err != nil { diff --git a/vendor/github.com/coreos/go-oidc/oidc/util.go b/vendor/github.com/coreos/go-oidc/oidc/util.go index 843f9ec081..f2a5a195e4 100644 --- a/vendor/github.com/coreos/go-oidc/oidc/util.go +++ b/vendor/github.com/coreos/go-oidc/oidc/util.go @@ -59,8 +59,8 @@ func NewClaims(iss, sub string, aud interface{}, iat, exp time.Time) jose.Claims "iss": iss, "sub": sub, "aud": aud, - "iat": float64(iat.Unix()), - "exp": float64(exp.Unix()), + "iat": iat.Unix(), + "exp": exp.Unix(), } } diff --git a/vendor/github.com/robfig/cron/.gitignore b/vendor/github.com/robfig/cron/.gitignore new file mode 100644 index 0000000000..00268614f0 --- /dev/null +++ b/vendor/github.com/robfig/cron/.gitignore @@ -0,0 +1,22 @@ +# Compiled Object files, Static and Dynamic libs (Shared Objects) +*.o +*.a +*.so + +# Folders +_obj +_test + +# Architecture specific extensions/prefixes +*.[568vq] +[568vq].out + +*.cgo1.go +*.cgo2.c +_cgo_defun.c +_cgo_gotypes.go +_cgo_export.* + +_testmain.go + +*.exe diff --git a/vendor/github.com/robfig/cron/.travis.yml b/vendor/github.com/robfig/cron/.travis.yml new file mode 100644 index 0000000000..4f2ee4d973 --- /dev/null +++ b/vendor/github.com/robfig/cron/.travis.yml @@ -0,0 +1 @@ +language: go diff --git a/vendor/github.com/robfig/cron/LICENSE b/vendor/github.com/robfig/cron/LICENSE new file mode 100644 index 0000000000..3a0f627ffe --- /dev/null +++ b/vendor/github.com/robfig/cron/LICENSE @@ -0,0 +1,21 @@ +Copyright (C) 2012 Rob Figueiredo +All Rights Reserved. + +MIT LICENSE + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/github.com/robfig/cron/README.md b/vendor/github.com/robfig/cron/README.md new file mode 100644 index 0000000000..157ed082d4 --- /dev/null +++ b/vendor/github.com/robfig/cron/README.md @@ -0,0 +1,2 @@ +[![GoDoc](http://godoc.org/github.com/robfig/cron?status.png)](http://godoc.org/github.com/robfig/cron) +[![Build Status](https://travis-ci.org/robfig/cron.svg?branch=master)](https://travis-ci.org/robfig/cron) diff --git a/vendor/github.com/robfig/cron/constantdelay.go b/vendor/github.com/robfig/cron/constantdelay.go new file mode 100644 index 0000000000..cd6e7b1be9 --- /dev/null +++ b/vendor/github.com/robfig/cron/constantdelay.go @@ -0,0 +1,27 @@ +package cron + +import "time" + +// ConstantDelaySchedule represents a simple recurring duty cycle, e.g. "Every 5 minutes". +// It does not support jobs more frequent than once a second. +type ConstantDelaySchedule struct { + Delay time.Duration +} + +// Every returns a crontab Schedule that activates once every duration. +// Delays of less than a second are not supported (will round up to 1 second). +// Any fields less than a Second are truncated. +func Every(duration time.Duration) ConstantDelaySchedule { + if duration < time.Second { + duration = time.Second + } + return ConstantDelaySchedule{ + Delay: duration - time.Duration(duration.Nanoseconds())%time.Second, + } +} + +// Next returns the next time this should be run. +// This rounds so that the next activation time will be on the second. +func (schedule ConstantDelaySchedule) Next(t time.Time) time.Time { + return t.Add(schedule.Delay - time.Duration(t.Nanosecond())*time.Nanosecond) +} diff --git a/vendor/github.com/robfig/cron/cron.go b/vendor/github.com/robfig/cron/cron.go new file mode 100644 index 0000000000..9c1e6c31a5 --- /dev/null +++ b/vendor/github.com/robfig/cron/cron.go @@ -0,0 +1,227 @@ +// This library implements a cron spec parser and runner. See the README for +// more details. +package cron + +import ( + "log" + "runtime" + "sort" + "time" +) + +// Cron keeps track of any number of entries, invoking the associated func as +// specified by the schedule. It may be started, stopped, and the entries may +// be inspected while running. +type Cron struct { + entries []*Entry + stop chan struct{} + add chan *Entry + snapshot chan []*Entry + running bool + ErrorLog *log.Logger +} + +// Job is an interface for submitted cron jobs. +type Job interface { + Run() +} + +// The Schedule describes a job's duty cycle. +type Schedule interface { + // Return the next activation time, later than the given time. + // Next is invoked initially, and then each time the job is run. + Next(time.Time) time.Time +} + +// Entry consists of a schedule and the func to execute on that schedule. +type Entry struct { + // The schedule on which this job should be run. + Schedule Schedule + + // The next time the job will run. This is the zero time if Cron has not been + // started or this entry's schedule is unsatisfiable + Next time.Time + + // The last time this job was run. This is the zero time if the job has never + // been run. + Prev time.Time + + // The Job to run. + Job Job +} + +// byTime is a wrapper for sorting the entry array by time +// (with zero time at the end). +type byTime []*Entry + +func (s byTime) Len() int { return len(s) } +func (s byTime) Swap(i, j int) { s[i], s[j] = s[j], s[i] } +func (s byTime) Less(i, j int) bool { + // Two zero times should return false. + // Otherwise, zero is "greater" than any other time. + // (To sort it at the end of the list.) + if s[i].Next.IsZero() { + return false + } + if s[j].Next.IsZero() { + return true + } + return s[i].Next.Before(s[j].Next) +} + +// New returns a new Cron job runner. +func New() *Cron { + return &Cron{ + entries: nil, + add: make(chan *Entry), + stop: make(chan struct{}), + snapshot: make(chan []*Entry), + running: false, + ErrorLog: nil, + } +} + +// A wrapper that turns a func() into a cron.Job +type FuncJob func() + +func (f FuncJob) Run() { f() } + +// AddFunc adds a func to the Cron to be run on the given schedule. +func (c *Cron) AddFunc(spec string, cmd func()) error { + return c.AddJob(spec, FuncJob(cmd)) +} + +// AddJob adds a Job to the Cron to be run on the given schedule. +func (c *Cron) AddJob(spec string, cmd Job) error { + schedule, err := Parse(spec) + if err != nil { + return err + } + c.Schedule(schedule, cmd) + return nil +} + +// Schedule adds a Job to the Cron to be run on the given schedule. +func (c *Cron) Schedule(schedule Schedule, cmd Job) { + entry := &Entry{ + Schedule: schedule, + Job: cmd, + } + if !c.running { + c.entries = append(c.entries, entry) + return + } + + c.add <- entry +} + +// Entries returns a snapshot of the cron entries. +func (c *Cron) Entries() []*Entry { + if c.running { + c.snapshot <- nil + x := <-c.snapshot + return x + } + return c.entrySnapshot() +} + +// Start the cron scheduler in its own go-routine. +func (c *Cron) Start() { + c.running = true + go c.run() +} + +func (c *Cron) runWithRecovery(j Job) { + defer func() { + if r := recover(); r != nil { + const size = 64 << 10 + buf := make([]byte, size) + buf = buf[:runtime.Stack(buf, false)] + c.logf("cron: panic running job: %v\n%s", r, buf) + } + }() + j.Run() +} + +// Run the scheduler.. this is private just due to the need to synchronize +// access to the 'running' state variable. +func (c *Cron) run() { + // Figure out the next activation times for each entry. + now := time.Now().Local() + for _, entry := range c.entries { + entry.Next = entry.Schedule.Next(now) + } + + for { + // Determine the next entry to run. + sort.Sort(byTime(c.entries)) + + var effective time.Time + if len(c.entries) == 0 || c.entries[0].Next.IsZero() { + // If there are no entries yet, just sleep - it still handles new entries + // and stop requests. + effective = now.AddDate(10, 0, 0) + } else { + effective = c.entries[0].Next + } + + select { + case now = <-time.After(effective.Sub(now)): + // Run every entry whose next time was this effective time. + for _, e := range c.entries { + if e.Next != effective { + break + } + go c.runWithRecovery(e.Job) + e.Prev = e.Next + e.Next = e.Schedule.Next(effective) + } + continue + + case newEntry := <-c.add: + c.entries = append(c.entries, newEntry) + newEntry.Next = newEntry.Schedule.Next(time.Now().Local()) + + case <-c.snapshot: + c.snapshot <- c.entrySnapshot() + + case <-c.stop: + return + } + + // 'now' should be updated after newEntry and snapshot cases. + now = time.Now().Local() + } +} + +// Logs an error to stderr or to the configured error log +func (c *Cron) logf(format string, args ...interface{}) { + if c.ErrorLog != nil { + c.ErrorLog.Printf(format, args...) + } else { + log.Printf(format, args...) + } +} + +// Stop stops the cron scheduler if it is running; otherwise it does nothing. +func (c *Cron) Stop() { + if !c.running { + return + } + c.stop <- struct{}{} + c.running = false +} + +// entrySnapshot returns a copy of the current cron entry list. +func (c *Cron) entrySnapshot() []*Entry { + entries := []*Entry{} + for _, e := range c.entries { + entries = append(entries, &Entry{ + Schedule: e.Schedule, + Next: e.Next, + Prev: e.Prev, + Job: e.Job, + }) + } + return entries +} diff --git a/vendor/github.com/robfig/cron/doc.go b/vendor/github.com/robfig/cron/doc.go new file mode 100644 index 0000000000..dbdf50127a --- /dev/null +++ b/vendor/github.com/robfig/cron/doc.go @@ -0,0 +1,129 @@ +/* +Package cron implements a cron spec parser and job runner. + +Usage + +Callers may register Funcs to be invoked on a given schedule. Cron will run +them in their own goroutines. + + c := cron.New() + c.AddFunc("0 30 * * * *", func() { fmt.Println("Every hour on the half hour") }) + c.AddFunc("@hourly", func() { fmt.Println("Every hour") }) + c.AddFunc("@every 1h30m", func() { fmt.Println("Every hour thirty") }) + c.Start() + .. + // Funcs are invoked in their own goroutine, asynchronously. + ... + // Funcs may also be added to a running Cron + c.AddFunc("@daily", func() { fmt.Println("Every day") }) + .. + // Inspect the cron job entries' next and previous run times. + inspect(c.Entries()) + .. + c.Stop() // Stop the scheduler (does not stop any jobs already running). + +CRON Expression Format + +A cron expression represents a set of times, using 6 space-separated fields. + + Field name | Mandatory? | Allowed values | Allowed special characters + ---------- | ---------- | -------------- | -------------------------- + Seconds | Yes | 0-59 | * / , - + Minutes | Yes | 0-59 | * / , - + Hours | Yes | 0-23 | * / , - + Day of month | Yes | 1-31 | * / , - ? + Month | Yes | 1-12 or JAN-DEC | * / , - + Day of week | Yes | 0-6 or SUN-SAT | * / , - ? + +Note: Month and Day-of-week field values are case insensitive. "SUN", "Sun", +and "sun" are equally accepted. + +Special Characters + +Asterisk ( * ) + +The asterisk indicates that the cron expression will match for all values of the +field; e.g., using an asterisk in the 5th field (month) would indicate every +month. + +Slash ( / ) + +Slashes are used to describe increments of ranges. For example 3-59/15 in the +1st field (minutes) would indicate the 3rd minute of the hour and every 15 +minutes thereafter. The form "*\/..." is equivalent to the form "first-last/...", +that is, an increment over the largest possible range of the field. The form +"N/..." is accepted as meaning "N-MAX/...", that is, starting at N, use the +increment until the end of that specific range. It does not wrap around. + +Comma ( , ) + +Commas are used to separate items of a list. For example, using "MON,WED,FRI" in +the 5th field (day of week) would mean Mondays, Wednesdays and Fridays. + +Hyphen ( - ) + +Hyphens are used to define ranges. For example, 9-17 would indicate every +hour between 9am and 5pm inclusive. + +Question mark ( ? ) + +Question mark may be used instead of '*' for leaving either day-of-month or +day-of-week blank. + +Predefined schedules + +You may use one of several pre-defined schedules in place of a cron expression. + + Entry | Description | Equivalent To + ----- | ----------- | ------------- + @yearly (or @annually) | Run once a year, midnight, Jan. 1st | 0 0 0 1 1 * + @monthly | Run once a month, midnight, first of month | 0 0 0 1 * * + @weekly | Run once a week, midnight on Sunday | 0 0 0 * * 0 + @daily (or @midnight) | Run once a day, midnight | 0 0 0 * * * + @hourly | Run once an hour, beginning of hour | 0 0 * * * * + +Intervals + +You may also schedule a job to execute at fixed intervals. This is supported by +formatting the cron spec like this: + + @every + +where "duration" is a string accepted by time.ParseDuration +(http://golang.org/pkg/time/#ParseDuration). + +For example, "@every 1h30m10s" would indicate a schedule that activates every +1 hour, 30 minutes, 10 seconds. + +Note: The interval does not take the job runtime into account. For example, +if a job takes 3 minutes to run, and it is scheduled to run every 5 minutes, +it will have only 2 minutes of idle time between each run. + +Time zones + +All interpretation and scheduling is done in the machine's local time zone (as +provided by the Go time package (http://www.golang.org/pkg/time). + +Be aware that jobs scheduled during daylight-savings leap-ahead transitions will +not be run! + +Thread safety + +Since the Cron service runs concurrently with the calling code, some amount of +care must be taken to ensure proper synchronization. + +All cron methods are designed to be correctly synchronized as long as the caller +ensures that invocations have a clear happens-before ordering between them. + +Implementation + +Cron entries are stored in an array, sorted by their next activation time. Cron +sleeps until the next job is due to be run. + +Upon waking: + - it runs each entry that is active on that second + - it calculates the next run times for the jobs that were run + - it re-sorts the array of entries by next activation time. + - it goes to sleep until the soonest job. +*/ +package cron diff --git a/vendor/github.com/robfig/cron/parser.go b/vendor/github.com/robfig/cron/parser.go new file mode 100644 index 0000000000..4224fa9308 --- /dev/null +++ b/vendor/github.com/robfig/cron/parser.go @@ -0,0 +1,231 @@ +package cron + +import ( + "fmt" + "log" + "math" + "strconv" + "strings" + "time" +) + +// Parse returns a new crontab schedule representing the given spec. +// It returns a descriptive error if the spec is not valid. +// +// It accepts +// - Full crontab specs, e.g. "* * * * * ?" +// - Descriptors, e.g. "@midnight", "@every 1h30m" +func Parse(spec string) (_ Schedule, err error) { + // Convert panics into errors + defer func() { + if recovered := recover(); recovered != nil { + err = fmt.Errorf("%v", recovered) + } + }() + + if spec[0] == '@' { + return parseDescriptor(spec), nil + } + + // Split on whitespace. We require 5 or 6 fields. + // (second) (minute) (hour) (day of month) (month) (day of week, optional) + fields := strings.Fields(spec) + if len(fields) != 5 && len(fields) != 6 { + log.Panicf("Expected 5 or 6 fields, found %d: %s", len(fields), spec) + } + + // If a sixth field is not provided (DayOfWeek), then it is equivalent to star. + if len(fields) == 5 { + fields = append(fields, "*") + } + + schedule := &SpecSchedule{ + Second: getField(fields[0], seconds), + Minute: getField(fields[1], minutes), + Hour: getField(fields[2], hours), + Dom: getField(fields[3], dom), + Month: getField(fields[4], months), + Dow: getField(fields[5], dow), + } + + return schedule, nil +} + +// getField returns an Int with the bits set representing all of the times that +// the field represents. A "field" is a comma-separated list of "ranges". +func getField(field string, r bounds) uint64 { + // list = range {"," range} + var bits uint64 + ranges := strings.FieldsFunc(field, func(r rune) bool { return r == ',' }) + for _, expr := range ranges { + bits |= getRange(expr, r) + } + return bits +} + +// getRange returns the bits indicated by the given expression: +// number | number "-" number [ "/" number ] +func getRange(expr string, r bounds) uint64 { + + var ( + start, end, step uint + rangeAndStep = strings.Split(expr, "/") + lowAndHigh = strings.Split(rangeAndStep[0], "-") + singleDigit = len(lowAndHigh) == 1 + ) + + var extra_star uint64 + if lowAndHigh[0] == "*" || lowAndHigh[0] == "?" { + start = r.min + end = r.max + extra_star = starBit + } else { + start = parseIntOrName(lowAndHigh[0], r.names) + switch len(lowAndHigh) { + case 1: + end = start + case 2: + end = parseIntOrName(lowAndHigh[1], r.names) + default: + log.Panicf("Too many hyphens: %s", expr) + } + } + + switch len(rangeAndStep) { + case 1: + step = 1 + case 2: + step = mustParseInt(rangeAndStep[1]) + + // Special handling: "N/step" means "N-max/step". + if singleDigit { + end = r.max + } + default: + log.Panicf("Too many slashes: %s", expr) + } + + if start < r.min { + log.Panicf("Beginning of range (%d) below minimum (%d): %s", start, r.min, expr) + } + if end > r.max { + log.Panicf("End of range (%d) above maximum (%d): %s", end, r.max, expr) + } + if start > end { + log.Panicf("Beginning of range (%d) beyond end of range (%d): %s", start, end, expr) + } + + return getBits(start, end, step) | extra_star +} + +// parseIntOrName returns the (possibly-named) integer contained in expr. +func parseIntOrName(expr string, names map[string]uint) uint { + if names != nil { + if namedInt, ok := names[strings.ToLower(expr)]; ok { + return namedInt + } + } + return mustParseInt(expr) +} + +// mustParseInt parses the given expression as an int or panics. +func mustParseInt(expr string) uint { + num, err := strconv.Atoi(expr) + if err != nil { + log.Panicf("Failed to parse int from %s: %s", expr, err) + } + if num < 0 { + log.Panicf("Negative number (%d) not allowed: %s", num, expr) + } + + return uint(num) +} + +// getBits sets all bits in the range [min, max], modulo the given step size. +func getBits(min, max, step uint) uint64 { + var bits uint64 + + // If step is 1, use shifts. + if step == 1 { + return ^(math.MaxUint64 << (max + 1)) & (math.MaxUint64 << min) + } + + // Else, use a simple loop. + for i := min; i <= max; i += step { + bits |= 1 << i + } + return bits +} + +// all returns all bits within the given bounds. (plus the star bit) +func all(r bounds) uint64 { + return getBits(r.min, r.max, 1) | starBit +} + +// parseDescriptor returns a pre-defined schedule for the expression, or panics +// if none matches. +func parseDescriptor(spec string) Schedule { + switch spec { + case "@yearly", "@annually": + return &SpecSchedule{ + Second: 1 << seconds.min, + Minute: 1 << minutes.min, + Hour: 1 << hours.min, + Dom: 1 << dom.min, + Month: 1 << months.min, + Dow: all(dow), + } + + case "@monthly": + return &SpecSchedule{ + Second: 1 << seconds.min, + Minute: 1 << minutes.min, + Hour: 1 << hours.min, + Dom: 1 << dom.min, + Month: all(months), + Dow: all(dow), + } + + case "@weekly": + return &SpecSchedule{ + Second: 1 << seconds.min, + Minute: 1 << minutes.min, + Hour: 1 << hours.min, + Dom: all(dom), + Month: all(months), + Dow: 1 << dow.min, + } + + case "@daily", "@midnight": + return &SpecSchedule{ + Second: 1 << seconds.min, + Minute: 1 << minutes.min, + Hour: 1 << hours.min, + Dom: all(dom), + Month: all(months), + Dow: all(dow), + } + + case "@hourly": + return &SpecSchedule{ + Second: 1 << seconds.min, + Minute: 1 << minutes.min, + Hour: all(hours), + Dom: all(dom), + Month: all(months), + Dow: all(dow), + } + } + + const every = "@every " + if strings.HasPrefix(spec, every) { + duration, err := time.ParseDuration(spec[len(every):]) + if err != nil { + log.Panicf("Failed to parse duration %s: %s", spec, err) + } + return Every(duration) + } + + log.Panicf("Unrecognized descriptor: %s", spec) + return nil +} diff --git a/vendor/github.com/robfig/cron/spec.go b/vendor/github.com/robfig/cron/spec.go new file mode 100644 index 0000000000..afa5ac86cc --- /dev/null +++ b/vendor/github.com/robfig/cron/spec.go @@ -0,0 +1,159 @@ +package cron + +import "time" + +// SpecSchedule specifies a duty cycle (to the second granularity), based on a +// traditional crontab specification. It is computed initially and stored as bit sets. +type SpecSchedule struct { + Second, Minute, Hour, Dom, Month, Dow uint64 +} + +// bounds provides a range of acceptable values (plus a map of name to value). +type bounds struct { + min, max uint + names map[string]uint +} + +// The bounds for each field. +var ( + seconds = bounds{0, 59, nil} + minutes = bounds{0, 59, nil} + hours = bounds{0, 23, nil} + dom = bounds{1, 31, nil} + months = bounds{1, 12, map[string]uint{ + "jan": 1, + "feb": 2, + "mar": 3, + "apr": 4, + "may": 5, + "jun": 6, + "jul": 7, + "aug": 8, + "sep": 9, + "oct": 10, + "nov": 11, + "dec": 12, + }} + dow = bounds{0, 6, map[string]uint{ + "sun": 0, + "mon": 1, + "tue": 2, + "wed": 3, + "thu": 4, + "fri": 5, + "sat": 6, + }} +) + +const ( + // Set the top bit if a star was included in the expression. + starBit = 1 << 63 +) + +// Next returns the next time this schedule is activated, greater than the given +// time. If no time can be found to satisfy the schedule, return the zero time. +func (s *SpecSchedule) Next(t time.Time) time.Time { + // General approach: + // For Month, Day, Hour, Minute, Second: + // Check if the time value matches. If yes, continue to the next field. + // If the field doesn't match the schedule, then increment the field until it matches. + // While incrementing the field, a wrap-around brings it back to the beginning + // of the field list (since it is necessary to re-verify previous field + // values) + + // Start at the earliest possible time (the upcoming second). + t = t.Add(1*time.Second - time.Duration(t.Nanosecond())*time.Nanosecond) + + // This flag indicates whether a field has been incremented. + added := false + + // If no time is found within five years, return zero. + yearLimit := t.Year() + 5 + +WRAP: + if t.Year() > yearLimit { + return time.Time{} + } + + // Find the first applicable month. + // If it's this month, then do nothing. + for 1< 0 + dowMatch bool = 1< 0 + ) + + if s.Dom&starBit > 0 || s.Dow&starBit > 0 { + return domMatch && dowMatch + } + return domMatch || dowMatch +} diff --git a/vendor/github.com/vmware/govmomi/.drone.sec b/vendor/github.com/vmware/govmomi/.drone.sec index f8b8c9a77e..ad52e59ac8 100644 --- a/vendor/github.com/vmware/govmomi/.drone.sec +++ b/vendor/github.com/vmware/govmomi/.drone.sec @@ -1 +1 @@ -eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkExMjhHQ00ifQ.FP7BTRxaTbVILW2DBSeJu63eb2Ppa3-gxe5Ja6B5y9iijsqJWkg9k_4iGnojcfgIXz0GVL7XPqdGOFrzQAJWYn0US53t3OINyjwm0J4O0UFHoyLXjwCscfQ3MU_Ha-nVpoWoBll8Omyv4tXykWs2_lCt9LT6h8u7DlYaz2cFns6JFcawRPe-cbN_yuDM7P24wSHNwPGk_Ls1MvR4phmrwCsIhV7e82Be8bVRMU4btbxv1JSqUgGr6vur8JKqM4n0_yKOtBPswcH4_jyzmQABjaKAUfpuznOsfO42t9RyeV7L6IZfFIqgpZMh00DOl3a2I_YdDpydZT1laCGd1_Sn8Q.pCgShcjPktT8Bx48.pbMl3UhYFCe9iVvTCLrxsoOFziShsKSAIzMc4ZphUFb91BvUFATSGOnEYcfFRdCl3Dd5sFzvFcbIiPvDn5klhk-HZMMSHxPbPGutBsSFoPb4WwRPSz9FxybQkXB1DLFpgMGAMfGyjnt1k5420KDyuogwTNUvMOg_vxnH_P7b.zGHv8arI8aMdXX6wyo51RQ \ No newline at end of file +eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkExMjhHQ00ifQ.kK6pryC8R-O1R0Gj9ydLvQuIZlcYLGze23WdW7xbpiEEKdz6nweJrMm7ysy8lgu1tM47JVo19p2_b26bNKSQshCUOETvd7Hb2UMZOjnyUnqdyAAyoi6UkIquXfUUbHTNS0iMxwSxxW9KMp2GXNq8-o6T8xQZTDirBJFKKd8ZNUasTaoa5j8U9IfdR1aCavTBuOhvk8IVs-jSbY5TVJMJiE0IOPXois7aRJ6uAiANQBk9VKLegEcZD_qAewecXHDsHi-u0jbmg3o3PPaJaK_Qv5dsPlR2M-E2kE3AGUn0-zn5zYRngoAZ8WZr2O4GvLdltJKq9i2z7jOrdOzzRcDRow.96qvwl_E1Hj15u7Q.hWs-jQ8FsqQFD7pE9N-UEP1BWQ9rsJIcCaPvQRIp8Fukm_vvlw9YEaEq0ERLrsUWsJWpd1ca8_h8x7xD6f_d5YppwRqRHIeGIsdBOTMhNs0lG8ikkQXLat-UroCpy8EC17nuUtDE2E2Kdxrk4Cdd6Bk-dKk0Ta4w3Ud0YBKa.P8zrO7xizgv0i98eVWWzEg \ No newline at end of file diff --git a/vendor/github.com/vmware/govmomi/.drone.yml b/vendor/github.com/vmware/govmomi/.drone.yml index 9a0280d85b..c1febba3ca 100644 --- a/vendor/github.com/vmware/govmomi/.drone.yml +++ b/vendor/github.com/vmware/govmomi/.drone.yml @@ -9,15 +9,9 @@ build: - GOVC_INSECURE=1 - VCA=1 commands: - - go get golang.org/x/tools/cmd/vet - - go get golang.org/x/tools/cmd/goimports - - go get github.com/davecgh/go-spew/spew - - go get - - make all - - make install + - make all install - git clone https://github.com/sstephenson/bats.git /tmp/bats - /tmp/bats/install.sh /usr/local - apt-get -qq update && apt-get install -yqq uuid-runtime bsdmainutils jq - govc/test/images/update.sh - bats govc/test - - govc/test/clean.sh diff --git a/vendor/github.com/vmware/govmomi/.gitignore b/vendor/github.com/vmware/govmomi/.gitignore new file mode 100644 index 0000000000..769c244007 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/.gitignore @@ -0,0 +1 @@ +secrets.yml diff --git a/vendor/github.com/vmware/govmomi/.travis.yml b/vendor/github.com/vmware/govmomi/.travis.yml index 7b73bab265..3c12d87776 100644 --- a/vendor/github.com/vmware/govmomi/.travis.yml +++ b/vendor/github.com/vmware/govmomi/.travis.yml @@ -1,11 +1,12 @@ sudo: false + language: go -go: 1.4 + +go: + - 1.6 before_install: - - go get golang.org/x/tools/cmd/vet - - go get golang.org/x/tools/cmd/goimports - - go get github.com/davecgh/go-spew/spew + - make vendor script: - make check test diff --git a/vendor/github.com/vmware/govmomi/CHANGELOG.md b/vendor/github.com/vmware/govmomi/CHANGELOG.md index b7255c6d92..c695d4a1a1 100644 --- a/vendor/github.com/vmware/govmomi/CHANGELOG.md +++ b/vendor/github.com/vmware/govmomi/CHANGELOG.md @@ -1,5 +1,33 @@ # changelog +### 0.6.2 (2016-05-11) + +* Get complete file details in Datastore.Stat + +* SOAP decoding fixes + +* Add VirtualMachine.RemoveAllSnapshot + +### 0.6.1 (2016-04-30) + +* Fix mo.Entity interface + +### 0.6.0 (2016-04-29) + +* Add Common.Rename method + +* Add mo.Entity interface + +* Add OptionManager + +* Add Finder.FolderList method + +* Add VirtualMachine.WaitForNetIP method + +* Add VirtualMachine.RevertToSnapshot method + +* Add Datastore.Download method + ### 0.5.0 (2016-03-30) Generated fields using xsd type 'int' change to Go type 'int32' diff --git a/vendor/github.com/vmware/govmomi/CONTRIBUTORS b/vendor/github.com/vmware/govmomi/CONTRIBUTORS index 5468618e85..11b2194367 100644 --- a/vendor/github.com/vmware/govmomi/CONTRIBUTORS +++ b/vendor/github.com/vmware/govmomi/CONTRIBUTORS @@ -7,11 +7,13 @@ Alvaro Miranda Amit Bathla Andrew Chin Arran Walker +Austin Parker Bob Killen Bruce Downs Clint Greenwood Cédric Blomart Danny Lockard +Dave Tucker Doug MacEachern Eloy Coto Eric Yutao @@ -28,6 +30,7 @@ Mevan Samaratunga Pieter Noordhuis runner.mei S.Çağlar Onur +Sergey Ignatov Takaaki Furukawa Steve Purcell Yang Yang diff --git a/vendor/github.com/vmware/govmomi/Makefile b/vendor/github.com/vmware/govmomi/Makefile index 5a42647324..af14896340 100644 --- a/vendor/github.com/vmware/govmomi/Makefile +++ b/vendor/github.com/vmware/govmomi/Makefile @@ -4,7 +4,12 @@ all: check test check: goimports govet -goimports: +vendor: + go get golang.org/x/tools/cmd/goimports + go get github.com/davecgh/go-spew/spew + go get golang.org/x/net/context + +goimports: vendor @echo checking go imports... @! goimports -d . 2>&1 | egrep -v '^$$' @@ -12,9 +17,8 @@ govet: @echo checking go vet... @go tool vet -structtags=false -methods=false . -test: - go get +test: vendor go test -v $(TEST_OPTS) ./... -install: +install: vendor go install github.com/vmware/govmomi/govc diff --git a/vendor/github.com/vmware/govmomi/find/finder.go b/vendor/github.com/vmware/govmomi/find/finder.go index 9f3ce3c2da..3e9c3acb35 100644 --- a/vendor/github.com/vmware/govmomi/find/finder.go +++ b/vendor/github.com/vmware/govmomi/find/finder.go @@ -762,28 +762,42 @@ func (f *Finder) VirtualApp(ctx context.Context, path string) (*object.VirtualAp return apps[0], nil } -func (f *Finder) Folder(ctx context.Context, path string) (*object.Folder, error) { - mo, err := f.ManagedObjectList(ctx, path) +func (f *Finder) FolderList(ctx context.Context, path string) ([]*object.Folder, error) { + es, err := f.ManagedObjectList(ctx, path) if err != nil { return nil, err } - if len(mo) == 0 { + var folders []*object.Folder + + for _, e := range es { + switch o := e.Object.(type) { + case mo.Folder: + folder := object.NewFolder(f.client, o.Reference()) + folder.InventoryPath = e.Path + folders = append(folders, folder) + case *object.Folder: + // RootFolder + folders = append(folders, o) + } + } + + if len(folders) == 0 { return nil, &NotFoundError{"folder", path} } - if len(mo) > 1 { + return folders, nil +} + +func (f *Finder) Folder(ctx context.Context, path string) (*object.Folder, error) { + folders, err := f.FolderList(ctx, path) + if err != nil { + return nil, err + } + + if len(folders) > 1 { return nil, &MultipleFoundError{"folder", path} } - ref := mo[0].Object.Reference() - if ref.Type != "Folder" { - return nil, &NotFoundError{"folder", path} - } - - folder := object.NewFolder(f.client, ref) - - folder.InventoryPath = mo[0].Path - - return folder, nil + return folders[0], nil } diff --git a/vendor/github.com/vmware/govmomi/object/common.go b/vendor/github.com/vmware/govmomi/object/common.go index 3e641441ab..97972849f9 100644 --- a/vendor/github.com/vmware/govmomi/object/common.go +++ b/vendor/github.com/vmware/govmomi/object/common.go @@ -69,3 +69,17 @@ func (c Common) Destroy(ctx context.Context) (*Task, error) { return NewTask(c.c, res.Returnval), nil } + +func (c Common) Rename(ctx context.Context, name string) (*Task, error) { + req := types.Rename_Task{ + This: c.Reference(), + NewName: name, + } + + res, err := methods.Rename_Task(ctx, c.c, &req) + if err != nil { + return nil, err + } + + return NewTask(c.c, res.Returnval), nil +} diff --git a/vendor/github.com/vmware/govmomi/object/datastore.go b/vendor/github.com/vmware/govmomi/object/datastore.go index f59eb811c8..123dde8a83 100644 --- a/vendor/github.com/vmware/govmomi/object/datastore.go +++ b/vendor/github.com/vmware/govmomi/object/datastore.go @@ -220,7 +220,16 @@ func (d Datastore) UploadFile(ctx context.Context, file string, path string, par return d.Client().UploadFile(file, u, p) } -// DownloadFile via soap.Upload with an http service ticket +// Download via soap.Download with an http service ticket +func (d Datastore) Download(ctx context.Context, path string, param *soap.Download) (io.ReadCloser, int64, error) { + u, p, err := d.downloadTicket(ctx, path, param) + if err != nil { + return nil, 0, err + } + return d.Client().Download(u, p) +} + +// DownloadFile via soap.Download with an http service ticket func (d Datastore) DownloadFile(ctx context.Context, path string, file string, param *soap.Download) error { u, p, err := d.downloadTicket(ctx, path, param) if err != nil { @@ -305,8 +314,10 @@ func (d Datastore) Stat(ctx context.Context, file string) (types.BaseFileInfo, e spec := types.HostDatastoreBrowserSearchSpec{ Details: &types.FileQueryFlags{ - FileType: true, - FileOwner: types.NewBool(true), // TODO: omitempty is generated, but seems to be required + FileType: true, + FileSize: true, + Modification: true, + FileOwner: types.NewBool(true), }, MatchPattern: []string{path.Base(file)}, } diff --git a/vendor/github.com/vmware/govmomi/object/folder.go b/vendor/github.com/vmware/govmomi/object/folder.go index 38fddd6da4..97c793470a 100644 --- a/vendor/github.com/vmware/govmomi/object/folder.go +++ b/vendor/github.com/vmware/govmomi/object/folder.go @@ -37,7 +37,9 @@ func NewFolder(c *vim25.Client, ref types.ManagedObjectReference) *Folder { } func NewRootFolder(c *vim25.Client) *Folder { - return NewFolder(c, c.ServiceContent.RootFolder) + f := NewFolder(c, c.ServiceContent.RootFolder) + f.InventoryPath = "/" + return f } func (f Folder) Children(ctx context.Context) ([]Reference, error) { @@ -196,3 +198,17 @@ func (f Folder) CreateDVS(ctx context.Context, spec types.DVSCreateSpec) (*Task, return NewTask(f.c, res.Returnval), nil } + +func (f Folder) MoveInto(ctx context.Context, list []types.ManagedObjectReference) (*Task, error) { + req := types.MoveIntoFolder_Task{ + This: f.Reference(), + List: list, + } + + res, err := methods.MoveIntoFolder_Task(ctx, f.c, &req) + if err != nil { + return nil, err + } + + return NewTask(f.c, res.Returnval), nil +} diff --git a/vendor/github.com/vmware/govmomi/object/host_account_manager.go b/vendor/github.com/vmware/govmomi/object/host_account_manager.go new file mode 100644 index 0000000000..9505f508c4 --- /dev/null +++ b/vendor/github.com/vmware/govmomi/object/host_account_manager.go @@ -0,0 +1,64 @@ +/* +Copyright (c) 2016 VMware, Inc. All Rights Reserved. + +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 object + +import ( + "github.com/vmware/govmomi/vim25" + "github.com/vmware/govmomi/vim25/methods" + "github.com/vmware/govmomi/vim25/types" + "golang.org/x/net/context" +) + +type HostAccountManager struct { + Common +} + +func NewHostAccountManager(c *vim25.Client, ref types.ManagedObjectReference) *HostAccountManager { + return &HostAccountManager{ + Common: NewCommon(c, ref), + } +} + +func (m HostAccountManager) Create(ctx context.Context, user *types.HostAccountSpec) error { + req := types.CreateUser{ + This: m.Reference(), + User: user, + } + + _, err := methods.CreateUser(ctx, m.Client(), &req) + return err +} + +func (m HostAccountManager) Update(ctx context.Context, user *types.HostAccountSpec) error { + req := types.UpdateUser{ + This: m.Reference(), + User: user, + } + + _, err := methods.UpdateUser(ctx, m.Client(), &req) + return err +} + +func (m HostAccountManager) Remove(ctx context.Context, userName string) error { + req := types.RemoveUser{ + This: m.Reference(), + UserName: userName, + } + + _, err := methods.RemoveUser(ctx, m.Client(), &req) + return err +} diff --git a/vendor/github.com/vmware/govmomi/object/host_config_manager.go b/vendor/github.com/vmware/govmomi/object/host_config_manager.go index 6d906e8c52..12327ee0f0 100644 --- a/vendor/github.com/vmware/govmomi/object/host_config_manager.go +++ b/vendor/github.com/vmware/govmomi/object/host_config_manager.go @@ -98,3 +98,25 @@ func (m HostConfigManager) VsanSystem(ctx context.Context) (*HostVsanSystem, err return NewHostVsanSystem(m.c, *h.ConfigManager.VsanSystem), nil } + +func (m HostConfigManager) AccountManager(ctx context.Context) (*HostAccountManager, error) { + var h mo.HostSystem + + err := m.Properties(ctx, m.Reference(), []string{"configManager.accountManager"}, &h) + if err != nil { + return nil, err + } + + return NewHostAccountManager(m.c, *h.ConfigManager.AccountManager), nil +} + +func (m HostConfigManager) OptionManager(ctx context.Context) (*OptionManager, error) { + var h mo.HostSystem + + err := m.Properties(ctx, m.Reference(), []string{"configManager.advancedOption"}, &h) + if err != nil { + return nil, err + } + + return NewOptionManager(m.c, *h.ConfigManager.AdvancedOption), nil +} diff --git a/vendor/github.com/vmware/govmomi/object/option_manager.go b/vendor/github.com/vmware/govmomi/object/option_manager.go new file mode 100644 index 0000000000..eae1223ccc --- /dev/null +++ b/vendor/github.com/vmware/govmomi/object/option_manager.go @@ -0,0 +1,58 @@ +/* +Copyright (c) 2016 VMware, Inc. All Rights Reserved. + +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 object + +import ( + "github.com/vmware/govmomi/vim25" + "github.com/vmware/govmomi/vim25/methods" + "github.com/vmware/govmomi/vim25/types" + "golang.org/x/net/context" +) + +type OptionManager struct { + Common +} + +func NewOptionManager(c *vim25.Client, ref types.ManagedObjectReference) *OptionManager { + return &OptionManager{ + Common: NewCommon(c, ref), + } +} + +func (m OptionManager) Query(ctx context.Context, name string) ([]types.BaseOptionValue, error) { + req := types.QueryOptions{ + This: m.Reference(), + Name: name, + } + + res, err := methods.QueryOptions(ctx, m.Client(), &req) + if err != nil { + return nil, err + } + + return res.Returnval, nil +} + +func (m OptionManager) Update(ctx context.Context, value []types.BaseOptionValue) error { + req := types.UpdateOptions{ + This: m.Reference(), + ChangedValue: value, + } + + _, err := methods.UpdateOptions(ctx, m.Client(), &req) + return err +} diff --git a/vendor/github.com/vmware/govmomi/object/virtual_device_list.go b/vendor/github.com/vmware/govmomi/object/virtual_device_list.go index 91e0ca1206..327b5d27ab 100644 --- a/vendor/github.com/vmware/govmomi/object/virtual_device_list.go +++ b/vendor/github.com/vmware/govmomi/object/virtual_device_list.go @@ -63,7 +63,6 @@ func EthernetCardTypes() VirtualDeviceList { &types.VirtualVmxnet3{}, }).Select(func(device types.BaseVirtualDevice) bool { c := device.(types.BaseVirtualEthernetCard).GetVirtualEthernetCard() - c.AddressType = string(types.VirtualEthernetCardMacTypeGenerated) c.GetVirtualDevice().Key = -1 return true }) diff --git a/vendor/github.com/vmware/govmomi/object/virtual_machine.go b/vendor/github.com/vmware/govmomi/object/virtual_machine.go index 701b27e4a4..4faeae75e3 100644 --- a/vendor/github.com/vmware/govmomi/object/virtual_machine.go +++ b/vendor/github.com/vmware/govmomi/object/virtual_machine.go @@ -19,6 +19,7 @@ package object import ( "errors" "fmt" + "net" "github.com/vmware/govmomi/property" "github.com/vmware/govmomi/vim25" @@ -245,6 +246,77 @@ func (v VirtualMachine) WaitForIP(ctx context.Context) (string, error) { return ip, nil } +// WaitForNetIP waits for the VM guest.net property to report an IP address for all VM NICs. +// Only consider IPv4 addresses if the v4 param is true. +// Returns a map with MAC address as the key and IP address list as the value. +func (v VirtualMachine) WaitForNetIP(ctx context.Context, v4 bool) (map[string][]string, error) { + macs := make(map[string][]string) + + p := property.DefaultCollector(v.c) + + // Wait for all NICs to have a MacAddress, which may not be generated yet. + err := property.Wait(ctx, p, v.Reference(), []string{"config.hardware.device"}, func(pc []types.PropertyChange) bool { + for _, c := range pc { + if c.Op != types.PropertyChangeOpAssign { + continue + } + + devices := c.Val.(types.ArrayOfVirtualDevice).VirtualDevice + for _, device := range devices { + if nic, ok := device.(types.BaseVirtualEthernetCard); ok { + mac := nic.GetVirtualEthernetCard().MacAddress + if mac == "" { + return false + } + macs[mac] = nil + } + } + } + + return true + }) + + err = property.Wait(ctx, p, v.Reference(), []string{"guest.net"}, func(pc []types.PropertyChange) bool { + for _, c := range pc { + if c.Op != types.PropertyChangeOpAssign { + continue + } + + nics := c.Val.(types.ArrayOfGuestNicInfo).GuestNicInfo + for _, nic := range nics { + mac := nic.MacAddress + if mac == "" || nic.IpConfig == nil { + continue + } + + for _, ip := range nic.IpConfig.IpAddress { + if _, ok := macs[mac]; !ok { + continue // Ignore any that don't correspond to a VM device + } + if v4 && net.ParseIP(ip.IpAddress).To4() == nil { + continue // Ignore non IPv4 address + } + macs[mac] = append(macs[mac], ip.IpAddress) + } + } + } + + for _, ips := range macs { + if len(ips) == 0 { + return false + } + } + + return true + }) + + if err != nil { + return nil, err + } + + return macs, nil +} + // Device returns the VirtualMachine's config.hardware.device property. func (v VirtualMachine) Device(ctx context.Context) (VirtualDeviceList, error) { var o mo.VirtualMachine @@ -336,8 +408,12 @@ func (v VirtualMachine) EditDevice(ctx context.Context, device ...types.BaseVirt } // RemoveDevice removes the given devices on the VirtualMachine -func (v VirtualMachine) RemoveDevice(ctx context.Context, device ...types.BaseVirtualDevice) error { - return v.configureDevice(ctx, types.VirtualDeviceConfigSpecOperationRemove, types.VirtualDeviceConfigSpecFileOperationDestroy, device...) +func (v VirtualMachine) RemoveDevice(ctx context.Context, keepFiles bool, device ...types.BaseVirtualDevice) error { + fop := types.VirtualDeviceConfigSpecFileOperationDestroy + if keepFiles { + fop = "" + } + return v.configureDevice(ctx, types.VirtualDeviceConfigSpecOperationRemove, fop, device...) } // BootOptions returns the VirtualMachine's config.bootOptions property. @@ -400,6 +476,76 @@ func (v VirtualMachine) CreateSnapshot(ctx context.Context, name string, descrip return NewTask(v.c, res.Returnval), nil } +// RemoveAllSnapshot removes all snapshots of a virtual machine +func (v VirtualMachine) RemoveAllSnapshot(ctx context.Context, consolidate *bool) (*Task, error) { + req := types.RemoveAllSnapshots_Task{ + This: v.Reference(), + Consolidate: consolidate, + } + + res, err := methods.RemoveAllSnapshots_Task(ctx, v.c, &req) + if err != nil { + return nil, err + } + + return NewTask(v.c, res.Returnval), nil +} + +// RevertToSnapshot reverts to a named snapshot +func (v VirtualMachine) RevertToSnapshot(ctx context.Context, name string, suppressPowerOn bool) (*Task, error) { + var o mo.VirtualMachine + + err := v.Properties(ctx, v.Reference(), []string{"snapshot"}, &o) + + snapshotTree := o.Snapshot.RootSnapshotList + if len(snapshotTree) < 1 { + return nil, errors.New("No snapshots for this VM") + } + + snapshot, err := traverseSnapshotInTree(snapshotTree, name) + if err != nil { + return nil, err + } + + req := types.RevertToSnapshot_Task{ + This: snapshot, + SuppressPowerOn: types.NewBool(suppressPowerOn), + } + + res, err := methods.RevertToSnapshot_Task(ctx, v.c, &req) + if err != nil { + return nil, err + } + + return NewTask(v.c, res.Returnval), nil +} + +// traverseSnapshotInTree is a recursive function that will traverse a snapshot tree to find a given snapshot +func traverseSnapshotInTree(tree []types.VirtualMachineSnapshotTree, name string) (types.ManagedObjectReference, error) { + var o types.ManagedObjectReference + if tree == nil { + return o, errors.New("Snapshot tree is empty") + } + for _, s := range tree { + if s.Name == name { + o = s.Snapshot + break + } else { + childTree := s.ChildSnapshotList + var err error + o, err = traverseSnapshotInTree(childTree, name) + if err != nil { + return o, err + } + } + } + if o.Value == "" { + return o, errors.New("Snapshot not found") + } + + return o, nil +} + // IsToolsRunning returns true if VMware Tools is currently running in the guest OS, and false otherwise. func (v VirtualMachine) IsToolsRunning(ctx context.Context) (bool, error) { var o mo.VirtualMachine diff --git a/vendor/github.com/vmware/govmomi/vim25/mo/entity.go b/vendor/github.com/vmware/govmomi/vim25/mo/entity.go new file mode 100644 index 0000000000..193e6f71ea --- /dev/null +++ b/vendor/github.com/vmware/govmomi/vim25/mo/entity.go @@ -0,0 +1,24 @@ +/* +Copyright (c) 2016 VMware, Inc. All Rights Reserved. + +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 mo + +// Entity is the interface that is implemented by all managed objects +// that extend ManagedEntity. +type Entity interface { + Reference + Entity() *ManagedEntity +} diff --git a/vendor/github.com/vmware/govmomi/vim25/mo/mo.go b/vendor/github.com/vmware/govmomi/vim25/mo/mo.go index 45b5a8d394..f68b890a5d 100644 --- a/vendor/github.com/vmware/govmomi/vim25/mo/mo.go +++ b/vendor/github.com/vmware/govmomi/vim25/mo/mo.go @@ -130,6 +130,10 @@ type ComputeResource struct { ConfigurationEx types.BaseComputeResourceConfigInfo `mo:"configurationEx"` } +func (m *ComputeResource) Entity() *ManagedEntity { + return &m.ManagedEntity +} + func init() { t["ComputeResource"] = reflect.TypeOf((*ComputeResource)(nil)).Elem() } @@ -187,6 +191,10 @@ type Datacenter struct { Configuration types.DatacenterConfigInfo `mo:"configuration"` } +func (m *Datacenter) Entity() *ManagedEntity { + return &m.ManagedEntity +} + func init() { t["Datacenter"] = reflect.TypeOf((*Datacenter)(nil)).Elem() } @@ -203,6 +211,10 @@ type Datastore struct { IormConfiguration *types.StorageIORMInfo `mo:"iormConfiguration"` } +func (m *Datastore) Entity() *ManagedEntity { + return &m.ManagedEntity +} + func init() { t["Datastore"] = reflect.TypeOf((*Datastore)(nil)).Elem() } @@ -255,6 +267,10 @@ type DistributedVirtualSwitch struct { Runtime *types.DVSRuntimeInfo `mo:"runtime"` } +func (m *DistributedVirtualSwitch) Entity() *ManagedEntity { + return &m.ManagedEntity +} + func init() { t["DistributedVirtualSwitch"] = reflect.TypeOf((*DistributedVirtualSwitch)(nil)).Elem() } @@ -359,6 +375,10 @@ type Folder struct { ChildEntity []types.ManagedObjectReference `mo:"childEntity"` } +func (m *Folder) Entity() *ManagedEntity { + return &m.ManagedEntity +} + func init() { t["Folder"] = reflect.TypeOf((*Folder)(nil)).Elem() } @@ -878,6 +898,10 @@ type HostSystem struct { SystemResources *types.HostSystemResourceInfo `mo:"systemResources"` } +func (m *HostSystem) Entity() *ManagedEntity { + return &m.ManagedEntity +} + func init() { t["HostSystem"] = reflect.TypeOf((*HostSystem)(nil)).Elem() } @@ -1117,6 +1141,10 @@ type Network struct { Vm []types.ManagedObjectReference `mo:"vm"` } +func (m *Network) Entity() *ManagedEntity { + return &m.ManagedEntity +} + func init() { t["Network"] = reflect.TypeOf((*Network)(nil)).Elem() } @@ -1286,6 +1314,10 @@ type ResourcePool struct { ChildConfiguration []types.ResourceConfigSpec `mo:"childConfiguration"` } +func (m *ResourcePool) Entity() *ManagedEntity { + return &m.ManagedEntity +} + func init() { t["ResourcePool"] = reflect.TypeOf((*ResourcePool)(nil)).Elem() } @@ -1551,6 +1583,10 @@ type VirtualMachine struct { GuestHeartbeatStatus types.ManagedEntityStatus `mo:"guestHeartbeatStatus"` } +func (m *VirtualMachine) Entity() *ManagedEntity { + return &m.ManagedEntity +} + func init() { t["VirtualMachine"] = reflect.TypeOf((*VirtualMachine)(nil)).Elem() } diff --git a/vendor/github.com/vmware/govmomi/vim25/mo/type_info.go b/vendor/github.com/vmware/govmomi/vim25/mo/type_info.go index 119d237407..0c9e5b0348 100644 --- a/vendor/github.com/vmware/govmomi/vim25/mo/type_info.go +++ b/vendor/github.com/vmware/govmomi/vim25/mo/type_info.go @@ -189,12 +189,20 @@ func assignValue(val reflect.Value, fi []int, pv reflect.Value) { npv := reflect.New(pt) npv.Elem().Set(pv) pv = npv + pt = pv.Type() } else { panic(fmt.Sprintf("type %s doesn't implement %s", pt.Name(), rt.Name())) } } - rv.Set(pv) + if pt.AssignableTo(rt) { + rv.Set(pv) + } else if rt.ConvertibleTo(pt) { + rv.Set(pv.Convert(rt)) + } else { + panic(fmt.Sprintf("cannot assign %s (%s) to %s (%s)", rt.Name(), rt.Kind(), pt.Name(), pt.Kind())) + } + return } diff --git a/vendor/github.com/vmware/govmomi/vim25/soap/client.go b/vendor/github.com/vmware/govmomi/vim25/soap/client.go index c28006a391..4f65afb63f 100644 --- a/vendor/github.com/vmware/govmomi/vim25/soap/client.go +++ b/vendor/github.com/vmware/govmomi/vim25/soap/client.go @@ -428,23 +428,12 @@ var DefaultDownload = Download{ Method: "GET", } -// DownloadFile GETs the given URL to a local file -func (c *Client) DownloadFile(file string, u *url.URL, param *Download) error { - var err error - - if param == nil { - param = &DefaultDownload - } - - fh, err := os.Create(file) - if err != nil { - return err - } - defer fh.Close() +// Download GETs the remote file from the given URL +func (c *Client) Download(u *url.URL, param *Download) (io.ReadCloser, int64, error) { req, err := http.NewRequest(param.Method, u.String(), nil) if err != nil { - return err + return nil, 0, err } if param.Ticket != nil { @@ -453,11 +442,9 @@ func (c *Client) DownloadFile(file string, u *url.URL, param *Download) error { res, err := c.Client.Do(req) if err != nil { - return err + return nil, 0, err } - defer res.Body.Close() - switch res.StatusCode { case http.StatusOK: default: @@ -465,12 +452,37 @@ func (c *Client) DownloadFile(file string, u *url.URL, param *Download) error { } if err != nil { - return err + return nil, 0, err } - var r io.Reader = res.Body + var r io.ReadCloser = res.Body + + return r, res.ContentLength, nil +} + +// DownloadFile GETs the given URL to a local file +func (c *Client) DownloadFile(file string, u *url.URL, param *Download) error { + var err error + if param == nil { + param = &DefaultDownload + } + + rc, contentLength, err := c.Download(u, param) + if err != nil { + return err + } + defer rc.Close() + + var r io.Reader = rc + + fh, err := os.Create(file) + if err != nil { + return err + } + defer fh.Close() + if param.Progress != nil { - pr := progress.NewReader(param.Progress, res.Body, res.ContentLength) + pr := progress.NewReader(param.Progress, r, contentLength) r = pr // Mark progress reader as done when returning from this function. diff --git a/vendor/github.com/vmware/govmomi/vim25/xml/read.go b/vendor/github.com/vmware/govmomi/vim25/xml/read.go index 12a0ce270f..5b407b7909 100644 --- a/vendor/github.com/vmware/govmomi/vim25/xml/read.go +++ b/vendor/github.com/vmware/govmomi/vim25/xml/read.go @@ -271,9 +271,19 @@ var ( // Find reflect.Type for an element's type attribute. func (p *Decoder) typeForElement(val reflect.Value, start *StartElement) reflect.Type { t := "" - for _, a := range start.Attr { + for i, a := range start.Attr { if a.Name == xmlSchemaInstance { t = a.Value + // HACK: ensure xsi:type is last in the list to avoid using that value for + // a "type" attribute, such as ManagedObjectReference.Type for example. + // Note that xsi:type is already the last attribute in VC/ESX responses. + // This is only an issue with govmomi simulator generated responses. + // Proper fix will require finding a few needles in this xml package haystack. + x := len(start.Attr) - 1 + if i != x { + start.Attr[i] = start.Attr[x] + start.Attr[x] = a + } break } } diff --git a/vendor/k8s.io/heapster/metrics/apis/metrics/v1alpha1/types.go b/vendor/k8s.io/heapster/metrics/apis/metrics/v1alpha1/types.go new file mode 100644 index 0000000000..03435be8a1 --- /dev/null +++ b/vendor/k8s.io/heapster/metrics/apis/metrics/v1alpha1/types.go @@ -0,0 +1,56 @@ +// Copyright 2016 Google Inc. All Rights Reserved. +// +// 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 v1alpha1 + +import ( + "k8s.io/kubernetes/pkg/api/unversioned" + "k8s.io/kubernetes/pkg/api/v1" +) + +// resource usage metrics of a node. +type NodeMetrics struct { + unversioned.TypeMeta `json:",inline"` + v1.ObjectMeta `json:"metadata,omitempty"` + + // The following fields define time interval from which metrics were + // collected from the interval [Timestamp-Window, Timestamp]. + Timestamp unversioned.Time `json:"timestamp"` + Window unversioned.Duration `json:"window"` + + // The memory usage is the memory working set. + Usage v1.ResourceList `json:"usage"` +} + +// resource usage metrics of a pod. +type PodMetrics struct { + unversioned.TypeMeta `json:",inline"` + v1.ObjectMeta `json:"metadata,omitempty"` + + // The following fields define time interval from which metrics were + // collected from the interval [Timestamp-Window, Timestamp]. + Timestamp unversioned.Time `json:"timestamp"` + Window unversioned.Duration `json:"window"` + + // Metrics for all containers are collected within the same time window. + Containers []ContainerMetrics `json:"containers"` +} + +// resource usage metrics of a container. +type ContainerMetrics struct { + // Container name corresponding to the one from pod.spec.containers. + Name string `json:"name"` + // The memory usage is the memory working set. + Usage v1.ResourceList `json:"usage"` +} diff --git a/vendor/k8s.io/kubernetes/cmd/kube-apiserver/app/options/options.go b/vendor/k8s.io/kubernetes/cmd/kube-apiserver/app/options/options.go index 2d68cfc137..9f3e002592 100644 --- a/vendor/k8s.io/kubernetes/cmd/kube-apiserver/app/options/options.go +++ b/vendor/k8s.io/kubernetes/cmd/kube-apiserver/app/options/options.go @@ -18,14 +18,10 @@ limitations under the License. package options import ( - "strings" "time" - "k8s.io/kubernetes/pkg/admission" - "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/validation" - "k8s.io/kubernetes/pkg/apiserver" - "k8s.io/kubernetes/pkg/genericapiserver" + genericoptions "k8s.io/kubernetes/pkg/genericapiserver/options" kubeletclient "k8s.io/kubernetes/pkg/kubelet/client" "k8s.io/kubernetes/pkg/master/ports" @@ -34,54 +30,30 @@ import ( // APIServer runs a kubernetes api server. type APIServer struct { - *genericapiserver.ServerRunOptions - AdmissionControl string - AdmissionControlConfigFile string + *genericoptions.ServerRunOptions AllowPrivileged bool - AuthorizationMode string - AuthorizationConfig apiserver.AuthorizationConfig - BasicAuthFile string - DefaultStorageMediaType string - DeleteCollectionWorkers int - EtcdServersOverrides []string EventTTL time.Duration - KeystoneURL string KubeletConfig kubeletclient.KubeletClientConfig - MasterServiceNamespace string MaxConnectionBytesPerSec int64 - OIDCCAFile string - OIDCClientID string - OIDCIssuerURL string - OIDCUsernameClaim string - OIDCGroupsClaim string SSHKeyfile string SSHUser string ServiceAccountKeyFile string ServiceAccountLookup bool WebhookTokenAuthnConfigFile string - // The default values for StorageVersions. StorageVersions overrides - // these; you can change this if you want to change the defaults (e.g., - // for testing). This is not actually exposed as a flag. - DefaultStorageVersions string - TokenAuthFile string - WatchCacheSizes []string + WebhookTokenAuthnCacheTTL time.Duration } // NewAPIServer creates a new APIServer object with default parameters func NewAPIServer() *APIServer { s := APIServer{ - ServerRunOptions: genericapiserver.NewServerRunOptions(), - AdmissionControl: "AlwaysAdmit", - AuthorizationMode: "AlwaysAllow", - DefaultStorageMediaType: "application/json", - DeleteCollectionWorkers: 1, - EventTTL: 1 * time.Hour, - MasterServiceNamespace: api.NamespaceDefault, + ServerRunOptions: genericoptions.NewServerRunOptions(), + EventTTL: 1 * time.Hour, KubeletConfig: kubeletclient.KubeletClientConfig{ Port: ports.KubeletPort, EnableHttps: true, HTTPTimeout: time.Duration(5) * time.Second, }, + WebhookTokenAuthnCacheTTL: 2 * time.Minute, } return &s } @@ -92,30 +64,12 @@ func (s *APIServer) AddFlags(fs *pflag.FlagSet) { s.ServerRunOptions.AddFlags(fs) // Note: the weird ""+ in below lines seems to be the only way to get gofmt to // arrange these text blocks sensibly. Grrr. - fs.StringVar(&s.DefaultStorageMediaType, "storage-media-type", s.DefaultStorageMediaType, "The media type to use to store objects in storage. Defaults to application/json. Some resources may only support a specific media type and will ignore this setting.") fs.DurationVar(&s.EventTTL, "event-ttl", s.EventTTL, "Amount of time to retain events. Default 1 hour.") - fs.StringVar(&s.BasicAuthFile, "basic-auth-file", s.BasicAuthFile, "If set, the file that will be used to admit requests to the secure port of the API server via http basic authentication.") - fs.StringVar(&s.TokenAuthFile, "token-auth-file", s.TokenAuthFile, "If set, the file that will be used to secure the secure port of the API server via token authentication.") - fs.StringVar(&s.OIDCIssuerURL, "oidc-issuer-url", s.OIDCIssuerURL, "The URL of the OpenID issuer, only HTTPS scheme will be accepted. If set, it will be used to verify the OIDC JSON Web Token (JWT)") - fs.StringVar(&s.OIDCClientID, "oidc-client-id", s.OIDCClientID, "The client ID for the OpenID Connect client, must be set if oidc-issuer-url is set") - fs.StringVar(&s.OIDCCAFile, "oidc-ca-file", s.OIDCCAFile, "If set, the OpenID server's certificate will be verified by one of the authorities in the oidc-ca-file, otherwise the host's root CA set will be used") - fs.StringVar(&s.OIDCUsernameClaim, "oidc-username-claim", "sub", ""+ - "The OpenID claim to use as the user name. Note that claims other than the default ('sub') is not "+ - "guaranteed to be unique and immutable. This flag is experimental, please see the authentication documentation for further details.") - fs.StringVar(&s.OIDCGroupsClaim, "oidc-groups-claim", "", "If provided, the name of a custom OpenID Connect claim for specifying user groups. The claim value is expected to be an array of strings. This flag is experimental, please see the authentication documentation for further details.") fs.StringVar(&s.ServiceAccountKeyFile, "service-account-key-file", s.ServiceAccountKeyFile, "File containing PEM-encoded x509 RSA private or public key, used to verify ServiceAccount tokens. If unspecified, --tls-private-key-file is used.") fs.BoolVar(&s.ServiceAccountLookup, "service-account-lookup", s.ServiceAccountLookup, "If true, validate ServiceAccount tokens exist in etcd as part of authentication.") - fs.StringVar(&s.KeystoneURL, "experimental-keystone-url", s.KeystoneURL, "If passed, activates the keystone authentication plugin") - fs.StringVar(&s.AuthorizationMode, "authorization-mode", s.AuthorizationMode, "Ordered list of plug-ins to do authorization on secure port. Comma-delimited list of: "+strings.Join(apiserver.AuthorizationModeChoices, ",")) - fs.StringVar(&s.AuthorizationConfig.PolicyFile, "authorization-policy-file", s.AuthorizationConfig.PolicyFile, "File with authorization policy in csv format, used with --authorization-mode=ABAC, on the secure port.") - fs.StringVar(&s.AuthorizationConfig.WebhookConfigFile, "authorization-webhook-config-file", s.AuthorizationConfig.WebhookConfigFile, "File with webhook configuration in kubeconfig format, used with --authorization-mode=Webhook. The API server will query the remote service to determine access on the API server's secure port.") fs.StringVar(&s.WebhookTokenAuthnConfigFile, "authentication-token-webhook-config-file", s.WebhookTokenAuthnConfigFile, "File with webhook configuration for token authentication in kubeconfig format. The API server will query the remote service to determine authentication for bearer tokens.") - fs.StringVar(&s.AdmissionControl, "admission-control", s.AdmissionControl, "Ordered list of plug-ins to do admission control of resources into cluster. Comma-delimited list of: "+strings.Join(admission.GetPlugins(), ", ")) - fs.StringVar(&s.AdmissionControlConfigFile, "admission-control-config-file", s.AdmissionControlConfigFile, "File with admission control configuration.") - fs.StringSliceVar(&s.EtcdServersOverrides, "etcd-servers-overrides", s.EtcdServersOverrides, "Per-resource etcd servers overrides, comma separated. The individual override format: group/resource#servers, where servers are http://ip:port, semicolon separated.") + fs.DurationVar(&s.WebhookTokenAuthnCacheTTL, "authentication-token-webhook-cache-ttl", s.WebhookTokenAuthnCacheTTL, "The duration to cache responses from the webhook token authenticator. Default is 2m") fs.BoolVar(&s.AllowPrivileged, "allow-privileged", s.AllowPrivileged, "If true, allow privileged containers.") - fs.StringVar(&s.MasterServiceNamespace, "master-service-namespace", s.MasterServiceNamespace, "The namespace from which the kubernetes master services should be injected into pods") - fs.IntVar(&s.DeleteCollectionWorkers, "delete-collection-workers", s.DeleteCollectionWorkers, "Number of workers spawned for DeleteCollection call. These are used to speed up namespace cleanup.") fs.StringVar(&s.SSHUser, "ssh-user", s.SSHUser, "If non-empty, use secure SSH proxy to the nodes, using this user name") fs.StringVar(&s.SSHKeyfile, "ssh-keyfile", s.SSHKeyfile, "If non-empty, use secure SSH proxy to the nodes, using this user keyfile") fs.Int64Var(&s.MaxConnectionBytesPerSec, "max-connection-bytes-per-sec", s.MaxConnectionBytesPerSec, "If non-zero, throttle each user connection to this number of bytes/sec. Currently only applies to long-running requests") @@ -129,5 +83,4 @@ func (s *APIServer) AddFlags(fs *pflag.FlagSet) { fs.StringVar(&s.KubeletConfig.CAFile, "kubelet-certificate-authority", s.KubeletConfig.CAFile, "Path to a cert. file for the certificate authority.") // TODO: delete this flag as soon as we identify and fix all clients that send malformed updates, like #14126. fs.BoolVar(&validation.RepairMalformedUpdates, "repair-malformed-updates", validation.RepairMalformedUpdates, "If true, server will do its best to fix the update request to pass the validation, e.g., setting empty UID in update request to its existing value. This flag can be turned off after we fix all the clients that send malformed updates.") - fs.StringSliceVar(&s.WatchCacheSizes, "watch-cache-sizes", s.WatchCacheSizes, "List of watch cache sizes for every resource (pods, nodes, etc.), comma separated. The individual override format: resource#size, where size is a number. It takes effect when watch-cache is enabled.") } diff --git a/vendor/k8s.io/kubernetes/cmd/kube-apiserver/app/server.go b/vendor/k8s.io/kubernetes/cmd/kube-apiserver/app/server.go index fd189a44fe..5ba29fac31 100644 --- a/vendor/k8s.io/kubernetes/cmd/kube-apiserver/app/server.go +++ b/vendor/k8s.io/kubernetes/cmd/kube-apiserver/app/server.go @@ -190,6 +190,7 @@ func Run(s *options.APIServer) error { ServiceAccountTokenGetter: serviceAccountGetter, KeystoneURL: s.KeystoneURL, WebhookTokenAuthnConfigFile: s.WebhookTokenAuthnConfigFile, + WebhookTokenAuthnCacheTTL: s.WebhookTokenAuthnCacheTTL, }) if err != nil { diff --git a/vendor/k8s.io/kubernetes/cmd/kube-controller-manager/app/controllermanager.go b/vendor/k8s.io/kubernetes/cmd/kube-controller-manager/app/controllermanager.go index fb6d54355f..a1f6618f65 100644 --- a/vendor/k8s.io/kubernetes/cmd/kube-controller-manager/app/controllermanager.go +++ b/vendor/k8s.io/kubernetes/cmd/kube-controller-manager/app/controllermanager.go @@ -227,10 +227,11 @@ func StartControllers(s *options.CMServer, kubeClient *client.Client, kubeconfig // this cidr has been validated already _, clusterCIDR, _ := net.ParseCIDR(s.ClusterCIDR) + _, serviceCIDR, _ := net.ParseCIDR(s.ServiceCIDR) nodeController := nodecontroller.NewNodeController(cloud, clientset.NewForConfigOrDie(restclient.AddUserAgent(kubeconfig, "node-controller")), s.PodEvictionTimeout.Duration, flowcontrol.NewTokenBucketRateLimiter(s.DeletingPodsQps, int(s.DeletingPodsBurst)), flowcontrol.NewTokenBucketRateLimiter(s.DeletingPodsQps, int(s.DeletingPodsBurst)), - s.NodeMonitorGracePeriod.Duration, s.NodeStartupGracePeriod.Duration, s.NodeMonitorPeriod.Duration, clusterCIDR, s.AllocateNodeCIDRs) + s.NodeMonitorGracePeriod.Duration, s.NodeStartupGracePeriod.Duration, s.NodeMonitorPeriod.Duration, clusterCIDR, serviceCIDR, int(s.NodeCIDRMaskSize), s.AllocateNodeCIDRs) nodeController.Run(s.NodeSyncPeriod.Duration) time.Sleep(wait.Jitter(s.ControllerStartInterval.Duration, ControllerStartJitter)) @@ -298,7 +299,7 @@ func StartControllers(s *options.CMServer, kubeClient *client.Client, kubeconfig // Find the list of namespaced resources via discovery that the namespace controller must manage namespaceKubeClient := clientset.NewForConfigOrDie(restclient.AddUserAgent(kubeconfig, "namespace-controller")) namespaceClientPool := dynamic.NewClientPool(restclient.AddUserAgent(kubeconfig, "namespace-controller"), dynamic.LegacyAPIPathResolverFunc) - groupVersionResources, err := namespacecontroller.ServerPreferredNamespacedGroupVersionResources(namespaceKubeClient.Discovery()) + groupVersionResources, err := namespaceKubeClient.Discovery().ServerPreferredNamespacedResources() if err != nil { glog.Fatalf("Failed to get supported resources from server: %v", err) } @@ -373,38 +374,23 @@ func StartControllers(s *options.CMServer, kubeClient *client.Client, kubeconfig } } - volumePlugins := ProbeRecyclableVolumePlugins(s.VolumeConfiguration) provisioner, err := NewVolumeProvisioner(cloud, s.VolumeConfiguration) if err != nil { glog.Fatal("A Provisioner could not be created, but one was expected. Provisioning will not work. This functionality is considered an early Alpha version.") } - pvclaimBinder := persistentvolumecontroller.NewPersistentVolumeClaimBinder(clientset.NewForConfigOrDie(restclient.AddUserAgent(kubeconfig, "persistent-volume-binder")), s.PVClaimBinderSyncPeriod.Duration) - pvclaimBinder.Run() - time.Sleep(wait.Jitter(s.ControllerStartInterval.Duration, ControllerStartJitter)) - - pvRecycler, err := persistentvolumecontroller.NewPersistentVolumeRecycler( - clientset.NewForConfigOrDie(restclient.AddUserAgent(kubeconfig, "persistent-volume-recycler")), + volumeController := persistentvolumecontroller.NewPersistentVolumeController( + clientset.NewForConfigOrDie(restclient.AddUserAgent(kubeconfig, "persistent-volume-binder")), s.PVClaimBinderSyncPeriod.Duration, - int(s.VolumeConfiguration.PersistentVolumeRecyclerConfiguration.MaximumRetry), + provisioner, ProbeRecyclableVolumePlugins(s.VolumeConfiguration), cloud, + s.ClusterName, + nil, nil, nil, ) - if err != nil { - glog.Fatalf("Failed to start persistent volume recycler: %+v", err) - } - pvRecycler.Run() + volumeController.Run() time.Sleep(wait.Jitter(s.ControllerStartInterval.Duration, ControllerStartJitter)) - if provisioner != nil { - pvController, err := persistentvolumecontroller.NewPersistentVolumeProvisionerController(persistentvolumecontroller.NewControllerClient(clientset.NewForConfigOrDie(restclient.AddUserAgent(kubeconfig, "persistent-volume-provisioner"))), s.PVClaimBinderSyncPeriod.Duration, s.ClusterName, volumePlugins, provisioner, cloud) - if err != nil { - glog.Fatalf("Failed to start persistent volume provisioner controller: %+v", err) - } - pvController.Run() - time.Sleep(wait.Jitter(s.ControllerStartInterval.Duration, ControllerStartJitter)) - } - go volume.NewAttachDetachController(clientset.NewForConfigOrDie(restclient.AddUserAgent(kubeconfig, "attachdetach-controller")), podInformer, nodeInformer, ResyncPeriod(s)()). Run(wait.NeverStop) time.Sleep(wait.Jitter(s.ControllerStartInterval.Duration, ControllerStartJitter)) diff --git a/vendor/k8s.io/kubernetes/cmd/kube-controller-manager/app/options/options.go b/vendor/k8s.io/kubernetes/cmd/kube-controller-manager/app/options/options.go index 180120cd47..40d85a1228 100644 --- a/vendor/k8s.io/kubernetes/cmd/kube-controller-manager/app/options/options.go +++ b/vendor/k8s.io/kubernetes/cmd/kube-controller-manager/app/options/options.go @@ -70,6 +70,7 @@ func NewCMServer() *CMServer { NodeStartupGracePeriod: unversioned.Duration{Duration: 60 * time.Second}, NodeMonitorPeriod: unversioned.Duration{Duration: 5 * time.Second}, ClusterName: "kubernetes", + NodeCIDRMaskSize: 24, TerminatedPodGCThreshold: 12500, VolumeConfiguration: componentconfig.VolumeConfiguration{ EnableHostPathProvisioning: false, @@ -81,6 +82,7 @@ func NewCMServer() *CMServer { IncrementTimeoutHostPath: 30, }, }, + ContentType: "application/vnd.kubernetes.protobuf", KubeAPIQPS: 20.0, KubeAPIBurst: 30, LeaderElection: leaderelection.DefaultLeaderElectionConfiguration(), @@ -141,11 +143,13 @@ func (s *CMServer) AddFlags(fs *pflag.FlagSet) { fs.BoolVar(&s.EnableProfiling, "profiling", true, "Enable profiling via web interface host:port/debug/pprof/") fs.StringVar(&s.ClusterName, "cluster-name", s.ClusterName, "The instance prefix for the cluster") fs.StringVar(&s.ClusterCIDR, "cluster-cidr", s.ClusterCIDR, "CIDR Range for Pods in cluster.") + fs.StringVar(&s.ServiceCIDR, "service-cluster-ip-range", s.ServiceCIDR, "CIDR Range for Services in cluster.") + fs.Int32Var(&s.NodeCIDRMaskSize, "node-cidr-mask-size", s.NodeCIDRMaskSize, "Mask size for node cidr in cluster.") fs.BoolVar(&s.AllocateNodeCIDRs, "allocate-node-cidrs", false, "Should CIDRs for Pods be allocated and set on the cloud provider.") fs.StringVar(&s.Master, "master", s.Master, "The address of the Kubernetes API server (overrides any value in kubeconfig)") fs.StringVar(&s.Kubeconfig, "kubeconfig", s.Kubeconfig, "Path to kubeconfig file with authorization and master location information.") fs.StringVar(&s.RootCAFile, "root-ca-file", s.RootCAFile, "If set, this root certificate authority will be included in service account's token secret. This must be a valid PEM-encoded CA bundle.") - fs.StringVar(&s.ContentType, "kube-api-content-type", s.ContentType, "ContentType of requests sent to apiserver. Passing application/vnd.kubernetes.protobuf is an experimental feature now.") + fs.StringVar(&s.ContentType, "kube-api-content-type", s.ContentType, "Content type of requests sent to apiserver.") fs.Float32Var(&s.KubeAPIQPS, "kube-api-qps", s.KubeAPIQPS, "QPS to use while talking with kubernetes apiserver") fs.Int32Var(&s.KubeAPIBurst, "kube-api-burst", s.KubeAPIBurst, "Burst to use while talking with kubernetes apiserver") fs.DurationVar(&s.ControllerStartInterval.Duration, "controller-start-interval", s.ControllerStartInterval.Duration, "Interval between starting controller managers.") diff --git a/vendor/k8s.io/kubernetes/cmd/kube-controller-manager/app/plugins.go b/vendor/k8s.io/kubernetes/cmd/kube-controller-manager/app/plugins.go index 33651191b4..c34cb1d7a2 100644 --- a/vendor/k8s.io/kubernetes/cmd/kube-controller-manager/app/plugins.go +++ b/vendor/k8s.io/kubernetes/cmd/kube-controller-manager/app/plugins.go @@ -32,6 +32,7 @@ import ( "k8s.io/kubernetes/pkg/cloudprovider/providers/aws" "k8s.io/kubernetes/pkg/cloudprovider/providers/gce" "k8s.io/kubernetes/pkg/cloudprovider/providers/openstack" + "k8s.io/kubernetes/pkg/cloudprovider/providers/vsphere" "k8s.io/kubernetes/pkg/util/io" "k8s.io/kubernetes/pkg/volume" "k8s.io/kubernetes/pkg/volume/aws_ebs" @@ -39,6 +40,7 @@ import ( "k8s.io/kubernetes/pkg/volume/gce_pd" "k8s.io/kubernetes/pkg/volume/host_path" "k8s.io/kubernetes/pkg/volume/nfs" + "k8s.io/kubernetes/pkg/volume/vsphere_volume" "github.com/golang/glog" ) @@ -79,6 +81,7 @@ func ProbeRecyclableVolumePlugins(config componentconfig.VolumeConfiguration) [] allPlugins = append(allPlugins, aws_ebs.ProbeVolumePlugins()...) allPlugins = append(allPlugins, gce_pd.ProbeVolumePlugins()...) allPlugins = append(allPlugins, cinder.ProbeVolumePlugins()...) + allPlugins = append(allPlugins, vsphere_volume.ProbeVolumePlugins()...) return allPlugins } @@ -97,6 +100,8 @@ func NewVolumeProvisioner(cloud cloudprovider.Interface, config componentconfig. return getProvisionablePluginFromVolumePlugins(gce_pd.ProbeVolumePlugins()) case cloud != nil && openstack.ProviderName == cloud.ProviderName(): return getProvisionablePluginFromVolumePlugins(cinder.ProbeVolumePlugins()) + case cloud != nil && vsphere.ProviderName == cloud.ProviderName(): + return getProvisionablePluginFromVolumePlugins(vsphere_volume.ProbeVolumePlugins()) } return nil, nil } diff --git a/vendor/k8s.io/kubernetes/cmd/kube-proxy/app/options/options.go b/vendor/k8s.io/kubernetes/cmd/kube-proxy/app/options/options.go index 9f342829da..5bb1a69782 100644 --- a/vendor/k8s.io/kubernetes/cmd/kube-proxy/app/options/options.go +++ b/vendor/k8s.io/kubernetes/cmd/kube-proxy/app/options/options.go @@ -53,6 +53,7 @@ func NewProxyConfig() *ProxyServerConfig { api.Scheme.Convert(&v1alpha1.KubeProxyConfiguration{}, &config) return &ProxyServerConfig{ KubeProxyConfiguration: config, + ContentType: "application/vnd.kubernetes.protobuf", KubeAPIQPS: 5.0, KubeAPIBurst: 10, ConfigSyncPeriod: 15 * time.Minute, @@ -78,7 +79,7 @@ func (s *ProxyServerConfig) AddFlags(fs *pflag.FlagSet) { fs.BoolVar(&s.MasqueradeAll, "masquerade-all", s.MasqueradeAll, "If using the pure iptables proxy, SNAT everything") fs.StringVar(&s.ClusterCIDR, "cluster-cidr", s.ClusterCIDR, "The CIDR range of pods in the cluster. It is used to bridge traffic coming from outside of the cluster. If not provided, no off-cluster bridging will be performed.") fs.BoolVar(&s.CleanupAndExit, "cleanup-iptables", s.CleanupAndExit, "If true cleanup iptables rules and exit.") - fs.StringVar(&s.ContentType, "kube-api-content-type", s.ContentType, "ContentType of requests sent to apiserver. Passing application/vnd.kubernetes.protobuf is an experimental feature now.") + fs.StringVar(&s.ContentType, "kube-api-content-type", s.ContentType, "Content type of requests sent to apiserver.") fs.Float32Var(&s.KubeAPIQPS, "kube-api-qps", s.KubeAPIQPS, "QPS to use while talking with kubernetes apiserver") fs.Int32Var(&s.KubeAPIBurst, "kube-api-burst", s.KubeAPIBurst, "Burst to use while talking with kubernetes apiserver") fs.DurationVar(&s.UDPIdleTimeout.Duration, "udp-timeout", s.UDPIdleTimeout.Duration, "How long an idle UDP connection will be kept open (e.g. '250ms', '2s'). Must be greater than 0. Only applicable for proxy-mode=userspace") diff --git a/vendor/k8s.io/kubernetes/cmd/kubelet/app/options/options.go b/vendor/k8s.io/kubernetes/cmd/kubelet/app/options/options.go index a58dacac7b..31a681f4df 100644 --- a/vendor/k8s.io/kubernetes/cmd/kubelet/app/options/options.go +++ b/vendor/k8s.io/kubernetes/cmd/kubelet/app/options/options.go @@ -116,6 +116,7 @@ func NewKubeletServer() *KubeletServer { NodeLabels: make(map[string]string), OOMScoreAdj: int32(qos.KubeletOOMScoreAdj), LockFilePath: "", + ExitOnLockContention: false, PodInfraContainerImage: GetDefaultPodInfraContainerImage(), Port: ports.KubeletPort, ReadOnlyPort: ports.KubeletReadOnlyPort, @@ -135,6 +136,7 @@ func NewKubeletServer() *KubeletServer { SyncFrequency: unversioned.Duration{Duration: 1 * time.Minute}, SystemCgroups: "", ReconcileCIDR: true, + ContentType: "application/vnd.kubernetes.protobuf", KubeAPIQPS: 5.0, KubeAPIBurst: 10, ExperimentalFlannelOverlay: experimentalFlannelOverlay, @@ -220,6 +222,7 @@ func (s *KubeletServer) AddFlags(fs *pflag.FlagSet) { fs.StringVar(&s.CgroupRoot, "cgroup-root", s.CgroupRoot, "Optional root cgroup to use for pods. This is handled by the container runtime on a best effort basis. Default: '', which means use the container runtime default.") fs.StringVar(&s.ContainerRuntime, "container-runtime", s.ContainerRuntime, "The container runtime to use. Possible values: 'docker', 'rkt'. Default: 'docker'.") fs.StringVar(&s.LockFilePath, "lock-file", s.LockFilePath, " The path to file for kubelet to use as a lock file.") + fs.BoolVar(&s.ExitOnLockContention, "exit-on-lock-contention", s.ExitOnLockContention, "Whether kubelet should exit upon lock-file contention.") fs.StringVar(&s.RktPath, "rkt-path", s.RktPath, "Path of rkt binary. Leave empty to use the first rkt in $PATH. Only used if --container-runtime='rkt'.") fs.StringVar(&s.RktAPIEndpoint, "rkt-api-endpoint", s.RktAPIEndpoint, "The endpoint of the rkt API service to communicate with. Only used if --container-runtime='rkt'.") fs.StringVar(&s.RktStage1Image, "rkt-stage1-image", s.RktStage1Image, "image to use as stage1. Local paths and http/https URLs are supported. If empty, the 'stage1.aci' in the same directory as '--rkt-path' will be used.") @@ -244,7 +247,7 @@ func (s *KubeletServer) AddFlags(fs *pflag.FlagSet) { fs.Var(&s.SystemReserved, "system-reserved", "A set of ResourceName=ResourceQuantity (e.g. cpu=200m,memory=150G) pairs that describe resources reserved for non-kubernetes components. Currently only cpu and memory are supported. See http://releases.k8s.io/HEAD/docs/user-guide/compute-resources.md for more detail. [default=none]") fs.Var(&s.KubeReserved, "kube-reserved", "A set of ResourceName=ResourceQuantity (e.g. cpu=200m,memory=150G) pairs that describe resources reserved for kubernetes system components. Currently only cpu and memory are supported. See http://releases.k8s.io/HEAD/docs/user-guide/compute-resources.md for more detail. [default=none]") fs.BoolVar(&s.RegisterSchedulable, "register-schedulable", s.RegisterSchedulable, "Register the node as schedulable. No-op if register-node is false. [default=true]") - fs.StringVar(&s.ContentType, "kube-api-content-type", s.ContentType, "ContentType of requests sent to apiserver. Passing application/vnd.kubernetes.protobuf is an experimental feature now.") + fs.StringVar(&s.ContentType, "kube-api-content-type", s.ContentType, "Content type of requests sent to apiserver.") fs.Float32Var(&s.KubeAPIQPS, "kube-api-qps", s.KubeAPIQPS, "QPS to use while talking with kubernetes apiserver") fs.Int32Var(&s.KubeAPIBurst, "kube-api-burst", s.KubeAPIBurst, "Burst to use while talking with kubernetes apiserver") fs.BoolVar(&s.SerializeImagePulls, "serialize-image-pulls", s.SerializeImagePulls, "Pull images one at a time. We recommend *not* changing the default value on nodes that run docker daemon with version < 1.9 or an Aufs storage backend. Issue #10959 has more details. [default=true]") @@ -257,4 +260,5 @@ func (s *KubeletServer) AddFlags(fs *pflag.FlagSet) { fs.StringVar(&s.EvictionSoft, "eviction-soft", s.EvictionSoft, "A set of eviction thresholds (e.g. memory.available<1.5Gi) that if met over a corresponding grace period would trigger a pod eviction.") fs.StringVar(&s.EvictionSoftGracePeriod, "eviction-soft-grace-period", s.EvictionSoftGracePeriod, "A set of eviction grace periods (e.g. memory.available=1m30s) that correspond to how long a soft eviction threshold must hold before triggering a pod eviction.") fs.DurationVar(&s.EvictionPressureTransitionPeriod.Duration, "eviction-pressure-transition-period", s.EvictionPressureTransitionPeriod.Duration, "Duration for which the kubelet has to wait before transitioning out of an eviction pressure condition.") + fs.Int32Var(&s.EvictionMaxPodGracePeriod, "eviction-max-pod-grace-period", s.EvictionMaxPodGracePeriod, "Maximum allowed grace period (in seconds) to use when terminating pods in response to a soft eviction threshold being met. If negative, defer to pod specified value.") } diff --git a/vendor/k8s.io/kubernetes/cmd/kubelet/app/plugins.go b/vendor/k8s.io/kubernetes/cmd/kubelet/app/plugins.go index c9388d1278..18e078599b 100644 --- a/vendor/k8s.io/kubernetes/cmd/kubelet/app/plugins.go +++ b/vendor/k8s.io/kubernetes/cmd/kubelet/app/plugins.go @@ -44,9 +44,9 @@ import ( "k8s.io/kubernetes/pkg/volume/host_path" "k8s.io/kubernetes/pkg/volume/iscsi" "k8s.io/kubernetes/pkg/volume/nfs" - "k8s.io/kubernetes/pkg/volume/persistent_claim" "k8s.io/kubernetes/pkg/volume/rbd" "k8s.io/kubernetes/pkg/volume/secret" + "k8s.io/kubernetes/pkg/volume/vsphere_volume" // Cloud providers _ "k8s.io/kubernetes/pkg/cloudprovider/providers" ) @@ -72,7 +72,6 @@ func ProbeVolumePlugins(pluginDir string) []volume.VolumePlugin { allPlugins = append(allPlugins, secret.ProbeVolumePlugins()...) allPlugins = append(allPlugins, iscsi.ProbeVolumePlugins()...) allPlugins = append(allPlugins, glusterfs.ProbeVolumePlugins()...) - allPlugins = append(allPlugins, persistent_claim.ProbeVolumePlugins()...) allPlugins = append(allPlugins, rbd.ProbeVolumePlugins()...) allPlugins = append(allPlugins, cinder.ProbeVolumePlugins()...) allPlugins = append(allPlugins, cephfs.ProbeVolumePlugins()...) @@ -82,6 +81,7 @@ func ProbeVolumePlugins(pluginDir string) []volume.VolumePlugin { allPlugins = append(allPlugins, flexvolume.ProbeVolumePlugins(pluginDir)...) allPlugins = append(allPlugins, azure_file.ProbeVolumePlugins()...) allPlugins = append(allPlugins, configmap.ProbeVolumePlugins()...) + allPlugins = append(allPlugins, vsphere_volume.ProbeVolumePlugins()...) return allPlugins } diff --git a/vendor/k8s.io/kubernetes/cmd/kubelet/app/server.go b/vendor/k8s.io/kubernetes/cmd/kubelet/app/server.go index bf2cc623d9..6e852cd5ae 100644 --- a/vendor/k8s.io/kubernetes/cmd/kubelet/app/server.go +++ b/vendor/k8s.io/kubernetes/cmd/kubelet/app/server.go @@ -19,6 +19,7 @@ package app import ( "crypto/tls" + "errors" "fmt" "math/rand" "net" @@ -190,6 +191,7 @@ func UnsecuredKubeletConfig(s *options.KubeletServer) (*KubeletConfig, error) { } evictionConfig := eviction.Config{ PressureTransitionPeriod: s.EvictionPressureTransitionPeriod.Duration, + MaxPodGracePeriodSeconds: int64(s.EvictionMaxPodGracePeriod), Thresholds: thresholds, } @@ -289,11 +291,22 @@ func Run(s *options.KubeletServer, kcfg *KubeletConfig) error { } func run(s *options.KubeletServer, kcfg *KubeletConfig) (err error) { + if s.ExitOnLockContention && s.LockFilePath == "" { + return errors.New("cannot exit on lock file contention: no lock file specified") + } + + done := make(chan struct{}) if s.LockFilePath != "" { glog.Infof("aquiring lock on %q", s.LockFilePath) if err := flock.Acquire(s.LockFilePath); err != nil { return fmt.Errorf("unable to aquire file lock on %q: %v", s.LockFilePath, err) } + if s.ExitOnLockContention { + glog.Infof("watching for inotify events for: %v", s.LockFilePath) + if err := watchForLockfileContention(s.LockFilePath, done); err != nil { + return err + } + } } if c, err := configz.New("componentconfig"); err == nil { c.Set(s.KubeletConfiguration) @@ -330,7 +343,7 @@ func run(s *options.KubeletServer, kcfg *KubeletConfig) (err error) { } if kcfg.CAdvisorInterface == nil { - kcfg.CAdvisorInterface, err = cadvisor.New(s.CAdvisorPort) + kcfg.CAdvisorInterface, err = cadvisor.New(s.CAdvisorPort, kcfg.ContainerRuntime) if err != nil { return err } @@ -383,8 +396,8 @@ func run(s *options.KubeletServer, kcfg *KubeletConfig) (err error) { return nil } - // run forever - select {} + <-done + return nil } // InitializeTLS checks for a configured TLSCertFile and TLSPrivateKeyFile: if unspecified a new self-signed @@ -927,10 +940,10 @@ func parseResourceList(m utilconfig.ConfigurationMap) (api.ResourceList, error) if err != nil { return nil, err } - if q.Amount.Sign() == -1 { + if q.Sign() == -1 { return nil, fmt.Errorf("resource quantity for %q cannot be negative: %v", k, v) } - rl[api.ResourceName(k)] = *q + rl[api.ResourceName(k)] = q default: return nil, fmt.Errorf("cannot reserve %q resource", k) } diff --git a/vendor/k8s.io/kubernetes/cmd/kubelet/app/server_linux.go b/vendor/k8s.io/kubernetes/cmd/kubelet/app/server_linux.go new file mode 100644 index 0000000000..a687f6f8da --- /dev/null +++ b/vendor/k8s.io/kubernetes/cmd/kubelet/app/server_linux.go @@ -0,0 +1,44 @@ +/* +Copyright 2015 The Kubernetes Authors All rights reserved. + +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 app + +import ( + "github.com/golang/glog" + "golang.org/x/exp/inotify" +) + +func watchForLockfileContention(path string, done chan struct{}) error { + watcher, err := inotify.NewWatcher() + if err != nil { + glog.Errorf("unable to create watcher for lockfile: %v", err) + return err + } + if err = watcher.AddWatch(path, inotify.IN_OPEN|inotify.IN_DELETE_SELF); err != nil { + glog.Errorf("unable to watch lockfile: %v", err) + return err + } + go func() { + select { + case ev := <-watcher.Event: + glog.Infof("inotify event: %v", ev) + case err = <-watcher.Error: + glog.Errorf("inotify watcher error: %v", err) + } + close(done) + }() + return nil +} diff --git a/vendor/k8s.io/kubernetes/cmd/kubelet/app/server_unsupported.go b/vendor/k8s.io/kubernetes/cmd/kubelet/app/server_unsupported.go new file mode 100644 index 0000000000..8647b8b68b --- /dev/null +++ b/vendor/k8s.io/kubernetes/cmd/kubelet/app/server_unsupported.go @@ -0,0 +1,25 @@ +// +build !linux + +/* +Copyright 2015 The Kubernetes Authors All rights reserved. + +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 app + +import "errors" + +func watchForLockfileContention(path string, done chan struct{}) error { + return errors.New("kubelet unsupported in this build") +} diff --git a/vendor/k8s.io/kubernetes/pkg/api/deep_copy_generated.go b/vendor/k8s.io/kubernetes/pkg/api/deep_copy_generated.go index 2a21495a90..013e59d256 100644 --- a/vendor/k8s.io/kubernetes/pkg/api/deep_copy_generated.go +++ b/vendor/k8s.io/kubernetes/pkg/api/deep_copy_generated.go @@ -175,9 +175,12 @@ func init() { DeepCopy_api_ServiceSpec, DeepCopy_api_ServiceStatus, DeepCopy_api_TCPSocketAction, + DeepCopy_api_Taint, + DeepCopy_api_Toleration, DeepCopy_api_Volume, DeepCopy_api_VolumeMount, DeepCopy_api_VolumeSource, + DeepCopy_api_VsphereVirtualDiskVolumeSource, DeepCopy_api_WeightedPodAffinityTerm, ); err != nil { // if one of the deep copy functions is malformed, detect it immediately. @@ -1585,6 +1588,8 @@ func DeepCopy_api_NodeSystemInfo(in NodeSystemInfo, out *NodeSystemInfo, c *conv out.ContainerRuntimeVersion = in.ContainerRuntimeVersion out.KubeletVersion = in.KubeletVersion out.KubeProxyVersion = in.KubeProxyVersion + out.OperatingSystem = in.OperatingSystem + out.Architecture = in.Architecture return nil } @@ -1921,6 +1926,15 @@ func DeepCopy_api_PersistentVolumeSource(in PersistentVolumeSource, out *Persist } else { out.AzureFile = nil } + if in.VsphereVolume != nil { + in, out := in.VsphereVolume, &out.VsphereVolume + *out = new(VsphereVirtualDiskVolumeSource) + if err := DeepCopy_api_VsphereVirtualDiskVolumeSource(*in, *out, c); err != nil { + return err + } + } else { + out.VsphereVolume = nil + } return nil } @@ -2230,6 +2244,17 @@ func DeepCopy_api_PodSpec(in PodSpec, out *PodSpec, c *conversion.Cloner) error } else { out.Volumes = nil } + if in.InitContainers != nil { + in, out := in.InitContainers, &out.InitContainers + *out = make([]Container, len(in)) + for i := range in { + if err := DeepCopy_api_Container(in[i], &(*out)[i], c); err != nil { + return err + } + } + } else { + out.InitContainers = nil + } if in.Containers != nil { in, out := in.Containers, &out.Containers *out = make([]Container, len(in)) @@ -2319,6 +2344,17 @@ func DeepCopy_api_PodStatus(in PodStatus, out *PodStatus, c *conversion.Cloner) } else { out.StartTime = nil } + if in.InitContainerStatuses != nil { + in, out := in.InitContainerStatuses, &out.InitContainerStatuses + *out = make([]ContainerStatus, len(in)) + for i := range in { + if err := DeepCopy_api_ContainerStatus(in[i], &(*out)[i], c); err != nil { + return err + } + } + } else { + out.InitContainerStatuses = nil + } if in.ContainerStatuses != nil { in, out := in.ContainerStatuses, &out.ContainerStatuses *out = make([]ContainerStatus, len(in)) @@ -2722,6 +2758,17 @@ func DeepCopy_api_SecretList(in SecretList, out *SecretList, c *conversion.Clone func DeepCopy_api_SecretVolumeSource(in SecretVolumeSource, out *SecretVolumeSource, c *conversion.Cloner) error { out.SecretName = in.SecretName + if in.Items != nil { + in, out := in.Items, &out.Items + *out = make([]KeyToPath, len(in)) + for i := range in { + if err := DeepCopy_api_KeyToPath(in[i], &(*out)[i], c); err != nil { + return err + } + } + } else { + out.Items = nil + } return nil } @@ -2943,6 +2990,21 @@ func DeepCopy_api_TCPSocketAction(in TCPSocketAction, out *TCPSocketAction, c *c return nil } +func DeepCopy_api_Taint(in Taint, out *Taint, c *conversion.Cloner) error { + out.Key = in.Key + out.Value = in.Value + out.Effect = in.Effect + return nil +} + +func DeepCopy_api_Toleration(in Toleration, out *Toleration, c *conversion.Cloner) error { + out.Key = in.Key + out.Operator = in.Operator + out.Value = in.Value + out.Effect = in.Effect + return nil +} + func DeepCopy_api_Volume(in Volume, out *Volume, c *conversion.Cloner) error { out.Name = in.Name if err := DeepCopy_api_VolumeSource(in.VolumeSource, &out.VolumeSource, c); err != nil { @@ -3131,6 +3193,21 @@ func DeepCopy_api_VolumeSource(in VolumeSource, out *VolumeSource, c *conversion } else { out.ConfigMap = nil } + if in.VsphereVolume != nil { + in, out := in.VsphereVolume, &out.VsphereVolume + *out = new(VsphereVirtualDiskVolumeSource) + if err := DeepCopy_api_VsphereVirtualDiskVolumeSource(*in, *out, c); err != nil { + return err + } + } else { + out.VsphereVolume = nil + } + return nil +} + +func DeepCopy_api_VsphereVirtualDiskVolumeSource(in VsphereVirtualDiskVolumeSource, out *VsphereVirtualDiskVolumeSource, c *conversion.Cloner) error { + out.VolumePath = in.VolumePath + out.FSType = in.FSType return nil } diff --git a/vendor/k8s.io/kubernetes/pkg/api/errors/errors.go b/vendor/k8s.io/kubernetes/pkg/api/errors/errors.go index 345ad0e043..89e83c2e3a 100644 --- a/vendor/k8s.io/kubernetes/pkg/api/errors/errors.go +++ b/vendor/k8s.io/kubernetes/pkg/api/errors/errors.go @@ -93,7 +93,7 @@ func FromObject(obj runtime.Object) error { } // NewNotFound returns a new error which indicates that the resource of the kind and the name was not found. -func NewNotFound(qualifiedResource unversioned.GroupResource, name string) error { +func NewNotFound(qualifiedResource unversioned.GroupResource, name string) *StatusError { return &StatusError{unversioned.Status{ Status: unversioned.StatusFailure, Code: http.StatusNotFound, @@ -108,7 +108,7 @@ func NewNotFound(qualifiedResource unversioned.GroupResource, name string) error } // NewAlreadyExists returns an error indicating the item requested exists by that identifier. -func NewAlreadyExists(qualifiedResource unversioned.GroupResource, name string) error { +func NewAlreadyExists(qualifiedResource unversioned.GroupResource, name string) *StatusError { return &StatusError{unversioned.Status{ Status: unversioned.StatusFailure, Code: http.StatusConflict, @@ -124,7 +124,7 @@ func NewAlreadyExists(qualifiedResource unversioned.GroupResource, name string) // NewUnauthorized returns an error indicating the client is not authorized to perform the requested // action. -func NewUnauthorized(reason string) error { +func NewUnauthorized(reason string) *StatusError { message := reason if len(message) == 0 { message = "not authorized" @@ -138,7 +138,7 @@ func NewUnauthorized(reason string) error { } // NewForbidden returns an error indicating the requested action was forbidden -func NewForbidden(qualifiedResource unversioned.GroupResource, name string, err error) error { +func NewForbidden(qualifiedResource unversioned.GroupResource, name string, err error) *StatusError { return &StatusError{unversioned.Status{ Status: unversioned.StatusFailure, Code: http.StatusForbidden, @@ -153,7 +153,7 @@ func NewForbidden(qualifiedResource unversioned.GroupResource, name string, err } // NewConflict returns an error indicating the item can't be updated as provided. -func NewConflict(qualifiedResource unversioned.GroupResource, name string, err error) error { +func NewConflict(qualifiedResource unversioned.GroupResource, name string, err error) *StatusError { return &StatusError{unversioned.Status{ Status: unversioned.StatusFailure, Code: http.StatusConflict, @@ -168,7 +168,7 @@ func NewConflict(qualifiedResource unversioned.GroupResource, name string, err e } // NewGone returns an error indicating the item no longer available at the server and no forwarding address is known. -func NewGone(message string) error { +func NewGone(message string) *StatusError { return &StatusError{unversioned.Status{ Status: unversioned.StatusFailure, Code: http.StatusGone, @@ -178,7 +178,7 @@ func NewGone(message string) error { } // NewInvalid returns an error indicating the item is invalid and cannot be processed. -func NewInvalid(qualifiedKind unversioned.GroupKind, name string, errs field.ErrorList) error { +func NewInvalid(qualifiedKind unversioned.GroupKind, name string, errs field.ErrorList) *StatusError { causes := make([]unversioned.StatusCause, 0, len(errs)) for i := range errs { err := errs[i] @@ -203,7 +203,7 @@ func NewInvalid(qualifiedKind unversioned.GroupKind, name string, errs field.Err } // NewBadRequest creates an error that indicates that the request is invalid and can not be processed. -func NewBadRequest(reason string) error { +func NewBadRequest(reason string) *StatusError { return &StatusError{unversioned.Status{ Status: unversioned.StatusFailure, Code: http.StatusBadRequest, @@ -213,7 +213,7 @@ func NewBadRequest(reason string) error { } // NewServiceUnavailable creates an error that indicates that the requested service is unavailable. -func NewServiceUnavailable(reason string) error { +func NewServiceUnavailable(reason string) *StatusError { return &StatusError{unversioned.Status{ Status: unversioned.StatusFailure, Code: http.StatusServiceUnavailable, @@ -223,7 +223,7 @@ func NewServiceUnavailable(reason string) error { } // NewMethodNotSupported returns an error indicating the requested action is not supported on this kind. -func NewMethodNotSupported(qualifiedResource unversioned.GroupResource, action string) error { +func NewMethodNotSupported(qualifiedResource unversioned.GroupResource, action string) *StatusError { return &StatusError{unversioned.Status{ Status: unversioned.StatusFailure, Code: http.StatusMethodNotAllowed, @@ -238,7 +238,7 @@ func NewMethodNotSupported(qualifiedResource unversioned.GroupResource, action s // NewServerTimeout returns an error indicating the requested action could not be completed due to a // transient error, and the client should try again. -func NewServerTimeout(qualifiedResource unversioned.GroupResource, operation string, retryAfterSeconds int) error { +func NewServerTimeout(qualifiedResource unversioned.GroupResource, operation string, retryAfterSeconds int) *StatusError { return &StatusError{unversioned.Status{ Status: unversioned.StatusFailure, Code: http.StatusInternalServerError, @@ -255,12 +255,12 @@ func NewServerTimeout(qualifiedResource unversioned.GroupResource, operation str // NewServerTimeoutForKind should not exist. Server timeouts happen when accessing resources, the Kind is just what we // happened to be looking at when the request failed. This delegates to keep code sane, but we should work towards removing this. -func NewServerTimeoutForKind(qualifiedKind unversioned.GroupKind, operation string, retryAfterSeconds int) error { +func NewServerTimeoutForKind(qualifiedKind unversioned.GroupKind, operation string, retryAfterSeconds int) *StatusError { return NewServerTimeout(unversioned.GroupResource{Group: qualifiedKind.Group, Resource: qualifiedKind.Kind}, operation, retryAfterSeconds) } // NewInternalError returns an error indicating the item is invalid and cannot be processed. -func NewInternalError(err error) error { +func NewInternalError(err error) *StatusError { return &StatusError{unversioned.Status{ Status: unversioned.StatusFailure, Code: http.StatusInternalServerError, @@ -274,7 +274,7 @@ func NewInternalError(err error) error { // NewTimeoutError returns an error indicating that a timeout occurred before the request // could be completed. Clients may retry, but the operation may still complete. -func NewTimeoutError(message string, retryAfterSeconds int) error { +func NewTimeoutError(message string, retryAfterSeconds int) *StatusError { return &StatusError{unversioned.Status{ Status: unversioned.StatusFailure, Code: StatusServerTimeout, @@ -287,7 +287,7 @@ func NewTimeoutError(message string, retryAfterSeconds int) error { } // NewGenericServerResponse returns a new error for server responses that are not in a recognizable form. -func NewGenericServerResponse(code int, verb string, qualifiedResource unversioned.GroupResource, name, serverMessage string, retryAfterSeconds int, isUnexpectedResponse bool) error { +func NewGenericServerResponse(code int, verb string, qualifiedResource unversioned.GroupResource, name, serverMessage string, retryAfterSeconds int, isUnexpectedResponse bool) *StatusError { reason := unversioned.StatusReasonUnknown message := fmt.Sprintf("the server responded with the status code %d but did not return more information", code) switch code { diff --git a/vendor/k8s.io/kubernetes/pkg/api/helpers.go b/vendor/k8s.io/kubernetes/pkg/api/helpers.go index 96b7db58a8..7af5ed8af5 100644 --- a/vendor/k8s.io/kubernetes/pkg/api/helpers.go +++ b/vendor/k8s.io/kubernetes/pkg/api/helpers.go @@ -58,16 +58,7 @@ var Semantic = conversion.EqualitiesOrDie( // TODO: if we decide it's important, it should be safe to start comparing the format. // // Uninitialized quantities are equivalent to 0 quantities. - if a.Amount == nil && b.MilliValue() == 0 { - return true - } - if b.Amount == nil && a.MilliValue() == 0 { - return true - } - if a.Amount == nil || b.Amount == nil { - return false - } - return a.Amount.Cmp(b.Amount) == 0 + return a.Cmp(b) == 0 }, func(a, b unversioned.Time) bool { return a.UTC() == b.UTC() @@ -411,9 +402,19 @@ func NodeSelectorRequirementsAsSelector(nsm []NodeSelectorRequirement) (labels.S return selector, nil } -// AffinityAnnotationKey represents the key of affinity data (json serialized) -// in the Annotations of a Pod. -const AffinityAnnotationKey string = "scheduler.alpha.kubernetes.io/affinity" +const ( + // AffinityAnnotationKey represents the key of affinity data (json serialized) + // in the Annotations of a Pod. + AffinityAnnotationKey string = "scheduler.alpha.kubernetes.io/affinity" + + // TolerationsAnnotationKey represents the key of tolerations data (json serialized) + // in the Annotations of a Pod. + TolerationsAnnotationKey string = "scheduler.alpha.kubernetes.io/tolerations" + + // TaintsAnnotationKey represents the key of taints data (json serialized) + // in the Annotations of a Node. + TaintsAnnotationKey string = "scheduler.alpha.kubernetes.io/taints" +) // GetAffinityFromPod gets the json serialized affinity data from Pod.Annotations // and converts it to the Affinity type in api. @@ -427,3 +428,61 @@ func GetAffinityFromPodAnnotations(annotations map[string]string) (Affinity, err } return affinity, nil } + +// GetTolerationsFromPodAnnotations gets the json serialized tolerations data from Pod.Annotations +// and converts it to the []Toleration type in api. +func GetTolerationsFromPodAnnotations(annotations map[string]string) ([]Toleration, error) { + var tolerations []Toleration + if len(annotations) > 0 && annotations[TolerationsAnnotationKey] != "" { + err := json.Unmarshal([]byte(annotations[TolerationsAnnotationKey]), &tolerations) + if err != nil { + return tolerations, err + } + } + return tolerations, nil +} + +// GetTaintsFromNodeAnnotations gets the json serialized taints data from Pod.Annotations +// and converts it to the []Taint type in api. +func GetTaintsFromNodeAnnotations(annotations map[string]string) ([]Taint, error) { + var taints []Taint + if len(annotations) > 0 && annotations[TaintsAnnotationKey] != "" { + err := json.Unmarshal([]byte(annotations[TaintsAnnotationKey]), &taints) + if err != nil { + return []Taint{}, err + } + } + return taints, nil +} + +// TolerationToleratesTaint checks if the toleration tolerates the taint. +func TolerationToleratesTaint(toleration Toleration, taint Taint) bool { + if len(toleration.Effect) != 0 && toleration.Effect != taint.Effect { + return false + } + + if toleration.Key != taint.Key { + return false + } + // TODO: Use proper defaulting when Toleration becomes a field of PodSpec + if (len(toleration.Operator) == 0 || toleration.Operator == TolerationOpEqual) && toleration.Value == taint.Value { + return true + } + if toleration.Operator == TolerationOpExists { + return true + } + return false + +} + +// TaintToleratedByTolerations checks if taint is tolerated by any of the tolerations. +func TaintToleratedByTolerations(taint Taint, tolerations []Toleration) bool { + tolerated := false + for _, toleration := range tolerations { + if TolerationToleratesTaint(toleration, taint) { + tolerated = true + break + } + } + return tolerated +} diff --git a/vendor/k8s.io/kubernetes/pkg/api/meta.go b/vendor/k8s.io/kubernetes/pkg/api/meta.go index d5590f49d2..d0cddcadb0 100644 --- a/vendor/k8s.io/kubernetes/pkg/api/meta.go +++ b/vendor/k8s.io/kubernetes/pkg/api/meta.go @@ -17,6 +17,7 @@ limitations under the License. package api import ( + "k8s.io/kubernetes/pkg/api/meta/metatypes" "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/conversion" "k8s.io/kubernetes/pkg/runtime" @@ -89,3 +90,25 @@ func (meta *ObjectMeta) GetLabels() map[string]string { return m func (meta *ObjectMeta) SetLabels(labels map[string]string) { meta.Labels = labels } func (meta *ObjectMeta) GetAnnotations() map[string]string { return meta.Annotations } func (meta *ObjectMeta) SetAnnotations(annotations map[string]string) { meta.Annotations = annotations } + +func (meta *ObjectMeta) GetOwnerReferences() []metatypes.OwnerReference { + ret := make([]metatypes.OwnerReference, len(meta.OwnerReferences)) + for i := 0; i < len(meta.OwnerReferences); i++ { + ret[i].Kind = meta.OwnerReferences[i].Kind + ret[i].Name = meta.OwnerReferences[i].Name + ret[i].UID = meta.OwnerReferences[i].UID + ret[i].APIVersion = meta.OwnerReferences[i].APIVersion + } + return ret +} + +func (meta *ObjectMeta) SetOwnerReferences(references []metatypes.OwnerReference) { + newReferences := make([]OwnerReference, len(references)) + for i := 0; i < len(references); i++ { + newReferences[i].Kind = references[i].Kind + newReferences[i].Name = references[i].Name + newReferences[i].UID = references[i].UID + newReferences[i].APIVersion = references[i].APIVersion + } + meta.OwnerReferences = newReferences +} diff --git a/vendor/k8s.io/kubernetes/pkg/api/meta/interfaces.go b/vendor/k8s.io/kubernetes/pkg/api/meta/interfaces.go index ffebcf3436..36d41e8bda 100644 --- a/vendor/k8s.io/kubernetes/pkg/api/meta/interfaces.go +++ b/vendor/k8s.io/kubernetes/pkg/api/meta/interfaces.go @@ -17,6 +17,7 @@ limitations under the License. package meta import ( + "k8s.io/kubernetes/pkg/api/meta/metatypes" "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/types" @@ -57,6 +58,14 @@ type Object interface { SetLabels(labels map[string]string) GetAnnotations() map[string]string SetAnnotations(annotations map[string]string) + GetOwnerReferences() []metatypes.OwnerReference + SetOwnerReferences([]metatypes.OwnerReference) +} + +var _ Object = &runtime.Unstructured{} + +type ListMetaAccessor interface { + GetListMeta() List } // List lets you work with list metadata from any of the versioned or @@ -177,5 +186,3 @@ type RESTMapper interface { AliasesForResource(resource string) ([]string, bool) ResourceSingularizer(resource string) (singular string, err error) } - -var _ Object = &runtime.Unstructured{} diff --git a/vendor/k8s.io/kubernetes/pkg/api/meta/meta.go b/vendor/k8s.io/kubernetes/pkg/api/meta/meta.go index 4001d6969b..37ba93bdd9 100644 --- a/vendor/k8s.io/kubernetes/pkg/api/meta/meta.go +++ b/vendor/k8s.io/kubernetes/pkg/api/meta/meta.go @@ -20,6 +20,7 @@ import ( "fmt" "reflect" + "k8s.io/kubernetes/pkg/api/meta/metatypes" "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/conversion" "k8s.io/kubernetes/pkg/runtime" @@ -28,19 +29,53 @@ import ( "github.com/golang/glog" ) +func ListAccessor(obj interface{}) (List, error) { + if listMetaAccessor, ok := obj.(ListMetaAccessor); ok { + if om := listMetaAccessor.GetListMeta(); om != nil { + return om, nil + } + } + // we may get passed an object that is directly portable to List + if list, ok := obj.(List); ok { + return list, nil + } + glog.V(4).Infof("Calling ListAccessor on non-internal object: %v", reflect.TypeOf(obj)) + // legacy path for objects that do not implement List and ListMetaAccessor via + // reflection - very slow code path. + v, err := conversion.EnforcePtr(obj) + if err != nil { + return nil, err + } + t := v.Type() + if v.Kind() != reflect.Struct { + return nil, fmt.Errorf("expected struct, but got %v: %v (%#v)", v.Kind(), t, v.Interface()) + } + a := &genericAccessor{} + listMeta := v.FieldByName("ListMeta") + if listMeta.IsValid() { + // look for the ListMeta fields + if err := extractFromListMeta(listMeta, a); err != nil { + return nil, fmt.Errorf("unable to find list fields on %#v: %v", listMeta, err) + } + } else { + return nil, fmt.Errorf("unable to find listMeta on %#v", v) + } + return a, nil +} + // Accessor takes an arbitrary object pointer and returns meta.Interface. // obj must be a pointer to an API type. An error is returned if the minimum // required fields are missing. Fields that are not required return the default // value and are a no-op if set. func Accessor(obj interface{}) (Object, error) { - if oi, ok := obj.(ObjectMetaAccessor); ok { - if om := oi.GetObjectMeta(); om != nil { + if objectMetaAccessor, ok := obj.(ObjectMetaAccessor); ok { + if om := objectMetaAccessor.GetObjectMeta(); om != nil { return om, nil } } // we may get passed an object that is directly portable to Object - if oi, ok := obj.(Object); ok { - return oi, nil + if object, ok := obj.(Object); ok { + return object, nil } glog.V(4).Infof("Calling Accessor on non-internal object: %v", reflect.TypeOf(obj)) @@ -310,6 +345,40 @@ func (resourceAccessor) SetResourceVersion(obj runtime.Object, version string) e return nil } +// extractFromOwnerReference extracts v to o. v is the OwnerReferences field of an object. +func extractFromOwnerReference(v reflect.Value, o *metatypes.OwnerReference) error { + if err := runtime.Field(v, "APIVersion", &o.APIVersion); err != nil { + return err + } + if err := runtime.Field(v, "Kind", &o.Kind); err != nil { + return err + } + if err := runtime.Field(v, "Name", &o.Name); err != nil { + return err + } + if err := runtime.Field(v, "UID", &o.UID); err != nil { + return err + } + return nil +} + +// setOwnerReference sets v to o. v is the OwnerReferences field of an object. +func setOwnerReference(v reflect.Value, o *metatypes.OwnerReference) error { + if err := runtime.SetField(o.APIVersion, v, "APIVersion"); err != nil { + return err + } + if err := runtime.SetField(o.Kind, v, "Kind"); err != nil { + return err + } + if err := runtime.SetField(o.Name, v, "Name"); err != nil { + return err + } + if err := runtime.SetField(o.UID, v, "UID"); err != nil { + return err + } + return nil +} + // genericAccessor contains pointers to strings that can modify an arbitrary // struct and implements the Accessor interface. type genericAccessor struct { @@ -325,6 +394,7 @@ type genericAccessor struct { deletionTimestamp **unversioned.Time labels *map[string]string annotations *map[string]string + ownerReferences reflect.Value } func (a genericAccessor) GetNamespace() string { @@ -457,6 +527,41 @@ func (a genericAccessor) SetAnnotations(annotations map[string]string) { *a.annotations = annotations } +func (a genericAccessor) GetOwnerReferences() []metatypes.OwnerReference { + var ret []metatypes.OwnerReference + s := a.ownerReferences + if s.Kind() != reflect.Ptr || s.Elem().Kind() != reflect.Slice { + glog.Errorf("expect %v to be a pointer to slice", s) + return ret + } + s = s.Elem() + // Set the capacity to one element greater to avoid copy if the caller later append an element. + ret = make([]metatypes.OwnerReference, s.Len(), s.Len()+1) + for i := 0; i < s.Len(); i++ { + if err := extractFromOwnerReference(s.Index(i), &ret[i]); err != nil { + glog.Errorf("extractFromOwnerReference failed: %v", err) + return ret + } + } + return ret +} + +func (a genericAccessor) SetOwnerReferences(references []metatypes.OwnerReference) { + s := a.ownerReferences + if s.Kind() != reflect.Ptr || s.Elem().Kind() != reflect.Slice { + glog.Errorf("expect %v to be a pointer to slice", s) + } + s = s.Elem() + newReferences := reflect.MakeSlice(s.Type(), len(references), len(references)) + for i := 0; i < len(references); i++ { + if err := setOwnerReference(newReferences.Index(i), &references[i]); err != nil { + glog.Errorf("setOwnerReference failed: %v", err) + return + } + } + s.Set(newReferences) +} + // extractFromTypeMeta extracts pointers to version and kind fields from an object func extractFromTypeMeta(v reflect.Value, a *genericAccessor) error { if err := runtime.FieldPtr(v, "APIVersion", &a.apiVersion); err != nil { @@ -494,6 +599,14 @@ func extractFromObjectMeta(v reflect.Value, a *genericAccessor) error { if err := runtime.FieldPtr(v, "Annotations", &a.annotations); err != nil { return err } + ownerReferences := v.FieldByName("OwnerReferences") + if !ownerReferences.IsValid() { + return fmt.Errorf("struct %#v lacks OwnerReferences type", v) + } + if ownerReferences.Kind() != reflect.Slice { + return fmt.Errorf("expect %v to be a slice", ownerReferences.Kind()) + } + a.ownerReferences = ownerReferences.Addr() return nil } diff --git a/vendor/k8s.io/kubernetes/pkg/api/meta/metatypes/deep_copy_generated.go b/vendor/k8s.io/kubernetes/pkg/api/meta/metatypes/deep_copy_generated.go new file mode 100644 index 0000000000..f06a194e54 --- /dev/null +++ b/vendor/k8s.io/kubernetes/pkg/api/meta/metatypes/deep_copy_generated.go @@ -0,0 +1,33 @@ +// +build !ignore_autogenerated + +/* +Copyright 2016 The Kubernetes Authors All rights reserved. + +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. +*/ + +// This file was autogenerated by deepcopy-gen. Do not edit it manually! + +package metatypes + +import ( + conversion "k8s.io/kubernetes/pkg/conversion" +) + +func DeepCopy_metatypes_OwnerReference(in OwnerReference, out *OwnerReference, c *conversion.Cloner) error { + out.APIVersion = in.APIVersion + out.Kind = in.Kind + out.UID = in.UID + out.Name = in.Name + return nil +} diff --git a/vendor/k8s.io/kubernetes/pkg/api/meta/metatypes/types.go b/vendor/k8s.io/kubernetes/pkg/api/meta/metatypes/types.go new file mode 100644 index 0000000000..ca4edf72e2 --- /dev/null +++ b/vendor/k8s.io/kubernetes/pkg/api/meta/metatypes/types.go @@ -0,0 +1,29 @@ +/* +Copyright 2014 The Kubernetes Authors All rights reserved. + +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. +*/ + +// The types defined in this package are used by the meta package to represent +// the in-memory version of objects. We cannot reuse the __internal version of +// API objects because it causes import cycle. +package metatypes + +import "k8s.io/kubernetes/pkg/types" + +type OwnerReference struct { + APIVersion string + Kind string + UID types.UID + Name string +} diff --git a/vendor/k8s.io/kubernetes/pkg/api/resource/amount.go b/vendor/k8s.io/kubernetes/pkg/api/resource/amount.go new file mode 100644 index 0000000000..49caf3c173 --- /dev/null +++ b/vendor/k8s.io/kubernetes/pkg/api/resource/amount.go @@ -0,0 +1,298 @@ +/* +Copyright 2014 The Kubernetes Authors All rights reserved. + +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 resource + +import ( + "math/big" + "strconv" + + inf "gopkg.in/inf.v0" +) + +// Scale is used for getting and setting the base-10 scaled value. +// Base-2 scales are omitted for mathematical simplicity. +// See Quantity.ScaledValue for more details. +type Scale int32 + +// infScale adapts a Scale value to an inf.Scale value. +func (s Scale) infScale() inf.Scale { + return inf.Scale(-s) // inf.Scale is upside-down +} + +const ( + Nano Scale = -9 + Micro Scale = -6 + Milli Scale = -3 + Kilo Scale = 3 + Mega Scale = 6 + Giga Scale = 9 + Tera Scale = 12 + Peta Scale = 15 + Exa Scale = 18 +) + +var ( + Zero = int64Amount{} + + // Used by quantity strings - treat as read only + zeroBytes = []byte("0") +) + +// int64Amount represents a fixed precision numerator and arbitary scale exponent. It is faster +// than operations on inf.Dec for values that can be represented as int64. +type int64Amount struct { + value int64 + scale Scale +} + +// Sign returns 0 if the value is zero, -1 if it is less than 0, or 1 if it is greater than 0. +func (a int64Amount) Sign() int { + switch { + case a.value == 0: + return 0 + case a.value > 0: + return 1 + default: + return -1 + } +} + +// AsInt64 returns the current amount as an int64 at scale 0, or false if the value cannot be +// represented in an int64 OR would result in a loss of precision. This method is intended as +// an optimization to avoid calling AsDec. +func (a int64Amount) AsInt64() (int64, bool) { + if a.scale == 0 { + return a.value, true + } + if a.scale < 0 { + // TODO: attempt to reduce factors, although it is assumed that factors are reduced prior + // to the int64Amount being created. + return 0, false + } + return positiveScaleInt64(a.value, a.scale) +} + +// AsScaledInt64 returns an int64 representing the value of this amount at the specified scale, +// rounding up, or false if that would result in overflow. (1e20).AsScaledInt64(1) would result +// in overflow because 1e19 is not representable as an int64. Note that setting a scale larger +// than the current value may result in loss of precision - i.e. (1e-6).AsScaledInt64(0) would +// return 1, because 0.000001 is rounded up to 1. +func (a int64Amount) AsScaledInt64(scale Scale) (result int64, ok bool) { + if a.scale < scale { + result, _ = negativeScaleInt64(a.value, scale-a.scale) + return result, true + } + return positiveScaleInt64(a.value, a.scale-scale) +} + +// AsDec returns an inf.Dec representation of this value. +func (a int64Amount) AsDec() *inf.Dec { + var base inf.Dec + base.SetUnscaled(a.value) + base.SetScale(inf.Scale(-a.scale)) + return &base +} + +// Cmp returns 0 if a and b are equal, 1 if a is greater than b, or -1 if a is less than b. +func (a int64Amount) Cmp(b int64Amount) int { + switch { + case a.scale == b.scale: + // compare only the unscaled portion + case a.scale > b.scale: + result, remainder, exact := divideByScaleInt64(b.value, a.scale-b.scale) + if !exact { + return a.AsDec().Cmp(b.AsDec()) + } + if result == a.value { + switch { + case remainder == 0: + return 0 + case remainder > 0: + return -1 + default: + return 1 + } + } + b.value = result + default: + result, remainder, exact := divideByScaleInt64(a.value, b.scale-a.scale) + if !exact { + return a.AsDec().Cmp(b.AsDec()) + } + if result == b.value { + switch { + case remainder == 0: + return 0 + case remainder > 0: + return 1 + default: + return -1 + } + } + a.value = result + } + + switch { + case a.value == b.value: + return 0 + case a.value < b.value: + return -1 + default: + return 1 + } +} + +// Add adds two int64Amounts together, matching scales. It will return false and not mutate +// a if overflow or underflow would result. +func (a *int64Amount) Add(b int64Amount) bool { + switch { + case b.value == 0: + return true + case a.value == 0: + a.value = b.value + a.scale = b.scale + return true + case a.scale == b.scale: + c, ok := int64Add(a.value, b.value) + if !ok { + return false + } + a.value = c + case a.scale > b.scale: + c, ok := positiveScaleInt64(a.value, a.scale-b.scale) + if !ok { + return false + } + c, ok = int64Add(c, b.value) + if !ok { + return false + } + a.scale = b.scale + a.value = c + default: + c, ok := positiveScaleInt64(b.value, b.scale-a.scale) + if !ok { + return false + } + c, ok = int64Add(a.value, c) + if !ok { + return false + } + a.value = c + } + return true +} + +// Sub removes the value of b from the current amount, or returns false if underflow would result. +func (a *int64Amount) Sub(b int64Amount) bool { + return a.Add(int64Amount{value: -b.value, scale: b.scale}) +} + +// AsScale adjusts this amount to set a minimum scale, rounding up, and returns true iff no precision +// was lost. (1.1e5).AsScale(5) would return 1.1e5, but (1.1e5).AsScale(6) would return 1e6. +func (a int64Amount) AsScale(scale Scale) (int64Amount, bool) { + if a.scale >= scale { + return a, true + } + result, exact := negativeScaleInt64(a.value, scale-a.scale) + return int64Amount{value: result, scale: scale}, exact +} + +// AsCanonicalBytes accepts a buffer to write the base-10 string value of this field to, and returns +// either that buffer or a larger buffer and the current exponent of the value. The value is adjusted +// until the exponent is a multiple of 3 - i.e. 1.1e5 would return "110", 3. +func (a int64Amount) AsCanonicalBytes(out []byte) (result []byte, exponent int32) { + mantissa := a.value + exponent = int32(a.scale) + + amount, times := removeInt64Factors(mantissa, 10) + exponent += int32(times) + + // make sure exponent is a multiple of 3 + var ok bool + switch exponent % 3 { + case 1, -2: + amount, ok = int64MultiplyScale10(amount) + if !ok { + return infDecAmount{a.AsDec()}.AsCanonicalBytes(out) + } + exponent = exponent - 1 + case 2, -1: + amount, ok = int64MultiplyScale100(amount) + if !ok { + return infDecAmount{a.AsDec()}.AsCanonicalBytes(out) + } + exponent = exponent - 2 + } + return strconv.AppendInt(out, amount, 10), exponent +} + +// AsCanonicalBase1024Bytes accepts a buffer to write the base-1024 string value of this field to, and returns +// either that buffer or a larger buffer and the current exponent of the value. 2048 is 2 * 1024 ^ 1 and would +// return []byte("2048"), 1. +func (a int64Amount) AsCanonicalBase1024Bytes(out []byte) (result []byte, exponent int32) { + value, ok := a.AsScaledInt64(0) + if !ok { + return infDecAmount{a.AsDec()}.AsCanonicalBase1024Bytes(out) + } + amount, exponent := removeInt64Factors(value, 1024) + return strconv.AppendInt(out, amount, 10), exponent +} + +// infDecAmount implements common operations over an inf.Dec that are specific to the quantity +// representation. +type infDecAmount struct { + *inf.Dec +} + +// AsScale adjusts this amount to set a minimum scale, rounding up, and returns true iff no precision +// was lost. (1.1e5).AsScale(5) would return 1.1e5, but (1.1e5).AsScale(6) would return 1e6. +func (a infDecAmount) AsScale(scale Scale) (infDecAmount, bool) { + tmp := &inf.Dec{} + tmp.Round(a.Dec, scale.infScale(), inf.RoundUp) + return infDecAmount{tmp}, tmp.Cmp(a.Dec) == 0 +} + +// AsCanonicalBytes accepts a buffer to write the base-10 string value of this field to, and returns +// either that buffer or a larger buffer and the current exponent of the value. The value is adjusted +// until the exponent is a multiple of 3 - i.e. 1.1e5 would return "110", 3. +func (a infDecAmount) AsCanonicalBytes(out []byte) (result []byte, exponent int32) { + mantissa := a.Dec.UnscaledBig() + exponent = int32(-a.Dec.Scale()) + amount := big.NewInt(0).Set(mantissa) + // move all factors of 10 into the exponent for easy reasoning + amount, times := removeBigIntFactors(amount, bigTen) + exponent += times + + // make sure exponent is a multiple of 3 + for exponent%3 != 0 { + amount.Mul(amount, bigTen) + exponent-- + } + + return append(out, amount.String()...), exponent +} + +// AsCanonicalBase1024Bytes accepts a buffer to write the base-1024 string value of this field to, and returns +// either that buffer or a larger buffer and the current exponent of the value. 2048 is 2 * 1024 ^ 1 and would +// return []byte("2048"), 1. +func (a infDecAmount) AsCanonicalBase1024Bytes(out []byte) (result []byte, exponent int32) { + tmp := &inf.Dec{} + tmp.Round(a.Dec, 0, inf.RoundUp) + amount, exponent := removeBigIntFactors(tmp.UnscaledBig(), big1024) + return append(out, amount.String()...), exponent +} diff --git a/vendor/k8s.io/kubernetes/pkg/api/resource/deep_copy_generated.go b/vendor/k8s.io/kubernetes/pkg/api/resource/deep_copy_generated.go index 6a34e2d434..3f72141073 100644 --- a/vendor/k8s.io/kubernetes/pkg/api/resource/deep_copy_generated.go +++ b/vendor/k8s.io/kubernetes/pkg/api/resource/deep_copy_generated.go @@ -21,35 +21,27 @@ limitations under the License. package resource import ( - inf_v0 "gopkg.in/inf.v0" conversion "k8s.io/kubernetes/pkg/conversion" ) func DeepCopy_resource_Quantity(in Quantity, out *Quantity, c *conversion.Cloner) error { - if in.Amount != nil { - in, out := in.Amount, &out.Amount - *out = new(inf_v0.Dec) - if newVal, err := c.DeepCopy(*in); err != nil { - return err - } else { - **out = newVal.(inf_v0.Dec) - } + if newVal, err := c.DeepCopy(in.i); err != nil { + return err } else { - out.Amount = nil + out.i = newVal.(int64Amount) } - out.Format = in.Format - return nil -} - -func DeepCopy_resource_QuantityProto(in QuantityProto, out *QuantityProto, c *conversion.Cloner) error { - out.Format = in.Format - out.Scale = in.Scale - if in.Bigint != nil { - in, out := in.Bigint, &out.Bigint + if newVal, err := c.DeepCopy(in.d); err != nil { + return err + } else { + out.d = newVal.(infDecAmount) + } + if in.s != nil { + in, out := in.s, &out.s *out = make([]byte, len(in)) copy(*out, in) } else { - out.Bigint = nil + out.s = nil } + out.Format = in.Format return nil } diff --git a/vendor/k8s.io/kubernetes/pkg/api/resource/generated.pb.go b/vendor/k8s.io/kubernetes/pkg/api/resource/generated.pb.go index 7484f92761..cf9447a321 100644 --- a/vendor/k8s.io/kubernetes/pkg/api/resource/generated.pb.go +++ b/vendor/k8s.io/kubernetes/pkg/api/resource/generated.pb.go @@ -26,7 +26,6 @@ limitations under the License. It has these top-level messages: Quantity - QuantityProto */ package resource @@ -34,8 +33,6 @@ import proto "github.com/gogo/protobuf/proto" import fmt "fmt" import math "math" -import io "io" - // Reference imports to suppress errors if they are not otherwise used. var _ = proto.Marshal var _ = fmt.Errorf @@ -44,328 +41,6 @@ var _ = math.Inf func (m *Quantity) Reset() { *m = Quantity{} } func (*Quantity) ProtoMessage() {} -func (m *QuantityProto) Reset() { *m = QuantityProto{} } -func (m *QuantityProto) String() string { return proto.CompactTextString(m) } -func (*QuantityProto) ProtoMessage() {} - func init() { proto.RegisterType((*Quantity)(nil), "k8s.io.kubernetes.pkg.api.resource.Quantity") - proto.RegisterType((*QuantityProto)(nil), "k8s.io.kubernetes.pkg.api.resource.QuantityProto") } -func (m *QuantityProto) Marshal() (data []byte, err error) { - size := m.Size() - data = make([]byte, size) - n, err := m.MarshalTo(data) - if err != nil { - return nil, err - } - return data[:n], nil -} - -func (m *QuantityProto) MarshalTo(data []byte) (int, error) { - var i int - _ = i - var l int - _ = l - data[i] = 0xa - i++ - i = encodeVarintGenerated(data, i, uint64(len(m.Format))) - i += copy(data[i:], m.Format) - data[i] = 0x10 - i++ - i = encodeVarintGenerated(data, i, uint64(m.Scale)) - if m.Bigint != nil { - data[i] = 0x1a - i++ - i = encodeVarintGenerated(data, i, uint64(len(m.Bigint))) - i += copy(data[i:], m.Bigint) - } - return i, nil -} - -func encodeFixed64Generated(data []byte, offset int, v uint64) int { - data[offset] = uint8(v) - data[offset+1] = uint8(v >> 8) - data[offset+2] = uint8(v >> 16) - data[offset+3] = uint8(v >> 24) - data[offset+4] = uint8(v >> 32) - data[offset+5] = uint8(v >> 40) - data[offset+6] = uint8(v >> 48) - data[offset+7] = uint8(v >> 56) - return offset + 8 -} -func encodeFixed32Generated(data []byte, offset int, v uint32) int { - data[offset] = uint8(v) - data[offset+1] = uint8(v >> 8) - data[offset+2] = uint8(v >> 16) - data[offset+3] = uint8(v >> 24) - return offset + 4 -} -func encodeVarintGenerated(data []byte, offset int, v uint64) int { - for v >= 1<<7 { - data[offset] = uint8(v&0x7f | 0x80) - v >>= 7 - offset++ - } - data[offset] = uint8(v) - return offset + 1 -} -func (m *QuantityProto) Size() (n int) { - var l int - _ = l - l = len(m.Format) - n += 1 + l + sovGenerated(uint64(l)) - n += 1 + sovGenerated(uint64(m.Scale)) - if m.Bigint != nil { - l = len(m.Bigint) - n += 1 + l + sovGenerated(uint64(l)) - } - return n -} - -func sovGenerated(x uint64) (n int) { - for { - n++ - x >>= 7 - if x == 0 { - break - } - } - return n -} -func sozGenerated(x uint64) (n int) { - return sovGenerated(uint64((x << 1) ^ uint64((int64(x) >> 63)))) -} -func (m *QuantityProto) Unmarshal(data []byte) error { - l := len(data) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := data[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: QuantityProto: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: QuantityProto: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Format", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := data[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Format = Format(data[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Scale", wireType) - } - m.Scale = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := data[iNdEx] - iNdEx++ - m.Scale |= (int32(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Bigint", wireType) - } - var byteLen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := data[iNdEx] - iNdEx++ - byteLen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if byteLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + byteLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Bigint = append(m.Bigint[:0], data[iNdEx:postIndex]...) - if m.Bigint == nil { - m.Bigint = []byte{} - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(data[iNdEx:]) - if err != nil { - return err - } - if skippy < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func skipGenerated(data []byte) (n int, err error) { - l := len(data) - iNdEx := 0 - for iNdEx < l { - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflowGenerated - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - b := data[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - wireType := int(wire & 0x7) - switch wireType { - case 0: - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflowGenerated - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - iNdEx++ - if data[iNdEx-1] < 0x80 { - break - } - } - return iNdEx, nil - case 1: - iNdEx += 8 - return iNdEx, nil - case 2: - var length int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflowGenerated - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - b := data[iNdEx] - iNdEx++ - length |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - iNdEx += length - if length < 0 { - return 0, ErrInvalidLengthGenerated - } - return iNdEx, nil - case 3: - for { - var innerWire uint64 - var start int = iNdEx - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflowGenerated - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - b := data[iNdEx] - iNdEx++ - innerWire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - innerWireType := int(innerWire & 0x7) - if innerWireType == 4 { - break - } - next, err := skipGenerated(data[start:]) - if err != nil { - return 0, err - } - iNdEx = start + next - } - return iNdEx, nil - case 4: - return iNdEx, nil - case 5: - iNdEx += 4 - return iNdEx, nil - default: - return 0, fmt.Errorf("proto: illegal wireType %d", wireType) - } - } - panic("unreachable") -} - -var ( - ErrInvalidLengthGenerated = fmt.Errorf("proto: negative length found during unmarshaling") - ErrIntOverflowGenerated = fmt.Errorf("proto: integer overflow") -) diff --git a/vendor/k8s.io/kubernetes/pkg/api/resource/generated.proto b/vendor/k8s.io/kubernetes/pkg/api/resource/generated.proto index 34ede4581b..8a1376c32e 100644 --- a/vendor/k8s.io/kubernetes/pkg/api/resource/generated.proto +++ b/vendor/k8s.io/kubernetes/pkg/api/resource/generated.proto @@ -84,26 +84,10 @@ option go_package = "resource"; // cause implementors to also use a fixed point implementation. // // +protobuf=true -// +protobuf.embed=QuantityProto +// +protobuf.embed=string // +protobuf.options.marshal=false // +protobuf.options.(gogoproto.goproto_stringer)=false message Quantity { - optional QuantityProto QuantityProto = 1; -} - -// QuantityProto is a struct that is equivalent to Quantity, but intended for -// protobuf marshalling/unmarshalling. It is generated into a serialization -// that matches Quantity. Do not use in Go structs. -// -// +protobuf=true -message QuantityProto { - // The format of the quantity - optional string format = 1; - - // The scale dimension of the value - optional int32 scale = 2; - - // Bigint is serialized as a raw bytes array - optional bytes bigint = 3; + optional string string = 1; } diff --git a/vendor/k8s.io/kubernetes/pkg/api/resource/math.go b/vendor/k8s.io/kubernetes/pkg/api/resource/math.go new file mode 100644 index 0000000000..163aafa5db --- /dev/null +++ b/vendor/k8s.io/kubernetes/pkg/api/resource/math.go @@ -0,0 +1,327 @@ +/* +Copyright 2014 The Kubernetes Authors All rights reserved. + +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 resource + +import ( + "math/big" + + inf "gopkg.in/inf.v0" +) + +const ( + // maxInt64Factors is the highest value that will be checked when removing factors of 10 from an int64. + // It is also the maximum decimal digits that can be represented with an int64. + maxInt64Factors = 18 +) + +var ( + // Commonly needed big.Int values-- treat as read only! + bigTen = big.NewInt(10) + bigZero = big.NewInt(0) + bigOne = big.NewInt(1) + bigThousand = big.NewInt(1000) + big1024 = big.NewInt(1024) + + // Commonly needed inf.Dec values-- treat as read only! + decZero = inf.NewDec(0, 0) + decOne = inf.NewDec(1, 0) + decMinusOne = inf.NewDec(-1, 0) + decThousand = inf.NewDec(1000, 0) + dec1024 = inf.NewDec(1024, 0) + decMinus1024 = inf.NewDec(-1024, 0) + + // Largest (in magnitude) number allowed. + maxAllowed = infDecAmount{inf.NewDec((1<<63)-1, 0)} // == max int64 + + // The maximum value we can represent milli-units for. + // Compare with the return value of Quantity.Value() to + // see if it's safe to use Quantity.MilliValue(). + MaxMilliValue = int64(((1 << 63) - 1) / 1000) +) + +const mostNegative = -(mostPositive + 1) +const mostPositive = 1<<63 - 1 + +// int64Add returns a+b, or false if that would overflow int64. +func int64Add(a, b int64) (int64, bool) { + c := a + b + switch { + case a > 0 && b > 0: + if c < 0 { + return 0, false + } + case a < 0 && b < 0: + if c > 0 { + return 0, false + } + if a == mostNegative && b == mostNegative { + return 0, false + } + } + return c, true +} + +// int64Multiply returns a*b, or false if that would overflow or underflow int64. +func int64Multiply(a, b int64) (int64, bool) { + if a == 0 || b == 0 || a == 1 || b == 1 { + return a * b, true + } + if a == mostNegative || b == mostNegative { + return 0, false + } + c := a * b + return c, c/b == a +} + +// int64MultiplyScale returns a*b, assuming b is greater than one, or false if that would overflow or underflow int64. +// Use when b is known to be greater than one. +func int64MultiplyScale(a int64, b int64) (int64, bool) { + if a == 0 || a == 1 { + return a * b, true + } + if a == mostNegative && b != 1 { + return 0, false + } + c := a * b + return c, c/b == a +} + +// int64MultiplyScale10 multiplies a by 10, or returns false if that would overflow. This method is faster than +// int64Multiply(a, 10) because the compiler can optimize constant factor multiplication. +func int64MultiplyScale10(a int64) (int64, bool) { + if a == 0 || a == 1 { + return a * 10, true + } + if a == mostNegative { + return 0, false + } + c := a * 10 + return c, c/10 == a +} + +// int64MultiplyScale100 multiplies a by 100, or returns false if that would overflow. This method is faster than +// int64Multiply(a, 100) because the compiler can optimize constant factor multiplication. +func int64MultiplyScale100(a int64) (int64, bool) { + if a == 0 || a == 1 { + return a * 100, true + } + if a == mostNegative { + return 0, false + } + c := a * 100 + return c, c/100 == a +} + +// int64MultiplyScale1000 multiplies a by 1000, or returns false if that would overflow. This method is faster than +// int64Multiply(a, 1000) because the compiler can optimize constant factor multiplication. +func int64MultiplyScale1000(a int64) (int64, bool) { + if a == 0 || a == 1 { + return a * 1000, true + } + if a == mostNegative { + return 0, false + } + c := a * 1000 + return c, c/1000 == a +} + +// positiveScaleInt64 multiplies base by 10^scale, returning false if the +// value overflows. Passing a negative scale is undefined. +func positiveScaleInt64(base int64, scale Scale) (int64, bool) { + switch scale { + case 0: + return base, true + case 1: + return int64MultiplyScale10(base) + case 2: + return int64MultiplyScale100(base) + case 3: + return int64MultiplyScale1000(base) + case 6: + return int64MultiplyScale(base, 1000000) + case 9: + return int64MultiplyScale(base, 1000000000) + default: + value := base + var ok bool + for i := Scale(0); i < scale; i++ { + if value, ok = int64MultiplyScale(value, 10); !ok { + return 0, false + } + } + return value, true + } +} + +// negativeScaleInt64 reduces base by the provided scale, rounding up, until the +// value is zero or the scale is reached. Passing a negative scale is undefined. +// The value returned, if not exact, is rounded away from zero. +func negativeScaleInt64(base int64, scale Scale) (result int64, exact bool) { + if scale == 0 { + return base, true + } + + value := base + var fraction bool + for i := Scale(0); i < scale; i++ { + if !fraction && value%10 != 0 { + fraction = true + } + value = value / 10 + if value == 0 { + if fraction { + if base > 0 { + return 1, false + } + return -1, false + } + return 0, true + } + } + if fraction { + if base > 0 { + value += 1 + } else { + value += -1 + } + } + return value, !fraction +} + +func pow10Int64(b int64) int64 { + switch b { + case 0: + return 1 + case 1: + return 10 + case 2: + return 100 + case 3: + return 1000 + case 4: + return 10000 + case 5: + return 100000 + case 6: + return 1000000 + case 7: + return 10000000 + case 8: + return 100000000 + case 9: + return 1000000000 + case 10: + return 10000000000 + case 11: + return 100000000000 + case 12: + return 1000000000000 + case 13: + return 10000000000000 + case 14: + return 100000000000000 + case 15: + return 1000000000000000 + case 16: + return 10000000000000000 + case 17: + return 100000000000000000 + case 18: + return 1000000000000000000 + default: + return 0 + } +} + +// powInt64 raises a to the bth power. Is not overflow aware. +func powInt64(a, b int64) int64 { + p := int64(1) + for b > 0 { + if b&1 != 0 { + p *= a + } + b >>= 1 + a *= a + } + return p +} + +// negativeScaleInt64 returns the result of dividing base by scale * 10 and the remainder, or +// false if no such division is possible. Dividing by negative scales is undefined. +func divideByScaleInt64(base int64, scale Scale) (result, remainder int64, exact bool) { + if scale == 0 { + return base, 0, true + } + // the max scale representable in base 10 in an int64 is 18 decimal places + if scale >= 18 { + return 0, base, false + } + divisor := pow10Int64(int64(scale)) + return base / divisor, base % divisor, true +} + +// removeInt64Factors divides in a loop; the return values have the property that +// value == result * base ^ scale +func removeInt64Factors(value int64, base int64) (result int64, times int32) { + times = 0 + result = value + negative := result < 0 + if negative { + result = -result + } + switch base { + // allow the compiler to optimize the common cases + case 10: + for result >= 10 && result%10 == 0 { + times++ + result = result / 10 + } + // allow the compiler to optimize the common cases + case 1024: + for result >= 1024 && result%1024 == 0 { + times++ + result = result / 1024 + } + default: + for result >= base && result%base == 0 { + times++ + result = result / base + } + } + if negative { + result = -result + } + return result, times +} + +// removeBigIntFactors divides in a loop; the return values have the property that +// d == result * factor ^ times +// d may be modified in place. +// If d == 0, then the return values will be (0, 0) +func removeBigIntFactors(d, factor *big.Int) (result *big.Int, times int32) { + q := big.NewInt(0) + m := big.NewInt(0) + for d.Cmp(bigZero) != 0 { + q.DivMod(d, factor, m) + if m.Cmp(bigZero) != 0 { + break + } + times++ + d, q = q, d + } + return d, times +} diff --git a/vendor/k8s.io/kubernetes/pkg/api/resource/quantity.go b/vendor/k8s.io/kubernetes/pkg/api/resource/quantity.go index e61c8800ec..47c0ac08e8 100644 --- a/vendor/k8s.io/kubernetes/pkg/api/resource/quantity.go +++ b/vendor/k8s.io/kubernetes/pkg/api/resource/quantity.go @@ -17,10 +17,12 @@ limitations under the License. package resource import ( + "bytes" "errors" "fmt" "math/big" "regexp" + "strconv" "strings" flag "github.com/spf13/pflag" @@ -86,19 +88,34 @@ import ( // cause implementors to also use a fixed point implementation. // // +protobuf=true -// +protobuf.embed=QuantityProto +// +protobuf.embed=string // +protobuf.options.marshal=false // +protobuf.options.(gogoproto.goproto_stringer)=false type Quantity struct { - // Amount is public, so you can manipulate it if the accessor - // functions are not sufficient. - Amount *inf.Dec + // i is the quantity in int64 scaled form, if d.Dec == nil + i int64Amount + // d is the quantity in inf.Dec form if d.Dec != nil + d infDecAmount + // s is the generated value of this quantity to avoid recalculation + s []byte // Change Format at will. See the comment for Canonicalize for // more details. Format } +// CanonicalValue allows a quantity amount to be converted to a string. +type CanonicalValue interface { + // AsCanonicalBytes returns a byte array representing the string representation + // of the value mantissa and an int32 representing its exponent in base-10. Callers may + // pass a byte slice to the method to avoid allocations. + AsCanonicalBytes(out []byte) ([]byte, int32) + // AsCanonicalBase1024Bytes returns a byte array representing the string representation + // of the value mantissa and an int32 representing its exponent in base-1024. Callers + // may pass a byte slice to the method to avoid allocations. + AsCanonicalBase1024Bytes(out []byte) ([]byte, int32) +} + // Format lists the three possible formattings of a quantity. type Format string @@ -115,26 +132,9 @@ func MustParse(str string) Quantity { if err != nil { panic(fmt.Errorf("cannot parse '%v': %v", str, err)) } - return *q + return q } -// Scale is used for getting and setting the base-10 scaled value. -// Base-2 scales are omitted for mathematical simplicity. -// See Quantity.ScaledValue for more details. -type Scale int - -const ( - Nano Scale = -9 - Micro Scale = -6 - Milli Scale = -3 - Kilo Scale = 3 - Mega Scale = 6 - Giga Scale = 9 - Tera Scale = 12 - Peta Scale = 15 - Exa Scale = 18 -) - const ( // splitREString is used to separate a number from its suffix; as such, // this is overly permissive, but that's OK-- it will be checked later. @@ -149,47 +149,189 @@ var ( ErrFormatWrong = errors.New("quantities must match the regular expression '" + splitREString + "'") ErrNumeric = errors.New("unable to parse numeric part of quantity") ErrSuffix = errors.New("unable to parse quantity's suffix") - - // Commonly needed big.Int values-- treat as read only! - bigTen = big.NewInt(10) - bigZero = big.NewInt(0) - bigOne = big.NewInt(1) - bigThousand = big.NewInt(1000) - big1024 = big.NewInt(1024) - - // Commonly needed inf.Dec values-- treat as read only! - decZero = inf.NewDec(0, 0) - decOne = inf.NewDec(1, 0) - decMinusOne = inf.NewDec(-1, 0) - decThousand = inf.NewDec(1000, 0) - dec1024 = inf.NewDec(1024, 0) - decMinus1024 = inf.NewDec(-1024, 0) - - // Largest (in magnitude) number allowed. - maxAllowed = inf.NewDec((1<<63)-1, 0) // == max int64 - - // The maximum value we can represent milli-units for. - // Compare with the return value of Quantity.Value() to - // see if it's safe to use Quantity.MilliValue(). - MaxMilliValue = int64(((1 << 63) - 1) / 1000) ) +// parseQuantityString is a fast scanner for quantity values. +func parseQuantityString(str string) (positive bool, value, num, denom, suffix string, err error) { + positive = true + pos := 0 + end := len(str) + + // handle leading sign + if pos < end { + switch str[0] { + case '-': + positive = false + pos++ + case '+': + pos++ + } + } + + // strip leading zeros +Zeroes: + for i := pos; ; i++ { + if i >= end { + num = "0" + value = num + return + } + switch str[i] { + case '0': + pos++ + default: + break Zeroes + } + } + + // extract the numerator +Num: + for i := pos; ; i++ { + if i >= end { + num = str[pos:end] + value = str[0:end] + return + } + switch str[i] { + case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': + default: + num = str[pos:i] + pos = i + break Num + } + } + + // if we stripped all numerator positions, always return 0 + if len(num) == 0 { + num = "0" + } + + // handle a denominator + if pos < end && str[pos] == '.' { + pos++ + Denom: + for i := pos; ; i++ { + if i >= end { + denom = str[pos:end] + value = str[0:end] + return + } + switch str[i] { + case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': + default: + denom = str[pos:i] + pos = i + break Denom + } + } + // TODO: we currently allow 1.G, but we may not want to in the future. + // if len(denom) == 0 { + // err = ErrFormatWrong + // return + // } + } + value = str[0:pos] + + // grab the elements of the suffix + suffixStart := pos + for i := pos; ; i++ { + if i >= end { + suffix = str[suffixStart:end] + return + } + if !strings.ContainsAny(str[i:i+1], "eEinumkKMGTP") { + pos = i + break + } + } + if pos < end { + switch str[pos] { + case '-', '+': + pos++ + } + } +Suffix: + for i := pos; ; i++ { + if i >= end { + suffix = str[suffixStart:end] + return + } + switch str[i] { + case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': + default: + pos = i + break Suffix + } + } + // we encountered a non decimal in the Suffix loop, but the last character + // was not a valid exponent + err = ErrFormatWrong + return +} + // ParseQuantity turns str into a Quantity, or returns an error. -func ParseQuantity(str string) (*Quantity, error) { - parts := splitRE.FindStringSubmatch(strings.TrimSpace(str)) - // regexp returns are entire match, followed by an entry for each () section. - if len(parts) != 3 { - return nil, ErrFormatWrong +func ParseQuantity(str string) (Quantity, error) { + if len(str) == 0 { + return Quantity{}, ErrFormatWrong + } + if str == "0" { + return Quantity{Format: DecimalSI}, nil + } + + positive, value, num, denom, suf, err := parseQuantityString(str) + if err != nil { + return Quantity{}, err + } + + base, exponent, format, ok := quantitySuffixer.interpret(suffix(suf)) + if !ok { + return Quantity{}, ErrSuffix + } + + precision := int32(0) + scale := int32(0) + mantissa := int64(1) + switch format { + case DecimalExponent, DecimalSI: + scale = exponent + precision = maxInt64Factors - int32(len(num)+len(denom)) + case BinarySI: + scale = 0 + switch { + case exponent >= 0 && len(denom) == 0: + // only handle positive binary numbers with the fast path + mantissa = int64(int64(mantissa) << uint64(exponent)) + // 1Mi (2^20) has ~6 digits of decimal precision, so exponent*3/10 -1 is roughly the precision + precision = 15 - int32(len(num)) - int32(float32(exponent)*3/10) - 1 + default: + precision = -1 + } + } + + if precision >= 0 { + // if we have a denominator, shift the entire value to the left by the number of places in the + // denominator + scale -= int32(len(denom)) + if scale >= int32(Nano) { + shifted := num + denom + + var value int64 + value, err := strconv.ParseInt(shifted, 10, 64) + if err != nil { + return Quantity{}, ErrNumeric + } + if result, ok := int64Multiply(value, int64(mantissa)); ok { + if !positive { + result = -result + } + return Quantity{i: int64Amount{value: result, scale: Scale(scale)}, Format: format}, nil + } + } } amount := new(inf.Dec) - if _, ok := amount.SetString(parts[1]); !ok { - return nil, ErrNumeric - } - - base, exponent, format, ok := quantitySuffixer.interpret(suffix(parts[2])) - if !ok { - return nil, ErrSuffix + if _, ok := amount.SetString(value); !ok { + return Quantity{}, ErrNumeric } // So that no one but us has to think about suffixes, remove it. @@ -217,9 +359,11 @@ func ParseQuantity(str string) (*Quantity, error) { } // The max is just a simple cap. - if amount.Cmp(maxAllowed) > 0 { - amount.Set(maxAllowed) + // TODO: this prevents accumulating quantities greater than int64, for instance quota across a cluster + if format == BinarySI && amount.Cmp(maxAllowed.Dec) > 0 { + amount.Set(maxAllowed.Dec) } + if format == BinarySI && amount.Cmp(decOne) < 0 && amount.Cmp(decZero) > 0 { // This avoids rounding and hopefully confusion, too. format = DecimalSI @@ -228,25 +372,7 @@ func ParseQuantity(str string) (*Quantity, error) { amount.Neg(amount) } - return &Quantity{amount, format}, nil -} - -// removeFactors divides in a loop; the return values have the property that -// d == result * factor ^ times -// d may be modified in place. -// If d == 0, then the return values will be (0, 0) -func removeFactors(d, factor *big.Int) (result *big.Int, times int) { - q := big.NewInt(0) - m := big.NewInt(0) - for d.Cmp(bigZero) != 0 { - q.DivMod(d, factor, m) - if m.Cmp(bigZero) != 0 { - break - } - times++ - d, q = q, d - } - return d, times + return Quantity{d: infDecAmount{amount}, Format: format}, nil } // Canonicalize returns the canonical form of q and its suffix (see comment on Quantity). @@ -256,27 +382,22 @@ func removeFactors(d, factor *big.Int) (result *big.Int, times int) { // -1 and +1, it will be emitted as if q.Format were DecimalSI. // * Otherwise, if q.Format is set to BinarySI, frational parts of q.Amount will be // rounded up. (1.1i becomes 2i.) -func (q *Quantity) Canonicalize() (string, suffix) { - if q.Amount == nil { - return "0", "" - } - - // zero is zero always - if q.Amount.Cmp(&inf.Dec{}) == 0 { - return "0", "" +func (q *Quantity) CanonicalizeBytes(out []byte) (result, suffix []byte) { + if q.IsZero() { + return zeroBytes, nil } + var rounded CanonicalValue format := q.Format switch format { case DecimalExponent, DecimalSI: case BinarySI: - if q.Amount.Cmp(decMinus1024) > 0 && q.Amount.Cmp(dec1024) < 0 { + if q.CmpInt64(-1024) > 0 && q.CmpInt64(1024) < 0 { // This avoids rounding and hopefully confusion, too. format = DecimalSI } else { - tmp := &inf.Dec{} - tmp.Round(q.Amount, 0, inf.RoundUp) - if tmp.Cmp(q.Amount) != 0 { + var exact bool + if rounded, exact = q.AsScale(0); !exact { // Don't lose precision-- show as DecimalSI format = DecimalSI } @@ -289,125 +410,223 @@ func (q *Quantity) Canonicalize() (string, suffix) { // one of the other formats. switch format { case DecimalExponent, DecimalSI: - mantissa := q.Amount.UnscaledBig() - exponent := int(-q.Amount.Scale()) - amount := big.NewInt(0).Set(mantissa) - // move all factors of 10 into the exponent for easy reasoning - amount, times := removeFactors(amount, bigTen) - exponent += times - - // make sure exponent is a multiple of 3 - for exponent%3 != 0 { - amount.Mul(amount, bigTen) - exponent-- - } - - suffix, _ := quantitySuffixer.construct(10, exponent, format) - number := amount.String() + number, exponent := q.AsCanonicalBytes(out) + suffix, _ := quantitySuffixer.constructBytes(10, exponent, format) return number, suffix - case BinarySI: - tmp := &inf.Dec{} - tmp.Round(q.Amount, 0, inf.RoundUp) - - amount, exponent := removeFactors(tmp.UnscaledBig(), big1024) - suffix, _ := quantitySuffixer.construct(2, exponent*10, format) - number := amount.String() + default: + // format must be BinarySI + number, exponent := rounded.AsCanonicalBase1024Bytes(out) + suffix, _ := quantitySuffixer.constructBytes(2, exponent*10, format) return number, suffix } - return "0", "" } +// AsInt64 returns a representation of the current value as an int64 if a fast conversion +// is possible. If false is returned, callers must use the inf.Dec form of this quantity. +func (q *Quantity) AsInt64() (int64, bool) { + if q.d.Dec != nil { + return 0, false + } + return q.i.AsInt64() +} + +// ToDec promotes the quantity in place to use an inf.Dec representation and returns itself. +func (q *Quantity) ToDec() *Quantity { + if q.d.Dec == nil { + q.d.Dec = q.i.AsDec() + q.i = int64Amount{} + } + return q +} + +// AsDec returns the quantity as represented by a scaled inf.Dec. +func (q *Quantity) AsDec() *inf.Dec { + if q.d.Dec != nil { + return q.d.Dec + } + q.d.Dec = q.i.AsDec() + q.i = int64Amount{} + return q.d.Dec +} + +// AsCanonicalBytes returns the canonical byte representation of this quantity as a mantissa +// and base 10 exponent. The out byte slice may be passed to the method to avoid an extra +// allocation. +func (q *Quantity) AsCanonicalBytes(out []byte) (result []byte, exponent int32) { + if q.d.Dec != nil { + return q.d.AsCanonicalBytes(out) + } + return q.i.AsCanonicalBytes(out) +} + +// IsZero returns true if the quantity is equal to zero. +func (q *Quantity) IsZero() bool { + if q.d.Dec != nil { + return q.d.Dec.Sign() == 0 + } + return q.i.value == 0 +} + +// Sign returns 0 if the quantity is zero, -1 if the quantity is less than zero, or 1 if the +// quantity is greater than zero. +func (q *Quantity) Sign() int { + if q.d.Dec != nil { + return q.d.Dec.Sign() + } + return q.i.Sign() +} + +// AsScaled returns the current value, rounded up to the provided scale, and returns +// false if the scale resulted in a loss of precision. +func (q *Quantity) AsScale(scale Scale) (CanonicalValue, bool) { + if q.d.Dec != nil { + return q.d.AsScale(scale) + } + return q.i.AsScale(scale) +} + +// RoundUp updates the quantity to the provided scale, ensuring that the value is at +// least 1. False is returned if the rounding operation resulted in a loss of precision. +// Negative numbers are rounded away from zero (-9 scale 1 rounds to -10). +func (q *Quantity) RoundUp(scale Scale) bool { + if q.d.Dec != nil { + d, exact := q.d.AsScale(scale) + q.d = d + return exact + } + i, exact := q.i.AsScale(scale) + q.i = i + return exact +} + +// Add adds the provide y quantity to the current value. If the current value is zero, +// the format of the quantity will be updated to the format of y. +func (q *Quantity) Add(y Quantity) { + q.s = nil + if q.d.Dec == nil && y.d.Dec == nil { + if q.i.value == 0 { + q.Format = y.Format + } + if q.i.Add(y.i) { + return + } + } else if q.IsZero() { + q.Format = y.Format + } + q.ToDec().d.Dec.Add(q.d.Dec, y.AsDec()) +} + +// Sub subtracts the provided quantity from the current value in place. If the current +// value is zero, the format of the quantity will be updated to the format of y. +func (q *Quantity) Sub(y Quantity) { + q.s = nil + if q.IsZero() { + q.Format = y.Format + } + if q.d.Dec == nil && y.d.Dec == nil && q.i.Sub(y.i) { + return + } + q.ToDec().d.Dec.Sub(q.d.Dec, y.AsDec()) +} + +// Cmp returns 0 if the quantity is equal to y, -1 if the quantity is less than y, or 1 if the +// quantity is greater than y. +func (q *Quantity) Cmp(y Quantity) int { + if q.d.Dec == nil && y.d.Dec == nil { + return q.i.Cmp(y.i) + } + return q.AsDec().Cmp(y.AsDec()) +} + +// CmpInt64 returns 0 if the quantity is equal to y, -1 if the quantity is less than y, or 1 if the +// quantity is greater than y. +func (q *Quantity) CmpInt64(y int64) int { + if q.d.Dec != nil { + return q.d.Dec.Cmp(inf.NewDec(y, inf.Scale(0))) + } + return q.i.Cmp(int64Amount{value: y}) +} + +// Neg sets quantity to be the negative value of itself. +func (q *Quantity) Neg() { + q.s = nil + if q.d.Dec == nil { + q.i.value = -q.i.value + return + } + q.d.Dec.Neg(q.d.Dec) +} + +// toBytes ensures q.s is set to a byte slice representing the canonical string form of this +// quantity and then returns the value. CanonicalizeBytes is an expensive operation, and caching +// this result significantly reduces the cost of normal parse / marshal operations on Quantity. +func (q *Quantity) toBytes() []byte { + if q.s == nil { + result := make([]byte, 0, int64QuantityExpectedBytes) + number, suffix := q.CanonicalizeBytes(result) + number = append(number, suffix...) + q.s = number + } + return q.s +} + +// int64QuantityExpectedBytes is the expected width in bytes of the canonical string representation +// of most Quantity values. +const int64QuantityExpectedBytes = 18 + // String formats the Quantity as a string. func (q *Quantity) String() string { - number, suffix := q.Canonicalize() - return number + string(suffix) -} - -// Cmp compares q and y and returns: -// -// -1 if q < y -// 0 if q == y -// +1 if q > y -// -func (q *Quantity) Cmp(y Quantity) int { - if q.Amount == nil { - if y.Amount == nil { - return 0 - } - return -y.Amount.Sign() - } - if y.Amount == nil { - return q.Amount.Sign() - } - return q.Amount.Cmp(y.Amount) -} - -func (q *Quantity) Add(y Quantity) error { - switch { - case y.Amount == nil: - // Adding 0: do nothing. - case q.Amount == nil: - q.Amount = &inf.Dec{} - return q.Add(y) - default: - // we want to preserve the format of the non-zero value - zero := &inf.Dec{} - if q.Amount.Cmp(zero) == 0 && y.Amount.Cmp(zero) != 0 { - q.Format = y.Format - } - q.Amount.Add(q.Amount, y.Amount) - } - return nil -} - -func (q *Quantity) Sub(y Quantity) error { - switch { - case y.Amount == nil: - // Subtracting 0: do nothing. - case q.Amount == nil: - q.Amount = &inf.Dec{} - return q.Sub(y) - default: - // we want to preserve the format of the non-zero value - zero := &inf.Dec{} - if q.Amount.Cmp(zero) == 0 && y.Amount.Cmp(zero) != 0 { - q.Format = y.Format - } - q.Amount.Sub(q.Amount, y.Amount) - } - return nil -} - -// Neg sets q to the negative value of y. -// It updates the format of q to match y. -func (q *Quantity) Neg(y Quantity) error { - switch { - case y.Amount == nil: - *q = y - case q.Amount == nil: - q.Amount = &inf.Dec{} - fallthrough - default: - q.Amount.Neg(y.Amount) - q.Format = y.Format - } - return nil + return string(q.toBytes()) } // MarshalJSON implements the json.Marshaller interface. func (q Quantity) MarshalJSON() ([]byte, error) { - return []byte(`"` + q.String() + `"`), nil + if q.s != nil { + out := make([]byte, len(q.s)+2) + out[0], out[len(out)-1] = '"', '"' + copy(out[1:], q.s) + return out, nil + } + result := make([]byte, int64QuantityExpectedBytes, int64QuantityExpectedBytes) + result[0] = '"' + number, suffix := q.CanonicalizeBytes(result[1:1]) + // if the same slice was returned to us that we passed in, avoid another allocation by copying number into + // the source slice and returning that + if len(number) > 0 && &number[0] == &result[1] && (len(number)+len(suffix)+2) <= int64QuantityExpectedBytes { + number = append(number, suffix...) + number = append(number, '"') + return result[:1+len(number)], nil + } + // if CanonicalizeBytes needed more space than our slice provided, we may need to allocate again so use + // append + result = result[:1] + result = append(result, number...) + result = append(result, suffix...) + result = append(result, '"') + return result, nil } // UnmarshalJSON implements the json.Unmarshaller interface. func (q *Quantity) UnmarshalJSON(value []byte) error { - str := string(value) - parsed, err := ParseQuantity(strings.Trim(str, `"`)) + l := len(value) + if l == 4 && bytes.Equal(value, []byte("null")) { + q.d.Dec = nil + q.i = int64Amount{} + return nil + } + if l < 2 { + return ErrFormatWrong + } + if value[0] == '"' && value[l-1] == '"' { + value = value[1 : l-1] + } + parsed, err := ParseQuantity(string(value)) if err != nil { return err } + parsed.s = value // This copy is safe because parsed will not be referred to again. - *q = *parsed + *q = parsed return nil } @@ -415,7 +634,7 @@ func (q *Quantity) UnmarshalJSON(value []byte) error { // value in the given format. func NewQuantity(value int64, format Format) *Quantity { return &Quantity{ - Amount: inf.NewDec(value, 0), + i: int64Amount{value: value}, Format: format, } } @@ -426,7 +645,7 @@ func NewQuantity(value int64, format Format) *Quantity { // values x where (-1 < x < 1) && (x != 0). func NewMilliQuantity(value int64, format Format) *Quantity { return &Quantity{ - Amount: inf.NewDec(value, 3), + i: int64Amount{value: value, scale: -3}, Format: format, } } @@ -435,7 +654,7 @@ func NewMilliQuantity(value int64, format Format) *Quantity { // value * 10^scale in DecimalSI format. func NewScaledQuantity(value int64, scale Scale) *Quantity { return &Quantity{ - Amount: inf.NewDec(value, scale.infScale()), + i: int64Amount{value: value, scale: scale}, Format: DecimalSI, } } @@ -454,10 +673,12 @@ func (q *Quantity) MilliValue() int64 { // ScaledValue returns the value of ceil(q * 10^scale); this could overflow an int64. // To detect overflow, call Value() first and verify the expected magnitude. func (q *Quantity) ScaledValue(scale Scale) int64 { - if q.Amount == nil { - return 0 + if q.d.Dec == nil { + i, _ := q.i.AsScaledInt64(scale) + return i } - return scaledValue(q.Amount.UnscaledBig(), int(q.Amount.Scale()), int(scale.infScale())) + dec := q.d.Dec + return scaledValue(dec.UnscaledBig(), int(dec.Scale()), int(scale.infScale())) } // Set sets q's value to be value. @@ -472,22 +693,25 @@ func (q *Quantity) SetMilli(value int64) { // SetScaled sets q's value to be value * 10^scale func (q *Quantity) SetScaled(value int64, scale Scale) { - if q.Amount == nil { - q.Amount = &inf.Dec{} - } - q.Amount.SetUnscaled(value) - q.Amount.SetScale(scale.infScale()) + q.s = nil + q.d.Dec = nil + q.i = int64Amount{value: value, scale: scale} } // Copy is a convenience function that makes a deep copy for you. Non-deep // copies of quantities share pointers and you will regret that. func (q *Quantity) Copy() *Quantity { - if q.Amount == nil { - return NewQuantity(0, q.Format) + if q.d.Dec == nil { + return &Quantity{ + s: q.s, + i: q.i, + Format: q.Format, + } } tmp := &inf.Dec{} return &Quantity{ - Amount: tmp.Set(q.Amount), + s: q.s, + d: infDecAmount{tmp.Set(q.d.Dec)}, Format: q.Format, } } @@ -504,7 +728,7 @@ func (qf qFlag) Set(val string) error { return err } // This copy is OK because q will not be referenced again. - *qf.dest = *q + *qf.dest = q return nil } @@ -531,8 +755,3 @@ func QuantityFlag(flagName, defaultValue, description string) *Quantity { func NewQuantityFlagValue(q *Quantity) flag.Value { return qFlag{q} } - -// infScale adapts a Scale value to an inf.Scale value. -func (s Scale) infScale() inf.Scale { - return inf.Scale(-s) // inf.Scale is upside-down -} diff --git a/vendor/k8s.io/kubernetes/pkg/api/resource/quantity_proto.go b/vendor/k8s.io/kubernetes/pkg/api/resource/quantity_proto.go index 01d5c2997e..0159a4112b 100644 --- a/vendor/k8s.io/kubernetes/pkg/api/resource/quantity_proto.go +++ b/vendor/k8s.io/kubernetes/pkg/api/resource/quantity_proto.go @@ -17,62 +17,268 @@ limitations under the License. package resource import ( - "math/big" + "fmt" + "io" - inf "gopkg.in/inf.v0" + "github.com/gogo/protobuf/proto" ) -// QuantityProto is a struct that is equivalent to Quantity, but intended for -// protobuf marshalling/unmarshalling. It is generated into a serialization -// that matches Quantity. Do not use in Go structs. -// -// +protobuf=true -type QuantityProto struct { - // The format of the quantity - Format Format `protobuf:"bytes,1,opt,name=format,casttype=Format"` - // The scale dimension of the value - Scale int32 `protobuf:"varint,2,opt,name=scale"` - // Bigint is serialized as a raw bytes array - Bigint []byte `protobuf:"bytes,3,opt,name=bigint"` +var _ proto.Sizer = &Quantity{} + +func (m *Quantity) Marshal() (data []byte, err error) { + size := m.Size() + data = make([]byte, size) + n, err := m.MarshalTo(data) + if err != nil { + return nil, err + } + return data[:n], nil } -// ProtoTime returns the Time as a new ProtoTime value. -func (q *Quantity) QuantityProto() *QuantityProto { - if q == nil { - return &QuantityProto{} - } - p := &QuantityProto{ - Format: q.Format, - } - if q.Amount != nil { - p.Scale = int32(q.Amount.Scale()) - p.Bigint = q.Amount.UnscaledBig().Bytes() - } - return p +// MarshalTo is a customized version of the generated Protobuf unmarshaler for a struct +// with a single string field. +func (m *Quantity) MarshalTo(data []byte) (int, error) { + var i int + _ = i + var l int + _ = l + + data[i] = 0xa + i++ + // BEGIN CUSTOM MARSHAL + out := m.toBytes() + i = encodeVarintGenerated(data, i, uint64(len(out))) + i += copy(data[i:], out) + // END CUSTOM MARSHAL + + return i, nil } -// Size implements the protobuf marshalling interface. -func (q *Quantity) Size() (n int) { return q.QuantityProto().Size() } - -// Reset implements the protobuf marshalling interface. -func (q *Quantity) Unmarshal(data []byte) error { - p := QuantityProto{} - if err := p.Unmarshal(data); err != nil { - return err +func encodeVarintGenerated(data []byte, offset int, v uint64) int { + for v >= 1<<7 { + data[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + data[offset] = uint8(v) + return offset + 1 +} + +func (m *Quantity) Size() (n int) { + var l int + _ = l + + // BEGIN CUSTOM SIZE + l = len(m.toBytes()) + // END CUSTOM SIZE + + n += 1 + l + sovGenerated(uint64(l)) + return n +} + +func sovGenerated(x uint64) (n int) { + for { + n++ + x >>= 7 + if x == 0 { + break + } + } + return n +} + +// Unmarshal is a customized version of the generated Protobuf unmarshaler for a struct +// with a single string field. +func (m *Quantity) Unmarshal(data []byte) error { + l := len(data) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Quantity: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Quantity: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field String_", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := string(data[iNdEx:postIndex]) + + // BEGIN CUSTOM DECODE + p, err := ParseQuantity(s) + if err != nil { + return err + } + *m = p + // END CUSTOM DECODE + + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(data[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF } - q.Format = p.Format - b := big.NewInt(0) - b.SetBytes(p.Bigint) - q.Amount = inf.NewDecBig(b, inf.Scale(p.Scale)) return nil } -// Marshal implements the protobuf marshalling interface. -func (q *Quantity) Marshal() (data []byte, err error) { - return q.QuantityProto().Marshal() +func skipGenerated(data []byte) (n int, err error) { + l := len(data) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowGenerated + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowGenerated + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if data[iNdEx-1] < 0x80 { + break + } + } + return iNdEx, nil + case 1: + iNdEx += 8 + return iNdEx, nil + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowGenerated + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + iNdEx += length + if length < 0 { + return 0, ErrInvalidLengthGenerated + } + return iNdEx, nil + case 3: + for { + var innerWire uint64 + var start int = iNdEx + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowGenerated + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + innerWire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + innerWireType := int(innerWire & 0x7) + if innerWireType == 4 { + break + } + next, err := skipGenerated(data[start:]) + if err != nil { + return 0, err + } + iNdEx = start + next + } + return iNdEx, nil + case 4: + return iNdEx, nil + case 5: + iNdEx += 4 + return iNdEx, nil + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + } + panic("unreachable") } -// MarshalTo implements the protobuf marshalling interface. -func (q *Quantity) MarshalTo(data []byte) (int, error) { - return q.QuantityProto().MarshalTo(data) -} +var ( + ErrInvalidLengthGenerated = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowGenerated = fmt.Errorf("proto: integer overflow") +) diff --git a/vendor/k8s.io/kubernetes/pkg/api/resource/suffix.go b/vendor/k8s.io/kubernetes/pkg/api/resource/suffix.go index 529712365d..0aa2ce2bf6 100644 --- a/vendor/k8s.io/kubernetes/pkg/api/resource/suffix.go +++ b/vendor/k8s.io/kubernetes/pkg/api/resource/suffix.go @@ -24,8 +24,9 @@ type suffix string // suffixer can interpret and construct suffixes. type suffixer interface { - interpret(suffix) (base, exponent int, fmt Format, ok bool) - construct(base, exponent int, fmt Format) (s suffix, ok bool) + interpret(suffix) (base, exponent int32, fmt Format, ok bool) + construct(base, exponent int32, fmt Format) (s suffix, ok bool) + constructBytes(base, exponent int32, fmt Format) (s []byte, ok bool) } // quantitySuffixer handles suffixes for all three formats that quantity @@ -33,12 +34,13 @@ type suffixer interface { var quantitySuffixer = newSuffixer() type bePair struct { - base, exponent int + base, exponent int32 } type listSuffixer struct { - suffixToBE map[suffix]bePair - beToSuffix map[bePair]suffix + suffixToBE map[suffix]bePair + beToSuffix map[bePair]suffix + beToSuffixBytes map[bePair][]byte } func (ls *listSuffixer) addSuffix(s suffix, pair bePair) { @@ -48,11 +50,15 @@ func (ls *listSuffixer) addSuffix(s suffix, pair bePair) { if ls.beToSuffix == nil { ls.beToSuffix = map[bePair]suffix{} } + if ls.beToSuffixBytes == nil { + ls.beToSuffixBytes = map[bePair][]byte{} + } ls.suffixToBE[s] = pair ls.beToSuffix[pair] = s + ls.beToSuffixBytes[pair] = []byte(s) } -func (ls *listSuffixer) lookup(s suffix) (base, exponent int, ok bool) { +func (ls *listSuffixer) lookup(s suffix) (base, exponent int32, ok bool) { pair, ok := ls.suffixToBE[s] if !ok { return 0, 0, false @@ -60,19 +66,50 @@ func (ls *listSuffixer) lookup(s suffix) (base, exponent int, ok bool) { return pair.base, pair.exponent, true } -func (ls *listSuffixer) construct(base, exponent int) (s suffix, ok bool) { +func (ls *listSuffixer) construct(base, exponent int32) (s suffix, ok bool) { s, ok = ls.beToSuffix[bePair{base, exponent}] return } +func (ls *listSuffixer) constructBytes(base, exponent int32) (s []byte, ok bool) { + s, ok = ls.beToSuffixBytes[bePair{base, exponent}] + return +} + type suffixHandler struct { decSuffixes listSuffixer binSuffixes listSuffixer } +type fastLookup struct { + *suffixHandler +} + +func (l fastLookup) interpret(s suffix) (base, exponent int32, format Format, ok bool) { + switch s { + case "": + return 10, 0, DecimalSI, true + case "n": + return 10, -9, DecimalSI, true + case "u": + return 10, -6, DecimalSI, true + case "m": + return 10, -3, DecimalSI, true + case "k": + return 10, 3, DecimalSI, true + case "M": + return 10, 6, DecimalSI, true + case "G": + return 10, 9, DecimalSI, true + } + return l.suffixHandler.interpret(s) +} + func newSuffixer() suffixer { sh := &suffixHandler{} + // IMPORTANT: if you change this section you must change fastLookup + sh.binSuffixes.addSuffix("Ki", bePair{2, 10}) sh.binSuffixes.addSuffix("Mi", bePair{2, 20}) sh.binSuffixes.addSuffix("Gi", bePair{2, 30}) @@ -94,10 +131,10 @@ func newSuffixer() suffixer { sh.decSuffixes.addSuffix("P", bePair{10, 15}) sh.decSuffixes.addSuffix("E", bePair{10, 18}) - return sh + return fastLookup{sh} } -func (sh *suffixHandler) construct(base, exponent int, fmt Format) (s suffix, ok bool) { +func (sh *suffixHandler) construct(base, exponent int32, fmt Format) (s suffix, ok bool) { switch fmt { case DecimalSI: return sh.decSuffixes.construct(base, exponent) @@ -115,7 +152,32 @@ func (sh *suffixHandler) construct(base, exponent int, fmt Format) (s suffix, ok return "", false } -func (sh *suffixHandler) interpret(suffix suffix) (base, exponent int, fmt Format, ok bool) { +func (sh *suffixHandler) constructBytes(base, exponent int32, format Format) (s []byte, ok bool) { + switch format { + case DecimalSI: + return sh.decSuffixes.constructBytes(base, exponent) + case BinarySI: + return sh.binSuffixes.constructBytes(base, exponent) + case DecimalExponent: + if base != 10 { + return nil, false + } + if exponent == 0 { + return nil, true + } + result := make([]byte, 8, 8) + result[0] = 'e' + number := strconv.AppendInt(result[1:1], int64(exponent), 10) + if &result[1] == &number[0] { + return result[:1+len(number)], true + } + result = append(result[:1], number...) + return result, true + } + return nil, false +} + +func (sh *suffixHandler) interpret(suffix suffix) (base, exponent int32, fmt Format, ok bool) { // Try lookup tables first if b, e, ok := sh.decSuffixes.lookup(suffix); ok { return b, e, DecimalSI, true @@ -129,7 +191,7 @@ func (sh *suffixHandler) interpret(suffix suffix) (base, exponent int, fmt Forma if err != nil { return 0, 0, DecimalExponent, false } - return 10, int(parsed), DecimalExponent, true + return 10, int32(parsed), DecimalExponent, true } return 0, 0, DecimalExponent, false diff --git a/vendor/k8s.io/kubernetes/pkg/api/resource_helpers.go b/vendor/k8s.io/kubernetes/pkg/api/resource_helpers.go index 9f71502a61..2a664d8dc8 100644 --- a/vendor/k8s.io/kubernetes/pkg/api/resource_helpers.go +++ b/vendor/k8s.io/kubernetes/pkg/api/resource_helpers.go @@ -92,6 +92,8 @@ func GetPodReadyCondition(status PodStatus) *PodCondition { return condition } +// GetPodCondition extracts the provided condition from the given status and returns that. +// Returns nil and -1 if the condition is not present, and the the index of the located condition. func GetPodCondition(status *PodStatus, conditionType PodConditionType) (int, *PodCondition) { for i, c := range status.Conditions { if c.Type == conditionType { @@ -118,13 +120,16 @@ func UpdatePodCondition(status *PodStatus, condition *PodCondition) bool { if condition.Status == oldCondition.Status { condition.LastTransitionTime = oldCondition.LastTransitionTime } + + isEqual := condition.Status == oldCondition.Status && + condition.Reason == oldCondition.Reason && + condition.Message == oldCondition.Message && + condition.LastProbeTime.Equal(oldCondition.LastProbeTime) && + condition.LastTransitionTime.Equal(oldCondition.LastTransitionTime) + status.Conditions[conditionIndex] = *condition // Return true if one of the fields have changed. - return condition.Status != oldCondition.Status || - condition.Reason != oldCondition.Reason || - condition.Message != oldCondition.Message || - !condition.LastProbeTime.Equal(oldCondition.LastProbeTime) || - !condition.LastTransitionTime.Equal(oldCondition.LastTransitionTime) + return !isEqual } } @@ -146,15 +151,40 @@ func PodRequestsAndLimits(pod *Pod) (reqs map[ResourceName]resource.Quantity, li for name, quantity := range container.Resources.Requests { if value, ok := reqs[name]; !ok { reqs[name] = *quantity.Copy() - } else if err = value.Add(quantity); err != nil { - return nil, nil, err + } else { + value.Add(quantity) + reqs[name] = value } } for name, quantity := range container.Resources.Limits { if value, ok := limits[name]; !ok { limits[name] = *quantity.Copy() - } else if err = value.Add(quantity); err != nil { - return nil, nil, err + } else { + value.Add(quantity) + limits[name] = value + } + } + } + // init containers define the minimum of any resource + for _, container := range pod.Spec.InitContainers { + for name, quantity := range container.Resources.Requests { + value, ok := reqs[name] + if !ok { + reqs[name] = *quantity.Copy() + continue + } + if quantity.Cmp(value) > 0 { + reqs[name] = *quantity.Copy() + } + } + for name, quantity := range container.Resources.Limits { + value, ok := limits[name] + if !ok { + limits[name] = *quantity.Copy() + continue + } + if quantity.Cmp(value) > 0 { + limits[name] = *quantity.Copy() } } } diff --git a/vendor/k8s.io/kubernetes/pkg/api/types.generated.go b/vendor/k8s.io/kubernetes/pkg/api/types.generated.go index 94f775f6f6..77c65ff8c7 100644 --- a/vendor/k8s.io/kubernetes/pkg/api/types.generated.go +++ b/vendor/k8s.io/kubernetes/pkg/api/types.generated.go @@ -1,5 +1,5 @@ /* -Copyright 2015 The Kubernetes Authors All rights reserved. +Copyright 2016 The Kubernetes Authors All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -25,14 +25,13 @@ import ( "errors" "fmt" codec1978 "github.com/ugorji/go/codec" - pkg4_inf_v0 "gopkg.in/inf.v0" pkg3_resource "k8s.io/kubernetes/pkg/api/resource" pkg2_unversioned "k8s.io/kubernetes/pkg/api/unversioned" - pkg7_fields "k8s.io/kubernetes/pkg/fields" - pkg6_labels "k8s.io/kubernetes/pkg/labels" - pkg8_runtime "k8s.io/kubernetes/pkg/runtime" + pkg6_fields "k8s.io/kubernetes/pkg/fields" + pkg5_labels "k8s.io/kubernetes/pkg/labels" + pkg7_runtime "k8s.io/kubernetes/pkg/runtime" pkg1_types "k8s.io/kubernetes/pkg/types" - pkg5_intstr "k8s.io/kubernetes/pkg/util/intstr" + pkg4_intstr "k8s.io/kubernetes/pkg/util/intstr" "reflect" "runtime" time "time" @@ -68,16 +67,15 @@ func init() { panic(err) } if false { // reference the types, but skip this branch at build/run time - var v0 pkg4_inf_v0.Dec - var v1 pkg3_resource.Quantity - var v2 pkg2_unversioned.Time - var v3 pkg7_fields.Selector - var v4 pkg6_labels.Selector - var v5 pkg8_runtime.Object - var v6 pkg1_types.UID - var v7 pkg5_intstr.IntOrString - var v8 time.Time - _, _, _, _, _, _, _, _, _ = v0, v1, v2, v3, v4, v5, v6, v7, v8 + var v0 pkg3_resource.Quantity + var v1 pkg2_unversioned.Time + var v2 pkg6_fields.Selector + var v3 pkg5_labels.Selector + var v4 pkg7_runtime.Object + var v5 pkg1_types.UID + var v6 pkg4_intstr.IntOrString + var v7 time.Time + _, _, _, _, _, _, _, _ = v0, v1, v2, v3, v4, v5, v6, v7 } } @@ -1082,7 +1080,7 @@ func (x *Volume) CodecEncodeSelf(e *codec1978.Encoder) { } else { yysep2 := !z.EncBinary() yy2arr2 := z.EncBasicHandle().StructToArray - var yyq2 [20]bool + var yyq2 [21]bool _, _, _ = yysep2, yyq2, yy2arr2 const yyr2 bool = false yyq2[1] = x.VolumeSource.HostPath != nil && x.HostPath != nil @@ -1104,9 +1102,10 @@ func (x *Volume) CodecEncodeSelf(e *codec1978.Encoder) { yyq2[17] = x.VolumeSource.FC != nil && x.FC != nil yyq2[18] = x.VolumeSource.AzureFile != nil && x.AzureFile != nil yyq2[19] = x.VolumeSource.ConfigMap != nil && x.ConfigMap != nil + yyq2[20] = x.VolumeSource.VsphereVolume != nil && x.VsphereVolume != nil var yynn2 int if yyr2 || yy2arr2 { - r.EncodeArrayStart(20) + r.EncodeArrayStart(21) } else { yynn2 = 1 for _, b := range yyq2 { @@ -1839,6 +1838,43 @@ func (x *Volume) CodecEncodeSelf(e *codec1978.Encoder) { } } } + var yyn63 bool + if x.VolumeSource.VsphereVolume == nil { + yyn63 = true + goto LABEL63 + } + LABEL63: + if yyr2 || yy2arr2 { + if yyn63 { + r.EncodeNil() + } else { + z.EncSendContainerState(codecSelfer_containerArrayElem1234) + if yyq2[20] { + if x.VsphereVolume == nil { + r.EncodeNil() + } else { + x.VsphereVolume.CodecEncodeSelf(e) + } + } else { + r.EncodeNil() + } + } + } else { + if yyq2[20] { + z.EncSendContainerState(codecSelfer_containerMapKey1234) + r.EncodeString(codecSelferC_UTF81234, string("vsphereVolume")) + z.EncSendContainerState(codecSelfer_containerMapValue1234) + if yyn63 { + r.EncodeNil() + } else { + if x.VsphereVolume == nil { + r.EncodeNil() + } else { + x.VsphereVolume.CodecEncodeSelf(e) + } + } + } + } if yyr2 || yy2arr2 { z.EncSendContainerState(codecSelfer_containerArrayEnd1234) } else { @@ -2172,6 +2208,20 @@ func (x *Volume) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) { } x.ConfigMap.CodecDecodeSelf(d) } + case "vsphereVolume": + if x.VolumeSource.VsphereVolume == nil { + x.VolumeSource.VsphereVolume = new(VsphereVirtualDiskVolumeSource) + } + if r.TryDecodeAsNil() { + if x.VsphereVolume != nil { + x.VsphereVolume = nil + } + } else { + if x.VsphereVolume == nil { + x.VsphereVolume = new(VsphereVirtualDiskVolumeSource) + } + x.VsphereVolume.CodecDecodeSelf(d) + } default: z.DecStructFieldNotFound(-1, yys3) } // end switch yys3 @@ -2183,16 +2233,16 @@ func (x *Volume) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { var h codecSelfer1234 z, r := codec1978.GenHelperDecoder(d) _, _, _ = h, z, r - var yyj24 int - var yyb24 bool - var yyhl24 bool = l >= 0 - yyj24++ - if yyhl24 { - yyb24 = yyj24 > l + var yyj25 int + var yyb25 bool + var yyhl25 bool = l >= 0 + yyj25++ + if yyhl25 { + yyb25 = yyj25 > l } else { - yyb24 = r.CheckBreak() + yyb25 = r.CheckBreak() } - if yyb24 { + if yyb25 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -2205,13 +2255,13 @@ func (x *Volume) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { if x.VolumeSource.HostPath == nil { x.VolumeSource.HostPath = new(HostPathVolumeSource) } - yyj24++ - if yyhl24 { - yyb24 = yyj24 > l + yyj25++ + if yyhl25 { + yyb25 = yyj25 > l } else { - yyb24 = r.CheckBreak() + yyb25 = r.CheckBreak() } - if yyb24 { + if yyb25 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -2229,13 +2279,13 @@ func (x *Volume) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { if x.VolumeSource.EmptyDir == nil { x.VolumeSource.EmptyDir = new(EmptyDirVolumeSource) } - yyj24++ - if yyhl24 { - yyb24 = yyj24 > l + yyj25++ + if yyhl25 { + yyb25 = yyj25 > l } else { - yyb24 = r.CheckBreak() + yyb25 = r.CheckBreak() } - if yyb24 { + if yyb25 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -2253,13 +2303,13 @@ func (x *Volume) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { if x.VolumeSource.GCEPersistentDisk == nil { x.VolumeSource.GCEPersistentDisk = new(GCEPersistentDiskVolumeSource) } - yyj24++ - if yyhl24 { - yyb24 = yyj24 > l + yyj25++ + if yyhl25 { + yyb25 = yyj25 > l } else { - yyb24 = r.CheckBreak() + yyb25 = r.CheckBreak() } - if yyb24 { + if yyb25 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -2277,13 +2327,13 @@ func (x *Volume) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { if x.VolumeSource.AWSElasticBlockStore == nil { x.VolumeSource.AWSElasticBlockStore = new(AWSElasticBlockStoreVolumeSource) } - yyj24++ - if yyhl24 { - yyb24 = yyj24 > l + yyj25++ + if yyhl25 { + yyb25 = yyj25 > l } else { - yyb24 = r.CheckBreak() + yyb25 = r.CheckBreak() } - if yyb24 { + if yyb25 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -2301,13 +2351,13 @@ func (x *Volume) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { if x.VolumeSource.GitRepo == nil { x.VolumeSource.GitRepo = new(GitRepoVolumeSource) } - yyj24++ - if yyhl24 { - yyb24 = yyj24 > l + yyj25++ + if yyhl25 { + yyb25 = yyj25 > l } else { - yyb24 = r.CheckBreak() + yyb25 = r.CheckBreak() } - if yyb24 { + if yyb25 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -2325,13 +2375,13 @@ func (x *Volume) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { if x.VolumeSource.Secret == nil { x.VolumeSource.Secret = new(SecretVolumeSource) } - yyj24++ - if yyhl24 { - yyb24 = yyj24 > l + yyj25++ + if yyhl25 { + yyb25 = yyj25 > l } else { - yyb24 = r.CheckBreak() + yyb25 = r.CheckBreak() } - if yyb24 { + if yyb25 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -2349,13 +2399,13 @@ func (x *Volume) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { if x.VolumeSource.NFS == nil { x.VolumeSource.NFS = new(NFSVolumeSource) } - yyj24++ - if yyhl24 { - yyb24 = yyj24 > l + yyj25++ + if yyhl25 { + yyb25 = yyj25 > l } else { - yyb24 = r.CheckBreak() + yyb25 = r.CheckBreak() } - if yyb24 { + if yyb25 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -2373,13 +2423,13 @@ func (x *Volume) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { if x.VolumeSource.ISCSI == nil { x.VolumeSource.ISCSI = new(ISCSIVolumeSource) } - yyj24++ - if yyhl24 { - yyb24 = yyj24 > l + yyj25++ + if yyhl25 { + yyb25 = yyj25 > l } else { - yyb24 = r.CheckBreak() + yyb25 = r.CheckBreak() } - if yyb24 { + if yyb25 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -2397,13 +2447,13 @@ func (x *Volume) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { if x.VolumeSource.Glusterfs == nil { x.VolumeSource.Glusterfs = new(GlusterfsVolumeSource) } - yyj24++ - if yyhl24 { - yyb24 = yyj24 > l + yyj25++ + if yyhl25 { + yyb25 = yyj25 > l } else { - yyb24 = r.CheckBreak() + yyb25 = r.CheckBreak() } - if yyb24 { + if yyb25 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -2421,13 +2471,13 @@ func (x *Volume) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { if x.VolumeSource.PersistentVolumeClaim == nil { x.VolumeSource.PersistentVolumeClaim = new(PersistentVolumeClaimVolumeSource) } - yyj24++ - if yyhl24 { - yyb24 = yyj24 > l + yyj25++ + if yyhl25 { + yyb25 = yyj25 > l } else { - yyb24 = r.CheckBreak() + yyb25 = r.CheckBreak() } - if yyb24 { + if yyb25 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -2445,13 +2495,13 @@ func (x *Volume) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { if x.VolumeSource.RBD == nil { x.VolumeSource.RBD = new(RBDVolumeSource) } - yyj24++ - if yyhl24 { - yyb24 = yyj24 > l + yyj25++ + if yyhl25 { + yyb25 = yyj25 > l } else { - yyb24 = r.CheckBreak() + yyb25 = r.CheckBreak() } - if yyb24 { + if yyb25 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -2469,13 +2519,13 @@ func (x *Volume) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { if x.VolumeSource.FlexVolume == nil { x.VolumeSource.FlexVolume = new(FlexVolumeSource) } - yyj24++ - if yyhl24 { - yyb24 = yyj24 > l + yyj25++ + if yyhl25 { + yyb25 = yyj25 > l } else { - yyb24 = r.CheckBreak() + yyb25 = r.CheckBreak() } - if yyb24 { + if yyb25 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -2493,13 +2543,13 @@ func (x *Volume) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { if x.VolumeSource.Cinder == nil { x.VolumeSource.Cinder = new(CinderVolumeSource) } - yyj24++ - if yyhl24 { - yyb24 = yyj24 > l + yyj25++ + if yyhl25 { + yyb25 = yyj25 > l } else { - yyb24 = r.CheckBreak() + yyb25 = r.CheckBreak() } - if yyb24 { + if yyb25 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -2517,13 +2567,13 @@ func (x *Volume) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { if x.VolumeSource.CephFS == nil { x.VolumeSource.CephFS = new(CephFSVolumeSource) } - yyj24++ - if yyhl24 { - yyb24 = yyj24 > l + yyj25++ + if yyhl25 { + yyb25 = yyj25 > l } else { - yyb24 = r.CheckBreak() + yyb25 = r.CheckBreak() } - if yyb24 { + if yyb25 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -2541,13 +2591,13 @@ func (x *Volume) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { if x.VolumeSource.Flocker == nil { x.VolumeSource.Flocker = new(FlockerVolumeSource) } - yyj24++ - if yyhl24 { - yyb24 = yyj24 > l + yyj25++ + if yyhl25 { + yyb25 = yyj25 > l } else { - yyb24 = r.CheckBreak() + yyb25 = r.CheckBreak() } - if yyb24 { + if yyb25 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -2565,13 +2615,13 @@ func (x *Volume) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { if x.VolumeSource.DownwardAPI == nil { x.VolumeSource.DownwardAPI = new(DownwardAPIVolumeSource) } - yyj24++ - if yyhl24 { - yyb24 = yyj24 > l + yyj25++ + if yyhl25 { + yyb25 = yyj25 > l } else { - yyb24 = r.CheckBreak() + yyb25 = r.CheckBreak() } - if yyb24 { + if yyb25 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -2589,13 +2639,13 @@ func (x *Volume) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { if x.VolumeSource.FC == nil { x.VolumeSource.FC = new(FCVolumeSource) } - yyj24++ - if yyhl24 { - yyb24 = yyj24 > l + yyj25++ + if yyhl25 { + yyb25 = yyj25 > l } else { - yyb24 = r.CheckBreak() + yyb25 = r.CheckBreak() } - if yyb24 { + if yyb25 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -2613,13 +2663,13 @@ func (x *Volume) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { if x.VolumeSource.AzureFile == nil { x.VolumeSource.AzureFile = new(AzureFileVolumeSource) } - yyj24++ - if yyhl24 { - yyb24 = yyj24 > l + yyj25++ + if yyhl25 { + yyb25 = yyj25 > l } else { - yyb24 = r.CheckBreak() + yyb25 = r.CheckBreak() } - if yyb24 { + if yyb25 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -2637,13 +2687,13 @@ func (x *Volume) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { if x.VolumeSource.ConfigMap == nil { x.VolumeSource.ConfigMap = new(ConfigMapVolumeSource) } - yyj24++ - if yyhl24 { - yyb24 = yyj24 > l + yyj25++ + if yyhl25 { + yyb25 = yyj25 > l } else { - yyb24 = r.CheckBreak() + yyb25 = r.CheckBreak() } - if yyb24 { + if yyb25 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -2658,18 +2708,42 @@ func (x *Volume) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { } x.ConfigMap.CodecDecodeSelf(d) } - for { - yyj24++ - if yyhl24 { - yyb24 = yyj24 > l - } else { - yyb24 = r.CheckBreak() + if x.VolumeSource.VsphereVolume == nil { + x.VolumeSource.VsphereVolume = new(VsphereVirtualDiskVolumeSource) + } + yyj25++ + if yyhl25 { + yyb25 = yyj25 > l + } else { + yyb25 = r.CheckBreak() + } + if yyb25 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) + return + } + z.DecSendContainerState(codecSelfer_containerArrayElem1234) + if r.TryDecodeAsNil() { + if x.VsphereVolume != nil { + x.VsphereVolume = nil } - if yyb24 { + } else { + if x.VsphereVolume == nil { + x.VsphereVolume = new(VsphereVirtualDiskVolumeSource) + } + x.VsphereVolume.CodecDecodeSelf(d) + } + for { + yyj25++ + if yyhl25 { + yyb25 = yyj25 > l + } else { + yyb25 = r.CheckBreak() + } + if yyb25 { break } z.DecSendContainerState(codecSelfer_containerArrayElem1234) - z.DecStructFieldNotFound(yyj24-1, "") + z.DecStructFieldNotFound(yyj25-1, "") } z.DecSendContainerState(codecSelfer_containerArrayEnd1234) } @@ -2688,7 +2762,7 @@ func (x *VolumeSource) CodecEncodeSelf(e *codec1978.Encoder) { } else { yysep2 := !z.EncBinary() yy2arr2 := z.EncBasicHandle().StructToArray - var yyq2 [19]bool + var yyq2 [20]bool _, _, _ = yysep2, yyq2, yy2arr2 const yyr2 bool = false yyq2[0] = x.HostPath != nil @@ -2710,9 +2784,10 @@ func (x *VolumeSource) CodecEncodeSelf(e *codec1978.Encoder) { yyq2[16] = x.FC != nil yyq2[17] = x.AzureFile != nil yyq2[18] = x.ConfigMap != nil + yyq2[19] = x.VsphereVolume != nil var yynn2 int if yyr2 || yy2arr2 { - r.EncodeArrayStart(19) + r.EncodeArrayStart(20) } else { yynn2 = 0 for _, b := range yyq2 { @@ -3160,6 +3235,29 @@ func (x *VolumeSource) CodecEncodeSelf(e *codec1978.Encoder) { } } } + if yyr2 || yy2arr2 { + z.EncSendContainerState(codecSelfer_containerArrayElem1234) + if yyq2[19] { + if x.VsphereVolume == nil { + r.EncodeNil() + } else { + x.VsphereVolume.CodecEncodeSelf(e) + } + } else { + r.EncodeNil() + } + } else { + if yyq2[19] { + z.EncSendContainerState(codecSelfer_containerMapKey1234) + r.EncodeString(codecSelferC_UTF81234, string("vsphereVolume")) + z.EncSendContainerState(codecSelfer_containerMapValue1234) + if x.VsphereVolume == nil { + r.EncodeNil() + } else { + x.VsphereVolume.CodecEncodeSelf(e) + } + } + } if yyr2 || yy2arr2 { z.EncSendContainerState(codecSelfer_containerArrayEnd1234) } else { @@ -3430,6 +3528,17 @@ func (x *VolumeSource) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) { } x.ConfigMap.CodecDecodeSelf(d) } + case "vsphereVolume": + if r.TryDecodeAsNil() { + if x.VsphereVolume != nil { + x.VsphereVolume = nil + } + } else { + if x.VsphereVolume == nil { + x.VsphereVolume = new(VsphereVirtualDiskVolumeSource) + } + x.VsphereVolume.CodecDecodeSelf(d) + } default: z.DecStructFieldNotFound(-1, yys3) } // end switch yys3 @@ -3441,16 +3550,16 @@ func (x *VolumeSource) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { var h codecSelfer1234 z, r := codec1978.GenHelperDecoder(d) _, _, _ = h, z, r - var yyj23 int - var yyb23 bool - var yyhl23 bool = l >= 0 - yyj23++ - if yyhl23 { - yyb23 = yyj23 > l + var yyj24 int + var yyb24 bool + var yyhl24 bool = l >= 0 + yyj24++ + if yyhl24 { + yyb24 = yyj24 > l } else { - yyb23 = r.CheckBreak() + yyb24 = r.CheckBreak() } - if yyb23 { + if yyb24 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -3465,13 +3574,13 @@ func (x *VolumeSource) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { } x.HostPath.CodecDecodeSelf(d) } - yyj23++ - if yyhl23 { - yyb23 = yyj23 > l + yyj24++ + if yyhl24 { + yyb24 = yyj24 > l } else { - yyb23 = r.CheckBreak() + yyb24 = r.CheckBreak() } - if yyb23 { + if yyb24 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -3486,13 +3595,13 @@ func (x *VolumeSource) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { } x.EmptyDir.CodecDecodeSelf(d) } - yyj23++ - if yyhl23 { - yyb23 = yyj23 > l + yyj24++ + if yyhl24 { + yyb24 = yyj24 > l } else { - yyb23 = r.CheckBreak() + yyb24 = r.CheckBreak() } - if yyb23 { + if yyb24 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -3507,13 +3616,13 @@ func (x *VolumeSource) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { } x.GCEPersistentDisk.CodecDecodeSelf(d) } - yyj23++ - if yyhl23 { - yyb23 = yyj23 > l + yyj24++ + if yyhl24 { + yyb24 = yyj24 > l } else { - yyb23 = r.CheckBreak() + yyb24 = r.CheckBreak() } - if yyb23 { + if yyb24 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -3528,13 +3637,13 @@ func (x *VolumeSource) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { } x.AWSElasticBlockStore.CodecDecodeSelf(d) } - yyj23++ - if yyhl23 { - yyb23 = yyj23 > l + yyj24++ + if yyhl24 { + yyb24 = yyj24 > l } else { - yyb23 = r.CheckBreak() + yyb24 = r.CheckBreak() } - if yyb23 { + if yyb24 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -3549,13 +3658,13 @@ func (x *VolumeSource) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { } x.GitRepo.CodecDecodeSelf(d) } - yyj23++ - if yyhl23 { - yyb23 = yyj23 > l + yyj24++ + if yyhl24 { + yyb24 = yyj24 > l } else { - yyb23 = r.CheckBreak() + yyb24 = r.CheckBreak() } - if yyb23 { + if yyb24 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -3570,13 +3679,13 @@ func (x *VolumeSource) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { } x.Secret.CodecDecodeSelf(d) } - yyj23++ - if yyhl23 { - yyb23 = yyj23 > l + yyj24++ + if yyhl24 { + yyb24 = yyj24 > l } else { - yyb23 = r.CheckBreak() + yyb24 = r.CheckBreak() } - if yyb23 { + if yyb24 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -3591,13 +3700,13 @@ func (x *VolumeSource) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { } x.NFS.CodecDecodeSelf(d) } - yyj23++ - if yyhl23 { - yyb23 = yyj23 > l + yyj24++ + if yyhl24 { + yyb24 = yyj24 > l } else { - yyb23 = r.CheckBreak() + yyb24 = r.CheckBreak() } - if yyb23 { + if yyb24 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -3612,13 +3721,13 @@ func (x *VolumeSource) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { } x.ISCSI.CodecDecodeSelf(d) } - yyj23++ - if yyhl23 { - yyb23 = yyj23 > l + yyj24++ + if yyhl24 { + yyb24 = yyj24 > l } else { - yyb23 = r.CheckBreak() + yyb24 = r.CheckBreak() } - if yyb23 { + if yyb24 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -3633,13 +3742,13 @@ func (x *VolumeSource) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { } x.Glusterfs.CodecDecodeSelf(d) } - yyj23++ - if yyhl23 { - yyb23 = yyj23 > l + yyj24++ + if yyhl24 { + yyb24 = yyj24 > l } else { - yyb23 = r.CheckBreak() + yyb24 = r.CheckBreak() } - if yyb23 { + if yyb24 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -3654,13 +3763,13 @@ func (x *VolumeSource) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { } x.PersistentVolumeClaim.CodecDecodeSelf(d) } - yyj23++ - if yyhl23 { - yyb23 = yyj23 > l + yyj24++ + if yyhl24 { + yyb24 = yyj24 > l } else { - yyb23 = r.CheckBreak() + yyb24 = r.CheckBreak() } - if yyb23 { + if yyb24 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -3675,13 +3784,13 @@ func (x *VolumeSource) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { } x.RBD.CodecDecodeSelf(d) } - yyj23++ - if yyhl23 { - yyb23 = yyj23 > l + yyj24++ + if yyhl24 { + yyb24 = yyj24 > l } else { - yyb23 = r.CheckBreak() + yyb24 = r.CheckBreak() } - if yyb23 { + if yyb24 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -3696,13 +3805,13 @@ func (x *VolumeSource) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { } x.FlexVolume.CodecDecodeSelf(d) } - yyj23++ - if yyhl23 { - yyb23 = yyj23 > l + yyj24++ + if yyhl24 { + yyb24 = yyj24 > l } else { - yyb23 = r.CheckBreak() + yyb24 = r.CheckBreak() } - if yyb23 { + if yyb24 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -3717,13 +3826,13 @@ func (x *VolumeSource) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { } x.Cinder.CodecDecodeSelf(d) } - yyj23++ - if yyhl23 { - yyb23 = yyj23 > l + yyj24++ + if yyhl24 { + yyb24 = yyj24 > l } else { - yyb23 = r.CheckBreak() + yyb24 = r.CheckBreak() } - if yyb23 { + if yyb24 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -3738,13 +3847,13 @@ func (x *VolumeSource) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { } x.CephFS.CodecDecodeSelf(d) } - yyj23++ - if yyhl23 { - yyb23 = yyj23 > l + yyj24++ + if yyhl24 { + yyb24 = yyj24 > l } else { - yyb23 = r.CheckBreak() + yyb24 = r.CheckBreak() } - if yyb23 { + if yyb24 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -3759,13 +3868,13 @@ func (x *VolumeSource) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { } x.Flocker.CodecDecodeSelf(d) } - yyj23++ - if yyhl23 { - yyb23 = yyj23 > l + yyj24++ + if yyhl24 { + yyb24 = yyj24 > l } else { - yyb23 = r.CheckBreak() + yyb24 = r.CheckBreak() } - if yyb23 { + if yyb24 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -3780,13 +3889,13 @@ func (x *VolumeSource) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { } x.DownwardAPI.CodecDecodeSelf(d) } - yyj23++ - if yyhl23 { - yyb23 = yyj23 > l + yyj24++ + if yyhl24 { + yyb24 = yyj24 > l } else { - yyb23 = r.CheckBreak() + yyb24 = r.CheckBreak() } - if yyb23 { + if yyb24 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -3801,13 +3910,13 @@ func (x *VolumeSource) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { } x.FC.CodecDecodeSelf(d) } - yyj23++ - if yyhl23 { - yyb23 = yyj23 > l + yyj24++ + if yyhl24 { + yyb24 = yyj24 > l } else { - yyb23 = r.CheckBreak() + yyb24 = r.CheckBreak() } - if yyb23 { + if yyb24 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -3822,13 +3931,13 @@ func (x *VolumeSource) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { } x.AzureFile.CodecDecodeSelf(d) } - yyj23++ - if yyhl23 { - yyb23 = yyj23 > l + yyj24++ + if yyhl24 { + yyb24 = yyj24 > l } else { - yyb23 = r.CheckBreak() + yyb24 = r.CheckBreak() } - if yyb23 { + if yyb24 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -3843,18 +3952,39 @@ func (x *VolumeSource) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { } x.ConfigMap.CodecDecodeSelf(d) } - for { - yyj23++ - if yyhl23 { - yyb23 = yyj23 > l - } else { - yyb23 = r.CheckBreak() + yyj24++ + if yyhl24 { + yyb24 = yyj24 > l + } else { + yyb24 = r.CheckBreak() + } + if yyb24 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) + return + } + z.DecSendContainerState(codecSelfer_containerArrayElem1234) + if r.TryDecodeAsNil() { + if x.VsphereVolume != nil { + x.VsphereVolume = nil } - if yyb23 { + } else { + if x.VsphereVolume == nil { + x.VsphereVolume = new(VsphereVirtualDiskVolumeSource) + } + x.VsphereVolume.CodecDecodeSelf(d) + } + for { + yyj24++ + if yyhl24 { + yyb24 = yyj24 > l + } else { + yyb24 = r.CheckBreak() + } + if yyb24 { break } z.DecSendContainerState(codecSelfer_containerArrayElem1234) - z.DecStructFieldNotFound(yyj23-1, "") + z.DecStructFieldNotFound(yyj24-1, "") } z.DecSendContainerState(codecSelfer_containerArrayEnd1234) } @@ -3873,7 +4003,7 @@ func (x *PersistentVolumeSource) CodecEncodeSelf(e *codec1978.Encoder) { } else { yysep2 := !z.EncBinary() yy2arr2 := z.EncBasicHandle().StructToArray - var yyq2 [13]bool + var yyq2 [14]bool _, _, _ = yysep2, yyq2, yy2arr2 const yyr2 bool = false yyq2[0] = x.GCEPersistentDisk != nil @@ -3889,9 +4019,10 @@ func (x *PersistentVolumeSource) CodecEncodeSelf(e *codec1978.Encoder) { yyq2[10] = x.FC != nil yyq2[11] = x.Flocker != nil yyq2[12] = x.AzureFile != nil + yyq2[13] = x.VsphereVolume != nil var yynn2 int if yyr2 || yy2arr2 { - r.EncodeArrayStart(13) + r.EncodeArrayStart(14) } else { yynn2 = 0 for _, b := range yyq2 { @@ -4201,6 +4332,29 @@ func (x *PersistentVolumeSource) CodecEncodeSelf(e *codec1978.Encoder) { } } } + if yyr2 || yy2arr2 { + z.EncSendContainerState(codecSelfer_containerArrayElem1234) + if yyq2[13] { + if x.VsphereVolume == nil { + r.EncodeNil() + } else { + x.VsphereVolume.CodecEncodeSelf(e) + } + } else { + r.EncodeNil() + } + } else { + if yyq2[13] { + z.EncSendContainerState(codecSelfer_containerMapKey1234) + r.EncodeString(codecSelferC_UTF81234, string("vsphereVolume")) + z.EncSendContainerState(codecSelfer_containerMapValue1234) + if x.VsphereVolume == nil { + r.EncodeNil() + } else { + x.VsphereVolume.CodecEncodeSelf(e) + } + } + } if yyr2 || yy2arr2 { z.EncSendContainerState(codecSelfer_containerArrayEnd1234) } else { @@ -4405,6 +4559,17 @@ func (x *PersistentVolumeSource) codecDecodeSelfFromMap(l int, d *codec1978.Deco } x.AzureFile.CodecDecodeSelf(d) } + case "vsphereVolume": + if r.TryDecodeAsNil() { + if x.VsphereVolume != nil { + x.VsphereVolume = nil + } + } else { + if x.VsphereVolume == nil { + x.VsphereVolume = new(VsphereVirtualDiskVolumeSource) + } + x.VsphereVolume.CodecDecodeSelf(d) + } default: z.DecStructFieldNotFound(-1, yys3) } // end switch yys3 @@ -4416,16 +4581,16 @@ func (x *PersistentVolumeSource) codecDecodeSelfFromArray(l int, d *codec1978.De var h codecSelfer1234 z, r := codec1978.GenHelperDecoder(d) _, _, _ = h, z, r - var yyj17 int - var yyb17 bool - var yyhl17 bool = l >= 0 - yyj17++ - if yyhl17 { - yyb17 = yyj17 > l + var yyj18 int + var yyb18 bool + var yyhl18 bool = l >= 0 + yyj18++ + if yyhl18 { + yyb18 = yyj18 > l } else { - yyb17 = r.CheckBreak() + yyb18 = r.CheckBreak() } - if yyb17 { + if yyb18 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -4440,13 +4605,13 @@ func (x *PersistentVolumeSource) codecDecodeSelfFromArray(l int, d *codec1978.De } x.GCEPersistentDisk.CodecDecodeSelf(d) } - yyj17++ - if yyhl17 { - yyb17 = yyj17 > l + yyj18++ + if yyhl18 { + yyb18 = yyj18 > l } else { - yyb17 = r.CheckBreak() + yyb18 = r.CheckBreak() } - if yyb17 { + if yyb18 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -4461,13 +4626,13 @@ func (x *PersistentVolumeSource) codecDecodeSelfFromArray(l int, d *codec1978.De } x.AWSElasticBlockStore.CodecDecodeSelf(d) } - yyj17++ - if yyhl17 { - yyb17 = yyj17 > l + yyj18++ + if yyhl18 { + yyb18 = yyj18 > l } else { - yyb17 = r.CheckBreak() + yyb18 = r.CheckBreak() } - if yyb17 { + if yyb18 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -4482,13 +4647,13 @@ func (x *PersistentVolumeSource) codecDecodeSelfFromArray(l int, d *codec1978.De } x.HostPath.CodecDecodeSelf(d) } - yyj17++ - if yyhl17 { - yyb17 = yyj17 > l + yyj18++ + if yyhl18 { + yyb18 = yyj18 > l } else { - yyb17 = r.CheckBreak() + yyb18 = r.CheckBreak() } - if yyb17 { + if yyb18 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -4503,13 +4668,13 @@ func (x *PersistentVolumeSource) codecDecodeSelfFromArray(l int, d *codec1978.De } x.Glusterfs.CodecDecodeSelf(d) } - yyj17++ - if yyhl17 { - yyb17 = yyj17 > l + yyj18++ + if yyhl18 { + yyb18 = yyj18 > l } else { - yyb17 = r.CheckBreak() + yyb18 = r.CheckBreak() } - if yyb17 { + if yyb18 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -4524,13 +4689,13 @@ func (x *PersistentVolumeSource) codecDecodeSelfFromArray(l int, d *codec1978.De } x.NFS.CodecDecodeSelf(d) } - yyj17++ - if yyhl17 { - yyb17 = yyj17 > l + yyj18++ + if yyhl18 { + yyb18 = yyj18 > l } else { - yyb17 = r.CheckBreak() + yyb18 = r.CheckBreak() } - if yyb17 { + if yyb18 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -4545,13 +4710,13 @@ func (x *PersistentVolumeSource) codecDecodeSelfFromArray(l int, d *codec1978.De } x.RBD.CodecDecodeSelf(d) } - yyj17++ - if yyhl17 { - yyb17 = yyj17 > l + yyj18++ + if yyhl18 { + yyb18 = yyj18 > l } else { - yyb17 = r.CheckBreak() + yyb18 = r.CheckBreak() } - if yyb17 { + if yyb18 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -4566,13 +4731,13 @@ func (x *PersistentVolumeSource) codecDecodeSelfFromArray(l int, d *codec1978.De } x.ISCSI.CodecDecodeSelf(d) } - yyj17++ - if yyhl17 { - yyb17 = yyj17 > l + yyj18++ + if yyhl18 { + yyb18 = yyj18 > l } else { - yyb17 = r.CheckBreak() + yyb18 = r.CheckBreak() } - if yyb17 { + if yyb18 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -4587,13 +4752,13 @@ func (x *PersistentVolumeSource) codecDecodeSelfFromArray(l int, d *codec1978.De } x.FlexVolume.CodecDecodeSelf(d) } - yyj17++ - if yyhl17 { - yyb17 = yyj17 > l + yyj18++ + if yyhl18 { + yyb18 = yyj18 > l } else { - yyb17 = r.CheckBreak() + yyb18 = r.CheckBreak() } - if yyb17 { + if yyb18 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -4608,13 +4773,13 @@ func (x *PersistentVolumeSource) codecDecodeSelfFromArray(l int, d *codec1978.De } x.Cinder.CodecDecodeSelf(d) } - yyj17++ - if yyhl17 { - yyb17 = yyj17 > l + yyj18++ + if yyhl18 { + yyb18 = yyj18 > l } else { - yyb17 = r.CheckBreak() + yyb18 = r.CheckBreak() } - if yyb17 { + if yyb18 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -4629,13 +4794,13 @@ func (x *PersistentVolumeSource) codecDecodeSelfFromArray(l int, d *codec1978.De } x.CephFS.CodecDecodeSelf(d) } - yyj17++ - if yyhl17 { - yyb17 = yyj17 > l + yyj18++ + if yyhl18 { + yyb18 = yyj18 > l } else { - yyb17 = r.CheckBreak() + yyb18 = r.CheckBreak() } - if yyb17 { + if yyb18 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -4650,13 +4815,13 @@ func (x *PersistentVolumeSource) codecDecodeSelfFromArray(l int, d *codec1978.De } x.FC.CodecDecodeSelf(d) } - yyj17++ - if yyhl17 { - yyb17 = yyj17 > l + yyj18++ + if yyhl18 { + yyb18 = yyj18 > l } else { - yyb17 = r.CheckBreak() + yyb18 = r.CheckBreak() } - if yyb17 { + if yyb18 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -4671,13 +4836,13 @@ func (x *PersistentVolumeSource) codecDecodeSelfFromArray(l int, d *codec1978.De } x.Flocker.CodecDecodeSelf(d) } - yyj17++ - if yyhl17 { - yyb17 = yyj17 > l + yyj18++ + if yyhl18 { + yyb18 = yyj18 > l } else { - yyb17 = r.CheckBreak() + yyb18 = r.CheckBreak() } - if yyb17 { + if yyb18 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -4692,18 +4857,39 @@ func (x *PersistentVolumeSource) codecDecodeSelfFromArray(l int, d *codec1978.De } x.AzureFile.CodecDecodeSelf(d) } - for { - yyj17++ - if yyhl17 { - yyb17 = yyj17 > l - } else { - yyb17 = r.CheckBreak() + yyj18++ + if yyhl18 { + yyb18 = yyj18 > l + } else { + yyb18 = r.CheckBreak() + } + if yyb18 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) + return + } + z.DecSendContainerState(codecSelfer_containerArrayElem1234) + if r.TryDecodeAsNil() { + if x.VsphereVolume != nil { + x.VsphereVolume = nil } - if yyb17 { + } else { + if x.VsphereVolume == nil { + x.VsphereVolume = new(VsphereVirtualDiskVolumeSource) + } + x.VsphereVolume.CodecDecodeSelf(d) + } + for { + yyj18++ + if yyhl18 { + yyb18 = yyj18 > l + } else { + yyb18 = r.CheckBreak() + } + if yyb18 { break } z.DecSendContainerState(codecSelfer_containerArrayElem1234) - z.DecStructFieldNotFound(yyj17-1, "") + z.DecStructFieldNotFound(yyj18-1, "") } z.DecSendContainerState(codecSelfer_containerArrayEnd1234) } @@ -5275,7 +5461,7 @@ func (x *PersistentVolumeSpec) CodecEncodeSelf(e *codec1978.Encoder) { } else { yysep2 := !z.EncBinary() yy2arr2 := z.EncBasicHandle().StructToArray - var yyq2 [17]bool + var yyq2 [18]bool _, _, _ = yysep2, yyq2, yy2arr2 const yyr2 bool = false yyq2[1] = len(x.AccessModes) != 0 @@ -5294,9 +5480,10 @@ func (x *PersistentVolumeSpec) CodecEncodeSelf(e *codec1978.Encoder) { yyq2[14] = x.PersistentVolumeSource.FC != nil && x.FC != nil yyq2[15] = x.PersistentVolumeSource.Flocker != nil && x.Flocker != nil yyq2[16] = x.PersistentVolumeSource.AzureFile != nil && x.AzureFile != nil + yyq2[17] = x.PersistentVolumeSource.VsphereVolume != nil && x.VsphereVolume != nil var yynn2 int if yyr2 || yy2arr2 { - r.EncodeArrayStart(17) + r.EncodeArrayStart(18) } else { yynn2 = 1 for _, b := range yyq2 { @@ -5876,6 +6063,43 @@ func (x *PersistentVolumeSpec) CodecEncodeSelf(e *codec1978.Encoder) { } } } + var yyn54 bool + if x.PersistentVolumeSource.VsphereVolume == nil { + yyn54 = true + goto LABEL54 + } + LABEL54: + if yyr2 || yy2arr2 { + if yyn54 { + r.EncodeNil() + } else { + z.EncSendContainerState(codecSelfer_containerArrayElem1234) + if yyq2[17] { + if x.VsphereVolume == nil { + r.EncodeNil() + } else { + x.VsphereVolume.CodecEncodeSelf(e) + } + } else { + r.EncodeNil() + } + } + } else { + if yyq2[17] { + z.EncSendContainerState(codecSelfer_containerMapKey1234) + r.EncodeString(codecSelferC_UTF81234, string("vsphereVolume")) + z.EncSendContainerState(codecSelfer_containerMapValue1234) + if yyn54 { + r.EncodeNil() + } else { + if x.VsphereVolume == nil { + r.EncodeNil() + } else { + x.VsphereVolume.CodecEncodeSelf(e) + } + } + } + } if yyr2 || yy2arr2 { z.EncSendContainerState(codecSelfer_containerArrayEnd1234) } else { @@ -6155,6 +6379,20 @@ func (x *PersistentVolumeSpec) codecDecodeSelfFromMap(l int, d *codec1978.Decode } x.AzureFile.CodecDecodeSelf(d) } + case "vsphereVolume": + if x.PersistentVolumeSource.VsphereVolume == nil { + x.PersistentVolumeSource.VsphereVolume = new(VsphereVirtualDiskVolumeSource) + } + if r.TryDecodeAsNil() { + if x.VsphereVolume != nil { + x.VsphereVolume = nil + } + } else { + if x.VsphereVolume == nil { + x.VsphereVolume = new(VsphereVirtualDiskVolumeSource) + } + x.VsphereVolume.CodecDecodeSelf(d) + } default: z.DecStructFieldNotFound(-1, yys3) } // end switch yys3 @@ -6166,16 +6404,16 @@ func (x *PersistentVolumeSpec) codecDecodeSelfFromArray(l int, d *codec1978.Deco var h codecSelfer1234 z, r := codec1978.GenHelperDecoder(d) _, _, _ = h, z, r - var yyj22 int - var yyb22 bool - var yyhl22 bool = l >= 0 - yyj22++ - if yyhl22 { - yyb22 = yyj22 > l + var yyj23 int + var yyb23 bool + var yyhl23 bool = l >= 0 + yyj23++ + if yyhl23 { + yyb23 = yyj23 > l } else { - yyb22 = r.CheckBreak() + yyb23 = r.CheckBreak() } - if yyb22 { + if yyb23 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -6183,16 +6421,16 @@ func (x *PersistentVolumeSpec) codecDecodeSelfFromArray(l int, d *codec1978.Deco if r.TryDecodeAsNil() { x.Capacity = nil } else { - yyv23 := &x.Capacity - yyv23.CodecDecodeSelf(d) + yyv24 := &x.Capacity + yyv24.CodecDecodeSelf(d) } - yyj22++ - if yyhl22 { - yyb22 = yyj22 > l + yyj23++ + if yyhl23 { + yyb23 = yyj23 > l } else { - yyb22 = r.CheckBreak() + yyb23 = r.CheckBreak() } - if yyb22 { + if yyb23 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -6200,21 +6438,21 @@ func (x *PersistentVolumeSpec) codecDecodeSelfFromArray(l int, d *codec1978.Deco if r.TryDecodeAsNil() { x.AccessModes = nil } else { - yyv24 := &x.AccessModes - yym25 := z.DecBinary() - _ = yym25 + yyv25 := &x.AccessModes + yym26 := z.DecBinary() + _ = yym26 if false { } else { - h.decSlicePersistentVolumeAccessMode((*[]PersistentVolumeAccessMode)(yyv24), d) + h.decSlicePersistentVolumeAccessMode((*[]PersistentVolumeAccessMode)(yyv25), d) } } - yyj22++ - if yyhl22 { - yyb22 = yyj22 > l + yyj23++ + if yyhl23 { + yyb23 = yyj23 > l } else { - yyb22 = r.CheckBreak() + yyb23 = r.CheckBreak() } - if yyb22 { + if yyb23 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -6229,13 +6467,13 @@ func (x *PersistentVolumeSpec) codecDecodeSelfFromArray(l int, d *codec1978.Deco } x.ClaimRef.CodecDecodeSelf(d) } - yyj22++ - if yyhl22 { - yyb22 = yyj22 > l + yyj23++ + if yyhl23 { + yyb23 = yyj23 > l } else { - yyb22 = r.CheckBreak() + yyb23 = r.CheckBreak() } - if yyb22 { + if yyb23 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -6248,13 +6486,13 @@ func (x *PersistentVolumeSpec) codecDecodeSelfFromArray(l int, d *codec1978.Deco if x.PersistentVolumeSource.GCEPersistentDisk == nil { x.PersistentVolumeSource.GCEPersistentDisk = new(GCEPersistentDiskVolumeSource) } - yyj22++ - if yyhl22 { - yyb22 = yyj22 > l + yyj23++ + if yyhl23 { + yyb23 = yyj23 > l } else { - yyb22 = r.CheckBreak() + yyb23 = r.CheckBreak() } - if yyb22 { + if yyb23 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -6272,13 +6510,13 @@ func (x *PersistentVolumeSpec) codecDecodeSelfFromArray(l int, d *codec1978.Deco if x.PersistentVolumeSource.AWSElasticBlockStore == nil { x.PersistentVolumeSource.AWSElasticBlockStore = new(AWSElasticBlockStoreVolumeSource) } - yyj22++ - if yyhl22 { - yyb22 = yyj22 > l + yyj23++ + if yyhl23 { + yyb23 = yyj23 > l } else { - yyb22 = r.CheckBreak() + yyb23 = r.CheckBreak() } - if yyb22 { + if yyb23 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -6296,13 +6534,13 @@ func (x *PersistentVolumeSpec) codecDecodeSelfFromArray(l int, d *codec1978.Deco if x.PersistentVolumeSource.HostPath == nil { x.PersistentVolumeSource.HostPath = new(HostPathVolumeSource) } - yyj22++ - if yyhl22 { - yyb22 = yyj22 > l + yyj23++ + if yyhl23 { + yyb23 = yyj23 > l } else { - yyb22 = r.CheckBreak() + yyb23 = r.CheckBreak() } - if yyb22 { + if yyb23 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -6320,13 +6558,13 @@ func (x *PersistentVolumeSpec) codecDecodeSelfFromArray(l int, d *codec1978.Deco if x.PersistentVolumeSource.Glusterfs == nil { x.PersistentVolumeSource.Glusterfs = new(GlusterfsVolumeSource) } - yyj22++ - if yyhl22 { - yyb22 = yyj22 > l + yyj23++ + if yyhl23 { + yyb23 = yyj23 > l } else { - yyb22 = r.CheckBreak() + yyb23 = r.CheckBreak() } - if yyb22 { + if yyb23 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -6344,13 +6582,13 @@ func (x *PersistentVolumeSpec) codecDecodeSelfFromArray(l int, d *codec1978.Deco if x.PersistentVolumeSource.NFS == nil { x.PersistentVolumeSource.NFS = new(NFSVolumeSource) } - yyj22++ - if yyhl22 { - yyb22 = yyj22 > l + yyj23++ + if yyhl23 { + yyb23 = yyj23 > l } else { - yyb22 = r.CheckBreak() + yyb23 = r.CheckBreak() } - if yyb22 { + if yyb23 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -6368,13 +6606,13 @@ func (x *PersistentVolumeSpec) codecDecodeSelfFromArray(l int, d *codec1978.Deco if x.PersistentVolumeSource.RBD == nil { x.PersistentVolumeSource.RBD = new(RBDVolumeSource) } - yyj22++ - if yyhl22 { - yyb22 = yyj22 > l + yyj23++ + if yyhl23 { + yyb23 = yyj23 > l } else { - yyb22 = r.CheckBreak() + yyb23 = r.CheckBreak() } - if yyb22 { + if yyb23 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -6392,13 +6630,13 @@ func (x *PersistentVolumeSpec) codecDecodeSelfFromArray(l int, d *codec1978.Deco if x.PersistentVolumeSource.ISCSI == nil { x.PersistentVolumeSource.ISCSI = new(ISCSIVolumeSource) } - yyj22++ - if yyhl22 { - yyb22 = yyj22 > l + yyj23++ + if yyhl23 { + yyb23 = yyj23 > l } else { - yyb22 = r.CheckBreak() + yyb23 = r.CheckBreak() } - if yyb22 { + if yyb23 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -6416,13 +6654,13 @@ func (x *PersistentVolumeSpec) codecDecodeSelfFromArray(l int, d *codec1978.Deco if x.PersistentVolumeSource.FlexVolume == nil { x.PersistentVolumeSource.FlexVolume = new(FlexVolumeSource) } - yyj22++ - if yyhl22 { - yyb22 = yyj22 > l + yyj23++ + if yyhl23 { + yyb23 = yyj23 > l } else { - yyb22 = r.CheckBreak() + yyb23 = r.CheckBreak() } - if yyb22 { + if yyb23 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -6440,13 +6678,13 @@ func (x *PersistentVolumeSpec) codecDecodeSelfFromArray(l int, d *codec1978.Deco if x.PersistentVolumeSource.Cinder == nil { x.PersistentVolumeSource.Cinder = new(CinderVolumeSource) } - yyj22++ - if yyhl22 { - yyb22 = yyj22 > l + yyj23++ + if yyhl23 { + yyb23 = yyj23 > l } else { - yyb22 = r.CheckBreak() + yyb23 = r.CheckBreak() } - if yyb22 { + if yyb23 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -6464,13 +6702,13 @@ func (x *PersistentVolumeSpec) codecDecodeSelfFromArray(l int, d *codec1978.Deco if x.PersistentVolumeSource.CephFS == nil { x.PersistentVolumeSource.CephFS = new(CephFSVolumeSource) } - yyj22++ - if yyhl22 { - yyb22 = yyj22 > l + yyj23++ + if yyhl23 { + yyb23 = yyj23 > l } else { - yyb22 = r.CheckBreak() + yyb23 = r.CheckBreak() } - if yyb22 { + if yyb23 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -6488,13 +6726,13 @@ func (x *PersistentVolumeSpec) codecDecodeSelfFromArray(l int, d *codec1978.Deco if x.PersistentVolumeSource.FC == nil { x.PersistentVolumeSource.FC = new(FCVolumeSource) } - yyj22++ - if yyhl22 { - yyb22 = yyj22 > l + yyj23++ + if yyhl23 { + yyb23 = yyj23 > l } else { - yyb22 = r.CheckBreak() + yyb23 = r.CheckBreak() } - if yyb22 { + if yyb23 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -6512,13 +6750,13 @@ func (x *PersistentVolumeSpec) codecDecodeSelfFromArray(l int, d *codec1978.Deco if x.PersistentVolumeSource.Flocker == nil { x.PersistentVolumeSource.Flocker = new(FlockerVolumeSource) } - yyj22++ - if yyhl22 { - yyb22 = yyj22 > l + yyj23++ + if yyhl23 { + yyb23 = yyj23 > l } else { - yyb22 = r.CheckBreak() + yyb23 = r.CheckBreak() } - if yyb22 { + if yyb23 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -6536,13 +6774,13 @@ func (x *PersistentVolumeSpec) codecDecodeSelfFromArray(l int, d *codec1978.Deco if x.PersistentVolumeSource.AzureFile == nil { x.PersistentVolumeSource.AzureFile = new(AzureFileVolumeSource) } - yyj22++ - if yyhl22 { - yyb22 = yyj22 > l + yyj23++ + if yyhl23 { + yyb23 = yyj23 > l } else { - yyb22 = r.CheckBreak() + yyb23 = r.CheckBreak() } - if yyb22 { + if yyb23 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -6557,18 +6795,42 @@ func (x *PersistentVolumeSpec) codecDecodeSelfFromArray(l int, d *codec1978.Deco } x.AzureFile.CodecDecodeSelf(d) } - for { - yyj22++ - if yyhl22 { - yyb22 = yyj22 > l - } else { - yyb22 = r.CheckBreak() + if x.PersistentVolumeSource.VsphereVolume == nil { + x.PersistentVolumeSource.VsphereVolume = new(VsphereVirtualDiskVolumeSource) + } + yyj23++ + if yyhl23 { + yyb23 = yyj23 > l + } else { + yyb23 = r.CheckBreak() + } + if yyb23 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) + return + } + z.DecSendContainerState(codecSelfer_containerArrayElem1234) + if r.TryDecodeAsNil() { + if x.VsphereVolume != nil { + x.VsphereVolume = nil } - if yyb22 { + } else { + if x.VsphereVolume == nil { + x.VsphereVolume = new(VsphereVirtualDiskVolumeSource) + } + x.VsphereVolume.CodecDecodeSelf(d) + } + for { + yyj23++ + if yyhl23 { + yyb23 = yyj23 > l + } else { + yyb23 = r.CheckBreak() + } + if yyb23 { break } z.DecSendContainerState(codecSelfer_containerArrayElem1234) - z.DecStructFieldNotFound(yyj22-1, "") + z.DecStructFieldNotFound(yyj23-1, "") } z.DecSendContainerState(codecSelfer_containerArrayEnd1234) } @@ -10914,13 +11176,14 @@ func (x *SecretVolumeSource) CodecEncodeSelf(e *codec1978.Encoder) { } else { yysep2 := !z.EncBinary() yy2arr2 := z.EncBasicHandle().StructToArray - var yyq2 [1]bool + var yyq2 [2]bool _, _, _ = yysep2, yyq2, yy2arr2 const yyr2 bool = false yyq2[0] = x.SecretName != "" + yyq2[1] = len(x.Items) != 0 var yynn2 int if yyr2 || yy2arr2 { - r.EncodeArrayStart(1) + r.EncodeArrayStart(2) } else { yynn2 = 0 for _, b := range yyq2 { @@ -10956,6 +11219,39 @@ func (x *SecretVolumeSource) CodecEncodeSelf(e *codec1978.Encoder) { } } } + if yyr2 || yy2arr2 { + z.EncSendContainerState(codecSelfer_containerArrayElem1234) + if yyq2[1] { + if x.Items == nil { + r.EncodeNil() + } else { + yym7 := z.EncBinary() + _ = yym7 + if false { + } else { + h.encSliceKeyToPath(([]KeyToPath)(x.Items), e) + } + } + } else { + r.EncodeNil() + } + } else { + if yyq2[1] { + z.EncSendContainerState(codecSelfer_containerMapKey1234) + r.EncodeString(codecSelferC_UTF81234, string("items")) + z.EncSendContainerState(codecSelfer_containerMapValue1234) + if x.Items == nil { + r.EncodeNil() + } else { + yym8 := z.EncBinary() + _ = yym8 + if false { + } else { + h.encSliceKeyToPath(([]KeyToPath)(x.Items), e) + } + } + } + } if yyr2 || yy2arr2 { z.EncSendContainerState(codecSelfer_containerArrayEnd1234) } else { @@ -11023,6 +11319,18 @@ func (x *SecretVolumeSource) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) } else { x.SecretName = string(r.DecodeString()) } + case "items": + if r.TryDecodeAsNil() { + x.Items = nil + } else { + yyv5 := &x.Items + yym6 := z.DecBinary() + _ = yym6 + if false { + } else { + h.decSliceKeyToPath((*[]KeyToPath)(yyv5), d) + } + } default: z.DecStructFieldNotFound(-1, yys3) } // end switch yys3 @@ -11034,16 +11342,16 @@ func (x *SecretVolumeSource) codecDecodeSelfFromArray(l int, d *codec1978.Decode var h codecSelfer1234 z, r := codec1978.GenHelperDecoder(d) _, _, _ = h, z, r - var yyj5 int - var yyb5 bool - var yyhl5 bool = l >= 0 - yyj5++ - if yyhl5 { - yyb5 = yyj5 > l + var yyj7 int + var yyb7 bool + var yyhl7 bool = l >= 0 + yyj7++ + if yyhl7 { + yyb7 = yyj7 > l } else { - yyb5 = r.CheckBreak() + yyb7 = r.CheckBreak() } - if yyb5 { + if yyb7 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -11053,18 +11361,40 @@ func (x *SecretVolumeSource) codecDecodeSelfFromArray(l int, d *codec1978.Decode } else { x.SecretName = string(r.DecodeString()) } - for { - yyj5++ - if yyhl5 { - yyb5 = yyj5 > l + yyj7++ + if yyhl7 { + yyb7 = yyj7 > l + } else { + yyb7 = r.CheckBreak() + } + if yyb7 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) + return + } + z.DecSendContainerState(codecSelfer_containerArrayElem1234) + if r.TryDecodeAsNil() { + x.Items = nil + } else { + yyv9 := &x.Items + yym10 := z.DecBinary() + _ = yym10 + if false { } else { - yyb5 = r.CheckBreak() + h.decSliceKeyToPath((*[]KeyToPath)(yyv9), d) } - if yyb5 { + } + for { + yyj7++ + if yyhl7 { + yyb7 = yyj7 > l + } else { + yyb7 = r.CheckBreak() + } + if yyb7 { break } z.DecSendContainerState(codecSelfer_containerArrayElem1234) - z.DecStructFieldNotFound(yyj5-1, "") + z.DecStructFieldNotFound(yyj7-1, "") } z.DecSendContainerState(codecSelfer_containerArrayEnd1234) } @@ -13549,6 +13879,216 @@ func (x *AzureFileVolumeSource) codecDecodeSelfFromArray(l int, d *codec1978.Dec z.DecSendContainerState(codecSelfer_containerArrayEnd1234) } +func (x *VsphereVirtualDiskVolumeSource) CodecEncodeSelf(e *codec1978.Encoder) { + var h codecSelfer1234 + z, r := codec1978.GenHelperEncoder(e) + _, _, _ = h, z, r + if x == nil { + r.EncodeNil() + } else { + yym1 := z.EncBinary() + _ = yym1 + if false { + } else if z.HasExtensions() && z.EncExt(x) { + } else { + yysep2 := !z.EncBinary() + yy2arr2 := z.EncBasicHandle().StructToArray + var yyq2 [2]bool + _, _, _ = yysep2, yyq2, yy2arr2 + const yyr2 bool = false + yyq2[1] = x.FSType != "" + var yynn2 int + if yyr2 || yy2arr2 { + r.EncodeArrayStart(2) + } else { + yynn2 = 1 + for _, b := range yyq2 { + if b { + yynn2++ + } + } + r.EncodeMapStart(yynn2) + yynn2 = 0 + } + if yyr2 || yy2arr2 { + z.EncSendContainerState(codecSelfer_containerArrayElem1234) + yym4 := z.EncBinary() + _ = yym4 + if false { + } else { + r.EncodeString(codecSelferC_UTF81234, string(x.VolumePath)) + } + } else { + z.EncSendContainerState(codecSelfer_containerMapKey1234) + r.EncodeString(codecSelferC_UTF81234, string("volumePath")) + z.EncSendContainerState(codecSelfer_containerMapValue1234) + yym5 := z.EncBinary() + _ = yym5 + if false { + } else { + r.EncodeString(codecSelferC_UTF81234, string(x.VolumePath)) + } + } + if yyr2 || yy2arr2 { + z.EncSendContainerState(codecSelfer_containerArrayElem1234) + if yyq2[1] { + yym7 := z.EncBinary() + _ = yym7 + if false { + } else { + r.EncodeString(codecSelferC_UTF81234, string(x.FSType)) + } + } else { + r.EncodeString(codecSelferC_UTF81234, "") + } + } else { + if yyq2[1] { + z.EncSendContainerState(codecSelfer_containerMapKey1234) + r.EncodeString(codecSelferC_UTF81234, string("fsType")) + z.EncSendContainerState(codecSelfer_containerMapValue1234) + yym8 := z.EncBinary() + _ = yym8 + if false { + } else { + r.EncodeString(codecSelferC_UTF81234, string(x.FSType)) + } + } + } + if yyr2 || yy2arr2 { + z.EncSendContainerState(codecSelfer_containerArrayEnd1234) + } else { + z.EncSendContainerState(codecSelfer_containerMapEnd1234) + } + } + } +} + +func (x *VsphereVirtualDiskVolumeSource) CodecDecodeSelf(d *codec1978.Decoder) { + var h codecSelfer1234 + z, r := codec1978.GenHelperDecoder(d) + _, _, _ = h, z, r + yym1 := z.DecBinary() + _ = yym1 + if false { + } else if z.HasExtensions() && z.DecExt(x) { + } else { + yyct2 := r.ContainerType() + if yyct2 == codecSelferValueTypeMap1234 { + yyl2 := r.ReadMapStart() + if yyl2 == 0 { + z.DecSendContainerState(codecSelfer_containerMapEnd1234) + } else { + x.codecDecodeSelfFromMap(yyl2, d) + } + } else if yyct2 == codecSelferValueTypeArray1234 { + yyl2 := r.ReadArrayStart() + if yyl2 == 0 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) + } else { + x.codecDecodeSelfFromArray(yyl2, d) + } + } else { + panic(codecSelferOnlyMapOrArrayEncodeToStructErr1234) + } + } +} + +func (x *VsphereVirtualDiskVolumeSource) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) { + var h codecSelfer1234 + z, r := codec1978.GenHelperDecoder(d) + _, _, _ = h, z, r + var yys3Slc = z.DecScratchBuffer() // default slice to decode into + _ = yys3Slc + var yyhl3 bool = l >= 0 + for yyj3 := 0; ; yyj3++ { + if yyhl3 { + if yyj3 >= l { + break + } + } else { + if r.CheckBreak() { + break + } + } + z.DecSendContainerState(codecSelfer_containerMapKey1234) + yys3Slc = r.DecodeBytes(yys3Slc, true, true) + yys3 := string(yys3Slc) + z.DecSendContainerState(codecSelfer_containerMapValue1234) + switch yys3 { + case "volumePath": + if r.TryDecodeAsNil() { + x.VolumePath = "" + } else { + x.VolumePath = string(r.DecodeString()) + } + case "fsType": + if r.TryDecodeAsNil() { + x.FSType = "" + } else { + x.FSType = string(r.DecodeString()) + } + default: + z.DecStructFieldNotFound(-1, yys3) + } // end switch yys3 + } // end for yyj3 + z.DecSendContainerState(codecSelfer_containerMapEnd1234) +} + +func (x *VsphereVirtualDiskVolumeSource) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { + var h codecSelfer1234 + z, r := codec1978.GenHelperDecoder(d) + _, _, _ = h, z, r + var yyj6 int + var yyb6 bool + var yyhl6 bool = l >= 0 + yyj6++ + if yyhl6 { + yyb6 = yyj6 > l + } else { + yyb6 = r.CheckBreak() + } + if yyb6 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) + return + } + z.DecSendContainerState(codecSelfer_containerArrayElem1234) + if r.TryDecodeAsNil() { + x.VolumePath = "" + } else { + x.VolumePath = string(r.DecodeString()) + } + yyj6++ + if yyhl6 { + yyb6 = yyj6 > l + } else { + yyb6 = r.CheckBreak() + } + if yyb6 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) + return + } + z.DecSendContainerState(codecSelfer_containerArrayElem1234) + if r.TryDecodeAsNil() { + x.FSType = "" + } else { + x.FSType = string(r.DecodeString()) + } + for { + yyj6++ + if yyhl6 { + yyb6 = yyj6 > l + } else { + yyb6 = r.CheckBreak() + } + if yyb6 { + break + } + z.DecSendContainerState(codecSelfer_containerArrayElem1234) + z.DecStructFieldNotFound(yyj6-1, "") + } + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) +} + func (x *ConfigMapVolumeSource) CodecEncodeSelf(e *codec1978.Encoder) { var h codecSelfer1234 z, r := codec1978.GenHelperEncoder(e) @@ -16227,7 +16767,7 @@ func (x *HTTPGetAction) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) { } case "port": if r.TryDecodeAsNil() { - x.Port = pkg5_intstr.IntOrString{} + x.Port = pkg4_intstr.IntOrString{} } else { yyv5 := &x.Port yym6 := z.DecBinary() @@ -16306,7 +16846,7 @@ func (x *HTTPGetAction) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { } z.DecSendContainerState(codecSelfer_containerArrayElem1234) if r.TryDecodeAsNil() { - x.Port = pkg5_intstr.IntOrString{} + x.Port = pkg4_intstr.IntOrString{} } else { yyv13 := &x.Port yym14 := z.DecBinary() @@ -16542,7 +17082,7 @@ func (x *TCPSocketAction) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) { switch yys3 { case "port": if r.TryDecodeAsNil() { - x.Port = pkg5_intstr.IntOrString{} + x.Port = pkg4_intstr.IntOrString{} } else { yyv4 := &x.Port yym5 := z.DecBinary() @@ -16581,7 +17121,7 @@ func (x *TCPSocketAction) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) } z.DecSendContainerState(codecSelfer_containerArrayElem1234) if r.TryDecodeAsNil() { - x.Port = pkg5_intstr.IntOrString{} + x.Port = pkg4_intstr.IntOrString{} } else { yyv7 := &x.Port yym8 := z.DecBinary() @@ -24521,6 +25061,592 @@ func (x *PreferredSchedulingTerm) codecDecodeSelfFromArray(l int, d *codec1978.D z.DecSendContainerState(codecSelfer_containerArrayEnd1234) } +func (x *Taint) CodecEncodeSelf(e *codec1978.Encoder) { + var h codecSelfer1234 + z, r := codec1978.GenHelperEncoder(e) + _, _, _ = h, z, r + if x == nil { + r.EncodeNil() + } else { + yym1 := z.EncBinary() + _ = yym1 + if false { + } else if z.HasExtensions() && z.EncExt(x) { + } else { + yysep2 := !z.EncBinary() + yy2arr2 := z.EncBasicHandle().StructToArray + var yyq2 [3]bool + _, _, _ = yysep2, yyq2, yy2arr2 + const yyr2 bool = false + yyq2[1] = x.Value != "" + var yynn2 int + if yyr2 || yy2arr2 { + r.EncodeArrayStart(3) + } else { + yynn2 = 2 + for _, b := range yyq2 { + if b { + yynn2++ + } + } + r.EncodeMapStart(yynn2) + yynn2 = 0 + } + if yyr2 || yy2arr2 { + z.EncSendContainerState(codecSelfer_containerArrayElem1234) + yym4 := z.EncBinary() + _ = yym4 + if false { + } else { + r.EncodeString(codecSelferC_UTF81234, string(x.Key)) + } + } else { + z.EncSendContainerState(codecSelfer_containerMapKey1234) + r.EncodeString(codecSelferC_UTF81234, string("key")) + z.EncSendContainerState(codecSelfer_containerMapValue1234) + yym5 := z.EncBinary() + _ = yym5 + if false { + } else { + r.EncodeString(codecSelferC_UTF81234, string(x.Key)) + } + } + if yyr2 || yy2arr2 { + z.EncSendContainerState(codecSelfer_containerArrayElem1234) + if yyq2[1] { + yym7 := z.EncBinary() + _ = yym7 + if false { + } else { + r.EncodeString(codecSelferC_UTF81234, string(x.Value)) + } + } else { + r.EncodeString(codecSelferC_UTF81234, "") + } + } else { + if yyq2[1] { + z.EncSendContainerState(codecSelfer_containerMapKey1234) + r.EncodeString(codecSelferC_UTF81234, string("value")) + z.EncSendContainerState(codecSelfer_containerMapValue1234) + yym8 := z.EncBinary() + _ = yym8 + if false { + } else { + r.EncodeString(codecSelferC_UTF81234, string(x.Value)) + } + } + } + if yyr2 || yy2arr2 { + z.EncSendContainerState(codecSelfer_containerArrayElem1234) + x.Effect.CodecEncodeSelf(e) + } else { + z.EncSendContainerState(codecSelfer_containerMapKey1234) + r.EncodeString(codecSelferC_UTF81234, string("effect")) + z.EncSendContainerState(codecSelfer_containerMapValue1234) + x.Effect.CodecEncodeSelf(e) + } + if yyr2 || yy2arr2 { + z.EncSendContainerState(codecSelfer_containerArrayEnd1234) + } else { + z.EncSendContainerState(codecSelfer_containerMapEnd1234) + } + } + } +} + +func (x *Taint) CodecDecodeSelf(d *codec1978.Decoder) { + var h codecSelfer1234 + z, r := codec1978.GenHelperDecoder(d) + _, _, _ = h, z, r + yym1 := z.DecBinary() + _ = yym1 + if false { + } else if z.HasExtensions() && z.DecExt(x) { + } else { + yyct2 := r.ContainerType() + if yyct2 == codecSelferValueTypeMap1234 { + yyl2 := r.ReadMapStart() + if yyl2 == 0 { + z.DecSendContainerState(codecSelfer_containerMapEnd1234) + } else { + x.codecDecodeSelfFromMap(yyl2, d) + } + } else if yyct2 == codecSelferValueTypeArray1234 { + yyl2 := r.ReadArrayStart() + if yyl2 == 0 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) + } else { + x.codecDecodeSelfFromArray(yyl2, d) + } + } else { + panic(codecSelferOnlyMapOrArrayEncodeToStructErr1234) + } + } +} + +func (x *Taint) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) { + var h codecSelfer1234 + z, r := codec1978.GenHelperDecoder(d) + _, _, _ = h, z, r + var yys3Slc = z.DecScratchBuffer() // default slice to decode into + _ = yys3Slc + var yyhl3 bool = l >= 0 + for yyj3 := 0; ; yyj3++ { + if yyhl3 { + if yyj3 >= l { + break + } + } else { + if r.CheckBreak() { + break + } + } + z.DecSendContainerState(codecSelfer_containerMapKey1234) + yys3Slc = r.DecodeBytes(yys3Slc, true, true) + yys3 := string(yys3Slc) + z.DecSendContainerState(codecSelfer_containerMapValue1234) + switch yys3 { + case "key": + if r.TryDecodeAsNil() { + x.Key = "" + } else { + x.Key = string(r.DecodeString()) + } + case "value": + if r.TryDecodeAsNil() { + x.Value = "" + } else { + x.Value = string(r.DecodeString()) + } + case "effect": + if r.TryDecodeAsNil() { + x.Effect = "" + } else { + x.Effect = TaintEffect(r.DecodeString()) + } + default: + z.DecStructFieldNotFound(-1, yys3) + } // end switch yys3 + } // end for yyj3 + z.DecSendContainerState(codecSelfer_containerMapEnd1234) +} + +func (x *Taint) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { + var h codecSelfer1234 + z, r := codec1978.GenHelperDecoder(d) + _, _, _ = h, z, r + var yyj7 int + var yyb7 bool + var yyhl7 bool = l >= 0 + yyj7++ + if yyhl7 { + yyb7 = yyj7 > l + } else { + yyb7 = r.CheckBreak() + } + if yyb7 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) + return + } + z.DecSendContainerState(codecSelfer_containerArrayElem1234) + if r.TryDecodeAsNil() { + x.Key = "" + } else { + x.Key = string(r.DecodeString()) + } + yyj7++ + if yyhl7 { + yyb7 = yyj7 > l + } else { + yyb7 = r.CheckBreak() + } + if yyb7 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) + return + } + z.DecSendContainerState(codecSelfer_containerArrayElem1234) + if r.TryDecodeAsNil() { + x.Value = "" + } else { + x.Value = string(r.DecodeString()) + } + yyj7++ + if yyhl7 { + yyb7 = yyj7 > l + } else { + yyb7 = r.CheckBreak() + } + if yyb7 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) + return + } + z.DecSendContainerState(codecSelfer_containerArrayElem1234) + if r.TryDecodeAsNil() { + x.Effect = "" + } else { + x.Effect = TaintEffect(r.DecodeString()) + } + for { + yyj7++ + if yyhl7 { + yyb7 = yyj7 > l + } else { + yyb7 = r.CheckBreak() + } + if yyb7 { + break + } + z.DecSendContainerState(codecSelfer_containerArrayElem1234) + z.DecStructFieldNotFound(yyj7-1, "") + } + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) +} + +func (x TaintEffect) CodecEncodeSelf(e *codec1978.Encoder) { + var h codecSelfer1234 + z, r := codec1978.GenHelperEncoder(e) + _, _, _ = h, z, r + yym1 := z.EncBinary() + _ = yym1 + if false { + } else if z.HasExtensions() && z.EncExt(x) { + } else { + r.EncodeString(codecSelferC_UTF81234, string(x)) + } +} + +func (x *TaintEffect) CodecDecodeSelf(d *codec1978.Decoder) { + var h codecSelfer1234 + z, r := codec1978.GenHelperDecoder(d) + _, _, _ = h, z, r + yym1 := z.DecBinary() + _ = yym1 + if false { + } else if z.HasExtensions() && z.DecExt(x) { + } else { + *((*string)(x)) = r.DecodeString() + } +} + +func (x *Toleration) CodecEncodeSelf(e *codec1978.Encoder) { + var h codecSelfer1234 + z, r := codec1978.GenHelperEncoder(e) + _, _, _ = h, z, r + if x == nil { + r.EncodeNil() + } else { + yym1 := z.EncBinary() + _ = yym1 + if false { + } else if z.HasExtensions() && z.EncExt(x) { + } else { + yysep2 := !z.EncBinary() + yy2arr2 := z.EncBasicHandle().StructToArray + var yyq2 [4]bool + _, _, _ = yysep2, yyq2, yy2arr2 + const yyr2 bool = false + yyq2[0] = x.Key != "" + yyq2[1] = x.Operator != "" + yyq2[2] = x.Value != "" + yyq2[3] = x.Effect != "" + var yynn2 int + if yyr2 || yy2arr2 { + r.EncodeArrayStart(4) + } else { + yynn2 = 0 + for _, b := range yyq2 { + if b { + yynn2++ + } + } + r.EncodeMapStart(yynn2) + yynn2 = 0 + } + if yyr2 || yy2arr2 { + z.EncSendContainerState(codecSelfer_containerArrayElem1234) + if yyq2[0] { + yym4 := z.EncBinary() + _ = yym4 + if false { + } else { + r.EncodeString(codecSelferC_UTF81234, string(x.Key)) + } + } else { + r.EncodeString(codecSelferC_UTF81234, "") + } + } else { + if yyq2[0] { + z.EncSendContainerState(codecSelfer_containerMapKey1234) + r.EncodeString(codecSelferC_UTF81234, string("key")) + z.EncSendContainerState(codecSelfer_containerMapValue1234) + yym5 := z.EncBinary() + _ = yym5 + if false { + } else { + r.EncodeString(codecSelferC_UTF81234, string(x.Key)) + } + } + } + if yyr2 || yy2arr2 { + z.EncSendContainerState(codecSelfer_containerArrayElem1234) + if yyq2[1] { + x.Operator.CodecEncodeSelf(e) + } else { + r.EncodeString(codecSelferC_UTF81234, "") + } + } else { + if yyq2[1] { + z.EncSendContainerState(codecSelfer_containerMapKey1234) + r.EncodeString(codecSelferC_UTF81234, string("operator")) + z.EncSendContainerState(codecSelfer_containerMapValue1234) + x.Operator.CodecEncodeSelf(e) + } + } + if yyr2 || yy2arr2 { + z.EncSendContainerState(codecSelfer_containerArrayElem1234) + if yyq2[2] { + yym10 := z.EncBinary() + _ = yym10 + if false { + } else { + r.EncodeString(codecSelferC_UTF81234, string(x.Value)) + } + } else { + r.EncodeString(codecSelferC_UTF81234, "") + } + } else { + if yyq2[2] { + z.EncSendContainerState(codecSelfer_containerMapKey1234) + r.EncodeString(codecSelferC_UTF81234, string("value")) + z.EncSendContainerState(codecSelfer_containerMapValue1234) + yym11 := z.EncBinary() + _ = yym11 + if false { + } else { + r.EncodeString(codecSelferC_UTF81234, string(x.Value)) + } + } + } + if yyr2 || yy2arr2 { + z.EncSendContainerState(codecSelfer_containerArrayElem1234) + if yyq2[3] { + x.Effect.CodecEncodeSelf(e) + } else { + r.EncodeString(codecSelferC_UTF81234, "") + } + } else { + if yyq2[3] { + z.EncSendContainerState(codecSelfer_containerMapKey1234) + r.EncodeString(codecSelferC_UTF81234, string("effect")) + z.EncSendContainerState(codecSelfer_containerMapValue1234) + x.Effect.CodecEncodeSelf(e) + } + } + if yyr2 || yy2arr2 { + z.EncSendContainerState(codecSelfer_containerArrayEnd1234) + } else { + z.EncSendContainerState(codecSelfer_containerMapEnd1234) + } + } + } +} + +func (x *Toleration) CodecDecodeSelf(d *codec1978.Decoder) { + var h codecSelfer1234 + z, r := codec1978.GenHelperDecoder(d) + _, _, _ = h, z, r + yym1 := z.DecBinary() + _ = yym1 + if false { + } else if z.HasExtensions() && z.DecExt(x) { + } else { + yyct2 := r.ContainerType() + if yyct2 == codecSelferValueTypeMap1234 { + yyl2 := r.ReadMapStart() + if yyl2 == 0 { + z.DecSendContainerState(codecSelfer_containerMapEnd1234) + } else { + x.codecDecodeSelfFromMap(yyl2, d) + } + } else if yyct2 == codecSelferValueTypeArray1234 { + yyl2 := r.ReadArrayStart() + if yyl2 == 0 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) + } else { + x.codecDecodeSelfFromArray(yyl2, d) + } + } else { + panic(codecSelferOnlyMapOrArrayEncodeToStructErr1234) + } + } +} + +func (x *Toleration) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) { + var h codecSelfer1234 + z, r := codec1978.GenHelperDecoder(d) + _, _, _ = h, z, r + var yys3Slc = z.DecScratchBuffer() // default slice to decode into + _ = yys3Slc + var yyhl3 bool = l >= 0 + for yyj3 := 0; ; yyj3++ { + if yyhl3 { + if yyj3 >= l { + break + } + } else { + if r.CheckBreak() { + break + } + } + z.DecSendContainerState(codecSelfer_containerMapKey1234) + yys3Slc = r.DecodeBytes(yys3Slc, true, true) + yys3 := string(yys3Slc) + z.DecSendContainerState(codecSelfer_containerMapValue1234) + switch yys3 { + case "key": + if r.TryDecodeAsNil() { + x.Key = "" + } else { + x.Key = string(r.DecodeString()) + } + case "operator": + if r.TryDecodeAsNil() { + x.Operator = "" + } else { + x.Operator = TolerationOperator(r.DecodeString()) + } + case "value": + if r.TryDecodeAsNil() { + x.Value = "" + } else { + x.Value = string(r.DecodeString()) + } + case "effect": + if r.TryDecodeAsNil() { + x.Effect = "" + } else { + x.Effect = TaintEffect(r.DecodeString()) + } + default: + z.DecStructFieldNotFound(-1, yys3) + } // end switch yys3 + } // end for yyj3 + z.DecSendContainerState(codecSelfer_containerMapEnd1234) +} + +func (x *Toleration) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { + var h codecSelfer1234 + z, r := codec1978.GenHelperDecoder(d) + _, _, _ = h, z, r + var yyj8 int + var yyb8 bool + var yyhl8 bool = l >= 0 + yyj8++ + if yyhl8 { + yyb8 = yyj8 > l + } else { + yyb8 = r.CheckBreak() + } + if yyb8 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) + return + } + z.DecSendContainerState(codecSelfer_containerArrayElem1234) + if r.TryDecodeAsNil() { + x.Key = "" + } else { + x.Key = string(r.DecodeString()) + } + yyj8++ + if yyhl8 { + yyb8 = yyj8 > l + } else { + yyb8 = r.CheckBreak() + } + if yyb8 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) + return + } + z.DecSendContainerState(codecSelfer_containerArrayElem1234) + if r.TryDecodeAsNil() { + x.Operator = "" + } else { + x.Operator = TolerationOperator(r.DecodeString()) + } + yyj8++ + if yyhl8 { + yyb8 = yyj8 > l + } else { + yyb8 = r.CheckBreak() + } + if yyb8 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) + return + } + z.DecSendContainerState(codecSelfer_containerArrayElem1234) + if r.TryDecodeAsNil() { + x.Value = "" + } else { + x.Value = string(r.DecodeString()) + } + yyj8++ + if yyhl8 { + yyb8 = yyj8 > l + } else { + yyb8 = r.CheckBreak() + } + if yyb8 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) + return + } + z.DecSendContainerState(codecSelfer_containerArrayElem1234) + if r.TryDecodeAsNil() { + x.Effect = "" + } else { + x.Effect = TaintEffect(r.DecodeString()) + } + for { + yyj8++ + if yyhl8 { + yyb8 = yyj8 > l + } else { + yyb8 = r.CheckBreak() + } + if yyb8 { + break + } + z.DecSendContainerState(codecSelfer_containerArrayElem1234) + z.DecStructFieldNotFound(yyj8-1, "") + } + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) +} + +func (x TolerationOperator) CodecEncodeSelf(e *codec1978.Encoder) { + var h codecSelfer1234 + z, r := codec1978.GenHelperEncoder(e) + _, _, _ = h, z, r + yym1 := z.EncBinary() + _ = yym1 + if false { + } else if z.HasExtensions() && z.EncExt(x) { + } else { + r.EncodeString(codecSelferC_UTF81234, string(x)) + } +} + +func (x *TolerationOperator) CodecDecodeSelf(d *codec1978.Decoder) { + var h codecSelfer1234 + z, r := codec1978.GenHelperDecoder(d) + _, _, _ = h, z, r + yym1 := z.DecBinary() + _ = yym1 + if false { + } else if z.HasExtensions() && z.DecExt(x) { + } else { + *((*string)(x)) = r.DecodeString() + } +} + func (x *PodSpec) CodecEncodeSelf(e *codec1978.Encoder) { var h codecSelfer1234 z, r := codec1978.GenHelperEncoder(e) @@ -30949,7 +32075,7 @@ func (x *ServicePort) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) { } case "targetPort": if r.TryDecodeAsNil() { - x.TargetPort = pkg5_intstr.IntOrString{} + x.TargetPort = pkg4_intstr.IntOrString{} } else { yyv7 := &x.TargetPort yym8 := z.DecBinary() @@ -31042,7 +32168,7 @@ func (x *ServicePort) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { } z.DecSendContainerState(codecSelfer_containerArrayElem1234) if r.TryDecodeAsNil() { - x.TargetPort = pkg5_intstr.IntOrString{} + x.TargetPort = pkg4_intstr.IntOrString{} } else { yyv14 := &x.TargetPort yym15 := z.DecBinary() @@ -34275,14 +35401,14 @@ func (x *NodeSystemInfo) CodecEncodeSelf(e *codec1978.Encoder) { } else { yysep2 := !z.EncBinary() yy2arr2 := z.EncBasicHandle().StructToArray - var yyq2 [8]bool + var yyq2 [10]bool _, _, _ = yysep2, yyq2, yy2arr2 const yyr2 bool = false var yynn2 int if yyr2 || yy2arr2 { - r.EncodeArrayStart(8) + r.EncodeArrayStart(10) } else { - yynn2 = 8 + yynn2 = 10 for _, b := range yyq2 { if b { yynn2++ @@ -34443,6 +35569,44 @@ func (x *NodeSystemInfo) CodecEncodeSelf(e *codec1978.Encoder) { r.EncodeString(codecSelferC_UTF81234, string(x.KubeProxyVersion)) } } + if yyr2 || yy2arr2 { + z.EncSendContainerState(codecSelfer_containerArrayElem1234) + yym28 := z.EncBinary() + _ = yym28 + if false { + } else { + r.EncodeString(codecSelferC_UTF81234, string(x.OperatingSystem)) + } + } else { + z.EncSendContainerState(codecSelfer_containerMapKey1234) + r.EncodeString(codecSelferC_UTF81234, string("operatingSystem")) + z.EncSendContainerState(codecSelfer_containerMapValue1234) + yym29 := z.EncBinary() + _ = yym29 + if false { + } else { + r.EncodeString(codecSelferC_UTF81234, string(x.OperatingSystem)) + } + } + if yyr2 || yy2arr2 { + z.EncSendContainerState(codecSelfer_containerArrayElem1234) + yym31 := z.EncBinary() + _ = yym31 + if false { + } else { + r.EncodeString(codecSelferC_UTF81234, string(x.Architecture)) + } + } else { + z.EncSendContainerState(codecSelfer_containerMapKey1234) + r.EncodeString(codecSelferC_UTF81234, string("architecture")) + z.EncSendContainerState(codecSelfer_containerMapValue1234) + yym32 := z.EncBinary() + _ = yym32 + if false { + } else { + r.EncodeString(codecSelferC_UTF81234, string(x.Architecture)) + } + } if yyr2 || yy2arr2 { z.EncSendContainerState(codecSelfer_containerArrayEnd1234) } else { @@ -34552,6 +35716,18 @@ func (x *NodeSystemInfo) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) { } else { x.KubeProxyVersion = string(r.DecodeString()) } + case "operatingSystem": + if r.TryDecodeAsNil() { + x.OperatingSystem = "" + } else { + x.OperatingSystem = string(r.DecodeString()) + } + case "architecture": + if r.TryDecodeAsNil() { + x.Architecture = "" + } else { + x.Architecture = string(r.DecodeString()) + } default: z.DecStructFieldNotFound(-1, yys3) } // end switch yys3 @@ -34563,16 +35739,16 @@ func (x *NodeSystemInfo) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { var h codecSelfer1234 z, r := codec1978.GenHelperDecoder(d) _, _, _ = h, z, r - var yyj12 int - var yyb12 bool - var yyhl12 bool = l >= 0 - yyj12++ - if yyhl12 { - yyb12 = yyj12 > l + var yyj14 int + var yyb14 bool + var yyhl14 bool = l >= 0 + yyj14++ + if yyhl14 { + yyb14 = yyj14 > l } else { - yyb12 = r.CheckBreak() + yyb14 = r.CheckBreak() } - if yyb12 { + if yyb14 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -34582,13 +35758,13 @@ func (x *NodeSystemInfo) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { } else { x.MachineID = string(r.DecodeString()) } - yyj12++ - if yyhl12 { - yyb12 = yyj12 > l + yyj14++ + if yyhl14 { + yyb14 = yyj14 > l } else { - yyb12 = r.CheckBreak() + yyb14 = r.CheckBreak() } - if yyb12 { + if yyb14 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -34598,13 +35774,13 @@ func (x *NodeSystemInfo) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { } else { x.SystemUUID = string(r.DecodeString()) } - yyj12++ - if yyhl12 { - yyb12 = yyj12 > l + yyj14++ + if yyhl14 { + yyb14 = yyj14 > l } else { - yyb12 = r.CheckBreak() + yyb14 = r.CheckBreak() } - if yyb12 { + if yyb14 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -34614,13 +35790,13 @@ func (x *NodeSystemInfo) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { } else { x.BootID = string(r.DecodeString()) } - yyj12++ - if yyhl12 { - yyb12 = yyj12 > l + yyj14++ + if yyhl14 { + yyb14 = yyj14 > l } else { - yyb12 = r.CheckBreak() + yyb14 = r.CheckBreak() } - if yyb12 { + if yyb14 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -34630,13 +35806,13 @@ func (x *NodeSystemInfo) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { } else { x.KernelVersion = string(r.DecodeString()) } - yyj12++ - if yyhl12 { - yyb12 = yyj12 > l + yyj14++ + if yyhl14 { + yyb14 = yyj14 > l } else { - yyb12 = r.CheckBreak() + yyb14 = r.CheckBreak() } - if yyb12 { + if yyb14 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -34646,13 +35822,13 @@ func (x *NodeSystemInfo) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { } else { x.OSImage = string(r.DecodeString()) } - yyj12++ - if yyhl12 { - yyb12 = yyj12 > l + yyj14++ + if yyhl14 { + yyb14 = yyj14 > l } else { - yyb12 = r.CheckBreak() + yyb14 = r.CheckBreak() } - if yyb12 { + if yyb14 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -34662,13 +35838,13 @@ func (x *NodeSystemInfo) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { } else { x.ContainerRuntimeVersion = string(r.DecodeString()) } - yyj12++ - if yyhl12 { - yyb12 = yyj12 > l + yyj14++ + if yyhl14 { + yyb14 = yyj14 > l } else { - yyb12 = r.CheckBreak() + yyb14 = r.CheckBreak() } - if yyb12 { + if yyb14 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -34678,13 +35854,13 @@ func (x *NodeSystemInfo) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { } else { x.KubeletVersion = string(r.DecodeString()) } - yyj12++ - if yyhl12 { - yyb12 = yyj12 > l + yyj14++ + if yyhl14 { + yyb14 = yyj14 > l } else { - yyb12 = r.CheckBreak() + yyb14 = r.CheckBreak() } - if yyb12 { + if yyb14 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -34694,18 +35870,50 @@ func (x *NodeSystemInfo) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { } else { x.KubeProxyVersion = string(r.DecodeString()) } + yyj14++ + if yyhl14 { + yyb14 = yyj14 > l + } else { + yyb14 = r.CheckBreak() + } + if yyb14 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) + return + } + z.DecSendContainerState(codecSelfer_containerArrayElem1234) + if r.TryDecodeAsNil() { + x.OperatingSystem = "" + } else { + x.OperatingSystem = string(r.DecodeString()) + } + yyj14++ + if yyhl14 { + yyb14 = yyj14 > l + } else { + yyb14 = r.CheckBreak() + } + if yyb14 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) + return + } + z.DecSendContainerState(codecSelfer_containerArrayElem1234) + if r.TryDecodeAsNil() { + x.Architecture = "" + } else { + x.Architecture = string(r.DecodeString()) + } for { - yyj12++ - if yyhl12 { - yyb12 = yyj12 > l + yyj14++ + if yyhl14 { + yyb14 = yyj14 > l } else { - yyb12 = r.CheckBreak() + yyb14 = r.CheckBreak() } - if yyb12 { + if yyb14 { break } z.DecSendContainerState(codecSelfer_containerArrayElem1234) - z.DecStructFieldNotFound(yyj12-1, "") + z.DecStructFieldNotFound(yyj14-1, "") } z.DecSendContainerState(codecSelfer_containerArrayEnd1234) } @@ -44809,7 +46017,7 @@ func (x *List) CodecEncodeSelf(e *codec1978.Encoder) { _ = yym9 if false { } else { - h.encSliceruntime_Object(([]pkg8_runtime.Object)(x.Items), e) + h.encSliceruntime_Object(([]pkg7_runtime.Object)(x.Items), e) } } } else { @@ -44823,7 +46031,7 @@ func (x *List) CodecEncodeSelf(e *codec1978.Encoder) { _ = yym10 if false { } else { - h.encSliceruntime_Object(([]pkg8_runtime.Object)(x.Items), e) + h.encSliceruntime_Object(([]pkg7_runtime.Object)(x.Items), e) } } } @@ -44960,7 +46168,7 @@ func (x *List) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) { _ = yym7 if false { } else { - h.decSliceruntime_Object((*[]pkg8_runtime.Object)(yyv6), d) + h.decSliceruntime_Object((*[]pkg7_runtime.Object)(yyv6), d) } } case "kind": @@ -45031,7 +46239,7 @@ func (x *List) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { _ = yym14 if false { } else { - h.decSliceruntime_Object((*[]pkg8_runtime.Object)(yyv13), d) + h.decSliceruntime_Object((*[]pkg7_runtime.Object)(yyv13), d) } } yyj10++ @@ -51396,7 +52604,7 @@ func (x codecSelfer1234) decSlicePersistentVolume(v *[]PersistentVolume, d *code yyrg1 := len(yyv1) > 0 yyv21 := yyv1 - yyrl1, yyrt1 = z.DecInferLen(yyl1, z.DecBasicHandle().MaxInitLen, 448) + yyrl1, yyrt1 = z.DecInferLen(yyl1, z.DecBasicHandle().MaxInitLen, 456) if yyrt1 { if yyrl1 <= cap(yyv1) { yyv1 = yyv1[:yyrl1] @@ -51595,125 +52803,6 @@ func (x codecSelfer1234) decSlicePersistentVolumeClaim(v *[]PersistentVolumeClai } } -func (x codecSelfer1234) encSliceDownwardAPIVolumeFile(v []DownwardAPIVolumeFile, e *codec1978.Encoder) { - var h codecSelfer1234 - z, r := codec1978.GenHelperEncoder(e) - _, _, _ = h, z, r - r.EncodeArrayStart(len(v)) - for _, yyv1 := range v { - z.EncSendContainerState(codecSelfer_containerArrayElem1234) - yy2 := &yyv1 - yy2.CodecEncodeSelf(e) - } - z.EncSendContainerState(codecSelfer_containerArrayEnd1234) -} - -func (x codecSelfer1234) decSliceDownwardAPIVolumeFile(v *[]DownwardAPIVolumeFile, d *codec1978.Decoder) { - var h codecSelfer1234 - z, r := codec1978.GenHelperDecoder(d) - _, _, _ = h, z, r - - yyv1 := *v - yyh1, yyl1 := z.DecSliceHelperStart() - var yyc1 bool - _ = yyc1 - if yyl1 == 0 { - if yyv1 == nil { - yyv1 = []DownwardAPIVolumeFile{} - yyc1 = true - } else if len(yyv1) != 0 { - yyv1 = yyv1[:0] - yyc1 = true - } - } else if yyl1 > 0 { - var yyrr1, yyrl1 int - var yyrt1 bool - _, _ = yyrl1, yyrt1 - yyrr1 = yyl1 // len(yyv1) - if yyl1 > cap(yyv1) { - - yyrg1 := len(yyv1) > 0 - yyv21 := yyv1 - yyrl1, yyrt1 = z.DecInferLen(yyl1, z.DecBasicHandle().MaxInitLen, 48) - if yyrt1 { - if yyrl1 <= cap(yyv1) { - yyv1 = yyv1[:yyrl1] - } else { - yyv1 = make([]DownwardAPIVolumeFile, yyrl1) - } - } else { - yyv1 = make([]DownwardAPIVolumeFile, yyrl1) - } - yyc1 = true - yyrr1 = len(yyv1) - if yyrg1 { - copy(yyv1, yyv21) - } - } else if yyl1 != len(yyv1) { - yyv1 = yyv1[:yyl1] - yyc1 = true - } - yyj1 := 0 - for ; yyj1 < yyrr1; yyj1++ { - yyh1.ElemContainerState(yyj1) - if r.TryDecodeAsNil() { - yyv1[yyj1] = DownwardAPIVolumeFile{} - } else { - yyv2 := &yyv1[yyj1] - yyv2.CodecDecodeSelf(d) - } - - } - if yyrt1 { - for ; yyj1 < yyl1; yyj1++ { - yyv1 = append(yyv1, DownwardAPIVolumeFile{}) - yyh1.ElemContainerState(yyj1) - if r.TryDecodeAsNil() { - yyv1[yyj1] = DownwardAPIVolumeFile{} - } else { - yyv3 := &yyv1[yyj1] - yyv3.CodecDecodeSelf(d) - } - - } - } - - } else { - yyj1 := 0 - for ; !r.CheckBreak(); yyj1++ { - - if yyj1 >= len(yyv1) { - yyv1 = append(yyv1, DownwardAPIVolumeFile{}) // var yyz1 DownwardAPIVolumeFile - yyc1 = true - } - yyh1.ElemContainerState(yyj1) - if yyj1 < len(yyv1) { - if r.TryDecodeAsNil() { - yyv1[yyj1] = DownwardAPIVolumeFile{} - } else { - yyv4 := &yyv1[yyj1] - yyv4.CodecDecodeSelf(d) - } - - } else { - z.DecSwallow() - } - - } - if yyj1 < len(yyv1) { - yyv1 = yyv1[:yyj1] - yyc1 = true - } else if yyj1 == 0 && yyv1 == nil { - yyv1 = []DownwardAPIVolumeFile{} - yyc1 = true - } - } - yyh1.End() - if yyc1 { - *v = yyv1 - } -} - func (x codecSelfer1234) encSliceKeyToPath(v []KeyToPath, e *codec1978.Encoder) { var h codecSelfer1234 z, r := codec1978.GenHelperEncoder(e) @@ -51833,6 +52922,125 @@ func (x codecSelfer1234) decSliceKeyToPath(v *[]KeyToPath, d *codec1978.Decoder) } } +func (x codecSelfer1234) encSliceDownwardAPIVolumeFile(v []DownwardAPIVolumeFile, e *codec1978.Encoder) { + var h codecSelfer1234 + z, r := codec1978.GenHelperEncoder(e) + _, _, _ = h, z, r + r.EncodeArrayStart(len(v)) + for _, yyv1 := range v { + z.EncSendContainerState(codecSelfer_containerArrayElem1234) + yy2 := &yyv1 + yy2.CodecEncodeSelf(e) + } + z.EncSendContainerState(codecSelfer_containerArrayEnd1234) +} + +func (x codecSelfer1234) decSliceDownwardAPIVolumeFile(v *[]DownwardAPIVolumeFile, d *codec1978.Decoder) { + var h codecSelfer1234 + z, r := codec1978.GenHelperDecoder(d) + _, _, _ = h, z, r + + yyv1 := *v + yyh1, yyl1 := z.DecSliceHelperStart() + var yyc1 bool + _ = yyc1 + if yyl1 == 0 { + if yyv1 == nil { + yyv1 = []DownwardAPIVolumeFile{} + yyc1 = true + } else if len(yyv1) != 0 { + yyv1 = yyv1[:0] + yyc1 = true + } + } else if yyl1 > 0 { + var yyrr1, yyrl1 int + var yyrt1 bool + _, _ = yyrl1, yyrt1 + yyrr1 = yyl1 // len(yyv1) + if yyl1 > cap(yyv1) { + + yyrg1 := len(yyv1) > 0 + yyv21 := yyv1 + yyrl1, yyrt1 = z.DecInferLen(yyl1, z.DecBasicHandle().MaxInitLen, 48) + if yyrt1 { + if yyrl1 <= cap(yyv1) { + yyv1 = yyv1[:yyrl1] + } else { + yyv1 = make([]DownwardAPIVolumeFile, yyrl1) + } + } else { + yyv1 = make([]DownwardAPIVolumeFile, yyrl1) + } + yyc1 = true + yyrr1 = len(yyv1) + if yyrg1 { + copy(yyv1, yyv21) + } + } else if yyl1 != len(yyv1) { + yyv1 = yyv1[:yyl1] + yyc1 = true + } + yyj1 := 0 + for ; yyj1 < yyrr1; yyj1++ { + yyh1.ElemContainerState(yyj1) + if r.TryDecodeAsNil() { + yyv1[yyj1] = DownwardAPIVolumeFile{} + } else { + yyv2 := &yyv1[yyj1] + yyv2.CodecDecodeSelf(d) + } + + } + if yyrt1 { + for ; yyj1 < yyl1; yyj1++ { + yyv1 = append(yyv1, DownwardAPIVolumeFile{}) + yyh1.ElemContainerState(yyj1) + if r.TryDecodeAsNil() { + yyv1[yyj1] = DownwardAPIVolumeFile{} + } else { + yyv3 := &yyv1[yyj1] + yyv3.CodecDecodeSelf(d) + } + + } + } + + } else { + yyj1 := 0 + for ; !r.CheckBreak(); yyj1++ { + + if yyj1 >= len(yyv1) { + yyv1 = append(yyv1, DownwardAPIVolumeFile{}) // var yyz1 DownwardAPIVolumeFile + yyc1 = true + } + yyh1.ElemContainerState(yyj1) + if yyj1 < len(yyv1) { + if r.TryDecodeAsNil() { + yyv1[yyj1] = DownwardAPIVolumeFile{} + } else { + yyv4 := &yyv1[yyj1] + yyv4.CodecDecodeSelf(d) + } + + } else { + z.DecSwallow() + } + + } + if yyj1 < len(yyv1) { + yyv1 = yyv1[:yyj1] + yyc1 = true + } else if yyj1 == 0 && yyv1 == nil { + yyv1 = []DownwardAPIVolumeFile{} + yyc1 = true + } + } + yyh1.End() + if yyc1 { + *v = yyv1 + } +} + func (x codecSelfer1234) encSliceHTTPHeader(v []HTTPHeader, e *codec1978.Encoder) { var h codecSelfer1234 z, r := codec1978.GenHelperEncoder(e) @@ -52458,7 +53666,7 @@ func (x codecSelfer1234) decSlicePod(v *[]Pod, d *codec1978.Decoder) { yyrg1 := len(yyv1) > 0 yyv21 := yyv1 - yyrl1, yyrt1 = z.DecInferLen(yyl1, z.DecBasicHandle().MaxInitLen, 576) + yyrl1, yyrt1 = z.DecInferLen(yyl1, z.DecBasicHandle().MaxInitLen, 624) if yyrt1 { if yyrl1 <= cap(yyv1) { yyv1 = yyv1[:yyrl1] @@ -53172,7 +54380,7 @@ func (x codecSelfer1234) decSliceVolume(v *[]Volume, d *codec1978.Decoder) { yyrg1 := len(yyv1) > 0 yyv21 := yyv1 - yyrl1, yyrt1 = z.DecInferLen(yyl1, z.DecBasicHandle().MaxInitLen, 168) + yyrl1, yyrt1 = z.DecInferLen(yyl1, z.DecBasicHandle().MaxInitLen, 176) if yyrt1 { if yyrl1 <= cap(yyv1) { yyv1 = yyv1[:yyrl1] @@ -53767,7 +54975,7 @@ func (x codecSelfer1234) decSlicePodTemplate(v *[]PodTemplate, d *codec1978.Deco yyrg1 := len(yyv1) > 0 yyv21 := yyv1 - yyrl1, yyrt1 = z.DecInferLen(yyl1, z.DecBasicHandle().MaxInitLen, 648) + yyrl1, yyrt1 = z.DecInferLen(yyl1, z.DecBasicHandle().MaxInitLen, 672) if yyrt1 { if yyrl1 <= cap(yyv1) { yyv1 = yyv1[:yyrl1] @@ -55426,7 +56634,7 @@ func (x codecSelfer1234) decResourceList(v *ResourceList, d *codec1978.Decoder) yyl1 := r.ReadMapStart() yybh1 := z.DecBasicHandle() if yyv1 == nil { - yyrl1, _ := z.DecInferLen(yyl1, yybh1.MaxInitLen, 40) + yyrl1, _ := z.DecInferLen(yyl1, yybh1.MaxInitLen, 80) yyv1 = make(map[ResourceName]pkg3_resource.Quantity, yyrl1) *v = yyv1 } @@ -55547,7 +56755,7 @@ func (x codecSelfer1234) decSliceNode(v *[]Node, d *codec1978.Decoder) { yyrg1 := len(yyv1) > 0 yyv21 := yyv1 - yyrl1, yyrt1 = z.DecInferLen(yyl1, z.DecBasicHandle().MaxInitLen, 536) + yyrl1, yyrt1 = z.DecInferLen(yyl1, z.DecBasicHandle().MaxInitLen, 568) if yyrt1 { if yyrl1 <= cap(yyv1) { yyv1 = yyv1[:yyrl1] @@ -55975,7 +57183,7 @@ func (x codecSelfer1234) decSliceEvent(v *[]Event, d *codec1978.Decoder) { } } -func (x codecSelfer1234) encSliceruntime_Object(v []pkg8_runtime.Object, e *codec1978.Encoder) { +func (x codecSelfer1234) encSliceruntime_Object(v []pkg7_runtime.Object, e *codec1978.Encoder) { var h codecSelfer1234 z, r := codec1978.GenHelperEncoder(e) _, _, _ = h, z, r @@ -55997,7 +57205,7 @@ func (x codecSelfer1234) encSliceruntime_Object(v []pkg8_runtime.Object, e *code z.EncSendContainerState(codecSelfer_containerArrayEnd1234) } -func (x codecSelfer1234) decSliceruntime_Object(v *[]pkg8_runtime.Object, d *codec1978.Decoder) { +func (x codecSelfer1234) decSliceruntime_Object(v *[]pkg7_runtime.Object, d *codec1978.Decoder) { var h codecSelfer1234 z, r := codec1978.GenHelperDecoder(d) _, _, _ = h, z, r @@ -56008,7 +57216,7 @@ func (x codecSelfer1234) decSliceruntime_Object(v *[]pkg8_runtime.Object, d *cod _ = yyc1 if yyl1 == 0 { if yyv1 == nil { - yyv1 = []pkg8_runtime.Object{} + yyv1 = []pkg7_runtime.Object{} yyc1 = true } else if len(yyv1) != 0 { yyv1 = yyv1[:0] @@ -56028,10 +57236,10 @@ func (x codecSelfer1234) decSliceruntime_Object(v *[]pkg8_runtime.Object, d *cod if yyrl1 <= cap(yyv1) { yyv1 = yyv1[:yyrl1] } else { - yyv1 = make([]pkg8_runtime.Object, yyrl1) + yyv1 = make([]pkg7_runtime.Object, yyrl1) } } else { - yyv1 = make([]pkg8_runtime.Object, yyrl1) + yyv1 = make([]pkg7_runtime.Object, yyrl1) } yyc1 = true yyrr1 = len(yyv1) @@ -56084,7 +57292,7 @@ func (x codecSelfer1234) decSliceruntime_Object(v *[]pkg8_runtime.Object, d *cod for ; !r.CheckBreak(); yyj1++ { if yyj1 >= len(yyv1) { - yyv1 = append(yyv1, nil) // var yyz1 pkg8_runtime.Object + yyv1 = append(yyv1, nil) // var yyz1 pkg7_runtime.Object yyc1 = true } yyh1.ElemContainerState(yyj1) @@ -56111,7 +57319,7 @@ func (x codecSelfer1234) decSliceruntime_Object(v *[]pkg8_runtime.Object, d *cod yyv1 = yyv1[:yyj1] yyc1 = true } else if yyj1 == 0 && yyv1 == nil { - yyv1 = []pkg8_runtime.Object{} + yyv1 = []pkg7_runtime.Object{} yyc1 = true } } diff --git a/vendor/k8s.io/kubernetes/pkg/api/types.go b/vendor/k8s.io/kubernetes/pkg/api/types.go index fe927bf35d..a536c5b668 100644 --- a/vendor/k8s.io/kubernetes/pkg/api/types.go +++ b/vendor/k8s.io/kubernetes/pkg/api/types.go @@ -229,6 +229,8 @@ type VolumeSource struct { AzureFile *AzureFileVolumeSource `json:"azureFile,omitempty"` // ConfigMap represents a configMap that should populate this volume ConfigMap *ConfigMapVolumeSource `json:"configMap,omitempty"` + // VsphereVolume represents a vSphere volume attached and mounted on kubelets host machine + VsphereVolume *VsphereVirtualDiskVolumeSource `json:"vsphereVolume,omitempty"` } // Similar to VolumeSource but meant for the administrator who creates PVs. @@ -267,6 +269,8 @@ type PersistentVolumeSource struct { Flocker *FlockerVolumeSource `json:"flocker,omitempty"` // AzureFile represents an Azure File Service mount on the host and bind mount to the pod. AzureFile *AzureFileVolumeSource `json:"azureFile,omitempty"` + // VsphereVolume represents a vSphere volume attached and mounted on kubelets host machine + VsphereVolume *VsphereVirtualDiskVolumeSource `json:"vsphereVolume,omitempty"` } type PersistentVolumeClaimVolumeSource struct { @@ -411,6 +415,10 @@ const ( ClaimPending PersistentVolumeClaimPhase = "Pending" // used for PersistentVolumeClaims that are bound ClaimBound PersistentVolumeClaimPhase = "Bound" + // used for PersistentVolumeClaims that lost their underlying + // PersistentVolume. The claim was bound to a PersistentVolume and this + // volume does not exist any longer and all data on it was lost. + ClaimLost PersistentVolumeClaimPhase = "Lost" ) // Represents a host path mapped into a pod. @@ -582,6 +590,14 @@ type GitRepoVolumeSource struct { type SecretVolumeSource struct { // Name of the secret in the pod's namespace to use. SecretName string `json:"secretName,omitempty"` + // If unspecified, each key-value pair in the Data field of the referenced + // Secret will be projected into the volume as a file whose name is the + // key and content is the value. If specified, the listed keys will be + // projected into the specified paths, and unlisted keys will not be + // present. If a key is specified which is not present in the Secret, + // the volume setup will error. Paths must be relative and may not contain + // the '..' path or start with '..'. + Items []KeyToPath `json:"items,omitempty"` } // Represents an NFS mount that lasts the lifetime of a pod. @@ -704,6 +720,16 @@ type AzureFileVolumeSource struct { ReadOnly bool `json:"readOnly,omitempty"` } +// Represents a vSphere volume resource. +type VsphereVirtualDiskVolumeSource struct { + // Path that identifies vSphere volume vmdk + VolumePath string `json:"volumePath"` + // Filesystem type to mount. + // Must be a filesystem type supported by the host operating system. + // Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + FSType string `json:"fsType,omitempty"` +} + // Adapts a ConfigMap into a volume. // // The contents of the target ConfigMap's Data field will be presented in a @@ -1076,6 +1102,8 @@ const ( // PodReady means the pod is able to service requests and should be added to the // load balancing pools of all matching services. PodReady PodConditionType = "Ready" + // PodInitialized means that all init containers in the pod have started successfully. + PodInitialized PodConditionType = "Initialized" ) type PodCondition struct { @@ -1306,10 +1334,79 @@ type PreferredSchedulingTerm struct { Preference NodeSelectorTerm `json:"preference"` } +// The node this Taint is attached to has the effect "effect" on +// any pod that that does not tolerate the Taint. +type Taint struct { + // Required. The taint key to be applied to a node. + Key string `json:"key" patchStrategy:"merge" patchMergeKey:"key"` + // Required. The taint value corresponding to the taint key. + Value string `json:"value,omitempty"` + // Required. The effect of the taint on pods + // that do not tolerate the taint. + // Valid effects are NoSchedule and PreferNoSchedule. + Effect TaintEffect `json:"effect"` +} + +type TaintEffect string + +const ( + // Do not allow new pods to schedule onto the node unless they tolerate the taint, + // but allow all pods submitted to Kubelet without going through the scheduler + // to start, and allow all already-running pods to continue running. + // Enforced by the scheduler. + TaintEffectNoSchedule TaintEffect = "NoSchedule" + // Like TaintEffectNoSchedule, but the scheduler tries not to schedule + // new pods onto the node, rather than prohibiting new pods from scheduling + // onto the node entirely. Enforced by the scheduler. + TaintEffectPreferNoSchedule TaintEffect = "PreferNoSchedule" + // NOT YET IMPLEMENTED. TODO: Uncomment field once it is implemented. + // Do not allow new pods to schedule onto the node unless they tolerate the taint, + // do not allow pods to start on Kubelet unless they tolerate the taint, + // but allow all already-running pods to continue running. + // Enforced by the scheduler and Kubelet. + // TaintEffectNoScheduleNoAdmit TaintEffect = "NoScheduleNoAdmit" + // NOT YET IMPLEMENTED. TODO: Uncomment field once it is implemented. + // Do not allow new pods to schedule onto the node unless they tolerate the taint, + // do not allow pods to start on Kubelet unless they tolerate the taint, + // and evict any already-running pods that do not tolerate the taint. + // Enforced by the scheduler and Kubelet. + // TaintEffectNoScheduleNoAdmitNoExecute = "NoScheduleNoAdmitNoExecute" +) + +// The pod this Toleration is attached to tolerates any taint that matches +// the triple using the matching operator . +type Toleration struct { + // Required. Key is the taint key that the toleration applies to. + Key string `json:"key,omitempty" patchStrategy:"merge" patchMergeKey:"key"` + // operator represents a key's relationship to the value. + // Valid operators are Exists and Equal. Defaults to Equal. + // Exists is equivalent to wildcard for value, so that a pod can + // tolerate all taints of a particular category. + Operator TolerationOperator `json:"operator,omitempty"` + // Value is the taint value the toleration matches to. + // If the operator is Exists, the value should be empty, otherwise just a regular string. + Value string `json:"value,omitempty"` + // Effect indicates the taint effect to match. Empty means match all taint effects. + // When specified, allowed values are NoSchedule and PreferNoSchedule. + Effect TaintEffect `json:"effect,omitempty"` + // TODO: For forgiveness (#1574), we'd eventually add at least a grace period + // here, and possibly an occurrence threshold and period. +} + +// A toleration operator is the set of operators that can be used in a toleration. +type TolerationOperator string + +const ( + TolerationOpExists TolerationOperator = "Exists" + TolerationOpEqual TolerationOperator = "Equal" +) + // PodSpec is a description of a pod type PodSpec struct { Volumes []Volume `json:"volumes"` - // Required: there must be at least one container in a pod. + // List of initialization containers belonging to the pod. + InitContainers []Container `json:"-"` + // List of containers belonging to the pod. Containers []Container `json:"containers"` RestartPolicy RestartPolicy `json:"restartPolicy,omitempty"` // Optional duration in seconds the pod needs to terminate gracefully. May be decreased in delete request. @@ -1416,6 +1513,11 @@ type PodStatus struct { // This is before the Kubelet pulled the container image(s) for the pod. StartTime *unversioned.Time `json:"startTime,omitempty"` + // The list has one entry per init container in the manifest. The most recent successful + // init container will have ready = true, the most recently started container will have + // startTime set. + // More info: http://releases.k8s.io/HEAD/docs/user-guide/pod-states.md#container-statuses + InitContainerStatuses []ContainerStatus `json:"-"` // The list has one entry per container in the manifest. Each entry is // currently the output of `docker inspect`. This output format is *not* // final and should not be relied upon. @@ -1832,6 +1934,10 @@ type NodeSystemInfo struct { KubeletVersion string `json:"kubeletVersion"` // KubeProxy Version reported by the node. KubeProxyVersion string `json:"kubeProxyVersion"` + // The Operating System reported by the node + OperatingSystem string `json:"operatingSystem"` + // The Architecture reported by the node + Architecture string `json:"architecture"` } // NodeStatus is information about the current status of a node. @@ -1885,6 +1991,8 @@ const ( // NodeOutOfDisk means the kubelet will not accept new pods due to insufficient free disk // space on the node. NodeOutOfDisk NodeConditionType = "OutOfDisk" + // NodeMemoryPressure means the kubelet is under pressure due to insufficient available memory. + NodeMemoryPressure NodeConditionType = "MemoryPressure" ) type NodeCondition struct { diff --git a/vendor/k8s.io/kubernetes/pkg/api/unversioned/deep_copy_generated.go b/vendor/k8s.io/kubernetes/pkg/api/unversioned/deep_copy_generated.go index 6a7cd5c533..c4a551d657 100644 --- a/vendor/k8s.io/kubernetes/pkg/api/unversioned/deep_copy_generated.go +++ b/vendor/k8s.io/kubernetes/pkg/api/unversioned/deep_copy_generated.go @@ -21,15 +21,127 @@ limitations under the License. package unversioned import ( + "time" + conversion "k8s.io/kubernetes/pkg/conversion" - time "time" ) +func DeepCopy_unversioned_APIGroup(in APIGroup, out *APIGroup, c *conversion.Cloner) error { + if err := DeepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + return err + } + out.Name = in.Name + if in.Versions != nil { + in, out := in.Versions, &out.Versions + *out = make([]GroupVersionForDiscovery, len(in)) + for i := range in { + if err := DeepCopy_unversioned_GroupVersionForDiscovery(in[i], &(*out)[i], c); err != nil { + return err + } + } + } else { + out.Versions = nil + } + if err := DeepCopy_unversioned_GroupVersionForDiscovery(in.PreferredVersion, &out.PreferredVersion, c); err != nil { + return err + } + if in.ServerAddressByClientCIDRs != nil { + in, out := in.ServerAddressByClientCIDRs, &out.ServerAddressByClientCIDRs + *out = make([]ServerAddressByClientCIDR, len(in)) + for i := range in { + if err := DeepCopy_unversioned_ServerAddressByClientCIDR(in[i], &(*out)[i], c); err != nil { + return err + } + } + } else { + out.ServerAddressByClientCIDRs = nil + } + return nil +} + +func DeepCopy_unversioned_APIGroupList(in APIGroupList, out *APIGroupList, c *conversion.Cloner) error { + if err := DeepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + return err + } + if in.Groups != nil { + in, out := in.Groups, &out.Groups + *out = make([]APIGroup, len(in)) + for i := range in { + if err := DeepCopy_unversioned_APIGroup(in[i], &(*out)[i], c); err != nil { + return err + } + } + } else { + out.Groups = nil + } + return nil +} + +func DeepCopy_unversioned_APIResource(in APIResource, out *APIResource, c *conversion.Cloner) error { + out.Name = in.Name + out.Namespaced = in.Namespaced + out.Kind = in.Kind + return nil +} + +func DeepCopy_unversioned_APIResourceList(in APIResourceList, out *APIResourceList, c *conversion.Cloner) error { + if err := DeepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + return err + } + out.GroupVersion = in.GroupVersion + if in.APIResources != nil { + in, out := in.APIResources, &out.APIResources + *out = make([]APIResource, len(in)) + for i := range in { + if err := DeepCopy_unversioned_APIResource(in[i], &(*out)[i], c); err != nil { + return err + } + } + } else { + out.APIResources = nil + } + return nil +} + +func DeepCopy_unversioned_APIVersions(in APIVersions, out *APIVersions, c *conversion.Cloner) error { + if err := DeepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + return err + } + if in.Versions != nil { + in, out := in.Versions, &out.Versions + *out = make([]string, len(in)) + copy(*out, in) + } else { + out.Versions = nil + } + if in.ServerAddressByClientCIDRs != nil { + in, out := in.ServerAddressByClientCIDRs, &out.ServerAddressByClientCIDRs + *out = make([]ServerAddressByClientCIDR, len(in)) + for i := range in { + if err := DeepCopy_unversioned_ServerAddressByClientCIDR(in[i], &(*out)[i], c); err != nil { + return err + } + } + } else { + out.ServerAddressByClientCIDRs = nil + } + return nil +} + func DeepCopy_unversioned_Duration(in Duration, out *Duration, c *conversion.Cloner) error { out.Duration = in.Duration return nil } +func DeepCopy_unversioned_ExportOptions(in ExportOptions, out *ExportOptions, c *conversion.Cloner) error { + if err := DeepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + return err + } + out.Export = in.Export + out.Exact = in.Exact + return nil +} + func DeepCopy_unversioned_GroupKind(in GroupKind, out *GroupKind, c *conversion.Cloner) error { out.Group = in.Group out.Kind = in.Kind @@ -48,6 +160,12 @@ func DeepCopy_unversioned_GroupVersion(in GroupVersion, out *GroupVersion, c *co return nil } +func DeepCopy_unversioned_GroupVersionForDiscovery(in GroupVersionForDiscovery, out *GroupVersionForDiscovery, c *conversion.Cloner) error { + out.GroupVersion = in.GroupVersion + out.Version = in.Version + return nil +} + func DeepCopy_unversioned_GroupVersionKind(in GroupVersionKind, out *GroupVersionKind, c *conversion.Cloner) error { out.Group = in.Group out.Version = in.Version @@ -105,6 +223,76 @@ func DeepCopy_unversioned_ListMeta(in ListMeta, out *ListMeta, c *conversion.Clo return nil } +func DeepCopy_unversioned_Patch(in Patch, out *Patch, c *conversion.Cloner) error { + return nil +} + +func DeepCopy_unversioned_RootPaths(in RootPaths, out *RootPaths, c *conversion.Cloner) error { + if in.Paths != nil { + in, out := in.Paths, &out.Paths + *out = make([]string, len(in)) + copy(*out, in) + } else { + out.Paths = nil + } + return nil +} + +func DeepCopy_unversioned_ServerAddressByClientCIDR(in ServerAddressByClientCIDR, out *ServerAddressByClientCIDR, c *conversion.Cloner) error { + out.ClientCIDR = in.ClientCIDR + out.ServerAddress = in.ServerAddress + return nil +} + +func DeepCopy_unversioned_Status(in Status, out *Status, c *conversion.Cloner) error { + if err := DeepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + return err + } + if err := DeepCopy_unversioned_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { + return err + } + out.Status = in.Status + out.Message = in.Message + out.Reason = in.Reason + if in.Details != nil { + in, out := in.Details, &out.Details + *out = new(StatusDetails) + if err := DeepCopy_unversioned_StatusDetails(*in, *out, c); err != nil { + return err + } + } else { + out.Details = nil + } + out.Code = in.Code + return nil +} + +func DeepCopy_unversioned_StatusCause(in StatusCause, out *StatusCause, c *conversion.Cloner) error { + out.Type = in.Type + out.Message = in.Message + out.Field = in.Field + return nil +} + +func DeepCopy_unversioned_StatusDetails(in StatusDetails, out *StatusDetails, c *conversion.Cloner) error { + out.Name = in.Name + out.Group = in.Group + out.Kind = in.Kind + if in.Causes != nil { + in, out := in.Causes, &out.Causes + *out = make([]StatusCause, len(in)) + for i := range in { + if err := DeepCopy_unversioned_StatusCause(in[i], &(*out)[i], c); err != nil { + return err + } + } + } else { + out.Causes = nil + } + out.RetryAfterSeconds = in.RetryAfterSeconds + return nil +} + func DeepCopy_unversioned_Time(in Time, out *Time, c *conversion.Cloner) error { if newVal, err := c.DeepCopy(in.Time); err != nil { return err diff --git a/vendor/k8s.io/kubernetes/pkg/api/unversioned/group_version.go b/vendor/k8s.io/kubernetes/pkg/api/unversioned/group_version.go index 9d29341cfc..167002c3fc 100644 --- a/vendor/k8s.io/kubernetes/pkg/api/unversioned/group_version.go +++ b/vendor/k8s.io/kubernetes/pkg/api/unversioned/group_version.go @@ -29,8 +29,8 @@ import ( // `resource.group.com` -> `group=com, version=group, resource=resource` and `group=group.com, resource=resource` func ParseResourceArg(arg string) (*GroupVersionResource, GroupResource) { var gvr *GroupVersionResource - s := strings.SplitN(arg, ".", 3) - if len(s) == 3 { + if strings.Count(arg, ".") >= 2 { + s := strings.SplitN(arg, ".", 3) gvr = &GroupVersionResource{Group: s[2], Version: s[1], Resource: s[0]} } @@ -64,12 +64,11 @@ func (gr *GroupResource) String() string { // ParseGroupResource turns "resource.group" string into a GroupResource struct. Empty strings are allowed // for each field. func ParseGroupResource(gr string) GroupResource { - s := strings.SplitN(gr, ".", 2) - if len(s) == 1 { - return GroupResource{Resource: s[0]} + if i := strings.Index(gr, "."); i == -1 { + return GroupResource{Resource: gr} + } else { + return GroupResource{Group: gr[i+1:], Resource: gr[:i]} } - - return GroupResource{Group: s[1], Resource: s[0]} } // GroupVersionResource unambiguously identifies a resource. It doesn't anonymously include GroupVersion @@ -189,18 +188,14 @@ func ParseGroupVersion(gv string) (GroupVersion, error) { return GroupVersion{}, nil } - s := strings.Split(gv, "/") - // "v1" is the only special case. Otherwise GroupVersion is expected to contain - // one "/" dividing the string into two parts. - switch { - case len(s) == 1 && gv == "v1": - return GroupVersion{"", "v1"}, nil - case len(s) == 1: - return GroupVersion{"", s[0]}, nil - case len(s) == 2: - return GroupVersion{s[0], s[1]}, nil + switch strings.Count(gv, "/") { + case 0: + return GroupVersion{"", gv}, nil + case 1: + i := strings.Index(gv, "/") + return GroupVersion{gv[:i], gv[i+1:]}, nil default: - return GroupVersion{}, fmt.Errorf("Unexpected GroupVersion string: %v", gv) + return GroupVersion{}, fmt.Errorf("unexpected GroupVersion string: %v", gv) } } diff --git a/vendor/k8s.io/kubernetes/pkg/api/unversioned/types_swagger_doc_generated.go b/vendor/k8s.io/kubernetes/pkg/api/unversioned/types_swagger_doc_generated.go index e0e74dad1d..8caef8e549 100644 --- a/vendor/k8s.io/kubernetes/pkg/api/unversioned/types_swagger_doc_generated.go +++ b/vendor/k8s.io/kubernetes/pkg/api/unversioned/types_swagger_doc_generated.go @@ -1,5 +1,5 @@ /* -Copyright 2015 The Kubernetes Authors All rights reserved. +Copyright 2016 The Kubernetes Authors All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/vendor/k8s.io/kubernetes/pkg/api/unversioned/validation/validation.go b/vendor/k8s.io/kubernetes/pkg/api/unversioned/validation/validation.go index e0b4f17560..47852e3e29 100644 --- a/vendor/k8s.io/kubernetes/pkg/api/unversioned/validation/validation.go +++ b/vendor/k8s.io/kubernetes/pkg/api/unversioned/validation/validation.go @@ -17,18 +17,11 @@ limitations under the License. package validation import ( - "fmt" - "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/util/validation" "k8s.io/kubernetes/pkg/util/validation/field" ) -var ( - labelValueErrorMsg string = fmt.Sprintf(`must have at most %d characters, matching regex %s: e.g. "MyValue" or ""`, validation.LabelValueMaxLength, validation.LabelValueFmt) - qualifiedNameErrorMsg string = fmt.Sprintf(`must be a qualified name (at most %d characters, matching regex %s), with an optional DNS subdomain prefix (at most %d characters, matching regex %s) and slash (/): e.g. "MyName" or "example.com/MyName"`, validation.QualifiedNameMaxLength, validation.QualifiedNameFmt, validation.DNS1123SubdomainMaxLength, validation.DNS1123SubdomainFmt) -) - func ValidateLabelSelector(ps *unversioned.LabelSelector, fldPath *field.Path) field.ErrorList { allErrs := field.ErrorList{} if ps == nil { @@ -62,8 +55,8 @@ func ValidateLabelSelectorRequirement(sr unversioned.LabelSelectorRequirement, f // ValidateLabelName validates that the label name is correctly defined. func ValidateLabelName(labelName string, fldPath *field.Path) field.ErrorList { allErrs := field.ErrorList{} - if !validation.IsQualifiedName(labelName) { - allErrs = append(allErrs, field.Invalid(fldPath, labelName, qualifiedNameErrorMsg)) + for _, msg := range validation.IsQualifiedName(labelName) { + allErrs = append(allErrs, field.Invalid(fldPath, labelName, msg)) } return allErrs } @@ -73,8 +66,8 @@ func ValidateLabels(labels map[string]string, fldPath *field.Path) field.ErrorLi allErrs := field.ErrorList{} for k, v := range labels { allErrs = append(allErrs, ValidateLabelName(k, fldPath)...) - if !validation.IsValidLabelValue(v) { - allErrs = append(allErrs, field.Invalid(fldPath, v, labelValueErrorMsg)) + for _, msg := range validation.IsValidLabelValue(v) { + allErrs = append(allErrs, field.Invalid(fldPath, v, msg)) } } return allErrs diff --git a/vendor/k8s.io/kubernetes/pkg/api/unversioned/well_known_labels.go b/vendor/k8s.io/kubernetes/pkg/api/unversioned/well_known_labels.go index 2472942ab0..08e4f68892 100644 --- a/vendor/k8s.io/kubernetes/pkg/api/unversioned/well_known_labels.go +++ b/vendor/k8s.io/kubernetes/pkg/api/unversioned/well_known_labels.go @@ -24,4 +24,7 @@ const ( LabelZoneRegion = "failure-domain.beta.kubernetes.io/region" LabelInstanceType = "beta.kubernetes.io/instance-type" + + LabelOS = "beta.kubernetes.io/os" + LabelArch = "beta.kubernetes.io/arch" ) diff --git a/vendor/k8s.io/kubernetes/pkg/api/v1/conversion.go b/vendor/k8s.io/kubernetes/pkg/api/v1/conversion.go index a3631d00c7..501d345995 100644 --- a/vendor/k8s.io/kubernetes/pkg/api/v1/conversion.go +++ b/vendor/k8s.io/kubernetes/pkg/api/v1/conversion.go @@ -17,10 +17,9 @@ limitations under the License. package v1 import ( + "encoding/json" "fmt" - inf "gopkg.in/inf.v0" - "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/conversion" "k8s.io/kubernetes/pkg/runtime" @@ -258,6 +257,81 @@ func Convert_v1_ReplicationControllerSpec_To_api_ReplicationControllerSpec(in *R return nil } +func Convert_api_PodStatusResult_To_v1_PodStatusResult(in *api.PodStatusResult, out *PodStatusResult, s conversion.Scope) error { + if err := autoConvert_api_PodStatusResult_To_v1_PodStatusResult(in, out, s); err != nil { + return err + } + + if len(out.Status.InitContainerStatuses) > 0 { + if out.Annotations == nil { + out.Annotations = make(map[string]string) + } + value, err := json.Marshal(out.Status.InitContainerStatuses) + if err != nil { + return err + } + out.Annotations[PodInitContainerStatusesAnnotationKey] = string(value) + } else { + delete(out.Annotations, PodInitContainerStatusesAnnotationKey) + } + return nil +} + +func Convert_v1_PodStatusResult_To_api_PodStatusResult(in *PodStatusResult, out *api.PodStatusResult, s conversion.Scope) error { + // TODO: when we move init container to beta, remove these conversions + if value, ok := in.Annotations[PodInitContainerStatusesAnnotationKey]; ok { + var values []ContainerStatus + if err := json.Unmarshal([]byte(value), &values); err != nil { + return err + } + in.Status.InitContainerStatuses = values + } + + if err := autoConvert_v1_PodStatusResult_To_api_PodStatusResult(in, out, s); err != nil { + return err + } + delete(out.Annotations, PodInitContainerStatusesAnnotationKey) + return nil +} + +func Convert_api_PodTemplateSpec_To_v1_PodTemplateSpec(in *api.PodTemplateSpec, out *PodTemplateSpec, s conversion.Scope) error { + if err := autoConvert_api_PodTemplateSpec_To_v1_PodTemplateSpec(in, out, s); err != nil { + return err + } + + // TODO: when we move init container to beta, remove these conversions + if len(out.Spec.InitContainers) > 0 { + if out.Annotations == nil { + out.Annotations = make(map[string]string) + } + value, err := json.Marshal(out.Spec.InitContainers) + if err != nil { + return err + } + out.Annotations[PodInitContainersAnnotationKey] = string(value) + } else { + delete(out.Annotations, PodInitContainersAnnotationKey) + } + return nil +} + +func Convert_v1_PodTemplateSpec_To_api_PodTemplateSpec(in *PodTemplateSpec, out *api.PodTemplateSpec, s conversion.Scope) error { + // TODO: when we move init container to beta, remove these conversions + if value, ok := in.Annotations[PodInitContainersAnnotationKey]; ok { + var values []Container + if err := json.Unmarshal([]byte(value), &values); err != nil { + return err + } + in.Spec.InitContainers = values + } + + if err := autoConvert_v1_PodTemplateSpec_To_api_PodTemplateSpec(in, out, s); err != nil { + return err + } + delete(out.Annotations, PodInitContainersAnnotationKey) + return nil +} + // The following two PodSpec conversions are done here to support ServiceAccount // as an alias for ServiceAccountName. func Convert_api_PodSpec_To_v1_PodSpec(in *api.PodSpec, out *PodSpec, s conversion.Scope) error { @@ -271,6 +345,16 @@ func Convert_api_PodSpec_To_v1_PodSpec(in *api.PodSpec, out *PodSpec, s conversi } else { out.Volumes = nil } + if in.InitContainers != nil { + out.InitContainers = make([]Container, len(in.InitContainers)) + for i := range in.InitContainers { + if err := Convert_api_Container_To_v1_Container(&in.InitContainers[i], &out.InitContainers[i], s); err != nil { + return err + } + } + } else { + out.InitContainers = nil + } if in.Containers != nil { out.Containers = make([]Container, len(in.Containers)) for i := range in.Containers { @@ -346,6 +430,16 @@ func Convert_v1_PodSpec_To_api_PodSpec(in *PodSpec, out *api.PodSpec, s conversi } else { out.Volumes = nil } + if in.InitContainers != nil { + out.InitContainers = make([]api.Container, len(in.InitContainers)) + for i := range in.InitContainers { + if err := Convert_v1_Container_To_api_Container(&in.InitContainers[i], &out.InitContainers[i], s); err != nil { + return err + } + } + } else { + out.InitContainers = nil + } if in.Containers != nil { out.Containers = make([]api.Container, len(in.Containers)) for i := range in.Containers { @@ -419,6 +513,33 @@ func Convert_api_Pod_To_v1_Pod(in *api.Pod, out *Pod, s conversion.Scope) error if err := autoConvert_api_Pod_To_v1_Pod(in, out, s); err != nil { return err } + + // TODO: when we move init container to beta, remove these conversions + if len(out.Spec.InitContainers) > 0 { + if out.Annotations == nil { + out.Annotations = make(map[string]string) + } + value, err := json.Marshal(out.Spec.InitContainers) + if err != nil { + return err + } + out.Annotations[PodInitContainersAnnotationKey] = string(value) + } else { + delete(out.Annotations, PodInitContainersAnnotationKey) + } + if len(out.Status.InitContainerStatuses) > 0 { + if out.Annotations == nil { + out.Annotations = make(map[string]string) + } + value, err := json.Marshal(out.Status.InitContainerStatuses) + if err != nil { + return err + } + out.Annotations[PodInitContainerStatusesAnnotationKey] = string(value) + } else { + delete(out.Annotations, PodInitContainerStatusesAnnotationKey) + } + // We need to reset certain fields for mirror pods from pre-v1.1 kubelet // (#15960). // TODO: Remove this code after we drop support for v1.0 kubelets. @@ -434,7 +555,28 @@ func Convert_api_Pod_To_v1_Pod(in *api.Pod, out *Pod, s conversion.Scope) error } func Convert_v1_Pod_To_api_Pod(in *Pod, out *api.Pod, s conversion.Scope) error { - return autoConvert_v1_Pod_To_api_Pod(in, out, s) + // TODO: when we move init container to beta, remove these conversions + if value, ok := in.Annotations[PodInitContainersAnnotationKey]; ok { + var values []Container + if err := json.Unmarshal([]byte(value), &values); err != nil { + return err + } + in.Spec.InitContainers = values + } + if value, ok := in.Annotations[PodInitContainerStatusesAnnotationKey]; ok { + var values []ContainerStatus + if err := json.Unmarshal([]byte(value), &values); err != nil { + return err + } + in.Status.InitContainerStatuses = values + } + + if err := autoConvert_v1_Pod_To_api_Pod(in, out, s); err != nil { + return err + } + delete(out.Annotations, PodInitContainersAnnotationKey) + delete(out.Annotations, PodInitContainerStatusesAnnotationKey) + return nil } func Convert_api_ServiceSpec_To_v1_ServiceSpec(in *api.ServiceSpec, out *ServiceSpec, s conversion.Scope) error { @@ -535,8 +677,8 @@ func Convert_v1_ResourceList_To_api_ResourceList(in *ResourceList, out *api.Reso // TODO(#18538): We round up resource values to milli scale to maintain API compatibility. // In the future, we should instead reject values that need rounding. - const milliScale = 3 - value.Amount.Round(value.Amount, milliScale, inf.RoundUp) + const milliScale = -3 + value.RoundUp(milliScale) converted[api.ResourceName(key)] = *value } diff --git a/vendor/k8s.io/kubernetes/pkg/api/v1/conversion_generated.go b/vendor/k8s.io/kubernetes/pkg/api/v1/conversion_generated.go index 2b102bd0ed..74e1fb4eb3 100644 --- a/vendor/k8s.io/kubernetes/pkg/api/v1/conversion_generated.go +++ b/vendor/k8s.io/kubernetes/pkg/api/v1/conversion_generated.go @@ -311,12 +311,18 @@ func init() { Convert_api_ServiceStatus_To_v1_ServiceStatus, Convert_v1_TCPSocketAction_To_api_TCPSocketAction, Convert_api_TCPSocketAction_To_v1_TCPSocketAction, + Convert_v1_Taint_To_api_Taint, + Convert_api_Taint_To_v1_Taint, + Convert_v1_Toleration_To_api_Toleration, + Convert_api_Toleration_To_v1_Toleration, Convert_v1_Volume_To_api_Volume, Convert_api_Volume_To_v1_Volume, Convert_v1_VolumeMount_To_api_VolumeMount, Convert_api_VolumeMount_To_v1_VolumeMount, Convert_v1_VolumeSource_To_api_VolumeSource, Convert_api_VolumeSource_To_v1_VolumeSource, + Convert_v1_VsphereVirtualDiskVolumeSource_To_api_VsphereVirtualDiskVolumeSource, + Convert_api_VsphereVirtualDiskVolumeSource_To_v1_VsphereVirtualDiskVolumeSource, Convert_v1_WeightedPodAffinityTerm_To_api_WeightedPodAffinityTerm, Convert_api_WeightedPodAffinityTerm_To_v1_WeightedPodAffinityTerm, ); err != nil { @@ -3588,6 +3594,8 @@ func autoConvert_v1_NodeSystemInfo_To_api_NodeSystemInfo(in *NodeSystemInfo, out out.ContainerRuntimeVersion = in.ContainerRuntimeVersion out.KubeletVersion = in.KubeletVersion out.KubeProxyVersion = in.KubeProxyVersion + out.OperatingSystem = in.OperatingSystem + out.Architecture = in.Architecture return nil } @@ -3604,6 +3612,8 @@ func autoConvert_api_NodeSystemInfo_To_v1_NodeSystemInfo(in *api.NodeSystemInfo, out.ContainerRuntimeVersion = in.ContainerRuntimeVersion out.KubeletVersion = in.KubeletVersion out.KubeProxyVersion = in.KubeProxyVersion + out.OperatingSystem = in.OperatingSystem + out.Architecture = in.Architecture return nil } @@ -4240,6 +4250,15 @@ func autoConvert_v1_PersistentVolumeSource_To_api_PersistentVolumeSource(in *Per } else { out.AzureFile = nil } + if in.VsphereVolume != nil { + in, out := &in.VsphereVolume, &out.VsphereVolume + *out = new(api.VsphereVirtualDiskVolumeSource) + if err := Convert_v1_VsphereVirtualDiskVolumeSource_To_api_VsphereVirtualDiskVolumeSource(*in, *out, s); err != nil { + return err + } + } else { + out.VsphereVolume = nil + } return nil } @@ -4365,6 +4384,15 @@ func autoConvert_api_PersistentVolumeSource_To_v1_PersistentVolumeSource(in *api } else { out.AzureFile = nil } + if in.VsphereVolume != nil { + in, out := &in.VsphereVolume, &out.VsphereVolume + *out = new(VsphereVirtualDiskVolumeSource) + if err := Convert_api_VsphereVirtualDiskVolumeSource_To_v1_VsphereVirtualDiskVolumeSource(*in, *out, s); err != nil { + return err + } + } else { + out.VsphereVolume = nil + } return nil } @@ -5008,6 +5036,17 @@ func autoConvert_api_PodSpec_To_v1_PodSpec(in *api.PodSpec, out *PodSpec, s conv } else { out.Volumes = nil } + if in.InitContainers != nil { + in, out := &in.InitContainers, &out.InitContainers + *out = make([]Container, len(*in)) + for i := range *in { + if err := Convert_api_Container_To_v1_Container(&(*in)[i], &(*out)[i], s); err != nil { + return err + } + } + } else { + out.InitContainers = nil + } if in.Containers != nil { in, out := &in.Containers, &out.Containers *out = make([]Container, len(*in)) @@ -5097,6 +5136,17 @@ func autoConvert_v1_PodStatus_To_api_PodStatus(in *PodStatus, out *api.PodStatus } else { out.StartTime = nil } + if in.InitContainerStatuses != nil { + in, out := &in.InitContainerStatuses, &out.InitContainerStatuses + *out = make([]api.ContainerStatus, len(*in)) + for i := range *in { + if err := Convert_v1_ContainerStatus_To_api_ContainerStatus(&(*in)[i], &(*out)[i], s); err != nil { + return err + } + } + } else { + out.InitContainerStatuses = nil + } if in.ContainerStatuses != nil { in, out := &in.ContainerStatuses, &out.ContainerStatuses *out = make([]api.ContainerStatus, len(*in)) @@ -5141,6 +5191,17 @@ func autoConvert_api_PodStatus_To_v1_PodStatus(in *api.PodStatus, out *PodStatus } else { out.StartTime = nil } + if in.InitContainerStatuses != nil { + in, out := &in.InitContainerStatuses, &out.InitContainerStatuses + *out = make([]ContainerStatus, len(*in)) + for i := range *in { + if err := Convert_api_ContainerStatus_To_v1_ContainerStatus(&(*in)[i], &(*out)[i], s); err != nil { + return err + } + } + } else { + out.InitContainerStatuses = nil + } if in.ContainerStatuses != nil { in, out := &in.ContainerStatuses, &out.ContainerStatuses *out = make([]ContainerStatus, len(*in)) @@ -5172,10 +5233,6 @@ func autoConvert_v1_PodStatusResult_To_api_PodStatusResult(in *PodStatusResult, return nil } -func Convert_v1_PodStatusResult_To_api_PodStatusResult(in *PodStatusResult, out *api.PodStatusResult, s conversion.Scope) error { - return autoConvert_v1_PodStatusResult_To_api_PodStatusResult(in, out, s) -} - func autoConvert_api_PodStatusResult_To_v1_PodStatusResult(in *api.PodStatusResult, out *PodStatusResult, s conversion.Scope) error { if err := api.Convert_unversioned_TypeMeta_To_unversioned_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { return err @@ -5189,10 +5246,6 @@ func autoConvert_api_PodStatusResult_To_v1_PodStatusResult(in *api.PodStatusResu return nil } -func Convert_api_PodStatusResult_To_v1_PodStatusResult(in *api.PodStatusResult, out *PodStatusResult, s conversion.Scope) error { - return autoConvert_api_PodStatusResult_To_v1_PodStatusResult(in, out, s) -} - func autoConvert_v1_PodTemplate_To_api_PodTemplate(in *PodTemplate, out *api.PodTemplate, s conversion.Scope) error { if err := api.Convert_unversioned_TypeMeta_To_unversioned_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { return err @@ -5287,10 +5340,6 @@ func autoConvert_v1_PodTemplateSpec_To_api_PodTemplateSpec(in *PodTemplateSpec, return nil } -func Convert_v1_PodTemplateSpec_To_api_PodTemplateSpec(in *PodTemplateSpec, out *api.PodTemplateSpec, s conversion.Scope) error { - return autoConvert_v1_PodTemplateSpec_To_api_PodTemplateSpec(in, out, s) -} - func autoConvert_api_PodTemplateSpec_To_v1_PodTemplateSpec(in *api.PodTemplateSpec, out *PodTemplateSpec, s conversion.Scope) error { if err := Convert_api_ObjectMeta_To_v1_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { return err @@ -5301,10 +5350,6 @@ func autoConvert_api_PodTemplateSpec_To_v1_PodTemplateSpec(in *api.PodTemplateSp return nil } -func Convert_api_PodTemplateSpec_To_v1_PodTemplateSpec(in *api.PodTemplateSpec, out *PodTemplateSpec, s conversion.Scope) error { - return autoConvert_api_PodTemplateSpec_To_v1_PodTemplateSpec(in, out, s) -} - func autoConvert_v1_Preconditions_To_api_Preconditions(in *Preconditions, out *api.Preconditions, s conversion.Scope) error { if in.UID != nil { in, out := &in.UID, &out.UID @@ -5994,6 +6039,17 @@ func Convert_api_SecretList_To_v1_SecretList(in *api.SecretList, out *SecretList func autoConvert_v1_SecretVolumeSource_To_api_SecretVolumeSource(in *SecretVolumeSource, out *api.SecretVolumeSource, s conversion.Scope) error { out.SecretName = in.SecretName + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]api.KeyToPath, len(*in)) + for i := range *in { + if err := Convert_v1_KeyToPath_To_api_KeyToPath(&(*in)[i], &(*out)[i], s); err != nil { + return err + } + } + } else { + out.Items = nil + } return nil } @@ -6003,6 +6059,17 @@ func Convert_v1_SecretVolumeSource_To_api_SecretVolumeSource(in *SecretVolumeSou func autoConvert_api_SecretVolumeSource_To_v1_SecretVolumeSource(in *api.SecretVolumeSource, out *SecretVolumeSource, s conversion.Scope) error { out.SecretName = in.SecretName + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]KeyToPath, len(*in)) + for i := range *in { + if err := Convert_api_KeyToPath_To_v1_KeyToPath(&(*in)[i], &(*out)[i], s); err != nil { + return err + } + } + } else { + out.Items = nil + } return nil } @@ -6527,6 +6594,52 @@ func Convert_api_TCPSocketAction_To_v1_TCPSocketAction(in *api.TCPSocketAction, return autoConvert_api_TCPSocketAction_To_v1_TCPSocketAction(in, out, s) } +func autoConvert_v1_Taint_To_api_Taint(in *Taint, out *api.Taint, s conversion.Scope) error { + out.Key = in.Key + out.Value = in.Value + out.Effect = api.TaintEffect(in.Effect) + return nil +} + +func Convert_v1_Taint_To_api_Taint(in *Taint, out *api.Taint, s conversion.Scope) error { + return autoConvert_v1_Taint_To_api_Taint(in, out, s) +} + +func autoConvert_api_Taint_To_v1_Taint(in *api.Taint, out *Taint, s conversion.Scope) error { + out.Key = in.Key + out.Value = in.Value + out.Effect = TaintEffect(in.Effect) + return nil +} + +func Convert_api_Taint_To_v1_Taint(in *api.Taint, out *Taint, s conversion.Scope) error { + return autoConvert_api_Taint_To_v1_Taint(in, out, s) +} + +func autoConvert_v1_Toleration_To_api_Toleration(in *Toleration, out *api.Toleration, s conversion.Scope) error { + out.Key = in.Key + out.Operator = api.TolerationOperator(in.Operator) + out.Value = in.Value + out.Effect = api.TaintEffect(in.Effect) + return nil +} + +func Convert_v1_Toleration_To_api_Toleration(in *Toleration, out *api.Toleration, s conversion.Scope) error { + return autoConvert_v1_Toleration_To_api_Toleration(in, out, s) +} + +func autoConvert_api_Toleration_To_v1_Toleration(in *api.Toleration, out *Toleration, s conversion.Scope) error { + out.Key = in.Key + out.Operator = TolerationOperator(in.Operator) + out.Value = in.Value + out.Effect = TaintEffect(in.Effect) + return nil +} + +func Convert_api_Toleration_To_v1_Toleration(in *api.Toleration, out *Toleration, s conversion.Scope) error { + return autoConvert_api_Toleration_To_v1_Toleration(in, out, s) +} + func autoConvert_v1_Volume_To_api_Volume(in *Volume, out *api.Volume, s conversion.Scope) error { SetDefaults_Volume(in) out.Name = in.Name @@ -6748,6 +6861,15 @@ func autoConvert_v1_VolumeSource_To_api_VolumeSource(in *VolumeSource, out *api. } else { out.ConfigMap = nil } + if in.VsphereVolume != nil { + in, out := &in.VsphereVolume, &out.VsphereVolume + *out = new(api.VsphereVirtualDiskVolumeSource) + if err := Convert_v1_VsphereVirtualDiskVolumeSource_To_api_VsphereVirtualDiskVolumeSource(*in, *out, s); err != nil { + return err + } + } else { + out.VsphereVolume = nil + } return nil } @@ -6927,6 +7049,15 @@ func autoConvert_api_VolumeSource_To_v1_VolumeSource(in *api.VolumeSource, out * } else { out.ConfigMap = nil } + if in.VsphereVolume != nil { + in, out := &in.VsphereVolume, &out.VsphereVolume + *out = new(VsphereVirtualDiskVolumeSource) + if err := Convert_api_VsphereVirtualDiskVolumeSource_To_v1_VsphereVirtualDiskVolumeSource(*in, *out, s); err != nil { + return err + } + } else { + out.VsphereVolume = nil + } return nil } @@ -6934,6 +7065,26 @@ func Convert_api_VolumeSource_To_v1_VolumeSource(in *api.VolumeSource, out *Volu return autoConvert_api_VolumeSource_To_v1_VolumeSource(in, out, s) } +func autoConvert_v1_VsphereVirtualDiskVolumeSource_To_api_VsphereVirtualDiskVolumeSource(in *VsphereVirtualDiskVolumeSource, out *api.VsphereVirtualDiskVolumeSource, s conversion.Scope) error { + out.VolumePath = in.VolumePath + out.FSType = in.FSType + return nil +} + +func Convert_v1_VsphereVirtualDiskVolumeSource_To_api_VsphereVirtualDiskVolumeSource(in *VsphereVirtualDiskVolumeSource, out *api.VsphereVirtualDiskVolumeSource, s conversion.Scope) error { + return autoConvert_v1_VsphereVirtualDiskVolumeSource_To_api_VsphereVirtualDiskVolumeSource(in, out, s) +} + +func autoConvert_api_VsphereVirtualDiskVolumeSource_To_v1_VsphereVirtualDiskVolumeSource(in *api.VsphereVirtualDiskVolumeSource, out *VsphereVirtualDiskVolumeSource, s conversion.Scope) error { + out.VolumePath = in.VolumePath + out.FSType = in.FSType + return nil +} + +func Convert_api_VsphereVirtualDiskVolumeSource_To_v1_VsphereVirtualDiskVolumeSource(in *api.VsphereVirtualDiskVolumeSource, out *VsphereVirtualDiskVolumeSource, s conversion.Scope) error { + return autoConvert_api_VsphereVirtualDiskVolumeSource_To_v1_VsphereVirtualDiskVolumeSource(in, out, s) +} + func autoConvert_v1_WeightedPodAffinityTerm_To_api_WeightedPodAffinityTerm(in *WeightedPodAffinityTerm, out *api.WeightedPodAffinityTerm, s conversion.Scope) error { out.Weight = int(in.Weight) if err := Convert_v1_PodAffinityTerm_To_api_PodAffinityTerm(&in.PodAffinityTerm, &out.PodAffinityTerm, s); err != nil { diff --git a/vendor/k8s.io/kubernetes/pkg/api/v1/deep_copy_generated.go b/vendor/k8s.io/kubernetes/pkg/api/v1/deep_copy_generated.go index 376cc44a7a..7a6e9c1454 100644 --- a/vendor/k8s.io/kubernetes/pkg/api/v1/deep_copy_generated.go +++ b/vendor/k8s.io/kubernetes/pkg/api/v1/deep_copy_generated.go @@ -172,9 +172,12 @@ func init() { DeepCopy_v1_ServiceSpec, DeepCopy_v1_ServiceStatus, DeepCopy_v1_TCPSocketAction, + DeepCopy_v1_Taint, + DeepCopy_v1_Toleration, DeepCopy_v1_Volume, DeepCopy_v1_VolumeMount, DeepCopy_v1_VolumeSource, + DeepCopy_v1_VsphereVirtualDiskVolumeSource, DeepCopy_v1_WeightedPodAffinityTerm, ); err != nil { // if one of the deep copy functions is malformed, detect it immediately. @@ -1532,6 +1535,8 @@ func DeepCopy_v1_NodeSystemInfo(in NodeSystemInfo, out *NodeSystemInfo, c *conve out.ContainerRuntimeVersion = in.ContainerRuntimeVersion out.KubeletVersion = in.KubeletVersion out.KubeProxyVersion = in.KubeProxyVersion + out.OperatingSystem = in.OperatingSystem + out.Architecture = in.Architecture return nil } @@ -1868,6 +1873,15 @@ func DeepCopy_v1_PersistentVolumeSource(in PersistentVolumeSource, out *Persiste } else { out.AzureFile = nil } + if in.VsphereVolume != nil { + in, out := in.VsphereVolume, &out.VsphereVolume + *out = new(VsphereVirtualDiskVolumeSource) + if err := DeepCopy_v1_VsphereVirtualDiskVolumeSource(*in, *out, c); err != nil { + return err + } + } else { + out.VsphereVolume = nil + } return nil } @@ -2174,6 +2188,17 @@ func DeepCopy_v1_PodSpec(in PodSpec, out *PodSpec, c *conversion.Cloner) error { } else { out.Volumes = nil } + if in.InitContainers != nil { + in, out := in.InitContainers, &out.InitContainers + *out = make([]Container, len(in)) + for i := range in { + if err := DeepCopy_v1_Container(in[i], &(*out)[i], c); err != nil { + return err + } + } + } else { + out.InitContainers = nil + } if in.Containers != nil { in, out := in.Containers, &out.Containers *out = make([]Container, len(in)) @@ -2267,6 +2292,17 @@ func DeepCopy_v1_PodStatus(in PodStatus, out *PodStatus, c *conversion.Cloner) e } else { out.StartTime = nil } + if in.InitContainerStatuses != nil { + in, out := in.InitContainerStatuses, &out.InitContainerStatuses + *out = make([]ContainerStatus, len(in)) + for i := range in { + if err := DeepCopy_v1_ContainerStatus(in[i], &(*out)[i], c); err != nil { + return err + } + } + } else { + out.InitContainerStatuses = nil + } if in.ContainerStatuses != nil { in, out := in.ContainerStatuses, &out.ContainerStatuses *out = make([]ContainerStatus, len(in)) @@ -2676,6 +2712,17 @@ func DeepCopy_v1_SecretList(in SecretList, out *SecretList, c *conversion.Cloner func DeepCopy_v1_SecretVolumeSource(in SecretVolumeSource, out *SecretVolumeSource, c *conversion.Cloner) error { out.SecretName = in.SecretName + if in.Items != nil { + in, out := in.Items, &out.Items + *out = make([]KeyToPath, len(in)) + for i := range in { + if err := DeepCopy_v1_KeyToPath(in[i], &(*out)[i], c); err != nil { + return err + } + } + } else { + out.Items = nil + } return nil } @@ -2904,6 +2951,21 @@ func DeepCopy_v1_TCPSocketAction(in TCPSocketAction, out *TCPSocketAction, c *co return nil } +func DeepCopy_v1_Taint(in Taint, out *Taint, c *conversion.Cloner) error { + out.Key = in.Key + out.Value = in.Value + out.Effect = in.Effect + return nil +} + +func DeepCopy_v1_Toleration(in Toleration, out *Toleration, c *conversion.Cloner) error { + out.Key = in.Key + out.Operator = in.Operator + out.Value = in.Value + out.Effect = in.Effect + return nil +} + func DeepCopy_v1_Volume(in Volume, out *Volume, c *conversion.Cloner) error { out.Name = in.Name if err := DeepCopy_v1_VolumeSource(in.VolumeSource, &out.VolumeSource, c); err != nil { @@ -3092,6 +3154,21 @@ func DeepCopy_v1_VolumeSource(in VolumeSource, out *VolumeSource, c *conversion. } else { out.ConfigMap = nil } + if in.VsphereVolume != nil { + in, out := in.VsphereVolume, &out.VsphereVolume + *out = new(VsphereVirtualDiskVolumeSource) + if err := DeepCopy_v1_VsphereVirtualDiskVolumeSource(*in, *out, c); err != nil { + return err + } + } else { + out.VsphereVolume = nil + } + return nil +} + +func DeepCopy_v1_VsphereVirtualDiskVolumeSource(in VsphereVirtualDiskVolumeSource, out *VsphereVirtualDiskVolumeSource, c *conversion.Cloner) error { + out.VolumePath = in.VolumePath + out.FSType = in.FSType return nil } diff --git a/vendor/k8s.io/kubernetes/pkg/api/v1/generated.pb.go b/vendor/k8s.io/kubernetes/pkg/api/v1/generated.pb.go index 956ef7f0d0..02ed1a87e8 100644 --- a/vendor/k8s.io/kubernetes/pkg/api/v1/generated.pb.go +++ b/vendor/k8s.io/kubernetes/pkg/api/v1/generated.pb.go @@ -165,9 +165,12 @@ limitations under the License. ServiceSpec ServiceStatus TCPSocketAction + Taint + Toleration Volume VolumeMount VolumeSource + VsphereVirtualDiskVolumeSource WeightedPodAffinityTerm */ package v1 @@ -749,6 +752,14 @@ func (m *TCPSocketAction) Reset() { *m = TCPSocketAction{} } func (m *TCPSocketAction) String() string { return proto.CompactTextString(m) } func (*TCPSocketAction) ProtoMessage() {} +func (m *Taint) Reset() { *m = Taint{} } +func (m *Taint) String() string { return proto.CompactTextString(m) } +func (*Taint) ProtoMessage() {} + +func (m *Toleration) Reset() { *m = Toleration{} } +func (m *Toleration) String() string { return proto.CompactTextString(m) } +func (*Toleration) ProtoMessage() {} + func (m *Volume) Reset() { *m = Volume{} } func (m *Volume) String() string { return proto.CompactTextString(m) } func (*Volume) ProtoMessage() {} @@ -761,6 +772,10 @@ func (m *VolumeSource) Reset() { *m = VolumeSource{} } func (m *VolumeSource) String() string { return proto.CompactTextString(m) } func (*VolumeSource) ProtoMessage() {} +func (m *VsphereVirtualDiskVolumeSource) Reset() { *m = VsphereVirtualDiskVolumeSource{} } +func (m *VsphereVirtualDiskVolumeSource) String() string { return proto.CompactTextString(m) } +func (*VsphereVirtualDiskVolumeSource) ProtoMessage() {} + func (m *WeightedPodAffinityTerm) Reset() { *m = WeightedPodAffinityTerm{} } func (m *WeightedPodAffinityTerm) String() string { return proto.CompactTextString(m) } func (*WeightedPodAffinityTerm) ProtoMessage() {} @@ -906,9 +921,12 @@ func init() { proto.RegisterType((*ServiceSpec)(nil), "k8s.io.kubernetes.pkg.api.v1.ServiceSpec") proto.RegisterType((*ServiceStatus)(nil), "k8s.io.kubernetes.pkg.api.v1.ServiceStatus") proto.RegisterType((*TCPSocketAction)(nil), "k8s.io.kubernetes.pkg.api.v1.TCPSocketAction") + proto.RegisterType((*Taint)(nil), "k8s.io.kubernetes.pkg.api.v1.Taint") + proto.RegisterType((*Toleration)(nil), "k8s.io.kubernetes.pkg.api.v1.Toleration") proto.RegisterType((*Volume)(nil), "k8s.io.kubernetes.pkg.api.v1.Volume") proto.RegisterType((*VolumeMount)(nil), "k8s.io.kubernetes.pkg.api.v1.VolumeMount") proto.RegisterType((*VolumeSource)(nil), "k8s.io.kubernetes.pkg.api.v1.VolumeSource") + proto.RegisterType((*VsphereVirtualDiskVolumeSource)(nil), "k8s.io.kubernetes.pkg.api.v1.VsphereVirtualDiskVolumeSource") proto.RegisterType((*WeightedPodAffinityTerm)(nil), "k8s.io.kubernetes.pkg.api.v1.WeightedPodAffinityTerm") } func (m *AWSElasticBlockStoreVolumeSource) Marshal() (data []byte, err error) { @@ -4163,6 +4181,14 @@ func (m *NodeSystemInfo) MarshalTo(data []byte) (int, error) { i++ i = encodeVarintGenerated(data, i, uint64(len(m.KubeProxyVersion))) i += copy(data[i:], m.KubeProxyVersion) + data[i] = 0x4a + i++ + i = encodeVarintGenerated(data, i, uint64(len(m.OperatingSystem))) + i += copy(data[i:], m.OperatingSystem) + data[i] = 0x52 + i++ + i = encodeVarintGenerated(data, i, uint64(len(m.Architecture))) + i += copy(data[i:], m.Architecture) return i, nil } @@ -4840,6 +4866,16 @@ func (m *PersistentVolumeSource) MarshalTo(data []byte) (int, error) { } i += n97 } + if m.VsphereVolume != nil { + data[i] = 0x72 + i++ + i = encodeVarintGenerated(data, i, uint64(m.VsphereVolume.Size())) + n98, err := m.VsphereVolume.MarshalTo(data[i:]) + if err != nil { + return 0, err + } + i += n98 + } return i, nil } @@ -4873,21 +4909,21 @@ func (m *PersistentVolumeSpec) MarshalTo(data []byte) (int, error) { data[i] = 0x12 i++ i = encodeVarintGenerated(data, i, uint64((&v).Size())) - n98, err := (&v).MarshalTo(data[i:]) + n99, err := (&v).MarshalTo(data[i:]) if err != nil { return 0, err } - i += n98 + i += n99 } } data[i] = 0x12 i++ i = encodeVarintGenerated(data, i, uint64(m.PersistentVolumeSource.Size())) - n99, err := m.PersistentVolumeSource.MarshalTo(data[i:]) + n100, err := m.PersistentVolumeSource.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n99 + i += n100 if len(m.AccessModes) > 0 { for _, s := range m.AccessModes { data[i] = 0x1a @@ -4907,11 +4943,11 @@ func (m *PersistentVolumeSpec) MarshalTo(data []byte) (int, error) { data[i] = 0x22 i++ i = encodeVarintGenerated(data, i, uint64(m.ClaimRef.Size())) - n100, err := m.ClaimRef.MarshalTo(data[i:]) + n101, err := m.ClaimRef.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n100 + i += n101 } data[i] = 0x2a i++ @@ -4968,27 +5004,27 @@ func (m *Pod) MarshalTo(data []byte) (int, error) { data[i] = 0xa i++ i = encodeVarintGenerated(data, i, uint64(m.ObjectMeta.Size())) - n101, err := m.ObjectMeta.MarshalTo(data[i:]) - if err != nil { - return 0, err - } - i += n101 - data[i] = 0x12 - i++ - i = encodeVarintGenerated(data, i, uint64(m.Spec.Size())) - n102, err := m.Spec.MarshalTo(data[i:]) + n102, err := m.ObjectMeta.MarshalTo(data[i:]) if err != nil { return 0, err } i += n102 - data[i] = 0x1a + data[i] = 0x12 i++ - i = encodeVarintGenerated(data, i, uint64(m.Status.Size())) - n103, err := m.Status.MarshalTo(data[i:]) + i = encodeVarintGenerated(data, i, uint64(m.Spec.Size())) + n103, err := m.Spec.MarshalTo(data[i:]) if err != nil { return 0, err } i += n103 + data[i] = 0x1a + i++ + i = encodeVarintGenerated(data, i, uint64(m.Status.Size())) + n104, err := m.Status.MarshalTo(data[i:]) + if err != nil { + return 0, err + } + i += n104 return i, nil } @@ -5053,11 +5089,11 @@ func (m *PodAffinityTerm) MarshalTo(data []byte) (int, error) { data[i] = 0xa i++ i = encodeVarintGenerated(data, i, uint64(m.LabelSelector.Size())) - n104, err := m.LabelSelector.MarshalTo(data[i:]) + n105, err := m.LabelSelector.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n104 + i += n105 } if len(m.Namespaces) > 0 { for _, s := range m.Namespaces { @@ -5203,19 +5239,19 @@ func (m *PodCondition) MarshalTo(data []byte) (int, error) { data[i] = 0x1a i++ i = encodeVarintGenerated(data, i, uint64(m.LastProbeTime.Size())) - n105, err := m.LastProbeTime.MarshalTo(data[i:]) - if err != nil { - return 0, err - } - i += n105 - data[i] = 0x22 - i++ - i = encodeVarintGenerated(data, i, uint64(m.LastTransitionTime.Size())) - n106, err := m.LastTransitionTime.MarshalTo(data[i:]) + n106, err := m.LastProbeTime.MarshalTo(data[i:]) if err != nil { return 0, err } i += n106 + data[i] = 0x22 + i++ + i = encodeVarintGenerated(data, i, uint64(m.LastTransitionTime.Size())) + n107, err := m.LastTransitionTime.MarshalTo(data[i:]) + if err != nil { + return 0, err + } + i += n107 data[i] = 0x2a i++ i = encodeVarintGenerated(data, i, uint64(len(m.Reason))) @@ -5314,11 +5350,11 @@ func (m *PodList) MarshalTo(data []byte) (int, error) { data[i] = 0xa i++ i = encodeVarintGenerated(data, i, uint64(m.ListMeta.Size())) - n107, err := m.ListMeta.MarshalTo(data[i:]) + n108, err := m.ListMeta.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n107 + i += n108 if len(m.Items) > 0 { for _, msg := range m.Items { data[i] = 0x12 @@ -5378,11 +5414,11 @@ func (m *PodLogOptions) MarshalTo(data []byte) (int, error) { data[i] = 0x2a i++ i = encodeVarintGenerated(data, i, uint64(m.SinceTime.Size())) - n108, err := m.SinceTime.MarshalTo(data[i:]) + n109, err := m.SinceTime.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n108 + i += n109 } data[i] = 0x30 i++ @@ -5446,11 +5482,11 @@ func (m *PodSecurityContext) MarshalTo(data []byte) (int, error) { data[i] = 0xa i++ i = encodeVarintGenerated(data, i, uint64(m.SELinuxOptions.Size())) - n109, err := m.SELinuxOptions.MarshalTo(data[i:]) + n110, err := m.SELinuxOptions.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n109 + i += n110 } if m.RunAsUser != nil { data[i] = 0x10 @@ -5596,11 +5632,11 @@ func (m *PodSpec) MarshalTo(data []byte) (int, error) { data[i] = 0x72 i++ i = encodeVarintGenerated(data, i, uint64(m.SecurityContext.Size())) - n110, err := m.SecurityContext.MarshalTo(data[i:]) + n111, err := m.SecurityContext.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n110 + i += n111 } if len(m.ImagePullSecrets) > 0 { for _, msg := range m.ImagePullSecrets { @@ -5680,11 +5716,11 @@ func (m *PodStatus) MarshalTo(data []byte) (int, error) { data[i] = 0x3a i++ i = encodeVarintGenerated(data, i, uint64(m.StartTime.Size())) - n111, err := m.StartTime.MarshalTo(data[i:]) + n112, err := m.StartTime.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n111 + i += n112 } if len(m.ContainerStatuses) > 0 { for _, msg := range m.ContainerStatuses { @@ -5719,19 +5755,19 @@ func (m *PodStatusResult) MarshalTo(data []byte) (int, error) { data[i] = 0xa i++ i = encodeVarintGenerated(data, i, uint64(m.ObjectMeta.Size())) - n112, err := m.ObjectMeta.MarshalTo(data[i:]) - if err != nil { - return 0, err - } - i += n112 - data[i] = 0x12 - i++ - i = encodeVarintGenerated(data, i, uint64(m.Status.Size())) - n113, err := m.Status.MarshalTo(data[i:]) + n113, err := m.ObjectMeta.MarshalTo(data[i:]) if err != nil { return 0, err } i += n113 + data[i] = 0x12 + i++ + i = encodeVarintGenerated(data, i, uint64(m.Status.Size())) + n114, err := m.Status.MarshalTo(data[i:]) + if err != nil { + return 0, err + } + i += n114 return i, nil } @@ -5753,19 +5789,19 @@ func (m *PodTemplate) MarshalTo(data []byte) (int, error) { data[i] = 0xa i++ i = encodeVarintGenerated(data, i, uint64(m.ObjectMeta.Size())) - n114, err := m.ObjectMeta.MarshalTo(data[i:]) - if err != nil { - return 0, err - } - i += n114 - data[i] = 0x12 - i++ - i = encodeVarintGenerated(data, i, uint64(m.Template.Size())) - n115, err := m.Template.MarshalTo(data[i:]) + n115, err := m.ObjectMeta.MarshalTo(data[i:]) if err != nil { return 0, err } i += n115 + data[i] = 0x12 + i++ + i = encodeVarintGenerated(data, i, uint64(m.Template.Size())) + n116, err := m.Template.MarshalTo(data[i:]) + if err != nil { + return 0, err + } + i += n116 return i, nil } @@ -5787,11 +5823,11 @@ func (m *PodTemplateList) MarshalTo(data []byte) (int, error) { data[i] = 0xa i++ i = encodeVarintGenerated(data, i, uint64(m.ListMeta.Size())) - n116, err := m.ListMeta.MarshalTo(data[i:]) + n117, err := m.ListMeta.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n116 + i += n117 if len(m.Items) > 0 { for _, msg := range m.Items { data[i] = 0x12 @@ -5825,19 +5861,19 @@ func (m *PodTemplateSpec) MarshalTo(data []byte) (int, error) { data[i] = 0xa i++ i = encodeVarintGenerated(data, i, uint64(m.ObjectMeta.Size())) - n117, err := m.ObjectMeta.MarshalTo(data[i:]) - if err != nil { - return 0, err - } - i += n117 - data[i] = 0x12 - i++ - i = encodeVarintGenerated(data, i, uint64(m.Spec.Size())) - n118, err := m.Spec.MarshalTo(data[i:]) + n118, err := m.ObjectMeta.MarshalTo(data[i:]) if err != nil { return 0, err } i += n118 + data[i] = 0x12 + i++ + i = encodeVarintGenerated(data, i, uint64(m.Spec.Size())) + n119, err := m.Spec.MarshalTo(data[i:]) + if err != nil { + return 0, err + } + i += n119 return i, nil } @@ -5886,11 +5922,11 @@ func (m *PreferredSchedulingTerm) MarshalTo(data []byte) (int, error) { data[i] = 0x12 i++ i = encodeVarintGenerated(data, i, uint64(m.Preference.Size())) - n119, err := m.Preference.MarshalTo(data[i:]) + n120, err := m.Preference.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n119 + i += n120 return i, nil } @@ -5912,11 +5948,11 @@ func (m *Probe) MarshalTo(data []byte) (int, error) { data[i] = 0xa i++ i = encodeVarintGenerated(data, i, uint64(m.Handler.Size())) - n120, err := m.Handler.MarshalTo(data[i:]) + n121, err := m.Handler.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n120 + i += n121 data[i] = 0x10 i++ i = encodeVarintGenerated(data, i, uint64(m.InitialDelaySeconds)) @@ -5989,11 +6025,11 @@ func (m *RBDVolumeSource) MarshalTo(data []byte) (int, error) { data[i] = 0x3a i++ i = encodeVarintGenerated(data, i, uint64(m.SecretRef.Size())) - n121, err := m.SecretRef.MarshalTo(data[i:]) + n122, err := m.SecretRef.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n121 + i += n122 } data[i] = 0x40 i++ @@ -6024,11 +6060,11 @@ func (m *RangeAllocation) MarshalTo(data []byte) (int, error) { data[i] = 0xa i++ i = encodeVarintGenerated(data, i, uint64(m.ObjectMeta.Size())) - n122, err := m.ObjectMeta.MarshalTo(data[i:]) + n123, err := m.ObjectMeta.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n122 + i += n123 data[i] = 0x12 i++ i = encodeVarintGenerated(data, i, uint64(len(m.Range))) @@ -6060,27 +6096,27 @@ func (m *ReplicationController) MarshalTo(data []byte) (int, error) { data[i] = 0xa i++ i = encodeVarintGenerated(data, i, uint64(m.ObjectMeta.Size())) - n123, err := m.ObjectMeta.MarshalTo(data[i:]) - if err != nil { - return 0, err - } - i += n123 - data[i] = 0x12 - i++ - i = encodeVarintGenerated(data, i, uint64(m.Spec.Size())) - n124, err := m.Spec.MarshalTo(data[i:]) + n124, err := m.ObjectMeta.MarshalTo(data[i:]) if err != nil { return 0, err } i += n124 - data[i] = 0x1a + data[i] = 0x12 i++ - i = encodeVarintGenerated(data, i, uint64(m.Status.Size())) - n125, err := m.Status.MarshalTo(data[i:]) + i = encodeVarintGenerated(data, i, uint64(m.Spec.Size())) + n125, err := m.Spec.MarshalTo(data[i:]) if err != nil { return 0, err } i += n125 + data[i] = 0x1a + i++ + i = encodeVarintGenerated(data, i, uint64(m.Status.Size())) + n126, err := m.Status.MarshalTo(data[i:]) + if err != nil { + return 0, err + } + i += n126 return i, nil } @@ -6102,11 +6138,11 @@ func (m *ReplicationControllerList) MarshalTo(data []byte) (int, error) { data[i] = 0xa i++ i = encodeVarintGenerated(data, i, uint64(m.ListMeta.Size())) - n126, err := m.ListMeta.MarshalTo(data[i:]) + n127, err := m.ListMeta.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n126 + i += n127 if len(m.Items) > 0 { for _, msg := range m.Items { data[i] = 0x12 @@ -6163,11 +6199,11 @@ func (m *ReplicationControllerSpec) MarshalTo(data []byte) (int, error) { data[i] = 0x1a i++ i = encodeVarintGenerated(data, i, uint64(m.Template.Size())) - n127, err := m.Template.MarshalTo(data[i:]) + n128, err := m.Template.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n127 + i += n128 } return i, nil } @@ -6217,27 +6253,27 @@ func (m *ResourceQuota) MarshalTo(data []byte) (int, error) { data[i] = 0xa i++ i = encodeVarintGenerated(data, i, uint64(m.ObjectMeta.Size())) - n128, err := m.ObjectMeta.MarshalTo(data[i:]) - if err != nil { - return 0, err - } - i += n128 - data[i] = 0x12 - i++ - i = encodeVarintGenerated(data, i, uint64(m.Spec.Size())) - n129, err := m.Spec.MarshalTo(data[i:]) + n129, err := m.ObjectMeta.MarshalTo(data[i:]) if err != nil { return 0, err } i += n129 - data[i] = 0x1a + data[i] = 0x12 i++ - i = encodeVarintGenerated(data, i, uint64(m.Status.Size())) - n130, err := m.Status.MarshalTo(data[i:]) + i = encodeVarintGenerated(data, i, uint64(m.Spec.Size())) + n130, err := m.Spec.MarshalTo(data[i:]) if err != nil { return 0, err } i += n130 + data[i] = 0x1a + i++ + i = encodeVarintGenerated(data, i, uint64(m.Status.Size())) + n131, err := m.Status.MarshalTo(data[i:]) + if err != nil { + return 0, err + } + i += n131 return i, nil } @@ -6259,11 +6295,11 @@ func (m *ResourceQuotaList) MarshalTo(data []byte) (int, error) { data[i] = 0xa i++ i = encodeVarintGenerated(data, i, uint64(m.ListMeta.Size())) - n131, err := m.ListMeta.MarshalTo(data[i:]) + n132, err := m.ListMeta.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n131 + i += n132 if len(m.Items) > 0 { for _, msg := range m.Items { data[i] = 0x12 @@ -6309,11 +6345,11 @@ func (m *ResourceQuotaSpec) MarshalTo(data []byte) (int, error) { data[i] = 0x12 i++ i = encodeVarintGenerated(data, i, uint64((&v).Size())) - n132, err := (&v).MarshalTo(data[i:]) + n133, err := (&v).MarshalTo(data[i:]) if err != nil { return 0, err } - i += n132 + i += n133 } } if len(m.Scopes) > 0 { @@ -6364,11 +6400,11 @@ func (m *ResourceQuotaStatus) MarshalTo(data []byte) (int, error) { data[i] = 0x12 i++ i = encodeVarintGenerated(data, i, uint64((&v).Size())) - n133, err := (&v).MarshalTo(data[i:]) + n134, err := (&v).MarshalTo(data[i:]) if err != nil { return 0, err } - i += n133 + i += n134 } } if len(m.Used) > 0 { @@ -6386,11 +6422,11 @@ func (m *ResourceQuotaStatus) MarshalTo(data []byte) (int, error) { data[i] = 0x12 i++ i = encodeVarintGenerated(data, i, uint64((&v).Size())) - n134, err := (&v).MarshalTo(data[i:]) + n135, err := (&v).MarshalTo(data[i:]) if err != nil { return 0, err } - i += n134 + i += n135 } } return i, nil @@ -6426,11 +6462,11 @@ func (m *ResourceRequirements) MarshalTo(data []byte) (int, error) { data[i] = 0x12 i++ i = encodeVarintGenerated(data, i, uint64((&v).Size())) - n135, err := (&v).MarshalTo(data[i:]) + n136, err := (&v).MarshalTo(data[i:]) if err != nil { return 0, err } - i += n135 + i += n136 } } if len(m.Requests) > 0 { @@ -6448,11 +6484,11 @@ func (m *ResourceRequirements) MarshalTo(data []byte) (int, error) { data[i] = 0x12 i++ i = encodeVarintGenerated(data, i, uint64((&v).Size())) - n136, err := (&v).MarshalTo(data[i:]) + n137, err := (&v).MarshalTo(data[i:]) if err != nil { return 0, err } - i += n136 + i += n137 } } return i, nil @@ -6510,11 +6546,11 @@ func (m *Secret) MarshalTo(data []byte) (int, error) { data[i] = 0xa i++ i = encodeVarintGenerated(data, i, uint64(m.ObjectMeta.Size())) - n137, err := m.ObjectMeta.MarshalTo(data[i:]) + n138, err := m.ObjectMeta.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n137 + i += n138 if len(m.Data) > 0 { for k := range m.Data { data[i] = 0x12 @@ -6557,11 +6593,11 @@ func (m *SecretKeySelector) MarshalTo(data []byte) (int, error) { data[i] = 0xa i++ i = encodeVarintGenerated(data, i, uint64(m.LocalObjectReference.Size())) - n138, err := m.LocalObjectReference.MarshalTo(data[i:]) + n139, err := m.LocalObjectReference.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n138 + i += n139 data[i] = 0x12 i++ i = encodeVarintGenerated(data, i, uint64(len(m.Key))) @@ -6587,11 +6623,11 @@ func (m *SecretList) MarshalTo(data []byte) (int, error) { data[i] = 0xa i++ i = encodeVarintGenerated(data, i, uint64(m.ListMeta.Size())) - n139, err := m.ListMeta.MarshalTo(data[i:]) + n140, err := m.ListMeta.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n139 + i += n140 if len(m.Items) > 0 { for _, msg := range m.Items { data[i] = 0x12 @@ -6626,6 +6662,18 @@ func (m *SecretVolumeSource) MarshalTo(data []byte) (int, error) { i++ i = encodeVarintGenerated(data, i, uint64(len(m.SecretName))) i += copy(data[i:], m.SecretName) + if len(m.Items) > 0 { + for _, msg := range m.Items { + data[i] = 0x12 + i++ + i = encodeVarintGenerated(data, i, uint64(msg.Size())) + n, err := msg.MarshalTo(data[i:]) + if err != nil { + return 0, err + } + i += n + } + } return i, nil } @@ -6648,11 +6696,11 @@ func (m *SecurityContext) MarshalTo(data []byte) (int, error) { data[i] = 0xa i++ i = encodeVarintGenerated(data, i, uint64(m.Capabilities.Size())) - n140, err := m.Capabilities.MarshalTo(data[i:]) + n141, err := m.Capabilities.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n140 + i += n141 } if m.Privileged != nil { data[i] = 0x10 @@ -6668,11 +6716,11 @@ func (m *SecurityContext) MarshalTo(data []byte) (int, error) { data[i] = 0x1a i++ i = encodeVarintGenerated(data, i, uint64(m.SELinuxOptions.Size())) - n141, err := m.SELinuxOptions.MarshalTo(data[i:]) + n142, err := m.SELinuxOptions.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n141 + i += n142 } if m.RunAsUser != nil { data[i] = 0x20 @@ -6720,11 +6768,11 @@ func (m *SerializedReference) MarshalTo(data []byte) (int, error) { data[i] = 0xa i++ i = encodeVarintGenerated(data, i, uint64(m.Reference.Size())) - n142, err := m.Reference.MarshalTo(data[i:]) + n143, err := m.Reference.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n142 + i += n143 return i, nil } @@ -6746,27 +6794,27 @@ func (m *Service) MarshalTo(data []byte) (int, error) { data[i] = 0xa i++ i = encodeVarintGenerated(data, i, uint64(m.ObjectMeta.Size())) - n143, err := m.ObjectMeta.MarshalTo(data[i:]) - if err != nil { - return 0, err - } - i += n143 - data[i] = 0x12 - i++ - i = encodeVarintGenerated(data, i, uint64(m.Spec.Size())) - n144, err := m.Spec.MarshalTo(data[i:]) + n144, err := m.ObjectMeta.MarshalTo(data[i:]) if err != nil { return 0, err } i += n144 - data[i] = 0x1a + data[i] = 0x12 i++ - i = encodeVarintGenerated(data, i, uint64(m.Status.Size())) - n145, err := m.Status.MarshalTo(data[i:]) + i = encodeVarintGenerated(data, i, uint64(m.Spec.Size())) + n145, err := m.Spec.MarshalTo(data[i:]) if err != nil { return 0, err } i += n145 + data[i] = 0x1a + i++ + i = encodeVarintGenerated(data, i, uint64(m.Status.Size())) + n146, err := m.Status.MarshalTo(data[i:]) + if err != nil { + return 0, err + } + i += n146 return i, nil } @@ -6788,11 +6836,11 @@ func (m *ServiceAccount) MarshalTo(data []byte) (int, error) { data[i] = 0xa i++ i = encodeVarintGenerated(data, i, uint64(m.ObjectMeta.Size())) - n146, err := m.ObjectMeta.MarshalTo(data[i:]) + n147, err := m.ObjectMeta.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n146 + i += n147 if len(m.Secrets) > 0 { for _, msg := range m.Secrets { data[i] = 0x12 @@ -6838,11 +6886,11 @@ func (m *ServiceAccountList) MarshalTo(data []byte) (int, error) { data[i] = 0xa i++ i = encodeVarintGenerated(data, i, uint64(m.ListMeta.Size())) - n147, err := m.ListMeta.MarshalTo(data[i:]) + n148, err := m.ListMeta.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n147 + i += n148 if len(m.Items) > 0 { for _, msg := range m.Items { data[i] = 0x12 @@ -6876,11 +6924,11 @@ func (m *ServiceList) MarshalTo(data []byte) (int, error) { data[i] = 0xa i++ i = encodeVarintGenerated(data, i, uint64(m.ListMeta.Size())) - n148, err := m.ListMeta.MarshalTo(data[i:]) + n149, err := m.ListMeta.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n148 + i += n149 if len(m.Items) > 0 { for _, msg := range m.Items { data[i] = 0x12 @@ -6925,11 +6973,11 @@ func (m *ServicePort) MarshalTo(data []byte) (int, error) { data[i] = 0x22 i++ i = encodeVarintGenerated(data, i, uint64(m.TargetPort.Size())) - n149, err := m.TargetPort.MarshalTo(data[i:]) + n150, err := m.TargetPort.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n149 + i += n150 data[i] = 0x28 i++ i = encodeVarintGenerated(data, i, uint64(m.NodePort)) @@ -7069,11 +7117,11 @@ func (m *ServiceStatus) MarshalTo(data []byte) (int, error) { data[i] = 0xa i++ i = encodeVarintGenerated(data, i, uint64(m.LoadBalancer.Size())) - n150, err := m.LoadBalancer.MarshalTo(data[i:]) + n151, err := m.LoadBalancer.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n150 + i += n151 return i, nil } @@ -7095,11 +7143,75 @@ func (m *TCPSocketAction) MarshalTo(data []byte) (int, error) { data[i] = 0xa i++ i = encodeVarintGenerated(data, i, uint64(m.Port.Size())) - n151, err := m.Port.MarshalTo(data[i:]) + n152, err := m.Port.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n151 + i += n152 + return i, nil +} + +func (m *Taint) Marshal() (data []byte, err error) { + size := m.Size() + data = make([]byte, size) + n, err := m.MarshalTo(data) + if err != nil { + return nil, err + } + return data[:n], nil +} + +func (m *Taint) MarshalTo(data []byte) (int, error) { + var i int + _ = i + var l int + _ = l + data[i] = 0xa + i++ + i = encodeVarintGenerated(data, i, uint64(len(m.Key))) + i += copy(data[i:], m.Key) + data[i] = 0x12 + i++ + i = encodeVarintGenerated(data, i, uint64(len(m.Value))) + i += copy(data[i:], m.Value) + data[i] = 0x1a + i++ + i = encodeVarintGenerated(data, i, uint64(len(m.Effect))) + i += copy(data[i:], m.Effect) + return i, nil +} + +func (m *Toleration) Marshal() (data []byte, err error) { + size := m.Size() + data = make([]byte, size) + n, err := m.MarshalTo(data) + if err != nil { + return nil, err + } + return data[:n], nil +} + +func (m *Toleration) MarshalTo(data []byte) (int, error) { + var i int + _ = i + var l int + _ = l + data[i] = 0xa + i++ + i = encodeVarintGenerated(data, i, uint64(len(m.Key))) + i += copy(data[i:], m.Key) + data[i] = 0x12 + i++ + i = encodeVarintGenerated(data, i, uint64(len(m.Operator))) + i += copy(data[i:], m.Operator) + data[i] = 0x1a + i++ + i = encodeVarintGenerated(data, i, uint64(len(m.Value))) + i += copy(data[i:], m.Value) + data[i] = 0x22 + i++ + i = encodeVarintGenerated(data, i, uint64(len(m.Effect))) + i += copy(data[i:], m.Effect) return i, nil } @@ -7125,11 +7237,11 @@ func (m *Volume) MarshalTo(data []byte) (int, error) { data[i] = 0x12 i++ i = encodeVarintGenerated(data, i, uint64(m.VolumeSource.Size())) - n152, err := m.VolumeSource.MarshalTo(data[i:]) + n153, err := m.VolumeSource.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n152 + i += n153 return i, nil } @@ -7190,163 +7302,163 @@ func (m *VolumeSource) MarshalTo(data []byte) (int, error) { data[i] = 0xa i++ i = encodeVarintGenerated(data, i, uint64(m.HostPath.Size())) - n153, err := m.HostPath.MarshalTo(data[i:]) - if err != nil { - return 0, err - } - i += n153 - } - if m.EmptyDir != nil { - data[i] = 0x12 - i++ - i = encodeVarintGenerated(data, i, uint64(m.EmptyDir.Size())) - n154, err := m.EmptyDir.MarshalTo(data[i:]) + n154, err := m.HostPath.MarshalTo(data[i:]) if err != nil { return 0, err } i += n154 } - if m.GCEPersistentDisk != nil { - data[i] = 0x1a + if m.EmptyDir != nil { + data[i] = 0x12 i++ - i = encodeVarintGenerated(data, i, uint64(m.GCEPersistentDisk.Size())) - n155, err := m.GCEPersistentDisk.MarshalTo(data[i:]) + i = encodeVarintGenerated(data, i, uint64(m.EmptyDir.Size())) + n155, err := m.EmptyDir.MarshalTo(data[i:]) if err != nil { return 0, err } i += n155 } - if m.AWSElasticBlockStore != nil { - data[i] = 0x22 + if m.GCEPersistentDisk != nil { + data[i] = 0x1a i++ - i = encodeVarintGenerated(data, i, uint64(m.AWSElasticBlockStore.Size())) - n156, err := m.AWSElasticBlockStore.MarshalTo(data[i:]) + i = encodeVarintGenerated(data, i, uint64(m.GCEPersistentDisk.Size())) + n156, err := m.GCEPersistentDisk.MarshalTo(data[i:]) if err != nil { return 0, err } i += n156 } - if m.GitRepo != nil { - data[i] = 0x2a + if m.AWSElasticBlockStore != nil { + data[i] = 0x22 i++ - i = encodeVarintGenerated(data, i, uint64(m.GitRepo.Size())) - n157, err := m.GitRepo.MarshalTo(data[i:]) + i = encodeVarintGenerated(data, i, uint64(m.AWSElasticBlockStore.Size())) + n157, err := m.AWSElasticBlockStore.MarshalTo(data[i:]) if err != nil { return 0, err } i += n157 } - if m.Secret != nil { - data[i] = 0x32 + if m.GitRepo != nil { + data[i] = 0x2a i++ - i = encodeVarintGenerated(data, i, uint64(m.Secret.Size())) - n158, err := m.Secret.MarshalTo(data[i:]) + i = encodeVarintGenerated(data, i, uint64(m.GitRepo.Size())) + n158, err := m.GitRepo.MarshalTo(data[i:]) if err != nil { return 0, err } i += n158 } - if m.NFS != nil { - data[i] = 0x3a + if m.Secret != nil { + data[i] = 0x32 i++ - i = encodeVarintGenerated(data, i, uint64(m.NFS.Size())) - n159, err := m.NFS.MarshalTo(data[i:]) + i = encodeVarintGenerated(data, i, uint64(m.Secret.Size())) + n159, err := m.Secret.MarshalTo(data[i:]) if err != nil { return 0, err } i += n159 } - if m.ISCSI != nil { - data[i] = 0x42 + if m.NFS != nil { + data[i] = 0x3a i++ - i = encodeVarintGenerated(data, i, uint64(m.ISCSI.Size())) - n160, err := m.ISCSI.MarshalTo(data[i:]) + i = encodeVarintGenerated(data, i, uint64(m.NFS.Size())) + n160, err := m.NFS.MarshalTo(data[i:]) if err != nil { return 0, err } i += n160 } - if m.Glusterfs != nil { - data[i] = 0x4a + if m.ISCSI != nil { + data[i] = 0x42 i++ - i = encodeVarintGenerated(data, i, uint64(m.Glusterfs.Size())) - n161, err := m.Glusterfs.MarshalTo(data[i:]) + i = encodeVarintGenerated(data, i, uint64(m.ISCSI.Size())) + n161, err := m.ISCSI.MarshalTo(data[i:]) if err != nil { return 0, err } i += n161 } - if m.PersistentVolumeClaim != nil { - data[i] = 0x52 + if m.Glusterfs != nil { + data[i] = 0x4a i++ - i = encodeVarintGenerated(data, i, uint64(m.PersistentVolumeClaim.Size())) - n162, err := m.PersistentVolumeClaim.MarshalTo(data[i:]) + i = encodeVarintGenerated(data, i, uint64(m.Glusterfs.Size())) + n162, err := m.Glusterfs.MarshalTo(data[i:]) if err != nil { return 0, err } i += n162 } - if m.RBD != nil { - data[i] = 0x5a + if m.PersistentVolumeClaim != nil { + data[i] = 0x52 i++ - i = encodeVarintGenerated(data, i, uint64(m.RBD.Size())) - n163, err := m.RBD.MarshalTo(data[i:]) + i = encodeVarintGenerated(data, i, uint64(m.PersistentVolumeClaim.Size())) + n163, err := m.PersistentVolumeClaim.MarshalTo(data[i:]) if err != nil { return 0, err } i += n163 } - if m.FlexVolume != nil { - data[i] = 0x62 + if m.RBD != nil { + data[i] = 0x5a i++ - i = encodeVarintGenerated(data, i, uint64(m.FlexVolume.Size())) - n164, err := m.FlexVolume.MarshalTo(data[i:]) + i = encodeVarintGenerated(data, i, uint64(m.RBD.Size())) + n164, err := m.RBD.MarshalTo(data[i:]) if err != nil { return 0, err } i += n164 } - if m.Cinder != nil { - data[i] = 0x6a + if m.FlexVolume != nil { + data[i] = 0x62 i++ - i = encodeVarintGenerated(data, i, uint64(m.Cinder.Size())) - n165, err := m.Cinder.MarshalTo(data[i:]) + i = encodeVarintGenerated(data, i, uint64(m.FlexVolume.Size())) + n165, err := m.FlexVolume.MarshalTo(data[i:]) if err != nil { return 0, err } i += n165 } - if m.CephFS != nil { - data[i] = 0x72 + if m.Cinder != nil { + data[i] = 0x6a i++ - i = encodeVarintGenerated(data, i, uint64(m.CephFS.Size())) - n166, err := m.CephFS.MarshalTo(data[i:]) + i = encodeVarintGenerated(data, i, uint64(m.Cinder.Size())) + n166, err := m.Cinder.MarshalTo(data[i:]) if err != nil { return 0, err } i += n166 } - if m.Flocker != nil { - data[i] = 0x7a + if m.CephFS != nil { + data[i] = 0x72 i++ - i = encodeVarintGenerated(data, i, uint64(m.Flocker.Size())) - n167, err := m.Flocker.MarshalTo(data[i:]) + i = encodeVarintGenerated(data, i, uint64(m.CephFS.Size())) + n167, err := m.CephFS.MarshalTo(data[i:]) if err != nil { return 0, err } i += n167 } + if m.Flocker != nil { + data[i] = 0x7a + i++ + i = encodeVarintGenerated(data, i, uint64(m.Flocker.Size())) + n168, err := m.Flocker.MarshalTo(data[i:]) + if err != nil { + return 0, err + } + i += n168 + } if m.DownwardAPI != nil { data[i] = 0x82 i++ data[i] = 0x1 i++ i = encodeVarintGenerated(data, i, uint64(m.DownwardAPI.Size())) - n168, err := m.DownwardAPI.MarshalTo(data[i:]) + n169, err := m.DownwardAPI.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n168 + i += n169 } if m.FC != nil { data[i] = 0x8a @@ -7354,11 +7466,11 @@ func (m *VolumeSource) MarshalTo(data []byte) (int, error) { data[i] = 0x1 i++ i = encodeVarintGenerated(data, i, uint64(m.FC.Size())) - n169, err := m.FC.MarshalTo(data[i:]) + n170, err := m.FC.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n169 + i += n170 } if m.AzureFile != nil { data[i] = 0x92 @@ -7366,11 +7478,11 @@ func (m *VolumeSource) MarshalTo(data []byte) (int, error) { data[i] = 0x1 i++ i = encodeVarintGenerated(data, i, uint64(m.AzureFile.Size())) - n170, err := m.AzureFile.MarshalTo(data[i:]) + n171, err := m.AzureFile.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n170 + i += n171 } if m.ConfigMap != nil { data[i] = 0x9a @@ -7378,12 +7490,50 @@ func (m *VolumeSource) MarshalTo(data []byte) (int, error) { data[i] = 0x1 i++ i = encodeVarintGenerated(data, i, uint64(m.ConfigMap.Size())) - n171, err := m.ConfigMap.MarshalTo(data[i:]) + n172, err := m.ConfigMap.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n171 + i += n172 } + if m.VsphereVolume != nil { + data[i] = 0xa2 + i++ + data[i] = 0x1 + i++ + i = encodeVarintGenerated(data, i, uint64(m.VsphereVolume.Size())) + n173, err := m.VsphereVolume.MarshalTo(data[i:]) + if err != nil { + return 0, err + } + i += n173 + } + return i, nil +} + +func (m *VsphereVirtualDiskVolumeSource) Marshal() (data []byte, err error) { + size := m.Size() + data = make([]byte, size) + n, err := m.MarshalTo(data) + if err != nil { + return nil, err + } + return data[:n], nil +} + +func (m *VsphereVirtualDiskVolumeSource) MarshalTo(data []byte) (int, error) { + var i int + _ = i + var l int + _ = l + data[i] = 0xa + i++ + i = encodeVarintGenerated(data, i, uint64(len(m.VolumePath))) + i += copy(data[i:], m.VolumePath) + data[i] = 0x12 + i++ + i = encodeVarintGenerated(data, i, uint64(len(m.FSType))) + i += copy(data[i:], m.FSType) return i, nil } @@ -7408,11 +7558,11 @@ func (m *WeightedPodAffinityTerm) MarshalTo(data []byte) (int, error) { data[i] = 0x12 i++ i = encodeVarintGenerated(data, i, uint64(m.PodAffinityTerm.Size())) - n172, err := m.PodAffinityTerm.MarshalTo(data[i:]) + n174, err := m.PodAffinityTerm.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n172 + i += n174 return i, nil } @@ -8631,6 +8781,10 @@ func (m *NodeSystemInfo) Size() (n int) { n += 1 + l + sovGenerated(uint64(l)) l = len(m.KubeProxyVersion) n += 1 + l + sovGenerated(uint64(l)) + l = len(m.OperatingSystem) + n += 1 + l + sovGenerated(uint64(l)) + l = len(m.Architecture) + n += 1 + l + sovGenerated(uint64(l)) return n } @@ -8889,6 +9043,10 @@ func (m *PersistentVolumeSource) Size() (n int) { l = m.AzureFile.Size() n += 1 + l + sovGenerated(uint64(l)) } + if m.VsphereVolume != nil { + l = m.VsphereVolume.Size() + n += 1 + l + sovGenerated(uint64(l)) + } return n } @@ -9537,6 +9695,12 @@ func (m *SecretVolumeSource) Size() (n int) { _ = l l = len(m.SecretName) n += 1 + l + sovGenerated(uint64(l)) + if len(m.Items) > 0 { + for _, e := range m.Items { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } return n } @@ -9712,6 +9876,32 @@ func (m *TCPSocketAction) Size() (n int) { return n } +func (m *Taint) Size() (n int) { + var l int + _ = l + l = len(m.Key) + n += 1 + l + sovGenerated(uint64(l)) + l = len(m.Value) + n += 1 + l + sovGenerated(uint64(l)) + l = len(m.Effect) + n += 1 + l + sovGenerated(uint64(l)) + return n +} + +func (m *Toleration) Size() (n int) { + var l int + _ = l + l = len(m.Key) + n += 1 + l + sovGenerated(uint64(l)) + l = len(m.Operator) + n += 1 + l + sovGenerated(uint64(l)) + l = len(m.Value) + n += 1 + l + sovGenerated(uint64(l)) + l = len(m.Effect) + n += 1 + l + sovGenerated(uint64(l)) + return n +} + func (m *Volume) Size() (n int) { var l int _ = l @@ -9814,6 +10004,20 @@ func (m *VolumeSource) Size() (n int) { l = m.ConfigMap.Size() n += 2 + l + sovGenerated(uint64(l)) } + if m.VsphereVolume != nil { + l = m.VsphereVolume.Size() + n += 2 + l + sovGenerated(uint64(l)) + } + return n +} + +func (m *VsphereVirtualDiskVolumeSource) Size() (n int) { + var l int + _ = l + l = len(m.VolumePath) + n += 1 + l + sovGenerated(uint64(l)) + l = len(m.FSType) + n += 1 + l + sovGenerated(uint64(l)) return n } @@ -21462,6 +21666,64 @@ func (m *NodeSystemInfo) Unmarshal(data []byte) error { } m.KubeProxyVersion = string(data[iNdEx:postIndex]) iNdEx = postIndex + case 9: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field OperatingSystem", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.OperatingSystem = string(data[iNdEx:postIndex]) + iNdEx = postIndex + case 10: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Architecture", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Architecture = string(data[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenerated(data[iNdEx:]) @@ -24039,6 +24301,39 @@ func (m *PersistentVolumeSource) Unmarshal(data []byte) error { return err } iNdEx = postIndex + case 14: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field VsphereVolume", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.VsphereVolume == nil { + m.VsphereVolume = &VsphereVirtualDiskVolumeSource{} + } + if err := m.VsphereVolume.Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenerated(data[iNdEx:]) @@ -30487,6 +30782,37 @@ func (m *SecretVolumeSource) Unmarshal(data []byte) error { } m.SecretName = string(data[iNdEx:postIndex]) iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Items", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Items = append(m.Items, KeyToPath{}) + if err := m.Items[len(m.Items)-1].Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenerated(data[iNdEx:]) @@ -32072,6 +32398,309 @@ func (m *TCPSocketAction) Unmarshal(data []byte) error { } return nil } +func (m *Taint) Unmarshal(data []byte) error { + l := len(data) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Taint: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Taint: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Key", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Key = string(data[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Value", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Value = string(data[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Effect", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Effect = TaintEffect(data[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(data[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *Toleration) Unmarshal(data []byte) error { + l := len(data) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Toleration: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Toleration: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Key", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Key = string(data[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Operator", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Operator = TolerationOperator(data[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Value", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Value = string(data[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Effect", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Effect = TaintEffect(data[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(data[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func (m *Volume) Unmarshal(data []byte) error { l := len(data) iNdEx := 0 @@ -32994,6 +33623,147 @@ func (m *VolumeSource) Unmarshal(data []byte) error { return err } iNdEx = postIndex + case 20: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field VsphereVolume", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.VsphereVolume == nil { + m.VsphereVolume = &VsphereVirtualDiskVolumeSource{} + } + if err := m.VsphereVolume.Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(data[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *VsphereVirtualDiskVolumeSource) Unmarshal(data []byte) error { + l := len(data) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: VsphereVirtualDiskVolumeSource: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: VsphereVirtualDiskVolumeSource: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field VolumePath", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.VolumePath = string(data[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field FSType", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.FSType = string(data[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenerated(data[iNdEx:]) diff --git a/vendor/k8s.io/kubernetes/pkg/api/v1/generated.proto b/vendor/k8s.io/kubernetes/pkg/api/v1/generated.proto index db63aef8e2..936db15129 100644 --- a/vendor/k8s.io/kubernetes/pkg/api/v1/generated.proto +++ b/vendor/k8s.io/kubernetes/pkg/api/v1/generated.proto @@ -295,7 +295,7 @@ message Container { // More info: http://releases.k8s.io/HEAD/docs/user-guide/persistent-volumes.md#resources optional ResourceRequirements resources = 8; - // Pod volumes to mount into the container's filesyste. + // Pod volumes to mount into the container's filesystem. // Cannot be updated. repeated VolumeMount volumeMounts = 9; @@ -1322,6 +1322,12 @@ message NodeSystemInfo { // KubeProxy Version reported by the node. optional string kubeProxyVersion = 8; + + // The Operating System reported by the node + optional string operatingSystem = 9; + + // The Architecture reported by the node + optional string architecture = 10; } // ObjectFieldSelector selects an APIVersioned field of an object. @@ -1670,6 +1676,9 @@ message PersistentVolumeSource { // AzureFile represents an Azure File Service mount on the host and bind mount to the pod. optional AzureFileVolumeSource azureFile = 13; + + // VsphereVolume represents a vSphere volume attached and mounted on kubelets host machine + optional VsphereVirtualDiskVolumeSource vsphereVolume = 14; } // PersistentVolumeSpec is the specification of a persistent volume. @@ -2458,6 +2467,15 @@ message SecretVolumeSource { // Name of the secret in the pod's namespace to use. // More info: http://releases.k8s.io/HEAD/docs/user-guide/volumes.md#secrets optional string secretName = 1; + + // If unspecified, each key-value pair in the Data field of the referenced + // Secret will be projected into the volume as a file whose name is the + // key and content is the value. If specified, the listed keys will be + // projected into the specified paths, and unlisted keys will not be + // present. If a key is specified which is not present in the Secret, + // the volume setup will error. Paths must be relative and may not contain + // the '..' path or start with '..'. + repeated KeyToPath items = 2; } // SecurityContext holds security configuration that will be applied to a container. @@ -2680,6 +2698,42 @@ message TCPSocketAction { optional k8s.io.kubernetes.pkg.util.intstr.IntOrString port = 1; } +// The node this Taint is attached to has the effect "effect" on +// any pod that that does not tolerate the Taint. +message Taint { + // Required. The taint key to be applied to a node. + optional string key = 1; + + // Required. The taint value corresponding to the taint key. + optional string value = 2; + + // Required. The effect of the taint on pods + // that do not tolerate the taint. + // Valid effects are NoSchedule and PreferNoSchedule. + optional string effect = 3; +} + +// The pod this Toleration is attached to tolerates any taint that matches +// the triple using the matching operator . +message Toleration { + // Required. Key is the taint key that the toleration applies to. + optional string key = 1; + + // operator represents a key's relationship to the value. + // Valid operators are Exists and Equal. Defaults to Equal. + // Exists is equivalent to wildcard for value, so that a pod can + // tolerate all taints of a particular category. + optional string operator = 2; + + // Value is the taint value the toleration matches to. + // If the operator is Exists, the value should be empty, otherwise just a regular string. + optional string value = 3; + + // Effect indicates the taint effect to match. Empty means match all taint effects. + // When specified, allowed values are NoSchedule and PreferNoSchedule. + optional string effect = 4; +} + // Volume represents a named volume in a pod that may be accessed by any container in the pod. message Volume { // Volume's name. @@ -2793,6 +2847,20 @@ message VolumeSource { // ConfigMap represents a configMap that should populate this volume optional ConfigMapVolumeSource configMap = 19; + + // VsphereVolume represents a vSphere volume attached and mounted on kubelets host machine + optional VsphereVirtualDiskVolumeSource vsphereVolume = 20; +} + +// Represents a vSphere volume resource. +message VsphereVirtualDiskVolumeSource { + // Path that identifies vSphere volume vmdk + optional string volumePath = 1; + + // Filesystem type to mount. + // Must be a filesystem type supported by the host operating system. + // Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + optional string fsType = 2; } // The weights of all of the matched WeightedPodAffinityTerm fields are added per-node to find the most preferred node(s) diff --git a/vendor/k8s.io/kubernetes/pkg/api/v1/types.generated.go b/vendor/k8s.io/kubernetes/pkg/api/v1/types.generated.go index afcf01486f..dd945b1e00 100644 --- a/vendor/k8s.io/kubernetes/pkg/api/v1/types.generated.go +++ b/vendor/k8s.io/kubernetes/pkg/api/v1/types.generated.go @@ -1,5 +1,5 @@ /* -Copyright 2015 The Kubernetes Authors All rights reserved. +Copyright 2016 The Kubernetes Authors All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -25,12 +25,11 @@ import ( "errors" "fmt" codec1978 "github.com/ugorji/go/codec" - pkg4_inf_v0 "gopkg.in/inf.v0" pkg3_resource "k8s.io/kubernetes/pkg/api/resource" pkg2_unversioned "k8s.io/kubernetes/pkg/api/unversioned" - pkg6_runtime "k8s.io/kubernetes/pkg/runtime" + pkg5_runtime "k8s.io/kubernetes/pkg/runtime" pkg1_types "k8s.io/kubernetes/pkg/types" - pkg5_intstr "k8s.io/kubernetes/pkg/util/intstr" + pkg4_intstr "k8s.io/kubernetes/pkg/util/intstr" "reflect" "runtime" time "time" @@ -66,14 +65,13 @@ func init() { panic(err) } if false { // reference the types, but skip this branch at build/run time - var v0 pkg4_inf_v0.Dec - var v1 pkg3_resource.Quantity - var v2 pkg2_unversioned.Time - var v3 pkg6_runtime.RawExtension - var v4 pkg1_types.UID - var v5 pkg5_intstr.IntOrString - var v6 time.Time - _, _, _, _, _, _, _ = v0, v1, v2, v3, v4, v5, v6 + var v0 pkg3_resource.Quantity + var v1 pkg2_unversioned.Time + var v2 pkg5_runtime.RawExtension + var v3 pkg1_types.UID + var v4 pkg4_intstr.IntOrString + var v5 time.Time + _, _, _, _, _, _ = v0, v1, v2, v3, v4, v5 } } @@ -1078,7 +1076,7 @@ func (x *Volume) CodecEncodeSelf(e *codec1978.Encoder) { } else { yysep2 := !z.EncBinary() yy2arr2 := z.EncBasicHandle().StructToArray - var yyq2 [20]bool + var yyq2 [21]bool _, _, _ = yysep2, yyq2, yy2arr2 const yyr2 bool = false yyq2[1] = x.VolumeSource.HostPath != nil && x.HostPath != nil @@ -1100,9 +1098,10 @@ func (x *Volume) CodecEncodeSelf(e *codec1978.Encoder) { yyq2[17] = x.VolumeSource.FC != nil && x.FC != nil yyq2[18] = x.VolumeSource.AzureFile != nil && x.AzureFile != nil yyq2[19] = x.VolumeSource.ConfigMap != nil && x.ConfigMap != nil + yyq2[20] = x.VolumeSource.VsphereVolume != nil && x.VsphereVolume != nil var yynn2 int if yyr2 || yy2arr2 { - r.EncodeArrayStart(20) + r.EncodeArrayStart(21) } else { yynn2 = 1 for _, b := range yyq2 { @@ -1835,6 +1834,43 @@ func (x *Volume) CodecEncodeSelf(e *codec1978.Encoder) { } } } + var yyn63 bool + if x.VolumeSource.VsphereVolume == nil { + yyn63 = true + goto LABEL63 + } + LABEL63: + if yyr2 || yy2arr2 { + if yyn63 { + r.EncodeNil() + } else { + z.EncSendContainerState(codecSelfer_containerArrayElem1234) + if yyq2[20] { + if x.VsphereVolume == nil { + r.EncodeNil() + } else { + x.VsphereVolume.CodecEncodeSelf(e) + } + } else { + r.EncodeNil() + } + } + } else { + if yyq2[20] { + z.EncSendContainerState(codecSelfer_containerMapKey1234) + r.EncodeString(codecSelferC_UTF81234, string("vsphereVolume")) + z.EncSendContainerState(codecSelfer_containerMapValue1234) + if yyn63 { + r.EncodeNil() + } else { + if x.VsphereVolume == nil { + r.EncodeNil() + } else { + x.VsphereVolume.CodecEncodeSelf(e) + } + } + } + } if yyr2 || yy2arr2 { z.EncSendContainerState(codecSelfer_containerArrayEnd1234) } else { @@ -2168,6 +2204,20 @@ func (x *Volume) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) { } x.ConfigMap.CodecDecodeSelf(d) } + case "vsphereVolume": + if x.VolumeSource.VsphereVolume == nil { + x.VolumeSource.VsphereVolume = new(VsphereVirtualDiskVolumeSource) + } + if r.TryDecodeAsNil() { + if x.VsphereVolume != nil { + x.VsphereVolume = nil + } + } else { + if x.VsphereVolume == nil { + x.VsphereVolume = new(VsphereVirtualDiskVolumeSource) + } + x.VsphereVolume.CodecDecodeSelf(d) + } default: z.DecStructFieldNotFound(-1, yys3) } // end switch yys3 @@ -2179,16 +2229,16 @@ func (x *Volume) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { var h codecSelfer1234 z, r := codec1978.GenHelperDecoder(d) _, _, _ = h, z, r - var yyj24 int - var yyb24 bool - var yyhl24 bool = l >= 0 - yyj24++ - if yyhl24 { - yyb24 = yyj24 > l + var yyj25 int + var yyb25 bool + var yyhl25 bool = l >= 0 + yyj25++ + if yyhl25 { + yyb25 = yyj25 > l } else { - yyb24 = r.CheckBreak() + yyb25 = r.CheckBreak() } - if yyb24 { + if yyb25 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -2201,13 +2251,13 @@ func (x *Volume) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { if x.VolumeSource.HostPath == nil { x.VolumeSource.HostPath = new(HostPathVolumeSource) } - yyj24++ - if yyhl24 { - yyb24 = yyj24 > l + yyj25++ + if yyhl25 { + yyb25 = yyj25 > l } else { - yyb24 = r.CheckBreak() + yyb25 = r.CheckBreak() } - if yyb24 { + if yyb25 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -2225,13 +2275,13 @@ func (x *Volume) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { if x.VolumeSource.EmptyDir == nil { x.VolumeSource.EmptyDir = new(EmptyDirVolumeSource) } - yyj24++ - if yyhl24 { - yyb24 = yyj24 > l + yyj25++ + if yyhl25 { + yyb25 = yyj25 > l } else { - yyb24 = r.CheckBreak() + yyb25 = r.CheckBreak() } - if yyb24 { + if yyb25 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -2249,13 +2299,13 @@ func (x *Volume) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { if x.VolumeSource.GCEPersistentDisk == nil { x.VolumeSource.GCEPersistentDisk = new(GCEPersistentDiskVolumeSource) } - yyj24++ - if yyhl24 { - yyb24 = yyj24 > l + yyj25++ + if yyhl25 { + yyb25 = yyj25 > l } else { - yyb24 = r.CheckBreak() + yyb25 = r.CheckBreak() } - if yyb24 { + if yyb25 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -2273,13 +2323,13 @@ func (x *Volume) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { if x.VolumeSource.AWSElasticBlockStore == nil { x.VolumeSource.AWSElasticBlockStore = new(AWSElasticBlockStoreVolumeSource) } - yyj24++ - if yyhl24 { - yyb24 = yyj24 > l + yyj25++ + if yyhl25 { + yyb25 = yyj25 > l } else { - yyb24 = r.CheckBreak() + yyb25 = r.CheckBreak() } - if yyb24 { + if yyb25 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -2297,13 +2347,13 @@ func (x *Volume) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { if x.VolumeSource.GitRepo == nil { x.VolumeSource.GitRepo = new(GitRepoVolumeSource) } - yyj24++ - if yyhl24 { - yyb24 = yyj24 > l + yyj25++ + if yyhl25 { + yyb25 = yyj25 > l } else { - yyb24 = r.CheckBreak() + yyb25 = r.CheckBreak() } - if yyb24 { + if yyb25 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -2321,13 +2371,13 @@ func (x *Volume) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { if x.VolumeSource.Secret == nil { x.VolumeSource.Secret = new(SecretVolumeSource) } - yyj24++ - if yyhl24 { - yyb24 = yyj24 > l + yyj25++ + if yyhl25 { + yyb25 = yyj25 > l } else { - yyb24 = r.CheckBreak() + yyb25 = r.CheckBreak() } - if yyb24 { + if yyb25 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -2345,13 +2395,13 @@ func (x *Volume) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { if x.VolumeSource.NFS == nil { x.VolumeSource.NFS = new(NFSVolumeSource) } - yyj24++ - if yyhl24 { - yyb24 = yyj24 > l + yyj25++ + if yyhl25 { + yyb25 = yyj25 > l } else { - yyb24 = r.CheckBreak() + yyb25 = r.CheckBreak() } - if yyb24 { + if yyb25 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -2369,13 +2419,13 @@ func (x *Volume) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { if x.VolumeSource.ISCSI == nil { x.VolumeSource.ISCSI = new(ISCSIVolumeSource) } - yyj24++ - if yyhl24 { - yyb24 = yyj24 > l + yyj25++ + if yyhl25 { + yyb25 = yyj25 > l } else { - yyb24 = r.CheckBreak() + yyb25 = r.CheckBreak() } - if yyb24 { + if yyb25 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -2393,13 +2443,13 @@ func (x *Volume) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { if x.VolumeSource.Glusterfs == nil { x.VolumeSource.Glusterfs = new(GlusterfsVolumeSource) } - yyj24++ - if yyhl24 { - yyb24 = yyj24 > l + yyj25++ + if yyhl25 { + yyb25 = yyj25 > l } else { - yyb24 = r.CheckBreak() + yyb25 = r.CheckBreak() } - if yyb24 { + if yyb25 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -2417,13 +2467,13 @@ func (x *Volume) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { if x.VolumeSource.PersistentVolumeClaim == nil { x.VolumeSource.PersistentVolumeClaim = new(PersistentVolumeClaimVolumeSource) } - yyj24++ - if yyhl24 { - yyb24 = yyj24 > l + yyj25++ + if yyhl25 { + yyb25 = yyj25 > l } else { - yyb24 = r.CheckBreak() + yyb25 = r.CheckBreak() } - if yyb24 { + if yyb25 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -2441,13 +2491,13 @@ func (x *Volume) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { if x.VolumeSource.RBD == nil { x.VolumeSource.RBD = new(RBDVolumeSource) } - yyj24++ - if yyhl24 { - yyb24 = yyj24 > l + yyj25++ + if yyhl25 { + yyb25 = yyj25 > l } else { - yyb24 = r.CheckBreak() + yyb25 = r.CheckBreak() } - if yyb24 { + if yyb25 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -2465,13 +2515,13 @@ func (x *Volume) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { if x.VolumeSource.FlexVolume == nil { x.VolumeSource.FlexVolume = new(FlexVolumeSource) } - yyj24++ - if yyhl24 { - yyb24 = yyj24 > l + yyj25++ + if yyhl25 { + yyb25 = yyj25 > l } else { - yyb24 = r.CheckBreak() + yyb25 = r.CheckBreak() } - if yyb24 { + if yyb25 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -2489,13 +2539,13 @@ func (x *Volume) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { if x.VolumeSource.Cinder == nil { x.VolumeSource.Cinder = new(CinderVolumeSource) } - yyj24++ - if yyhl24 { - yyb24 = yyj24 > l + yyj25++ + if yyhl25 { + yyb25 = yyj25 > l } else { - yyb24 = r.CheckBreak() + yyb25 = r.CheckBreak() } - if yyb24 { + if yyb25 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -2513,13 +2563,13 @@ func (x *Volume) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { if x.VolumeSource.CephFS == nil { x.VolumeSource.CephFS = new(CephFSVolumeSource) } - yyj24++ - if yyhl24 { - yyb24 = yyj24 > l + yyj25++ + if yyhl25 { + yyb25 = yyj25 > l } else { - yyb24 = r.CheckBreak() + yyb25 = r.CheckBreak() } - if yyb24 { + if yyb25 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -2537,13 +2587,13 @@ func (x *Volume) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { if x.VolumeSource.Flocker == nil { x.VolumeSource.Flocker = new(FlockerVolumeSource) } - yyj24++ - if yyhl24 { - yyb24 = yyj24 > l + yyj25++ + if yyhl25 { + yyb25 = yyj25 > l } else { - yyb24 = r.CheckBreak() + yyb25 = r.CheckBreak() } - if yyb24 { + if yyb25 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -2561,13 +2611,13 @@ func (x *Volume) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { if x.VolumeSource.DownwardAPI == nil { x.VolumeSource.DownwardAPI = new(DownwardAPIVolumeSource) } - yyj24++ - if yyhl24 { - yyb24 = yyj24 > l + yyj25++ + if yyhl25 { + yyb25 = yyj25 > l } else { - yyb24 = r.CheckBreak() + yyb25 = r.CheckBreak() } - if yyb24 { + if yyb25 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -2585,13 +2635,13 @@ func (x *Volume) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { if x.VolumeSource.FC == nil { x.VolumeSource.FC = new(FCVolumeSource) } - yyj24++ - if yyhl24 { - yyb24 = yyj24 > l + yyj25++ + if yyhl25 { + yyb25 = yyj25 > l } else { - yyb24 = r.CheckBreak() + yyb25 = r.CheckBreak() } - if yyb24 { + if yyb25 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -2609,13 +2659,13 @@ func (x *Volume) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { if x.VolumeSource.AzureFile == nil { x.VolumeSource.AzureFile = new(AzureFileVolumeSource) } - yyj24++ - if yyhl24 { - yyb24 = yyj24 > l + yyj25++ + if yyhl25 { + yyb25 = yyj25 > l } else { - yyb24 = r.CheckBreak() + yyb25 = r.CheckBreak() } - if yyb24 { + if yyb25 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -2633,13 +2683,13 @@ func (x *Volume) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { if x.VolumeSource.ConfigMap == nil { x.VolumeSource.ConfigMap = new(ConfigMapVolumeSource) } - yyj24++ - if yyhl24 { - yyb24 = yyj24 > l + yyj25++ + if yyhl25 { + yyb25 = yyj25 > l } else { - yyb24 = r.CheckBreak() + yyb25 = r.CheckBreak() } - if yyb24 { + if yyb25 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -2654,18 +2704,42 @@ func (x *Volume) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { } x.ConfigMap.CodecDecodeSelf(d) } - for { - yyj24++ - if yyhl24 { - yyb24 = yyj24 > l - } else { - yyb24 = r.CheckBreak() + if x.VolumeSource.VsphereVolume == nil { + x.VolumeSource.VsphereVolume = new(VsphereVirtualDiskVolumeSource) + } + yyj25++ + if yyhl25 { + yyb25 = yyj25 > l + } else { + yyb25 = r.CheckBreak() + } + if yyb25 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) + return + } + z.DecSendContainerState(codecSelfer_containerArrayElem1234) + if r.TryDecodeAsNil() { + if x.VsphereVolume != nil { + x.VsphereVolume = nil } - if yyb24 { + } else { + if x.VsphereVolume == nil { + x.VsphereVolume = new(VsphereVirtualDiskVolumeSource) + } + x.VsphereVolume.CodecDecodeSelf(d) + } + for { + yyj25++ + if yyhl25 { + yyb25 = yyj25 > l + } else { + yyb25 = r.CheckBreak() + } + if yyb25 { break } z.DecSendContainerState(codecSelfer_containerArrayElem1234) - z.DecStructFieldNotFound(yyj24-1, "") + z.DecStructFieldNotFound(yyj25-1, "") } z.DecSendContainerState(codecSelfer_containerArrayEnd1234) } @@ -2684,7 +2758,7 @@ func (x *VolumeSource) CodecEncodeSelf(e *codec1978.Encoder) { } else { yysep2 := !z.EncBinary() yy2arr2 := z.EncBasicHandle().StructToArray - var yyq2 [19]bool + var yyq2 [20]bool _, _, _ = yysep2, yyq2, yy2arr2 const yyr2 bool = false yyq2[0] = x.HostPath != nil @@ -2706,9 +2780,10 @@ func (x *VolumeSource) CodecEncodeSelf(e *codec1978.Encoder) { yyq2[16] = x.FC != nil yyq2[17] = x.AzureFile != nil yyq2[18] = x.ConfigMap != nil + yyq2[19] = x.VsphereVolume != nil var yynn2 int if yyr2 || yy2arr2 { - r.EncodeArrayStart(19) + r.EncodeArrayStart(20) } else { yynn2 = 0 for _, b := range yyq2 { @@ -3156,6 +3231,29 @@ func (x *VolumeSource) CodecEncodeSelf(e *codec1978.Encoder) { } } } + if yyr2 || yy2arr2 { + z.EncSendContainerState(codecSelfer_containerArrayElem1234) + if yyq2[19] { + if x.VsphereVolume == nil { + r.EncodeNil() + } else { + x.VsphereVolume.CodecEncodeSelf(e) + } + } else { + r.EncodeNil() + } + } else { + if yyq2[19] { + z.EncSendContainerState(codecSelfer_containerMapKey1234) + r.EncodeString(codecSelferC_UTF81234, string("vsphereVolume")) + z.EncSendContainerState(codecSelfer_containerMapValue1234) + if x.VsphereVolume == nil { + r.EncodeNil() + } else { + x.VsphereVolume.CodecEncodeSelf(e) + } + } + } if yyr2 || yy2arr2 { z.EncSendContainerState(codecSelfer_containerArrayEnd1234) } else { @@ -3426,6 +3524,17 @@ func (x *VolumeSource) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) { } x.ConfigMap.CodecDecodeSelf(d) } + case "vsphereVolume": + if r.TryDecodeAsNil() { + if x.VsphereVolume != nil { + x.VsphereVolume = nil + } + } else { + if x.VsphereVolume == nil { + x.VsphereVolume = new(VsphereVirtualDiskVolumeSource) + } + x.VsphereVolume.CodecDecodeSelf(d) + } default: z.DecStructFieldNotFound(-1, yys3) } // end switch yys3 @@ -3437,16 +3546,16 @@ func (x *VolumeSource) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { var h codecSelfer1234 z, r := codec1978.GenHelperDecoder(d) _, _, _ = h, z, r - var yyj23 int - var yyb23 bool - var yyhl23 bool = l >= 0 - yyj23++ - if yyhl23 { - yyb23 = yyj23 > l + var yyj24 int + var yyb24 bool + var yyhl24 bool = l >= 0 + yyj24++ + if yyhl24 { + yyb24 = yyj24 > l } else { - yyb23 = r.CheckBreak() + yyb24 = r.CheckBreak() } - if yyb23 { + if yyb24 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -3461,13 +3570,13 @@ func (x *VolumeSource) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { } x.HostPath.CodecDecodeSelf(d) } - yyj23++ - if yyhl23 { - yyb23 = yyj23 > l + yyj24++ + if yyhl24 { + yyb24 = yyj24 > l } else { - yyb23 = r.CheckBreak() + yyb24 = r.CheckBreak() } - if yyb23 { + if yyb24 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -3482,13 +3591,13 @@ func (x *VolumeSource) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { } x.EmptyDir.CodecDecodeSelf(d) } - yyj23++ - if yyhl23 { - yyb23 = yyj23 > l + yyj24++ + if yyhl24 { + yyb24 = yyj24 > l } else { - yyb23 = r.CheckBreak() + yyb24 = r.CheckBreak() } - if yyb23 { + if yyb24 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -3503,13 +3612,13 @@ func (x *VolumeSource) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { } x.GCEPersistentDisk.CodecDecodeSelf(d) } - yyj23++ - if yyhl23 { - yyb23 = yyj23 > l + yyj24++ + if yyhl24 { + yyb24 = yyj24 > l } else { - yyb23 = r.CheckBreak() + yyb24 = r.CheckBreak() } - if yyb23 { + if yyb24 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -3524,13 +3633,13 @@ func (x *VolumeSource) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { } x.AWSElasticBlockStore.CodecDecodeSelf(d) } - yyj23++ - if yyhl23 { - yyb23 = yyj23 > l + yyj24++ + if yyhl24 { + yyb24 = yyj24 > l } else { - yyb23 = r.CheckBreak() + yyb24 = r.CheckBreak() } - if yyb23 { + if yyb24 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -3545,13 +3654,13 @@ func (x *VolumeSource) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { } x.GitRepo.CodecDecodeSelf(d) } - yyj23++ - if yyhl23 { - yyb23 = yyj23 > l + yyj24++ + if yyhl24 { + yyb24 = yyj24 > l } else { - yyb23 = r.CheckBreak() + yyb24 = r.CheckBreak() } - if yyb23 { + if yyb24 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -3566,13 +3675,13 @@ func (x *VolumeSource) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { } x.Secret.CodecDecodeSelf(d) } - yyj23++ - if yyhl23 { - yyb23 = yyj23 > l + yyj24++ + if yyhl24 { + yyb24 = yyj24 > l } else { - yyb23 = r.CheckBreak() + yyb24 = r.CheckBreak() } - if yyb23 { + if yyb24 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -3587,13 +3696,13 @@ func (x *VolumeSource) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { } x.NFS.CodecDecodeSelf(d) } - yyj23++ - if yyhl23 { - yyb23 = yyj23 > l + yyj24++ + if yyhl24 { + yyb24 = yyj24 > l } else { - yyb23 = r.CheckBreak() + yyb24 = r.CheckBreak() } - if yyb23 { + if yyb24 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -3608,13 +3717,13 @@ func (x *VolumeSource) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { } x.ISCSI.CodecDecodeSelf(d) } - yyj23++ - if yyhl23 { - yyb23 = yyj23 > l + yyj24++ + if yyhl24 { + yyb24 = yyj24 > l } else { - yyb23 = r.CheckBreak() + yyb24 = r.CheckBreak() } - if yyb23 { + if yyb24 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -3629,13 +3738,13 @@ func (x *VolumeSource) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { } x.Glusterfs.CodecDecodeSelf(d) } - yyj23++ - if yyhl23 { - yyb23 = yyj23 > l + yyj24++ + if yyhl24 { + yyb24 = yyj24 > l } else { - yyb23 = r.CheckBreak() + yyb24 = r.CheckBreak() } - if yyb23 { + if yyb24 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -3650,13 +3759,13 @@ func (x *VolumeSource) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { } x.PersistentVolumeClaim.CodecDecodeSelf(d) } - yyj23++ - if yyhl23 { - yyb23 = yyj23 > l + yyj24++ + if yyhl24 { + yyb24 = yyj24 > l } else { - yyb23 = r.CheckBreak() + yyb24 = r.CheckBreak() } - if yyb23 { + if yyb24 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -3671,13 +3780,13 @@ func (x *VolumeSource) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { } x.RBD.CodecDecodeSelf(d) } - yyj23++ - if yyhl23 { - yyb23 = yyj23 > l + yyj24++ + if yyhl24 { + yyb24 = yyj24 > l } else { - yyb23 = r.CheckBreak() + yyb24 = r.CheckBreak() } - if yyb23 { + if yyb24 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -3692,13 +3801,13 @@ func (x *VolumeSource) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { } x.FlexVolume.CodecDecodeSelf(d) } - yyj23++ - if yyhl23 { - yyb23 = yyj23 > l + yyj24++ + if yyhl24 { + yyb24 = yyj24 > l } else { - yyb23 = r.CheckBreak() + yyb24 = r.CheckBreak() } - if yyb23 { + if yyb24 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -3713,13 +3822,13 @@ func (x *VolumeSource) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { } x.Cinder.CodecDecodeSelf(d) } - yyj23++ - if yyhl23 { - yyb23 = yyj23 > l + yyj24++ + if yyhl24 { + yyb24 = yyj24 > l } else { - yyb23 = r.CheckBreak() + yyb24 = r.CheckBreak() } - if yyb23 { + if yyb24 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -3734,13 +3843,13 @@ func (x *VolumeSource) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { } x.CephFS.CodecDecodeSelf(d) } - yyj23++ - if yyhl23 { - yyb23 = yyj23 > l + yyj24++ + if yyhl24 { + yyb24 = yyj24 > l } else { - yyb23 = r.CheckBreak() + yyb24 = r.CheckBreak() } - if yyb23 { + if yyb24 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -3755,13 +3864,13 @@ func (x *VolumeSource) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { } x.Flocker.CodecDecodeSelf(d) } - yyj23++ - if yyhl23 { - yyb23 = yyj23 > l + yyj24++ + if yyhl24 { + yyb24 = yyj24 > l } else { - yyb23 = r.CheckBreak() + yyb24 = r.CheckBreak() } - if yyb23 { + if yyb24 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -3776,13 +3885,13 @@ func (x *VolumeSource) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { } x.DownwardAPI.CodecDecodeSelf(d) } - yyj23++ - if yyhl23 { - yyb23 = yyj23 > l + yyj24++ + if yyhl24 { + yyb24 = yyj24 > l } else { - yyb23 = r.CheckBreak() + yyb24 = r.CheckBreak() } - if yyb23 { + if yyb24 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -3797,13 +3906,13 @@ func (x *VolumeSource) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { } x.FC.CodecDecodeSelf(d) } - yyj23++ - if yyhl23 { - yyb23 = yyj23 > l + yyj24++ + if yyhl24 { + yyb24 = yyj24 > l } else { - yyb23 = r.CheckBreak() + yyb24 = r.CheckBreak() } - if yyb23 { + if yyb24 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -3818,13 +3927,13 @@ func (x *VolumeSource) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { } x.AzureFile.CodecDecodeSelf(d) } - yyj23++ - if yyhl23 { - yyb23 = yyj23 > l + yyj24++ + if yyhl24 { + yyb24 = yyj24 > l } else { - yyb23 = r.CheckBreak() + yyb24 = r.CheckBreak() } - if yyb23 { + if yyb24 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -3839,18 +3948,39 @@ func (x *VolumeSource) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { } x.ConfigMap.CodecDecodeSelf(d) } - for { - yyj23++ - if yyhl23 { - yyb23 = yyj23 > l - } else { - yyb23 = r.CheckBreak() + yyj24++ + if yyhl24 { + yyb24 = yyj24 > l + } else { + yyb24 = r.CheckBreak() + } + if yyb24 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) + return + } + z.DecSendContainerState(codecSelfer_containerArrayElem1234) + if r.TryDecodeAsNil() { + if x.VsphereVolume != nil { + x.VsphereVolume = nil } - if yyb23 { + } else { + if x.VsphereVolume == nil { + x.VsphereVolume = new(VsphereVirtualDiskVolumeSource) + } + x.VsphereVolume.CodecDecodeSelf(d) + } + for { + yyj24++ + if yyhl24 { + yyb24 = yyj24 > l + } else { + yyb24 = r.CheckBreak() + } + if yyb24 { break } z.DecSendContainerState(codecSelfer_containerArrayElem1234) - z.DecStructFieldNotFound(yyj23-1, "") + z.DecStructFieldNotFound(yyj24-1, "") } z.DecSendContainerState(codecSelfer_containerArrayEnd1234) } @@ -4079,7 +4209,7 @@ func (x *PersistentVolumeSource) CodecEncodeSelf(e *codec1978.Encoder) { } else { yysep2 := !z.EncBinary() yy2arr2 := z.EncBasicHandle().StructToArray - var yyq2 [13]bool + var yyq2 [14]bool _, _, _ = yysep2, yyq2, yy2arr2 const yyr2 bool = false yyq2[0] = x.GCEPersistentDisk != nil @@ -4095,9 +4225,10 @@ func (x *PersistentVolumeSource) CodecEncodeSelf(e *codec1978.Encoder) { yyq2[10] = x.Flocker != nil yyq2[11] = x.FlexVolume != nil yyq2[12] = x.AzureFile != nil + yyq2[13] = x.VsphereVolume != nil var yynn2 int if yyr2 || yy2arr2 { - r.EncodeArrayStart(13) + r.EncodeArrayStart(14) } else { yynn2 = 0 for _, b := range yyq2 { @@ -4407,6 +4538,29 @@ func (x *PersistentVolumeSource) CodecEncodeSelf(e *codec1978.Encoder) { } } } + if yyr2 || yy2arr2 { + z.EncSendContainerState(codecSelfer_containerArrayElem1234) + if yyq2[13] { + if x.VsphereVolume == nil { + r.EncodeNil() + } else { + x.VsphereVolume.CodecEncodeSelf(e) + } + } else { + r.EncodeNil() + } + } else { + if yyq2[13] { + z.EncSendContainerState(codecSelfer_containerMapKey1234) + r.EncodeString(codecSelferC_UTF81234, string("vsphereVolume")) + z.EncSendContainerState(codecSelfer_containerMapValue1234) + if x.VsphereVolume == nil { + r.EncodeNil() + } else { + x.VsphereVolume.CodecEncodeSelf(e) + } + } + } if yyr2 || yy2arr2 { z.EncSendContainerState(codecSelfer_containerArrayEnd1234) } else { @@ -4611,6 +4765,17 @@ func (x *PersistentVolumeSource) codecDecodeSelfFromMap(l int, d *codec1978.Deco } x.AzureFile.CodecDecodeSelf(d) } + case "vsphereVolume": + if r.TryDecodeAsNil() { + if x.VsphereVolume != nil { + x.VsphereVolume = nil + } + } else { + if x.VsphereVolume == nil { + x.VsphereVolume = new(VsphereVirtualDiskVolumeSource) + } + x.VsphereVolume.CodecDecodeSelf(d) + } default: z.DecStructFieldNotFound(-1, yys3) } // end switch yys3 @@ -4622,16 +4787,16 @@ func (x *PersistentVolumeSource) codecDecodeSelfFromArray(l int, d *codec1978.De var h codecSelfer1234 z, r := codec1978.GenHelperDecoder(d) _, _, _ = h, z, r - var yyj17 int - var yyb17 bool - var yyhl17 bool = l >= 0 - yyj17++ - if yyhl17 { - yyb17 = yyj17 > l + var yyj18 int + var yyb18 bool + var yyhl18 bool = l >= 0 + yyj18++ + if yyhl18 { + yyb18 = yyj18 > l } else { - yyb17 = r.CheckBreak() + yyb18 = r.CheckBreak() } - if yyb17 { + if yyb18 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -4646,13 +4811,13 @@ func (x *PersistentVolumeSource) codecDecodeSelfFromArray(l int, d *codec1978.De } x.GCEPersistentDisk.CodecDecodeSelf(d) } - yyj17++ - if yyhl17 { - yyb17 = yyj17 > l + yyj18++ + if yyhl18 { + yyb18 = yyj18 > l } else { - yyb17 = r.CheckBreak() + yyb18 = r.CheckBreak() } - if yyb17 { + if yyb18 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -4667,13 +4832,13 @@ func (x *PersistentVolumeSource) codecDecodeSelfFromArray(l int, d *codec1978.De } x.AWSElasticBlockStore.CodecDecodeSelf(d) } - yyj17++ - if yyhl17 { - yyb17 = yyj17 > l + yyj18++ + if yyhl18 { + yyb18 = yyj18 > l } else { - yyb17 = r.CheckBreak() + yyb18 = r.CheckBreak() } - if yyb17 { + if yyb18 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -4688,13 +4853,13 @@ func (x *PersistentVolumeSource) codecDecodeSelfFromArray(l int, d *codec1978.De } x.HostPath.CodecDecodeSelf(d) } - yyj17++ - if yyhl17 { - yyb17 = yyj17 > l + yyj18++ + if yyhl18 { + yyb18 = yyj18 > l } else { - yyb17 = r.CheckBreak() + yyb18 = r.CheckBreak() } - if yyb17 { + if yyb18 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -4709,13 +4874,13 @@ func (x *PersistentVolumeSource) codecDecodeSelfFromArray(l int, d *codec1978.De } x.Glusterfs.CodecDecodeSelf(d) } - yyj17++ - if yyhl17 { - yyb17 = yyj17 > l + yyj18++ + if yyhl18 { + yyb18 = yyj18 > l } else { - yyb17 = r.CheckBreak() + yyb18 = r.CheckBreak() } - if yyb17 { + if yyb18 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -4730,13 +4895,13 @@ func (x *PersistentVolumeSource) codecDecodeSelfFromArray(l int, d *codec1978.De } x.NFS.CodecDecodeSelf(d) } - yyj17++ - if yyhl17 { - yyb17 = yyj17 > l + yyj18++ + if yyhl18 { + yyb18 = yyj18 > l } else { - yyb17 = r.CheckBreak() + yyb18 = r.CheckBreak() } - if yyb17 { + if yyb18 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -4751,13 +4916,13 @@ func (x *PersistentVolumeSource) codecDecodeSelfFromArray(l int, d *codec1978.De } x.RBD.CodecDecodeSelf(d) } - yyj17++ - if yyhl17 { - yyb17 = yyj17 > l + yyj18++ + if yyhl18 { + yyb18 = yyj18 > l } else { - yyb17 = r.CheckBreak() + yyb18 = r.CheckBreak() } - if yyb17 { + if yyb18 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -4772,13 +4937,13 @@ func (x *PersistentVolumeSource) codecDecodeSelfFromArray(l int, d *codec1978.De } x.ISCSI.CodecDecodeSelf(d) } - yyj17++ - if yyhl17 { - yyb17 = yyj17 > l + yyj18++ + if yyhl18 { + yyb18 = yyj18 > l } else { - yyb17 = r.CheckBreak() + yyb18 = r.CheckBreak() } - if yyb17 { + if yyb18 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -4793,13 +4958,13 @@ func (x *PersistentVolumeSource) codecDecodeSelfFromArray(l int, d *codec1978.De } x.Cinder.CodecDecodeSelf(d) } - yyj17++ - if yyhl17 { - yyb17 = yyj17 > l + yyj18++ + if yyhl18 { + yyb18 = yyj18 > l } else { - yyb17 = r.CheckBreak() + yyb18 = r.CheckBreak() } - if yyb17 { + if yyb18 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -4814,13 +4979,13 @@ func (x *PersistentVolumeSource) codecDecodeSelfFromArray(l int, d *codec1978.De } x.CephFS.CodecDecodeSelf(d) } - yyj17++ - if yyhl17 { - yyb17 = yyj17 > l + yyj18++ + if yyhl18 { + yyb18 = yyj18 > l } else { - yyb17 = r.CheckBreak() + yyb18 = r.CheckBreak() } - if yyb17 { + if yyb18 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -4835,13 +5000,13 @@ func (x *PersistentVolumeSource) codecDecodeSelfFromArray(l int, d *codec1978.De } x.FC.CodecDecodeSelf(d) } - yyj17++ - if yyhl17 { - yyb17 = yyj17 > l + yyj18++ + if yyhl18 { + yyb18 = yyj18 > l } else { - yyb17 = r.CheckBreak() + yyb18 = r.CheckBreak() } - if yyb17 { + if yyb18 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -4856,13 +5021,13 @@ func (x *PersistentVolumeSource) codecDecodeSelfFromArray(l int, d *codec1978.De } x.Flocker.CodecDecodeSelf(d) } - yyj17++ - if yyhl17 { - yyb17 = yyj17 > l + yyj18++ + if yyhl18 { + yyb18 = yyj18 > l } else { - yyb17 = r.CheckBreak() + yyb18 = r.CheckBreak() } - if yyb17 { + if yyb18 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -4877,13 +5042,13 @@ func (x *PersistentVolumeSource) codecDecodeSelfFromArray(l int, d *codec1978.De } x.FlexVolume.CodecDecodeSelf(d) } - yyj17++ - if yyhl17 { - yyb17 = yyj17 > l + yyj18++ + if yyhl18 { + yyb18 = yyj18 > l } else { - yyb17 = r.CheckBreak() + yyb18 = r.CheckBreak() } - if yyb17 { + if yyb18 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -4898,18 +5063,39 @@ func (x *PersistentVolumeSource) codecDecodeSelfFromArray(l int, d *codec1978.De } x.AzureFile.CodecDecodeSelf(d) } - for { - yyj17++ - if yyhl17 { - yyb17 = yyj17 > l - } else { - yyb17 = r.CheckBreak() + yyj18++ + if yyhl18 { + yyb18 = yyj18 > l + } else { + yyb18 = r.CheckBreak() + } + if yyb18 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) + return + } + z.DecSendContainerState(codecSelfer_containerArrayElem1234) + if r.TryDecodeAsNil() { + if x.VsphereVolume != nil { + x.VsphereVolume = nil } - if yyb17 { + } else { + if x.VsphereVolume == nil { + x.VsphereVolume = new(VsphereVirtualDiskVolumeSource) + } + x.VsphereVolume.CodecDecodeSelf(d) + } + for { + yyj18++ + if yyhl18 { + yyb18 = yyj18 > l + } else { + yyb18 = r.CheckBreak() + } + if yyb18 { break } z.DecSendContainerState(codecSelfer_containerArrayElem1234) - z.DecStructFieldNotFound(yyj17-1, "") + z.DecStructFieldNotFound(yyj18-1, "") } z.DecSendContainerState(codecSelfer_containerArrayEnd1234) } @@ -5271,7 +5457,7 @@ func (x *PersistentVolumeSpec) CodecEncodeSelf(e *codec1978.Encoder) { } else { yysep2 := !z.EncBinary() yy2arr2 := z.EncBasicHandle().StructToArray - var yyq2 [17]bool + var yyq2 [18]bool _, _, _ = yysep2, yyq2, yy2arr2 const yyr2 bool = false yyq2[0] = len(x.Capacity) != 0 @@ -5291,9 +5477,10 @@ func (x *PersistentVolumeSpec) CodecEncodeSelf(e *codec1978.Encoder) { yyq2[14] = x.PersistentVolumeSource.Flocker != nil && x.Flocker != nil yyq2[15] = x.PersistentVolumeSource.FlexVolume != nil && x.FlexVolume != nil yyq2[16] = x.PersistentVolumeSource.AzureFile != nil && x.AzureFile != nil + yyq2[17] = x.PersistentVolumeSource.VsphereVolume != nil && x.VsphereVolume != nil var yynn2 int if yyr2 || yy2arr2 { - r.EncodeArrayStart(17) + r.EncodeArrayStart(18) } else { yynn2 = 0 for _, b := range yyq2 { @@ -5879,6 +6066,43 @@ func (x *PersistentVolumeSpec) CodecEncodeSelf(e *codec1978.Encoder) { } } } + var yyn54 bool + if x.PersistentVolumeSource.VsphereVolume == nil { + yyn54 = true + goto LABEL54 + } + LABEL54: + if yyr2 || yy2arr2 { + if yyn54 { + r.EncodeNil() + } else { + z.EncSendContainerState(codecSelfer_containerArrayElem1234) + if yyq2[17] { + if x.VsphereVolume == nil { + r.EncodeNil() + } else { + x.VsphereVolume.CodecEncodeSelf(e) + } + } else { + r.EncodeNil() + } + } + } else { + if yyq2[17] { + z.EncSendContainerState(codecSelfer_containerMapKey1234) + r.EncodeString(codecSelferC_UTF81234, string("vsphereVolume")) + z.EncSendContainerState(codecSelfer_containerMapValue1234) + if yyn54 { + r.EncodeNil() + } else { + if x.VsphereVolume == nil { + r.EncodeNil() + } else { + x.VsphereVolume.CodecEncodeSelf(e) + } + } + } + } if yyr2 || yy2arr2 { z.EncSendContainerState(codecSelfer_containerArrayEnd1234) } else { @@ -6158,6 +6382,20 @@ func (x *PersistentVolumeSpec) codecDecodeSelfFromMap(l int, d *codec1978.Decode } x.AzureFile.CodecDecodeSelf(d) } + case "vsphereVolume": + if x.PersistentVolumeSource.VsphereVolume == nil { + x.PersistentVolumeSource.VsphereVolume = new(VsphereVirtualDiskVolumeSource) + } + if r.TryDecodeAsNil() { + if x.VsphereVolume != nil { + x.VsphereVolume = nil + } + } else { + if x.VsphereVolume == nil { + x.VsphereVolume = new(VsphereVirtualDiskVolumeSource) + } + x.VsphereVolume.CodecDecodeSelf(d) + } default: z.DecStructFieldNotFound(-1, yys3) } // end switch yys3 @@ -6169,16 +6407,16 @@ func (x *PersistentVolumeSpec) codecDecodeSelfFromArray(l int, d *codec1978.Deco var h codecSelfer1234 z, r := codec1978.GenHelperDecoder(d) _, _, _ = h, z, r - var yyj22 int - var yyb22 bool - var yyhl22 bool = l >= 0 - yyj22++ - if yyhl22 { - yyb22 = yyj22 > l + var yyj23 int + var yyb23 bool + var yyhl23 bool = l >= 0 + yyj23++ + if yyhl23 { + yyb23 = yyj23 > l } else { - yyb22 = r.CheckBreak() + yyb23 = r.CheckBreak() } - if yyb22 { + if yyb23 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -6186,16 +6424,16 @@ func (x *PersistentVolumeSpec) codecDecodeSelfFromArray(l int, d *codec1978.Deco if r.TryDecodeAsNil() { x.Capacity = nil } else { - yyv23 := &x.Capacity - yyv23.CodecDecodeSelf(d) + yyv24 := &x.Capacity + yyv24.CodecDecodeSelf(d) } - yyj22++ - if yyhl22 { - yyb22 = yyj22 > l + yyj23++ + if yyhl23 { + yyb23 = yyj23 > l } else { - yyb22 = r.CheckBreak() + yyb23 = r.CheckBreak() } - if yyb22 { + if yyb23 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -6203,21 +6441,21 @@ func (x *PersistentVolumeSpec) codecDecodeSelfFromArray(l int, d *codec1978.Deco if r.TryDecodeAsNil() { x.AccessModes = nil } else { - yyv24 := &x.AccessModes - yym25 := z.DecBinary() - _ = yym25 + yyv25 := &x.AccessModes + yym26 := z.DecBinary() + _ = yym26 if false { } else { - h.decSlicePersistentVolumeAccessMode((*[]PersistentVolumeAccessMode)(yyv24), d) + h.decSlicePersistentVolumeAccessMode((*[]PersistentVolumeAccessMode)(yyv25), d) } } - yyj22++ - if yyhl22 { - yyb22 = yyj22 > l + yyj23++ + if yyhl23 { + yyb23 = yyj23 > l } else { - yyb22 = r.CheckBreak() + yyb23 = r.CheckBreak() } - if yyb22 { + if yyb23 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -6232,13 +6470,13 @@ func (x *PersistentVolumeSpec) codecDecodeSelfFromArray(l int, d *codec1978.Deco } x.ClaimRef.CodecDecodeSelf(d) } - yyj22++ - if yyhl22 { - yyb22 = yyj22 > l + yyj23++ + if yyhl23 { + yyb23 = yyj23 > l } else { - yyb22 = r.CheckBreak() + yyb23 = r.CheckBreak() } - if yyb22 { + if yyb23 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -6251,13 +6489,13 @@ func (x *PersistentVolumeSpec) codecDecodeSelfFromArray(l int, d *codec1978.Deco if x.PersistentVolumeSource.GCEPersistentDisk == nil { x.PersistentVolumeSource.GCEPersistentDisk = new(GCEPersistentDiskVolumeSource) } - yyj22++ - if yyhl22 { - yyb22 = yyj22 > l + yyj23++ + if yyhl23 { + yyb23 = yyj23 > l } else { - yyb22 = r.CheckBreak() + yyb23 = r.CheckBreak() } - if yyb22 { + if yyb23 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -6275,13 +6513,13 @@ func (x *PersistentVolumeSpec) codecDecodeSelfFromArray(l int, d *codec1978.Deco if x.PersistentVolumeSource.AWSElasticBlockStore == nil { x.PersistentVolumeSource.AWSElasticBlockStore = new(AWSElasticBlockStoreVolumeSource) } - yyj22++ - if yyhl22 { - yyb22 = yyj22 > l + yyj23++ + if yyhl23 { + yyb23 = yyj23 > l } else { - yyb22 = r.CheckBreak() + yyb23 = r.CheckBreak() } - if yyb22 { + if yyb23 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -6299,13 +6537,13 @@ func (x *PersistentVolumeSpec) codecDecodeSelfFromArray(l int, d *codec1978.Deco if x.PersistentVolumeSource.HostPath == nil { x.PersistentVolumeSource.HostPath = new(HostPathVolumeSource) } - yyj22++ - if yyhl22 { - yyb22 = yyj22 > l + yyj23++ + if yyhl23 { + yyb23 = yyj23 > l } else { - yyb22 = r.CheckBreak() + yyb23 = r.CheckBreak() } - if yyb22 { + if yyb23 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -6323,13 +6561,13 @@ func (x *PersistentVolumeSpec) codecDecodeSelfFromArray(l int, d *codec1978.Deco if x.PersistentVolumeSource.Glusterfs == nil { x.PersistentVolumeSource.Glusterfs = new(GlusterfsVolumeSource) } - yyj22++ - if yyhl22 { - yyb22 = yyj22 > l + yyj23++ + if yyhl23 { + yyb23 = yyj23 > l } else { - yyb22 = r.CheckBreak() + yyb23 = r.CheckBreak() } - if yyb22 { + if yyb23 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -6347,13 +6585,13 @@ func (x *PersistentVolumeSpec) codecDecodeSelfFromArray(l int, d *codec1978.Deco if x.PersistentVolumeSource.NFS == nil { x.PersistentVolumeSource.NFS = new(NFSVolumeSource) } - yyj22++ - if yyhl22 { - yyb22 = yyj22 > l + yyj23++ + if yyhl23 { + yyb23 = yyj23 > l } else { - yyb22 = r.CheckBreak() + yyb23 = r.CheckBreak() } - if yyb22 { + if yyb23 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -6371,13 +6609,13 @@ func (x *PersistentVolumeSpec) codecDecodeSelfFromArray(l int, d *codec1978.Deco if x.PersistentVolumeSource.RBD == nil { x.PersistentVolumeSource.RBD = new(RBDVolumeSource) } - yyj22++ - if yyhl22 { - yyb22 = yyj22 > l + yyj23++ + if yyhl23 { + yyb23 = yyj23 > l } else { - yyb22 = r.CheckBreak() + yyb23 = r.CheckBreak() } - if yyb22 { + if yyb23 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -6395,13 +6633,13 @@ func (x *PersistentVolumeSpec) codecDecodeSelfFromArray(l int, d *codec1978.Deco if x.PersistentVolumeSource.ISCSI == nil { x.PersistentVolumeSource.ISCSI = new(ISCSIVolumeSource) } - yyj22++ - if yyhl22 { - yyb22 = yyj22 > l + yyj23++ + if yyhl23 { + yyb23 = yyj23 > l } else { - yyb22 = r.CheckBreak() + yyb23 = r.CheckBreak() } - if yyb22 { + if yyb23 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -6419,13 +6657,13 @@ func (x *PersistentVolumeSpec) codecDecodeSelfFromArray(l int, d *codec1978.Deco if x.PersistentVolumeSource.Cinder == nil { x.PersistentVolumeSource.Cinder = new(CinderVolumeSource) } - yyj22++ - if yyhl22 { - yyb22 = yyj22 > l + yyj23++ + if yyhl23 { + yyb23 = yyj23 > l } else { - yyb22 = r.CheckBreak() + yyb23 = r.CheckBreak() } - if yyb22 { + if yyb23 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -6443,13 +6681,13 @@ func (x *PersistentVolumeSpec) codecDecodeSelfFromArray(l int, d *codec1978.Deco if x.PersistentVolumeSource.CephFS == nil { x.PersistentVolumeSource.CephFS = new(CephFSVolumeSource) } - yyj22++ - if yyhl22 { - yyb22 = yyj22 > l + yyj23++ + if yyhl23 { + yyb23 = yyj23 > l } else { - yyb22 = r.CheckBreak() + yyb23 = r.CheckBreak() } - if yyb22 { + if yyb23 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -6467,13 +6705,13 @@ func (x *PersistentVolumeSpec) codecDecodeSelfFromArray(l int, d *codec1978.Deco if x.PersistentVolumeSource.FC == nil { x.PersistentVolumeSource.FC = new(FCVolumeSource) } - yyj22++ - if yyhl22 { - yyb22 = yyj22 > l + yyj23++ + if yyhl23 { + yyb23 = yyj23 > l } else { - yyb22 = r.CheckBreak() + yyb23 = r.CheckBreak() } - if yyb22 { + if yyb23 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -6491,13 +6729,13 @@ func (x *PersistentVolumeSpec) codecDecodeSelfFromArray(l int, d *codec1978.Deco if x.PersistentVolumeSource.Flocker == nil { x.PersistentVolumeSource.Flocker = new(FlockerVolumeSource) } - yyj22++ - if yyhl22 { - yyb22 = yyj22 > l + yyj23++ + if yyhl23 { + yyb23 = yyj23 > l } else { - yyb22 = r.CheckBreak() + yyb23 = r.CheckBreak() } - if yyb22 { + if yyb23 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -6515,13 +6753,13 @@ func (x *PersistentVolumeSpec) codecDecodeSelfFromArray(l int, d *codec1978.Deco if x.PersistentVolumeSource.FlexVolume == nil { x.PersistentVolumeSource.FlexVolume = new(FlexVolumeSource) } - yyj22++ - if yyhl22 { - yyb22 = yyj22 > l + yyj23++ + if yyhl23 { + yyb23 = yyj23 > l } else { - yyb22 = r.CheckBreak() + yyb23 = r.CheckBreak() } - if yyb22 { + if yyb23 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -6539,13 +6777,13 @@ func (x *PersistentVolumeSpec) codecDecodeSelfFromArray(l int, d *codec1978.Deco if x.PersistentVolumeSource.AzureFile == nil { x.PersistentVolumeSource.AzureFile = new(AzureFileVolumeSource) } - yyj22++ - if yyhl22 { - yyb22 = yyj22 > l + yyj23++ + if yyhl23 { + yyb23 = yyj23 > l } else { - yyb22 = r.CheckBreak() + yyb23 = r.CheckBreak() } - if yyb22 { + if yyb23 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -6560,18 +6798,42 @@ func (x *PersistentVolumeSpec) codecDecodeSelfFromArray(l int, d *codec1978.Deco } x.AzureFile.CodecDecodeSelf(d) } - for { - yyj22++ - if yyhl22 { - yyb22 = yyj22 > l - } else { - yyb22 = r.CheckBreak() + if x.PersistentVolumeSource.VsphereVolume == nil { + x.PersistentVolumeSource.VsphereVolume = new(VsphereVirtualDiskVolumeSource) + } + yyj23++ + if yyhl23 { + yyb23 = yyj23 > l + } else { + yyb23 = r.CheckBreak() + } + if yyb23 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) + return + } + z.DecSendContainerState(codecSelfer_containerArrayElem1234) + if r.TryDecodeAsNil() { + if x.VsphereVolume != nil { + x.VsphereVolume = nil } - if yyb22 { + } else { + if x.VsphereVolume == nil { + x.VsphereVolume = new(VsphereVirtualDiskVolumeSource) + } + x.VsphereVolume.CodecDecodeSelf(d) + } + for { + yyj23++ + if yyhl23 { + yyb23 = yyj23 > l + } else { + yyb23 = r.CheckBreak() + } + if yyb23 { break } z.DecSendContainerState(codecSelfer_containerArrayElem1234) - z.DecStructFieldNotFound(yyj22-1, "") + z.DecStructFieldNotFound(yyj23-1, "") } z.DecSendContainerState(codecSelfer_containerArrayEnd1234) } @@ -11751,13 +12013,14 @@ func (x *SecretVolumeSource) CodecEncodeSelf(e *codec1978.Encoder) { } else { yysep2 := !z.EncBinary() yy2arr2 := z.EncBasicHandle().StructToArray - var yyq2 [1]bool + var yyq2 [2]bool _, _, _ = yysep2, yyq2, yy2arr2 const yyr2 bool = false yyq2[0] = x.SecretName != "" + yyq2[1] = len(x.Items) != 0 var yynn2 int if yyr2 || yy2arr2 { - r.EncodeArrayStart(1) + r.EncodeArrayStart(2) } else { yynn2 = 0 for _, b := range yyq2 { @@ -11793,6 +12056,39 @@ func (x *SecretVolumeSource) CodecEncodeSelf(e *codec1978.Encoder) { } } } + if yyr2 || yy2arr2 { + z.EncSendContainerState(codecSelfer_containerArrayElem1234) + if yyq2[1] { + if x.Items == nil { + r.EncodeNil() + } else { + yym7 := z.EncBinary() + _ = yym7 + if false { + } else { + h.encSliceKeyToPath(([]KeyToPath)(x.Items), e) + } + } + } else { + r.EncodeNil() + } + } else { + if yyq2[1] { + z.EncSendContainerState(codecSelfer_containerMapKey1234) + r.EncodeString(codecSelferC_UTF81234, string("items")) + z.EncSendContainerState(codecSelfer_containerMapValue1234) + if x.Items == nil { + r.EncodeNil() + } else { + yym8 := z.EncBinary() + _ = yym8 + if false { + } else { + h.encSliceKeyToPath(([]KeyToPath)(x.Items), e) + } + } + } + } if yyr2 || yy2arr2 { z.EncSendContainerState(codecSelfer_containerArrayEnd1234) } else { @@ -11860,6 +12156,18 @@ func (x *SecretVolumeSource) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) } else { x.SecretName = string(r.DecodeString()) } + case "items": + if r.TryDecodeAsNil() { + x.Items = nil + } else { + yyv5 := &x.Items + yym6 := z.DecBinary() + _ = yym6 + if false { + } else { + h.decSliceKeyToPath((*[]KeyToPath)(yyv5), d) + } + } default: z.DecStructFieldNotFound(-1, yys3) } // end switch yys3 @@ -11871,16 +12179,16 @@ func (x *SecretVolumeSource) codecDecodeSelfFromArray(l int, d *codec1978.Decode var h codecSelfer1234 z, r := codec1978.GenHelperDecoder(d) _, _, _ = h, z, r - var yyj5 int - var yyb5 bool - var yyhl5 bool = l >= 0 - yyj5++ - if yyhl5 { - yyb5 = yyj5 > l + var yyj7 int + var yyb7 bool + var yyhl7 bool = l >= 0 + yyj7++ + if yyhl7 { + yyb7 = yyj7 > l } else { - yyb5 = r.CheckBreak() + yyb7 = r.CheckBreak() } - if yyb5 { + if yyb7 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -11890,18 +12198,40 @@ func (x *SecretVolumeSource) codecDecodeSelfFromArray(l int, d *codec1978.Decode } else { x.SecretName = string(r.DecodeString()) } - for { - yyj5++ - if yyhl5 { - yyb5 = yyj5 > l + yyj7++ + if yyhl7 { + yyb7 = yyj7 > l + } else { + yyb7 = r.CheckBreak() + } + if yyb7 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) + return + } + z.DecSendContainerState(codecSelfer_containerArrayElem1234) + if r.TryDecodeAsNil() { + x.Items = nil + } else { + yyv9 := &x.Items + yym10 := z.DecBinary() + _ = yym10 + if false { } else { - yyb5 = r.CheckBreak() + h.decSliceKeyToPath((*[]KeyToPath)(yyv9), d) } - if yyb5 { + } + for { + yyj7++ + if yyhl7 { + yyb7 = yyj7 > l + } else { + yyb7 = r.CheckBreak() + } + if yyb7 { break } z.DecSendContainerState(codecSelfer_containerArrayElem1234) - z.DecStructFieldNotFound(yyj5-1, "") + z.DecStructFieldNotFound(yyj7-1, "") } z.DecSendContainerState(codecSelfer_containerArrayEnd1234) } @@ -13145,6 +13475,216 @@ func (x *AzureFileVolumeSource) codecDecodeSelfFromArray(l int, d *codec1978.Dec z.DecSendContainerState(codecSelfer_containerArrayEnd1234) } +func (x *VsphereVirtualDiskVolumeSource) CodecEncodeSelf(e *codec1978.Encoder) { + var h codecSelfer1234 + z, r := codec1978.GenHelperEncoder(e) + _, _, _ = h, z, r + if x == nil { + r.EncodeNil() + } else { + yym1 := z.EncBinary() + _ = yym1 + if false { + } else if z.HasExtensions() && z.EncExt(x) { + } else { + yysep2 := !z.EncBinary() + yy2arr2 := z.EncBasicHandle().StructToArray + var yyq2 [2]bool + _, _, _ = yysep2, yyq2, yy2arr2 + const yyr2 bool = false + yyq2[1] = x.FSType != "" + var yynn2 int + if yyr2 || yy2arr2 { + r.EncodeArrayStart(2) + } else { + yynn2 = 1 + for _, b := range yyq2 { + if b { + yynn2++ + } + } + r.EncodeMapStart(yynn2) + yynn2 = 0 + } + if yyr2 || yy2arr2 { + z.EncSendContainerState(codecSelfer_containerArrayElem1234) + yym4 := z.EncBinary() + _ = yym4 + if false { + } else { + r.EncodeString(codecSelferC_UTF81234, string(x.VolumePath)) + } + } else { + z.EncSendContainerState(codecSelfer_containerMapKey1234) + r.EncodeString(codecSelferC_UTF81234, string("volumePath")) + z.EncSendContainerState(codecSelfer_containerMapValue1234) + yym5 := z.EncBinary() + _ = yym5 + if false { + } else { + r.EncodeString(codecSelferC_UTF81234, string(x.VolumePath)) + } + } + if yyr2 || yy2arr2 { + z.EncSendContainerState(codecSelfer_containerArrayElem1234) + if yyq2[1] { + yym7 := z.EncBinary() + _ = yym7 + if false { + } else { + r.EncodeString(codecSelferC_UTF81234, string(x.FSType)) + } + } else { + r.EncodeString(codecSelferC_UTF81234, "") + } + } else { + if yyq2[1] { + z.EncSendContainerState(codecSelfer_containerMapKey1234) + r.EncodeString(codecSelferC_UTF81234, string("fsType")) + z.EncSendContainerState(codecSelfer_containerMapValue1234) + yym8 := z.EncBinary() + _ = yym8 + if false { + } else { + r.EncodeString(codecSelferC_UTF81234, string(x.FSType)) + } + } + } + if yyr2 || yy2arr2 { + z.EncSendContainerState(codecSelfer_containerArrayEnd1234) + } else { + z.EncSendContainerState(codecSelfer_containerMapEnd1234) + } + } + } +} + +func (x *VsphereVirtualDiskVolumeSource) CodecDecodeSelf(d *codec1978.Decoder) { + var h codecSelfer1234 + z, r := codec1978.GenHelperDecoder(d) + _, _, _ = h, z, r + yym1 := z.DecBinary() + _ = yym1 + if false { + } else if z.HasExtensions() && z.DecExt(x) { + } else { + yyct2 := r.ContainerType() + if yyct2 == codecSelferValueTypeMap1234 { + yyl2 := r.ReadMapStart() + if yyl2 == 0 { + z.DecSendContainerState(codecSelfer_containerMapEnd1234) + } else { + x.codecDecodeSelfFromMap(yyl2, d) + } + } else if yyct2 == codecSelferValueTypeArray1234 { + yyl2 := r.ReadArrayStart() + if yyl2 == 0 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) + } else { + x.codecDecodeSelfFromArray(yyl2, d) + } + } else { + panic(codecSelferOnlyMapOrArrayEncodeToStructErr1234) + } + } +} + +func (x *VsphereVirtualDiskVolumeSource) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) { + var h codecSelfer1234 + z, r := codec1978.GenHelperDecoder(d) + _, _, _ = h, z, r + var yys3Slc = z.DecScratchBuffer() // default slice to decode into + _ = yys3Slc + var yyhl3 bool = l >= 0 + for yyj3 := 0; ; yyj3++ { + if yyhl3 { + if yyj3 >= l { + break + } + } else { + if r.CheckBreak() { + break + } + } + z.DecSendContainerState(codecSelfer_containerMapKey1234) + yys3Slc = r.DecodeBytes(yys3Slc, true, true) + yys3 := string(yys3Slc) + z.DecSendContainerState(codecSelfer_containerMapValue1234) + switch yys3 { + case "volumePath": + if r.TryDecodeAsNil() { + x.VolumePath = "" + } else { + x.VolumePath = string(r.DecodeString()) + } + case "fsType": + if r.TryDecodeAsNil() { + x.FSType = "" + } else { + x.FSType = string(r.DecodeString()) + } + default: + z.DecStructFieldNotFound(-1, yys3) + } // end switch yys3 + } // end for yyj3 + z.DecSendContainerState(codecSelfer_containerMapEnd1234) +} + +func (x *VsphereVirtualDiskVolumeSource) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { + var h codecSelfer1234 + z, r := codec1978.GenHelperDecoder(d) + _, _, _ = h, z, r + var yyj6 int + var yyb6 bool + var yyhl6 bool = l >= 0 + yyj6++ + if yyhl6 { + yyb6 = yyj6 > l + } else { + yyb6 = r.CheckBreak() + } + if yyb6 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) + return + } + z.DecSendContainerState(codecSelfer_containerArrayElem1234) + if r.TryDecodeAsNil() { + x.VolumePath = "" + } else { + x.VolumePath = string(r.DecodeString()) + } + yyj6++ + if yyhl6 { + yyb6 = yyj6 > l + } else { + yyb6 = r.CheckBreak() + } + if yyb6 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) + return + } + z.DecSendContainerState(codecSelfer_containerArrayElem1234) + if r.TryDecodeAsNil() { + x.FSType = "" + } else { + x.FSType = string(r.DecodeString()) + } + for { + yyj6++ + if yyhl6 { + yyb6 = yyj6 > l + } else { + yyb6 = r.CheckBreak() + } + if yyb6 { + break + } + z.DecSendContainerState(codecSelfer_containerArrayElem1234) + z.DecStructFieldNotFound(yyj6-1, "") + } + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) +} + func (x *ConfigMapVolumeSource) CodecEncodeSelf(e *codec1978.Encoder) { var h codecSelfer1234 z, r := codec1978.GenHelperEncoder(e) @@ -15844,7 +16384,7 @@ func (x *HTTPGetAction) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) { } case "port": if r.TryDecodeAsNil() { - x.Port = pkg5_intstr.IntOrString{} + x.Port = pkg4_intstr.IntOrString{} } else { yyv5 := &x.Port yym6 := z.DecBinary() @@ -15923,7 +16463,7 @@ func (x *HTTPGetAction) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { } z.DecSendContainerState(codecSelfer_containerArrayElem1234) if r.TryDecodeAsNil() { - x.Port = pkg5_intstr.IntOrString{} + x.Port = pkg4_intstr.IntOrString{} } else { yyv13 := &x.Port yym14 := z.DecBinary() @@ -16152,7 +16692,7 @@ func (x *TCPSocketAction) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) { switch yys3 { case "port": if r.TryDecodeAsNil() { - x.Port = pkg5_intstr.IntOrString{} + x.Port = pkg4_intstr.IntOrString{} } else { yyv4 := &x.Port yym5 := z.DecBinary() @@ -16191,7 +16731,7 @@ func (x *TCPSocketAction) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) } z.DecSendContainerState(codecSelfer_containerArrayElem1234) if r.TryDecodeAsNil() { - x.Port = pkg5_intstr.IntOrString{} + x.Port = pkg4_intstr.IntOrString{} } else { yyv7 := &x.Port yym8 := z.DecBinary() @@ -23801,6 +24341,592 @@ func (x *PreferredSchedulingTerm) codecDecodeSelfFromArray(l int, d *codec1978.D z.DecSendContainerState(codecSelfer_containerArrayEnd1234) } +func (x *Taint) CodecEncodeSelf(e *codec1978.Encoder) { + var h codecSelfer1234 + z, r := codec1978.GenHelperEncoder(e) + _, _, _ = h, z, r + if x == nil { + r.EncodeNil() + } else { + yym1 := z.EncBinary() + _ = yym1 + if false { + } else if z.HasExtensions() && z.EncExt(x) { + } else { + yysep2 := !z.EncBinary() + yy2arr2 := z.EncBasicHandle().StructToArray + var yyq2 [3]bool + _, _, _ = yysep2, yyq2, yy2arr2 + const yyr2 bool = false + yyq2[1] = x.Value != "" + var yynn2 int + if yyr2 || yy2arr2 { + r.EncodeArrayStart(3) + } else { + yynn2 = 2 + for _, b := range yyq2 { + if b { + yynn2++ + } + } + r.EncodeMapStart(yynn2) + yynn2 = 0 + } + if yyr2 || yy2arr2 { + z.EncSendContainerState(codecSelfer_containerArrayElem1234) + yym4 := z.EncBinary() + _ = yym4 + if false { + } else { + r.EncodeString(codecSelferC_UTF81234, string(x.Key)) + } + } else { + z.EncSendContainerState(codecSelfer_containerMapKey1234) + r.EncodeString(codecSelferC_UTF81234, string("key")) + z.EncSendContainerState(codecSelfer_containerMapValue1234) + yym5 := z.EncBinary() + _ = yym5 + if false { + } else { + r.EncodeString(codecSelferC_UTF81234, string(x.Key)) + } + } + if yyr2 || yy2arr2 { + z.EncSendContainerState(codecSelfer_containerArrayElem1234) + if yyq2[1] { + yym7 := z.EncBinary() + _ = yym7 + if false { + } else { + r.EncodeString(codecSelferC_UTF81234, string(x.Value)) + } + } else { + r.EncodeString(codecSelferC_UTF81234, "") + } + } else { + if yyq2[1] { + z.EncSendContainerState(codecSelfer_containerMapKey1234) + r.EncodeString(codecSelferC_UTF81234, string("value")) + z.EncSendContainerState(codecSelfer_containerMapValue1234) + yym8 := z.EncBinary() + _ = yym8 + if false { + } else { + r.EncodeString(codecSelferC_UTF81234, string(x.Value)) + } + } + } + if yyr2 || yy2arr2 { + z.EncSendContainerState(codecSelfer_containerArrayElem1234) + x.Effect.CodecEncodeSelf(e) + } else { + z.EncSendContainerState(codecSelfer_containerMapKey1234) + r.EncodeString(codecSelferC_UTF81234, string("effect")) + z.EncSendContainerState(codecSelfer_containerMapValue1234) + x.Effect.CodecEncodeSelf(e) + } + if yyr2 || yy2arr2 { + z.EncSendContainerState(codecSelfer_containerArrayEnd1234) + } else { + z.EncSendContainerState(codecSelfer_containerMapEnd1234) + } + } + } +} + +func (x *Taint) CodecDecodeSelf(d *codec1978.Decoder) { + var h codecSelfer1234 + z, r := codec1978.GenHelperDecoder(d) + _, _, _ = h, z, r + yym1 := z.DecBinary() + _ = yym1 + if false { + } else if z.HasExtensions() && z.DecExt(x) { + } else { + yyct2 := r.ContainerType() + if yyct2 == codecSelferValueTypeMap1234 { + yyl2 := r.ReadMapStart() + if yyl2 == 0 { + z.DecSendContainerState(codecSelfer_containerMapEnd1234) + } else { + x.codecDecodeSelfFromMap(yyl2, d) + } + } else if yyct2 == codecSelferValueTypeArray1234 { + yyl2 := r.ReadArrayStart() + if yyl2 == 0 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) + } else { + x.codecDecodeSelfFromArray(yyl2, d) + } + } else { + panic(codecSelferOnlyMapOrArrayEncodeToStructErr1234) + } + } +} + +func (x *Taint) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) { + var h codecSelfer1234 + z, r := codec1978.GenHelperDecoder(d) + _, _, _ = h, z, r + var yys3Slc = z.DecScratchBuffer() // default slice to decode into + _ = yys3Slc + var yyhl3 bool = l >= 0 + for yyj3 := 0; ; yyj3++ { + if yyhl3 { + if yyj3 >= l { + break + } + } else { + if r.CheckBreak() { + break + } + } + z.DecSendContainerState(codecSelfer_containerMapKey1234) + yys3Slc = r.DecodeBytes(yys3Slc, true, true) + yys3 := string(yys3Slc) + z.DecSendContainerState(codecSelfer_containerMapValue1234) + switch yys3 { + case "key": + if r.TryDecodeAsNil() { + x.Key = "" + } else { + x.Key = string(r.DecodeString()) + } + case "value": + if r.TryDecodeAsNil() { + x.Value = "" + } else { + x.Value = string(r.DecodeString()) + } + case "effect": + if r.TryDecodeAsNil() { + x.Effect = "" + } else { + x.Effect = TaintEffect(r.DecodeString()) + } + default: + z.DecStructFieldNotFound(-1, yys3) + } // end switch yys3 + } // end for yyj3 + z.DecSendContainerState(codecSelfer_containerMapEnd1234) +} + +func (x *Taint) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { + var h codecSelfer1234 + z, r := codec1978.GenHelperDecoder(d) + _, _, _ = h, z, r + var yyj7 int + var yyb7 bool + var yyhl7 bool = l >= 0 + yyj7++ + if yyhl7 { + yyb7 = yyj7 > l + } else { + yyb7 = r.CheckBreak() + } + if yyb7 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) + return + } + z.DecSendContainerState(codecSelfer_containerArrayElem1234) + if r.TryDecodeAsNil() { + x.Key = "" + } else { + x.Key = string(r.DecodeString()) + } + yyj7++ + if yyhl7 { + yyb7 = yyj7 > l + } else { + yyb7 = r.CheckBreak() + } + if yyb7 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) + return + } + z.DecSendContainerState(codecSelfer_containerArrayElem1234) + if r.TryDecodeAsNil() { + x.Value = "" + } else { + x.Value = string(r.DecodeString()) + } + yyj7++ + if yyhl7 { + yyb7 = yyj7 > l + } else { + yyb7 = r.CheckBreak() + } + if yyb7 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) + return + } + z.DecSendContainerState(codecSelfer_containerArrayElem1234) + if r.TryDecodeAsNil() { + x.Effect = "" + } else { + x.Effect = TaintEffect(r.DecodeString()) + } + for { + yyj7++ + if yyhl7 { + yyb7 = yyj7 > l + } else { + yyb7 = r.CheckBreak() + } + if yyb7 { + break + } + z.DecSendContainerState(codecSelfer_containerArrayElem1234) + z.DecStructFieldNotFound(yyj7-1, "") + } + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) +} + +func (x TaintEffect) CodecEncodeSelf(e *codec1978.Encoder) { + var h codecSelfer1234 + z, r := codec1978.GenHelperEncoder(e) + _, _, _ = h, z, r + yym1 := z.EncBinary() + _ = yym1 + if false { + } else if z.HasExtensions() && z.EncExt(x) { + } else { + r.EncodeString(codecSelferC_UTF81234, string(x)) + } +} + +func (x *TaintEffect) CodecDecodeSelf(d *codec1978.Decoder) { + var h codecSelfer1234 + z, r := codec1978.GenHelperDecoder(d) + _, _, _ = h, z, r + yym1 := z.DecBinary() + _ = yym1 + if false { + } else if z.HasExtensions() && z.DecExt(x) { + } else { + *((*string)(x)) = r.DecodeString() + } +} + +func (x *Toleration) CodecEncodeSelf(e *codec1978.Encoder) { + var h codecSelfer1234 + z, r := codec1978.GenHelperEncoder(e) + _, _, _ = h, z, r + if x == nil { + r.EncodeNil() + } else { + yym1 := z.EncBinary() + _ = yym1 + if false { + } else if z.HasExtensions() && z.EncExt(x) { + } else { + yysep2 := !z.EncBinary() + yy2arr2 := z.EncBasicHandle().StructToArray + var yyq2 [4]bool + _, _, _ = yysep2, yyq2, yy2arr2 + const yyr2 bool = false + yyq2[0] = x.Key != "" + yyq2[1] = x.Operator != "" + yyq2[2] = x.Value != "" + yyq2[3] = x.Effect != "" + var yynn2 int + if yyr2 || yy2arr2 { + r.EncodeArrayStart(4) + } else { + yynn2 = 0 + for _, b := range yyq2 { + if b { + yynn2++ + } + } + r.EncodeMapStart(yynn2) + yynn2 = 0 + } + if yyr2 || yy2arr2 { + z.EncSendContainerState(codecSelfer_containerArrayElem1234) + if yyq2[0] { + yym4 := z.EncBinary() + _ = yym4 + if false { + } else { + r.EncodeString(codecSelferC_UTF81234, string(x.Key)) + } + } else { + r.EncodeString(codecSelferC_UTF81234, "") + } + } else { + if yyq2[0] { + z.EncSendContainerState(codecSelfer_containerMapKey1234) + r.EncodeString(codecSelferC_UTF81234, string("key")) + z.EncSendContainerState(codecSelfer_containerMapValue1234) + yym5 := z.EncBinary() + _ = yym5 + if false { + } else { + r.EncodeString(codecSelferC_UTF81234, string(x.Key)) + } + } + } + if yyr2 || yy2arr2 { + z.EncSendContainerState(codecSelfer_containerArrayElem1234) + if yyq2[1] { + x.Operator.CodecEncodeSelf(e) + } else { + r.EncodeString(codecSelferC_UTF81234, "") + } + } else { + if yyq2[1] { + z.EncSendContainerState(codecSelfer_containerMapKey1234) + r.EncodeString(codecSelferC_UTF81234, string("operator")) + z.EncSendContainerState(codecSelfer_containerMapValue1234) + x.Operator.CodecEncodeSelf(e) + } + } + if yyr2 || yy2arr2 { + z.EncSendContainerState(codecSelfer_containerArrayElem1234) + if yyq2[2] { + yym10 := z.EncBinary() + _ = yym10 + if false { + } else { + r.EncodeString(codecSelferC_UTF81234, string(x.Value)) + } + } else { + r.EncodeString(codecSelferC_UTF81234, "") + } + } else { + if yyq2[2] { + z.EncSendContainerState(codecSelfer_containerMapKey1234) + r.EncodeString(codecSelferC_UTF81234, string("value")) + z.EncSendContainerState(codecSelfer_containerMapValue1234) + yym11 := z.EncBinary() + _ = yym11 + if false { + } else { + r.EncodeString(codecSelferC_UTF81234, string(x.Value)) + } + } + } + if yyr2 || yy2arr2 { + z.EncSendContainerState(codecSelfer_containerArrayElem1234) + if yyq2[3] { + x.Effect.CodecEncodeSelf(e) + } else { + r.EncodeString(codecSelferC_UTF81234, "") + } + } else { + if yyq2[3] { + z.EncSendContainerState(codecSelfer_containerMapKey1234) + r.EncodeString(codecSelferC_UTF81234, string("effect")) + z.EncSendContainerState(codecSelfer_containerMapValue1234) + x.Effect.CodecEncodeSelf(e) + } + } + if yyr2 || yy2arr2 { + z.EncSendContainerState(codecSelfer_containerArrayEnd1234) + } else { + z.EncSendContainerState(codecSelfer_containerMapEnd1234) + } + } + } +} + +func (x *Toleration) CodecDecodeSelf(d *codec1978.Decoder) { + var h codecSelfer1234 + z, r := codec1978.GenHelperDecoder(d) + _, _, _ = h, z, r + yym1 := z.DecBinary() + _ = yym1 + if false { + } else if z.HasExtensions() && z.DecExt(x) { + } else { + yyct2 := r.ContainerType() + if yyct2 == codecSelferValueTypeMap1234 { + yyl2 := r.ReadMapStart() + if yyl2 == 0 { + z.DecSendContainerState(codecSelfer_containerMapEnd1234) + } else { + x.codecDecodeSelfFromMap(yyl2, d) + } + } else if yyct2 == codecSelferValueTypeArray1234 { + yyl2 := r.ReadArrayStart() + if yyl2 == 0 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) + } else { + x.codecDecodeSelfFromArray(yyl2, d) + } + } else { + panic(codecSelferOnlyMapOrArrayEncodeToStructErr1234) + } + } +} + +func (x *Toleration) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) { + var h codecSelfer1234 + z, r := codec1978.GenHelperDecoder(d) + _, _, _ = h, z, r + var yys3Slc = z.DecScratchBuffer() // default slice to decode into + _ = yys3Slc + var yyhl3 bool = l >= 0 + for yyj3 := 0; ; yyj3++ { + if yyhl3 { + if yyj3 >= l { + break + } + } else { + if r.CheckBreak() { + break + } + } + z.DecSendContainerState(codecSelfer_containerMapKey1234) + yys3Slc = r.DecodeBytes(yys3Slc, true, true) + yys3 := string(yys3Slc) + z.DecSendContainerState(codecSelfer_containerMapValue1234) + switch yys3 { + case "key": + if r.TryDecodeAsNil() { + x.Key = "" + } else { + x.Key = string(r.DecodeString()) + } + case "operator": + if r.TryDecodeAsNil() { + x.Operator = "" + } else { + x.Operator = TolerationOperator(r.DecodeString()) + } + case "value": + if r.TryDecodeAsNil() { + x.Value = "" + } else { + x.Value = string(r.DecodeString()) + } + case "effect": + if r.TryDecodeAsNil() { + x.Effect = "" + } else { + x.Effect = TaintEffect(r.DecodeString()) + } + default: + z.DecStructFieldNotFound(-1, yys3) + } // end switch yys3 + } // end for yyj3 + z.DecSendContainerState(codecSelfer_containerMapEnd1234) +} + +func (x *Toleration) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { + var h codecSelfer1234 + z, r := codec1978.GenHelperDecoder(d) + _, _, _ = h, z, r + var yyj8 int + var yyb8 bool + var yyhl8 bool = l >= 0 + yyj8++ + if yyhl8 { + yyb8 = yyj8 > l + } else { + yyb8 = r.CheckBreak() + } + if yyb8 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) + return + } + z.DecSendContainerState(codecSelfer_containerArrayElem1234) + if r.TryDecodeAsNil() { + x.Key = "" + } else { + x.Key = string(r.DecodeString()) + } + yyj8++ + if yyhl8 { + yyb8 = yyj8 > l + } else { + yyb8 = r.CheckBreak() + } + if yyb8 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) + return + } + z.DecSendContainerState(codecSelfer_containerArrayElem1234) + if r.TryDecodeAsNil() { + x.Operator = "" + } else { + x.Operator = TolerationOperator(r.DecodeString()) + } + yyj8++ + if yyhl8 { + yyb8 = yyj8 > l + } else { + yyb8 = r.CheckBreak() + } + if yyb8 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) + return + } + z.DecSendContainerState(codecSelfer_containerArrayElem1234) + if r.TryDecodeAsNil() { + x.Value = "" + } else { + x.Value = string(r.DecodeString()) + } + yyj8++ + if yyhl8 { + yyb8 = yyj8 > l + } else { + yyb8 = r.CheckBreak() + } + if yyb8 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) + return + } + z.DecSendContainerState(codecSelfer_containerArrayElem1234) + if r.TryDecodeAsNil() { + x.Effect = "" + } else { + x.Effect = TaintEffect(r.DecodeString()) + } + for { + yyj8++ + if yyhl8 { + yyb8 = yyj8 > l + } else { + yyb8 = r.CheckBreak() + } + if yyb8 { + break + } + z.DecSendContainerState(codecSelfer_containerArrayElem1234) + z.DecStructFieldNotFound(yyj8-1, "") + } + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) +} + +func (x TolerationOperator) CodecEncodeSelf(e *codec1978.Encoder) { + var h codecSelfer1234 + z, r := codec1978.GenHelperEncoder(e) + _, _, _ = h, z, r + yym1 := z.EncBinary() + _ = yym1 + if false { + } else if z.HasExtensions() && z.EncExt(x) { + } else { + r.EncodeString(codecSelferC_UTF81234, string(x)) + } +} + +func (x *TolerationOperator) CodecDecodeSelf(d *codec1978.Decoder) { + var h codecSelfer1234 + z, r := codec1978.GenHelperDecoder(d) + _, _, _ = h, z, r + yym1 := z.DecBinary() + _ = yym1 + if false { + } else if z.HasExtensions() && z.DecExt(x) { + } else { + *((*string)(x)) = r.DecodeString() + } +} + func (x *PodSpec) CodecEncodeSelf(e *codec1978.Encoder) { var h codecSelfer1234 z, r := codec1978.GenHelperEncoder(e) @@ -30438,7 +31564,7 @@ func (x *ServicePort) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) { } case "targetPort": if r.TryDecodeAsNil() { - x.TargetPort = pkg5_intstr.IntOrString{} + x.TargetPort = pkg4_intstr.IntOrString{} } else { yyv7 := &x.TargetPort yym8 := z.DecBinary() @@ -30531,7 +31657,7 @@ func (x *ServicePort) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { } z.DecSendContainerState(codecSelfer_containerArrayElem1234) if r.TryDecodeAsNil() { - x.TargetPort = pkg5_intstr.IntOrString{} + x.TargetPort = pkg4_intstr.IntOrString{} } else { yyv14 := &x.TargetPort yym15 := z.DecBinary() @@ -34157,14 +35283,14 @@ func (x *NodeSystemInfo) CodecEncodeSelf(e *codec1978.Encoder) { } else { yysep2 := !z.EncBinary() yy2arr2 := z.EncBasicHandle().StructToArray - var yyq2 [8]bool + var yyq2 [10]bool _, _, _ = yysep2, yyq2, yy2arr2 const yyr2 bool = false var yynn2 int if yyr2 || yy2arr2 { - r.EncodeArrayStart(8) + r.EncodeArrayStart(10) } else { - yynn2 = 8 + yynn2 = 10 for _, b := range yyq2 { if b { yynn2++ @@ -34325,6 +35451,44 @@ func (x *NodeSystemInfo) CodecEncodeSelf(e *codec1978.Encoder) { r.EncodeString(codecSelferC_UTF81234, string(x.KubeProxyVersion)) } } + if yyr2 || yy2arr2 { + z.EncSendContainerState(codecSelfer_containerArrayElem1234) + yym28 := z.EncBinary() + _ = yym28 + if false { + } else { + r.EncodeString(codecSelferC_UTF81234, string(x.OperatingSystem)) + } + } else { + z.EncSendContainerState(codecSelfer_containerMapKey1234) + r.EncodeString(codecSelferC_UTF81234, string("operatingSystem")) + z.EncSendContainerState(codecSelfer_containerMapValue1234) + yym29 := z.EncBinary() + _ = yym29 + if false { + } else { + r.EncodeString(codecSelferC_UTF81234, string(x.OperatingSystem)) + } + } + if yyr2 || yy2arr2 { + z.EncSendContainerState(codecSelfer_containerArrayElem1234) + yym31 := z.EncBinary() + _ = yym31 + if false { + } else { + r.EncodeString(codecSelferC_UTF81234, string(x.Architecture)) + } + } else { + z.EncSendContainerState(codecSelfer_containerMapKey1234) + r.EncodeString(codecSelferC_UTF81234, string("architecture")) + z.EncSendContainerState(codecSelfer_containerMapValue1234) + yym32 := z.EncBinary() + _ = yym32 + if false { + } else { + r.EncodeString(codecSelferC_UTF81234, string(x.Architecture)) + } + } if yyr2 || yy2arr2 { z.EncSendContainerState(codecSelfer_containerArrayEnd1234) } else { @@ -34434,6 +35598,18 @@ func (x *NodeSystemInfo) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) { } else { x.KubeProxyVersion = string(r.DecodeString()) } + case "operatingSystem": + if r.TryDecodeAsNil() { + x.OperatingSystem = "" + } else { + x.OperatingSystem = string(r.DecodeString()) + } + case "architecture": + if r.TryDecodeAsNil() { + x.Architecture = "" + } else { + x.Architecture = string(r.DecodeString()) + } default: z.DecStructFieldNotFound(-1, yys3) } // end switch yys3 @@ -34445,16 +35621,16 @@ func (x *NodeSystemInfo) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { var h codecSelfer1234 z, r := codec1978.GenHelperDecoder(d) _, _, _ = h, z, r - var yyj12 int - var yyb12 bool - var yyhl12 bool = l >= 0 - yyj12++ - if yyhl12 { - yyb12 = yyj12 > l + var yyj14 int + var yyb14 bool + var yyhl14 bool = l >= 0 + yyj14++ + if yyhl14 { + yyb14 = yyj14 > l } else { - yyb12 = r.CheckBreak() + yyb14 = r.CheckBreak() } - if yyb12 { + if yyb14 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -34464,13 +35640,13 @@ func (x *NodeSystemInfo) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { } else { x.MachineID = string(r.DecodeString()) } - yyj12++ - if yyhl12 { - yyb12 = yyj12 > l + yyj14++ + if yyhl14 { + yyb14 = yyj14 > l } else { - yyb12 = r.CheckBreak() + yyb14 = r.CheckBreak() } - if yyb12 { + if yyb14 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -34480,13 +35656,13 @@ func (x *NodeSystemInfo) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { } else { x.SystemUUID = string(r.DecodeString()) } - yyj12++ - if yyhl12 { - yyb12 = yyj12 > l + yyj14++ + if yyhl14 { + yyb14 = yyj14 > l } else { - yyb12 = r.CheckBreak() + yyb14 = r.CheckBreak() } - if yyb12 { + if yyb14 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -34496,13 +35672,13 @@ func (x *NodeSystemInfo) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { } else { x.BootID = string(r.DecodeString()) } - yyj12++ - if yyhl12 { - yyb12 = yyj12 > l + yyj14++ + if yyhl14 { + yyb14 = yyj14 > l } else { - yyb12 = r.CheckBreak() + yyb14 = r.CheckBreak() } - if yyb12 { + if yyb14 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -34512,13 +35688,13 @@ func (x *NodeSystemInfo) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { } else { x.KernelVersion = string(r.DecodeString()) } - yyj12++ - if yyhl12 { - yyb12 = yyj12 > l + yyj14++ + if yyhl14 { + yyb14 = yyj14 > l } else { - yyb12 = r.CheckBreak() + yyb14 = r.CheckBreak() } - if yyb12 { + if yyb14 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -34528,13 +35704,13 @@ func (x *NodeSystemInfo) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { } else { x.OSImage = string(r.DecodeString()) } - yyj12++ - if yyhl12 { - yyb12 = yyj12 > l + yyj14++ + if yyhl14 { + yyb14 = yyj14 > l } else { - yyb12 = r.CheckBreak() + yyb14 = r.CheckBreak() } - if yyb12 { + if yyb14 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -34544,13 +35720,13 @@ func (x *NodeSystemInfo) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { } else { x.ContainerRuntimeVersion = string(r.DecodeString()) } - yyj12++ - if yyhl12 { - yyb12 = yyj12 > l + yyj14++ + if yyhl14 { + yyb14 = yyj14 > l } else { - yyb12 = r.CheckBreak() + yyb14 = r.CheckBreak() } - if yyb12 { + if yyb14 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -34560,13 +35736,13 @@ func (x *NodeSystemInfo) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { } else { x.KubeletVersion = string(r.DecodeString()) } - yyj12++ - if yyhl12 { - yyb12 = yyj12 > l + yyj14++ + if yyhl14 { + yyb14 = yyj14 > l } else { - yyb12 = r.CheckBreak() + yyb14 = r.CheckBreak() } - if yyb12 { + if yyb14 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -34576,18 +35752,50 @@ func (x *NodeSystemInfo) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { } else { x.KubeProxyVersion = string(r.DecodeString()) } + yyj14++ + if yyhl14 { + yyb14 = yyj14 > l + } else { + yyb14 = r.CheckBreak() + } + if yyb14 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) + return + } + z.DecSendContainerState(codecSelfer_containerArrayElem1234) + if r.TryDecodeAsNil() { + x.OperatingSystem = "" + } else { + x.OperatingSystem = string(r.DecodeString()) + } + yyj14++ + if yyhl14 { + yyb14 = yyj14 > l + } else { + yyb14 = r.CheckBreak() + } + if yyb14 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) + return + } + z.DecSendContainerState(codecSelfer_containerArrayElem1234) + if r.TryDecodeAsNil() { + x.Architecture = "" + } else { + x.Architecture = string(r.DecodeString()) + } for { - yyj12++ - if yyhl12 { - yyb12 = yyj12 > l + yyj14++ + if yyhl14 { + yyb14 = yyj14 > l } else { - yyb12 = r.CheckBreak() + yyb14 = r.CheckBreak() } - if yyb12 { + if yyb14 { break } z.DecSendContainerState(codecSelfer_containerArrayElem1234) - z.DecStructFieldNotFound(yyj12-1, "") + z.DecStructFieldNotFound(yyj14-1, "") } z.DecSendContainerState(codecSelfer_containerArrayEnd1234) } @@ -44621,7 +45829,7 @@ func (x *List) CodecEncodeSelf(e *codec1978.Encoder) { _ = yym9 if false { } else { - h.encSliceruntime_RawExtension(([]pkg6_runtime.RawExtension)(x.Items), e) + h.encSliceruntime_RawExtension(([]pkg5_runtime.RawExtension)(x.Items), e) } } } else { @@ -44635,7 +45843,7 @@ func (x *List) CodecEncodeSelf(e *codec1978.Encoder) { _ = yym10 if false { } else { - h.encSliceruntime_RawExtension(([]pkg6_runtime.RawExtension)(x.Items), e) + h.encSliceruntime_RawExtension(([]pkg5_runtime.RawExtension)(x.Items), e) } } } @@ -44772,7 +45980,7 @@ func (x *List) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) { _ = yym7 if false { } else { - h.decSliceruntime_RawExtension((*[]pkg6_runtime.RawExtension)(yyv6), d) + h.decSliceruntime_RawExtension((*[]pkg5_runtime.RawExtension)(yyv6), d) } } case "kind": @@ -44843,7 +46051,7 @@ func (x *List) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { _ = yym14 if false { } else { - h.decSliceruntime_RawExtension((*[]pkg6_runtime.RawExtension)(yyv13), d) + h.decSliceruntime_RawExtension((*[]pkg5_runtime.RawExtension)(yyv13), d) } } yyj10++ @@ -51568,7 +52776,7 @@ func (x codecSelfer1234) decSlicePersistentVolume(v *[]PersistentVolume, d *code yyrg1 := len(yyv1) > 0 yyv21 := yyv1 - yyrl1, yyrt1 = z.DecInferLen(yyl1, z.DecBasicHandle().MaxInitLen, 448) + yyrl1, yyrt1 = z.DecInferLen(yyl1, z.DecBasicHandle().MaxInitLen, 456) if yyrt1 { if yyrl1 <= cap(yyv1) { yyv1 = yyv1[:yyrl1] @@ -53106,7 +54314,7 @@ func (x codecSelfer1234) decSliceVolume(v *[]Volume, d *codec1978.Decoder) { yyrg1 := len(yyv1) > 0 yyv21 := yyv1 - yyrl1, yyrt1 = z.DecInferLen(yyl1, z.DecBasicHandle().MaxInitLen, 168) + yyrl1, yyrt1 = z.DecInferLen(yyl1, z.DecBasicHandle().MaxInitLen, 176) if yyrt1 { if yyrl1 <= cap(yyv1) { yyv1 = yyv1[:yyrl1] @@ -53701,7 +54909,7 @@ func (x codecSelfer1234) decSlicePod(v *[]Pod, d *codec1978.Decoder) { yyrg1 := len(yyv1) > 0 yyv21 := yyv1 - yyrl1, yyrt1 = z.DecInferLen(yyl1, z.DecBasicHandle().MaxInitLen, 600) + yyrl1, yyrt1 = z.DecInferLen(yyl1, z.DecBasicHandle().MaxInitLen, 648) if yyrt1 { if yyrl1 <= cap(yyv1) { yyv1 = yyv1[:yyrl1] @@ -53820,7 +55028,7 @@ func (x codecSelfer1234) decSlicePodTemplate(v *[]PodTemplate, d *codec1978.Deco yyrg1 := len(yyv1) > 0 yyv21 := yyv1 - yyrl1, yyrt1 = z.DecInferLen(yyl1, z.DecBasicHandle().MaxInitLen, 672) + yyrl1, yyrt1 = z.DecInferLen(yyl1, z.DecBasicHandle().MaxInitLen, 696) if yyrt1 { if yyrl1 <= cap(yyv1) { yyv1 = yyv1[:yyrl1] @@ -55479,7 +56687,7 @@ func (x codecSelfer1234) decResourceList(v *ResourceList, d *codec1978.Decoder) yyl1 := r.ReadMapStart() yybh1 := z.DecBasicHandle() if yyv1 == nil { - yyrl1, _ := z.DecInferLen(yyl1, yybh1.MaxInitLen, 40) + yyrl1, _ := z.DecInferLen(yyl1, yybh1.MaxInitLen, 80) yyv1 = make(map[ResourceName]pkg3_resource.Quantity, yyrl1) *v = yyv1 } @@ -55600,7 +56808,7 @@ func (x codecSelfer1234) decSliceNode(v *[]Node, d *codec1978.Decoder) { yyrg1 := len(yyv1) > 0 yyv21 := yyv1 - yyrl1, yyrt1 = z.DecInferLen(yyl1, z.DecBasicHandle().MaxInitLen, 536) + yyrl1, yyrt1 = z.DecInferLen(yyl1, z.DecBasicHandle().MaxInitLen, 568) if yyrt1 { if yyrl1 <= cap(yyv1) { yyv1 = yyv1[:yyrl1] @@ -56028,7 +57236,7 @@ func (x codecSelfer1234) decSliceEvent(v *[]Event, d *codec1978.Decoder) { } } -func (x codecSelfer1234) encSliceruntime_RawExtension(v []pkg6_runtime.RawExtension, e *codec1978.Encoder) { +func (x codecSelfer1234) encSliceruntime_RawExtension(v []pkg5_runtime.RawExtension, e *codec1978.Encoder) { var h codecSelfer1234 z, r := codec1978.GenHelperEncoder(e) _, _, _ = h, z, r @@ -56049,7 +57257,7 @@ func (x codecSelfer1234) encSliceruntime_RawExtension(v []pkg6_runtime.RawExtens z.EncSendContainerState(codecSelfer_containerArrayEnd1234) } -func (x codecSelfer1234) decSliceruntime_RawExtension(v *[]pkg6_runtime.RawExtension, d *codec1978.Decoder) { +func (x codecSelfer1234) decSliceruntime_RawExtension(v *[]pkg5_runtime.RawExtension, d *codec1978.Decoder) { var h codecSelfer1234 z, r := codec1978.GenHelperDecoder(d) _, _, _ = h, z, r @@ -56060,7 +57268,7 @@ func (x codecSelfer1234) decSliceruntime_RawExtension(v *[]pkg6_runtime.RawExten _ = yyc1 if yyl1 == 0 { if yyv1 == nil { - yyv1 = []pkg6_runtime.RawExtension{} + yyv1 = []pkg5_runtime.RawExtension{} yyc1 = true } else if len(yyv1) != 0 { yyv1 = yyv1[:0] @@ -56080,10 +57288,10 @@ func (x codecSelfer1234) decSliceruntime_RawExtension(v *[]pkg6_runtime.RawExten if yyrl1 <= cap(yyv1) { yyv1 = yyv1[:yyrl1] } else { - yyv1 = make([]pkg6_runtime.RawExtension, yyrl1) + yyv1 = make([]pkg5_runtime.RawExtension, yyrl1) } } else { - yyv1 = make([]pkg6_runtime.RawExtension, yyrl1) + yyv1 = make([]pkg5_runtime.RawExtension, yyrl1) } yyc1 = true yyrr1 = len(yyv1) @@ -56098,7 +57306,7 @@ func (x codecSelfer1234) decSliceruntime_RawExtension(v *[]pkg6_runtime.RawExten for ; yyj1 < yyrr1; yyj1++ { yyh1.ElemContainerState(yyj1) if r.TryDecodeAsNil() { - yyv1[yyj1] = pkg6_runtime.RawExtension{} + yyv1[yyj1] = pkg5_runtime.RawExtension{} } else { yyv2 := &yyv1[yyj1] yym3 := z.DecBinary() @@ -56115,10 +57323,10 @@ func (x codecSelfer1234) decSliceruntime_RawExtension(v *[]pkg6_runtime.RawExten } if yyrt1 { for ; yyj1 < yyl1; yyj1++ { - yyv1 = append(yyv1, pkg6_runtime.RawExtension{}) + yyv1 = append(yyv1, pkg5_runtime.RawExtension{}) yyh1.ElemContainerState(yyj1) if r.TryDecodeAsNil() { - yyv1[yyj1] = pkg6_runtime.RawExtension{} + yyv1[yyj1] = pkg5_runtime.RawExtension{} } else { yyv4 := &yyv1[yyj1] yym5 := z.DecBinary() @@ -56140,13 +57348,13 @@ func (x codecSelfer1234) decSliceruntime_RawExtension(v *[]pkg6_runtime.RawExten for ; !r.CheckBreak(); yyj1++ { if yyj1 >= len(yyv1) { - yyv1 = append(yyv1, pkg6_runtime.RawExtension{}) // var yyz1 pkg6_runtime.RawExtension + yyv1 = append(yyv1, pkg5_runtime.RawExtension{}) // var yyz1 pkg5_runtime.RawExtension yyc1 = true } yyh1.ElemContainerState(yyj1) if yyj1 < len(yyv1) { if r.TryDecodeAsNil() { - yyv1[yyj1] = pkg6_runtime.RawExtension{} + yyv1[yyj1] = pkg5_runtime.RawExtension{} } else { yyv6 := &yyv1[yyj1] yym7 := z.DecBinary() @@ -56169,7 +57377,7 @@ func (x codecSelfer1234) decSliceruntime_RawExtension(v *[]pkg6_runtime.RawExten yyv1 = yyv1[:yyj1] yyc1 = true } else if yyj1 == 0 && yyv1 == nil { - yyv1 = []pkg6_runtime.RawExtension{} + yyv1 = []pkg5_runtime.RawExtension{} yyc1 = true } } diff --git a/vendor/k8s.io/kubernetes/pkg/api/v1/types.go b/vendor/k8s.io/kubernetes/pkg/api/v1/types.go index 5e2aa82021..5c12919253 100644 --- a/vendor/k8s.io/kubernetes/pkg/api/v1/types.go +++ b/vendor/k8s.io/kubernetes/pkg/api/v1/types.go @@ -184,7 +184,7 @@ type ObjectMeta struct { // is an identifier for the responsible component that will remove the entry // from the list. If the deletionTimestamp of the object is non-nil, entries // in this list can only be removed. - Finalizers []string `json:"finalizers,omitempty" protobuf:"bytes,14,rep,name=finalizers"` + Finalizers []string `json:"finalizers,omitempty" patchStrategy:"merge" protobuf:"bytes,14,rep,name=finalizers"` } const ( @@ -273,6 +273,8 @@ type VolumeSource struct { AzureFile *AzureFileVolumeSource `json:"azureFile,omitempty" protobuf:"bytes,18,opt,name=azureFile"` // ConfigMap represents a configMap that should populate this volume ConfigMap *ConfigMapVolumeSource `json:"configMap,omitempty" protobuf:"bytes,19,opt,name=configMap"` + // VsphereVolume represents a vSphere volume attached and mounted on kubelets host machine + VsphereVolume *VsphereVirtualDiskVolumeSource `json:"vsphereVolume,omitempty" protobuf:"bytes,20,opt,name=vsphereVolume"` } // PersistentVolumeClaimVolumeSource references the user's PVC in the same namespace. @@ -333,6 +335,8 @@ type PersistentVolumeSource struct { FlexVolume *FlexVolumeSource `json:"flexVolume,omitempty" protobuf:"bytes,12,opt,name=flexVolume"` // AzureFile represents an Azure File Service mount on the host and bind mount to the pod. AzureFile *AzureFileVolumeSource `json:"azureFile,omitempty" protobuf:"bytes,13,opt,name=azureFile"` + // VsphereVolume represents a vSphere volume attached and mounted on kubelets host machine + VsphereVolume *VsphereVirtualDiskVolumeSource `json:"vsphereVolume,omitempty" protobuf:"bytes,14,opt,name=vsphereVolume"` } // +genclient=true,nonNamespaced=true @@ -506,6 +510,10 @@ const ( ClaimPending PersistentVolumeClaimPhase = "Pending" // used for PersistentVolumeClaims that are bound ClaimBound PersistentVolumeClaimPhase = "Bound" + // used for PersistentVolumeClaims that lost their underlying + // PersistentVolume. The claim was bound to a PersistentVolume and this + // volume does not exist any longer and all data on it was lost. + ClaimLost PersistentVolumeClaimPhase = "Lost" ) // Represents a host path mapped into a pod. @@ -749,6 +757,14 @@ type SecretVolumeSource struct { // Name of the secret in the pod's namespace to use. // More info: http://releases.k8s.io/HEAD/docs/user-guide/volumes.md#secrets SecretName string `json:"secretName,omitempty" protobuf:"bytes,1,opt,name=secretName"` + // If unspecified, each key-value pair in the Data field of the referenced + // Secret will be projected into the volume as a file whose name is the + // key and content is the value. If specified, the listed keys will be + // projected into the specified paths, and unlisted keys will not be + // present. If a key is specified which is not present in the Secret, + // the volume setup will error. Paths must be relative and may not contain + // the '..' path or start with '..'. + Items []KeyToPath `json:"items,omitempty" protobuf:"bytes,2,rep,name=items"` } // Represents an NFS mount that lasts the lifetime of a pod. @@ -822,6 +838,16 @@ type AzureFileVolumeSource struct { ReadOnly bool `json:"readOnly,omitempty" protobuf:"varint,3,opt,name=readOnly"` } +// Represents a vSphere volume resource. +type VsphereVirtualDiskVolumeSource struct { + // Path that identifies vSphere volume vmdk + VolumePath string `json:"volumePath" protobuf:"bytes,1,opt,name=volumePath"` + // Filesystem type to mount. + // Must be a filesystem type supported by the host operating system. + // Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + FSType string `json:"fsType,omitempty" protobuf:"bytes,2,opt,name=fsType"` +} + // Adapts a ConfigMap into a volume. // // The contents of the target ConfigMap's Data field will be presented in a @@ -1106,7 +1132,7 @@ type Container struct { // Cannot be updated. // More info: http://releases.k8s.io/HEAD/docs/user-guide/persistent-volumes.md#resources Resources ResourceRequirements `json:"resources,omitempty" protobuf:"bytes,8,opt,name=resources"` - // Pod volumes to mount into the container's filesyste. + // Pod volumes to mount into the container's filesystem. // Cannot be updated. VolumeMounts []VolumeMount `json:"volumeMounts,omitempty" patchStrategy:"merge" patchMergeKey:"name" protobuf:"bytes,9,rep,name=volumeMounts"` // Periodic probe of container liveness. @@ -1541,11 +1567,103 @@ type PreferredSchedulingTerm struct { Preference NodeSelectorTerm `json:"preference" protobuf:"bytes,2,opt,name=preference"` } +// The node this Taint is attached to has the effect "effect" on +// any pod that that does not tolerate the Taint. +type Taint struct { + // Required. The taint key to be applied to a node. + Key string `json:"key" patchStrategy:"merge" patchMergeKey:"key" protobuf:"bytes,1,opt,name=key"` + // Required. The taint value corresponding to the taint key. + Value string `json:"value,omitempty" protobuf:"bytes,2,opt,name=value"` + // Required. The effect of the taint on pods + // that do not tolerate the taint. + // Valid effects are NoSchedule and PreferNoSchedule. + Effect TaintEffect `json:"effect" protobuf:"bytes,3,opt,name=effect,casttype=TaintEffect"` +} + +type TaintEffect string + +const ( + // Do not allow new pods to schedule onto the node unless they tolerate the taint, + // but allow all pods submitted to Kubelet without going through the scheduler + // to start, and allow all already-running pods to continue running. + // Enforced by the scheduler. + TaintEffectNoSchedule TaintEffect = "NoSchedule" + // Like TaintEffectNoSchedule, but the scheduler tries not to schedule + // new pods onto the node, rather than prohibiting new pods from scheduling + // onto the node entirely. Enforced by the scheduler. + TaintEffectPreferNoSchedule TaintEffect = "PreferNoSchedule" + // NOT YET IMPLEMENTED. TODO: Uncomment field once it is implemented. + // Do not allow new pods to schedule onto the node unless they tolerate the taint, + // do not allow pods to start on Kubelet unless they tolerate the taint, + // but allow all already-running pods to continue running. + // Enforced by the scheduler and Kubelet. + // TaintEffectNoScheduleNoAdmit TaintEffect = "NoScheduleNoAdmit" + // NOT YET IMPLEMENTED. TODO: Uncomment field once it is implemented. + // Do not allow new pods to schedule onto the node unless they tolerate the taint, + // do not allow pods to start on Kubelet unless they tolerate the taint, + // and evict any already-running pods that do not tolerate the taint. + // Enforced by the scheduler and Kubelet. + // TaintEffectNoScheduleNoAdmitNoExecute = "NoScheduleNoAdmitNoExecute" +) + +// The pod this Toleration is attached to tolerates any taint that matches +// the triple using the matching operator . +type Toleration struct { + // Required. Key is the taint key that the toleration applies to. + Key string `json:"key,omitempty" patchStrategy:"merge" patchMergeKey:"key" protobuf:"bytes,1,opt,name=key"` + // operator represents a key's relationship to the value. + // Valid operators are Exists and Equal. Defaults to Equal. + // Exists is equivalent to wildcard for value, so that a pod can + // tolerate all taints of a particular category. + Operator TolerationOperator `json:"operator,omitempty" protobuf:"bytes,2,opt,name=operator,casttype=TolerationOperator"` + // Value is the taint value the toleration matches to. + // If the operator is Exists, the value should be empty, otherwise just a regular string. + Value string `json:"value,omitempty" protobuf:"bytes,3,opt,name=value"` + // Effect indicates the taint effect to match. Empty means match all taint effects. + // When specified, allowed values are NoSchedule and PreferNoSchedule. + Effect TaintEffect `json:"effect,omitempty" protobuf:"bytes,4,opt,name=effect,casttype=TaintEffect"` + // TODO: For forgiveness (#1574), we'd eventually add at least a grace period + // here, and possibly an occurrence threshold and period. +} + +// A toleration operator is the set of operators that can be used in a toleration. +type TolerationOperator string + +const ( + TolerationOpExists TolerationOperator = "Exists" + TolerationOpEqual TolerationOperator = "Equal" +) + +const ( + // This annotation key will be used to contain an array of v1 JSON encoded Containers + // for init containers. The annotation will be placed into the internal type and cleared. + PodInitContainersAnnotationKey = "pod.alpha.kubernetes.io/init-containers" + // This annotation key will be used to contain an array of v1 JSON encoded + // ContainerStatuses for init containers. The annotation will be placed into the internal + // type and cleared. + PodInitContainerStatusesAnnotationKey = "pod.alpha.kubernetes.io/init-container-statuses" +) + // PodSpec is a description of a pod. type PodSpec struct { // List of volumes that can be mounted by containers belonging to the pod. // More info: http://releases.k8s.io/HEAD/docs/user-guide/volumes.md Volumes []Volume `json:"volumes,omitempty" patchStrategy:"merge" patchMergeKey:"name" protobuf:"bytes,1,rep,name=volumes"` + // List of initialization containers belonging to the pod. + // Init containers are executed in order prior to containers being started. If any + // init container fails, the pod is considered to have failed and is handled according + // to its restartPolicy. The name for an init container or normal container must be + // unique among all containers. + // Init containers may not have Lifecycle actions, Readiness probes, or Liveness probes. + // The resourceRequirements of an init container are taken into account during scheduling + // by finding the highest request/limit for each resource type, and then using the max of + // of that value or the sum of the normal containers. Limits are applied to init containers + // in a similar fashion. + // Init containers cannot currently be added or removed. + // Init containers are in alpha state and may change without notice. + // Cannot be updated. + // More info: http://releases.k8s.io/HEAD/docs/user-guide/containers.md + InitContainers []Container `json:"-" patchStrategy:"merge" patchMergeKey:"name"` // List of containers belonging to the pod. // Containers cannot currently be added or removed. // There must be at least one container in a Pod. @@ -1679,6 +1797,12 @@ type PodStatus struct { // This is before the Kubelet pulled the container image(s) for the pod. StartTime *unversioned.Time `json:"startTime,omitempty" protobuf:"bytes,7,opt,name=startTime"` + // The list has one entry per init container in the manifest. The most recent successful + // init container will have ready = true, the most recently started container will have + // startTime set. + // Init containers are in alpha state and may change without notice. + // More info: http://releases.k8s.io/HEAD/docs/user-guide/pod-states.md#container-statuses + InitContainerStatuses []ContainerStatus `json:"-"` // The list has one entry per container in the manifest. Each entry is currently the output // of `docker inspect`. // More info: http://releases.k8s.io/HEAD/docs/user-guide/pod-states.md#container-statuses @@ -2208,6 +2332,10 @@ type NodeSystemInfo struct { KubeletVersion string `json:"kubeletVersion" protobuf:"bytes,7,opt,name=kubeletVersion"` // KubeProxy Version reported by the node. KubeProxyVersion string `json:"kubeProxyVersion" protobuf:"bytes,8,opt,name=kubeProxyVersion"` + // The Operating System reported by the node + OperatingSystem string `json:"operatingSystem" protobuf:"bytes,9,opt,name=operatingSystem"` + // The Architecture reported by the node + Architecture string `json:"architecture" protobuf:"bytes,10,opt,name=architecture"` } // NodeStatus is information about the current status of a node. @@ -2269,6 +2397,8 @@ const ( // NodeOutOfDisk means the kubelet will not accept new pods due to insufficient free disk // space on the node. NodeOutOfDisk NodeConditionType = "OutOfDisk" + // NodeMemoryPressure means the kubelet is under pressure due to insufficient available memory. + NodeMemoryPressure NodeConditionType = "MemoryPressure" ) // NodeCondition contains condition infromation for a node. diff --git a/vendor/k8s.io/kubernetes/pkg/api/v1/types_swagger_doc_generated.go b/vendor/k8s.io/kubernetes/pkg/api/v1/types_swagger_doc_generated.go index de7305a09f..398924e6df 100644 --- a/vendor/k8s.io/kubernetes/pkg/api/v1/types_swagger_doc_generated.go +++ b/vendor/k8s.io/kubernetes/pkg/api/v1/types_swagger_doc_generated.go @@ -1,5 +1,5 @@ /* -Copyright 2015 The Kubernetes Authors All rights reserved. +Copyright 2016 The Kubernetes Authors All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -186,7 +186,7 @@ var map_Container = map[string]string{ "ports": "List of ports to expose from the container. Exposing a port here gives the system additional information about the network connections a container uses, but is primarily informational. Not specifying a port here DOES NOT prevent that port from being exposed. Any port which is listening on the default \"0.0.0.0\" address inside a container will be accessible from the network. Cannot be updated.", "env": "List of environment variables to set in the container. Cannot be updated.", "resources": "Compute Resources required by this container. Cannot be updated. More info: http://releases.k8s.io/HEAD/docs/user-guide/persistent-volumes.md#resources", - "volumeMounts": "Pod volumes to mount into the container's filesyste. Cannot be updated.", + "volumeMounts": "Pod volumes to mount into the container's filesystem. Cannot be updated.", "livenessProbe": "Periodic probe of container liveness. Container will be restarted if the probe fails. Cannot be updated. More info: http://releases.k8s.io/HEAD/docs/user-guide/pod-states.md#container-probes", "readinessProbe": "Periodic probe of container service readiness. Container will be removed from service endpoints if the probe fails. Cannot be updated. More info: http://releases.k8s.io/HEAD/docs/user-guide/pod-states.md#container-probes", "lifecycle": "Actions that the management system should take in response to container lifecycle events. Cannot be updated.", @@ -894,6 +894,8 @@ var map_NodeSystemInfo = map[string]string{ "containerRuntimeVersion": "ContainerRuntime Version reported by the node through runtime remote API (e.g. docker://1.5.0).", "kubeletVersion": "Kubelet Version reported by the node.", "kubeProxyVersion": "KubeProxy Version reported by the node.", + "operatingSystem": "The Operating System reported by the node", + "architecture": "The Architecture reported by the node", } func (NodeSystemInfo) SwaggerDoc() map[string]string { @@ -1048,6 +1050,7 @@ var map_PersistentVolumeSource = map[string]string{ "flocker": "Flocker represents a Flocker volume attached to a kubelet's host machine and exposed to the pod for its usage. This depends on the Flocker control service being running", "flexVolume": "FlexVolume represents a generic volume resource that is provisioned/attached using a exec based plugin. This is an alpha feature and may change in future.", "azureFile": "AzureFile represents an Azure File Service mount on the host and bind mount to the pod.", + "vsphereVolume": "VsphereVolume represents a vSphere volume attached and mounted on kubelets host machine", } func (PersistentVolumeSource) SwaggerDoc() map[string]string { @@ -1487,6 +1490,7 @@ func (SecretList) SwaggerDoc() map[string]string { var map_SecretVolumeSource = map[string]string{ "": "Adapts a Secret into a volume.\n\nThe contents of the target Secret's Data field will be presented in a volume as files using the keys in the Data field as the file names. Secret volumes support ownership management and SELinux relabeling.", "secretName": "Name of the secret in the pod's namespace to use. More info: http://releases.k8s.io/HEAD/docs/user-guide/volumes.md#secrets", + "items": "If unspecified, each key-value pair in the Data field of the referenced Secret will be projected into the volume as a file whose name is the key and content is the value. If specified, the listed keys will be projected into the specified paths, and unlisted keys will not be present. If a key is specified which is not present in the Secret, the volume setup will error. Paths must be relative and may not contain the '..' path or start with '..'.", } func (SecretVolumeSource) SwaggerDoc() map[string]string { @@ -1614,6 +1618,29 @@ func (TCPSocketAction) SwaggerDoc() map[string]string { return map_TCPSocketAction } +var map_Taint = map[string]string{ + "": "The node this Taint is attached to has the effect \"effect\" on any pod that that does not tolerate the Taint.", + "key": "Required. The taint key to be applied to a node.", + "value": "Required. The taint value corresponding to the taint key.", + "effect": "Required. The effect of the taint on pods that do not tolerate the taint. Valid effects are NoSchedule and PreferNoSchedule.", +} + +func (Taint) SwaggerDoc() map[string]string { + return map_Taint +} + +var map_Toleration = map[string]string{ + "": "The pod this Toleration is attached to tolerates any taint that matches the triple using the matching operator .", + "key": "Required. Key is the taint key that the toleration applies to.", + "operator": "operator represents a key's relationship to the value. Valid operators are Exists and Equal. Defaults to Equal. Exists is equivalent to wildcard for value, so that a pod can tolerate all taints of a particular category.", + "value": "Value is the taint value the toleration matches to. If the operator is Exists, the value should be empty, otherwise just a regular string.", + "effect": "Effect indicates the taint effect to match. Empty means match all taint effects. When specified, allowed values are NoSchedule and PreferNoSchedule.", +} + +func (Toleration) SwaggerDoc() map[string]string { + return map_Toleration +} + var map_Volume = map[string]string{ "": "Volume represents a named volume in a pod that may be accessed by any container in the pod.", "name": "Volume's name. Must be a DNS_LABEL and unique within the pod. More info: http://releases.k8s.io/HEAD/docs/user-guide/identifiers.md#names", @@ -1647,21 +1674,32 @@ var map_VolumeSource = map[string]string{ "iscsi": "ISCSI represents an ISCSI Disk resource that is attached to a kubelet's host machine and then exposed to the pod. More info: http://releases.k8s.io/HEAD/examples/iscsi/README.md", "glusterfs": "Glusterfs represents a Glusterfs mount on the host that shares a pod's lifetime. More info: http://releases.k8s.io/HEAD/examples/glusterfs/README.md", "persistentVolumeClaim": "PersistentVolumeClaimVolumeSource represents a reference to a PersistentVolumeClaim in the same namespace. More info: http://releases.k8s.io/HEAD/docs/user-guide/persistent-volumes.md#persistentvolumeclaims", - "rbd": "RBD represents a Rados Block Device mount on the host that shares a pod's lifetime. More info: http://releases.k8s.io/HEAD/examples/rbd/README.md", - "flexVolume": "FlexVolume represents a generic volume resource that is provisioned/attached using a exec based plugin. This is an alpha feature and may change in future.", - "cinder": "Cinder represents a cinder volume attached and mounted on kubelets host machine More info: http://releases.k8s.io/HEAD/examples/mysql-cinder-pd/README.md", - "cephfs": "CephFS represents a Ceph FS mount on the host that shares a pod's lifetime", - "flocker": "Flocker represents a Flocker volume attached to a kubelet's host machine. This depends on the Flocker control service being running", - "downwardAPI": "DownwardAPI represents downward API about the pod that should populate this volume", - "fc": "FC represents a Fibre Channel resource that is attached to a kubelet's host machine and then exposed to the pod.", - "azureFile": "AzureFile represents an Azure File Service mount on the host and bind mount to the pod.", - "configMap": "ConfigMap represents a configMap that should populate this volume", + "rbd": "RBD represents a Rados Block Device mount on the host that shares a pod's lifetime. More info: http://releases.k8s.io/HEAD/examples/rbd/README.md", + "flexVolume": "FlexVolume represents a generic volume resource that is provisioned/attached using a exec based plugin. This is an alpha feature and may change in future.", + "cinder": "Cinder represents a cinder volume attached and mounted on kubelets host machine More info: http://releases.k8s.io/HEAD/examples/mysql-cinder-pd/README.md", + "cephfs": "CephFS represents a Ceph FS mount on the host that shares a pod's lifetime", + "flocker": "Flocker represents a Flocker volume attached to a kubelet's host machine. This depends on the Flocker control service being running", + "downwardAPI": "DownwardAPI represents downward API about the pod that should populate this volume", + "fc": "FC represents a Fibre Channel resource that is attached to a kubelet's host machine and then exposed to the pod.", + "azureFile": "AzureFile represents an Azure File Service mount on the host and bind mount to the pod.", + "configMap": "ConfigMap represents a configMap that should populate this volume", + "vsphereVolume": "VsphereVolume represents a vSphere volume attached and mounted on kubelets host machine", } func (VolumeSource) SwaggerDoc() map[string]string { return map_VolumeSource } +var map_VsphereVirtualDiskVolumeSource = map[string]string{ + "": "Represents a vSphere volume resource.", + "volumePath": "Path that identifies vSphere volume vmdk", + "fsType": "Filesystem type to mount. Must be a filesystem type supported by the host operating system. Ex. \"ext4\", \"xfs\", \"ntfs\". Implicitly inferred to be \"ext4\" if unspecified.", +} + +func (VsphereVirtualDiskVolumeSource) SwaggerDoc() map[string]string { + return map_VsphereVirtualDiskVolumeSource +} + var map_WeightedPodAffinityTerm = map[string]string{ "": "The weights of all of the matched WeightedPodAffinityTerm fields are added per-node to find the most preferred node(s)", "weight": "weight associated with matching the corresponding podAffinityTerm, in the range 1-100.", diff --git a/vendor/k8s.io/kubernetes/pkg/api/validation/events.go b/vendor/k8s.io/kubernetes/pkg/api/validation/events.go index d1a89c45c6..1182429582 100644 --- a/vendor/k8s.io/kubernetes/pkg/api/validation/events.go +++ b/vendor/k8s.io/kubernetes/pkg/api/validation/events.go @@ -37,8 +37,8 @@ func ValidateEvent(event *api.Event) field.ErrorList { event.Namespace != event.InvolvedObject.Namespace { allErrs = append(allErrs, field.Invalid(field.NewPath("involvedObject", "namespace"), event.InvolvedObject.Namespace, "does not match involvedObject")) } - if !validation.IsDNS1123Subdomain(event.Namespace) { - allErrs = append(allErrs, field.Invalid(field.NewPath("namespace"), event.Namespace, "")) + for _, msg := range validation.IsDNS1123Subdomain(event.Namespace) { + allErrs = append(allErrs, field.Invalid(field.NewPath("namespace"), event.Namespace, msg)) } return allErrs } diff --git a/vendor/k8s.io/kubernetes/pkg/api/validation/name.go b/vendor/k8s.io/kubernetes/pkg/api/validation/name.go index e36775b601..cf2eb8bb29 100644 --- a/vendor/k8s.io/kubernetes/pkg/api/validation/name.go +++ b/vendor/k8s.io/kubernetes/pkg/api/validation/name.go @@ -28,36 +28,36 @@ var NameMayNotBe = []string{".", ".."} var NameMayNotContain = []string{"/", "%"} // IsValidPathSegmentName validates the name can be safely encoded as a path segment -func IsValidPathSegmentName(name string) (bool, string) { +func IsValidPathSegmentName(name string) []string { for _, illegalName := range NameMayNotBe { if name == illegalName { - return false, fmt.Sprintf(`name may not be %q`, illegalName) + return []string{fmt.Sprintf(`may not be '%s'`, illegalName)} } } for _, illegalContent := range NameMayNotContain { if strings.Contains(name, illegalContent) { - return false, fmt.Sprintf(`name may not contain %q`, illegalContent) + return []string{fmt.Sprintf(`may not contain '%s'`, illegalContent)} } } - return true, "" + return nil } // IsValidPathSegmentPrefix validates the name can be used as a prefix for a name which will be encoded as a path segment // It does not check for exact matches with disallowed names, since an arbitrary suffix might make the name valid -func IsValidPathSegmentPrefix(name string) (bool, string) { +func IsValidPathSegmentPrefix(name string) []string { for _, illegalContent := range NameMayNotContain { if strings.Contains(name, illegalContent) { - return false, fmt.Sprintf(`name may not contain %q`, illegalContent) + return []string{fmt.Sprintf(`may not contain '%s'`, illegalContent)} } } - return true, "" + return nil } // ValidatePathSegmentName validates the name can be safely encoded as a path segment -func ValidatePathSegmentName(name string, prefix bool) (bool, string) { +func ValidatePathSegmentName(name string, prefix bool) []string { if prefix { return IsValidPathSegmentPrefix(name) } else { diff --git a/vendor/k8s.io/kubernetes/pkg/api/validation/validation.go b/vendor/k8s.io/kubernetes/pkg/api/validation/validation.go index 5acba71cb7..484c0b6e46 100644 --- a/vendor/k8s.io/kubernetes/pkg/api/validation/validation.go +++ b/vendor/k8s.io/kubernetes/pkg/api/validation/validation.go @@ -58,11 +58,6 @@ func InclusiveRangeErrorMsg(lo, hi int) string { return fmt.Sprintf(`must be between %d and %d, inclusive`, lo, hi) } -var labelValueErrorMsg string = fmt.Sprintf(`must have at most %d characters, matching regex %s: e.g. "MyValue" or ""`, validation.LabelValueMaxLength, validation.LabelValueFmt) -var qualifiedNameErrorMsg string = fmt.Sprintf(`must be a qualified name (at most %d characters, matching regex %s), with an optional DNS subdomain prefix (at most %d characters, matching regex %s) and slash (/): e.g. "MyName" or "example.com/MyName"`, validation.QualifiedNameMaxLength, validation.QualifiedNameFmt, validation.DNS1123SubdomainMaxLength, validation.DNS1123SubdomainFmt) -var DNSSubdomainErrorMsg string = fmt.Sprintf(`must be a DNS subdomain (at most %d characters, matching regex %s): e.g. "example.com"`, validation.DNS1123SubdomainMaxLength, validation.DNS1123SubdomainFmt) -var DNS1123LabelErrorMsg string = fmt.Sprintf(`must be a DNS label (at most %d characters, matching regex %s): e.g. "my-name"`, validation.DNS1123LabelMaxLength, validation.DNS1123LabelFmt) -var DNS952LabelErrorMsg string = fmt.Sprintf(`must be a DNS 952 label (at most %d characters, matching regex %s): e.g. "my-name"`, validation.DNS952LabelMaxLength, validation.DNS952LabelFmt) var pdPartitionErrorMsg string = InclusiveRangeErrorMsg(1, 255) var PortRangeErrorMsg string = InclusiveRangeErrorMsg(1, 65535) var IdRangeErrorMsg string = InclusiveRangeErrorMsg(0, math.MaxInt32) @@ -94,8 +89,8 @@ func ValidateAnnotations(annotations map[string]string, fldPath *field.Path) fie allErrs := field.ErrorList{} var totalSize int64 for k, v := range annotations { - if !validation.IsQualifiedName(strings.ToLower(k)) { - allErrs = append(allErrs, field.Invalid(fldPath, k, qualifiedNameErrorMsg)) + for _, msg := range validation.IsQualifiedName(strings.ToLower(k)) { + allErrs = append(allErrs, field.Invalid(fldPath, k, msg)) } totalSize += (int64)(len(k)) + (int64)(len(v)) } @@ -111,12 +106,20 @@ func ValidatePodSpecificAnnotations(annotations map[string]string, fldPath *fiel allErrs = append(allErrs, ValidateAffinityInPodAnnotations(annotations, fldPath)...) } - if hostname, exists := annotations[utilpod.PodHostnameAnnotation]; exists && !validation.IsDNS1123Label(hostname) { - allErrs = append(allErrs, field.Invalid(fldPath, utilpod.PodHostnameAnnotation, DNS1123LabelErrorMsg)) + if annotations[api.TolerationsAnnotationKey] != "" { + allErrs = append(allErrs, ValidateTolerationsInPodAnnotations(annotations, fldPath)...) } - if subdomain, exists := annotations[utilpod.PodSubdomainAnnotation]; exists && !validation.IsDNS1123Label(subdomain) { - allErrs = append(allErrs, field.Invalid(fldPath, utilpod.PodSubdomainAnnotation, DNS1123LabelErrorMsg)) + if hostname, exists := annotations[utilpod.PodHostnameAnnotation]; exists { + for _, msg := range validation.IsDNS1123Label(hostname) { + allErrs = append(allErrs, field.Invalid(fldPath, utilpod.PodHostnameAnnotation, msg)) + } + } + + if subdomain, exists := annotations[utilpod.PodSubdomainAnnotation]; exists { + for _, msg := range validation.IsDNS1123Label(subdomain) { + allErrs = append(allErrs, field.Invalid(fldPath, utilpod.PodSubdomainAnnotation, msg)) + } } return allErrs @@ -164,9 +167,11 @@ func ValidateOwnerReferences(ownerReferences []api.OwnerReference, fldPath *fiel } // ValidateNameFunc validates that the provided name is valid for a given resource type. -// Not all resources have the same validation rules for names. Prefix is true if the -// name will have a value appended to it. -type ValidateNameFunc func(name string, prefix bool) (bool, string) +// Not all resources have the same validation rules for names. Prefix is true +// if the name will have a value appended to it. If the name is not valid, +// this returns a list of descriptions of individual characteristics of the +// value that were not valid. Otherwise this returns an empty list or nil. +type ValidateNameFunc func(name string, prefix bool) []string // maskTrailingDash replaces the final character of a string with a subdomain safe // value if is a dash. @@ -180,106 +185,77 @@ func maskTrailingDash(name string) string { // ValidatePodName can be used to check whether the given pod name is valid. // Prefix indicates this name will be used as part of generation, in which case // trailing dashes are allowed. -func ValidatePodName(name string, prefix bool) (bool, string) { - return NameIsDNSSubdomain(name, prefix) -} +var ValidatePodName = NameIsDNSSubdomain // ValidateReplicationControllerName can be used to check whether the given replication // controller name is valid. // Prefix indicates this name will be used as part of generation, in which case // trailing dashes are allowed. -func ValidateReplicationControllerName(name string, prefix bool) (bool, string) { - return NameIsDNSSubdomain(name, prefix) -} +var ValidateReplicationControllerName = NameIsDNSSubdomain // ValidateServiceName can be used to check whether the given service name is valid. // Prefix indicates this name will be used as part of generation, in which case // trailing dashes are allowed. -func ValidateServiceName(name string, prefix bool) (bool, string) { - return NameIsDNS952Label(name, prefix) -} +var ValidateServiceName = NameIsDNS952Label // ValidateNodeName can be used to check whether the given node name is valid. // Prefix indicates this name will be used as part of generation, in which case // trailing dashes are allowed. -func ValidateNodeName(name string, prefix bool) (bool, string) { - return NameIsDNSSubdomain(name, prefix) -} +var ValidateNodeName = NameIsDNSSubdomain // ValidateNamespaceName can be used to check whether the given namespace name is valid. // Prefix indicates this name will be used as part of generation, in which case // trailing dashes are allowed. -func ValidateNamespaceName(name string, prefix bool) (bool, string) { - return NameIsDNSLabel(name, prefix) -} +var ValidateNamespaceName = NameIsDNSLabel // ValidateLimitRangeName can be used to check whether the given limit range name is valid. // Prefix indicates this name will be used as part of generation, in which case // trailing dashes are allowed. -func ValidateLimitRangeName(name string, prefix bool) (bool, string) { - return NameIsDNSSubdomain(name, prefix) -} +var ValidateLimitRangeName = NameIsDNSSubdomain // ValidateResourceQuotaName can be used to check whether the given // resource quota name is valid. // Prefix indicates this name will be used as part of generation, in which case // trailing dashes are allowed. -func ValidateResourceQuotaName(name string, prefix bool) (bool, string) { - return NameIsDNSSubdomain(name, prefix) -} +var ValidateResourceQuotaName = NameIsDNSSubdomain // ValidateSecretName can be used to check whether the given secret name is valid. // Prefix indicates this name will be used as part of generation, in which case // trailing dashes are allowed. -func ValidateSecretName(name string, prefix bool) (bool, string) { - return NameIsDNSSubdomain(name, prefix) -} +var ValidateSecretName = NameIsDNSSubdomain // ValidateServiceAccountName can be used to check whether the given service account name is valid. // Prefix indicates this name will be used as part of generation, in which case // trailing dashes are allowed. -func ValidateServiceAccountName(name string, prefix bool) (bool, string) { - return NameIsDNSSubdomain(name, prefix) -} +var ValidateServiceAccountName = NameIsDNSSubdomain // ValidateEndpointsName can be used to check whether the given endpoints name is valid. // Prefix indicates this name will be used as part of generation, in which case // trailing dashes are allowed. -func ValidateEndpointsName(name string, prefix bool) (bool, string) { - return NameIsDNSSubdomain(name, prefix) -} +var ValidateEndpointsName = NameIsDNSSubdomain // NameIsDNSSubdomain is a ValidateNameFunc for names that must be a DNS subdomain. -func NameIsDNSSubdomain(name string, prefix bool) (bool, string) { +func NameIsDNSSubdomain(name string, prefix bool) []string { if prefix { name = maskTrailingDash(name) } - if validation.IsDNS1123Subdomain(name) { - return true, "" - } - return false, DNSSubdomainErrorMsg + return validation.IsDNS1123Subdomain(name) } // NameIsDNSLabel is a ValidateNameFunc for names that must be a DNS 1123 label. -func NameIsDNSLabel(name string, prefix bool) (bool, string) { +func NameIsDNSLabel(name string, prefix bool) []string { if prefix { name = maskTrailingDash(name) } - if validation.IsDNS1123Label(name) { - return true, "" - } - return false, DNS1123LabelErrorMsg + return validation.IsDNS1123Label(name) } // NameIsDNS952Label is a ValidateNameFunc for names that must be a DNS 952 label. -func NameIsDNS952Label(name string, prefix bool) (bool, string) { +func NameIsDNS952Label(name string, prefix bool) []string { if prefix { name = maskTrailingDash(name) } - if validation.IsDNS952Label(name) { - return true, "" - } - return false, DNS952LabelErrorMsg + return validation.IsDNS952Label(name) } // Validates that given value is not negative. @@ -316,8 +292,8 @@ func ValidateObjectMeta(meta *api.ObjectMeta, requiresNamespace bool, nameFn Val allErrs := field.ErrorList{} if len(meta.GenerateName) != 0 { - if ok, qualifier := nameFn(meta.GenerateName, true); !ok { - allErrs = append(allErrs, field.Invalid(fldPath.Child("generateName"), meta.GenerateName, qualifier)) + for _, msg := range nameFn(meta.GenerateName, true) { + allErrs = append(allErrs, field.Invalid(fldPath.Child("generateName"), meta.GenerateName, msg)) } } // If the generated name validates, but the calculated value does not, it's a problem with generation, and we @@ -326,15 +302,17 @@ func ValidateObjectMeta(meta *api.ObjectMeta, requiresNamespace bool, nameFn Val if len(meta.Name) == 0 { allErrs = append(allErrs, field.Required(fldPath.Child("name"), "name or generateName is required")) } else { - if ok, qualifier := nameFn(meta.Name, false); !ok { - allErrs = append(allErrs, field.Invalid(fldPath.Child("name"), meta.Name, qualifier)) + for _, msg := range nameFn(meta.Name, false) { + allErrs = append(allErrs, field.Invalid(fldPath.Child("name"), meta.Name, msg)) } } if requiresNamespace { if len(meta.Namespace) == 0 { allErrs = append(allErrs, field.Required(fldPath.Child("namespace"), "")) - } else if ok, _ := ValidateNamespaceName(meta.Namespace, false); !ok { - allErrs = append(allErrs, field.Invalid(fldPath.Child("namespace"), meta.Namespace, DNS1123LabelErrorMsg)) + } else { + for _, msg := range ValidateNamespaceName(meta.Namespace, false) { + allErrs = append(allErrs, field.Invalid(fldPath.Child("namespace"), meta.Namespace, msg)) + } } } else { if len(meta.Namespace) != 0 { @@ -413,8 +391,10 @@ func validateVolumes(volumes []api.Volume, fldPath *field.Path) (sets.String, fi el := validateVolumeSource(&vol.VolumeSource, idxPath) if len(vol.Name) == 0 { el = append(el, field.Required(idxPath.Child("name"), "")) - } else if !validation.IsDNS1123Label(vol.Name) { - el = append(el, field.Invalid(idxPath.Child("name"), vol.Name, DNS1123LabelErrorMsg)) + } else if msgs := validation.IsDNS1123Label(vol.Name); len(msgs) != 0 { + for i := range msgs { + el = append(el, field.Invalid(idxPath.Child("name"), vol.Name, msgs[i])) + } } else if allNames.Has(vol.Name) { el = append(el, field.Duplicate(idxPath.Child("name"), vol.Name)) } @@ -818,9 +798,9 @@ func validateAzureFile(azure *api.AzureFileVolumeSource, fldPath *field.Path) fi return allErrs } -func ValidatePersistentVolumeName(name string, prefix bool) (bool, string) { - return NameIsDNSSubdomain(name, prefix) -} +// ValidatePersistentVolumeName checks that a name is appropriate for a +// PersistentVolumeName object. +var ValidatePersistentVolumeName = NameIsDNSSubdomain var supportedAccessModes = sets.NewString(string(api.ReadWriteOnce), string(api.ReadOnlyMany), string(api.ReadWriteMany)) @@ -1327,6 +1307,37 @@ func validatePullPolicy(policy api.PullPolicy, fldPath *field.Path) field.ErrorL return allErrors } +func validateInitContainers(containers, otherContainers []api.Container, volumes sets.String, fldPath *field.Path) field.ErrorList { + var allErrs field.ErrorList + if len(containers) > 0 { + allErrs = append(allErrs, validateContainers(containers, volumes, fldPath)...) + } + + allNames := sets.String{} + for _, ctr := range otherContainers { + allNames.Insert(ctr.Name) + } + for i, ctr := range containers { + idxPath := fldPath.Index(i) + if allNames.Has(ctr.Name) { + allErrs = append(allErrs, field.Duplicate(idxPath.Child("name"), ctr.Name)) + } + if len(ctr.Name) > 0 { + allNames.Insert(ctr.Name) + } + if ctr.Lifecycle != nil { + allErrs = append(allErrs, field.Invalid(idxPath.Child("lifecycle"), ctr.Lifecycle, "must not be set for init containers")) + } + if ctr.LivenessProbe != nil { + allErrs = append(allErrs, field.Invalid(idxPath.Child("livenessProbe"), ctr.LivenessProbe, "must not be set for init containers")) + } + if ctr.ReadinessProbe != nil { + allErrs = append(allErrs, field.Invalid(idxPath.Child("readinessProbe"), ctr.ReadinessProbe, "must not be set for init containers")) + } + } + return allErrs +} + func validateContainers(containers []api.Container, volumes sets.String, fldPath *field.Path) field.ErrorList { allErrs := field.ErrorList{} @@ -1339,8 +1350,10 @@ func validateContainers(containers []api.Container, volumes sets.String, fldPath idxPath := fldPath.Index(i) if len(ctr.Name) == 0 { allErrs = append(allErrs, field.Required(idxPath.Child("name"), "")) - } else if !validation.IsDNS1123Label(ctr.Name) { - allErrs = append(allErrs, field.Invalid(idxPath.Child("name"), ctr.Name, DNS1123LabelErrorMsg)) + } else if msgs := validation.IsDNS1123Label(ctr.Name); len(msgs) != 0 { + for i := range msgs { + allErrs = append(allErrs, field.Invalid(idxPath.Child("name"), ctr.Name, msgs[i])) + } } else if allNames.Has(ctr.Name) { allErrs = append(allErrs, field.Duplicate(idxPath.Child("name"), ctr.Name)) } else { @@ -1433,6 +1446,60 @@ func validateImagePullSecrets(imagePullSecrets []api.LocalObjectReference, fldPa return allErrors } +func validateTaintEffect(effect *api.TaintEffect, allowEmpty bool, fldPath *field.Path) field.ErrorList { + if !allowEmpty && len(*effect) == 0 { + return field.ErrorList{field.Required(fldPath, "")} + } + + allErrors := field.ErrorList{} + switch *effect { + // TODO: Replace next line with subsequent commented-out line when implement TaintEffectNoScheduleNoAdmit, TaintEffectNoScheduleNoAdmitNoExecute. + case api.TaintEffectNoSchedule, api.TaintEffectPreferNoSchedule: + // case api.TaintEffectNoSchedule, api.TaintEffectPreferNoSchedule, api.TaintEffectNoScheduleNoAdmit, api.TaintEffectNoScheduleNoAdmitNoExecute: + default: + validValues := []string{ + string(api.TaintEffectNoSchedule), + string(api.TaintEffectPreferNoSchedule), + // TODO: Uncomment this block when implement TaintEffectNoScheduleNoAdmit, TaintEffectNoScheduleNoAdmitNoExecute. + // string(api.TaintEffectNoScheduleNoAdmit), + // string(api.TaintEffectNoScheduleNoAdmitNoExecute), + } + allErrors = append(allErrors, field.NotSupported(fldPath, effect, validValues)) + } + return allErrors +} + +// validateTolerations tests if given tolerations have valid data. +func validateTolerations(tolerations []api.Toleration, fldPath *field.Path) field.ErrorList { + allErrors := field.ErrorList{} + for i, toleration := range tolerations { + idxPath := fldPath.Index(i) + // validate the toleration key + allErrors = append(allErrors, unversionedvalidation.ValidateLabelName(toleration.Key, idxPath.Child("key"))...) + + // validate toleration operator and value + switch toleration.Operator { + case api.TolerationOpEqual, "": + if errs := validation.IsValidLabelValue(toleration.Value); len(errs) != 0 { + allErrors = append(allErrors, field.Invalid(idxPath.Child("operator"), toleration.Value, strings.Join(errs, ";"))) + } + case api.TolerationOpExists: + if len(toleration.Value) > 0 { + allErrors = append(allErrors, field.Invalid(idxPath.Child("operator"), toleration, "value must be empty when `operator` is 'Exists'")) + } + default: + validValues := []string{string(api.TolerationOpEqual), string(api.TolerationOpExists)} + allErrors = append(allErrors, field.NotSupported(idxPath.Child("operator"), toleration.Operator, validValues)) + } + + // validate toleration effect + if len(toleration.Effect) > 0 { + allErrors = append(allErrors, validateTaintEffect(&toleration.Effect, true, idxPath.Child("effect"))...) + } + } + return allErrors +} + // ValidatePod tests if required fields in the pod are set. func ValidatePod(pod *api.Pod) field.ErrorList { fldPath := field.NewPath("metadata") @@ -1452,19 +1519,20 @@ func ValidatePodSpec(spec *api.PodSpec, fldPath *field.Path) field.ErrorList { allVolumes, vErrs := validateVolumes(spec.Volumes, fldPath.Child("volumes")) allErrs = append(allErrs, vErrs...) allErrs = append(allErrs, validateContainers(spec.Containers, allVolumes, fldPath.Child("containers"))...) + allErrs = append(allErrs, validateInitContainers(spec.InitContainers, spec.Containers, allVolumes, fldPath.Child("initContainers"))...) allErrs = append(allErrs, validateRestartPolicy(&spec.RestartPolicy, fldPath.Child("restartPolicy"))...) allErrs = append(allErrs, validateDNSPolicy(&spec.DNSPolicy, fldPath.Child("dnsPolicy"))...) allErrs = append(allErrs, unversionedvalidation.ValidateLabels(spec.NodeSelector, fldPath.Child("nodeSelector"))...) allErrs = append(allErrs, ValidatePodSecurityContext(spec.SecurityContext, spec, fldPath, fldPath.Child("securityContext"))...) allErrs = append(allErrs, validateImagePullSecrets(spec.ImagePullSecrets, fldPath.Child("imagePullSecrets"))...) if len(spec.ServiceAccountName) > 0 { - if ok, msg := ValidateServiceAccountName(spec.ServiceAccountName, false); !ok { + for _, msg := range ValidateServiceAccountName(spec.ServiceAccountName, false) { allErrs = append(allErrs, field.Invalid(fldPath.Child("serviceAccountName"), spec.ServiceAccountName, msg)) } } if len(spec.NodeName) > 0 { - if ok, msg := ValidateNodeName(spec.NodeName, false); !ok { + for _, msg := range ValidateNodeName(spec.NodeName, false) { allErrs = append(allErrs, field.Invalid(fldPath.Child("nodeName"), spec.NodeName, msg)) } } @@ -1475,12 +1543,16 @@ func ValidatePodSpec(spec *api.PodSpec, fldPath *field.Path) field.ErrorList { } } - if len(spec.Hostname) > 0 && !validation.IsDNS1123Label(spec.Hostname) { - allErrs = append(allErrs, field.Invalid(fldPath.Child("hostname"), spec.Hostname, DNS1123LabelErrorMsg)) + if len(spec.Hostname) > 0 { + for _, msg := range validation.IsDNS1123Label(spec.Hostname) { + allErrs = append(allErrs, field.Invalid(fldPath.Child("hostname"), spec.Hostname, msg)) + } } - if len(spec.Subdomain) > 0 && !validation.IsDNS1123Label(spec.Subdomain) { - allErrs = append(allErrs, field.Invalid(fldPath.Child("subdomain"), spec.Subdomain, DNS1123LabelErrorMsg)) + if len(spec.Subdomain) > 0 { + for _, msg := range validation.IsDNS1123Label(spec.Subdomain) { + allErrs = append(allErrs, field.Invalid(fldPath.Child("subdomain"), spec.Subdomain, msg)) + } } return allErrs @@ -1558,8 +1630,8 @@ func validatePodAffinityTerm(podAffinityTerm api.PodAffinityTerm, allowEmptyTopo allErrs := field.ErrorList{} allErrs = append(allErrs, unversionedvalidation.ValidateLabelSelector(podAffinityTerm.LabelSelector, fldPath.Child("matchExpressions"))...) for _, name := range podAffinityTerm.Namespaces { - if ok, _ := ValidateNamespaceName(name, false); !ok { - allErrs = append(allErrs, field.Invalid(fldPath.Child("namespace"), name, DNS1123LabelErrorMsg)) + for _, msg := range ValidateNamespaceName(name, false) { + allErrs = append(allErrs, field.Invalid(fldPath.Child("namespace"), name, msg)) } } if !allowEmptyTopologyKey && len(podAffinityTerm.TopologyKey) == 0 { @@ -1671,6 +1743,22 @@ func ValidateAffinityInPodAnnotations(annotations map[string]string, fldPath *fi return allErrs } +// ValidateTolerationsInPodAnnotations tests that the serialized tolerations in Pod.Annotations has valid data +func ValidateTolerationsInPodAnnotations(annotations map[string]string, fldPath *field.Path) field.ErrorList { + allErrs := field.ErrorList{} + + tolerations, err := api.GetTolerationsFromPodAnnotations(annotations) + if err != nil { + allErrs = append(allErrs, field.Invalid(fldPath, api.TolerationsAnnotationKey, err.Error())) + return allErrs + } + if len(tolerations) > 0 { + allErrs = append(allErrs, validateTolerations(tolerations, fldPath.Child(api.TolerationsAnnotationKey))...) + } + + return allErrs +} + // ValidatePodSecurityContext test that the specified PodSecurityContext has valid data. func ValidatePodSecurityContext(securityContext *api.PodSecurityContext, spec *api.PodSpec, specPath, fldPath *field.Path) field.ErrorList { allErrs := field.ErrorList{} @@ -1932,8 +2020,10 @@ func validateServicePort(sp *api.ServicePort, requireName, isHeadlessService boo if requireName && len(sp.Name) == 0 { allErrs = append(allErrs, field.Required(fldPath.Child("name"), "")) } else if len(sp.Name) != 0 { - if !validation.IsDNS1123Label(sp.Name) { - allErrs = append(allErrs, field.Invalid(fldPath.Child("name"), sp.Name, DNS1123LabelErrorMsg)) + if msgs := validation.IsDNS1123Label(sp.Name); len(msgs) != 0 { + for i := range msgs { + allErrs = append(allErrs, field.Invalid(fldPath.Child("name"), sp.Name, msgs[i])) + } } else if allNames.Has(sp.Name) { allErrs = append(allErrs, field.Duplicate(fldPath.Child("name"), sp.Name)) } else { @@ -2083,9 +2173,51 @@ func ValidateReadOnlyPersistentDisks(volumes []api.Volume, fldPath *field.Path) return allErrs } +// validateTaints tests if given taints have valid data. +func validateTaints(taints []api.Taint, fldPath *field.Path) field.ErrorList { + allErrors := field.ErrorList{} + for i, currTaint := range taints { + idxPath := fldPath.Index(i) + // validate the taint key + allErrors = append(allErrors, unversionedvalidation.ValidateLabelName(currTaint.Key, idxPath.Child("key"))...) + // validate the taint value + if errs := validation.IsValidLabelValue(currTaint.Value); len(errs) != 0 { + allErrors = append(allErrors, field.Invalid(idxPath.Child("value"), currTaint.Value, strings.Join(errs, ";"))) + } + // validate the taint effect + allErrors = append(allErrors, validateTaintEffect(&currTaint.Effect, false, idxPath.Child("effect"))...) + } + return allErrors +} + +// ValidateTaintsInNodeAnnotations tests that the serialized taints in Node.Annotations has valid data +func ValidateTaintsInNodeAnnotations(annotations map[string]string, fldPath *field.Path) field.ErrorList { + allErrs := field.ErrorList{} + + taints, err := api.GetTaintsFromNodeAnnotations(annotations) + if err != nil { + allErrs = append(allErrs, field.Invalid(fldPath, api.TaintsAnnotationKey, err.Error())) + return allErrs + } + if len(taints) > 0 { + allErrs = append(allErrs, validateTaints(taints, fldPath.Child(api.TaintsAnnotationKey))...) + } + + return allErrs +} + +func ValidateNodeSpecificAnnotations(annotations map[string]string, fldPath *field.Path) field.ErrorList { + if annotations[api.TaintsAnnotationKey] != "" { + return ValidateTaintsInNodeAnnotations(annotations, fldPath) + } + return field.ErrorList{} +} + // ValidateNode tests if required fields in the node are set. func ValidateNode(node *api.Node) field.ErrorList { - allErrs := ValidateObjectMeta(&node.ObjectMeta, false, ValidateNodeName, field.NewPath("metadata")) + fldPath := field.NewPath("metadata") + allErrs := ValidateObjectMeta(&node.ObjectMeta, false, ValidateNodeName, fldPath) + allErrs = append(allErrs, ValidateNodeSpecificAnnotations(node.ObjectMeta.Annotations, fldPath.Child("annotations"))...) // Only validate spec. All status fields are optional and can be updated later. @@ -2100,7 +2232,9 @@ func ValidateNode(node *api.Node) field.ErrorList { // ValidateNodeUpdate tests to make sure a node update can be applied. Modifies oldNode. func ValidateNodeUpdate(node, oldNode *api.Node) field.ErrorList { - allErrs := ValidateObjectMetaUpdate(&node.ObjectMeta, &oldNode.ObjectMeta, field.NewPath("metadata")) + fldPath := field.NewPath("metadata") + allErrs := ValidateObjectMetaUpdate(&node.ObjectMeta, &oldNode.ObjectMeta, fldPath) + allErrs = append(allErrs, ValidateNodeSpecificAnnotations(node.ObjectMeta.Annotations, fldPath.Child("annotations"))...) // TODO: Enable the code once we have better api object.status update model. Currently, // anyone can update node status. @@ -2148,8 +2282,11 @@ func ValidateNodeUpdate(node, oldNode *api.Node) field.ErrorList { // Refer to docs/design/resources.md for more details. func validateResourceName(value string, fldPath *field.Path) field.ErrorList { allErrs := field.ErrorList{} - if !validation.IsQualifiedName(value) { - return append(allErrs, field.Invalid(fldPath, value, qualifiedNameErrorMsg)) + for _, msg := range validation.IsQualifiedName(value) { + allErrs = append(allErrs, field.Invalid(fldPath, value, msg)) + } + if len(allErrs) != 0 { + return allErrs } if len(strings.Split(value, "/")) == 1 { @@ -2188,8 +2325,11 @@ func validateResourceQuotaResourceName(value string, fldPath *field.Path) field. // Validate limit range types func validateLimitRangeTypeName(value string, fldPath *field.Path) field.ErrorList { allErrs := field.ErrorList{} - if !validation.IsQualifiedName(value) { - return append(allErrs, field.Invalid(fldPath, value, qualifiedNameErrorMsg)) + for _, msg := range validation.IsQualifiedName(value) { + allErrs = append(allErrs, field.Invalid(fldPath, value, msg)) + } + if len(allErrs) != 0 { + return allErrs } if len(strings.Split(value, "/")) == 1 { @@ -2445,9 +2585,7 @@ func ValidateSecretUpdate(newSecret, oldSecret *api.Secret) field.ErrorList { // ValidateConfigMapName can be used to check whether the given ConfigMap name is valid. // Prefix indicates this name will be used as part of generation, in which case // trailing dashes are allowed. -func ValidateConfigMapName(name string, prefix bool) (bool, string) { - return NameIsDNSSubdomain(name, prefix) -} +var ValidateConfigMapName = NameIsDNSSubdomain // ValidateConfigMap tests whether required fields in the ConfigMap are set. func ValidateConfigMap(cfg *api.ConfigMap) field.ErrorList { @@ -2659,8 +2797,11 @@ func ValidateNamespace(namespace *api.Namespace) field.ErrorList { // Validate finalizer names func validateFinalizerName(stringValue string, fldPath *field.Path) field.ErrorList { allErrs := field.ErrorList{} - if !validation.IsQualifiedName(stringValue) { - return append(allErrs, field.Invalid(fldPath, stringValue, qualifiedNameErrorMsg)) + for _, msg := range validation.IsQualifiedName(stringValue) { + allErrs = append(allErrs, field.Invalid(fldPath, stringValue, msg)) + } + if len(allErrs) != 0 { + return allErrs } if len(strings.Split(stringValue, "/")) == 1 { @@ -2753,8 +2894,10 @@ func validateEndpointAddress(address *api.EndpointAddress, fldPath *field.Path) if !validation.IsValidIP(address.IP) { allErrs = append(allErrs, field.Invalid(fldPath.Child("ip"), address.IP, "must be a valid IP address")) } - if len(address.Hostname) > 0 && !validation.IsDNS1123Label(address.Hostname) { - allErrs = append(allErrs, field.Invalid(fldPath.Child("hostname"), address.Hostname, DNS1123LabelErrorMsg)) + if len(address.Hostname) > 0 { + for _, msg := range validation.IsDNS1123Label(address.Hostname) { + allErrs = append(allErrs, field.Invalid(fldPath.Child("hostname"), address.Hostname, msg)) + } } if len(allErrs) > 0 { return allErrs @@ -2788,8 +2931,8 @@ func validateEndpointPort(port *api.EndpointPort, requireName bool, fldPath *fie if requireName && len(port.Name) == 0 { allErrs = append(allErrs, field.Required(fldPath.Child("name"), "")) } else if len(port.Name) != 0 { - if !validation.IsDNS1123Label(port.Name) { - allErrs = append(allErrs, field.Invalid(fldPath.Child("name"), port.Name, DNS1123LabelErrorMsg)) + for _, msg := range validation.IsDNS1123Label(port.Name) { + allErrs = append(allErrs, field.Invalid(fldPath.Child("name"), port.Name, msg)) } } if !validation.IsValidPortNum(int(port.Port)) { @@ -2863,8 +3006,8 @@ func ValidateLoadBalancerStatus(status *api.LoadBalancerStatus, fldPath *field.P } } if len(ingress.Hostname) > 0 { - if valid, errMsg := NameIsDNSSubdomain(ingress.Hostname, false); !valid { - allErrs = append(allErrs, field.Invalid(idxPath.Child("hostname"), ingress.Hostname, errMsg)) + for _, msg := range validation.IsDNS1123Subdomain(ingress.Hostname) { + allErrs = append(allErrs, field.Invalid(idxPath.Child("hostname"), ingress.Hostname, msg)) } if isIP := (net.ParseIP(ingress.Hostname) != nil); isIP { allErrs = append(allErrs, field.Invalid(idxPath.Child("hostname"), ingress.Hostname, "must be a DNS name, not an IP address")) @@ -2885,7 +3028,7 @@ func isValidHostnamesMap(serializedPodHostNames string) bool { } for ip, hostRecord := range podHostNames { - if !validation.IsDNS1123Label(hostRecord.HostName) { + if len(validation.IsDNS1123Label(hostRecord.HostName)) != 0 { return false } if net.ParseIP(ip) == nil { diff --git a/vendor/k8s.io/kubernetes/pkg/apis/apps/types.generated.go b/vendor/k8s.io/kubernetes/pkg/apis/apps/types.generated.go index 79bdd06979..9903f8e135 100644 --- a/vendor/k8s.io/kubernetes/pkg/apis/apps/types.generated.go +++ b/vendor/k8s.io/kubernetes/pkg/apis/apps/types.generated.go @@ -1,5 +1,5 @@ /* -Copyright 2015 The Kubernetes Authors All rights reserved. +Copyright 2016 The Kubernetes Authors All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -25,12 +25,11 @@ import ( "errors" "fmt" codec1978 "github.com/ugorji/go/codec" - pkg5_inf_v0 "gopkg.in/inf.v0" pkg2_api "k8s.io/kubernetes/pkg/api" pkg4_resource "k8s.io/kubernetes/pkg/api/resource" pkg1_unversioned "k8s.io/kubernetes/pkg/api/unversioned" pkg3_types "k8s.io/kubernetes/pkg/types" - pkg6_intstr "k8s.io/kubernetes/pkg/util/intstr" + pkg5_intstr "k8s.io/kubernetes/pkg/util/intstr" "reflect" "runtime" time "time" @@ -66,14 +65,13 @@ func init() { panic(err) } if false { // reference the types, but skip this branch at build/run time - var v0 pkg5_inf_v0.Dec - var v1 pkg2_api.ObjectMeta - var v2 pkg4_resource.Quantity - var v3 pkg1_unversioned.TypeMeta - var v4 pkg3_types.UID - var v5 pkg6_intstr.IntOrString - var v6 time.Time - _, _, _, _, _, _, _ = v0, v1, v2, v3, v4, v5, v6 + var v0 pkg2_api.ObjectMeta + var v1 pkg4_resource.Quantity + var v2 pkg1_unversioned.TypeMeta + var v3 pkg3_types.UID + var v4 pkg5_intstr.IntOrString + var v5 time.Time + _, _, _, _, _, _ = v0, v1, v2, v3, v4, v5 } } @@ -1555,7 +1553,7 @@ func (x codecSelfer1234) decSlicePetSet(v *[]PetSet, d *codec1978.Decoder) { yyrg1 := len(yyv1) > 0 yyv21 := yyv1 - yyrl1, yyrt1 = z.DecInferLen(yyl1, z.DecBasicHandle().MaxInitLen, 720) + yyrl1, yyrt1 = z.DecInferLen(yyl1, z.DecBasicHandle().MaxInitLen, 744) if yyrt1 { if yyrl1 <= cap(yyv1) { yyv1 = yyv1[:yyrl1] diff --git a/vendor/k8s.io/kubernetes/pkg/apis/apps/v1alpha1/types.generated.go b/vendor/k8s.io/kubernetes/pkg/apis/apps/v1alpha1/types.generated.go index d817967761..a548f53133 100644 --- a/vendor/k8s.io/kubernetes/pkg/apis/apps/v1alpha1/types.generated.go +++ b/vendor/k8s.io/kubernetes/pkg/apis/apps/v1alpha1/types.generated.go @@ -1,5 +1,5 @@ /* -Copyright 2015 The Kubernetes Authors All rights reserved. +Copyright 2016 The Kubernetes Authors All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -25,12 +25,11 @@ import ( "errors" "fmt" codec1978 "github.com/ugorji/go/codec" - pkg5_inf_v0 "gopkg.in/inf.v0" pkg4_resource "k8s.io/kubernetes/pkg/api/resource" pkg1_unversioned "k8s.io/kubernetes/pkg/api/unversioned" pkg2_v1 "k8s.io/kubernetes/pkg/api/v1" pkg3_types "k8s.io/kubernetes/pkg/types" - pkg6_intstr "k8s.io/kubernetes/pkg/util/intstr" + pkg5_intstr "k8s.io/kubernetes/pkg/util/intstr" "reflect" "runtime" time "time" @@ -66,14 +65,13 @@ func init() { panic(err) } if false { // reference the types, but skip this branch at build/run time - var v0 pkg5_inf_v0.Dec - var v1 pkg4_resource.Quantity - var v2 pkg1_unversioned.TypeMeta - var v3 pkg2_v1.ObjectMeta - var v4 pkg3_types.UID - var v5 pkg6_intstr.IntOrString - var v6 time.Time - _, _, _, _, _, _, _ = v0, v1, v2, v3, v4, v5, v6 + var v0 pkg4_resource.Quantity + var v1 pkg1_unversioned.TypeMeta + var v2 pkg2_v1.ObjectMeta + var v3 pkg3_types.UID + var v4 pkg5_intstr.IntOrString + var v5 time.Time + _, _, _, _, _, _ = v0, v1, v2, v3, v4, v5 } } @@ -1585,7 +1583,7 @@ func (x codecSelfer1234) decSlicePetSet(v *[]PetSet, d *codec1978.Decoder) { yyrg1 := len(yyv1) > 0 yyv21 := yyv1 - yyrl1, yyrt1 = z.DecInferLen(yyl1, z.DecBasicHandle().MaxInitLen, 744) + yyrl1, yyrt1 = z.DecInferLen(yyl1, z.DecBasicHandle().MaxInitLen, 768) if yyrt1 { if yyrl1 <= cap(yyv1) { yyv1 = yyv1[:yyrl1] diff --git a/vendor/k8s.io/kubernetes/pkg/apis/apps/v1alpha1/types_swagger_doc_generated.go b/vendor/k8s.io/kubernetes/pkg/apis/apps/v1alpha1/types_swagger_doc_generated.go index 04b340c54b..6306b48123 100644 --- a/vendor/k8s.io/kubernetes/pkg/apis/apps/v1alpha1/types_swagger_doc_generated.go +++ b/vendor/k8s.io/kubernetes/pkg/apis/apps/v1alpha1/types_swagger_doc_generated.go @@ -1,5 +1,5 @@ /* -Copyright 2015 The Kubernetes Authors All rights reserved. +Copyright 2016 The Kubernetes Authors All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/vendor/k8s.io/kubernetes/pkg/apis/apps/validation/validation.go b/vendor/k8s.io/kubernetes/pkg/apis/apps/validation/validation.go index ce83ef8c52..acbdfedfe1 100644 --- a/vendor/k8s.io/kubernetes/pkg/apis/apps/validation/validation.go +++ b/vendor/k8s.io/kubernetes/pkg/apis/apps/validation/validation.go @@ -28,11 +28,10 @@ import ( "k8s.io/kubernetes/pkg/util/validation/field" ) -// ValidatePetSetName can be used to check whether the given PetSet -// name is valid. +// ValidatePetSetName can be used to check whether the given PetSet name is valid. // Prefix indicates this name will be used as part of generation, in which case // trailing dashes are allowed. -func ValidatePetSetName(name string, prefix bool) (bool, string) { +func ValidatePetSetName(name string, prefix bool) []string { // TODO: Validate that there's name for the suffix inserted by the pets. // Currently this is just "-index". In the future we may allow a user // specified list of suffixes and we need to validate the longest one. diff --git a/vendor/k8s.io/kubernetes/pkg/apis/authentication.k8s.io/types.generated.go b/vendor/k8s.io/kubernetes/pkg/apis/authentication.k8s.io/types.generated.go index cb46e80132..b3b72d653b 100644 --- a/vendor/k8s.io/kubernetes/pkg/apis/authentication.k8s.io/types.generated.go +++ b/vendor/k8s.io/kubernetes/pkg/apis/authentication.k8s.io/types.generated.go @@ -1,5 +1,5 @@ /* -Copyright 2015 The Kubernetes Authors All rights reserved. +Copyright 2016 The Kubernetes Authors All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/vendor/k8s.io/kubernetes/pkg/apis/authentication.k8s.io/v1beta1/types.generated.go b/vendor/k8s.io/kubernetes/pkg/apis/authentication.k8s.io/v1beta1/types.generated.go index 76f48c81ca..62d287ff57 100644 --- a/vendor/k8s.io/kubernetes/pkg/apis/authentication.k8s.io/v1beta1/types.generated.go +++ b/vendor/k8s.io/kubernetes/pkg/apis/authentication.k8s.io/v1beta1/types.generated.go @@ -1,5 +1,5 @@ /* -Copyright 2015 The Kubernetes Authors All rights reserved. +Copyright 2016 The Kubernetes Authors All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/vendor/k8s.io/kubernetes/pkg/apis/authentication.k8s.io/v1beta1/types.go b/vendor/k8s.io/kubernetes/pkg/apis/authentication.k8s.io/v1beta1/types.go index 7513541f6a..fc136877a9 100644 --- a/vendor/k8s.io/kubernetes/pkg/apis/authentication.k8s.io/v1beta1/types.go +++ b/vendor/k8s.io/kubernetes/pkg/apis/authentication.k8s.io/v1beta1/types.go @@ -21,6 +21,8 @@ import ( ) // TokenReview attempts to authenticate a token to a known user. +// Note: TokenReview requests may be cached by the webhook token authenticator +// plugin in the kube-apiserver. type TokenReview struct { unversioned.TypeMeta `json:",inline"` diff --git a/vendor/k8s.io/kubernetes/pkg/apis/authorization/types.generated.go b/vendor/k8s.io/kubernetes/pkg/apis/authorization/types.generated.go index e4f92c8c5b..1c071376ca 100644 --- a/vendor/k8s.io/kubernetes/pkg/apis/authorization/types.generated.go +++ b/vendor/k8s.io/kubernetes/pkg/apis/authorization/types.generated.go @@ -1,5 +1,5 @@ /* -Copyright 2015 The Kubernetes Authors All rights reserved. +Copyright 2016 The Kubernetes Authors All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/vendor/k8s.io/kubernetes/pkg/apis/authorization/v1beta1/types.generated.go b/vendor/k8s.io/kubernetes/pkg/apis/authorization/v1beta1/types.generated.go index 7a0175ac96..3b5e4fbe93 100644 --- a/vendor/k8s.io/kubernetes/pkg/apis/authorization/v1beta1/types.generated.go +++ b/vendor/k8s.io/kubernetes/pkg/apis/authorization/v1beta1/types.generated.go @@ -1,5 +1,5 @@ /* -Copyright 2015 The Kubernetes Authors All rights reserved. +Copyright 2016 The Kubernetes Authors All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/vendor/k8s.io/kubernetes/pkg/apis/authorization/v1beta1/types_swagger_doc_generated.go b/vendor/k8s.io/kubernetes/pkg/apis/authorization/v1beta1/types_swagger_doc_generated.go index 9807b8fcdd..d4c337db79 100644 --- a/vendor/k8s.io/kubernetes/pkg/apis/authorization/v1beta1/types_swagger_doc_generated.go +++ b/vendor/k8s.io/kubernetes/pkg/apis/authorization/v1beta1/types_swagger_doc_generated.go @@ -1,5 +1,5 @@ /* -Copyright 2015 The Kubernetes Authors All rights reserved. +Copyright 2016 The Kubernetes Authors All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/vendor/k8s.io/kubernetes/pkg/apis/autoscaling/types.generated.go b/vendor/k8s.io/kubernetes/pkg/apis/autoscaling/types.generated.go index c62c8ea41a..fdd0591900 100644 --- a/vendor/k8s.io/kubernetes/pkg/apis/autoscaling/types.generated.go +++ b/vendor/k8s.io/kubernetes/pkg/apis/autoscaling/types.generated.go @@ -1,5 +1,5 @@ /* -Copyright 2015 The Kubernetes Authors All rights reserved. +Copyright 2016 The Kubernetes Authors All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/vendor/k8s.io/kubernetes/pkg/apis/autoscaling/v1/types.generated.go b/vendor/k8s.io/kubernetes/pkg/apis/autoscaling/v1/types.generated.go index 29cc66ebcc..d8401bb8bc 100644 --- a/vendor/k8s.io/kubernetes/pkg/apis/autoscaling/v1/types.generated.go +++ b/vendor/k8s.io/kubernetes/pkg/apis/autoscaling/v1/types.generated.go @@ -1,5 +1,5 @@ /* -Copyright 2015 The Kubernetes Authors All rights reserved. +Copyright 2016 The Kubernetes Authors All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/vendor/k8s.io/kubernetes/pkg/apis/autoscaling/v1/types_swagger_doc_generated.go b/vendor/k8s.io/kubernetes/pkg/apis/autoscaling/v1/types_swagger_doc_generated.go index 56ed2baccc..6e63745709 100644 --- a/vendor/k8s.io/kubernetes/pkg/apis/autoscaling/v1/types_swagger_doc_generated.go +++ b/vendor/k8s.io/kubernetes/pkg/apis/autoscaling/v1/types_swagger_doc_generated.go @@ -1,5 +1,5 @@ /* -Copyright 2015 The Kubernetes Authors All rights reserved. +Copyright 2016 The Kubernetes Authors All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/vendor/k8s.io/kubernetes/pkg/apis/autoscaling/validation/validation.go b/vendor/k8s.io/kubernetes/pkg/apis/autoscaling/validation/validation.go index fee1119616..3432e3cb1c 100644 --- a/vendor/k8s.io/kubernetes/pkg/apis/autoscaling/validation/validation.go +++ b/vendor/k8s.io/kubernetes/pkg/apis/autoscaling/validation/validation.go @@ -39,10 +39,7 @@ func ValidateScale(scale *autoscaling.Scale) field.ErrorList { // ValidateHorizontalPodAutoscaler can be used to check whether the given autoscaler name is valid. // Prefix indicates this name will be used as part of generation, in which case trailing dashes are allowed. -func ValidateHorizontalPodAutoscalerName(name string, prefix bool) (bool, string) { - // TODO: finally move it to pkg/api/validation and use nameIsDNSSubdomain function - return apivalidation.ValidateReplicationControllerName(name, prefix) -} +var ValidateHorizontalPodAutoscalerName = apivalidation.ValidateReplicationControllerName func validateHorizontalPodAutoscalerSpec(autoscaler autoscaling.HorizontalPodAutoscalerSpec, fldPath *field.Path) field.ErrorList { allErrs := field.ErrorList{} @@ -68,14 +65,18 @@ func ValidateCrossVersionObjectReference(ref autoscaling.CrossVersionObjectRefer allErrs := field.ErrorList{} if len(ref.Kind) == 0 { allErrs = append(allErrs, field.Required(fldPath.Child("kind"), "")) - } else if ok, msg := apivalidation.IsValidPathSegmentName(ref.Kind); !ok { - allErrs = append(allErrs, field.Invalid(fldPath.Child("kind"), ref.Kind, msg)) + } else { + for _, msg := range apivalidation.IsValidPathSegmentName(ref.Kind) { + allErrs = append(allErrs, field.Invalid(fldPath.Child("kind"), ref.Kind, msg)) + } } if len(ref.Name) == 0 { allErrs = append(allErrs, field.Required(fldPath.Child("name"), "")) - } else if ok, msg := apivalidation.IsValidPathSegmentName(ref.Name); !ok { - allErrs = append(allErrs, field.Invalid(fldPath.Child("name"), ref.Name, msg)) + } else { + for _, msg := range apivalidation.IsValidPathSegmentName(ref.Name) { + allErrs = append(allErrs, field.Invalid(fldPath.Child("name"), ref.Name, msg)) + } } return allErrs diff --git a/vendor/k8s.io/kubernetes/pkg/apis/batch/register.go b/vendor/k8s.io/kubernetes/pkg/apis/batch/register.go index a3dc9b4de9..8406f9ffba 100644 --- a/vendor/k8s.io/kubernetes/pkg/apis/batch/register.go +++ b/vendor/k8s.io/kubernetes/pkg/apis/batch/register.go @@ -49,10 +49,14 @@ func addKnownTypes(scheme *runtime.Scheme) { &Job{}, &JobList{}, &JobTemplate{}, + &ScheduledJob{}, + &ScheduledJobList{}, &api.ListOptions{}, ) } -func (obj *Job) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta } -func (obj *JobList) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta } -func (obj *JobTemplate) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta } +func (obj *Job) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta } +func (obj *JobList) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta } +func (obj *JobTemplate) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta } +func (obj *ScheduledJob) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta } +func (obj *ScheduledJobList) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta } diff --git a/vendor/k8s.io/kubernetes/pkg/apis/batch/types.generated.go b/vendor/k8s.io/kubernetes/pkg/apis/batch/types.generated.go index fb31594407..68605cc67a 100644 --- a/vendor/k8s.io/kubernetes/pkg/apis/batch/types.generated.go +++ b/vendor/k8s.io/kubernetes/pkg/apis/batch/types.generated.go @@ -1,5 +1,5 @@ /* -Copyright 2015 The Kubernetes Authors All rights reserved. +Copyright 2016 The Kubernetes Authors All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -25,12 +25,11 @@ import ( "errors" "fmt" codec1978 "github.com/ugorji/go/codec" - pkg5_inf_v0 "gopkg.in/inf.v0" pkg2_api "k8s.io/kubernetes/pkg/api" pkg4_resource "k8s.io/kubernetes/pkg/api/resource" pkg1_unversioned "k8s.io/kubernetes/pkg/api/unversioned" pkg3_types "k8s.io/kubernetes/pkg/types" - pkg6_intstr "k8s.io/kubernetes/pkg/util/intstr" + pkg5_intstr "k8s.io/kubernetes/pkg/util/intstr" "reflect" "runtime" time "time" @@ -66,14 +65,13 @@ func init() { panic(err) } if false { // reference the types, but skip this branch at build/run time - var v0 pkg5_inf_v0.Dec - var v1 pkg2_api.ObjectMeta - var v2 pkg4_resource.Quantity - var v3 pkg1_unversioned.TypeMeta - var v4 pkg3_types.UID - var v5 pkg6_intstr.IntOrString - var v6 time.Time - _, _, _, _, _, _, _ = v0, v1, v2, v3, v4, v5, v6 + var v0 pkg2_api.ObjectMeta + var v1 pkg4_resource.Quantity + var v2 pkg1_unversioned.TypeMeta + var v3 pkg3_types.UID + var v4 pkg5_intstr.IntOrString + var v5 time.Time + _, _, _, _, _, _ = v0, v1, v2, v3, v4, v5 } } @@ -4205,7 +4203,7 @@ func (x codecSelfer1234) decSliceJob(v *[]Job, d *codec1978.Decoder) { yyrg1 := len(yyv1) > 0 yyv21 := yyv1 - yyrl1, yyrt1 = z.DecInferLen(yyl1, z.DecBasicHandle().MaxInitLen, 744) + yyrl1, yyrt1 = z.DecInferLen(yyl1, z.DecBasicHandle().MaxInitLen, 768) if yyrt1 { if yyrl1 <= cap(yyv1) { yyv1 = yyv1[:yyrl1] @@ -4443,7 +4441,7 @@ func (x codecSelfer1234) decSliceScheduledJob(v *[]ScheduledJob, d *codec1978.De yyrg1 := len(yyv1) > 0 yyv21 := yyv1 - yyrl1, yyrt1 = z.DecInferLen(yyl1, z.DecBasicHandle().MaxInitLen, 976) + yyrl1, yyrt1 = z.DecInferLen(yyl1, z.DecBasicHandle().MaxInitLen, 1000) if yyrt1 { if yyrl1 <= cap(yyv1) { yyv1 = yyv1[:yyrl1] diff --git a/vendor/k8s.io/kubernetes/pkg/apis/batch/types.go b/vendor/k8s.io/kubernetes/pkg/apis/batch/types.go index 4e9e6b6230..756d4c9d6b 100644 --- a/vendor/k8s.io/kubernetes/pkg/apis/batch/types.go +++ b/vendor/k8s.io/kubernetes/pkg/apis/batch/types.go @@ -165,6 +165,8 @@ type JobCondition struct { Message string `json:"message,omitempty"` } +// +genclient=true + // ScheduledJob represents the configuration of a single scheduled job. type ScheduledJob struct { unversioned.TypeMeta `json:",inline"` diff --git a/vendor/k8s.io/kubernetes/pkg/apis/batch/v1/conversion_generated.go b/vendor/k8s.io/kubernetes/pkg/apis/batch/v1/conversion_generated.go index ef7a013380..9fc08b6d1c 100644 --- a/vendor/k8s.io/kubernetes/pkg/apis/batch/v1/conversion_generated.go +++ b/vendor/k8s.io/kubernetes/pkg/apis/batch/v1/conversion_generated.go @@ -217,8 +217,7 @@ func autoConvert_v1_JobSpec_To_batch_JobSpec(in *JobSpec, out *batch.JobSpec, s } else { out.ManualSelector = nil } - // TODO: Inefficient conversion - can we improve it? - if err := s.Convert(&in.Template, &out.Template, 0); err != nil { + if err := api_v1.Convert_v1_PodTemplateSpec_To_api_PodTemplateSpec(&in.Template, &out.Template, s); err != nil { return err } return nil @@ -262,8 +261,7 @@ func autoConvert_batch_JobSpec_To_v1_JobSpec(in *batch.JobSpec, out *JobSpec, s } else { out.ManualSelector = nil } - // TODO: Inefficient conversion - can we improve it? - if err := s.Convert(&in.Template, &out.Template, 0); err != nil { + if err := api_v1.Convert_api_PodTemplateSpec_To_v1_PodTemplateSpec(&in.Template, &out.Template, s); err != nil { return err } return nil diff --git a/vendor/k8s.io/kubernetes/pkg/apis/batch/v1/types.generated.go b/vendor/k8s.io/kubernetes/pkg/apis/batch/v1/types.generated.go index 0dd4005437..58d5f6f54c 100644 --- a/vendor/k8s.io/kubernetes/pkg/apis/batch/v1/types.generated.go +++ b/vendor/k8s.io/kubernetes/pkg/apis/batch/v1/types.generated.go @@ -1,5 +1,5 @@ /* -Copyright 2015 The Kubernetes Authors All rights reserved. +Copyright 2016 The Kubernetes Authors All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -25,12 +25,11 @@ import ( "errors" "fmt" codec1978 "github.com/ugorji/go/codec" - pkg5_inf_v0 "gopkg.in/inf.v0" pkg4_resource "k8s.io/kubernetes/pkg/api/resource" pkg1_unversioned "k8s.io/kubernetes/pkg/api/unversioned" pkg2_v1 "k8s.io/kubernetes/pkg/api/v1" pkg3_types "k8s.io/kubernetes/pkg/types" - pkg6_intstr "k8s.io/kubernetes/pkg/util/intstr" + pkg5_intstr "k8s.io/kubernetes/pkg/util/intstr" "reflect" "runtime" time "time" @@ -66,14 +65,13 @@ func init() { panic(err) } if false { // reference the types, but skip this branch at build/run time - var v0 pkg5_inf_v0.Dec - var v1 pkg4_resource.Quantity - var v2 pkg1_unversioned.TypeMeta - var v3 pkg2_v1.ObjectMeta - var v4 pkg3_types.UID - var v5 pkg6_intstr.IntOrString - var v6 time.Time - _, _, _, _, _, _, _ = v0, v1, v2, v3, v4, v5, v6 + var v0 pkg4_resource.Quantity + var v1 pkg1_unversioned.TypeMeta + var v2 pkg2_v1.ObjectMeta + var v3 pkg3_types.UID + var v4 pkg5_intstr.IntOrString + var v5 time.Time + _, _, _, _, _, _ = v0, v1, v2, v3, v4, v5 } } @@ -2867,7 +2865,7 @@ func (x codecSelfer1234) decSliceJob(v *[]Job, d *codec1978.Decoder) { yyrg1 := len(yyv1) > 0 yyv21 := yyv1 - yyrl1, yyrt1 = z.DecInferLen(yyl1, z.DecBasicHandle().MaxInitLen, 768) + yyrl1, yyrt1 = z.DecInferLen(yyl1, z.DecBasicHandle().MaxInitLen, 792) if yyrt1 { if yyrl1 <= cap(yyv1) { yyv1 = yyv1[:yyrl1] diff --git a/vendor/k8s.io/kubernetes/pkg/apis/batch/v1/types_swagger_doc_generated.go b/vendor/k8s.io/kubernetes/pkg/apis/batch/v1/types_swagger_doc_generated.go index 8b52558439..3e758b0096 100644 --- a/vendor/k8s.io/kubernetes/pkg/apis/batch/v1/types_swagger_doc_generated.go +++ b/vendor/k8s.io/kubernetes/pkg/apis/batch/v1/types_swagger_doc_generated.go @@ -1,5 +1,5 @@ /* -Copyright 2015 The Kubernetes Authors All rights reserved. +Copyright 2016 The Kubernetes Authors All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/vendor/k8s.io/kubernetes/pkg/apis/batch/v2alpha1/conversion.go b/vendor/k8s.io/kubernetes/pkg/apis/batch/v2alpha1/conversion.go index dc063dc90a..4714fda0fb 100644 --- a/vendor/k8s.io/kubernetes/pkg/apis/batch/v2alpha1/conversion.go +++ b/vendor/k8s.io/kubernetes/pkg/apis/batch/v2alpha1/conversion.go @@ -39,15 +39,18 @@ func addConversionFuncs(scheme *runtime.Scheme) { panic(err) } - err = api.Scheme.AddFieldLabelConversionFunc("batch/v2alpha1", "Job", - func(label, value string) (string, string, error) { - switch label { - case "metadata.name", "metadata.namespace", "status.successful": - return label, value, nil - default: - return "", "", fmt.Errorf("field label not supported: %s", label) - } - }) + // Add field label conversions for kinds having selectable nothing but ObjectMeta fields. + for _, kind := range []string{"Job", "JobTemplate", "ScheduledJob"} { + err = api.Scheme.AddFieldLabelConversionFunc("batch/v2alpha1", kind, + func(label, value string) (string, string, error) { + switch label { + case "metadata.name", "metadata.namespace", "status.successful": + return label, value, nil + default: + return "", "", fmt.Errorf("field label not supported: %s", label) + } + }) + } if err != nil { // If one of the conversion functions is malformed, detect it immediately. panic(err) diff --git a/vendor/k8s.io/kubernetes/pkg/apis/batch/v2alpha1/conversion_generated.go b/vendor/k8s.io/kubernetes/pkg/apis/batch/v2alpha1/conversion_generated.go index 7ab274c2c8..fd65487317 100644 --- a/vendor/k8s.io/kubernetes/pkg/apis/batch/v2alpha1/conversion_generated.go +++ b/vendor/k8s.io/kubernetes/pkg/apis/batch/v2alpha1/conversion_generated.go @@ -48,6 +48,12 @@ func init() { Convert_unversioned_LabelSelector_To_v2alpha1_LabelSelector, Convert_v2alpha1_LabelSelectorRequirement_To_unversioned_LabelSelectorRequirement, Convert_unversioned_LabelSelectorRequirement_To_v2alpha1_LabelSelectorRequirement, + Convert_v2alpha1_ScheduledJob_To_batch_ScheduledJob, + Convert_batch_ScheduledJob_To_v2alpha1_ScheduledJob, + Convert_v2alpha1_ScheduledJobList_To_batch_ScheduledJobList, + Convert_batch_ScheduledJobList_To_v2alpha1_ScheduledJobList, + Convert_v2alpha1_ScheduledJobSpec_To_batch_ScheduledJobSpec, + Convert_batch_ScheduledJobSpec_To_v2alpha1_ScheduledJobSpec, Convert_v2alpha1_ScheduledJobStatus_To_batch_ScheduledJobStatus, Convert_batch_ScheduledJobStatus_To_v2alpha1_ScheduledJobStatus, ); err != nil { @@ -223,8 +229,7 @@ func autoConvert_v2alpha1_JobSpec_To_batch_JobSpec(in *JobSpec, out *batch.JobSp } else { out.ManualSelector = nil } - // TODO: Inefficient conversion - can we improve it? - if err := s.Convert(&in.Template, &out.Template, 0); err != nil { + if err := v1.Convert_v1_PodTemplateSpec_To_api_PodTemplateSpec(&in.Template, &out.Template, s); err != nil { return err } return nil @@ -268,8 +273,7 @@ func autoConvert_batch_JobSpec_To_v2alpha1_JobSpec(in *batch.JobSpec, out *JobSp } else { out.ManualSelector = nil } - // TODO: Inefficient conversion - can we improve it? - if err := s.Convert(&in.Template, &out.Template, 0); err != nil { + if err := v1.Convert_api_PodTemplateSpec_To_v1_PodTemplateSpec(&in.Template, &out.Template, s); err != nil { return err } return nil @@ -511,6 +515,141 @@ func Convert_unversioned_LabelSelectorRequirement_To_v2alpha1_LabelSelectorRequi return autoConvert_unversioned_LabelSelectorRequirement_To_v2alpha1_LabelSelectorRequirement(in, out, s) } +func autoConvert_v2alpha1_ScheduledJob_To_batch_ScheduledJob(in *ScheduledJob, out *batch.ScheduledJob, s conversion.Scope) error { + SetDefaults_ScheduledJob(in) + if err := api.Convert_unversioned_TypeMeta_To_unversioned_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + return err + } + // TODO: Inefficient conversion - can we improve it? + if err := s.Convert(&in.ObjectMeta, &out.ObjectMeta, 0); err != nil { + return err + } + if err := Convert_v2alpha1_ScheduledJobSpec_To_batch_ScheduledJobSpec(&in.Spec, &out.Spec, s); err != nil { + return err + } + if err := Convert_v2alpha1_ScheduledJobStatus_To_batch_ScheduledJobStatus(&in.Status, &out.Status, s); err != nil { + return err + } + return nil +} + +func Convert_v2alpha1_ScheduledJob_To_batch_ScheduledJob(in *ScheduledJob, out *batch.ScheduledJob, s conversion.Scope) error { + return autoConvert_v2alpha1_ScheduledJob_To_batch_ScheduledJob(in, out, s) +} + +func autoConvert_batch_ScheduledJob_To_v2alpha1_ScheduledJob(in *batch.ScheduledJob, out *ScheduledJob, s conversion.Scope) error { + if err := api.Convert_unversioned_TypeMeta_To_unversioned_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + return err + } + // TODO: Inefficient conversion - can we improve it? + if err := s.Convert(&in.ObjectMeta, &out.ObjectMeta, 0); err != nil { + return err + } + if err := Convert_batch_ScheduledJobSpec_To_v2alpha1_ScheduledJobSpec(&in.Spec, &out.Spec, s); err != nil { + return err + } + if err := Convert_batch_ScheduledJobStatus_To_v2alpha1_ScheduledJobStatus(&in.Status, &out.Status, s); err != nil { + return err + } + return nil +} + +func Convert_batch_ScheduledJob_To_v2alpha1_ScheduledJob(in *batch.ScheduledJob, out *ScheduledJob, s conversion.Scope) error { + return autoConvert_batch_ScheduledJob_To_v2alpha1_ScheduledJob(in, out, s) +} + +func autoConvert_v2alpha1_ScheduledJobList_To_batch_ScheduledJobList(in *ScheduledJobList, out *batch.ScheduledJobList, s conversion.Scope) error { + if err := api.Convert_unversioned_TypeMeta_To_unversioned_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + return err + } + if err := api.Convert_unversioned_ListMeta_To_unversioned_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + return err + } + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]batch.ScheduledJob, len(*in)) + for i := range *in { + if err := Convert_v2alpha1_ScheduledJob_To_batch_ScheduledJob(&(*in)[i], &(*out)[i], s); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +func Convert_v2alpha1_ScheduledJobList_To_batch_ScheduledJobList(in *ScheduledJobList, out *batch.ScheduledJobList, s conversion.Scope) error { + return autoConvert_v2alpha1_ScheduledJobList_To_batch_ScheduledJobList(in, out, s) +} + +func autoConvert_batch_ScheduledJobList_To_v2alpha1_ScheduledJobList(in *batch.ScheduledJobList, out *ScheduledJobList, s conversion.Scope) error { + if err := api.Convert_unversioned_TypeMeta_To_unversioned_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + return err + } + if err := api.Convert_unversioned_ListMeta_To_unversioned_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + return err + } + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]ScheduledJob, len(*in)) + for i := range *in { + if err := Convert_batch_ScheduledJob_To_v2alpha1_ScheduledJob(&(*in)[i], &(*out)[i], s); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +func Convert_batch_ScheduledJobList_To_v2alpha1_ScheduledJobList(in *batch.ScheduledJobList, out *ScheduledJobList, s conversion.Scope) error { + return autoConvert_batch_ScheduledJobList_To_v2alpha1_ScheduledJobList(in, out, s) +} + +func autoConvert_v2alpha1_ScheduledJobSpec_To_batch_ScheduledJobSpec(in *ScheduledJobSpec, out *batch.ScheduledJobSpec, s conversion.Scope) error { + out.Schedule = in.Schedule + if in.StartingDeadlineSeconds != nil { + in, out := &in.StartingDeadlineSeconds, &out.StartingDeadlineSeconds + *out = new(int64) + **out = **in + } else { + out.StartingDeadlineSeconds = nil + } + out.ConcurrencyPolicy = batch.ConcurrencyPolicy(in.ConcurrencyPolicy) + out.Suspend = in.Suspend + if err := Convert_v2alpha1_JobTemplateSpec_To_batch_JobTemplateSpec(&in.JobTemplate, &out.JobTemplate, s); err != nil { + return err + } + return nil +} + +func Convert_v2alpha1_ScheduledJobSpec_To_batch_ScheduledJobSpec(in *ScheduledJobSpec, out *batch.ScheduledJobSpec, s conversion.Scope) error { + return autoConvert_v2alpha1_ScheduledJobSpec_To_batch_ScheduledJobSpec(in, out, s) +} + +func autoConvert_batch_ScheduledJobSpec_To_v2alpha1_ScheduledJobSpec(in *batch.ScheduledJobSpec, out *ScheduledJobSpec, s conversion.Scope) error { + out.Schedule = in.Schedule + if in.StartingDeadlineSeconds != nil { + in, out := &in.StartingDeadlineSeconds, &out.StartingDeadlineSeconds + *out = new(int64) + **out = **in + } else { + out.StartingDeadlineSeconds = nil + } + out.ConcurrencyPolicy = ConcurrencyPolicy(in.ConcurrencyPolicy) + out.Suspend = in.Suspend + if err := Convert_batch_JobTemplateSpec_To_v2alpha1_JobTemplateSpec(&in.JobTemplate, &out.JobTemplate, s); err != nil { + return err + } + return nil +} + +func Convert_batch_ScheduledJobSpec_To_v2alpha1_ScheduledJobSpec(in *batch.ScheduledJobSpec, out *ScheduledJobSpec, s conversion.Scope) error { + return autoConvert_batch_ScheduledJobSpec_To_v2alpha1_ScheduledJobSpec(in, out, s) +} + func autoConvert_v2alpha1_ScheduledJobStatus_To_batch_ScheduledJobStatus(in *ScheduledJobStatus, out *batch.ScheduledJobStatus, s conversion.Scope) error { if in.Active != nil { in, out := &in.Active, &out.Active diff --git a/vendor/k8s.io/kubernetes/pkg/apis/batch/v2alpha1/deep_copy_generated.go b/vendor/k8s.io/kubernetes/pkg/apis/batch/v2alpha1/deep_copy_generated.go index 3cc325bbc4..8e0eb343a5 100644 --- a/vendor/k8s.io/kubernetes/pkg/apis/batch/v2alpha1/deep_copy_generated.go +++ b/vendor/k8s.io/kubernetes/pkg/apis/batch/v2alpha1/deep_copy_generated.go @@ -287,14 +287,8 @@ func DeepCopy_v2alpha1_ScheduledJobSpec(in ScheduledJobSpec, out *ScheduledJobSp } out.ConcurrencyPolicy = in.ConcurrencyPolicy out.Suspend = in.Suspend - if in.JobTemplate != nil { - in, out := in.JobTemplate, &out.JobTemplate - *out = new(JobTemplateSpec) - if err := DeepCopy_v2alpha1_JobTemplateSpec(*in, *out, c); err != nil { - return err - } - } else { - out.JobTemplate = nil + if err := DeepCopy_v2alpha1_JobTemplateSpec(in.JobTemplate, &out.JobTemplate, c); err != nil { + return err } return nil } diff --git a/vendor/k8s.io/kubernetes/pkg/apis/batch/v2alpha1/defaults.go b/vendor/k8s.io/kubernetes/pkg/apis/batch/v2alpha1/defaults.go index d1b90e33d0..72da797c77 100644 --- a/vendor/k8s.io/kubernetes/pkg/apis/batch/v2alpha1/defaults.go +++ b/vendor/k8s.io/kubernetes/pkg/apis/batch/v2alpha1/defaults.go @@ -23,6 +23,7 @@ import ( func addDefaultingFuncs(scheme *runtime.Scheme) { scheme.AddDefaultingFuncs( SetDefaults_Job, + SetDefaults_ScheduledJob, ) } @@ -40,3 +41,9 @@ func SetDefaults_Job(obj *Job) { *obj.Spec.Parallelism = 1 } } + +func SetDefaults_ScheduledJob(obj *ScheduledJob) { + if obj.Spec.ConcurrencyPolicy == "" { + obj.Spec.ConcurrencyPolicy = AllowConcurrent + } +} diff --git a/vendor/k8s.io/kubernetes/pkg/apis/batch/v2alpha1/generated.pb.go b/vendor/k8s.io/kubernetes/pkg/apis/batch/v2alpha1/generated.pb.go index 94c97b8e39..a642fa691c 100644 --- a/vendor/k8s.io/kubernetes/pkg/apis/batch/v2alpha1/generated.pb.go +++ b/vendor/k8s.io/kubernetes/pkg/apis/batch/v2alpha1/generated.pb.go @@ -644,16 +644,14 @@ func (m *ScheduledJobSpec) MarshalTo(data []byte) (int, error) { data[i] = 0 } i++ - if m.JobTemplate != nil { - data[i] = 0x2a - i++ - i = encodeVarintGenerated(data, i, uint64(m.JobTemplate.Size())) - n19, err := m.JobTemplate.MarshalTo(data[i:]) - if err != nil { - return 0, err - } - i += n19 + data[i] = 0x2a + i++ + i = encodeVarintGenerated(data, i, uint64(m.JobTemplate.Size())) + n19, err := m.JobTemplate.MarshalTo(data[i:]) + if err != nil { + return 0, err } + i += n19 return i, nil } @@ -908,10 +906,8 @@ func (m *ScheduledJobSpec) Size() (n int) { l = len(m.ConcurrencyPolicy) n += 1 + l + sovGenerated(uint64(l)) n += 2 - if m.JobTemplate != nil { - l = m.JobTemplate.Size() - n += 1 + l + sovGenerated(uint64(l)) - } + l = m.JobTemplate.Size() + n += 1 + l + sovGenerated(uint64(l)) return n } @@ -2772,9 +2768,6 @@ func (m *ScheduledJobSpec) Unmarshal(data []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if m.JobTemplate == nil { - m.JobTemplate = &JobTemplateSpec{} - } if err := m.JobTemplate.Unmarshal(data[iNdEx:postIndex]); err != nil { return err } diff --git a/vendor/k8s.io/kubernetes/pkg/apis/batch/v2alpha1/register.go b/vendor/k8s.io/kubernetes/pkg/apis/batch/v2alpha1/register.go index f887d71656..3d9dcb83f6 100644 --- a/vendor/k8s.io/kubernetes/pkg/apis/batch/v2alpha1/register.go +++ b/vendor/k8s.io/kubernetes/pkg/apis/batch/v2alpha1/register.go @@ -41,11 +41,15 @@ func addKnownTypes(scheme *runtime.Scheme) { &Job{}, &JobList{}, &JobTemplate{}, + &ScheduledJob{}, + &ScheduledJobList{}, &v1.ListOptions{}, ) versionedwatch.AddToGroupVersion(scheme, SchemeGroupVersion) } -func (obj *JobTemplate) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta } -func (obj *Job) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta } -func (obj *JobList) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta } +func (obj *Job) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta } +func (obj *JobList) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta } +func (obj *JobTemplate) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta } +func (obj *ScheduledJob) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta } +func (obj *ScheduledJobList) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta } diff --git a/vendor/k8s.io/kubernetes/pkg/apis/batch/v2alpha1/types.generated.go b/vendor/k8s.io/kubernetes/pkg/apis/batch/v2alpha1/types.generated.go index 30c96c7f52..7b64c81d24 100644 --- a/vendor/k8s.io/kubernetes/pkg/apis/batch/v2alpha1/types.generated.go +++ b/vendor/k8s.io/kubernetes/pkg/apis/batch/v2alpha1/types.generated.go @@ -1,5 +1,5 @@ /* -Copyright 2015 The Kubernetes Authors All rights reserved. +Copyright 2016 The Kubernetes Authors All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -25,12 +25,11 @@ import ( "errors" "fmt" codec1978 "github.com/ugorji/go/codec" - pkg5_inf_v0 "gopkg.in/inf.v0" pkg4_resource "k8s.io/kubernetes/pkg/api/resource" pkg1_unversioned "k8s.io/kubernetes/pkg/api/unversioned" pkg2_v1 "k8s.io/kubernetes/pkg/api/v1" pkg3_types "k8s.io/kubernetes/pkg/types" - pkg6_intstr "k8s.io/kubernetes/pkg/util/intstr" + pkg5_intstr "k8s.io/kubernetes/pkg/util/intstr" "reflect" "runtime" time "time" @@ -66,14 +65,13 @@ func init() { panic(err) } if false { // reference the types, but skip this branch at build/run time - var v0 pkg5_inf_v0.Dec - var v1 pkg4_resource.Quantity - var v2 pkg1_unversioned.TypeMeta - var v3 pkg2_v1.ObjectMeta - var v4 pkg3_types.UID - var v5 pkg6_intstr.IntOrString - var v6 time.Time - _, _, _, _, _, _, _ = v0, v1, v2, v3, v4, v5, v6 + var v0 pkg4_resource.Quantity + var v1 pkg1_unversioned.TypeMeta + var v2 pkg2_v1.ObjectMeta + var v3 pkg3_types.UID + var v4 pkg5_intstr.IntOrString + var v5 time.Time + _, _, _, _, _, _ = v0, v1, v2, v3, v4, v5 } } @@ -3599,20 +3597,14 @@ func (x *ScheduledJobSpec) CodecEncodeSelf(e *codec1978.Encoder) { } if yyr2 || yy2arr2 { z.EncSendContainerState(codecSelfer_containerArrayElem1234) - if x.JobTemplate == nil { - r.EncodeNil() - } else { - x.JobTemplate.CodecEncodeSelf(e) - } + yy18 := &x.JobTemplate + yy18.CodecEncodeSelf(e) } else { z.EncSendContainerState(codecSelfer_containerMapKey1234) r.EncodeString(codecSelferC_UTF81234, string("jobTemplate")) z.EncSendContainerState(codecSelfer_containerMapValue1234) - if x.JobTemplate == nil { - r.EncodeNil() - } else { - x.JobTemplate.CodecEncodeSelf(e) - } + yy20 := &x.JobTemplate + yy20.CodecEncodeSelf(e) } if yyr2 || yy2arr2 { z.EncSendContainerState(codecSelfer_containerArrayEnd1234) @@ -3711,14 +3703,10 @@ func (x *ScheduledJobSpec) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) { } case "jobTemplate": if r.TryDecodeAsNil() { - if x.JobTemplate != nil { - x.JobTemplate = nil - } + x.JobTemplate = JobTemplateSpec{} } else { - if x.JobTemplate == nil { - x.JobTemplate = new(JobTemplateSpec) - } - x.JobTemplate.CodecDecodeSelf(d) + yyv9 := &x.JobTemplate + yyv9.CodecDecodeSelf(d) } default: z.DecStructFieldNotFound(-1, yys3) @@ -3820,14 +3808,10 @@ func (x *ScheduledJobSpec) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) } z.DecSendContainerState(codecSelfer_containerArrayElem1234) if r.TryDecodeAsNil() { - if x.JobTemplate != nil { - x.JobTemplate = nil - } + x.JobTemplate = JobTemplateSpec{} } else { - if x.JobTemplate == nil { - x.JobTemplate = new(JobTemplateSpec) - } - x.JobTemplate.CodecDecodeSelf(d) + yyv16 := &x.JobTemplate + yyv16.CodecDecodeSelf(d) } for { yyj10++ @@ -4739,7 +4723,7 @@ func (x codecSelfer1234) decSliceJob(v *[]Job, d *codec1978.Decoder) { yyrg1 := len(yyv1) > 0 yyv21 := yyv1 - yyrl1, yyrt1 = z.DecInferLen(yyl1, z.DecBasicHandle().MaxInitLen, 768) + yyrl1, yyrt1 = z.DecInferLen(yyl1, z.DecBasicHandle().MaxInitLen, 792) if yyrt1 { if yyrl1 <= cap(yyv1) { yyv1 = yyv1[:yyrl1] @@ -4977,7 +4961,7 @@ func (x codecSelfer1234) decSliceScheduledJob(v *[]ScheduledJob, d *codec1978.De yyrg1 := len(yyv1) > 0 yyv21 := yyv1 - yyrl1, yyrt1 = z.DecInferLen(yyl1, z.DecBasicHandle().MaxInitLen, 328) + yyrl1, yyrt1 = z.DecInferLen(yyl1, z.DecBasicHandle().MaxInitLen, 1024) if yyrt1 { if yyrl1 <= cap(yyv1) { yyv1 = yyv1[:yyrl1] diff --git a/vendor/k8s.io/kubernetes/pkg/apis/batch/v2alpha1/types.go b/vendor/k8s.io/kubernetes/pkg/apis/batch/v2alpha1/types.go index f6615f1ef6..f33dfc1ed6 100644 --- a/vendor/k8s.io/kubernetes/pkg/apis/batch/v2alpha1/types.go +++ b/vendor/k8s.io/kubernetes/pkg/apis/batch/v2alpha1/types.go @@ -215,7 +215,7 @@ type ScheduledJobSpec struct { // JobTemplate is the object that describes the job that will be created when // executing a ScheduledJob. - JobTemplate *JobTemplateSpec `json:"jobTemplate" protobuf:"bytes,5,opt,name=jobTemplate"` + JobTemplate JobTemplateSpec `json:"jobTemplate" protobuf:"bytes,5,opt,name=jobTemplate"` } // ConcurrencyPolicy describes how the job will be handled. diff --git a/vendor/k8s.io/kubernetes/pkg/apis/batch/v2alpha1/types_swagger_doc_generated.go b/vendor/k8s.io/kubernetes/pkg/apis/batch/v2alpha1/types_swagger_doc_generated.go index 471a6be1c3..7f0e3b1997 100644 --- a/vendor/k8s.io/kubernetes/pkg/apis/batch/v2alpha1/types_swagger_doc_generated.go +++ b/vendor/k8s.io/kubernetes/pkg/apis/batch/v2alpha1/types_swagger_doc_generated.go @@ -1,5 +1,5 @@ /* -Copyright 2015 The Kubernetes Authors All rights reserved. +Copyright 2016 The Kubernetes Authors All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/vendor/k8s.io/kubernetes/pkg/apis/batch/validation/validation.go b/vendor/k8s.io/kubernetes/pkg/apis/batch/validation/validation.go index d4d1875783..ca1ea5b9e9 100644 --- a/vendor/k8s.io/kubernetes/pkg/apis/batch/validation/validation.go +++ b/vendor/k8s.io/kubernetes/pkg/apis/batch/validation/validation.go @@ -17,6 +17,8 @@ limitations under the License. package validation import ( + "github.com/robfig/cron" + "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/unversioned" unversionedvalidation "k8s.io/kubernetes/pkg/api/unversioned/validation" @@ -155,3 +157,65 @@ func ValidateJobStatusUpdate(status, oldStatus batch.JobStatus) field.ErrorList allErrs = append(allErrs, ValidateJobStatus(&status, field.NewPath("status"))...) return allErrs } + +func ValidateScheduledJob(scheduledJob *batch.ScheduledJob) field.ErrorList { + // ScheduledJobs and rcs have the same name validation + allErrs := apivalidation.ValidateObjectMeta(&scheduledJob.ObjectMeta, true, apivalidation.ValidateReplicationControllerName, field.NewPath("metadata")) + allErrs = append(allErrs, ValidateScheduledJobSpec(&scheduledJob.Spec, field.NewPath("spec"))...) + return allErrs +} + +func ValidateScheduledJobSpec(spec *batch.ScheduledJobSpec, fldPath *field.Path) field.ErrorList { + allErrs := field.ErrorList{} + + if len(spec.Schedule) == 0 { + allErrs = append(allErrs, field.Required(fldPath.Child("schedule"), "")) + } else { + allErrs = append(allErrs, validateScheduleFormat(spec.Schedule, fldPath.Child("schedule"))...) + } + if spec.StartingDeadlineSeconds != nil { + allErrs = append(allErrs, apivalidation.ValidateNonnegativeField(int64(*spec.StartingDeadlineSeconds), fldPath.Child("startingDeadlineSeconds"))...) + } + allErrs = append(allErrs, validateConcurrencyPolicy(&spec.ConcurrencyPolicy, fldPath.Child("concurrencyPolicy"))...) + allErrs = append(allErrs, ValidateJobTemplateSpec(&spec.JobTemplate, fldPath.Child("jobTemplate"))...) + + return allErrs +} + +func validateConcurrencyPolicy(concurrencyPolicy *batch.ConcurrencyPolicy, fldPath *field.Path) field.ErrorList { + allErrs := field.ErrorList{} + switch *concurrencyPolicy { + case batch.AllowConcurrent, batch.ForbidConcurrent, batch.ReplaceConcurrent: + break + case "": + allErrs = append(allErrs, field.Required(fldPath, "")) + default: + validValues := []string{string(batch.AllowConcurrent), string(batch.ForbidConcurrent), string(batch.ReplaceConcurrent)} + allErrs = append(allErrs, field.NotSupported(fldPath, *concurrencyPolicy, validValues)) + } + + return allErrs +} + +func validateScheduleFormat(schedule string, fldPath *field.Path) field.ErrorList { + allErrs := field.ErrorList{} + _, err := cron.Parse(schedule) + if err != nil { + allErrs = append(allErrs, field.Invalid(fldPath, schedule, err.Error())) + } + + return allErrs +} + +func ValidateJobTemplate(job *batch.JobTemplate) field.ErrorList { + // this method should be identical to ValidateJob + allErrs := apivalidation.ValidateObjectMeta(&job.ObjectMeta, true, apivalidation.ValidateReplicationControllerName, field.NewPath("metadata")) + allErrs = append(allErrs, ValidateJobTemplateSpec(&job.Template, field.NewPath("template"))...) + return allErrs +} + +func ValidateJobTemplateSpec(spec *batch.JobTemplateSpec, fldPath *field.Path) field.ErrorList { + // this method should be identical to ValidateJob + allErrs := ValidateJobSpec(&spec.Spec, fldPath.Child("spec")) + return allErrs +} diff --git a/vendor/k8s.io/kubernetes/pkg/apis/componentconfig/deep_copy_generated.go b/vendor/k8s.io/kubernetes/pkg/apis/componentconfig/deep_copy_generated.go index 631f6b4795..e36fb927aa 100644 --- a/vendor/k8s.io/kubernetes/pkg/apis/componentconfig/deep_copy_generated.go +++ b/vendor/k8s.io/kubernetes/pkg/apis/componentconfig/deep_copy_generated.go @@ -117,6 +117,8 @@ func DeepCopy_componentconfig_KubeControllerManagerConfiguration(in KubeControll out.EnableProfiling = in.EnableProfiling out.ClusterName = in.ClusterName out.ClusterCIDR = in.ClusterCIDR + out.ServiceCIDR = in.ServiceCIDR + out.NodeCIDRMaskSize = in.NodeCIDRMaskSize out.AllocateNodeCIDRs = in.AllocateNodeCIDRs out.RootCAFile = in.RootCAFile out.ContentType = in.ContentType @@ -272,6 +274,7 @@ func DeepCopy_componentconfig_KubeletConfiguration(in KubeletConfiguration, out out.RktAPIEndpoint = in.RktAPIEndpoint out.RktStage1Image = in.RktStage1Image out.LockFilePath = in.LockFilePath + out.ExitOnLockContention = in.ExitOnLockContention out.ConfigureCBR0 = in.ConfigureCBR0 out.HairpinMode = in.HairpinMode out.BabysitDaemons = in.BabysitDaemons @@ -311,6 +314,7 @@ func DeepCopy_componentconfig_KubeletConfiguration(in KubeletConfiguration, out if err := unversioned.DeepCopy_unversioned_Duration(in.EvictionPressureTransitionPeriod, &out.EvictionPressureTransitionPeriod, c); err != nil { return err } + out.EvictionMaxPodGracePeriod = in.EvictionMaxPodGracePeriod return nil } diff --git a/vendor/k8s.io/kubernetes/pkg/apis/componentconfig/types.generated.go b/vendor/k8s.io/kubernetes/pkg/apis/componentconfig/types.generated.go index d9996c2b8c..1881035188 100644 --- a/vendor/k8s.io/kubernetes/pkg/apis/componentconfig/types.generated.go +++ b/vendor/k8s.io/kubernetes/pkg/apis/componentconfig/types.generated.go @@ -1,5 +1,5 @@ /* -Copyright 2015 The Kubernetes Authors All rights reserved. +Copyright 2016 The Kubernetes Authors All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -1175,7 +1175,7 @@ func (x *KubeletConfiguration) CodecEncodeSelf(e *codec1978.Encoder) { } else { yysep2 := !z.EncBinary() yy2arr2 := z.EncBasicHandle().StructToArray - var yyq2 [85]bool + var yyq2 [87]bool _, _, _ = yysep2, yyq2, yy2arr2 const yyr2 bool = false yyq2[47] = x.CloudProvider != "" @@ -1187,17 +1187,18 @@ func (x *KubeletConfiguration) CodecEncodeSelf(e *codec1978.Encoder) { yyq2[54] = x.RktPath != "" yyq2[55] = x.RktAPIEndpoint != "" yyq2[56] = x.RktStage1Image != "" - yyq2[76] = true - yyq2[77] = x.NodeIP != "" - yyq2[81] = x.EvictionHard != "" - yyq2[82] = x.EvictionSoft != "" - yyq2[83] = x.EvictionSoftGracePeriod != "" - yyq2[84] = true + yyq2[77] = true + yyq2[78] = x.NodeIP != "" + yyq2[82] = x.EvictionHard != "" + yyq2[83] = x.EvictionSoft != "" + yyq2[84] = x.EvictionSoftGracePeriod != "" + yyq2[85] = true + yyq2[86] = x.EvictionMaxPodGracePeriod != 0 var yynn2 int if yyr2 || yy2arr2 { - r.EncodeArrayStart(85) + r.EncodeArrayStart(87) } else { - yynn2 = 70 + yynn2 = 71 for _, b := range yyq2 { if b { yynn2++ @@ -2432,17 +2433,17 @@ func (x *KubeletConfiguration) CodecEncodeSelf(e *codec1978.Encoder) { _ = yym194 if false { } else { - r.EncodeBool(bool(x.ConfigureCBR0)) + r.EncodeBool(bool(x.ExitOnLockContention)) } } else { z.EncSendContainerState(codecSelfer_containerMapKey1234) - r.EncodeString(codecSelferC_UTF81234, string("configureCbr0")) + r.EncodeString(codecSelferC_UTF81234, string("exitOnLockContention")) z.EncSendContainerState(codecSelfer_containerMapValue1234) yym195 := z.EncBinary() _ = yym195 if false { } else { - r.EncodeBool(bool(x.ConfigureCBR0)) + r.EncodeBool(bool(x.ExitOnLockContention)) } } if yyr2 || yy2arr2 { @@ -2451,17 +2452,17 @@ func (x *KubeletConfiguration) CodecEncodeSelf(e *codec1978.Encoder) { _ = yym197 if false { } else { - r.EncodeString(codecSelferC_UTF81234, string(x.HairpinMode)) + r.EncodeBool(bool(x.ConfigureCBR0)) } } else { z.EncSendContainerState(codecSelfer_containerMapKey1234) - r.EncodeString(codecSelferC_UTF81234, string("hairpinMode")) + r.EncodeString(codecSelferC_UTF81234, string("configureCbr0")) z.EncSendContainerState(codecSelfer_containerMapValue1234) yym198 := z.EncBinary() _ = yym198 if false { } else { - r.EncodeString(codecSelferC_UTF81234, string(x.HairpinMode)) + r.EncodeBool(bool(x.ConfigureCBR0)) } } if yyr2 || yy2arr2 { @@ -2470,17 +2471,17 @@ func (x *KubeletConfiguration) CodecEncodeSelf(e *codec1978.Encoder) { _ = yym200 if false { } else { - r.EncodeBool(bool(x.BabysitDaemons)) + r.EncodeString(codecSelferC_UTF81234, string(x.HairpinMode)) } } else { z.EncSendContainerState(codecSelfer_containerMapKey1234) - r.EncodeString(codecSelferC_UTF81234, string("babysitDaemons")) + r.EncodeString(codecSelferC_UTF81234, string("hairpinMode")) z.EncSendContainerState(codecSelfer_containerMapValue1234) yym201 := z.EncBinary() _ = yym201 if false { } else { - r.EncodeBool(bool(x.BabysitDaemons)) + r.EncodeString(codecSelferC_UTF81234, string(x.HairpinMode)) } } if yyr2 || yy2arr2 { @@ -2489,17 +2490,17 @@ func (x *KubeletConfiguration) CodecEncodeSelf(e *codec1978.Encoder) { _ = yym203 if false { } else { - r.EncodeInt(int64(x.MaxPods)) + r.EncodeBool(bool(x.BabysitDaemons)) } } else { z.EncSendContainerState(codecSelfer_containerMapKey1234) - r.EncodeString(codecSelferC_UTF81234, string("maxPods")) + r.EncodeString(codecSelferC_UTF81234, string("babysitDaemons")) z.EncSendContainerState(codecSelfer_containerMapValue1234) yym204 := z.EncBinary() _ = yym204 if false { } else { - r.EncodeInt(int64(x.MaxPods)) + r.EncodeBool(bool(x.BabysitDaemons)) } } if yyr2 || yy2arr2 { @@ -2508,17 +2509,17 @@ func (x *KubeletConfiguration) CodecEncodeSelf(e *codec1978.Encoder) { _ = yym206 if false { } else { - r.EncodeInt(int64(x.NvidiaGPUs)) + r.EncodeInt(int64(x.MaxPods)) } } else { z.EncSendContainerState(codecSelfer_containerMapKey1234) - r.EncodeString(codecSelferC_UTF81234, string("nvidiaGPUs")) + r.EncodeString(codecSelferC_UTF81234, string("maxPods")) z.EncSendContainerState(codecSelfer_containerMapValue1234) yym207 := z.EncBinary() _ = yym207 if false { } else { - r.EncodeInt(int64(x.NvidiaGPUs)) + r.EncodeInt(int64(x.MaxPods)) } } if yyr2 || yy2arr2 { @@ -2527,17 +2528,17 @@ func (x *KubeletConfiguration) CodecEncodeSelf(e *codec1978.Encoder) { _ = yym209 if false { } else { - r.EncodeString(codecSelferC_UTF81234, string(x.DockerExecHandlerName)) + r.EncodeInt(int64(x.NvidiaGPUs)) } } else { z.EncSendContainerState(codecSelfer_containerMapKey1234) - r.EncodeString(codecSelferC_UTF81234, string("dockerExecHandlerName")) + r.EncodeString(codecSelferC_UTF81234, string("nvidiaGPUs")) z.EncSendContainerState(codecSelfer_containerMapValue1234) yym210 := z.EncBinary() _ = yym210 if false { } else { - r.EncodeString(codecSelferC_UTF81234, string(x.DockerExecHandlerName)) + r.EncodeInt(int64(x.NvidiaGPUs)) } } if yyr2 || yy2arr2 { @@ -2546,17 +2547,17 @@ func (x *KubeletConfiguration) CodecEncodeSelf(e *codec1978.Encoder) { _ = yym212 if false { } else { - r.EncodeString(codecSelferC_UTF81234, string(x.PodCIDR)) + r.EncodeString(codecSelferC_UTF81234, string(x.DockerExecHandlerName)) } } else { z.EncSendContainerState(codecSelfer_containerMapKey1234) - r.EncodeString(codecSelferC_UTF81234, string("podCIDR")) + r.EncodeString(codecSelferC_UTF81234, string("dockerExecHandlerName")) z.EncSendContainerState(codecSelfer_containerMapValue1234) yym213 := z.EncBinary() _ = yym213 if false { } else { - r.EncodeString(codecSelferC_UTF81234, string(x.PodCIDR)) + r.EncodeString(codecSelferC_UTF81234, string(x.DockerExecHandlerName)) } } if yyr2 || yy2arr2 { @@ -2565,17 +2566,17 @@ func (x *KubeletConfiguration) CodecEncodeSelf(e *codec1978.Encoder) { _ = yym215 if false { } else { - r.EncodeString(codecSelferC_UTF81234, string(x.ResolverConfig)) + r.EncodeString(codecSelferC_UTF81234, string(x.PodCIDR)) } } else { z.EncSendContainerState(codecSelfer_containerMapKey1234) - r.EncodeString(codecSelferC_UTF81234, string("resolvConf")) + r.EncodeString(codecSelferC_UTF81234, string("podCIDR")) z.EncSendContainerState(codecSelfer_containerMapValue1234) yym216 := z.EncBinary() _ = yym216 if false { } else { - r.EncodeString(codecSelferC_UTF81234, string(x.ResolverConfig)) + r.EncodeString(codecSelferC_UTF81234, string(x.PodCIDR)) } } if yyr2 || yy2arr2 { @@ -2584,17 +2585,17 @@ func (x *KubeletConfiguration) CodecEncodeSelf(e *codec1978.Encoder) { _ = yym218 if false { } else { - r.EncodeBool(bool(x.CPUCFSQuota)) + r.EncodeString(codecSelferC_UTF81234, string(x.ResolverConfig)) } } else { z.EncSendContainerState(codecSelfer_containerMapKey1234) - r.EncodeString(codecSelferC_UTF81234, string("cpuCFSQuota")) + r.EncodeString(codecSelferC_UTF81234, string("resolvConf")) z.EncSendContainerState(codecSelfer_containerMapValue1234) yym219 := z.EncBinary() _ = yym219 if false { } else { - r.EncodeBool(bool(x.CPUCFSQuota)) + r.EncodeString(codecSelferC_UTF81234, string(x.ResolverConfig)) } } if yyr2 || yy2arr2 { @@ -2603,17 +2604,17 @@ func (x *KubeletConfiguration) CodecEncodeSelf(e *codec1978.Encoder) { _ = yym221 if false { } else { - r.EncodeBool(bool(x.Containerized)) + r.EncodeBool(bool(x.CPUCFSQuota)) } } else { z.EncSendContainerState(codecSelfer_containerMapKey1234) - r.EncodeString(codecSelferC_UTF81234, string("containerized")) + r.EncodeString(codecSelferC_UTF81234, string("cpuCFSQuota")) z.EncSendContainerState(codecSelfer_containerMapValue1234) yym222 := z.EncBinary() _ = yym222 if false { } else { - r.EncodeBool(bool(x.Containerized)) + r.EncodeBool(bool(x.CPUCFSQuota)) } } if yyr2 || yy2arr2 { @@ -2622,17 +2623,17 @@ func (x *KubeletConfiguration) CodecEncodeSelf(e *codec1978.Encoder) { _ = yym224 if false { } else { - r.EncodeUint(uint64(x.MaxOpenFiles)) + r.EncodeBool(bool(x.Containerized)) } } else { z.EncSendContainerState(codecSelfer_containerMapKey1234) - r.EncodeString(codecSelferC_UTF81234, string("maxOpenFiles")) + r.EncodeString(codecSelferC_UTF81234, string("containerized")) z.EncSendContainerState(codecSelfer_containerMapValue1234) yym225 := z.EncBinary() _ = yym225 if false { } else { - r.EncodeUint(uint64(x.MaxOpenFiles)) + r.EncodeBool(bool(x.Containerized)) } } if yyr2 || yy2arr2 { @@ -2641,17 +2642,17 @@ func (x *KubeletConfiguration) CodecEncodeSelf(e *codec1978.Encoder) { _ = yym227 if false { } else { - r.EncodeBool(bool(x.ReconcileCIDR)) + r.EncodeUint(uint64(x.MaxOpenFiles)) } } else { z.EncSendContainerState(codecSelfer_containerMapKey1234) - r.EncodeString(codecSelferC_UTF81234, string("reconcileCIDR")) + r.EncodeString(codecSelferC_UTF81234, string("maxOpenFiles")) z.EncSendContainerState(codecSelfer_containerMapValue1234) yym228 := z.EncBinary() _ = yym228 if false { } else { - r.EncodeBool(bool(x.ReconcileCIDR)) + r.EncodeUint(uint64(x.MaxOpenFiles)) } } if yyr2 || yy2arr2 { @@ -2660,17 +2661,17 @@ func (x *KubeletConfiguration) CodecEncodeSelf(e *codec1978.Encoder) { _ = yym230 if false { } else { - r.EncodeBool(bool(x.RegisterSchedulable)) + r.EncodeBool(bool(x.ReconcileCIDR)) } } else { z.EncSendContainerState(codecSelfer_containerMapKey1234) - r.EncodeString(codecSelferC_UTF81234, string("registerSchedulable")) + r.EncodeString(codecSelferC_UTF81234, string("reconcileCIDR")) z.EncSendContainerState(codecSelfer_containerMapValue1234) yym231 := z.EncBinary() _ = yym231 if false { } else { - r.EncodeBool(bool(x.RegisterSchedulable)) + r.EncodeBool(bool(x.ReconcileCIDR)) } } if yyr2 || yy2arr2 { @@ -2679,17 +2680,17 @@ func (x *KubeletConfiguration) CodecEncodeSelf(e *codec1978.Encoder) { _ = yym233 if false { } else { - r.EncodeString(codecSelferC_UTF81234, string(x.ContentType)) + r.EncodeBool(bool(x.RegisterSchedulable)) } } else { z.EncSendContainerState(codecSelfer_containerMapKey1234) - r.EncodeString(codecSelferC_UTF81234, string("contentType")) + r.EncodeString(codecSelferC_UTF81234, string("registerSchedulable")) z.EncSendContainerState(codecSelfer_containerMapValue1234) yym234 := z.EncBinary() _ = yym234 if false { } else { - r.EncodeString(codecSelferC_UTF81234, string(x.ContentType)) + r.EncodeBool(bool(x.RegisterSchedulable)) } } if yyr2 || yy2arr2 { @@ -2698,17 +2699,17 @@ func (x *KubeletConfiguration) CodecEncodeSelf(e *codec1978.Encoder) { _ = yym236 if false { } else { - r.EncodeFloat32(float32(x.KubeAPIQPS)) + r.EncodeString(codecSelferC_UTF81234, string(x.ContentType)) } } else { z.EncSendContainerState(codecSelfer_containerMapKey1234) - r.EncodeString(codecSelferC_UTF81234, string("kubeAPIQPS")) + r.EncodeString(codecSelferC_UTF81234, string("contentType")) z.EncSendContainerState(codecSelfer_containerMapValue1234) yym237 := z.EncBinary() _ = yym237 if false { } else { - r.EncodeFloat32(float32(x.KubeAPIQPS)) + r.EncodeString(codecSelferC_UTF81234, string(x.ContentType)) } } if yyr2 || yy2arr2 { @@ -2717,17 +2718,17 @@ func (x *KubeletConfiguration) CodecEncodeSelf(e *codec1978.Encoder) { _ = yym239 if false { } else { - r.EncodeInt(int64(x.KubeAPIBurst)) + r.EncodeFloat32(float32(x.KubeAPIQPS)) } } else { z.EncSendContainerState(codecSelfer_containerMapKey1234) - r.EncodeString(codecSelferC_UTF81234, string("kubeAPIBurst")) + r.EncodeString(codecSelferC_UTF81234, string("kubeAPIQPS")) z.EncSendContainerState(codecSelfer_containerMapValue1234) yym240 := z.EncBinary() _ = yym240 if false { } else { - r.EncodeInt(int64(x.KubeAPIBurst)) + r.EncodeFloat32(float32(x.KubeAPIQPS)) } } if yyr2 || yy2arr2 { @@ -2736,17 +2737,17 @@ func (x *KubeletConfiguration) CodecEncodeSelf(e *codec1978.Encoder) { _ = yym242 if false { } else { - r.EncodeBool(bool(x.SerializeImagePulls)) + r.EncodeInt(int64(x.KubeAPIBurst)) } } else { z.EncSendContainerState(codecSelfer_containerMapKey1234) - r.EncodeString(codecSelferC_UTF81234, string("serializeImagePulls")) + r.EncodeString(codecSelferC_UTF81234, string("kubeAPIBurst")) z.EncSendContainerState(codecSelfer_containerMapValue1234) yym243 := z.EncBinary() _ = yym243 if false { } else { - r.EncodeBool(bool(x.SerializeImagePulls)) + r.EncodeInt(int64(x.KubeAPIBurst)) } } if yyr2 || yy2arr2 { @@ -2754,6 +2755,25 @@ func (x *KubeletConfiguration) CodecEncodeSelf(e *codec1978.Encoder) { yym245 := z.EncBinary() _ = yym245 if false { + } else { + r.EncodeBool(bool(x.SerializeImagePulls)) + } + } else { + z.EncSendContainerState(codecSelfer_containerMapKey1234) + r.EncodeString(codecSelferC_UTF81234, string("serializeImagePulls")) + z.EncSendContainerState(codecSelfer_containerMapValue1234) + yym246 := z.EncBinary() + _ = yym246 + if false { + } else { + r.EncodeBool(bool(x.SerializeImagePulls)) + } + } + if yyr2 || yy2arr2 { + z.EncSendContainerState(codecSelfer_containerArrayElem1234) + yym248 := z.EncBinary() + _ = yym248 + if false { } else { r.EncodeBool(bool(x.ExperimentalFlannelOverlay)) } @@ -2761,8 +2781,8 @@ func (x *KubeletConfiguration) CodecEncodeSelf(e *codec1978.Encoder) { z.EncSendContainerState(codecSelfer_containerMapKey1234) r.EncodeString(codecSelferC_UTF81234, string("experimentalFlannelOverlay")) z.EncSendContainerState(codecSelfer_containerMapValue1234) - yym246 := z.EncBinary() - _ = yym246 + yym249 := z.EncBinary() + _ = yym249 if false { } else { r.EncodeBool(bool(x.ExperimentalFlannelOverlay)) @@ -2770,42 +2790,42 @@ func (x *KubeletConfiguration) CodecEncodeSelf(e *codec1978.Encoder) { } if yyr2 || yy2arr2 { z.EncSendContainerState(codecSelfer_containerArrayElem1234) - if yyq2[76] { - yy248 := &x.OutOfDiskTransitionFrequency - yym249 := z.EncBinary() - _ = yym249 + if yyq2[77] { + yy251 := &x.OutOfDiskTransitionFrequency + yym252 := z.EncBinary() + _ = yym252 if false { - } else if z.HasExtensions() && z.EncExt(yy248) { - } else if !yym249 && z.IsJSONHandle() { - z.EncJSONMarshal(yy248) + } else if z.HasExtensions() && z.EncExt(yy251) { + } else if !yym252 && z.IsJSONHandle() { + z.EncJSONMarshal(yy251) } else { - z.EncFallback(yy248) + z.EncFallback(yy251) } } else { r.EncodeNil() } } else { - if yyq2[76] { + if yyq2[77] { z.EncSendContainerState(codecSelfer_containerMapKey1234) r.EncodeString(codecSelferC_UTF81234, string("outOfDiskTransitionFrequency")) z.EncSendContainerState(codecSelfer_containerMapValue1234) - yy250 := &x.OutOfDiskTransitionFrequency - yym251 := z.EncBinary() - _ = yym251 + yy253 := &x.OutOfDiskTransitionFrequency + yym254 := z.EncBinary() + _ = yym254 if false { - } else if z.HasExtensions() && z.EncExt(yy250) { - } else if !yym251 && z.IsJSONHandle() { - z.EncJSONMarshal(yy250) + } else if z.HasExtensions() && z.EncExt(yy253) { + } else if !yym254 && z.IsJSONHandle() { + z.EncJSONMarshal(yy253) } else { - z.EncFallback(yy250) + z.EncFallback(yy253) } } } if yyr2 || yy2arr2 { z.EncSendContainerState(codecSelfer_containerArrayElem1234) - if yyq2[77] { - yym253 := z.EncBinary() - _ = yym253 + if yyq2[78] { + yym256 := z.EncBinary() + _ = yym256 if false { } else { r.EncodeString(codecSelferC_UTF81234, string(x.NodeIP)) @@ -2814,12 +2834,12 @@ func (x *KubeletConfiguration) CodecEncodeSelf(e *codec1978.Encoder) { r.EncodeString(codecSelferC_UTF81234, "") } } else { - if yyq2[77] { + if yyq2[78] { z.EncSendContainerState(codecSelfer_containerMapKey1234) r.EncodeString(codecSelferC_UTF81234, string("nodeIP")) z.EncSendContainerState(codecSelfer_containerMapValue1234) - yym254 := z.EncBinary() - _ = yym254 + yym257 := z.EncBinary() + _ = yym257 if false { } else { r.EncodeString(codecSelferC_UTF81234, string(x.NodeIP)) @@ -2831,8 +2851,8 @@ func (x *KubeletConfiguration) CodecEncodeSelf(e *codec1978.Encoder) { if x.NodeLabels == nil { r.EncodeNil() } else { - yym256 := z.EncBinary() - _ = yym256 + yym259 := z.EncBinary() + _ = yym259 if false { } else { z.F.EncMapStringStringV(x.NodeLabels, false, e) @@ -2845,8 +2865,8 @@ func (x *KubeletConfiguration) CodecEncodeSelf(e *codec1978.Encoder) { if x.NodeLabels == nil { r.EncodeNil() } else { - yym257 := z.EncBinary() - _ = yym257 + yym260 := z.EncBinary() + _ = yym260 if false { } else { z.F.EncMapStringStringV(x.NodeLabels, false, e) @@ -2855,8 +2875,8 @@ func (x *KubeletConfiguration) CodecEncodeSelf(e *codec1978.Encoder) { } if yyr2 || yy2arr2 { z.EncSendContainerState(codecSelfer_containerArrayElem1234) - yym259 := z.EncBinary() - _ = yym259 + yym262 := z.EncBinary() + _ = yym262 if false { } else { r.EncodeString(codecSelferC_UTF81234, string(x.NonMasqueradeCIDR)) @@ -2865,8 +2885,8 @@ func (x *KubeletConfiguration) CodecEncodeSelf(e *codec1978.Encoder) { z.EncSendContainerState(codecSelfer_containerMapKey1234) r.EncodeString(codecSelferC_UTF81234, string("nonMasqueradeCIDR")) z.EncSendContainerState(codecSelfer_containerMapValue1234) - yym260 := z.EncBinary() - _ = yym260 + yym263 := z.EncBinary() + _ = yym263 if false { } else { r.EncodeString(codecSelferC_UTF81234, string(x.NonMasqueradeCIDR)) @@ -2874,8 +2894,8 @@ func (x *KubeletConfiguration) CodecEncodeSelf(e *codec1978.Encoder) { } if yyr2 || yy2arr2 { z.EncSendContainerState(codecSelfer_containerArrayElem1234) - yym262 := z.EncBinary() - _ = yym262 + yym265 := z.EncBinary() + _ = yym265 if false { } else { r.EncodeBool(bool(x.EnableCustomMetrics)) @@ -2884,38 +2904,13 @@ func (x *KubeletConfiguration) CodecEncodeSelf(e *codec1978.Encoder) { z.EncSendContainerState(codecSelfer_containerMapKey1234) r.EncodeString(codecSelferC_UTF81234, string("enableCustomMetrics")) z.EncSendContainerState(codecSelfer_containerMapValue1234) - yym263 := z.EncBinary() - _ = yym263 + yym266 := z.EncBinary() + _ = yym266 if false { } else { r.EncodeBool(bool(x.EnableCustomMetrics)) } } - if yyr2 || yy2arr2 { - z.EncSendContainerState(codecSelfer_containerArrayElem1234) - if yyq2[81] { - yym265 := z.EncBinary() - _ = yym265 - if false { - } else { - r.EncodeString(codecSelferC_UTF81234, string(x.EvictionHard)) - } - } else { - r.EncodeString(codecSelferC_UTF81234, "") - } - } else { - if yyq2[81] { - z.EncSendContainerState(codecSelfer_containerMapKey1234) - r.EncodeString(codecSelferC_UTF81234, string("evictionHard")) - z.EncSendContainerState(codecSelfer_containerMapValue1234) - yym266 := z.EncBinary() - _ = yym266 - if false { - } else { - r.EncodeString(codecSelferC_UTF81234, string(x.EvictionHard)) - } - } - } if yyr2 || yy2arr2 { z.EncSendContainerState(codecSelfer_containerArrayElem1234) if yyq2[82] { @@ -2923,7 +2918,7 @@ func (x *KubeletConfiguration) CodecEncodeSelf(e *codec1978.Encoder) { _ = yym268 if false { } else { - r.EncodeString(codecSelferC_UTF81234, string(x.EvictionSoft)) + r.EncodeString(codecSelferC_UTF81234, string(x.EvictionHard)) } } else { r.EncodeString(codecSelferC_UTF81234, "") @@ -2931,13 +2926,13 @@ func (x *KubeletConfiguration) CodecEncodeSelf(e *codec1978.Encoder) { } else { if yyq2[82] { z.EncSendContainerState(codecSelfer_containerMapKey1234) - r.EncodeString(codecSelferC_UTF81234, string("evictionSoft")) + r.EncodeString(codecSelferC_UTF81234, string("evictionHard")) z.EncSendContainerState(codecSelfer_containerMapValue1234) yym269 := z.EncBinary() _ = yym269 if false { } else { - r.EncodeString(codecSelferC_UTF81234, string(x.EvictionSoft)) + r.EncodeString(codecSelferC_UTF81234, string(x.EvictionHard)) } } } @@ -2948,7 +2943,7 @@ func (x *KubeletConfiguration) CodecEncodeSelf(e *codec1978.Encoder) { _ = yym271 if false { } else { - r.EncodeString(codecSelferC_UTF81234, string(x.EvictionSoftGracePeriod)) + r.EncodeString(codecSelferC_UTF81234, string(x.EvictionSoft)) } } else { r.EncodeString(codecSelferC_UTF81234, "") @@ -2956,11 +2951,36 @@ func (x *KubeletConfiguration) CodecEncodeSelf(e *codec1978.Encoder) { } else { if yyq2[83] { z.EncSendContainerState(codecSelfer_containerMapKey1234) - r.EncodeString(codecSelferC_UTF81234, string("evictionSoftGracePeriod")) + r.EncodeString(codecSelferC_UTF81234, string("evictionSoft")) z.EncSendContainerState(codecSelfer_containerMapValue1234) yym272 := z.EncBinary() _ = yym272 if false { + } else { + r.EncodeString(codecSelferC_UTF81234, string(x.EvictionSoft)) + } + } + } + if yyr2 || yy2arr2 { + z.EncSendContainerState(codecSelfer_containerArrayElem1234) + if yyq2[84] { + yym274 := z.EncBinary() + _ = yym274 + if false { + } else { + r.EncodeString(codecSelferC_UTF81234, string(x.EvictionSoftGracePeriod)) + } + } else { + r.EncodeString(codecSelferC_UTF81234, "") + } + } else { + if yyq2[84] { + z.EncSendContainerState(codecSelfer_containerMapKey1234) + r.EncodeString(codecSelferC_UTF81234, string("evictionSoftGracePeriod")) + z.EncSendContainerState(codecSelfer_containerMapValue1234) + yym275 := z.EncBinary() + _ = yym275 + if false { } else { r.EncodeString(codecSelferC_UTF81234, string(x.EvictionSoftGracePeriod)) } @@ -2968,34 +2988,59 @@ func (x *KubeletConfiguration) CodecEncodeSelf(e *codec1978.Encoder) { } if yyr2 || yy2arr2 { z.EncSendContainerState(codecSelfer_containerArrayElem1234) - if yyq2[84] { - yy274 := &x.EvictionPressureTransitionPeriod - yym275 := z.EncBinary() - _ = yym275 + if yyq2[85] { + yy277 := &x.EvictionPressureTransitionPeriod + yym278 := z.EncBinary() + _ = yym278 if false { - } else if z.HasExtensions() && z.EncExt(yy274) { - } else if !yym275 && z.IsJSONHandle() { - z.EncJSONMarshal(yy274) + } else if z.HasExtensions() && z.EncExt(yy277) { + } else if !yym278 && z.IsJSONHandle() { + z.EncJSONMarshal(yy277) } else { - z.EncFallback(yy274) + z.EncFallback(yy277) } } else { r.EncodeNil() } } else { - if yyq2[84] { + if yyq2[85] { z.EncSendContainerState(codecSelfer_containerMapKey1234) r.EncodeString(codecSelferC_UTF81234, string("evictionPressureTransitionPeriod")) z.EncSendContainerState(codecSelfer_containerMapValue1234) - yy276 := &x.EvictionPressureTransitionPeriod - yym277 := z.EncBinary() - _ = yym277 + yy279 := &x.EvictionPressureTransitionPeriod + yym280 := z.EncBinary() + _ = yym280 if false { - } else if z.HasExtensions() && z.EncExt(yy276) { - } else if !yym277 && z.IsJSONHandle() { - z.EncJSONMarshal(yy276) + } else if z.HasExtensions() && z.EncExt(yy279) { + } else if !yym280 && z.IsJSONHandle() { + z.EncJSONMarshal(yy279) } else { - z.EncFallback(yy276) + z.EncFallback(yy279) + } + } + } + if yyr2 || yy2arr2 { + z.EncSendContainerState(codecSelfer_containerArrayElem1234) + if yyq2[86] { + yym282 := z.EncBinary() + _ = yym282 + if false { + } else { + r.EncodeInt(int64(x.EvictionMaxPodGracePeriod)) + } + } else { + r.EncodeInt(0) + } + } else { + if yyq2[86] { + z.EncSendContainerState(codecSelfer_containerMapKey1234) + r.EncodeString(codecSelferC_UTF81234, string("evictionMaxPodGracePeriod")) + z.EncSendContainerState(codecSelfer_containerMapValue1234) + yym283 := z.EncBinary() + _ = yym283 + if false { + } else { + r.EncodeInt(int64(x.EvictionMaxPodGracePeriod)) } } } @@ -3480,6 +3525,12 @@ func (x *KubeletConfiguration) codecDecodeSelfFromMap(l int, d *codec1978.Decode } else { x.LockFilePath = string(r.DecodeString()) } + case "exitOnLockContention": + if r.TryDecodeAsNil() { + x.ExitOnLockContention = false + } else { + x.ExitOnLockContention = bool(r.DecodeBool()) + } case "configureCbr0": if r.TryDecodeAsNil() { x.ConfigureCBR0 = false @@ -3592,15 +3643,15 @@ func (x *KubeletConfiguration) codecDecodeSelfFromMap(l int, d *codec1978.Decode if r.TryDecodeAsNil() { x.OutOfDiskTransitionFrequency = pkg1_unversioned.Duration{} } else { - yyv88 := &x.OutOfDiskTransitionFrequency - yym89 := z.DecBinary() - _ = yym89 + yyv89 := &x.OutOfDiskTransitionFrequency + yym90 := z.DecBinary() + _ = yym90 if false { - } else if z.HasExtensions() && z.DecExt(yyv88) { - } else if !yym89 && z.IsJSONHandle() { - z.DecJSONUnmarshal(yyv88) + } else if z.HasExtensions() && z.DecExt(yyv89) { + } else if !yym90 && z.IsJSONHandle() { + z.DecJSONUnmarshal(yyv89) } else { - z.DecFallback(yyv88, false) + z.DecFallback(yyv89, false) } } case "nodeIP": @@ -3613,12 +3664,12 @@ func (x *KubeletConfiguration) codecDecodeSelfFromMap(l int, d *codec1978.Decode if r.TryDecodeAsNil() { x.NodeLabels = nil } else { - yyv91 := &x.NodeLabels - yym92 := z.DecBinary() - _ = yym92 + yyv92 := &x.NodeLabels + yym93 := z.DecBinary() + _ = yym93 if false { } else { - z.F.DecMapStringStringX(yyv91, false, d) + z.F.DecMapStringStringX(yyv92, false, d) } } case "nonMasqueradeCIDR": @@ -3655,17 +3706,23 @@ func (x *KubeletConfiguration) codecDecodeSelfFromMap(l int, d *codec1978.Decode if r.TryDecodeAsNil() { x.EvictionPressureTransitionPeriod = pkg1_unversioned.Duration{} } else { - yyv98 := &x.EvictionPressureTransitionPeriod - yym99 := z.DecBinary() - _ = yym99 + yyv99 := &x.EvictionPressureTransitionPeriod + yym100 := z.DecBinary() + _ = yym100 if false { - } else if z.HasExtensions() && z.DecExt(yyv98) { - } else if !yym99 && z.IsJSONHandle() { - z.DecJSONUnmarshal(yyv98) + } else if z.HasExtensions() && z.DecExt(yyv99) { + } else if !yym100 && z.IsJSONHandle() { + z.DecJSONUnmarshal(yyv99) } else { - z.DecFallback(yyv98, false) + z.DecFallback(yyv99, false) } } + case "evictionMaxPodGracePeriod": + if r.TryDecodeAsNil() { + x.EvictionMaxPodGracePeriod = 0 + } else { + x.EvictionMaxPodGracePeriod = int32(r.DecodeInt(32)) + } default: z.DecStructFieldNotFound(-1, yys3) } // end switch yys3 @@ -3677,16 +3734,16 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco var h codecSelfer1234 z, r := codec1978.GenHelperDecoder(d) _, _, _ = h, z, r - var yyj100 int - var yyb100 bool - var yyhl100 bool = l >= 0 - yyj100++ - if yyhl100 { - yyb100 = yyj100 > l + var yyj102 int + var yyb102 bool + var yyhl102 bool = l >= 0 + yyj102++ + if yyhl102 { + yyb102 = yyj102 > l } else { - yyb100 = r.CheckBreak() + yyb102 = r.CheckBreak() } - if yyb100 { + if yyb102 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -3696,13 +3753,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.Config = string(r.DecodeString()) } - yyj100++ - if yyhl100 { - yyb100 = yyj100 > l + yyj102++ + if yyhl102 { + yyb102 = yyj102 > l } else { - yyb100 = r.CheckBreak() + yyb102 = r.CheckBreak() } - if yyb100 { + if yyb102 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -3710,32 +3767,7 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco if r.TryDecodeAsNil() { x.SyncFrequency = pkg1_unversioned.Duration{} } else { - yyv102 := &x.SyncFrequency - yym103 := z.DecBinary() - _ = yym103 - if false { - } else if z.HasExtensions() && z.DecExt(yyv102) { - } else if !yym103 && z.IsJSONHandle() { - z.DecJSONUnmarshal(yyv102) - } else { - z.DecFallback(yyv102, false) - } - } - yyj100++ - if yyhl100 { - yyb100 = yyj100 > l - } else { - yyb100 = r.CheckBreak() - } - if yyb100 { - z.DecSendContainerState(codecSelfer_containerArrayEnd1234) - return - } - z.DecSendContainerState(codecSelfer_containerArrayElem1234) - if r.TryDecodeAsNil() { - x.FileCheckFrequency = pkg1_unversioned.Duration{} - } else { - yyv104 := &x.FileCheckFrequency + yyv104 := &x.SyncFrequency yym105 := z.DecBinary() _ = yym105 if false { @@ -3746,21 +3778,21 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco z.DecFallback(yyv104, false) } } - yyj100++ - if yyhl100 { - yyb100 = yyj100 > l + yyj102++ + if yyhl102 { + yyb102 = yyj102 > l } else { - yyb100 = r.CheckBreak() + yyb102 = r.CheckBreak() } - if yyb100 { + if yyb102 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } z.DecSendContainerState(codecSelfer_containerArrayElem1234) if r.TryDecodeAsNil() { - x.HTTPCheckFrequency = pkg1_unversioned.Duration{} + x.FileCheckFrequency = pkg1_unversioned.Duration{} } else { - yyv106 := &x.HTTPCheckFrequency + yyv106 := &x.FileCheckFrequency yym107 := z.DecBinary() _ = yym107 if false { @@ -3771,13 +3803,38 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco z.DecFallback(yyv106, false) } } - yyj100++ - if yyhl100 { - yyb100 = yyj100 > l + yyj102++ + if yyhl102 { + yyb102 = yyj102 > l } else { - yyb100 = r.CheckBreak() + yyb102 = r.CheckBreak() } - if yyb100 { + if yyb102 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) + return + } + z.DecSendContainerState(codecSelfer_containerArrayElem1234) + if r.TryDecodeAsNil() { + x.HTTPCheckFrequency = pkg1_unversioned.Duration{} + } else { + yyv108 := &x.HTTPCheckFrequency + yym109 := z.DecBinary() + _ = yym109 + if false { + } else if z.HasExtensions() && z.DecExt(yyv108) { + } else if !yym109 && z.IsJSONHandle() { + z.DecJSONUnmarshal(yyv108) + } else { + z.DecFallback(yyv108, false) + } + } + yyj102++ + if yyhl102 { + yyb102 = yyj102 > l + } else { + yyb102 = r.CheckBreak() + } + if yyb102 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -3787,13 +3844,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.ManifestURL = string(r.DecodeString()) } - yyj100++ - if yyhl100 { - yyb100 = yyj100 > l + yyj102++ + if yyhl102 { + yyb102 = yyj102 > l } else { - yyb100 = r.CheckBreak() + yyb102 = r.CheckBreak() } - if yyb100 { + if yyb102 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -3803,13 +3860,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.ManifestURLHeader = string(r.DecodeString()) } - yyj100++ - if yyhl100 { - yyb100 = yyj100 > l + yyj102++ + if yyhl102 { + yyb102 = yyj102 > l } else { - yyb100 = r.CheckBreak() + yyb102 = r.CheckBreak() } - if yyb100 { + if yyb102 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -3819,13 +3876,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.EnableServer = bool(r.DecodeBool()) } - yyj100++ - if yyhl100 { - yyb100 = yyj100 > l + yyj102++ + if yyhl102 { + yyb102 = yyj102 > l } else { - yyb100 = r.CheckBreak() + yyb102 = r.CheckBreak() } - if yyb100 { + if yyb102 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -3835,13 +3892,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.Address = string(r.DecodeString()) } - yyj100++ - if yyhl100 { - yyb100 = yyj100 > l + yyj102++ + if yyhl102 { + yyb102 = yyj102 > l } else { - yyb100 = r.CheckBreak() + yyb102 = r.CheckBreak() } - if yyb100 { + if yyb102 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -3851,13 +3908,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.Port = uint(r.DecodeUint(codecSelferBitsize1234)) } - yyj100++ - if yyhl100 { - yyb100 = yyj100 > l + yyj102++ + if yyhl102 { + yyb102 = yyj102 > l } else { - yyb100 = r.CheckBreak() + yyb102 = r.CheckBreak() } - if yyb100 { + if yyb102 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -3867,13 +3924,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.ReadOnlyPort = uint(r.DecodeUint(codecSelferBitsize1234)) } - yyj100++ - if yyhl100 { - yyb100 = yyj100 > l + yyj102++ + if yyhl102 { + yyb102 = yyj102 > l } else { - yyb100 = r.CheckBreak() + yyb102 = r.CheckBreak() } - if yyb100 { + if yyb102 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -3883,13 +3940,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.TLSCertFile = string(r.DecodeString()) } - yyj100++ - if yyhl100 { - yyb100 = yyj100 > l + yyj102++ + if yyhl102 { + yyb102 = yyj102 > l } else { - yyb100 = r.CheckBreak() + yyb102 = r.CheckBreak() } - if yyb100 { + if yyb102 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -3899,13 +3956,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.TLSPrivateKeyFile = string(r.DecodeString()) } - yyj100++ - if yyhl100 { - yyb100 = yyj100 > l + yyj102++ + if yyhl102 { + yyb102 = yyj102 > l } else { - yyb100 = r.CheckBreak() + yyb102 = r.CheckBreak() } - if yyb100 { + if yyb102 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -3915,13 +3972,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.CertDirectory = string(r.DecodeString()) } - yyj100++ - if yyhl100 { - yyb100 = yyj100 > l + yyj102++ + if yyhl102 { + yyb102 = yyj102 > l } else { - yyb100 = r.CheckBreak() + yyb102 = r.CheckBreak() } - if yyb100 { + if yyb102 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -3931,13 +3988,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.HostnameOverride = string(r.DecodeString()) } - yyj100++ - if yyhl100 { - yyb100 = yyj100 > l + yyj102++ + if yyhl102 { + yyb102 = yyj102 > l } else { - yyb100 = r.CheckBreak() + yyb102 = r.CheckBreak() } - if yyb100 { + if yyb102 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -3947,13 +4004,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.PodInfraContainerImage = string(r.DecodeString()) } - yyj100++ - if yyhl100 { - yyb100 = yyj100 > l + yyj102++ + if yyhl102 { + yyb102 = yyj102 > l } else { - yyb100 = r.CheckBreak() + yyb102 = r.CheckBreak() } - if yyb100 { + if yyb102 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -3963,13 +4020,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.DockerEndpoint = string(r.DecodeString()) } - yyj100++ - if yyhl100 { - yyb100 = yyj100 > l + yyj102++ + if yyhl102 { + yyb102 = yyj102 > l } else { - yyb100 = r.CheckBreak() + yyb102 = r.CheckBreak() } - if yyb100 { + if yyb102 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -3979,13 +4036,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.RootDirectory = string(r.DecodeString()) } - yyj100++ - if yyhl100 { - yyb100 = yyj100 > l + yyj102++ + if yyhl102 { + yyb102 = yyj102 > l } else { - yyb100 = r.CheckBreak() + yyb102 = r.CheckBreak() } - if yyb100 { + if yyb102 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -3995,13 +4052,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.AllowPrivileged = bool(r.DecodeBool()) } - yyj100++ - if yyhl100 { - yyb100 = yyj100 > l + yyj102++ + if yyhl102 { + yyb102 = yyj102 > l } else { - yyb100 = r.CheckBreak() + yyb102 = r.CheckBreak() } - if yyb100 { + if yyb102 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -4011,13 +4068,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.HostNetworkSources = string(r.DecodeString()) } - yyj100++ - if yyhl100 { - yyb100 = yyj100 > l + yyj102++ + if yyhl102 { + yyb102 = yyj102 > l } else { - yyb100 = r.CheckBreak() + yyb102 = r.CheckBreak() } - if yyb100 { + if yyb102 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -4027,13 +4084,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.HostPIDSources = string(r.DecodeString()) } - yyj100++ - if yyhl100 { - yyb100 = yyj100 > l + yyj102++ + if yyhl102 { + yyb102 = yyj102 > l } else { - yyb100 = r.CheckBreak() + yyb102 = r.CheckBreak() } - if yyb100 { + if yyb102 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -4043,13 +4100,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.HostIPCSources = string(r.DecodeString()) } - yyj100++ - if yyhl100 { - yyb100 = yyj100 > l + yyj102++ + if yyhl102 { + yyb102 = yyj102 > l } else { - yyb100 = r.CheckBreak() + yyb102 = r.CheckBreak() } - if yyb100 { + if yyb102 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -4059,13 +4116,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.RegistryPullQPS = float64(r.DecodeFloat(false)) } - yyj100++ - if yyhl100 { - yyb100 = yyj100 > l + yyj102++ + if yyhl102 { + yyb102 = yyj102 > l } else { - yyb100 = r.CheckBreak() + yyb102 = r.CheckBreak() } - if yyb100 { + if yyb102 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -4075,13 +4132,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.RegistryBurst = int32(r.DecodeInt(32)) } - yyj100++ - if yyhl100 { - yyb100 = yyj100 > l + yyj102++ + if yyhl102 { + yyb102 = yyj102 > l } else { - yyb100 = r.CheckBreak() + yyb102 = r.CheckBreak() } - if yyb100 { + if yyb102 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -4091,13 +4148,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.EventRecordQPS = float32(r.DecodeFloat(true)) } - yyj100++ - if yyhl100 { - yyb100 = yyj100 > l + yyj102++ + if yyhl102 { + yyb102 = yyj102 > l } else { - yyb100 = r.CheckBreak() + yyb102 = r.CheckBreak() } - if yyb100 { + if yyb102 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -4107,13 +4164,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.EventBurst = int32(r.DecodeInt(32)) } - yyj100++ - if yyhl100 { - yyb100 = yyj100 > l + yyj102++ + if yyhl102 { + yyb102 = yyj102 > l } else { - yyb100 = r.CheckBreak() + yyb102 = r.CheckBreak() } - if yyb100 { + if yyb102 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -4123,13 +4180,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.EnableDebuggingHandlers = bool(r.DecodeBool()) } - yyj100++ - if yyhl100 { - yyb100 = yyj100 > l + yyj102++ + if yyhl102 { + yyb102 = yyj102 > l } else { - yyb100 = r.CheckBreak() + yyb102 = r.CheckBreak() } - if yyb100 { + if yyb102 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -4137,24 +4194,24 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco if r.TryDecodeAsNil() { x.MinimumGCAge = pkg1_unversioned.Duration{} } else { - yyv130 := &x.MinimumGCAge - yym131 := z.DecBinary() - _ = yym131 + yyv132 := &x.MinimumGCAge + yym133 := z.DecBinary() + _ = yym133 if false { - } else if z.HasExtensions() && z.DecExt(yyv130) { - } else if !yym131 && z.IsJSONHandle() { - z.DecJSONUnmarshal(yyv130) + } else if z.HasExtensions() && z.DecExt(yyv132) { + } else if !yym133 && z.IsJSONHandle() { + z.DecJSONUnmarshal(yyv132) } else { - z.DecFallback(yyv130, false) + z.DecFallback(yyv132, false) } } - yyj100++ - if yyhl100 { - yyb100 = yyj100 > l + yyj102++ + if yyhl102 { + yyb102 = yyj102 > l } else { - yyb100 = r.CheckBreak() + yyb102 = r.CheckBreak() } - if yyb100 { + if yyb102 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -4164,13 +4221,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.MaxPerPodContainerCount = int32(r.DecodeInt(32)) } - yyj100++ - if yyhl100 { - yyb100 = yyj100 > l + yyj102++ + if yyhl102 { + yyb102 = yyj102 > l } else { - yyb100 = r.CheckBreak() + yyb102 = r.CheckBreak() } - if yyb100 { + if yyb102 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -4180,13 +4237,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.MaxContainerCount = int32(r.DecodeInt(32)) } - yyj100++ - if yyhl100 { - yyb100 = yyj100 > l + yyj102++ + if yyhl102 { + yyb102 = yyj102 > l } else { - yyb100 = r.CheckBreak() + yyb102 = r.CheckBreak() } - if yyb100 { + if yyb102 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -4196,13 +4253,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.CAdvisorPort = uint(r.DecodeUint(codecSelferBitsize1234)) } - yyj100++ - if yyhl100 { - yyb100 = yyj100 > l + yyj102++ + if yyhl102 { + yyb102 = yyj102 > l } else { - yyb100 = r.CheckBreak() + yyb102 = r.CheckBreak() } - if yyb100 { + if yyb102 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -4212,13 +4269,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.HealthzPort = int32(r.DecodeInt(32)) } - yyj100++ - if yyhl100 { - yyb100 = yyj100 > l + yyj102++ + if yyhl102 { + yyb102 = yyj102 > l } else { - yyb100 = r.CheckBreak() + yyb102 = r.CheckBreak() } - if yyb100 { + if yyb102 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -4228,13 +4285,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.HealthzBindAddress = string(r.DecodeString()) } - yyj100++ - if yyhl100 { - yyb100 = yyj100 > l + yyj102++ + if yyhl102 { + yyb102 = yyj102 > l } else { - yyb100 = r.CheckBreak() + yyb102 = r.CheckBreak() } - if yyb100 { + if yyb102 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -4244,13 +4301,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.OOMScoreAdj = int32(r.DecodeInt(32)) } - yyj100++ - if yyhl100 { - yyb100 = yyj100 > l + yyj102++ + if yyhl102 { + yyb102 = yyj102 > l } else { - yyb100 = r.CheckBreak() + yyb102 = r.CheckBreak() } - if yyb100 { + if yyb102 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -4260,13 +4317,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.RegisterNode = bool(r.DecodeBool()) } - yyj100++ - if yyhl100 { - yyb100 = yyj100 > l + yyj102++ + if yyhl102 { + yyb102 = yyj102 > l } else { - yyb100 = r.CheckBreak() + yyb102 = r.CheckBreak() } - if yyb100 { + if yyb102 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -4276,13 +4333,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.ClusterDomain = string(r.DecodeString()) } - yyj100++ - if yyhl100 { - yyb100 = yyj100 > l + yyj102++ + if yyhl102 { + yyb102 = yyj102 > l } else { - yyb100 = r.CheckBreak() + yyb102 = r.CheckBreak() } - if yyb100 { + if yyb102 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -4292,13 +4349,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.MasterServiceNamespace = string(r.DecodeString()) } - yyj100++ - if yyhl100 { - yyb100 = yyj100 > l + yyj102++ + if yyhl102 { + yyb102 = yyj102 > l } else { - yyb100 = r.CheckBreak() + yyb102 = r.CheckBreak() } - if yyb100 { + if yyb102 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -4308,13 +4365,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.ClusterDNS = string(r.DecodeString()) } - yyj100++ - if yyhl100 { - yyb100 = yyj100 > l + yyj102++ + if yyhl102 { + yyb102 = yyj102 > l } else { - yyb100 = r.CheckBreak() + yyb102 = r.CheckBreak() } - if yyb100 { + if yyb102 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -4322,32 +4379,7 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco if r.TryDecodeAsNil() { x.StreamingConnectionIdleTimeout = pkg1_unversioned.Duration{} } else { - yyv142 := &x.StreamingConnectionIdleTimeout - yym143 := z.DecBinary() - _ = yym143 - if false { - } else if z.HasExtensions() && z.DecExt(yyv142) { - } else if !yym143 && z.IsJSONHandle() { - z.DecJSONUnmarshal(yyv142) - } else { - z.DecFallback(yyv142, false) - } - } - yyj100++ - if yyhl100 { - yyb100 = yyj100 > l - } else { - yyb100 = r.CheckBreak() - } - if yyb100 { - z.DecSendContainerState(codecSelfer_containerArrayEnd1234) - return - } - z.DecSendContainerState(codecSelfer_containerArrayElem1234) - if r.TryDecodeAsNil() { - x.NodeStatusUpdateFrequency = pkg1_unversioned.Duration{} - } else { - yyv144 := &x.NodeStatusUpdateFrequency + yyv144 := &x.StreamingConnectionIdleTimeout yym145 := z.DecBinary() _ = yym145 if false { @@ -4358,21 +4390,21 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco z.DecFallback(yyv144, false) } } - yyj100++ - if yyhl100 { - yyb100 = yyj100 > l + yyj102++ + if yyhl102 { + yyb102 = yyj102 > l } else { - yyb100 = r.CheckBreak() + yyb102 = r.CheckBreak() } - if yyb100 { + if yyb102 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } z.DecSendContainerState(codecSelfer_containerArrayElem1234) if r.TryDecodeAsNil() { - x.ImageMinimumGCAge = pkg1_unversioned.Duration{} + x.NodeStatusUpdateFrequency = pkg1_unversioned.Duration{} } else { - yyv146 := &x.ImageMinimumGCAge + yyv146 := &x.NodeStatusUpdateFrequency yym147 := z.DecBinary() _ = yym147 if false { @@ -4383,13 +4415,38 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco z.DecFallback(yyv146, false) } } - yyj100++ - if yyhl100 { - yyb100 = yyj100 > l + yyj102++ + if yyhl102 { + yyb102 = yyj102 > l } else { - yyb100 = r.CheckBreak() + yyb102 = r.CheckBreak() } - if yyb100 { + if yyb102 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) + return + } + z.DecSendContainerState(codecSelfer_containerArrayElem1234) + if r.TryDecodeAsNil() { + x.ImageMinimumGCAge = pkg1_unversioned.Duration{} + } else { + yyv148 := &x.ImageMinimumGCAge + yym149 := z.DecBinary() + _ = yym149 + if false { + } else if z.HasExtensions() && z.DecExt(yyv148) { + } else if !yym149 && z.IsJSONHandle() { + z.DecJSONUnmarshal(yyv148) + } else { + z.DecFallback(yyv148, false) + } + } + yyj102++ + if yyhl102 { + yyb102 = yyj102 > l + } else { + yyb102 = r.CheckBreak() + } + if yyb102 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -4399,13 +4456,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.ImageGCHighThresholdPercent = int32(r.DecodeInt(32)) } - yyj100++ - if yyhl100 { - yyb100 = yyj100 > l + yyj102++ + if yyhl102 { + yyb102 = yyj102 > l } else { - yyb100 = r.CheckBreak() + yyb102 = r.CheckBreak() } - if yyb100 { + if yyb102 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -4415,13 +4472,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.ImageGCLowThresholdPercent = int32(r.DecodeInt(32)) } - yyj100++ - if yyhl100 { - yyb100 = yyj100 > l + yyj102++ + if yyhl102 { + yyb102 = yyj102 > l } else { - yyb100 = r.CheckBreak() + yyb102 = r.CheckBreak() } - if yyb100 { + if yyb102 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -4431,13 +4488,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.LowDiskSpaceThresholdMB = int32(r.DecodeInt(32)) } - yyj100++ - if yyhl100 { - yyb100 = yyj100 > l + yyj102++ + if yyhl102 { + yyb102 = yyj102 > l } else { - yyb100 = r.CheckBreak() + yyb102 = r.CheckBreak() } - if yyb100 { + if yyb102 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -4445,24 +4502,24 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco if r.TryDecodeAsNil() { x.VolumeStatsAggPeriod = pkg1_unversioned.Duration{} } else { - yyv151 := &x.VolumeStatsAggPeriod - yym152 := z.DecBinary() - _ = yym152 + yyv153 := &x.VolumeStatsAggPeriod + yym154 := z.DecBinary() + _ = yym154 if false { - } else if z.HasExtensions() && z.DecExt(yyv151) { - } else if !yym152 && z.IsJSONHandle() { - z.DecJSONUnmarshal(yyv151) + } else if z.HasExtensions() && z.DecExt(yyv153) { + } else if !yym154 && z.IsJSONHandle() { + z.DecJSONUnmarshal(yyv153) } else { - z.DecFallback(yyv151, false) + z.DecFallback(yyv153, false) } } - yyj100++ - if yyhl100 { - yyb100 = yyj100 > l + yyj102++ + if yyhl102 { + yyb102 = yyj102 > l } else { - yyb100 = r.CheckBreak() + yyb102 = r.CheckBreak() } - if yyb100 { + if yyb102 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -4472,13 +4529,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.NetworkPluginName = string(r.DecodeString()) } - yyj100++ - if yyhl100 { - yyb100 = yyj100 > l + yyj102++ + if yyhl102 { + yyb102 = yyj102 > l } else { - yyb100 = r.CheckBreak() + yyb102 = r.CheckBreak() } - if yyb100 { + if yyb102 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -4488,13 +4545,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.NetworkPluginDir = string(r.DecodeString()) } - yyj100++ - if yyhl100 { - yyb100 = yyj100 > l + yyj102++ + if yyhl102 { + yyb102 = yyj102 > l } else { - yyb100 = r.CheckBreak() + yyb102 = r.CheckBreak() } - if yyb100 { + if yyb102 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -4504,13 +4561,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.VolumePluginDir = string(r.DecodeString()) } - yyj100++ - if yyhl100 { - yyb100 = yyj100 > l + yyj102++ + if yyhl102 { + yyb102 = yyj102 > l } else { - yyb100 = r.CheckBreak() + yyb102 = r.CheckBreak() } - if yyb100 { + if yyb102 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -4520,13 +4577,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.CloudProvider = string(r.DecodeString()) } - yyj100++ - if yyhl100 { - yyb100 = yyj100 > l + yyj102++ + if yyhl102 { + yyb102 = yyj102 > l } else { - yyb100 = r.CheckBreak() + yyb102 = r.CheckBreak() } - if yyb100 { + if yyb102 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -4536,13 +4593,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.CloudConfigFile = string(r.DecodeString()) } - yyj100++ - if yyhl100 { - yyb100 = yyj100 > l + yyj102++ + if yyhl102 { + yyb102 = yyj102 > l } else { - yyb100 = r.CheckBreak() + yyb102 = r.CheckBreak() } - if yyb100 { + if yyb102 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -4552,13 +4609,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.KubeletCgroups = string(r.DecodeString()) } - yyj100++ - if yyhl100 { - yyb100 = yyj100 > l + yyj102++ + if yyhl102 { + yyb102 = yyj102 > l } else { - yyb100 = r.CheckBreak() + yyb102 = r.CheckBreak() } - if yyb100 { + if yyb102 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -4568,13 +4625,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.RuntimeCgroups = string(r.DecodeString()) } - yyj100++ - if yyhl100 { - yyb100 = yyj100 > l + yyj102++ + if yyhl102 { + yyb102 = yyj102 > l } else { - yyb100 = r.CheckBreak() + yyb102 = r.CheckBreak() } - if yyb100 { + if yyb102 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -4584,13 +4641,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.SystemCgroups = string(r.DecodeString()) } - yyj100++ - if yyhl100 { - yyb100 = yyj100 > l + yyj102++ + if yyhl102 { + yyb102 = yyj102 > l } else { - yyb100 = r.CheckBreak() + yyb102 = r.CheckBreak() } - if yyb100 { + if yyb102 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -4600,13 +4657,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.CgroupRoot = string(r.DecodeString()) } - yyj100++ - if yyhl100 { - yyb100 = yyj100 > l + yyj102++ + if yyhl102 { + yyb102 = yyj102 > l } else { - yyb100 = r.CheckBreak() + yyb102 = r.CheckBreak() } - if yyb100 { + if yyb102 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -4616,13 +4673,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.ContainerRuntime = string(r.DecodeString()) } - yyj100++ - if yyhl100 { - yyb100 = yyj100 > l + yyj102++ + if yyhl102 { + yyb102 = yyj102 > l } else { - yyb100 = r.CheckBreak() + yyb102 = r.CheckBreak() } - if yyb100 { + if yyb102 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -4632,13 +4689,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.RktPath = string(r.DecodeString()) } - yyj100++ - if yyhl100 { - yyb100 = yyj100 > l + yyj102++ + if yyhl102 { + yyb102 = yyj102 > l } else { - yyb100 = r.CheckBreak() + yyb102 = r.CheckBreak() } - if yyb100 { + if yyb102 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -4648,13 +4705,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.RktAPIEndpoint = string(r.DecodeString()) } - yyj100++ - if yyhl100 { - yyb100 = yyj100 > l + yyj102++ + if yyhl102 { + yyb102 = yyj102 > l } else { - yyb100 = r.CheckBreak() + yyb102 = r.CheckBreak() } - if yyb100 { + if yyb102 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -4664,13 +4721,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.RktStage1Image = string(r.DecodeString()) } - yyj100++ - if yyhl100 { - yyb100 = yyj100 > l + yyj102++ + if yyhl102 { + yyb102 = yyj102 > l } else { - yyb100 = r.CheckBreak() + yyb102 = r.CheckBreak() } - if yyb100 { + if yyb102 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -4680,13 +4737,29 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.LockFilePath = string(r.DecodeString()) } - yyj100++ - if yyhl100 { - yyb100 = yyj100 > l + yyj102++ + if yyhl102 { + yyb102 = yyj102 > l } else { - yyb100 = r.CheckBreak() + yyb102 = r.CheckBreak() } - if yyb100 { + if yyb102 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) + return + } + z.DecSendContainerState(codecSelfer_containerArrayElem1234) + if r.TryDecodeAsNil() { + x.ExitOnLockContention = false + } else { + x.ExitOnLockContention = bool(r.DecodeBool()) + } + yyj102++ + if yyhl102 { + yyb102 = yyj102 > l + } else { + yyb102 = r.CheckBreak() + } + if yyb102 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -4696,13 +4769,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.ConfigureCBR0 = bool(r.DecodeBool()) } - yyj100++ - if yyhl100 { - yyb100 = yyj100 > l + yyj102++ + if yyhl102 { + yyb102 = yyj102 > l } else { - yyb100 = r.CheckBreak() + yyb102 = r.CheckBreak() } - if yyb100 { + if yyb102 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -4712,13 +4785,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.HairpinMode = string(r.DecodeString()) } - yyj100++ - if yyhl100 { - yyb100 = yyj100 > l + yyj102++ + if yyhl102 { + yyb102 = yyj102 > l } else { - yyb100 = r.CheckBreak() + yyb102 = r.CheckBreak() } - if yyb100 { + if yyb102 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -4728,13 +4801,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.BabysitDaemons = bool(r.DecodeBool()) } - yyj100++ - if yyhl100 { - yyb100 = yyj100 > l + yyj102++ + if yyhl102 { + yyb102 = yyj102 > l } else { - yyb100 = r.CheckBreak() + yyb102 = r.CheckBreak() } - if yyb100 { + if yyb102 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -4744,13 +4817,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.MaxPods = int32(r.DecodeInt(32)) } - yyj100++ - if yyhl100 { - yyb100 = yyj100 > l + yyj102++ + if yyhl102 { + yyb102 = yyj102 > l } else { - yyb100 = r.CheckBreak() + yyb102 = r.CheckBreak() } - if yyb100 { + if yyb102 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -4760,13 +4833,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.NvidiaGPUs = int32(r.DecodeInt(32)) } - yyj100++ - if yyhl100 { - yyb100 = yyj100 > l + yyj102++ + if yyhl102 { + yyb102 = yyj102 > l } else { - yyb100 = r.CheckBreak() + yyb102 = r.CheckBreak() } - if yyb100 { + if yyb102 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -4776,13 +4849,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.DockerExecHandlerName = string(r.DecodeString()) } - yyj100++ - if yyhl100 { - yyb100 = yyj100 > l + yyj102++ + if yyhl102 { + yyb102 = yyj102 > l } else { - yyb100 = r.CheckBreak() + yyb102 = r.CheckBreak() } - if yyb100 { + if yyb102 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -4792,13 +4865,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.PodCIDR = string(r.DecodeString()) } - yyj100++ - if yyhl100 { - yyb100 = yyj100 > l + yyj102++ + if yyhl102 { + yyb102 = yyj102 > l } else { - yyb100 = r.CheckBreak() + yyb102 = r.CheckBreak() } - if yyb100 { + if yyb102 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -4808,13 +4881,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.ResolverConfig = string(r.DecodeString()) } - yyj100++ - if yyhl100 { - yyb100 = yyj100 > l + yyj102++ + if yyhl102 { + yyb102 = yyj102 > l } else { - yyb100 = r.CheckBreak() + yyb102 = r.CheckBreak() } - if yyb100 { + if yyb102 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -4824,13 +4897,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.CPUCFSQuota = bool(r.DecodeBool()) } - yyj100++ - if yyhl100 { - yyb100 = yyj100 > l + yyj102++ + if yyhl102 { + yyb102 = yyj102 > l } else { - yyb100 = r.CheckBreak() + yyb102 = r.CheckBreak() } - if yyb100 { + if yyb102 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -4840,13 +4913,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.Containerized = bool(r.DecodeBool()) } - yyj100++ - if yyhl100 { - yyb100 = yyj100 > l + yyj102++ + if yyhl102 { + yyb102 = yyj102 > l } else { - yyb100 = r.CheckBreak() + yyb102 = r.CheckBreak() } - if yyb100 { + if yyb102 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -4856,13 +4929,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.MaxOpenFiles = uint64(r.DecodeUint(64)) } - yyj100++ - if yyhl100 { - yyb100 = yyj100 > l + yyj102++ + if yyhl102 { + yyb102 = yyj102 > l } else { - yyb100 = r.CheckBreak() + yyb102 = r.CheckBreak() } - if yyb100 { + if yyb102 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -4872,13 +4945,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.ReconcileCIDR = bool(r.DecodeBool()) } - yyj100++ - if yyhl100 { - yyb100 = yyj100 > l + yyj102++ + if yyhl102 { + yyb102 = yyj102 > l } else { - yyb100 = r.CheckBreak() + yyb102 = r.CheckBreak() } - if yyb100 { + if yyb102 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -4888,13 +4961,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.RegisterSchedulable = bool(r.DecodeBool()) } - yyj100++ - if yyhl100 { - yyb100 = yyj100 > l + yyj102++ + if yyhl102 { + yyb102 = yyj102 > l } else { - yyb100 = r.CheckBreak() + yyb102 = r.CheckBreak() } - if yyb100 { + if yyb102 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -4904,13 +4977,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.ContentType = string(r.DecodeString()) } - yyj100++ - if yyhl100 { - yyb100 = yyj100 > l + yyj102++ + if yyhl102 { + yyb102 = yyj102 > l } else { - yyb100 = r.CheckBreak() + yyb102 = r.CheckBreak() } - if yyb100 { + if yyb102 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -4920,13 +4993,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.KubeAPIQPS = float32(r.DecodeFloat(true)) } - yyj100++ - if yyhl100 { - yyb100 = yyj100 > l + yyj102++ + if yyhl102 { + yyb102 = yyj102 > l } else { - yyb100 = r.CheckBreak() + yyb102 = r.CheckBreak() } - if yyb100 { + if yyb102 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -4936,13 +5009,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.KubeAPIBurst = int32(r.DecodeInt(32)) } - yyj100++ - if yyhl100 { - yyb100 = yyj100 > l + yyj102++ + if yyhl102 { + yyb102 = yyj102 > l } else { - yyb100 = r.CheckBreak() + yyb102 = r.CheckBreak() } - if yyb100 { + if yyb102 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -4952,13 +5025,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.SerializeImagePulls = bool(r.DecodeBool()) } - yyj100++ - if yyhl100 { - yyb100 = yyj100 > l + yyj102++ + if yyhl102 { + yyb102 = yyj102 > l } else { - yyb100 = r.CheckBreak() + yyb102 = r.CheckBreak() } - if yyb100 { + if yyb102 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -4968,13 +5041,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.ExperimentalFlannelOverlay = bool(r.DecodeBool()) } - yyj100++ - if yyhl100 { - yyb100 = yyj100 > l + yyj102++ + if yyhl102 { + yyb102 = yyj102 > l } else { - yyb100 = r.CheckBreak() + yyb102 = r.CheckBreak() } - if yyb100 { + if yyb102 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -4982,24 +5055,24 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco if r.TryDecodeAsNil() { x.OutOfDiskTransitionFrequency = pkg1_unversioned.Duration{} } else { - yyv185 := &x.OutOfDiskTransitionFrequency - yym186 := z.DecBinary() - _ = yym186 + yyv188 := &x.OutOfDiskTransitionFrequency + yym189 := z.DecBinary() + _ = yym189 if false { - } else if z.HasExtensions() && z.DecExt(yyv185) { - } else if !yym186 && z.IsJSONHandle() { - z.DecJSONUnmarshal(yyv185) + } else if z.HasExtensions() && z.DecExt(yyv188) { + } else if !yym189 && z.IsJSONHandle() { + z.DecJSONUnmarshal(yyv188) } else { - z.DecFallback(yyv185, false) + z.DecFallback(yyv188, false) } } - yyj100++ - if yyhl100 { - yyb100 = yyj100 > l + yyj102++ + if yyhl102 { + yyb102 = yyj102 > l } else { - yyb100 = r.CheckBreak() + yyb102 = r.CheckBreak() } - if yyb100 { + if yyb102 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -5009,13 +5082,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.NodeIP = string(r.DecodeString()) } - yyj100++ - if yyhl100 { - yyb100 = yyj100 > l + yyj102++ + if yyhl102 { + yyb102 = yyj102 > l } else { - yyb100 = r.CheckBreak() + yyb102 = r.CheckBreak() } - if yyb100 { + if yyb102 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -5023,21 +5096,21 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco if r.TryDecodeAsNil() { x.NodeLabels = nil } else { - yyv188 := &x.NodeLabels - yym189 := z.DecBinary() - _ = yym189 + yyv191 := &x.NodeLabels + yym192 := z.DecBinary() + _ = yym192 if false { } else { - z.F.DecMapStringStringX(yyv188, false, d) + z.F.DecMapStringStringX(yyv191, false, d) } } - yyj100++ - if yyhl100 { - yyb100 = yyj100 > l + yyj102++ + if yyhl102 { + yyb102 = yyj102 > l } else { - yyb100 = r.CheckBreak() + yyb102 = r.CheckBreak() } - if yyb100 { + if yyb102 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -5047,13 +5120,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.NonMasqueradeCIDR = string(r.DecodeString()) } - yyj100++ - if yyhl100 { - yyb100 = yyj100 > l + yyj102++ + if yyhl102 { + yyb102 = yyj102 > l } else { - yyb100 = r.CheckBreak() + yyb102 = r.CheckBreak() } - if yyb100 { + if yyb102 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -5063,13 +5136,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.EnableCustomMetrics = bool(r.DecodeBool()) } - yyj100++ - if yyhl100 { - yyb100 = yyj100 > l + yyj102++ + if yyhl102 { + yyb102 = yyj102 > l } else { - yyb100 = r.CheckBreak() + yyb102 = r.CheckBreak() } - if yyb100 { + if yyb102 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -5079,13 +5152,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.EvictionHard = string(r.DecodeString()) } - yyj100++ - if yyhl100 { - yyb100 = yyj100 > l + yyj102++ + if yyhl102 { + yyb102 = yyj102 > l } else { - yyb100 = r.CheckBreak() + yyb102 = r.CheckBreak() } - if yyb100 { + if yyb102 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -5095,13 +5168,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.EvictionSoft = string(r.DecodeString()) } - yyj100++ - if yyhl100 { - yyb100 = yyj100 > l + yyj102++ + if yyhl102 { + yyb102 = yyj102 > l } else { - yyb100 = r.CheckBreak() + yyb102 = r.CheckBreak() } - if yyb100 { + if yyb102 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -5111,13 +5184,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.EvictionSoftGracePeriod = string(r.DecodeString()) } - yyj100++ - if yyhl100 { - yyb100 = yyj100 > l + yyj102++ + if yyhl102 { + yyb102 = yyj102 > l } else { - yyb100 = r.CheckBreak() + yyb102 = r.CheckBreak() } - if yyb100 { + if yyb102 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -5125,29 +5198,45 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco if r.TryDecodeAsNil() { x.EvictionPressureTransitionPeriod = pkg1_unversioned.Duration{} } else { - yyv195 := &x.EvictionPressureTransitionPeriod - yym196 := z.DecBinary() - _ = yym196 + yyv198 := &x.EvictionPressureTransitionPeriod + yym199 := z.DecBinary() + _ = yym199 if false { - } else if z.HasExtensions() && z.DecExt(yyv195) { - } else if !yym196 && z.IsJSONHandle() { - z.DecJSONUnmarshal(yyv195) + } else if z.HasExtensions() && z.DecExt(yyv198) { + } else if !yym199 && z.IsJSONHandle() { + z.DecJSONUnmarshal(yyv198) } else { - z.DecFallback(yyv195, false) + z.DecFallback(yyv198, false) } } + yyj102++ + if yyhl102 { + yyb102 = yyj102 > l + } else { + yyb102 = r.CheckBreak() + } + if yyb102 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) + return + } + z.DecSendContainerState(codecSelfer_containerArrayElem1234) + if r.TryDecodeAsNil() { + x.EvictionMaxPodGracePeriod = 0 + } else { + x.EvictionMaxPodGracePeriod = int32(r.DecodeInt(32)) + } for { - yyj100++ - if yyhl100 { - yyb100 = yyj100 > l + yyj102++ + if yyhl102 { + yyb102 = yyj102 > l } else { - yyb100 = r.CheckBreak() + yyb102 = r.CheckBreak() } - if yyb100 { + if yyb102 { break } z.DecSendContainerState(codecSelfer_containerArrayElem1234) - z.DecStructFieldNotFound(yyj100-1, "") + z.DecStructFieldNotFound(yyj102-1, "") } z.DecSendContainerState(codecSelfer_containerArrayEnd1234) } @@ -6232,16 +6321,16 @@ func (x *KubeControllerManagerConfiguration) CodecEncodeSelf(e *codec1978.Encode } else { yysep2 := !z.EncBinary() yy2arr2 := z.EncBasicHandle().StructToArray - var yyq2 [45]bool + var yyq2 [47]bool _, _, _ = yysep2, yyq2, yy2arr2 const yyr2 bool = false - yyq2[43] = x.Kind != "" - yyq2[44] = x.APIVersion != "" + yyq2[45] = x.Kind != "" + yyq2[46] = x.APIVersion != "" var yynn2 int if yyr2 || yy2arr2 { - r.EncodeArrayStart(45) + r.EncodeArrayStart(47) } else { - yynn2 = 43 + yynn2 = 45 for _, b := range yyq2 { if b { yynn2++ @@ -7017,17 +7106,17 @@ func (x *KubeControllerManagerConfiguration) CodecEncodeSelf(e *codec1978.Encode _ = yym133 if false { } else { - r.EncodeBool(bool(x.AllocateNodeCIDRs)) + r.EncodeString(codecSelferC_UTF81234, string(x.ServiceCIDR)) } } else { z.EncSendContainerState(codecSelfer_containerMapKey1234) - r.EncodeString(codecSelferC_UTF81234, string("allocateNodeCIDRs")) + r.EncodeString(codecSelferC_UTF81234, string("serviceCIDR")) z.EncSendContainerState(codecSelfer_containerMapValue1234) yym134 := z.EncBinary() _ = yym134 if false { } else { - r.EncodeBool(bool(x.AllocateNodeCIDRs)) + r.EncodeString(codecSelferC_UTF81234, string(x.ServiceCIDR)) } } if yyr2 || yy2arr2 { @@ -7036,17 +7125,17 @@ func (x *KubeControllerManagerConfiguration) CodecEncodeSelf(e *codec1978.Encode _ = yym136 if false { } else { - r.EncodeString(codecSelferC_UTF81234, string(x.RootCAFile)) + r.EncodeInt(int64(x.NodeCIDRMaskSize)) } } else { z.EncSendContainerState(codecSelfer_containerMapKey1234) - r.EncodeString(codecSelferC_UTF81234, string("rootCAFile")) + r.EncodeString(codecSelferC_UTF81234, string("nodeCIDRMaskSize")) z.EncSendContainerState(codecSelfer_containerMapValue1234) yym137 := z.EncBinary() _ = yym137 if false { } else { - r.EncodeString(codecSelferC_UTF81234, string(x.RootCAFile)) + r.EncodeInt(int64(x.NodeCIDRMaskSize)) } } if yyr2 || yy2arr2 { @@ -7055,17 +7144,17 @@ func (x *KubeControllerManagerConfiguration) CodecEncodeSelf(e *codec1978.Encode _ = yym139 if false { } else { - r.EncodeString(codecSelferC_UTF81234, string(x.ContentType)) + r.EncodeBool(bool(x.AllocateNodeCIDRs)) } } else { z.EncSendContainerState(codecSelfer_containerMapKey1234) - r.EncodeString(codecSelferC_UTF81234, string("contentType")) + r.EncodeString(codecSelferC_UTF81234, string("allocateNodeCIDRs")) z.EncSendContainerState(codecSelfer_containerMapValue1234) yym140 := z.EncBinary() _ = yym140 if false { } else { - r.EncodeString(codecSelferC_UTF81234, string(x.ContentType)) + r.EncodeBool(bool(x.AllocateNodeCIDRs)) } } if yyr2 || yy2arr2 { @@ -7074,17 +7163,17 @@ func (x *KubeControllerManagerConfiguration) CodecEncodeSelf(e *codec1978.Encode _ = yym142 if false { } else { - r.EncodeFloat32(float32(x.KubeAPIQPS)) + r.EncodeString(codecSelferC_UTF81234, string(x.RootCAFile)) } } else { z.EncSendContainerState(codecSelfer_containerMapKey1234) - r.EncodeString(codecSelferC_UTF81234, string("kubeAPIQPS")) + r.EncodeString(codecSelferC_UTF81234, string("rootCAFile")) z.EncSendContainerState(codecSelfer_containerMapValue1234) yym143 := z.EncBinary() _ = yym143 if false { } else { - r.EncodeFloat32(float32(x.KubeAPIQPS)) + r.EncodeString(codecSelferC_UTF81234, string(x.RootCAFile)) } } if yyr2 || yy2arr2 { @@ -7092,6 +7181,44 @@ func (x *KubeControllerManagerConfiguration) CodecEncodeSelf(e *codec1978.Encode yym145 := z.EncBinary() _ = yym145 if false { + } else { + r.EncodeString(codecSelferC_UTF81234, string(x.ContentType)) + } + } else { + z.EncSendContainerState(codecSelfer_containerMapKey1234) + r.EncodeString(codecSelferC_UTF81234, string("contentType")) + z.EncSendContainerState(codecSelfer_containerMapValue1234) + yym146 := z.EncBinary() + _ = yym146 + if false { + } else { + r.EncodeString(codecSelferC_UTF81234, string(x.ContentType)) + } + } + if yyr2 || yy2arr2 { + z.EncSendContainerState(codecSelfer_containerArrayElem1234) + yym148 := z.EncBinary() + _ = yym148 + if false { + } else { + r.EncodeFloat32(float32(x.KubeAPIQPS)) + } + } else { + z.EncSendContainerState(codecSelfer_containerMapKey1234) + r.EncodeString(codecSelferC_UTF81234, string("kubeAPIQPS")) + z.EncSendContainerState(codecSelfer_containerMapValue1234) + yym149 := z.EncBinary() + _ = yym149 + if false { + } else { + r.EncodeFloat32(float32(x.KubeAPIQPS)) + } + } + if yyr2 || yy2arr2 { + z.EncSendContainerState(codecSelfer_containerArrayElem1234) + yym151 := z.EncBinary() + _ = yym151 + if false { } else { r.EncodeInt(int64(x.KubeAPIBurst)) } @@ -7099,8 +7226,8 @@ func (x *KubeControllerManagerConfiguration) CodecEncodeSelf(e *codec1978.Encode z.EncSendContainerState(codecSelfer_containerMapKey1234) r.EncodeString(codecSelferC_UTF81234, string("kubeAPIBurst")) z.EncSendContainerState(codecSelfer_containerMapValue1234) - yym146 := z.EncBinary() - _ = yym146 + yym152 := z.EncBinary() + _ = yym152 if false { } else { r.EncodeInt(int64(x.KubeAPIBurst)) @@ -7108,58 +7235,58 @@ func (x *KubeControllerManagerConfiguration) CodecEncodeSelf(e *codec1978.Encode } if yyr2 || yy2arr2 { z.EncSendContainerState(codecSelfer_containerArrayElem1234) - yy148 := &x.LeaderElection - yy148.CodecEncodeSelf(e) + yy154 := &x.LeaderElection + yy154.CodecEncodeSelf(e) } else { z.EncSendContainerState(codecSelfer_containerMapKey1234) r.EncodeString(codecSelferC_UTF81234, string("leaderElection")) z.EncSendContainerState(codecSelfer_containerMapValue1234) - yy150 := &x.LeaderElection - yy150.CodecEncodeSelf(e) + yy156 := &x.LeaderElection + yy156.CodecEncodeSelf(e) } if yyr2 || yy2arr2 { z.EncSendContainerState(codecSelfer_containerArrayElem1234) - yy153 := &x.VolumeConfiguration - yy153.CodecEncodeSelf(e) + yy159 := &x.VolumeConfiguration + yy159.CodecEncodeSelf(e) } else { z.EncSendContainerState(codecSelfer_containerMapKey1234) r.EncodeString(codecSelferC_UTF81234, string("volumeConfiguration")) z.EncSendContainerState(codecSelfer_containerMapValue1234) - yy155 := &x.VolumeConfiguration - yy155.CodecEncodeSelf(e) + yy161 := &x.VolumeConfiguration + yy161.CodecEncodeSelf(e) } if yyr2 || yy2arr2 { z.EncSendContainerState(codecSelfer_containerArrayElem1234) - yy158 := &x.ControllerStartInterval - yym159 := z.EncBinary() - _ = yym159 + yy164 := &x.ControllerStartInterval + yym165 := z.EncBinary() + _ = yym165 if false { - } else if z.HasExtensions() && z.EncExt(yy158) { - } else if !yym159 && z.IsJSONHandle() { - z.EncJSONMarshal(yy158) + } else if z.HasExtensions() && z.EncExt(yy164) { + } else if !yym165 && z.IsJSONHandle() { + z.EncJSONMarshal(yy164) } else { - z.EncFallback(yy158) + z.EncFallback(yy164) } } else { z.EncSendContainerState(codecSelfer_containerMapKey1234) r.EncodeString(codecSelferC_UTF81234, string("controllerStartInterval")) z.EncSendContainerState(codecSelfer_containerMapValue1234) - yy160 := &x.ControllerStartInterval - yym161 := z.EncBinary() - _ = yym161 + yy166 := &x.ControllerStartInterval + yym167 := z.EncBinary() + _ = yym167 if false { - } else if z.HasExtensions() && z.EncExt(yy160) { - } else if !yym161 && z.IsJSONHandle() { - z.EncJSONMarshal(yy160) + } else if z.HasExtensions() && z.EncExt(yy166) { + } else if !yym167 && z.IsJSONHandle() { + z.EncJSONMarshal(yy166) } else { - z.EncFallback(yy160) + z.EncFallback(yy166) } } if yyr2 || yy2arr2 { z.EncSendContainerState(codecSelfer_containerArrayElem1234) - if yyq2[43] { - yym163 := z.EncBinary() - _ = yym163 + if yyq2[45] { + yym169 := z.EncBinary() + _ = yym169 if false { } else { r.EncodeString(codecSelferC_UTF81234, string(x.Kind)) @@ -7168,12 +7295,12 @@ func (x *KubeControllerManagerConfiguration) CodecEncodeSelf(e *codec1978.Encode r.EncodeString(codecSelferC_UTF81234, "") } } else { - if yyq2[43] { + if yyq2[45] { z.EncSendContainerState(codecSelfer_containerMapKey1234) r.EncodeString(codecSelferC_UTF81234, string("kind")) z.EncSendContainerState(codecSelfer_containerMapValue1234) - yym164 := z.EncBinary() - _ = yym164 + yym170 := z.EncBinary() + _ = yym170 if false { } else { r.EncodeString(codecSelferC_UTF81234, string(x.Kind)) @@ -7182,9 +7309,9 @@ func (x *KubeControllerManagerConfiguration) CodecEncodeSelf(e *codec1978.Encode } if yyr2 || yy2arr2 { z.EncSendContainerState(codecSelfer_containerArrayElem1234) - if yyq2[44] { - yym166 := z.EncBinary() - _ = yym166 + if yyq2[46] { + yym172 := z.EncBinary() + _ = yym172 if false { } else { r.EncodeString(codecSelferC_UTF81234, string(x.APIVersion)) @@ -7193,12 +7320,12 @@ func (x *KubeControllerManagerConfiguration) CodecEncodeSelf(e *codec1978.Encode r.EncodeString(codecSelferC_UTF81234, "") } } else { - if yyq2[44] { + if yyq2[46] { z.EncSendContainerState(codecSelfer_containerMapKey1234) r.EncodeString(codecSelferC_UTF81234, string("apiVersion")) z.EncSendContainerState(codecSelfer_containerMapValue1234) - yym167 := z.EncBinary() - _ = yym167 + yym173 := z.EncBinary() + _ = yym173 if false { } else { r.EncodeString(codecSelferC_UTF81234, string(x.APIVersion)) @@ -7584,6 +7711,18 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromMap(l int, d *co } else { x.ClusterCIDR = string(r.DecodeString()) } + case "serviceCIDR": + if r.TryDecodeAsNil() { + x.ServiceCIDR = "" + } else { + x.ServiceCIDR = string(r.DecodeString()) + } + case "nodeCIDRMaskSize": + if r.TryDecodeAsNil() { + x.NodeCIDRMaskSize = 0 + } else { + x.NodeCIDRMaskSize = int32(r.DecodeInt(32)) + } case "allocateNodeCIDRs": if r.TryDecodeAsNil() { x.AllocateNodeCIDRs = false @@ -7618,29 +7757,29 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromMap(l int, d *co if r.TryDecodeAsNil() { x.LeaderElection = LeaderElectionConfiguration{} } else { - yyv56 := &x.LeaderElection - yyv56.CodecDecodeSelf(d) + yyv58 := &x.LeaderElection + yyv58.CodecDecodeSelf(d) } case "volumeConfiguration": if r.TryDecodeAsNil() { x.VolumeConfiguration = VolumeConfiguration{} } else { - yyv57 := &x.VolumeConfiguration - yyv57.CodecDecodeSelf(d) + yyv59 := &x.VolumeConfiguration + yyv59.CodecDecodeSelf(d) } case "controllerStartInterval": if r.TryDecodeAsNil() { x.ControllerStartInterval = pkg1_unversioned.Duration{} } else { - yyv58 := &x.ControllerStartInterval - yym59 := z.DecBinary() - _ = yym59 + yyv60 := &x.ControllerStartInterval + yym61 := z.DecBinary() + _ = yym61 if false { - } else if z.HasExtensions() && z.DecExt(yyv58) { - } else if !yym59 && z.IsJSONHandle() { - z.DecJSONUnmarshal(yyv58) + } else if z.HasExtensions() && z.DecExt(yyv60) { + } else if !yym61 && z.IsJSONHandle() { + z.DecJSONUnmarshal(yyv60) } else { - z.DecFallback(yyv58, false) + z.DecFallback(yyv60, false) } } case "kind": @@ -7666,16 +7805,16 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromArray(l int, d * var h codecSelfer1234 z, r := codec1978.GenHelperDecoder(d) _, _, _ = h, z, r - var yyj62 int - var yyb62 bool - var yyhl62 bool = l >= 0 - yyj62++ - if yyhl62 { - yyb62 = yyj62 > l + var yyj64 int + var yyb64 bool + var yyhl64 bool = l >= 0 + yyj64++ + if yyhl64 { + yyb64 = yyj64 > l } else { - yyb62 = r.CheckBreak() + yyb64 = r.CheckBreak() } - if yyb62 { + if yyb64 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -7685,13 +7824,13 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromArray(l int, d * } else { x.Port = int32(r.DecodeInt(32)) } - yyj62++ - if yyhl62 { - yyb62 = yyj62 > l + yyj64++ + if yyhl64 { + yyb64 = yyj64 > l } else { - yyb62 = r.CheckBreak() + yyb64 = r.CheckBreak() } - if yyb62 { + if yyb64 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -7701,13 +7840,13 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromArray(l int, d * } else { x.Address = string(r.DecodeString()) } - yyj62++ - if yyhl62 { - yyb62 = yyj62 > l + yyj64++ + if yyhl64 { + yyb64 = yyj64 > l } else { - yyb62 = r.CheckBreak() + yyb64 = r.CheckBreak() } - if yyb62 { + if yyb64 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -7717,13 +7856,13 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromArray(l int, d * } else { x.CloudProvider = string(r.DecodeString()) } - yyj62++ - if yyhl62 { - yyb62 = yyj62 > l + yyj64++ + if yyhl64 { + yyb64 = yyj64 > l } else { - yyb62 = r.CheckBreak() + yyb64 = r.CheckBreak() } - if yyb62 { + if yyb64 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -7733,13 +7872,13 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromArray(l int, d * } else { x.CloudConfigFile = string(r.DecodeString()) } - yyj62++ - if yyhl62 { - yyb62 = yyj62 > l + yyj64++ + if yyhl64 { + yyb64 = yyj64 > l } else { - yyb62 = r.CheckBreak() + yyb64 = r.CheckBreak() } - if yyb62 { + if yyb64 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -7749,13 +7888,13 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromArray(l int, d * } else { x.ConcurrentEndpointSyncs = int32(r.DecodeInt(32)) } - yyj62++ - if yyhl62 { - yyb62 = yyj62 > l + yyj64++ + if yyhl64 { + yyb64 = yyj64 > l } else { - yyb62 = r.CheckBreak() + yyb64 = r.CheckBreak() } - if yyb62 { + if yyb64 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -7765,13 +7904,13 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromArray(l int, d * } else { x.ConcurrentRSSyncs = int32(r.DecodeInt(32)) } - yyj62++ - if yyhl62 { - yyb62 = yyj62 > l + yyj64++ + if yyhl64 { + yyb64 = yyj64 > l } else { - yyb62 = r.CheckBreak() + yyb64 = r.CheckBreak() } - if yyb62 { + if yyb64 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -7781,13 +7920,13 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromArray(l int, d * } else { x.ConcurrentRCSyncs = int32(r.DecodeInt(32)) } - yyj62++ - if yyhl62 { - yyb62 = yyj62 > l + yyj64++ + if yyhl64 { + yyb64 = yyj64 > l } else { - yyb62 = r.CheckBreak() + yyb64 = r.CheckBreak() } - if yyb62 { + if yyb64 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -7797,13 +7936,13 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromArray(l int, d * } else { x.ConcurrentResourceQuotaSyncs = int32(r.DecodeInt(32)) } - yyj62++ - if yyhl62 { - yyb62 = yyj62 > l + yyj64++ + if yyhl64 { + yyb64 = yyj64 > l } else { - yyb62 = r.CheckBreak() + yyb64 = r.CheckBreak() } - if yyb62 { + if yyb64 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -7813,13 +7952,13 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromArray(l int, d * } else { x.ConcurrentDeploymentSyncs = int32(r.DecodeInt(32)) } - yyj62++ - if yyhl62 { - yyb62 = yyj62 > l + yyj64++ + if yyhl64 { + yyb64 = yyj64 > l } else { - yyb62 = r.CheckBreak() + yyb64 = r.CheckBreak() } - if yyb62 { + if yyb64 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -7829,13 +7968,13 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromArray(l int, d * } else { x.ConcurrentDaemonSetSyncs = int32(r.DecodeInt(32)) } - yyj62++ - if yyhl62 { - yyb62 = yyj62 > l + yyj64++ + if yyhl64 { + yyb64 = yyj64 > l } else { - yyb62 = r.CheckBreak() + yyb64 = r.CheckBreak() } - if yyb62 { + if yyb64 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -7845,13 +7984,13 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromArray(l int, d * } else { x.ConcurrentJobSyncs = int32(r.DecodeInt(32)) } - yyj62++ - if yyhl62 { - yyb62 = yyj62 > l + yyj64++ + if yyhl64 { + yyb64 = yyj64 > l } else { - yyb62 = r.CheckBreak() + yyb64 = r.CheckBreak() } - if yyb62 { + if yyb64 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -7861,13 +8000,13 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromArray(l int, d * } else { x.ConcurrentNamespaceSyncs = int32(r.DecodeInt(32)) } - yyj62++ - if yyhl62 { - yyb62 = yyj62 > l + yyj64++ + if yyhl64 { + yyb64 = yyj64 > l } else { - yyb62 = r.CheckBreak() + yyb64 = r.CheckBreak() } - if yyb62 { + if yyb64 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -7877,13 +8016,13 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromArray(l int, d * } else { x.LookupCacheSizeForRC = int32(r.DecodeInt(32)) } - yyj62++ - if yyhl62 { - yyb62 = yyj62 > l + yyj64++ + if yyhl64 { + yyb64 = yyj64 > l } else { - yyb62 = r.CheckBreak() + yyb64 = r.CheckBreak() } - if yyb62 { + if yyb64 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -7893,13 +8032,13 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromArray(l int, d * } else { x.LookupCacheSizeForRS = int32(r.DecodeInt(32)) } - yyj62++ - if yyhl62 { - yyb62 = yyj62 > l + yyj64++ + if yyhl64 { + yyb64 = yyj64 > l } else { - yyb62 = r.CheckBreak() + yyb64 = r.CheckBreak() } - if yyb62 { + if yyb64 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -7909,13 +8048,13 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromArray(l int, d * } else { x.LookupCacheSizeForDaemonSet = int32(r.DecodeInt(32)) } - yyj62++ - if yyhl62 { - yyb62 = yyj62 > l + yyj64++ + if yyhl64 { + yyb64 = yyj64 > l } else { - yyb62 = r.CheckBreak() + yyb64 = r.CheckBreak() } - if yyb62 { + if yyb64 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -7923,32 +8062,7 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromArray(l int, d * if r.TryDecodeAsNil() { x.ServiceSyncPeriod = pkg1_unversioned.Duration{} } else { - yyv78 := &x.ServiceSyncPeriod - yym79 := z.DecBinary() - _ = yym79 - if false { - } else if z.HasExtensions() && z.DecExt(yyv78) { - } else if !yym79 && z.IsJSONHandle() { - z.DecJSONUnmarshal(yyv78) - } else { - z.DecFallback(yyv78, false) - } - } - yyj62++ - if yyhl62 { - yyb62 = yyj62 > l - } else { - yyb62 = r.CheckBreak() - } - if yyb62 { - z.DecSendContainerState(codecSelfer_containerArrayEnd1234) - return - } - z.DecSendContainerState(codecSelfer_containerArrayElem1234) - if r.TryDecodeAsNil() { - x.NodeSyncPeriod = pkg1_unversioned.Duration{} - } else { - yyv80 := &x.NodeSyncPeriod + yyv80 := &x.ServiceSyncPeriod yym81 := z.DecBinary() _ = yym81 if false { @@ -7959,21 +8073,21 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromArray(l int, d * z.DecFallback(yyv80, false) } } - yyj62++ - if yyhl62 { - yyb62 = yyj62 > l + yyj64++ + if yyhl64 { + yyb64 = yyj64 > l } else { - yyb62 = r.CheckBreak() + yyb64 = r.CheckBreak() } - if yyb62 { + if yyb64 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } z.DecSendContainerState(codecSelfer_containerArrayElem1234) if r.TryDecodeAsNil() { - x.ResourceQuotaSyncPeriod = pkg1_unversioned.Duration{} + x.NodeSyncPeriod = pkg1_unversioned.Duration{} } else { - yyv82 := &x.ResourceQuotaSyncPeriod + yyv82 := &x.NodeSyncPeriod yym83 := z.DecBinary() _ = yym83 if false { @@ -7984,21 +8098,21 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromArray(l int, d * z.DecFallback(yyv82, false) } } - yyj62++ - if yyhl62 { - yyb62 = yyj62 > l + yyj64++ + if yyhl64 { + yyb64 = yyj64 > l } else { - yyb62 = r.CheckBreak() + yyb64 = r.CheckBreak() } - if yyb62 { + if yyb64 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } z.DecSendContainerState(codecSelfer_containerArrayElem1234) if r.TryDecodeAsNil() { - x.NamespaceSyncPeriod = pkg1_unversioned.Duration{} + x.ResourceQuotaSyncPeriod = pkg1_unversioned.Duration{} } else { - yyv84 := &x.NamespaceSyncPeriod + yyv84 := &x.ResourceQuotaSyncPeriod yym85 := z.DecBinary() _ = yym85 if false { @@ -8009,21 +8123,21 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromArray(l int, d * z.DecFallback(yyv84, false) } } - yyj62++ - if yyhl62 { - yyb62 = yyj62 > l + yyj64++ + if yyhl64 { + yyb64 = yyj64 > l } else { - yyb62 = r.CheckBreak() + yyb64 = r.CheckBreak() } - if yyb62 { + if yyb64 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } z.DecSendContainerState(codecSelfer_containerArrayElem1234) if r.TryDecodeAsNil() { - x.PVClaimBinderSyncPeriod = pkg1_unversioned.Duration{} + x.NamespaceSyncPeriod = pkg1_unversioned.Duration{} } else { - yyv86 := &x.PVClaimBinderSyncPeriod + yyv86 := &x.NamespaceSyncPeriod yym87 := z.DecBinary() _ = yym87 if false { @@ -8034,21 +8148,21 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromArray(l int, d * z.DecFallback(yyv86, false) } } - yyj62++ - if yyhl62 { - yyb62 = yyj62 > l + yyj64++ + if yyhl64 { + yyb64 = yyj64 > l } else { - yyb62 = r.CheckBreak() + yyb64 = r.CheckBreak() } - if yyb62 { + if yyb64 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } z.DecSendContainerState(codecSelfer_containerArrayElem1234) if r.TryDecodeAsNil() { - x.MinResyncPeriod = pkg1_unversioned.Duration{} + x.PVClaimBinderSyncPeriod = pkg1_unversioned.Duration{} } else { - yyv88 := &x.MinResyncPeriod + yyv88 := &x.PVClaimBinderSyncPeriod yym89 := z.DecBinary() _ = yym89 if false { @@ -8059,13 +8173,38 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromArray(l int, d * z.DecFallback(yyv88, false) } } - yyj62++ - if yyhl62 { - yyb62 = yyj62 > l + yyj64++ + if yyhl64 { + yyb64 = yyj64 > l } else { - yyb62 = r.CheckBreak() + yyb64 = r.CheckBreak() } - if yyb62 { + if yyb64 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) + return + } + z.DecSendContainerState(codecSelfer_containerArrayElem1234) + if r.TryDecodeAsNil() { + x.MinResyncPeriod = pkg1_unversioned.Duration{} + } else { + yyv90 := &x.MinResyncPeriod + yym91 := z.DecBinary() + _ = yym91 + if false { + } else if z.HasExtensions() && z.DecExt(yyv90) { + } else if !yym91 && z.IsJSONHandle() { + z.DecJSONUnmarshal(yyv90) + } else { + z.DecFallback(yyv90, false) + } + } + yyj64++ + if yyhl64 { + yyb64 = yyj64 > l + } else { + yyb64 = r.CheckBreak() + } + if yyb64 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -8075,13 +8214,13 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromArray(l int, d * } else { x.TerminatedPodGCThreshold = int32(r.DecodeInt(32)) } - yyj62++ - if yyhl62 { - yyb62 = yyj62 > l + yyj64++ + if yyhl64 { + yyb64 = yyj64 > l } else { - yyb62 = r.CheckBreak() + yyb64 = r.CheckBreak() } - if yyb62 { + if yyb64 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -8089,32 +8228,7 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromArray(l int, d * if r.TryDecodeAsNil() { x.HorizontalPodAutoscalerSyncPeriod = pkg1_unversioned.Duration{} } else { - yyv91 := &x.HorizontalPodAutoscalerSyncPeriod - yym92 := z.DecBinary() - _ = yym92 - if false { - } else if z.HasExtensions() && z.DecExt(yyv91) { - } else if !yym92 && z.IsJSONHandle() { - z.DecJSONUnmarshal(yyv91) - } else { - z.DecFallback(yyv91, false) - } - } - yyj62++ - if yyhl62 { - yyb62 = yyj62 > l - } else { - yyb62 = r.CheckBreak() - } - if yyb62 { - z.DecSendContainerState(codecSelfer_containerArrayEnd1234) - return - } - z.DecSendContainerState(codecSelfer_containerArrayElem1234) - if r.TryDecodeAsNil() { - x.DeploymentControllerSyncPeriod = pkg1_unversioned.Duration{} - } else { - yyv93 := &x.DeploymentControllerSyncPeriod + yyv93 := &x.HorizontalPodAutoscalerSyncPeriod yym94 := z.DecBinary() _ = yym94 if false { @@ -8125,21 +8239,21 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromArray(l int, d * z.DecFallback(yyv93, false) } } - yyj62++ - if yyhl62 { - yyb62 = yyj62 > l + yyj64++ + if yyhl64 { + yyb64 = yyj64 > l } else { - yyb62 = r.CheckBreak() + yyb64 = r.CheckBreak() } - if yyb62 { + if yyb64 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } z.DecSendContainerState(codecSelfer_containerArrayElem1234) if r.TryDecodeAsNil() { - x.PodEvictionTimeout = pkg1_unversioned.Duration{} + x.DeploymentControllerSyncPeriod = pkg1_unversioned.Duration{} } else { - yyv95 := &x.PodEvictionTimeout + yyv95 := &x.DeploymentControllerSyncPeriod yym96 := z.DecBinary() _ = yym96 if false { @@ -8150,13 +8264,38 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromArray(l int, d * z.DecFallback(yyv95, false) } } - yyj62++ - if yyhl62 { - yyb62 = yyj62 > l + yyj64++ + if yyhl64 { + yyb64 = yyj64 > l } else { - yyb62 = r.CheckBreak() + yyb64 = r.CheckBreak() } - if yyb62 { + if yyb64 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) + return + } + z.DecSendContainerState(codecSelfer_containerArrayElem1234) + if r.TryDecodeAsNil() { + x.PodEvictionTimeout = pkg1_unversioned.Duration{} + } else { + yyv97 := &x.PodEvictionTimeout + yym98 := z.DecBinary() + _ = yym98 + if false { + } else if z.HasExtensions() && z.DecExt(yyv97) { + } else if !yym98 && z.IsJSONHandle() { + z.DecJSONUnmarshal(yyv97) + } else { + z.DecFallback(yyv97, false) + } + } + yyj64++ + if yyhl64 { + yyb64 = yyj64 > l + } else { + yyb64 = r.CheckBreak() + } + if yyb64 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -8166,13 +8305,13 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromArray(l int, d * } else { x.DeletingPodsQps = float32(r.DecodeFloat(true)) } - yyj62++ - if yyhl62 { - yyb62 = yyj62 > l + yyj64++ + if yyhl64 { + yyb64 = yyj64 > l } else { - yyb62 = r.CheckBreak() + yyb64 = r.CheckBreak() } - if yyb62 { + if yyb64 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -8182,13 +8321,13 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromArray(l int, d * } else { x.DeletingPodsBurst = int32(r.DecodeInt(32)) } - yyj62++ - if yyhl62 { - yyb62 = yyj62 > l + yyj64++ + if yyhl64 { + yyb64 = yyj64 > l } else { - yyb62 = r.CheckBreak() + yyb64 = r.CheckBreak() } - if yyb62 { + if yyb64 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -8196,24 +8335,24 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromArray(l int, d * if r.TryDecodeAsNil() { x.NodeMonitorGracePeriod = pkg1_unversioned.Duration{} } else { - yyv99 := &x.NodeMonitorGracePeriod - yym100 := z.DecBinary() - _ = yym100 + yyv101 := &x.NodeMonitorGracePeriod + yym102 := z.DecBinary() + _ = yym102 if false { - } else if z.HasExtensions() && z.DecExt(yyv99) { - } else if !yym100 && z.IsJSONHandle() { - z.DecJSONUnmarshal(yyv99) + } else if z.HasExtensions() && z.DecExt(yyv101) { + } else if !yym102 && z.IsJSONHandle() { + z.DecJSONUnmarshal(yyv101) } else { - z.DecFallback(yyv99, false) + z.DecFallback(yyv101, false) } } - yyj62++ - if yyhl62 { - yyb62 = yyj62 > l + yyj64++ + if yyhl64 { + yyb64 = yyj64 > l } else { - yyb62 = r.CheckBreak() + yyb64 = r.CheckBreak() } - if yyb62 { + if yyb64 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -8223,13 +8362,13 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromArray(l int, d * } else { x.RegisterRetryCount = int32(r.DecodeInt(32)) } - yyj62++ - if yyhl62 { - yyb62 = yyj62 > l + yyj64++ + if yyhl64 { + yyb64 = yyj64 > l } else { - yyb62 = r.CheckBreak() + yyb64 = r.CheckBreak() } - if yyb62 { + if yyb64 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -8237,32 +8376,7 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromArray(l int, d * if r.TryDecodeAsNil() { x.NodeStartupGracePeriod = pkg1_unversioned.Duration{} } else { - yyv102 := &x.NodeStartupGracePeriod - yym103 := z.DecBinary() - _ = yym103 - if false { - } else if z.HasExtensions() && z.DecExt(yyv102) { - } else if !yym103 && z.IsJSONHandle() { - z.DecJSONUnmarshal(yyv102) - } else { - z.DecFallback(yyv102, false) - } - } - yyj62++ - if yyhl62 { - yyb62 = yyj62 > l - } else { - yyb62 = r.CheckBreak() - } - if yyb62 { - z.DecSendContainerState(codecSelfer_containerArrayEnd1234) - return - } - z.DecSendContainerState(codecSelfer_containerArrayElem1234) - if r.TryDecodeAsNil() { - x.NodeMonitorPeriod = pkg1_unversioned.Duration{} - } else { - yyv104 := &x.NodeMonitorPeriod + yyv104 := &x.NodeStartupGracePeriod yym105 := z.DecBinary() _ = yym105 if false { @@ -8273,13 +8387,38 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromArray(l int, d * z.DecFallback(yyv104, false) } } - yyj62++ - if yyhl62 { - yyb62 = yyj62 > l + yyj64++ + if yyhl64 { + yyb64 = yyj64 > l } else { - yyb62 = r.CheckBreak() + yyb64 = r.CheckBreak() } - if yyb62 { + if yyb64 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) + return + } + z.DecSendContainerState(codecSelfer_containerArrayElem1234) + if r.TryDecodeAsNil() { + x.NodeMonitorPeriod = pkg1_unversioned.Duration{} + } else { + yyv106 := &x.NodeMonitorPeriod + yym107 := z.DecBinary() + _ = yym107 + if false { + } else if z.HasExtensions() && z.DecExt(yyv106) { + } else if !yym107 && z.IsJSONHandle() { + z.DecJSONUnmarshal(yyv106) + } else { + z.DecFallback(yyv106, false) + } + } + yyj64++ + if yyhl64 { + yyb64 = yyj64 > l + } else { + yyb64 = r.CheckBreak() + } + if yyb64 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -8289,13 +8428,13 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromArray(l int, d * } else { x.ServiceAccountKeyFile = string(r.DecodeString()) } - yyj62++ - if yyhl62 { - yyb62 = yyj62 > l + yyj64++ + if yyhl64 { + yyb64 = yyj64 > l } else { - yyb62 = r.CheckBreak() + yyb64 = r.CheckBreak() } - if yyb62 { + if yyb64 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -8305,13 +8444,13 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromArray(l int, d * } else { x.EnableProfiling = bool(r.DecodeBool()) } - yyj62++ - if yyhl62 { - yyb62 = yyj62 > l + yyj64++ + if yyhl64 { + yyb64 = yyj64 > l } else { - yyb62 = r.CheckBreak() + yyb64 = r.CheckBreak() } - if yyb62 { + if yyb64 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -8321,13 +8460,13 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromArray(l int, d * } else { x.ClusterName = string(r.DecodeString()) } - yyj62++ - if yyhl62 { - yyb62 = yyj62 > l + yyj64++ + if yyhl64 { + yyb64 = yyj64 > l } else { - yyb62 = r.CheckBreak() + yyb64 = r.CheckBreak() } - if yyb62 { + if yyb64 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -8337,13 +8476,45 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromArray(l int, d * } else { x.ClusterCIDR = string(r.DecodeString()) } - yyj62++ - if yyhl62 { - yyb62 = yyj62 > l + yyj64++ + if yyhl64 { + yyb64 = yyj64 > l } else { - yyb62 = r.CheckBreak() + yyb64 = r.CheckBreak() } - if yyb62 { + if yyb64 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) + return + } + z.DecSendContainerState(codecSelfer_containerArrayElem1234) + if r.TryDecodeAsNil() { + x.ServiceCIDR = "" + } else { + x.ServiceCIDR = string(r.DecodeString()) + } + yyj64++ + if yyhl64 { + yyb64 = yyj64 > l + } else { + yyb64 = r.CheckBreak() + } + if yyb64 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) + return + } + z.DecSendContainerState(codecSelfer_containerArrayElem1234) + if r.TryDecodeAsNil() { + x.NodeCIDRMaskSize = 0 + } else { + x.NodeCIDRMaskSize = int32(r.DecodeInt(32)) + } + yyj64++ + if yyhl64 { + yyb64 = yyj64 > l + } else { + yyb64 = r.CheckBreak() + } + if yyb64 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -8353,13 +8524,13 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromArray(l int, d * } else { x.AllocateNodeCIDRs = bool(r.DecodeBool()) } - yyj62++ - if yyhl62 { - yyb62 = yyj62 > l + yyj64++ + if yyhl64 { + yyb64 = yyj64 > l } else { - yyb62 = r.CheckBreak() + yyb64 = r.CheckBreak() } - if yyb62 { + if yyb64 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -8369,13 +8540,13 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromArray(l int, d * } else { x.RootCAFile = string(r.DecodeString()) } - yyj62++ - if yyhl62 { - yyb62 = yyj62 > l + yyj64++ + if yyhl64 { + yyb64 = yyj64 > l } else { - yyb62 = r.CheckBreak() + yyb64 = r.CheckBreak() } - if yyb62 { + if yyb64 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -8385,13 +8556,13 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromArray(l int, d * } else { x.ContentType = string(r.DecodeString()) } - yyj62++ - if yyhl62 { - yyb62 = yyj62 > l + yyj64++ + if yyhl64 { + yyb64 = yyj64 > l } else { - yyb62 = r.CheckBreak() + yyb64 = r.CheckBreak() } - if yyb62 { + if yyb64 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -8401,13 +8572,13 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromArray(l int, d * } else { x.KubeAPIQPS = float32(r.DecodeFloat(true)) } - yyj62++ - if yyhl62 { - yyb62 = yyj62 > l + yyj64++ + if yyhl64 { + yyb64 = yyj64 > l } else { - yyb62 = r.CheckBreak() + yyb64 = r.CheckBreak() } - if yyb62 { + if yyb64 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -8417,13 +8588,13 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromArray(l int, d * } else { x.KubeAPIBurst = int32(r.DecodeInt(32)) } - yyj62++ - if yyhl62 { - yyb62 = yyj62 > l + yyj64++ + if yyhl64 { + yyb64 = yyj64 > l } else { - yyb62 = r.CheckBreak() + yyb64 = r.CheckBreak() } - if yyb62 { + if yyb64 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -8431,16 +8602,16 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromArray(l int, d * if r.TryDecodeAsNil() { x.LeaderElection = LeaderElectionConfiguration{} } else { - yyv115 := &x.LeaderElection - yyv115.CodecDecodeSelf(d) + yyv119 := &x.LeaderElection + yyv119.CodecDecodeSelf(d) } - yyj62++ - if yyhl62 { - yyb62 = yyj62 > l + yyj64++ + if yyhl64 { + yyb64 = yyj64 > l } else { - yyb62 = r.CheckBreak() + yyb64 = r.CheckBreak() } - if yyb62 { + if yyb64 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -8448,16 +8619,16 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromArray(l int, d * if r.TryDecodeAsNil() { x.VolumeConfiguration = VolumeConfiguration{} } else { - yyv116 := &x.VolumeConfiguration - yyv116.CodecDecodeSelf(d) + yyv120 := &x.VolumeConfiguration + yyv120.CodecDecodeSelf(d) } - yyj62++ - if yyhl62 { - yyb62 = yyj62 > l + yyj64++ + if yyhl64 { + yyb64 = yyj64 > l } else { - yyb62 = r.CheckBreak() + yyb64 = r.CheckBreak() } - if yyb62 { + if yyb64 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -8465,24 +8636,24 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromArray(l int, d * if r.TryDecodeAsNil() { x.ControllerStartInterval = pkg1_unversioned.Duration{} } else { - yyv117 := &x.ControllerStartInterval - yym118 := z.DecBinary() - _ = yym118 + yyv121 := &x.ControllerStartInterval + yym122 := z.DecBinary() + _ = yym122 if false { - } else if z.HasExtensions() && z.DecExt(yyv117) { - } else if !yym118 && z.IsJSONHandle() { - z.DecJSONUnmarshal(yyv117) + } else if z.HasExtensions() && z.DecExt(yyv121) { + } else if !yym122 && z.IsJSONHandle() { + z.DecJSONUnmarshal(yyv121) } else { - z.DecFallback(yyv117, false) + z.DecFallback(yyv121, false) } } - yyj62++ - if yyhl62 { - yyb62 = yyj62 > l + yyj64++ + if yyhl64 { + yyb64 = yyj64 > l } else { - yyb62 = r.CheckBreak() + yyb64 = r.CheckBreak() } - if yyb62 { + if yyb64 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -8492,13 +8663,13 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromArray(l int, d * } else { x.Kind = string(r.DecodeString()) } - yyj62++ - if yyhl62 { - yyb62 = yyj62 > l + yyj64++ + if yyhl64 { + yyb64 = yyj64 > l } else { - yyb62 = r.CheckBreak() + yyb64 = r.CheckBreak() } - if yyb62 { + if yyb64 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -8509,17 +8680,17 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromArray(l int, d * x.APIVersion = string(r.DecodeString()) } for { - yyj62++ - if yyhl62 { - yyb62 = yyj62 > l + yyj64++ + if yyhl64 { + yyb64 = yyj64 > l } else { - yyb62 = r.CheckBreak() + yyb64 = r.CheckBreak() } - if yyb62 { + if yyb64 { break } z.DecSendContainerState(codecSelfer_containerArrayElem1234) - z.DecStructFieldNotFound(yyj62-1, "") + z.DecStructFieldNotFound(yyj64-1, "") } z.DecSendContainerState(codecSelfer_containerArrayEnd1234) } diff --git a/vendor/k8s.io/kubernetes/pkg/apis/componentconfig/types.go b/vendor/k8s.io/kubernetes/pkg/apis/componentconfig/types.go index ffef22ce0f..dd289700ef 100644 --- a/vendor/k8s.io/kubernetes/pkg/apis/componentconfig/types.go +++ b/vendor/k8s.io/kubernetes/pkg/apis/componentconfig/types.go @@ -273,6 +273,11 @@ type KubeletConfiguration struct { // It uses this file as a lock to synchronize with other kubelet processes // that may be running. LockFilePath string `json:"lockFilePath"` + // ExitOnLockContention is a flag that signifies to the kubelet that it is running + // in "bootstrap" mode. This requires that 'LockFilePath' has been set. + // This will cause the kubelet to listen to inotify events on the lock file, + // releasing it and exiting when another process tries to open that file. + ExitOnLockContention bool `json:"exitOnLockContention"` // configureCBR0 enables the kublet to configure cbr0 based on // Node.Spec.PodCIDR. ConfigureCBR0 bool `json:"configureCbr0"` @@ -351,6 +356,8 @@ type KubeletConfiguration struct { EvictionSoftGracePeriod string `json:"evictionSoftGracePeriod,omitempty"` // Duration for which the kubelet has to wait before transitioning out of an eviction pressure condition. EvictionPressureTransitionPeriod unversioned.Duration `json:"evictionPressureTransitionPeriod,omitempty"` + // Maximum allowed grace period (in seconds) to use when terminating pods in response to a soft eviction threshold being met. + EvictionMaxPodGracePeriod int32 `json:"evictionMaxPodGracePeriod,omitempty"` } type KubeSchedulerConfiguration struct { @@ -520,6 +527,10 @@ type KubeControllerManagerConfiguration struct { ClusterName string `json:"clusterName"` // clusterCIDR is CIDR Range for Pods in cluster. ClusterCIDR string `json:"clusterCIDR"` + // serviceCIDR is CIDR Range for Services in cluster. + ServiceCIDR string `json:"serviceCIDR"` + // NodeCIDRMaskSize is the mask size for node cidr in cluster. + NodeCIDRMaskSize int32 `json:"nodeCIDRMaskSize"` // allocateNodeCIDRs enables CIDRs for Pods to be allocated and set on the // cloud provider. AllocateNodeCIDRs bool `json:"allocateNodeCIDRs"` diff --git a/vendor/k8s.io/kubernetes/pkg/apis/componentconfig/v1alpha1/defaults.go b/vendor/k8s.io/kubernetes/pkg/apis/componentconfig/v1alpha1/defaults.go index a199b04ac9..bab6bb3e32 100644 --- a/vendor/k8s.io/kubernetes/pkg/apis/componentconfig/v1alpha1/defaults.go +++ b/vendor/k8s.io/kubernetes/pkg/apis/componentconfig/v1alpha1/defaults.go @@ -80,6 +80,9 @@ func SetDefaults_KubeSchedulerConfiguration(obj *KubeSchedulerConfiguration) { if obj.AlgorithmProvider == "" { obj.AlgorithmProvider = "DefaultProvider" } + if obj.ContentType == "" { + obj.ContentType = "application/vnd.kubernetes.protobuf" + } if obj.KubeAPIQPS == 0 { obj.KubeAPIQPS = 50.0 } diff --git a/vendor/k8s.io/kubernetes/pkg/apis/extensions/deep_copy_generated.go b/vendor/k8s.io/kubernetes/pkg/apis/extensions/deep_copy_generated.go index 835765e6d1..0d36541178 100644 --- a/vendor/k8s.io/kubernetes/pkg/apis/extensions/deep_copy_generated.go +++ b/vendor/k8s.io/kubernetes/pkg/apis/extensions/deep_copy_generated.go @@ -58,6 +58,12 @@ func init() { DeepCopy_extensions_IngressSpec, DeepCopy_extensions_IngressStatus, DeepCopy_extensions_IngressTLS, + DeepCopy_extensions_NetworkPolicy, + DeepCopy_extensions_NetworkPolicyIngressRule, + DeepCopy_extensions_NetworkPolicyList, + DeepCopy_extensions_NetworkPolicyPeer, + DeepCopy_extensions_NetworkPolicyPort, + DeepCopy_extensions_NetworkPolicySpec, DeepCopy_extensions_PodSecurityPolicy, DeepCopy_extensions_PodSecurityPolicyList, DeepCopy_extensions_PodSecurityPolicySpec, @@ -484,6 +490,130 @@ func DeepCopy_extensions_IngressTLS(in IngressTLS, out *IngressTLS, c *conversio return nil } +func DeepCopy_extensions_NetworkPolicy(in NetworkPolicy, out *NetworkPolicy, c *conversion.Cloner) error { + if err := unversioned.DeepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + return err + } + if err := api.DeepCopy_api_ObjectMeta(in.ObjectMeta, &out.ObjectMeta, c); err != nil { + return err + } + if err := DeepCopy_extensions_NetworkPolicySpec(in.Spec, &out.Spec, c); err != nil { + return err + } + return nil +} + +func DeepCopy_extensions_NetworkPolicyIngressRule(in NetworkPolicyIngressRule, out *NetworkPolicyIngressRule, c *conversion.Cloner) error { + if in.Ports != nil { + in, out := in.Ports, &out.Ports + *out = make([]NetworkPolicyPort, len(in)) + for i := range in { + if err := DeepCopy_extensions_NetworkPolicyPort(in[i], &(*out)[i], c); err != nil { + return err + } + } + } else { + out.Ports = nil + } + if in.From != nil { + in, out := in.From, &out.From + *out = make([]NetworkPolicyPeer, len(in)) + for i := range in { + if err := DeepCopy_extensions_NetworkPolicyPeer(in[i], &(*out)[i], c); err != nil { + return err + } + } + } else { + out.From = nil + } + return nil +} + +func DeepCopy_extensions_NetworkPolicyList(in NetworkPolicyList, out *NetworkPolicyList, c *conversion.Cloner) error { + if err := unversioned.DeepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + return err + } + if err := unversioned.DeepCopy_unversioned_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { + return err + } + if in.Items != nil { + in, out := in.Items, &out.Items + *out = make([]NetworkPolicy, len(in)) + for i := range in { + if err := DeepCopy_extensions_NetworkPolicy(in[i], &(*out)[i], c); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +func DeepCopy_extensions_NetworkPolicyPeer(in NetworkPolicyPeer, out *NetworkPolicyPeer, c *conversion.Cloner) error { + if in.PodSelector != nil { + in, out := in.PodSelector, &out.PodSelector + *out = new(unversioned.LabelSelector) + if err := unversioned.DeepCopy_unversioned_LabelSelector(*in, *out, c); err != nil { + return err + } + } else { + out.PodSelector = nil + } + if in.NamespaceSelector != nil { + in, out := in.NamespaceSelector, &out.NamespaceSelector + *out = new(unversioned.LabelSelector) + if err := unversioned.DeepCopy_unversioned_LabelSelector(*in, *out, c); err != nil { + return err + } + } else { + out.NamespaceSelector = nil + } + return nil +} + +func DeepCopy_extensions_NetworkPolicyPort(in NetworkPolicyPort, out *NetworkPolicyPort, c *conversion.Cloner) error { + if in.Protocol != nil { + in, out := in.Protocol, &out.Protocol + *out = new(api.Protocol) + if newVal, err := c.DeepCopy(*in); err != nil { + return err + } else { + **out = newVal.(api.Protocol) + } + } else { + out.Protocol = nil + } + if in.Port != nil { + in, out := in.Port, &out.Port + *out = new(intstr.IntOrString) + if err := intstr.DeepCopy_intstr_IntOrString(*in, *out, c); err != nil { + return err + } + } else { + out.Port = nil + } + return nil +} + +func DeepCopy_extensions_NetworkPolicySpec(in NetworkPolicySpec, out *NetworkPolicySpec, c *conversion.Cloner) error { + if err := unversioned.DeepCopy_unversioned_LabelSelector(in.PodSelector, &out.PodSelector, c); err != nil { + return err + } + if in.Ingress != nil { + in, out := in.Ingress, &out.Ingress + *out = make([]NetworkPolicyIngressRule, len(in)) + for i := range in { + if err := DeepCopy_extensions_NetworkPolicyIngressRule(in[i], &(*out)[i], c); err != nil { + return err + } + } + } else { + out.Ingress = nil + } + return nil +} + func DeepCopy_extensions_PodSecurityPolicy(in PodSecurityPolicy, out *PodSecurityPolicy, c *conversion.Cloner) error { if err := unversioned.DeepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { return err diff --git a/vendor/k8s.io/kubernetes/pkg/apis/extensions/register.go b/vendor/k8s.io/kubernetes/pkg/apis/extensions/register.go index 0e6482a97e..3264ae658a 100644 --- a/vendor/k8s.io/kubernetes/pkg/apis/extensions/register.go +++ b/vendor/k8s.io/kubernetes/pkg/apis/extensions/register.go @@ -73,6 +73,8 @@ func addKnownTypes(scheme *runtime.Scheme) { &api.ExportOptions{}, &PodSecurityPolicy{}, &PodSecurityPolicyList{}, + &NetworkPolicy{}, + &NetworkPolicyList{}, ) } @@ -93,3 +95,5 @@ func (obj *ReplicaSet) GetObjectKind() unversioned.ObjectKind { func (obj *ReplicaSetList) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta } func (obj *PodSecurityPolicy) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta } func (obj *PodSecurityPolicyList) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta } +func (obj *NetworkPolicy) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta } +func (obj *NetworkPolicyList) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta } diff --git a/vendor/k8s.io/kubernetes/pkg/apis/extensions/types.generated.go b/vendor/k8s.io/kubernetes/pkg/apis/extensions/types.generated.go index 030741f22d..2d46079685 100644 --- a/vendor/k8s.io/kubernetes/pkg/apis/extensions/types.generated.go +++ b/vendor/k8s.io/kubernetes/pkg/apis/extensions/types.generated.go @@ -1,5 +1,5 @@ /* -Copyright 2015 The Kubernetes Authors All rights reserved. +Copyright 2016 The Kubernetes Authors All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -25,12 +25,11 @@ import ( "errors" "fmt" codec1978 "github.com/ugorji/go/codec" - pkg5_inf_v0 "gopkg.in/inf.v0" pkg2_api "k8s.io/kubernetes/pkg/api" pkg4_resource "k8s.io/kubernetes/pkg/api/resource" pkg1_unversioned "k8s.io/kubernetes/pkg/api/unversioned" pkg3_types "k8s.io/kubernetes/pkg/types" - pkg6_intstr "k8s.io/kubernetes/pkg/util/intstr" + pkg5_intstr "k8s.io/kubernetes/pkg/util/intstr" "reflect" "runtime" time "time" @@ -66,14 +65,13 @@ func init() { panic(err) } if false { // reference the types, but skip this branch at build/run time - var v0 pkg5_inf_v0.Dec - var v1 pkg2_api.ObjectMeta - var v2 pkg4_resource.Quantity - var v3 pkg1_unversioned.LabelSelector - var v4 pkg3_types.UID - var v5 pkg6_intstr.IntOrString - var v6 time.Time - _, _, _, _, _, _, _ = v0, v1, v2, v3, v4, v5, v6 + var v0 pkg2_api.ObjectMeta + var v1 pkg4_resource.Quantity + var v2 pkg1_unversioned.LabelSelector + var v3 pkg3_types.UID + var v4 pkg5_intstr.IntOrString + var v5 time.Time + _, _, _, _, _, _ = v0, v1, v2, v3, v4, v5 } } @@ -4916,7 +4914,7 @@ func (x *RollingUpdateDeployment) codecDecodeSelfFromMap(l int, d *codec1978.Dec switch yys3 { case "maxUnavailable": if r.TryDecodeAsNil() { - x.MaxUnavailable = pkg6_intstr.IntOrString{} + x.MaxUnavailable = pkg5_intstr.IntOrString{} } else { yyv4 := &x.MaxUnavailable yym5 := z.DecBinary() @@ -4931,7 +4929,7 @@ func (x *RollingUpdateDeployment) codecDecodeSelfFromMap(l int, d *codec1978.Dec } case "maxSurge": if r.TryDecodeAsNil() { - x.MaxSurge = pkg6_intstr.IntOrString{} + x.MaxSurge = pkg5_intstr.IntOrString{} } else { yyv6 := &x.MaxSurge yym7 := z.DecBinary() @@ -4970,7 +4968,7 @@ func (x *RollingUpdateDeployment) codecDecodeSelfFromArray(l int, d *codec1978.D } z.DecSendContainerState(codecSelfer_containerArrayElem1234) if r.TryDecodeAsNil() { - x.MaxUnavailable = pkg6_intstr.IntOrString{} + x.MaxUnavailable = pkg5_intstr.IntOrString{} } else { yyv9 := &x.MaxUnavailable yym10 := z.DecBinary() @@ -4995,7 +4993,7 @@ func (x *RollingUpdateDeployment) codecDecodeSelfFromArray(l int, d *codec1978.D } z.DecSendContainerState(codecSelfer_containerArrayElem1234) if r.TryDecodeAsNil() { - x.MaxSurge = pkg6_intstr.IntOrString{} + x.MaxSurge = pkg5_intstr.IntOrString{} } else { yyv11 := &x.MaxSurge yym12 := z.DecBinary() @@ -9593,7 +9591,7 @@ func (x *IngressBackend) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) { } case "servicePort": if r.TryDecodeAsNil() { - x.ServicePort = pkg6_intstr.IntOrString{} + x.ServicePort = pkg5_intstr.IntOrString{} } else { yyv5 := &x.ServicePort yym6 := z.DecBinary() @@ -9648,7 +9646,7 @@ func (x *IngressBackend) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { } z.DecSendContainerState(codecSelfer_containerArrayElem1234) if r.TryDecodeAsNil() { - x.ServicePort = pkg6_intstr.IntOrString{} + x.ServicePort = pkg5_intstr.IntOrString{} } else { yyv9 := &x.ServicePort yym10 := z.DecBinary() @@ -13810,6 +13808,1706 @@ func (x *PodSecurityPolicyList) codecDecodeSelfFromArray(l int, d *codec1978.Dec z.DecSendContainerState(codecSelfer_containerArrayEnd1234) } +func (x *NetworkPolicy) CodecEncodeSelf(e *codec1978.Encoder) { + var h codecSelfer1234 + z, r := codec1978.GenHelperEncoder(e) + _, _, _ = h, z, r + if x == nil { + r.EncodeNil() + } else { + yym1 := z.EncBinary() + _ = yym1 + if false { + } else if z.HasExtensions() && z.EncExt(x) { + } else { + yysep2 := !z.EncBinary() + yy2arr2 := z.EncBasicHandle().StructToArray + var yyq2 [4]bool + _, _, _ = yysep2, yyq2, yy2arr2 + const yyr2 bool = false + yyq2[0] = true + yyq2[1] = true + yyq2[2] = x.Kind != "" + yyq2[3] = x.APIVersion != "" + var yynn2 int + if yyr2 || yy2arr2 { + r.EncodeArrayStart(4) + } else { + yynn2 = 0 + for _, b := range yyq2 { + if b { + yynn2++ + } + } + r.EncodeMapStart(yynn2) + yynn2 = 0 + } + if yyr2 || yy2arr2 { + z.EncSendContainerState(codecSelfer_containerArrayElem1234) + if yyq2[0] { + yy4 := &x.ObjectMeta + yy4.CodecEncodeSelf(e) + } else { + r.EncodeNil() + } + } else { + if yyq2[0] { + z.EncSendContainerState(codecSelfer_containerMapKey1234) + r.EncodeString(codecSelferC_UTF81234, string("metadata")) + z.EncSendContainerState(codecSelfer_containerMapValue1234) + yy6 := &x.ObjectMeta + yy6.CodecEncodeSelf(e) + } + } + if yyr2 || yy2arr2 { + z.EncSendContainerState(codecSelfer_containerArrayElem1234) + if yyq2[1] { + yy9 := &x.Spec + yy9.CodecEncodeSelf(e) + } else { + r.EncodeNil() + } + } else { + if yyq2[1] { + z.EncSendContainerState(codecSelfer_containerMapKey1234) + r.EncodeString(codecSelferC_UTF81234, string("spec")) + z.EncSendContainerState(codecSelfer_containerMapValue1234) + yy11 := &x.Spec + yy11.CodecEncodeSelf(e) + } + } + if yyr2 || yy2arr2 { + z.EncSendContainerState(codecSelfer_containerArrayElem1234) + if yyq2[2] { + yym14 := z.EncBinary() + _ = yym14 + if false { + } else { + r.EncodeString(codecSelferC_UTF81234, string(x.Kind)) + } + } else { + r.EncodeString(codecSelferC_UTF81234, "") + } + } else { + if yyq2[2] { + z.EncSendContainerState(codecSelfer_containerMapKey1234) + r.EncodeString(codecSelferC_UTF81234, string("kind")) + z.EncSendContainerState(codecSelfer_containerMapValue1234) + yym15 := z.EncBinary() + _ = yym15 + if false { + } else { + r.EncodeString(codecSelferC_UTF81234, string(x.Kind)) + } + } + } + if yyr2 || yy2arr2 { + z.EncSendContainerState(codecSelfer_containerArrayElem1234) + if yyq2[3] { + yym17 := z.EncBinary() + _ = yym17 + if false { + } else { + r.EncodeString(codecSelferC_UTF81234, string(x.APIVersion)) + } + } else { + r.EncodeString(codecSelferC_UTF81234, "") + } + } else { + if yyq2[3] { + z.EncSendContainerState(codecSelfer_containerMapKey1234) + r.EncodeString(codecSelferC_UTF81234, string("apiVersion")) + z.EncSendContainerState(codecSelfer_containerMapValue1234) + yym18 := z.EncBinary() + _ = yym18 + if false { + } else { + r.EncodeString(codecSelferC_UTF81234, string(x.APIVersion)) + } + } + } + if yyr2 || yy2arr2 { + z.EncSendContainerState(codecSelfer_containerArrayEnd1234) + } else { + z.EncSendContainerState(codecSelfer_containerMapEnd1234) + } + } + } +} + +func (x *NetworkPolicy) CodecDecodeSelf(d *codec1978.Decoder) { + var h codecSelfer1234 + z, r := codec1978.GenHelperDecoder(d) + _, _, _ = h, z, r + yym1 := z.DecBinary() + _ = yym1 + if false { + } else if z.HasExtensions() && z.DecExt(x) { + } else { + yyct2 := r.ContainerType() + if yyct2 == codecSelferValueTypeMap1234 { + yyl2 := r.ReadMapStart() + if yyl2 == 0 { + z.DecSendContainerState(codecSelfer_containerMapEnd1234) + } else { + x.codecDecodeSelfFromMap(yyl2, d) + } + } else if yyct2 == codecSelferValueTypeArray1234 { + yyl2 := r.ReadArrayStart() + if yyl2 == 0 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) + } else { + x.codecDecodeSelfFromArray(yyl2, d) + } + } else { + panic(codecSelferOnlyMapOrArrayEncodeToStructErr1234) + } + } +} + +func (x *NetworkPolicy) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) { + var h codecSelfer1234 + z, r := codec1978.GenHelperDecoder(d) + _, _, _ = h, z, r + var yys3Slc = z.DecScratchBuffer() // default slice to decode into + _ = yys3Slc + var yyhl3 bool = l >= 0 + for yyj3 := 0; ; yyj3++ { + if yyhl3 { + if yyj3 >= l { + break + } + } else { + if r.CheckBreak() { + break + } + } + z.DecSendContainerState(codecSelfer_containerMapKey1234) + yys3Slc = r.DecodeBytes(yys3Slc, true, true) + yys3 := string(yys3Slc) + z.DecSendContainerState(codecSelfer_containerMapValue1234) + switch yys3 { + case "metadata": + if r.TryDecodeAsNil() { + x.ObjectMeta = pkg2_api.ObjectMeta{} + } else { + yyv4 := &x.ObjectMeta + yyv4.CodecDecodeSelf(d) + } + case "spec": + if r.TryDecodeAsNil() { + x.Spec = NetworkPolicySpec{} + } else { + yyv5 := &x.Spec + yyv5.CodecDecodeSelf(d) + } + case "kind": + if r.TryDecodeAsNil() { + x.Kind = "" + } else { + x.Kind = string(r.DecodeString()) + } + case "apiVersion": + if r.TryDecodeAsNil() { + x.APIVersion = "" + } else { + x.APIVersion = string(r.DecodeString()) + } + default: + z.DecStructFieldNotFound(-1, yys3) + } // end switch yys3 + } // end for yyj3 + z.DecSendContainerState(codecSelfer_containerMapEnd1234) +} + +func (x *NetworkPolicy) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { + var h codecSelfer1234 + z, r := codec1978.GenHelperDecoder(d) + _, _, _ = h, z, r + var yyj8 int + var yyb8 bool + var yyhl8 bool = l >= 0 + yyj8++ + if yyhl8 { + yyb8 = yyj8 > l + } else { + yyb8 = r.CheckBreak() + } + if yyb8 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) + return + } + z.DecSendContainerState(codecSelfer_containerArrayElem1234) + if r.TryDecodeAsNil() { + x.ObjectMeta = pkg2_api.ObjectMeta{} + } else { + yyv9 := &x.ObjectMeta + yyv9.CodecDecodeSelf(d) + } + yyj8++ + if yyhl8 { + yyb8 = yyj8 > l + } else { + yyb8 = r.CheckBreak() + } + if yyb8 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) + return + } + z.DecSendContainerState(codecSelfer_containerArrayElem1234) + if r.TryDecodeAsNil() { + x.Spec = NetworkPolicySpec{} + } else { + yyv10 := &x.Spec + yyv10.CodecDecodeSelf(d) + } + yyj8++ + if yyhl8 { + yyb8 = yyj8 > l + } else { + yyb8 = r.CheckBreak() + } + if yyb8 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) + return + } + z.DecSendContainerState(codecSelfer_containerArrayElem1234) + if r.TryDecodeAsNil() { + x.Kind = "" + } else { + x.Kind = string(r.DecodeString()) + } + yyj8++ + if yyhl8 { + yyb8 = yyj8 > l + } else { + yyb8 = r.CheckBreak() + } + if yyb8 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) + return + } + z.DecSendContainerState(codecSelfer_containerArrayElem1234) + if r.TryDecodeAsNil() { + x.APIVersion = "" + } else { + x.APIVersion = string(r.DecodeString()) + } + for { + yyj8++ + if yyhl8 { + yyb8 = yyj8 > l + } else { + yyb8 = r.CheckBreak() + } + if yyb8 { + break + } + z.DecSendContainerState(codecSelfer_containerArrayElem1234) + z.DecStructFieldNotFound(yyj8-1, "") + } + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) +} + +func (x *NetworkPolicySpec) CodecEncodeSelf(e *codec1978.Encoder) { + var h codecSelfer1234 + z, r := codec1978.GenHelperEncoder(e) + _, _, _ = h, z, r + if x == nil { + r.EncodeNil() + } else { + yym1 := z.EncBinary() + _ = yym1 + if false { + } else if z.HasExtensions() && z.EncExt(x) { + } else { + yysep2 := !z.EncBinary() + yy2arr2 := z.EncBasicHandle().StructToArray + var yyq2 [2]bool + _, _, _ = yysep2, yyq2, yy2arr2 + const yyr2 bool = false + yyq2[1] = len(x.Ingress) != 0 + var yynn2 int + if yyr2 || yy2arr2 { + r.EncodeArrayStart(2) + } else { + yynn2 = 1 + for _, b := range yyq2 { + if b { + yynn2++ + } + } + r.EncodeMapStart(yynn2) + yynn2 = 0 + } + if yyr2 || yy2arr2 { + z.EncSendContainerState(codecSelfer_containerArrayElem1234) + yy4 := &x.PodSelector + yym5 := z.EncBinary() + _ = yym5 + if false { + } else if z.HasExtensions() && z.EncExt(yy4) { + } else { + z.EncFallback(yy4) + } + } else { + z.EncSendContainerState(codecSelfer_containerMapKey1234) + r.EncodeString(codecSelferC_UTF81234, string("podSelector")) + z.EncSendContainerState(codecSelfer_containerMapValue1234) + yy6 := &x.PodSelector + yym7 := z.EncBinary() + _ = yym7 + if false { + } else if z.HasExtensions() && z.EncExt(yy6) { + } else { + z.EncFallback(yy6) + } + } + if yyr2 || yy2arr2 { + z.EncSendContainerState(codecSelfer_containerArrayElem1234) + if yyq2[1] { + if x.Ingress == nil { + r.EncodeNil() + } else { + yym9 := z.EncBinary() + _ = yym9 + if false { + } else { + h.encSliceNetworkPolicyIngressRule(([]NetworkPolicyIngressRule)(x.Ingress), e) + } + } + } else { + r.EncodeNil() + } + } else { + if yyq2[1] { + z.EncSendContainerState(codecSelfer_containerMapKey1234) + r.EncodeString(codecSelferC_UTF81234, string("ingress")) + z.EncSendContainerState(codecSelfer_containerMapValue1234) + if x.Ingress == nil { + r.EncodeNil() + } else { + yym10 := z.EncBinary() + _ = yym10 + if false { + } else { + h.encSliceNetworkPolicyIngressRule(([]NetworkPolicyIngressRule)(x.Ingress), e) + } + } + } + } + if yyr2 || yy2arr2 { + z.EncSendContainerState(codecSelfer_containerArrayEnd1234) + } else { + z.EncSendContainerState(codecSelfer_containerMapEnd1234) + } + } + } +} + +func (x *NetworkPolicySpec) CodecDecodeSelf(d *codec1978.Decoder) { + var h codecSelfer1234 + z, r := codec1978.GenHelperDecoder(d) + _, _, _ = h, z, r + yym1 := z.DecBinary() + _ = yym1 + if false { + } else if z.HasExtensions() && z.DecExt(x) { + } else { + yyct2 := r.ContainerType() + if yyct2 == codecSelferValueTypeMap1234 { + yyl2 := r.ReadMapStart() + if yyl2 == 0 { + z.DecSendContainerState(codecSelfer_containerMapEnd1234) + } else { + x.codecDecodeSelfFromMap(yyl2, d) + } + } else if yyct2 == codecSelferValueTypeArray1234 { + yyl2 := r.ReadArrayStart() + if yyl2 == 0 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) + } else { + x.codecDecodeSelfFromArray(yyl2, d) + } + } else { + panic(codecSelferOnlyMapOrArrayEncodeToStructErr1234) + } + } +} + +func (x *NetworkPolicySpec) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) { + var h codecSelfer1234 + z, r := codec1978.GenHelperDecoder(d) + _, _, _ = h, z, r + var yys3Slc = z.DecScratchBuffer() // default slice to decode into + _ = yys3Slc + var yyhl3 bool = l >= 0 + for yyj3 := 0; ; yyj3++ { + if yyhl3 { + if yyj3 >= l { + break + } + } else { + if r.CheckBreak() { + break + } + } + z.DecSendContainerState(codecSelfer_containerMapKey1234) + yys3Slc = r.DecodeBytes(yys3Slc, true, true) + yys3 := string(yys3Slc) + z.DecSendContainerState(codecSelfer_containerMapValue1234) + switch yys3 { + case "podSelector": + if r.TryDecodeAsNil() { + x.PodSelector = pkg1_unversioned.LabelSelector{} + } else { + yyv4 := &x.PodSelector + yym5 := z.DecBinary() + _ = yym5 + if false { + } else if z.HasExtensions() && z.DecExt(yyv4) { + } else { + z.DecFallback(yyv4, false) + } + } + case "ingress": + if r.TryDecodeAsNil() { + x.Ingress = nil + } else { + yyv6 := &x.Ingress + yym7 := z.DecBinary() + _ = yym7 + if false { + } else { + h.decSliceNetworkPolicyIngressRule((*[]NetworkPolicyIngressRule)(yyv6), d) + } + } + default: + z.DecStructFieldNotFound(-1, yys3) + } // end switch yys3 + } // end for yyj3 + z.DecSendContainerState(codecSelfer_containerMapEnd1234) +} + +func (x *NetworkPolicySpec) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { + var h codecSelfer1234 + z, r := codec1978.GenHelperDecoder(d) + _, _, _ = h, z, r + var yyj8 int + var yyb8 bool + var yyhl8 bool = l >= 0 + yyj8++ + if yyhl8 { + yyb8 = yyj8 > l + } else { + yyb8 = r.CheckBreak() + } + if yyb8 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) + return + } + z.DecSendContainerState(codecSelfer_containerArrayElem1234) + if r.TryDecodeAsNil() { + x.PodSelector = pkg1_unversioned.LabelSelector{} + } else { + yyv9 := &x.PodSelector + yym10 := z.DecBinary() + _ = yym10 + if false { + } else if z.HasExtensions() && z.DecExt(yyv9) { + } else { + z.DecFallback(yyv9, false) + } + } + yyj8++ + if yyhl8 { + yyb8 = yyj8 > l + } else { + yyb8 = r.CheckBreak() + } + if yyb8 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) + return + } + z.DecSendContainerState(codecSelfer_containerArrayElem1234) + if r.TryDecodeAsNil() { + x.Ingress = nil + } else { + yyv11 := &x.Ingress + yym12 := z.DecBinary() + _ = yym12 + if false { + } else { + h.decSliceNetworkPolicyIngressRule((*[]NetworkPolicyIngressRule)(yyv11), d) + } + } + for { + yyj8++ + if yyhl8 { + yyb8 = yyj8 > l + } else { + yyb8 = r.CheckBreak() + } + if yyb8 { + break + } + z.DecSendContainerState(codecSelfer_containerArrayElem1234) + z.DecStructFieldNotFound(yyj8-1, "") + } + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) +} + +func (x *NetworkPolicyIngressRule) CodecEncodeSelf(e *codec1978.Encoder) { + var h codecSelfer1234 + z, r := codec1978.GenHelperEncoder(e) + _, _, _ = h, z, r + if x == nil { + r.EncodeNil() + } else { + yym1 := z.EncBinary() + _ = yym1 + if false { + } else if z.HasExtensions() && z.EncExt(x) { + } else { + yysep2 := !z.EncBinary() + yy2arr2 := z.EncBasicHandle().StructToArray + var yyq2 [2]bool + _, _, _ = yysep2, yyq2, yy2arr2 + const yyr2 bool = false + yyq2[0] = len(x.Ports) != 0 + yyq2[1] = len(x.From) != 0 + var yynn2 int + if yyr2 || yy2arr2 { + r.EncodeArrayStart(2) + } else { + yynn2 = 0 + for _, b := range yyq2 { + if b { + yynn2++ + } + } + r.EncodeMapStart(yynn2) + yynn2 = 0 + } + if yyr2 || yy2arr2 { + z.EncSendContainerState(codecSelfer_containerArrayElem1234) + if yyq2[0] { + if x.Ports == nil { + r.EncodeNil() + } else { + yym4 := z.EncBinary() + _ = yym4 + if false { + } else { + h.encSliceNetworkPolicyPort(([]NetworkPolicyPort)(x.Ports), e) + } + } + } else { + r.EncodeNil() + } + } else { + if yyq2[0] { + z.EncSendContainerState(codecSelfer_containerMapKey1234) + r.EncodeString(codecSelferC_UTF81234, string("ports")) + z.EncSendContainerState(codecSelfer_containerMapValue1234) + if x.Ports == nil { + r.EncodeNil() + } else { + yym5 := z.EncBinary() + _ = yym5 + if false { + } else { + h.encSliceNetworkPolicyPort(([]NetworkPolicyPort)(x.Ports), e) + } + } + } + } + if yyr2 || yy2arr2 { + z.EncSendContainerState(codecSelfer_containerArrayElem1234) + if yyq2[1] { + if x.From == nil { + r.EncodeNil() + } else { + yym7 := z.EncBinary() + _ = yym7 + if false { + } else { + h.encSliceNetworkPolicyPeer(([]NetworkPolicyPeer)(x.From), e) + } + } + } else { + r.EncodeNil() + } + } else { + if yyq2[1] { + z.EncSendContainerState(codecSelfer_containerMapKey1234) + r.EncodeString(codecSelferC_UTF81234, string("from")) + z.EncSendContainerState(codecSelfer_containerMapValue1234) + if x.From == nil { + r.EncodeNil() + } else { + yym8 := z.EncBinary() + _ = yym8 + if false { + } else { + h.encSliceNetworkPolicyPeer(([]NetworkPolicyPeer)(x.From), e) + } + } + } + } + if yyr2 || yy2arr2 { + z.EncSendContainerState(codecSelfer_containerArrayEnd1234) + } else { + z.EncSendContainerState(codecSelfer_containerMapEnd1234) + } + } + } +} + +func (x *NetworkPolicyIngressRule) CodecDecodeSelf(d *codec1978.Decoder) { + var h codecSelfer1234 + z, r := codec1978.GenHelperDecoder(d) + _, _, _ = h, z, r + yym1 := z.DecBinary() + _ = yym1 + if false { + } else if z.HasExtensions() && z.DecExt(x) { + } else { + yyct2 := r.ContainerType() + if yyct2 == codecSelferValueTypeMap1234 { + yyl2 := r.ReadMapStart() + if yyl2 == 0 { + z.DecSendContainerState(codecSelfer_containerMapEnd1234) + } else { + x.codecDecodeSelfFromMap(yyl2, d) + } + } else if yyct2 == codecSelferValueTypeArray1234 { + yyl2 := r.ReadArrayStart() + if yyl2 == 0 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) + } else { + x.codecDecodeSelfFromArray(yyl2, d) + } + } else { + panic(codecSelferOnlyMapOrArrayEncodeToStructErr1234) + } + } +} + +func (x *NetworkPolicyIngressRule) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) { + var h codecSelfer1234 + z, r := codec1978.GenHelperDecoder(d) + _, _, _ = h, z, r + var yys3Slc = z.DecScratchBuffer() // default slice to decode into + _ = yys3Slc + var yyhl3 bool = l >= 0 + for yyj3 := 0; ; yyj3++ { + if yyhl3 { + if yyj3 >= l { + break + } + } else { + if r.CheckBreak() { + break + } + } + z.DecSendContainerState(codecSelfer_containerMapKey1234) + yys3Slc = r.DecodeBytes(yys3Slc, true, true) + yys3 := string(yys3Slc) + z.DecSendContainerState(codecSelfer_containerMapValue1234) + switch yys3 { + case "ports": + if r.TryDecodeAsNil() { + x.Ports = nil + } else { + yyv4 := &x.Ports + yym5 := z.DecBinary() + _ = yym5 + if false { + } else { + h.decSliceNetworkPolicyPort((*[]NetworkPolicyPort)(yyv4), d) + } + } + case "from": + if r.TryDecodeAsNil() { + x.From = nil + } else { + yyv6 := &x.From + yym7 := z.DecBinary() + _ = yym7 + if false { + } else { + h.decSliceNetworkPolicyPeer((*[]NetworkPolicyPeer)(yyv6), d) + } + } + default: + z.DecStructFieldNotFound(-1, yys3) + } // end switch yys3 + } // end for yyj3 + z.DecSendContainerState(codecSelfer_containerMapEnd1234) +} + +func (x *NetworkPolicyIngressRule) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { + var h codecSelfer1234 + z, r := codec1978.GenHelperDecoder(d) + _, _, _ = h, z, r + var yyj8 int + var yyb8 bool + var yyhl8 bool = l >= 0 + yyj8++ + if yyhl8 { + yyb8 = yyj8 > l + } else { + yyb8 = r.CheckBreak() + } + if yyb8 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) + return + } + z.DecSendContainerState(codecSelfer_containerArrayElem1234) + if r.TryDecodeAsNil() { + x.Ports = nil + } else { + yyv9 := &x.Ports + yym10 := z.DecBinary() + _ = yym10 + if false { + } else { + h.decSliceNetworkPolicyPort((*[]NetworkPolicyPort)(yyv9), d) + } + } + yyj8++ + if yyhl8 { + yyb8 = yyj8 > l + } else { + yyb8 = r.CheckBreak() + } + if yyb8 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) + return + } + z.DecSendContainerState(codecSelfer_containerArrayElem1234) + if r.TryDecodeAsNil() { + x.From = nil + } else { + yyv11 := &x.From + yym12 := z.DecBinary() + _ = yym12 + if false { + } else { + h.decSliceNetworkPolicyPeer((*[]NetworkPolicyPeer)(yyv11), d) + } + } + for { + yyj8++ + if yyhl8 { + yyb8 = yyj8 > l + } else { + yyb8 = r.CheckBreak() + } + if yyb8 { + break + } + z.DecSendContainerState(codecSelfer_containerArrayElem1234) + z.DecStructFieldNotFound(yyj8-1, "") + } + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) +} + +func (x *NetworkPolicyPort) CodecEncodeSelf(e *codec1978.Encoder) { + var h codecSelfer1234 + z, r := codec1978.GenHelperEncoder(e) + _, _, _ = h, z, r + if x == nil { + r.EncodeNil() + } else { + yym1 := z.EncBinary() + _ = yym1 + if false { + } else if z.HasExtensions() && z.EncExt(x) { + } else { + yysep2 := !z.EncBinary() + yy2arr2 := z.EncBasicHandle().StructToArray + var yyq2 [2]bool + _, _, _ = yysep2, yyq2, yy2arr2 + const yyr2 bool = false + yyq2[0] = x.Protocol != nil + yyq2[1] = x.Port != nil + var yynn2 int + if yyr2 || yy2arr2 { + r.EncodeArrayStart(2) + } else { + yynn2 = 0 + for _, b := range yyq2 { + if b { + yynn2++ + } + } + r.EncodeMapStart(yynn2) + yynn2 = 0 + } + if yyr2 || yy2arr2 { + z.EncSendContainerState(codecSelfer_containerArrayElem1234) + if yyq2[0] { + if x.Protocol == nil { + r.EncodeNil() + } else { + yy4 := *x.Protocol + yysf5 := &yy4 + yysf5.CodecEncodeSelf(e) + } + } else { + r.EncodeNil() + } + } else { + if yyq2[0] { + z.EncSendContainerState(codecSelfer_containerMapKey1234) + r.EncodeString(codecSelferC_UTF81234, string("protocol")) + z.EncSendContainerState(codecSelfer_containerMapValue1234) + if x.Protocol == nil { + r.EncodeNil() + } else { + yy6 := *x.Protocol + yysf7 := &yy6 + yysf7.CodecEncodeSelf(e) + } + } + } + if yyr2 || yy2arr2 { + z.EncSendContainerState(codecSelfer_containerArrayElem1234) + if yyq2[1] { + if x.Port == nil { + r.EncodeNil() + } else { + yym9 := z.EncBinary() + _ = yym9 + if false { + } else if z.HasExtensions() && z.EncExt(x.Port) { + } else if !yym9 && z.IsJSONHandle() { + z.EncJSONMarshal(x.Port) + } else { + z.EncFallback(x.Port) + } + } + } else { + r.EncodeNil() + } + } else { + if yyq2[1] { + z.EncSendContainerState(codecSelfer_containerMapKey1234) + r.EncodeString(codecSelferC_UTF81234, string("port")) + z.EncSendContainerState(codecSelfer_containerMapValue1234) + if x.Port == nil { + r.EncodeNil() + } else { + yym10 := z.EncBinary() + _ = yym10 + if false { + } else if z.HasExtensions() && z.EncExt(x.Port) { + } else if !yym10 && z.IsJSONHandle() { + z.EncJSONMarshal(x.Port) + } else { + z.EncFallback(x.Port) + } + } + } + } + if yyr2 || yy2arr2 { + z.EncSendContainerState(codecSelfer_containerArrayEnd1234) + } else { + z.EncSendContainerState(codecSelfer_containerMapEnd1234) + } + } + } +} + +func (x *NetworkPolicyPort) CodecDecodeSelf(d *codec1978.Decoder) { + var h codecSelfer1234 + z, r := codec1978.GenHelperDecoder(d) + _, _, _ = h, z, r + yym1 := z.DecBinary() + _ = yym1 + if false { + } else if z.HasExtensions() && z.DecExt(x) { + } else { + yyct2 := r.ContainerType() + if yyct2 == codecSelferValueTypeMap1234 { + yyl2 := r.ReadMapStart() + if yyl2 == 0 { + z.DecSendContainerState(codecSelfer_containerMapEnd1234) + } else { + x.codecDecodeSelfFromMap(yyl2, d) + } + } else if yyct2 == codecSelferValueTypeArray1234 { + yyl2 := r.ReadArrayStart() + if yyl2 == 0 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) + } else { + x.codecDecodeSelfFromArray(yyl2, d) + } + } else { + panic(codecSelferOnlyMapOrArrayEncodeToStructErr1234) + } + } +} + +func (x *NetworkPolicyPort) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) { + var h codecSelfer1234 + z, r := codec1978.GenHelperDecoder(d) + _, _, _ = h, z, r + var yys3Slc = z.DecScratchBuffer() // default slice to decode into + _ = yys3Slc + var yyhl3 bool = l >= 0 + for yyj3 := 0; ; yyj3++ { + if yyhl3 { + if yyj3 >= l { + break + } + } else { + if r.CheckBreak() { + break + } + } + z.DecSendContainerState(codecSelfer_containerMapKey1234) + yys3Slc = r.DecodeBytes(yys3Slc, true, true) + yys3 := string(yys3Slc) + z.DecSendContainerState(codecSelfer_containerMapValue1234) + switch yys3 { + case "protocol": + if r.TryDecodeAsNil() { + if x.Protocol != nil { + x.Protocol = nil + } + } else { + if x.Protocol == nil { + x.Protocol = new(pkg2_api.Protocol) + } + x.Protocol.CodecDecodeSelf(d) + } + case "port": + if r.TryDecodeAsNil() { + if x.Port != nil { + x.Port = nil + } + } else { + if x.Port == nil { + x.Port = new(pkg5_intstr.IntOrString) + } + yym6 := z.DecBinary() + _ = yym6 + if false { + } else if z.HasExtensions() && z.DecExt(x.Port) { + } else if !yym6 && z.IsJSONHandle() { + z.DecJSONUnmarshal(x.Port) + } else { + z.DecFallback(x.Port, false) + } + } + default: + z.DecStructFieldNotFound(-1, yys3) + } // end switch yys3 + } // end for yyj3 + z.DecSendContainerState(codecSelfer_containerMapEnd1234) +} + +func (x *NetworkPolicyPort) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { + var h codecSelfer1234 + z, r := codec1978.GenHelperDecoder(d) + _, _, _ = h, z, r + var yyj7 int + var yyb7 bool + var yyhl7 bool = l >= 0 + yyj7++ + if yyhl7 { + yyb7 = yyj7 > l + } else { + yyb7 = r.CheckBreak() + } + if yyb7 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) + return + } + z.DecSendContainerState(codecSelfer_containerArrayElem1234) + if r.TryDecodeAsNil() { + if x.Protocol != nil { + x.Protocol = nil + } + } else { + if x.Protocol == nil { + x.Protocol = new(pkg2_api.Protocol) + } + x.Protocol.CodecDecodeSelf(d) + } + yyj7++ + if yyhl7 { + yyb7 = yyj7 > l + } else { + yyb7 = r.CheckBreak() + } + if yyb7 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) + return + } + z.DecSendContainerState(codecSelfer_containerArrayElem1234) + if r.TryDecodeAsNil() { + if x.Port != nil { + x.Port = nil + } + } else { + if x.Port == nil { + x.Port = new(pkg5_intstr.IntOrString) + } + yym10 := z.DecBinary() + _ = yym10 + if false { + } else if z.HasExtensions() && z.DecExt(x.Port) { + } else if !yym10 && z.IsJSONHandle() { + z.DecJSONUnmarshal(x.Port) + } else { + z.DecFallback(x.Port, false) + } + } + for { + yyj7++ + if yyhl7 { + yyb7 = yyj7 > l + } else { + yyb7 = r.CheckBreak() + } + if yyb7 { + break + } + z.DecSendContainerState(codecSelfer_containerArrayElem1234) + z.DecStructFieldNotFound(yyj7-1, "") + } + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) +} + +func (x *NetworkPolicyPeer) CodecEncodeSelf(e *codec1978.Encoder) { + var h codecSelfer1234 + z, r := codec1978.GenHelperEncoder(e) + _, _, _ = h, z, r + if x == nil { + r.EncodeNil() + } else { + yym1 := z.EncBinary() + _ = yym1 + if false { + } else if z.HasExtensions() && z.EncExt(x) { + } else { + yysep2 := !z.EncBinary() + yy2arr2 := z.EncBasicHandle().StructToArray + var yyq2 [2]bool + _, _, _ = yysep2, yyq2, yy2arr2 + const yyr2 bool = false + yyq2[0] = x.PodSelector != nil + yyq2[1] = x.NamespaceSelector != nil + var yynn2 int + if yyr2 || yy2arr2 { + r.EncodeArrayStart(2) + } else { + yynn2 = 0 + for _, b := range yyq2 { + if b { + yynn2++ + } + } + r.EncodeMapStart(yynn2) + yynn2 = 0 + } + if yyr2 || yy2arr2 { + z.EncSendContainerState(codecSelfer_containerArrayElem1234) + if yyq2[0] { + if x.PodSelector == nil { + r.EncodeNil() + } else { + yym4 := z.EncBinary() + _ = yym4 + if false { + } else if z.HasExtensions() && z.EncExt(x.PodSelector) { + } else { + z.EncFallback(x.PodSelector) + } + } + } else { + r.EncodeNil() + } + } else { + if yyq2[0] { + z.EncSendContainerState(codecSelfer_containerMapKey1234) + r.EncodeString(codecSelferC_UTF81234, string("podSelector")) + z.EncSendContainerState(codecSelfer_containerMapValue1234) + if x.PodSelector == nil { + r.EncodeNil() + } else { + yym5 := z.EncBinary() + _ = yym5 + if false { + } else if z.HasExtensions() && z.EncExt(x.PodSelector) { + } else { + z.EncFallback(x.PodSelector) + } + } + } + } + if yyr2 || yy2arr2 { + z.EncSendContainerState(codecSelfer_containerArrayElem1234) + if yyq2[1] { + if x.NamespaceSelector == nil { + r.EncodeNil() + } else { + yym7 := z.EncBinary() + _ = yym7 + if false { + } else if z.HasExtensions() && z.EncExt(x.NamespaceSelector) { + } else { + z.EncFallback(x.NamespaceSelector) + } + } + } else { + r.EncodeNil() + } + } else { + if yyq2[1] { + z.EncSendContainerState(codecSelfer_containerMapKey1234) + r.EncodeString(codecSelferC_UTF81234, string("namespaceSelector")) + z.EncSendContainerState(codecSelfer_containerMapValue1234) + if x.NamespaceSelector == nil { + r.EncodeNil() + } else { + yym8 := z.EncBinary() + _ = yym8 + if false { + } else if z.HasExtensions() && z.EncExt(x.NamespaceSelector) { + } else { + z.EncFallback(x.NamespaceSelector) + } + } + } + } + if yyr2 || yy2arr2 { + z.EncSendContainerState(codecSelfer_containerArrayEnd1234) + } else { + z.EncSendContainerState(codecSelfer_containerMapEnd1234) + } + } + } +} + +func (x *NetworkPolicyPeer) CodecDecodeSelf(d *codec1978.Decoder) { + var h codecSelfer1234 + z, r := codec1978.GenHelperDecoder(d) + _, _, _ = h, z, r + yym1 := z.DecBinary() + _ = yym1 + if false { + } else if z.HasExtensions() && z.DecExt(x) { + } else { + yyct2 := r.ContainerType() + if yyct2 == codecSelferValueTypeMap1234 { + yyl2 := r.ReadMapStart() + if yyl2 == 0 { + z.DecSendContainerState(codecSelfer_containerMapEnd1234) + } else { + x.codecDecodeSelfFromMap(yyl2, d) + } + } else if yyct2 == codecSelferValueTypeArray1234 { + yyl2 := r.ReadArrayStart() + if yyl2 == 0 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) + } else { + x.codecDecodeSelfFromArray(yyl2, d) + } + } else { + panic(codecSelferOnlyMapOrArrayEncodeToStructErr1234) + } + } +} + +func (x *NetworkPolicyPeer) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) { + var h codecSelfer1234 + z, r := codec1978.GenHelperDecoder(d) + _, _, _ = h, z, r + var yys3Slc = z.DecScratchBuffer() // default slice to decode into + _ = yys3Slc + var yyhl3 bool = l >= 0 + for yyj3 := 0; ; yyj3++ { + if yyhl3 { + if yyj3 >= l { + break + } + } else { + if r.CheckBreak() { + break + } + } + z.DecSendContainerState(codecSelfer_containerMapKey1234) + yys3Slc = r.DecodeBytes(yys3Slc, true, true) + yys3 := string(yys3Slc) + z.DecSendContainerState(codecSelfer_containerMapValue1234) + switch yys3 { + case "podSelector": + if r.TryDecodeAsNil() { + if x.PodSelector != nil { + x.PodSelector = nil + } + } else { + if x.PodSelector == nil { + x.PodSelector = new(pkg1_unversioned.LabelSelector) + } + yym5 := z.DecBinary() + _ = yym5 + if false { + } else if z.HasExtensions() && z.DecExt(x.PodSelector) { + } else { + z.DecFallback(x.PodSelector, false) + } + } + case "namespaceSelector": + if r.TryDecodeAsNil() { + if x.NamespaceSelector != nil { + x.NamespaceSelector = nil + } + } else { + if x.NamespaceSelector == nil { + x.NamespaceSelector = new(pkg1_unversioned.LabelSelector) + } + yym7 := z.DecBinary() + _ = yym7 + if false { + } else if z.HasExtensions() && z.DecExt(x.NamespaceSelector) { + } else { + z.DecFallback(x.NamespaceSelector, false) + } + } + default: + z.DecStructFieldNotFound(-1, yys3) + } // end switch yys3 + } // end for yyj3 + z.DecSendContainerState(codecSelfer_containerMapEnd1234) +} + +func (x *NetworkPolicyPeer) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { + var h codecSelfer1234 + z, r := codec1978.GenHelperDecoder(d) + _, _, _ = h, z, r + var yyj8 int + var yyb8 bool + var yyhl8 bool = l >= 0 + yyj8++ + if yyhl8 { + yyb8 = yyj8 > l + } else { + yyb8 = r.CheckBreak() + } + if yyb8 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) + return + } + z.DecSendContainerState(codecSelfer_containerArrayElem1234) + if r.TryDecodeAsNil() { + if x.PodSelector != nil { + x.PodSelector = nil + } + } else { + if x.PodSelector == nil { + x.PodSelector = new(pkg1_unversioned.LabelSelector) + } + yym10 := z.DecBinary() + _ = yym10 + if false { + } else if z.HasExtensions() && z.DecExt(x.PodSelector) { + } else { + z.DecFallback(x.PodSelector, false) + } + } + yyj8++ + if yyhl8 { + yyb8 = yyj8 > l + } else { + yyb8 = r.CheckBreak() + } + if yyb8 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) + return + } + z.DecSendContainerState(codecSelfer_containerArrayElem1234) + if r.TryDecodeAsNil() { + if x.NamespaceSelector != nil { + x.NamespaceSelector = nil + } + } else { + if x.NamespaceSelector == nil { + x.NamespaceSelector = new(pkg1_unversioned.LabelSelector) + } + yym12 := z.DecBinary() + _ = yym12 + if false { + } else if z.HasExtensions() && z.DecExt(x.NamespaceSelector) { + } else { + z.DecFallback(x.NamespaceSelector, false) + } + } + for { + yyj8++ + if yyhl8 { + yyb8 = yyj8 > l + } else { + yyb8 = r.CheckBreak() + } + if yyb8 { + break + } + z.DecSendContainerState(codecSelfer_containerArrayElem1234) + z.DecStructFieldNotFound(yyj8-1, "") + } + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) +} + +func (x *NetworkPolicyList) CodecEncodeSelf(e *codec1978.Encoder) { + var h codecSelfer1234 + z, r := codec1978.GenHelperEncoder(e) + _, _, _ = h, z, r + if x == nil { + r.EncodeNil() + } else { + yym1 := z.EncBinary() + _ = yym1 + if false { + } else if z.HasExtensions() && z.EncExt(x) { + } else { + yysep2 := !z.EncBinary() + yy2arr2 := z.EncBasicHandle().StructToArray + var yyq2 [4]bool + _, _, _ = yysep2, yyq2, yy2arr2 + const yyr2 bool = false + yyq2[0] = true + yyq2[2] = x.Kind != "" + yyq2[3] = x.APIVersion != "" + var yynn2 int + if yyr2 || yy2arr2 { + r.EncodeArrayStart(4) + } else { + yynn2 = 1 + for _, b := range yyq2 { + if b { + yynn2++ + } + } + r.EncodeMapStart(yynn2) + yynn2 = 0 + } + if yyr2 || yy2arr2 { + z.EncSendContainerState(codecSelfer_containerArrayElem1234) + if yyq2[0] { + yy4 := &x.ListMeta + yym5 := z.EncBinary() + _ = yym5 + if false { + } else if z.HasExtensions() && z.EncExt(yy4) { + } else { + z.EncFallback(yy4) + } + } else { + r.EncodeNil() + } + } else { + if yyq2[0] { + z.EncSendContainerState(codecSelfer_containerMapKey1234) + r.EncodeString(codecSelferC_UTF81234, string("metadata")) + z.EncSendContainerState(codecSelfer_containerMapValue1234) + yy6 := &x.ListMeta + yym7 := z.EncBinary() + _ = yym7 + if false { + } else if z.HasExtensions() && z.EncExt(yy6) { + } else { + z.EncFallback(yy6) + } + } + } + if yyr2 || yy2arr2 { + z.EncSendContainerState(codecSelfer_containerArrayElem1234) + if x.Items == nil { + r.EncodeNil() + } else { + yym9 := z.EncBinary() + _ = yym9 + if false { + } else { + h.encSliceNetworkPolicy(([]NetworkPolicy)(x.Items), e) + } + } + } else { + z.EncSendContainerState(codecSelfer_containerMapKey1234) + r.EncodeString(codecSelferC_UTF81234, string("items")) + z.EncSendContainerState(codecSelfer_containerMapValue1234) + if x.Items == nil { + r.EncodeNil() + } else { + yym10 := z.EncBinary() + _ = yym10 + if false { + } else { + h.encSliceNetworkPolicy(([]NetworkPolicy)(x.Items), e) + } + } + } + if yyr2 || yy2arr2 { + z.EncSendContainerState(codecSelfer_containerArrayElem1234) + if yyq2[2] { + yym12 := z.EncBinary() + _ = yym12 + if false { + } else { + r.EncodeString(codecSelferC_UTF81234, string(x.Kind)) + } + } else { + r.EncodeString(codecSelferC_UTF81234, "") + } + } else { + if yyq2[2] { + z.EncSendContainerState(codecSelfer_containerMapKey1234) + r.EncodeString(codecSelferC_UTF81234, string("kind")) + z.EncSendContainerState(codecSelfer_containerMapValue1234) + yym13 := z.EncBinary() + _ = yym13 + if false { + } else { + r.EncodeString(codecSelferC_UTF81234, string(x.Kind)) + } + } + } + if yyr2 || yy2arr2 { + z.EncSendContainerState(codecSelfer_containerArrayElem1234) + if yyq2[3] { + yym15 := z.EncBinary() + _ = yym15 + if false { + } else { + r.EncodeString(codecSelferC_UTF81234, string(x.APIVersion)) + } + } else { + r.EncodeString(codecSelferC_UTF81234, "") + } + } else { + if yyq2[3] { + z.EncSendContainerState(codecSelfer_containerMapKey1234) + r.EncodeString(codecSelferC_UTF81234, string("apiVersion")) + z.EncSendContainerState(codecSelfer_containerMapValue1234) + yym16 := z.EncBinary() + _ = yym16 + if false { + } else { + r.EncodeString(codecSelferC_UTF81234, string(x.APIVersion)) + } + } + } + if yyr2 || yy2arr2 { + z.EncSendContainerState(codecSelfer_containerArrayEnd1234) + } else { + z.EncSendContainerState(codecSelfer_containerMapEnd1234) + } + } + } +} + +func (x *NetworkPolicyList) CodecDecodeSelf(d *codec1978.Decoder) { + var h codecSelfer1234 + z, r := codec1978.GenHelperDecoder(d) + _, _, _ = h, z, r + yym1 := z.DecBinary() + _ = yym1 + if false { + } else if z.HasExtensions() && z.DecExt(x) { + } else { + yyct2 := r.ContainerType() + if yyct2 == codecSelferValueTypeMap1234 { + yyl2 := r.ReadMapStart() + if yyl2 == 0 { + z.DecSendContainerState(codecSelfer_containerMapEnd1234) + } else { + x.codecDecodeSelfFromMap(yyl2, d) + } + } else if yyct2 == codecSelferValueTypeArray1234 { + yyl2 := r.ReadArrayStart() + if yyl2 == 0 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) + } else { + x.codecDecodeSelfFromArray(yyl2, d) + } + } else { + panic(codecSelferOnlyMapOrArrayEncodeToStructErr1234) + } + } +} + +func (x *NetworkPolicyList) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) { + var h codecSelfer1234 + z, r := codec1978.GenHelperDecoder(d) + _, _, _ = h, z, r + var yys3Slc = z.DecScratchBuffer() // default slice to decode into + _ = yys3Slc + var yyhl3 bool = l >= 0 + for yyj3 := 0; ; yyj3++ { + if yyhl3 { + if yyj3 >= l { + break + } + } else { + if r.CheckBreak() { + break + } + } + z.DecSendContainerState(codecSelfer_containerMapKey1234) + yys3Slc = r.DecodeBytes(yys3Slc, true, true) + yys3 := string(yys3Slc) + z.DecSendContainerState(codecSelfer_containerMapValue1234) + switch yys3 { + case "metadata": + if r.TryDecodeAsNil() { + x.ListMeta = pkg1_unversioned.ListMeta{} + } else { + yyv4 := &x.ListMeta + yym5 := z.DecBinary() + _ = yym5 + if false { + } else if z.HasExtensions() && z.DecExt(yyv4) { + } else { + z.DecFallback(yyv4, false) + } + } + case "items": + if r.TryDecodeAsNil() { + x.Items = nil + } else { + yyv6 := &x.Items + yym7 := z.DecBinary() + _ = yym7 + if false { + } else { + h.decSliceNetworkPolicy((*[]NetworkPolicy)(yyv6), d) + } + } + case "kind": + if r.TryDecodeAsNil() { + x.Kind = "" + } else { + x.Kind = string(r.DecodeString()) + } + case "apiVersion": + if r.TryDecodeAsNil() { + x.APIVersion = "" + } else { + x.APIVersion = string(r.DecodeString()) + } + default: + z.DecStructFieldNotFound(-1, yys3) + } // end switch yys3 + } // end for yyj3 + z.DecSendContainerState(codecSelfer_containerMapEnd1234) +} + +func (x *NetworkPolicyList) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { + var h codecSelfer1234 + z, r := codec1978.GenHelperDecoder(d) + _, _, _ = h, z, r + var yyj10 int + var yyb10 bool + var yyhl10 bool = l >= 0 + yyj10++ + if yyhl10 { + yyb10 = yyj10 > l + } else { + yyb10 = r.CheckBreak() + } + if yyb10 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) + return + } + z.DecSendContainerState(codecSelfer_containerArrayElem1234) + if r.TryDecodeAsNil() { + x.ListMeta = pkg1_unversioned.ListMeta{} + } else { + yyv11 := &x.ListMeta + yym12 := z.DecBinary() + _ = yym12 + if false { + } else if z.HasExtensions() && z.DecExt(yyv11) { + } else { + z.DecFallback(yyv11, false) + } + } + yyj10++ + if yyhl10 { + yyb10 = yyj10 > l + } else { + yyb10 = r.CheckBreak() + } + if yyb10 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) + return + } + z.DecSendContainerState(codecSelfer_containerArrayElem1234) + if r.TryDecodeAsNil() { + x.Items = nil + } else { + yyv13 := &x.Items + yym14 := z.DecBinary() + _ = yym14 + if false { + } else { + h.decSliceNetworkPolicy((*[]NetworkPolicy)(yyv13), d) + } + } + yyj10++ + if yyhl10 { + yyb10 = yyj10 > l + } else { + yyb10 = r.CheckBreak() + } + if yyb10 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) + return + } + z.DecSendContainerState(codecSelfer_containerArrayElem1234) + if r.TryDecodeAsNil() { + x.Kind = "" + } else { + x.Kind = string(r.DecodeString()) + } + yyj10++ + if yyhl10 { + yyb10 = yyj10 > l + } else { + yyb10 = r.CheckBreak() + } + if yyb10 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) + return + } + z.DecSendContainerState(codecSelfer_containerArrayElem1234) + if r.TryDecodeAsNil() { + x.APIVersion = "" + } else { + x.APIVersion = string(r.DecodeString()) + } + for { + yyj10++ + if yyhl10 { + yyb10 = yyj10 > l + } else { + yyb10 = r.CheckBreak() + } + if yyb10 { + break + } + z.DecSendContainerState(codecSelfer_containerArrayElem1234) + z.DecStructFieldNotFound(yyj10-1, "") + } + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) +} + func (x codecSelfer1234) encSliceCustomMetricTarget(v []CustomMetricTarget, e *codec1978.Encoder) { var h codecSelfer1234 z, r := codec1978.GenHelperEncoder(e) @@ -13849,7 +15547,7 @@ func (x codecSelfer1234) decSliceCustomMetricTarget(v *[]CustomMetricTarget, d * yyrg1 := len(yyv1) > 0 yyv21 := yyv1 - yyrl1, yyrt1 = z.DecInferLen(yyl1, z.DecBasicHandle().MaxInitLen, 40) + yyrl1, yyrt1 = z.DecInferLen(yyl1, z.DecBasicHandle().MaxInitLen, 80) if yyrt1 { if yyrl1 <= cap(yyv1) { yyv1 = yyv1[:yyrl1] @@ -13968,7 +15666,7 @@ func (x codecSelfer1234) decSliceCustomMetricCurrentStatus(v *[]CustomMetricCurr yyrg1 := len(yyv1) > 0 yyv21 := yyv1 - yyrl1, yyrt1 = z.DecInferLen(yyl1, z.DecBasicHandle().MaxInitLen, 40) + yyrl1, yyrt1 = z.DecInferLen(yyl1, z.DecBasicHandle().MaxInitLen, 80) if yyrt1 { if yyrl1 <= cap(yyv1) { yyv1 = yyv1[:yyrl1] @@ -14325,7 +16023,7 @@ func (x codecSelfer1234) decSliceDeployment(v *[]Deployment, d *codec1978.Decode yyrg1 := len(yyv1) > 0 yyv21 := yyv1 - yyrl1, yyrt1 = z.DecInferLen(yyl1, z.DecBasicHandle().MaxInitLen, 744) + yyrl1, yyrt1 = z.DecInferLen(yyl1, z.DecBasicHandle().MaxInitLen, 768) if yyrt1 { if yyrl1 <= cap(yyv1) { yyv1 = yyv1[:yyrl1] @@ -14444,7 +16142,7 @@ func (x codecSelfer1234) decSliceDaemonSet(v *[]DaemonSet, d *codec1978.Decoder) yyrg1 := len(yyv1) > 0 yyv21 := yyv1 - yyrl1, yyrt1 = z.DecInferLen(yyl1, z.DecBasicHandle().MaxInitLen, 672) + yyrl1, yyrt1 = z.DecInferLen(yyl1, z.DecBasicHandle().MaxInitLen, 696) if yyrt1 { if yyrl1 <= cap(yyv1) { yyv1 = yyv1[:yyrl1] @@ -15158,7 +16856,7 @@ func (x codecSelfer1234) decSliceReplicaSet(v *[]ReplicaSet, d *codec1978.Decode yyrg1 := len(yyv1) > 0 yyv21 := yyv1 - yyrl1, yyrt1 = z.DecInferLen(yyl1, z.DecBasicHandle().MaxInitLen, 680) + yyrl1, yyrt1 = z.DecInferLen(yyl1, z.DecBasicHandle().MaxInitLen, 704) if yyrt1 { if yyrl1 <= cap(yyv1) { yyv1 = yyv1[:yyrl1] @@ -15815,3 +17513,479 @@ func (x codecSelfer1234) decSlicePodSecurityPolicy(v *[]PodSecurityPolicy, d *co *v = yyv1 } } + +func (x codecSelfer1234) encSliceNetworkPolicyIngressRule(v []NetworkPolicyIngressRule, e *codec1978.Encoder) { + var h codecSelfer1234 + z, r := codec1978.GenHelperEncoder(e) + _, _, _ = h, z, r + r.EncodeArrayStart(len(v)) + for _, yyv1 := range v { + z.EncSendContainerState(codecSelfer_containerArrayElem1234) + yy2 := &yyv1 + yy2.CodecEncodeSelf(e) + } + z.EncSendContainerState(codecSelfer_containerArrayEnd1234) +} + +func (x codecSelfer1234) decSliceNetworkPolicyIngressRule(v *[]NetworkPolicyIngressRule, d *codec1978.Decoder) { + var h codecSelfer1234 + z, r := codec1978.GenHelperDecoder(d) + _, _, _ = h, z, r + + yyv1 := *v + yyh1, yyl1 := z.DecSliceHelperStart() + var yyc1 bool + _ = yyc1 + if yyl1 == 0 { + if yyv1 == nil { + yyv1 = []NetworkPolicyIngressRule{} + yyc1 = true + } else if len(yyv1) != 0 { + yyv1 = yyv1[:0] + yyc1 = true + } + } else if yyl1 > 0 { + var yyrr1, yyrl1 int + var yyrt1 bool + _, _ = yyrl1, yyrt1 + yyrr1 = yyl1 // len(yyv1) + if yyl1 > cap(yyv1) { + + yyrg1 := len(yyv1) > 0 + yyv21 := yyv1 + yyrl1, yyrt1 = z.DecInferLen(yyl1, z.DecBasicHandle().MaxInitLen, 48) + if yyrt1 { + if yyrl1 <= cap(yyv1) { + yyv1 = yyv1[:yyrl1] + } else { + yyv1 = make([]NetworkPolicyIngressRule, yyrl1) + } + } else { + yyv1 = make([]NetworkPolicyIngressRule, yyrl1) + } + yyc1 = true + yyrr1 = len(yyv1) + if yyrg1 { + copy(yyv1, yyv21) + } + } else if yyl1 != len(yyv1) { + yyv1 = yyv1[:yyl1] + yyc1 = true + } + yyj1 := 0 + for ; yyj1 < yyrr1; yyj1++ { + yyh1.ElemContainerState(yyj1) + if r.TryDecodeAsNil() { + yyv1[yyj1] = NetworkPolicyIngressRule{} + } else { + yyv2 := &yyv1[yyj1] + yyv2.CodecDecodeSelf(d) + } + + } + if yyrt1 { + for ; yyj1 < yyl1; yyj1++ { + yyv1 = append(yyv1, NetworkPolicyIngressRule{}) + yyh1.ElemContainerState(yyj1) + if r.TryDecodeAsNil() { + yyv1[yyj1] = NetworkPolicyIngressRule{} + } else { + yyv3 := &yyv1[yyj1] + yyv3.CodecDecodeSelf(d) + } + + } + } + + } else { + yyj1 := 0 + for ; !r.CheckBreak(); yyj1++ { + + if yyj1 >= len(yyv1) { + yyv1 = append(yyv1, NetworkPolicyIngressRule{}) // var yyz1 NetworkPolicyIngressRule + yyc1 = true + } + yyh1.ElemContainerState(yyj1) + if yyj1 < len(yyv1) { + if r.TryDecodeAsNil() { + yyv1[yyj1] = NetworkPolicyIngressRule{} + } else { + yyv4 := &yyv1[yyj1] + yyv4.CodecDecodeSelf(d) + } + + } else { + z.DecSwallow() + } + + } + if yyj1 < len(yyv1) { + yyv1 = yyv1[:yyj1] + yyc1 = true + } else if yyj1 == 0 && yyv1 == nil { + yyv1 = []NetworkPolicyIngressRule{} + yyc1 = true + } + } + yyh1.End() + if yyc1 { + *v = yyv1 + } +} + +func (x codecSelfer1234) encSliceNetworkPolicyPort(v []NetworkPolicyPort, e *codec1978.Encoder) { + var h codecSelfer1234 + z, r := codec1978.GenHelperEncoder(e) + _, _, _ = h, z, r + r.EncodeArrayStart(len(v)) + for _, yyv1 := range v { + z.EncSendContainerState(codecSelfer_containerArrayElem1234) + yy2 := &yyv1 + yy2.CodecEncodeSelf(e) + } + z.EncSendContainerState(codecSelfer_containerArrayEnd1234) +} + +func (x codecSelfer1234) decSliceNetworkPolicyPort(v *[]NetworkPolicyPort, d *codec1978.Decoder) { + var h codecSelfer1234 + z, r := codec1978.GenHelperDecoder(d) + _, _, _ = h, z, r + + yyv1 := *v + yyh1, yyl1 := z.DecSliceHelperStart() + var yyc1 bool + _ = yyc1 + if yyl1 == 0 { + if yyv1 == nil { + yyv1 = []NetworkPolicyPort{} + yyc1 = true + } else if len(yyv1) != 0 { + yyv1 = yyv1[:0] + yyc1 = true + } + } else if yyl1 > 0 { + var yyrr1, yyrl1 int + var yyrt1 bool + _, _ = yyrl1, yyrt1 + yyrr1 = yyl1 // len(yyv1) + if yyl1 > cap(yyv1) { + + yyrg1 := len(yyv1) > 0 + yyv21 := yyv1 + yyrl1, yyrt1 = z.DecInferLen(yyl1, z.DecBasicHandle().MaxInitLen, 16) + if yyrt1 { + if yyrl1 <= cap(yyv1) { + yyv1 = yyv1[:yyrl1] + } else { + yyv1 = make([]NetworkPolicyPort, yyrl1) + } + } else { + yyv1 = make([]NetworkPolicyPort, yyrl1) + } + yyc1 = true + yyrr1 = len(yyv1) + if yyrg1 { + copy(yyv1, yyv21) + } + } else if yyl1 != len(yyv1) { + yyv1 = yyv1[:yyl1] + yyc1 = true + } + yyj1 := 0 + for ; yyj1 < yyrr1; yyj1++ { + yyh1.ElemContainerState(yyj1) + if r.TryDecodeAsNil() { + yyv1[yyj1] = NetworkPolicyPort{} + } else { + yyv2 := &yyv1[yyj1] + yyv2.CodecDecodeSelf(d) + } + + } + if yyrt1 { + for ; yyj1 < yyl1; yyj1++ { + yyv1 = append(yyv1, NetworkPolicyPort{}) + yyh1.ElemContainerState(yyj1) + if r.TryDecodeAsNil() { + yyv1[yyj1] = NetworkPolicyPort{} + } else { + yyv3 := &yyv1[yyj1] + yyv3.CodecDecodeSelf(d) + } + + } + } + + } else { + yyj1 := 0 + for ; !r.CheckBreak(); yyj1++ { + + if yyj1 >= len(yyv1) { + yyv1 = append(yyv1, NetworkPolicyPort{}) // var yyz1 NetworkPolicyPort + yyc1 = true + } + yyh1.ElemContainerState(yyj1) + if yyj1 < len(yyv1) { + if r.TryDecodeAsNil() { + yyv1[yyj1] = NetworkPolicyPort{} + } else { + yyv4 := &yyv1[yyj1] + yyv4.CodecDecodeSelf(d) + } + + } else { + z.DecSwallow() + } + + } + if yyj1 < len(yyv1) { + yyv1 = yyv1[:yyj1] + yyc1 = true + } else if yyj1 == 0 && yyv1 == nil { + yyv1 = []NetworkPolicyPort{} + yyc1 = true + } + } + yyh1.End() + if yyc1 { + *v = yyv1 + } +} + +func (x codecSelfer1234) encSliceNetworkPolicyPeer(v []NetworkPolicyPeer, e *codec1978.Encoder) { + var h codecSelfer1234 + z, r := codec1978.GenHelperEncoder(e) + _, _, _ = h, z, r + r.EncodeArrayStart(len(v)) + for _, yyv1 := range v { + z.EncSendContainerState(codecSelfer_containerArrayElem1234) + yy2 := &yyv1 + yy2.CodecEncodeSelf(e) + } + z.EncSendContainerState(codecSelfer_containerArrayEnd1234) +} + +func (x codecSelfer1234) decSliceNetworkPolicyPeer(v *[]NetworkPolicyPeer, d *codec1978.Decoder) { + var h codecSelfer1234 + z, r := codec1978.GenHelperDecoder(d) + _, _, _ = h, z, r + + yyv1 := *v + yyh1, yyl1 := z.DecSliceHelperStart() + var yyc1 bool + _ = yyc1 + if yyl1 == 0 { + if yyv1 == nil { + yyv1 = []NetworkPolicyPeer{} + yyc1 = true + } else if len(yyv1) != 0 { + yyv1 = yyv1[:0] + yyc1 = true + } + } else if yyl1 > 0 { + var yyrr1, yyrl1 int + var yyrt1 bool + _, _ = yyrl1, yyrt1 + yyrr1 = yyl1 // len(yyv1) + if yyl1 > cap(yyv1) { + + yyrg1 := len(yyv1) > 0 + yyv21 := yyv1 + yyrl1, yyrt1 = z.DecInferLen(yyl1, z.DecBasicHandle().MaxInitLen, 16) + if yyrt1 { + if yyrl1 <= cap(yyv1) { + yyv1 = yyv1[:yyrl1] + } else { + yyv1 = make([]NetworkPolicyPeer, yyrl1) + } + } else { + yyv1 = make([]NetworkPolicyPeer, yyrl1) + } + yyc1 = true + yyrr1 = len(yyv1) + if yyrg1 { + copy(yyv1, yyv21) + } + } else if yyl1 != len(yyv1) { + yyv1 = yyv1[:yyl1] + yyc1 = true + } + yyj1 := 0 + for ; yyj1 < yyrr1; yyj1++ { + yyh1.ElemContainerState(yyj1) + if r.TryDecodeAsNil() { + yyv1[yyj1] = NetworkPolicyPeer{} + } else { + yyv2 := &yyv1[yyj1] + yyv2.CodecDecodeSelf(d) + } + + } + if yyrt1 { + for ; yyj1 < yyl1; yyj1++ { + yyv1 = append(yyv1, NetworkPolicyPeer{}) + yyh1.ElemContainerState(yyj1) + if r.TryDecodeAsNil() { + yyv1[yyj1] = NetworkPolicyPeer{} + } else { + yyv3 := &yyv1[yyj1] + yyv3.CodecDecodeSelf(d) + } + + } + } + + } else { + yyj1 := 0 + for ; !r.CheckBreak(); yyj1++ { + + if yyj1 >= len(yyv1) { + yyv1 = append(yyv1, NetworkPolicyPeer{}) // var yyz1 NetworkPolicyPeer + yyc1 = true + } + yyh1.ElemContainerState(yyj1) + if yyj1 < len(yyv1) { + if r.TryDecodeAsNil() { + yyv1[yyj1] = NetworkPolicyPeer{} + } else { + yyv4 := &yyv1[yyj1] + yyv4.CodecDecodeSelf(d) + } + + } else { + z.DecSwallow() + } + + } + if yyj1 < len(yyv1) { + yyv1 = yyv1[:yyj1] + yyc1 = true + } else if yyj1 == 0 && yyv1 == nil { + yyv1 = []NetworkPolicyPeer{} + yyc1 = true + } + } + yyh1.End() + if yyc1 { + *v = yyv1 + } +} + +func (x codecSelfer1234) encSliceNetworkPolicy(v []NetworkPolicy, e *codec1978.Encoder) { + var h codecSelfer1234 + z, r := codec1978.GenHelperEncoder(e) + _, _, _ = h, z, r + r.EncodeArrayStart(len(v)) + for _, yyv1 := range v { + z.EncSendContainerState(codecSelfer_containerArrayElem1234) + yy2 := &yyv1 + yy2.CodecEncodeSelf(e) + } + z.EncSendContainerState(codecSelfer_containerArrayEnd1234) +} + +func (x codecSelfer1234) decSliceNetworkPolicy(v *[]NetworkPolicy, d *codec1978.Decoder) { + var h codecSelfer1234 + z, r := codec1978.GenHelperDecoder(d) + _, _, _ = h, z, r + + yyv1 := *v + yyh1, yyl1 := z.DecSliceHelperStart() + var yyc1 bool + _ = yyc1 + if yyl1 == 0 { + if yyv1 == nil { + yyv1 = []NetworkPolicy{} + yyc1 = true + } else if len(yyv1) != 0 { + yyv1 = yyv1[:0] + yyc1 = true + } + } else if yyl1 > 0 { + var yyrr1, yyrl1 int + var yyrt1 bool + _, _ = yyrl1, yyrt1 + yyrr1 = yyl1 // len(yyv1) + if yyl1 > cap(yyv1) { + + yyrg1 := len(yyv1) > 0 + yyv21 := yyv1 + yyrl1, yyrt1 = z.DecInferLen(yyl1, z.DecBasicHandle().MaxInitLen, 296) + if yyrt1 { + if yyrl1 <= cap(yyv1) { + yyv1 = yyv1[:yyrl1] + } else { + yyv1 = make([]NetworkPolicy, yyrl1) + } + } else { + yyv1 = make([]NetworkPolicy, yyrl1) + } + yyc1 = true + yyrr1 = len(yyv1) + if yyrg1 { + copy(yyv1, yyv21) + } + } else if yyl1 != len(yyv1) { + yyv1 = yyv1[:yyl1] + yyc1 = true + } + yyj1 := 0 + for ; yyj1 < yyrr1; yyj1++ { + yyh1.ElemContainerState(yyj1) + if r.TryDecodeAsNil() { + yyv1[yyj1] = NetworkPolicy{} + } else { + yyv2 := &yyv1[yyj1] + yyv2.CodecDecodeSelf(d) + } + + } + if yyrt1 { + for ; yyj1 < yyl1; yyj1++ { + yyv1 = append(yyv1, NetworkPolicy{}) + yyh1.ElemContainerState(yyj1) + if r.TryDecodeAsNil() { + yyv1[yyj1] = NetworkPolicy{} + } else { + yyv3 := &yyv1[yyj1] + yyv3.CodecDecodeSelf(d) + } + + } + } + + } else { + yyj1 := 0 + for ; !r.CheckBreak(); yyj1++ { + + if yyj1 >= len(yyv1) { + yyv1 = append(yyv1, NetworkPolicy{}) // var yyz1 NetworkPolicy + yyc1 = true + } + yyh1.ElemContainerState(yyj1) + if yyj1 < len(yyv1) { + if r.TryDecodeAsNil() { + yyv1[yyj1] = NetworkPolicy{} + } else { + yyv4 := &yyv1[yyj1] + yyv4.CodecDecodeSelf(d) + } + + } else { + z.DecSwallow() + } + + } + if yyj1 < len(yyv1) { + yyv1 = yyv1[:yyj1] + yyc1 = true + } else if yyj1 == 0 && yyv1 == nil { + yyv1 = []NetworkPolicy{} + yyc1 = true + } + } + yyh1.End() + if yyc1 { + *v = yyv1 + } +} diff --git a/vendor/k8s.io/kubernetes/pkg/apis/extensions/types.go b/vendor/k8s.io/kubernetes/pkg/apis/extensions/types.go index 7a307d2c7e..8b1b6ef317 100644 --- a/vendor/k8s.io/kubernetes/pkg/apis/extensions/types.go +++ b/vendor/k8s.io/kubernetes/pkg/apis/extensions/types.go @@ -710,6 +710,7 @@ var ( DownwardAPI FSType = "downwardAPI" FC FSType = "fc" ConfigMap FSType = "configMap" + VsphereVolume FSType = "vsphereVolume" All FSType = "*" ) @@ -809,3 +810,89 @@ type PodSecurityPolicyList struct { Items []PodSecurityPolicy `json:"items"` } + +type NetworkPolicy struct { + unversioned.TypeMeta `json:",inline"` + api.ObjectMeta `json:"metadata,omitempty"` + + // Specification of the desired behavior for this NetworkPolicy. + Spec NetworkPolicySpec `json:"spec,omitempty"` +} + +type NetworkPolicySpec struct { + // Selects the pods to which this NetworkPolicy object applies. The array of ingress rules + // is applied to any pods selected by this field. Multiple network policies can select the + // same set of pods. In this case, the ingress rules for each are combined additively. + // This field is NOT optional and follows standard label selector semantics. + // An empty podSelector matches all pods in this namespace. + PodSelector unversioned.LabelSelector `json:"podSelector"` + + // List of ingress rules to be applied to the selected pods. + // Traffic is allowed to a pod if namespace.networkPolicy.ingress.isolation is undefined and cluster policy allows it, + // OR if the traffic source is the pod's local node, + // OR if the traffic matches at least one ingress rule across all of the NetworkPolicy + // objects whose podSelector matches the pod. + // If this field is empty then this NetworkPolicy does not affect ingress isolation. + // If this field is present and contains at least one rule, this policy allows any traffic + // which matches at least one of the ingress rules in this list. + Ingress []NetworkPolicyIngressRule `json:"ingress,omitempty"` +} + +// This NetworkPolicyIngressRule matches traffic if and only if the traffic matches both ports AND from. +type NetworkPolicyIngressRule struct { + // List of ports which should be made accessible on the pods selected for this rule. + // Each item in this list is combined using a logical OR. + // If this field is not provided, this rule matches all ports (traffic not restricted by port). + // If this field is empty, this rule matches no ports (no traffic matches). + // If this field is present and contains at least one item, then this rule allows traffic + // only if the traffic matches at least one port in the list. + // TODO: Update this to be a pointer to slice as soon as auto-generation supports it. + Ports []NetworkPolicyPort `json:"ports,omitempty"` + + // List of sources which should be able to access the pods selected for this rule. + // Items in this list are combined using a logical OR operation. + // If this field is not provided, this rule matches all sources (traffic not restricted by source). + // If this field is empty, this rule matches no sources (no traffic matches). + // If this field is present and contains at least on item, this rule allows traffic only if the + // traffic matches at least one item in the from list. + // TODO: Update this to be a pointer to slice as soon as auto-generation supports it. + From []NetworkPolicyPeer `json:"from,omitempty"` +} + +type NetworkPolicyPort struct { + // Optional. The protocol (TCP or UDP) which traffic must match. + // If not specified, this field defaults to TCP. + Protocol *api.Protocol `json:"protocol,omitempty"` + + // If specified, the port on the given protocol. This can + // either be a numerical or named port on a pod. If this field is not provided, + // this matches all port names and numbers. + // If present, only traffic on the specified protocol AND port + // will be matched. + Port *intstr.IntOrString `json:"port,omitempty"` +} + +type NetworkPolicyPeer struct { + // Exactly one of the following must be specified. + + // This is a label selector which selects Pods in this namespace. + // This field follows standard label selector semantics. + // If not provided, this selector selects no pods. + // If present but empty, this selector selects all pods in this namespace. + PodSelector *unversioned.LabelSelector `json:"podSelector,omitempty"` + + // Selects Namespaces using cluster scoped-labels. This + // matches all pods in all namespaces selected by this label selector. + // This field follows standard label selector semantics. + // If omited, this selector selects no namespaces. + // If present but empty, this selector selects all namespaces. + NamespaceSelector *unversioned.LabelSelector `json:"namespaceSelector,omitempty"` +} + +// NetworkPolicyList is a list of NetworkPolicy objects. +type NetworkPolicyList struct { + unversioned.TypeMeta `json:",inline"` + unversioned.ListMeta `json:"metadata,omitempty"` + + Items []NetworkPolicy `json:"items"` +} diff --git a/vendor/k8s.io/kubernetes/pkg/apis/extensions/v1beta1/conversion_generated.go b/vendor/k8s.io/kubernetes/pkg/apis/extensions/v1beta1/conversion_generated.go index 4b8506a9d5..3a1776e8fb 100644 --- a/vendor/k8s.io/kubernetes/pkg/apis/extensions/v1beta1/conversion_generated.go +++ b/vendor/k8s.io/kubernetes/pkg/apis/extensions/v1beta1/conversion_generated.go @@ -28,6 +28,7 @@ import ( batch "k8s.io/kubernetes/pkg/apis/batch" extensions "k8s.io/kubernetes/pkg/apis/extensions" conversion "k8s.io/kubernetes/pkg/conversion" + intstr "k8s.io/kubernetes/pkg/util/intstr" ) func init() { @@ -110,6 +111,18 @@ func init() { Convert_unversioned_LabelSelector_To_v1beta1_LabelSelector, Convert_v1beta1_LabelSelectorRequirement_To_unversioned_LabelSelectorRequirement, Convert_unversioned_LabelSelectorRequirement_To_v1beta1_LabelSelectorRequirement, + Convert_v1beta1_NetworkPolicy_To_extensions_NetworkPolicy, + Convert_extensions_NetworkPolicy_To_v1beta1_NetworkPolicy, + Convert_v1beta1_NetworkPolicyIngressRule_To_extensions_NetworkPolicyIngressRule, + Convert_extensions_NetworkPolicyIngressRule_To_v1beta1_NetworkPolicyIngressRule, + Convert_v1beta1_NetworkPolicyList_To_extensions_NetworkPolicyList, + Convert_extensions_NetworkPolicyList_To_v1beta1_NetworkPolicyList, + Convert_v1beta1_NetworkPolicyPeer_To_extensions_NetworkPolicyPeer, + Convert_extensions_NetworkPolicyPeer_To_v1beta1_NetworkPolicyPeer, + Convert_v1beta1_NetworkPolicyPort_To_extensions_NetworkPolicyPort, + Convert_extensions_NetworkPolicyPort_To_v1beta1_NetworkPolicyPort, + Convert_v1beta1_NetworkPolicySpec_To_extensions_NetworkPolicySpec, + Convert_extensions_NetworkPolicySpec_To_v1beta1_NetworkPolicySpec, Convert_v1beta1_PodSecurityPolicy_To_extensions_PodSecurityPolicy, Convert_extensions_PodSecurityPolicy_To_v1beta1_PodSecurityPolicy, Convert_v1beta1_PodSecurityPolicyList_To_extensions_PodSecurityPolicyList, @@ -401,8 +414,7 @@ func autoConvert_v1beta1_DaemonSetSpec_To_extensions_DaemonSetSpec(in *DaemonSet } else { out.Selector = nil } - // TODO: Inefficient conversion - can we improve it? - if err := s.Convert(&in.Template, &out.Template, 0); err != nil { + if err := v1.Convert_v1_PodTemplateSpec_To_api_PodTemplateSpec(&in.Template, &out.Template, s); err != nil { return err } return nil @@ -422,8 +434,7 @@ func autoConvert_extensions_DaemonSetSpec_To_v1beta1_DaemonSetSpec(in *extension } else { out.Selector = nil } - // TODO: Inefficient conversion - can we improve it? - if err := s.Convert(&in.Template, &out.Template, 0); err != nil { + if err := v1.Convert_api_PodTemplateSpec_To_v1_PodTemplateSpec(&in.Template, &out.Template, s); err != nil { return err } return nil @@ -1558,6 +1569,297 @@ func Convert_unversioned_LabelSelectorRequirement_To_v1beta1_LabelSelectorRequir return autoConvert_unversioned_LabelSelectorRequirement_To_v1beta1_LabelSelectorRequirement(in, out, s) } +func autoConvert_v1beta1_NetworkPolicy_To_extensions_NetworkPolicy(in *NetworkPolicy, out *extensions.NetworkPolicy, s conversion.Scope) error { + SetDefaults_NetworkPolicy(in) + if err := api.Convert_unversioned_TypeMeta_To_unversioned_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + return err + } + // TODO: Inefficient conversion - can we improve it? + if err := s.Convert(&in.ObjectMeta, &out.ObjectMeta, 0); err != nil { + return err + } + if err := Convert_v1beta1_NetworkPolicySpec_To_extensions_NetworkPolicySpec(&in.Spec, &out.Spec, s); err != nil { + return err + } + return nil +} + +func Convert_v1beta1_NetworkPolicy_To_extensions_NetworkPolicy(in *NetworkPolicy, out *extensions.NetworkPolicy, s conversion.Scope) error { + return autoConvert_v1beta1_NetworkPolicy_To_extensions_NetworkPolicy(in, out, s) +} + +func autoConvert_extensions_NetworkPolicy_To_v1beta1_NetworkPolicy(in *extensions.NetworkPolicy, out *NetworkPolicy, s conversion.Scope) error { + if err := api.Convert_unversioned_TypeMeta_To_unversioned_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + return err + } + // TODO: Inefficient conversion - can we improve it? + if err := s.Convert(&in.ObjectMeta, &out.ObjectMeta, 0); err != nil { + return err + } + if err := Convert_extensions_NetworkPolicySpec_To_v1beta1_NetworkPolicySpec(&in.Spec, &out.Spec, s); err != nil { + return err + } + return nil +} + +func Convert_extensions_NetworkPolicy_To_v1beta1_NetworkPolicy(in *extensions.NetworkPolicy, out *NetworkPolicy, s conversion.Scope) error { + return autoConvert_extensions_NetworkPolicy_To_v1beta1_NetworkPolicy(in, out, s) +} + +func autoConvert_v1beta1_NetworkPolicyIngressRule_To_extensions_NetworkPolicyIngressRule(in *NetworkPolicyIngressRule, out *extensions.NetworkPolicyIngressRule, s conversion.Scope) error { + if in.Ports != nil { + in, out := &in.Ports, &out.Ports + *out = make([]extensions.NetworkPolicyPort, len(*in)) + for i := range *in { + if err := Convert_v1beta1_NetworkPolicyPort_To_extensions_NetworkPolicyPort(&(*in)[i], &(*out)[i], s); err != nil { + return err + } + } + } else { + out.Ports = nil + } + if in.From != nil { + in, out := &in.From, &out.From + *out = make([]extensions.NetworkPolicyPeer, len(*in)) + for i := range *in { + if err := Convert_v1beta1_NetworkPolicyPeer_To_extensions_NetworkPolicyPeer(&(*in)[i], &(*out)[i], s); err != nil { + return err + } + } + } else { + out.From = nil + } + return nil +} + +func Convert_v1beta1_NetworkPolicyIngressRule_To_extensions_NetworkPolicyIngressRule(in *NetworkPolicyIngressRule, out *extensions.NetworkPolicyIngressRule, s conversion.Scope) error { + return autoConvert_v1beta1_NetworkPolicyIngressRule_To_extensions_NetworkPolicyIngressRule(in, out, s) +} + +func autoConvert_extensions_NetworkPolicyIngressRule_To_v1beta1_NetworkPolicyIngressRule(in *extensions.NetworkPolicyIngressRule, out *NetworkPolicyIngressRule, s conversion.Scope) error { + if in.Ports != nil { + in, out := &in.Ports, &out.Ports + *out = make([]NetworkPolicyPort, len(*in)) + for i := range *in { + if err := Convert_extensions_NetworkPolicyPort_To_v1beta1_NetworkPolicyPort(&(*in)[i], &(*out)[i], s); err != nil { + return err + } + } + } else { + out.Ports = nil + } + if in.From != nil { + in, out := &in.From, &out.From + *out = make([]NetworkPolicyPeer, len(*in)) + for i := range *in { + if err := Convert_extensions_NetworkPolicyPeer_To_v1beta1_NetworkPolicyPeer(&(*in)[i], &(*out)[i], s); err != nil { + return err + } + } + } else { + out.From = nil + } + return nil +} + +func Convert_extensions_NetworkPolicyIngressRule_To_v1beta1_NetworkPolicyIngressRule(in *extensions.NetworkPolicyIngressRule, out *NetworkPolicyIngressRule, s conversion.Scope) error { + return autoConvert_extensions_NetworkPolicyIngressRule_To_v1beta1_NetworkPolicyIngressRule(in, out, s) +} + +func autoConvert_v1beta1_NetworkPolicyList_To_extensions_NetworkPolicyList(in *NetworkPolicyList, out *extensions.NetworkPolicyList, s conversion.Scope) error { + if err := api.Convert_unversioned_TypeMeta_To_unversioned_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + return err + } + if err := api.Convert_unversioned_ListMeta_To_unversioned_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + return err + } + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]extensions.NetworkPolicy, len(*in)) + for i := range *in { + if err := Convert_v1beta1_NetworkPolicy_To_extensions_NetworkPolicy(&(*in)[i], &(*out)[i], s); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +func Convert_v1beta1_NetworkPolicyList_To_extensions_NetworkPolicyList(in *NetworkPolicyList, out *extensions.NetworkPolicyList, s conversion.Scope) error { + return autoConvert_v1beta1_NetworkPolicyList_To_extensions_NetworkPolicyList(in, out, s) +} + +func autoConvert_extensions_NetworkPolicyList_To_v1beta1_NetworkPolicyList(in *extensions.NetworkPolicyList, out *NetworkPolicyList, s conversion.Scope) error { + if err := api.Convert_unversioned_TypeMeta_To_unversioned_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + return err + } + if err := api.Convert_unversioned_ListMeta_To_unversioned_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + return err + } + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]NetworkPolicy, len(*in)) + for i := range *in { + if err := Convert_extensions_NetworkPolicy_To_v1beta1_NetworkPolicy(&(*in)[i], &(*out)[i], s); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +func Convert_extensions_NetworkPolicyList_To_v1beta1_NetworkPolicyList(in *extensions.NetworkPolicyList, out *NetworkPolicyList, s conversion.Scope) error { + return autoConvert_extensions_NetworkPolicyList_To_v1beta1_NetworkPolicyList(in, out, s) +} + +func autoConvert_v1beta1_NetworkPolicyPeer_To_extensions_NetworkPolicyPeer(in *NetworkPolicyPeer, out *extensions.NetworkPolicyPeer, s conversion.Scope) error { + if in.PodSelector != nil { + in, out := &in.PodSelector, &out.PodSelector + *out = new(unversioned.LabelSelector) + if err := Convert_v1beta1_LabelSelector_To_unversioned_LabelSelector(*in, *out, s); err != nil { + return err + } + } else { + out.PodSelector = nil + } + if in.NamespaceSelector != nil { + in, out := &in.NamespaceSelector, &out.NamespaceSelector + *out = new(unversioned.LabelSelector) + if err := Convert_v1beta1_LabelSelector_To_unversioned_LabelSelector(*in, *out, s); err != nil { + return err + } + } else { + out.NamespaceSelector = nil + } + return nil +} + +func Convert_v1beta1_NetworkPolicyPeer_To_extensions_NetworkPolicyPeer(in *NetworkPolicyPeer, out *extensions.NetworkPolicyPeer, s conversion.Scope) error { + return autoConvert_v1beta1_NetworkPolicyPeer_To_extensions_NetworkPolicyPeer(in, out, s) +} + +func autoConvert_extensions_NetworkPolicyPeer_To_v1beta1_NetworkPolicyPeer(in *extensions.NetworkPolicyPeer, out *NetworkPolicyPeer, s conversion.Scope) error { + if in.PodSelector != nil { + in, out := &in.PodSelector, &out.PodSelector + *out = new(LabelSelector) + if err := Convert_unversioned_LabelSelector_To_v1beta1_LabelSelector(*in, *out, s); err != nil { + return err + } + } else { + out.PodSelector = nil + } + if in.NamespaceSelector != nil { + in, out := &in.NamespaceSelector, &out.NamespaceSelector + *out = new(LabelSelector) + if err := Convert_unversioned_LabelSelector_To_v1beta1_LabelSelector(*in, *out, s); err != nil { + return err + } + } else { + out.NamespaceSelector = nil + } + return nil +} + +func Convert_extensions_NetworkPolicyPeer_To_v1beta1_NetworkPolicyPeer(in *extensions.NetworkPolicyPeer, out *NetworkPolicyPeer, s conversion.Scope) error { + return autoConvert_extensions_NetworkPolicyPeer_To_v1beta1_NetworkPolicyPeer(in, out, s) +} + +func autoConvert_v1beta1_NetworkPolicyPort_To_extensions_NetworkPolicyPort(in *NetworkPolicyPort, out *extensions.NetworkPolicyPort, s conversion.Scope) error { + if in.Protocol != nil { + in, out := &in.Protocol, &out.Protocol + *out = new(api.Protocol) + **out = api.Protocol(**in) + } else { + out.Protocol = nil + } + if in.Port != nil { + in, out := &in.Port, &out.Port + *out = new(intstr.IntOrString) + if err := api.Convert_intstr_IntOrString_To_intstr_IntOrString(*in, *out, s); err != nil { + return err + } + } else { + out.Port = nil + } + return nil +} + +func Convert_v1beta1_NetworkPolicyPort_To_extensions_NetworkPolicyPort(in *NetworkPolicyPort, out *extensions.NetworkPolicyPort, s conversion.Scope) error { + return autoConvert_v1beta1_NetworkPolicyPort_To_extensions_NetworkPolicyPort(in, out, s) +} + +func autoConvert_extensions_NetworkPolicyPort_To_v1beta1_NetworkPolicyPort(in *extensions.NetworkPolicyPort, out *NetworkPolicyPort, s conversion.Scope) error { + if in.Protocol != nil { + in, out := &in.Protocol, &out.Protocol + *out = new(v1.Protocol) + **out = v1.Protocol(**in) + } else { + out.Protocol = nil + } + if in.Port != nil { + in, out := &in.Port, &out.Port + *out = new(intstr.IntOrString) + if err := api.Convert_intstr_IntOrString_To_intstr_IntOrString(*in, *out, s); err != nil { + return err + } + } else { + out.Port = nil + } + return nil +} + +func Convert_extensions_NetworkPolicyPort_To_v1beta1_NetworkPolicyPort(in *extensions.NetworkPolicyPort, out *NetworkPolicyPort, s conversion.Scope) error { + return autoConvert_extensions_NetworkPolicyPort_To_v1beta1_NetworkPolicyPort(in, out, s) +} + +func autoConvert_v1beta1_NetworkPolicySpec_To_extensions_NetworkPolicySpec(in *NetworkPolicySpec, out *extensions.NetworkPolicySpec, s conversion.Scope) error { + if err := Convert_v1beta1_LabelSelector_To_unversioned_LabelSelector(&in.PodSelector, &out.PodSelector, s); err != nil { + return err + } + if in.Ingress != nil { + in, out := &in.Ingress, &out.Ingress + *out = make([]extensions.NetworkPolicyIngressRule, len(*in)) + for i := range *in { + if err := Convert_v1beta1_NetworkPolicyIngressRule_To_extensions_NetworkPolicyIngressRule(&(*in)[i], &(*out)[i], s); err != nil { + return err + } + } + } else { + out.Ingress = nil + } + return nil +} + +func Convert_v1beta1_NetworkPolicySpec_To_extensions_NetworkPolicySpec(in *NetworkPolicySpec, out *extensions.NetworkPolicySpec, s conversion.Scope) error { + return autoConvert_v1beta1_NetworkPolicySpec_To_extensions_NetworkPolicySpec(in, out, s) +} + +func autoConvert_extensions_NetworkPolicySpec_To_v1beta1_NetworkPolicySpec(in *extensions.NetworkPolicySpec, out *NetworkPolicySpec, s conversion.Scope) error { + if err := Convert_unversioned_LabelSelector_To_v1beta1_LabelSelector(&in.PodSelector, &out.PodSelector, s); err != nil { + return err + } + if in.Ingress != nil { + in, out := &in.Ingress, &out.Ingress + *out = make([]NetworkPolicyIngressRule, len(*in)) + for i := range *in { + if err := Convert_extensions_NetworkPolicyIngressRule_To_v1beta1_NetworkPolicyIngressRule(&(*in)[i], &(*out)[i], s); err != nil { + return err + } + } + } else { + out.Ingress = nil + } + return nil +} + +func Convert_extensions_NetworkPolicySpec_To_v1beta1_NetworkPolicySpec(in *extensions.NetworkPolicySpec, out *NetworkPolicySpec, s conversion.Scope) error { + return autoConvert_extensions_NetworkPolicySpec_To_v1beta1_NetworkPolicySpec(in, out, s) +} + func autoConvert_v1beta1_PodSecurityPolicy_To_extensions_PodSecurityPolicy(in *PodSecurityPolicy, out *extensions.PodSecurityPolicy, s conversion.Scope) error { if err := api.Convert_unversioned_TypeMeta_To_unversioned_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { return err diff --git a/vendor/k8s.io/kubernetes/pkg/apis/extensions/v1beta1/deep_copy_generated.go b/vendor/k8s.io/kubernetes/pkg/apis/extensions/v1beta1/deep_copy_generated.go index 7b359190e7..dd33d0d08f 100644 --- a/vendor/k8s.io/kubernetes/pkg/apis/extensions/v1beta1/deep_copy_generated.go +++ b/vendor/k8s.io/kubernetes/pkg/apis/extensions/v1beta1/deep_copy_generated.go @@ -73,6 +73,12 @@ func init() { DeepCopy_v1beta1_LabelSelector, DeepCopy_v1beta1_LabelSelectorRequirement, DeepCopy_v1beta1_ListOptions, + DeepCopy_v1beta1_NetworkPolicy, + DeepCopy_v1beta1_NetworkPolicyIngressRule, + DeepCopy_v1beta1_NetworkPolicyList, + DeepCopy_v1beta1_NetworkPolicyPeer, + DeepCopy_v1beta1_NetworkPolicyPort, + DeepCopy_v1beta1_NetworkPolicySpec, DeepCopy_v1beta1_PodSecurityPolicy, DeepCopy_v1beta1_PodSecurityPolicyList, DeepCopy_v1beta1_PodSecurityPolicySpec, @@ -796,6 +802,130 @@ func DeepCopy_v1beta1_ListOptions(in ListOptions, out *ListOptions, c *conversio return nil } +func DeepCopy_v1beta1_NetworkPolicy(in NetworkPolicy, out *NetworkPolicy, c *conversion.Cloner) error { + if err := unversioned.DeepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + return err + } + if err := v1.DeepCopy_v1_ObjectMeta(in.ObjectMeta, &out.ObjectMeta, c); err != nil { + return err + } + if err := DeepCopy_v1beta1_NetworkPolicySpec(in.Spec, &out.Spec, c); err != nil { + return err + } + return nil +} + +func DeepCopy_v1beta1_NetworkPolicyIngressRule(in NetworkPolicyIngressRule, out *NetworkPolicyIngressRule, c *conversion.Cloner) error { + if in.Ports != nil { + in, out := in.Ports, &out.Ports + *out = make([]NetworkPolicyPort, len(in)) + for i := range in { + if err := DeepCopy_v1beta1_NetworkPolicyPort(in[i], &(*out)[i], c); err != nil { + return err + } + } + } else { + out.Ports = nil + } + if in.From != nil { + in, out := in.From, &out.From + *out = make([]NetworkPolicyPeer, len(in)) + for i := range in { + if err := DeepCopy_v1beta1_NetworkPolicyPeer(in[i], &(*out)[i], c); err != nil { + return err + } + } + } else { + out.From = nil + } + return nil +} + +func DeepCopy_v1beta1_NetworkPolicyList(in NetworkPolicyList, out *NetworkPolicyList, c *conversion.Cloner) error { + if err := unversioned.DeepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + return err + } + if err := unversioned.DeepCopy_unversioned_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { + return err + } + if in.Items != nil { + in, out := in.Items, &out.Items + *out = make([]NetworkPolicy, len(in)) + for i := range in { + if err := DeepCopy_v1beta1_NetworkPolicy(in[i], &(*out)[i], c); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +func DeepCopy_v1beta1_NetworkPolicyPeer(in NetworkPolicyPeer, out *NetworkPolicyPeer, c *conversion.Cloner) error { + if in.PodSelector != nil { + in, out := in.PodSelector, &out.PodSelector + *out = new(LabelSelector) + if err := DeepCopy_v1beta1_LabelSelector(*in, *out, c); err != nil { + return err + } + } else { + out.PodSelector = nil + } + if in.NamespaceSelector != nil { + in, out := in.NamespaceSelector, &out.NamespaceSelector + *out = new(LabelSelector) + if err := DeepCopy_v1beta1_LabelSelector(*in, *out, c); err != nil { + return err + } + } else { + out.NamespaceSelector = nil + } + return nil +} + +func DeepCopy_v1beta1_NetworkPolicyPort(in NetworkPolicyPort, out *NetworkPolicyPort, c *conversion.Cloner) error { + if in.Protocol != nil { + in, out := in.Protocol, &out.Protocol + *out = new(v1.Protocol) + if newVal, err := c.DeepCopy(*in); err != nil { + return err + } else { + **out = newVal.(v1.Protocol) + } + } else { + out.Protocol = nil + } + if in.Port != nil { + in, out := in.Port, &out.Port + *out = new(intstr.IntOrString) + if err := intstr.DeepCopy_intstr_IntOrString(*in, *out, c); err != nil { + return err + } + } else { + out.Port = nil + } + return nil +} + +func DeepCopy_v1beta1_NetworkPolicySpec(in NetworkPolicySpec, out *NetworkPolicySpec, c *conversion.Cloner) error { + if err := DeepCopy_v1beta1_LabelSelector(in.PodSelector, &out.PodSelector, c); err != nil { + return err + } + if in.Ingress != nil { + in, out := in.Ingress, &out.Ingress + *out = make([]NetworkPolicyIngressRule, len(in)) + for i := range in { + if err := DeepCopy_v1beta1_NetworkPolicyIngressRule(in[i], &(*out)[i], c); err != nil { + return err + } + } + } else { + out.Ingress = nil + } + return nil +} + func DeepCopy_v1beta1_PodSecurityPolicy(in PodSecurityPolicy, out *PodSecurityPolicy, c *conversion.Cloner) error { if err := unversioned.DeepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { return err diff --git a/vendor/k8s.io/kubernetes/pkg/apis/extensions/v1beta1/defaults.go b/vendor/k8s.io/kubernetes/pkg/apis/extensions/v1beta1/defaults.go index bf4989da05..71e55a467a 100644 --- a/vendor/k8s.io/kubernetes/pkg/apis/extensions/v1beta1/defaults.go +++ b/vendor/k8s.io/kubernetes/pkg/apis/extensions/v1beta1/defaults.go @@ -17,6 +17,7 @@ limitations under the License. package v1beta1 import ( + "k8s.io/kubernetes/pkg/api/v1" "k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/util/intstr" ) @@ -28,6 +29,7 @@ func addDefaultingFuncs(scheme *runtime.Scheme) { SetDefaults_Job, SetDefaults_HorizontalPodAutoscaler, SetDefaults_ReplicaSet, + SetDefaults_NetworkPolicy, ) } @@ -150,3 +152,16 @@ func SetDefaults_ReplicaSet(obj *ReplicaSet) { *obj.Spec.Replicas = 1 } } + +func SetDefaults_NetworkPolicy(obj *NetworkPolicy) { + // Default any undefined Protocol fields to TCP. + for _, i := range obj.Spec.Ingress { + // TODO: Update Ports to be a pointer to slice as soon as auto-generation supports it. + for _, p := range i.Ports { + if p.Protocol == nil { + proto := v1.ProtocolTCP + p.Protocol = &proto + } + } + } +} diff --git a/vendor/k8s.io/kubernetes/pkg/apis/extensions/v1beta1/generated.pb.go b/vendor/k8s.io/kubernetes/pkg/apis/extensions/v1beta1/generated.pb.go index 70ea18bd5c..3120ce17ff 100644 --- a/vendor/k8s.io/kubernetes/pkg/apis/extensions/v1beta1/generated.pb.go +++ b/vendor/k8s.io/kubernetes/pkg/apis/extensions/v1beta1/generated.pb.go @@ -67,6 +67,12 @@ limitations under the License. LabelSelector LabelSelectorRequirement ListOptions + NetworkPolicy + NetworkPolicyIngressRule + NetworkPolicyList + NetworkPolicyPeer + NetworkPolicyPort + NetworkPolicySpec PodSecurityPolicy PodSecurityPolicyList PodSecurityPolicySpec @@ -275,6 +281,30 @@ func (m *ListOptions) Reset() { *m = ListOptions{} } func (m *ListOptions) String() string { return proto.CompactTextString(m) } func (*ListOptions) ProtoMessage() {} +func (m *NetworkPolicy) Reset() { *m = NetworkPolicy{} } +func (m *NetworkPolicy) String() string { return proto.CompactTextString(m) } +func (*NetworkPolicy) ProtoMessage() {} + +func (m *NetworkPolicyIngressRule) Reset() { *m = NetworkPolicyIngressRule{} } +func (m *NetworkPolicyIngressRule) String() string { return proto.CompactTextString(m) } +func (*NetworkPolicyIngressRule) ProtoMessage() {} + +func (m *NetworkPolicyList) Reset() { *m = NetworkPolicyList{} } +func (m *NetworkPolicyList) String() string { return proto.CompactTextString(m) } +func (*NetworkPolicyList) ProtoMessage() {} + +func (m *NetworkPolicyPeer) Reset() { *m = NetworkPolicyPeer{} } +func (m *NetworkPolicyPeer) String() string { return proto.CompactTextString(m) } +func (*NetworkPolicyPeer) ProtoMessage() {} + +func (m *NetworkPolicyPort) Reset() { *m = NetworkPolicyPort{} } +func (m *NetworkPolicyPort) String() string { return proto.CompactTextString(m) } +func (*NetworkPolicyPort) ProtoMessage() {} + +func (m *NetworkPolicySpec) Reset() { *m = NetworkPolicySpec{} } +func (m *NetworkPolicySpec) String() string { return proto.CompactTextString(m) } +func (*NetworkPolicySpec) ProtoMessage() {} + func (m *PodSecurityPolicy) Reset() { *m = PodSecurityPolicy{} } func (m *PodSecurityPolicy) String() string { return proto.CompactTextString(m) } func (*PodSecurityPolicy) ProtoMessage() {} @@ -402,6 +432,12 @@ func init() { proto.RegisterType((*LabelSelector)(nil), "k8s.io.kubernetes.pkg.apis.extensions.v1beta1.LabelSelector") proto.RegisterType((*LabelSelectorRequirement)(nil), "k8s.io.kubernetes.pkg.apis.extensions.v1beta1.LabelSelectorRequirement") proto.RegisterType((*ListOptions)(nil), "k8s.io.kubernetes.pkg.apis.extensions.v1beta1.ListOptions") + proto.RegisterType((*NetworkPolicy)(nil), "k8s.io.kubernetes.pkg.apis.extensions.v1beta1.NetworkPolicy") + proto.RegisterType((*NetworkPolicyIngressRule)(nil), "k8s.io.kubernetes.pkg.apis.extensions.v1beta1.NetworkPolicyIngressRule") + proto.RegisterType((*NetworkPolicyList)(nil), "k8s.io.kubernetes.pkg.apis.extensions.v1beta1.NetworkPolicyList") + proto.RegisterType((*NetworkPolicyPeer)(nil), "k8s.io.kubernetes.pkg.apis.extensions.v1beta1.NetworkPolicyPeer") + proto.RegisterType((*NetworkPolicyPort)(nil), "k8s.io.kubernetes.pkg.apis.extensions.v1beta1.NetworkPolicyPort") + proto.RegisterType((*NetworkPolicySpec)(nil), "k8s.io.kubernetes.pkg.apis.extensions.v1beta1.NetworkPolicySpec") proto.RegisterType((*PodSecurityPolicy)(nil), "k8s.io.kubernetes.pkg.apis.extensions.v1beta1.PodSecurityPolicy") proto.RegisterType((*PodSecurityPolicyList)(nil), "k8s.io.kubernetes.pkg.apis.extensions.v1beta1.PodSecurityPolicyList") proto.RegisterType((*PodSecurityPolicySpec)(nil), "k8s.io.kubernetes.pkg.apis.extensions.v1beta1.PodSecurityPolicySpec") @@ -2005,7 +2041,7 @@ func (m *ListOptions) MarshalTo(data []byte) (int, error) { return i, nil } -func (m *PodSecurityPolicy) Marshal() (data []byte, err error) { +func (m *NetworkPolicy) Marshal() (data []byte, err error) { size := m.Size() data = make([]byte, size) n, err := m.MarshalTo(data) @@ -2015,7 +2051,7 @@ func (m *PodSecurityPolicy) Marshal() (data []byte, err error) { return data[:n], nil } -func (m *PodSecurityPolicy) MarshalTo(data []byte) (int, error) { +func (m *NetworkPolicy) MarshalTo(data []byte) (int, error) { var i int _ = i var l int @@ -2039,6 +2075,230 @@ func (m *PodSecurityPolicy) MarshalTo(data []byte) (int, error) { return i, nil } +func (m *NetworkPolicyIngressRule) Marshal() (data []byte, err error) { + size := m.Size() + data = make([]byte, size) + n, err := m.MarshalTo(data) + if err != nil { + return nil, err + } + return data[:n], nil +} + +func (m *NetworkPolicyIngressRule) MarshalTo(data []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.Ports) > 0 { + for _, msg := range m.Ports { + data[i] = 0xa + i++ + i = encodeVarintGenerated(data, i, uint64(msg.Size())) + n, err := msg.MarshalTo(data[i:]) + if err != nil { + return 0, err + } + i += n + } + } + if len(m.From) > 0 { + for _, msg := range m.From { + data[i] = 0x12 + i++ + i = encodeVarintGenerated(data, i, uint64(msg.Size())) + n, err := msg.MarshalTo(data[i:]) + if err != nil { + return 0, err + } + i += n + } + } + return i, nil +} + +func (m *NetworkPolicyList) Marshal() (data []byte, err error) { + size := m.Size() + data = make([]byte, size) + n, err := m.MarshalTo(data) + if err != nil { + return nil, err + } + return data[:n], nil +} + +func (m *NetworkPolicyList) MarshalTo(data []byte) (int, error) { + var i int + _ = i + var l int + _ = l + data[i] = 0xa + i++ + i = encodeVarintGenerated(data, i, uint64(m.ListMeta.Size())) + n48, err := m.ListMeta.MarshalTo(data[i:]) + if err != nil { + return 0, err + } + i += n48 + if len(m.Items) > 0 { + for _, msg := range m.Items { + data[i] = 0x12 + i++ + i = encodeVarintGenerated(data, i, uint64(msg.Size())) + n, err := msg.MarshalTo(data[i:]) + if err != nil { + return 0, err + } + i += n + } + } + return i, nil +} + +func (m *NetworkPolicyPeer) Marshal() (data []byte, err error) { + size := m.Size() + data = make([]byte, size) + n, err := m.MarshalTo(data) + if err != nil { + return nil, err + } + return data[:n], nil +} + +func (m *NetworkPolicyPeer) MarshalTo(data []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.PodSelector != nil { + data[i] = 0xa + i++ + i = encodeVarintGenerated(data, i, uint64(m.PodSelector.Size())) + n49, err := m.PodSelector.MarshalTo(data[i:]) + if err != nil { + return 0, err + } + i += n49 + } + if m.NamespaceSelector != nil { + data[i] = 0x12 + i++ + i = encodeVarintGenerated(data, i, uint64(m.NamespaceSelector.Size())) + n50, err := m.NamespaceSelector.MarshalTo(data[i:]) + if err != nil { + return 0, err + } + i += n50 + } + return i, nil +} + +func (m *NetworkPolicyPort) Marshal() (data []byte, err error) { + size := m.Size() + data = make([]byte, size) + n, err := m.MarshalTo(data) + if err != nil { + return nil, err + } + return data[:n], nil +} + +func (m *NetworkPolicyPort) MarshalTo(data []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.Protocol != nil { + data[i] = 0xa + i++ + i = encodeVarintGenerated(data, i, uint64(len(*m.Protocol))) + i += copy(data[i:], *m.Protocol) + } + if m.Port != nil { + data[i] = 0x12 + i++ + i = encodeVarintGenerated(data, i, uint64(m.Port.Size())) + n51, err := m.Port.MarshalTo(data[i:]) + if err != nil { + return 0, err + } + i += n51 + } + return i, nil +} + +func (m *NetworkPolicySpec) Marshal() (data []byte, err error) { + size := m.Size() + data = make([]byte, size) + n, err := m.MarshalTo(data) + if err != nil { + return nil, err + } + return data[:n], nil +} + +func (m *NetworkPolicySpec) MarshalTo(data []byte) (int, error) { + var i int + _ = i + var l int + _ = l + data[i] = 0xa + i++ + i = encodeVarintGenerated(data, i, uint64(m.PodSelector.Size())) + n52, err := m.PodSelector.MarshalTo(data[i:]) + if err != nil { + return 0, err + } + i += n52 + if len(m.Ingress) > 0 { + for _, msg := range m.Ingress { + data[i] = 0x12 + i++ + i = encodeVarintGenerated(data, i, uint64(msg.Size())) + n, err := msg.MarshalTo(data[i:]) + if err != nil { + return 0, err + } + i += n + } + } + return i, nil +} + +func (m *PodSecurityPolicy) Marshal() (data []byte, err error) { + size := m.Size() + data = make([]byte, size) + n, err := m.MarshalTo(data) + if err != nil { + return nil, err + } + return data[:n], nil +} + +func (m *PodSecurityPolicy) MarshalTo(data []byte) (int, error) { + var i int + _ = i + var l int + _ = l + data[i] = 0xa + i++ + i = encodeVarintGenerated(data, i, uint64(m.ObjectMeta.Size())) + n53, err := m.ObjectMeta.MarshalTo(data[i:]) + if err != nil { + return 0, err + } + i += n53 + data[i] = 0x12 + i++ + i = encodeVarintGenerated(data, i, uint64(m.Spec.Size())) + n54, err := m.Spec.MarshalTo(data[i:]) + if err != nil { + return 0, err + } + i += n54 + return i, nil +} + func (m *PodSecurityPolicyList) Marshal() (data []byte, err error) { size := m.Size() data = make([]byte, size) @@ -2057,11 +2317,11 @@ func (m *PodSecurityPolicyList) MarshalTo(data []byte) (int, error) { data[i] = 0xa i++ i = encodeVarintGenerated(data, i, uint64(m.ListMeta.Size())) - n48, err := m.ListMeta.MarshalTo(data[i:]) + n55, err := m.ListMeta.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n48 + i += n55 if len(m.Items) > 0 { for _, msg := range m.Items { data[i] = 0x12 @@ -2199,35 +2459,35 @@ func (m *PodSecurityPolicySpec) MarshalTo(data []byte) (int, error) { data[i] = 0x52 i++ i = encodeVarintGenerated(data, i, uint64(m.SELinux.Size())) - n49, err := m.SELinux.MarshalTo(data[i:]) + n56, err := m.SELinux.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n49 + i += n56 data[i] = 0x5a i++ i = encodeVarintGenerated(data, i, uint64(m.RunAsUser.Size())) - n50, err := m.RunAsUser.MarshalTo(data[i:]) + n57, err := m.RunAsUser.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n50 + i += n57 data[i] = 0x62 i++ i = encodeVarintGenerated(data, i, uint64(m.SupplementalGroups.Size())) - n51, err := m.SupplementalGroups.MarshalTo(data[i:]) + n58, err := m.SupplementalGroups.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n51 + i += n58 data[i] = 0x6a i++ i = encodeVarintGenerated(data, i, uint64(m.FSGroup.Size())) - n52, err := m.FSGroup.MarshalTo(data[i:]) + n59, err := m.FSGroup.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n52 + i += n59 data[i] = 0x70 i++ if m.ReadOnlyRootFilesystem { @@ -2257,27 +2517,27 @@ func (m *ReplicaSet) MarshalTo(data []byte) (int, error) { data[i] = 0xa i++ i = encodeVarintGenerated(data, i, uint64(m.ObjectMeta.Size())) - n53, err := m.ObjectMeta.MarshalTo(data[i:]) + n60, err := m.ObjectMeta.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n53 + i += n60 data[i] = 0x12 i++ i = encodeVarintGenerated(data, i, uint64(m.Spec.Size())) - n54, err := m.Spec.MarshalTo(data[i:]) + n61, err := m.Spec.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n54 + i += n61 data[i] = 0x1a i++ i = encodeVarintGenerated(data, i, uint64(m.Status.Size())) - n55, err := m.Status.MarshalTo(data[i:]) + n62, err := m.Status.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n55 + i += n62 return i, nil } @@ -2299,11 +2559,11 @@ func (m *ReplicaSetList) MarshalTo(data []byte) (int, error) { data[i] = 0xa i++ i = encodeVarintGenerated(data, i, uint64(m.ListMeta.Size())) - n56, err := m.ListMeta.MarshalTo(data[i:]) + n63, err := m.ListMeta.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n56 + i += n63 if len(m.Items) > 0 { for _, msg := range m.Items { data[i] = 0x12 @@ -2343,20 +2603,20 @@ func (m *ReplicaSetSpec) MarshalTo(data []byte) (int, error) { data[i] = 0x12 i++ i = encodeVarintGenerated(data, i, uint64(m.Selector.Size())) - n57, err := m.Selector.MarshalTo(data[i:]) + n64, err := m.Selector.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n57 + i += n64 } data[i] = 0x1a i++ i = encodeVarintGenerated(data, i, uint64(m.Template.Size())) - n58, err := m.Template.MarshalTo(data[i:]) + n65, err := m.Template.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n58 + i += n65 return i, nil } @@ -2445,21 +2705,21 @@ func (m *RollingUpdateDeployment) MarshalTo(data []byte) (int, error) { data[i] = 0xa i++ i = encodeVarintGenerated(data, i, uint64(m.MaxUnavailable.Size())) - n59, err := m.MaxUnavailable.MarshalTo(data[i:]) + n66, err := m.MaxUnavailable.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n59 + i += n66 } if m.MaxSurge != nil { data[i] = 0x12 i++ i = encodeVarintGenerated(data, i, uint64(m.MaxSurge.Size())) - n60, err := m.MaxSurge.MarshalTo(data[i:]) + n67, err := m.MaxSurge.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n60 + i += n67 } return i, nil } @@ -2521,11 +2781,11 @@ func (m *SELinuxStrategyOptions) MarshalTo(data []byte) (int, error) { data[i] = 0x12 i++ i = encodeVarintGenerated(data, i, uint64(m.SELinuxOptions.Size())) - n61, err := m.SELinuxOptions.MarshalTo(data[i:]) + n68, err := m.SELinuxOptions.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n61 + i += n68 } return i, nil } @@ -2548,27 +2808,27 @@ func (m *Scale) MarshalTo(data []byte) (int, error) { data[i] = 0xa i++ i = encodeVarintGenerated(data, i, uint64(m.ObjectMeta.Size())) - n62, err := m.ObjectMeta.MarshalTo(data[i:]) + n69, err := m.ObjectMeta.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n62 + i += n69 data[i] = 0x12 i++ i = encodeVarintGenerated(data, i, uint64(m.Spec.Size())) - n63, err := m.Spec.MarshalTo(data[i:]) + n70, err := m.Spec.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n63 + i += n70 data[i] = 0x1a i++ i = encodeVarintGenerated(data, i, uint64(m.Status.Size())) - n64, err := m.Status.MarshalTo(data[i:]) + n71, err := m.Status.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n64 + i += n71 return i, nil } @@ -2721,11 +2981,11 @@ func (m *ThirdPartyResource) MarshalTo(data []byte) (int, error) { data[i] = 0xa i++ i = encodeVarintGenerated(data, i, uint64(m.ObjectMeta.Size())) - n65, err := m.ObjectMeta.MarshalTo(data[i:]) + n72, err := m.ObjectMeta.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n65 + i += n72 data[i] = 0x12 i++ i = encodeVarintGenerated(data, i, uint64(len(m.Description))) @@ -2763,11 +3023,11 @@ func (m *ThirdPartyResourceData) MarshalTo(data []byte) (int, error) { data[i] = 0xa i++ i = encodeVarintGenerated(data, i, uint64(m.ObjectMeta.Size())) - n66, err := m.ObjectMeta.MarshalTo(data[i:]) + n73, err := m.ObjectMeta.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n66 + i += n73 if m.Data != nil { data[i] = 0x12 i++ @@ -2795,11 +3055,11 @@ func (m *ThirdPartyResourceDataList) MarshalTo(data []byte) (int, error) { data[i] = 0xa i++ i = encodeVarintGenerated(data, i, uint64(m.ListMeta.Size())) - n67, err := m.ListMeta.MarshalTo(data[i:]) + n74, err := m.ListMeta.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n67 + i += n74 if len(m.Items) > 0 { for _, msg := range m.Items { data[i] = 0x12 @@ -2833,11 +3093,11 @@ func (m *ThirdPartyResourceList) MarshalTo(data []byte) (int, error) { data[i] = 0xa i++ i = encodeVarintGenerated(data, i, uint64(m.ListMeta.Size())) - n68, err := m.ListMeta.MarshalTo(data[i:]) + n75, err := m.ListMeta.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n68 + i += n75 if len(m.Items) > 0 { for _, msg := range m.Items { data[i] = 0x12 @@ -3442,6 +3702,90 @@ func (m *ListOptions) Size() (n int) { return n } +func (m *NetworkPolicy) Size() (n int) { + var l int + _ = l + l = m.ObjectMeta.Size() + n += 1 + l + sovGenerated(uint64(l)) + l = m.Spec.Size() + n += 1 + l + sovGenerated(uint64(l)) + return n +} + +func (m *NetworkPolicyIngressRule) Size() (n int) { + var l int + _ = l + if len(m.Ports) > 0 { + for _, e := range m.Ports { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } + if len(m.From) > 0 { + for _, e := range m.From { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } + return n +} + +func (m *NetworkPolicyList) Size() (n int) { + var l int + _ = l + l = m.ListMeta.Size() + n += 1 + l + sovGenerated(uint64(l)) + if len(m.Items) > 0 { + for _, e := range m.Items { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } + return n +} + +func (m *NetworkPolicyPeer) Size() (n int) { + var l int + _ = l + if m.PodSelector != nil { + l = m.PodSelector.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + if m.NamespaceSelector != nil { + l = m.NamespaceSelector.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + return n +} + +func (m *NetworkPolicyPort) Size() (n int) { + var l int + _ = l + if m.Protocol != nil { + l = len(*m.Protocol) + n += 1 + l + sovGenerated(uint64(l)) + } + if m.Port != nil { + l = m.Port.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + return n +} + +func (m *NetworkPolicySpec) Size() (n int) { + var l int + _ = l + l = m.PodSelector.Size() + n += 1 + l + sovGenerated(uint64(l)) + if len(m.Ingress) > 0 { + for _, e := range m.Ingress { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } + return n +} + func (m *PodSecurityPolicy) Size() (n int) { var l int _ = l @@ -9129,6 +9473,679 @@ func (m *ListOptions) Unmarshal(data []byte) error { } return nil } +func (m *NetworkPolicy) Unmarshal(data []byte) error { + l := len(data) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: NetworkPolicy: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: NetworkPolicy: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ObjectMeta", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.ObjectMeta.Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Spec", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Spec.Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(data[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *NetworkPolicyIngressRule) Unmarshal(data []byte) error { + l := len(data) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: NetworkPolicyIngressRule: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: NetworkPolicyIngressRule: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Ports", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Ports = append(m.Ports, NetworkPolicyPort{}) + if err := m.Ports[len(m.Ports)-1].Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field From", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.From = append(m.From, NetworkPolicyPeer{}) + if err := m.From[len(m.From)-1].Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(data[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *NetworkPolicyList) Unmarshal(data []byte) error { + l := len(data) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: NetworkPolicyList: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: NetworkPolicyList: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ListMeta", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.ListMeta.Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Items", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Items = append(m.Items, NetworkPolicy{}) + if err := m.Items[len(m.Items)-1].Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(data[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *NetworkPolicyPeer) Unmarshal(data []byte) error { + l := len(data) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: NetworkPolicyPeer: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: NetworkPolicyPeer: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field PodSelector", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.PodSelector == nil { + m.PodSelector = &LabelSelector{} + } + if err := m.PodSelector.Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field NamespaceSelector", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.NamespaceSelector == nil { + m.NamespaceSelector = &LabelSelector{} + } + if err := m.NamespaceSelector.Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(data[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *NetworkPolicyPort) Unmarshal(data []byte) error { + l := len(data) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: NetworkPolicyPort: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: NetworkPolicyPort: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Protocol", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := k8s_io_kubernetes_pkg_api_v1.Protocol(data[iNdEx:postIndex]) + m.Protocol = &s + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Port", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Port == nil { + m.Port = &k8s_io_kubernetes_pkg_util_intstr.IntOrString{} + } + if err := m.Port.Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(data[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *NetworkPolicySpec) Unmarshal(data []byte) error { + l := len(data) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: NetworkPolicySpec: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: NetworkPolicySpec: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field PodSelector", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.PodSelector.Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Ingress", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Ingress = append(m.Ingress, NetworkPolicyIngressRule{}) + if err := m.Ingress[len(m.Ingress)-1].Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(data[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func (m *PodSecurityPolicy) Unmarshal(data []byte) error { l := len(data) iNdEx := 0 diff --git a/vendor/k8s.io/kubernetes/pkg/apis/extensions/v1beta1/generated.proto b/vendor/k8s.io/kubernetes/pkg/apis/extensions/v1beta1/generated.proto index a16b98b2fd..aa408bb096 100644 --- a/vendor/k8s.io/kubernetes/pkg/apis/extensions/v1beta1/generated.proto +++ b/vendor/k8s.io/kubernetes/pkg/apis/extensions/v1beta1/generated.proto @@ -625,6 +625,93 @@ message ListOptions { optional int64 timeoutSeconds = 5; } +message NetworkPolicy { + // Standard object's metadata. + // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata + optional k8s.io.kubernetes.pkg.api.v1.ObjectMeta metadata = 1; + + // Specification of the desired behavior for this NetworkPolicy. + optional NetworkPolicySpec spec = 2; +} + +// This NetworkPolicyIngressRule matches traffic if and only if the traffic matches both ports AND from. +message NetworkPolicyIngressRule { + // List of ports which should be made accessible on the pods selected for this rule. + // Each item in this list is combined using a logical OR. + // If this field is not provided, this rule matches all ports (traffic not restricted by port). + // If this field is empty, this rule matches no ports (no traffic matches). + // If this field is present and contains at least one item, then this rule allows traffic + // only if the traffic matches at least one port in the list. + // TODO: Update this to be a pointer to slice as soon as auto-generation supports it. + repeated NetworkPolicyPort ports = 1; + + // List of sources which should be able to access the pods selected for this rule. + // Items in this list are combined using a logical OR operation. + // If this field is not provided, this rule matches all sources (traffic not restricted by source). + // If this field is empty, this rule matches no sources (no traffic matches). + // If this field is present and contains at least on item, this rule allows traffic only if the + // traffic matches at least one item in the from list. + // TODO: Update this to be a pointer to slice as soon as auto-generation supports it. + repeated NetworkPolicyPeer from = 2; +} + +// Network Policy List is a list of NetworkPolicy objects. +message NetworkPolicyList { + // Standard list metadata. + // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata + optional k8s.io.kubernetes.pkg.api.unversioned.ListMeta metadata = 1; + + // Items is a list of schema objects. + repeated NetworkPolicy items = 2; +} + +message NetworkPolicyPeer { + // This is a label selector which selects Pods in this namespace. + // This field follows standard label selector semantics. + // If not provided, this selector selects no pods. + // If present but empty, this selector selects all pods in this namespace. + optional LabelSelector podSelector = 1; + + // Selects Namespaces using cluster scoped-labels. This + // matches all pods in all namespaces selected by this label selector. + // This field follows standard label selector semantics. + // If omited, this selector selects no namespaces. + // If present but empty, this selector selects all namespaces. + optional LabelSelector namespaceSelector = 2; +} + +message NetworkPolicyPort { + // Optional. The protocol (TCP or UDP) which traffic must match. + // If not specified, this field defaults to TCP. + optional string protocol = 1; + + // If specified, the port on the given protocol. This can + // either be a numerical or named port on a pod. If this field is not provided, + // this matches all port names and numbers. + // If present, only traffic on the specified protocol AND port + // will be matched. + optional k8s.io.kubernetes.pkg.util.intstr.IntOrString port = 2; +} + +message NetworkPolicySpec { + // Selects the pods to which this NetworkPolicy object applies. The array of ingress rules + // is applied to any pods selected by this field. Multiple network policies can select the + // same set of pods. In this case, the ingress rules for each are combined additively. + // This field is NOT optional and follows standard label selector semantics. + // An empty podSelector matches all pods in this namespace. + optional LabelSelector podSelector = 1; + + // List of ingress rules to be applied to the selected pods. + // Traffic is allowed to a pod if namespace.networkPolicy.ingress.isolation is undefined and cluster policy allows it, + // OR if the traffic source is the pod's local node, + // OR if the traffic matches at least one ingress rule across all of the NetworkPolicy + // objects whose podSelector matches the pod. + // If this field is empty then this NetworkPolicy does not affect ingress isolation. + // If this field is present and contains at least one rule, this policy allows any traffic + // which matches at least one of the ingress rules in this list. + repeated NetworkPolicyIngressRule ingress = 2; +} + // Pod Security Policy governs the ability to make requests that affect the Security Context // that will be applied to a pod and container. message PodSecurityPolicy { diff --git a/vendor/k8s.io/kubernetes/pkg/apis/extensions/v1beta1/register.go b/vendor/k8s.io/kubernetes/pkg/apis/extensions/v1beta1/register.go index ee662c4631..041e2cbc16 100644 --- a/vendor/k8s.io/kubernetes/pkg/apis/extensions/v1beta1/register.go +++ b/vendor/k8s.io/kubernetes/pkg/apis/extensions/v1beta1/register.go @@ -61,6 +61,8 @@ func addKnownTypes(scheme *runtime.Scheme) { &ReplicaSetList{}, &PodSecurityPolicy{}, &PodSecurityPolicyList{}, + &NetworkPolicy{}, + &NetworkPolicyList{}, ) // Add the watch version that applies versionedwatch.AddToGroupVersion(scheme, SchemeGroupVersion) @@ -88,3 +90,5 @@ func (obj *ReplicaSet) GetObjectKind() unversioned.ObjectKind { func (obj *ReplicaSetList) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta } func (obj *PodSecurityPolicy) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta } func (obj *PodSecurityPolicyList) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta } +func (obj *NetworkPolicy) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta } +func (obj *NetworkPolicyList) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta } diff --git a/vendor/k8s.io/kubernetes/pkg/apis/extensions/v1beta1/types.generated.go b/vendor/k8s.io/kubernetes/pkg/apis/extensions/v1beta1/types.generated.go index a3c789b9d9..4546c9baed 100644 --- a/vendor/k8s.io/kubernetes/pkg/apis/extensions/v1beta1/types.generated.go +++ b/vendor/k8s.io/kubernetes/pkg/apis/extensions/v1beta1/types.generated.go @@ -1,5 +1,5 @@ /* -Copyright 2015 The Kubernetes Authors All rights reserved. +Copyright 2016 The Kubernetes Authors All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -25,12 +25,11 @@ import ( "errors" "fmt" codec1978 "github.com/ugorji/go/codec" - pkg5_inf_v0 "gopkg.in/inf.v0" pkg4_resource "k8s.io/kubernetes/pkg/api/resource" pkg1_unversioned "k8s.io/kubernetes/pkg/api/unversioned" pkg2_v1 "k8s.io/kubernetes/pkg/api/v1" pkg3_types "k8s.io/kubernetes/pkg/types" - pkg6_intstr "k8s.io/kubernetes/pkg/util/intstr" + pkg5_intstr "k8s.io/kubernetes/pkg/util/intstr" "reflect" "runtime" time "time" @@ -66,14 +65,13 @@ func init() { panic(err) } if false { // reference the types, but skip this branch at build/run time - var v0 pkg5_inf_v0.Dec - var v1 pkg4_resource.Quantity - var v2 pkg1_unversioned.TypeMeta - var v3 pkg2_v1.ObjectMeta - var v4 pkg3_types.UID - var v5 pkg6_intstr.IntOrString - var v6 time.Time - _, _, _, _, _, _, _ = v0, v1, v2, v3, v4, v5, v6 + var v0 pkg4_resource.Quantity + var v1 pkg1_unversioned.TypeMeta + var v2 pkg2_v1.ObjectMeta + var v3 pkg3_types.UID + var v4 pkg5_intstr.IntOrString + var v5 time.Time + _, _, _, _, _, _ = v0, v1, v2, v3, v4, v5 } } @@ -6923,7 +6921,7 @@ func (x *RollingUpdateDeployment) codecDecodeSelfFromMap(l int, d *codec1978.Dec } } else { if x.MaxUnavailable == nil { - x.MaxUnavailable = new(pkg6_intstr.IntOrString) + x.MaxUnavailable = new(pkg5_intstr.IntOrString) } yym5 := z.DecBinary() _ = yym5 @@ -6942,7 +6940,7 @@ func (x *RollingUpdateDeployment) codecDecodeSelfFromMap(l int, d *codec1978.Dec } } else { if x.MaxSurge == nil { - x.MaxSurge = new(pkg6_intstr.IntOrString) + x.MaxSurge = new(pkg5_intstr.IntOrString) } yym7 := z.DecBinary() _ = yym7 @@ -6985,7 +6983,7 @@ func (x *RollingUpdateDeployment) codecDecodeSelfFromArray(l int, d *codec1978.D } } else { if x.MaxUnavailable == nil { - x.MaxUnavailable = new(pkg6_intstr.IntOrString) + x.MaxUnavailable = new(pkg5_intstr.IntOrString) } yym10 := z.DecBinary() _ = yym10 @@ -7014,7 +7012,7 @@ func (x *RollingUpdateDeployment) codecDecodeSelfFromArray(l int, d *codec1978.D } } else { if x.MaxSurge == nil { - x.MaxSurge = new(pkg6_intstr.IntOrString) + x.MaxSurge = new(pkg5_intstr.IntOrString) } yym12 := z.DecBinary() _ = yym12 @@ -13794,7 +13792,7 @@ func (x *IngressBackend) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) { } case "servicePort": if r.TryDecodeAsNil() { - x.ServicePort = pkg6_intstr.IntOrString{} + x.ServicePort = pkg5_intstr.IntOrString{} } else { yyv5 := &x.ServicePort yym6 := z.DecBinary() @@ -13849,7 +13847,7 @@ func (x *IngressBackend) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { } z.DecSendContainerState(codecSelfer_containerArrayElem1234) if r.TryDecodeAsNil() { - x.ServicePort = pkg6_intstr.IntOrString{} + x.ServicePort = pkg5_intstr.IntOrString{} } else { yyv9 := &x.ServicePort yym10 := z.DecBinary() @@ -19354,6 +19352,1634 @@ func (x *PodSecurityPolicyList) codecDecodeSelfFromArray(l int, d *codec1978.Dec z.DecSendContainerState(codecSelfer_containerArrayEnd1234) } +func (x *NetworkPolicy) CodecEncodeSelf(e *codec1978.Encoder) { + var h codecSelfer1234 + z, r := codec1978.GenHelperEncoder(e) + _, _, _ = h, z, r + if x == nil { + r.EncodeNil() + } else { + yym1 := z.EncBinary() + _ = yym1 + if false { + } else if z.HasExtensions() && z.EncExt(x) { + } else { + yysep2 := !z.EncBinary() + yy2arr2 := z.EncBasicHandle().StructToArray + var yyq2 [4]bool + _, _, _ = yysep2, yyq2, yy2arr2 + const yyr2 bool = false + yyq2[0] = true + yyq2[1] = true + yyq2[2] = x.Kind != "" + yyq2[3] = x.APIVersion != "" + var yynn2 int + if yyr2 || yy2arr2 { + r.EncodeArrayStart(4) + } else { + yynn2 = 0 + for _, b := range yyq2 { + if b { + yynn2++ + } + } + r.EncodeMapStart(yynn2) + yynn2 = 0 + } + if yyr2 || yy2arr2 { + z.EncSendContainerState(codecSelfer_containerArrayElem1234) + if yyq2[0] { + yy4 := &x.ObjectMeta + yy4.CodecEncodeSelf(e) + } else { + r.EncodeNil() + } + } else { + if yyq2[0] { + z.EncSendContainerState(codecSelfer_containerMapKey1234) + r.EncodeString(codecSelferC_UTF81234, string("metadata")) + z.EncSendContainerState(codecSelfer_containerMapValue1234) + yy6 := &x.ObjectMeta + yy6.CodecEncodeSelf(e) + } + } + if yyr2 || yy2arr2 { + z.EncSendContainerState(codecSelfer_containerArrayElem1234) + if yyq2[1] { + yy9 := &x.Spec + yy9.CodecEncodeSelf(e) + } else { + r.EncodeNil() + } + } else { + if yyq2[1] { + z.EncSendContainerState(codecSelfer_containerMapKey1234) + r.EncodeString(codecSelferC_UTF81234, string("spec")) + z.EncSendContainerState(codecSelfer_containerMapValue1234) + yy11 := &x.Spec + yy11.CodecEncodeSelf(e) + } + } + if yyr2 || yy2arr2 { + z.EncSendContainerState(codecSelfer_containerArrayElem1234) + if yyq2[2] { + yym14 := z.EncBinary() + _ = yym14 + if false { + } else { + r.EncodeString(codecSelferC_UTF81234, string(x.Kind)) + } + } else { + r.EncodeString(codecSelferC_UTF81234, "") + } + } else { + if yyq2[2] { + z.EncSendContainerState(codecSelfer_containerMapKey1234) + r.EncodeString(codecSelferC_UTF81234, string("kind")) + z.EncSendContainerState(codecSelfer_containerMapValue1234) + yym15 := z.EncBinary() + _ = yym15 + if false { + } else { + r.EncodeString(codecSelferC_UTF81234, string(x.Kind)) + } + } + } + if yyr2 || yy2arr2 { + z.EncSendContainerState(codecSelfer_containerArrayElem1234) + if yyq2[3] { + yym17 := z.EncBinary() + _ = yym17 + if false { + } else { + r.EncodeString(codecSelferC_UTF81234, string(x.APIVersion)) + } + } else { + r.EncodeString(codecSelferC_UTF81234, "") + } + } else { + if yyq2[3] { + z.EncSendContainerState(codecSelfer_containerMapKey1234) + r.EncodeString(codecSelferC_UTF81234, string("apiVersion")) + z.EncSendContainerState(codecSelfer_containerMapValue1234) + yym18 := z.EncBinary() + _ = yym18 + if false { + } else { + r.EncodeString(codecSelferC_UTF81234, string(x.APIVersion)) + } + } + } + if yyr2 || yy2arr2 { + z.EncSendContainerState(codecSelfer_containerArrayEnd1234) + } else { + z.EncSendContainerState(codecSelfer_containerMapEnd1234) + } + } + } +} + +func (x *NetworkPolicy) CodecDecodeSelf(d *codec1978.Decoder) { + var h codecSelfer1234 + z, r := codec1978.GenHelperDecoder(d) + _, _, _ = h, z, r + yym1 := z.DecBinary() + _ = yym1 + if false { + } else if z.HasExtensions() && z.DecExt(x) { + } else { + yyct2 := r.ContainerType() + if yyct2 == codecSelferValueTypeMap1234 { + yyl2 := r.ReadMapStart() + if yyl2 == 0 { + z.DecSendContainerState(codecSelfer_containerMapEnd1234) + } else { + x.codecDecodeSelfFromMap(yyl2, d) + } + } else if yyct2 == codecSelferValueTypeArray1234 { + yyl2 := r.ReadArrayStart() + if yyl2 == 0 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) + } else { + x.codecDecodeSelfFromArray(yyl2, d) + } + } else { + panic(codecSelferOnlyMapOrArrayEncodeToStructErr1234) + } + } +} + +func (x *NetworkPolicy) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) { + var h codecSelfer1234 + z, r := codec1978.GenHelperDecoder(d) + _, _, _ = h, z, r + var yys3Slc = z.DecScratchBuffer() // default slice to decode into + _ = yys3Slc + var yyhl3 bool = l >= 0 + for yyj3 := 0; ; yyj3++ { + if yyhl3 { + if yyj3 >= l { + break + } + } else { + if r.CheckBreak() { + break + } + } + z.DecSendContainerState(codecSelfer_containerMapKey1234) + yys3Slc = r.DecodeBytes(yys3Slc, true, true) + yys3 := string(yys3Slc) + z.DecSendContainerState(codecSelfer_containerMapValue1234) + switch yys3 { + case "metadata": + if r.TryDecodeAsNil() { + x.ObjectMeta = pkg2_v1.ObjectMeta{} + } else { + yyv4 := &x.ObjectMeta + yyv4.CodecDecodeSelf(d) + } + case "spec": + if r.TryDecodeAsNil() { + x.Spec = NetworkPolicySpec{} + } else { + yyv5 := &x.Spec + yyv5.CodecDecodeSelf(d) + } + case "kind": + if r.TryDecodeAsNil() { + x.Kind = "" + } else { + x.Kind = string(r.DecodeString()) + } + case "apiVersion": + if r.TryDecodeAsNil() { + x.APIVersion = "" + } else { + x.APIVersion = string(r.DecodeString()) + } + default: + z.DecStructFieldNotFound(-1, yys3) + } // end switch yys3 + } // end for yyj3 + z.DecSendContainerState(codecSelfer_containerMapEnd1234) +} + +func (x *NetworkPolicy) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { + var h codecSelfer1234 + z, r := codec1978.GenHelperDecoder(d) + _, _, _ = h, z, r + var yyj8 int + var yyb8 bool + var yyhl8 bool = l >= 0 + yyj8++ + if yyhl8 { + yyb8 = yyj8 > l + } else { + yyb8 = r.CheckBreak() + } + if yyb8 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) + return + } + z.DecSendContainerState(codecSelfer_containerArrayElem1234) + if r.TryDecodeAsNil() { + x.ObjectMeta = pkg2_v1.ObjectMeta{} + } else { + yyv9 := &x.ObjectMeta + yyv9.CodecDecodeSelf(d) + } + yyj8++ + if yyhl8 { + yyb8 = yyj8 > l + } else { + yyb8 = r.CheckBreak() + } + if yyb8 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) + return + } + z.DecSendContainerState(codecSelfer_containerArrayElem1234) + if r.TryDecodeAsNil() { + x.Spec = NetworkPolicySpec{} + } else { + yyv10 := &x.Spec + yyv10.CodecDecodeSelf(d) + } + yyj8++ + if yyhl8 { + yyb8 = yyj8 > l + } else { + yyb8 = r.CheckBreak() + } + if yyb8 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) + return + } + z.DecSendContainerState(codecSelfer_containerArrayElem1234) + if r.TryDecodeAsNil() { + x.Kind = "" + } else { + x.Kind = string(r.DecodeString()) + } + yyj8++ + if yyhl8 { + yyb8 = yyj8 > l + } else { + yyb8 = r.CheckBreak() + } + if yyb8 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) + return + } + z.DecSendContainerState(codecSelfer_containerArrayElem1234) + if r.TryDecodeAsNil() { + x.APIVersion = "" + } else { + x.APIVersion = string(r.DecodeString()) + } + for { + yyj8++ + if yyhl8 { + yyb8 = yyj8 > l + } else { + yyb8 = r.CheckBreak() + } + if yyb8 { + break + } + z.DecSendContainerState(codecSelfer_containerArrayElem1234) + z.DecStructFieldNotFound(yyj8-1, "") + } + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) +} + +func (x *NetworkPolicySpec) CodecEncodeSelf(e *codec1978.Encoder) { + var h codecSelfer1234 + z, r := codec1978.GenHelperEncoder(e) + _, _, _ = h, z, r + if x == nil { + r.EncodeNil() + } else { + yym1 := z.EncBinary() + _ = yym1 + if false { + } else if z.HasExtensions() && z.EncExt(x) { + } else { + yysep2 := !z.EncBinary() + yy2arr2 := z.EncBasicHandle().StructToArray + var yyq2 [2]bool + _, _, _ = yysep2, yyq2, yy2arr2 + const yyr2 bool = false + yyq2[1] = len(x.Ingress) != 0 + var yynn2 int + if yyr2 || yy2arr2 { + r.EncodeArrayStart(2) + } else { + yynn2 = 1 + for _, b := range yyq2 { + if b { + yynn2++ + } + } + r.EncodeMapStart(yynn2) + yynn2 = 0 + } + if yyr2 || yy2arr2 { + z.EncSendContainerState(codecSelfer_containerArrayElem1234) + yy4 := &x.PodSelector + yy4.CodecEncodeSelf(e) + } else { + z.EncSendContainerState(codecSelfer_containerMapKey1234) + r.EncodeString(codecSelferC_UTF81234, string("podSelector")) + z.EncSendContainerState(codecSelfer_containerMapValue1234) + yy6 := &x.PodSelector + yy6.CodecEncodeSelf(e) + } + if yyr2 || yy2arr2 { + z.EncSendContainerState(codecSelfer_containerArrayElem1234) + if yyq2[1] { + if x.Ingress == nil { + r.EncodeNil() + } else { + yym9 := z.EncBinary() + _ = yym9 + if false { + } else { + h.encSliceNetworkPolicyIngressRule(([]NetworkPolicyIngressRule)(x.Ingress), e) + } + } + } else { + r.EncodeNil() + } + } else { + if yyq2[1] { + z.EncSendContainerState(codecSelfer_containerMapKey1234) + r.EncodeString(codecSelferC_UTF81234, string("ingress")) + z.EncSendContainerState(codecSelfer_containerMapValue1234) + if x.Ingress == nil { + r.EncodeNil() + } else { + yym10 := z.EncBinary() + _ = yym10 + if false { + } else { + h.encSliceNetworkPolicyIngressRule(([]NetworkPolicyIngressRule)(x.Ingress), e) + } + } + } + } + if yyr2 || yy2arr2 { + z.EncSendContainerState(codecSelfer_containerArrayEnd1234) + } else { + z.EncSendContainerState(codecSelfer_containerMapEnd1234) + } + } + } +} + +func (x *NetworkPolicySpec) CodecDecodeSelf(d *codec1978.Decoder) { + var h codecSelfer1234 + z, r := codec1978.GenHelperDecoder(d) + _, _, _ = h, z, r + yym1 := z.DecBinary() + _ = yym1 + if false { + } else if z.HasExtensions() && z.DecExt(x) { + } else { + yyct2 := r.ContainerType() + if yyct2 == codecSelferValueTypeMap1234 { + yyl2 := r.ReadMapStart() + if yyl2 == 0 { + z.DecSendContainerState(codecSelfer_containerMapEnd1234) + } else { + x.codecDecodeSelfFromMap(yyl2, d) + } + } else if yyct2 == codecSelferValueTypeArray1234 { + yyl2 := r.ReadArrayStart() + if yyl2 == 0 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) + } else { + x.codecDecodeSelfFromArray(yyl2, d) + } + } else { + panic(codecSelferOnlyMapOrArrayEncodeToStructErr1234) + } + } +} + +func (x *NetworkPolicySpec) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) { + var h codecSelfer1234 + z, r := codec1978.GenHelperDecoder(d) + _, _, _ = h, z, r + var yys3Slc = z.DecScratchBuffer() // default slice to decode into + _ = yys3Slc + var yyhl3 bool = l >= 0 + for yyj3 := 0; ; yyj3++ { + if yyhl3 { + if yyj3 >= l { + break + } + } else { + if r.CheckBreak() { + break + } + } + z.DecSendContainerState(codecSelfer_containerMapKey1234) + yys3Slc = r.DecodeBytes(yys3Slc, true, true) + yys3 := string(yys3Slc) + z.DecSendContainerState(codecSelfer_containerMapValue1234) + switch yys3 { + case "podSelector": + if r.TryDecodeAsNil() { + x.PodSelector = LabelSelector{} + } else { + yyv4 := &x.PodSelector + yyv4.CodecDecodeSelf(d) + } + case "ingress": + if r.TryDecodeAsNil() { + x.Ingress = nil + } else { + yyv5 := &x.Ingress + yym6 := z.DecBinary() + _ = yym6 + if false { + } else { + h.decSliceNetworkPolicyIngressRule((*[]NetworkPolicyIngressRule)(yyv5), d) + } + } + default: + z.DecStructFieldNotFound(-1, yys3) + } // end switch yys3 + } // end for yyj3 + z.DecSendContainerState(codecSelfer_containerMapEnd1234) +} + +func (x *NetworkPolicySpec) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { + var h codecSelfer1234 + z, r := codec1978.GenHelperDecoder(d) + _, _, _ = h, z, r + var yyj7 int + var yyb7 bool + var yyhl7 bool = l >= 0 + yyj7++ + if yyhl7 { + yyb7 = yyj7 > l + } else { + yyb7 = r.CheckBreak() + } + if yyb7 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) + return + } + z.DecSendContainerState(codecSelfer_containerArrayElem1234) + if r.TryDecodeAsNil() { + x.PodSelector = LabelSelector{} + } else { + yyv8 := &x.PodSelector + yyv8.CodecDecodeSelf(d) + } + yyj7++ + if yyhl7 { + yyb7 = yyj7 > l + } else { + yyb7 = r.CheckBreak() + } + if yyb7 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) + return + } + z.DecSendContainerState(codecSelfer_containerArrayElem1234) + if r.TryDecodeAsNil() { + x.Ingress = nil + } else { + yyv9 := &x.Ingress + yym10 := z.DecBinary() + _ = yym10 + if false { + } else { + h.decSliceNetworkPolicyIngressRule((*[]NetworkPolicyIngressRule)(yyv9), d) + } + } + for { + yyj7++ + if yyhl7 { + yyb7 = yyj7 > l + } else { + yyb7 = r.CheckBreak() + } + if yyb7 { + break + } + z.DecSendContainerState(codecSelfer_containerArrayElem1234) + z.DecStructFieldNotFound(yyj7-1, "") + } + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) +} + +func (x *NetworkPolicyIngressRule) CodecEncodeSelf(e *codec1978.Encoder) { + var h codecSelfer1234 + z, r := codec1978.GenHelperEncoder(e) + _, _, _ = h, z, r + if x == nil { + r.EncodeNil() + } else { + yym1 := z.EncBinary() + _ = yym1 + if false { + } else if z.HasExtensions() && z.EncExt(x) { + } else { + yysep2 := !z.EncBinary() + yy2arr2 := z.EncBasicHandle().StructToArray + var yyq2 [2]bool + _, _, _ = yysep2, yyq2, yy2arr2 + const yyr2 bool = false + yyq2[0] = len(x.Ports) != 0 + yyq2[1] = len(x.From) != 0 + var yynn2 int + if yyr2 || yy2arr2 { + r.EncodeArrayStart(2) + } else { + yynn2 = 0 + for _, b := range yyq2 { + if b { + yynn2++ + } + } + r.EncodeMapStart(yynn2) + yynn2 = 0 + } + if yyr2 || yy2arr2 { + z.EncSendContainerState(codecSelfer_containerArrayElem1234) + if yyq2[0] { + if x.Ports == nil { + r.EncodeNil() + } else { + yym4 := z.EncBinary() + _ = yym4 + if false { + } else { + h.encSliceNetworkPolicyPort(([]NetworkPolicyPort)(x.Ports), e) + } + } + } else { + r.EncodeNil() + } + } else { + if yyq2[0] { + z.EncSendContainerState(codecSelfer_containerMapKey1234) + r.EncodeString(codecSelferC_UTF81234, string("ports")) + z.EncSendContainerState(codecSelfer_containerMapValue1234) + if x.Ports == nil { + r.EncodeNil() + } else { + yym5 := z.EncBinary() + _ = yym5 + if false { + } else { + h.encSliceNetworkPolicyPort(([]NetworkPolicyPort)(x.Ports), e) + } + } + } + } + if yyr2 || yy2arr2 { + z.EncSendContainerState(codecSelfer_containerArrayElem1234) + if yyq2[1] { + if x.From == nil { + r.EncodeNil() + } else { + yym7 := z.EncBinary() + _ = yym7 + if false { + } else { + h.encSliceNetworkPolicyPeer(([]NetworkPolicyPeer)(x.From), e) + } + } + } else { + r.EncodeNil() + } + } else { + if yyq2[1] { + z.EncSendContainerState(codecSelfer_containerMapKey1234) + r.EncodeString(codecSelferC_UTF81234, string("from")) + z.EncSendContainerState(codecSelfer_containerMapValue1234) + if x.From == nil { + r.EncodeNil() + } else { + yym8 := z.EncBinary() + _ = yym8 + if false { + } else { + h.encSliceNetworkPolicyPeer(([]NetworkPolicyPeer)(x.From), e) + } + } + } + } + if yyr2 || yy2arr2 { + z.EncSendContainerState(codecSelfer_containerArrayEnd1234) + } else { + z.EncSendContainerState(codecSelfer_containerMapEnd1234) + } + } + } +} + +func (x *NetworkPolicyIngressRule) CodecDecodeSelf(d *codec1978.Decoder) { + var h codecSelfer1234 + z, r := codec1978.GenHelperDecoder(d) + _, _, _ = h, z, r + yym1 := z.DecBinary() + _ = yym1 + if false { + } else if z.HasExtensions() && z.DecExt(x) { + } else { + yyct2 := r.ContainerType() + if yyct2 == codecSelferValueTypeMap1234 { + yyl2 := r.ReadMapStart() + if yyl2 == 0 { + z.DecSendContainerState(codecSelfer_containerMapEnd1234) + } else { + x.codecDecodeSelfFromMap(yyl2, d) + } + } else if yyct2 == codecSelferValueTypeArray1234 { + yyl2 := r.ReadArrayStart() + if yyl2 == 0 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) + } else { + x.codecDecodeSelfFromArray(yyl2, d) + } + } else { + panic(codecSelferOnlyMapOrArrayEncodeToStructErr1234) + } + } +} + +func (x *NetworkPolicyIngressRule) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) { + var h codecSelfer1234 + z, r := codec1978.GenHelperDecoder(d) + _, _, _ = h, z, r + var yys3Slc = z.DecScratchBuffer() // default slice to decode into + _ = yys3Slc + var yyhl3 bool = l >= 0 + for yyj3 := 0; ; yyj3++ { + if yyhl3 { + if yyj3 >= l { + break + } + } else { + if r.CheckBreak() { + break + } + } + z.DecSendContainerState(codecSelfer_containerMapKey1234) + yys3Slc = r.DecodeBytes(yys3Slc, true, true) + yys3 := string(yys3Slc) + z.DecSendContainerState(codecSelfer_containerMapValue1234) + switch yys3 { + case "ports": + if r.TryDecodeAsNil() { + x.Ports = nil + } else { + yyv4 := &x.Ports + yym5 := z.DecBinary() + _ = yym5 + if false { + } else { + h.decSliceNetworkPolicyPort((*[]NetworkPolicyPort)(yyv4), d) + } + } + case "from": + if r.TryDecodeAsNil() { + x.From = nil + } else { + yyv6 := &x.From + yym7 := z.DecBinary() + _ = yym7 + if false { + } else { + h.decSliceNetworkPolicyPeer((*[]NetworkPolicyPeer)(yyv6), d) + } + } + default: + z.DecStructFieldNotFound(-1, yys3) + } // end switch yys3 + } // end for yyj3 + z.DecSendContainerState(codecSelfer_containerMapEnd1234) +} + +func (x *NetworkPolicyIngressRule) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { + var h codecSelfer1234 + z, r := codec1978.GenHelperDecoder(d) + _, _, _ = h, z, r + var yyj8 int + var yyb8 bool + var yyhl8 bool = l >= 0 + yyj8++ + if yyhl8 { + yyb8 = yyj8 > l + } else { + yyb8 = r.CheckBreak() + } + if yyb8 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) + return + } + z.DecSendContainerState(codecSelfer_containerArrayElem1234) + if r.TryDecodeAsNil() { + x.Ports = nil + } else { + yyv9 := &x.Ports + yym10 := z.DecBinary() + _ = yym10 + if false { + } else { + h.decSliceNetworkPolicyPort((*[]NetworkPolicyPort)(yyv9), d) + } + } + yyj8++ + if yyhl8 { + yyb8 = yyj8 > l + } else { + yyb8 = r.CheckBreak() + } + if yyb8 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) + return + } + z.DecSendContainerState(codecSelfer_containerArrayElem1234) + if r.TryDecodeAsNil() { + x.From = nil + } else { + yyv11 := &x.From + yym12 := z.DecBinary() + _ = yym12 + if false { + } else { + h.decSliceNetworkPolicyPeer((*[]NetworkPolicyPeer)(yyv11), d) + } + } + for { + yyj8++ + if yyhl8 { + yyb8 = yyj8 > l + } else { + yyb8 = r.CheckBreak() + } + if yyb8 { + break + } + z.DecSendContainerState(codecSelfer_containerArrayElem1234) + z.DecStructFieldNotFound(yyj8-1, "") + } + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) +} + +func (x *NetworkPolicyPort) CodecEncodeSelf(e *codec1978.Encoder) { + var h codecSelfer1234 + z, r := codec1978.GenHelperEncoder(e) + _, _, _ = h, z, r + if x == nil { + r.EncodeNil() + } else { + yym1 := z.EncBinary() + _ = yym1 + if false { + } else if z.HasExtensions() && z.EncExt(x) { + } else { + yysep2 := !z.EncBinary() + yy2arr2 := z.EncBasicHandle().StructToArray + var yyq2 [2]bool + _, _, _ = yysep2, yyq2, yy2arr2 + const yyr2 bool = false + yyq2[0] = x.Protocol != nil + yyq2[1] = x.Port != nil + var yynn2 int + if yyr2 || yy2arr2 { + r.EncodeArrayStart(2) + } else { + yynn2 = 0 + for _, b := range yyq2 { + if b { + yynn2++ + } + } + r.EncodeMapStart(yynn2) + yynn2 = 0 + } + if yyr2 || yy2arr2 { + z.EncSendContainerState(codecSelfer_containerArrayElem1234) + if yyq2[0] { + if x.Protocol == nil { + r.EncodeNil() + } else { + yy4 := *x.Protocol + yysf5 := &yy4 + yysf5.CodecEncodeSelf(e) + } + } else { + r.EncodeNil() + } + } else { + if yyq2[0] { + z.EncSendContainerState(codecSelfer_containerMapKey1234) + r.EncodeString(codecSelferC_UTF81234, string("protocol")) + z.EncSendContainerState(codecSelfer_containerMapValue1234) + if x.Protocol == nil { + r.EncodeNil() + } else { + yy6 := *x.Protocol + yysf7 := &yy6 + yysf7.CodecEncodeSelf(e) + } + } + } + if yyr2 || yy2arr2 { + z.EncSendContainerState(codecSelfer_containerArrayElem1234) + if yyq2[1] { + if x.Port == nil { + r.EncodeNil() + } else { + yym9 := z.EncBinary() + _ = yym9 + if false { + } else if z.HasExtensions() && z.EncExt(x.Port) { + } else if !yym9 && z.IsJSONHandle() { + z.EncJSONMarshal(x.Port) + } else { + z.EncFallback(x.Port) + } + } + } else { + r.EncodeNil() + } + } else { + if yyq2[1] { + z.EncSendContainerState(codecSelfer_containerMapKey1234) + r.EncodeString(codecSelferC_UTF81234, string("port")) + z.EncSendContainerState(codecSelfer_containerMapValue1234) + if x.Port == nil { + r.EncodeNil() + } else { + yym10 := z.EncBinary() + _ = yym10 + if false { + } else if z.HasExtensions() && z.EncExt(x.Port) { + } else if !yym10 && z.IsJSONHandle() { + z.EncJSONMarshal(x.Port) + } else { + z.EncFallback(x.Port) + } + } + } + } + if yyr2 || yy2arr2 { + z.EncSendContainerState(codecSelfer_containerArrayEnd1234) + } else { + z.EncSendContainerState(codecSelfer_containerMapEnd1234) + } + } + } +} + +func (x *NetworkPolicyPort) CodecDecodeSelf(d *codec1978.Decoder) { + var h codecSelfer1234 + z, r := codec1978.GenHelperDecoder(d) + _, _, _ = h, z, r + yym1 := z.DecBinary() + _ = yym1 + if false { + } else if z.HasExtensions() && z.DecExt(x) { + } else { + yyct2 := r.ContainerType() + if yyct2 == codecSelferValueTypeMap1234 { + yyl2 := r.ReadMapStart() + if yyl2 == 0 { + z.DecSendContainerState(codecSelfer_containerMapEnd1234) + } else { + x.codecDecodeSelfFromMap(yyl2, d) + } + } else if yyct2 == codecSelferValueTypeArray1234 { + yyl2 := r.ReadArrayStart() + if yyl2 == 0 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) + } else { + x.codecDecodeSelfFromArray(yyl2, d) + } + } else { + panic(codecSelferOnlyMapOrArrayEncodeToStructErr1234) + } + } +} + +func (x *NetworkPolicyPort) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) { + var h codecSelfer1234 + z, r := codec1978.GenHelperDecoder(d) + _, _, _ = h, z, r + var yys3Slc = z.DecScratchBuffer() // default slice to decode into + _ = yys3Slc + var yyhl3 bool = l >= 0 + for yyj3 := 0; ; yyj3++ { + if yyhl3 { + if yyj3 >= l { + break + } + } else { + if r.CheckBreak() { + break + } + } + z.DecSendContainerState(codecSelfer_containerMapKey1234) + yys3Slc = r.DecodeBytes(yys3Slc, true, true) + yys3 := string(yys3Slc) + z.DecSendContainerState(codecSelfer_containerMapValue1234) + switch yys3 { + case "protocol": + if r.TryDecodeAsNil() { + if x.Protocol != nil { + x.Protocol = nil + } + } else { + if x.Protocol == nil { + x.Protocol = new(pkg2_v1.Protocol) + } + x.Protocol.CodecDecodeSelf(d) + } + case "port": + if r.TryDecodeAsNil() { + if x.Port != nil { + x.Port = nil + } + } else { + if x.Port == nil { + x.Port = new(pkg5_intstr.IntOrString) + } + yym6 := z.DecBinary() + _ = yym6 + if false { + } else if z.HasExtensions() && z.DecExt(x.Port) { + } else if !yym6 && z.IsJSONHandle() { + z.DecJSONUnmarshal(x.Port) + } else { + z.DecFallback(x.Port, false) + } + } + default: + z.DecStructFieldNotFound(-1, yys3) + } // end switch yys3 + } // end for yyj3 + z.DecSendContainerState(codecSelfer_containerMapEnd1234) +} + +func (x *NetworkPolicyPort) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { + var h codecSelfer1234 + z, r := codec1978.GenHelperDecoder(d) + _, _, _ = h, z, r + var yyj7 int + var yyb7 bool + var yyhl7 bool = l >= 0 + yyj7++ + if yyhl7 { + yyb7 = yyj7 > l + } else { + yyb7 = r.CheckBreak() + } + if yyb7 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) + return + } + z.DecSendContainerState(codecSelfer_containerArrayElem1234) + if r.TryDecodeAsNil() { + if x.Protocol != nil { + x.Protocol = nil + } + } else { + if x.Protocol == nil { + x.Protocol = new(pkg2_v1.Protocol) + } + x.Protocol.CodecDecodeSelf(d) + } + yyj7++ + if yyhl7 { + yyb7 = yyj7 > l + } else { + yyb7 = r.CheckBreak() + } + if yyb7 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) + return + } + z.DecSendContainerState(codecSelfer_containerArrayElem1234) + if r.TryDecodeAsNil() { + if x.Port != nil { + x.Port = nil + } + } else { + if x.Port == nil { + x.Port = new(pkg5_intstr.IntOrString) + } + yym10 := z.DecBinary() + _ = yym10 + if false { + } else if z.HasExtensions() && z.DecExt(x.Port) { + } else if !yym10 && z.IsJSONHandle() { + z.DecJSONUnmarshal(x.Port) + } else { + z.DecFallback(x.Port, false) + } + } + for { + yyj7++ + if yyhl7 { + yyb7 = yyj7 > l + } else { + yyb7 = r.CheckBreak() + } + if yyb7 { + break + } + z.DecSendContainerState(codecSelfer_containerArrayElem1234) + z.DecStructFieldNotFound(yyj7-1, "") + } + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) +} + +func (x *NetworkPolicyPeer) CodecEncodeSelf(e *codec1978.Encoder) { + var h codecSelfer1234 + z, r := codec1978.GenHelperEncoder(e) + _, _, _ = h, z, r + if x == nil { + r.EncodeNil() + } else { + yym1 := z.EncBinary() + _ = yym1 + if false { + } else if z.HasExtensions() && z.EncExt(x) { + } else { + yysep2 := !z.EncBinary() + yy2arr2 := z.EncBasicHandle().StructToArray + var yyq2 [2]bool + _, _, _ = yysep2, yyq2, yy2arr2 + const yyr2 bool = false + yyq2[0] = x.PodSelector != nil + yyq2[1] = x.NamespaceSelector != nil + var yynn2 int + if yyr2 || yy2arr2 { + r.EncodeArrayStart(2) + } else { + yynn2 = 0 + for _, b := range yyq2 { + if b { + yynn2++ + } + } + r.EncodeMapStart(yynn2) + yynn2 = 0 + } + if yyr2 || yy2arr2 { + z.EncSendContainerState(codecSelfer_containerArrayElem1234) + if yyq2[0] { + if x.PodSelector == nil { + r.EncodeNil() + } else { + x.PodSelector.CodecEncodeSelf(e) + } + } else { + r.EncodeNil() + } + } else { + if yyq2[0] { + z.EncSendContainerState(codecSelfer_containerMapKey1234) + r.EncodeString(codecSelferC_UTF81234, string("podSelector")) + z.EncSendContainerState(codecSelfer_containerMapValue1234) + if x.PodSelector == nil { + r.EncodeNil() + } else { + x.PodSelector.CodecEncodeSelf(e) + } + } + } + if yyr2 || yy2arr2 { + z.EncSendContainerState(codecSelfer_containerArrayElem1234) + if yyq2[1] { + if x.NamespaceSelector == nil { + r.EncodeNil() + } else { + x.NamespaceSelector.CodecEncodeSelf(e) + } + } else { + r.EncodeNil() + } + } else { + if yyq2[1] { + z.EncSendContainerState(codecSelfer_containerMapKey1234) + r.EncodeString(codecSelferC_UTF81234, string("namespaceSelector")) + z.EncSendContainerState(codecSelfer_containerMapValue1234) + if x.NamespaceSelector == nil { + r.EncodeNil() + } else { + x.NamespaceSelector.CodecEncodeSelf(e) + } + } + } + if yyr2 || yy2arr2 { + z.EncSendContainerState(codecSelfer_containerArrayEnd1234) + } else { + z.EncSendContainerState(codecSelfer_containerMapEnd1234) + } + } + } +} + +func (x *NetworkPolicyPeer) CodecDecodeSelf(d *codec1978.Decoder) { + var h codecSelfer1234 + z, r := codec1978.GenHelperDecoder(d) + _, _, _ = h, z, r + yym1 := z.DecBinary() + _ = yym1 + if false { + } else if z.HasExtensions() && z.DecExt(x) { + } else { + yyct2 := r.ContainerType() + if yyct2 == codecSelferValueTypeMap1234 { + yyl2 := r.ReadMapStart() + if yyl2 == 0 { + z.DecSendContainerState(codecSelfer_containerMapEnd1234) + } else { + x.codecDecodeSelfFromMap(yyl2, d) + } + } else if yyct2 == codecSelferValueTypeArray1234 { + yyl2 := r.ReadArrayStart() + if yyl2 == 0 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) + } else { + x.codecDecodeSelfFromArray(yyl2, d) + } + } else { + panic(codecSelferOnlyMapOrArrayEncodeToStructErr1234) + } + } +} + +func (x *NetworkPolicyPeer) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) { + var h codecSelfer1234 + z, r := codec1978.GenHelperDecoder(d) + _, _, _ = h, z, r + var yys3Slc = z.DecScratchBuffer() // default slice to decode into + _ = yys3Slc + var yyhl3 bool = l >= 0 + for yyj3 := 0; ; yyj3++ { + if yyhl3 { + if yyj3 >= l { + break + } + } else { + if r.CheckBreak() { + break + } + } + z.DecSendContainerState(codecSelfer_containerMapKey1234) + yys3Slc = r.DecodeBytes(yys3Slc, true, true) + yys3 := string(yys3Slc) + z.DecSendContainerState(codecSelfer_containerMapValue1234) + switch yys3 { + case "podSelector": + if r.TryDecodeAsNil() { + if x.PodSelector != nil { + x.PodSelector = nil + } + } else { + if x.PodSelector == nil { + x.PodSelector = new(LabelSelector) + } + x.PodSelector.CodecDecodeSelf(d) + } + case "namespaceSelector": + if r.TryDecodeAsNil() { + if x.NamespaceSelector != nil { + x.NamespaceSelector = nil + } + } else { + if x.NamespaceSelector == nil { + x.NamespaceSelector = new(LabelSelector) + } + x.NamespaceSelector.CodecDecodeSelf(d) + } + default: + z.DecStructFieldNotFound(-1, yys3) + } // end switch yys3 + } // end for yyj3 + z.DecSendContainerState(codecSelfer_containerMapEnd1234) +} + +func (x *NetworkPolicyPeer) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { + var h codecSelfer1234 + z, r := codec1978.GenHelperDecoder(d) + _, _, _ = h, z, r + var yyj6 int + var yyb6 bool + var yyhl6 bool = l >= 0 + yyj6++ + if yyhl6 { + yyb6 = yyj6 > l + } else { + yyb6 = r.CheckBreak() + } + if yyb6 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) + return + } + z.DecSendContainerState(codecSelfer_containerArrayElem1234) + if r.TryDecodeAsNil() { + if x.PodSelector != nil { + x.PodSelector = nil + } + } else { + if x.PodSelector == nil { + x.PodSelector = new(LabelSelector) + } + x.PodSelector.CodecDecodeSelf(d) + } + yyj6++ + if yyhl6 { + yyb6 = yyj6 > l + } else { + yyb6 = r.CheckBreak() + } + if yyb6 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) + return + } + z.DecSendContainerState(codecSelfer_containerArrayElem1234) + if r.TryDecodeAsNil() { + if x.NamespaceSelector != nil { + x.NamespaceSelector = nil + } + } else { + if x.NamespaceSelector == nil { + x.NamespaceSelector = new(LabelSelector) + } + x.NamespaceSelector.CodecDecodeSelf(d) + } + for { + yyj6++ + if yyhl6 { + yyb6 = yyj6 > l + } else { + yyb6 = r.CheckBreak() + } + if yyb6 { + break + } + z.DecSendContainerState(codecSelfer_containerArrayElem1234) + z.DecStructFieldNotFound(yyj6-1, "") + } + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) +} + +func (x *NetworkPolicyList) CodecEncodeSelf(e *codec1978.Encoder) { + var h codecSelfer1234 + z, r := codec1978.GenHelperEncoder(e) + _, _, _ = h, z, r + if x == nil { + r.EncodeNil() + } else { + yym1 := z.EncBinary() + _ = yym1 + if false { + } else if z.HasExtensions() && z.EncExt(x) { + } else { + yysep2 := !z.EncBinary() + yy2arr2 := z.EncBasicHandle().StructToArray + var yyq2 [4]bool + _, _, _ = yysep2, yyq2, yy2arr2 + const yyr2 bool = false + yyq2[0] = true + yyq2[2] = x.Kind != "" + yyq2[3] = x.APIVersion != "" + var yynn2 int + if yyr2 || yy2arr2 { + r.EncodeArrayStart(4) + } else { + yynn2 = 1 + for _, b := range yyq2 { + if b { + yynn2++ + } + } + r.EncodeMapStart(yynn2) + yynn2 = 0 + } + if yyr2 || yy2arr2 { + z.EncSendContainerState(codecSelfer_containerArrayElem1234) + if yyq2[0] { + yy4 := &x.ListMeta + yym5 := z.EncBinary() + _ = yym5 + if false { + } else if z.HasExtensions() && z.EncExt(yy4) { + } else { + z.EncFallback(yy4) + } + } else { + r.EncodeNil() + } + } else { + if yyq2[0] { + z.EncSendContainerState(codecSelfer_containerMapKey1234) + r.EncodeString(codecSelferC_UTF81234, string("metadata")) + z.EncSendContainerState(codecSelfer_containerMapValue1234) + yy6 := &x.ListMeta + yym7 := z.EncBinary() + _ = yym7 + if false { + } else if z.HasExtensions() && z.EncExt(yy6) { + } else { + z.EncFallback(yy6) + } + } + } + if yyr2 || yy2arr2 { + z.EncSendContainerState(codecSelfer_containerArrayElem1234) + if x.Items == nil { + r.EncodeNil() + } else { + yym9 := z.EncBinary() + _ = yym9 + if false { + } else { + h.encSliceNetworkPolicy(([]NetworkPolicy)(x.Items), e) + } + } + } else { + z.EncSendContainerState(codecSelfer_containerMapKey1234) + r.EncodeString(codecSelferC_UTF81234, string("items")) + z.EncSendContainerState(codecSelfer_containerMapValue1234) + if x.Items == nil { + r.EncodeNil() + } else { + yym10 := z.EncBinary() + _ = yym10 + if false { + } else { + h.encSliceNetworkPolicy(([]NetworkPolicy)(x.Items), e) + } + } + } + if yyr2 || yy2arr2 { + z.EncSendContainerState(codecSelfer_containerArrayElem1234) + if yyq2[2] { + yym12 := z.EncBinary() + _ = yym12 + if false { + } else { + r.EncodeString(codecSelferC_UTF81234, string(x.Kind)) + } + } else { + r.EncodeString(codecSelferC_UTF81234, "") + } + } else { + if yyq2[2] { + z.EncSendContainerState(codecSelfer_containerMapKey1234) + r.EncodeString(codecSelferC_UTF81234, string("kind")) + z.EncSendContainerState(codecSelfer_containerMapValue1234) + yym13 := z.EncBinary() + _ = yym13 + if false { + } else { + r.EncodeString(codecSelferC_UTF81234, string(x.Kind)) + } + } + } + if yyr2 || yy2arr2 { + z.EncSendContainerState(codecSelfer_containerArrayElem1234) + if yyq2[3] { + yym15 := z.EncBinary() + _ = yym15 + if false { + } else { + r.EncodeString(codecSelferC_UTF81234, string(x.APIVersion)) + } + } else { + r.EncodeString(codecSelferC_UTF81234, "") + } + } else { + if yyq2[3] { + z.EncSendContainerState(codecSelfer_containerMapKey1234) + r.EncodeString(codecSelferC_UTF81234, string("apiVersion")) + z.EncSendContainerState(codecSelfer_containerMapValue1234) + yym16 := z.EncBinary() + _ = yym16 + if false { + } else { + r.EncodeString(codecSelferC_UTF81234, string(x.APIVersion)) + } + } + } + if yyr2 || yy2arr2 { + z.EncSendContainerState(codecSelfer_containerArrayEnd1234) + } else { + z.EncSendContainerState(codecSelfer_containerMapEnd1234) + } + } + } +} + +func (x *NetworkPolicyList) CodecDecodeSelf(d *codec1978.Decoder) { + var h codecSelfer1234 + z, r := codec1978.GenHelperDecoder(d) + _, _, _ = h, z, r + yym1 := z.DecBinary() + _ = yym1 + if false { + } else if z.HasExtensions() && z.DecExt(x) { + } else { + yyct2 := r.ContainerType() + if yyct2 == codecSelferValueTypeMap1234 { + yyl2 := r.ReadMapStart() + if yyl2 == 0 { + z.DecSendContainerState(codecSelfer_containerMapEnd1234) + } else { + x.codecDecodeSelfFromMap(yyl2, d) + } + } else if yyct2 == codecSelferValueTypeArray1234 { + yyl2 := r.ReadArrayStart() + if yyl2 == 0 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) + } else { + x.codecDecodeSelfFromArray(yyl2, d) + } + } else { + panic(codecSelferOnlyMapOrArrayEncodeToStructErr1234) + } + } +} + +func (x *NetworkPolicyList) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) { + var h codecSelfer1234 + z, r := codec1978.GenHelperDecoder(d) + _, _, _ = h, z, r + var yys3Slc = z.DecScratchBuffer() // default slice to decode into + _ = yys3Slc + var yyhl3 bool = l >= 0 + for yyj3 := 0; ; yyj3++ { + if yyhl3 { + if yyj3 >= l { + break + } + } else { + if r.CheckBreak() { + break + } + } + z.DecSendContainerState(codecSelfer_containerMapKey1234) + yys3Slc = r.DecodeBytes(yys3Slc, true, true) + yys3 := string(yys3Slc) + z.DecSendContainerState(codecSelfer_containerMapValue1234) + switch yys3 { + case "metadata": + if r.TryDecodeAsNil() { + x.ListMeta = pkg1_unversioned.ListMeta{} + } else { + yyv4 := &x.ListMeta + yym5 := z.DecBinary() + _ = yym5 + if false { + } else if z.HasExtensions() && z.DecExt(yyv4) { + } else { + z.DecFallback(yyv4, false) + } + } + case "items": + if r.TryDecodeAsNil() { + x.Items = nil + } else { + yyv6 := &x.Items + yym7 := z.DecBinary() + _ = yym7 + if false { + } else { + h.decSliceNetworkPolicy((*[]NetworkPolicy)(yyv6), d) + } + } + case "kind": + if r.TryDecodeAsNil() { + x.Kind = "" + } else { + x.Kind = string(r.DecodeString()) + } + case "apiVersion": + if r.TryDecodeAsNil() { + x.APIVersion = "" + } else { + x.APIVersion = string(r.DecodeString()) + } + default: + z.DecStructFieldNotFound(-1, yys3) + } // end switch yys3 + } // end for yyj3 + z.DecSendContainerState(codecSelfer_containerMapEnd1234) +} + +func (x *NetworkPolicyList) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { + var h codecSelfer1234 + z, r := codec1978.GenHelperDecoder(d) + _, _, _ = h, z, r + var yyj10 int + var yyb10 bool + var yyhl10 bool = l >= 0 + yyj10++ + if yyhl10 { + yyb10 = yyj10 > l + } else { + yyb10 = r.CheckBreak() + } + if yyb10 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) + return + } + z.DecSendContainerState(codecSelfer_containerArrayElem1234) + if r.TryDecodeAsNil() { + x.ListMeta = pkg1_unversioned.ListMeta{} + } else { + yyv11 := &x.ListMeta + yym12 := z.DecBinary() + _ = yym12 + if false { + } else if z.HasExtensions() && z.DecExt(yyv11) { + } else { + z.DecFallback(yyv11, false) + } + } + yyj10++ + if yyhl10 { + yyb10 = yyj10 > l + } else { + yyb10 = r.CheckBreak() + } + if yyb10 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) + return + } + z.DecSendContainerState(codecSelfer_containerArrayElem1234) + if r.TryDecodeAsNil() { + x.Items = nil + } else { + yyv13 := &x.Items + yym14 := z.DecBinary() + _ = yym14 + if false { + } else { + h.decSliceNetworkPolicy((*[]NetworkPolicy)(yyv13), d) + } + } + yyj10++ + if yyhl10 { + yyb10 = yyj10 > l + } else { + yyb10 = r.CheckBreak() + } + if yyb10 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) + return + } + z.DecSendContainerState(codecSelfer_containerArrayElem1234) + if r.TryDecodeAsNil() { + x.Kind = "" + } else { + x.Kind = string(r.DecodeString()) + } + yyj10++ + if yyhl10 { + yyb10 = yyj10 > l + } else { + yyb10 = r.CheckBreak() + } + if yyb10 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) + return + } + z.DecSendContainerState(codecSelfer_containerArrayElem1234) + if r.TryDecodeAsNil() { + x.APIVersion = "" + } else { + x.APIVersion = string(r.DecodeString()) + } + for { + yyj10++ + if yyhl10 { + yyb10 = yyj10 > l + } else { + yyb10 = r.CheckBreak() + } + if yyb10 { + break + } + z.DecSendContainerState(codecSelfer_containerArrayElem1234) + z.DecStructFieldNotFound(yyj10-1, "") + } + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) +} + func (x codecSelfer1234) encSliceCustomMetricTarget(v []CustomMetricTarget, e *codec1978.Encoder) { var h codecSelfer1234 z, r := codec1978.GenHelperEncoder(e) @@ -19393,7 +21019,7 @@ func (x codecSelfer1234) decSliceCustomMetricTarget(v *[]CustomMetricTarget, d * yyrg1 := len(yyv1) > 0 yyv21 := yyv1 - yyrl1, yyrt1 = z.DecInferLen(yyl1, z.DecBasicHandle().MaxInitLen, 40) + yyrl1, yyrt1 = z.DecInferLen(yyl1, z.DecBasicHandle().MaxInitLen, 80) if yyrt1 { if yyrl1 <= cap(yyv1) { yyv1 = yyv1[:yyrl1] @@ -19512,7 +21138,7 @@ func (x codecSelfer1234) decSliceCustomMetricCurrentStatus(v *[]CustomMetricCurr yyrg1 := len(yyv1) > 0 yyv21 := yyv1 - yyrl1, yyrt1 = z.DecInferLen(yyl1, z.DecBasicHandle().MaxInitLen, 40) + yyrl1, yyrt1 = z.DecInferLen(yyl1, z.DecBasicHandle().MaxInitLen, 80) if yyrt1 { if yyrl1 <= cap(yyv1) { yyv1 = yyv1[:yyrl1] @@ -19988,7 +21614,7 @@ func (x codecSelfer1234) decSliceDeployment(v *[]Deployment, d *codec1978.Decode yyrg1 := len(yyv1) > 0 yyv21 := yyv1 - yyrl1, yyrt1 = z.DecInferLen(yyl1, z.DecBasicHandle().MaxInitLen, 768) + yyrl1, yyrt1 = z.DecInferLen(yyl1, z.DecBasicHandle().MaxInitLen, 792) if yyrt1 { if yyrl1 <= cap(yyv1) { yyv1 = yyv1[:yyrl1] @@ -20107,7 +21733,7 @@ func (x codecSelfer1234) decSliceDaemonSet(v *[]DaemonSet, d *codec1978.Decoder) yyrg1 := len(yyv1) > 0 yyv21 := yyv1 - yyrl1, yyrt1 = z.DecInferLen(yyl1, z.DecBasicHandle().MaxInitLen, 696) + yyrl1, yyrt1 = z.DecInferLen(yyl1, z.DecBasicHandle().MaxInitLen, 720) if yyrt1 { if yyrl1 <= cap(yyv1) { yyv1 = yyv1[:yyrl1] @@ -20345,7 +21971,7 @@ func (x codecSelfer1234) decSliceJob(v *[]Job, d *codec1978.Decoder) { yyrg1 := len(yyv1) > 0 yyv21 := yyv1 - yyrl1, yyrt1 = z.DecInferLen(yyl1, z.DecBasicHandle().MaxInitLen, 768) + yyrl1, yyrt1 = z.DecInferLen(yyl1, z.DecBasicHandle().MaxInitLen, 792) if yyrt1 { if yyrl1 <= cap(yyv1) { yyv1 = yyv1[:yyrl1] @@ -21178,7 +22804,7 @@ func (x codecSelfer1234) decSliceReplicaSet(v *[]ReplicaSet, d *codec1978.Decode yyrg1 := len(yyv1) > 0 yyv21 := yyv1 - yyrl1, yyrt1 = z.DecInferLen(yyl1, z.DecBasicHandle().MaxInitLen, 704) + yyrl1, yyrt1 = z.DecInferLen(yyl1, z.DecBasicHandle().MaxInitLen, 728) if yyrt1 { if yyrl1 <= cap(yyv1) { yyv1 = yyv1[:yyrl1] @@ -21835,3 +23461,479 @@ func (x codecSelfer1234) decSlicePodSecurityPolicy(v *[]PodSecurityPolicy, d *co *v = yyv1 } } + +func (x codecSelfer1234) encSliceNetworkPolicyIngressRule(v []NetworkPolicyIngressRule, e *codec1978.Encoder) { + var h codecSelfer1234 + z, r := codec1978.GenHelperEncoder(e) + _, _, _ = h, z, r + r.EncodeArrayStart(len(v)) + for _, yyv1 := range v { + z.EncSendContainerState(codecSelfer_containerArrayElem1234) + yy2 := &yyv1 + yy2.CodecEncodeSelf(e) + } + z.EncSendContainerState(codecSelfer_containerArrayEnd1234) +} + +func (x codecSelfer1234) decSliceNetworkPolicyIngressRule(v *[]NetworkPolicyIngressRule, d *codec1978.Decoder) { + var h codecSelfer1234 + z, r := codec1978.GenHelperDecoder(d) + _, _, _ = h, z, r + + yyv1 := *v + yyh1, yyl1 := z.DecSliceHelperStart() + var yyc1 bool + _ = yyc1 + if yyl1 == 0 { + if yyv1 == nil { + yyv1 = []NetworkPolicyIngressRule{} + yyc1 = true + } else if len(yyv1) != 0 { + yyv1 = yyv1[:0] + yyc1 = true + } + } else if yyl1 > 0 { + var yyrr1, yyrl1 int + var yyrt1 bool + _, _ = yyrl1, yyrt1 + yyrr1 = yyl1 // len(yyv1) + if yyl1 > cap(yyv1) { + + yyrg1 := len(yyv1) > 0 + yyv21 := yyv1 + yyrl1, yyrt1 = z.DecInferLen(yyl1, z.DecBasicHandle().MaxInitLen, 48) + if yyrt1 { + if yyrl1 <= cap(yyv1) { + yyv1 = yyv1[:yyrl1] + } else { + yyv1 = make([]NetworkPolicyIngressRule, yyrl1) + } + } else { + yyv1 = make([]NetworkPolicyIngressRule, yyrl1) + } + yyc1 = true + yyrr1 = len(yyv1) + if yyrg1 { + copy(yyv1, yyv21) + } + } else if yyl1 != len(yyv1) { + yyv1 = yyv1[:yyl1] + yyc1 = true + } + yyj1 := 0 + for ; yyj1 < yyrr1; yyj1++ { + yyh1.ElemContainerState(yyj1) + if r.TryDecodeAsNil() { + yyv1[yyj1] = NetworkPolicyIngressRule{} + } else { + yyv2 := &yyv1[yyj1] + yyv2.CodecDecodeSelf(d) + } + + } + if yyrt1 { + for ; yyj1 < yyl1; yyj1++ { + yyv1 = append(yyv1, NetworkPolicyIngressRule{}) + yyh1.ElemContainerState(yyj1) + if r.TryDecodeAsNil() { + yyv1[yyj1] = NetworkPolicyIngressRule{} + } else { + yyv3 := &yyv1[yyj1] + yyv3.CodecDecodeSelf(d) + } + + } + } + + } else { + yyj1 := 0 + for ; !r.CheckBreak(); yyj1++ { + + if yyj1 >= len(yyv1) { + yyv1 = append(yyv1, NetworkPolicyIngressRule{}) // var yyz1 NetworkPolicyIngressRule + yyc1 = true + } + yyh1.ElemContainerState(yyj1) + if yyj1 < len(yyv1) { + if r.TryDecodeAsNil() { + yyv1[yyj1] = NetworkPolicyIngressRule{} + } else { + yyv4 := &yyv1[yyj1] + yyv4.CodecDecodeSelf(d) + } + + } else { + z.DecSwallow() + } + + } + if yyj1 < len(yyv1) { + yyv1 = yyv1[:yyj1] + yyc1 = true + } else if yyj1 == 0 && yyv1 == nil { + yyv1 = []NetworkPolicyIngressRule{} + yyc1 = true + } + } + yyh1.End() + if yyc1 { + *v = yyv1 + } +} + +func (x codecSelfer1234) encSliceNetworkPolicyPort(v []NetworkPolicyPort, e *codec1978.Encoder) { + var h codecSelfer1234 + z, r := codec1978.GenHelperEncoder(e) + _, _, _ = h, z, r + r.EncodeArrayStart(len(v)) + for _, yyv1 := range v { + z.EncSendContainerState(codecSelfer_containerArrayElem1234) + yy2 := &yyv1 + yy2.CodecEncodeSelf(e) + } + z.EncSendContainerState(codecSelfer_containerArrayEnd1234) +} + +func (x codecSelfer1234) decSliceNetworkPolicyPort(v *[]NetworkPolicyPort, d *codec1978.Decoder) { + var h codecSelfer1234 + z, r := codec1978.GenHelperDecoder(d) + _, _, _ = h, z, r + + yyv1 := *v + yyh1, yyl1 := z.DecSliceHelperStart() + var yyc1 bool + _ = yyc1 + if yyl1 == 0 { + if yyv1 == nil { + yyv1 = []NetworkPolicyPort{} + yyc1 = true + } else if len(yyv1) != 0 { + yyv1 = yyv1[:0] + yyc1 = true + } + } else if yyl1 > 0 { + var yyrr1, yyrl1 int + var yyrt1 bool + _, _ = yyrl1, yyrt1 + yyrr1 = yyl1 // len(yyv1) + if yyl1 > cap(yyv1) { + + yyrg1 := len(yyv1) > 0 + yyv21 := yyv1 + yyrl1, yyrt1 = z.DecInferLen(yyl1, z.DecBasicHandle().MaxInitLen, 16) + if yyrt1 { + if yyrl1 <= cap(yyv1) { + yyv1 = yyv1[:yyrl1] + } else { + yyv1 = make([]NetworkPolicyPort, yyrl1) + } + } else { + yyv1 = make([]NetworkPolicyPort, yyrl1) + } + yyc1 = true + yyrr1 = len(yyv1) + if yyrg1 { + copy(yyv1, yyv21) + } + } else if yyl1 != len(yyv1) { + yyv1 = yyv1[:yyl1] + yyc1 = true + } + yyj1 := 0 + for ; yyj1 < yyrr1; yyj1++ { + yyh1.ElemContainerState(yyj1) + if r.TryDecodeAsNil() { + yyv1[yyj1] = NetworkPolicyPort{} + } else { + yyv2 := &yyv1[yyj1] + yyv2.CodecDecodeSelf(d) + } + + } + if yyrt1 { + for ; yyj1 < yyl1; yyj1++ { + yyv1 = append(yyv1, NetworkPolicyPort{}) + yyh1.ElemContainerState(yyj1) + if r.TryDecodeAsNil() { + yyv1[yyj1] = NetworkPolicyPort{} + } else { + yyv3 := &yyv1[yyj1] + yyv3.CodecDecodeSelf(d) + } + + } + } + + } else { + yyj1 := 0 + for ; !r.CheckBreak(); yyj1++ { + + if yyj1 >= len(yyv1) { + yyv1 = append(yyv1, NetworkPolicyPort{}) // var yyz1 NetworkPolicyPort + yyc1 = true + } + yyh1.ElemContainerState(yyj1) + if yyj1 < len(yyv1) { + if r.TryDecodeAsNil() { + yyv1[yyj1] = NetworkPolicyPort{} + } else { + yyv4 := &yyv1[yyj1] + yyv4.CodecDecodeSelf(d) + } + + } else { + z.DecSwallow() + } + + } + if yyj1 < len(yyv1) { + yyv1 = yyv1[:yyj1] + yyc1 = true + } else if yyj1 == 0 && yyv1 == nil { + yyv1 = []NetworkPolicyPort{} + yyc1 = true + } + } + yyh1.End() + if yyc1 { + *v = yyv1 + } +} + +func (x codecSelfer1234) encSliceNetworkPolicyPeer(v []NetworkPolicyPeer, e *codec1978.Encoder) { + var h codecSelfer1234 + z, r := codec1978.GenHelperEncoder(e) + _, _, _ = h, z, r + r.EncodeArrayStart(len(v)) + for _, yyv1 := range v { + z.EncSendContainerState(codecSelfer_containerArrayElem1234) + yy2 := &yyv1 + yy2.CodecEncodeSelf(e) + } + z.EncSendContainerState(codecSelfer_containerArrayEnd1234) +} + +func (x codecSelfer1234) decSliceNetworkPolicyPeer(v *[]NetworkPolicyPeer, d *codec1978.Decoder) { + var h codecSelfer1234 + z, r := codec1978.GenHelperDecoder(d) + _, _, _ = h, z, r + + yyv1 := *v + yyh1, yyl1 := z.DecSliceHelperStart() + var yyc1 bool + _ = yyc1 + if yyl1 == 0 { + if yyv1 == nil { + yyv1 = []NetworkPolicyPeer{} + yyc1 = true + } else if len(yyv1) != 0 { + yyv1 = yyv1[:0] + yyc1 = true + } + } else if yyl1 > 0 { + var yyrr1, yyrl1 int + var yyrt1 bool + _, _ = yyrl1, yyrt1 + yyrr1 = yyl1 // len(yyv1) + if yyl1 > cap(yyv1) { + + yyrg1 := len(yyv1) > 0 + yyv21 := yyv1 + yyrl1, yyrt1 = z.DecInferLen(yyl1, z.DecBasicHandle().MaxInitLen, 16) + if yyrt1 { + if yyrl1 <= cap(yyv1) { + yyv1 = yyv1[:yyrl1] + } else { + yyv1 = make([]NetworkPolicyPeer, yyrl1) + } + } else { + yyv1 = make([]NetworkPolicyPeer, yyrl1) + } + yyc1 = true + yyrr1 = len(yyv1) + if yyrg1 { + copy(yyv1, yyv21) + } + } else if yyl1 != len(yyv1) { + yyv1 = yyv1[:yyl1] + yyc1 = true + } + yyj1 := 0 + for ; yyj1 < yyrr1; yyj1++ { + yyh1.ElemContainerState(yyj1) + if r.TryDecodeAsNil() { + yyv1[yyj1] = NetworkPolicyPeer{} + } else { + yyv2 := &yyv1[yyj1] + yyv2.CodecDecodeSelf(d) + } + + } + if yyrt1 { + for ; yyj1 < yyl1; yyj1++ { + yyv1 = append(yyv1, NetworkPolicyPeer{}) + yyh1.ElemContainerState(yyj1) + if r.TryDecodeAsNil() { + yyv1[yyj1] = NetworkPolicyPeer{} + } else { + yyv3 := &yyv1[yyj1] + yyv3.CodecDecodeSelf(d) + } + + } + } + + } else { + yyj1 := 0 + for ; !r.CheckBreak(); yyj1++ { + + if yyj1 >= len(yyv1) { + yyv1 = append(yyv1, NetworkPolicyPeer{}) // var yyz1 NetworkPolicyPeer + yyc1 = true + } + yyh1.ElemContainerState(yyj1) + if yyj1 < len(yyv1) { + if r.TryDecodeAsNil() { + yyv1[yyj1] = NetworkPolicyPeer{} + } else { + yyv4 := &yyv1[yyj1] + yyv4.CodecDecodeSelf(d) + } + + } else { + z.DecSwallow() + } + + } + if yyj1 < len(yyv1) { + yyv1 = yyv1[:yyj1] + yyc1 = true + } else if yyj1 == 0 && yyv1 == nil { + yyv1 = []NetworkPolicyPeer{} + yyc1 = true + } + } + yyh1.End() + if yyc1 { + *v = yyv1 + } +} + +func (x codecSelfer1234) encSliceNetworkPolicy(v []NetworkPolicy, e *codec1978.Encoder) { + var h codecSelfer1234 + z, r := codec1978.GenHelperEncoder(e) + _, _, _ = h, z, r + r.EncodeArrayStart(len(v)) + for _, yyv1 := range v { + z.EncSendContainerState(codecSelfer_containerArrayElem1234) + yy2 := &yyv1 + yy2.CodecEncodeSelf(e) + } + z.EncSendContainerState(codecSelfer_containerArrayEnd1234) +} + +func (x codecSelfer1234) decSliceNetworkPolicy(v *[]NetworkPolicy, d *codec1978.Decoder) { + var h codecSelfer1234 + z, r := codec1978.GenHelperDecoder(d) + _, _, _ = h, z, r + + yyv1 := *v + yyh1, yyl1 := z.DecSliceHelperStart() + var yyc1 bool + _ = yyc1 + if yyl1 == 0 { + if yyv1 == nil { + yyv1 = []NetworkPolicy{} + yyc1 = true + } else if len(yyv1) != 0 { + yyv1 = yyv1[:0] + yyc1 = true + } + } else if yyl1 > 0 { + var yyrr1, yyrl1 int + var yyrt1 bool + _, _ = yyrl1, yyrt1 + yyrr1 = yyl1 // len(yyv1) + if yyl1 > cap(yyv1) { + + yyrg1 := len(yyv1) > 0 + yyv21 := yyv1 + yyrl1, yyrt1 = z.DecInferLen(yyl1, z.DecBasicHandle().MaxInitLen, 296) + if yyrt1 { + if yyrl1 <= cap(yyv1) { + yyv1 = yyv1[:yyrl1] + } else { + yyv1 = make([]NetworkPolicy, yyrl1) + } + } else { + yyv1 = make([]NetworkPolicy, yyrl1) + } + yyc1 = true + yyrr1 = len(yyv1) + if yyrg1 { + copy(yyv1, yyv21) + } + } else if yyl1 != len(yyv1) { + yyv1 = yyv1[:yyl1] + yyc1 = true + } + yyj1 := 0 + for ; yyj1 < yyrr1; yyj1++ { + yyh1.ElemContainerState(yyj1) + if r.TryDecodeAsNil() { + yyv1[yyj1] = NetworkPolicy{} + } else { + yyv2 := &yyv1[yyj1] + yyv2.CodecDecodeSelf(d) + } + + } + if yyrt1 { + for ; yyj1 < yyl1; yyj1++ { + yyv1 = append(yyv1, NetworkPolicy{}) + yyh1.ElemContainerState(yyj1) + if r.TryDecodeAsNil() { + yyv1[yyj1] = NetworkPolicy{} + } else { + yyv3 := &yyv1[yyj1] + yyv3.CodecDecodeSelf(d) + } + + } + } + + } else { + yyj1 := 0 + for ; !r.CheckBreak(); yyj1++ { + + if yyj1 >= len(yyv1) { + yyv1 = append(yyv1, NetworkPolicy{}) // var yyz1 NetworkPolicy + yyc1 = true + } + yyh1.ElemContainerState(yyj1) + if yyj1 < len(yyv1) { + if r.TryDecodeAsNil() { + yyv1[yyj1] = NetworkPolicy{} + } else { + yyv4 := &yyv1[yyj1] + yyv4.CodecDecodeSelf(d) + } + + } else { + z.DecSwallow() + } + + } + if yyj1 < len(yyv1) { + yyv1 = yyv1[:yyj1] + yyc1 = true + } else if yyj1 == 0 && yyv1 == nil { + yyv1 = []NetworkPolicy{} + yyc1 = true + } + } + yyh1.End() + if yyc1 { + *v = yyv1 + } +} diff --git a/vendor/k8s.io/kubernetes/pkg/apis/extensions/v1beta1/types.go b/vendor/k8s.io/kubernetes/pkg/apis/extensions/v1beta1/types.go index b7a255d6bf..de374615f5 100644 --- a/vendor/k8s.io/kubernetes/pkg/apis/extensions/v1beta1/types.go +++ b/vendor/k8s.io/kubernetes/pkg/apis/extensions/v1beta1/types.go @@ -1102,3 +1102,94 @@ type PodSecurityPolicyList struct { // Items is a list of schema objects. Items []PodSecurityPolicy `json:"items" protobuf:"bytes,2,rep,name=items"` } + +type NetworkPolicy struct { + unversioned.TypeMeta `json:",inline"` + // Standard object's metadata. + // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata + v1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` + + // Specification of the desired behavior for this NetworkPolicy. + Spec NetworkPolicySpec `json:"spec,omitempty" protobuf:"bytes,2,opt,name=spec"` +} + +type NetworkPolicySpec struct { + // Selects the pods to which this NetworkPolicy object applies. The array of ingress rules + // is applied to any pods selected by this field. Multiple network policies can select the + // same set of pods. In this case, the ingress rules for each are combined additively. + // This field is NOT optional and follows standard label selector semantics. + // An empty podSelector matches all pods in this namespace. + PodSelector LabelSelector `json:"podSelector" protobuf:"bytes,1,opt,name=podSelector"` + + // List of ingress rules to be applied to the selected pods. + // Traffic is allowed to a pod if namespace.networkPolicy.ingress.isolation is undefined and cluster policy allows it, + // OR if the traffic source is the pod's local node, + // OR if the traffic matches at least one ingress rule across all of the NetworkPolicy + // objects whose podSelector matches the pod. + // If this field is empty then this NetworkPolicy does not affect ingress isolation. + // If this field is present and contains at least one rule, this policy allows any traffic + // which matches at least one of the ingress rules in this list. + Ingress []NetworkPolicyIngressRule `json:"ingress,omitempty" protobuf:"bytes,2,rep,name=ingress"` +} + +// This NetworkPolicyIngressRule matches traffic if and only if the traffic matches both ports AND from. +type NetworkPolicyIngressRule struct { + // List of ports which should be made accessible on the pods selected for this rule. + // Each item in this list is combined using a logical OR. + // If this field is not provided, this rule matches all ports (traffic not restricted by port). + // If this field is empty, this rule matches no ports (no traffic matches). + // If this field is present and contains at least one item, then this rule allows traffic + // only if the traffic matches at least one port in the list. + // TODO: Update this to be a pointer to slice as soon as auto-generation supports it. + Ports []NetworkPolicyPort `json:"ports,omitempty" protobuf:"bytes,1,rep,name=ports"` + + // List of sources which should be able to access the pods selected for this rule. + // Items in this list are combined using a logical OR operation. + // If this field is not provided, this rule matches all sources (traffic not restricted by source). + // If this field is empty, this rule matches no sources (no traffic matches). + // If this field is present and contains at least on item, this rule allows traffic only if the + // traffic matches at least one item in the from list. + // TODO: Update this to be a pointer to slice as soon as auto-generation supports it. + From []NetworkPolicyPeer `json:"from,omitempty" protobuf:"bytes,2,rep,name=from"` +} + +type NetworkPolicyPort struct { + // Optional. The protocol (TCP or UDP) which traffic must match. + // If not specified, this field defaults to TCP. + Protocol *v1.Protocol `json:"protocol,omitempty" protobuf:"bytes,1,opt,name=protocol,casttype=k8s.io/kubernetes/pkg/api/v1.Protocol"` + + // If specified, the port on the given protocol. This can + // either be a numerical or named port on a pod. If this field is not provided, + // this matches all port names and numbers. + // If present, only traffic on the specified protocol AND port + // will be matched. + Port *intstr.IntOrString `json:"port,omitempty" protobuf:"bytes,2,opt,name=port"` +} + +type NetworkPolicyPeer struct { + // Exactly one of the following must be specified. + + // This is a label selector which selects Pods in this namespace. + // This field follows standard label selector semantics. + // If not provided, this selector selects no pods. + // If present but empty, this selector selects all pods in this namespace. + PodSelector *LabelSelector `json:"podSelector,omitempty" protobuf:"bytes,1,opt,name=podSelector"` + + // Selects Namespaces using cluster scoped-labels. This + // matches all pods in all namespaces selected by this label selector. + // This field follows standard label selector semantics. + // If omited, this selector selects no namespaces. + // If present but empty, this selector selects all namespaces. + NamespaceSelector *LabelSelector `json:"namespaceSelector,omitempty" protobuf:"bytes,2,opt,name=namespaceSelector"` +} + +// Network Policy List is a list of NetworkPolicy objects. +type NetworkPolicyList struct { + unversioned.TypeMeta `json:",inline"` + // Standard list metadata. + // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata + unversioned.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` + + // Items is a list of schema objects. + Items []NetworkPolicy `json:"items" protobuf:"bytes,2,rep,name=items"` +} diff --git a/vendor/k8s.io/kubernetes/pkg/apis/extensions/v1beta1/types_swagger_doc_generated.go b/vendor/k8s.io/kubernetes/pkg/apis/extensions/v1beta1/types_swagger_doc_generated.go index e39e19cefd..c8892f08a4 100644 --- a/vendor/k8s.io/kubernetes/pkg/apis/extensions/v1beta1/types_swagger_doc_generated.go +++ b/vendor/k8s.io/kubernetes/pkg/apis/extensions/v1beta1/types_swagger_doc_generated.go @@ -1,5 +1,5 @@ /* -Copyright 2015 The Kubernetes Authors All rights reserved. +Copyright 2016 The Kubernetes Authors All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -456,6 +456,62 @@ func (ListOptions) SwaggerDoc() map[string]string { return map_ListOptions } +var map_NetworkPolicy = map[string]string{ + "metadata": "Standard object's metadata. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata", + "spec": "Specification of the desired behavior for this NetworkPolicy.", +} + +func (NetworkPolicy) SwaggerDoc() map[string]string { + return map_NetworkPolicy +} + +var map_NetworkPolicyIngressRule = map[string]string{ + "": "This NetworkPolicyIngressRule matches traffic if and only if the traffic matches both ports AND from.", + "ports": "List of ports which should be made accessible on the pods selected for this rule. Each item in this list is combined using a logical OR. If this field is not provided, this rule matches all ports (traffic not restricted by port). If this field is empty, this rule matches no ports (no traffic matches). If this field is present and contains at least one item, then this rule allows traffic only if the traffic matches at least one port in the list.", + "from": "List of sources which should be able to access the pods selected for this rule. Items in this list are combined using a logical OR operation. If this field is not provided, this rule matches all sources (traffic not restricted by source). If this field is empty, this rule matches no sources (no traffic matches). If this field is present and contains at least on item, this rule allows traffic only if the traffic matches at least one item in the from list.", +} + +func (NetworkPolicyIngressRule) SwaggerDoc() map[string]string { + return map_NetworkPolicyIngressRule +} + +var map_NetworkPolicyList = map[string]string{ + "": "Network Policy List is a list of NetworkPolicy objects.", + "metadata": "Standard list metadata. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata", + "items": "Items is a list of schema objects.", +} + +func (NetworkPolicyList) SwaggerDoc() map[string]string { + return map_NetworkPolicyList +} + +var map_NetworkPolicyPeer = map[string]string{ + "podSelector": "This is a label selector which selects Pods in this namespace. This field follows standard label selector semantics. If not provided, this selector selects no pods. If present but empty, this selector selects all pods in this namespace.", + "namespaceSelector": "Selects Namespaces using cluster scoped-labels. This matches all pods in all namespaces selected by this label selector. This field follows standard label selector semantics. If omited, this selector selects no namespaces. If present but empty, this selector selects all namespaces.", +} + +func (NetworkPolicyPeer) SwaggerDoc() map[string]string { + return map_NetworkPolicyPeer +} + +var map_NetworkPolicyPort = map[string]string{ + "protocol": "Optional. The protocol (TCP or UDP) which traffic must match. If not specified, this field defaults to TCP.", + "port": "If specified, the port on the given protocol. This can either be a numerical or named port on a pod. If this field is not provided, this matches all port names and numbers. If present, only traffic on the specified protocol AND port will be matched.", +} + +func (NetworkPolicyPort) SwaggerDoc() map[string]string { + return map_NetworkPolicyPort +} + +var map_NetworkPolicySpec = map[string]string{ + "podSelector": "Selects the pods to which this NetworkPolicy object applies. The array of ingress rules is applied to any pods selected by this field. Multiple network policies can select the same set of pods. In this case, the ingress rules for each are combined additively. This field is NOT optional and follows standard label selector semantics. An empty podSelector matches all pods in this namespace.", + "ingress": "List of ingress rules to be applied to the selected pods. Traffic is allowed to a pod if namespace.networkPolicy.ingress.isolation is undefined and cluster policy allows it, OR if the traffic source is the pod's local node, OR if the traffic matches at least one ingress rule across all of the NetworkPolicy objects whose podSelector matches the pod. If this field is empty then this NetworkPolicy does not affect ingress isolation. If this field is present and contains at least one rule, this policy allows any traffic which matches at least one of the ingress rules in this list.", +} + +func (NetworkPolicySpec) SwaggerDoc() map[string]string { + return map_NetworkPolicySpec +} + var map_PodSecurityPolicy = map[string]string{ "": "Pod Security Policy governs the ability to make requests that affect the Security Context that will be applied to a pod and container.", "metadata": "Standard object's metadata. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata", diff --git a/vendor/k8s.io/kubernetes/pkg/apis/extensions/validation/validation.go b/vendor/k8s.io/kubernetes/pkg/apis/extensions/validation/validation.go index 4ef1e7ff00..1d251e897f 100644 --- a/vendor/k8s.io/kubernetes/pkg/apis/extensions/validation/validation.go +++ b/vendor/k8s.io/kubernetes/pkg/apis/extensions/validation/validation.go @@ -19,6 +19,7 @@ package validation import ( "fmt" "net" + "reflect" "regexp" "strconv" "strings" @@ -43,8 +44,21 @@ func ValidateThirdPartyResourceUpdate(update, old *extensions.ThirdPartyResource return allErrs } -func ValidateThirdPartyResourceName(name string, prefix bool) (bool, string) { - return apivalidation.NameIsDNSSubdomain(name, prefix) +func ValidateThirdPartyResourceName(name string, prefix bool) []string { + // Make sure it's a valid DNS subdomain + if msgs := apivalidation.NameIsDNSSubdomain(name, prefix); len(msgs) != 0 { + return msgs + } + + // Make sure it's at least three segments (kind + two-segment group name) + if !prefix { + parts := strings.Split(name, ".") + if len(parts) < 3 { + return []string{"must be at least three segments long: .."} + } + } + + return nil } func ValidateThirdPartyResource(obj *extensions.ThirdPartyResource) field.ErrorList { @@ -56,6 +70,10 @@ func ValidateThirdPartyResource(obj *extensions.ThirdPartyResource) field.ErrorL version := &obj.Versions[ix] if len(version.Name) == 0 { allErrs = append(allErrs, field.Invalid(field.NewPath("versions").Index(ix).Child("name"), version, "must not be empty")) + } else { + for _, msg := range validation.IsDNS1123Label(version.Name) { + allErrs = append(allErrs, field.Invalid(field.NewPath("versions").Index(ix).Child("name"), version, msg)) + } } if versions.Has(version.Name) { allErrs = append(allErrs, field.Duplicate(field.NewPath("versions").Index(ix).Child("name"), version)) @@ -122,14 +140,10 @@ func ValidateDaemonSetSpec(spec *extensions.DaemonSetSpec, fldPath *field.Path) // ValidateDaemonSetName can be used to check whether the given daemon set name is valid. // Prefix indicates this name will be used as part of generation, in which case // trailing dashes are allowed. -func ValidateDaemonSetName(name string, prefix bool) (bool, string) { - return apivalidation.NameIsDNSSubdomain(name, prefix) -} +var ValidateDaemonSetName = apivalidation.NameIsDNSSubdomain // Validates that the given name can be used as a deployment name. -func ValidateDeploymentName(name string, prefix bool) (bool, string) { - return apivalidation.NameIsDNSSubdomain(name, prefix) -} +var ValidateDeploymentName = apivalidation.NameIsDNSSubdomain func ValidatePositiveIntOrPercent(intOrPercent intstr.IntOrString, fldPath *field.Path) field.ErrorList { allErrs := field.ErrorList{} @@ -275,15 +289,11 @@ func ValidateDeploymentRollback(obj *extensions.DeploymentRollback) field.ErrorL } func ValidateThirdPartyResourceDataUpdate(update, old *extensions.ThirdPartyResourceData) field.ErrorList { - return ValidateThirdPartyResourceData(update) + return apivalidation.ValidateObjectMetaUpdate(&update.ObjectMeta, &old.ObjectMeta, field.NewPath("metadata")) } func ValidateThirdPartyResourceData(obj *extensions.ThirdPartyResourceData) field.ErrorList { - allErrs := field.ErrorList{} - if len(obj.Name) == 0 { - allErrs = append(allErrs, field.Required(field.NewPath("name"), "")) - } - return allErrs + return apivalidation.ValidateObjectMeta(&obj.ObjectMeta, true, apivalidation.NameIsDNSLabel, field.NewPath("metadata")) } // ValidateIngress tests if required fields in the Ingress are set. @@ -294,9 +304,7 @@ func ValidateIngress(ingress *extensions.Ingress) field.ErrorList { } // ValidateIngressName validates that the given name can be used as an Ingress name. -func ValidateIngressName(name string, prefix bool) (bool, string) { - return apivalidation.NameIsDNSSubdomain(name, prefix) -} +var ValidateIngressName = apivalidation.NameIsDNSSubdomain func validateIngressTLS(spec *extensions.IngressSpec, fldPath *field.Path) field.ErrorList { allErrs := field.ErrorList{} @@ -346,8 +354,8 @@ func validateIngressRules(IngressRules []extensions.IngressRule, fldPath *field. if len(ih.Host) > 0 { // TODO: Ports and ips are allowed in the host part of a url // according to RFC 3986, consider allowing them. - if valid, errMsg := apivalidation.NameIsDNSSubdomain(ih.Host, false); !valid { - allErrs = append(allErrs, field.Invalid(fldPath.Index(i).Child("host"), ih.Host, errMsg)) + for _, msg := range validation.IsDNS1123Subdomain(ih.Host) { + allErrs = append(allErrs, field.Invalid(fldPath.Index(i).Child("host"), ih.Host, msg)) } if isIP := (net.ParseIP(ih.Host) != nil); isIP { allErrs = append(allErrs, field.Invalid(fldPath.Index(i).Child("host"), ih.Host, "must be a DNS name, not an IP address")) @@ -402,12 +410,14 @@ func validateIngressBackend(backend *extensions.IngressBackend, fldPath *field.P // All backends must reference a single local service by name, and a single service port by name or number. if len(backend.ServiceName) == 0 { return append(allErrs, field.Required(fldPath.Child("serviceName"), "")) - } else if ok, errMsg := apivalidation.ValidateServiceName(backend.ServiceName, false); !ok { - allErrs = append(allErrs, field.Invalid(fldPath.Child("serviceName"), backend.ServiceName, errMsg)) + } else { + for _, msg := range apivalidation.ValidateServiceName(backend.ServiceName, false) { + allErrs = append(allErrs, field.Invalid(fldPath.Child("serviceName"), backend.ServiceName, msg)) + } } if backend.ServicePort.Type == intstr.String { - if !validation.IsDNS1123Label(backend.ServicePort.StrVal) { - allErrs = append(allErrs, field.Invalid(fldPath.Child("servicePort"), backend.ServicePort.StrVal, apivalidation.DNS1123LabelErrorMsg)) + for _, msg := range validation.IsDNS1123Label(backend.ServicePort.StrVal) { + allErrs = append(allErrs, field.Invalid(fldPath.Child("servicePort"), backend.ServicePort.StrVal, msg)) } if !validation.IsValidPortName(backend.ServicePort.StrVal) { allErrs = append(allErrs, field.Invalid(fldPath.Child("servicePort"), backend.ServicePort.StrVal, apivalidation.PortNameErrorMsg)) @@ -433,9 +443,7 @@ func ValidateScale(scale *extensions.Scale) field.ErrorList { // name is valid. // Prefix indicates this name will be used as part of generation, in which case // trailing dashes are allowed. -func ValidateReplicaSetName(name string, prefix bool) (bool, string) { - return apivalidation.NameIsDNSSubdomain(name, prefix) -} +var ValidateReplicaSetName = apivalidation.NameIsDNSSubdomain // ValidateReplicaSet tests if required fields in the ReplicaSet are set. func ValidateReplicaSet(rs *extensions.ReplicaSet) field.ErrorList { @@ -515,9 +523,7 @@ func ValidatePodTemplateSpecForReplicaSet(template *api.PodTemplateSpec, selecto // pod security policy name is valid. // Prefix indicates this name will be used as part of generation, in which case // trailing dashes are allowed. -func ValidatePodSecurityPolicyName(name string, prefix bool) (bool, string) { - return apivalidation.NameIsDNSSubdomain(name, prefix) -} +var ValidatePodSecurityPolicyName = apivalidation.NameIsDNSSubdomain func ValidatePodSecurityPolicy(psp *extensions.PodSecurityPolicy) field.ErrorList { allErrs := field.ErrorList{} @@ -676,3 +682,58 @@ func ValidatePodSecurityPolicyUpdate(old *extensions.PodSecurityPolicy, new *ext allErrs = append(allErrs, ValidatePodSecurityPolicySpec(&new.Spec, field.NewPath("spec"))...) return allErrs } + +// ValidateNetworkPolicyName can be used to check whether the given networkpolicy +// name is valid. +func ValidateNetworkPolicyName(name string, prefix bool) []string { + return apivalidation.NameIsDNSSubdomain(name, prefix) +} + +// ValidateNetworkPolicySpec tests if required fields in the networkpolicy spec are set. +func ValidateNetworkPolicySpec(spec *extensions.NetworkPolicySpec, fldPath *field.Path) field.ErrorList { + allErrs := field.ErrorList{} + allErrs = append(allErrs, unversionedvalidation.ValidateLabelSelector(&spec.PodSelector, fldPath.Child("podSelector"))...) + + // Validate ingress rules. + for _, i := range spec.Ingress { + // TODO: Update From to be a pointer to slice as soon as auto-generation supports it. + for _, f := range i.From { + numFroms := 0 + allErrs := field.ErrorList{} + if f.PodSelector != nil { + numFroms++ + allErrs = append(allErrs, unversionedvalidation.ValidateLabelSelector(f.PodSelector, fldPath.Child("podSelector"))...) + } + if f.NamespaceSelector != nil { + if numFroms > 0 { + allErrs = append(allErrs, field.Forbidden(fldPath, "may not specify more than 1 from type")) + } else { + numFroms++ + allErrs = append(allErrs, unversionedvalidation.ValidateLabelSelector(f.NamespaceSelector, fldPath.Child("namespaces"))...) + } + } + + if numFroms == 0 { + // At least one of PodSelector and NamespaceSelector must be defined. + allErrs = append(allErrs, field.Required(fldPath, "must specify a from type")) + } + } + } + return allErrs +} + +// ValidateNetworkPolicy validates a networkpolicy. +func ValidateNetworkPolicy(np *extensions.NetworkPolicy) field.ErrorList { + allErrs := apivalidation.ValidateObjectMeta(&np.ObjectMeta, true, ValidateNetworkPolicyName, field.NewPath("metadata")) + allErrs = append(allErrs, ValidateNetworkPolicySpec(&np.Spec, field.NewPath("spec"))...) + return allErrs +} + +// ValidateNetworkPolicyUpdate tests if an update to a NetworkPolicy is valid. +func ValidateNetworkPolicyUpdate(np, oldNP *extensions.NetworkPolicy) field.ErrorList { + allErrs := field.ErrorList{} + if !reflect.DeepEqual(np, oldNP) { + allErrs = append(allErrs, field.Forbidden(field.NewPath("spec"), "updates to networkpolicy spec are forbidden.")) + } + return allErrs +} diff --git a/vendor/k8s.io/kubernetes/pkg/apis/metrics/types.generated.go b/vendor/k8s.io/kubernetes/pkg/apis/metrics/types.generated.go index ecf3e8b36f..17eedfd974 100644 --- a/vendor/k8s.io/kubernetes/pkg/apis/metrics/types.generated.go +++ b/vendor/k8s.io/kubernetes/pkg/apis/metrics/types.generated.go @@ -1,5 +1,5 @@ /* -Copyright 2015 The Kubernetes Authors All rights reserved. +Copyright 2016 The Kubernetes Authors All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/vendor/k8s.io/kubernetes/pkg/apis/metrics/v1alpha1/types.generated.go b/vendor/k8s.io/kubernetes/pkg/apis/metrics/v1alpha1/types.generated.go index 2e6d2f3c18..e4f3f9db46 100644 --- a/vendor/k8s.io/kubernetes/pkg/apis/metrics/v1alpha1/types.generated.go +++ b/vendor/k8s.io/kubernetes/pkg/apis/metrics/v1alpha1/types.generated.go @@ -1,5 +1,5 @@ /* -Copyright 2015 The Kubernetes Authors All rights reserved. +Copyright 2016 The Kubernetes Authors All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/vendor/k8s.io/kubernetes/pkg/apis/policy/deep_copy_generated.go b/vendor/k8s.io/kubernetes/pkg/apis/policy/deep_copy_generated.go index 9b067a0df9..390e4b4a7b 100644 --- a/vendor/k8s.io/kubernetes/pkg/apis/policy/deep_copy_generated.go +++ b/vendor/k8s.io/kubernetes/pkg/apis/policy/deep_copy_generated.go @@ -30,6 +30,7 @@ import ( func init() { if err := api.Scheme.AddGeneratedDeepCopyFuncs( DeepCopy_policy_PodDisruptionBudget, + DeepCopy_policy_PodDisruptionBudgetList, DeepCopy_policy_PodDisruptionBudgetSpec, DeepCopy_policy_PodDisruptionBudgetStatus, ); err != nil { @@ -54,6 +55,27 @@ func DeepCopy_policy_PodDisruptionBudget(in PodDisruptionBudget, out *PodDisrupt return nil } +func DeepCopy_policy_PodDisruptionBudgetList(in PodDisruptionBudgetList, out *PodDisruptionBudgetList, c *conversion.Cloner) error { + if err := unversioned.DeepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + return err + } + if err := unversioned.DeepCopy_unversioned_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { + return err + } + if in.Items != nil { + in, out := in.Items, &out.Items + *out = make([]PodDisruptionBudget, len(in)) + for i := range in { + if err := DeepCopy_policy_PodDisruptionBudget(in[i], &(*out)[i], c); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + func DeepCopy_policy_PodDisruptionBudgetSpec(in PodDisruptionBudgetSpec, out *PodDisruptionBudgetSpec, c *conversion.Cloner) error { if err := intstr.DeepCopy_intstr_IntOrString(in.MinAvailable, &out.MinAvailable, c); err != nil { return err diff --git a/vendor/k8s.io/kubernetes/pkg/apis/policy/register.go b/vendor/k8s.io/kubernetes/pkg/apis/policy/register.go index 842541f547..7aa010a0f3 100644 --- a/vendor/k8s.io/kubernetes/pkg/apis/policy/register.go +++ b/vendor/k8s.io/kubernetes/pkg/apis/policy/register.go @@ -47,7 +47,9 @@ func addKnownTypes(scheme *runtime.Scheme) { // TODO this gets cleaned up when the types are fixed scheme.AddKnownTypes(SchemeGroupVersion, &PodDisruptionBudget{}, + &PodDisruptionBudgetList{}, ) } -func (obj *PodDisruptionBudget) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta } +func (obj *PodDisruptionBudget) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta } +func (obj *PodDisruptionBudgetList) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta } diff --git a/vendor/k8s.io/kubernetes/pkg/apis/policy/types.generated.go b/vendor/k8s.io/kubernetes/pkg/apis/policy/types.generated.go index 9d1ab75fbf..08be370f15 100644 --- a/vendor/k8s.io/kubernetes/pkg/apis/policy/types.generated.go +++ b/vendor/k8s.io/kubernetes/pkg/apis/policy/types.generated.go @@ -1,5 +1,5 @@ /* -Copyright 2015 The Kubernetes Authors All rights reserved. +Copyright 2016 The Kubernetes Authors All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -975,3 +975,466 @@ func (x *PodDisruptionBudget) codecDecodeSelfFromArray(l int, d *codec1978.Decod } z.DecSendContainerState(codecSelfer_containerArrayEnd1234) } + +func (x *PodDisruptionBudgetList) CodecEncodeSelf(e *codec1978.Encoder) { + var h codecSelfer1234 + z, r := codec1978.GenHelperEncoder(e) + _, _, _ = h, z, r + if x == nil { + r.EncodeNil() + } else { + yym1 := z.EncBinary() + _ = yym1 + if false { + } else if z.HasExtensions() && z.EncExt(x) { + } else { + yysep2 := !z.EncBinary() + yy2arr2 := z.EncBasicHandle().StructToArray + var yyq2 [4]bool + _, _, _ = yysep2, yyq2, yy2arr2 + const yyr2 bool = false + yyq2[0] = true + yyq2[2] = x.Kind != "" + yyq2[3] = x.APIVersion != "" + var yynn2 int + if yyr2 || yy2arr2 { + r.EncodeArrayStart(4) + } else { + yynn2 = 1 + for _, b := range yyq2 { + if b { + yynn2++ + } + } + r.EncodeMapStart(yynn2) + yynn2 = 0 + } + if yyr2 || yy2arr2 { + z.EncSendContainerState(codecSelfer_containerArrayElem1234) + if yyq2[0] { + yy4 := &x.ListMeta + yym5 := z.EncBinary() + _ = yym5 + if false { + } else if z.HasExtensions() && z.EncExt(yy4) { + } else { + z.EncFallback(yy4) + } + } else { + r.EncodeNil() + } + } else { + if yyq2[0] { + z.EncSendContainerState(codecSelfer_containerMapKey1234) + r.EncodeString(codecSelferC_UTF81234, string("metadata")) + z.EncSendContainerState(codecSelfer_containerMapValue1234) + yy6 := &x.ListMeta + yym7 := z.EncBinary() + _ = yym7 + if false { + } else if z.HasExtensions() && z.EncExt(yy6) { + } else { + z.EncFallback(yy6) + } + } + } + if yyr2 || yy2arr2 { + z.EncSendContainerState(codecSelfer_containerArrayElem1234) + if x.Items == nil { + r.EncodeNil() + } else { + yym9 := z.EncBinary() + _ = yym9 + if false { + } else { + h.encSlicePodDisruptionBudget(([]PodDisruptionBudget)(x.Items), e) + } + } + } else { + z.EncSendContainerState(codecSelfer_containerMapKey1234) + r.EncodeString(codecSelferC_UTF81234, string("items")) + z.EncSendContainerState(codecSelfer_containerMapValue1234) + if x.Items == nil { + r.EncodeNil() + } else { + yym10 := z.EncBinary() + _ = yym10 + if false { + } else { + h.encSlicePodDisruptionBudget(([]PodDisruptionBudget)(x.Items), e) + } + } + } + if yyr2 || yy2arr2 { + z.EncSendContainerState(codecSelfer_containerArrayElem1234) + if yyq2[2] { + yym12 := z.EncBinary() + _ = yym12 + if false { + } else { + r.EncodeString(codecSelferC_UTF81234, string(x.Kind)) + } + } else { + r.EncodeString(codecSelferC_UTF81234, "") + } + } else { + if yyq2[2] { + z.EncSendContainerState(codecSelfer_containerMapKey1234) + r.EncodeString(codecSelferC_UTF81234, string("kind")) + z.EncSendContainerState(codecSelfer_containerMapValue1234) + yym13 := z.EncBinary() + _ = yym13 + if false { + } else { + r.EncodeString(codecSelferC_UTF81234, string(x.Kind)) + } + } + } + if yyr2 || yy2arr2 { + z.EncSendContainerState(codecSelfer_containerArrayElem1234) + if yyq2[3] { + yym15 := z.EncBinary() + _ = yym15 + if false { + } else { + r.EncodeString(codecSelferC_UTF81234, string(x.APIVersion)) + } + } else { + r.EncodeString(codecSelferC_UTF81234, "") + } + } else { + if yyq2[3] { + z.EncSendContainerState(codecSelfer_containerMapKey1234) + r.EncodeString(codecSelferC_UTF81234, string("apiVersion")) + z.EncSendContainerState(codecSelfer_containerMapValue1234) + yym16 := z.EncBinary() + _ = yym16 + if false { + } else { + r.EncodeString(codecSelferC_UTF81234, string(x.APIVersion)) + } + } + } + if yyr2 || yy2arr2 { + z.EncSendContainerState(codecSelfer_containerArrayEnd1234) + } else { + z.EncSendContainerState(codecSelfer_containerMapEnd1234) + } + } + } +} + +func (x *PodDisruptionBudgetList) CodecDecodeSelf(d *codec1978.Decoder) { + var h codecSelfer1234 + z, r := codec1978.GenHelperDecoder(d) + _, _, _ = h, z, r + yym1 := z.DecBinary() + _ = yym1 + if false { + } else if z.HasExtensions() && z.DecExt(x) { + } else { + yyct2 := r.ContainerType() + if yyct2 == codecSelferValueTypeMap1234 { + yyl2 := r.ReadMapStart() + if yyl2 == 0 { + z.DecSendContainerState(codecSelfer_containerMapEnd1234) + } else { + x.codecDecodeSelfFromMap(yyl2, d) + } + } else if yyct2 == codecSelferValueTypeArray1234 { + yyl2 := r.ReadArrayStart() + if yyl2 == 0 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) + } else { + x.codecDecodeSelfFromArray(yyl2, d) + } + } else { + panic(codecSelferOnlyMapOrArrayEncodeToStructErr1234) + } + } +} + +func (x *PodDisruptionBudgetList) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) { + var h codecSelfer1234 + z, r := codec1978.GenHelperDecoder(d) + _, _, _ = h, z, r + var yys3Slc = z.DecScratchBuffer() // default slice to decode into + _ = yys3Slc + var yyhl3 bool = l >= 0 + for yyj3 := 0; ; yyj3++ { + if yyhl3 { + if yyj3 >= l { + break + } + } else { + if r.CheckBreak() { + break + } + } + z.DecSendContainerState(codecSelfer_containerMapKey1234) + yys3Slc = r.DecodeBytes(yys3Slc, true, true) + yys3 := string(yys3Slc) + z.DecSendContainerState(codecSelfer_containerMapValue1234) + switch yys3 { + case "metadata": + if r.TryDecodeAsNil() { + x.ListMeta = pkg2_unversioned.ListMeta{} + } else { + yyv4 := &x.ListMeta + yym5 := z.DecBinary() + _ = yym5 + if false { + } else if z.HasExtensions() && z.DecExt(yyv4) { + } else { + z.DecFallback(yyv4, false) + } + } + case "items": + if r.TryDecodeAsNil() { + x.Items = nil + } else { + yyv6 := &x.Items + yym7 := z.DecBinary() + _ = yym7 + if false { + } else { + h.decSlicePodDisruptionBudget((*[]PodDisruptionBudget)(yyv6), d) + } + } + case "kind": + if r.TryDecodeAsNil() { + x.Kind = "" + } else { + x.Kind = string(r.DecodeString()) + } + case "apiVersion": + if r.TryDecodeAsNil() { + x.APIVersion = "" + } else { + x.APIVersion = string(r.DecodeString()) + } + default: + z.DecStructFieldNotFound(-1, yys3) + } // end switch yys3 + } // end for yyj3 + z.DecSendContainerState(codecSelfer_containerMapEnd1234) +} + +func (x *PodDisruptionBudgetList) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { + var h codecSelfer1234 + z, r := codec1978.GenHelperDecoder(d) + _, _, _ = h, z, r + var yyj10 int + var yyb10 bool + var yyhl10 bool = l >= 0 + yyj10++ + if yyhl10 { + yyb10 = yyj10 > l + } else { + yyb10 = r.CheckBreak() + } + if yyb10 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) + return + } + z.DecSendContainerState(codecSelfer_containerArrayElem1234) + if r.TryDecodeAsNil() { + x.ListMeta = pkg2_unversioned.ListMeta{} + } else { + yyv11 := &x.ListMeta + yym12 := z.DecBinary() + _ = yym12 + if false { + } else if z.HasExtensions() && z.DecExt(yyv11) { + } else { + z.DecFallback(yyv11, false) + } + } + yyj10++ + if yyhl10 { + yyb10 = yyj10 > l + } else { + yyb10 = r.CheckBreak() + } + if yyb10 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) + return + } + z.DecSendContainerState(codecSelfer_containerArrayElem1234) + if r.TryDecodeAsNil() { + x.Items = nil + } else { + yyv13 := &x.Items + yym14 := z.DecBinary() + _ = yym14 + if false { + } else { + h.decSlicePodDisruptionBudget((*[]PodDisruptionBudget)(yyv13), d) + } + } + yyj10++ + if yyhl10 { + yyb10 = yyj10 > l + } else { + yyb10 = r.CheckBreak() + } + if yyb10 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) + return + } + z.DecSendContainerState(codecSelfer_containerArrayElem1234) + if r.TryDecodeAsNil() { + x.Kind = "" + } else { + x.Kind = string(r.DecodeString()) + } + yyj10++ + if yyhl10 { + yyb10 = yyj10 > l + } else { + yyb10 = r.CheckBreak() + } + if yyb10 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) + return + } + z.DecSendContainerState(codecSelfer_containerArrayElem1234) + if r.TryDecodeAsNil() { + x.APIVersion = "" + } else { + x.APIVersion = string(r.DecodeString()) + } + for { + yyj10++ + if yyhl10 { + yyb10 = yyj10 > l + } else { + yyb10 = r.CheckBreak() + } + if yyb10 { + break + } + z.DecSendContainerState(codecSelfer_containerArrayElem1234) + z.DecStructFieldNotFound(yyj10-1, "") + } + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) +} + +func (x codecSelfer1234) encSlicePodDisruptionBudget(v []PodDisruptionBudget, e *codec1978.Encoder) { + var h codecSelfer1234 + z, r := codec1978.GenHelperEncoder(e) + _, _, _ = h, z, r + r.EncodeArrayStart(len(v)) + for _, yyv1 := range v { + z.EncSendContainerState(codecSelfer_containerArrayElem1234) + yy2 := &yyv1 + yy2.CodecEncodeSelf(e) + } + z.EncSendContainerState(codecSelfer_containerArrayEnd1234) +} + +func (x codecSelfer1234) decSlicePodDisruptionBudget(v *[]PodDisruptionBudget, d *codec1978.Decoder) { + var h codecSelfer1234 + z, r := codec1978.GenHelperDecoder(d) + _, _, _ = h, z, r + + yyv1 := *v + yyh1, yyl1 := z.DecSliceHelperStart() + var yyc1 bool + _ = yyc1 + if yyl1 == 0 { + if yyv1 == nil { + yyv1 = []PodDisruptionBudget{} + yyc1 = true + } else if len(yyv1) != 0 { + yyv1 = yyv1[:0] + yyc1 = true + } + } else if yyl1 > 0 { + var yyrr1, yyrl1 int + var yyrt1 bool + _, _ = yyrl1, yyrt1 + yyrr1 = yyl1 // len(yyv1) + if yyl1 > cap(yyv1) { + + yyrg1 := len(yyv1) > 0 + yyv21 := yyv1 + yyrl1, yyrt1 = z.DecInferLen(yyl1, z.DecBasicHandle().MaxInitLen, 296) + if yyrt1 { + if yyrl1 <= cap(yyv1) { + yyv1 = yyv1[:yyrl1] + } else { + yyv1 = make([]PodDisruptionBudget, yyrl1) + } + } else { + yyv1 = make([]PodDisruptionBudget, yyrl1) + } + yyc1 = true + yyrr1 = len(yyv1) + if yyrg1 { + copy(yyv1, yyv21) + } + } else if yyl1 != len(yyv1) { + yyv1 = yyv1[:yyl1] + yyc1 = true + } + yyj1 := 0 + for ; yyj1 < yyrr1; yyj1++ { + yyh1.ElemContainerState(yyj1) + if r.TryDecodeAsNil() { + yyv1[yyj1] = PodDisruptionBudget{} + } else { + yyv2 := &yyv1[yyj1] + yyv2.CodecDecodeSelf(d) + } + + } + if yyrt1 { + for ; yyj1 < yyl1; yyj1++ { + yyv1 = append(yyv1, PodDisruptionBudget{}) + yyh1.ElemContainerState(yyj1) + if r.TryDecodeAsNil() { + yyv1[yyj1] = PodDisruptionBudget{} + } else { + yyv3 := &yyv1[yyj1] + yyv3.CodecDecodeSelf(d) + } + + } + } + + } else { + yyj1 := 0 + for ; !r.CheckBreak(); yyj1++ { + + if yyj1 >= len(yyv1) { + yyv1 = append(yyv1, PodDisruptionBudget{}) // var yyz1 PodDisruptionBudget + yyc1 = true + } + yyh1.ElemContainerState(yyj1) + if yyj1 < len(yyv1) { + if r.TryDecodeAsNil() { + yyv1[yyj1] = PodDisruptionBudget{} + } else { + yyv4 := &yyv1[yyj1] + yyv4.CodecDecodeSelf(d) + } + + } else { + z.DecSwallow() + } + + } + if yyj1 < len(yyv1) { + yyv1 = yyv1[:yyj1] + yyc1 = true + } else if yyj1 == 0 && yyv1 == nil { + yyv1 = []PodDisruptionBudget{} + yyc1 = true + } + } + yyh1.End() + if yyc1 { + *v = yyv1 + } +} diff --git a/vendor/k8s.io/kubernetes/pkg/apis/policy/types.go b/vendor/k8s.io/kubernetes/pkg/apis/policy/types.go index d3851cb9a1..2ecf41bcff 100644 --- a/vendor/k8s.io/kubernetes/pkg/apis/policy/types.go +++ b/vendor/k8s.io/kubernetes/pkg/apis/policy/types.go @@ -61,3 +61,10 @@ type PodDisruptionBudget struct { // Most recently observed status of the PodDisruptionBudget. Status PodDisruptionBudgetStatus `json:"status,omitempty"` } + +// PodDisruptionBudgetList is a collection of PodDisruptionBudgets. +type PodDisruptionBudgetList struct { + unversioned.TypeMeta `json:",inline"` + unversioned.ListMeta `json:"metadata,omitempty"` + Items []PodDisruptionBudget `json:"items"` +} diff --git a/vendor/k8s.io/kubernetes/pkg/apis/policy/v1alpha1/conversion_generated.go b/vendor/k8s.io/kubernetes/pkg/apis/policy/v1alpha1/conversion_generated.go index 17e4f4c9c6..bc9ee703fd 100644 --- a/vendor/k8s.io/kubernetes/pkg/apis/policy/v1alpha1/conversion_generated.go +++ b/vendor/k8s.io/kubernetes/pkg/apis/policy/v1alpha1/conversion_generated.go @@ -31,6 +31,8 @@ func init() { if err := api.Scheme.AddGeneratedConversionFuncs( Convert_v1alpha1_PodDisruptionBudget_To_policy_PodDisruptionBudget, Convert_policy_PodDisruptionBudget_To_v1alpha1_PodDisruptionBudget, + Convert_v1alpha1_PodDisruptionBudgetList_To_policy_PodDisruptionBudgetList, + Convert_policy_PodDisruptionBudgetList_To_v1alpha1_PodDisruptionBudgetList, Convert_v1alpha1_PodDisruptionBudgetSpec_To_policy_PodDisruptionBudgetSpec, Convert_policy_PodDisruptionBudgetSpec_To_v1alpha1_PodDisruptionBudgetSpec, Convert_v1alpha1_PodDisruptionBudgetStatus_To_policy_PodDisruptionBudgetStatus, @@ -83,6 +85,56 @@ func Convert_policy_PodDisruptionBudget_To_v1alpha1_PodDisruptionBudget(in *poli return autoConvert_policy_PodDisruptionBudget_To_v1alpha1_PodDisruptionBudget(in, out, s) } +func autoConvert_v1alpha1_PodDisruptionBudgetList_To_policy_PodDisruptionBudgetList(in *PodDisruptionBudgetList, out *policy.PodDisruptionBudgetList, s conversion.Scope) error { + if err := api.Convert_unversioned_TypeMeta_To_unversioned_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + return err + } + if err := api.Convert_unversioned_ListMeta_To_unversioned_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + return err + } + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]policy.PodDisruptionBudget, len(*in)) + for i := range *in { + if err := Convert_v1alpha1_PodDisruptionBudget_To_policy_PodDisruptionBudget(&(*in)[i], &(*out)[i], s); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +func Convert_v1alpha1_PodDisruptionBudgetList_To_policy_PodDisruptionBudgetList(in *PodDisruptionBudgetList, out *policy.PodDisruptionBudgetList, s conversion.Scope) error { + return autoConvert_v1alpha1_PodDisruptionBudgetList_To_policy_PodDisruptionBudgetList(in, out, s) +} + +func autoConvert_policy_PodDisruptionBudgetList_To_v1alpha1_PodDisruptionBudgetList(in *policy.PodDisruptionBudgetList, out *PodDisruptionBudgetList, s conversion.Scope) error { + if err := api.Convert_unversioned_TypeMeta_To_unversioned_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil { + return err + } + if err := api.Convert_unversioned_ListMeta_To_unversioned_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil { + return err + } + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]PodDisruptionBudget, len(*in)) + for i := range *in { + if err := Convert_policy_PodDisruptionBudget_To_v1alpha1_PodDisruptionBudget(&(*in)[i], &(*out)[i], s); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +func Convert_policy_PodDisruptionBudgetList_To_v1alpha1_PodDisruptionBudgetList(in *policy.PodDisruptionBudgetList, out *PodDisruptionBudgetList, s conversion.Scope) error { + return autoConvert_policy_PodDisruptionBudgetList_To_v1alpha1_PodDisruptionBudgetList(in, out, s) +} + func autoConvert_v1alpha1_PodDisruptionBudgetSpec_To_policy_PodDisruptionBudgetSpec(in *PodDisruptionBudgetSpec, out *policy.PodDisruptionBudgetSpec, s conversion.Scope) error { if err := api.Convert_intstr_IntOrString_To_intstr_IntOrString(&in.MinAvailable, &out.MinAvailable, s); err != nil { return err diff --git a/vendor/k8s.io/kubernetes/pkg/apis/policy/v1alpha1/deep_copy_generated.go b/vendor/k8s.io/kubernetes/pkg/apis/policy/v1alpha1/deep_copy_generated.go index 307fa7d4d9..74680aff84 100644 --- a/vendor/k8s.io/kubernetes/pkg/apis/policy/v1alpha1/deep_copy_generated.go +++ b/vendor/k8s.io/kubernetes/pkg/apis/policy/v1alpha1/deep_copy_generated.go @@ -31,6 +31,7 @@ import ( func init() { if err := api.Scheme.AddGeneratedDeepCopyFuncs( DeepCopy_v1alpha1_PodDisruptionBudget, + DeepCopy_v1alpha1_PodDisruptionBudgetList, DeepCopy_v1alpha1_PodDisruptionBudgetSpec, DeepCopy_v1alpha1_PodDisruptionBudgetStatus, ); err != nil { @@ -55,6 +56,27 @@ func DeepCopy_v1alpha1_PodDisruptionBudget(in PodDisruptionBudget, out *PodDisru return nil } +func DeepCopy_v1alpha1_PodDisruptionBudgetList(in PodDisruptionBudgetList, out *PodDisruptionBudgetList, c *conversion.Cloner) error { + if err := unversioned.DeepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil { + return err + } + if err := unversioned.DeepCopy_unversioned_ListMeta(in.ListMeta, &out.ListMeta, c); err != nil { + return err + } + if in.Items != nil { + in, out := in.Items, &out.Items + *out = make([]PodDisruptionBudget, len(in)) + for i := range in { + if err := DeepCopy_v1alpha1_PodDisruptionBudget(in[i], &(*out)[i], c); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + func DeepCopy_v1alpha1_PodDisruptionBudgetSpec(in PodDisruptionBudgetSpec, out *PodDisruptionBudgetSpec, c *conversion.Cloner) error { if err := intstr.DeepCopy_intstr_IntOrString(in.MinAvailable, &out.MinAvailable, c); err != nil { return err diff --git a/vendor/k8s.io/kubernetes/pkg/apis/policy/v1alpha1/generated.pb.go b/vendor/k8s.io/kubernetes/pkg/apis/policy/v1alpha1/generated.pb.go index 9ebd5b3625..867a6b0a6d 100644 --- a/vendor/k8s.io/kubernetes/pkg/apis/policy/v1alpha1/generated.pb.go +++ b/vendor/k8s.io/kubernetes/pkg/apis/policy/v1alpha1/generated.pb.go @@ -26,6 +26,7 @@ limitations under the License. It has these top-level messages: PodDisruptionBudget + PodDisruptionBudgetList PodDisruptionBudgetSpec PodDisruptionBudgetStatus */ @@ -48,6 +49,10 @@ func (m *PodDisruptionBudget) Reset() { *m = PodDisruptionBudget{} } func (m *PodDisruptionBudget) String() string { return proto.CompactTextString(m) } func (*PodDisruptionBudget) ProtoMessage() {} +func (m *PodDisruptionBudgetList) Reset() { *m = PodDisruptionBudgetList{} } +func (m *PodDisruptionBudgetList) String() string { return proto.CompactTextString(m) } +func (*PodDisruptionBudgetList) ProtoMessage() {} + func (m *PodDisruptionBudgetSpec) Reset() { *m = PodDisruptionBudgetSpec{} } func (m *PodDisruptionBudgetSpec) String() string { return proto.CompactTextString(m) } func (*PodDisruptionBudgetSpec) ProtoMessage() {} @@ -58,6 +63,7 @@ func (*PodDisruptionBudgetStatus) ProtoMessage() {} func init() { proto.RegisterType((*PodDisruptionBudget)(nil), "k8s.io.kubernetes.pkg.apis.policy.v1alpha1.PodDisruptionBudget") + proto.RegisterType((*PodDisruptionBudgetList)(nil), "k8s.io.kubernetes.pkg.apis.policy.v1alpha1.PodDisruptionBudgetList") proto.RegisterType((*PodDisruptionBudgetSpec)(nil), "k8s.io.kubernetes.pkg.apis.policy.v1alpha1.PodDisruptionBudgetSpec") proto.RegisterType((*PodDisruptionBudgetStatus)(nil), "k8s.io.kubernetes.pkg.apis.policy.v1alpha1.PodDisruptionBudgetStatus") } @@ -103,6 +109,44 @@ func (m *PodDisruptionBudget) MarshalTo(data []byte) (int, error) { return i, nil } +func (m *PodDisruptionBudgetList) Marshal() (data []byte, err error) { + size := m.Size() + data = make([]byte, size) + n, err := m.MarshalTo(data) + if err != nil { + return nil, err + } + return data[:n], nil +} + +func (m *PodDisruptionBudgetList) MarshalTo(data []byte) (int, error) { + var i int + _ = i + var l int + _ = l + data[i] = 0xa + i++ + i = encodeVarintGenerated(data, i, uint64(m.ListMeta.Size())) + n4, err := m.ListMeta.MarshalTo(data[i:]) + if err != nil { + return 0, err + } + i += n4 + if len(m.Items) > 0 { + for _, msg := range m.Items { + data[i] = 0x12 + i++ + i = encodeVarintGenerated(data, i, uint64(msg.Size())) + n, err := msg.MarshalTo(data[i:]) + if err != nil { + return 0, err + } + i += n + } + } + return i, nil +} + func (m *PodDisruptionBudgetSpec) Marshal() (data []byte, err error) { size := m.Size() data = make([]byte, size) @@ -121,20 +165,20 @@ func (m *PodDisruptionBudgetSpec) MarshalTo(data []byte) (int, error) { data[i] = 0xa i++ i = encodeVarintGenerated(data, i, uint64(m.MinAvailable.Size())) - n4, err := m.MinAvailable.MarshalTo(data[i:]) + n5, err := m.MinAvailable.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n4 + i += n5 if m.Selector != nil { data[i] = 0x12 i++ i = encodeVarintGenerated(data, i, uint64(m.Selector.Size())) - n5, err := m.Selector.MarshalTo(data[i:]) + n6, err := m.Selector.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n5 + i += n6 } return i, nil } @@ -213,6 +257,20 @@ func (m *PodDisruptionBudget) Size() (n int) { return n } +func (m *PodDisruptionBudgetList) Size() (n int) { + var l int + _ = l + l = m.ListMeta.Size() + n += 1 + l + sovGenerated(uint64(l)) + if len(m.Items) > 0 { + for _, e := range m.Items { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } + return n +} + func (m *PodDisruptionBudgetSpec) Size() (n int) { var l int _ = l @@ -388,6 +446,117 @@ func (m *PodDisruptionBudget) Unmarshal(data []byte) error { } return nil } +func (m *PodDisruptionBudgetList) Unmarshal(data []byte) error { + l := len(data) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: PodDisruptionBudgetList: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: PodDisruptionBudgetList: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ListMeta", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.ListMeta.Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Items", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Items = append(m.Items, PodDisruptionBudget{}) + if err := m.Items[len(m.Items)-1].Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(data[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func (m *PodDisruptionBudgetSpec) Unmarshal(data []byte) error { l := len(data) iNdEx := 0 diff --git a/vendor/k8s.io/kubernetes/pkg/apis/policy/v1alpha1/generated.proto b/vendor/k8s.io/kubernetes/pkg/apis/policy/v1alpha1/generated.proto index 24e3298531..866d0ae578 100644 --- a/vendor/k8s.io/kubernetes/pkg/apis/policy/v1alpha1/generated.proto +++ b/vendor/k8s.io/kubernetes/pkg/apis/policy/v1alpha1/generated.proto @@ -41,6 +41,13 @@ message PodDisruptionBudget { optional PodDisruptionBudgetStatus status = 3; } +// PodDisruptionBudgetList is a collection of PodDisruptionBudgets. +message PodDisruptionBudgetList { + optional k8s.io.kubernetes.pkg.api.unversioned.ListMeta metadata = 1; + + repeated PodDisruptionBudget items = 2; +} + // PodDisruptionBudgetSpec is a description of a PodDisruptionBudget. message PodDisruptionBudgetSpec { // The minimum number of pods that must be available simultaneously. This diff --git a/vendor/k8s.io/kubernetes/pkg/apis/policy/v1alpha1/register.go b/vendor/k8s.io/kubernetes/pkg/apis/policy/v1alpha1/register.go index 2181e6c2c0..ac41af6dbf 100644 --- a/vendor/k8s.io/kubernetes/pkg/apis/policy/v1alpha1/register.go +++ b/vendor/k8s.io/kubernetes/pkg/apis/policy/v1alpha1/register.go @@ -40,9 +40,11 @@ func AddToScheme(scheme *runtime.Scheme) { func addKnownTypes(scheme *runtime.Scheme) { scheme.AddKnownTypes(SchemeGroupVersion, &PodDisruptionBudget{}, + &PodDisruptionBudgetList{}, ) // Add the watch version that applies versionedwatch.AddToGroupVersion(scheme, SchemeGroupVersion) } -func (obj *PodDisruptionBudget) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta } +func (obj *PodDisruptionBudget) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta } +func (obj *PodDisruptionBudgetList) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta } diff --git a/vendor/k8s.io/kubernetes/pkg/apis/policy/v1alpha1/types.generated.go b/vendor/k8s.io/kubernetes/pkg/apis/policy/v1alpha1/types.generated.go index b7bfc50276..7ed4308bcc 100644 --- a/vendor/k8s.io/kubernetes/pkg/apis/policy/v1alpha1/types.generated.go +++ b/vendor/k8s.io/kubernetes/pkg/apis/policy/v1alpha1/types.generated.go @@ -1,5 +1,5 @@ /* -Copyright 2015 The Kubernetes Authors All rights reserved. +Copyright 2016 The Kubernetes Authors All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -975,3 +975,466 @@ func (x *PodDisruptionBudget) codecDecodeSelfFromArray(l int, d *codec1978.Decod } z.DecSendContainerState(codecSelfer_containerArrayEnd1234) } + +func (x *PodDisruptionBudgetList) CodecEncodeSelf(e *codec1978.Encoder) { + var h codecSelfer1234 + z, r := codec1978.GenHelperEncoder(e) + _, _, _ = h, z, r + if x == nil { + r.EncodeNil() + } else { + yym1 := z.EncBinary() + _ = yym1 + if false { + } else if z.HasExtensions() && z.EncExt(x) { + } else { + yysep2 := !z.EncBinary() + yy2arr2 := z.EncBasicHandle().StructToArray + var yyq2 [4]bool + _, _, _ = yysep2, yyq2, yy2arr2 + const yyr2 bool = false + yyq2[0] = true + yyq2[2] = x.Kind != "" + yyq2[3] = x.APIVersion != "" + var yynn2 int + if yyr2 || yy2arr2 { + r.EncodeArrayStart(4) + } else { + yynn2 = 1 + for _, b := range yyq2 { + if b { + yynn2++ + } + } + r.EncodeMapStart(yynn2) + yynn2 = 0 + } + if yyr2 || yy2arr2 { + z.EncSendContainerState(codecSelfer_containerArrayElem1234) + if yyq2[0] { + yy4 := &x.ListMeta + yym5 := z.EncBinary() + _ = yym5 + if false { + } else if z.HasExtensions() && z.EncExt(yy4) { + } else { + z.EncFallback(yy4) + } + } else { + r.EncodeNil() + } + } else { + if yyq2[0] { + z.EncSendContainerState(codecSelfer_containerMapKey1234) + r.EncodeString(codecSelferC_UTF81234, string("metadata")) + z.EncSendContainerState(codecSelfer_containerMapValue1234) + yy6 := &x.ListMeta + yym7 := z.EncBinary() + _ = yym7 + if false { + } else if z.HasExtensions() && z.EncExt(yy6) { + } else { + z.EncFallback(yy6) + } + } + } + if yyr2 || yy2arr2 { + z.EncSendContainerState(codecSelfer_containerArrayElem1234) + if x.Items == nil { + r.EncodeNil() + } else { + yym9 := z.EncBinary() + _ = yym9 + if false { + } else { + h.encSlicePodDisruptionBudget(([]PodDisruptionBudget)(x.Items), e) + } + } + } else { + z.EncSendContainerState(codecSelfer_containerMapKey1234) + r.EncodeString(codecSelferC_UTF81234, string("items")) + z.EncSendContainerState(codecSelfer_containerMapValue1234) + if x.Items == nil { + r.EncodeNil() + } else { + yym10 := z.EncBinary() + _ = yym10 + if false { + } else { + h.encSlicePodDisruptionBudget(([]PodDisruptionBudget)(x.Items), e) + } + } + } + if yyr2 || yy2arr2 { + z.EncSendContainerState(codecSelfer_containerArrayElem1234) + if yyq2[2] { + yym12 := z.EncBinary() + _ = yym12 + if false { + } else { + r.EncodeString(codecSelferC_UTF81234, string(x.Kind)) + } + } else { + r.EncodeString(codecSelferC_UTF81234, "") + } + } else { + if yyq2[2] { + z.EncSendContainerState(codecSelfer_containerMapKey1234) + r.EncodeString(codecSelferC_UTF81234, string("kind")) + z.EncSendContainerState(codecSelfer_containerMapValue1234) + yym13 := z.EncBinary() + _ = yym13 + if false { + } else { + r.EncodeString(codecSelferC_UTF81234, string(x.Kind)) + } + } + } + if yyr2 || yy2arr2 { + z.EncSendContainerState(codecSelfer_containerArrayElem1234) + if yyq2[3] { + yym15 := z.EncBinary() + _ = yym15 + if false { + } else { + r.EncodeString(codecSelferC_UTF81234, string(x.APIVersion)) + } + } else { + r.EncodeString(codecSelferC_UTF81234, "") + } + } else { + if yyq2[3] { + z.EncSendContainerState(codecSelfer_containerMapKey1234) + r.EncodeString(codecSelferC_UTF81234, string("apiVersion")) + z.EncSendContainerState(codecSelfer_containerMapValue1234) + yym16 := z.EncBinary() + _ = yym16 + if false { + } else { + r.EncodeString(codecSelferC_UTF81234, string(x.APIVersion)) + } + } + } + if yyr2 || yy2arr2 { + z.EncSendContainerState(codecSelfer_containerArrayEnd1234) + } else { + z.EncSendContainerState(codecSelfer_containerMapEnd1234) + } + } + } +} + +func (x *PodDisruptionBudgetList) CodecDecodeSelf(d *codec1978.Decoder) { + var h codecSelfer1234 + z, r := codec1978.GenHelperDecoder(d) + _, _, _ = h, z, r + yym1 := z.DecBinary() + _ = yym1 + if false { + } else if z.HasExtensions() && z.DecExt(x) { + } else { + yyct2 := r.ContainerType() + if yyct2 == codecSelferValueTypeMap1234 { + yyl2 := r.ReadMapStart() + if yyl2 == 0 { + z.DecSendContainerState(codecSelfer_containerMapEnd1234) + } else { + x.codecDecodeSelfFromMap(yyl2, d) + } + } else if yyct2 == codecSelferValueTypeArray1234 { + yyl2 := r.ReadArrayStart() + if yyl2 == 0 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) + } else { + x.codecDecodeSelfFromArray(yyl2, d) + } + } else { + panic(codecSelferOnlyMapOrArrayEncodeToStructErr1234) + } + } +} + +func (x *PodDisruptionBudgetList) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) { + var h codecSelfer1234 + z, r := codec1978.GenHelperDecoder(d) + _, _, _ = h, z, r + var yys3Slc = z.DecScratchBuffer() // default slice to decode into + _ = yys3Slc + var yyhl3 bool = l >= 0 + for yyj3 := 0; ; yyj3++ { + if yyhl3 { + if yyj3 >= l { + break + } + } else { + if r.CheckBreak() { + break + } + } + z.DecSendContainerState(codecSelfer_containerMapKey1234) + yys3Slc = r.DecodeBytes(yys3Slc, true, true) + yys3 := string(yys3Slc) + z.DecSendContainerState(codecSelfer_containerMapValue1234) + switch yys3 { + case "metadata": + if r.TryDecodeAsNil() { + x.ListMeta = pkg2_unversioned.ListMeta{} + } else { + yyv4 := &x.ListMeta + yym5 := z.DecBinary() + _ = yym5 + if false { + } else if z.HasExtensions() && z.DecExt(yyv4) { + } else { + z.DecFallback(yyv4, false) + } + } + case "items": + if r.TryDecodeAsNil() { + x.Items = nil + } else { + yyv6 := &x.Items + yym7 := z.DecBinary() + _ = yym7 + if false { + } else { + h.decSlicePodDisruptionBudget((*[]PodDisruptionBudget)(yyv6), d) + } + } + case "kind": + if r.TryDecodeAsNil() { + x.Kind = "" + } else { + x.Kind = string(r.DecodeString()) + } + case "apiVersion": + if r.TryDecodeAsNil() { + x.APIVersion = "" + } else { + x.APIVersion = string(r.DecodeString()) + } + default: + z.DecStructFieldNotFound(-1, yys3) + } // end switch yys3 + } // end for yyj3 + z.DecSendContainerState(codecSelfer_containerMapEnd1234) +} + +func (x *PodDisruptionBudgetList) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { + var h codecSelfer1234 + z, r := codec1978.GenHelperDecoder(d) + _, _, _ = h, z, r + var yyj10 int + var yyb10 bool + var yyhl10 bool = l >= 0 + yyj10++ + if yyhl10 { + yyb10 = yyj10 > l + } else { + yyb10 = r.CheckBreak() + } + if yyb10 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) + return + } + z.DecSendContainerState(codecSelfer_containerArrayElem1234) + if r.TryDecodeAsNil() { + x.ListMeta = pkg2_unversioned.ListMeta{} + } else { + yyv11 := &x.ListMeta + yym12 := z.DecBinary() + _ = yym12 + if false { + } else if z.HasExtensions() && z.DecExt(yyv11) { + } else { + z.DecFallback(yyv11, false) + } + } + yyj10++ + if yyhl10 { + yyb10 = yyj10 > l + } else { + yyb10 = r.CheckBreak() + } + if yyb10 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) + return + } + z.DecSendContainerState(codecSelfer_containerArrayElem1234) + if r.TryDecodeAsNil() { + x.Items = nil + } else { + yyv13 := &x.Items + yym14 := z.DecBinary() + _ = yym14 + if false { + } else { + h.decSlicePodDisruptionBudget((*[]PodDisruptionBudget)(yyv13), d) + } + } + yyj10++ + if yyhl10 { + yyb10 = yyj10 > l + } else { + yyb10 = r.CheckBreak() + } + if yyb10 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) + return + } + z.DecSendContainerState(codecSelfer_containerArrayElem1234) + if r.TryDecodeAsNil() { + x.Kind = "" + } else { + x.Kind = string(r.DecodeString()) + } + yyj10++ + if yyhl10 { + yyb10 = yyj10 > l + } else { + yyb10 = r.CheckBreak() + } + if yyb10 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) + return + } + z.DecSendContainerState(codecSelfer_containerArrayElem1234) + if r.TryDecodeAsNil() { + x.APIVersion = "" + } else { + x.APIVersion = string(r.DecodeString()) + } + for { + yyj10++ + if yyhl10 { + yyb10 = yyj10 > l + } else { + yyb10 = r.CheckBreak() + } + if yyb10 { + break + } + z.DecSendContainerState(codecSelfer_containerArrayElem1234) + z.DecStructFieldNotFound(yyj10-1, "") + } + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) +} + +func (x codecSelfer1234) encSlicePodDisruptionBudget(v []PodDisruptionBudget, e *codec1978.Encoder) { + var h codecSelfer1234 + z, r := codec1978.GenHelperEncoder(e) + _, _, _ = h, z, r + r.EncodeArrayStart(len(v)) + for _, yyv1 := range v { + z.EncSendContainerState(codecSelfer_containerArrayElem1234) + yy2 := &yyv1 + yy2.CodecEncodeSelf(e) + } + z.EncSendContainerState(codecSelfer_containerArrayEnd1234) +} + +func (x codecSelfer1234) decSlicePodDisruptionBudget(v *[]PodDisruptionBudget, d *codec1978.Decoder) { + var h codecSelfer1234 + z, r := codec1978.GenHelperDecoder(d) + _, _, _ = h, z, r + + yyv1 := *v + yyh1, yyl1 := z.DecSliceHelperStart() + var yyc1 bool + _ = yyc1 + if yyl1 == 0 { + if yyv1 == nil { + yyv1 = []PodDisruptionBudget{} + yyc1 = true + } else if len(yyv1) != 0 { + yyv1 = yyv1[:0] + yyc1 = true + } + } else if yyl1 > 0 { + var yyrr1, yyrl1 int + var yyrt1 bool + _, _ = yyrl1, yyrt1 + yyrr1 = yyl1 // len(yyv1) + if yyl1 > cap(yyv1) { + + yyrg1 := len(yyv1) > 0 + yyv21 := yyv1 + yyrl1, yyrt1 = z.DecInferLen(yyl1, z.DecBasicHandle().MaxInitLen, 296) + if yyrt1 { + if yyrl1 <= cap(yyv1) { + yyv1 = yyv1[:yyrl1] + } else { + yyv1 = make([]PodDisruptionBudget, yyrl1) + } + } else { + yyv1 = make([]PodDisruptionBudget, yyrl1) + } + yyc1 = true + yyrr1 = len(yyv1) + if yyrg1 { + copy(yyv1, yyv21) + } + } else if yyl1 != len(yyv1) { + yyv1 = yyv1[:yyl1] + yyc1 = true + } + yyj1 := 0 + for ; yyj1 < yyrr1; yyj1++ { + yyh1.ElemContainerState(yyj1) + if r.TryDecodeAsNil() { + yyv1[yyj1] = PodDisruptionBudget{} + } else { + yyv2 := &yyv1[yyj1] + yyv2.CodecDecodeSelf(d) + } + + } + if yyrt1 { + for ; yyj1 < yyl1; yyj1++ { + yyv1 = append(yyv1, PodDisruptionBudget{}) + yyh1.ElemContainerState(yyj1) + if r.TryDecodeAsNil() { + yyv1[yyj1] = PodDisruptionBudget{} + } else { + yyv3 := &yyv1[yyj1] + yyv3.CodecDecodeSelf(d) + } + + } + } + + } else { + yyj1 := 0 + for ; !r.CheckBreak(); yyj1++ { + + if yyj1 >= len(yyv1) { + yyv1 = append(yyv1, PodDisruptionBudget{}) // var yyz1 PodDisruptionBudget + yyc1 = true + } + yyh1.ElemContainerState(yyj1) + if yyj1 < len(yyv1) { + if r.TryDecodeAsNil() { + yyv1[yyj1] = PodDisruptionBudget{} + } else { + yyv4 := &yyv1[yyj1] + yyv4.CodecDecodeSelf(d) + } + + } else { + z.DecSwallow() + } + + } + if yyj1 < len(yyv1) { + yyv1 = yyv1[:yyj1] + yyc1 = true + } else if yyj1 == 0 && yyv1 == nil { + yyv1 = []PodDisruptionBudget{} + yyc1 = true + } + } + yyh1.End() + if yyc1 { + *v = yyv1 + } +} diff --git a/vendor/k8s.io/kubernetes/pkg/apis/policy/v1alpha1/types.go b/vendor/k8s.io/kubernetes/pkg/apis/policy/v1alpha1/types.go index baf5d9e164..1f3265ae27 100644 --- a/vendor/k8s.io/kubernetes/pkg/apis/policy/v1alpha1/types.go +++ b/vendor/k8s.io/kubernetes/pkg/apis/policy/v1alpha1/types.go @@ -62,3 +62,10 @@ type PodDisruptionBudget struct { // Most recently observed status of the PodDisruptionBudget. Status PodDisruptionBudgetStatus `json:"status,omitempty" protobuf:"bytes,3,opt,name=status"` } + +// PodDisruptionBudgetList is a collection of PodDisruptionBudgets. +type PodDisruptionBudgetList struct { + unversioned.TypeMeta `json:",inline"` + unversioned.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` + Items []PodDisruptionBudget `json:"items" protobuf:"bytes,2,rep,name=items"` +} diff --git a/vendor/k8s.io/kubernetes/pkg/apis/policy/v1alpha1/types_swagger_doc_generated.go b/vendor/k8s.io/kubernetes/pkg/apis/policy/v1alpha1/types_swagger_doc_generated.go new file mode 100644 index 0000000000..8ca1782f4f --- /dev/null +++ b/vendor/k8s.io/kubernetes/pkg/apis/policy/v1alpha1/types_swagger_doc_generated.go @@ -0,0 +1,70 @@ +/* +Copyright 2016 The Kubernetes Authors All rights reserved. + +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 v1alpha1 + +// This file contains a collection of methods that can be used from go-restful to +// generate Swagger API documentation for its models. Please read this PR for more +// information on the implementation: https://github.com/emicklei/go-restful/pull/215 +// +// TODOs are ignored from the parser (e.g. TODO(andronat):... || TODO:...) if and only if +// they are on one line! For multiple line or blocks that you want to ignore use ---. +// Any context after a --- is ignored. +// +// Those methods can be generated by using hack/update-generated-swagger-docs.sh + +// AUTO-GENERATED FUNCTIONS START HERE +var map_PodDisruptionBudget = map[string]string{ + "": "PodDisruptionBudget is an object to define the max disruption that can be caused to a collection of pods", + "spec": "Specification of the desired behavior of the PodDisruptionBudget.", + "status": "Most recently observed status of the PodDisruptionBudget.", +} + +func (PodDisruptionBudget) SwaggerDoc() map[string]string { + return map_PodDisruptionBudget +} + +var map_PodDisruptionBudgetList = map[string]string{ + "": "PodDisruptionBudgetList is a collection of PodDisruptionBudgets.", +} + +func (PodDisruptionBudgetList) SwaggerDoc() map[string]string { + return map_PodDisruptionBudgetList +} + +var map_PodDisruptionBudgetSpec = map[string]string{ + "": "PodDisruptionBudgetSpec is a description of a PodDisruptionBudget.", + "minAvailable": "The minimum number of pods that must be available simultaneously. This can be either an integer or a string specifying a percentage, e.g. \"28%\".", + "selector": "Label query over pods whose evictions are managed by the disruption budget.", +} + +func (PodDisruptionBudgetSpec) SwaggerDoc() map[string]string { + return map_PodDisruptionBudgetSpec +} + +var map_PodDisruptionBudgetStatus = map[string]string{ + "": "PodDisruptionBudgetStatus represents information about the status of a PodDisruptionBudget. Status may trail the actual state of a system.", + "disruptionAllowed": "Whether or not a disruption is currently allowed.", + "currentHealthy": "current number of healthy pods", + "desiredHealthy": "minimum desired number of healthy pods", + "expectedPods": "total number of pods counted by this disruption budget", +} + +func (PodDisruptionBudgetStatus) SwaggerDoc() map[string]string { + return map_PodDisruptionBudgetStatus +} + +// AUTO-GENERATED FUNCTIONS END HERE diff --git a/vendor/k8s.io/kubernetes/pkg/apis/policy/validation/validation.go b/vendor/k8s.io/kubernetes/pkg/apis/policy/validation/validation.go new file mode 100644 index 0000000000..6d40450ba8 --- /dev/null +++ b/vendor/k8s.io/kubernetes/pkg/apis/policy/validation/validation.go @@ -0,0 +1,55 @@ +/* +Copyright 2016 The Kubernetes Authors All rights reserved. + +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 validation + +import ( + "reflect" + + unversionedvalidation "k8s.io/kubernetes/pkg/api/unversioned/validation" + extensionsvalidation "k8s.io/kubernetes/pkg/apis/extensions/validation" + "k8s.io/kubernetes/pkg/apis/policy" + "k8s.io/kubernetes/pkg/util/validation/field" +) + +func ValidatePodDisruptionBudget(pdb *policy.PodDisruptionBudget) field.ErrorList { + allErrs := ValidatePodDisruptionBudgetSpec(pdb.Spec, field.NewPath("spec")) + return allErrs +} + +func ValidatePodDisruptionBudgetUpdate(pdb, oldPdb *policy.PodDisruptionBudget) field.ErrorList { + allErrs := field.ErrorList{} + + restoreGeneration := pdb.Generation + pdb.Generation = oldPdb.Generation + + if !reflect.DeepEqual(pdb, oldPdb) { + allErrs = append(allErrs, field.Forbidden(field.NewPath("spec"), "updates to poddisruptionbudget spec are forbidden.")) + } + + pdb.Generation = restoreGeneration + return allErrs +} + +func ValidatePodDisruptionBudgetSpec(spec policy.PodDisruptionBudgetSpec, fldPath *field.Path) field.ErrorList { + allErrs := field.ErrorList{} + + allErrs = append(allErrs, extensionsvalidation.ValidatePositiveIntOrPercent(spec.MinAvailable, fldPath.Child("minAvailable"))...) + allErrs = append(allErrs, extensionsvalidation.IsNotMoreThan100Percent(spec.MinAvailable, fldPath.Child("minAvailable"))...) + allErrs = append(allErrs, unversionedvalidation.ValidateLabelSelector(spec.Selector, fldPath.Child("selector"))...) + + return allErrs +} diff --git a/vendor/k8s.io/kubernetes/pkg/apiserver/apiserver.go b/vendor/k8s.io/kubernetes/pkg/apiserver/apiserver.go index 49db40d618..e96369c297 100644 --- a/vendor/k8s.io/kubernetes/pkg/apiserver/apiserver.go +++ b/vendor/k8s.io/kubernetes/pkg/apiserver/apiserver.go @@ -26,6 +26,7 @@ import ( "net/http" "path" rt "runtime" + "strconv" "strings" "time" @@ -449,6 +450,11 @@ func writeNegotiated(s runtime.NegotiatedSerializer, gv unversioned.GroupVersion func errorNegotiated(err error, s runtime.NegotiatedSerializer, gv unversioned.GroupVersion, w http.ResponseWriter, req *http.Request) int { status := errToAPIStatus(err) code := int(status.Code) + // when writing an error, check to see if the status indicates a retry after period + if status.Details != nil && status.Details.RetryAfterSeconds > 0 { + delay := strconv.Itoa(int(status.Details.RetryAfterSeconds)) + w.Header().Set("Retry-After", delay) + } writeNegotiated(s, gv, w, req, code, status) return code } diff --git a/vendor/k8s.io/kubernetes/pkg/apiserver/authenticator/authn.go b/vendor/k8s.io/kubernetes/pkg/apiserver/authenticator/authn.go index bbce5b3588..56dfcf8ad1 100644 --- a/vendor/k8s.io/kubernetes/pkg/apiserver/authenticator/authn.go +++ b/vendor/k8s.io/kubernetes/pkg/apiserver/authenticator/authn.go @@ -18,6 +18,7 @@ package authenticator import ( "crypto/rsa" + "time" "k8s.io/kubernetes/pkg/auth/authenticator" "k8s.io/kubernetes/pkg/auth/authenticator/bearertoken" @@ -47,6 +48,7 @@ type AuthenticatorConfig struct { ServiceAccountTokenGetter serviceaccount.ServiceAccountTokenGetter KeystoneURL string WebhookTokenAuthnConfigFile string + WebhookTokenAuthnCacheTTL time.Duration } // New returns an authenticator.Request or an error that supports the standard @@ -103,7 +105,7 @@ func New(config AuthenticatorConfig) (authenticator.Request, error) { } if len(config.WebhookTokenAuthnConfigFile) > 0 { - webhookTokenAuth, err := newWebhookTokenAuthenticator(config.WebhookTokenAuthnConfigFile) + webhookTokenAuth, err := newWebhookTokenAuthenticator(config.WebhookTokenAuthnConfigFile, config.WebhookTokenAuthnCacheTTL) if err != nil { return nil, err } @@ -198,8 +200,8 @@ func newAuthenticatorFromKeystoneURL(keystoneURL string) (authenticator.Request, return basicauth.New(keystoneAuthenticator), nil } -func newWebhookTokenAuthenticator(webhookConfigFile string) (authenticator.Request, error) { - webhookTokenAuthenticator, err := webhook.New(webhookConfigFile) +func newWebhookTokenAuthenticator(webhookConfigFile string, ttl time.Duration) (authenticator.Request, error) { + webhookTokenAuthenticator, err := webhook.New(webhookConfigFile, ttl) if err != nil { return nil, err } diff --git a/vendor/k8s.io/kubernetes/pkg/apiserver/authz.go b/vendor/k8s.io/kubernetes/pkg/apiserver/authz.go index 88e8f6284e..78be39a676 100644 --- a/vendor/k8s.io/kubernetes/pkg/apiserver/authz.go +++ b/vendor/k8s.io/kubernetes/pkg/apiserver/authz.go @@ -19,6 +19,7 @@ package apiserver import ( "errors" "fmt" + "time" "k8s.io/kubernetes/pkg/auth/authorizer" "k8s.io/kubernetes/pkg/auth/authorizer/abac" @@ -77,6 +78,10 @@ type AuthorizationConfig struct { // Kubeconfig file for Webhook authorization plugin. WebhookConfigFile string + // TTL for caching of authorized responses from the webhook server. + WebhookCacheAuthorizedTTL time.Duration + // TTL for caching of unauthorized responses from the webhook server. + WebhookCacheUnauthorizedTTL time.Duration } // NewAuthorizerFromAuthorizationConfig returns the right sort of union of multiple authorizer.Authorizer objects @@ -114,7 +119,9 @@ func NewAuthorizerFromAuthorizationConfig(authorizationModes []string, config Au if config.WebhookConfigFile == "" { return nil, errors.New("Webhook's configuration file not passed") } - webhookAuthorizer, err := webhook.New(config.WebhookConfigFile) + webhookAuthorizer, err := webhook.New(config.WebhookConfigFile, + config.WebhookCacheAuthorizedTTL, + config.WebhookCacheUnauthorizedTTL) if err != nil { return nil, err } diff --git a/vendor/k8s.io/kubernetes/pkg/apiserver/handlers.go b/vendor/k8s.io/kubernetes/pkg/apiserver/handlers.go index d9b2eb8546..64c8397467 100644 --- a/vendor/k8s.io/kubernetes/pkg/apiserver/handlers.go +++ b/vendor/k8s.io/kubernetes/pkg/apiserver/handlers.go @@ -119,12 +119,16 @@ func MaxInFlightLimit(c chan bool, longRunningRequestCheck LongRunningRequestChe defer func() { <-c }() handler.ServeHTTP(w, r) default: - tooManyRequests(w) + tooManyRequests(r, w) } }) } -func tooManyRequests(w http.ResponseWriter) { +func tooManyRequests(req *http.Request, w http.ResponseWriter) { + // "Too Many Requests" response is returned before logger is setup for the request. + // So we need to explicitly log it here. + defer httplog.NewLogged(req, &w).Log() + // Return a 429 status indicating "Too Many Requests" w.Header().Set("Retry-After", RetryAfter) http.Error(w, "Too many requests, please try again later.", errors.StatusTooManyRequests) diff --git a/vendor/k8s.io/kubernetes/pkg/apiserver/metrics/metrics.go b/vendor/k8s.io/kubernetes/pkg/apiserver/metrics/metrics.go index fb7736b067..dc7fe7009a 100644 --- a/vendor/k8s.io/kubernetes/pkg/apiserver/metrics/metrics.go +++ b/vendor/k8s.io/kubernetes/pkg/apiserver/metrics/metrics.go @@ -35,9 +35,9 @@ var ( requestCounter = prometheus.NewCounterVec( prometheus.CounterOpts{ Name: "apiserver_request_count", - Help: "Counter of apiserver requests broken out for each verb, API resource, client, and HTTP response code.", + Help: "Counter of apiserver requests broken out for each verb, API resource, client, and HTTP response contentType and code.", }, - []string{"verb", "resource", "client", "code"}, + []string{"verb", "resource", "client", "contentType", "code"}, ) requestLatencies = prometheus.NewHistogramVec( prometheus.HistogramOpts{ @@ -66,9 +66,9 @@ func Register() { prometheus.MustRegister(requestLatenciesSummary) } -func Monitor(verb, resource *string, client string, httpCode int, reqStart time.Time) { +func Monitor(verb, resource *string, client, contentType string, httpCode int, reqStart time.Time) { elapsed := float64((time.Since(reqStart)) / time.Microsecond) - requestCounter.WithLabelValues(*verb, *resource, client, codeToString(httpCode)).Inc() + requestCounter.WithLabelValues(*verb, *resource, client, contentType, codeToString(httpCode)).Inc() requestLatencies.WithLabelValues(*verb, *resource).Observe(elapsed) requestLatenciesSummary.WithLabelValues(*verb, *resource).Observe(elapsed) } @@ -99,7 +99,7 @@ func InstrumentRouteFunc(verb, resource string, routeFunc restful.RouteFunction) response.ResponseWriter = rw routeFunc(request, response) - Monitor(&verb, &resource, utilnet.GetHTTPClient(request.Request), delegate.status, now) + Monitor(&verb, &resource, utilnet.GetHTTPClient(request.Request), rw.Header().Get("Content-Type"), delegate.status, now) }) } diff --git a/vendor/k8s.io/kubernetes/pkg/apiserver/proxy.go b/vendor/k8s.io/kubernetes/pkg/apiserver/proxy.go index 5c581032be..4b3d00d77d 100644 --- a/vendor/k8s.io/kubernetes/pkg/apiserver/proxy.go +++ b/vendor/k8s.io/kubernetes/pkg/apiserver/proxy.go @@ -57,7 +57,7 @@ func (r *ProxyHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) { var apiResource string var httpCode int reqStart := time.Now() - defer metrics.Monitor(&verb, &apiResource, net.GetHTTPClient(req), httpCode, reqStart) + defer metrics.Monitor(&verb, &apiResource, net.GetHTTPClient(req), w.Header().Get("Content-Type"), httpCode, reqStart) requestInfo, err := r.requestInfoResolver.GetRequestInfo(req) if err != nil || !requestInfo.IsResourceRequest { diff --git a/vendor/k8s.io/kubernetes/pkg/apiserver/resthandler.go b/vendor/k8s.io/kubernetes/pkg/apiserver/resthandler.go index 8bf9f4e7d2..4a1e970067 100644 --- a/vendor/k8s.io/kubernetes/pkg/apiserver/resthandler.go +++ b/vendor/k8s.io/kubernetes/pkg/apiserver/resthandler.go @@ -17,6 +17,7 @@ limitations under the License. package apiserver import ( + "encoding/hex" "encoding/json" "fmt" "math/rand" @@ -376,7 +377,7 @@ func createHandler(r rest.NamedCreater, scope RequestScope, typer runtime.Object trace.Step("About to convert to expected version") obj, gvk, err := decoder.Decode(body, &defaultGVK, original) if err != nil { - err = transformDecodeError(typer, err, original, gvk) + err = transformDecodeError(typer, err, original, gvk, body) scope.err(err, res.ResponseWriter, req.Request) return } @@ -650,7 +651,7 @@ func UpdateResource(r rest.Updater, scope RequestScope, typer runtime.ObjectType trace.Step("About to convert to expected version") obj, gvk, err := scope.Serializer.DecoderToVersion(s, defaultGVK.GroupVersion()).Decode(body, &defaultGVK, original) if err != nil { - err = transformDecodeError(typer, err, original, gvk) + err = transformDecodeError(typer, err, original, gvk, body) scope.err(err, res.ResponseWriter, req.Request) return } @@ -938,7 +939,7 @@ func finishRequest(timeout time.Duration, fn resultFunc) (result runtime.Object, } // transformDecodeError adds additional information when a decode fails. -func transformDecodeError(typer runtime.ObjectTyper, baseErr error, into runtime.Object, gvk *unversioned.GroupVersionKind) error { +func transformDecodeError(typer runtime.ObjectTyper, baseErr error, into runtime.Object, gvk *unversioned.GroupVersionKind, body []byte) error { objGVK, err := typer.ObjectKind(into) if err != nil { return err @@ -946,7 +947,8 @@ func transformDecodeError(typer runtime.ObjectTyper, baseErr error, into runtime if gvk != nil && len(gvk.Kind) > 0 { return errors.NewBadRequest(fmt.Sprintf("%s in version %q cannot be handled as a %s: %v", gvk.Kind, gvk.Version, objGVK.Kind, baseErr)) } - return errors.NewBadRequest(fmt.Sprintf("the object provided is unrecognized (must be of type %s): %v", objGVK.Kind, baseErr)) + summary := summarizeData(body, 30) + return errors.NewBadRequest(fmt.Sprintf("the object provided is unrecognized (must be of type %s): %v (%s)", objGVK.Kind, baseErr, summary)) } // setSelfLink sets the self link of an object (or the child items in a list) to the base URL of the request @@ -1038,3 +1040,20 @@ func getPatchedJS(patchType api.PatchType, originalJS, patchJS []byte, obj runti return nil, fmt.Errorf("unknown Content-Type header for patch: %v", patchType) } } + +func summarizeData(data []byte, maxLength int) string { + switch { + case len(data) == 0: + return "" + case data[0] == '{': + if len(data) > maxLength { + return string(data[:maxLength]) + " ..." + } + return string(data) + default: + if len(data) > maxLength { + return hex.EncodeToString(data[:maxLength]) + " ..." + } + return hex.EncodeToString(data) + } +} diff --git a/vendor/k8s.io/kubernetes/pkg/auth/handlers/handlers.go b/vendor/k8s.io/kubernetes/pkg/auth/handlers/handlers.go index ac316763ab..d005752f16 100644 --- a/vendor/k8s.io/kubernetes/pkg/auth/handlers/handlers.go +++ b/vendor/k8s.io/kubernetes/pkg/auth/handlers/handlers.go @@ -18,12 +18,29 @@ package handlers import ( "net/http" + "strings" "github.com/golang/glog" + "github.com/prometheus/client_golang/prometheus" + "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/auth/authenticator" ) +var ( + authenticatedUserCounter = prometheus.NewCounterVec( + prometheus.CounterOpts{ + Name: "authenticated_user_requests", + Help: "Counter of authenticated requests broken out by username.", + }, + []string{"username"}, + ) +) + +func init() { + prometheus.MustRegister(authenticatedUserCounter) +} + // NewRequestAuthenticator creates an http handler that tries to authenticate the given request as a user, and then // stores any such user found onto the provided context for the request. If authentication fails or returns an error // the failed handler is used. On success, handler is invoked to serve the request. @@ -44,6 +61,8 @@ func NewRequestAuthenticator(mapper api.RequestContextMapper, auth authenticator mapper.Update(req, api.WithUser(ctx, user)) } + authenticatedUserCounter.WithLabelValues(compressUsername(user.GetName())).Inc() + handler.ServeHTTP(w, req) }), ) @@ -66,3 +85,25 @@ func unauthorizedBasicAuth(w http.ResponseWriter, req *http.Request) { func unauthorized(w http.ResponseWriter, req *http.Request) { http.Error(w, "Unauthorized", http.StatusUnauthorized) } + +// compressUsername maps all possible usernames onto a small set of categories +// of usernames. This is done both to limit the cardinality of the +// authorized_user_requests metric, and to avoid pushing actual usernames in the +// metric. +func compressUsername(username string) string { + switch { + // Known internal identities. + case username == "admin" || + username == "client" || + username == "kube_proxy" || + username == "kubelet" || + username == "system:serviceaccount:kube-system:default": + return username + // Probably an email address. + case strings.Contains(username, "@"): + return "email_id" + // Anything else (custom service accounts, custom external identities, etc.) + default: + return "other" + } +} diff --git a/vendor/k8s.io/kubernetes/pkg/client/cache/delta_fifo.go b/vendor/k8s.io/kubernetes/pkg/client/cache/delta_fifo.go index e5dce16b61..800d952bb2 100644 --- a/vendor/k8s.io/kubernetes/pkg/client/cache/delta_fifo.go +++ b/vendor/k8s.io/kubernetes/pkg/client/cache/delta_fifo.go @@ -306,6 +306,10 @@ func (f *DeltaFIFO) queueActionLocked(actionType DeltaType, obj interface{}) err func (f *DeltaFIFO) List() []interface{} { f.lock.RLock() defer f.lock.RUnlock() + return f.listLocked() +} + +func (f *DeltaFIFO) listLocked() []interface{} { list := make([]interface{}, 0, len(f.items)) for _, item := range f.items { // Copy item's slice so operations on this slice (delta @@ -452,6 +456,27 @@ func (f *DeltaFIFO) Replace(list []interface{}, resourceVersion string) error { return nil } +// Resync will send a sync event for each item +func (f *DeltaFIFO) Resync() error { + f.lock.RLock() + defer f.lock.RUnlock() + for _, k := range f.knownObjects.ListKeys() { + obj, exists, err := f.knownObjects.GetByKey(k) + if err != nil { + glog.Errorf("Unexpected error %v during lookup of key %v, unable to queue object for sync", err, k) + continue + } else if !exists { + glog.Infof("Key %v does not exist in known objects store, unable to queue object for sync", k) + continue + } + + if err := f.queueActionLocked(Sync, obj); err != nil { + return fmt.Errorf("couldn't queue object: %v", err) + } + } + return nil +} + // A KeyListerGetter is anything that knows how to list its keys and look up by key. type KeyListerGetter interface { KeyLister diff --git a/vendor/k8s.io/kubernetes/pkg/client/cache/expiration_cache.go b/vendor/k8s.io/kubernetes/pkg/client/cache/expiration_cache.go index 964deda079..ad8684e8c3 100644 --- a/vendor/k8s.io/kubernetes/pkg/client/cache/expiration_cache.go +++ b/vendor/k8s.io/kubernetes/pkg/client/cache/expiration_cache.go @@ -146,6 +146,7 @@ func (c *ExpirationCache) ListKeys() []string { func (c *ExpirationCache) Add(obj interface{}) error { c.expirationLock.Lock() defer c.expirationLock.Unlock() + key, err := c.keyFunc(obj) if err != nil { return KeyError{obj, err} @@ -191,6 +192,11 @@ func (c *ExpirationCache) Replace(list []interface{}, resourceVersion string) er return nil } +// Resync will touch all objects to put them into the processing queue +func (c *ExpirationCache) Resync() error { + return c.cacheStorage.Resync() +} + // NewTTLStore creates and returns a ExpirationCache with a TTLPolicy func NewTTLStore(keyFunc KeyFunc, ttl time.Duration) Store { return &ExpirationCache{ diff --git a/vendor/k8s.io/kubernetes/pkg/client/cache/fake_custom_store.go b/vendor/k8s.io/kubernetes/pkg/client/cache/fake_custom_store.go new file mode 100644 index 0000000000..ccd69ef7bf --- /dev/null +++ b/vendor/k8s.io/kubernetes/pkg/client/cache/fake_custom_store.go @@ -0,0 +1,102 @@ +/* +Copyright 2016 The Kubernetes Authors All rights reserved. + +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 cache + +// FakeStore lets you define custom functions for store operations +type FakeCustomStore struct { + AddFunc func(obj interface{}) error + UpdateFunc func(obj interface{}) error + DeleteFunc func(obj interface{}) error + ListFunc func() []interface{} + ListKeysFunc func() []string + GetFunc func(obj interface{}) (item interface{}, exists bool, err error) + GetByKeyFunc func(key string) (item interface{}, exists bool, err error) + ReplaceFunc func(list []interface{}, resourceVerion string) error + ResyncFunc func() error +} + +// Add calls the custom Add function if defined +func (f *FakeCustomStore) Add(obj interface{}) error { + if f.AddFunc != nil { + return f.AddFunc(obj) + } + return nil +} + +// Update calls the custom Update function if defined +func (f *FakeCustomStore) Update(obj interface{}) error { + if f.UpdateFunc != nil { + return f.Update(obj) + } + return nil +} + +// Delete calls the custom Delete function if defined +func (f *FakeCustomStore) Delete(obj interface{}) error { + if f.DeleteFunc != nil { + return f.DeleteFunc(obj) + } + return nil +} + +// List calls the custom List function if defined +func (f *FakeCustomStore) List() []interface{} { + if f.ListFunc != nil { + return f.ListFunc() + } + return nil +} + +// ListKeys calls the custom ListKeys function if defined +func (f *FakeCustomStore) ListKeys() []string { + if f.ListKeysFunc != nil { + return f.ListKeysFunc() + } + return nil +} + +// Get calls the custom Get function if defined +func (f *FakeCustomStore) Get(obj interface{}) (item interface{}, exists bool, err error) { + if f.GetFunc != nil { + return f.GetFunc(obj) + } + return nil, false, nil +} + +// GetByKey calls the custom GetByKey function if defined +func (f *FakeCustomStore) GetByKey(key string) (item interface{}, exists bool, err error) { + if f.GetByKeyFunc != nil { + return f.GetByKeyFunc(key) + } + return nil, false, nil +} + +// Replace calls the custom Replace function if defined +func (f *FakeCustomStore) Replace(list []interface{}, resourceVersion string) error { + if f.ReplaceFunc != nil { + return f.ReplaceFunc(list, resourceVersion) + } + return nil +} + +// Resync calls the custom Resync function if defined +func (f *FakeCustomStore) Resync() error { + if f.ResyncFunc != nil { + return f.ResyncFunc() + } + return nil +} diff --git a/vendor/k8s.io/kubernetes/pkg/client/cache/fifo.go b/vendor/k8s.io/kubernetes/pkg/client/cache/fifo.go index d4076a326d..f98bea6f44 100644 --- a/vendor/k8s.io/kubernetes/pkg/client/cache/fifo.go +++ b/vendor/k8s.io/kubernetes/pkg/client/cache/fifo.go @@ -18,6 +18,8 @@ package cache import ( "sync" + + "k8s.io/kubernetes/pkg/util/sets" ) // Queue is exactly like a Store, but has a Pop() method too. @@ -241,6 +243,26 @@ func (f *FIFO) Replace(list []interface{}, resourceVersion string) error { return nil } +// Resync will touch all objects to put them into the processing queue +func (f *FIFO) Resync() error { + f.lock.Lock() + defer f.lock.Unlock() + + inQueue := sets.NewString() + for _, id := range f.queue { + inQueue.Insert(id) + } + for id := range f.items { + if !inQueue.Has(id) { + f.queue = append(f.queue, id) + } + } + if len(f.queue) > 0 { + f.cond.Broadcast() + } + return nil +} + // NewFIFO returns a Store which can be used to queue up items to // process. func NewFIFO(keyFunc KeyFunc) *FIFO { diff --git a/vendor/k8s.io/kubernetes/pkg/client/cache/index.go b/vendor/k8s.io/kubernetes/pkg/client/cache/index.go index 19c5e0650d..572f2c06b6 100644 --- a/vendor/k8s.io/kubernetes/pkg/client/cache/index.go +++ b/vendor/k8s.io/kubernetes/pkg/client/cache/index.go @@ -34,6 +34,10 @@ type Indexer interface { ByIndex(indexName, indexKey string) ([]interface{}, error) // GetIndexer return the indexers GetIndexers() Indexers + + // AddIndexers adds more indexers to this store. If you call this after you already have data + // in the store, the results are undefined. + AddIndexers(newIndexers Indexers) error } // IndexFunc knows how to provide an indexed value for an object. diff --git a/vendor/k8s.io/kubernetes/pkg/client/cache/reflector.go b/vendor/k8s.io/kubernetes/pkg/client/cache/reflector.go index 6f5658f9c7..3a5025a28a 100644 --- a/vendor/k8s.io/kubernetes/pkg/client/cache/reflector.go +++ b/vendor/k8s.io/kubernetes/pkg/client/cache/reflector.go @@ -246,35 +246,6 @@ func (r *Reflector) resyncChan() (<-chan time.Time, func() bool) { return t.C, t.Stop } -// We want to avoid situations when periodic resyncing is breaking the TCP -// connection. -// If response`s body is not read to completion before calling body.Close(), -// that TCP connection will not be reused in the future - see #15664 issue -// for more details. -// Thus, we set timeout for watch requests to be smaller than the remaining -// time until next periodic resync and force resyncing ourself to avoid -// breaking TCP connection. -// -// TODO: This should be parametrizable based on server load. -func (r *Reflector) timeoutForWatch() *int64 { - randTimeout := time.Duration(float64(minWatchTimeout) * (rand.Float64() + 1.0)) - timeout := r.nextResync.Sub(r.now()) - timeoutThreshold - if timeout < 0 || randTimeout < timeout { - timeout = randTimeout - } - timeoutSeconds := int64(timeout.Seconds()) - return &timeoutSeconds -} - -// Returns true if we are close enough to next planned periodic resync -// and we can force resyncing ourself now. -func (r *Reflector) canForceResyncNow() bool { - if r.nextResync.IsZero() { - return false - } - return r.now().Add(forceResyncThreshold).After(r.nextResync) -} - // ListAndWatch first lists all items and get the resource version at the moment of call, // and then use the resource version to watch. // It returns error if ListAndWatch didn't even try to initialize watch. @@ -292,11 +263,11 @@ func (r *Reflector) ListAndWatch(stopCh <-chan struct{}) error { if err != nil { return fmt.Errorf("%s: Failed to list %v: %v", r.name, r.expectedType, err) } - metaInterface, err := meta.Accessor(list) + listMetaInterface, err := meta.ListAccessor(list) if err != nil { - return fmt.Errorf("%s: Unable to understand list result %#v", r.name, list) + return fmt.Errorf("%s: Unable to understand list result %#v: %v", r.name, list, err) } - resourceVersion = metaInterface.GetResourceVersion() + resourceVersion = listMetaInterface.GetResourceVersion() items, err := meta.ExtractList(list) if err != nil { return fmt.Errorf("%s: Unable to understand list result %#v (%v)", r.name, list, err) @@ -306,13 +277,33 @@ func (r *Reflector) ListAndWatch(stopCh <-chan struct{}) error { } r.setLastSyncResourceVersion(resourceVersion) - for { - options := api.ListOptions{ - ResourceVersion: resourceVersion, - // We want to avoid situations when resyncing is breaking the TCP connection - // - see comment for 'timeoutForWatch()' for more details. - TimeoutSeconds: r.timeoutForWatch(), + resyncerrc := make(chan error, 1) + go func() { + for { + select { + case <-resyncCh: + case <-stopCh: + return + } + glog.V(4).Infof("%s: next resync planned for %#v, forcing now", r.name, r.nextResync) + if err := r.store.Resync(); err != nil { + resyncerrc <- err + return + } + cleanup() + resyncCh, cleanup = r.resyncChan() } + }() + + for { + timemoutseconds := int64(minWatchTimeout.Seconds() * (rand.Float64() + 1.0)) + options = api.ListOptions{ + ResourceVersion: resourceVersion, + // We want to avoid situations of hanging watchers. Stop any wachers that do not + // receive any events within the timeout window. + TimeoutSeconds: &timemoutseconds, + } + w, err := r.listerWatcher.Watch(options) if err != nil { switch err { @@ -337,16 +328,13 @@ func (r *Reflector) ListAndWatch(stopCh <-chan struct{}) error { } return nil } - if err := r.watchHandler(w, &resourceVersion, resyncCh, stopCh); err != nil { - if err != errorResyncRequested && err != errorStopRequested { + + if err := r.watchHandler(w, &resourceVersion, resyncerrc, stopCh); err != nil { + if err != errorStopRequested { glog.Warningf("%s: watch of %v ended with: %v", r.name, r.expectedType, err) } return nil } - if r.canForceResyncNow() { - glog.V(4).Infof("%s: next resync planned for %#v, forcing now", r.name, r.nextResync) - return nil - } } } @@ -360,7 +348,7 @@ func (r *Reflector) syncWith(items []runtime.Object, resourceVersion string) err } // watchHandler watches w and keeps *resourceVersion up to date. -func (r *Reflector) watchHandler(w watch.Interface, resourceVersion *string, resyncCh <-chan time.Time, stopCh <-chan struct{}) error { +func (r *Reflector) watchHandler(w watch.Interface, resourceVersion *string, errc chan error, stopCh <-chan struct{}) error { start := time.Now() eventCount := 0 @@ -373,8 +361,8 @@ loop: select { case <-stopCh: return errorStopRequested - case <-resyncCh: - return errorResyncRequested + case err := <-errc: + return err case event, ok := <-w.ResultChan(): if !ok { break loop diff --git a/vendor/k8s.io/kubernetes/pkg/client/cache/store.go b/vendor/k8s.io/kubernetes/pkg/client/cache/store.go index b7f6f54ceb..71115f2ce5 100644 --- a/vendor/k8s.io/kubernetes/pkg/client/cache/store.go +++ b/vendor/k8s.io/kubernetes/pkg/client/cache/store.go @@ -44,6 +44,7 @@ type Store interface { // given list. Store takes ownership of the list, you should not reference // it after calling this function. Replace([]interface{}, string) error + Resync() error } // KeyFunc knows how to make a key from an object. Implementations should be deterministic. @@ -180,6 +181,10 @@ func (c *cache) ByIndex(indexName, indexKey string) ([]interface{}, error) { return c.cacheStorage.ByIndex(indexName, indexKey) } +func (c *cache) AddIndexers(newIndexers Indexers) error { + return c.cacheStorage.AddIndexers(newIndexers) +} + // Get returns the requested item, or sets exists=false. // Get is completely threadsafe as long as you treat all items as immutable. func (c *cache) Get(obj interface{}) (item interface{}, exists bool, err error) { @@ -213,6 +218,11 @@ func (c *cache) Replace(list []interface{}, resourceVersion string) error { return nil } +// Resync touches all items in the store to force processing +func (c *cache) Resync() error { + return c.cacheStorage.Resync() +} + // NewStore returns a Store implemented simply with a map and a lock. func NewStore(keyFunc KeyFunc) Store { return &cache{ diff --git a/vendor/k8s.io/kubernetes/pkg/client/cache/thread_safe_store.go b/vendor/k8s.io/kubernetes/pkg/client/cache/thread_safe_store.go index b9c6e25b26..11077e25b2 100644 --- a/vendor/k8s.io/kubernetes/pkg/client/cache/thread_safe_store.go +++ b/vendor/k8s.io/kubernetes/pkg/client/cache/thread_safe_store.go @@ -46,6 +46,11 @@ type ThreadSafeStore interface { ListIndexFuncValues(name string) []string ByIndex(indexName, indexKey string) ([]interface{}, error) GetIndexers() Indexers + + // AddIndexers adds more indexers to this store. If you call this after you already have data + // in the store, the results are undefined. + AddIndexers(newIndexers Indexers) error + Resync() error } // threadSafeMap implements ThreadSafeStore @@ -195,6 +200,27 @@ func (c *threadSafeMap) GetIndexers() Indexers { return c.indexers } +func (c *threadSafeMap) AddIndexers(newIndexers Indexers) error { + c.lock.Lock() + defer c.lock.Unlock() + + if len(c.items) > 0 { + return fmt.Errorf("cannot add indexers to running index") + } + + oldKeys := sets.StringKeySet(c.indexers) + newKeys := sets.StringKeySet(newIndexers) + + if oldKeys.HasAny(newKeys.List()...) { + return fmt.Errorf("indexer conflict: %v", oldKeys.Intersection(newKeys)) + } + + for k, v := range newIndexers { + c.indexers[k] = v + } + return nil +} + // updateIndices modifies the objects location in the managed indexes, if this is an update, you must provide an oldObj // updateIndices must be called from a function that already has a lock on the cache func (c *threadSafeMap) updateIndices(oldObj interface{}, newObj interface{}, key string) error { @@ -247,6 +273,11 @@ func (c *threadSafeMap) deleteFromIndices(obj interface{}, key string) error { return nil } +func (c *threadSafeMap) Resync() error { + // Nothing to do + return nil +} + func NewThreadSafeStore(indexers Indexers, indices Indices) ThreadSafeStore { return &threadSafeMap{ items: map[string]interface{}{}, diff --git a/vendor/k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/import_known_versions.go b/vendor/k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/import_known_versions.go index 291037d523..7e7709bcfd 100644 --- a/vendor/k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/import_known_versions.go +++ b/vendor/k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/import_known_versions.go @@ -29,6 +29,7 @@ import ( _ "k8s.io/kubernetes/pkg/apis/componentconfig/install" _ "k8s.io/kubernetes/pkg/apis/extensions/install" _ "k8s.io/kubernetes/pkg/apis/metrics/install" + _ "k8s.io/kubernetes/pkg/apis/policy/install" ) func init() { diff --git a/vendor/k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/batch/unversioned/batch_client.go b/vendor/k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/batch/unversioned/batch_client.go index 58b67ceda0..83d9d749c4 100644 --- a/vendor/k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/batch/unversioned/batch_client.go +++ b/vendor/k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/batch/unversioned/batch_client.go @@ -25,6 +25,7 @@ import ( type BatchInterface interface { GetRESTClient() *restclient.RESTClient JobsGetter + ScheduledJobsGetter } // BatchClient is used to interact with features provided by the Batch group. @@ -36,6 +37,10 @@ func (c *BatchClient) Jobs(namespace string) JobInterface { return newJobs(c, namespace) } +func (c *BatchClient) ScheduledJobs(namespace string) ScheduledJobInterface { + return newScheduledJobs(c, namespace) +} + // NewForConfig creates a new BatchClient for the given config. func NewForConfig(c *restclient.Config) (*BatchClient, error) { config := *c diff --git a/vendor/k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/batch/unversioned/generated_expansion.go b/vendor/k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/batch/unversioned/generated_expansion.go index 08c0e265d2..f876ef63fc 100644 --- a/vendor/k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/batch/unversioned/generated_expansion.go +++ b/vendor/k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/batch/unversioned/generated_expansion.go @@ -17,3 +17,5 @@ limitations under the License. package unversioned type JobExpansion interface{} + +type ScheduledJobExpansion interface{} diff --git a/vendor/k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/batch/unversioned/scheduledjob.go b/vendor/k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/batch/unversioned/scheduledjob.go new file mode 100644 index 0000000000..2675d11c48 --- /dev/null +++ b/vendor/k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/batch/unversioned/scheduledjob.go @@ -0,0 +1,150 @@ +/* +Copyright 2016 The Kubernetes Authors All rights reserved. + +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 unversioned + +import ( + api "k8s.io/kubernetes/pkg/api" + batch "k8s.io/kubernetes/pkg/apis/batch" + watch "k8s.io/kubernetes/pkg/watch" +) + +// ScheduledJobsGetter has a method to return a ScheduledJobInterface. +// A group's client should implement this interface. +type ScheduledJobsGetter interface { + ScheduledJobs(namespace string) ScheduledJobInterface +} + +// ScheduledJobInterface has methods to work with ScheduledJob resources. +type ScheduledJobInterface interface { + Create(*batch.ScheduledJob) (*batch.ScheduledJob, error) + Update(*batch.ScheduledJob) (*batch.ScheduledJob, error) + UpdateStatus(*batch.ScheduledJob) (*batch.ScheduledJob, error) + Delete(name string, options *api.DeleteOptions) error + DeleteCollection(options *api.DeleteOptions, listOptions api.ListOptions) error + Get(name string) (*batch.ScheduledJob, error) + List(opts api.ListOptions) (*batch.ScheduledJobList, error) + Watch(opts api.ListOptions) (watch.Interface, error) + ScheduledJobExpansion +} + +// scheduledJobs implements ScheduledJobInterface +type scheduledJobs struct { + client *BatchClient + ns string +} + +// newScheduledJobs returns a ScheduledJobs +func newScheduledJobs(c *BatchClient, namespace string) *scheduledJobs { + return &scheduledJobs{ + client: c, + ns: namespace, + } +} + +// Create takes the representation of a scheduledJob and creates it. Returns the server's representation of the scheduledJob, and an error, if there is any. +func (c *scheduledJobs) Create(scheduledJob *batch.ScheduledJob) (result *batch.ScheduledJob, err error) { + result = &batch.ScheduledJob{} + err = c.client.Post(). + Namespace(c.ns). + Resource("scheduledjobs"). + Body(scheduledJob). + Do(). + Into(result) + return +} + +// Update takes the representation of a scheduledJob and updates it. Returns the server's representation of the scheduledJob, and an error, if there is any. +func (c *scheduledJobs) Update(scheduledJob *batch.ScheduledJob) (result *batch.ScheduledJob, err error) { + result = &batch.ScheduledJob{} + err = c.client.Put(). + Namespace(c.ns). + Resource("scheduledjobs"). + Name(scheduledJob.Name). + Body(scheduledJob). + Do(). + Into(result) + return +} + +func (c *scheduledJobs) UpdateStatus(scheduledJob *batch.ScheduledJob) (result *batch.ScheduledJob, err error) { + result = &batch.ScheduledJob{} + err = c.client.Put(). + Namespace(c.ns). + Resource("scheduledjobs"). + Name(scheduledJob.Name). + SubResource("status"). + Body(scheduledJob). + Do(). + Into(result) + return +} + +// Delete takes name of the scheduledJob and deletes it. Returns an error if one occurs. +func (c *scheduledJobs) Delete(name string, options *api.DeleteOptions) error { + return c.client.Delete(). + Namespace(c.ns). + Resource("scheduledjobs"). + Name(name). + Body(options). + Do(). + Error() +} + +// DeleteCollection deletes a collection of objects. +func (c *scheduledJobs) DeleteCollection(options *api.DeleteOptions, listOptions api.ListOptions) error { + return c.client.Delete(). + Namespace(c.ns). + Resource("scheduledjobs"). + VersionedParams(&listOptions, api.ParameterCodec). + Body(options). + Do(). + Error() +} + +// Get takes name of the scheduledJob, and returns the corresponding scheduledJob object, and an error if there is any. +func (c *scheduledJobs) Get(name string) (result *batch.ScheduledJob, err error) { + result = &batch.ScheduledJob{} + err = c.client.Get(). + Namespace(c.ns). + Resource("scheduledjobs"). + Name(name). + Do(). + Into(result) + return +} + +// List takes label and field selectors, and returns the list of ScheduledJobs that match those selectors. +func (c *scheduledJobs) List(opts api.ListOptions) (result *batch.ScheduledJobList, err error) { + result = &batch.ScheduledJobList{} + err = c.client.Get(). + Namespace(c.ns). + Resource("scheduledjobs"). + VersionedParams(&opts, api.ParameterCodec). + Do(). + Into(result) + return +} + +// Watch returns a watch.Interface that watches the requested scheduledJobs. +func (c *scheduledJobs) Watch(opts api.ListOptions) (watch.Interface, error) { + return c.client.Get(). + Prefix("watch"). + Namespace(c.ns). + Resource("scheduledjobs"). + VersionedParams(&opts, api.ParameterCodec). + Watch() +} diff --git a/vendor/k8s.io/kubernetes/pkg/client/restclient/request.go b/vendor/k8s.io/kubernetes/pkg/client/restclient/request.go index 7050eab9a9..9fd3f0ddb0 100644 --- a/vendor/k8s.io/kubernetes/pkg/client/restclient/request.go +++ b/vendor/k8s.io/kubernetes/pkg/client/restclient/request.go @@ -179,8 +179,8 @@ func (r *Request) Resource(resource string) *Request { r.err = fmt.Errorf("resource already set to %q, cannot change to %q", r.resource, resource) return r } - if ok, msg := validation.IsValidPathSegmentName(resource); !ok { - r.err = fmt.Errorf("invalid resource %q: %s", resource, msg) + if msgs := validation.IsValidPathSegmentName(resource); len(msgs) != 0 { + r.err = fmt.Errorf("invalid resource %q: %v", resource, msgs) return r } r.resource = resource @@ -199,8 +199,8 @@ func (r *Request) SubResource(subresources ...string) *Request { return r } for _, s := range subresources { - if ok, msg := validation.IsValidPathSegmentName(s); !ok { - r.err = fmt.Errorf("invalid subresource %q: %s", s, msg) + if msgs := validation.IsValidPathSegmentName(s); len(msgs) != 0 { + r.err = fmt.Errorf("invalid subresource %q: %v", s, msgs) return r } } @@ -221,8 +221,8 @@ func (r *Request) Name(resourceName string) *Request { r.err = fmt.Errorf("resource name already set to %q, cannot change to %q", r.resourceName, resourceName) return r } - if ok, msg := validation.IsValidPathSegmentName(resourceName); !ok { - r.err = fmt.Errorf("invalid resource name %q: %s", resourceName, msg) + if msgs := validation.IsValidPathSegmentName(resourceName); len(msgs) != 0 { + r.err = fmt.Errorf("invalid resource name %q: %v", resourceName, msgs) return r } r.resourceName = resourceName @@ -238,8 +238,8 @@ func (r *Request) Namespace(namespace string) *Request { r.err = fmt.Errorf("namespace already set to %q, cannot change to %q", r.namespace, namespace) return r } - if ok, msg := validation.IsValidPathSegmentName(namespace); !ok { - r.err = fmt.Errorf("invalid namespace %q: %s", namespace, msg) + if msgs := validation.IsValidPathSegmentName(namespace); len(msgs) != 0 { + r.err = fmt.Errorf("invalid namespace %q: %v", namespace, msgs) return r } r.namespaceSet = true @@ -539,10 +539,10 @@ func (r *Request) Body(obj interface{}) *Request { return r } glog.V(8).Infof("Request Body: %s", string(data)) - r.body = bytes.NewBuffer(data) + r.body = bytes.NewReader(data) case []byte: glog.V(8).Infof("Request Body: %s", string(t)) - r.body = bytes.NewBuffer(t) + r.body = bytes.NewReader(t) case io.Reader: r.body = t case runtime.Object: @@ -556,7 +556,7 @@ func (r *Request) Body(obj interface{}) *Request { return r } glog.V(8).Infof("Request Body: %s", string(data)) - r.body = bytes.NewBuffer(data) + r.body = bytes.NewReader(data) r.SetHeader("Content-Type", r.content.ContentType) default: r.err = fmt.Errorf("unknown type used for body: %+v", obj) @@ -823,6 +823,15 @@ func (r *Request) request(fn func(*http.Request, *http.Response)) error { retries++ if seconds, wait := checkWait(resp); wait && retries < maxRetries { + if seeker, ok := r.body.(io.Seeker); ok && r.body != nil { + _, err := seeker.Seek(0, 0) + if err != nil { + glog.V(4).Infof("Could not retry request, can't Seek() back to beginning of body for %T", r.body) + fn(req, resp) + return true + } + } + glog.V(4).Infof("Got a Retry-After %s response for attempt %d to %v", seconds, retries, url) r.backoffMgr.Sleep(time.Duration(seconds) * time.Second) return false diff --git a/vendor/k8s.io/kubernetes/pkg/client/typed/discovery/discovery_client.go b/vendor/k8s.io/kubernetes/pkg/client/typed/discovery/discovery_client.go index 4a0f0b91ac..283dd5a63e 100644 --- a/vendor/k8s.io/kubernetes/pkg/client/typed/discovery/discovery_client.go +++ b/vendor/k8s.io/kubernetes/pkg/client/typed/discovery/discovery_client.go @@ -20,6 +20,7 @@ import ( "encoding/json" "fmt" "net/url" + "strings" "github.com/emicklei/go-restful/swagger" @@ -30,6 +31,7 @@ import ( "k8s.io/kubernetes/pkg/client/restclient" "k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/runtime/serializer" + utilerrors "k8s.io/kubernetes/pkg/util/errors" "k8s.io/kubernetes/pkg/version" ) @@ -55,6 +57,12 @@ type ServerResourcesInterface interface { ServerResourcesForGroupVersion(groupVersion string) (*unversioned.APIResourceList, error) // ServerResources returns the supported resources for all groups and versions. ServerResources() (map[string]*unversioned.APIResourceList, error) + // ServerPreferredResources returns the supported resources with the version preferred by the + // server. + ServerPreferredResources() ([]unversioned.GroupVersionResource, error) + // ServerPreferredNamespacedResources returns the supported namespaced resources with the + // version preferred by the server. + ServerPreferredNamespacedResources() ([]unversioned.GroupVersionResource, error) } // ServerVersionInterface has a method for retrieving the server's version. @@ -163,6 +171,50 @@ func (d *DiscoveryClient) ServerResources() (map[string]*unversioned.APIResource return result, nil } +// serverPreferredResources returns the supported resources with the version preferred by the +// server. If namespaced is true, only namespaced resources will be returned. +func (d *DiscoveryClient) serverPreferredResources(namespaced bool) ([]unversioned.GroupVersionResource, error) { + results := []unversioned.GroupVersionResource{} + serverGroupList, err := d.ServerGroups() + if err != nil { + return results, err + } + + allErrs := []error{} + for _, apiGroup := range serverGroupList.Groups { + preferredVersion := apiGroup.PreferredVersion + apiResourceList, err := d.ServerResourcesForGroupVersion(preferredVersion.GroupVersion) + if err != nil { + allErrs = append(allErrs, err) + continue + } + groupVersion := unversioned.GroupVersion{Group: apiGroup.Name, Version: preferredVersion.Version} + for _, apiResource := range apiResourceList.APIResources { + // ignore the root scoped resources if "namespaced" is true. + if namespaced && !apiResource.Namespaced { + continue + } + if strings.Contains(apiResource.Name, "/") { + continue + } + results = append(results, groupVersion.WithResource(apiResource.Name)) + } + } + return results, utilerrors.NewAggregate(allErrs) +} + +// ServerPreferredResources returns the supported resources with the version preferred by the +// server. +func (d *DiscoveryClient) ServerPreferredResources() ([]unversioned.GroupVersionResource, error) { + return d.serverPreferredResources(false) +} + +// ServerPreferredNamespacedResources returns the supported namespaced resources with the +// version preferred by the server. +func (d *DiscoveryClient) ServerPreferredNamespacedResources() ([]unversioned.GroupVersionResource, error) { + return d.serverPreferredResources(true) +} + // ServerVersion retrieves and parses the server's version (git version). func (d *DiscoveryClient) ServerVersion() (*version.Info, error) { body, err := d.Get().AbsPath("/version").Do().Raw() diff --git a/vendor/k8s.io/kubernetes/pkg/client/typed/dynamic/client.go b/vendor/k8s.io/kubernetes/pkg/client/typed/dynamic/client.go index 8df836f49c..96700ac944 100644 --- a/vendor/k8s.io/kubernetes/pkg/client/typed/dynamic/client.go +++ b/vendor/k8s.io/kubernetes/pkg/client/typed/dynamic/client.go @@ -98,20 +98,11 @@ type ResourceClient struct { ns string } -// namespace applies a namespace to the request if the configured -// resource is a namespaced resource. Otherwise, it just returns the -// passed in request. -func (rc *ResourceClient) namespace(req *restclient.Request) *restclient.Request { - if rc.resource.Namespaced { - return req.Namespace(rc.ns) - } - return req -} - // List returns a list of objects for this resource. func (rc *ResourceClient) List(opts runtime.Object) (*runtime.UnstructuredList, error) { result := new(runtime.UnstructuredList) - err := rc.namespace(rc.cl.Get()). + err := rc.cl.Get(). + NamespaceIfScoped(rc.ns, rc.resource.Namespaced). Resource(rc.resource.Name). VersionedParams(opts, parameterEncoder). Do(). @@ -122,7 +113,8 @@ func (rc *ResourceClient) List(opts runtime.Object) (*runtime.UnstructuredList, // Get gets the resource with the specified name. func (rc *ResourceClient) Get(name string) (*runtime.Unstructured, error) { result := new(runtime.Unstructured) - err := rc.namespace(rc.cl.Get()). + err := rc.cl.Get(). + NamespaceIfScoped(rc.ns, rc.resource.Namespaced). Resource(rc.resource.Name). Name(name). Do(). @@ -132,7 +124,8 @@ func (rc *ResourceClient) Get(name string) (*runtime.Unstructured, error) { // Delete deletes the resource with the specified name. func (rc *ResourceClient) Delete(name string, opts *v1.DeleteOptions) error { - return rc.namespace(rc.cl.Delete()). + return rc.cl.Delete(). + NamespaceIfScoped(rc.ns, rc.resource.Namespaced). Resource(rc.resource.Name). Name(name). Body(opts). @@ -142,7 +135,8 @@ func (rc *ResourceClient) Delete(name string, opts *v1.DeleteOptions) error { // DeleteCollection deletes a collection of objects. func (rc *ResourceClient) DeleteCollection(deleteOptions *v1.DeleteOptions, listOptions runtime.Object) error { - return rc.namespace(rc.cl.Delete()). + return rc.cl.Delete(). + NamespaceIfScoped(rc.ns, rc.resource.Namespaced). Resource(rc.resource.Name). VersionedParams(listOptions, parameterEncoder). Body(deleteOptions). @@ -153,7 +147,8 @@ func (rc *ResourceClient) DeleteCollection(deleteOptions *v1.DeleteOptions, list // Create creates the provided resource. func (rc *ResourceClient) Create(obj *runtime.Unstructured) (*runtime.Unstructured, error) { result := new(runtime.Unstructured) - err := rc.namespace(rc.cl.Post()). + err := rc.cl.Post(). + NamespaceIfScoped(rc.ns, rc.resource.Namespaced). Resource(rc.resource.Name). Body(obj). Do(). @@ -167,7 +162,8 @@ func (rc *ResourceClient) Update(obj *runtime.Unstructured) (*runtime.Unstructur if len(obj.GetName()) == 0 { return result, errors.New("object missing name") } - err := rc.namespace(rc.cl.Put()). + err := rc.cl.Put(). + NamespaceIfScoped(rc.ns, rc.resource.Namespaced). Resource(rc.resource.Name). Name(obj.GetName()). Body(obj). @@ -178,12 +174,26 @@ func (rc *ResourceClient) Update(obj *runtime.Unstructured) (*runtime.Unstructur // Watch returns a watch.Interface that watches the resource. func (rc *ResourceClient) Watch(opts runtime.Object) (watch.Interface, error) { - return rc.namespace(rc.cl.Get().Prefix("watch")). + return rc.cl.Get(). + Prefix("watch"). + NamespaceIfScoped(rc.ns, rc.resource.Namespaced). Resource(rc.resource.Name). VersionedParams(opts, parameterEncoder). Watch() } +func (rc *ResourceClient) Patch(name string, pt api.PatchType, data []byte) (*runtime.Unstructured, error) { + result := new(runtime.Unstructured) + err := rc.cl.Patch(pt). + NamespaceIfScoped(rc.ns, rc.resource.Namespaced). + Resource(rc.resource.Name). + Name(name). + Body(data). + Do(). + Into(result) + return result, err +} + // dynamicCodec is a codec that wraps the standard unstructured codec // with special handling for Status objects. type dynamicCodec struct{} diff --git a/vendor/k8s.io/kubernetes/pkg/client/typed/dynamic/client_pool.go b/vendor/k8s.io/kubernetes/pkg/client/typed/dynamic/client_pool.go index 4bdd3ecabb..f7c6505fd7 100644 --- a/vendor/k8s.io/kubernetes/pkg/client/typed/dynamic/client_pool.go +++ b/vendor/k8s.io/kubernetes/pkg/client/typed/dynamic/client_pool.go @@ -50,8 +50,9 @@ type clientPoolImpl struct { // NewClientPool returns a ClientPool from the specified config func NewClientPool(config *restclient.Config, apiPathResolverFunc APIPathResolverFunc) ClientPool { + confCopy := *config return &clientPoolImpl{ - config: config, + config: &confCopy, clients: map[unversioned.GroupVersion]*Client{}, apiPathResolverFunc: apiPathResolverFunc, } diff --git a/vendor/k8s.io/kubernetes/pkg/client/typed/dynamic/dynamic_util.go b/vendor/k8s.io/kubernetes/pkg/client/typed/dynamic/dynamic_util.go new file mode 100644 index 0000000000..bcd18b2c6d --- /dev/null +++ b/vendor/k8s.io/kubernetes/pkg/client/typed/dynamic/dynamic_util.go @@ -0,0 +1,119 @@ +/* +Copyright 2016 The Kubernetes Authors All rights reserved. + +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 dynamic + +import ( + "fmt" + + "k8s.io/kubernetes/pkg/api/meta" + "k8s.io/kubernetes/pkg/api/unversioned" + "k8s.io/kubernetes/pkg/runtime" +) + +// VersionInterfaces provides an object converter and metadata +// accessor appropriate for use with unstructured objects. +func VersionInterfaces(unversioned.GroupVersion) (*meta.VersionInterfaces, error) { + return &meta.VersionInterfaces{ + ObjectConvertor: &runtime.UnstructuredObjectConverter{}, + MetadataAccessor: meta.NewAccessor(), + }, nil +} + +// NewDiscoveryRESTMapper returns a RESTMapper based on discovery information. +func NewDiscoveryRESTMapper(resources []*unversioned.APIResourceList, versionFunc meta.VersionInterfacesFunc) (*meta.DefaultRESTMapper, error) { + rm := meta.NewDefaultRESTMapper(nil, versionFunc) + for _, resourceList := range resources { + gv, err := unversioned.ParseGroupVersion(resourceList.GroupVersion) + if err != nil { + return nil, err + } + + for _, resource := range resourceList.APIResources { + gvk := gv.WithKind(resource.Kind) + scope := meta.RESTScopeRoot + if resource.Namespaced { + scope = meta.RESTScopeNamespace + } + rm.Add(gvk, scope) + } + } + return rm, nil +} + +// ObjectTyper provides an ObjectTyper implmentation for +// runtime.Unstructured object based on discovery information. +type ObjectTyper struct { + registered map[unversioned.GroupVersionKind]bool +} + +// NewObjectTyper constructs an ObjectTyper from discovery information. +func NewObjectTyper(resources []*unversioned.APIResourceList) (runtime.ObjectTyper, error) { + ot := &ObjectTyper{registered: make(map[unversioned.GroupVersionKind]bool)} + for _, resourceList := range resources { + gv, err := unversioned.ParseGroupVersion(resourceList.GroupVersion) + if err != nil { + return nil, err + } + + for _, resource := range resourceList.APIResources { + ot.registered[gv.WithKind(resource.Kind)] = true + } + } + return ot, nil +} + +// ObjectKind returns the group,version,kind of the provided object, +// or an error if the object in not *runtime.Unstructured or has no +// group,version,kind information. +func (ot *ObjectTyper) ObjectKind(obj runtime.Object) (unversioned.GroupVersionKind, error) { + if _, ok := obj.(*runtime.Unstructured); !ok { + return unversioned.GroupVersionKind{}, fmt.Errorf("type %T is invalid for dynamic object typer", obj) + } + + return obj.GetObjectKind().GroupVersionKind(), nil +} + +// ObjectKinds returns a slice of one element with the +// group,version,kind of the provided object, or an error if the +// object is not *runtime.Unstructured or has no group,version,kind +// information. +func (ot *ObjectTyper) ObjectKinds(obj runtime.Object) ([]unversioned.GroupVersionKind, error) { + gvk, err := ot.ObjectKind(obj) + if err != nil { + return nil, err + } + + return []unversioned.GroupVersionKind{gvk}, nil +} + +// Recognizes returns true if the provided group,version,kind was in +// the discovery information. +func (ot *ObjectTyper) Recognizes(gvk unversioned.GroupVersionKind) bool { + return ot.registered[gvk] +} + +// IsUnversioned returns false always because *runtime.Unstructured +// objects should always have group,version,kind information set. ok +// will be true if the object's group,version,kind is registered. +func (ot *ObjectTyper) IsUnversioned(obj runtime.Object) (unversioned bool, ok bool) { + gvk, err := ot.ObjectKind(obj) + if err != nil { + return false, false + } + + return false, ot.registered[gvk] +} diff --git a/vendor/k8s.io/kubernetes/pkg/client/unversioned/batch.go b/vendor/k8s.io/kubernetes/pkg/client/unversioned/batch.go index c228ccf1e0..40fc49dc12 100644 --- a/vendor/k8s.io/kubernetes/pkg/client/unversioned/batch.go +++ b/vendor/k8s.io/kubernetes/pkg/client/unversioned/batch.go @@ -27,6 +27,7 @@ import ( type BatchInterface interface { JobsNamespacer + ScheduledJobsNamespacer } // BatchClient is used to interact with Kubernetes batch features. @@ -38,6 +39,10 @@ func (c *BatchClient) Jobs(namespace string) JobInterface { return newJobsV1(c, namespace) } +func (c *BatchClient) ScheduledJobs(namespace string) ScheduledJobInterface { + return newScheduledJobs(c, namespace) +} + func NewBatch(c *restclient.Config) (*BatchClient, error) { config := *c if err := setBatchDefaults(&config, nil); err != nil { diff --git a/vendor/k8s.io/kubernetes/pkg/client/unversioned/client.go b/vendor/k8s.io/kubernetes/pkg/client/unversioned/client.go index f81b41d56a..67aafe6bd4 100644 --- a/vendor/k8s.io/kubernetes/pkg/client/unversioned/client.go +++ b/vendor/k8s.io/kubernetes/pkg/client/unversioned/client.go @@ -120,6 +120,7 @@ type Client struct { *BatchClient *ExtensionsClient *AppsClient + *PolicyClient *discovery.DiscoveryClient } diff --git a/vendor/k8s.io/kubernetes/pkg/client/unversioned/clientcmd/validation.go b/vendor/k8s.io/kubernetes/pkg/client/unversioned/clientcmd/validation.go index bd1bd735e0..1690f515e9 100644 --- a/vendor/k8s.io/kubernetes/pkg/client/unversioned/clientcmd/validation.go +++ b/vendor/k8s.io/kubernetes/pkg/client/unversioned/clientcmd/validation.go @@ -260,8 +260,10 @@ func validateContext(contextName string, context clientcmdapi.Context, config cl validationErrors = append(validationErrors, fmt.Errorf("cluster %q was not found for context %q", context.Cluster, contextName)) } - if (len(context.Namespace) != 0) && !validation.IsDNS952Label(context.Namespace) { - validationErrors = append(validationErrors, fmt.Errorf("namespace %q for context %q does not conform to the kubernetes DNS952 rules", context.Namespace, contextName)) + if len(context.Namespace) != 0 { + if len(validation.IsDNS1123Label(context.Namespace)) != 0 { + validationErrors = append(validationErrors, fmt.Errorf("namespace %q for context %q does not conform to the kubernetes DNS_LABEL rules", context.Namespace, contextName)) + } } return validationErrors diff --git a/vendor/k8s.io/kubernetes/pkg/client/unversioned/doc.go b/vendor/k8s.io/kubernetes/pkg/client/unversioned/doc.go index f9c7f16e71..252d809758 100644 --- a/vendor/k8s.io/kubernetes/pkg/client/unversioned/doc.go +++ b/vendor/k8s.io/kubernetes/pkg/client/unversioned/doc.go @@ -24,8 +24,6 @@ Most consumers should use the Config object to create a Client: import ( client "k8s.io/kubernetes/pkg/client/unversioned" "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/fields" - "k8s.io/kubernetes/pkg/labels" ) [...] @@ -39,7 +37,7 @@ Most consumers should use the Config object to create a Client: if err != nil { // handle error } - pods, err := client.Pods(api.NamespaceDefault).List(labels.Everything(), fields.Everything()) + pods, err := client.Pods(api.NamespaceDefault).List(api.ListOptions{}) if err != nil { // handle error } diff --git a/vendor/k8s.io/kubernetes/pkg/client/unversioned/extensions.go b/vendor/k8s.io/kubernetes/pkg/client/unversioned/extensions.go index 6dfe46fe66..3c9114d9a8 100644 --- a/vendor/k8s.io/kubernetes/pkg/client/unversioned/extensions.go +++ b/vendor/k8s.io/kubernetes/pkg/client/unversioned/extensions.go @@ -33,6 +33,7 @@ type ExtensionsInterface interface { DeploymentsNamespacer JobsNamespacer IngressNamespacer + NetworkPolicyNamespacer ThirdPartyResourceNamespacer ReplicaSetsNamespacer PodSecurityPoliciesInterface @@ -69,6 +70,10 @@ func (c *ExtensionsClient) Ingress(namespace string) IngressInterface { return newIngress(c, namespace) } +func (c *ExtensionsClient) NetworkPolicies(namespace string) NetworkPolicyInterface { + return newNetworkPolicies(c, namespace) +} + func (c *ExtensionsClient) ThirdPartyResources() ThirdPartyResourceInterface { return newThirdPartyResources(c) } diff --git a/vendor/k8s.io/kubernetes/pkg/client/unversioned/helper.go b/vendor/k8s.io/kubernetes/pkg/client/unversioned/helper.go index 0f2d669459..058041e2cb 100644 --- a/vendor/k8s.io/kubernetes/pkg/client/unversioned/helper.go +++ b/vendor/k8s.io/kubernetes/pkg/client/unversioned/helper.go @@ -26,6 +26,7 @@ import ( "k8s.io/kubernetes/pkg/apis/autoscaling" "k8s.io/kubernetes/pkg/apis/batch" "k8s.io/kubernetes/pkg/apis/extensions" + "k8s.io/kubernetes/pkg/apis/policy" "k8s.io/kubernetes/pkg/client/restclient" "k8s.io/kubernetes/pkg/client/typed/discovery" "k8s.io/kubernetes/pkg/util/sets" @@ -85,6 +86,15 @@ func New(c *restclient.Config) (*Client, error) { return nil, err } } + var policyClient *PolicyClient + if registered.IsRegistered(policy.GroupName) { + policyConfig := *c + policyClient, err = NewPolicy(&policyConfig) + if err != nil { + return nil, err + } + } + var appsClient *AppsClient if registered.IsRegistered(apps.GroupName) { appsConfig := *c @@ -94,7 +104,7 @@ func New(c *restclient.Config) (*Client, error) { } } - return &Client{RESTClient: client, AutoscalingClient: autoscalingClient, BatchClient: batchClient, ExtensionsClient: extensionsClient, DiscoveryClient: discoveryClient, AppsClient: appsClient}, nil + return &Client{RESTClient: client, AutoscalingClient: autoscalingClient, BatchClient: batchClient, ExtensionsClient: extensionsClient, DiscoveryClient: discoveryClient, AppsClient: appsClient, PolicyClient: policyClient}, nil } // MatchesServerVersion queries the server to compares the build version diff --git a/vendor/k8s.io/kubernetes/pkg/client/unversioned/network_policys.go b/vendor/k8s.io/kubernetes/pkg/client/unversioned/network_policys.go new file mode 100644 index 0000000000..0dc9d97be8 --- /dev/null +++ b/vendor/k8s.io/kubernetes/pkg/client/unversioned/network_policys.go @@ -0,0 +1,92 @@ +/* +Copyright 2015 The Kubernetes Authors All rights reserved. + +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 unversioned + +import ( + "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/apis/extensions" + "k8s.io/kubernetes/pkg/watch" +) + +// NetworkPolicyNamespacer has methods to work with NetworkPolicy resources in a namespace +type NetworkPolicyNamespacer interface { + NetworkPolicies(namespace string) NetworkPolicyInterface +} + +// NetworkPolicyInterface exposes methods to work on NetworkPolicy resources. +type NetworkPolicyInterface interface { + List(opts api.ListOptions) (*extensions.NetworkPolicyList, error) + Get(name string) (*extensions.NetworkPolicy, error) + Create(networkPolicy *extensions.NetworkPolicy) (*extensions.NetworkPolicy, error) + Update(networkPolicy *extensions.NetworkPolicy) (*extensions.NetworkPolicy, error) + Delete(name string, options *api.DeleteOptions) error + Watch(opts api.ListOptions) (watch.Interface, error) +} + +// NetworkPolicies implements NetworkPolicyNamespacer interface +type NetworkPolicies struct { + r *ExtensionsClient + ns string +} + +// newNetworkPolicies returns a NetworkPolicies +func newNetworkPolicies(c *ExtensionsClient, namespace string) *NetworkPolicies { + return &NetworkPolicies{c, namespace} +} + +// List returns a list of networkPolicy that match the label and field selectors. +func (c *NetworkPolicies) List(opts api.ListOptions) (result *extensions.NetworkPolicyList, err error) { + result = &extensions.NetworkPolicyList{} + err = c.r.Get().Namespace(c.ns).Resource("networkpolicies").VersionedParams(&opts, api.ParameterCodec).Do().Into(result) + return +} + +// Get returns information about a particular networkPolicy. +func (c *NetworkPolicies) Get(name string) (result *extensions.NetworkPolicy, err error) { + result = &extensions.NetworkPolicy{} + err = c.r.Get().Namespace(c.ns).Resource("networkpolicies").Name(name).Do().Into(result) + return +} + +// Create creates a new networkPolicy. +func (c *NetworkPolicies) Create(networkPolicy *extensions.NetworkPolicy) (result *extensions.NetworkPolicy, err error) { + result = &extensions.NetworkPolicy{} + err = c.r.Post().Namespace(c.ns).Resource("networkpolicies").Body(networkPolicy).Do().Into(result) + return +} + +// Update updates an existing networkPolicy. +func (c *NetworkPolicies) Update(networkPolicy *extensions.NetworkPolicy) (result *extensions.NetworkPolicy, err error) { + result = &extensions.NetworkPolicy{} + err = c.r.Put().Namespace(c.ns).Resource("networkpolicies").Name(networkPolicy.Name).Body(networkPolicy).Do().Into(result) + return +} + +// Delete deletes a networkPolicy, returns error if one occurs. +func (c *NetworkPolicies) Delete(name string, options *api.DeleteOptions) (err error) { + return c.r.Delete().Namespace(c.ns).Resource("networkpolicies").Name(name).Body(options).Do().Error() +} + +// Watch returns a watch.Interface that watches the requested networkPolicy. +func (c *NetworkPolicies) Watch(opts api.ListOptions) (watch.Interface, error) { + return c.r.Get(). + Prefix("watch"). + Namespace(c.ns). + Resource("networkpolicies"). + VersionedParams(&opts, api.ParameterCodec). + Watch() +} diff --git a/vendor/k8s.io/kubernetes/pkg/client/unversioned/pod_disruption_budgets.go b/vendor/k8s.io/kubernetes/pkg/client/unversioned/pod_disruption_budgets.go new file mode 100644 index 0000000000..14f373f376 --- /dev/null +++ b/vendor/k8s.io/kubernetes/pkg/client/unversioned/pod_disruption_budgets.go @@ -0,0 +1,100 @@ +/* +Copyright 2015 The Kubernetes Authors All rights reserved. + +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 unversioned + +import ( + "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/apis/policy" + "k8s.io/kubernetes/pkg/watch" +) + +// PodDisruptionBudgetNamespacer has methods to work with PodDisruptionBudget resources in a namespace +type PodDisruptionBudgetNamespacer interface { + PodDisruptionBudgets(namespace string) PodDisruptionBudgetInterface +} + +// PodDisruptionBudgetInterface exposes methods to work on PodDisruptionBudget resources. +type PodDisruptionBudgetInterface interface { + List(opts api.ListOptions) (*policy.PodDisruptionBudgetList, error) + Get(name string) (*policy.PodDisruptionBudget, error) + Create(podDisruptionBudget *policy.PodDisruptionBudget) (*policy.PodDisruptionBudget, error) + Update(podDisruptionBudget *policy.PodDisruptionBudget) (*policy.PodDisruptionBudget, error) + Delete(name string, options *api.DeleteOptions) error + Watch(opts api.ListOptions) (watch.Interface, error) + UpdateStatus(podDisruptionBudget *policy.PodDisruptionBudget) (*policy.PodDisruptionBudget, error) +} + +// podDisruptionBudget implements PodDisruptionBudgetNamespacer interface +type podDisruptionBudget struct { + r *PolicyClient + ns string +} + +// newPodDisruptionBudget returns a podDisruptionBudget +func newPodDisruptionBudget(c *PolicyClient, namespace string) *podDisruptionBudget { + return &podDisruptionBudget{c, namespace} +} + +// List returns a list of podDisruptionBudget that match the label and field selectors. +func (c *podDisruptionBudget) List(opts api.ListOptions) (result *policy.PodDisruptionBudgetList, err error) { + result = &policy.PodDisruptionBudgetList{} + err = c.r.Get().Namespace(c.ns).Resource("poddisruptionbudgets").VersionedParams(&opts, api.ParameterCodec).Do().Into(result) + return +} + +// Get returns information about a particular podDisruptionBudget. +func (c *podDisruptionBudget) Get(name string) (result *policy.PodDisruptionBudget, err error) { + result = &policy.PodDisruptionBudget{} + err = c.r.Get().Namespace(c.ns).Resource("poddisruptionbudgets").Name(name).Do().Into(result) + return +} + +// Create creates a new podDisruptionBudget. +func (c *podDisruptionBudget) Create(podDisruptionBudget *policy.PodDisruptionBudget) (result *policy.PodDisruptionBudget, err error) { + result = &policy.PodDisruptionBudget{} + err = c.r.Post().Namespace(c.ns).Resource("poddisruptionbudgets").Body(podDisruptionBudget).Do().Into(result) + return +} + +// Update updates an existing podDisruptionBudget. +func (c *podDisruptionBudget) Update(podDisruptionBudget *policy.PodDisruptionBudget) (result *policy.PodDisruptionBudget, err error) { + result = &policy.PodDisruptionBudget{} + err = c.r.Put().Namespace(c.ns).Resource("poddisruptionbudgets").Name(podDisruptionBudget.Name).Body(podDisruptionBudget).Do().Into(result) + return +} + +// Delete deletes a podDisruptionBudget, returns error if one occurs. +func (c *podDisruptionBudget) Delete(name string, options *api.DeleteOptions) (err error) { + return c.r.Delete().Namespace(c.ns).Resource("poddisruptionbudgets").Name(name).Body(options).Do().Error() +} + +// Watch returns a watch.Interface that watches the requested podDisruptionBudget. +func (c *podDisruptionBudget) Watch(opts api.ListOptions) (watch.Interface, error) { + return c.r.Get(). + Prefix("watch"). + Namespace(c.ns). + Resource("poddisruptionbudgets"). + VersionedParams(&opts, api.ParameterCodec). + Watch() +} + +// UpdateStatus takes the name of the podDisruptionBudget and the new status. Returns the server's representation of the podDisruptionBudget, and an error, if it occurs. +func (c *podDisruptionBudget) UpdateStatus(podDisruptionBudget *policy.PodDisruptionBudget) (result *policy.PodDisruptionBudget, err error) { + result = &policy.PodDisruptionBudget{} + err = c.r.Put().Namespace(c.ns).Resource("poddisruptionbudgets").Name(podDisruptionBudget.Name).SubResource("status").Body(podDisruptionBudget).Do().Into(result) + return +} diff --git a/vendor/k8s.io/kubernetes/pkg/client/unversioned/policy.go b/vendor/k8s.io/kubernetes/pkg/client/unversioned/policy.go new file mode 100644 index 0000000000..8b06ce275a --- /dev/null +++ b/vendor/k8s.io/kubernetes/pkg/client/unversioned/policy.go @@ -0,0 +1,83 @@ +/* +Copyright 2015 The Kubernetes Authors All rights reserved. + +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 unversioned + +import ( + "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/apimachinery/registered" + "k8s.io/kubernetes/pkg/apis/policy" + "k8s.io/kubernetes/pkg/client/restclient" +) + +type PolicyInterface interface { + PodDisruptionBudgetNamespacer +} + +// PolicyClient is used to interact with Kubernetes batch features. +type PolicyClient struct { + *restclient.RESTClient +} + +func (c *PolicyClient) PodDisruptionBudgets(namespace string) PodDisruptionBudgetInterface { + return newPodDisruptionBudget(c, namespace) +} + +func NewPolicy(c *restclient.Config) (*PolicyClient, error) { + config := *c + if err := setPolicyDefaults(&config); err != nil { + return nil, err + } + client, err := restclient.RESTClientFor(&config) + if err != nil { + return nil, err + } + return &PolicyClient{client}, nil +} + +func NewPolicyOrDie(c *restclient.Config) *PolicyClient { + client, err := NewPolicy(c) + if err != nil { + panic(err) + } + return client +} + +func setPolicyDefaults(config *restclient.Config) error { + g, err := registered.Group(policy.GroupName) + if err != nil { + return err + } + config.APIPath = defaultAPIPath + if config.UserAgent == "" { + config.UserAgent = restclient.DefaultKubernetesUserAgent() + } + // TODO: Unconditionally set the config.Version, until we fix the config. + //if config.Version == "" { + copyGroupVersion := g.GroupVersion + config.GroupVersion = ©GroupVersion + //} + + config.Codec = api.Codecs.LegacyCodec(*config.GroupVersion) + config.NegotiatedSerializer = api.Codecs + if config.QPS == 0 { + config.QPS = 5 + } + if config.Burst == 0 { + config.Burst = 10 + } + return nil +} diff --git a/vendor/k8s.io/kubernetes/pkg/client/unversioned/scheduledjobs.go b/vendor/k8s.io/kubernetes/pkg/client/unversioned/scheduledjobs.go new file mode 100644 index 0000000000..d2b83fce20 --- /dev/null +++ b/vendor/k8s.io/kubernetes/pkg/client/unversioned/scheduledjobs.go @@ -0,0 +1,103 @@ +/* +Copyright 2016 The Kubernetes Authors All rights reserved. + +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 unversioned + +import ( + "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/apis/batch" + "k8s.io/kubernetes/pkg/watch" +) + +// ScheduledJobsNamespacer has methods to work with ScheduledJob resources in a namespace +type ScheduledJobsNamespacer interface { + ScheduledJobs(namespace string) ScheduledJobInterface +} + +// ScheduledJobInterface exposes methods to work on ScheduledJob resources. +type ScheduledJobInterface interface { + List(opts api.ListOptions) (*batch.ScheduledJobList, error) + Get(name string) (*batch.ScheduledJob, error) + Create(scheduledJob *batch.ScheduledJob) (*batch.ScheduledJob, error) + Update(scheduledJob *batch.ScheduledJob) (*batch.ScheduledJob, error) + Delete(name string, options *api.DeleteOptions) error + Watch(opts api.ListOptions) (watch.Interface, error) + UpdateStatus(scheduledJob *batch.ScheduledJob) (*batch.ScheduledJob, error) +} + +// scheduledJobs implements ScheduledJobsNamespacer interface +type scheduledJobs struct { + r *BatchClient + ns string +} + +// newScheduledJobs returns a scheduledJobs +func newScheduledJobs(c *BatchClient, namespace string) *scheduledJobs { + return &scheduledJobs{c, namespace} +} + +// Ensure statically that scheduledJobs implements ScheduledJobInterface. +var _ ScheduledJobInterface = &scheduledJobs{} + +// List returns a list of scheduled jobs that match the label and field selectors. +func (c *scheduledJobs) List(opts api.ListOptions) (result *batch.ScheduledJobList, err error) { + result = &batch.ScheduledJobList{} + err = c.r.Get().Namespace(c.ns).Resource("scheduledJobs").VersionedParams(&opts, api.ParameterCodec).Do().Into(result) + return +} + +// Get returns information about a particular scheduled job. +func (c *scheduledJobs) Get(name string) (result *batch.ScheduledJob, err error) { + result = &batch.ScheduledJob{} + err = c.r.Get().Namespace(c.ns).Resource("scheduledJobs").Name(name).Do().Into(result) + return +} + +// Create creates a new scheduled job. +func (c *scheduledJobs) Create(job *batch.ScheduledJob) (result *batch.ScheduledJob, err error) { + result = &batch.ScheduledJob{} + err = c.r.Post().Namespace(c.ns).Resource("scheduledJobs").Body(job).Do().Into(result) + return +} + +// Update updates an existing scheduled job. +func (c *scheduledJobs) Update(job *batch.ScheduledJob) (result *batch.ScheduledJob, err error) { + result = &batch.ScheduledJob{} + err = c.r.Put().Namespace(c.ns).Resource("scheduledJobs").Name(job.Name).Body(job).Do().Into(result) + return +} + +// Delete deletes a scheduled job, returns error if one occurs. +func (c *scheduledJobs) Delete(name string, options *api.DeleteOptions) (err error) { + return c.r.Delete().Namespace(c.ns).Resource("scheduledJobs").Name(name).Body(options).Do().Error() +} + +// Watch returns a watch.Interface that watches the requested scheduled jobs. +func (c *scheduledJobs) Watch(opts api.ListOptions) (watch.Interface, error) { + return c.r.Get(). + Prefix("watch"). + Namespace(c.ns). + Resource("scheduledJobs"). + VersionedParams(&opts, api.ParameterCodec). + Watch() +} + +// UpdateStatus takes the name of the scheduled job and the new status. Returns the server's representation of the scheduled job, and an error, if it occurs. +func (c *scheduledJobs) UpdateStatus(job *batch.ScheduledJob) (result *batch.ScheduledJob, err error) { + result = &batch.ScheduledJob{} + err = c.r.Put().Namespace(c.ns).Resource("scheduledJobs").Name(job.Name).SubResource("status").Body(job).Do().Into(result) + return +} diff --git a/vendor/k8s.io/kubernetes/pkg/cloudprovider/providers/aws/aws.go b/vendor/k8s.io/kubernetes/pkg/cloudprovider/providers/aws/aws.go index 1ecf9a7e74..3ea6dfcfd1 100644 --- a/vendor/k8s.io/kubernetes/pkg/cloudprovider/providers/aws/aws.go +++ b/vendor/k8s.io/kubernetes/pkg/cloudprovider/providers/aws/aws.go @@ -42,7 +42,7 @@ import ( "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/cloudprovider" - "k8s.io/kubernetes/pkg/credentialprovider/aws" + aws_credentials "k8s.io/kubernetes/pkg/credentialprovider/aws" "k8s.io/kubernetes/pkg/types" "github.com/golang/glog" @@ -585,21 +585,7 @@ func getAvailabilityZone(metadata EC2Metadata) (string, error) { } func isRegionValid(region string) bool { - regions := [...]string{ - "us-east-1", - "us-west-1", - "us-west-2", - "eu-west-1", - "eu-central-1", - "ap-southeast-1", - "ap-southeast-2", - "ap-northeast-1", - "ap-northeast-2", - "cn-north-1", - "us-gov-west-1", - "sa-east-1", - } - for _, r := range regions { + for _, r := range aws_credentials.AWSRegions { if r == region { return true } @@ -924,23 +910,6 @@ type awsInstanceType struct { // This should be stored as a single letter (i.e. c, not sdc or /dev/sdc) type mountDevice string -// TODO: Also return number of mounts allowed? -func (self *awsInstanceType) getEBSMountDevices() []mountDevice { - // See: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/block-device-mapping-concepts.html - // We will generate "ba", "bb", "bc"..."bz", "ca", ..., up to DefaultMaxEBSVolumes - devices := []mountDevice{} - count := 0 - for first := 'b'; count < DefaultMaxEBSVolumes; first++ { - for second := 'a'; count < DefaultMaxEBSVolumes && second <= 'z'; second++ { - device := mountDevice(fmt.Sprintf("%c%c", first, second)) - devices = append(devices, device) - count++ - } - } - - return devices -} - type awsInstance struct { ec2 EC2 @@ -1070,19 +1039,20 @@ func (self *awsInstance) getMountDevice(volumeID string, assign bool) (assigned return mountDevice(""), false, nil } - // Check all the valid mountpoints to see if any of them are free - valid := instanceType.getEBSMountDevices() - chosen := mountDevice("") - for _, mountDevice := range valid { - _, found := deviceMappings[mountDevice] - if !found { - chosen = mountDevice - break + // Find the first unused device in sequence 'ba', 'bb', 'bc', ... 'bz', 'ca', ... 'zz' + var chosen mountDevice + for first := 'b'; first <= 'z' && chosen == ""; first++ { + for second := 'a'; second <= 'z' && chosen == ""; second++ { + candidate := mountDevice(fmt.Sprintf("%c%c", first, second)) + if _, found := deviceMappings[candidate]; !found { + chosen = candidate + break + } } } if chosen == "" { - glog.Warningf("Could not assign a mount device (all in use?). mappings=%v, valid=%v", deviceMappings, valid) + glog.Warningf("Could not assign a mount device (all in use?). mappings=%v", deviceMappings) return "", false, fmt.Errorf("Too many EBS volumes attached to node %s.", self.nodeName) } diff --git a/vendor/k8s.io/kubernetes/pkg/cloudprovider/providers/vsphere/vsphere.go b/vendor/k8s.io/kubernetes/pkg/cloudprovider/providers/vsphere/vsphere.go index 0dc5f10379..7724149e59 100644 --- a/vendor/k8s.io/kubernetes/pkg/cloudprovider/providers/vsphere/vsphere.go +++ b/vendor/k8s.io/kubernetes/pkg/cloudprovider/providers/vsphere/vsphere.go @@ -41,6 +41,11 @@ import ( const ProviderName = "vsphere" const ActivePowerState = "poweredOn" +const DefaultDiskController = "scsi" +const DefaultSCSIControllerType = "lsilogic" + +var ErrNoDiskUUIDFound = errors.New("no disk UUID found") +var ErrNoDevicesFound = errors.New("No devices found") // VSphere is an implementation of cloud provider Interface for VSphere. type VSphere struct { @@ -63,6 +68,10 @@ type VSphereConfig struct { Network struct { PublicNetwork string `gcfg:"public-network"` } + Disk struct { + DiskController string `dcfg:"diskcontroller"` + SCSIControllerType string `dcfg:"scsicontrollertype"` + } } func readConfig(config io.Reader) (VSphereConfig, error) { @@ -94,6 +103,9 @@ func readInstanceID(cfg *VSphereConfig) (string, error) { if err != nil { return "", err } + if out.Len() == 0 { + return "", fmt.Errorf("unable to retrieve Instance ID") + } // Create context ctx, cancel := context.WithCancel(context.Background()) @@ -133,6 +145,12 @@ func newVSphere(cfg VSphereConfig) (*VSphere, error) { return nil, err } + if cfg.Disk.DiskController == "" { + cfg.Disk.DiskController = DefaultDiskController + } + if cfg.Disk.SCSIControllerType == "" { + cfg.Disk.SCSIControllerType = DefaultSCSIControllerType + } vs := VSphere{ cfg: &cfg, localInstanceID: id, @@ -426,3 +444,292 @@ func (vs *VSphere) Routes() (cloudprovider.Routes, bool) { func (vs *VSphere) ScrubDNS(nameservers, searches []string) (nsOut, srchOut []string) { return nameservers, searches } + +func getVirtualMachineDevices(cfg *VSphereConfig, ctx context.Context, c *govmomi.Client, name string) (*object.VirtualMachine, object.VirtualDeviceList, *object.Datastore, error) { + + // Create a new finder + f := find.NewFinder(c.Client, true) + + // Fetch and set data center + dc, err := f.Datacenter(ctx, cfg.Global.Datacenter) + if err != nil { + return nil, nil, nil, err + } + f.SetDatacenter(dc) + + // Find datastores + ds, err := f.Datastore(ctx, cfg.Global.Datastore) + if err != nil { + return nil, nil, nil, err + } + + vm, err := f.VirtualMachine(ctx, name) + if err != nil { + return nil, nil, nil, err + } + + // Get devices from VM + vmDevices, err := vm.Device(ctx) + if err != nil { + return nil, nil, nil, err + } + return vm, vmDevices, ds, nil +} + +//cleaning up the controller +func cleanUpController(newSCSIController types.BaseVirtualDevice, vmDevices object.VirtualDeviceList, vm *object.VirtualMachine, ctx context.Context) error { + ctls := vmDevices.SelectByType(newSCSIController) + if len(ctls) < 1 { + return ErrNoDevicesFound + } + newScsi := ctls[len(ctls)-1] + err := vm.RemoveDevice(ctx, true, newScsi) + if err != nil { + return err + } + return nil +} + +// Attaches given virtual disk volume to the compute running kubelet. +func (vs *VSphere) AttachDisk(vmDiskPath string, nodeName string) (diskID string, diskUUID string, err error) { + // Create context + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + // Create vSphere client + c, err := vsphereLogin(vs.cfg, ctx) + if err != nil { + return "", "", err + } + defer c.Logout(ctx) + + // Find virtual machine to attach disk to + var vSphereInstance string + if nodeName == "" { + vSphereInstance = vs.localInstanceID + } else { + vSphereInstance = nodeName + } + + // Get VM device list + vm, vmDevices, ds, err := getVirtualMachineDevices(vs.cfg, ctx, c, vSphereInstance) + if err != nil { + return "", "", err + } + + // find SCSI controller to attach the disk + var newSCSICreated bool = false + var newSCSIController types.BaseVirtualDevice + diskController, err := vmDevices.FindDiskController(vs.cfg.Disk.DiskController) + if err != nil { + // create a scsi controller if there is not one + newSCSIController, err := vmDevices.CreateSCSIController(vs.cfg.Disk.SCSIControllerType) + if err != nil { + glog.V(3).Infof("Cannot create new SCSI controller - %v", err) + return "", "", err + } + configNewSCSIController := newSCSIController.(types.BaseVirtualSCSIController).GetVirtualSCSIController() + hotAndRemove := true + configNewSCSIController.HotAddRemove = &hotAndRemove + configNewSCSIController.SharedBus = types.VirtualSCSISharing(types.VirtualSCSISharingNoSharing) + + // add the scsi controller to virtual machine + err = vm.AddDevice(context.TODO(), newSCSIController) + if err != nil { + glog.V(3).Infof("Cannot add SCSI controller to vm - %v", err) + // attempt clean up of scsi controller + if vmDevices, err := vm.Device(ctx); err == nil { + cleanUpController(newSCSIController, vmDevices, vm, ctx) + } + return "", "", err + } + + // verify scsi controller in virtual machine + vmDevices, err = vm.Device(ctx) + if err != nil { + //cannot cleanup if there is no device list + return "", "", err + } + if diskController, err = vmDevices.FindDiskController(vs.cfg.Disk.DiskController); err != nil { + glog.V(3).Infof("Cannot find disk controller - %v", err) + // attempt clean up of scsi controller + cleanUpController(newSCSIController, vmDevices, vm, ctx) + return "", "", err + } + newSCSICreated = true + } + + disk := vmDevices.CreateDisk(diskController, ds.Reference(), vmDiskPath) + backing := disk.Backing.(*types.VirtualDiskFlatVer2BackingInfo) + backing.DiskMode = string(types.VirtualDiskModeIndependent_persistent) + disk = vmDevices.ChildDisk(disk) + + // Attach disk to the VM + err = vm.AddDevice(ctx, disk) + if err != nil { + glog.V(3).Infof("Cannot add disk to the vm - %v", err) + if newSCSICreated { + cleanUpController(newSCSIController, vmDevices, vm, ctx) + } + return "", "", err + } + + vmDevices, err = vm.Device(ctx) + if err != nil { + if newSCSICreated { + cleanUpController(newSCSIController, vmDevices, vm, ctx) + } + return "", "", err + } + devices := vmDevices.SelectByType(disk) + if len(devices) < 1 { + if newSCSICreated { + cleanUpController(newSCSIController, vmDevices, vm, ctx) + } + return "", "", ErrNoDevicesFound + } + + // get new disk id + newDevice := devices[len(devices)-1] + deviceName := devices.Name(newDevice) + + // get device uuid + diskUUID, err = getVirtualDiskUUID(newDevice) + if err != nil { + if newSCSICreated { + cleanUpController(newSCSIController, vmDevices, vm, ctx) + } + vs.DetachDisk(deviceName, vSphereInstance) + return "", "", err + } + + return deviceName, diskUUID, nil +} + +func getVirtualDiskUUID(newDevice types.BaseVirtualDevice) (string, error) { + vd := newDevice.GetVirtualDevice() + + if b, ok := vd.Backing.(*types.VirtualDiskFlatVer2BackingInfo); ok { + uuidWithNoHypens := strings.Replace(b.Uuid, "-", "", -1) + return uuidWithNoHypens, nil + } + return "", ErrNoDiskUUIDFound +} + +// Detaches given virtual disk volume from the compute running kubelet. +func (vs *VSphere) DetachDisk(diskID string, nodeName string) error { + // Create context + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + // Create vSphere client + c, err := vsphereLogin(vs.cfg, ctx) + if err != nil { + return err + } + defer c.Logout(ctx) + + // Find VM to detach disk from + var vSphereInstance string + if nodeName == "" { + vSphereInstance = vs.localInstanceID + } else { + vSphereInstance = nodeName + } + + vm, vmDevices, _, err := getVirtualMachineDevices(vs.cfg, ctx, c, vSphereInstance) + if err != nil { + return err + } + + // Remove disk from VM + device := vmDevices.Find(diskID) + if device == nil { + return fmt.Errorf("device '%s' not found", diskID) + } + + err = vm.RemoveDevice(ctx, false, device) + if err != nil { + return err + } + + return nil +} + +// Create a volume of given size (in KiB). +func (vs *VSphere) CreateVolume(name string, size int, tags *map[string]string) (volumePath string, err error) { + // Create context + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + // Create vSphere client + c, err := vsphereLogin(vs.cfg, ctx) + if err != nil { + return "", err + } + defer c.Logout(ctx) + + // Create a new finder + f := find.NewFinder(c.Client, true) + + // Fetch and set data center + dc, err := f.Datacenter(ctx, vs.cfg.Global.Datacenter) + f.SetDatacenter(dc) + + // Create a virtual disk manager + vmDiskPath := "[" + vs.cfg.Global.Datastore + "] " + name + ".vmdk" + virtualDiskManager := object.NewVirtualDiskManager(c.Client) + + // Create specification for new virtual disk + vmDiskSpec := &types.FileBackedVirtualDiskSpec{ + VirtualDiskSpec: types.VirtualDiskSpec{ + AdapterType: (*tags)["adapterType"], + DiskType: (*tags)["diskType"], + }, + CapacityKb: int64(size), + } + + // Create virtual disk + task, err := virtualDiskManager.CreateVirtualDisk(ctx, vmDiskPath, dc, vmDiskSpec) + if err != nil { + return "", err + } + err = task.Wait(ctx) + if err != nil { + return "", err + } + + return vmDiskPath, nil +} + +// Deletes a volume given volume name. +func (vs *VSphere) DeleteVolume(vmDiskPath string) error { + // Create context + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + // Create vSphere client + c, err := vsphereLogin(vs.cfg, ctx) + if err != nil { + return err + } + defer c.Logout(ctx) + + // Create a new finder + f := find.NewFinder(c.Client, true) + + // Fetch and set data center + dc, err := f.Datacenter(ctx, vs.cfg.Global.Datacenter) + f.SetDatacenter(dc) + + // Create a virtual disk manager + virtualDiskManager := object.NewVirtualDiskManager(c.Client) + + // Delete virtual disk + task, err := virtualDiskManager.DeleteVirtualDisk(ctx, vmDiskPath, dc) + if err != nil { + return err + } + + return task.Wait(ctx) +} diff --git a/vendor/k8s.io/kubernetes/pkg/controller/controller_utils.go b/vendor/k8s.io/kubernetes/pkg/controller/controller_utils.go index 7945741c66..0748017346 100644 --- a/vendor/k8s.io/kubernetes/pkg/controller/controller_utils.go +++ b/vendor/k8s.io/kubernetes/pkg/controller/controller_utils.go @@ -399,7 +399,7 @@ func getPodsAnnotationSet(template *api.PodTemplateSpec, object runtime.Object) func getPodsPrefix(controllerName string) string { // use the dash (if the name isn't too long) to make the pod name a bit prettier prefix := fmt.Sprintf("%s-", controllerName) - if ok, _ := validation.ValidatePodName(prefix, true); !ok { + if len(validation.ValidatePodName(prefix, true)) != 0 { prefix = controllerName } return prefix diff --git a/vendor/k8s.io/kubernetes/pkg/controller/framework/shared_informer.go b/vendor/k8s.io/kubernetes/pkg/controller/framework/shared_informer.go index 9d9d99bcf4..ce9ddf2c71 100644 --- a/vendor/k8s.io/kubernetes/pkg/controller/framework/shared_informer.go +++ b/vendor/k8s.io/kubernetes/pkg/controller/framework/shared_informer.go @@ -57,14 +57,7 @@ type SharedIndexInformer interface { // TODO: create a cache/factory of these at a higher level for the list all, watch all of a given resource that can // be shared amongst all consumers. func NewSharedInformer(lw cache.ListerWatcher, objType runtime.Object, resyncPeriod time.Duration) SharedInformer { - sharedInformer := &sharedIndexInformer{ - processor: &sharedProcessor{}, - indexer: cache.NewIndexer(DeletionHandlingMetaNamespaceKeyFunc, cache.Indexers{}), - listerWatcher: lw, - objectType: objType, - fullResyncPeriod: resyncPeriod, - } - return sharedInformer + return NewSharedIndexInformer(lw, objType, resyncPeriod, cache.Indexers{}) } // NewSharedIndexInformer creates a new instance for the listwatcher. @@ -139,11 +132,12 @@ func (s *sharedIndexInformer) Run(stopCh <-chan struct{}) { Process: s.HandleDeltas, } - s.controller = New(cfg) func() { s.startedLock.Lock() defer s.startedLock.Unlock() + + s.controller = New(cfg) s.started = true }() @@ -158,6 +152,12 @@ func (s *sharedIndexInformer) isStarted() bool { } func (s *sharedIndexInformer) HasSynced() bool { + s.startedLock.Lock() + defer s.startedLock.Unlock() + + if s.controller == nil { + return false + } return s.controller.HasSynced() } @@ -177,17 +177,7 @@ func (s *sharedIndexInformer) AddIndexers(indexers cache.Indexers) error { return fmt.Errorf("informer has already started") } - oldIndexers := s.indexer.GetIndexers() - - for name, indexFunc := range oldIndexers { - if _, exist := indexers[name]; exist { - return fmt.Errorf("there is an index named %s already exist", name) - } - indexers[name] = indexFunc - } - - s.indexer = cache.NewIndexer(DeletionHandlingMetaNamespaceKeyFunc, indexers) - return nil + return s.indexer.AddIndexers(indexers) } func (s *sharedIndexInformer) GetController() ControllerInterface { diff --git a/vendor/k8s.io/kubernetes/pkg/controller/lookup_cache.go b/vendor/k8s.io/kubernetes/pkg/controller/lookup_cache.go index 5d82908be0..3c43e1e300 100644 --- a/vendor/k8s.io/kubernetes/pkg/controller/lookup_cache.go +++ b/vendor/k8s.io/kubernetes/pkg/controller/lookup_cache.go @@ -72,8 +72,8 @@ func (c *MatchingCache) Add(labelObj objectWithMeta, selectorObj objectWithMeta) // we need check in the external request to ensure the cache data is not dirty. func (c *MatchingCache) GetMatchingObject(labelObj objectWithMeta) (controller interface{}, exists bool) { key := keyFunc(labelObj) - c.mutex.Lock() - defer c.mutex.Unlock() + c.mutex.RLock() + defer c.mutex.RUnlock() return c.cache.Get(key) } diff --git a/vendor/k8s.io/kubernetes/pkg/controller/namespace/namespace_controller_utils.go b/vendor/k8s.io/kubernetes/pkg/controller/namespace/namespace_controller_utils.go index a48d409121..9971e3ee5e 100644 --- a/vendor/k8s.io/kubernetes/pkg/controller/namespace/namespace_controller_utils.go +++ b/vendor/k8s.io/kubernetes/pkg/controller/namespace/namespace_controller_utils.go @@ -18,7 +18,6 @@ package namespace import ( "fmt" - "strings" "time" "k8s.io/kubernetes/pkg/api" @@ -26,10 +25,8 @@ import ( "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/api/v1" clientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" - "k8s.io/kubernetes/pkg/client/typed/discovery" "k8s.io/kubernetes/pkg/client/typed/dynamic" "k8s.io/kubernetes/pkg/runtime" - utilerrors "k8s.io/kubernetes/pkg/util/errors" "k8s.io/kubernetes/pkg/util/sets" "github.com/golang/glog" @@ -452,33 +449,3 @@ func estimateGracefulTerminationForPods(kubeClient clientset.Interface, ns strin } return estimate, nil } - -// ServerPreferredNamespacedGroupVersionResources uses the specified client to discover the set of preferred groupVersionResources that are namespaced -func ServerPreferredNamespacedGroupVersionResources(discoveryClient discovery.DiscoveryInterface) ([]unversioned.GroupVersionResource, error) { - results := []unversioned.GroupVersionResource{} - serverGroupList, err := discoveryClient.ServerGroups() - if err != nil { - return results, err - } - - allErrs := []error{} - for _, apiGroup := range serverGroupList.Groups { - preferredVersion := apiGroup.PreferredVersion - apiResourceList, err := discoveryClient.ServerResourcesForGroupVersion(preferredVersion.GroupVersion) - if err != nil { - allErrs = append(allErrs, err) - continue - } - groupVersion := unversioned.GroupVersion{Group: apiGroup.Name, Version: preferredVersion.Version} - for _, apiResource := range apiResourceList.APIResources { - if !apiResource.Namespaced { - continue - } - if strings.Contains(apiResource.Name, "/") { - continue - } - results = append(results, groupVersion.WithResource(apiResource.Name)) - } - } - return results, utilerrors.NewAggregate(allErrs) -} diff --git a/vendor/k8s.io/kubernetes/pkg/controller/node/cidr_allocator.go b/vendor/k8s.io/kubernetes/pkg/controller/node/cidr_allocator.go new file mode 100644 index 0000000000..4bb4a2503d --- /dev/null +++ b/vendor/k8s.io/kubernetes/pkg/controller/node/cidr_allocator.go @@ -0,0 +1,157 @@ +/* +Copyright 2016 The Kubernetes Authors All rights reserved. + +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 node + +import ( + "encoding/binary" + "errors" + "fmt" + "math/big" + "net" + "sync" +) + +var errCIDRRangeNoCIDRsRemaining = errors.New("CIDR allocation failed; there are no remaining CIDRs left to allocate in the accepted range") + +// CIDRAllocator is an interface implemented by things that know how to allocate/occupy/recycle CIDR for nodes. +type CIDRAllocator interface { + AllocateNext() (*net.IPNet, error) + Occupy(*net.IPNet) error + Release(*net.IPNet) error +} + +type rangeAllocator struct { + clusterCIDR *net.IPNet + clusterIP net.IP + clusterMaskSize int + subNetMaskSize int + maxCIDRs int + used big.Int + lock sync.Mutex +} + +// NewCIDRRangeAllocator returns a CIDRAllocator to allocate CIDR for node +// Caller must ensure subNetMaskSize is not less than cluster CIDR mask size. +func NewCIDRRangeAllocator(clusterCIDR *net.IPNet, subNetMaskSize int) CIDRAllocator { + clusterMask := clusterCIDR.Mask + clusterMaskSize, _ := clusterMask.Size() + + ra := &rangeAllocator{ + clusterCIDR: clusterCIDR, + clusterIP: clusterCIDR.IP.To4(), + clusterMaskSize: clusterMaskSize, + subNetMaskSize: subNetMaskSize, + maxCIDRs: 1 << uint32(subNetMaskSize-clusterMaskSize), + } + return ra +} + +func (r *rangeAllocator) AllocateNext() (*net.IPNet, error) { + r.lock.Lock() + defer r.lock.Unlock() + + nextUnused := -1 + for i := 0; i < r.maxCIDRs; i++ { + if r.used.Bit(i) == 0 { + nextUnused = i + break + } + } + if nextUnused == -1 { + return nil, errCIDRRangeNoCIDRsRemaining + } + + r.used.SetBit(&r.used, nextUnused, 1) + + j := uint32(nextUnused) << uint32(32-r.subNetMaskSize) + ipInt := (binary.BigEndian.Uint32(r.clusterIP)) | j + ip := make([]byte, 4) + binary.BigEndian.PutUint32(ip, ipInt) + + return &net.IPNet{ + IP: ip, + Mask: net.CIDRMask(r.subNetMaskSize, 32), + }, nil +} + +func (r *rangeAllocator) Release(cidr *net.IPNet) error { + used, err := r.getIndexForCIDR(cidr) + if err != nil { + return err + } + + r.lock.Lock() + defer r.lock.Unlock() + r.used.SetBit(&r.used, used, 0) + + return nil +} + +func (r *rangeAllocator) MaxCIDRs() int { + return r.maxCIDRs +} + +func (r *rangeAllocator) Occupy(cidr *net.IPNet) (err error) { + begin, end := 0, r.maxCIDRs + cidrMask := cidr.Mask + maskSize, _ := cidrMask.Size() + + if !r.clusterCIDR.Contains(cidr.IP.Mask(r.clusterCIDR.Mask)) && !cidr.Contains(r.clusterCIDR.IP.Mask(cidr.Mask)) { + return fmt.Errorf("cidr %v is out the range of cluster cidr %v", cidr, r.clusterCIDR) + } + + if r.clusterMaskSize < maskSize { + subNetMask := net.CIDRMask(r.subNetMaskSize, 32) + begin, err = r.getIndexForCIDR(&net.IPNet{ + IP: cidr.IP.To4().Mask(subNetMask), + Mask: subNetMask, + }) + if err != nil { + return err + } + + ip := make([]byte, 4) + ipInt := binary.BigEndian.Uint32(cidr.IP) | (^binary.BigEndian.Uint32(cidr.Mask)) + binary.BigEndian.PutUint32(ip, ipInt) + end, err = r.getIndexForCIDR(&net.IPNet{ + IP: net.IP(ip).To4().Mask(subNetMask), + Mask: subNetMask, + }) + if err != nil { + return err + } + } + + r.lock.Lock() + defer r.lock.Unlock() + + for i := begin; i <= end; i++ { + r.used.SetBit(&r.used, i, 1) + } + + return nil +} + +func (r *rangeAllocator) getIndexForCIDR(cidr *net.IPNet) (int, error) { + cidrIndex := (binary.BigEndian.Uint32(r.clusterIP) ^ binary.BigEndian.Uint32(cidr.IP.To4())) >> uint32(32-r.subNetMaskSize) + + if cidrIndex >= uint32(r.maxCIDRs) { + return 0, fmt.Errorf("CIDR: %v is out of the range of CIDR allocator", cidr) + } + + return int(cidrIndex), nil +} diff --git a/vendor/k8s.io/kubernetes/pkg/controller/node/nodecontroller.go b/vendor/k8s.io/kubernetes/pkg/controller/node/nodecontroller.go index af87c36883..804ce745c1 100644 --- a/vendor/k8s.io/kubernetes/pkg/controller/node/nodecontroller.go +++ b/vendor/k8s.io/kubernetes/pkg/controller/node/nodecontroller.go @@ -44,6 +44,7 @@ import ( "k8s.io/kubernetes/pkg/util/metrics" utilruntime "k8s.io/kubernetes/pkg/util/runtime" "k8s.io/kubernetes/pkg/util/sets" + "k8s.io/kubernetes/pkg/util/system" "k8s.io/kubernetes/pkg/util/wait" "k8s.io/kubernetes/pkg/version" "k8s.io/kubernetes/pkg/watch" @@ -56,6 +57,8 @@ var ( const ( // nodeStatusUpdateRetry controls the number of retries of writing NodeStatus update. nodeStatusUpdateRetry = 5 + // podCIDRUpdateRetry controls the number of retries of writing Node.Spec.PodCIDR update. + podCIDRUpdateRetry = 5 // controls how often NodeController will try to evict Pods from non-responsive Nodes. nodeEvictionPeriod = 100 * time.Millisecond ) @@ -70,6 +73,7 @@ type NodeController struct { allocateNodeCIDRs bool cloud cloudprovider.Interface clusterCIDR *net.IPNet + serviceCIDR *net.IPNet deletingPodsRateLimiter flowcontrol.RateLimiter knownNodeSet sets.String kubeClient clientset.Interface @@ -120,9 +124,16 @@ type NodeController struct { // DaemonSet framework and store daemonSetController *framework.Controller daemonSetStore cache.StoreToDaemonSetLister + // allocate/recycle CIDRs for node if allocateNodeCIDRs == true + cidrAllocator CIDRAllocator forcefullyDeletePod func(*api.Pod) error nodeExistsInCloudProvider func(string) (bool, error) + + // If in network segmentation mode NodeController won't evict Pods from unhealthy Nodes. + // It is enabled when all Nodes observed by the NodeController are NotReady and disabled + // when NC sees any healthy Node. This is a temporary fix for v1.3. + networkSegmentationMode bool } // NewNodeController returns a new node controller to sync instances from cloudprovider. @@ -136,23 +147,31 @@ func NewNodeController( nodeStartupGracePeriod time.Duration, nodeMonitorPeriod time.Duration, clusterCIDR *net.IPNet, + serviceCIDR *net.IPNet, + nodeCIDRMaskSize int, allocateNodeCIDRs bool) *NodeController { eventBroadcaster := record.NewBroadcaster() recorder := eventBroadcaster.NewRecorder(api.EventSource{Component: "controllermanager"}) eventBroadcaster.StartLogging(glog.Infof) if kubeClient != nil { - glog.Infof("Sending events to api server.") + glog.V(0).Infof("Sending events to api server.") eventBroadcaster.StartRecordingToSink(&unversionedcore.EventSinkImpl{Interface: kubeClient.Core().Events("")}) } else { - glog.Infof("No api server defined - no events will be sent to API server.") + glog.V(0).Infof("No api server defined - no events will be sent to API server.") } if kubeClient != nil && kubeClient.Core().GetRESTClient().GetRateLimiter() != nil { metrics.RegisterMetricAndTrackRateLimiterUsage("node_controller", kubeClient.Core().GetRESTClient().GetRateLimiter()) } - if allocateNodeCIDRs && clusterCIDR == nil { - glog.Fatal("NodeController: Must specify clusterCIDR if allocateNodeCIDRs == true.") + if allocateNodeCIDRs { + if clusterCIDR == nil { + glog.Fatal("NodeController: Must specify clusterCIDR if allocateNodeCIDRs == true.") + } + mask := clusterCIDR.Mask + if maskSize, _ := mask.Size(); maskSize > nodeCIDRMaskSize { + glog.Fatal("NodeController: Invalid clusterCIDR, mask size of clusterCIDR must be less than nodeCIDRMaskSize.") + } } evictorLock := sync.Mutex{} @@ -173,6 +192,7 @@ func NewNodeController( lookupIP: net.LookupIP, now: unversioned.Now, clusterCIDR: clusterCIDR, + serviceCIDR: serviceCIDR, allocateNodeCIDRs: allocateNodeCIDRs, forcefullyDeletePod: func(p *api.Pod) error { return forcefullyDeletePod(kubeClient, p) }, nodeExistsInCloudProvider: func(nodeName string) (bool, error) { return nodeExistsInCloudProvider(cloud, nodeName) }, @@ -198,6 +218,15 @@ func NewNodeController( // they'll get the benefits they expect. It will also reserve the name for future refactorings. cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, ) + + nodeEventHandlerFuncs := framework.ResourceEventHandlerFuncs{} + if nc.allocateNodeCIDRs { + nodeEventHandlerFuncs = framework.ResourceEventHandlerFuncs{ + AddFunc: nc.allocateOrOccupyCIDR, + DeleteFunc: nc.recycleCIDR, + } + } + nc.nodeStore.Store, nc.nodeController = framework.NewInformer( &cache.ListWatch{ ListFunc: func(options api.ListOptions) (runtime.Object, error) { @@ -209,8 +238,9 @@ func NewNodeController( }, &api.Node{}, controller.NoResyncPeriodFunc(), - framework.ResourceEventHandlerFuncs{}, + nodeEventHandlerFuncs, ) + nc.daemonSetStore.Store, nc.daemonSetController = framework.NewInformer( &cache.ListWatch{ ListFunc: func(options api.ListOptions) (runtime.Object, error) { @@ -224,11 +254,20 @@ func NewNodeController( controller.NoResyncPeriodFunc(), framework.ResourceEventHandlerFuncs{}, ) + + if allocateNodeCIDRs { + nc.cidrAllocator = NewCIDRRangeAllocator(clusterCIDR, nodeCIDRMaskSize) + } + return nc } // Run starts an asynchronous loop that monitors the status of cluster nodes. func (nc *NodeController) Run(period time.Duration) { + if nc.allocateNodeCIDRs { + nc.filterOutServiceRange() + } + go nc.nodeController.Run(wait.NeverStop) go nc.podController.Run(wait.NeverStop) go nc.daemonSetController.Run(wait.NeverStop) @@ -282,7 +321,7 @@ func (nc *NodeController) Run(period time.Duration) { } if completed { - glog.Infof("All pods terminated on %s", value.Value) + glog.V(2).Infof("All pods terminated on %s", value.Value) nc.recordNodeEvent(value.Value, api.EventTypeNormal, "TerminatedAllPods", fmt.Sprintf("Terminated all Pods on Node %s.", value.Value)) return true, 0 } @@ -299,17 +338,78 @@ func (nc *NodeController) Run(period time.Duration) { go wait.Until(nc.cleanupOrphanedPods, 30*time.Second, wait.NeverStop) } -// Generates num pod CIDRs that could be assigned to nodes. -func generateCIDRs(clusterCIDR *net.IPNet, num int) sets.String { - res := sets.NewString() - cidrIP := clusterCIDR.IP.To4() - for i := 0; i < num; i++ { - // TODO: Make the CIDRs configurable. - b1 := byte(i >> 8) - b2 := byte(i % 256) - res.Insert(fmt.Sprintf("%d.%d.%d.0/24", cidrIP[0], cidrIP[1]+b1, cidrIP[2]+b2)) +func (nc *NodeController) filterOutServiceRange() { + if !nc.clusterCIDR.Contains(nc.serviceCIDR.IP.Mask(nc.clusterCIDR.Mask)) && !nc.serviceCIDR.Contains(nc.clusterCIDR.IP.Mask(nc.serviceCIDR.Mask)) { + return + } + + if err := nc.cidrAllocator.Occupy(nc.serviceCIDR); err != nil { + glog.Errorf("Error filtering out service cidr: %v", err) + } +} + +// allocateOrOccupyCIDR looks at each new observed node, assigns it a valid CIDR +// if it doesn't currently have one or mark the CIDR as used if the node already have one. +func (nc *NodeController) allocateOrOccupyCIDR(obj interface{}) { + node := obj.(*api.Node) + + if node.Spec.PodCIDR != "" { + _, podCIDR, err := net.ParseCIDR(node.Spec.PodCIDR) + if err != nil { + glog.Errorf("failed to parse node %s, CIDR %s", node.Name, node.Spec.PodCIDR) + return + } + if err := nc.cidrAllocator.Occupy(podCIDR); err != nil { + glog.Errorf("failed to mark cidr as occupied :%v", err) + return + } + return + } + + podCIDR, err := nc.cidrAllocator.AllocateNext() + if err != nil { + nc.recordNodeStatusChange(node, "CIDRNotAvailable") + return + } + + glog.V(4).Infof("Assigning node %s CIDR %s", node.Name, podCIDR) + for rep := 0; rep < podCIDRUpdateRetry; rep++ { + node.Spec.PodCIDR = podCIDR.String() + if _, err := nc.kubeClient.Core().Nodes().Update(node); err == nil { + glog.Errorf("Failed while updating Node.Spec.PodCIDR : %v", err) + break + } + node, err = nc.kubeClient.Core().Nodes().Get(node.Name) + if err != nil { + glog.Errorf("Failed while getting node %v to retry updating Node.Spec.PodCIDR: %v", node.Name, err) + break + } + } + if err != nil { + glog.Errorf("Update PodCIDR of node %v from NodeController exceeds retry count.", node.Name) + nc.recordNodeStatusChange(node, "CIDRAssignmentFailed") + glog.Errorf("CIDR assignment for node %v failed: %v", node.Name, err) + } +} + +// recycleCIDR recycles the CIDR of a removed node +func (nc *NodeController) recycleCIDR(obj interface{}) { + node := obj.(*api.Node) + + if node.Spec.PodCIDR == "" { + return + } + + _, podCIDR, err := net.ParseCIDR(node.Spec.PodCIDR) + if err != nil { + glog.Errorf("failed to parse node %s, CIDR %s", node.Name, node.Spec.PodCIDR) + return + } + + glog.V(4).Infof("recycle node %s CIDR %s", node.Name, podCIDR) + if err := nc.cidrAllocator.Release(podCIDR); err != nil { + glog.Errorf("failed to release cidr: %v", err) } - return res } // getCondition returns a condition object for the specific condition @@ -371,7 +471,7 @@ func (nc *NodeController) maybeDeleteTerminatingPod(obj interface{}) { node := nodeObj.(*api.Node) v, err := version.Parse(node.Status.NodeInfo.KubeletVersion) if err != nil { - glog.Infof("couldn't parse verions %q of minion: %v", node.Status.NodeInfo.KubeletVersion, err) + glog.V(0).Infof("couldn't parse verions %q of minion: %v", node.Status.NodeInfo.KubeletVersion, err) utilruntime.HandleError(nc.forcefullyDeletePod(pod)) return } @@ -407,7 +507,7 @@ func forcefullyDeletePod(c clientset.Interface, pod *api.Pod) error { var zero int64 err := c.Core().Pods(pod.Namespace).Delete(pod.Name, &api.DeleteOptions{GracePeriodSeconds: &zero}) if err == nil { - glog.Infof("forceful deletion of %s succeeded", pod.Name) + glog.V(4).Infof("forceful deletion of %s succeeded", pod.Name) } return err } @@ -444,18 +544,14 @@ func (nc *NodeController) monitorNodeStatus() error { } } - if nc.allocateNodeCIDRs { - // TODO (cjcullen): Use pkg/controller/framework to watch nodes and - // reduce lists/decouple this from monitoring status. - nc.reconcileNodeCIDRs(nodes) - } + seenReady := false for i := range nodes.Items { var gracePeriod time.Duration - var lastReadyCondition api.NodeCondition - var readyCondition *api.NodeCondition + var observedReadyCondition api.NodeCondition + var currentReadyCondition *api.NodeCondition node := &nodes.Items[i] for rep := 0; rep < nodeStatusUpdateRetry; rep++ { - gracePeriod, lastReadyCondition, readyCondition, err = nc.tryUpdateNodeStatus(node) + gracePeriod, observedReadyCondition, currentReadyCondition, err = nc.tryUpdateNodeStatus(node) if err == nil { break } @@ -474,28 +570,32 @@ func (nc *NodeController) monitorNodeStatus() error { decisionTimestamp := nc.now() - if readyCondition != nil { + if currentReadyCondition != nil { // Check eviction timeout against decisionTimestamp - if lastReadyCondition.Status == api.ConditionFalse && + if observedReadyCondition.Status == api.ConditionFalse && decisionTimestamp.After(nc.nodeStatusMap[node.Name].readyTransitionTimestamp.Add(nc.podEvictionTimeout)) { if nc.evictPods(node.Name) { glog.V(4).Infof("Evicting pods on node %s: %v is later than %v + %v", node.Name, decisionTimestamp, nc.nodeStatusMap[node.Name].readyTransitionTimestamp, nc.podEvictionTimeout) } } - if lastReadyCondition.Status == api.ConditionUnknown && + if observedReadyCondition.Status == api.ConditionUnknown && decisionTimestamp.After(nc.nodeStatusMap[node.Name].probeTimestamp.Add(nc.podEvictionTimeout)) { if nc.evictPods(node.Name) { glog.V(4).Infof("Evicting pods on node %s: %v is later than %v + %v", node.Name, decisionTimestamp, nc.nodeStatusMap[node.Name].readyTransitionTimestamp, nc.podEvictionTimeout-gracePeriod) } } - if lastReadyCondition.Status == api.ConditionTrue { + if observedReadyCondition.Status == api.ConditionTrue { + // We do not treat a master node as a part of the cluster for network segmentation checking. + if !system.IsMasterNode(node) { + seenReady = true + } if nc.cancelPodEviction(node.Name) { glog.V(2).Infof("Node %s is ready again, cancelled pod eviction", node.Name) } } // Report node event. - if readyCondition.Status != api.ConditionTrue && lastReadyCondition.Status == api.ConditionTrue { + if currentReadyCondition.Status != api.ConditionTrue && observedReadyCondition.Status == api.ConditionTrue { nc.recordNodeStatusChange(node, "NodeNotReady") if err = nc.markAllPodsNotReady(node.Name); err != nil { utilruntime.HandleError(fmt.Errorf("Unable to mark all pods NotReady on node %v: %v", node.Name, err)) @@ -504,14 +604,14 @@ func (nc *NodeController) monitorNodeStatus() error { // Check with the cloud provider to see if the node still exists. If it // doesn't, delete the node immediately. - if readyCondition.Status != api.ConditionTrue && nc.cloud != nil { + if currentReadyCondition.Status != api.ConditionTrue && nc.cloud != nil { exists, err := nc.nodeExistsInCloudProvider(node.Name) if err != nil { glog.Errorf("Error determining if node %v exists in cloud: %v", node.Name, err) continue } if !exists { - glog.Infof("Deleting node (no longer present in cloud provider): %s", node.Name) + glog.V(2).Infof("Deleting node (no longer present in cloud provider): %s", node.Name) nc.recordNodeEvent(node.Name, api.EventTypeNormal, "DeletingNode", fmt.Sprintf("Deleting Node %v because it's not present according to cloud provider", node.Name)) go func(nodeName string) { defer utilruntime.HandleCrash() @@ -527,6 +627,20 @@ func (nc *NodeController) monitorNodeStatus() error { } } } + + // NC don't see any Ready Node. We assume that the network is segmented and Nodes cannot connect to API server and + // update their statuses. NC enteres network segmentation mode and cancels all evictions in progress. + if !seenReady { + nc.networkSegmentationMode = true + nc.stopAllPodEvictions() + glog.V(2).Info("NodeController is entering network segmentation mode.") + } else { + if nc.networkSegmentationMode { + nc.forceUpdateAllProbeTimes() + nc.networkSegmentationMode = false + glog.V(2).Info("NodeController exited network segmentation mode.") + } + } return nil } @@ -567,42 +681,6 @@ func (nc *NodeController) forcefullyDeleteNode(nodeName string) error { return nil } -// reconcileNodeCIDRs looks at each node and assigns it a valid CIDR -// if it doesn't currently have one. -func (nc *NodeController) reconcileNodeCIDRs(nodes *api.NodeList) { - glog.V(4).Infof("Reconciling cidrs for %d nodes", len(nodes.Items)) - // TODO(roberthbailey): This seems inefficient. Why re-calculate CIDRs - // on each sync period? - availableCIDRs := generateCIDRs(nc.clusterCIDR, len(nodes.Items)) - for _, node := range nodes.Items { - if node.Spec.PodCIDR != "" { - glog.V(4).Infof("CIDR %s is already being used by node %s", node.Spec.PodCIDR, node.Name) - availableCIDRs.Delete(node.Spec.PodCIDR) - } - } - for _, node := range nodes.Items { - if node.Spec.PodCIDR == "" { - // Re-GET node (because ours might be stale by now). - n, err := nc.kubeClient.Core().Nodes().Get(node.Name) - if err != nil { - glog.Errorf("Failed to get node %q: %v", node.Name, err) - continue - } - podCIDR, found := availableCIDRs.PopAny() - if !found { - nc.recordNodeStatusChange(n, "CIDRNotAvailable") - continue - } - glog.V(1).Infof("Assigning node %s CIDR %s", n.Name, podCIDR) - n.Spec.PodCIDR = podCIDR - if _, err := nc.kubeClient.Core().Nodes().Update(n); err != nil { - nc.recordNodeStatusChange(&node, "CIDRAssignmentFailed") - } - } - - } -} - func (nc *NodeController) recordNodeEvent(nodeName, eventtype, reason, event string) { ref := &api.ObjectReference{ Kind: "Node", @@ -632,13 +710,13 @@ func (nc *NodeController) recordNodeStatusChange(node *api.Node, new_status stri func (nc *NodeController) tryUpdateNodeStatus(node *api.Node) (time.Duration, api.NodeCondition, *api.NodeCondition, error) { var err error var gracePeriod time.Duration - var lastReadyCondition api.NodeCondition - readyCondition := nc.getCondition(&node.Status, api.NodeReady) - if readyCondition == nil { + var observedReadyCondition api.NodeCondition + currentReadyCondition := nc.getCondition(&node.Status, api.NodeReady) + if currentReadyCondition == nil { // If ready condition is nil, then kubelet (or nodecontroller) never posted node status. // A fake ready condition is created, where LastProbeTime and LastTransitionTime is set // to node.CreationTimestamp to avoid handle the corner case. - lastReadyCondition = api.NodeCondition{ + observedReadyCondition = api.NodeCondition{ Type: api.NodeReady, Status: api.ConditionUnknown, LastHeartbeatTime: node.CreationTimestamp, @@ -652,7 +730,7 @@ func (nc *NodeController) tryUpdateNodeStatus(node *api.Node) (time.Duration, ap } } else { // If ready condition is not nil, make a copy of it, since we may modify it in place later. - lastReadyCondition = *readyCondition + observedReadyCondition = *currentReadyCondition gracePeriod = nc.nodeMonitorGracePeriod } @@ -683,7 +761,6 @@ func (nc *NodeController) tryUpdateNodeStatus(node *api.Node) (time.Duration, ap probeTimestamp: nc.now(), readyTransitionTimestamp: nc.now(), } - nc.nodeStatusMap[node.Name] = savedNodeStatus } else if savedCondition == nil && observedCondition != nil { glog.V(1).Infof("Creating timestamp entry for newly observed Node %s", node.Name) savedNodeStatus = nodeStatusData{ @@ -691,7 +768,6 @@ func (nc *NodeController) tryUpdateNodeStatus(node *api.Node) (time.Duration, ap probeTimestamp: nc.now(), readyTransitionTimestamp: nc.now(), } - nc.nodeStatusMap[node.Name] = savedNodeStatus } else if savedCondition != nil && observedCondition == nil { glog.Errorf("ReadyCondition was removed from Status of Node %s", node.Name) // TODO: figure out what to do in this case. For now we do the same thing as above. @@ -700,7 +776,6 @@ func (nc *NodeController) tryUpdateNodeStatus(node *api.Node) (time.Duration, ap probeTimestamp: nc.now(), readyTransitionTimestamp: nc.now(), } - nc.nodeStatusMap[node.Name] = savedNodeStatus } else if savedCondition != nil && observedCondition != nil && savedCondition.LastHeartbeatTime != observedCondition.LastHeartbeatTime { var transitionTime unversioned.Time // If ReadyCondition changed since the last time we checked, we update the transition timestamp to "now", @@ -713,7 +788,7 @@ func (nc *NodeController) tryUpdateNodeStatus(node *api.Node) (time.Duration, ap transitionTime = savedNodeStatus.readyTransitionTimestamp } if glog.V(5) { - glog.Infof("Node %s ReadyCondition updated. Updating timestamp: %+v vs %+v.", node.Name, savedNodeStatus.status, node.Status) + glog.V(5).Infof("Node %s ReadyCondition updated. Updating timestamp: %+v vs %+v.", node.Name, savedNodeStatus.status, node.Status) } else { glog.V(3).Infof("Node %s ReadyCondition updated. Updating timestamp.", node.Name) } @@ -722,13 +797,13 @@ func (nc *NodeController) tryUpdateNodeStatus(node *api.Node) (time.Duration, ap probeTimestamp: nc.now(), readyTransitionTimestamp: transitionTime, } - nc.nodeStatusMap[node.Name] = savedNodeStatus } + nc.nodeStatusMap[node.Name] = savedNodeStatus if nc.now().After(savedNodeStatus.probeTimestamp.Add(gracePeriod)) { // NodeReady condition was last set longer ago than gracePeriod, so update it to Unknown // (regardless of its current value) in the master. - if readyCondition == nil { + if currentReadyCondition == nil { glog.V(2).Infof("node %v is never updated by kubelet", node.Name) node.Status.Conditions = append(node.Status.Conditions, api.NodeCondition{ Type: api.NodeReady, @@ -740,14 +815,14 @@ func (nc *NodeController) tryUpdateNodeStatus(node *api.Node) (time.Duration, ap }) } else { glog.V(4).Infof("node %v hasn't been updated for %+v. Last ready condition is: %+v", - node.Name, nc.now().Time.Sub(savedNodeStatus.probeTimestamp.Time), lastReadyCondition) - if lastReadyCondition.Status != api.ConditionUnknown { - readyCondition.Status = api.ConditionUnknown - readyCondition.Reason = "NodeStatusUnknown" - readyCondition.Message = fmt.Sprintf("Kubelet stopped posting node status.") + node.Name, nc.now().Time.Sub(savedNodeStatus.probeTimestamp.Time), observedReadyCondition) + if observedReadyCondition.Status != api.ConditionUnknown { + currentReadyCondition.Status = api.ConditionUnknown + currentReadyCondition.Reason = "NodeStatusUnknown" + currentReadyCondition.Message = fmt.Sprintf("Kubelet stopped posting node status.") // LastProbeTime is the last time we heard from kubelet. - readyCondition.LastHeartbeatTime = lastReadyCondition.LastHeartbeatTime - readyCondition.LastTransitionTime = nc.now() + currentReadyCondition.LastHeartbeatTime = observedReadyCondition.LastHeartbeatTime + currentReadyCondition.LastTransitionTime = nc.now() } } @@ -776,27 +851,41 @@ func (nc *NodeController) tryUpdateNodeStatus(node *api.Node) (time.Duration, ap } } - if !api.Semantic.DeepEqual(nc.getCondition(&node.Status, api.NodeReady), &lastReadyCondition) { + if !api.Semantic.DeepEqual(nc.getCondition(&node.Status, api.NodeReady), &observedReadyCondition) { if _, err = nc.kubeClient.Core().Nodes().UpdateStatus(node); err != nil { glog.Errorf("Error updating node %s: %v", node.Name, err) - return gracePeriod, lastReadyCondition, readyCondition, err + return gracePeriod, observedReadyCondition, currentReadyCondition, err } else { nc.nodeStatusMap[node.Name] = nodeStatusData{ status: node.Status, probeTimestamp: nc.nodeStatusMap[node.Name].probeTimestamp, readyTransitionTimestamp: nc.now(), } - return gracePeriod, lastReadyCondition, readyCondition, nil + return gracePeriod, observedReadyCondition, currentReadyCondition, nil } } } - return gracePeriod, lastReadyCondition, readyCondition, err + return gracePeriod, observedReadyCondition, currentReadyCondition, err +} + +// forceUpdateAllProbeTimes bumps all observed timestamps in saved nodeStatuses to now. This makes +// all eviction timer to reset. +func (nc *NodeController) forceUpdateAllProbeTimes() { + now := nc.now() + for k, v := range nc.nodeStatusMap { + v.probeTimestamp = now + v.readyTransitionTimestamp = now + nc.nodeStatusMap[k] = v + } } // evictPods queues an eviction for the provided node name, and returns false if the node is already // queued for eviction. func (nc *NodeController) evictPods(nodeName string) bool { + if nc.networkSegmentationMode { + return false + } nc.evictorLock.Lock() defer nc.evictorLock.Unlock() return nc.podEvictor.Add(nodeName) @@ -816,6 +905,15 @@ func (nc *NodeController) cancelPodEviction(nodeName string) bool { return false } +// stopAllPodEvictions removes any queued evictions for all Nodes. +func (nc *NodeController) stopAllPodEvictions() { + nc.evictorLock.Lock() + defer nc.evictorLock.Unlock() + glog.V(3).Infof("Cancelling all pod evictions.") + nc.podEvictor.Clear() + nc.terminationEvictor.Clear() +} + // deletePods will delete all pods from master running on given node, and return true // if any pods were deleted. func (nc *NodeController) deletePods(nodeName string) (bool, error) { diff --git a/vendor/k8s.io/kubernetes/pkg/controller/node/rate_limited_queue.go b/vendor/k8s.io/kubernetes/pkg/controller/node/rate_limited_queue.go index a3f0075655..a2865418fb 100644 --- a/vendor/k8s.io/kubernetes/pkg/controller/node/rate_limited_queue.go +++ b/vendor/k8s.io/kubernetes/pkg/controller/node/rate_limited_queue.go @@ -133,6 +133,18 @@ func (q *UniqueQueue) Head() (TimedValue, bool) { return *result, true } +// Clear removes all items from the queue and duplication preventing set. +func (q *UniqueQueue) Clear() { + q.lock.Lock() + defer q.lock.Unlock() + if q.queue.Len() > 0 { + q.queue = make(TimedQueue, 0) + } + if len(q.set) > 0 { + q.set = sets.NewString() + } +} + // RateLimitedTimedQueue is a unique item priority queue ordered by the expected next time // of execution. It is also rate limited. type RateLimitedTimedQueue struct { @@ -199,3 +211,8 @@ func (q *RateLimitedTimedQueue) Add(value string) bool { func (q *RateLimitedTimedQueue) Remove(value string) bool { return q.queue.Remove(value) } + +// Removes all items from the queue +func (q *RateLimitedTimedQueue) Clear() { + q.queue.Clear() +} diff --git a/vendor/k8s.io/kubernetes/pkg/controller/persistentvolume/controller.go b/vendor/k8s.io/kubernetes/pkg/controller/persistentvolume/controller.go new file mode 100644 index 0000000000..eb499fc89b --- /dev/null +++ b/vendor/k8s.io/kubernetes/pkg/controller/persistentvolume/controller.go @@ -0,0 +1,1224 @@ +/* +Copyright 2016 The Kubernetes Authors All rights reserved. + +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 persistentvolume + +import ( + "fmt" + "sync" + "time" + + "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/client/cache" + clientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" + "k8s.io/kubernetes/pkg/client/record" + "k8s.io/kubernetes/pkg/cloudprovider" + "k8s.io/kubernetes/pkg/controller/framework" + "k8s.io/kubernetes/pkg/conversion" + vol "k8s.io/kubernetes/pkg/volume" + + "github.com/golang/glog" +) + +// Design: +// +// The fundamental key to this design is the bi-directional "pointer" between +// PersistentVolumes (PVs) and PersistentVolumeClaims (PVCs), which is +// represented here as pvc.Spec.VolumeName and pv.Spec.ClaimRef. The bi-directionality +// is complicated to manage in a transactionless system, but without it we +// can't ensure sane behavior in the face of different forms of trouble. For +// example, a rogue HA controller instance could end up racing and making +// multiple bindings that are indistinguishable, resulting in potential data +// loss. +// +// This controller is designed to work in active-passive high availability mode. +// It *could* work also in active-active HA mode, all the object transitions are +// designed to cope with this, however performance could be lower as these two +// active controllers will step on each other toes frequently. +// +// This controller supports pre-bound (by the creator) objects in both +// directions: a PVC that wants a specific PV or a PV that is reserved for a +// specific PVC. +// +// The binding is two-step process. PV.Spec.ClaimRef is modified first and +// PVC.Spec.VolumeName second. At any point of this transaction, the PV or PVC +// can be modified by user or other controller or completelly deleted. Also, two +// (or more) controllers may try to bind different volumes to different claims +// at the same time. The controller must recover from any conflicts that may +// arise from these conditions. + +// annBindCompleted annotation applies to PVCs. It indicates that the lifecycle +// of the PVC has passed through the initial setup. This information changes how +// we interpret some observations of the state of the objects. Value of this +// annotation does not matter. +const annBindCompleted = "pv.kubernetes.io/bind-completed" + +// annBoundByController annotation applies to PVs and PVCs. It indicates that +// the binding (PV->PVC or PVC->PV) was installed by the controller. The +// absence of this annotation means the binding was done by the user (i.e. +// pre-bound). Value of this annotation does not matter. +const annBoundByController = "pv.kubernetes.io/bound-by-controller" + +// annClass annotation represents a new field which instructs dynamic +// provisioning to choose a particular storage class (aka profile). +// Value of this annotation should be empty. +const annClass = "volume.alpha.kubernetes.io/storage-class" + +// This annotation is added to a PV that has been dynamically provisioned by +// Kubernetes. It's value is name of volume plugin that created the volume. +// It serves both user (to show where a PV comes from) and Kubernetes (to +// recognize dynamically provisioned PVs in its decissions). +const annDynamicallyProvisioned = "pv.kubernetes.io/provisioned-by" + +// Name of a tag attached to a real volume in cloud (e.g. AWS EBS or GCE PD) +// with namespace of a persistent volume claim used to create this volume. +const cloudVolumeCreatedForClaimNamespaceTag = "kubernetes.io/created-for/pvc/namespace" + +// Name of a tag attached to a real volume in cloud (e.g. AWS EBS or GCE PD) +// with name of a persistent volume claim used to create this volume. +const cloudVolumeCreatedForClaimNameTag = "kubernetes.io/created-for/pvc/name" + +// Name of a tag attached to a real volume in cloud (e.g. AWS EBS or GCE PD) +// with name of appropriate Kubernetes persistent volume . +const cloudVolumeCreatedForVolumeNameTag = "kubernetes.io/created-for/pv/name" + +// Number of retries when we create a PV object for a provisioned volume. +const createProvisionedPVRetryCount = 5 + +// Interval between retries when we create a PV object for a provisioned volume. +const createProvisionedPVInterval = 10 * time.Second + +// PersistentVolumeController is a controller that synchronizes +// PersistentVolumeClaims and PersistentVolumes. It starts two +// framework.Controllers that watch PerstentVolume and PersistentVolumeClaim +// changes. +type PersistentVolumeController struct { + volumes persistentVolumeOrderedIndex + volumeController *framework.Controller + volumeControllerStopCh chan struct{} + claims cache.Store + claimController *framework.Controller + claimControllerStopCh chan struct{} + kubeClient clientset.Interface + eventRecorder record.EventRecorder + cloud cloudprovider.Interface + recyclePluginMgr vol.VolumePluginMgr + provisioner vol.ProvisionableVolumePlugin + clusterName string + + // PersistentVolumeController keeps track of long running operations and + // makes sure it won't start the same operation twice in parallel. + // Each operation is identified by unique operationName. + // Simple keymutex.KeyMutex is not enough, we need to know what operations + // are in progress (so we don't schedule a new one) and keymutex.KeyMutex + // does not provide such functionality. + + // runningOperationsMapLock guards access to runningOperations map + runningOperationsMapLock sync.Mutex + // runningOperations is map of running operations. The value does not + // matter, presence of a key is enough to consider an operation running. + runningOperations map[string]bool + + // For testing only: hook to call before an asynchronous operation starts. + // Not used when set to nil. + preOperationHook func(operationName string, operationArgument interface{}) + + createProvisionedPVRetryCount int + createProvisionedPVInterval time.Duration +} + +// syncClaim is the main controller method to decide what to do with a claim. +// It's invoked by appropriate framework.Controller callbacks when a claim is +// created, updated or periodically synced. We do not differentiate between +// these events. +// For easier readability, it was split into syncUnboundClaim and syncBoundClaim +// methods. +func (ctrl *PersistentVolumeController) syncClaim(claim *api.PersistentVolumeClaim) error { + glog.V(4).Infof("synchronizing PersistentVolumeClaim[%s]: %s", claimToClaimKey(claim), getClaimStatusForLogging(claim)) + + if !hasAnnotation(claim.ObjectMeta, annBindCompleted) { + return ctrl.syncUnboundClaim(claim) + } else { + return ctrl.syncBoundClaim(claim) + } +} + +// syncUnboundClaim is the main controller method to decide what to do with an +// unbound claim. +func (ctrl *PersistentVolumeController) syncUnboundClaim(claim *api.PersistentVolumeClaim) error { + // This is a new PVC that has not completed binding + // OBSERVATION: pvc is "Pending" + if claim.Spec.VolumeName == "" { + // User did not care which PV they get. + // [Unit test set 1] + volume, err := ctrl.volumes.findBestMatchForClaim(claim) + if err != nil { + glog.V(2).Infof("synchronizing unbound PersistentVolumeClaim[%s]: Error finding PV for claim: %v", claimToClaimKey(claim), err) + return fmt.Errorf("Error finding PV for claim %q: %v", claimToClaimKey(claim), err) + } + if volume == nil { + glog.V(4).Infof("synchronizing unbound PersistentVolumeClaim[%s]: no volume found", claimToClaimKey(claim)) + // No PV could be found + // OBSERVATION: pvc is "Pending", will retry + if hasAnnotation(claim.ObjectMeta, annClass) { + if err = ctrl.provisionClaim(claim); err != nil { + return err + } + return nil + } + // Mark the claim as Pending and try to find a match in the next + // periodic syncClaim + if _, err = ctrl.updateClaimPhase(claim, api.ClaimPending); err != nil { + return err + } + return nil + } else /* pv != nil */ { + // Found a PV for this claim + // OBSERVATION: pvc is "Pending", pv is "Available" + glog.V(4).Infof("synchronizing unbound PersistentVolumeClaim[%s]: volume %q found: %s", claimToClaimKey(claim), volume.Name, getVolumeStatusForLogging(volume)) + if err = ctrl.bind(volume, claim); err != nil { + // On any error saving the volume or the claim, subsequent + // syncClaim will finish the binding. + return err + } + // OBSERVATION: claim is "Bound", pv is "Bound" + return nil + } + } else /* pvc.Spec.VolumeName != nil */ { + // [Unit test set 2] + // User asked for a specific PV. + glog.V(4).Infof("synchronizing unbound PersistentVolumeClaim[%s]: volume %q requested", claimToClaimKey(claim), claim.Spec.VolumeName) + obj, found, err := ctrl.volumes.store.GetByKey(claim.Spec.VolumeName) + if err != nil { + return err + } + if !found { + // User asked for a PV that does not exist. + // OBSERVATION: pvc is "Pending" + // Retry later. + glog.V(4).Infof("synchronizing unbound PersistentVolumeClaim[%s]: volume %q requested and not found, will try again next time", claimToClaimKey(claim), claim.Spec.VolumeName) + if _, err = ctrl.updateClaimPhase(claim, api.ClaimPending); err != nil { + return err + } + return nil + } else { + volume, ok := obj.(*api.PersistentVolume) + if !ok { + return fmt.Errorf("Cannot convert object from volume cache to volume %q!?: %+v", claim.Spec.VolumeName, obj) + } + glog.V(4).Infof("synchronizing unbound PersistentVolumeClaim[%s]: volume %q requested and found: %s", claimToClaimKey(claim), claim.Spec.VolumeName, getVolumeStatusForLogging(volume)) + if volume.Spec.ClaimRef == nil { + // User asked for a PV that is not claimed + // OBSERVATION: pvc is "Pending", pv is "Available" + glog.V(4).Infof("synchronizing unbound PersistentVolumeClaim[%s]: volume is unbound, binding", claimToClaimKey(claim)) + if err = ctrl.bind(volume, claim); err != nil { + // On any error saving the volume or the claim, subsequent + // syncClaim will finish the binding. + return err + } + // OBSERVATION: pvc is "Bound", pv is "Bound" + return nil + } else if isVolumeBoundToClaim(volume, claim) { + // User asked for a PV that is claimed by this PVC + // OBSERVATION: pvc is "Pending", pv is "Bound" + glog.V(4).Infof("synchronizing unbound PersistentVolumeClaim[%s]: volume already bound, finishing the binding", claimToClaimKey(claim)) + + // Finish the volume binding by adding claim UID. + if err = ctrl.bind(volume, claim); err != nil { + return err + } + // OBSERVATION: pvc is "Bound", pv is "Bound" + return nil + } else { + // User asked for a PV that is claimed by someone else + // OBSERVATION: pvc is "Pending", pv is "Bound" + if !hasAnnotation(claim.ObjectMeta, annBoundByController) { + glog.V(4).Infof("synchronizing unbound PersistentVolumeClaim[%s]: volume already bound to different claim by user, will retry later", claimToClaimKey(claim)) + // User asked for a specific PV, retry later + if _, err = ctrl.updateClaimPhase(claim, api.ClaimPending); err != nil { + return err + } + return nil + } else { + // This should never happen because someone had to remove + // annBindCompleted annotation on the claim. + glog.V(4).Infof("synchronizing unbound PersistentVolumeClaim[%s]: volume already bound to different claim %q by controller, THIS SHOULD NEVER HAPPEN", claimToClaimKey(claim), claimrefToClaimKey(volume.Spec.ClaimRef)) + return fmt.Errorf("Invalid binding of claim %q to volume %q: volume already claimed by %q", claimToClaimKey(claim), claim.Spec.VolumeName, claimrefToClaimKey(volume.Spec.ClaimRef)) + } + } + } + } +} + +// syncBoundClaim is the main controller method to decide what to do with a +// bound claim. +func (ctrl *PersistentVolumeController) syncBoundClaim(claim *api.PersistentVolumeClaim) error { + // hasAnnotation(pvc, annBindCompleted) + // This PVC has previously been bound + // OBSERVATION: pvc is not "Pending" + // [Unit test set 3] + if claim.Spec.VolumeName == "" { + // Claim was bound before but not any more. + if _, err := ctrl.updateClaimPhaseWithEvent(claim, api.ClaimLost, api.EventTypeWarning, "ClaimLost", "Bound claim has lost reference to PersistentVolume. Data on the volume is lost!"); err != nil { + return err + } + return nil + } + obj, found, err := ctrl.volumes.store.GetByKey(claim.Spec.VolumeName) + if err != nil { + return err + } + if !found { + // Claim is bound to a non-existing volume. + if _, err = ctrl.updateClaimPhaseWithEvent(claim, api.ClaimLost, api.EventTypeWarning, "ClaimLost", "Bound claim has lost its PersistentVolume. Data on the volume is lost!"); err != nil { + return err + } + return nil + } else { + volume, ok := obj.(*api.PersistentVolume) + if !ok { + return fmt.Errorf("Cannot convert object from volume cache to volume %q!?: %+v", claim.Spec.VolumeName, obj) + } + + glog.V(4).Infof("synchronizing bound PersistentVolumeClaim[%s]: volume %q found: %s", claimToClaimKey(claim), claim.Spec.VolumeName, getVolumeStatusForLogging(volume)) + if volume.Spec.ClaimRef == nil { + // Claim is bound but volume has come unbound. + // Or, a claim was bound and the controller has not received updated + // volume yet. We can't distinguish these cases. + // Bind the volume again and set all states to Bound. + glog.V(4).Infof("synchronizing bound PersistentVolumeClaim[%s]: volume is unbound, fixing", claimToClaimKey(claim)) + if err = ctrl.bind(volume, claim); err != nil { + // Objects not saved, next syncPV or syncClaim will try again + return err + } + return nil + } else if volume.Spec.ClaimRef.UID == claim.UID { + // All is well + // NOTE: syncPV can handle this so it can be left out. + // NOTE: bind() call here will do nothing in most cases as + // everything should be already set. + glog.V(4).Infof("synchronizing bound PersistentVolumeClaim[%s]: claim is already correctly bound", claimToClaimKey(claim)) + if err = ctrl.bind(volume, claim); err != nil { + // Objects not saved, next syncPV or syncClaim will try again + return err + } + return nil + } else { + // Claim is bound but volume has a different claimant. + // Set the claim phase to 'Lost', which is a terminal + // phase. + if _, err = ctrl.updateClaimPhaseWithEvent(claim, api.ClaimLost, api.EventTypeWarning, "ClaimMisbound", "Two claims are bound to the same volume, this one is bound incorrectly"); err != nil { + return err + } + return nil + } + } +} + +// syncVolume is the main controller method to decide what to do with a volume. +// It's invoked by appropriate framework.Controller callbacks when a volume is +// created, updated or periodically synced. We do not differentiate between +// these events. +func (ctrl *PersistentVolumeController) syncVolume(volume *api.PersistentVolume) error { + glog.V(4).Infof("synchronizing PersistentVolume[%s]: %s", volume.Name, getVolumeStatusForLogging(volume)) + + // [Unit test set 4] + if volume.Spec.ClaimRef == nil { + // Volume is unused + glog.V(4).Infof("synchronizing PersistentVolume[%s]: volume is unused", volume.Name) + if _, err := ctrl.updateVolumePhase(volume, api.VolumeAvailable); err != nil { + // Nothing was saved; we will fall back into the same + // condition in the next call to this method + return err + } + return nil + } else /* pv.Spec.ClaimRef != nil */ { + // Volume is bound to a claim. + if volume.Spec.ClaimRef.UID == "" { + // The PV is reserved for a PVC; that PVC has not yet been + // bound to this PV; the PVC sync will handle it. + glog.V(4).Infof("synchronizing PersistentVolume[%s]: volume is pre-bound to claim %s", volume.Name, claimrefToClaimKey(volume.Spec.ClaimRef)) + if _, err := ctrl.updateVolumePhase(volume, api.VolumeAvailable); err != nil { + // Nothing was saved; we will fall back into the same + // condition in the next call to this method + return err + } + return nil + } + glog.V(4).Infof("synchronizing PersistentVolume[%s]: volume is bound to claim %s", volume.Name, claimrefToClaimKey(volume.Spec.ClaimRef)) + // Get the PVC by _name_ + var claim *api.PersistentVolumeClaim + claimName := claimrefToClaimKey(volume.Spec.ClaimRef) + obj, found, err := ctrl.claims.GetByKey(claimName) + if err != nil { + return err + } + if !found { + glog.V(4).Infof("synchronizing PersistentVolume[%s]: claim %s not found", volume.Name, claimrefToClaimKey(volume.Spec.ClaimRef)) + // Fall through with claim = nil + } else { + var ok bool + claim, ok = obj.(*api.PersistentVolumeClaim) + if !ok { + return fmt.Errorf("Cannot convert object from volume cache to volume %q!?: %+v", claim.Spec.VolumeName, obj) + } + glog.V(4).Infof("synchronizing PersistentVolume[%s]: claim %s found: %s", volume.Name, claimrefToClaimKey(volume.Spec.ClaimRef), getClaimStatusForLogging(claim)) + } + if claim != nil && claim.UID != volume.Spec.ClaimRef.UID { + // The claim that the PV was pointing to was deleted, and another + // with the same name created. + glog.V(4).Infof("synchronizing PersistentVolume[%s]: claim %s has different UID, the old one must have been deleted", volume.Name, claimrefToClaimKey(volume.Spec.ClaimRef)) + // Treat the volume as bound to a missing claim. + claim = nil + } + + if claim == nil { + // If we get into this block, the claim must have been deleted; + // NOTE: reclaimVolume may either release the PV back into the pool or + // recycle it or do nothing (retain) + + // Do not overwrite previous Failed state - let the user see that + // something went wrong, while we still re-try to reclaim the + // volume. + if volume.Status.Phase != api.VolumeReleased && volume.Status.Phase != api.VolumeFailed { + // Also, log this only once: + glog.V(2).Infof("volume %q is released and reclaim policy %q will be executed", volume.Name, volume.Spec.PersistentVolumeReclaimPolicy) + if volume, err = ctrl.updateVolumePhase(volume, api.VolumeReleased); err != nil { + // Nothing was saved; we will fall back into the same condition + // in the next call to this method + return err + } + } + + if err = ctrl.reclaimVolume(volume); err != nil { + // Release failed, we will fall back into the same condition + // in the next call to this method + return err + } + return nil + } else if claim.Spec.VolumeName == "" { + if hasAnnotation(volume.ObjectMeta, annBoundByController) { + // The binding is not completed; let PVC sync handle it + glog.V(4).Infof("synchronizing PersistentVolume[%s]: volume not bound yet, waiting for syncClaim to fix it", volume.Name) + } else { + // Dangling PV; try to re-establish the link in the PVC sync + glog.V(4).Infof("synchronizing PersistentVolume[%s]: volume was bound and got unbound (by user?), waiting for syncClaim to fix it", volume.Name) + } + // In both cases, the volume is Bound and the claim is Pending. + // Next syncClaim will fix it. To speed it up, we enqueue the claim + // into the controller, which results in syncClaim to be called + // shortly (and in the right goroutine). + // This speeds up binding of provisioned volumes - provisioner saves + // only the new PV and it expects that next syncClaim will bind the + // claim to it. + clone, err := conversion.NewCloner().DeepCopy(claim) + if err != nil { + return fmt.Errorf("error cloning claim %q: %v", claimToClaimKey(claim), err) + } + glog.V(5).Infof("requeueing claim %q for faster syncClaim", claimToClaimKey(claim)) + err = ctrl.claimController.Requeue(clone) + if err != nil { + return fmt.Errorf("error enqueing claim %q for faster sync: %v", claimToClaimKey(claim), err) + } + return nil + } else if claim.Spec.VolumeName == volume.Name { + // Volume is bound to a claim properly, update status if necessary + glog.V(4).Infof("synchronizing PersistentVolume[%s]: all is bound", volume.Name) + if _, err = ctrl.updateVolumePhase(volume, api.VolumeBound); err != nil { + // Nothing was saved; we will fall back into the same + // condition in the next call to this method + return err + } + return nil + } else { + // Volume is bound to a claim, but the claim is bound elsewhere + if hasAnnotation(volume.ObjectMeta, annDynamicallyProvisioned) && volume.Spec.PersistentVolumeReclaimPolicy == api.PersistentVolumeReclaimDelete { + // This volume was dynamically provisioned for this claim. The + // claim got bound elsewhere, and thus this volume is not + // needed. Delete it. + if err = ctrl.reclaimVolume(volume); err != nil { + // Deletion failed, we will fall back into the same condition + // in the next call to this method + return err + } + return nil + } else { + // Volume is bound to a claim, but the claim is bound elsewhere + // and it's not dynamically provisioned. + if hasAnnotation(volume.ObjectMeta, annBoundByController) { + // This is part of the normal operation of the controller; the + // controller tried to use this volume for a claim but the claim + // was fulfilled by another volume. We did this; fix it. + glog.V(4).Infof("synchronizing PersistentVolume[%s]: volume is bound by controller to a claim that is bound to another volume, unbinding", volume.Name) + if err = ctrl.unbindVolume(volume); err != nil { + return err + } + return nil + } else { + // The PV must have been created with this ptr; leave it alone. + glog.V(4).Infof("synchronizing PersistentVolume[%s]: volume is bound by user to a claim that is bound to another volume, waiting for the claim to get unbound", volume.Name) + // This just updates the volume phase and clears + // volume.Spec.ClaimRef.UID. It leaves the volume pre-bound + // to the claim. + if err = ctrl.unbindVolume(volume); err != nil { + return err + } + return nil + } + } + } + } +} + +// updateClaimPhase saves new claim phase to API server. +func (ctrl *PersistentVolumeController) updateClaimPhase(claim *api.PersistentVolumeClaim, phase api.PersistentVolumeClaimPhase) (*api.PersistentVolumeClaim, error) { + glog.V(4).Infof("updating PersistentVolumeClaim[%s]: set phase %s", claimToClaimKey(claim), phase) + if claim.Status.Phase == phase { + // Nothing to do. + glog.V(4).Infof("updating PersistentVolumeClaim[%s]: phase %s already set", claimToClaimKey(claim), phase) + return claim, nil + } + + clone, err := conversion.NewCloner().DeepCopy(claim) + if err != nil { + return nil, fmt.Errorf("Error cloning claim: %v", err) + } + claimClone, ok := clone.(*api.PersistentVolumeClaim) + if !ok { + return nil, fmt.Errorf("Unexpected claim cast error : %v", claimClone) + } + + claimClone.Status.Phase = phase + newClaim, err := ctrl.kubeClient.Core().PersistentVolumeClaims(claimClone.Namespace).UpdateStatus(claimClone) + if err != nil { + glog.V(4).Infof("updating PersistentVolumeClaim[%s]: set phase %s failed: %v", claimToClaimKey(claim), phase, err) + return newClaim, err + } + glog.V(2).Infof("claim %q entered phase %q", claimToClaimKey(claim), phase) + return newClaim, nil +} + +// updateClaimPhaseWithEvent saves new claim phase to API server and emits given +// event on the claim. It saves the phase and emits the event only when the +// phase has actually changed from the version saved in API server. +func (ctrl *PersistentVolumeController) updateClaimPhaseWithEvent(claim *api.PersistentVolumeClaim, phase api.PersistentVolumeClaimPhase, eventtype, reason, message string) (*api.PersistentVolumeClaim, error) { + glog.V(4).Infof("updating updateClaimPhaseWithEvent[%s]: set phase %s", claimToClaimKey(claim), phase) + if claim.Status.Phase == phase { + // Nothing to do. + glog.V(4).Infof("updating updateClaimPhaseWithEvent[%s]: phase %s already set", claimToClaimKey(claim), phase) + return claim, nil + } + + newClaim, err := ctrl.updateClaimPhase(claim, phase) + if err != nil { + return nil, err + } + + // Emit the event only when the status change happens, not everytime + // syncClaim is called. + glog.V(3).Infof("claim %q changed status to %q: %s", claimToClaimKey(claim), phase, message) + ctrl.eventRecorder.Event(newClaim, eventtype, reason, message) + + return newClaim, nil +} + +// updateVolumePhase saves new volume phase to API server. +func (ctrl *PersistentVolumeController) updateVolumePhase(volume *api.PersistentVolume, phase api.PersistentVolumePhase) (*api.PersistentVolume, error) { + glog.V(4).Infof("updating PersistentVolume[%s]: set phase %s", volume.Name, phase) + if volume.Status.Phase == phase { + // Nothing to do. + glog.V(4).Infof("updating PersistentVolume[%s]: phase %s already set", volume.Name, phase) + return volume, nil + } + + clone, err := conversion.NewCloner().DeepCopy(volume) + if err != nil { + return nil, fmt.Errorf("Error cloning claim: %v", err) + } + volumeClone, ok := clone.(*api.PersistentVolume) + if !ok { + return nil, fmt.Errorf("Unexpected volume cast error : %v", volumeClone) + } + + volumeClone.Status.Phase = phase + newVol, err := ctrl.kubeClient.Core().PersistentVolumes().UpdateStatus(volumeClone) + if err != nil { + glog.V(4).Infof("updating PersistentVolume[%s]: set phase %s failed: %v", volume.Name, phase, err) + return newVol, err + } + glog.V(2).Infof("volume %q entered phase %q", volume.Name, phase) + return newVol, err +} + +// updateVolumePhaseWithEvent saves new volume phase to API server and emits +// given event on the volume. It saves the phase and emits the event only when +// the phase has actually changed from the version saved in API server. +func (ctrl *PersistentVolumeController) updateVolumePhaseWithEvent(volume *api.PersistentVolume, phase api.PersistentVolumePhase, eventtype, reason, message string) (*api.PersistentVolume, error) { + glog.V(4).Infof("updating updateVolumePhaseWithEvent[%s]: set phase %s", volume.Name, phase) + if volume.Status.Phase == phase { + // Nothing to do. + glog.V(4).Infof("updating updateVolumePhaseWithEvent[%s]: phase %s already set", volume.Name, phase) + return volume, nil + } + + newVol, err := ctrl.updateVolumePhase(volume, phase) + if err != nil { + return nil, err + } + + // Emit the event only when the status change happens, not everytime + // syncClaim is called. + glog.V(3).Infof("volume %q changed status to %q: %s", volume.Name, phase, message) + ctrl.eventRecorder.Event(newVol, eventtype, reason, message) + + return newVol, nil +} + +// bindVolumeToClaim modifes given volume to be bound to a claim and saves it to +// API server. The claim is not modified in this method! +func (ctrl *PersistentVolumeController) bindVolumeToClaim(volume *api.PersistentVolume, claim *api.PersistentVolumeClaim) (*api.PersistentVolume, error) { + glog.V(4).Infof("updating PersistentVolume[%s]: binding to %q", volume.Name, claimToClaimKey(claim)) + + dirty := false + + // Check if the volume was already bound (either by user or by controller) + shouldSetBoundByController := false + if !isVolumeBoundToClaim(volume, claim) { + shouldSetBoundByController = true + } + + // The volume from method args can be pointing to watcher cache. We must not + // modify these, therefore create a copy. + clone, err := conversion.NewCloner().DeepCopy(volume) + if err != nil { + return nil, fmt.Errorf("Error cloning pv: %v", err) + } + volumeClone, ok := clone.(*api.PersistentVolume) + if !ok { + return nil, fmt.Errorf("Unexpected volume cast error : %v", volumeClone) + } + + // Bind the volume to the claim if it is not bound yet + if volume.Spec.ClaimRef == nil || + volume.Spec.ClaimRef.Name != claim.Name || + volume.Spec.ClaimRef.Namespace != claim.Namespace || + volume.Spec.ClaimRef.UID != claim.UID { + + claimRef, err := api.GetReference(claim) + if err != nil { + return nil, fmt.Errorf("Unexpected error getting claim reference: %v", err) + } + volumeClone.Spec.ClaimRef = claimRef + dirty = true + } + + // Set annBoundByController if it is not set yet + if shouldSetBoundByController && !hasAnnotation(volumeClone.ObjectMeta, annBoundByController) { + setAnnotation(&volumeClone.ObjectMeta, annBoundByController, "yes") + dirty = true + } + + // Save the volume only if something was changed + if dirty { + glog.V(2).Infof("claim %q bound to volume %q", claimToClaimKey(claim), volume.Name) + newVol, err := ctrl.kubeClient.Core().PersistentVolumes().Update(volumeClone) + if err != nil { + glog.V(4).Infof("updating PersistentVolume[%s]: binding to %q failed: %v", volume.Name, claimToClaimKey(claim), err) + return newVol, err + } + glog.V(4).Infof("updating PersistentVolume[%s]: bound to %q", newVol.Name, claimToClaimKey(claim)) + return newVol, nil + } + + glog.V(4).Infof("updating PersistentVolume[%s]: already bound to %q", volume.Name, claimToClaimKey(claim)) + return volume, nil +} + +// bindClaimToVolume modifes given claim to be bound to a volume and saves it to +// API server. The volume is not modified in this method! +func (ctrl *PersistentVolumeController) bindClaimToVolume(claim *api.PersistentVolumeClaim, volume *api.PersistentVolume) (*api.PersistentVolumeClaim, error) { + glog.V(4).Infof("updating PersistentVolumeClaim[%s]: binding to %q", claimToClaimKey(claim), volume.Name) + + dirty := false + + // Check if the claim was already bound (either by controller or by user) + shouldSetBoundByController := false + if volume.Name != claim.Spec.VolumeName { + shouldSetBoundByController = true + } + + // The claim from method args can be pointing to watcher cache. We must not + // modify these, therefore create a copy. + clone, err := conversion.NewCloner().DeepCopy(claim) + if err != nil { + return nil, fmt.Errorf("Error cloning claim: %v", err) + } + claimClone, ok := clone.(*api.PersistentVolumeClaim) + if !ok { + return nil, fmt.Errorf("Unexpected claim cast error : %v", claimClone) + } + + // Bind the claim to the volume if it is not bound yet + if claimClone.Spec.VolumeName != volume.Name { + claimClone.Spec.VolumeName = volume.Name + dirty = true + } + + // Set annBoundByController if it is not set yet + if shouldSetBoundByController && !hasAnnotation(claimClone.ObjectMeta, annBoundByController) { + setAnnotation(&claimClone.ObjectMeta, annBoundByController, "yes") + dirty = true + } + + // Set annBindCompleted if it is not set yet + if !hasAnnotation(claimClone.ObjectMeta, annBindCompleted) { + setAnnotation(&claimClone.ObjectMeta, annBindCompleted, "yes") + dirty = true + } + + if dirty { + glog.V(2).Infof("volume %q bound to claim %q", volume.Name, claimToClaimKey(claim)) + newClaim, err := ctrl.kubeClient.Core().PersistentVolumeClaims(claim.Namespace).Update(claimClone) + if err != nil { + glog.V(4).Infof("updating PersistentVolumeClaim[%s]: binding to %q failed: %v", claimToClaimKey(claim), volume.Name, err) + return newClaim, err + } + glog.V(4).Infof("updating PersistentVolumeClaim[%s]: bound to %q", claimToClaimKey(claim), volume.Name) + return newClaim, nil + } + + glog.V(4).Infof("updating PersistentVolumeClaim[%s]: already bound to %q", claimToClaimKey(claim), volume.Name) + return claim, nil +} + +// bind saves binding information both to the volume and the claim and marks +// both objects as Bound. Volume is saved first. +// It returns on first error, it's up to the caller to implement some retry +// mechanism. +func (ctrl *PersistentVolumeController) bind(volume *api.PersistentVolume, claim *api.PersistentVolumeClaim) error { + var err error + // use updateClaim/updatedVolume to keep the original claim/volume for + // logging in error cases. + var updatedClaim *api.PersistentVolumeClaim + var updatedVolume *api.PersistentVolume + + glog.V(4).Infof("binding volume %q to claim %q", volume.Name, claimToClaimKey(claim)) + + if updatedVolume, err = ctrl.bindVolumeToClaim(volume, claim); err != nil { + glog.V(3).Infof("error binding volume %q to claim %q: failed saving the volume: %v", volume.Name, claimToClaimKey(claim), err) + return err + } + volume = updatedVolume + + if updatedVolume, err = ctrl.updateVolumePhase(volume, api.VolumeBound); err != nil { + glog.V(3).Infof("error binding volume %q to claim %q: failed saving the volume status: %v", volume.Name, claimToClaimKey(claim), err) + return err + } + volume = updatedVolume + + if updatedClaim, err = ctrl.bindClaimToVolume(claim, volume); err != nil { + glog.V(3).Infof("error binding volume %q to claim %q: failed saving the claim: %v", volume.Name, claimToClaimKey(claim), err) + return err + } + claim = updatedClaim + + if updatedClaim, err = ctrl.updateClaimPhase(claim, api.ClaimBound); err != nil { + glog.V(3).Infof("error binding volume %q to claim %q: failed saving the claim status: %v", volume.Name, claimToClaimKey(claim), err) + return err + } + claim = updatedClaim + + glog.V(4).Infof("volume %q bound to claim %q", volume.Name, claimToClaimKey(claim)) + glog.V(4).Infof("volume %q status after binding: %s", volume.Name, getVolumeStatusForLogging(volume)) + glog.V(4).Infof("claim %q status after binding: %s", claimToClaimKey(claim), getClaimStatusForLogging(claim)) + return nil +} + +// unbindVolume rolls back previous binding of the volume. This may be necessary +// when two controllers bound two volumes to single claim - when we detect this, +// only one binding succeeds and the second one must be rolled back. +// This method updates both Spec and Status. +// It returns on first error, it's up to the caller to implement some retry +// mechanism. +func (ctrl *PersistentVolumeController) unbindVolume(volume *api.PersistentVolume) error { + glog.V(4).Infof("updating PersistentVolume[%s]: rolling back binding from %q", volume.Name, claimrefToClaimKey(volume.Spec.ClaimRef)) + + // Save the PV only when any modification is neccesary. + clone, err := conversion.NewCloner().DeepCopy(volume) + if err != nil { + return fmt.Errorf("Error cloning pv: %v", err) + } + volumeClone, ok := clone.(*api.PersistentVolume) + if !ok { + return fmt.Errorf("Unexpected volume cast error : %v", volumeClone) + } + + if hasAnnotation(volume.ObjectMeta, annBoundByController) { + // The volume was bound by the controller. + volumeClone.Spec.ClaimRef = nil + delete(volumeClone.Annotations, annBoundByController) + if len(volumeClone.Annotations) == 0 { + // No annotations look better than empty annotation map (and it's easier + // to test). + volumeClone.Annotations = nil + } + } else { + // The volume was pre-bound by user. Clear only the binging UID. + volumeClone.Spec.ClaimRef.UID = "" + } + + newVol, err := ctrl.kubeClient.Core().PersistentVolumes().Update(volumeClone) + if err != nil { + glog.V(4).Infof("updating PersistentVolume[%s]: rollback failed: %v", volume.Name, err) + return err + } + glog.V(4).Infof("updating PersistentVolume[%s]: rolled back", newVol.Name) + + // Update the status + _, err = ctrl.updateVolumePhase(newVol, api.VolumeAvailable) + return err + +} + +// reclaimVolume implements volume.Spec.PersistentVolumeReclaimPolicy and +// starts appropriate reclaim action. +func (ctrl *PersistentVolumeController) reclaimVolume(volume *api.PersistentVolume) error { + switch volume.Spec.PersistentVolumeReclaimPolicy { + case api.PersistentVolumeReclaimRetain: + glog.V(4).Infof("reclaimVolume[%s]: policy is Retain, nothing to do", volume.Name) + + case api.PersistentVolumeReclaimRecycle: + glog.V(4).Infof("reclaimVolume[%s]: policy is Recycle", volume.Name) + ctrl.scheduleOperation("recycle-"+string(volume.UID), ctrl.recycleVolumeOperation, volume) + + case api.PersistentVolumeReclaimDelete: + glog.V(4).Infof("reclaimVolume[%s]: policy is Delete", volume.Name) + ctrl.scheduleOperation("delete-"+string(volume.UID), ctrl.deleteVolumeOperation, volume) + + default: + // Unknown PersistentVolumeReclaimPolicy + if _, err := ctrl.updateVolumePhaseWithEvent(volume, api.VolumeFailed, api.EventTypeWarning, "VolumeUnknownReclaimPolicy", "Volume has unrecognized PersistentVolumeReclaimPolicy"); err != nil { + return err + } + } + return nil +} + +// doRerecycleVolumeOperationcycleVolume recycles a volume. This method is +// running in standalone goroutine and already has all necessary locks. +func (ctrl *PersistentVolumeController) recycleVolumeOperation(arg interface{}) { + volume, ok := arg.(*api.PersistentVolume) + if !ok { + glog.Errorf("Cannot convert recycleVolumeOperation argument to volume, got %+v", arg) + return + } + glog.V(4).Infof("recycleVolumeOperation [%s] started", volume.Name) + + // This method may have been waiting for a volume lock for some time. + // Previous recycleVolumeOperation might just have saved an updated version, + // so read current volume state now. + newVolume, err := ctrl.kubeClient.Core().PersistentVolumes().Get(volume.Name) + if err != nil { + glog.V(3).Infof("error reading peristent volume %q: %v", volume.Name, err) + return + } + needsReclaim, err := ctrl.isVolumeReleased(newVolume) + if err != nil { + glog.V(3).Infof("error reading claim for volume %q: %v", volume.Name, err) + return + } + if !needsReclaim { + glog.V(3).Infof("volume %q no longer needs recycling, skipping", volume.Name) + return + } + + // Use the newest volume copy, this will save us from version conflicts on + // saving. + volume = newVolume + + // Find a plugin. + spec := vol.NewSpecFromPersistentVolume(volume, false) + plugin, err := ctrl.recyclePluginMgr.FindRecyclablePluginBySpec(spec) + if err != nil { + // No recycler found. Emit an event and mark the volume Failed. + if _, err = ctrl.updateVolumePhaseWithEvent(volume, api.VolumeFailed, api.EventTypeWarning, "VolumeFailedRecycle", "No recycler plugin found for the volume!"); err != nil { + glog.V(4).Infof("recycleVolumeOperation [%s]: failed to mark volume as failed: %v", volume.Name, err) + // Save failed, retry on the next deletion attempt + return + } + // Despite the volume being Failed, the controller will retry recycling + // the volume in every syncVolume() call. + return + } + + // Plugin found + recycler, err := plugin.NewRecycler(volume.Name, spec) + if err != nil { + // Cannot create recycler + strerr := fmt.Sprintf("Failed to create recycler: %v", err) + if _, err = ctrl.updateVolumePhaseWithEvent(volume, api.VolumeFailed, api.EventTypeWarning, "VolumeFailedRecycle", strerr); err != nil { + glog.V(4).Infof("recycleVolumeOperation [%s]: failed to mark volume as failed: %v", volume.Name, err) + // Save failed, retry on the next deletion attempt + return + } + // Despite the volume being Failed, the controller will retry recycling + // the volume in every syncVolume() call. + return + } + + if err = recycler.Recycle(); err != nil { + // Recycler failed + strerr := fmt.Sprintf("Recycler failed: %s", err) + if _, err = ctrl.updateVolumePhaseWithEvent(volume, api.VolumeFailed, api.EventTypeWarning, "VolumeFailedRecycle", strerr); err != nil { + glog.V(4).Infof("recycleVolumeOperation [%s]: failed to mark volume as failed: %v", volume.Name, err) + // Save failed, retry on the next deletion attempt + return + } + // Despite the volume being Failed, the controller will retry recycling + // the volume in every syncVolume() call. + return + } + + glog.V(2).Infof("volume %q recycled", volume.Name) + // Make the volume available again + if err = ctrl.unbindVolume(volume); err != nil { + // Oops, could not save the volume and therefore the controller will + // recycle the volume again on next update. We _could_ maintain a cache + // of "recently recycled volumes" and avoid unnecessary recycling, this + // is left out as future optimization. + glog.V(3).Infof("recycleVolumeOperation [%s]: failed to make recycled volume 'Available' (%v), we will recycle the volume again", volume.Name, err) + return + } + return +} + +// deleteVolumeOperation deletes a volume. This method is running in standalone +// goroutine and already has all necessary locks. +func (ctrl *PersistentVolumeController) deleteVolumeOperation(arg interface{}) { + volume, ok := arg.(*api.PersistentVolume) + if !ok { + glog.Errorf("Cannot convert deleteVolumeOperation argument to volume, got %+v", arg) + return + } + glog.V(4).Infof("deleteVolumeOperation [%s] started", volume.Name) + + // This method may have been waiting for a volume lock for some time. + // Previous deleteVolumeOperation might just have saved an updated version, so + // read current volume state now. + newVolume, err := ctrl.kubeClient.Core().PersistentVolumes().Get(volume.Name) + if err != nil { + glog.V(3).Infof("error reading peristent volume %q: %v", volume.Name, err) + return + } + needsReclaim, err := ctrl.isVolumeReleased(newVolume) + if err != nil { + glog.V(3).Infof("error reading claim for volume %q: %v", volume.Name, err) + return + } + if !needsReclaim { + glog.V(3).Infof("volume %q no longer needs deletion, skipping", volume.Name) + return + } + + if err = ctrl.doDeleteVolume(volume); err != nil { + // Delete failed, update the volume and emit an event. + glog.V(3).Infof("deletion of volume %q failed: %v", volume.Name, err) + if _, err = ctrl.updateVolumePhaseWithEvent(volume, api.VolumeFailed, api.EventTypeWarning, "VolumeFailedDelete", err.Error()); err != nil { + glog.V(4).Infof("deleteVolumeOperation [%s]: failed to mark volume as failed: %v", volume.Name, err) + // Save failed, retry on the next deletion attempt + return + } + // Despite the volume being Failed, the controller will retry deleting + // the volume in every syncVolume() call. + return + } + + glog.V(4).Infof("deleteVolumeOperation [%s]: success", volume.Name) + // Delete the volume + if err = ctrl.kubeClient.Core().PersistentVolumes().Delete(volume.Name, nil); err != nil { + // Oops, could not delete the volume and therefore the controller will + // try to delete the volume again on next update. We _could_ maintain a + // cache of "recently deleted volumes" and avoid unnecessary deletion, + // this is left out as future optimization. + glog.V(3).Infof("failed to delete volume %q from database: %v", volume.Name, err) + return + } + return +} + +// isVolumeReleased returns true if given volume is released and can be recycled +// or deleted, based on its retain policy. I.e. the volume is bound to a claim +// and the claim does not exist or exists and is bound to different volume. +func (ctrl *PersistentVolumeController) isVolumeReleased(volume *api.PersistentVolume) (bool, error) { + // A volume needs reclaim if it has ClaimRef and appropriate claim does not + // exist. + if volume.Spec.ClaimRef == nil { + glog.V(4).Infof("isVolumeReleased[%s]: ClaimRef is nil", volume.Name) + return false, nil + } + if volume.Spec.ClaimRef.UID == "" { + // This is a volume bound by user and the controller has not finished + // binding to the real claim yet. + glog.V(4).Infof("isVolumeReleased[%s]: ClaimRef is not bound", volume.Name) + return false, nil + } + + var claim *api.PersistentVolumeClaim + claimName := claimrefToClaimKey(volume.Spec.ClaimRef) + obj, found, err := ctrl.claims.GetByKey(claimName) + if err != nil { + return false, err + } + if !found { + // Fall through with claim = nil + } else { + var ok bool + claim, ok = obj.(*api.PersistentVolumeClaim) + if !ok { + return false, fmt.Errorf("Cannot convert object from claim cache to claim!?: %+v", obj) + } + } + if claim != nil && claim.UID == volume.Spec.ClaimRef.UID { + // the claim still exists and has the right UID + glog.V(4).Infof("isVolumeReleased[%s]: ClaimRef is still valid, volume is not released", volume.Name) + return false, nil + } + + glog.V(2).Infof("isVolumeReleased[%s]: volume is released", volume.Name) + return true, nil +} + +// doDeleteVolume finds appropriate delete plugin and deletes given volume +// (it will be re-used in future provisioner error cases). +func (ctrl *PersistentVolumeController) doDeleteVolume(volume *api.PersistentVolume) error { + glog.V(4).Infof("doDeleteVolume [%s]", volume.Name) + // Find a plugin. + spec := vol.NewSpecFromPersistentVolume(volume, false) + plugin, err := ctrl.recyclePluginMgr.FindDeletablePluginBySpec(spec) + if err != nil { + // No deleter found. Emit an event and mark the volume Failed. + return fmt.Errorf("Error getting deleter volume plugin for volume %q: %v", volume.Name, err) + } + + // Plugin found + deleter, err := plugin.NewDeleter(spec) + if err != nil { + // Cannot create deleter + return fmt.Errorf("Failed to create deleter for volume %q: %v", volume.Name, err) + } + + if err = deleter.Delete(); err != nil { + // Deleter failed + return fmt.Errorf("Delete of volume %q failed: %v", volume.Name, err) + } + + glog.V(2).Infof("volume %q deleted", volume.Name) + return nil +} + +// provisionClaim starts new asynchronous operation to provision a claim. +func (ctrl *PersistentVolumeController) provisionClaim(claim *api.PersistentVolumeClaim) error { + glog.V(4).Infof("provisionClaim[%s]: started", claimToClaimKey(claim)) + ctrl.scheduleOperation("provision-"+string(claim.UID), ctrl.provisionClaimOperation, claim) + return nil +} + +// provisionClaimOperation provisions a volume. This method is running in +// standalone goroutine and already has all necessary locks. +func (ctrl *PersistentVolumeController) provisionClaimOperation(claimObj interface{}) { + claim, ok := claimObj.(*api.PersistentVolumeClaim) + if !ok { + glog.Errorf("Cannot convert provisionClaimOperation argument to claim, got %+v", claimObj) + return + } + glog.V(4).Infof("provisionClaimOperation [%s] started", claimToClaimKey(claim)) + + // A previous doProvisionClaim may just have finished while we were waiting for + // the locks. Check that PV (with deterministic name) hasn't been provisioned + // yet. + + pvName := ctrl.getProvisionedVolumeNameForClaim(claim) + volume, err := ctrl.kubeClient.Core().PersistentVolumes().Get(pvName) + if err == nil && volume != nil { + // Volume has been already provisioned, nothing to do. + glog.V(4).Infof("provisionClaimOperation [%s]: volume already exists, skipping", claimToClaimKey(claim)) + return + } + + // Prepare a claimRef to the claim early (to fail before a volume is + // provisioned) + claimRef, err := api.GetReference(claim) + if err != nil { + glog.V(3).Infof("unexpected error getting claim reference: %v", err) + return + } + + // TODO: find provisionable plugin based on a class/profile + plugin := ctrl.provisioner + if plugin == nil { + // No provisioner found. Emit an event. + ctrl.eventRecorder.Event(claim, api.EventTypeWarning, "ProvisioningFailed", "No provisioner plugin found for the claim!") + glog.V(2).Infof("no provisioner plugin found for claim %s!", claimToClaimKey(claim)) + // The controller will retry provisioning the volume in every + // syncVolume() call. + return + } + + // Gather provisioning options + tags := make(map[string]string) + tags[cloudVolumeCreatedForClaimNamespaceTag] = claim.Namespace + tags[cloudVolumeCreatedForClaimNameTag] = claim.Name + tags[cloudVolumeCreatedForVolumeNameTag] = pvName + + options := vol.VolumeOptions{ + Capacity: claim.Spec.Resources.Requests[api.ResourceName(api.ResourceStorage)], + AccessModes: claim.Spec.AccessModes, + PersistentVolumeReclaimPolicy: api.PersistentVolumeReclaimDelete, + CloudTags: &tags, + ClusterName: ctrl.clusterName, + PVName: pvName, + } + + // Provision the volume + provisioner, err := plugin.NewProvisioner(options) + if err != nil { + strerr := fmt.Sprintf("Failed to create provisioner: %v", err) + glog.V(2).Infof("failed to create provisioner for claim %q: %v", claimToClaimKey(claim), err) + ctrl.eventRecorder.Event(claim, api.EventTypeWarning, "ProvisioningFailed", strerr) + return + } + + volume, err = provisioner.Provision() + if err != nil { + strerr := fmt.Sprintf("Failed to provision volume: %v", err) + glog.V(2).Infof("failed to provision volume for claim %q: %v", claimToClaimKey(claim), err) + ctrl.eventRecorder.Event(claim, api.EventTypeWarning, "ProvisioningFailed", strerr) + return + } + + glog.V(3).Infof("volume %q for claim %q created", volume.Name, claimToClaimKey(claim)) + + // Create Kubernetes PV object for the volume. + volume.Name = pvName + // Bind it to the claim + volume.Spec.ClaimRef = claimRef + volume.Status.Phase = api.VolumeBound + + // Add annBoundByController (used in deleting the volume) + setAnnotation(&volume.ObjectMeta, annBoundByController, "yes") + setAnnotation(&volume.ObjectMeta, annDynamicallyProvisioned, plugin.Name()) + + // Try to create the PV object several times + for i := 0; i < ctrl.createProvisionedPVRetryCount; i++ { + glog.V(4).Infof("provisionClaimOperation [%s]: trying to save volume %s", claimToClaimKey(claim), volume.Name) + if _, err = ctrl.kubeClient.Core().PersistentVolumes().Create(volume); err == nil { + // Save succeeded. + glog.V(3).Infof("volume %q for claim %q saved", volume.Name, claimToClaimKey(claim)) + break + } + // Save failed, try again after a while. + glog.V(3).Infof("failed to save volume %q for claim %q: %v", volume.Name, claimToClaimKey(claim), err) + time.Sleep(ctrl.createProvisionedPVInterval) + } + + if err != nil { + // Save failed. Now we have a storage asset outside of Kubernetes, + // but we don't have appropriate PV object for it. + // Emit some event here and try to delete the storage asset several + // times. + strerr := fmt.Sprintf("Error creating provisioned PV object for claim %s: %v. Deleting the volume.", claimToClaimKey(claim), err) + glog.V(3).Info(strerr) + ctrl.eventRecorder.Event(claim, api.EventTypeWarning, "ProvisioningFailed", strerr) + + for i := 0; i < ctrl.createProvisionedPVRetryCount; i++ { + if err = ctrl.doDeleteVolume(volume); err == nil { + // Delete succeeded + glog.V(4).Infof("provisionClaimOperation [%s]: cleaning volume %s succeeded", claimToClaimKey(claim), volume.Name) + break + } + // Delete failed, try again after a while. + glog.V(3).Infof("failed to delete volume %q: %v", volume.Name, i, err) + time.Sleep(ctrl.createProvisionedPVInterval) + } + + if err != nil { + // Delete failed several times. There is orphaned volume and there + // is nothing we can do about it. + strerr := fmt.Sprintf("Error cleaning provisioned volume for claim %s: %v. Please delete manually.", claimToClaimKey(claim), err) + glog.V(2).Info(strerr) + ctrl.eventRecorder.Event(claim, api.EventTypeWarning, "ProvisioningCleanupFailed", strerr) + } + } else { + glog.V(2).Infof("volume %q provisioned for claim %q", volume.Name, claimToClaimKey(claim)) + } +} + +// getProvisionedVolumeNameForClaim returns PV.Name for the provisioned volume. +// The name must be unique +func (ctrl *PersistentVolumeController) getProvisionedVolumeNameForClaim(claim *api.PersistentVolumeClaim) string { + return "pvc-" + string(claim.UID) +} + +// scheduleOperation starts given asynchronous operation on given volume. It +// makes sure the operation is already not running. +func (ctrl *PersistentVolumeController) scheduleOperation(operationName string, operation func(arg interface{}), arg interface{}) { + glog.V(4).Infof("scheduleOperation[%s]", operationName) + + // Poke test code that an operation is just about to get started. + if ctrl.preOperationHook != nil { + ctrl.preOperationHook(operationName, arg) + } + + isRunning := func() bool { + // In anonymous func() to get the locking right. + ctrl.runningOperationsMapLock.Lock() + defer ctrl.runningOperationsMapLock.Unlock() + + if ctrl.isOperationRunning(operationName) { + glog.V(4).Infof("operation %q is already running, skipping", operationName) + return true + } + ctrl.startRunningOperation(operationName) + return false + }() + + if isRunning { + return + } + + // Run the operation in separate goroutine + go func() { + glog.V(4).Infof("scheduleOperation[%s]: running the operation", operationName) + operation(arg) + + ctrl.runningOperationsMapLock.Lock() + defer ctrl.runningOperationsMapLock.Unlock() + ctrl.finishRunningOperation(operationName) + }() +} + +func (ctrl *PersistentVolumeController) isOperationRunning(operationName string) bool { + _, found := ctrl.runningOperations[operationName] + return found +} + +func (ctrl *PersistentVolumeController) finishRunningOperation(operationName string) { + delete(ctrl.runningOperations, operationName) +} + +func (ctrl *PersistentVolumeController) startRunningOperation(operationName string) { + ctrl.runningOperations[operationName] = true +} diff --git a/vendor/k8s.io/kubernetes/pkg/controller/persistentvolume/controller_base.go b/vendor/k8s.io/kubernetes/pkg/controller/persistentvolume/controller_base.go new file mode 100644 index 0000000000..55c7417f00 --- /dev/null +++ b/vendor/k8s.io/kubernetes/pkg/controller/persistentvolume/controller_base.go @@ -0,0 +1,390 @@ +/* +Copyright 2016 The Kubernetes Authors All rights reserved. + +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 persistentvolume + +import ( + "fmt" + "time" + + "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/errors" + "k8s.io/kubernetes/pkg/client/cache" + clientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" + unversioned_core "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/core/unversioned" + "k8s.io/kubernetes/pkg/client/record" + "k8s.io/kubernetes/pkg/cloudprovider" + "k8s.io/kubernetes/pkg/controller/framework" + "k8s.io/kubernetes/pkg/runtime" + vol "k8s.io/kubernetes/pkg/volume" + "k8s.io/kubernetes/pkg/watch" + + "github.com/golang/glog" +) + +// This file contains the controller base functionality, i.e. framework to +// process PV/PVC added/updated/deleted events. The real binding, provisioning, +// recycling and deleting is done in controller.go + +// NewPersistentVolumeController creates a new PersistentVolumeController +func NewPersistentVolumeController( + kubeClient clientset.Interface, + syncPeriod time.Duration, + provisioner vol.ProvisionableVolumePlugin, + recyclers []vol.VolumePlugin, + cloud cloudprovider.Interface, + clusterName string, + volumeSource, claimSource cache.ListerWatcher, + eventRecorder record.EventRecorder, +) *PersistentVolumeController { + + if eventRecorder == nil { + broadcaster := record.NewBroadcaster() + broadcaster.StartRecordingToSink(&unversioned_core.EventSinkImpl{Interface: kubeClient.Core().Events("")}) + eventRecorder = broadcaster.NewRecorder(api.EventSource{Component: "persistentvolume-controller"}) + } + + controller := &PersistentVolumeController{ + kubeClient: kubeClient, + eventRecorder: eventRecorder, + runningOperations: make(map[string]bool), + cloud: cloud, + provisioner: provisioner, + clusterName: clusterName, + createProvisionedPVRetryCount: createProvisionedPVRetryCount, + createProvisionedPVInterval: createProvisionedPVInterval, + } + + controller.recyclePluginMgr.InitPlugins(recyclers, controller) + if controller.provisioner != nil { + if err := controller.provisioner.Init(controller); err != nil { + glog.Errorf("PersistentVolumeController: error initializing provisioner plugin: %v", err) + } + } + + if volumeSource == nil { + volumeSource = &cache.ListWatch{ + ListFunc: func(options api.ListOptions) (runtime.Object, error) { + return kubeClient.Core().PersistentVolumes().List(options) + }, + WatchFunc: func(options api.ListOptions) (watch.Interface, error) { + return kubeClient.Core().PersistentVolumes().Watch(options) + }, + } + } + + if claimSource == nil { + claimSource = &cache.ListWatch{ + ListFunc: func(options api.ListOptions) (runtime.Object, error) { + return kubeClient.Core().PersistentVolumeClaims(api.NamespaceAll).List(options) + }, + WatchFunc: func(options api.ListOptions) (watch.Interface, error) { + return kubeClient.Core().PersistentVolumeClaims(api.NamespaceAll).Watch(options) + }, + } + } + + controller.volumes.store, controller.volumeController = framework.NewIndexerInformer( + volumeSource, + &api.PersistentVolume{}, + syncPeriod, + framework.ResourceEventHandlerFuncs{ + AddFunc: controller.addVolume, + UpdateFunc: controller.updateVolume, + DeleteFunc: controller.deleteVolume, + }, + cache.Indexers{"accessmodes": accessModesIndexFunc}, + ) + controller.claims, controller.claimController = framework.NewInformer( + claimSource, + &api.PersistentVolumeClaim{}, + syncPeriod, + framework.ResourceEventHandlerFuncs{ + AddFunc: controller.addClaim, + UpdateFunc: controller.updateClaim, + DeleteFunc: controller.deleteClaim, + }, + ) + return controller +} + +// addVolume is callback from framework.Controller watching PersistentVolume +// events. +func (ctrl *PersistentVolumeController) addVolume(obj interface{}) { + if !ctrl.isFullySynced() { + return + } + + pv, ok := obj.(*api.PersistentVolume) + if !ok { + glog.Errorf("expected PersistentVolume but handler received %+v", obj) + return + } + if err := ctrl.syncVolume(pv); err != nil { + if errors.IsConflict(err) { + // Version conflict error happens quite often and the controller + // recovers from it easily. + glog.V(3).Infof("PersistentVolumeController could not add volume %q: %+v", pv.Name, err) + } else { + glog.Errorf("PersistentVolumeController could not add volume %q: %+v", pv.Name, err) + } + } +} + +// updateVolume is callback from framework.Controller watching PersistentVolume +// events. +func (ctrl *PersistentVolumeController) updateVolume(oldObj, newObj interface{}) { + if !ctrl.isFullySynced() { + return + } + + newVolume, ok := newObj.(*api.PersistentVolume) + if !ok { + glog.Errorf("Expected PersistentVolume but handler received %+v", newObj) + return + } + if err := ctrl.syncVolume(newVolume); err != nil { + if errors.IsConflict(err) { + // Version conflict error happens quite often and the controller + // recovers from it easily. + glog.V(3).Infof("PersistentVolumeController could not update volume %q: %+v", newVolume.Name, err) + } else { + glog.Errorf("PersistentVolumeController could not update volume %q: %+v", newVolume.Name, err) + } + } +} + +// deleteVolume is callback from framework.Controller watching PersistentVolume +// events. +func (ctrl *PersistentVolumeController) deleteVolume(obj interface{}) { + if !ctrl.isFullySynced() { + return + } + + var volume *api.PersistentVolume + var ok bool + volume, ok = obj.(*api.PersistentVolume) + if !ok { + if unknown, ok := obj.(cache.DeletedFinalStateUnknown); ok && unknown.Obj != nil { + volume, ok = unknown.Obj.(*api.PersistentVolume) + if !ok { + glog.Errorf("Expected PersistentVolume but deleteVolume received %+v", unknown.Obj) + return + } + } else { + glog.Errorf("Expected PersistentVolume but deleteVolume received %+v", obj) + return + } + } + + if !ok || volume == nil || volume.Spec.ClaimRef == nil { + return + } + + if claimObj, exists, _ := ctrl.claims.GetByKey(claimrefToClaimKey(volume.Spec.ClaimRef)); exists { + if claim, ok := claimObj.(*api.PersistentVolumeClaim); ok && claim != nil { + // sync the claim when its volume is deleted. Explicitly syncing the + // claim here in response to volume deletion prevents the claim from + // waiting until the next sync period for its Lost status. + err := ctrl.syncClaim(claim) + if err != nil { + if errors.IsConflict(err) { + // Version conflict error happens quite often and the + // controller recovers from it easily. + glog.V(3).Infof("PersistentVolumeController could not update volume %q from deleteVolume handler: %+v", claimToClaimKey(claim), err) + } else { + glog.Errorf("PersistentVolumeController could not update volume %q from deleteVolume handler: %+v", claimToClaimKey(claim), err) + } + } + } else { + glog.Errorf("Cannot convert object from claim cache to claim %q!?: %+v", claimrefToClaimKey(volume.Spec.ClaimRef), claimObj) + } + } +} + +// addClaim is callback from framework.Controller watching PersistentVolumeClaim +// events. +func (ctrl *PersistentVolumeController) addClaim(obj interface{}) { + if !ctrl.isFullySynced() { + return + } + + claim, ok := obj.(*api.PersistentVolumeClaim) + if !ok { + glog.Errorf("Expected PersistentVolumeClaim but addClaim received %+v", obj) + return + } + if err := ctrl.syncClaim(claim); err != nil { + if errors.IsConflict(err) { + // Version conflict error happens quite often and the controller + // recovers from it easily. + glog.V(3).Infof("PersistentVolumeController could not add claim %q: %+v", claimToClaimKey(claim), err) + } else { + glog.Errorf("PersistentVolumeController could not add claim %q: %+v", claimToClaimKey(claim), err) + } + } +} + +// updateClaim is callback from framework.Controller watching PersistentVolumeClaim +// events. +func (ctrl *PersistentVolumeController) updateClaim(oldObj, newObj interface{}) { + if !ctrl.isFullySynced() { + return + } + + newClaim, ok := newObj.(*api.PersistentVolumeClaim) + if !ok { + glog.Errorf("Expected PersistentVolumeClaim but updateClaim received %+v", newObj) + return + } + if err := ctrl.syncClaim(newClaim); err != nil { + if errors.IsConflict(err) { + // Version conflict error happens quite often and the controller + // recovers from it easily. + glog.V(3).Infof("PersistentVolumeController could not update claim %q: %+v", claimToClaimKey(newClaim), err) + } else { + glog.Errorf("PersistentVolumeController could not update claim %q: %+v", claimToClaimKey(newClaim), err) + } + } +} + +// deleteClaim is callback from framework.Controller watching PersistentVolumeClaim +// events. +func (ctrl *PersistentVolumeController) deleteClaim(obj interface{}) { + if !ctrl.isFullySynced() { + return + } + + var volume *api.PersistentVolume + var claim *api.PersistentVolumeClaim + var ok bool + + claim, ok = obj.(*api.PersistentVolumeClaim) + if !ok { + if unknown, ok := obj.(cache.DeletedFinalStateUnknown); ok && unknown.Obj != nil { + claim, ok = unknown.Obj.(*api.PersistentVolumeClaim) + if !ok { + glog.Errorf("Expected PersistentVolumeClaim but deleteClaim received %+v", unknown.Obj) + return + } + } else { + glog.Errorf("Expected PersistentVolumeClaim but deleteClaim received %+v", obj) + return + } + } + + if !ok || claim == nil { + return + } + + if pvObj, exists, _ := ctrl.volumes.store.GetByKey(claim.Spec.VolumeName); exists { + if volume, ok = pvObj.(*api.PersistentVolume); ok { + // sync the volume when its claim is deleted. Explicitly sync'ing the + // volume here in response to claim deletion prevents the volume from + // waiting until the next sync period for its Release. + if volume != nil { + err := ctrl.syncVolume(volume) + if err != nil { + if errors.IsConflict(err) { + // Version conflict error happens quite often and the + // controller recovers from it easily. + glog.V(3).Infof("PersistentVolumeController could not update volume %q from deleteClaim handler: %+v", volume.Name, err) + } else { + glog.Errorf("PersistentVolumeController could not update volume %q from deleteClaim handler: %+v", volume.Name, err) + } + } + } + } else { + glog.Errorf("Cannot convert object from volume cache to volume %q!?: %+v", claim.Spec.VolumeName, pvObj) + } + } +} + +// Run starts all of this controller's control loops +func (ctrl *PersistentVolumeController) Run() { + glog.V(4).Infof("starting PersistentVolumeController") + + if ctrl.volumeControllerStopCh == nil { + ctrl.volumeControllerStopCh = make(chan struct{}) + go ctrl.volumeController.Run(ctrl.volumeControllerStopCh) + } + + if ctrl.claimControllerStopCh == nil { + ctrl.claimControllerStopCh = make(chan struct{}) + go ctrl.claimController.Run(ctrl.claimControllerStopCh) + } +} + +// Stop gracefully shuts down this controller +func (ctrl *PersistentVolumeController) Stop() { + glog.V(4).Infof("stopping PersistentVolumeController") + close(ctrl.volumeControllerStopCh) + close(ctrl.claimControllerStopCh) +} + +// isFullySynced returns true, if both volume and claim caches are fully loaded +// after startup. +// We do not want to process events with not fully loaded caches - e.g. we might +// recycle/delete PVs that don't have corresponding claim in the cache yet. +func (ctrl *PersistentVolumeController) isFullySynced() bool { + return ctrl.volumeController.HasSynced() && ctrl.claimController.HasSynced() +} + +// Stateless functions + +func hasAnnotation(obj api.ObjectMeta, ann string) bool { + _, found := obj.Annotations[ann] + return found +} + +func setAnnotation(obj *api.ObjectMeta, ann string, value string) { + if obj.Annotations == nil { + obj.Annotations = make(map[string]string) + } + obj.Annotations[ann] = value +} + +func getClaimStatusForLogging(claim *api.PersistentVolumeClaim) string { + bound := hasAnnotation(claim.ObjectMeta, annBindCompleted) + boundByController := hasAnnotation(claim.ObjectMeta, annBoundByController) + + return fmt.Sprintf("phase: %s, bound to: %q, bindCompleted: %v, boundByController: %v", claim.Status.Phase, claim.Spec.VolumeName, bound, boundByController) +} + +func getVolumeStatusForLogging(volume *api.PersistentVolume) string { + boundByController := hasAnnotation(volume.ObjectMeta, annBoundByController) + claimName := "" + if volume.Spec.ClaimRef != nil { + claimName = fmt.Sprintf("%s/%s (uid: %s)", volume.Spec.ClaimRef.Namespace, volume.Spec.ClaimRef.Name, volume.Spec.ClaimRef.UID) + } + return fmt.Sprintf("phase: %s, bound to: %q, boundByController: %v", volume.Status.Phase, claimName, boundByController) +} + +// isVolumeBoundToClaim returns true, if given volume is pre-bound or bound +// to specific claim. Both claim.Name and claim.Namespace must be equal. +// If claim.UID is present in volume.Spec.ClaimRef, it must be equal too. +func isVolumeBoundToClaim(volume *api.PersistentVolume, claim *api.PersistentVolumeClaim) bool { + if volume.Spec.ClaimRef == nil { + return false + } + if claim.Name != volume.Spec.ClaimRef.Name || claim.Namespace != volume.Spec.ClaimRef.Namespace { + return false + } + if volume.Spec.ClaimRef.UID != "" && claim.UID != volume.Spec.ClaimRef.UID { + return false + } + return true +} diff --git a/vendor/k8s.io/kubernetes/pkg/controller/persistentvolume/types.go b/vendor/k8s.io/kubernetes/pkg/controller/persistentvolume/index.go similarity index 77% rename from vendor/k8s.io/kubernetes/pkg/controller/persistentvolume/types.go rename to vendor/k8s.io/kubernetes/pkg/controller/persistentvolume/index.go index 42ca368018..8da72389bd 100644 --- a/vendor/k8s.io/kubernetes/pkg/controller/persistentvolume/types.go +++ b/vendor/k8s.io/kubernetes/pkg/controller/persistentvolume/index.go @@ -24,34 +24,9 @@ import ( "k8s.io/kubernetes/pkg/client/cache" ) -const ( - // A PVClaim can request a quality of service tier by adding this annotation. The value of the annotation - // is arbitrary. The values are pre-defined by a cluster admin and known to users when requesting a QoS. - // For example tiers might be gold, silver, and tin and the admin configures what that means for each volume plugin that can provision a volume. - // Values in the alpha version of this feature are not meaningful, but will be in the full version of this feature. - qosProvisioningKey = "volume.alpha.kubernetes.io/storage-class" - // Name of a tag attached to a real volume in cloud (e.g. AWS EBS or GCE PD) - // with namespace of a persistent volume claim used to create this volume. - cloudVolumeCreatedForClaimNamespaceTag = "kubernetes.io/created-for/pvc/namespace" - // Name of a tag attached to a real volume in cloud (e.g. AWS EBS or GCE PD) - // with name of a persistent volume claim used to create this volume. - cloudVolumeCreatedForClaimNameTag = "kubernetes.io/created-for/pvc/name" - // Name of a tag attached to a real volume in cloud (e.g. AWS EBS or GCE PD) - // with name of appropriate Kubernetes persistent volume . - cloudVolumeCreatedForVolumeNameTag = "kubernetes.io/created-for/pv/name" -) - // persistentVolumeOrderedIndex is a cache.Store that keeps persistent volumes indexed by AccessModes and ordered by storage capacity. type persistentVolumeOrderedIndex struct { - cache.Indexer -} - -var _ cache.Store = &persistentVolumeOrderedIndex{} // persistentVolumeOrderedIndex is a Store - -func NewPersistentVolumeOrderedIndex() *persistentVolumeOrderedIndex { - return &persistentVolumeOrderedIndex{ - cache.NewIndexer(cache.MetaNamespaceKeyFunc, cache.Indexers{"accessmodes": accessModesIndexFunc}), - } + store cache.Indexer } // accessModesIndexFunc is an indexing function that returns a persistent volume's AccessModes as a string @@ -63,15 +38,15 @@ func accessModesIndexFunc(obj interface{}) ([]string, error) { return []string{""}, fmt.Errorf("object is not a persistent volume: %v", obj) } -// ListByAccessModes returns all volumes with the given set of AccessModeTypes *in order* of their storage capacity (low to high) -func (pvIndex *persistentVolumeOrderedIndex) ListByAccessModes(modes []api.PersistentVolumeAccessMode) ([]*api.PersistentVolume, error) { +// listByAccessModes returns all volumes with the given set of AccessModeTypes *in order* of their storage capacity (low to high) +func (pvIndex *persistentVolumeOrderedIndex) listByAccessModes(modes []api.PersistentVolumeAccessMode) ([]*api.PersistentVolume, error) { pv := &api.PersistentVolume{ Spec: api.PersistentVolumeSpec{ AccessModes: modes, }, } - objs, err := pvIndex.Index("accessmodes", pv) + objs, err := pvIndex.store.Index("accessmodes", pv) if err != nil { return nil, err } @@ -101,7 +76,7 @@ func (pvIndex *persistentVolumeOrderedIndex) findByClaim(claim *api.PersistentVo allPossibleModes := pvIndex.allPossibleMatchingAccessModes(claim.Spec.AccessModes) for _, modes := range allPossibleModes { - volumes, err := pvIndex.ListByAccessModes(modes) + volumes, err := pvIndex.listByAccessModes(modes) if err != nil { return nil, err } @@ -117,16 +92,20 @@ func (pvIndex *persistentVolumeOrderedIndex) findByClaim(claim *api.PersistentVo continue } - if claim.Name == volume.Spec.ClaimRef.Name && claim.Namespace == volume.Spec.ClaimRef.Namespace && claim.UID == volume.Spec.ClaimRef.UID { - // exact match! No search required. + if isVolumeBoundToClaim(volume, claim) { + // Exact match! No search required. return volume, nil } } - // a claim requesting provisioning will have an exact match pre-bound to the claim. - // no need to search through unbound volumes. The matching volume will be created by the provisioner - // and will match above when the claim is re-processed by the binder. - if keyExists(qosProvisioningKey, claim.Annotations) { + // We want to provision volumes if the annotation is set even if there + // is matching PV. Therefore, do not look for available PV and let + // a new volume to be provisioned. + // + // When provisioner creates a new PV to this claim, an exact match + // pre-bound to the claim will be found by the checks above during + // subsequent claim sync. + if hasAnnotation(claim.ObjectMeta, annClass) { return nil, nil } @@ -213,7 +192,7 @@ func matchStorageCapacity(pvA, pvB *api.PersistentVolume) bool { // func (pvIndex *persistentVolumeOrderedIndex) allPossibleMatchingAccessModes(requestedModes []api.PersistentVolumeAccessMode) [][]api.PersistentVolumeAccessMode { matchedModes := [][]api.PersistentVolumeAccessMode{} - keys := pvIndex.Indexer.ListIndexFuncValues("accessmodes") + keys := pvIndex.store.ListIndexFuncValues("accessmodes") for _, key := range keys { indexedModes := api.GetAccessModesFromString(key) if containedInAll(indexedModes, requestedModes) { @@ -265,3 +244,7 @@ func (c byAccessModes) Len() int { func claimToClaimKey(claim *api.PersistentVolumeClaim) string { return fmt.Sprintf("%s/%s", claim.Namespace, claim.Name) } + +func claimrefToClaimKey(claimref *api.ObjectReference) string { + return fmt.Sprintf("%s/%s", claimref.Namespace, claimref.Name) +} diff --git a/vendor/k8s.io/kubernetes/pkg/controller/persistentvolume/persistentvolume_claim_binder_controller.go b/vendor/k8s.io/kubernetes/pkg/controller/persistentvolume/persistentvolume_claim_binder_controller.go deleted file mode 100644 index a0e105a09c..0000000000 --- a/vendor/k8s.io/kubernetes/pkg/controller/persistentvolume/persistentvolume_claim_binder_controller.go +++ /dev/null @@ -1,530 +0,0 @@ -/* -Copyright 2014 The Kubernetes Authors All rights reserved. - -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 persistentvolume - -import ( - "fmt" - "sync" - "time" - - "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/api/errors" - "k8s.io/kubernetes/pkg/client/cache" - clientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" - "k8s.io/kubernetes/pkg/controller/framework" - "k8s.io/kubernetes/pkg/conversion" - "k8s.io/kubernetes/pkg/runtime" - "k8s.io/kubernetes/pkg/util/metrics" - "k8s.io/kubernetes/pkg/watch" - - "github.com/golang/glog" -) - -// PersistentVolumeClaimBinder is a controller that synchronizes PersistentVolumeClaims. -type PersistentVolumeClaimBinder struct { - volumeIndex *persistentVolumeOrderedIndex - volumeController *framework.Controller - claimController *framework.Controller - client binderClient - stopChannels map[string]chan struct{} - lock sync.RWMutex -} - -// NewPersistentVolumeClaimBinder creates a new PersistentVolumeClaimBinder -func NewPersistentVolumeClaimBinder(kubeClient clientset.Interface, syncPeriod time.Duration) *PersistentVolumeClaimBinder { - if kubeClient != nil && kubeClient.Core().GetRESTClient().GetRateLimiter() != nil { - metrics.RegisterMetricAndTrackRateLimiterUsage("pv_claim_binder_controller", kubeClient.Core().GetRESTClient().GetRateLimiter()) - } - volumeIndex := NewPersistentVolumeOrderedIndex() - binderClient := NewBinderClient(kubeClient) - binder := &PersistentVolumeClaimBinder{ - volumeIndex: volumeIndex, - client: binderClient, - } - - _, volumeController := framework.NewInformer( - &cache.ListWatch{ - ListFunc: func(options api.ListOptions) (runtime.Object, error) { - return kubeClient.Core().PersistentVolumes().List(options) - }, - WatchFunc: func(options api.ListOptions) (watch.Interface, error) { - return kubeClient.Core().PersistentVolumes().Watch(options) - }, - }, - &api.PersistentVolume{}, - // TODO: Can we have much longer period here? - syncPeriod, - framework.ResourceEventHandlerFuncs{ - AddFunc: binder.addVolume, - UpdateFunc: binder.updateVolume, - DeleteFunc: binder.deleteVolume, - }, - ) - _, claimController := framework.NewInformer( - &cache.ListWatch{ - ListFunc: func(options api.ListOptions) (runtime.Object, error) { - return kubeClient.Core().PersistentVolumeClaims(api.NamespaceAll).List(options) - }, - WatchFunc: func(options api.ListOptions) (watch.Interface, error) { - return kubeClient.Core().PersistentVolumeClaims(api.NamespaceAll).Watch(options) - }, - }, - &api.PersistentVolumeClaim{}, - // TODO: Can we have much longer period here? - syncPeriod, - framework.ResourceEventHandlerFuncs{ - AddFunc: binder.addClaim, - UpdateFunc: binder.updateClaim, - DeleteFunc: binder.deleteClaim, - }, - ) - - binder.claimController = claimController - binder.volumeController = volumeController - - return binder -} -func (binder *PersistentVolumeClaimBinder) addVolume(obj interface{}) { - binder.lock.Lock() - defer binder.lock.Unlock() - pv, ok := obj.(*api.PersistentVolume) - if !ok { - glog.Errorf("Expected PersistentVolume but handler received %+v", obj) - return - } - if err := syncVolume(binder.volumeIndex, binder.client, pv); err != nil { - glog.Errorf("PVClaimBinder could not add volume %s: %+v", pv.Name, err) - } -} - -func (binder *PersistentVolumeClaimBinder) updateVolume(oldObj, newObj interface{}) { - binder.lock.Lock() - defer binder.lock.Unlock() - newVolume, ok := newObj.(*api.PersistentVolume) - if !ok { - glog.Errorf("Expected PersistentVolume but handler received %+v", newObj) - return - } - if err := binder.volumeIndex.Update(newVolume); err != nil { - glog.Errorf("Error updating volume %s in index: %v", newVolume.Name, err) - return - } - if err := syncVolume(binder.volumeIndex, binder.client, newVolume); err != nil { - glog.Errorf("PVClaimBinder could not update volume %s: %+v", newVolume.Name, err) - } -} - -func (binder *PersistentVolumeClaimBinder) deleteVolume(obj interface{}) { - binder.lock.Lock() - defer binder.lock.Unlock() - volume, ok := obj.(*api.PersistentVolume) - if !ok { - glog.Errorf("Expected PersistentVolume but handler received %+v", obj) - return - } - if err := binder.volumeIndex.Delete(volume); err != nil { - glog.Errorf("Error deleting volume %s from index: %v", volume.Name, err) - } -} - -func (binder *PersistentVolumeClaimBinder) addClaim(obj interface{}) { - binder.lock.Lock() - defer binder.lock.Unlock() - claim, ok := obj.(*api.PersistentVolumeClaim) - if !ok { - glog.Errorf("Expected PersistentVolumeClaim but handler received %+v", obj) - return - } - if err := syncClaim(binder.volumeIndex, binder.client, claim); err != nil { - glog.Errorf("PVClaimBinder could not add claim %s: %+v", claim.Name, err) - } -} - -func (binder *PersistentVolumeClaimBinder) updateClaim(oldObj, newObj interface{}) { - binder.lock.Lock() - defer binder.lock.Unlock() - newClaim, ok := newObj.(*api.PersistentVolumeClaim) - if !ok { - glog.Errorf("Expected PersistentVolumeClaim but handler received %+v", newObj) - return - } - if err := syncClaim(binder.volumeIndex, binder.client, newClaim); err != nil { - glog.Errorf("PVClaimBinder could not update claim %s: %+v", newClaim.Name, err) - } -} - -func (binder *PersistentVolumeClaimBinder) deleteClaim(obj interface{}) { - binder.lock.Lock() - defer binder.lock.Unlock() - var volume *api.PersistentVolume - if pvc, ok := obj.(*api.PersistentVolumeClaim); ok { - if pvObj, exists, _ := binder.volumeIndex.GetByKey(pvc.Spec.VolumeName); exists { - if pv, ok := pvObj.(*api.PersistentVolume); ok { - volume = pv - } - } - } - if unk, ok := obj.(cache.DeletedFinalStateUnknown); ok && unk.Obj != nil { - if pv, ok := unk.Obj.(*api.PersistentVolume); ok { - volume = pv - } - } - - // sync the volume when its claim is deleted. Explicitly sync'ing the volume here in response to - // claim deletion prevents the volume from waiting until the next sync period for its Release. - if volume != nil { - err := syncVolume(binder.volumeIndex, binder.client, volume) - if err != nil { - glog.Errorf("PVClaimBinder could not update volume %s from deleteClaim handler: %+v", volume.Name, err) - } - } -} - -func syncVolume(volumeIndex *persistentVolumeOrderedIndex, binderClient binderClient, volume *api.PersistentVolume) (err error) { - glog.V(5).Infof("Synchronizing PersistentVolume[%s], current phase: %s\n", volume.Name, volume.Status.Phase) - - // The PV may have been modified by parallel call to syncVolume, load - // the current version. - newPv, err := binderClient.GetPersistentVolume(volume.Name) - if err != nil { - return fmt.Errorf("Cannot reload volume %s: %v", volume.Name, err) - } - volume = newPv - - // volumes can be in one of the following states: - // - // VolumePending -- default value -- not bound to a claim and not yet processed through this controller. - // VolumeAvailable -- not bound to a claim, but processed at least once and found in this controller's volumeIndex. - // VolumeBound -- bound to a claim because volume.Spec.ClaimRef != nil. Claim status may not be correct. - // VolumeReleased -- volume.Spec.ClaimRef != nil but the claim has been deleted by the user. - // VolumeFailed -- volume.Spec.ClaimRef != nil and the volume failed processing in the recycler - currentPhase := volume.Status.Phase - nextPhase := currentPhase - - // Always store the newest volume state in local cache. - _, exists, err := volumeIndex.Get(volume) - if err != nil { - return err - } - if !exists { - volumeIndex.Add(volume) - } else { - volumeIndex.Update(volume) - } - - if isBeingProvisioned(volume) { - glog.V(4).Infof("Skipping PersistentVolume[%s], waiting for provisioning to finish", volume.Name) - return nil - } - - switch currentPhase { - case api.VolumePending: - - // 4 possible states: - // 1. ClaimRef != nil, Claim exists, Claim UID == ClaimRef UID: Prebound to claim. Make volume available for binding (it will match PVC). - // 2. ClaimRef != nil, Claim exists, Claim UID != ClaimRef UID: Recently recycled. Remove bind. Make volume available for new claim. - // 3. ClaimRef != nil, Claim !exists: Recently recycled. Remove bind. Make volume available for new claim. - // 4. ClaimRef == nil: Neither recycled nor prebound. Make volume available for binding. - nextPhase = api.VolumeAvailable - - if volume.Spec.ClaimRef != nil { - claim, err := binderClient.GetPersistentVolumeClaim(volume.Spec.ClaimRef.Namespace, volume.Spec.ClaimRef.Name) - switch { - case err != nil && !errors.IsNotFound(err): - return fmt.Errorf("Error getting PersistentVolumeClaim[%s/%s]: %v", volume.Spec.ClaimRef.Namespace, volume.Spec.ClaimRef.Name, err) - case errors.IsNotFound(err) || (claim != nil && claim.UID != volume.Spec.ClaimRef.UID): - glog.V(5).Infof("PersistentVolume[%s] has a claim ref to a claim which does not exist", volume.Name) - if volume.Spec.PersistentVolumeReclaimPolicy == api.PersistentVolumeReclaimRecycle { - // Pending volumes that have a ClaimRef where the claim is missing were recently recycled. - // The Recycler set the phase to VolumePending to start the volume at the beginning of this lifecycle. - // removing ClaimRef unbinds the volume - clone, err := conversion.NewCloner().DeepCopy(volume) - if err != nil { - return fmt.Errorf("Error cloning pv: %v", err) - } - volumeClone, ok := clone.(*api.PersistentVolume) - if !ok { - return fmt.Errorf("Unexpected pv cast error : %v\n", volumeClone) - } - glog.V(5).Infof("PersistentVolume[%s] is recently recycled; remove claimRef.", volume.Name) - volumeClone.Spec.ClaimRef = nil - - if updatedVolume, err := binderClient.UpdatePersistentVolume(volumeClone); err != nil { - return fmt.Errorf("Unexpected error saving PersistentVolume: %+v", err) - } else { - volume = updatedVolume - volumeIndex.Update(volume) - } - } else { - // Pending volumes that has a ClaimRef and the claim is missing and is was not recycled. - // It must have been freshly provisioned and the claim was deleted during the provisioning. - // Mark the volume as Released, it will be deleted. - nextPhase = api.VolumeReleased - } - } - - // Dynamically provisioned claims remain Pending until its volume is completely provisioned. - // The provisioner updates the PV and triggers this update for the volume. Explicitly sync'ing - // the claim here prevents the need to wait until the next sync period when the claim would normally - // advance to Bound phase. Otherwise, the maximum wait time for the claim to be Bound is the default sync period. - if claim != nil && claim.Status.Phase == api.ClaimPending && keyExists(qosProvisioningKey, claim.Annotations) && isProvisioningComplete(volume) { - syncClaim(volumeIndex, binderClient, claim) - } - } - glog.V(5).Infof("PersistentVolume[%s] is available\n", volume.Name) - - // available volumes await a claim - case api.VolumeAvailable: - if volume.Spec.ClaimRef != nil { - _, err := binderClient.GetPersistentVolumeClaim(volume.Spec.ClaimRef.Namespace, volume.Spec.ClaimRef.Name) - if err == nil { - // change of phase will trigger an update event with the newly bound volume - glog.V(5).Infof("PersistentVolume[%s] is now bound\n", volume.Name) - nextPhase = api.VolumeBound - } else { - if errors.IsNotFound(err) { - nextPhase = api.VolumeReleased - } - } - } - - //bound volumes require verification of their bound claims - case api.VolumeBound: - if volume.Spec.ClaimRef == nil { - return fmt.Errorf("PersistentVolume[%s] expected to be bound but found nil claimRef: %+v", volume.Name, volume) - } else { - claim, err := binderClient.GetPersistentVolumeClaim(volume.Spec.ClaimRef.Namespace, volume.Spec.ClaimRef.Name) - - // A volume is Released when its bound claim cannot be found in the API server. - // A claim by the same name can be found if deleted and recreated before this controller can release - // the volume from the original claim, so a UID check is necessary. - if err != nil { - if errors.IsNotFound(err) { - nextPhase = api.VolumeReleased - } else { - return err - } - } else if claim != nil && claim.UID != volume.Spec.ClaimRef.UID { - nextPhase = api.VolumeReleased - } - } - - // released volumes require recycling - case api.VolumeReleased: - if volume.Spec.ClaimRef == nil { - return fmt.Errorf("PersistentVolume[%s] expected to be bound but found nil claimRef: %+v", volume.Name, volume) - } else { - // another process is watching for released volumes. - // PersistentVolumeReclaimPolicy is set per PersistentVolume - // Recycle - sets the PV to Pending and back under this controller's management - // Delete - delete events are handled by this controller's watch. PVs are removed from the index. - } - - // volumes are removed by processes external to this binder and must be removed from the cluster - case api.VolumeFailed: - if volume.Spec.ClaimRef == nil { - return fmt.Errorf("PersistentVolume[%s] expected to be bound but found nil claimRef: %+v", volume.Name, volume) - } else { - glog.V(5).Infof("PersistentVolume[%s] previously failed recycling. Skipping.\n", volume.Name) - } - } - - if currentPhase != nextPhase { - volume.Status.Phase = nextPhase - - // a change in state will trigger another update through this controller. - // each pass through this controller evaluates current phase and decides whether or not to change to the next phase - glog.V(5).Infof("PersistentVolume[%s] changing phase from %s to %s\n", volume.Name, currentPhase, nextPhase) - volume, err := binderClient.UpdatePersistentVolumeStatus(volume) - if err != nil { - // Rollback to previous phase - volume.Status.Phase = currentPhase - } - volumeIndex.Update(volume) - } - - return nil -} - -func syncClaim(volumeIndex *persistentVolumeOrderedIndex, binderClient binderClient, claim *api.PersistentVolumeClaim) (err error) { - glog.V(5).Infof("Synchronizing PersistentVolumeClaim[%s] for binding", claim.Name) - - // The claim may have been modified by parallel call to syncClaim, load - // the current version. - newClaim, err := binderClient.GetPersistentVolumeClaim(claim.Namespace, claim.Name) - if err != nil { - return fmt.Errorf("Cannot reload claim %s/%s: %v", claim.Namespace, claim.Name, err) - } - claim = newClaim - - switch claim.Status.Phase { - case api.ClaimPending: - // claims w/ a storage-class annotation for provisioning with *only* match volumes with a ClaimRef of the claim. - volume, err := volumeIndex.findBestMatchForClaim(claim) - if err != nil { - return err - } - - if volume == nil { - glog.V(5).Infof("A volume match does not exist for persistent claim: %s", claim.Name) - return nil - } - - if isBeingProvisioned(volume) { - glog.V(5).Infof("PersistentVolume[%s] for PersistentVolumeClaim[%s/%s] is still being provisioned.", volume.Name, claim.Namespace, claim.Name) - return nil - } - - claimRef, err := api.GetReference(claim) - if err != nil { - return fmt.Errorf("Unexpected error getting claim reference: %v\n", err) - } - - // Make a binding reference to the claim by persisting claimRef on the volume. - // The local cache must be updated with the new bind to prevent subsequent - // claims from binding to the volume. - if volume.Spec.ClaimRef == nil { - clone, err := conversion.NewCloner().DeepCopy(volume) - if err != nil { - return fmt.Errorf("Error cloning pv: %v", err) - } - volumeClone, ok := clone.(*api.PersistentVolume) - if !ok { - return fmt.Errorf("Unexpected pv cast error : %v\n", volumeClone) - } - volumeClone.Spec.ClaimRef = claimRef - if updatedVolume, err := binderClient.UpdatePersistentVolume(volumeClone); err != nil { - return fmt.Errorf("Unexpected error saving PersistentVolume.Status: %+v", err) - } else { - volume = updatedVolume - volumeIndex.Update(updatedVolume) - } - } - - // the bind is persisted on the volume above and will always match the claim in a search. - // claim would remain Pending if the update fails, so processing this state is idempotent. - // this only needs to be processed once. - if claim.Spec.VolumeName != volume.Name { - claim.Spec.VolumeName = volume.Name - claim, err = binderClient.UpdatePersistentVolumeClaim(claim) - if err != nil { - return fmt.Errorf("Error updating claim with VolumeName %s: %+v\n", volume.Name, err) - } - } - - claim.Status.Phase = api.ClaimBound - claim.Status.AccessModes = volume.Spec.AccessModes - claim.Status.Capacity = volume.Spec.Capacity - _, err = binderClient.UpdatePersistentVolumeClaimStatus(claim) - if err != nil { - return fmt.Errorf("Unexpected error saving claim status: %+v", err) - } - - case api.ClaimBound: - // no-op. Claim is bound, values from PV are set. PVCs are technically mutable in the API server - // and we don't want to handle those changes at this time. - - default: - return fmt.Errorf("Unknown state for PVC: %#v", claim) - - } - - glog.V(5).Infof("PersistentVolumeClaim[%s] is bound\n", claim.Name) - return nil -} - -func isBeingProvisioned(volume *api.PersistentVolume) bool { - value, found := volume.Annotations[pvProvisioningRequiredAnnotationKey] - if found && value != pvProvisioningCompletedAnnotationValue { - return true - } - return false -} - -// Run starts all of this binder's control loops -func (controller *PersistentVolumeClaimBinder) Run() { - glog.V(5).Infof("Starting PersistentVolumeClaimBinder\n") - if controller.stopChannels == nil { - controller.stopChannels = make(map[string]chan struct{}) - } - - if _, exists := controller.stopChannels["volumes"]; !exists { - controller.stopChannels["volumes"] = make(chan struct{}) - go controller.volumeController.Run(controller.stopChannels["volumes"]) - } - - if _, exists := controller.stopChannels["claims"]; !exists { - controller.stopChannels["claims"] = make(chan struct{}) - go controller.claimController.Run(controller.stopChannels["claims"]) - } -} - -// Stop gracefully shuts down this binder -func (controller *PersistentVolumeClaimBinder) Stop() { - glog.V(5).Infof("Stopping PersistentVolumeClaimBinder\n") - for name, stopChan := range controller.stopChannels { - close(stopChan) - delete(controller.stopChannels, name) - } -} - -// binderClient abstracts access to PVs and PVCs -type binderClient interface { - GetPersistentVolume(name string) (*api.PersistentVolume, error) - UpdatePersistentVolume(volume *api.PersistentVolume) (*api.PersistentVolume, error) - DeletePersistentVolume(volume *api.PersistentVolume) error - UpdatePersistentVolumeStatus(volume *api.PersistentVolume) (*api.PersistentVolume, error) - GetPersistentVolumeClaim(namespace, name string) (*api.PersistentVolumeClaim, error) - UpdatePersistentVolumeClaim(claim *api.PersistentVolumeClaim) (*api.PersistentVolumeClaim, error) - UpdatePersistentVolumeClaimStatus(claim *api.PersistentVolumeClaim) (*api.PersistentVolumeClaim, error) -} - -func NewBinderClient(c clientset.Interface) binderClient { - return &realBinderClient{c} -} - -type realBinderClient struct { - client clientset.Interface -} - -func (c *realBinderClient) GetPersistentVolume(name string) (*api.PersistentVolume, error) { - return c.client.Core().PersistentVolumes().Get(name) -} - -func (c *realBinderClient) UpdatePersistentVolume(volume *api.PersistentVolume) (*api.PersistentVolume, error) { - return c.client.Core().PersistentVolumes().Update(volume) -} - -func (c *realBinderClient) DeletePersistentVolume(volume *api.PersistentVolume) error { - return c.client.Core().PersistentVolumes().Delete(volume.Name, nil) -} - -func (c *realBinderClient) UpdatePersistentVolumeStatus(volume *api.PersistentVolume) (*api.PersistentVolume, error) { - return c.client.Core().PersistentVolumes().UpdateStatus(volume) -} - -func (c *realBinderClient) GetPersistentVolumeClaim(namespace, name string) (*api.PersistentVolumeClaim, error) { - return c.client.Core().PersistentVolumeClaims(namespace).Get(name) -} - -func (c *realBinderClient) UpdatePersistentVolumeClaim(claim *api.PersistentVolumeClaim) (*api.PersistentVolumeClaim, error) { - return c.client.Core().PersistentVolumeClaims(claim.Namespace).Update(claim) -} - -func (c *realBinderClient) UpdatePersistentVolumeClaimStatus(claim *api.PersistentVolumeClaim) (*api.PersistentVolumeClaim, error) { - return c.client.Core().PersistentVolumeClaims(claim.Namespace).UpdateStatus(claim) -} diff --git a/vendor/k8s.io/kubernetes/pkg/controller/persistentvolume/persistentvolume_provisioner_controller.go b/vendor/k8s.io/kubernetes/pkg/controller/persistentvolume/persistentvolume_provisioner_controller.go deleted file mode 100644 index fdb7804a3e..0000000000 --- a/vendor/k8s.io/kubernetes/pkg/controller/persistentvolume/persistentvolume_provisioner_controller.go +++ /dev/null @@ -1,536 +0,0 @@ -/* -Copyright 2015 The Kubernetes Authors All rights reserved. - -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 persistentvolume - -import ( - "fmt" - "sync" - "time" - - "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/client/cache" - clientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" - "k8s.io/kubernetes/pkg/cloudprovider" - "k8s.io/kubernetes/pkg/controller/framework" - "k8s.io/kubernetes/pkg/conversion" - "k8s.io/kubernetes/pkg/runtime" - "k8s.io/kubernetes/pkg/types" - "k8s.io/kubernetes/pkg/util/io" - "k8s.io/kubernetes/pkg/util/mount" - "k8s.io/kubernetes/pkg/volume" - "k8s.io/kubernetes/pkg/watch" - - "github.com/golang/glog" -) - -// PersistentVolumeProvisionerController reconciles the state of all PersistentVolumes and PersistentVolumeClaims. -type PersistentVolumeProvisionerController struct { - volumeController *framework.Controller - volumeStore cache.Store - claimController *framework.Controller - claimStore cache.Store - client controllerClient - cloud cloudprovider.Interface - provisioner volume.ProvisionableVolumePlugin - pluginMgr volume.VolumePluginMgr - stopChannels map[string]chan struct{} - mutex sync.RWMutex - clusterName string -} - -// constant name values for the controllers stopChannels map. -// the controller uses these for graceful shutdown -const volumesStopChannel = "volumes" -const claimsStopChannel = "claims" - -// NewPersistentVolumeProvisionerController creates a new PersistentVolumeProvisionerController -func NewPersistentVolumeProvisionerController(client controllerClient, syncPeriod time.Duration, clusterName string, plugins []volume.VolumePlugin, provisioner volume.ProvisionableVolumePlugin, cloud cloudprovider.Interface) (*PersistentVolumeProvisionerController, error) { - controller := &PersistentVolumeProvisionerController{ - client: client, - cloud: cloud, - provisioner: provisioner, - clusterName: clusterName, - } - - if err := controller.pluginMgr.InitPlugins(plugins, controller); err != nil { - return nil, fmt.Errorf("Could not initialize volume plugins for PersistentVolumeProvisionerController: %+v", err) - } - - glog.V(5).Infof("Initializing provisioner: %s", controller.provisioner.Name()) - controller.provisioner.Init(controller) - - controller.volumeStore, controller.volumeController = framework.NewInformer( - &cache.ListWatch{ - ListFunc: func(options api.ListOptions) (runtime.Object, error) { - return client.ListPersistentVolumes(options) - }, - WatchFunc: func(options api.ListOptions) (watch.Interface, error) { - return client.WatchPersistentVolumes(options) - }, - }, - &api.PersistentVolume{}, - syncPeriod, - framework.ResourceEventHandlerFuncs{ - AddFunc: controller.handleAddVolume, - UpdateFunc: controller.handleUpdateVolume, - // delete handler not needed in this controller. - // volume deletion is handled by the recycler controller - }, - ) - controller.claimStore, controller.claimController = framework.NewInformer( - &cache.ListWatch{ - ListFunc: func(options api.ListOptions) (runtime.Object, error) { - return client.ListPersistentVolumeClaims(api.NamespaceAll, options) - }, - WatchFunc: func(options api.ListOptions) (watch.Interface, error) { - return client.WatchPersistentVolumeClaims(api.NamespaceAll, options) - }, - }, - &api.PersistentVolumeClaim{}, - syncPeriod, - framework.ResourceEventHandlerFuncs{ - AddFunc: controller.handleAddClaim, - UpdateFunc: controller.handleUpdateClaim, - // delete handler not needed. - // normal recycling applies when a claim is deleted. - // recycling is handled by the binding controller. - }, - ) - - return controller, nil -} - -func (controller *PersistentVolumeProvisionerController) handleAddVolume(obj interface{}) { - controller.mutex.Lock() - defer controller.mutex.Unlock() - cachedPv, _, _ := controller.volumeStore.Get(obj) - if pv, ok := cachedPv.(*api.PersistentVolume); ok { - err := controller.reconcileVolume(pv) - if err != nil { - glog.Errorf("Error reconciling volume %s: %+v", pv.Name, err) - } - } -} - -func (controller *PersistentVolumeProvisionerController) handleUpdateVolume(oldObj, newObj interface{}) { - // The flow for Update is the same as Add. - // A volume is only provisioned if not done so already. - controller.handleAddVolume(newObj) -} - -func (controller *PersistentVolumeProvisionerController) handleAddClaim(obj interface{}) { - controller.mutex.Lock() - defer controller.mutex.Unlock() - cachedPvc, exists, _ := controller.claimStore.Get(obj) - if !exists { - glog.Errorf("PersistentVolumeClaim does not exist in the local cache: %+v", obj) - return - } - if pvc, ok := cachedPvc.(*api.PersistentVolumeClaim); ok { - err := controller.reconcileClaim(pvc) - if err != nil { - glog.Errorf("Error encoutered reconciling claim %s: %+v", pvc.Name, err) - } - } -} - -func (controller *PersistentVolumeProvisionerController) handleUpdateClaim(oldObj, newObj interface{}) { - // The flow for Update is the same as Add. - // A volume is only provisioned for a claim if not done so already. - controller.handleAddClaim(newObj) -} - -func (controller *PersistentVolumeProvisionerController) reconcileClaim(claim *api.PersistentVolumeClaim) error { - glog.V(5).Infof("Synchronizing PersistentVolumeClaim[%s] for dynamic provisioning", claim.Name) - - // The claim may have been modified by parallel call to reconcileClaim, load - // the current version. - newClaim, err := controller.client.GetPersistentVolumeClaim(claim.Namespace, claim.Name) - if err != nil { - return fmt.Errorf("Cannot reload claim %s/%s: %v", claim.Namespace, claim.Name, err) - } - claim = newClaim - err = controller.claimStore.Update(claim) - if err != nil { - return fmt.Errorf("Cannot update claim %s/%s: %v", claim.Namespace, claim.Name, err) - } - - if controller.provisioner == nil { - return fmt.Errorf("No provisioner configured for controller") - } - - // no provisioning requested, return Pending. Claim may be pending indefinitely without a match. - if !keyExists(qosProvisioningKey, claim.Annotations) { - glog.V(5).Infof("PersistentVolumeClaim[%s] no provisioning required", claim.Name) - return nil - } - if len(claim.Spec.VolumeName) != 0 { - glog.V(5).Infof("PersistentVolumeClaim[%s] already bound. No provisioning required", claim.Name) - return nil - } - if isAnnotationMatch(pvProvisioningRequiredAnnotationKey, pvProvisioningCompletedAnnotationValue, claim.Annotations) { - glog.V(5).Infof("PersistentVolumeClaim[%s] is already provisioned.", claim.Name) - return nil - } - - glog.V(5).Infof("PersistentVolumeClaim[%s] provisioning", claim.Name) - provisioner, err := controller.newProvisioner(controller.provisioner, claim, nil) - if err != nil { - return fmt.Errorf("Unexpected error getting new provisioner for claim %s: %v\n", claim.Name, err) - } - newVolume, err := provisioner.NewPersistentVolumeTemplate() - if err != nil { - return fmt.Errorf("Unexpected error getting new volume template for claim %s: %v\n", claim.Name, err) - } - - claimRef, err := api.GetReference(claim) - if err != nil { - return fmt.Errorf("Unexpected error getting claim reference for %s: %v\n", claim.Name, err) - } - - storageClass, _ := claim.Annotations[qosProvisioningKey] - - // the creation of this volume is the bind to the claim. - // The claim will match the volume during the next sync period when the volume is in the local cache - newVolume.Spec.ClaimRef = claimRef - newVolume.Annotations[pvProvisioningRequiredAnnotationKey] = "true" - newVolume.Annotations[qosProvisioningKey] = storageClass - newVolume, err = controller.client.CreatePersistentVolume(newVolume) - glog.V(5).Infof("Unprovisioned PersistentVolume[%s] created for PVC[%s], which will be fulfilled in the storage provider", newVolume.Name, claim.Name) - if err != nil { - return fmt.Errorf("PersistentVolumeClaim[%s] failed provisioning: %+v", claim.Name, err) - } - - claim.Annotations[pvProvisioningRequiredAnnotationKey] = pvProvisioningCompletedAnnotationValue - _, err = controller.client.UpdatePersistentVolumeClaim(claim) - if err != nil { - glog.Errorf("error updating persistent volume claim: %v", err) - } - - return nil -} - -func (controller *PersistentVolumeProvisionerController) reconcileVolume(pv *api.PersistentVolume) error { - glog.V(5).Infof("PersistentVolume[%s] reconciling", pv.Name) - - // The PV may have been modified by parallel call to reconcileVolume, load - // the current version. - newPv, err := controller.client.GetPersistentVolume(pv.Name) - if err != nil { - return fmt.Errorf("Cannot reload volume %s: %v", pv.Name, err) - } - pv = newPv - - if pv.Spec.ClaimRef == nil { - glog.V(5).Infof("PersistentVolume[%s] is not bound to a claim. No provisioning required", pv.Name) - return nil - } - - // TODO: fix this leaky abstraction. Had to make our own store key because ClaimRef fails the default keyfunc (no Meta on object). - obj, exists, _ := controller.claimStore.GetByKey(fmt.Sprintf("%s/%s", pv.Spec.ClaimRef.Namespace, pv.Spec.ClaimRef.Name)) - if !exists { - return fmt.Errorf("PersistentVolumeClaim[%s/%s] not found in local cache", pv.Spec.ClaimRef.Namespace, pv.Spec.ClaimRef.Name) - } - - claim, ok := obj.(*api.PersistentVolumeClaim) - if !ok { - return fmt.Errorf("PersistentVolumeClaim expected, but got %v", obj) - } - - // no provisioning required, volume is ready and Bound - if !keyExists(pvProvisioningRequiredAnnotationKey, pv.Annotations) { - glog.V(5).Infof("PersistentVolume[%s] does not require provisioning", pv.Name) - return nil - } - - // provisioning is completed, volume is ready. - if isProvisioningComplete(pv) { - glog.V(5).Infof("PersistentVolume[%s] is bound and provisioning is complete", pv.Name) - if pv.Spec.ClaimRef.Namespace != claim.Namespace || pv.Spec.ClaimRef.Name != claim.Name { - return fmt.Errorf("pre-bind mismatch - expected %s but found %s/%s", claimToClaimKey(claim), pv.Spec.ClaimRef.Namespace, pv.Spec.ClaimRef.Name) - } - return nil - } - - // provisioning is incomplete. Attempt to provision the volume. - glog.V(5).Infof("PersistentVolume[%s] provisioning in progress", pv.Name) - err = provisionVolume(pv, controller) - if err != nil { - return fmt.Errorf("Error provisioning PersistentVolume[%s]: %v", pv.Name, err) - } - - return nil -} - -// provisionVolume provisions a volume that has been created in the cluster but not yet fulfilled by -// the storage provider. -func provisionVolume(pv *api.PersistentVolume, controller *PersistentVolumeProvisionerController) error { - if isProvisioningComplete(pv) { - return fmt.Errorf("PersistentVolume[%s] is already provisioned", pv.Name) - } - - if _, exists := pv.Annotations[qosProvisioningKey]; !exists { - return fmt.Errorf("PersistentVolume[%s] does not contain a provisioning request. Provisioning not required.", pv.Name) - } - - if controller.provisioner == nil { - return fmt.Errorf("No provisioner found for volume: %s", pv.Name) - } - - // Find the claim in local cache - obj, exists, _ := controller.claimStore.GetByKey(fmt.Sprintf("%s/%s", pv.Spec.ClaimRef.Namespace, pv.Spec.ClaimRef.Name)) - if !exists { - return fmt.Errorf("Could not find PersistentVolumeClaim[%s/%s] in local cache", pv.Spec.ClaimRef.Name, pv.Name) - } - claim := obj.(*api.PersistentVolumeClaim) - - provisioner, _ := controller.newProvisioner(controller.provisioner, claim, pv) - err := provisioner.Provision(pv) - if err != nil { - glog.Errorf("Could not provision %s", pv.Name) - pv.Status.Phase = api.VolumeFailed - pv.Status.Message = err.Error() - if pv, apiErr := controller.client.UpdatePersistentVolumeStatus(pv); apiErr != nil { - return fmt.Errorf("PersistentVolume[%s] failed provisioning and also failed status update: %v - %v", pv.Name, err, apiErr) - } - return fmt.Errorf("PersistentVolume[%s] failed provisioning: %v", pv.Name, err) - } - - clone, err := conversion.NewCloner().DeepCopy(pv) - volumeClone, ok := clone.(*api.PersistentVolume) - if !ok { - return fmt.Errorf("Unexpected pv cast error : %v\n", volumeClone) - } - volumeClone.Annotations[pvProvisioningRequiredAnnotationKey] = pvProvisioningCompletedAnnotationValue - - pv, err = controller.client.UpdatePersistentVolume(volumeClone) - if err != nil { - // TODO: https://github.com/kubernetes/kubernetes/issues/14443 - // the volume was created in the infrastructure and likely has a PV name on it, - // but we failed to save the annotation that marks the volume as provisioned. - return fmt.Errorf("Error updating PersistentVolume[%s] with provisioning completed annotation. There is a potential for dupes and orphans.", volumeClone.Name) - } - return nil -} - -// Run starts all of this controller's control loops -func (controller *PersistentVolumeProvisionerController) Run() { - glog.V(5).Infof("Starting PersistentVolumeProvisionerController\n") - if controller.stopChannels == nil { - controller.stopChannels = make(map[string]chan struct{}) - } - - if _, exists := controller.stopChannels[volumesStopChannel]; !exists { - controller.stopChannels[volumesStopChannel] = make(chan struct{}) - go controller.volumeController.Run(controller.stopChannels[volumesStopChannel]) - } - - if _, exists := controller.stopChannels[claimsStopChannel]; !exists { - controller.stopChannels[claimsStopChannel] = make(chan struct{}) - go controller.claimController.Run(controller.stopChannels[claimsStopChannel]) - } -} - -// Stop gracefully shuts down this controller -func (controller *PersistentVolumeProvisionerController) Stop() { - glog.V(5).Infof("Stopping PersistentVolumeProvisionerController\n") - for name, stopChan := range controller.stopChannels { - close(stopChan) - delete(controller.stopChannels, name) - } -} - -func (controller *PersistentVolumeProvisionerController) newProvisioner(plugin volume.ProvisionableVolumePlugin, claim *api.PersistentVolumeClaim, pv *api.PersistentVolume) (volume.Provisioner, error) { - tags := make(map[string]string) - tags[cloudVolumeCreatedForClaimNamespaceTag] = claim.Namespace - tags[cloudVolumeCreatedForClaimNameTag] = claim.Name - - // pv can be nil when the provisioner has not created the PV yet - if pv != nil { - tags[cloudVolumeCreatedForVolumeNameTag] = pv.Name - } - - volumeOptions := volume.VolumeOptions{ - Capacity: claim.Spec.Resources.Requests[api.ResourceName(api.ResourceStorage)], - AccessModes: claim.Spec.AccessModes, - PersistentVolumeReclaimPolicy: api.PersistentVolumeReclaimDelete, - CloudTags: &tags, - ClusterName: controller.clusterName, - } - - if pv != nil { - volumeOptions.PVName = pv.Name - } - - provisioner, err := plugin.NewProvisioner(volumeOptions) - return provisioner, err -} - -// controllerClient abstracts access to PVs and PVCs. Easy to mock for testing and wrap for real client. -type controllerClient interface { - CreatePersistentVolume(pv *api.PersistentVolume) (*api.PersistentVolume, error) - ListPersistentVolumes(options api.ListOptions) (*api.PersistentVolumeList, error) - WatchPersistentVolumes(options api.ListOptions) (watch.Interface, error) - GetPersistentVolume(name string) (*api.PersistentVolume, error) - UpdatePersistentVolume(volume *api.PersistentVolume) (*api.PersistentVolume, error) - DeletePersistentVolume(volume *api.PersistentVolume) error - UpdatePersistentVolumeStatus(volume *api.PersistentVolume) (*api.PersistentVolume, error) - - GetPersistentVolumeClaim(namespace, name string) (*api.PersistentVolumeClaim, error) - ListPersistentVolumeClaims(namespace string, options api.ListOptions) (*api.PersistentVolumeClaimList, error) - WatchPersistentVolumeClaims(namespace string, options api.ListOptions) (watch.Interface, error) - UpdatePersistentVolumeClaim(claim *api.PersistentVolumeClaim) (*api.PersistentVolumeClaim, error) - UpdatePersistentVolumeClaimStatus(claim *api.PersistentVolumeClaim) (*api.PersistentVolumeClaim, error) - - // provided to give VolumeHost and plugins access to the kube client - GetKubeClient() clientset.Interface -} - -func NewControllerClient(c clientset.Interface) controllerClient { - return &realControllerClient{c} -} - -var _ controllerClient = &realControllerClient{} - -type realControllerClient struct { - client clientset.Interface -} - -func (c *realControllerClient) GetPersistentVolume(name string) (*api.PersistentVolume, error) { - return c.client.Core().PersistentVolumes().Get(name) -} - -func (c *realControllerClient) ListPersistentVolumes(options api.ListOptions) (*api.PersistentVolumeList, error) { - return c.client.Core().PersistentVolumes().List(options) -} - -func (c *realControllerClient) WatchPersistentVolumes(options api.ListOptions) (watch.Interface, error) { - return c.client.Core().PersistentVolumes().Watch(options) -} - -func (c *realControllerClient) CreatePersistentVolume(pv *api.PersistentVolume) (*api.PersistentVolume, error) { - return c.client.Core().PersistentVolumes().Create(pv) -} - -func (c *realControllerClient) UpdatePersistentVolume(volume *api.PersistentVolume) (*api.PersistentVolume, error) { - return c.client.Core().PersistentVolumes().Update(volume) -} - -func (c *realControllerClient) DeletePersistentVolume(volume *api.PersistentVolume) error { - return c.client.Core().PersistentVolumes().Delete(volume.Name, nil) -} - -func (c *realControllerClient) UpdatePersistentVolumeStatus(volume *api.PersistentVolume) (*api.PersistentVolume, error) { - return c.client.Core().PersistentVolumes().UpdateStatus(volume) -} - -func (c *realControllerClient) GetPersistentVolumeClaim(namespace, name string) (*api.PersistentVolumeClaim, error) { - return c.client.Core().PersistentVolumeClaims(namespace).Get(name) -} - -func (c *realControllerClient) ListPersistentVolumeClaims(namespace string, options api.ListOptions) (*api.PersistentVolumeClaimList, error) { - return c.client.Core().PersistentVolumeClaims(namespace).List(options) -} - -func (c *realControllerClient) WatchPersistentVolumeClaims(namespace string, options api.ListOptions) (watch.Interface, error) { - return c.client.Core().PersistentVolumeClaims(namespace).Watch(options) -} - -func (c *realControllerClient) UpdatePersistentVolumeClaim(claim *api.PersistentVolumeClaim) (*api.PersistentVolumeClaim, error) { - return c.client.Core().PersistentVolumeClaims(claim.Namespace).Update(claim) -} - -func (c *realControllerClient) UpdatePersistentVolumeClaimStatus(claim *api.PersistentVolumeClaim) (*api.PersistentVolumeClaim, error) { - return c.client.Core().PersistentVolumeClaims(claim.Namespace).UpdateStatus(claim) -} - -func (c *realControllerClient) GetKubeClient() clientset.Interface { - return c.client -} - -func keyExists(key string, haystack map[string]string) bool { - _, exists := haystack[key] - return exists -} - -func isProvisioningComplete(pv *api.PersistentVolume) bool { - return isAnnotationMatch(pvProvisioningRequiredAnnotationKey, pvProvisioningCompletedAnnotationValue, pv.Annotations) -} - -func isAnnotationMatch(key, needle string, haystack map[string]string) bool { - value, exists := haystack[key] - if !exists { - return false - } - return value == needle -} - -func isRecyclable(policy api.PersistentVolumeReclaimPolicy) bool { - return policy == api.PersistentVolumeReclaimDelete || policy == api.PersistentVolumeReclaimRecycle -} - -// VolumeHost implementation -// PersistentVolumeRecycler is host to the volume plugins, but does not actually mount any volumes. -// Because no mounting is performed, most of the VolumeHost methods are not implemented. -func (c *PersistentVolumeProvisionerController) GetPluginDir(podUID string) string { - return "" -} - -func (c *PersistentVolumeProvisionerController) GetPodVolumeDir(podUID types.UID, pluginName, volumeName string) string { - return "" -} - -func (c *PersistentVolumeProvisionerController) GetPodPluginDir(podUID types.UID, pluginName string) string { - return "" -} - -func (c *PersistentVolumeProvisionerController) GetKubeClient() clientset.Interface { - return c.client.GetKubeClient() -} - -func (c *PersistentVolumeProvisionerController) NewWrapperMounter(volName string, spec volume.Spec, pod *api.Pod, opts volume.VolumeOptions) (volume.Mounter, error) { - return nil, fmt.Errorf("NewWrapperMounter not supported by PVClaimBinder's VolumeHost implementation") -} - -func (c *PersistentVolumeProvisionerController) NewWrapperUnmounter(volName string, spec volume.Spec, podUID types.UID) (volume.Unmounter, error) { - return nil, fmt.Errorf("NewWrapperUnmounter not supported by PVClaimBinder's VolumeHost implementation") -} - -func (c *PersistentVolumeProvisionerController) GetCloudProvider() cloudprovider.Interface { - return c.cloud -} - -func (c *PersistentVolumeProvisionerController) GetMounter() mount.Interface { - return nil -} - -func (c *PersistentVolumeProvisionerController) GetWriter() io.Writer { - return nil -} - -func (c *PersistentVolumeProvisionerController) GetHostName() string { - return "" -} - -const ( - // these pair of constants are used by the provisioner. - // The key is a kube namespaced key that denotes a volume requires provisioning. - // The value is set only when provisioning is completed. Any other value will tell the provisioner - // that provisioning has not yet occurred. - pvProvisioningRequiredAnnotationKey = "volume.experimental.kubernetes.io/provisioning-required" - pvProvisioningCompletedAnnotationValue = "volume.experimental.kubernetes.io/provisioning-completed" -) diff --git a/vendor/k8s.io/kubernetes/pkg/controller/persistentvolume/persistentvolume_recycler_controller.go b/vendor/k8s.io/kubernetes/pkg/controller/persistentvolume/persistentvolume_recycler_controller.go deleted file mode 100644 index e73a5b9ebc..0000000000 --- a/vendor/k8s.io/kubernetes/pkg/controller/persistentvolume/persistentvolume_recycler_controller.go +++ /dev/null @@ -1,415 +0,0 @@ -/* -Copyright 2014 The Kubernetes Authors All rights reserved. - -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 persistentvolume - -import ( - "fmt" - "time" - - "github.com/golang/glog" - "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/client/cache" - clientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" - "k8s.io/kubernetes/pkg/cloudprovider" - "k8s.io/kubernetes/pkg/controller/framework" - "k8s.io/kubernetes/pkg/runtime" - "k8s.io/kubernetes/pkg/types" - ioutil "k8s.io/kubernetes/pkg/util/io" - "k8s.io/kubernetes/pkg/util/metrics" - "k8s.io/kubernetes/pkg/util/mount" - "k8s.io/kubernetes/pkg/volume" - "k8s.io/kubernetes/pkg/watch" -) - -var _ volume.VolumeHost = &PersistentVolumeRecycler{} - -// PersistentVolumeRecycler is a controller that watches for PersistentVolumes that are released from their claims. -// This controller will Recycle those volumes whose reclaim policy is set to PersistentVolumeReclaimRecycle and make them -// available again for a new claim. -type PersistentVolumeRecycler struct { - volumeController *framework.Controller - stopChannel chan struct{} - client recyclerClient - kubeClient clientset.Interface - pluginMgr volume.VolumePluginMgr - cloud cloudprovider.Interface - maximumRetry int - syncPeriod time.Duration - // Local cache of failed recycle / delete operations. Map volume.Name -> status of the volume. - // Only PVs in Released state have an entry here. - releasedVolumes map[string]releasedVolumeStatus -} - -// releasedVolumeStatus holds state of failed delete/recycle operation on a -// volume. The controller re-tries the operation several times and it stores -// retry count + timestamp of the last attempt here. -type releasedVolumeStatus struct { - // How many recycle/delete operations failed. - retryCount int - // Timestamp of the last attempt. - lastAttempt time.Time -} - -// NewPersistentVolumeRecycler creates a new PersistentVolumeRecycler -func NewPersistentVolumeRecycler(kubeClient clientset.Interface, syncPeriod time.Duration, maximumRetry int, plugins []volume.VolumePlugin, cloud cloudprovider.Interface) (*PersistentVolumeRecycler, error) { - recyclerClient := NewRecyclerClient(kubeClient) - if kubeClient != nil && kubeClient.Core().GetRESTClient().GetRateLimiter() != nil { - metrics.RegisterMetricAndTrackRateLimiterUsage("pv_recycler_controller", kubeClient.Core().GetRESTClient().GetRateLimiter()) - } - recycler := &PersistentVolumeRecycler{ - client: recyclerClient, - kubeClient: kubeClient, - cloud: cloud, - maximumRetry: maximumRetry, - syncPeriod: syncPeriod, - releasedVolumes: make(map[string]releasedVolumeStatus), - } - - if err := recycler.pluginMgr.InitPlugins(plugins, recycler); err != nil { - return nil, fmt.Errorf("Could not initialize volume plugins for PVClaimBinder: %+v", err) - } - - _, volumeController := framework.NewInformer( - &cache.ListWatch{ - ListFunc: func(options api.ListOptions) (runtime.Object, error) { - return kubeClient.Core().PersistentVolumes().List(options) - }, - WatchFunc: func(options api.ListOptions) (watch.Interface, error) { - return kubeClient.Core().PersistentVolumes().Watch(options) - }, - }, - &api.PersistentVolume{}, - syncPeriod, - framework.ResourceEventHandlerFuncs{ - AddFunc: func(obj interface{}) { - pv, ok := obj.(*api.PersistentVolume) - if !ok { - glog.Errorf("Error casting object to PersistentVolume: %v", obj) - return - } - recycler.reclaimVolume(pv) - }, - UpdateFunc: func(oldObj, newObj interface{}) { - pv, ok := newObj.(*api.PersistentVolume) - if !ok { - glog.Errorf("Error casting object to PersistentVolume: %v", newObj) - return - } - recycler.reclaimVolume(pv) - }, - DeleteFunc: func(obj interface{}) { - pv, ok := obj.(*api.PersistentVolume) - if !ok { - glog.Errorf("Error casting object to PersistentVolume: %v", obj) - return - } - recycler.reclaimVolume(pv) - recycler.removeReleasedVolume(pv) - }, - }, - ) - - recycler.volumeController = volumeController - return recycler, nil -} - -// shouldRecycle checks a volume and returns nil, if the volume should be -// recycled right now. Otherwise it returns an error with reason why it should -// not be recycled. -func (recycler *PersistentVolumeRecycler) shouldRecycle(pv *api.PersistentVolume) error { - if pv.Spec.ClaimRef == nil { - return fmt.Errorf("Volume does not have a reference to claim") - } - if pv.Status.Phase != api.VolumeReleased { - return fmt.Errorf("The volume is not in 'Released' phase") - } - - // The volume is Released, should we retry recycling? - status, found := recycler.releasedVolumes[pv.Name] - if !found { - // We don't know anything about this volume. The controller has been - // restarted or the volume has been marked as Released by another - // controller. Recycle/delete this volume as if it was just Released. - glog.V(5).Infof("PersistentVolume[%s] not found in local cache, recycling", pv.Name) - return nil - } - - // Check the timestamp - expectedRetry := status.lastAttempt.Add(recycler.syncPeriod) - if time.Now().After(expectedRetry) { - glog.V(5).Infof("PersistentVolume[%s] retrying recycle after timeout", pv.Name) - return nil - } - // It's too early - glog.V(5).Infof("PersistentVolume[%s] skipping recycle, it's too early: now: %v, next retry: %v", pv.Name, time.Now(), expectedRetry) - return fmt.Errorf("Too early after previous failure") -} - -func (recycler *PersistentVolumeRecycler) reclaimVolume(pv *api.PersistentVolume) error { - glog.V(5).Infof("Recycler: checking PersistentVolume[%s]\n", pv.Name) - // Always load the latest version of the volume - newPV, err := recycler.client.GetPersistentVolume(pv.Name) - if err != nil { - return fmt.Errorf("Could not find PersistentVolume %s", pv.Name) - } - pv = newPV - - err = recycler.shouldRecycle(pv) - if err == nil { - glog.V(5).Infof("Reclaiming PersistentVolume[%s]\n", pv.Name) - - // both handleRecycle and handleDelete block until completion - // TODO: allow parallel recycling operations to increase throughput - switch pv.Spec.PersistentVolumeReclaimPolicy { - case api.PersistentVolumeReclaimRecycle: - err = recycler.handleRecycle(pv) - case api.PersistentVolumeReclaimDelete: - err = recycler.handleDelete(pv) - case api.PersistentVolumeReclaimRetain: - glog.V(5).Infof("Volume %s is set to retain after release. Skipping.\n", pv.Name) - default: - err = fmt.Errorf("No PersistentVolumeReclaimPolicy defined for spec: %+v", pv) - } - if err != nil { - errMsg := fmt.Sprintf("Could not recycle volume spec: %+v", err) - glog.Errorf(errMsg) - return fmt.Errorf(errMsg) - } - return nil - } - glog.V(3).Infof("PersistentVolume[%s] phase %s - skipping: %v", pv.Name, pv.Status.Phase, err) - return nil -} - -// handleReleaseFailure evaluates a failed Recycle/Delete operation, updates -// internal controller state with new nr. of attempts and timestamp of the last -// attempt. Based on the number of failures it returns the next state of the -// volume (Released / Failed). -func (recycler *PersistentVolumeRecycler) handleReleaseFailure(pv *api.PersistentVolume) api.PersistentVolumePhase { - status, found := recycler.releasedVolumes[pv.Name] - if !found { - // First failure, set retryCount to 0 (will be inceremented few lines below) - status = releasedVolumeStatus{} - } - status.retryCount += 1 - - if status.retryCount > recycler.maximumRetry { - // This was the last attempt. Remove any internal state and mark the - // volume as Failed. - glog.V(3).Infof("PersistentVolume[%s] failed %d times - marking Failed", pv.Name, status.retryCount) - recycler.removeReleasedVolume(pv) - return api.VolumeFailed - } - - status.lastAttempt = time.Now() - recycler.releasedVolumes[pv.Name] = status - return api.VolumeReleased -} - -func (recycler *PersistentVolumeRecycler) removeReleasedVolume(pv *api.PersistentVolume) { - delete(recycler.releasedVolumes, pv.Name) -} - -func (recycler *PersistentVolumeRecycler) handleRecycle(pv *api.PersistentVolume) error { - glog.V(5).Infof("Recycling PersistentVolume[%s]\n", pv.Name) - - currentPhase := pv.Status.Phase - nextPhase := currentPhase - - spec := volume.NewSpecFromPersistentVolume(pv, false) - plugin, err := recycler.pluginMgr.FindRecyclablePluginBySpec(spec) - if err != nil { - nextPhase = api.VolumeFailed - pv.Status.Message = fmt.Sprintf("%v", err) - } - - // an error above means a suitable plugin for this volume was not found. - // we don't need to attempt recycling when plugin is nil, but we do need to persist the next/failed phase - // of the volume so that subsequent syncs won't attempt recycling through this handler func. - if plugin != nil { - volRecycler, err := plugin.NewRecycler(spec) - if err != nil { - return fmt.Errorf("Could not obtain Recycler for spec: %#v error: %v", spec, err) - } - // blocks until completion - if err := volRecycler.Recycle(); err != nil { - glog.Errorf("PersistentVolume[%s] failed recycling: %+v", pv.Name, err) - pv.Status.Message = fmt.Sprintf("Recycling error: %s", err) - nextPhase = recycler.handleReleaseFailure(pv) - } else { - glog.V(5).Infof("PersistentVolume[%s] successfully recycled\n", pv.Name) - // The volume has been recycled. Remove any internal state to make - // any subsequent bind+recycle cycle working. - recycler.removeReleasedVolume(pv) - nextPhase = api.VolumePending - } - } - - if currentPhase != nextPhase { - glog.V(5).Infof("PersistentVolume[%s] changing phase from %s to %s\n", pv.Name, currentPhase, nextPhase) - pv.Status.Phase = nextPhase - _, err := recycler.client.UpdatePersistentVolumeStatus(pv) - if err != nil { - // Rollback to previous phase - pv.Status.Phase = currentPhase - } - } - - return nil -} - -func (recycler *PersistentVolumeRecycler) handleDelete(pv *api.PersistentVolume) error { - glog.V(5).Infof("Deleting PersistentVolume[%s]\n", pv.Name) - - currentPhase := pv.Status.Phase - nextPhase := currentPhase - - spec := volume.NewSpecFromPersistentVolume(pv, false) - plugin, err := recycler.pluginMgr.FindDeletablePluginBySpec(spec) - if err != nil { - nextPhase = api.VolumeFailed - pv.Status.Message = fmt.Sprintf("%v", err) - } - - // an error above means a suitable plugin for this volume was not found. - // we don't need to attempt deleting when plugin is nil, but we do need to persist the next/failed phase - // of the volume so that subsequent syncs won't attempt deletion through this handler func. - if plugin != nil { - deleter, err := plugin.NewDeleter(spec) - if err != nil { - return fmt.Errorf("Could not obtain Deleter for spec: %#v error: %v", spec, err) - } - // blocks until completion - err = deleter.Delete() - if err != nil { - glog.Errorf("PersistentVolume[%s] failed deletion: %+v", pv.Name, err) - pv.Status.Message = fmt.Sprintf("Deletion error: %s", err) - nextPhase = recycler.handleReleaseFailure(pv) - } else { - glog.V(5).Infof("PersistentVolume[%s] successfully deleted through plugin\n", pv.Name) - recycler.removeReleasedVolume(pv) - // after successful deletion through the plugin, we can also remove the PV from the cluster - if err := recycler.client.DeletePersistentVolume(pv); err != nil { - return fmt.Errorf("error deleting persistent volume: %+v", err) - } - } - } - - if currentPhase != nextPhase { - glog.V(5).Infof("PersistentVolume[%s] changing phase from %s to %s\n", pv.Name, currentPhase, nextPhase) - pv.Status.Phase = nextPhase - _, err := recycler.client.UpdatePersistentVolumeStatus(pv) - if err != nil { - // Rollback to previous phase - pv.Status.Phase = currentPhase - } - } - - return nil -} - -// Run starts this recycler's control loops -func (recycler *PersistentVolumeRecycler) Run() { - glog.V(5).Infof("Starting PersistentVolumeRecycler\n") - if recycler.stopChannel == nil { - recycler.stopChannel = make(chan struct{}) - go recycler.volumeController.Run(recycler.stopChannel) - } -} - -// Stop gracefully shuts down this binder -func (recycler *PersistentVolumeRecycler) Stop() { - glog.V(5).Infof("Stopping PersistentVolumeRecycler\n") - if recycler.stopChannel != nil { - close(recycler.stopChannel) - recycler.stopChannel = nil - } -} - -// recyclerClient abstracts access to PVs -type recyclerClient interface { - GetPersistentVolume(name string) (*api.PersistentVolume, error) - UpdatePersistentVolume(volume *api.PersistentVolume) (*api.PersistentVolume, error) - DeletePersistentVolume(volume *api.PersistentVolume) error - UpdatePersistentVolumeStatus(volume *api.PersistentVolume) (*api.PersistentVolume, error) -} - -func NewRecyclerClient(c clientset.Interface) recyclerClient { - return &realRecyclerClient{c} -} - -type realRecyclerClient struct { - client clientset.Interface -} - -func (c *realRecyclerClient) GetPersistentVolume(name string) (*api.PersistentVolume, error) { - return c.client.Core().PersistentVolumes().Get(name) -} - -func (c *realRecyclerClient) UpdatePersistentVolume(volume *api.PersistentVolume) (*api.PersistentVolume, error) { - return c.client.Core().PersistentVolumes().Update(volume) -} - -func (c *realRecyclerClient) DeletePersistentVolume(volume *api.PersistentVolume) error { - return c.client.Core().PersistentVolumes().Delete(volume.Name, nil) -} - -func (c *realRecyclerClient) UpdatePersistentVolumeStatus(volume *api.PersistentVolume) (*api.PersistentVolume, error) { - return c.client.Core().PersistentVolumes().UpdateStatus(volume) -} - -// PersistentVolumeRecycler is host to the volume plugins, but does not actually mount any volumes. -// Because no mounting is performed, most of the VolumeHost methods are not implemented. -func (f *PersistentVolumeRecycler) GetPluginDir(podUID string) string { - return "" -} - -func (f *PersistentVolumeRecycler) GetPodVolumeDir(podUID types.UID, pluginName, volumeName string) string { - return "" -} - -func (f *PersistentVolumeRecycler) GetPodPluginDir(podUID types.UID, pluginName string) string { - return "" -} - -func (f *PersistentVolumeRecycler) GetKubeClient() clientset.Interface { - return f.kubeClient -} - -func (f *PersistentVolumeRecycler) NewWrapperMounter(volName string, spec volume.Spec, pod *api.Pod, opts volume.VolumeOptions) (volume.Mounter, error) { - return nil, fmt.Errorf("NewWrapperMounter not supported by PVClaimBinder's VolumeHost implementation") -} - -func (f *PersistentVolumeRecycler) NewWrapperUnmounter(volName string, spec volume.Spec, podUID types.UID) (volume.Unmounter, error) { - return nil, fmt.Errorf("NewWrapperUnmounter not supported by PVClaimBinder's VolumeHost implementation") -} - -func (f *PersistentVolumeRecycler) GetCloudProvider() cloudprovider.Interface { - return f.cloud -} - -func (f *PersistentVolumeRecycler) GetMounter() mount.Interface { - return nil -} - -func (f *PersistentVolumeRecycler) GetWriter() ioutil.Writer { - return nil -} - -func (f *PersistentVolumeRecycler) GetHostName() string { - return "" -} diff --git a/vendor/k8s.io/kubernetes/pkg/controller/persistentvolume/volume_host.go b/vendor/k8s.io/kubernetes/pkg/controller/persistentvolume/volume_host.go new file mode 100644 index 0000000000..f38ad0da4e --- /dev/null +++ b/vendor/k8s.io/kubernetes/pkg/controller/persistentvolume/volume_host.go @@ -0,0 +1,73 @@ +/* +Copyright 2016 The Kubernetes Authors All rights reserved. + +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 persistentvolume + +import ( + "fmt" + + "k8s.io/kubernetes/pkg/api" + clientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" + "k8s.io/kubernetes/pkg/cloudprovider" + "k8s.io/kubernetes/pkg/types" + "k8s.io/kubernetes/pkg/util/io" + "k8s.io/kubernetes/pkg/util/mount" + vol "k8s.io/kubernetes/pkg/volume" +) + +// VolumeHost interface implementation for PersistentVolumeController. + +var _ vol.VolumeHost = &PersistentVolumeController{} + +func (ctrl *PersistentVolumeController) GetPluginDir(pluginName string) string { + return "" +} + +func (ctrl *PersistentVolumeController) GetPodVolumeDir(podUID types.UID, pluginName string, volumeName string) string { + return "" +} + +func (ctrl *PersistentVolumeController) GetPodPluginDir(podUID types.UID, pluginName string) string { + return "" +} + +func (ctrl *PersistentVolumeController) GetKubeClient() clientset.Interface { + return ctrl.kubeClient +} + +func (ctrl *PersistentVolumeController) NewWrapperMounter(volName string, spec vol.Spec, pod *api.Pod, opts vol.VolumeOptions) (vol.Mounter, error) { + return nil, fmt.Errorf("PersistentVolumeController.NewWrapperMounter is not implemented") +} + +func (ctrl *PersistentVolumeController) NewWrapperUnmounter(volName string, spec vol.Spec, podUID types.UID) (vol.Unmounter, error) { + return nil, fmt.Errorf("PersistentVolumeController.NewWrapperMounter is not implemented") +} + +func (ctrl *PersistentVolumeController) GetCloudProvider() cloudprovider.Interface { + return ctrl.cloud +} + +func (ctrl *PersistentVolumeController) GetMounter() mount.Interface { + return nil +} + +func (ctrl *PersistentVolumeController) GetWriter() io.Writer { + return nil +} + +func (ctrl *PersistentVolumeController) GetHostName() string { + return "" +} diff --git a/vendor/k8s.io/kubernetes/pkg/controller/petset/fakes.go b/vendor/k8s.io/kubernetes/pkg/controller/petset/fakes.go index 04e3e99050..6c1c8e713f 100644 --- a/vendor/k8s.io/kubernetes/pkg/controller/petset/fakes.go +++ b/vendor/k8s.io/kubernetes/pkg/controller/petset/fakes.go @@ -44,10 +44,7 @@ func newPVC(name string) api.PersistentVolumeClaim { Spec: api.PersistentVolumeClaimSpec{ Resources: api.ResourceRequirements{ Requests: api.ResourceList{ - api.ResourceStorage: resource.Quantity{ - Amount: dec(1, 0), - Format: resource.BinarySI, - }, + api.ResourceStorage: *resource.NewQuantity(1, resource.BinarySI), }, }, }, diff --git a/vendor/k8s.io/kubernetes/pkg/controller/podautoscaler/horizontal.go b/vendor/k8s.io/kubernetes/pkg/controller/podautoscaler/horizontal.go index a8e092cafe..2ca083ff20 100644 --- a/vendor/k8s.io/kubernetes/pkg/controller/podautoscaler/horizontal.go +++ b/vendor/k8s.io/kubernetes/pkg/controller/podautoscaler/horizontal.go @@ -237,7 +237,7 @@ func (a *HorizontalController) computeReplicasForCustomMetrics(hpa *autoscaling. } statusList.Items = append(statusList.Items, extensions.CustomMetricCurrentStatus{ Name: customMetricTarget.Name, - CurrentValue: *quantity, + CurrentValue: quantity, }) } byteStatusList, err := json.Marshal(statusList) diff --git a/vendor/k8s.io/kubernetes/pkg/controller/podautoscaler/metrics/metrics_client.go b/vendor/k8s.io/kubernetes/pkg/controller/podautoscaler/metrics/metrics_client.go index 1d70f5f205..0e6f208ee6 100644 --- a/vendor/k8s.io/kubernetes/pkg/controller/podautoscaler/metrics/metrics_client.go +++ b/vendor/k8s.io/kubernetes/pkg/controller/podautoscaler/metrics/metrics_client.go @@ -24,10 +24,12 @@ import ( "github.com/golang/glog" "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/v1" clientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" "k8s.io/kubernetes/pkg/labels" heapster "k8s.io/heapster/metrics/api/v1/types" + metrics_api "k8s.io/heapster/metrics/apis/metrics/v1alpha1" ) const ( @@ -83,8 +85,6 @@ var averageFunction = func(metrics heapster.MetricResultList) (intAndFloat, int, return result, count, timestamp } -var heapsterCpuUsageMetricDefinition = metricDefinition{"cpu-usage", averageFunction} - func getHeapsterCustomMetricDefinition(metricName string) metricDefinition { return metricDefinition{"custom/" + metricName, averageFunction} } @@ -118,7 +118,7 @@ func (h *HeapsterMetricsClient) GetCpuConsumptionAndRequestInMillis(namespace st if err != nil { return 0, 0, time.Time{}, fmt.Errorf("failed to get pod list: %v", err) } - podNames := []string{} + podNames := map[string]struct{}{} requestSum := int64(0) missing := false for _, pod := range podList.Items { @@ -127,10 +127,9 @@ func (h *HeapsterMetricsClient) GetCpuConsumptionAndRequestInMillis(namespace st continue } - podNames = append(podNames, pod.Name) + podNames[pod.Name] = struct{}{} for _, container := range pod.Spec.Containers { - containerRequest := container.Resources.Requests[api.ResourceCPU] - if containerRequest.Amount != nil { + if containerRequest, ok := container.Resources.Requests[api.ResourceCPU]; ok { requestSum += containerRequest.MilliValue() } else { missing = true @@ -146,11 +145,52 @@ func (h *HeapsterMetricsClient) GetCpuConsumptionAndRequestInMillis(namespace st glog.V(4).Infof("%s %s - sum of CPU requested: %d", namespace, selector, requestSum) requestAvg := requestSum / int64(len(podList.Items)) // Consumption is already averaged and in millis. - consumption, timestamp, err := h.getForPods(heapsterCpuUsageMetricDefinition, namespace, podNames) + consumption, timestamp, err := h.getCpuUtilizationForPods(namespace, selector, podNames) if err != nil { return 0, 0, time.Time{}, err } - return consumption.intValue, requestAvg, timestamp, nil + return consumption, requestAvg, timestamp, nil +} + +func (h *HeapsterMetricsClient) getCpuUtilizationForPods(namespace string, selector labels.Selector, podNames map[string]struct{}) (int64, time.Time, error) { + metricPath := fmt.Sprintf("/apis/metrics/v1alpha1/namespaces/%s/pods", namespace) + params := map[string]string{"labelSelector": selector.String()} + + resultRaw, err := h.client.Core().Services(h.heapsterNamespace). + ProxyGet(h.heapsterScheme, h.heapsterService, h.heapsterPort, metricPath, params). + DoRaw() + if err != nil { + return 0, time.Time{}, fmt.Errorf("failed to get pods metrics: %v", err) + } + + glog.V(4).Infof("Heapster metrics result: %s", string(resultRaw)) + + metrics := make([]metrics_api.PodMetrics, 0) + err = json.Unmarshal(resultRaw, &metrics) + if err != nil { + return 0, time.Time{}, fmt.Errorf("failed to unmarshall heapster response: %v", err) + } + + if len(metrics) != len(podNames) { + return 0, time.Time{}, fmt.Errorf("metrics obtained for %d/%d of pods", len(metrics), len(podNames)) + } + + sum := int64(0) + for _, m := range metrics { + if _, found := podNames[m.Name]; found { + for _, c := range m.Containers { + cpu, found := c.Usage[v1.ResourceCPU] + if !found { + return 0, time.Time{}, fmt.Errorf("no cpu for container %v in pod %v/%v", c.Name, namespace, m.Name) + } + sum += cpu.MilliValue() + } + } else { + return 0, time.Time{}, fmt.Errorf("not expected metrics for pod %v/%v", namespace, m.Name) + } + } + + return sum / int64(len(metrics)), metrics[0].Timestamp.Time, nil } // GetCustomMetric returns the average value of the given custom metric from the @@ -175,14 +215,14 @@ func (h *HeapsterMetricsClient) GetCustomMetric(customMetricName string, namespa return nil, time.Time{}, fmt.Errorf("no running pods") } - value, timestamp, err := h.getForPods(metricSpec, namespace, podNames) + value, timestamp, err := h.getCustomMetricForPods(metricSpec, namespace, podNames) if err != nil { return nil, time.Time{}, err } return &value.floatValue, timestamp, nil } -func (h *HeapsterMetricsClient) getForPods(metricSpec metricDefinition, namespace string, podNames []string) (*intAndFloat, time.Time, error) { +func (h *HeapsterMetricsClient) getCustomMetricForPods(metricSpec metricDefinition, namespace string, podNames []string) (*intAndFloat, time.Time, error) { now := time.Now() diff --git a/vendor/k8s.io/kubernetes/pkg/controller/replication/replication_controller.go b/vendor/k8s.io/kubernetes/pkg/controller/replication/replication_controller.go index aaf4031068..6fda7ce896 100644 --- a/vendor/k8s.io/kubernetes/pkg/controller/replication/replication_controller.go +++ b/vendor/k8s.io/kubernetes/pkg/controller/replication/replication_controller.go @@ -47,7 +47,11 @@ const ( // We'll attempt to recompute the required replicas of all replication controllers // that have fulfilled their expectations at least this often. This recomputation // happens based on contents in local pod storage. - FullControllerResyncPeriod = 30 * time.Second + // Full Resync shouldn't be needed at all in a healthy system. This is a protection + // against disappearing objects and watch notification, that we believe should not + // happen at all. + // TODO: We should get rid of it completely in the fullness of time. + FullControllerResyncPeriod = 10 * time.Minute // Realistic value of the burstReplica field for the replication manager based off // performance requirements for kubernetes 1.0. @@ -477,6 +481,7 @@ func (rm *ReplicationManager) manageReplicas(filteredPods []*api.Pod, rc *api.Re // Decrement the expected number of creates because the informer won't observe this pod glog.V(2).Infof("Failed creation, decrementing expectations for controller %q/%q", rc.Namespace, rc.Name) rm.expectations.CreationObserved(rcKey) + rm.enqueueController(rc) utilruntime.HandleError(err) } }() @@ -518,6 +523,7 @@ func (rm *ReplicationManager) manageReplicas(filteredPods []*api.Pod, rc *api.Re podKey := controller.PodKey(filteredPods[ix]) glog.V(2).Infof("Failed to delete %v due to %v, decrementing expectations for controller %q/%q", podKey, err, rc.Namespace, rc.Name) rm.expectations.DeletionObserved(rcKey, podKey) + rm.enqueueController(rc) utilruntime.HandleError(err) } }(i) diff --git a/vendor/k8s.io/kubernetes/pkg/controller/resourcequota/resource_quota_controller.go b/vendor/k8s.io/kubernetes/pkg/controller/resourcequota/resource_quota_controller.go index a1e449d3c6..a64781c012 100644 --- a/vendor/k8s.io/kubernetes/pkg/controller/resourcequota/resource_quota_controller.go +++ b/vendor/k8s.io/kubernetes/pkg/controller/resourcequota/resource_quota_controller.go @@ -62,7 +62,7 @@ type ResourceQuotaController struct { // Watches changes to all resource quota rqController *framework.Controller // ResourceQuota objects that need to be synchronized - queue *workqueue.Type + queue workqueue.RateLimitingInterface // To allow injection of syncUsage for testing. syncHandler func(key string) error // function that controls full recalculation of quota usage @@ -77,7 +77,7 @@ func NewResourceQuotaController(options *ResourceQuotaControllerOptions) *Resour // build the resource quota controller rq := &ResourceQuotaController{ kubeClient: options.KubeClient, - queue: workqueue.New(), + queue: workqueue.NewRateLimitingQueue(workqueue.DefaultControllerRateLimiter()), resyncPeriod: options.ResyncPeriod, registry: options.Registry, replenishmentControllers: []framework.ControllerInterface{}, @@ -170,10 +170,12 @@ func (rq *ResourceQuotaController) worker() { } defer rq.queue.Done(key) err := rq.syncHandler(key.(string)) - if err != nil { - utilruntime.HandleError(err) - rq.queue.Add(key) + if err == nil { + rq.queue.Forget(key) + return false } + utilruntime.HandleError(err) + rq.queue.AddRateLimited(key) return false } for { diff --git a/vendor/k8s.io/kubernetes/pkg/credentialprovider/aws/aws_credentials.go b/vendor/k8s.io/kubernetes/pkg/credentialprovider/aws/aws_credentials.go index aeb7316b32..3b9b5c9820 100644 --- a/vendor/k8s.io/kubernetes/pkg/credentialprovider/aws/aws_credentials.go +++ b/vendor/k8s.io/kubernetes/pkg/credentialprovider/aws/aws_credentials.go @@ -14,10 +14,11 @@ See the License for the specific language governing permissions and limitations under the License. */ -package aws_credentials +package credentials import ( "encoding/base64" + "fmt" "strings" "time" @@ -26,23 +27,40 @@ import ( "github.com/aws/aws-sdk-go/aws/session" "github.com/aws/aws-sdk-go/service/ecr" "github.com/golang/glog" - "k8s.io/kubernetes/pkg/cloudprovider" "k8s.io/kubernetes/pkg/credentialprovider" ) -var registryUrls = []string{"*.dkr.ecr.*.amazonaws.com"} +// AWSRegions is the complete list of regions known to the AWS cloudprovider +// and credentialprovider. +var AWSRegions = [...]string{ + "us-east-1", + "us-west-1", + "us-west-2", + "eu-west-1", + "eu-central-1", + "ap-southeast-1", + "ap-southeast-2", + "ap-northeast-1", + "ap-northeast-2", + "cn-north-1", + "us-gov-west-1", + "sa-east-1", +} + +const registryURLTemplate = "*.dkr.ecr.%s.amazonaws.com" // awsHandlerLogger is a handler that logs all AWS SDK requests // Copied from cloudprovider/aws/log_handler.go func awsHandlerLogger(req *request.Request) { service := req.ClientInfo.ServiceName + region := req.Config.Region name := "?" if req.Operation != nil { name = req.Operation.Name } - glog.V(4).Infof("AWS request: %s %s", service, name) + glog.V(3).Infof("AWS request: %s:%s in %s", service, name, *region) } // An interface for testing purposes. @@ -59,22 +77,86 @@ func (p *ecrTokenGetter) GetAuthorizationToken(input *ecr.GetAuthorizationTokenI return p.svc.GetAuthorizationToken(input) } +// lazyEcrProvider is a DockerConfigProvider that creates on demand an +// ecrProvider for a given region and then proxies requests to it. +type lazyEcrProvider struct { + region string + regionURL string + actualProvider *credentialprovider.CachingDockerConfigProvider +} + +var _ credentialprovider.DockerConfigProvider = &lazyEcrProvider{} + // ecrProvider is a DockerConfigProvider that gets and refreshes 12-hour tokens // from AWS to access ECR. type ecrProvider struct { - getter tokenGetter + region string + regionURL string + getter tokenGetter } +var _ credentialprovider.DockerConfigProvider = &ecrProvider{} + +// Init creates a lazy provider for each AWS region, in order to support +// cross-region ECR access. They have to be lazy because it's unlikely, but not +// impossible, that we'll use more than one. // Not using the package init() function: this module should be initialized only // if using the AWS cloud provider. This way, we avoid timeouts waiting for a // non-existent provider. func Init() { - credentialprovider.RegisterCredentialProvider("aws-ecr-key", - &credentialprovider.CachingDockerConfigProvider{ - Provider: &ecrProvider{}, - // Refresh credentials a little earlier before they expire + for _, region := range AWSRegions { + credentialprovider.RegisterCredentialProvider("aws-ecr-"+region, + &lazyEcrProvider{ + region: region, + regionURL: fmt.Sprintf(registryURLTemplate, region), + }) + } + +} + +// Enabled implements DockerConfigProvider.Enabled for the lazy provider. +// Since we perform no checks/work of our own and actualProvider is only created +// later at image pulling time (if ever), always return true. +func (p *lazyEcrProvider) Enabled() bool { + return true +} + +// LazyProvide implements DockerConfigProvider.LazyProvide. It will be called +// by the client when attempting to pull an image and it will create the actual +// provider only when we actually need it the first time. +func (p *lazyEcrProvider) LazyProvide() *credentialprovider.DockerConfigEntry { + if p.actualProvider == nil { + glog.V(2).Infof("Creating ecrProvider for %s", p.region) + p.actualProvider = &credentialprovider.CachingDockerConfigProvider{ + Provider: newEcrProvider(p.region, nil), + // Refresh credentials a little earlier than expiration time Lifetime: 11*time.Hour + 55*time.Minute, - }) + } + if !p.actualProvider.Enabled() { + return nil + } + } + entry := p.actualProvider.Provide()[p.regionURL] + return &entry +} + +// Provide implements DockerConfigProvider.Provide, creating dummy credentials. +// Client code will call Provider.LazyProvide() at image pulling time. +func (p *lazyEcrProvider) Provide() credentialprovider.DockerConfig { + entry := credentialprovider.DockerConfigEntry{ + Provider: p, + } + cfg := credentialprovider.DockerConfig{} + cfg[p.regionURL] = entry + return cfg +} + +func newEcrProvider(region string, getter tokenGetter) *ecrProvider { + return &ecrProvider{ + region: region, + regionURL: fmt.Sprintf(registryURLTemplate, region), + getter: getter, + } } // Enabled implements DockerConfigProvider.Enabled for the AWS token-based implementation. @@ -82,33 +164,14 @@ func Init() { // TODO: figure how to enable it manually for deployments that are not on AWS but still // use ECR somehow? func (p *ecrProvider) Enabled() bool { - provider, err := cloudprovider.GetCloudProvider("aws", nil) - if err != nil { - glog.Errorf("while initializing AWS cloud provider %v", err) - return false - } - if provider == nil { - return false - } - - zones, ok := provider.Zones() - if !ok { - glog.Errorf("couldn't get Zones() interface") - return false - } - zone, err := zones.GetZone() - if err != nil { - glog.Errorf("while getting zone %v", err) - return false - } - if zone.Region == "" { - glog.Errorf("Region information is empty") + if p.region == "" { + glog.Errorf("Called ecrProvider.Enabled() with no region set") return false } getter := &ecrTokenGetter{svc: ecr.New(session.New(&aws.Config{ Credentials: nil, - Region: &zone.Region, + Region: &p.region, }))} getter.svc.Handlers.Sign.PushFrontNamed(request.NamedHandler{ Name: "k8s/logger", @@ -158,10 +221,10 @@ func (p *ecrProvider) Provide() credentialprovider.DockerConfig { Email: "not@val.id", } - // Add our entry for each of the supported container registry URLs - for _, k := range registryUrls { - cfg[k] = entry - } + glog.V(3).Infof("Adding credentials for user %s in %s", user, p.region) + // Add our config entry for this region's registry URLs + cfg[p.regionURL] = entry + } } return cfg diff --git a/vendor/k8s.io/kubernetes/pkg/genericapiserver/genericapiserver.go b/vendor/k8s.io/kubernetes/pkg/genericapiserver/genericapiserver.go index 4412c00987..2930ac5c20 100644 --- a/vendor/k8s.io/kubernetes/pkg/genericapiserver/genericapiserver.go +++ b/vendor/k8s.io/kubernetes/pkg/genericapiserver/genericapiserver.go @@ -40,6 +40,7 @@ import ( "k8s.io/kubernetes/pkg/auth/authorizer" "k8s.io/kubernetes/pkg/auth/handlers" "k8s.io/kubernetes/pkg/cloudprovider" + "k8s.io/kubernetes/pkg/genericapiserver/options" "k8s.io/kubernetes/pkg/registry/generic" "k8s.io/kubernetes/pkg/registry/generic/registry" ipallocator "k8s.io/kubernetes/pkg/registry/service/ipallocator" @@ -57,11 +58,7 @@ import ( "github.com/golang/glog" ) -const ( - DefaultEtcdPathPrefix = "/registry" - DefaultDeserializationCacheSize = 50000 - globalTimeout = time.Minute -) +const globalTimeout = time.Minute // Info about an API group. type APIGroupInfo struct { @@ -95,6 +92,7 @@ type APIGroupInfo struct { // Config is a structure used to configure a GenericAPIServer. type Config struct { + // The storage factory for other objects StorageFactory StorageFactory // allow downstream consumers to disable the core controller loops EnableLogsSupport bool @@ -538,7 +536,7 @@ func (s *GenericAPIServer) installGroupsDiscoveryHandler() { } // TODO: Longer term we should read this from some config store, rather than a flag. -func verifyClusterIPFlags(options *ServerRunOptions) { +func verifyClusterIPFlags(options *options.ServerRunOptions) { if options.ServiceClusterIPRange.IP == nil { glog.Fatal("No --service-cluster-ip-range specified") } @@ -548,7 +546,7 @@ func verifyClusterIPFlags(options *ServerRunOptions) { } } -func NewConfig(options *ServerRunOptions) *Config { +func NewConfig(options *options.ServerRunOptions) *Config { return &Config{ APIGroupPrefix: options.APIGroupPrefix, APIPrefix: options.APIPrefix, @@ -571,25 +569,25 @@ func NewConfig(options *ServerRunOptions) *Config { } } -func verifyServiceNodePort(options *ServerRunOptions) { +func verifyServiceNodePort(options *options.ServerRunOptions) { if options.KubernetesServiceNodePort > 0 && !options.ServiceNodePortRange.Contains(options.KubernetesServiceNodePort) { glog.Fatalf("Kubernetes service port range %v doesn't contain %v", options.ServiceNodePortRange, (options.KubernetesServiceNodePort)) } } -func verifyEtcdServersList(options *ServerRunOptions) { +func verifyEtcdServersList(options *options.ServerRunOptions) { if len(options.StorageConfig.ServerList) == 0 { glog.Fatalf("--etcd-servers must be specified") } } -func ValidateRunOptions(options *ServerRunOptions) { +func ValidateRunOptions(options *options.ServerRunOptions) { verifyClusterIPFlags(options) verifyServiceNodePort(options) verifyEtcdServersList(options) } -func DefaultAndValidateRunOptions(options *ServerRunOptions) { +func DefaultAndValidateRunOptions(options *options.ServerRunOptions) { ValidateRunOptions(options) // If advertise-address is not specified, use bind-address. If bind-address @@ -635,7 +633,7 @@ func DefaultAndValidateRunOptions(options *ServerRunOptions) { } } -func (s *GenericAPIServer) Run(options *ServerRunOptions) { +func (s *GenericAPIServer) Run(options *options.ServerRunOptions) { if s.enableSwaggerSupport { s.InstallSwaggerAPI() } diff --git a/vendor/k8s.io/kubernetes/pkg/genericapiserver/options/doc.go b/vendor/k8s.io/kubernetes/pkg/genericapiserver/options/doc.go new file mode 100644 index 0000000000..c90eb8b8d1 --- /dev/null +++ b/vendor/k8s.io/kubernetes/pkg/genericapiserver/options/doc.go @@ -0,0 +1,21 @@ +/* +Copyright 2016 The Kubernetes Authors All rights reserved. + +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 options is the public flags and options used by a generic api +// server. It takes a minimal set of dependencies and does not reference +// implementations, in order to ensure it may be reused by multiple components +// (such as CLI commands that wish to generate or validate config). +package options diff --git a/vendor/k8s.io/kubernetes/pkg/genericapiserver/server_run_options.go b/vendor/k8s.io/kubernetes/pkg/genericapiserver/options/server_run_options.go similarity index 67% rename from vendor/k8s.io/kubernetes/pkg/genericapiserver/server_run_options.go rename to vendor/k8s.io/kubernetes/pkg/genericapiserver/options/server_run_options.go index 48ef92a74c..64226143c1 100644 --- a/vendor/k8s.io/kubernetes/pkg/genericapiserver/server_run_options.go +++ b/vendor/k8s.io/kubernetes/pkg/genericapiserver/options/server_run_options.go @@ -14,16 +14,20 @@ See the License for the specific language governing permissions and limitations under the License. */ -package genericapiserver +package options import ( "net" "strconv" "strings" + "time" + "k8s.io/kubernetes/pkg/admission" + "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/unversioned" apiutil "k8s.io/kubernetes/pkg/api/util" "k8s.io/kubernetes/pkg/apimachinery/registered" + "k8s.io/kubernetes/pkg/apiserver" clientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" "k8s.io/kubernetes/pkg/client/restclient" "k8s.io/kubernetes/pkg/storage/storagebackend" @@ -35,36 +39,54 @@ import ( ) const ( + DefaultEtcdPathPrefix = "/registry" + DefaultDeserializationCacheSize = 50000 + // TODO: This can be tightened up. It still matches objects named watch or proxy. defaultLongRunningRequestRE = "(/|^)((watch|proxy)(/|$)|(logs?|portforward|exec|attach)/?$)" ) // ServerRunOptions contains the options while running a generic api server. type ServerRunOptions struct { - APIGroupPrefix string - APIPrefix string - AdvertiseAddress net.IP - BindAddress net.IP - CertDirectory string - ClientCAFile string - CloudConfigFile string - CloudProvider string - CorsAllowedOriginList []string + APIGroupPrefix string + APIPrefix string + AdmissionControl string + AdmissionControlConfigFile string + AdvertiseAddress net.IP + AuthorizationConfig apiserver.AuthorizationConfig + AuthorizationMode string + BasicAuthFile string + BindAddress net.IP + CertDirectory string + ClientCAFile string + CloudConfigFile string + CloudProvider string + CorsAllowedOriginList []string + DefaultStorageMediaType string + DeleteCollectionWorkers int // Used to specify the storage version that should be used for the legacy v1 api group. DeprecatedStorageVersion string EnableLogsSupport bool EnableProfiling bool EnableSwaggerUI bool EnableWatchCache bool + EtcdServersOverrides []string StorageConfig storagebackend.Config ExternalHost string InsecureBindAddress net.IP InsecurePort int + KeystoneURL string KubernetesServiceNodePort int LongRunningRequestRE string MasterCount int + MasterServiceNamespace string MaxRequestsInFlight int MinRequestTimeout int + OIDCCAFile string + OIDCClientID string + OIDCIssuerURL string + OIDCUsernameClaim string + OIDCGroupsClaim string RuntimeConfig config.ConfigurationMap SecurePort int ServiceClusterIPRange net.IPNet // TODO: make this a list @@ -76,31 +98,42 @@ type ServerRunOptions struct { DefaultStorageVersions string TLSCertFile string TLSPrivateKeyFile string + TokenAuthFile string + WatchCacheSizes []string } func NewServerRunOptions() *ServerRunOptions { return &ServerRunOptions{ - APIGroupPrefix: "/apis", - APIPrefix: "/api", - BindAddress: net.ParseIP("0.0.0.0"), - CertDirectory: "/var/run/kubernetes", - DefaultStorageVersions: registered.AllPreferredGroupVersions(), + APIGroupPrefix: "/apis", + APIPrefix: "/api", + AdmissionControl: "AlwaysAdmit", + AuthorizationMode: "AlwaysAllow", + AuthorizationConfig: apiserver.AuthorizationConfig{ + WebhookCacheAuthorizedTTL: 5 * time.Minute, + WebhookCacheUnauthorizedTTL: 30 * time.Second, + }, + BindAddress: net.ParseIP("0.0.0.0"), + CertDirectory: "/var/run/kubernetes", + DefaultStorageMediaType: "application/json", + DefaultStorageVersions: registered.AllPreferredGroupVersions(), StorageConfig: storagebackend.Config{ Prefix: DefaultEtcdPathPrefix, DeserializationCacheSize: DefaultDeserializationCacheSize, }, - EnableLogsSupport: true, - EnableProfiling: true, - EnableWatchCache: true, - InsecureBindAddress: net.ParseIP("127.0.0.1"), - InsecurePort: 8080, - LongRunningRequestRE: defaultLongRunningRequestRE, - MasterCount: 1, - MaxRequestsInFlight: 400, - MinRequestTimeout: 1800, - RuntimeConfig: make(config.ConfigurationMap), - SecurePort: 6443, - StorageVersions: registered.AllPreferredGroupVersions(), + DeleteCollectionWorkers: 1, + EnableLogsSupport: true, + EnableProfiling: true, + EnableWatchCache: true, + InsecureBindAddress: net.ParseIP("127.0.0.1"), + InsecurePort: 8080, + LongRunningRequestRE: defaultLongRunningRequestRE, + MasterCount: 1, + MasterServiceNamespace: api.NamespaceDefault, + MaxRequestsInFlight: 400, + MinRequestTimeout: 1800, + RuntimeConfig: make(config.ConfigurationMap), + SecurePort: 6443, + StorageVersions: registered.AllPreferredGroupVersions(), } } @@ -178,12 +211,25 @@ func (s *ServerRunOptions) NewSelfClient() (clientset.Interface, error) { func (s *ServerRunOptions) AddFlags(fs *pflag.FlagSet) { // Note: the weird ""+ in below lines seems to be the only way to get gofmt to // arrange these text blocks sensibly. Grrr. + + fs.StringVar(&s.AdmissionControl, "admission-control", s.AdmissionControl, "Ordered list of plug-ins to do admission control of resources into cluster. Comma-delimited list of: "+strings.Join(admission.GetPlugins(), ", ")) + fs.StringVar(&s.AdmissionControlConfigFile, "admission-control-config-file", s.AdmissionControlConfigFile, "File with admission control configuration.") + fs.IPVar(&s.AdvertiseAddress, "advertise-address", s.AdvertiseAddress, ""+ "The IP address on which to advertise the apiserver to members of the cluster. This "+ "address must be reachable by the rest of the cluster. If blank, the --bind-address "+ "will be used. If --bind-address is unspecified, the host's default interface will "+ "be used.") + fs.StringVar(&s.AuthorizationMode, "authorization-mode", s.AuthorizationMode, "Ordered list of plug-ins to do authorization on secure port. Comma-delimited list of: "+strings.Join(apiserver.AuthorizationModeChoices, ",")) + + fs.StringVar(&s.AuthorizationConfig.PolicyFile, "authorization-policy-file", s.AuthorizationConfig.PolicyFile, "File with authorization policy in csv format, used with --authorization-mode=ABAC, on the secure port.") + fs.StringVar(&s.AuthorizationConfig.WebhookConfigFile, "authorization-webhook-config-file", s.AuthorizationConfig.WebhookConfigFile, "File with webhook configuration in kubeconfig format, used with --authorization-mode=Webhook. The API server will query the remote service to determine access on the API server's secure port.") + fs.DurationVar(&s.AuthorizationConfig.WebhookCacheAuthorizedTTL, "authorization-webhook-cache-authorized-ttl", s.AuthorizationConfig.WebhookCacheAuthorizedTTL, "The duration to cache 'authorized' responses from the webhook authorizer. Default is 5m.") + fs.DurationVar(&s.AuthorizationConfig.WebhookCacheUnauthorizedTTL, "authorization-webhook-cache-unauthorized-ttl", s.AuthorizationConfig.WebhookCacheUnauthorizedTTL, "The duration to cache 'unauthorized' responses from the webhook authorizer. Default is 30s.") + + fs.StringVar(&s.BasicAuthFile, "basic-auth-file", s.BasicAuthFile, "If set, the file that will be used to admit requests to the secure port of the API server via http basic authentication.") + fs.IPVar(&s.BindAddress, "public-address-override", s.BindAddress, "DEPRECATED: see --bind-address instead") fs.MarkDeprecated("public-address-override", "see --bind-address instead") fs.IPVar(&s.BindAddress, "bind-address", s.BindAddress, ""+ @@ -201,14 +247,9 @@ func (s *ServerRunOptions) AddFlags(fs *pflag.FlagSet) { fs.StringSliceVar(&s.CorsAllowedOriginList, "cors-allowed-origins", s.CorsAllowedOriginList, "List of allowed origins for CORS, comma separated. An allowed origin can be a regular expression to support subdomain matching. If this list is empty CORS will not be enabled.") - fs.StringVar(&s.StorageConfig.Type, "storage-backend", s.StorageConfig.Type, "The storage backend for persistence. Options: 'etcd2' (default), 'etcd3'.") - fs.StringSliceVar(&s.StorageConfig.ServerList, "etcd-servers", s.StorageConfig.ServerList, "List of etcd servers to connect with (http://ip:port), comma separated.") - fs.StringVar(&s.StorageConfig.Prefix, "etcd-prefix", s.StorageConfig.Prefix, "The prefix for all resource paths in etcd.") - fs.StringVar(&s.StorageConfig.KeyFile, "etcd-keyfile", s.StorageConfig.KeyFile, "SSL key file used to secure etcd communication") - fs.StringVar(&s.StorageConfig.CertFile, "etcd-certfile", s.StorageConfig.CertFile, "SSL certification file used to secure etcd communication") - fs.StringVar(&s.StorageConfig.CAFile, "etcd-cafile", s.StorageConfig.CAFile, "SSL Certificate Authority file used to secure etcd communication") - fs.BoolVar(&s.StorageConfig.Quorum, "etcd-quorum-read", s.StorageConfig.Quorum, "If true, enable quorum read") - fs.IntVar(&s.StorageConfig.DeserializationCacheSize, "deserialization-cache-size", s.StorageConfig.DeserializationCacheSize, "Number of deserialized json objects to cache in memory.") + fs.StringVar(&s.DefaultStorageMediaType, "storage-media-type", s.DefaultStorageMediaType, "The media type to use to store objects in storage. Defaults to application/json. Some resources may only support a specific media type and will ignore this setting.") + + fs.IntVar(&s.DeleteCollectionWorkers, "delete-collection-workers", s.DeleteCollectionWorkers, "Number of workers spawned for DeleteCollection call. These are used to speed up namespace cleanup.") fs.BoolVar(&s.EnableProfiling, "profiling", s.EnableProfiling, "Enable profiling via web interface host:port/debug/pprof/") @@ -217,6 +258,8 @@ func (s *ServerRunOptions) AddFlags(fs *pflag.FlagSet) { // TODO: enable cache in integration tests. fs.BoolVar(&s.EnableWatchCache, "watch-cache", s.EnableWatchCache, "Enable watch caching in the apiserver") + fs.StringSliceVar(&s.EtcdServersOverrides, "etcd-servers-overrides", s.EtcdServersOverrides, "Per-resource etcd servers overrides, comma separated. The individual override format: group/resource#servers, where servers are http://ip:port, semicolon separated.") + fs.StringVar(&s.ExternalHost, "external-hostname", s.ExternalHost, "The hostname to use when generating externalized URLs for this master (e.g. Swagger API Docs.)") fs.IPVar(&s.InsecureBindAddress, "insecure-bind-address", s.InsecureBindAddress, ""+ @@ -233,6 +276,8 @@ func (s *ServerRunOptions) AddFlags(fs *pflag.FlagSet) { fs.IntVar(&s.InsecurePort, "port", s.InsecurePort, "DEPRECATED: see --insecure-port instead") fs.MarkDeprecated("port", "see --insecure-port instead") + fs.StringVar(&s.KeystoneURL, "experimental-keystone-url", s.KeystoneURL, "If passed, activates the keystone authentication plugin") + // See #14282 for details on how to test/try this option out. TODO remove this comment once this option is tested in CI. fs.IntVar(&s.KubernetesServiceNodePort, "kubernetes-service-node-port", s.KubernetesServiceNodePort, "If non-zero, the Kubernetes master service (which apiserver creates/maintains) will be of type NodePort, using this as the value of the port. If zero, the Kubernetes master service will be of type ClusterIP.") @@ -240,10 +285,20 @@ func (s *ServerRunOptions) AddFlags(fs *pflag.FlagSet) { fs.IntVar(&s.MasterCount, "apiserver-count", s.MasterCount, "The number of apiservers running in the cluster") + fs.StringVar(&s.MasterServiceNamespace, "master-service-namespace", s.MasterServiceNamespace, "The namespace from which the kubernetes master services should be injected into pods") + fs.IntVar(&s.MaxRequestsInFlight, "max-requests-inflight", s.MaxRequestsInFlight, "The maximum number of requests in flight at a given time. When the server exceeds this, it rejects requests. Zero for no limit.") fs.IntVar(&s.MinRequestTimeout, "min-request-timeout", s.MinRequestTimeout, "An optional field indicating the minimum number of seconds a handler must keep a request open before timing it out. Currently only honored by the watch request handler, which picks a randomized value above this number as the connection timeout, to spread out load.") + fs.StringVar(&s.OIDCIssuerURL, "oidc-issuer-url", s.OIDCIssuerURL, "The URL of the OpenID issuer, only HTTPS scheme will be accepted. If set, it will be used to verify the OIDC JSON Web Token (JWT)") + fs.StringVar(&s.OIDCClientID, "oidc-client-id", s.OIDCClientID, "The client ID for the OpenID Connect client, must be set if oidc-issuer-url is set") + fs.StringVar(&s.OIDCCAFile, "oidc-ca-file", s.OIDCCAFile, "If set, the OpenID server's certificate will be verified by one of the authorities in the oidc-ca-file, otherwise the host's root CA set will be used") + fs.StringVar(&s.OIDCUsernameClaim, "oidc-username-claim", "sub", ""+ + "The OpenID claim to use as the user name. Note that claims other than the default ('sub') is not "+ + "guaranteed to be unique and immutable. This flag is experimental, please see the authentication documentation for further details.") + fs.StringVar(&s.OIDCGroupsClaim, "oidc-groups-claim", "", "If provided, the name of a custom OpenID Connect claim for specifying user groups. The claim value is expected to be an array of strings. This flag is experimental, please see the authentication documentation for further details.") + fs.Var(&s.RuntimeConfig, "runtime-config", "A set of key=value pairs that describe runtime configuration that may be passed to apiserver. apis/ key can be used to turn on/off specific api versions. apis// can be used to turn on/off specific resources. api/all and api/legacy are special keys to control all and legacy api versions respectively.") fs.IntVar(&s.SecurePort, "secure-port", s.SecurePort, ""+ @@ -258,6 +313,15 @@ func (s *ServerRunOptions) AddFlags(fs *pflag.FlagSet) { fs.Var(&s.ServiceNodePortRange, "service-node-ports", "Deprecated: see --service-node-port-range instead.") fs.MarkDeprecated("service-node-ports", "see --service-node-port-range instead.") + fs.StringVar(&s.StorageConfig.Type, "storage-backend", s.StorageConfig.Type, "The storage backend for persistence. Options: 'etcd2' (default), 'etcd3'.") + fs.StringSliceVar(&s.StorageConfig.ServerList, "etcd-servers", s.StorageConfig.ServerList, "List of etcd servers to connect with (http://ip:port), comma separated.") + fs.StringVar(&s.StorageConfig.Prefix, "etcd-prefix", s.StorageConfig.Prefix, "The prefix for all resource paths in etcd.") + fs.StringVar(&s.StorageConfig.KeyFile, "etcd-keyfile", s.StorageConfig.KeyFile, "SSL key file used to secure etcd communication") + fs.StringVar(&s.StorageConfig.CertFile, "etcd-certfile", s.StorageConfig.CertFile, "SSL certification file used to secure etcd communication") + fs.StringVar(&s.StorageConfig.CAFile, "etcd-cafile", s.StorageConfig.CAFile, "SSL Certificate Authority file used to secure etcd communication") + fs.BoolVar(&s.StorageConfig.Quorum, "etcd-quorum-read", s.StorageConfig.Quorum, "If true, enable quorum read") + fs.IntVar(&s.StorageConfig.DeserializationCacheSize, "deserialization-cache-size", s.StorageConfig.DeserializationCacheSize, "Number of deserialized json objects to cache in memory.") + fs.StringVar(&s.DeprecatedStorageVersion, "storage-version", s.DeprecatedStorageVersion, "The version to store the legacy v1 resources with. Defaults to server preferred") fs.MarkDeprecated("storage-version", "--storage-version is deprecated and will be removed when the v1 API is retired. See --storage-versions instead.") fs.StringVar(&s.StorageVersions, "storage-versions", s.StorageVersions, "The per-group version to store resources in. "+ @@ -272,4 +336,8 @@ func (s *ServerRunOptions) AddFlags(fs *pflag.FlagSet) { "a self-signed certificate and key are generated for the public address and saved to /var/run/kubernetes.") fs.StringVar(&s.TLSPrivateKeyFile, "tls-private-key-file", s.TLSPrivateKeyFile, "File containing x509 private key matching --tls-cert-file.") + + fs.StringVar(&s.TokenAuthFile, "token-auth-file", s.TokenAuthFile, "If set, the file that will be used to secure the secure port of the API server via token authentication.") + + fs.StringSliceVar(&s.WatchCacheSizes, "watch-cache-sizes", s.WatchCacheSizes, "List of watch cache sizes for every resource (pods, nodes, etc.), comma separated. The individual override format: resource#size, where size is a number. It takes effect when watch-cache is enabled.") } diff --git a/vendor/k8s.io/kubernetes/pkg/genericapiserver/storage_factory.go b/vendor/k8s.io/kubernetes/pkg/genericapiserver/storage_factory.go index 45489c3307..fb25cb0b06 100644 --- a/vendor/k8s.io/kubernetes/pkg/genericapiserver/storage_factory.go +++ b/vendor/k8s.io/kubernetes/pkg/genericapiserver/storage_factory.go @@ -26,6 +26,7 @@ import ( "k8s.io/kubernetes/pkg/runtime/serializer/versioning" "k8s.io/kubernetes/pkg/storage" "k8s.io/kubernetes/pkg/storage/storagebackend" + storagebackendfactory "k8s.io/kubernetes/pkg/storage/storagebackend/factory" "k8s.io/kubernetes/pkg/util/sets" "github.com/golang/glog" @@ -70,7 +71,7 @@ type DefaultStorageFactory struct { newStorageCodecFn func(storageMediaType string, ns runtime.StorageSerializer, storageVersion, memoryVersion unversioned.GroupVersion, config storagebackend.Config) (codec runtime.Codec, err error) // newStorageFn exists to be overwritten for unit testing. - newStorageFn func(config storagebackend.Config) (etcdStorage storage.Interface, err error) + newStorageFn func(config storagebackend.Config, codec runtime.Codec) (etcdStorage storage.Interface, err error) } type groupResourceOverrides struct { @@ -212,15 +213,13 @@ func (s *DefaultStorageFactory) New(groupResource unversioned.GroupResource) (st return nil, err } - config.Codec = codec - glog.V(3).Infof("storing %v in %v, reading as %v from %v", groupResource, storageEncodingVersion, internalVersion, config) - return s.newStorageFn(config) + return s.newStorageFn(config, codec) } // newStorage is the default implementation for creating a storage backend. -func newStorage(config storagebackend.Config) (etcdStorage storage.Interface, err error) { - return storagebackend.Create(config) +func newStorage(config storagebackend.Config, codec runtime.Codec) (etcdStorage storage.Interface, err error) { + return storagebackendfactory.Create(config, codec) } // Get all backends for all registered storage destinations. diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cadvisor/cadvisor_linux.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cadvisor/cadvisor_linux.go index f7691b6384..b545b72e07 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cadvisor/cadvisor_linux.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/cadvisor/cadvisor_linux.go @@ -39,6 +39,7 @@ import ( ) type cadvisorClient struct { + runtime string manager.Manager } @@ -60,7 +61,7 @@ func init() { } // Creates a cAdvisor and exports its API on the specified port if port > 0. -func New(port uint) (Interface, error) { +func New(port uint, runtime string) (Interface, error) { sysFs, err := sysfs.NewRealSysFs() if err != nil { return nil, err @@ -73,6 +74,7 @@ func New(port uint) (Interface, error) { } cadvisorClient := &cadvisorClient{ + runtime: runtime, Manager: m, } @@ -148,7 +150,7 @@ func (cc *cadvisorClient) VersionInfo() (*cadvisorapi.VersionInfo, error) { func (cc *cadvisorClient) SubcontainerInfo(name string, req *cadvisorapi.ContainerInfoRequest) (map[string]*cadvisorapi.ContainerInfo, error) { infos, err := cc.SubcontainersInfo(name, req) - if err != nil { + if err != nil && len(infos) == 0 { return nil, err } @@ -156,15 +158,26 @@ func (cc *cadvisorClient) SubcontainerInfo(name string, req *cadvisorapi.Contain for _, info := range infos { result[info.Name] = info } - return result, nil + return result, err } func (cc *cadvisorClient) MachineInfo() (*cadvisorapi.MachineInfo, error) { return cc.GetMachineInfo() } -func (cc *cadvisorClient) DockerImagesFsInfo() (cadvisorapiv2.FsInfo, error) { - return cc.getFsInfo(cadvisorfs.LabelDockerImages) +func (cc *cadvisorClient) ImagesFsInfo() (cadvisorapiv2.FsInfo, error) { + var label string + + switch cc.runtime { + case "docker": + label = cadvisorfs.LabelDockerImages + case "rkt": + label = cadvisorfs.LabelRktImages + default: + return cadvisorapiv2.FsInfo{}, fmt.Errorf("ImagesFsInfo: unknown runtime: %v", cc.runtime) + } + + return cc.getFsInfo(label) } func (cc *cadvisorClient) RootFsInfo() (cadvisorapiv2.FsInfo, error) { diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cadvisor/cadvisor_unsupported.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cadvisor/cadvisor_unsupported.go index e0bcd4d6de..e5f281d646 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cadvisor/cadvisor_unsupported.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/cadvisor/cadvisor_unsupported.go @@ -31,7 +31,7 @@ type cadvisorUnsupported struct { var _ Interface = new(cadvisorUnsupported) -func New(port uint) (Interface, error) { +func New(port uint, runtime string) (Interface, error) { return &cadvisorUnsupported{}, nil } @@ -65,7 +65,7 @@ func (cu *cadvisorUnsupported) VersionInfo() (*cadvisorapi.VersionInfo, error) { return nil, unsupportedErr } -func (cu *cadvisorUnsupported) DockerImagesFsInfo() (cadvisorapiv2.FsInfo, error) { +func (cu *cadvisorUnsupported) ImagesFsInfo() (cadvisorapiv2.FsInfo, error) { return cadvisorapiv2.FsInfo{}, unsupportedErr } diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cadvisor/types.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cadvisor/types.go index 5bfbd2a0f0..fbf7b9e058 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cadvisor/types.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/cadvisor/types.go @@ -34,7 +34,7 @@ type Interface interface { VersionInfo() (*cadvisorapi.VersionInfo, error) // Returns usage information about the filesystem holding Docker images. - DockerImagesFsInfo() (cadvisorapiv2.FsInfo, error) + ImagesFsInfo() (cadvisorapiv2.FsInfo, error) // Returns usage information about the root filesystem. RootFsInfo() (cadvisorapiv2.FsInfo, error) diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/client/kubelet_client.go b/vendor/k8s.io/kubernetes/pkg/kubelet/client/kubelet_client.go index cd48f05c3d..bbaade4eee 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/client/kubelet_client.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/client/kubelet_client.go @@ -21,6 +21,7 @@ import ( "fmt" "net" "net/http" + "strings" "time" "k8s.io/kubernetes/pkg/api" @@ -98,8 +99,8 @@ func NewStaticKubeletClient(config *KubeletClientConfig) (KubeletClient, error) // In default HTTPKubeletClient ctx is unused. func (c *HTTPKubeletClient) GetConnectionInfo(ctx api.Context, nodeName string) (string, uint, http.RoundTripper, error) { - if ok, msg := validation.ValidateNodeName(nodeName, false); !ok { - return "", 0, nil, fmt.Errorf("invalid node name: %s", msg) + if errs := validation.ValidateNodeName(nodeName, false); len(errs) != 0 { + return "", 0, nil, fmt.Errorf("invalid node name: %s", strings.Join(errs, ";")) } scheme := "http" if c.Config.EnableHttps { diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/container_manager_linux.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/container_manager_linux.go index 45497dcb8f..fe754d8fa0 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/container_manager_linux.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/container_manager_linux.go @@ -20,6 +20,7 @@ package cm import ( "fmt" + "io/ioutil" "os" "os/exec" "path" @@ -39,6 +40,7 @@ import ( utilerrors "k8s.io/kubernetes/pkg/util/errors" "k8s.io/kubernetes/pkg/util/mount" "k8s.io/kubernetes/pkg/util/oom" + "k8s.io/kubernetes/pkg/util/runtime" "k8s.io/kubernetes/pkg/util/sets" utilsysctl "k8s.io/kubernetes/pkg/util/sysctl" "k8s.io/kubernetes/pkg/util/wait" @@ -51,6 +53,9 @@ const ( DockerMemoryLimitThresholdPercent = 70 // The minimum memory limit allocated to docker container: 150Mi MinDockerMemoryLimit = 150 * 1024 * 1024 + + dockerProcessName = "docker" + dockerPidFile = "/var/run/docker.pid" ) // A non-user container tracked by the Kubelet. @@ -262,11 +267,12 @@ func (cm *containerManagerImpl) setupNode() error { systemContainers = append(systemContainers, cont) } else { cm.periodicTasks = append(cm.periodicTasks, func() { - cont, err := getContainerNameForProcess("docker") + cont, err := getContainerNameForProcess(dockerProcessName, dockerPidFile) if err != nil { glog.Error(err) return } + glog.V(2).Infof("Discovered runtime cgroups name: %s", cont) cm.Lock() defer cm.Unlock() cm.RuntimeCgroupsName = cont @@ -324,8 +330,8 @@ func (cm *containerManagerImpl) setupNode() error { return nil } -func getContainerNameForProcess(name string) (string, error) { - pids, err := getPidsForProcess(name) +func getContainerNameForProcess(name, pidFile string) (string, error) { + pids, err := getPidsForProcess(name, pidFile) if err != nil { return "", fmt.Errorf("failed to detect process id for %q - %v", name, err) } @@ -418,7 +424,36 @@ func isProcessRunningInHost(pid int) (bool, error) { return initMntNs == processMntNs, nil } -func getPidsForProcess(name string) ([]int, error) { +func getPidFromPidFile(pidFile string) (int, error) { + file, err := os.Open(pidFile) + if err != nil { + return 0, fmt.Errorf("error opening pid file %s: %v", pidFile, err) + } + defer file.Close() + + data, err := ioutil.ReadAll(file) + if err != nil { + return 0, fmt.Errorf("error reading pid file %s: %v", pidFile, err) + } + + pid, err := strconv.Atoi(string(data)) + if err != nil { + return 0, fmt.Errorf("error parsing %s as a number: %v", string(data), err) + } + + return pid, nil +} + +func getPidsForProcess(name, pidFile string) ([]int, error) { + if len(pidFile) > 0 { + if pid, err := getPidFromPidFile(pidFile); err == nil { + return []int{pid}, nil + } else { + // log the error and fall back to pidof + runtime.HandleError(err) + } + } + out, err := exec.Command("pidof", name).Output() if err != nil { return []int{}, fmt.Errorf("failed to find pid of %q: %v", name, err) @@ -438,7 +473,7 @@ func getPidsForProcess(name string) ([]int, error) { // Ensures that the Docker daemon is in the desired container. func ensureDockerInContainer(cadvisor cadvisor.Interface, oomScoreAdj int, manager *fs.Manager) error { - pids, err := getPidsForProcess("docker") + pids, err := getPidsForProcess(dockerProcessName, dockerPidFile) if err != nil { return err } diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/container/os.go b/vendor/k8s.io/kubernetes/pkg/kubelet/container/os.go index 7fedd5703f..b9f7e0e663 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/container/os.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/container/os.go @@ -17,7 +17,9 @@ limitations under the License. package container import ( + "io/ioutil" "os" + "time" ) // OSInterface collects system level operations that need to be mocked out @@ -26,6 +28,12 @@ type OSInterface interface { Mkdir(path string, perm os.FileMode) error Symlink(oldname string, newname string) error Stat(path string) (os.FileInfo, error) + Remove(path string) error + Create(path string) (*os.File, error) + Hostname() (name string, err error) + Chtimes(path string, atime time.Time, mtime time.Time) error + Pipe() (r *os.File, w *os.File, err error) + ReadDir(dirname string) ([]os.FileInfo, error) } // RealOS is used to dispatch the real system level operaitons. @@ -45,3 +53,34 @@ func (RealOS) Symlink(oldname string, newname string) error { func (RealOS) Stat(path string) (os.FileInfo, error) { return os.Stat(path) } + +// Remove will call os.Remove to remove the path. +func (RealOS) Remove(path string) error { + return os.Remove(path) +} + +// Create will call os.Create to create and return a file +// at path. +func (RealOS) Create(path string) (*os.File, error) { + return os.Create(path) +} + +// Hostname will call os.Hostname to return the hostname. +func (RealOS) Hostname() (name string, err error) { + return os.Hostname() +} + +// Chtimes will call os.Chtimes to change the atime and mtime of the path +func (RealOS) Chtimes(path string, atime time.Time, mtime time.Time) error { + return os.Chtimes(path, atime, mtime) +} + +// Pipe will call os.Pipe to return a connected pair of pipe. +func (RealOS) Pipe() (r *os.File, w *os.File, err error) { + return os.Pipe() +} + +// ReadDir will call ioutil.ReadDir to return the files under the directory. +func (RealOS) ReadDir(dirname string) ([]os.FileInfo, error) { + return ioutil.ReadDir(dirname) +} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/container/ref.go b/vendor/k8s.io/kubernetes/pkg/kubelet/container/ref.go index 55e4d54657..ebfff2ebf7 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/container/ref.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/container/ref.go @@ -57,5 +57,15 @@ func fieldPath(pod *api.Pod, container *api.Container) (string, error) { } } } + for i := range pod.Spec.InitContainers { + here := &pod.Spec.InitContainers[i] + if here.Name == container.Name { + if here.Name == "" { + return fmt.Sprintf("spec.initContainers[%d]", i), nil + } else { + return fmt.Sprintf("spec.initContainers{%s}", here.Name), nil + } + } + } return "", fmt.Errorf("container %#v not found in pod %#v", container, pod) } diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/container/runtime.go b/vendor/k8s.io/kubernetes/pkg/kubelet/container/runtime.go index 803b9b166f..e7510359c3 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/container/runtime.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/container/runtime.go @@ -69,7 +69,7 @@ type Runtime interface { APIVersion() (Version, error) // Status returns error if the runtime is unhealthy; nil otherwise. Status() error - // GetPods returns a list containers group by pods. The boolean parameter + // GetPods returns a list of containers grouped by pods. The boolean parameter // specifies whether the runtime returns all containers including those already // exited and dead containers (used for garbage collection). GetPods(all bool) ([]*Pod, error) @@ -97,6 +97,12 @@ type Runtime interface { RemoveImage(image ImageSpec) error // Returns Image statistics. ImageStats() (*ImageStats, error) + // Returns the filesystem path of the pod's network namespace; if the + // runtime does not handle namespace creation itself, or cannot return + // the network namespace path, it should return an error. + // TODO: Change ContainerID to a Pod ID since the namespace is shared + // by all containers in the pod. + GetNetNS(containerID ContainerID) (string, error) // TODO(vmarmol): Unify pod and containerID args. // GetContainerLogs returns logs of a specific container. By // default, it returns a snapshot of the container log. Set 'follow' to true to @@ -115,9 +121,6 @@ type ContainerAttacher interface { // CommandRunner encapsulates the command runner interfaces for testability. type ContainerCommandRunner interface { - // TODO(vmarmol): Merge RunInContainer and ExecInContainer. - // Runs the command in the container of the specified pod. - RunInContainer(containerID ContainerID, cmd []string) ([]byte, error) // Runs the command in the container of the specified pod using nsenter. // Attaches the processes stdin, stdout, and stderr. Optionally uses a // tty. diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/container/sync_result.go b/vendor/k8s.io/kubernetes/pkg/kubelet/container/sync_result.go index 1c3aa9eea9..6a196f602b 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/container/sync_result.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/container/sync_result.go @@ -50,9 +50,10 @@ var ( ) var ( - ErrRunContainer = errors.New("RunContainerError") - ErrKillContainer = errors.New("KillContainerError") - ErrVerifyNonRoot = errors.New("VerifyNonRootError") + ErrRunContainer = errors.New("RunContainerError") + ErrKillContainer = errors.New("KillContainerError") + ErrVerifyNonRoot = errors.New("VerifyNonRootError") + ErrRunInitContainer = errors.New("RunInitContainerError") ) var ( @@ -69,6 +70,7 @@ const ( KillContainer SyncAction = "KillContainer" SetupNetwork SyncAction = "SetupNetwork" TeardownNetwork SyncAction = "TeardownNetwork" + InitContainer SyncAction = "InitContainer" ) // SyncResult is the result of sync action. diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/disk_manager.go b/vendor/k8s.io/kubernetes/pkg/kubelet/disk_manager.go index ad110cef4b..edf749b4f8 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/disk_manager.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/disk_manager.go @@ -35,7 +35,7 @@ const mb = 1024 * 1024 type diskSpaceManager interface { // Checks the available disk space IsRootDiskSpaceAvailable() (bool, error) - IsDockerDiskSpaceAvailable() (bool, error) + IsRuntimeDiskSpaceAvailable() (bool, error) } type DiskSpacePolicy struct { @@ -83,8 +83,8 @@ func (dm *realDiskSpaceManager) getFsInfo(fsType string, f func() (cadvisorapi.F return fsi, nil } -func (dm *realDiskSpaceManager) IsDockerDiskSpaceAvailable() (bool, error) { - return dm.isSpaceAvailable("docker", dm.policy.DockerFreeDiskMB, dm.cadvisor.DockerImagesFsInfo) +func (dm *realDiskSpaceManager) IsRuntimeDiskSpaceAvailable() (bool, error) { + return dm.isSpaceAvailable("runtime", dm.policy.DockerFreeDiskMB, dm.cadvisor.ImagesFsInfo) } func (dm *realDiskSpaceManager) IsRootDiskSpaceAvailable() (bool, error) { diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/dockertools/manager.go b/vendor/k8s.io/kubernetes/pkg/kubelet/dockertools/manager.go index 20c991e774..fea46a5a52 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/dockertools/manager.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/dockertools/manager.go @@ -37,6 +37,7 @@ import ( dockernat "github.com/docker/go-connections/nat" "github.com/golang/glog" cadvisorapi "github.com/google/cadvisor/info/v1" + "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/client/record" @@ -57,6 +58,7 @@ import ( "k8s.io/kubernetes/pkg/util/oom" "k8s.io/kubernetes/pkg/util/procfs" utilruntime "k8s.io/kubernetes/pkg/util/runtime" + "k8s.io/kubernetes/pkg/util/sets" utilstrings "k8s.io/kubernetes/pkg/util/strings" ) @@ -579,7 +581,7 @@ func (dm *DockerManager) runContainer( // 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.Amount == nil && cpuLimit.Amount != nil { + if cpuRequest.IsZero() && !cpuLimit.IsZero() { cpuShares = milliCPUToShares(cpuLimit.MilliValue()) } else { // if cpuRequest.Amount is nil, then milliCPUToShares will return the minimal number @@ -876,6 +878,9 @@ func (dm *DockerManager) podInfraContainerChanged(pod *api.Pod, podInfraContaine } else if dm.networkPlugin.Name() != "cni" && dm.networkPlugin.Name() != "kubenet" { // Docker only exports ports from the pod infra container. Let's // collect all of the relevant ports and export them. + for _, container := range pod.Spec.InitContainers { + ports = append(ports, container.Ports...) + } for _, container := range pod.Spec.Containers { ports = append(ports, container.Ports...) } @@ -982,53 +987,6 @@ func (dm *DockerManager) getDefaultSecurityOpt() ([]string, error) { return nil, nil } -// RunInContainer run the command inside the container identified by containerID -func (dm *DockerManager) RunInContainer(containerID kubecontainer.ContainerID, cmd []string) ([]byte, error) { - glog.V(2).Infof("Using docker native exec to run cmd %+v inside container %s", cmd, containerID) - createOpts := dockertypes.ExecConfig{ - Cmd: cmd, - AttachStdin: false, - AttachStdout: true, - AttachStderr: true, - Tty: false, - } - execObj, err := dm.client.CreateExec(containerID.ID, createOpts) - if err != nil { - return nil, fmt.Errorf("failed to run in container - Exec setup failed - %v", err) - } - var buf bytes.Buffer - startOpts := dockertypes.ExecStartCheck{Detach: false, Tty: false} - streamOpts := StreamOptions{ - OutputStream: &buf, - ErrorStream: &buf, - RawTerminal: false, - } - err = dm.client.StartExec(execObj.ID, startOpts, streamOpts) - if err != nil { - glog.V(2).Infof("StartExec With error: %v", err) - return nil, err - } - ticker := time.NewTicker(2 * time.Second) - defer ticker.Stop() - for { - inspect, err2 := dm.client.InspectExec(execObj.ID) - if err2 != nil { - glog.V(2).Infof("InspectExec %s failed with error: %+v", execObj.ID, err2) - return buf.Bytes(), err2 - } - if !inspect.Running { - if inspect.ExitCode != 0 { - glog.V(2).Infof("InspectExec %s exit with result %+v", execObj.ID, inspect) - err = &dockerExitError{inspect} - } - break - } - <-ticker.C - } - - return buf.Bytes(), err -} - type dockerExitError struct { Inspect *dockertypes.ContainerExecInspect } @@ -1226,6 +1184,14 @@ func (dm *DockerManager) killPodWithSyncResult(pod *api.Pod, runningPod kubecont break } } + if containerSpec == nil { + for i, c := range pod.Spec.InitContainers { + if c.Name == container.Name { + containerSpec = &pod.Spec.InitContainers[i] + break + } + } + } } // TODO: Handle this without signaling the pod infra container to @@ -1416,6 +1382,14 @@ func containerAndPodFromLabels(inspect *dockertypes.ContainerJSON) (pod *api.Pod break } } + if container == nil { + for ix := range pod.Spec.InitContainers { + if pod.Spec.InitContainers[ix].Name == name { + container = &pod.Spec.InitContainers[ix] + break + } + } + } if container == nil { err = fmt.Errorf("unable to find container %s in pod %v", name, pod) } @@ -1438,7 +1412,13 @@ func containerAndPodFromLabels(inspect *dockertypes.ContainerJSON) (pod *api.Pod return } -func (dm *DockerManager) applyOOMScoreAdj(container *api.Container, containerInfo *dockertypes.ContainerJSON) error { +func (dm *DockerManager) applyOOMScoreAdj(pod *api.Pod, container *api.Container, containerInfo *dockertypes.ContainerJSON) error { + if containerInfo.State.Pid == 0 { + // Container exited. We cannot do anything about it. Ignore this error. + glog.V(2).Infof("Failed to apply OOM score adj on container %q with ID %q. Init process does not exist.", containerInfo.Name, containerInfo.ID) + return nil + } + cgroupName, err := dm.procFs.GetFullContainerName(containerInfo.State.Pid) if err != nil { if err == os.ErrNotExist { @@ -1448,7 +1428,7 @@ func (dm *DockerManager) applyOOMScoreAdj(container *api.Container, containerInf } return err } - oomScoreAdj := dm.calculateOomScoreAdj(container) + oomScoreAdj := dm.calculateOomScoreAdj(pod, container) if err = dm.oomAdjuster.ApplyOOMScoreAdjContainer(cgroupName, oomScoreAdj, 5); err != nil { if err == os.ErrNotExist { // Container exited. We cannot do anything about it. Ignore this error. @@ -1472,6 +1452,7 @@ func (dm *DockerManager) runContainerInPod(pod *api.Pod, container *api.Containe if err != nil { glog.Errorf("Can't make a ref to pod %v, container %v: '%v'", pod.Name, container.Name, err) } + glog.Infof("Generating ref for container %s: %#v", container.Name, ref) opts, err := dm.runtimeHelper.GenerateRunContainerOptions(pod, container, podIP) if err != nil { @@ -1483,7 +1464,7 @@ func (dm *DockerManager) runContainerInPod(pod *api.Pod, container *api.Containe utsMode = namespaceModeHost } - oomScoreAdj := dm.calculateOomScoreAdj(container) + oomScoreAdj := dm.calculateOomScoreAdj(pod, container) id, err := dm.runContainer(pod, container, opts, ref, netMode, ipcMode, utsMode, pidMode, restartCount, oomScoreAdj) if err != nil { @@ -1519,14 +1500,10 @@ func (dm *DockerManager) runContainerInPod(pod *api.Pod, container *api.Containe if err != nil { return kubecontainer.ContainerID{}, fmt.Errorf("InspectContainer: %v", err) } - // Ensure the PID actually exists, else we'll move ourselves. - if containerInfo.State.Pid == 0 { - return kubecontainer.ContainerID{}, fmt.Errorf("can't get init PID for container %q", id) - } // Check if current docker version is higher than 1.10. Otherwise, we have to apply OOMScoreAdj instead of using docker API. - err = dm.applyOOMScoreAdjIfNeeded(container, containerInfo) - if err != nil { + // TODO: Remove this logic after we stop supporting docker version < 1.10. + if err = dm.applyOOMScoreAdjIfNeeded(pod, container, containerInfo); err != nil { return kubecontainer.ContainerID{}, err } @@ -1544,7 +1521,7 @@ func (dm *DockerManager) runContainerInPod(pod *api.Pod, container *api.Containe return id, err } -func (dm *DockerManager) applyOOMScoreAdjIfNeeded(container *api.Container, containerInfo *dockertypes.ContainerJSON) error { +func (dm *DockerManager) applyOOMScoreAdjIfNeeded(pod *api.Pod, container *api.Container, containerInfo *dockertypes.ContainerJSON) error { // Compare current API version with expected api version. result, err := dm.checkDockerAPIVersion(dockerv110APIVersion) if err != nil { @@ -1552,7 +1529,7 @@ func (dm *DockerManager) applyOOMScoreAdjIfNeeded(container *api.Container, cont } // If current api version is older than OOMScoreAdj requested, use the old way. if result < 0 { - if err := dm.applyOOMScoreAdj(container, containerInfo); err != nil { + if err := dm.applyOOMScoreAdj(pod, container, containerInfo); err != nil { return fmt.Errorf("Failed to apply oom-score-adj to container %q- %v", err, containerInfo.Name) } } @@ -1560,7 +1537,7 @@ func (dm *DockerManager) applyOOMScoreAdjIfNeeded(container *api.Container, cont return nil } -func (dm *DockerManager) calculateOomScoreAdj(container *api.Container) int { +func (dm *DockerManager) calculateOomScoreAdj(pod *api.Pod, container *api.Container) int { // Set OOM score of the container based on the priority of the container. // Processes in lower-priority pods should be killed first if the system runs out of memory. // The main pod infrastructure container is considered high priority, since if it is killed the @@ -1569,7 +1546,7 @@ func (dm *DockerManager) calculateOomScoreAdj(container *api.Container) int { if container.Name == PodInfraContainerName { oomScoreAdj = qos.PodInfraOOMAdj } else { - oomScoreAdj = qos.GetContainerOOMScoreAdjust(container, int64(dm.machineInfo.MemoryCapacity)) + oomScoreAdj = qos.GetContainerOOMScoreAdjust(pod, container, int64(dm.machineInfo.MemoryCapacity)) } @@ -1650,6 +1627,9 @@ func (dm *DockerManager) createPodInfraContainer(pod *api.Pod) (kubecontainer.Do } else { // Docker only exports ports from the pod infra container. Let's // collect all of the relevant ports and export them. + for _, container := range pod.Spec.InitContainers { + ports = append(ports, container.Ports...) + } for _, container := range pod.Spec.Containers { ports = append(ports, container.Ports...) } @@ -1687,13 +1667,16 @@ func (dm *DockerManager) createPodInfraContainer(pod *api.Pod) (kubecontainer.Do // should be kept running. If startInfraContainer is false then it contains an entry for infraContainerId (mapped to -1). // It shouldn't be the case where containersToStart is empty and containersToKeep contains only infraContainerId. In such case // Infra Container should be killed, hence it's removed from this map. -// - all running containers which are NOT contained in containersToKeep should be killed. +// - all init containers are stored in initContainersToKeep +// - all running containers which are NOT contained in containersToKeep and initContainersToKeep should be killed. type podContainerChangesSpec struct { - StartInfraContainer bool - InfraChanged bool - InfraContainerId kubecontainer.DockerID - ContainersToStart map[int]string - ContainersToKeep map[kubecontainer.DockerID]int + StartInfraContainer bool + InfraChanged bool + InfraContainerId kubecontainer.DockerID + InitFailed bool + InitContainersToKeep map[kubecontainer.DockerID]int + ContainersToStart map[int]string + ContainersToKeep map[kubecontainer.DockerID]int } func (dm *DockerManager) computePodContainerChanges(pod *api.Pod, podStatus *kubecontainer.PodStatus) (podContainerChangesSpec, error) { @@ -1730,6 +1713,35 @@ func (dm *DockerManager) computePodContainerChanges(pod *api.Pod, podStatus *kub containersToKeep[podInfraContainerID] = -1 } + // check the status of the init containers + initFailed := false + initContainersToKeep := make(map[kubecontainer.DockerID]int) + // always reset the init containers if the pod is reset + if !createPodInfraContainer { + // keep all successfully completed containers up to and including the first failing container + Containers: + for i, container := range pod.Spec.InitContainers { + containerStatus := podStatus.FindContainerStatusByName(container.Name) + if containerStatus == nil { + continue + } + switch { + case containerStatus == nil: + continue + case containerStatus.State == kubecontainer.ContainerStateRunning: + initContainersToKeep[kubecontainer.DockerID(containerStatus.ID.ID)] = i + case containerStatus.State == kubecontainer.ContainerStateExited: + initContainersToKeep[kubecontainer.DockerID(containerStatus.ID.ID)] = i + // TODO: should we abstract the "did the init container fail" check? + if containerStatus.ExitCode != 0 { + initFailed = true + break Containers + } + } + } + } + + // check the status of the containers for index, container := range pod.Spec.Containers { expectedHash := kubecontainer.HashContainer(&container) @@ -1763,6 +1775,19 @@ func (dm *DockerManager) computePodContainerChanges(pod *api.Pod, podStatus *kub continue } + if initFailed { + // initialization failed and Container exists + // If we have an initialization failure everything will be killed anyway + // If RestartPolicy is Always or OnFailure we restart containers that were running before we + // killed them when re-running initialization + if pod.Spec.RestartPolicy != api.RestartPolicyNever { + message := fmt.Sprintf("Failed to initialize pod. %q will be restarted.", container.Name) + glog.V(1).Info(message) + containersToStart[index] = message + } + continue + } + // At this point, the container is running and pod infra container is good. // We will look for changes and check healthiness for the container. containerChanged := hash != 0 && hash != expectedHash @@ -1790,17 +1815,21 @@ func (dm *DockerManager) computePodContainerChanges(pod *api.Pod, podStatus *kub // (In fact, when createPodInfraContainer is false, containersToKeep will not be touched). // - createPodInfraContainer is false and containersToKeep contains at least ID of Infra Container - // If Infra container is the last running one, we don't want to keep it. + // If Infra container is the last running one, we don't want to keep it, and we don't want to + // keep any init containers. if !createPodInfraContainer && len(containersToStart) == 0 && len(containersToKeep) == 1 { containersToKeep = make(map[kubecontainer.DockerID]int) + initContainersToKeep = make(map[kubecontainer.DockerID]int) } return podContainerChangesSpec{ - StartInfraContainer: createPodInfraContainer, - InfraChanged: changed, - InfraContainerId: podInfraContainerID, - ContainersToStart: containersToStart, - ContainersToKeep: containersToKeep, + StartInfraContainer: createPodInfraContainer, + InfraChanged: changed, + InfraContainerId: podInfraContainerID, + InitFailed: initFailed, + InitContainersToKeep: initContainersToKeep, + ContainersToStart: containersToStart, + ContainersToKeep: containersToKeep, }, nil } @@ -1844,7 +1873,8 @@ func (dm *DockerManager) SyncPod(pod *api.Pod, _ api.PodStatus, podStatus *kubec runningContainerStatues := podStatus.GetRunningContainerStatuses() for _, containerStatus := range runningContainerStatues { _, keep := containerChanges.ContainersToKeep[kubecontainer.DockerID(containerStatus.ID.ID)] - if !keep { + _, keepInit := containerChanges.InitContainersToKeep[kubecontainer.DockerID(containerStatus.ID.ID)] + if !keep && !keepInit { glog.V(3).Infof("Killing unwanted container %q(id=%q) for pod %q", containerStatus.Name, containerStatus.ID, format.Pod(pod)) // attempt to find the appropriate container policy var podContainer *api.Container @@ -1867,6 +1897,9 @@ func (dm *DockerManager) SyncPod(pod *api.Pod, _ api.PodStatus, podStatus *kubec } } + // Keep terminated init containers fairly aggressively controlled + dm.pruneInitContainersBeforeStart(pod, podStatus, containerChanges.InitContainersToKeep) + // We pass the value of the podIP down to runContainerInPod, which in turn // passes it to various other functions, in order to facilitate // functionality that requires this value (hosts file and downward API) @@ -1926,7 +1959,7 @@ func (dm *DockerManager) SyncPod(pod *api.Pod, _ api.PodStatus, podStatus *kubec } if dm.configureHairpinMode { - if err = hairpin.SetUpContainer(podInfraContainer.State.Pid, network.DefaultInterfaceName); err != nil { + if err = hairpin.SetUpContainerPid(podInfraContainer.State.Pid, network.DefaultInterfaceName); err != nil { glog.Warningf("Hairpin setup failed for pod %q: %v", format.Pod(pod), err) } } @@ -1936,14 +1969,78 @@ func (dm *DockerManager) SyncPod(pod *api.Pod, _ api.PodStatus, podStatus *kubec } } - // Start everything + next, status, done := findActiveInitContainer(pod, podStatus) + if status != nil { + if status.ExitCode != 0 { + // container initialization has failed, flag the pod as failed + initContainerResult := kubecontainer.NewSyncResult(kubecontainer.InitContainer, status.Name) + initContainerResult.Fail(kubecontainer.ErrRunInitContainer, fmt.Sprintf("init container %q exited with %d", status.Name, status.ExitCode)) + result.AddSyncResult(initContainerResult) + if pod.Spec.RestartPolicy == api.RestartPolicyNever { + utilruntime.HandleError(fmt.Errorf("error running pod %q init container %q, restart=Never: %+v", format.Pod(pod), status.Name, status)) + return + } + utilruntime.HandleError(fmt.Errorf("Error running pod %q init container %q, restarting: %+v", format.Pod(pod), status.Name, status)) + } + } + + // Note: when configuring the pod's containers anything that can be configured by pointing + // to the namespace of the infra container should use namespaceMode. This includes things like the net namespace + // and IPC namespace. PID mode cannot point to another container right now. + // See createPodInfraContainer for infra container setup. + namespaceMode := fmt.Sprintf("container:%v", podInfraContainerID) + pidMode := getPidMode(pod) + + if next != nil { + if len(containerChanges.ContainersToStart) == 0 { + glog.V(4).Infof("No containers to start, stopping at init container %+v in pod %v", next.Name, format.Pod(pod)) + return + } + + // If we need to start the next container, do so now then exit + container := next + startContainerResult := kubecontainer.NewSyncResult(kubecontainer.StartContainer, container.Name) + result.AddSyncResult(startContainerResult) + + // containerChanges.StartInfraContainer causes the containers to be restarted for config reasons + if !containerChanges.StartInfraContainer { + isInBackOff, err, msg := dm.doBackOff(pod, container, podStatus, backOff) + if isInBackOff { + startContainerResult.Fail(err, msg) + glog.V(4).Infof("Backing Off restarting init container %+v in pod %v", container, format.Pod(pod)) + return + } + } + + glog.V(4).Infof("Creating init container %+v in pod %v", container, format.Pod(pod)) + if err, msg := dm.tryContainerStart(container, pod, podStatus, pullSecrets, namespaceMode, pidMode, podIP); err != nil { + startContainerResult.Fail(err, msg) + utilruntime.HandleError(fmt.Errorf("container start failed: %v: %s", err, msg)) + return + } + + // Successfully started the container; clear the entry in the failure + glog.V(4).Infof("Completed init container %q for pod %q", container.Name, format.Pod(pod)) + return + } + if !done { + // init container still running + glog.V(4).Infof("An init container is still running in pod %v", format.Pod(pod)) + return + } + if containerChanges.InitFailed { + // init container still running + glog.V(4).Infof("Not all init containers have succeeded for pod %v", format.Pod(pod)) + return + } + + // Start regular containers for idx := range containerChanges.ContainersToStart { container := &pod.Spec.Containers[idx] startContainerResult := kubecontainer.NewSyncResult(kubecontainer.StartContainer, container.Name) result.AddSyncResult(startContainerResult) // containerChanges.StartInfraContainer causes the containers to be restarted for config reasons - // ignore backoff if !containerChanges.StartInfraContainer { isInBackOff, err, msg := dm.doBackOff(pod, container, podStatus, backOff) if isInBackOff { @@ -1952,46 +2049,131 @@ func (dm *DockerManager) SyncPod(pod *api.Pod, _ api.PodStatus, podStatus *kubec continue } } + glog.V(4).Infof("Creating container %+v in pod %v", container, format.Pod(pod)) - err, msg := dm.imagePuller.PullImage(pod, container, pullSecrets) - if err != nil { + if err, msg := dm.tryContainerStart(container, pod, podStatus, pullSecrets, namespaceMode, pidMode, podIP); err != nil { startContainerResult.Fail(err, msg) + utilruntime.HandleError(fmt.Errorf("container start failed: %v: %s", err, msg)) continue } - - if container.SecurityContext != nil && container.SecurityContext.RunAsNonRoot != nil && *container.SecurityContext.RunAsNonRoot { - err := dm.verifyNonRoot(container) - if err != nil { - startContainerResult.Fail(kubecontainer.ErrVerifyNonRoot, err.Error()) - glog.Errorf("Error running pod %q container %q: %v", format.Pod(pod), container.Name, err) - continue - } - } - // For a new container, the RestartCount should be 0 - restartCount := 0 - containerStatus := podStatus.FindContainerStatusByName(container.Name) - if containerStatus != nil { - restartCount = containerStatus.RestartCount + 1 - } - - // TODO(dawnchen): Check RestartPolicy.DelaySeconds before restart a container - // Note: when configuring the pod's containers anything that can be configured by pointing - // to the namespace of the infra container should use namespaceMode. This includes things like the net namespace - // and IPC namespace. PID mode cannot point to another container right now. - // See createPodInfraContainer for infra container setup. - namespaceMode := fmt.Sprintf("container:%v", podInfraContainerID) - _, err = dm.runContainerInPod(pod, container, namespaceMode, namespaceMode, getPidMode(pod), podIP, restartCount) - if err != nil { - startContainerResult.Fail(kubecontainer.ErrRunContainer, err.Error()) - // TODO(bburns) : Perhaps blacklist a container after N failures? - glog.Errorf("Error running pod %q container %q: %v", format.Pod(pod), container.Name, err) - continue - } - // Successfully started the container; clear the entry in the failure } return } +// tryContainerStart attempts to pull and start the container, returning an error and a reason string if the start +// was not successful. +func (dm *DockerManager) tryContainerStart(container *api.Container, pod *api.Pod, podStatus *kubecontainer.PodStatus, pullSecrets []api.Secret, namespaceMode, pidMode, podIP string) (err error, reason string) { + err, msg := dm.imagePuller.PullImage(pod, container, pullSecrets) + if err != nil { + return err, msg + } + + if container.SecurityContext != nil && container.SecurityContext.RunAsNonRoot != nil && *container.SecurityContext.RunAsNonRoot { + err := dm.verifyNonRoot(container) + if err != nil { + return kubecontainer.ErrVerifyNonRoot, err.Error() + } + } + + // For a new container, the RestartCount should be 0 + restartCount := 0 + containerStatus := podStatus.FindContainerStatusByName(container.Name) + if containerStatus != nil { + restartCount = containerStatus.RestartCount + 1 + } + + // TODO(dawnchen): Check RestartPolicy.DelaySeconds before restart a container + _, err = dm.runContainerInPod(pod, container, namespaceMode, namespaceMode, pidMode, podIP, restartCount) + if err != nil { + // TODO(bburns) : Perhaps blacklist a container after N failures? + return kubecontainer.ErrRunContainer, err.Error() + } + return nil, "" +} + +// pruneInitContainers ensures that before we begin creating init containers, we have reduced the number +// of outstanding init containers still present. This reduces load on the container garbage collector +// by only preserving the most recent terminated init container. +func (dm *DockerManager) pruneInitContainersBeforeStart(pod *api.Pod, podStatus *kubecontainer.PodStatus, initContainersToKeep map[kubecontainer.DockerID]int) { + // only the last execution of an init container should be preserved, and only preserve it if it is in the + // list of init containers to keep. + initContainerNames := sets.NewString() + for _, container := range pod.Spec.InitContainers { + initContainerNames.Insert(container.Name) + } + for name := range initContainerNames { + count := 0 + for _, status := range podStatus.ContainerStatuses { + if !initContainerNames.Has(status.Name) || status.State != kubecontainer.ContainerStateExited { + continue + } + count++ + // keep the first init container we see + if count == 1 { + continue + } + // if there is a reason to preserve the older container, do so + if _, ok := initContainersToKeep[kubecontainer.DockerID(status.ID.ID)]; ok { + continue + } + + // prune all other init containers that match this container name + // TODO: we may not need aggressive pruning + glog.V(4).Infof("Removing init container %q instance %q %d", status.Name, status.ID.ID, count) + if err := dm.client.RemoveContainer(status.ID.ID, dockertypes.ContainerRemoveOptions{RemoveVolumes: true}); err != nil { + if _, ok := err.(containerNotFoundError); ok { + count-- + continue + } + utilruntime.HandleError(fmt.Errorf("failed to remove pod init container %q: %v; Skipping pod %q", name, err, format.Pod(pod))) + // TODO: report serious errors + continue + } + + // remove any references to this container + if _, ok := dm.containerRefManager.GetRef(status.ID); ok { + dm.containerRefManager.ClearRef(status.ID) + } else { + glog.Warningf("No ref for pod '%q'", pod.Name) + } + } + } +} + +// findActiveInitContainer returns the status of the last failed container, the next init container to +// start, or done if there are no further init containers. Status is only returned if an init container +// failed, in which case next will point to the current container. +func findActiveInitContainer(pod *api.Pod, podStatus *kubecontainer.PodStatus) (next *api.Container, status *kubecontainer.ContainerStatus, done bool) { + if len(pod.Spec.InitContainers) == 0 { + return nil, nil, true + } + + for i := len(pod.Spec.InitContainers) - 1; i >= 0; i-- { + container := &pod.Spec.InitContainers[i] + status := podStatus.FindContainerStatusByName(container.Name) + switch { + case status == nil: + continue + case status.State == kubecontainer.ContainerStateRunning: + return nil, nil, false + case status.State == kubecontainer.ContainerStateExited: + switch { + // the container has failed, we'll have to retry + case status.ExitCode != 0: + return &pod.Spec.InitContainers[i], status, false + // all init containers successful + case i == (len(pod.Spec.InitContainers) - 1): + return nil, nil, true + // all containers up to i successful, go to i+1 + default: + return &pod.Spec.InitContainers[i+1], nil, false + } + } + } + + return &pod.Spec.InitContainers[0], nil, false +} + // verifyNonRoot returns an error if the container or image will run as the root user. func (dm *DockerManager) verifyNonRoot(container *api.Container) error { if securitycontext.HasRunAsUser(container) { @@ -2065,6 +2247,7 @@ func (dm *DockerManager) doBackOff(pod *api.Pod, container *api.Container, podSt } } if cStatus != nil { + glog.Infof("checking backoff for container %q in pod %q", container.Name, pod.Name) ts := cStatus.FinishedAt // found a container that requires backoff dockerName := KubeletContainerName{ diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/eviction/helpers.go b/vendor/k8s.io/kubernetes/pkg/kubelet/eviction/helpers.go index 4b689c967b..d5b95ab197 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/eviction/helpers.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/eviction/helpers.go @@ -18,18 +18,41 @@ package eviction import ( "fmt" + "sort" "strings" "time" + "github.com/golang/glog" + "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/resource" + statsapi "k8s.io/kubernetes/pkg/kubelet/api/v1alpha1/stats" + qosutil "k8s.io/kubernetes/pkg/kubelet/qos/util" + "k8s.io/kubernetes/pkg/kubelet/server/stats" + "k8s.io/kubernetes/pkg/quota/evaluator/core" "k8s.io/kubernetes/pkg/util/sets" ) const ( unsupportedEvictionSignal = "unsupported eviction signal %v" + // the reason reported back in status. + reason = "Evicted" + // the message associated with the reason. + message = "The node was low on compute resources." + // disk, in bytes. internal to this module, used to account for local disk usage. + resourceDisk api.ResourceName = "disk" ) +// resourceToRankFunc maps a resource to ranking function for that resource. +var resourceToRankFunc = map[api.ResourceName]rankFunc{ + api.ResourceMemory: rankMemoryPressure, +} + +// signalToNodeCondition maps a signal to the node condition to report if threshold is met. +var signalToNodeCondition = map[Signal]api.NodeConditionType{ + SignalMemoryAvailable: api.NodeMemoryPressure, +} + // signalToResource maps a Signal to its associated Resource. var signalToResource = map[Signal]api.ResourceName{ SignalMemoryAvailable: api.ResourceMemory, @@ -125,7 +148,7 @@ func parseThresholdStatement(statement string) (Threshold, error) { return Threshold{ Signal: signal, Operator: operator, - Value: *quantity, + Value: &quantity, }, nil } @@ -162,3 +185,382 @@ func parseGracePeriods(expr string) (map[Signal]time.Duration, error) { } return results, nil } + +// diskUsage converts used bytes into a resource quantity. +func diskUsage(fsStats *statsapi.FsStats) *resource.Quantity { + if fsStats == nil || fsStats.UsedBytes == nil { + return &resource.Quantity{Format: resource.BinarySI} + } + usage := int64(*fsStats.UsedBytes) + return resource.NewQuantity(usage, resource.BinarySI) +} + +// memoryUsage converts working set into a resource quantity. +func memoryUsage(memStats *statsapi.MemoryStats) *resource.Quantity { + if memStats == nil || memStats.WorkingSetBytes == nil { + return &resource.Quantity{Format: resource.BinarySI} + } + usage := int64(*memStats.WorkingSetBytes) + return resource.NewQuantity(usage, resource.BinarySI) +} + +// podUsage aggregates usage of compute resources. +// it supports the following memory and disk. +func podUsage(podStats statsapi.PodStats) (api.ResourceList, error) { + disk := resource.Quantity{Format: resource.BinarySI} + memory := resource.Quantity{Format: resource.BinarySI} + for _, container := range podStats.Containers { + // disk usage (if known) + // TODO: need to handle volumes + for _, fsStats := range []*statsapi.FsStats{container.Rootfs, container.Logs} { + disk.Add(*diskUsage(fsStats)) + } + // memory usage (if known) + memory.Add(*memoryUsage(container.Memory)) + } + return api.ResourceList{ + api.ResourceMemory: memory, + resourceDisk: disk, + }, nil +} + +// formatThreshold formats a threshold for logging. +func formatThreshold(threshold Threshold) string { + return fmt.Sprintf("threshold(signal=%v, operator=%v, value=%v, gracePeriod=%v)", threshold.Signal, threshold.Value.String(), threshold.Operator, threshold.GracePeriod) +} + +// cachedStatsFunc returns a statsFunc based on the provided pod stats. +func cachedStatsFunc(podStats []statsapi.PodStats) statsFunc { + uid2PodStats := map[string]statsapi.PodStats{} + for i := range podStats { + uid2PodStats[podStats[i].PodRef.UID] = podStats[i] + } + return func(pod *api.Pod) (statsapi.PodStats, bool) { + stats, found := uid2PodStats[string(pod.UID)] + return stats, found + } +} + +// Cmp compares p1 and p2 and returns: +// +// -1 if p1 < p2 +// 0 if p1 == p2 +// +1 if p1 > p2 +// +type cmpFunc func(p1, p2 *api.Pod) int + +// multiSorter implements the Sort interface, sorting changes within. +type multiSorter struct { + pods []*api.Pod + cmp []cmpFunc +} + +// Sort sorts the argument slice according to the less functions passed to OrderedBy. +func (ms *multiSorter) Sort(pods []*api.Pod) { + ms.pods = pods + sort.Sort(ms) +} + +// OrderedBy returns a Sorter that sorts using the cmp functions, in order. +// Call its Sort method to sort the data. +func orderedBy(cmp ...cmpFunc) *multiSorter { + return &multiSorter{ + cmp: cmp, + } +} + +// Len is part of sort.Interface. +func (ms *multiSorter) Len() int { + return len(ms.pods) +} + +// Swap is part of sort.Interface. +func (ms *multiSorter) Swap(i, j int) { + ms.pods[i], ms.pods[j] = ms.pods[j], ms.pods[i] +} + +// Less is part of sort.Interface. +func (ms *multiSorter) Less(i, j int) bool { + p1, p2 := ms.pods[i], ms.pods[j] + var k int + for k = 0; k < len(ms.cmp)-1; k++ { + cmpResult := ms.cmp[k](p1, p2) + // p1 is less than p2 + if cmpResult < 0 { + return true + } + // p1 is greater than p2 + if cmpResult > 0 { + return false + } + // we don't know yet + } + // the last cmp func is the final decider + return ms.cmp[k](p1, p2) < 0 +} + +// qos compares pods by QoS (BestEffort < Burstable < Guaranteed) +func qos(p1, p2 *api.Pod) int { + qosP1 := qosutil.GetPodQos(p1) + qosP2 := qosutil.GetPodQos(p2) + // its a tie + if qosP1 == qosP2 { + return 0 + } + // if p1 is best effort, we know p2 is burstable or guaranteed + if qosP1 == qosutil.BestEffort { + return -1 + } + // we know p1 and p2 are not besteffort, so if p1 is burstable, p2 must be guaranteed + if qosP1 == qosutil.Burstable { + if qosP2 == qosutil.Guaranteed { + return -1 + } + return 1 + } + // ok, p1 must be guaranteed. + return 1 +} + +// memory compares pods by largest consumer of memory relative to request. +func memory(stats statsFunc) cmpFunc { + return func(p1, p2 *api.Pod) int { + p1Stats, found := stats(p1) + // if we have no usage stats for p1, we want p2 first + if !found { + return -1 + } + // if we have no usage stats for p2, but p1 has usage, we want p1 first. + p2Stats, found := stats(p2) + if !found { + return 1 + } + // if we cant get usage for p1 measured, we want p2 first + p1Usage, err := podUsage(p1Stats) + if err != nil { + return -1 + } + // if we cant get usage for p2 measured, we want p1 first + p2Usage, err := podUsage(p2Stats) + if err != nil { + return 1 + } + + // adjust p1, p2 usage relative to the request (if any) + p1Memory := p1Usage[api.ResourceMemory] + p1Spec := core.PodUsageFunc(p1) + p1Request := p1Spec[api.ResourceRequestsMemory] + p1Memory.Sub(p1Request) + + p2Memory := p2Usage[api.ResourceMemory] + p2Spec := core.PodUsageFunc(p2) + p2Request := p2Spec[api.ResourceRequestsMemory] + p2Memory.Sub(p2Request) + + // if p2 is using more than p1, we want p2 first + return p2Memory.Cmp(p1Memory) + } +} + +// disk compares pods by largest consumer of disk relative to request. +func disk(stats statsFunc) cmpFunc { + return func(p1, p2 *api.Pod) int { + p1Stats, found := stats(p1) + // if we have no usage stats for p1, we want p2 first + if !found { + return -1 + } + // if we have no usage stats for p2, but p1 has usage, we want p1 first. + p2Stats, found := stats(p2) + if !found { + return 1 + } + // if we cant get usage for p1 measured, we want p2 first + p1Usage, err := podUsage(p1Stats) + if err != nil { + return -1 + } + // if we cant get usage for p2 measured, we want p1 first + p2Usage, err := podUsage(p2Stats) + if err != nil { + return 1 + } + + // disk is best effort, so we don't measure relative to a request. + // TODO: add disk as a guaranteed resource + p1Disk := p1Usage[api.ResourceStorage] + p2Disk := p2Usage[api.ResourceStorage] + // if p2 is using more than p1, we want p2 first + return p2Disk.Cmp(p1Disk) + } +} + +// rankMemoryPressure orders the input pods for eviction in response to memory pressure. +func rankMemoryPressure(pods []*api.Pod, stats statsFunc) { + orderedBy(qos, memory(stats)).Sort(pods) +} + +// rankDiskPressure orders the input pods for eviction in response to disk pressure. +func rankDiskPressure(pods []*api.Pod, stats statsFunc) { + orderedBy(qos, disk(stats)).Sort(pods) +} + +// byEvictionPriority implements sort.Interface for []api.ResourceName. +type byEvictionPriority []api.ResourceName + +func (a byEvictionPriority) Len() int { return len(a) } +func (a byEvictionPriority) Swap(i, j int) { a[i], a[j] = a[j], a[i] } + +// Less ranks memory before all other resources. +func (a byEvictionPriority) Less(i, j int) bool { + return a[i] == api.ResourceMemory +} + +// makeSignalObservations derives observations using the specified summary provider. +func makeSignalObservations(summaryProvider stats.SummaryProvider) (signalObservations, statsFunc, error) { + summary, err := summaryProvider.Get() + if err != nil { + return nil, nil, err + } + // build the function to work against for pod stats + statsFunc := cachedStatsFunc(summary.Pods) + // build an evaluation context for current eviction signals + result := signalObservations{} + result[SignalMemoryAvailable] = resource.NewQuantity(int64(*summary.Node.Memory.AvailableBytes), resource.BinarySI) + return result, statsFunc, nil +} + +// thresholdsMet returns the set of thresholds that were met independent of grace period +func thresholdsMet(thresholds []Threshold, observations signalObservations) []Threshold { + results := []Threshold{} + for i := range thresholds { + threshold := thresholds[i] + observed, found := observations[threshold.Signal] + if !found { + glog.Warningf("eviction manager: no observation found for eviction signal %v", threshold.Signal) + continue + } + // determine if we have met the specified threshold + thresholdMet := false + thresholdResult := threshold.Value.Cmp(*observed) + switch threshold.Operator { + case OpLessThan: + thresholdMet = thresholdResult > 0 + } + if thresholdMet { + results = append(results, threshold) + } + } + return results +} + +// thresholdsFirstObservedAt merges the input set of thresholds with the previous observation to determine when active set of thresholds were initially met. +func thresholdsFirstObservedAt(thresholds []Threshold, lastObservedAt thresholdsObservedAt, now time.Time) thresholdsObservedAt { + results := thresholdsObservedAt{} + for i := range thresholds { + observedAt, found := lastObservedAt[thresholds[i]] + if !found { + observedAt = now + } + results[thresholds[i]] = observedAt + } + return results +} + +// thresholdsMetGracePeriod returns the set of thresholds that have satisfied associated grace period +func thresholdsMetGracePeriod(observedAt thresholdsObservedAt, now time.Time) []Threshold { + results := []Threshold{} + for threshold, at := range observedAt { + duration := now.Sub(at) + if duration < threshold.GracePeriod { + glog.V(2).Infof("eviction manager: eviction criteria not yet met for %v, duration: %v", formatThreshold(threshold), duration) + continue + } + results = append(results, threshold) + } + return results +} + +// nodeConditions returns the set of node conditions associated with a threshold +func nodeConditions(thresholds []Threshold) []api.NodeConditionType { + results := []api.NodeConditionType{} + for _, threshold := range thresholds { + if nodeCondition, found := signalToNodeCondition[threshold.Signal]; found { + results = append(results, nodeCondition) + } + } + return results +} + +// nodeConditionsLastObservedAt merges the input with the previous observation to determine when a condition was most recently met. +func nodeConditionsLastObservedAt(nodeConditions []api.NodeConditionType, lastObservedAt nodeConditionsObservedAt, now time.Time) nodeConditionsObservedAt { + results := nodeConditionsObservedAt{} + // the input conditions were observed "now" + for i := range nodeConditions { + results[nodeConditions[i]] = now + } + // the conditions that were not observed now are merged in with their old time + for key, value := range lastObservedAt { + _, found := results[key] + if !found { + results[key] = value + } + } + return results +} + +// nodeConditionsObservedSince returns the set of conditions that have been observed within the specified period +func nodeConditionsObservedSince(observedAt nodeConditionsObservedAt, period time.Duration, now time.Time) []api.NodeConditionType { + results := []api.NodeConditionType{} + for nodeCondition, at := range observedAt { + duration := now.Sub(at) + if duration < period { + results = append(results, nodeCondition) + } + } + return results +} + +// hasNodeCondition returns true if the node condition is in the input list +func hasNodeCondition(inputs []api.NodeConditionType, item api.NodeConditionType) bool { + for _, input := range inputs { + if input == item { + return true + } + } + return false +} + +// hasThreshold returns true if the node condition is in the input list +func hasThreshold(inputs []Threshold, item Threshold) bool { + for _, input := range inputs { + if input.GracePeriod == item.GracePeriod && input.Operator == item.Operator && input.Signal == item.Signal && input.Value.Cmp(*item.Value) == 0 { + return true + } + } + return false +} + +// reclaimResources returns the set of resources that are starved based on thresholds met. +func reclaimResources(thresholds []Threshold) []api.ResourceName { + results := []api.ResourceName{} + for _, threshold := range thresholds { + if starvedResource, found := signalToResource[threshold.Signal]; found { + results = append(results, starvedResource) + } + } + return results +} + +// isSoftEviction returns true if the thresholds met for the starved resource are only soft thresholds +func isSoftEviction(thresholds []Threshold, starvedResource api.ResourceName) bool { + for _, threshold := range thresholds { + if resourceToCheck := signalToResource[threshold.Signal]; resourceToCheck != starvedResource { + continue + } + if threshold.GracePeriod == time.Duration(0) { + return false + } + } + return true +} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/eviction/manager.go b/vendor/k8s.io/kubernetes/pkg/kubelet/eviction/manager.go new file mode 100644 index 0000000000..a672ebb9b8 --- /dev/null +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/eviction/manager.go @@ -0,0 +1,220 @@ +/* +Copyright 2016 The Kubernetes Authors All rights reserved. + +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 eviction + +import ( + "sort" + "sync" + "time" + + "github.com/golang/glog" + "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/client/record" + "k8s.io/kubernetes/pkg/kubelet/lifecycle" + qosutil "k8s.io/kubernetes/pkg/kubelet/qos/util" + "k8s.io/kubernetes/pkg/kubelet/server/stats" + "k8s.io/kubernetes/pkg/kubelet/util/format" + "k8s.io/kubernetes/pkg/util" + "k8s.io/kubernetes/pkg/util/wait" +) + +// managerImpl implements NodeStabilityManager +type managerImpl struct { + // used to track time + clock util.Clock + // config is how the manager is configured + config Config + // the function to invoke to kill a pod + killPodFunc KillPodFunc + // protects access to internal state + sync.RWMutex + // node conditions are the set of conditions present + nodeConditions []api.NodeConditionType + // captures when a node condition was last observed based on a threshold being met + nodeConditionsLastObservedAt nodeConditionsObservedAt + // nodeRef is a reference to the node + nodeRef *api.ObjectReference + // used to record events about the node + recorder record.EventRecorder + // used to measure usage stats on system + summaryProvider stats.SummaryProvider + // records when a threshold was first observed + thresholdsFirstObservedAt thresholdsObservedAt +} + +// ensure it implements the required interface +var _ Manager = &managerImpl{} + +// NewManager returns a configured Manager and an associated admission handler to enforce eviction configuration. +func NewManager( + summaryProvider stats.SummaryProvider, + config Config, + killPodFunc KillPodFunc, + recorder record.EventRecorder, + nodeRef *api.ObjectReference, + clock util.Clock) (Manager, lifecycle.PodAdmitHandler, error) { + manager := &managerImpl{ + clock: clock, + killPodFunc: killPodFunc, + config: config, + recorder: recorder, + summaryProvider: summaryProvider, + nodeRef: nodeRef, + nodeConditionsLastObservedAt: nodeConditionsObservedAt{}, + thresholdsFirstObservedAt: thresholdsObservedAt{}, + } + return manager, manager, nil +} + +// Admit rejects a pod if its not safe to admit for node stability. +func (m *managerImpl) Admit(attrs *lifecycle.PodAdmitAttributes) lifecycle.PodAdmitResult { + m.RLock() + defer m.RUnlock() + if len(m.nodeConditions) == 0 { + return lifecycle.PodAdmitResult{Admit: true} + } + notBestEffort := qosutil.BestEffort != qosutil.GetPodQos(attrs.Pod) + if notBestEffort { + return lifecycle.PodAdmitResult{Admit: true} + } + glog.Warningf("Failed to admit pod %v - %s", format.Pod(attrs.Pod), "node has conditions: %v", m.nodeConditions) + // we reject all best effort pods until we are stable. + return lifecycle.PodAdmitResult{ + Admit: false, + Reason: reason, + Message: message, + } +} + +// Start starts the control loop to observe and response to low compute resources. +func (m *managerImpl) Start(podFunc ActivePodsFunc, monitoringInterval time.Duration) { + go wait.Until(func() { m.synchronize(podFunc) }, monitoringInterval, wait.NeverStop) +} + +// IsUnderMemoryPressure returns true if the node is under memory pressure. +func (m *managerImpl) IsUnderMemoryPressure() bool { + m.RLock() + defer m.RUnlock() + return hasNodeCondition(m.nodeConditions, api.NodeMemoryPressure) +} + +// synchronize is the main control loop that enforces eviction thresholds. +func (m *managerImpl) synchronize(podFunc ActivePodsFunc) { + // if we have nothing to do, just return + thresholds := m.config.Thresholds + if len(thresholds) == 0 { + return + } + + // make observations and get a function to derive pod usage stats relative to those observations. + observations, statsFunc, err := makeSignalObservations(m.summaryProvider) + if err != nil { + glog.Errorf("eviction manager: unexpected err: %v", err) + return + } + + // find the list of thresholds that are met independent of grace period + now := m.clock.Now() + + // determine the set of thresholds met independent of grace period + thresholds = thresholdsMet(thresholds, observations) + + // track when a threshold was first observed + thresholdsFirstObservedAt := thresholdsFirstObservedAt(thresholds, m.thresholdsFirstObservedAt, now) + + // the set of node conditions that are triggered by currently observed thresholds + nodeConditions := nodeConditions(thresholds) + + // track when a node condition was last observed + nodeConditionsLastObservedAt := nodeConditionsLastObservedAt(nodeConditions, m.nodeConditionsLastObservedAt, now) + + // node conditions report true if it has been observed within the transition period window + nodeConditions = nodeConditionsObservedSince(nodeConditionsLastObservedAt, m.config.PressureTransitionPeriod, now) + + // determine the set of thresholds we need to drive eviction behavior (i.e. all grace periods are met) + thresholds = thresholdsMetGracePeriod(thresholdsFirstObservedAt, now) + + // update internal state + m.Lock() + m.nodeConditions = nodeConditions + m.thresholdsFirstObservedAt = thresholdsFirstObservedAt + m.nodeConditionsLastObservedAt = nodeConditionsLastObservedAt + m.Unlock() + + // determine the set of resources under starvation + starvedResources := reclaimResources(thresholds) + if len(starvedResources) == 0 { + glog.V(3).Infof("eviction manager: no resources are starved") + return + } + + // rank the resources to reclaim by eviction priority + sort.Sort(byEvictionPriority(starvedResources)) + resourceToReclaim := starvedResources[0] + glog.Warningf("eviction manager: attempting to reclaim %v", resourceToReclaim) + + // determine if this is a soft or hard eviction associated with the resource + softEviction := isSoftEviction(thresholds, resourceToReclaim) + + // record an event about the resources we are now attempting to reclaim via eviction + m.recorder.Eventf(m.nodeRef, api.EventTypeWarning, "EvictionThresholdMet", "Attempting to reclaim %s", resourceToReclaim) + + // rank the pods for eviction + rank, ok := resourceToRankFunc[resourceToReclaim] + if !ok { + glog.Errorf("eviction manager: no ranking function for resource %s", resourceToReclaim) + return + } + + // the only candidates viable for eviction are those pods that had anything running. + activePods := podFunc() + if len(activePods) == 0 { + glog.Errorf("eviction manager: eviction thresholds have been met, but no pods are active to evict") + return + } + + // rank the running pods for eviction for the specified resource + rank(activePods, statsFunc) + + glog.Infof("eviction manager: pods ranked for eviction: %s", format.Pods(activePods)) + + // we kill at most a single pod during each eviction interval + for i := range activePods { + pod := activePods[i] + status := api.PodStatus{ + Phase: api.PodFailed, + Message: message, + Reason: reason, + } + // record that we are evicting the pod + m.recorder.Eventf(pod, api.EventTypeWarning, reason, message) + gracePeriodOverride := int64(0) + if softEviction { + gracePeriodOverride = m.config.MaxPodGracePeriodSeconds + } + // this is a blocking call and should only return when the pod and its containers are killed. + err := m.killPodFunc(pod, status, &gracePeriodOverride) + if err != nil { + glog.Infof("eviction manager: pod %s failed to evict %v", format.Pod(pod), err) + continue + } + // success, so we return until the next housekeeping interval + glog.Infof("eviction manager: pod %s evicted successfully", format.Pod(pod)) + return + } + glog.Infof("eviction manager: unable to evict any pods from the node") +} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/eviction/types.go b/vendor/k8s.io/kubernetes/pkg/kubelet/eviction/types.go index 9794cbf54a..3b4470d7c7 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/eviction/types.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/eviction/types.go @@ -21,6 +21,7 @@ import ( "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/resource" + statsapi "k8s.io/kubernetes/pkg/kubelet/api/v1alpha1/stats" ) // Signal defines a signal that can trigger eviction of pods on a node. @@ -43,6 +44,8 @@ const ( type Config struct { // PressureTransitionPeriod is duration the kubelet has to wait before transititioning out of a pressure condition. PressureTransitionPeriod time.Duration + // Maximum allowed grace period (in seconds) to use when terminating pods in response to a soft eviction threshold being met. + MaxPodGracePeriodSeconds int64 // Thresholds define the set of conditions monitored to trigger eviction. Thresholds []Threshold } @@ -54,11 +57,20 @@ type Threshold struct { // Operator represents a relationship of a signal to a value. Operator ThresholdOperator // value is a quantity associated with the signal that is evaluated against the specified operator. - Value resource.Quantity + Value *resource.Quantity // GracePeriod represents the amount of time that a threshold must be met before eviction is triggered. GracePeriod time.Duration } +// Manager evaluates when an eviction threshold for node stability has been met on the node. +type Manager interface { + // Start starts the control loop to monitor eviction thresholds at specified interval. + Start(podFunc ActivePodsFunc, monitoringInterval time.Duration) + + // IsUnderMemoryPressure returns true if the node is under memory pressure. + IsUnderMemoryPressure() bool +} + // KillPodFunc kills a pod. // The pod status is updated, and then it is killed with the specified grace period. // This function must block until either the pod is killed or an error is encountered. @@ -67,3 +79,21 @@ type Threshold struct { // status - the desired status to associate with the pod (i.e. why its killed) // gracePeriodOverride - the grace period override to use instead of what is on the pod spec type KillPodFunc func(pod *api.Pod, status api.PodStatus, gracePeriodOverride *int64) error + +// ActivePodsFunc returns pods bound to the kubelet that are active (i.e. non-terminal state) +type ActivePodsFunc func() []*api.Pod + +// statsFunc returns the usage stats if known for an input pod. +type statsFunc func(pod *api.Pod) (statsapi.PodStats, bool) + +// rankFunc sorts the pods in eviction order +type rankFunc func(pods []*api.Pod, stats statsFunc) + +// signalObservations maps a signal to an observed quantity +type signalObservations map[Signal]*resource.Quantity + +// thresholdsObservedAt maps a threshold to a time that it was observed +type thresholdsObservedAt map[Threshold]time.Time + +// nodeConditionsObservedAt maps a node condition to a time that it was observed +type nodeConditionsObservedAt map[api.NodeConditionType]time.Time diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/image_manager.go b/vendor/k8s.io/kubernetes/pkg/kubelet/image_manager.go index 892dcfe279..6f521647d6 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/image_manager.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/image_manager.go @@ -209,7 +209,7 @@ func (im *realImageManager) detectImages(detectTime time.Time) error { func (im *realImageManager) GarbageCollect() error { // Get disk usage on disk holding images. - fsInfo, err := im.cadvisor.DockerImagesFsInfo() + fsInfo, err := im.cadvisor.ImagesFsInfo() if err != nil { return err } diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/kubelet.go b/vendor/k8s.io/kubernetes/pkg/kubelet/kubelet.go index 2ce1518811..d09ace61b6 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/kubelet.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/kubelet.go @@ -26,6 +26,7 @@ import ( "os" "path" "path/filepath" + goRuntime "runtime" "sort" "strings" "sync" @@ -67,6 +68,7 @@ import ( "k8s.io/kubernetes/pkg/kubelet/status" kubetypes "k8s.io/kubernetes/pkg/kubelet/types" "k8s.io/kubernetes/pkg/kubelet/util/format" + "k8s.io/kubernetes/pkg/kubelet/util/ioutils" "k8s.io/kubernetes/pkg/kubelet/util/queue" "k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/securitycontext" @@ -116,6 +118,10 @@ const ( // Period for performing global cleanup tasks. housekeepingPeriod = time.Second * 2 + // Period for performing eviction monitoring. + // TODO ensure this is in sync with internal cadvisor housekeeping. + evictionMonitoringPeriod = time.Second * 10 + // The path in containers' filesystems where the hosts file is mounted. etcHostsPath = "/etc/hosts" @@ -145,6 +151,9 @@ const ( // Maximum period to wait for pod volume setup operations maxWaitForVolumeOps = 20 * time.Minute + + // maxImagesInStatus is the number of max images we store in image status. + maxImagesInNodeStatus = 50 ) // SyncHandler is an interface implemented by Kubelet, for testability @@ -429,9 +438,12 @@ func NewMainKubelet( klet, recorder, containerRefManager, + klet.podManager, klet.livenessManager, klet.volumeManager, klet.httpClient, + klet.networkPlugin, + klet.hairpinMode == componentconfig.HairpinVeth, utilexec.New(), kubecontainer.RealOS{}, imageBackOff, @@ -493,6 +505,14 @@ func NewMainKubelet( klet.podKillingCh = make(chan *kubecontainer.PodPair, podKillingChannelCapacity) klet.setNodeStatusFuncs = klet.defaultNodeStatusFuncs() + // setup eviction manager + evictionManager, evictionAdmitHandler, err := eviction.NewManager(klet.resourceAnalyzer, evictionConfig, killPodNow(klet.podWorkers), recorder, nodeRef, klet.clock) + if err != nil { + return nil, fmt.Errorf("failed to initialize eviction manager: %v", err) + } + klet.evictionManager = evictionManager + klet.AddPodAdmitHandler(evictionAdmitHandler) + // apply functional Option's for _, opt := range kubeOptions { opt(klet) @@ -565,6 +585,9 @@ type Kubelet struct { // this Kubelet services. podManager kubepod.Manager + // Needed to observe and respond to situations that could impact node stability + evictionManager eviction.Manager + // Needed to report events for containers belonging to deleted/modified pods. // Tracks references for reporting events containerRefManager *kubecontainer.RefManager @@ -958,19 +981,31 @@ func (kl *Kubelet) Run(updates <-chan kubetypes.PodUpdate) { // Start component sync loops. kl.statusManager.Start() kl.probeManager.Start() + kl.evictionManager.Start(kl.getActivePods, evictionMonitoringPeriod) // Start the pod lifecycle event generator. kl.pleg.Start() kl.syncLoop(updates, kl) } +// getActivePods returns non-terminal pods +func (kl *Kubelet) getActivePods() []*api.Pod { + allPods := kl.podManager.GetPods() + activePods := kl.filterOutTerminatedPods(allPods) + return activePods +} + // initialNodeStatus determines the initial node status, incorporating node // labels and information from the cloud provider. func (kl *Kubelet) initialNodeStatus() (*api.Node, error) { node := &api.Node{ ObjectMeta: api.ObjectMeta{ - Name: kl.nodeName, - Labels: map[string]string{unversioned.LabelHostname: kl.hostname}, + Name: kl.nodeName, + Labels: map[string]string{ + unversioned.LabelHostname: kl.hostname, + unversioned.LabelOS: goRuntime.GOOS, + unversioned.LabelArch: goRuntime.GOARCH, + }, }, Spec: api.NodeSpec{ Unschedulable: !kl.registerSchedulable, @@ -1282,14 +1317,13 @@ func (kl *Kubelet) GeneratePodHostNameAndDomain(pod *api.Pod) (string, string, e } hostname := pod.Name if len(pod.Spec.Hostname) > 0 { - if utilvalidation.IsDNS1123Label(pod.Spec.Hostname) { - hostname = pod.Spec.Hostname - } else { - return "", "", fmt.Errorf("Pod Hostname %q is not a valid DNS label.", pod.Spec.Hostname) + if msgs := utilvalidation.IsDNS1123Label(pod.Spec.Hostname); len(msgs) != 0 { + return "", "", fmt.Errorf("Pod Hostname %q is not a valid DNS label: %s", pod.Spec.Hostname, strings.Join(msgs, ";")) } + hostname = pod.Spec.Hostname } else { hostnameCandidate := podAnnotations[utilpod.PodHostnameAnnotation] - if utilvalidation.IsDNS1123Label(hostnameCandidate) { + if len(utilvalidation.IsDNS1123Label(hostnameCandidate)) == 0 { // use hostname annotation, if specified. hostname = hostnameCandidate } @@ -1301,14 +1335,13 @@ func (kl *Kubelet) GeneratePodHostNameAndDomain(pod *api.Pod) (string, string, e hostDomain := "" if len(pod.Spec.Subdomain) > 0 { - if utilvalidation.IsDNS1123Label(pod.Spec.Subdomain) { - hostDomain = fmt.Sprintf("%s.%s.svc.%s", pod.Spec.Subdomain, pod.Namespace, clusterDomain) - } else { - return "", "", fmt.Errorf("Pod Subdomain %q is not a valid DNS label.", pod.Spec.Subdomain) + if msgs := utilvalidation.IsDNS1123Label(pod.Spec.Subdomain); len(msgs) != 0 { + return "", "", fmt.Errorf("Pod Subdomain %q is not a valid DNS label: %s", pod.Spec.Subdomain, strings.Join(msgs, ";")) } + hostDomain = fmt.Sprintf("%s.%s.svc.%s", pod.Spec.Subdomain, pod.Namespace, clusterDomain) } else { subdomainCandidate := pod.Annotations[utilpod.PodSubdomainAnnotation] - if utilvalidation.IsDNS1123Label(subdomainCandidate) { + if len(utilvalidation.IsDNS1123Label(subdomainCandidate)) == 0 { hostDomain = fmt.Sprintf("%s.%s.svc.%s", subdomainCandidate, pod.Namespace, clusterDomain) } } @@ -1743,6 +1776,10 @@ func (kl *Kubelet) syncPod(o syncPodOptions) error { // Generate final API pod status with pod and status manager status apiPodStatus := kl.generateAPIPodStatus(pod, podStatus) + // The pod IP may be changed in generateAPIPodStatus if the pod is using host network. (See #24576) + // TODO(random-liu): After writing pod spec into container labels, check whether pod is using host network, and + // set pod IP to hostIP directly in runtime.GetPodStatus + podStatus.IP = apiPodStatus.PodIP // Record the time it takes for the pod to become running. existingStatus, ok := kl.statusManager.GetPodStatus(pod.UID) @@ -1750,18 +1787,18 @@ func (kl *Kubelet) syncPod(o syncPodOptions) error { !firstSeenTime.IsZero() { metrics.PodStartLatency.Observe(metrics.SinceInMicroseconds(firstSeenTime)) } + // Update status in the status manager kl.statusManager.SetPodStatus(pod, apiPodStatus) // Kill pod if it should not be running - if err := canRunPod(pod); err != nil || pod.DeletionTimestamp != nil || apiPodStatus.Phase == api.PodFailed { - if err := kl.killPod(pod, nil, podStatus, nil); err != nil { - // there was an error killing the pod, so we return that error directly - utilruntime.HandleError(err) - return err + if errOuter := canRunPod(pod); errOuter != nil || pod.DeletionTimestamp != nil || apiPodStatus.Phase == api.PodFailed { + if errInner := kl.killPod(pod, nil, podStatus, nil); errInner != nil { + errOuter = fmt.Errorf("error killing pod: %v", errInner) + utilruntime.HandleError(errOuter) } // there was no error killing the pod, but the pod cannot be run, so we return that err (if any) - return err + return errOuter } // Create Mirror Pod for Static Pod if it doesn't already exist @@ -2336,6 +2373,10 @@ func hasHostPortConflicts(pods []*api.Pod) bool { glog.Errorf("Pod %q: HostPort is already allocated, ignoring: %v", format.Pod(pod), errs) return true } + if errs := validation.AccumulateUniqueHostPorts(pod.Spec.InitContainers, &ports, field.NewPath("spec", "initContainers")); len(errs) > 0 { + glog.Errorf("Pod %q: HostPort is already allocated, ignoring: %v", format.Pod(pod), errs) + return true + } } return false } @@ -2345,7 +2386,7 @@ func (kl *Kubelet) isOutOfDisk() bool { outOfDockerDisk := false outOfRootDisk := false // Check disk space once globally and reject or accept all new pods. - withinBounds, err := kl.diskSpaceManager.IsDockerDiskSpaceAvailable() + withinBounds, err := kl.diskSpaceManager.IsRuntimeDiskSpaceAvailable() // Assume enough space in case of errors. if err == nil && !withinBounds { outOfDockerDisk = true @@ -3014,7 +3055,7 @@ func (kl *Kubelet) setNodeStatusMachineInfo(node *api.Node) { if kl.reservation.Kubernetes != nil { value.Sub(kl.reservation.Kubernetes[k]) } - if value.Amount != nil && value.Amount.Sign() < 0 { + if value.Sign() < 0 { // Negative Allocatable resources don't make sense. value.Set(0) } @@ -3049,7 +3090,7 @@ func (kl *Kubelet) setNodeStatusDaemonEndpoints(node *api.Node) { node.Status.DaemonEndpoints = *kl.daemonEndpoints } -// Set images list fot this node +// Set images list for the node func (kl *Kubelet) setNodeStatusImages(node *api.Node) { // Update image list of this node var imagesOnNode []api.ContainerImage @@ -3057,6 +3098,12 @@ func (kl *Kubelet) setNodeStatusImages(node *api.Node) { if err != nil { glog.Errorf("Error getting image list: %v", err) } else { + // sort the images from max to min, and only set top N images into the node status. + sort.Sort(byImageSize(containerImages)) + if maxImagesInNodeStatus < len(containerImages) { + containerImages = containerImages[0:maxImagesInNodeStatus] + } + for _, image := range containerImages { imagesOnNode = append(imagesOnNode, api.ContainerImage{ Names: append(image.RepoTags, image.RepoDigests...), @@ -3067,12 +3114,28 @@ func (kl *Kubelet) setNodeStatusImages(node *api.Node) { node.Status.Images = imagesOnNode } +// Set the GOOS and GOARCH for this node +func (kl *Kubelet) setNodeStatusGoRuntime(node *api.Node) { + node.Status.NodeInfo.OperatingSystem = goRuntime.GOOS + node.Status.NodeInfo.Architecture = goRuntime.GOARCH +} + +type byImageSize []kubecontainer.Image + +// Sort from max to min +func (a byImageSize) Less(i, j int) bool { + return a[i].Size > a[j].Size +} +func (a byImageSize) Len() int { return len(a) } +func (a byImageSize) Swap(i, j int) { a[i], a[j] = a[j], a[i] } + // Set status for the node. func (kl *Kubelet) setNodeStatusInfo(node *api.Node) { kl.setNodeStatusMachineInfo(node) kl.setNodeStatusVersionInfo(node) kl.setNodeStatusDaemonEndpoints(node) kl.setNodeStatusImages(node) + kl.setNodeStatusGoRuntime(node) } // Set Readycondition for the node. @@ -3134,6 +3197,64 @@ func (kl *Kubelet) setNodeReadyCondition(node *api.Node) { } } +// setNodeMemoryPressureCondition for the node. +// TODO: this needs to move somewhere centralized... +func (kl *Kubelet) setNodeMemoryPressureCondition(node *api.Node) { + currentTime := unversioned.NewTime(kl.clock.Now()) + var condition *api.NodeCondition + + // Check if NodeMemoryPressure condition already exists and if it does, just pick it up for update. + for i := range node.Status.Conditions { + if node.Status.Conditions[i].Type == api.NodeMemoryPressure { + condition = &node.Status.Conditions[i] + } + } + + newCondition := false + // If the NodeMemoryPressure condition doesn't exist, create one + if condition == nil { + condition = &api.NodeCondition{ + Type: api.NodeMemoryPressure, + Status: api.ConditionUnknown, + } + // cannot be appended to node.Status.Conditions here because it gets + // copied to the slice. So if we append to the slice here none of the + // updates we make below are reflected in the slice. + newCondition = true + } + + // Update the heartbeat time + condition.LastHeartbeatTime = currentTime + + // Note: The conditions below take care of the case when a new NodeMemoryPressure condition is + // created and as well as the case when the condition already exists. When a new condition + // is created its status is set to api.ConditionUnknown which matches either + // condition.Status != api.ConditionTrue or + // condition.Status != api.ConditionFalse in the conditions below depending on whether + // the kubelet is under memory pressure or not. + if kl.evictionManager.IsUnderMemoryPressure() { + if condition.Status != api.ConditionTrue { + condition.Status = api.ConditionTrue + condition.Reason = "KubeletHasInsufficientMemory" + condition.Message = "kubelet has insufficient memory available" + condition.LastTransitionTime = currentTime + kl.recordNodeStatusEvent(api.EventTypeNormal, "NodeHasInsufficientMemory") + } + } else { + if condition.Status != api.ConditionFalse { + condition.Status = api.ConditionFalse + condition.Reason = "KubeletHasSufficientMemory" + condition.Message = "kubelet has sufficient memory available" + condition.LastTransitionTime = currentTime + kl.recordNodeStatusEvent(api.EventTypeNormal, "NodeHasSufficientMemory") + } + } + + if newCondition { + node.Status.Conditions = append(node.Status.Conditions, *condition) + } +} + // Set OODcondition for the node. func (kl *Kubelet) setNodeOODCondition(node *api.Node) { currentTime := unversioned.NewTime(kl.clock.Now()) @@ -3239,6 +3360,7 @@ func (kl *Kubelet) defaultNodeStatusFuncs() []func(*api.Node) error { kl.setNodeAddress, withoutError(kl.setNodeStatusInfo), withoutError(kl.setNodeOODCondition), + withoutError(kl.setNodeMemoryPressureCondition), withoutError(kl.setNodeReadyCondition), withoutError(kl.recordNodeSchedulableEvent), } @@ -3292,12 +3414,46 @@ func (kl *Kubelet) tryUpdateNodeStatus() error { // This func is exported to simplify integration with 3rd party kubelet // integrations like kubernetes-mesos. func GetPhase(spec *api.PodSpec, info []api.ContainerStatus) api.PodPhase { + initialized := 0 + pendingInitialization := 0 + failedInitialization := 0 + for _, container := range spec.InitContainers { + containerStatus, ok := api.GetContainerStatus(info, container.Name) + if !ok { + pendingInitialization++ + continue + } + + switch { + case containerStatus.State.Running != nil: + pendingInitialization++ + case containerStatus.State.Terminated != nil: + if containerStatus.State.Terminated.ExitCode == 0 { + initialized++ + } else { + failedInitialization++ + } + case containerStatus.State.Waiting != nil: + if containerStatus.LastTerminationState.Terminated != nil { + if containerStatus.LastTerminationState.Terminated.ExitCode == 0 { + initialized++ + } else { + failedInitialization++ + } + } else { + pendingInitialization++ + } + default: + pendingInitialization++ + } + } + + unknown := 0 running := 0 waiting := 0 stopped := 0 failed := 0 succeeded := 0 - unknown := 0 for _, container := range spec.Containers { containerStatus, ok := api.GetContainerStatus(info, container.Name) if !ok { @@ -3326,7 +3482,13 @@ func GetPhase(spec *api.PodSpec, info []api.ContainerStatus) api.PodPhase { } } + if failedInitialization > 0 && spec.RestartPolicy == api.RestartPolicyNever { + return api.PodFailed + } + switch { + case pendingInitialization > 0: + fallthrough case waiting > 0: glog.V(5).Infof("pod waiting > 0, pending") // One or more containers has not been started @@ -3391,8 +3553,10 @@ func (kl *Kubelet) generateAPIPodStatus(pod *api.Pod, podStatus *kubecontainer.P // Assume info is ready to process spec := &pod.Spec - s.Phase = GetPhase(spec, s.ContainerStatuses) + allStatus := append(append([]api.ContainerStatus{}, s.ContainerStatuses...), s.InitContainerStatuses...) + s.Phase = GetPhase(spec, allStatus) kl.probeManager.UpdatePodStatus(pod.UID, s) + s.Conditions = append(s.Conditions, status.GeneratePodInitializedCondition(spec, s.InitContainerStatuses, s.Phase)) s.Conditions = append(s.Conditions, status.GeneratePodReadyCondition(spec, s.ContainerStatuses, s.Phase)) // s (the PodStatus we are creating) will not have a PodScheduled condition yet, because converStatusToAPIStatus() // does not create one. If the existing PodStatus has a PodScheduled condition, then copy it into s and make sure @@ -3425,9 +3589,27 @@ func (kl *Kubelet) generateAPIPodStatus(pod *api.Pod, podStatus *kubecontainer.P // alter the kubelet state at all. func (kl *Kubelet) convertStatusToAPIStatus(pod *api.Pod, podStatus *kubecontainer.PodStatus) *api.PodStatus { var apiPodStatus api.PodStatus - uid := pod.UID apiPodStatus.PodIP = podStatus.IP + apiPodStatus.ContainerStatuses = kl.convertToAPIContainerStatuses( + pod, podStatus, + pod.Status.ContainerStatuses, + pod.Spec.Containers, + len(pod.Spec.InitContainers) > 0, + false, + ) + apiPodStatus.InitContainerStatuses = kl.convertToAPIContainerStatuses( + pod, podStatus, + pod.Status.InitContainerStatuses, + pod.Spec.InitContainers, + len(pod.Spec.InitContainers) > 0, + true, + ) + + return &apiPodStatus +} + +func (kl *Kubelet) convertToAPIContainerStatuses(pod *api.Pod, podStatus *kubecontainer.PodStatus, previousStatus []api.ContainerStatus, containers []api.Container, hasInitContainers, isInitContainer bool) []api.ContainerStatus { convertContainerStatus := func(cs *kubecontainer.ContainerStatus) *api.ContainerStatus { cid := cs.ID.String() status := &api.ContainerStatus{ @@ -3456,15 +3638,19 @@ func (kl *Kubelet) convertStatusToAPIStatus(pod *api.Pod, podStatus *kubecontain } // Fetch old containers statuses from old pod status. - oldStatuses := make(map[string]api.ContainerStatus, len(pod.Spec.Containers)) - for _, status := range pod.Status.ContainerStatuses { + oldStatuses := make(map[string]api.ContainerStatus, len(containers)) + for _, status := range previousStatus { oldStatuses[status.Name] = status } // Set all container statuses to default waiting state - statuses := make(map[string]*api.ContainerStatus, len(pod.Spec.Containers)) + statuses := make(map[string]*api.ContainerStatus, len(containers)) defaultWaitingState := api.ContainerState{Waiting: &api.ContainerStateWaiting{Reason: "ContainerCreating"}} - for _, container := range pod.Spec.Containers { + if hasInitContainers { + defaultWaitingState = api.ContainerState{Waiting: &api.ContainerStateWaiting{Reason: "PodInitializing"}} + } + + for _, container := range containers { status := &api.ContainerStatus{ Name: container.Name, Image: container.Image, @@ -3480,7 +3666,6 @@ func (kl *Kubelet) convertStatusToAPIStatus(pod *api.Pod, podStatus *kubecontain // Make the latest container status comes first. sort.Sort(sort.Reverse(kubecontainer.SortContainerStatusesByCreationTime(podStatus.ContainerStatuses))) - // Set container statuses according to the statuses seen in pod status containerSeen := map[string]int{} for _, cStatus := range podStatus.ContainerStatuses { @@ -3502,13 +3687,21 @@ func (kl *Kubelet) convertStatusToAPIStatus(pod *api.Pod, podStatus *kubecontain } // Handle the containers failed to be started, which should be in Waiting state. - for _, container := range pod.Spec.Containers { + for _, container := range containers { + if isInitContainer { + // If the init container is terminated with exit code 0, it won't be restarted. + // TODO(random-liu): Handle this in a cleaner way. + s := podStatus.FindContainerStatusByName(container.Name) + if s != nil && s.State == kubecontainer.ContainerStateExited && s.ExitCode == 0 { + continue + } + } // If a container should be restarted in next syncpod, it is *Waiting*. if !kubecontainer.ShouldContainerBeRestarted(&container, pod, podStatus) { continue } status := statuses[container.Name] - reason, message, ok := kl.reasonCache.Get(uid, container.Name) + reason, message, ok := kl.reasonCache.Get(pod.UID, container.Name) if !ok { // In fact, we could also apply Waiting state here, but it is less informative, // and the container will be restarted soon, so we prefer the original state here. @@ -3530,15 +3723,15 @@ func (kl *Kubelet) convertStatusToAPIStatus(pod *api.Pod, podStatus *kubecontain statuses[container.Name] = status } - apiPodStatus.ContainerStatuses = make([]api.ContainerStatus, 0) + var containerStatuses []api.ContainerStatus for _, status := range statuses { - apiPodStatus.ContainerStatuses = append(apiPodStatus.ContainerStatuses, *status) + containerStatuses = append(containerStatuses, *status) } // Sort the container statuses since clients of this interface expect the list // of containers in a pod has a deterministic order. - sort.Sort(kubetypes.SortedContainerStatuses(apiPodStatus.ContainerStatuses)) - return &apiPodStatus + sort.Sort(kubetypes.SortedContainerStatuses(containerStatuses)) + return containerStatuses } // Returns logs of current machine. @@ -3569,7 +3762,15 @@ func (kl *Kubelet) RunInContainer(podFullName string, podUID types.UID, containe if container == nil { return nil, fmt.Errorf("container not found (%q)", containerName) } - return kl.runner.RunInContainer(container.ID, cmd) + + var buffer bytes.Buffer + output := ioutils.WriteCloserWrapper(&buffer) + err = kl.runner.ExecInContainer(container.ID, cmd, nil, output, output, false) + if err != nil { + return nil, err + } + + return buffer.Bytes(), nil } // ExecInContainer executes a command in a container, connecting the supplied diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/kubelet_cadvisor.go b/vendor/k8s.io/kubernetes/pkg/kubelet/kubelet_cadvisor.go index a398f71103..76bf6ceb34 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/kubelet_cadvisor.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/kubelet_cadvisor.go @@ -50,10 +50,10 @@ func (kl *Kubelet) GetContainerInfoV2(name string, options cadvisorapiv2.Request return kl.cadvisor.ContainerInfoV2(name, options) } -// DockerImagesFsInfo returns information about docker image fs usage from +// ImagesFsInfo returns information about docker image fs usage from // cadvisor. -func (kl *Kubelet) DockerImagesFsInfo() (cadvisorapiv2.FsInfo, error) { - return kl.cadvisor.DockerImagesFsInfo() +func (kl *Kubelet) ImagesFsInfo() (cadvisorapiv2.FsInfo, error) { + return kl.cadvisor.ImagesFsInfo() } // RootFsInfo returns info about the root fs from cadvisor. diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/lifecycle/handlers.go b/vendor/k8s.io/kubernetes/pkg/kubelet/lifecycle/handlers.go index 245a183c3e..1982d3400d 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/lifecycle/handlers.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/lifecycle/handlers.go @@ -21,10 +21,12 @@ import ( "net" "strconv" + "bytes" "github.com/golang/glog" "k8s.io/kubernetes/pkg/api" kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" kubetypes "k8s.io/kubernetes/pkg/kubelet/types" + "k8s.io/kubernetes/pkg/kubelet/util/ioutils" "k8s.io/kubernetes/pkg/types" "k8s.io/kubernetes/pkg/util/intstr" ) @@ -50,7 +52,9 @@ func NewHandlerRunner(httpGetter kubetypes.HttpGetter, commandRunner kubecontain func (hr *HandlerRunner) Run(containerID kubecontainer.ContainerID, pod *api.Pod, container *api.Container, handler *api.Handler) error { switch { case handler.Exec != nil: - _, err := hr.commandRunner.RunInContainer(containerID, handler.Exec.Command) + var buffer bytes.Buffer + output := ioutils.WriteCloserWrapper(&buffer) + err := hr.commandRunner.ExecInContainer(containerID, handler.Exec.Command, nil, output, output, false) return err case handler.HTTPGet != nil: return hr.runHTTPHandler(pod, container, handler) diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/network/hairpin/hairpin.go b/vendor/k8s.io/kubernetes/pkg/kubelet/network/hairpin/hairpin.go index cf5d293756..b725fbba3a 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/network/hairpin/hairpin.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/network/hairpin/hairpin.go @@ -40,13 +40,23 @@ var ( ethtoolOutputRegex = regexp.MustCompile("peer_ifindex: (\\d+)") ) -func SetUpContainer(containerPid int, containerInterfaceName string) error { - e := exec.New() - return setUpContainerInternal(e, containerPid, containerInterfaceName) +func SetUpContainerPid(containerPid int, containerInterfaceName string) error { + pidStr := fmt.Sprintf("%d", containerPid) + nsenterArgs := []string{"-t", pidStr, "-n"} + return setUpContainerInternal(containerInterfaceName, pidStr, nsenterArgs) } -func setUpContainerInternal(e exec.Interface, containerPid int, containerInterfaceName string) error { - hostIfName, err := findPairInterfaceOfContainerInterface(e, containerPid, containerInterfaceName) +func SetUpContainerPath(netnsPath string, containerInterfaceName string) error { + if netnsPath[0] != '/' { + return fmt.Errorf("netnsPath path '%s' was invalid", netnsPath) + } + nsenterArgs := []string{"-n", netnsPath} + return setUpContainerInternal(containerInterfaceName, netnsPath, nsenterArgs) +} + +func setUpContainerInternal(containerInterfaceName, containerDesc string, nsenterArgs []string) error { + e := exec.New() + hostIfName, err := findPairInterfaceOfContainerInterface(e, containerInterfaceName, containerDesc, nsenterArgs) if err != nil { glog.Infof("Unable to find pair interface, setting up all interfaces: %v", err) return setUpAllInterfaces() @@ -54,7 +64,7 @@ func setUpContainerInternal(e exec.Interface, containerPid int, containerInterfa return setUpInterface(hostIfName) } -func findPairInterfaceOfContainerInterface(e exec.Interface, containerPid int, containerInterfaceName string) (string, error) { +func findPairInterfaceOfContainerInterface(e exec.Interface, containerInterfaceName, containerDesc string, nsenterArgs []string) (string, error) { nsenterPath, err := e.LookPath("nsenter") if err != nil { return "", err @@ -63,15 +73,16 @@ func findPairInterfaceOfContainerInterface(e exec.Interface, containerPid int, c if err != nil { return "", err } - // Get container's interface index - output, err := e.Command(nsenterPath, "-t", fmt.Sprintf("%d", containerPid), "-n", "-F", "--", ethtoolPath, "--statistics", containerInterfaceName).CombinedOutput() + + nsenterArgs = append(nsenterArgs, "-F", "--", ethtoolPath, "--statistics", containerInterfaceName) + output, err := e.Command(nsenterPath, nsenterArgs...).CombinedOutput() if err != nil { - return "", fmt.Errorf("Unable to query interface %s of container %d: %v: %s", containerInterfaceName, containerPid, err, string(output)) + return "", fmt.Errorf("Unable to query interface %s of container %s: %v: %s", containerInterfaceName, containerDesc, err, string(output)) } // look for peer_ifindex match := ethtoolOutputRegex.FindSubmatch(output) if match == nil { - return "", fmt.Errorf("No peer_ifindex in interface statistics for %s of container %d", containerInterfaceName, containerPid) + return "", fmt.Errorf("No peer_ifindex in interface statistics for %s of container %s", containerInterfaceName, containerDesc) } peerIfIndex, err := strconv.Atoi(string(match[1])) if err != nil { // seems impossible (\d+ not numeric) diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/network/kubenet/kubenet_linux.go b/vendor/k8s.io/kubernetes/pkg/kubelet/network/kubenet/kubenet_linux.go index 0c85212d92..c274e9b56b 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/network/kubenet/kubenet_linux.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/network/kubenet/kubenet_linux.go @@ -31,10 +31,10 @@ import ( "github.com/vishvananda/netlink/nl" "github.com/appc/cni/libcni" + cnitypes "github.com/appc/cni/pkg/types" "github.com/golang/glog" "k8s.io/kubernetes/pkg/apis/componentconfig" kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" - "k8s.io/kubernetes/pkg/kubelet/dockertools" "k8s.io/kubernetes/pkg/kubelet/network" "k8s.io/kubernetes/pkg/util/bandwidth" utilexec "k8s.io/kubernetes/pkg/util/exec" @@ -55,6 +55,7 @@ type kubenetNetworkPlugin struct { host network.Host netConfig *libcni.NetworkConfig + loConfig *libcni.NetworkConfig cniConfig *libcni.CNIConfig shaper bandwidth.BandwidthShaper podCIDRs map[kubecontainer.ContainerID]string @@ -94,10 +95,20 @@ func (plugin *kubenetNetworkPlugin) Init(host network.Host, hairpinMode componen // was built-in, we simply ignore the error here. A better thing to do is // to check the kernel version in the future. plugin.execer.Command("modprobe", "br-netfilter").CombinedOutput() - if err := utilsysctl.SetSysctl(sysctlBridgeCallIptables, 1); err != nil { + err := utilsysctl.SetSysctl(sysctlBridgeCallIptables, 1) + if err != nil { glog.Warningf("can't set sysctl %s: %v", sysctlBridgeCallIptables, err) } + plugin.loConfig, err = libcni.ConfFromBytes([]byte(`{ + "cniVersion": "0.1.0", + "name": "kubenet-loopback", + "type": "loopback" +}`)) + if err != nil { + return fmt.Errorf("Failed to generate loopback config: %v", err) + } + return nil } @@ -250,7 +261,7 @@ func (plugin *kubenetNetworkPlugin) SetUpPod(namespace string, name string, id k start := time.Now() defer func() { - glog.V(4).Infof("TearDownPod took %v for %s/%s", time.Since(start), namespace, name) + glog.V(4).Infof("SetUpPod took %v for %s/%s", time.Since(start), namespace, name) }() pod, ok := plugin.host.GetPodByName(namespace, name) @@ -266,24 +277,21 @@ func (plugin *kubenetNetworkPlugin) SetUpPod(namespace string, name string, id k return fmt.Errorf("Kubenet cannot SetUpPod: %v", err) } - runtime, ok := plugin.host.GetRuntime().(*dockertools.DockerManager) - if !ok { - return fmt.Errorf("Kubenet execution called on non-docker runtime") - } - netnsPath, err := runtime.GetNetNS(id) - if err != nil { - return fmt.Errorf("Kubenet failed to retrieve network namespace path: %v", err) - } - - rt := buildCNIRuntimeConf(name, namespace, id, netnsPath) - if err != nil { - return fmt.Errorf("Error building CNI config: %v", err) - } - - if err = plugin.addContainerToNetwork(id, rt); err != nil { + // Bring up container loopback interface + if _, err := plugin.addContainerToNetwork(plugin.loConfig, "lo", namespace, name, id); err != nil { return err } + // Hook container up with our bridge + res, err := plugin.addContainerToNetwork(plugin.netConfig, network.DefaultInterfaceName, namespace, name, id) + if err != nil { + return err + } + if res.IP4 == nil || res.IP4.IP.String() == "" { + return fmt.Errorf("CNI plugin reported no IPv4 address for container %v.", id) + } + plugin.podCIDRs[id] = res.IP4.IP.String() + // Put the container bridge into promiscuous mode to force it to accept hairpin packets. // TODO: Remove this once the kernel bug (#20096) is fixed. // TODO: check and set promiscuous mode with netlink once vishvananda/netlink supports it @@ -330,20 +338,6 @@ func (plugin *kubenetNetworkPlugin) TearDownPod(namespace string, name string, i return fmt.Errorf("Kubenet needs a PodCIDR to tear down pods") } - runtime, ok := plugin.host.GetRuntime().(*dockertools.DockerManager) - if !ok { - return fmt.Errorf("Kubenet execution called on non-docker runtime") - } - netnsPath, err := runtime.GetNetNS(id) - if err != nil { - return err - } - - rt := buildCNIRuntimeConf(name, namespace, id, netnsPath) - if err != nil { - return fmt.Errorf("Error building CNI config: %v", err) - } - // no cached CIDR is Ok during teardown if cidr, ok := plugin.podCIDRs[id]; ok { glog.V(5).Infof("Removing pod CIDR %s from shaper", cidr) @@ -354,9 +348,10 @@ func (plugin *kubenetNetworkPlugin) TearDownPod(namespace string, name string, i } } } - if err = plugin.delContainerFromNetwork(id, rt); err != nil { + if err := plugin.delContainerFromNetwork(plugin.netConfig, network.DefaultInterfaceName, namespace, name, id); err != nil { return err } + delete(plugin.podCIDRs, id) return nil } @@ -373,12 +368,8 @@ func (plugin *kubenetNetworkPlugin) GetPodNetworkStatus(namespace string, name s return &network.PodNetworkStatus{IP: ip}, nil } } - // TODO: remove type conversion once kubenet supports multiple runtime - runtime, ok := plugin.host.GetRuntime().(*dockertools.DockerManager) - if !ok { - return nil, fmt.Errorf("Kubenet execution called on non-docker runtime") - } - netnsPath, err := runtime.GetNetNS(id) + + netnsPath, err := plugin.host.GetRuntime().GetNetNS(id) if err != nil { return nil, fmt.Errorf("Kubenet failed to retrieve network namespace path: %v", err) } @@ -412,37 +403,43 @@ func (plugin *kubenetNetworkPlugin) Status() error { return nil } -func buildCNIRuntimeConf(podName string, podNs string, podInfraContainerID kubecontainer.ContainerID, podNetnsPath string) *libcni.RuntimeConf { - glog.V(4).Infof("Kubenet: using netns path %v", podNetnsPath) - glog.V(4).Infof("Kubenet: using podns path %v", podNs) +func (plugin *kubenetNetworkPlugin) buildCNIRuntimeConf(ifName string, id kubecontainer.ContainerID) (*libcni.RuntimeConf, error) { + netnsPath, err := plugin.host.GetRuntime().GetNetNS(id) + if err != nil { + return nil, fmt.Errorf("Kubenet failed to retrieve network namespace path: %v", err) + } return &libcni.RuntimeConf{ - ContainerID: podInfraContainerID.ID, - NetNS: podNetnsPath, - IfName: network.DefaultInterfaceName, - } + ContainerID: id.ID, + NetNS: netnsPath, + IfName: ifName, + }, nil } -func (plugin *kubenetNetworkPlugin) addContainerToNetwork(id kubecontainer.ContainerID, rt *libcni.RuntimeConf) error { - glog.V(3).Infof("Calling cni plugins to add container to network with cni runtime: %+v", rt) - res, err := plugin.cniConfig.AddNetwork(plugin.netConfig, rt) +func (plugin *kubenetNetworkPlugin) addContainerToNetwork(config *libcni.NetworkConfig, ifName, namespace, name string, id kubecontainer.ContainerID) (*cnitypes.Result, error) { + rt, err := plugin.buildCNIRuntimeConf(ifName, id) if err != nil { - return fmt.Errorf("Error adding container to network: %v", err) - } - if res.IP4 == nil || res.IP4.IP.String() == "" { - return fmt.Errorf("CNI plugin reported no IPv4 address for container %v.", id) + return nil, fmt.Errorf("Error building CNI config: %v", err) } - plugin.podCIDRs[id] = res.IP4.IP.String() - return nil + glog.V(3).Infof("Adding %s/%s to '%s' with CNI '%s' plugin and runtime: %+v", namespace, name, config.Network.Name, config.Network.Type, rt) + res, err := plugin.cniConfig.AddNetwork(config, rt) + if err != nil { + return nil, fmt.Errorf("Error adding container to network: %v", err) + } + return res, nil } -func (plugin *kubenetNetworkPlugin) delContainerFromNetwork(id kubecontainer.ContainerID, rt *libcni.RuntimeConf) error { - glog.V(3).Infof("Calling cni plugins to remove container from network with cni runtime: %+v", rt) - if err := plugin.cniConfig.DelNetwork(plugin.netConfig, rt); err != nil { +func (plugin *kubenetNetworkPlugin) delContainerFromNetwork(config *libcni.NetworkConfig, ifName, namespace, name string, id kubecontainer.ContainerID) error { + rt, err := plugin.buildCNIRuntimeConf(ifName, id) + if err != nil { + return fmt.Errorf("Error building CNI config: %v", err) + } + + glog.V(3).Infof("Removing %s/%s from '%s' with CNI '%s' plugin and runtime: %+v", namespace, name, config.Network.Name, config.Network.Type, rt) + if err := plugin.cniConfig.DelNetwork(config, rt); err != nil { return fmt.Errorf("Error removing container from network: %v", err) } - delete(plugin.podCIDRs, id) return nil } diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/network/plugins.go b/vendor/k8s.io/kubernetes/pkg/kubelet/network/plugins.go index 36da95fced..1d52415b22 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/network/plugins.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/network/plugins.go @@ -120,8 +120,8 @@ func InitNetworkPlugin(plugins []NetworkPlugin, networkPluginName string, host H allErrs := []error{} for _, plugin := range plugins { name := plugin.Name() - if !validation.IsQualifiedName(name) { - allErrs = append(allErrs, fmt.Errorf("network plugin has invalid name: %#v", plugin)) + if errs := validation.IsQualifiedName(name); len(errs) != 0 { + allErrs = append(allErrs, fmt.Errorf("network plugin has invalid name: %q: %s", name, strings.Join(errs, ";"))) continue } diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/prober/manager.go b/vendor/k8s.io/kubernetes/pkg/kubelet/prober/manager.go index 9e46f0be3f..01218a75df 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/prober/manager.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/prober/manager.go @@ -207,6 +207,15 @@ func (m *manager) UpdatePodStatus(podUID types.UID, podStatus *api.PodStatus) { } podStatus.ContainerStatuses[i].Ready = ready } + // init containers are ready if they have exited with success or if a readiness probe has + // succeeded. + for i, c := range podStatus.InitContainerStatuses { + var ready bool + if c.State.Terminated != nil && c.State.Terminated.ExitCode == 0 { + ready = true + } + podStatus.InitContainerStatuses[i].Ready = ready + } } func (m *manager) getWorker(podUID types.UID, containerName string, probeType probeType) (*worker, bool) { diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/prober/prober.go b/vendor/k8s.io/kubernetes/pkg/kubelet/prober/prober.go index e322b54c40..c244026c30 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/prober/prober.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/prober/prober.go @@ -17,6 +17,7 @@ limitations under the License. package prober import ( + "bytes" "fmt" "net" "net/http" @@ -30,6 +31,7 @@ import ( kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" "k8s.io/kubernetes/pkg/kubelet/prober/results" "k8s.io/kubernetes/pkg/kubelet/util/format" + "k8s.io/kubernetes/pkg/kubelet/util/ioutils" "k8s.io/kubernetes/pkg/probe" execprobe "k8s.io/kubernetes/pkg/probe/exec" httprobe "k8s.io/kubernetes/pkg/probe/http" @@ -219,7 +221,14 @@ type execInContainer struct { func (p *prober) newExecInContainer(container api.Container, containerID kubecontainer.ContainerID, cmd []string) exec.Cmd { return execInContainer{func() ([]byte, error) { - return p.runner.RunInContainer(containerID, cmd) + var buffer bytes.Buffer + output := ioutils.WriteCloserWrapper(&buffer) + err := p.runner.ExecInContainer(containerID, cmd, nil, output, output, false) + if err != nil { + return nil, err + } + + return buffer.Bytes(), nil }} } diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/qos/memory_policy.go b/vendor/k8s.io/kubernetes/pkg/kubelet/qos/memory_policy.go deleted file mode 100644 index b785ab676f..0000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/qos/memory_policy.go +++ /dev/null @@ -1,75 +0,0 @@ -/* -Copyright 2015 The Kubernetes Authors All rights reserved. - -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 qos - -import ( - "k8s.io/kubernetes/pkg/api" -) - -const ( - PodInfraOOMAdj int = -999 - KubeletOOMScoreAdj int = -999 - KubeProxyOOMScoreAdj int = -999 -) - -// isMemoryBestEffort returns true if the container's memory requirements are best-effort. -func isMemoryBestEffort(container *api.Container) bool { - // A container is memory best-effort if its memory request is unspecified or 0. - // If a request is specified, then the user expects some kind of resource guarantee. - return container.Resources.Requests.Memory().Value() == 0 -} - -// isMemoryGuaranteed returns true if the container's memory requirements are Guaranteed. -func isMemoryGuaranteed(container *api.Container) bool { - // A container is memory guaranteed if its memory request == memory limit. - // If memory request == memory limit, the user is very confident of resource consumption. - memoryRequest := container.Resources.Requests.Memory() - memoryLimit := container.Resources.Limits.Memory() - return (*memoryRequest).Cmp(*memoryLimit) == 0 && memoryRequest.Value() != 0 -} - -// GetContainerOOMAdjust returns the amount by which the OOM score of all processes in the -// container should be adjusted. The OOM score of a process is the percentage of memory it consumes -// multiplied by 10 (barring exceptional cases) + a configurable quantity which is between -1000 -// and 1000. Containers with higher OOM scores are killed if the system runs out of memory. -// See https://lwn.net/Articles/391222/ for more information. -func GetContainerOOMScoreAdjust(container *api.Container, memoryCapacity int64) int { - if isMemoryGuaranteed(container) { - // Memory guaranteed containers should be the last to get killed. - return -999 - } else if isMemoryBestEffort(container) { - // Memory best-effort containers should be the first to be killed. - return 1000 - } else { - // Burstable containers are a middle tier, between Guaranteed and Best-Effort. Ideally, - // we want to protect Burstable containers that consume less memory than requested. - // The formula below is a heuristic. A container requesting for 10% of a system's - // memory will have an oom score adjust of 900. If a process in container Y - // uses over 10% of memory, its OOM score will be 1000. The idea is that containers - // which use more than their request will have an OOM score of 1000 and will be prime - // targets for OOM kills. - // Note that this is a heuristic, it won't work if a container has many small processes. - memoryRequest := container.Resources.Requests.Memory().Value() - oomScoreAdjust := 1000 - (1000*memoryRequest)/memoryCapacity - // A memory guaranteed container using 100% of memory can have an OOM score of 1. Ensure - // that memory burstable containers have a higher OOM score. - if oomScoreAdjust < 2 { - return 2 - } - return int(oomScoreAdjust) - } -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/qos/policy.go b/vendor/k8s.io/kubernetes/pkg/kubelet/qos/policy.go new file mode 100644 index 0000000000..511e629fad --- /dev/null +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/qos/policy.go @@ -0,0 +1,67 @@ +/* +Copyright 2015 The Kubernetes Authors All rights reserved. + +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 qos + +import ( + "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/kubelet/qos/util" +) + +const ( + PodInfraOOMAdj int = -999 + KubeletOOMScoreAdj int = -999 + KubeProxyOOMScoreAdj int = -999 + guaranteedOOMScoreAdj int = -998 + besteffortOOMScoreAdj int = 1000 +) + +// GetContainerOOMAdjust returns the amount by which the OOM score of all processes in the +// container should be adjusted. +// The OOM score of a process is the percentage of memory it consumes +// multiplied by 10 (barring exceptional cases) + a configurable quantity which is between -1000 +// and 1000. Containers with higher OOM scores are killed if the system runs out of memory. +// See https://lwn.net/Articles/391222/ for more information. +func GetContainerOOMScoreAdjust(pod *api.Pod, container *api.Container, memoryCapacity int64) int { + switch util.GetPodQos(pod) { + case util.Guaranteed: + // Guaranteed containers should be the last to get killed. + return guaranteedOOMScoreAdj + case util.BestEffort: + return besteffortOOMScoreAdj + } + + // Burstable containers are a middle tier, between Guaranteed and Best-Effort. Ideally, + // we want to protect Burstable containers that consume less memory than requested. + // The formula below is a heuristic. A container requesting for 10% of a system's + // memory will have an OOM score adjust of 900. If a process in container Y + // uses over 10% of memory, its OOM score will be 1000. The idea is that containers + // which use more than their request will have an OOM score of 1000 and will be prime + // targets for OOM kills. + // Note that this is a heuristic, it won't work if a container has many small processes. + memoryRequest := container.Resources.Requests.Memory().Value() + oomScoreAdjust := 1000 - (1000*memoryRequest)/memoryCapacity + // A guaranteed pod using 100% of memory can have an OOM score of 1. Ensure + // that burstable pods have a higher OOM score adjustment. + if oomScoreAdjust < 2 { + return 2 + } + // Give burstable pods a higher chance of survival over besteffort pods. + if int(oomScoreAdjust) == besteffortOOMScoreAdj { + return int(oomScoreAdjust - 1) + } + return int(oomScoreAdjust) +} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/qos/util/qos.go b/vendor/k8s.io/kubernetes/pkg/kubelet/qos/util/qos.go index 8e1038eda2..7b8264e16c 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/qos/util/qos.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/qos/util/qos.go @@ -18,7 +18,7 @@ package util import ( "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/util/sets" + "k8s.io/kubernetes/pkg/api/resource" ) const ( @@ -48,22 +48,61 @@ func isResourceBestEffort(container *api.Container, resource api.ResourceName) b } // GetPodQos returns the QoS class of a pod. -// The QoS class of a pod is the lowest QoS class for each resource in each container. +// A pod is besteffort if none of its containers have specified any requests or limits. +// A pod is guaranteed only when requests and limits are specified for all the containers and they are equal. +// A pod is burstable if limits and requests do not match across all containers. func GetPodQos(pod *api.Pod) string { - qosValues := sets.NewString() + requests := api.ResourceList{} + limits := api.ResourceList{} + zeroQuantity := resource.MustParse("0") + isGuaranteed := true for _, container := range pod.Spec.Containers { - qosPerResource := GetQoS(&container) - for _, qosValue := range qosPerResource { - qosValues.Insert(qosValue) + // process requests + for name, quantity := range container.Resources.Requests { + if quantity.Cmp(zeroQuantity) == 1 { + delta := quantity.Copy() + if _, exists := requests[name]; !exists { + requests[name] = *delta + } else { + delta.Add(requests[name]) + requests[name] = *delta + } + } + } + // process limits + for name, quantity := range container.Resources.Limits { + if quantity.Cmp(zeroQuantity) == 1 { + delta := quantity.Copy() + if _, exists := limits[name]; !exists { + limits[name] = *delta + } else { + delta.Add(limits[name]) + limits[name] = *delta + } + } + } + if len(container.Resources.Limits) != len(supportedComputeResources) { + isGuaranteed = false } } - if qosValues.Has(BestEffort) { + if len(requests) == 0 && len(limits) == 0 { return BestEffort } - if qosValues.Has(Burstable) { - return Burstable + // Check is requests match limits for all resources. + if isGuaranteed { + for name, req := range requests { + if lim, exists := limits[name]; !exists || lim.Cmp(req) != 0 { + isGuaranteed = false + break + } + } } - return Guaranteed + if isGuaranteed && + len(requests) == len(limits) && + len(limits) == len(supportedComputeResources) { + return Guaranteed + } + return Burstable } // GetQos returns a mapping of resource name to QoS class of a container diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/rkt/image.go b/vendor/k8s.io/kubernetes/pkg/kubelet/rkt/image.go index ae4d155407..3e4166aff7 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/rkt/image.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/rkt/image.go @@ -68,7 +68,7 @@ func (r *Runtime) PullImage(image kubecontainer.ImageSpec, pullSecrets []api.Sec return err } - if _, err := r.runCommand("fetch", dockerPrefix+img); err != nil { + if _, err := r.cli.RunCommand("fetch", dockerPrefix+img); err != nil { glog.Errorf("Failed to fetch: %v", err) return err } @@ -104,7 +104,7 @@ func (r *Runtime) RemoveImage(image kubecontainer.ImageSpec) error { if err != nil { return err } - if _, err := r.runCommand("image", "rm", imageID); err != nil { + if _, err := r.cli.RunCommand("image", "rm", imageID); err != nil { return err } return nil @@ -227,3 +227,17 @@ func (r *Runtime) writeDockerAuthConfig(image string, credsSlice []credentialpro } return nil } + +// ImageStats returns the image stat (total storage bytes). +func (r *Runtime) ImageStats() (*kubecontainer.ImageStats, error) { + var imageStat kubecontainer.ImageStats + listResp, err := r.apisvc.ListImages(context.Background(), &rktapi.ListImagesRequest{}) + if err != nil { + return nil, fmt.Errorf("couldn't list images: %v", err) + } + + for _, image := range listResp.Images { + imageStat.TotalStorageBytes = imageStat.TotalStorageBytes + uint64(image.Size) + } + return &imageStat, nil +} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/rkt/log.go b/vendor/k8s.io/kubernetes/pkg/kubelet/rkt/log.go index cad61bce4d..738b4ea45a 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/rkt/log.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/rkt/log.go @@ -18,6 +18,7 @@ package rkt import ( "bufio" + "bytes" "encoding/json" "fmt" "io" @@ -40,6 +41,8 @@ const ( journalSinceLayout = "2006-01-02 15:04:05" ) +var journalNoEntriesLine = []byte(`"-- No entries --"`) + // pipeLog reads and parses the journal json object from r, // and writes the logs line by line to w. func pipeLog(wg *sync.WaitGroup, logOptions *api.PodLogOptions, r io.ReadCloser, w io.Writer) { @@ -52,9 +55,12 @@ func pipeLog(wg *sync.WaitGroup, logOptions *api.PodLogOptions, r io.ReadCloser, for scanner.Scan() { var data interface{} b := scanner.Bytes() + if bytes.Equal(b, journalNoEntriesLine) { + continue + } if err := json.Unmarshal(b, &data); err != nil { - glog.Warningf("rkt: Cannot unmarshal journal log, skipping line: %v", err) + glog.Warningf("rkt: Cannot unmarshal journal log %q, skipping line: %v", string(b), err) continue } @@ -142,6 +148,7 @@ func (r *Runtime) GetContainerLogs(pod *api.Pod, containerID kubecontainer.Conta } } + glog.V(4).Infof("rkt: gettings logs with command %q", cmd.Args) outPipe, err := cmd.StdoutPipe() if err != nil { glog.Errorf("rkt: cannot create pipe for journalctl's stdout: %v", err) diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/rkt/rkt.go b/vendor/k8s.io/kubernetes/pkg/kubelet/rkt/rkt.go index 06d3f0d789..9e310ae5c7 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/rkt/rkt.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/rkt/rkt.go @@ -26,6 +26,7 @@ import ( "os/exec" "path" "path/filepath" + "sort" "strconv" "strings" "sync" @@ -44,6 +45,8 @@ import ( "k8s.io/kubernetes/pkg/credentialprovider" kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" "k8s.io/kubernetes/pkg/kubelet/lifecycle" + "k8s.io/kubernetes/pkg/kubelet/network" + "k8s.io/kubernetes/pkg/kubelet/network/hairpin" proberesults "k8s.io/kubernetes/pkg/kubelet/prober/results" kubetypes "k8s.io/kubernetes/pkg/kubelet/types" "k8s.io/kubernetes/pkg/kubelet/util/format" @@ -53,7 +56,6 @@ import ( "k8s.io/kubernetes/pkg/util/errors" utilexec "k8s.io/kubernetes/pkg/util/exec" "k8s.io/kubernetes/pkg/util/flowcontrol" - "k8s.io/kubernetes/pkg/util/sets" utilstrings "k8s.io/kubernetes/pkg/util/strings" utilwait "k8s.io/kubernetes/pkg/util/wait" ) @@ -62,9 +64,9 @@ const ( RktType = "rkt" DefaultRktAPIServiceEndpoint = "localhost:15441" - minimumAppcVersion = "0.7.4" - minimumRktBinVersion = "1.2.1" - recommendedRktBinVersion = "1.2.1" + minimumAppcVersion = "0.8.1" + minimumRktBinVersion = "1.6.0" + recommendedRktBinVersion = "1.6.0" minimumRktApiVersion = "1.0.0-alpha" minimumSystemdVersion = "219" @@ -72,10 +74,11 @@ const ( rktDataDir = "/var/lib/rkt" rktLocalConfigDir = "/etc/rkt" - kubernetesUnitPrefix = "k8s" + kubernetesUnitPrefix = "k8s_" unitKubernetesSection = "X-Kubernetes" - unitPodName = "POD" - unitRktID = "RktID" + unitPodUID = "PodUID" + unitPodName = "PodName" + unitPodNamespace = "PodNamespace" unitRestartCount = "RestartCount" k8sRktKubeletAnno = "rkt.kubernetes.io/managed-by-kubelet" @@ -113,6 +116,7 @@ const ( // uses systemd, so in order to run this runtime, systemd must be installed // on the machine. type Runtime struct { + cli cliInterface systemd systemdInterface // The grpc client for rkt api-service. apisvcConn *grpc.ClientConn @@ -122,6 +126,7 @@ type Runtime struct { dockerKeyring credentialprovider.DockerKeyring containerRefManager *kubecontainer.RefManager + podGetter podGetter runtimeHelper kubecontainer.RuntimeHelper recorder record.EventRecorder livenessManager proberesults.Manager @@ -131,8 +136,17 @@ type Runtime struct { execer utilexec.Interface os kubecontainer.OSInterface + // Network plugin. + networkPlugin network.NetworkPlugin + + // If true, the "hairpin mode" flag is set on container interfaces. + // A false value means the kubelet just backs off from setting it, + // it might already be true. + configureHairpinMode bool + // used for a systemd Exec, which requires the full path. - touchPath string + touchPath string + nsenterPath string versions versions } @@ -144,6 +158,18 @@ type volumeGetter interface { GetVolumes(podUID types.UID) (kubecontainer.VolumeMap, bool) } +// TODO(yifan): This duplicates the podGetter in dockertools. +type podGetter interface { + GetPodByUID(types.UID) (*api.Pod, bool) +} + +// cliInterface wrapps the command line calls for testing purpose. +type cliInterface interface { + // args are the arguments given to the 'rkt' command, + // e.g. args can be 'rm ${UUID}'. + RunCommand(args ...string) (result []string, err error) +} + // New creates the rkt container runtime which implements the container runtime interface. // It will test if the rkt binary is in the $PATH, and whether we can get the // version of it. If so, creates the rkt container runtime, otherwise returns an error. @@ -153,9 +179,12 @@ func New( runtimeHelper kubecontainer.RuntimeHelper, recorder record.EventRecorder, containerRefManager *kubecontainer.RefManager, + podGetter podGetter, livenessManager proberesults.Manager, volumeGetter volumeGetter, httpClient kubetypes.HttpGetter, + networkPlugin network.NetworkPlugin, + hairpinMode bool, execer utilexec.Interface, os kubecontainer.OSInterface, imageBackOff *flowcontrol.Backoff, @@ -188,20 +217,28 @@ func New( return nil, fmt.Errorf("cannot find touch binary: %v", err) } + nsenterPath, err := execer.LookPath("nsenter") + if err != nil { + return nil, fmt.Errorf("cannot find nsenter binary: %v", err) + } + rkt := &Runtime{ + os: kubecontainer.RealOS{}, systemd: systemd, apisvcConn: apisvcConn, apisvc: rktapi.NewPublicAPIClient(apisvcConn), config: config, dockerKeyring: credentialprovider.NewDockerKeyring(), containerRefManager: containerRefManager, + podGetter: podGetter, runtimeHelper: runtimeHelper, recorder: recorder, livenessManager: livenessManager, volumeGetter: volumeGetter, + networkPlugin: networkPlugin, execer: execer, - os: os, touchPath: touchPath, + nsenterPath: nsenterPath, } rkt.config, err = rkt.getConfig(rkt.config) @@ -221,6 +258,8 @@ func New( return nil, fmt.Errorf("rkt: error getting version info: %v", err) } + rkt.cli = rkt + return rkt, nil } @@ -239,9 +278,9 @@ func convertToACName(name string) appctypes.ACName { return *appctypes.MustACName(acname) } -// runCommand invokes rkt binary with arguments and returns the result +// RunCommand invokes rkt binary with arguments and returns the result // from stdout in a list of strings. Each string in the list is a line. -func (r *Runtime) runCommand(args ...string) ([]string, error) { +func (r *Runtime) RunCommand(args ...string) ([]string, error) { glog.V(4).Info("rkt: Run command:", args) var stdout, stderr bytes.Buffer @@ -257,7 +296,11 @@ func (r *Runtime) runCommand(args ...string) ([]string, error) { func makePodServiceFileName(uuid string) string { // TODO(yifan): Add name for readability? We need to consider the // limit of the length. - return fmt.Sprintf("%s_%s.service", kubernetesUnitPrefix, uuid) + return fmt.Sprintf("%s%s.service", kubernetesUnitPrefix, uuid) +} + +func getRktUUIDFromServiceFileName(filename string) string { + return strings.TrimPrefix(strings.TrimSuffix(filename, path.Ext(filename)), kubernetesUnitPrefix) } // setIsolators sets the apps' isolators according to the security context and resource spec. @@ -629,7 +672,7 @@ func (r *Runtime) podFinishedAt(podUID types.UID, rktUID string) time.Time { return stat.ModTime() } -func makeContainerLogMount(opts *kubecontainer.RunContainerOptions, container *api.Container) (*kubecontainer.Mount, error) { +func (r *Runtime) makeContainerLogMount(opts *kubecontainer.RunContainerOptions, container *api.Container) (*kubecontainer.Mount, error) { if opts.PodContainerDir == "" || container.TerminationMessagePath == "" { return nil, nil } @@ -641,7 +684,7 @@ func makeContainerLogMount(opts *kubecontainer.RunContainerOptions, container *a // on the disk. randomUID := util.NewUUID() containerLogPath := path.Join(opts.PodContainerDir, string(randomUID)) - fs, err := os.Create(containerLogPath) + fs, err := r.os.Create(containerLogPath) if err != nil { return nil, err } @@ -693,7 +736,7 @@ func (r *Runtime) newAppcRuntimeApp(pod *api.Pod, c api.Container, pullSecrets [ } // create the container log file and make a mount pair. - mnt, err := makeContainerLogMount(opts, &c) + mnt, err := r.makeContainerLogMount(opts, &c) if err != nil { return err } @@ -798,6 +841,19 @@ func kubernetesPodFilters(uid types.UID) []*rktapi.PodFilter { } } +func kubernetesPodsFilters() []*rktapi.PodFilter { + return []*rktapi.PodFilter{ + { + Annotations: []*rktapi.KeyValue{ + { + Key: k8sRktKubeletAnno, + Value: k8sRktKubeletAnnoValue, + }, + }, + }, + } +} + func newUnitOption(section, name, value string) *unit.UnitOption { return &unit.UnitOption{Section: section, Name: name, Value: value} } @@ -827,23 +883,22 @@ func serviceFilePath(serviceName string) string { } // generateRunCommand crafts a 'rkt run-prepared' command with necessary parameters. -func (r *Runtime) generateRunCommand(pod *api.Pod, uuid string) (string, error) { +func (r *Runtime) generateRunCommand(pod *api.Pod, uuid, netnsName string) (string, error) { runPrepared := r.buildCommand("run-prepared").Args + // Network namespace set up in kubelet; rkt networking not used + runPrepared = append(runPrepared, "--net=host") + var hostname string var err error - // Setup network configuration. - if kubecontainer.IsHostNetworkPod(pod) { - runPrepared = append(runPrepared, "--net=host") - + // Setup DNS and hostname configuration. + if len(netnsName) == 0 { // TODO(yifan): Let runtimeHelper.GeneratePodHostNameAndDomain() to handle this. - hostname, err = os.Hostname() + hostname, err = r.os.Hostname() if err != nil { return "", err } } else { - runPrepared = append(runPrepared, fmt.Sprintf("--net=%s", defaultNetworkName)) - // Setup DNS. dnsServers, dnsSearches, err := r.runtimeHelper.GetClusterDNS(pod) if err != nil { @@ -864,12 +919,37 @@ func (r *Runtime) generateRunCommand(pod *api.Pod, uuid string) (string, error) if err != nil { return "", err } + + // Drop the `rkt run-prepared` into the network namespace we + // created. + // TODO: switch to 'ip netns exec' once we can depend on a new + // enough version that doesn't have bugs like + // https://bugzilla.redhat.com/show_bug.cgi?id=882047 + nsenterExec := []string{r.nsenterPath, "--net=\"" + netnsPathFromName(netnsName) + "\"", "--"} + runPrepared = append(nsenterExec, runPrepared...) } + runPrepared = append(runPrepared, fmt.Sprintf("--hostname=%s", hostname)) runPrepared = append(runPrepared, uuid) return strings.Join(runPrepared, " "), nil } +func (r *Runtime) cleanupPodNetwork(pod *api.Pod) error { + glog.V(3).Infof("Calling network plugin %s to tear down pod for %s", r.networkPlugin.Name(), format.Pod(pod)) + + var teardownErr error + containerID := kubecontainer.ContainerID{ID: string(pod.UID)} + if err := r.networkPlugin.TearDownPod(pod.Namespace, pod.Name, containerID); err != nil { + teardownErr = fmt.Errorf("rkt: failed to tear down network for pod %s: %v", format.Pod(pod), err) + } + + if _, err := r.execer.Command("ip", "netns", "del", makePodNetnsName(pod.UID)).Output(); err != nil { + return fmt.Errorf("rkt: Failed to remove network namespace for pod %s: %v", format.Pod(pod), err) + } + + return teardownErr +} + // preparePod will: // // 1. Invoke 'rkt prepare' to prepare the pod, and get the rkt pod uuid. @@ -877,7 +957,7 @@ func (r *Runtime) generateRunCommand(pod *api.Pod, uuid string) (string, error) // // On success, it will return a string that represents name of the unit file // and the runtime pod. -func (r *Runtime) preparePod(pod *api.Pod, pullSecrets []api.Secret) (string, *kubecontainer.Pod, error) { +func (r *Runtime) preparePod(pod *api.Pod, pullSecrets []api.Secret, netnsName string) (string, *kubecontainer.Pod, error) { // Generate the pod manifest from the pod spec. manifest, err := r.makePodManifest(pod, pullSecrets) if err != nil { @@ -889,7 +969,7 @@ func (r *Runtime) preparePod(pod *api.Pod, pullSecrets []api.Secret) (string, *k } defer func() { manifestFile.Close() - if err := os.Remove(manifestFile.Name()); err != nil { + if err := r.os.Remove(manifestFile.Name()); err != nil { glog.Warningf("rkt: Cannot remove temp manifest file %q: %v", manifestFile.Name(), err) } }() @@ -911,7 +991,7 @@ func (r *Runtime) preparePod(pod *api.Pod, pullSecrets []api.Secret) (string, *k if r.config.Stage1Image != "" { cmds = append(cmds, "--stage1-path", r.config.Stage1Image) } - output, err := r.runCommand(cmds...) + output, err := r.cli.RunCommand(cmds...) if err != nil { return "", nil, err } @@ -922,7 +1002,7 @@ func (r *Runtime) preparePod(pod *api.Pod, pullSecrets []api.Secret) (string, *k glog.V(4).Infof("'rkt prepare' returns %q", uuid) // Create systemd service file for the rkt pod. - runPrepared, err := r.generateRunCommand(pod, uuid) + runPrepared, err := r.generateRunCommand(pod, uuid, netnsName) if err != nil { return "", nil, fmt.Errorf("failed to generate 'rkt run-prepared' command: %v", err) } @@ -937,11 +1017,15 @@ func (r *Runtime) preparePod(pod *api.Pod, pullSecrets []api.Secret) (string, *k newUnitOption("Service", "ExecStopPost", markPodFinished), // This enables graceful stop. newUnitOption("Service", "KillMode", "mixed"), + // Track pod info for garbage collection + newUnitOption(unitKubernetesSection, unitPodUID, string(pod.UID)), + newUnitOption(unitKubernetesSection, unitPodName, pod.Name), + newUnitOption(unitKubernetesSection, unitPodNamespace, pod.Namespace), } serviceName := makePodServiceFileName(uuid) glog.V(4).Infof("rkt: Creating service file %q for pod %q", serviceName, format.Pod(pod)) - serviceFile, err := os.Create(serviceFilePath(serviceName)) + serviceFile, err := r.os.Create(serviceFilePath(serviceName)) if err != nil { return "", nil, err } @@ -989,12 +1073,57 @@ func (r *Runtime) generateEvents(runtimePod *kubecontainer.Pod, reason string, f return } +func makePodNetnsName(podID types.UID) string { + return fmt.Sprintf("%s_%s", kubernetesUnitPrefix, string(podID)) +} + +func netnsPathFromName(netnsName string) string { + return fmt.Sprintf("/var/run/netns/%s", netnsName) +} + +func (r *Runtime) setupPodNetwork(pod *api.Pod) (string, error) { + netnsName := makePodNetnsName(pod.UID) + + // Create a new network namespace for the pod + r.execer.Command("ip", "netns", "del", netnsName).Output() + _, err := r.execer.Command("ip", "netns", "add", netnsName).Output() + if err != nil { + return "", fmt.Errorf("failed to create pod network namespace: %v", err) + } + + // Set up networking with the network plugin + glog.V(3).Infof("Calling network plugin %s to setup pod for %s", r.networkPlugin.Name(), format.Pod(pod)) + containerID := kubecontainer.ContainerID{ID: string(pod.UID)} + err = r.networkPlugin.SetUpPod(pod.Namespace, pod.Name, containerID) + if err != nil { + return "", fmt.Errorf("failed to set up pod network: %v", err) + } + + if r.configureHairpinMode { + if err = hairpin.SetUpContainerPath(netnsPathFromName(netnsName), network.DefaultInterfaceName); err != nil { + glog.Warningf("Hairpin setup failed for pod %q: %v", format.Pod(pod), err) + } + } + + return netnsName, nil +} + // RunPod first creates the unit file for a pod, and then // starts the unit over d-bus. func (r *Runtime) RunPod(pod *api.Pod, pullSecrets []api.Secret) error { glog.V(4).Infof("Rkt starts to run pod: name %q.", format.Pod(pod)) - name, runtimePod, prepareErr := r.preparePod(pod, pullSecrets) + var err error + var netnsName string + if !kubecontainer.IsHostNetworkPod(pod) { + netnsName, err = r.setupPodNetwork(pod) + if err != nil { + r.cleanupPodNetwork(pod) + return err + } + } + + name, runtimePod, prepareErr := r.preparePod(pod, pullSecrets, netnsName) // Set container references and generate events. // If preparedPod fails, then send out 'failed' events for each container. @@ -1014,6 +1143,7 @@ func (r *Runtime) RunPod(pod *api.Pod, pullSecrets []api.Secret) error { } if prepareErr != nil { + r.cleanupPodNetwork(pod) return prepareErr } @@ -1022,9 +1152,10 @@ func (r *Runtime) RunPod(pod *api.Pod, pullSecrets []api.Secret) error { // RestartUnit has the same effect as StartUnit if the unit is not running, besides it can restart // a unit if the unit file is changed and reloaded. reschan := make(chan string) - _, err := r.systemd.RestartUnit(name, "replace", reschan) + _, err = r.systemd.RestartUnit(name, "replace", reschan) if err != nil { r.generateEvents(runtimePod, "Failed", err) + r.cleanupPodNetwork(pod) return err } @@ -1032,6 +1163,7 @@ func (r *Runtime) RunPod(pod *api.Pod, pullSecrets []api.Secret) error { if res != "done" { err := fmt.Errorf("Failed to restart unit %q: %s", name, res) r.generateEvents(runtimePod, "Failed", err) + r.cleanupPodNetwork(pod) return err } @@ -1043,6 +1175,7 @@ func (r *Runtime) RunPod(pod *api.Pod, pullSecrets []api.Secret) error { if errKill := r.KillPod(pod, *runtimePod, nil); errKill != nil { return errors.NewAggregate([]error{err, errKill}) } + r.cleanupPodNetwork(pod) return err } @@ -1309,7 +1442,7 @@ func (r *Runtime) KillPod(pod *api.Pod, runningPod kubecontainer.Pod, gracePerio // Touch the systemd service file to update the mod time so it will // not be garbage collected too soon. - if err := os.Chtimes(serviceFilePath(serviceName), time.Now(), time.Now()); err != nil { + if err := r.os.Chtimes(serviceFilePath(serviceName), time.Now(), time.Now()); err != nil { glog.Errorf("rkt: Failed to change the modification time of the service file %q: %v", serviceName, err) return err } @@ -1329,6 +1462,21 @@ func (r *Runtime) KillPod(pod *api.Pod, runningPod kubecontainer.Pod, gracePerio return err } + // Clean up networking; use running pod details since 'pod' can be nil + if pod == nil || !kubecontainer.IsHostNetworkPod(pod) { + err := r.cleanupPodNetwork(&api.Pod{ + ObjectMeta: api.ObjectMeta{ + UID: runningPod.ID, + Name: runningPod.Name, + Namespace: runningPod.Namespace, + }, + }) + if err != nil { + glog.Errorf("rkt: failed to tear down network for unit %q: %v", serviceName, err) + return err + } + } + return nil } @@ -1426,67 +1574,213 @@ func (r *Runtime) SyncPod(pod *api.Pod, podStatus api.PodStatus, internalPodStat return } -// GarbageCollect collects the pods/containers. -// TODO(yifan): Enforce the gc policy, also, it would be better if we can -// just GC kubernetes pods. -func (r *Runtime) GarbageCollect(gcPolicy kubecontainer.ContainerGCPolicy) error { - if err := exec.Command("systemctl", "reset-failed").Run(); err != nil { - glog.Errorf("rkt: Failed to reset failed systemd services: %v, continue to gc anyway...", err) - } +// Sort rkt pods by creation time. +type podsByCreatedAt []*rktapi.Pod - if _, err := r.runCommand("gc", "--grace-period="+gcPolicy.MinAge.String(), "--expire-prepared="+gcPolicy.MinAge.String()); err != nil { - glog.Errorf("rkt: Failed to gc: %v", err) - } +func (s podsByCreatedAt) Len() int { return len(s) } +func (s podsByCreatedAt) Swap(i, j int) { s[i], s[j] = s[j], s[i] } +func (s podsByCreatedAt) Less(i, j int) bool { return s[i].CreatedAt < s[j].CreatedAt } - // GC all inactive systemd service files. - units, err := r.systemd.ListUnits() +// getPodUID returns the pod's API UID, it returns +// empty UID if the UID cannot be determined. +func getPodUID(pod *rktapi.Pod) types.UID { + for _, anno := range pod.Annotations { + if anno.Key == k8sRktUIDAnno { + return types.UID(anno.Value) + } + } + return types.UID("") +} + +// podIsActive returns true if the pod is embryo, preparing or running. +// If a pod is prepared, it is not guaranteed to be active (e.g. the systemd +// service might fail). +func podIsActive(pod *rktapi.Pod) bool { + return pod.State == rktapi.PodState_POD_STATE_EMBRYO || + pod.State == rktapi.PodState_POD_STATE_PREPARING || + pod.State == rktapi.PodState_POD_STATE_RUNNING +} + +// GetNetNS returns the network namespace path for the given container +func (r *Runtime) GetNetNS(containerID kubecontainer.ContainerID) (string, error) { + // This is a slight hack, kubenet shouldn't be asking us about a container id + // but a pod id. This is because it knows too much about the infra container. + // We pretend the pod.UID is an infra container ID. + // This deception is only possible because we played the same trick in + // `networkPlugin.SetUpPod` and `networkPlugin.TearDownPod`. + return netnsPathFromName(makePodNetnsName(types.UID(containerID.ID))), nil +} + +func podDetailsFromServiceFile(serviceFilePath string) (string, string, string, error) { + f, err := os.Open(serviceFilePath) if err != nil { - glog.Errorf("rkt: Failed to list units: %v", err) - return err + return "", "", "", err } - runningKubernetesUnits := sets.NewString() - for _, u := range units { - if strings.HasPrefix(u.Name, kubernetesUnitPrefix) && u.SubState == "running" { - runningKubernetesUnits.Insert(u.Name) + defer f.Close() + + opts, err := unit.Deserialize(f) + if err != nil { + return "", "", "", err + } + + var id, name, namespace string + for _, o := range opts { + if o.Section != unitKubernetesSection { + continue + } + switch o.Name { + case unitPodUID: + id = o.Value + case unitPodName: + name = o.Value + case unitPodNamespace: + namespace = o.Value + } + + if id != "" && name != "" && namespace != "" { + return id, name, namespace, nil } } - files, err := ioutil.ReadDir(systemdServiceDir) + return "", "", "", fmt.Errorf("failed to parse pod from file %s", serviceFilePath) +} + +// GarbageCollect collects the pods/containers. +// After one GC iteration: +// - The deleted pods will be removed. +// - If the number of containers exceeds gcPolicy.MaxContainers, +// then containers whose ages are older than gcPolicy.minAge will +// be removed. +func (r *Runtime) GarbageCollect(gcPolicy kubecontainer.ContainerGCPolicy) error { + var errlist []error + var totalInactiveContainers int + var inactivePods []*rktapi.Pod + var removeCandidates []*rktapi.Pod + var allPods = map[string]*rktapi.Pod{} + + glog.V(4).Infof("rkt: Garbage collecting triggered with policy %v", gcPolicy) + + if err := r.systemd.ResetFailed(); err != nil { + glog.Errorf("rkt: Failed to reset failed systemd services: %v, continue to gc anyway...", err) + } + + // GC all inactive systemd service files and pods. + files, err := r.os.ReadDir(systemdServiceDir) if err != nil { glog.Errorf("rkt: Failed to read the systemd service directory: %v", err) return err } + + resp, err := r.apisvc.ListPods(context.Background(), &rktapi.ListPodsRequest{Filters: kubernetesPodsFilters()}) + if err != nil { + glog.Errorf("rkt: Failed to list pods: %v", err) + return err + } + + // Mark inactive pods. + for _, pod := range resp.Pods { + allPods[pod.Id] = pod + if !podIsActive(pod) { + uid := getPodUID(pod) + if uid == types.UID("") { + glog.Errorf("rkt: Cannot get the UID of pod %q, pod is broken, will remove it", pod.Id) + removeCandidates = append(removeCandidates, pod) + continue + } + _, found := r.podGetter.GetPodByUID(uid) + if !found { + removeCandidates = append(removeCandidates, pod) + continue + } + + inactivePods = append(inactivePods, pod) + totalInactiveContainers = totalInactiveContainers + len(pod.Apps) + } + } + + // Remove any orphan service files. for _, f := range files { - if strings.HasPrefix(f.Name(), kubernetesUnitPrefix) && !runningKubernetesUnits.Has(f.Name()) && f.ModTime().Before(time.Now().Add(-gcPolicy.MinAge)) { - glog.V(4).Infof("rkt: Removing inactive systemd service file: %v", f.Name()) - if err := os.Remove(serviceFilePath(f.Name())); err != nil { - glog.Warningf("rkt: Failed to remove inactive systemd service file %v: %v", f.Name(), err) + serviceName := f.Name() + if strings.HasPrefix(serviceName, kubernetesUnitPrefix) { + rktUUID := getRktUUIDFromServiceFileName(serviceName) + if _, ok := allPods[rktUUID]; !ok { + glog.V(4).Infof("rkt: No rkt pod found for service file %q, will remove it", serviceName) + + serviceFile := serviceFilePath(serviceName) + + // Network may not be around anymore so errors are ignored + r.cleanupPodNetworkFromServiceFile(serviceFile) + + if err := r.os.Remove(serviceFile); err != nil { + errlist = append(errlist, fmt.Errorf("rkt: Failed to remove service file %q: %v", serviceName, err)) + } } } } - return nil -} -// Note: In rkt, the container ID is in the form of "UUID:appName", where -// appName is the container name. -// TODO(yifan): If the rkt is using lkvm as the stage1 image, then this function will fail. -func (r *Runtime) RunInContainer(containerID kubecontainer.ContainerID, cmd []string) ([]byte, error) { - glog.V(4).Infof("Rkt running in container.") + sort.Sort(podsByCreatedAt(inactivePods)) - id, err := parseContainerID(containerID) - if err != nil { - return nil, err - } - args := append([]string{}, "enter", fmt.Sprintf("--app=%s", id.appName), id.uuid) - args = append(args, cmd...) - - result, err := r.buildCommand(args...).CombinedOutput() - if err != nil { - if exitErr, ok := err.(*exec.ExitError); ok { - err = &rktExitError{exitErr} + // Enforce GCPolicy.MaxContainers. + for _, pod := range inactivePods { + if totalInactiveContainers <= gcPolicy.MaxContainers { + break + } + creationTime := time.Unix(0, pod.CreatedAt) + if creationTime.Add(gcPolicy.MinAge).Before(time.Now()) { + // The pod is old and we are exceeding the MaxContainers limit. + // Delete the pod. + removeCandidates = append(removeCandidates, pod) + totalInactiveContainers = totalInactiveContainers - len(pod.Apps) } } - return result, err + + // Remove pods and their servie files. + for _, pod := range removeCandidates { + if err := r.removePod(pod.Id); err != nil { + errlist = append(errlist, fmt.Errorf("rkt: Failed to clean up rkt pod %q: %v", pod.Id, err)) + } + } + + return errors.NewAggregate(errlist) +} + +// Read kubernetes pod UUID, namespace, and name from systemd service file and +// use that to clean up any pod network that may still exist. +func (r *Runtime) cleanupPodNetworkFromServiceFile(serviceFilePath string) { + id, name, namespace, err := podDetailsFromServiceFile(serviceFilePath) + if err == nil { + r.cleanupPodNetwork(&api.Pod{ + ObjectMeta: api.ObjectMeta{ + UID: types.UID(id), + Name: name, + Namespace: namespace, + }, + }) + } +} + +// removePod calls 'rkt rm $UUID' to delete a rkt pod, it also remove the systemd service file +// related to the pod. +func (r *Runtime) removePod(uuid string) error { + var errlist []error + glog.V(4).Infof("rkt: GC is removing pod %q", uuid) + + serviceName := makePodServiceFileName(uuid) + serviceFile := serviceFilePath(serviceName) + + // Network may not be around anymore so errors are ignored + r.cleanupPodNetworkFromServiceFile(serviceFile) + + if _, err := r.cli.RunCommand("rm", uuid); err != nil { + errlist = append(errlist, fmt.Errorf("rkt: Failed to remove pod %q: %v", uuid, err)) + } + + // GC systemd service files as well. + if err := r.os.Remove(serviceFile); err != nil { + errlist = append(errlist, fmt.Errorf("rkt: Failed to remove service file %q for pod %q: %v", serviceName, uuid, err)) + } + + return errors.NewAggregate(errlist) } // rktExitError implemets /pkg/util/exec.ExitError interface. @@ -1542,7 +1836,7 @@ func (r *Runtime) ExecInContainer(containerID kubecontainer.ContainerID, cmd []s // This way, if you run 'kubectl exec -i bash' (no tty) and type 'exit', // the call below to command.Run() can unblock because its Stdin is the read half // of the pipe. - r, w, err := os.Pipe() + r, w, err := r.os.Pipe() if err != nil { return err } @@ -1771,8 +2065,3 @@ func (r *Runtime) GetPodStatus(uid types.UID, name, namespace string) (*kubecont return podStatus, nil } - -// FIXME: I need to be implemented. -func (r *Runtime) ImageStats() (*kubecontainer.ImageStats, error) { - return &kubecontainer.ImageStats{}, nil -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/rkt/systemd.go b/vendor/k8s.io/kubernetes/pkg/kubelet/rkt/systemd.go index 14b2dc9db0..7151cfdce6 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/rkt/systemd.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/rkt/systemd.go @@ -62,6 +62,8 @@ type systemdInterface interface { RestartUnit(name string, mode string, ch chan<- string) (int, error) // Reload is equivalent to 'systemctl daemon-reload'. Reload() error + // ResetFailed is equivalent to 'systemctl reset-failed'. + ResetFailed() error } // systemd implements the systemdInterface using dbus and systemctl. @@ -101,3 +103,8 @@ func (s *systemd) Version() (systemdVersion, error) { } return systemdVersion(result), nil } + +// ResetFailed calls 'systemctl reset failed' +func (s *systemd) ResetFailed() error { + return exec.Command("systemctl", "reset-failed").Run() +} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/server/server.go b/vendor/k8s.io/kubernetes/pkg/kubelet/server/server.go index 163ecf57b6..f490a5075b 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/server/server.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/server/server.go @@ -171,7 +171,7 @@ type HostInterface interface { GetNode() (*api.Node, error) GetNodeConfig() cm.NodeConfig LatestLoopEntryTime() time.Time - DockerImagesFsInfo() (cadvisorapiv2.FsInfo, error) + ImagesFsInfo() (cadvisorapiv2.FsInfo, error) RootFsInfo() (cadvisorapiv2.FsInfo, error) ListVolumesForPod(podUID types.UID) (map[string]volume.Volume, bool) PLEGHealthCheck() (bool, error) @@ -465,6 +465,13 @@ func (s *Server) getContainerLogs(request *restful.Request, response *restful.Re containerExists = true } } + if !containerExists { + for _, container := range pod.Spec.InitContainers { + if container.Name == containerName { + containerExists = true + } + } + } if !containerExists { response.WriteError(http.StatusNotFound, fmt.Errorf("container %q not found in pod %q\n", containerName, podID)) return diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/server/stats/handler.go b/vendor/k8s.io/kubernetes/pkg/kubelet/server/stats/handler.go index 0d2221bac8..531d55350a 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/server/stats/handler.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/server/stats/handler.go @@ -24,11 +24,11 @@ import ( "path" "time" - "github.com/emicklei/go-restful" "github.com/golang/glog" cadvisorapi "github.com/google/cadvisor/info/v1" cadvisorapiv2 "github.com/google/cadvisor/info/v2" + "github.com/emicklei/go-restful" "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/kubelet/cm" kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" @@ -44,7 +44,7 @@ type StatsProvider interface { GetPodByName(namespace, name string) (*api.Pod, bool) GetNode() (*api.Node, error) GetNodeConfig() cm.NodeConfig - DockerImagesFsInfo() (cadvisorapiv2.FsInfo, error) + ImagesFsInfo() (cadvisorapiv2.FsInfo, error) RootFsInfo() (cadvisorapiv2.FsInfo, error) ListVolumesForPod(podUID types.UID) (map[string]volume.Volume, bool) GetPods() []*api.Pod @@ -133,14 +133,14 @@ func parseStatsRequest(request *restful.Request) (StatsRequest, error) { func (h *handler) handleStats(request *restful.Request, response *restful.Response) { query, err := parseStatsRequest(request) if err != nil { - handleError(response, err) + handleError(response, "/stats", err) return } // Root container stats. statsMap, err := h.provider.GetRawContainerInfo("/", query.cadvisorRequest(), false) if err != nil { - handleError(response, err) + handleError(response, fmt.Sprintf("/stats %v", query), err) return } writeResponse(response, statsMap["/"]) @@ -150,7 +150,7 @@ func (h *handler) handleStats(request *restful.Request, response *restful.Respon func (h *handler) handleSummary(request *restful.Request, response *restful.Response) { summary, err := h.summaryProvider.Get() if err != nil { - handleError(response, err) + handleError(response, "/stats/summary", err) } else { writeResponse(response, summary) } @@ -160,7 +160,7 @@ func (h *handler) handleSummary(request *restful.Request, response *restful.Resp func (h *handler) handleSystemContainer(request *restful.Request, response *restful.Response) { query, err := parseStatsRequest(request) if err != nil { - handleError(response, err) + handleError(response, "/stats/container", err) return } @@ -169,8 +169,13 @@ func (h *handler) handleSystemContainer(request *restful.Request, response *rest stats, err := h.provider.GetRawContainerInfo( containerName, query.cadvisorRequest(), query.Subcontainers) if err != nil { - handleError(response, err) - return + if _, ok := stats[containerName]; ok { + // If the failure is partial, log it and return a best-effort response. + glog.Errorf("Partial failure issuing GetRawContainerInfo(%v): %v", query, err) + } else { + handleError(response, fmt.Sprintf("/stats/container %v", query), err) + return + } } writeResponse(response, stats) } @@ -181,7 +186,7 @@ func (h *handler) handleSystemContainer(request *restful.Request, response *rest func (h *handler) handlePodContainer(request *restful.Request, response *restful.Response) { query, err := parseStatsRequest(request) if err != nil { - handleError(response, err) + handleError(response, request.Request.URL.String(), err) return } @@ -203,7 +208,7 @@ func (h *handler) handlePodContainer(request *restful.Request, response *restful pod, ok := h.provider.GetPodByName(params["namespace"], params["podName"]) if !ok { glog.V(4).Infof("Container not found: %v", params) - handleError(response, kubecontainer.ErrContainerNotFound) + response.WriteError(http.StatusNotFound, kubecontainer.ErrContainerNotFound) return } stats, err := h.provider.GetContainerInfo( @@ -213,7 +218,7 @@ func (h *handler) handlePodContainer(request *restful.Request, response *restful query.cadvisorRequest()) if err != nil { - handleError(response, err) + handleError(response, fmt.Sprintf("%s %v", request.Request.URL.String(), query), err) return } writeResponse(response, stats) @@ -226,13 +231,14 @@ func writeResponse(response *restful.Response, stats interface{}) { } // handleError serializes an error object into an HTTP response. -func handleError(response *restful.Response, err error) { +// request is provided for logging. +func handleError(response *restful.Response, request string, err error) { switch err { case kubecontainer.ErrContainerNotFound: response.WriteError(http.StatusNotFound, err) default: msg := fmt.Sprintf("Internal Error: %v", err) - glog.Errorf("HTTP InternalServerError: %s", msg) + glog.Errorf("HTTP InternalServerError serving %s: %s", request, msg) response.WriteErrorString(http.StatusInternalServerError, msg) } } diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/server/stats/summary.go b/vendor/k8s.io/kubernetes/pkg/kubelet/server/stats/summary.go index 5a1ee27973..678c0eca91 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/server/stats/summary.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/server/stats/summary.go @@ -68,26 +68,33 @@ func (sp *summaryProviderImpl) Get() (*stats.Summary, error) { } infos, err := sp.provider.GetContainerInfoV2("/", options) if err != nil { - return nil, err + if _, ok := infos["/"]; ok { + // If the failure is partial, log it and return a best-effort response. + glog.Errorf("Partial failure issuing GetContainerInfoV2: %v", err) + } else { + return nil, fmt.Errorf("failed GetContainerInfoV2: %v", err) + } } + // TODO(timstclair): Consider returning a best-effort response if any of the following errors + // occur. node, err := sp.provider.GetNode() if err != nil { - return nil, err + return nil, fmt.Errorf("failed GetNode: %v", err) } nodeConfig := sp.provider.GetNodeConfig() rootFsInfo, err := sp.provider.RootFsInfo() if err != nil { - return nil, err + return nil, fmt.Errorf("failed RootFsInfo: %v", err) } - imageFsInfo, err := sp.provider.DockerImagesFsInfo() + imageFsInfo, err := sp.provider.ImagesFsInfo() if err != nil { - return nil, err + return nil, fmt.Errorf("failed DockerImagesFsInfo: %v", err) } imageStats, err := sp.runtime.ImageStats() if err != nil || imageStats == nil { - return nil, err + return nil, fmt.Errorf("failed ImageStats: %v", err) } sb := &summaryBuilder{sp.fsResourceAnalyzer, node, nodeConfig, rootFsInfo, imageFsInfo, *imageStats, infos} return sb.build() diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/status/generate.go b/vendor/k8s.io/kubernetes/pkg/kubelet/status/generate.go index 05d845470b..cc000929a0 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/status/generate.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/status/generate.go @@ -77,3 +77,58 @@ func GeneratePodReadyCondition(spec *api.PodSpec, containerStatuses []api.Contai Status: api.ConditionTrue, } } + +// GeneratePodInitializedCondition returns initialized condition if all init containers in a pod are ready, else it +// returns an uninitialized condition. +func GeneratePodInitializedCondition(spec *api.PodSpec, containerStatuses []api.ContainerStatus, podPhase api.PodPhase) api.PodCondition { + // Find if all containers are ready or not. + if containerStatuses == nil && len(spec.InitContainers) > 0 { + return api.PodCondition{ + Type: api.PodInitialized, + Status: api.ConditionFalse, + Reason: "UnknownContainerStatuses", + } + } + unknownContainers := []string{} + unreadyContainers := []string{} + for _, container := range spec.InitContainers { + if containerStatus, ok := api.GetContainerStatus(containerStatuses, container.Name); ok { + if !containerStatus.Ready { + unreadyContainers = append(unreadyContainers, container.Name) + } + } else { + unknownContainers = append(unknownContainers, container.Name) + } + } + + // If all init containers are known and succeeded, just return PodCompleted. + if podPhase == api.PodSucceeded && len(unknownContainers) == 0 { + return api.PodCondition{ + Type: api.PodInitialized, + Status: api.ConditionTrue, + Reason: "PodCompleted", + } + } + + unreadyMessages := []string{} + if len(unknownContainers) > 0 { + unreadyMessages = append(unreadyMessages, fmt.Sprintf("containers with unknown status: %s", unknownContainers)) + } + if len(unreadyContainers) > 0 { + unreadyMessages = append(unreadyMessages, fmt.Sprintf("containers with incomplete status: %s", unreadyContainers)) + } + unreadyMessage := strings.Join(unreadyMessages, ", ") + if unreadyMessage != "" { + return api.PodCondition{ + Type: api.PodInitialized, + Status: api.ConditionFalse, + Reason: "ContainersNotInitialized", + Message: unreadyMessage, + } + } + + return api.PodCondition{ + Type: api.PodInitialized, + Status: api.ConditionTrue, + } +} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/status/manager.go b/vendor/k8s.io/kubernetes/pkg/kubelet/status/manager.go index 815cc78091..c9b5b1e4e2 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/status/manager.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/status/manager.go @@ -172,20 +172,14 @@ func (m *manager) SetContainerReadiness(podUID types.UID, containerID kubecontai } // Find the container to update. - containerIndex := -1 - for i, c := range oldStatus.status.ContainerStatuses { - if c.ContainerID == containerID.String() { - containerIndex = i - break - } - } - if containerIndex == -1 { + containerStatus, _, ok := findContainerStatus(&oldStatus.status, containerID.String()) + if !ok { glog.Warningf("Container readiness changed for unknown container: %q - %q", format.Pod(pod), containerID.String()) return } - if oldStatus.status.ContainerStatuses[containerIndex].Ready == ready { + if containerStatus.Ready == ready { glog.V(4).Infof("Container readiness unchanged (%v): %q - %q", ready, format.Pod(pod), containerID.String()) return @@ -196,7 +190,8 @@ func (m *manager) SetContainerReadiness(podUID types.UID, containerID kubecontai if err != nil { return } - status.ContainerStatuses[containerIndex].Ready = ready + containerStatus, _, _ = findContainerStatus(&status, containerID.String()) + containerStatus.Ready = ready // Update pod condition. readyConditionIndex := -1 @@ -217,6 +212,31 @@ func (m *manager) SetContainerReadiness(podUID types.UID, containerID kubecontai m.updateStatusInternal(pod, status, false) } +func findContainerStatus(status *api.PodStatus, containerID string) (containerStatus *api.ContainerStatus, init bool, ok bool) { + // Find the container to update. + containerIndex := -1 + for i, c := range status.ContainerStatuses { + if c.ContainerID == containerID { + containerIndex = i + break + } + } + if containerIndex != -1 { + return &status.ContainerStatuses[containerIndex], false, true + } + + for i, c := range status.InitContainerStatuses { + if c.ContainerID == containerID { + containerIndex = i + break + } + } + if containerIndex != -1 { + return &status.InitContainerStatuses[containerIndex], true, true + } + return nil, false, false +} + func (m *manager) TerminatePod(pod *api.Pod) { m.podStatusesLock.Lock() defer m.podStatusesLock.Unlock() @@ -233,6 +253,11 @@ func (m *manager) TerminatePod(pod *api.Pod) { Terminated: &api.ContainerStateTerminated{}, } } + for i := range status.InitContainerStatuses { + status.InitContainerStatuses[i].State = api.ContainerState{ + Terminated: &api.ContainerStateTerminated{}, + } + } m.updateStatusInternal(pod, pod.Status, true) } @@ -251,16 +276,27 @@ func (m *manager) updateStatusInternal(pod *api.Pod, status api.PodStatus, force } // Set ReadyCondition.LastTransitionTime. - if readyCondition := api.GetPodReadyCondition(status); readyCondition != nil { + if _, readyCondition := api.GetPodCondition(&status, api.PodReady); readyCondition != nil { // Need to set LastTransitionTime. lastTransitionTime := unversioned.Now() - oldReadyCondition := api.GetPodReadyCondition(oldStatus) + _, oldReadyCondition := api.GetPodCondition(&oldStatus, api.PodReady) if oldReadyCondition != nil && readyCondition.Status == oldReadyCondition.Status { lastTransitionTime = oldReadyCondition.LastTransitionTime } readyCondition.LastTransitionTime = lastTransitionTime } + // Set InitializedCondition.LastTransitionTime. + if _, initCondition := api.GetPodCondition(&status, api.PodInitialized); initCondition != nil { + // Need to set LastTransitionTime. + lastTransitionTime := unversioned.Now() + _, oldInitCondition := api.GetPodCondition(&oldStatus, api.PodInitialized) + if oldInitCondition != nil && initCondition.Status == oldInitCondition.Status { + lastTransitionTime = oldInitCondition.LastTransitionTime + } + initCondition.LastTransitionTime = lastTransitionTime + } + // ensure that the start time does not change across updates. if oldStatus.StartTime != nil && !oldStatus.StartTime.IsZero() { status.StartTime = oldStatus.StartTime @@ -490,6 +526,8 @@ func normalizeStatus(status *api.PodStatus) *api.PodStatus { normalizeTimeStamp(&condition.LastProbeTime) normalizeTimeStamp(&condition.LastTransitionTime) } + + // update container statuses for i := range status.ContainerStatuses { cstatus := &status.ContainerStatuses[i] normalizeContainerState(&cstatus.State) @@ -497,6 +535,15 @@ func normalizeStatus(status *api.PodStatus) *api.PodStatus { } // Sort the container statuses, so that the order won't affect the result of comparison sort.Sort(kubetypes.SortedContainerStatuses(status.ContainerStatuses)) + + // update init container statuses + for i := range status.InitContainerStatuses { + cstatus := &status.InitContainerStatuses[i] + normalizeContainerState(&cstatus.State) + normalizeContainerState(&cstatus.LastTerminationState) + } + // Sort the container statuses, so that the order won't affect the result of comparison + sort.Sort(kubetypes.SortedContainerStatuses(status.InitContainerStatuses)) return status } diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/util.go b/vendor/k8s.io/kubernetes/pkg/kubelet/util.go index a06a57ce56..ae2d94bfa1 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/util.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/util.go @@ -63,6 +63,11 @@ func canRunPod(pod *api.Pod) error { return fmt.Errorf("pod with UID %q specified privileged container, but is disallowed", pod.UID) } } + for _, container := range pod.Spec.InitContainers { + if securitycontext.HasPrivilegedRequest(&container) { + return fmt.Errorf("pod with UID %q specified privileged container, but is disallowed", pod.UID) + } + } } return nil } diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/util/ioutils/ioutils.go b/vendor/k8s.io/kubernetes/pkg/kubelet/util/ioutils/ioutils.go new file mode 100644 index 0000000000..fa700396ec --- /dev/null +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/util/ioutils/ioutils.go @@ -0,0 +1,37 @@ +/* +Copyright 2016 The Kubernetes Authors All rights reserved. + +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 ioutils + +import "io" + +// writeCloserWrapper represents a WriteCloser whose closer operation is noop. +type writeCloserWrapper struct { + Writer io.Writer +} + +func (w *writeCloserWrapper) Write(buf []byte) (int, error) { + return w.Writer.Write(buf) +} + +func (w *writeCloserWrapper) Close() error { + return nil +} + +// WriteCloserWrapper returns a writeCloserWrapper. +func WriteCloserWrapper(w io.Writer) io.WriteCloser { + return &writeCloserWrapper{w} +} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/volumes.go b/vendor/k8s.io/kubernetes/pkg/kubelet/volumes.go index 71ff3a24a8..fe2a78f694 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/volumes.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/volumes.go @@ -19,7 +19,9 @@ package kubelet import ( "fmt" "io/ioutil" + "os" "path" + "strconv" "github.com/golang/glog" "k8s.io/kubernetes/pkg/api" @@ -34,6 +36,10 @@ import ( "k8s.io/kubernetes/pkg/volume" ) +const ( + volumeGidAnnotationKey = "pv.beta.kubernetes.io/gid" +) + // This just exports required functions from kubelet proper, for use by volume // plugins. type volumeHost struct { @@ -126,8 +132,20 @@ func (kl *Kubelet) mountExternalVolumes(pod *api.Pod) (kubecontainer.VolumeMap, return nil, err } + var volSpec *volume.Spec + if pod.Spec.Volumes[i].VolumeSource.PersistentVolumeClaim != nil { + claimName := pod.Spec.Volumes[i].PersistentVolumeClaim.ClaimName + pv, err := kl.getPersistentVolumeByClaimName(claimName, pod.Namespace) + if err != nil { + glog.Errorf("Could not find persistentVolume for claim %s err %v", claimName, err) + return nil, err + } + kl.applyPersistentVolumeAnnotations(pv, pod) + volSpec = volume.NewSpecFromPersistentVolume(pv, pod.Spec.Volumes[i].PersistentVolumeClaim.ReadOnly) + } else { + volSpec = volume.NewSpecFromVolume(&pod.Spec.Volumes[i]) + } // Try to use a plugin for this volume. - volSpec := volume.NewSpecFromVolume(&pod.Spec.Volumes[i]) mounter, err := kl.newVolumeMounterFromPlugins(volSpec, pod, volume.VolumeOptions{RootContext: rootContext}) if err != nil { glog.Errorf("Could not create volume mounter for pod %s: %v", pod.UID, err) @@ -137,25 +155,33 @@ func (kl *Kubelet) mountExternalVolumes(pod *api.Pod) (kubecontainer.VolumeMap, // some volumes require attachment before mounter's setup. // The plugin can be nil, but non-nil errors are legitimate errors. // For non-nil plugins, Attachment to a node is required before Mounter's setup. - attacher, err := kl.newVolumeAttacherFromPlugins(volSpec, pod, volume.VolumeOptions{RootContext: rootContext}) + attacher, err := kl.newVolumeAttacherFromPlugins(volSpec, pod) if err != nil { glog.Errorf("Could not create volume attacher for pod %s: %v", pod.UID, err) return nil, err } if attacher != nil { - err = attacher.Attach(volSpec, kl.hostname) - if err != nil { + // If the device path is already mounted, avoid an expensive call to the + // cloud provider. + deviceMountPath := attacher.GetDeviceMountPath(volSpec) + notMountPoint, err := kl.mounter.IsLikelyNotMountPoint(deviceMountPath) + if err != nil && !os.IsNotExist(err) { return nil, err } + if notMountPoint { + err = attacher.Attach(volSpec, kl.hostname) + if err != nil { + return nil, err + } - devicePath, err := attacher.WaitForAttach(volSpec, maxWaitForVolumeOps) - if err != nil { - return nil, err - } + devicePath, err := attacher.WaitForAttach(volSpec, maxWaitForVolumeOps) + if err != nil { + return nil, err + } - deviceMountPath := attacher.GetDeviceMountPath(&volumeHost{kl}, volSpec) - if err = attacher.MountDevice(volSpec, devicePath, deviceMountPath, kl.mounter); err != nil { - return nil, err + if err = attacher.MountDevice(volSpec, devicePath, deviceMountPath, kl.mounter); err != nil { + return nil, err + } } } @@ -163,7 +189,7 @@ func (kl *Kubelet) mountExternalVolumes(pod *api.Pod) (kubecontainer.VolumeMap, if err != nil { return nil, err } - podVolumes[volSpec.Volume.Name] = kubecontainer.VolumeInfo{Mounter: mounter} + podVolumes[pod.Spec.Volumes[i].Name] = kubecontainer.VolumeInfo{Mounter: mounter} } return podVolumes, nil } @@ -270,6 +296,57 @@ func (kl *Kubelet) getPodVolumesFromDisk() map[string]cleaner { return currentVolumes } +func (kl *Kubelet) getPersistentVolumeByClaimName(claimName string, namespace string) (*api.PersistentVolume, error) { + claim, err := kl.kubeClient.Core().PersistentVolumeClaims(namespace).Get(claimName) + if err != nil { + glog.Errorf("Error finding claim: %+v\n", claimName) + return nil, err + } + glog.V(5).Infof("Found claim %v ", claim) + + if claim.Spec.VolumeName == "" { + return nil, fmt.Errorf("The claim %+v is not yet bound to a volume", claimName) + } + + pv, err := kl.kubeClient.Core().PersistentVolumes().Get(claim.Spec.VolumeName) + if err != nil { + glog.Errorf("Error finding persistent volume for claim: %+v\n", claimName) + return nil, err + } + + if pv.Spec.ClaimRef == nil { + return nil, fmt.Errorf("The volume is not yet bound to the claim. Expected to find the bind on volume.Spec.ClaimRef: %+v", pv) + } + + if pv.Spec.ClaimRef.UID != claim.UID { + return nil, fmt.Errorf("Expected volume.Spec.ClaimRef.UID %+v but have %+v", pv.Spec.ClaimRef.UID, claim.UID) + } + + return pv, nil +} + +func (kl *Kubelet) applyPersistentVolumeAnnotations(pv *api.PersistentVolume, pod *api.Pod) error { + // If a GID annotation is provided set the GID attribute. + if volumeGid, ok := pv.Annotations[volumeGidAnnotationKey]; ok { + gid, err := strconv.ParseInt(volumeGid, 10, 64) + if err != nil { + return fmt.Errorf("Invalid value for %s %v", volumeGidAnnotationKey, err) + } + + if pod.Spec.SecurityContext == nil { + pod.Spec.SecurityContext = &api.PodSecurityContext{} + } + for _, existingGid := range pod.Spec.SecurityContext.SupplementalGroups { + if gid == existingGid { + return nil + } + } + pod.Spec.SecurityContext.SupplementalGroups = append(pod.Spec.SecurityContext.SupplementalGroups, gid) + } + + return nil +} + // newVolumeMounterFromPlugins attempts to find a plugin by volume spec, pod // and volume options and then creates a Mounter. // Returns a valid Unmounter or an error. @@ -293,7 +370,7 @@ func (kl *Kubelet) newVolumeMounterFromPlugins(spec *volume.Spec, pod *api.Pod, // - an error if no plugin was found for the volume // or the attacher failed to instantiate // - nil if there is no appropriate attacher for this volume -func (kl *Kubelet) newVolumeAttacherFromPlugins(spec *volume.Spec, pod *api.Pod, opts volume.VolumeOptions) (volume.Attacher, error) { +func (kl *Kubelet) newVolumeAttacherFromPlugins(spec *volume.Spec, pod *api.Pod) (volume.Attacher, error) { plugin, err := kl.volumePluginMgr.FindAttachablePluginBySpec(spec) if err != nil { return nil, fmt.Errorf("can't use volume plugins for %s: %v", spec.Name(), err) diff --git a/vendor/k8s.io/kubernetes/pkg/labels/selector.go b/vendor/k8s.io/kubernetes/pkg/labels/selector.go index fb48b10e9e..ab64ecc809 100644 --- a/vendor/k8s.io/kubernetes/pkg/labels/selector.go +++ b/vendor/k8s.io/kubernetes/pkg/labels/selector.go @@ -764,19 +764,16 @@ func parse(selector string) (internalSelector, error) { return internalSelector(items), err } -var qualifiedNameErrorMsg string = fmt.Sprintf(`must be a qualified name (at most %d characters, matching regex %s), with an optional DNS subdomain prefix (at most %d characters, matching regex %s) and slash (/): e.g. "MyName" or "example.com/MyName"`, validation.QualifiedNameMaxLength, validation.QualifiedNameFmt, validation.DNS1123SubdomainMaxLength, validation.DNS1123SubdomainFmt) -var labelValueErrorMsg string = fmt.Sprintf(`must have at most %d characters, matching regex %s: e.g. "MyValue" or ""`, validation.LabelValueMaxLength, validation.LabelValueFmt) - func validateLabelKey(k string) error { - if !validation.IsQualifiedName(k) { - return fmt.Errorf("invalid label key: %s", qualifiedNameErrorMsg) + if errs := validation.IsQualifiedName(k); len(errs) != 0 { + return fmt.Errorf("invalid label key %q: %s", k, strings.Join(errs, "; ")) } return nil } func validateLabelValue(v string) error { - if !validation.IsValidLabelValue(v) { - return fmt.Errorf("invalid label value: %s", labelValueErrorMsg) + if errs := validation.IsValidLabelValue(v); len(errs) != 0 { + return fmt.Errorf("invalid label value: %q: %s", v, strings.Join(errs, "; ")) } return nil } diff --git a/vendor/k8s.io/kubernetes/pkg/master/master.go b/vendor/k8s.io/kubernetes/pkg/master/master.go index 93b396c91f..0b74b39cd1 100644 --- a/vendor/k8s.io/kubernetes/pkg/master/master.go +++ b/vendor/k8s.io/kubernetes/pkg/master/master.go @@ -41,6 +41,8 @@ import ( batchapiv2alpha1 "k8s.io/kubernetes/pkg/apis/batch/v2alpha1" "k8s.io/kubernetes/pkg/apis/extensions" extensionsapiv1beta1 "k8s.io/kubernetes/pkg/apis/extensions/v1beta1" + "k8s.io/kubernetes/pkg/apis/policy" + policyapiv1alpha1 "k8s.io/kubernetes/pkg/apis/policy/v1alpha1" "k8s.io/kubernetes/pkg/apiserver" apiservermetrics "k8s.io/kubernetes/pkg/apiserver/metrics" "k8s.io/kubernetes/pkg/genericapiserver" @@ -61,12 +63,14 @@ import ( limitrangeetcd "k8s.io/kubernetes/pkg/registry/limitrange/etcd" "k8s.io/kubernetes/pkg/registry/namespace" namespaceetcd "k8s.io/kubernetes/pkg/registry/namespace/etcd" + networkpolicyetcd "k8s.io/kubernetes/pkg/registry/networkpolicy/etcd" "k8s.io/kubernetes/pkg/registry/node" nodeetcd "k8s.io/kubernetes/pkg/registry/node/etcd" pvetcd "k8s.io/kubernetes/pkg/registry/persistentvolume/etcd" pvcetcd "k8s.io/kubernetes/pkg/registry/persistentvolumeclaim/etcd" petsetetcd "k8s.io/kubernetes/pkg/registry/petset/etcd" podetcd "k8s.io/kubernetes/pkg/registry/pod/etcd" + poddisruptionbudgetetcd "k8s.io/kubernetes/pkg/registry/poddisruptionbudget/etcd" pspetcd "k8s.io/kubernetes/pkg/registry/podsecuritypolicy/etcd" podtemplateetcd "k8s.io/kubernetes/pkg/registry/podtemplate/etcd" replicasetetcd "k8s.io/kubernetes/pkg/registry/replicaset/etcd" @@ -344,6 +348,38 @@ func (m *Master) InstallAPIs(c *Config) { allGroups = append(allGroups, group) } + if c.APIResourceConfigSource.AnyResourcesForVersionEnabled(policyapiv1alpha1.SchemeGroupVersion) { + policyResources := m.getPolicyResources(c) + policyGroupMeta := registered.GroupOrDie(policy.GroupName) + + // Hard code preferred group version to policy/v1alpha1 + policyGroupMeta.GroupVersion = policyapiv1alpha1.SchemeGroupVersion + + apiGroupInfo := genericapiserver.APIGroupInfo{ + GroupMeta: *policyGroupMeta, + VersionedResourcesStorageMap: map[string]map[string]rest.Storage{ + "v1alpha1": policyResources, + }, + OptionsExternalVersion: ®istered.GroupOrDie(api.GroupName).GroupVersion, + Scheme: api.Scheme, + ParameterCodec: api.ParameterCodec, + NegotiatedSerializer: api.Codecs, + } + apiGroupsInfo = append(apiGroupsInfo, apiGroupInfo) + + policyGVForDiscovery := unversioned.GroupVersionForDiscovery{ + GroupVersion: policyGroupMeta.GroupVersion.String(), + Version: policyGroupMeta.GroupVersion.Version, + } + group := unversioned.APIGroup{ + Name: policyGroupMeta.GroupVersion.Group, + Versions: []unversioned.GroupVersionForDiscovery{policyGVForDiscovery}, + PreferredVersion: policyGVForDiscovery, + } + allGroups = append(allGroups, group) + + } + if c.APIResourceConfigSource.AnyResourcesForVersionEnabled(appsapi.SchemeGroupVersion) { appsResources := m.getAppsResources(c) appsGroupMeta := registered.GroupOrDie(apps.GroupName) @@ -810,6 +846,10 @@ func (m *Master) getExtensionResources(c *Config) map[string]rest.Storage { storage["replicasets/status"] = replicaSetStorage.Status storage["replicasets/scale"] = replicaSetStorage.Scale } + networkPolicyStorage := networkpolicyetcd.NewREST(restOptions("networkpolicies")) + if c.APIResourceConfigSource.ResourceEnabled(version.WithResource("networkpolicies")) { + storage["networkpolicies"] = networkPolicyStorage + } return storage } @@ -839,7 +879,21 @@ func (m *Master) getBatchResources(c *Config, version unversioned.GroupVersion) return storage } -// getPetSetResources returns the resources for apps api +// getPolicyResources returns the resources for policy api +func (m *Master) getPolicyResources(c *Config) map[string]rest.Storage { + // TODO update when we support more than one version of this group + version := policyapiv1alpha1.SchemeGroupVersion + + storage := map[string]rest.Storage{} + if c.APIResourceConfigSource.ResourceEnabled(version.WithResource("poddisruptionbudgets")) { + poddisruptionbudgetStorage, poddisruptionbudgetStatusStorage := poddisruptionbudgetetcd.NewREST(m.GetRESTOptionsOrDie(c, policy.Resource("poddisruptionbudgets"))) + storage["poddisruptionbudgets"] = poddisruptionbudgetStorage + storage["poddisruptionbudgets/status"] = poddisruptionbudgetStatusStorage + } + return storage +} + +// getAppsResources returns the resources for apps api func (m *Master) getAppsResources(c *Config) map[string]rest.Storage { // TODO update when we support more than one version of this group version := appsapi.SchemeGroupVersion @@ -905,7 +959,7 @@ func (m *Master) IsTunnelSyncHealthy(req *http.Request) error { func DefaultAPIResourceConfigSource() *genericapiserver.ResourceConfig { ret := genericapiserver.NewResourceConfig() - ret.EnableVersions(apiv1.SchemeGroupVersion, extensionsapiv1beta1.SchemeGroupVersion, batchapiv1.SchemeGroupVersion, autoscalingapiv1.SchemeGroupVersion, appsapi.SchemeGroupVersion) + ret.EnableVersions(apiv1.SchemeGroupVersion, extensionsapiv1beta1.SchemeGroupVersion, batchapiv1.SchemeGroupVersion, autoscalingapiv1.SchemeGroupVersion, appsapi.SchemeGroupVersion, policyapiv1alpha1.SchemeGroupVersion) // all extensions resources except these are disabled by default ret.EnableResources( diff --git a/vendor/k8s.io/kubernetes/pkg/quota/evaluator/core/pods.go b/vendor/k8s.io/kubernetes/pkg/quota/evaluator/core/pods.go index da0b18a5e3..27a6ce83c8 100644 --- a/vendor/k8s.io/kubernetes/pkg/quota/evaluator/core/pods.go +++ b/vendor/k8s.io/kubernetes/pkg/quota/evaluator/core/pods.go @@ -23,12 +23,14 @@ import ( "k8s.io/kubernetes/pkg/admission" "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/resource" + "k8s.io/kubernetes/pkg/api/validation" clientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" "k8s.io/kubernetes/pkg/kubelet/qos/util" "k8s.io/kubernetes/pkg/quota" "k8s.io/kubernetes/pkg/quota/generic" "k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/util/sets" + "k8s.io/kubernetes/pkg/util/validation/field" ) // NewPodEvaluator returns an evaluator that can evaluate pods @@ -64,12 +66,26 @@ func NewPodEvaluator(kubeClient clientset.Interface) quota.Evaluator { } // PodConstraintsFunc verifies that all required resources are present on the pod +// In addition, it validates that the resources are valid (i.e. requests < limits) func PodConstraintsFunc(required []api.ResourceName, object runtime.Object) error { pod, ok := object.(*api.Pod) if !ok { return fmt.Errorf("Unexpected input object %v", object) } + // Pod level resources are often set during admission control + // As a consequence, we want to verify that resources are valid prior + // to ever charging quota prematurely in case they are not. + allErrs := field.ErrorList{} + fldPath := field.NewPath("spec").Child("containers") + for i, ctr := range pod.Spec.Containers { + idxPath := fldPath.Index(i) + allErrs = append(allErrs, validation.ValidateResourceRequirements(&ctr.Resources, idxPath.Child("resources"))...) + } + if len(allErrs) > 0 { + return allErrs.ToAggregate() + } + // TODO: fix this when we have pod level cgroups // since we do not yet pod level requests/limits, we need to ensure each // container makes an explict request or limit for a quota tracked resource diff --git a/vendor/k8s.io/kubernetes/pkg/quota/resources.go b/vendor/k8s.io/kubernetes/pkg/quota/resources.go index 0cb03a84af..0d5a750341 100644 --- a/vendor/k8s.io/kubernetes/pkg/quota/resources.go +++ b/vendor/k8s.io/kubernetes/pkg/quota/resources.go @@ -93,7 +93,7 @@ func Subtract(a api.ResourceList, b api.ResourceList) api.ResourceList { for key, value := range b { if _, found := result[key]; !found { quantity := *value.Copy() - quantity.Neg(value) + quantity.Neg() result[key] = quantity } } diff --git a/vendor/k8s.io/kubernetes/pkg/registry/cachesize/cachesize.go b/vendor/k8s.io/kubernetes/pkg/registry/cachesize/cachesize.go index 048597babc..b07a4cdff4 100644 --- a/vendor/k8s.io/kubernetes/pkg/registry/cachesize/cachesize.go +++ b/vendor/k8s.io/kubernetes/pkg/registry/cachesize/cachesize.go @@ -34,10 +34,12 @@ const ( Endpoints Resource = "endpoints" HorizontalPodAutoscalers Resource = "horizontalpodautoscalers" Ingress Resource = "ingress" + PodDisruptionBudget Resource = "poddisruptionbudgets" PetSet Resource = "petset" Jobs Resource = "jobs" LimitRanges Resource = "limitranges" Namespaces Resource = "namespaces" + NetworkPolicys Resource = "networkpolicies" Nodes Resource = "nodes" PersistentVolumes Resource = "persistentvolumes" PersistentVolumeClaims Resource = "persistentvolumeclaims" @@ -45,6 +47,7 @@ const ( PodTemplates Resource = "podtemplates" Replicasets Resource = "replicasets" ResourceQuotas Resource = "resourcequotas" + ScheduledJobs Resource = "scheduledjobs" Secrets Resource = "secrets" ServiceAccounts Resource = "serviceaccounts" Services Resource = "services" @@ -61,9 +64,11 @@ func init() { watchCacheSizes[HorizontalPodAutoscalers] = 100 watchCacheSizes[Ingress] = 100 watchCacheSizes[PetSet] = 100 + watchCacheSizes[PodDisruptionBudget] = 100 watchCacheSizes[Jobs] = 100 watchCacheSizes[LimitRanges] = 100 watchCacheSizes[Namespaces] = 100 + watchCacheSizes[NetworkPolicys] = 100 watchCacheSizes[Nodes] = 1000 watchCacheSizes[PersistentVolumes] = 100 watchCacheSizes[PersistentVolumeClaims] = 100 @@ -71,6 +76,7 @@ func init() { watchCacheSizes[PodTemplates] = 100 watchCacheSizes[Replicasets] = 100 watchCacheSizes[ResourceQuotas] = 100 + watchCacheSizes[ScheduledJobs] = 100 watchCacheSizes[Secrets] = 100 watchCacheSizes[ServiceAccounts] = 100 watchCacheSizes[Services] = 100 diff --git a/vendor/k8s.io/kubernetes/pkg/registry/generic/registry/store.go b/vendor/k8s.io/kubernetes/pkg/registry/generic/registry/store.go index 337143ce37..3e56d10b45 100644 --- a/vendor/k8s.io/kubernetes/pkg/registry/generic/registry/store.go +++ b/vendor/k8s.io/kubernetes/pkg/registry/generic/registry/store.go @@ -19,6 +19,7 @@ package registry import ( "fmt" "reflect" + "strings" "sync" "k8s.io/kubernetes/pkg/api" @@ -137,8 +138,8 @@ func NamespaceKeyFunc(ctx api.Context, prefix string, name string) (string, erro if len(name) == 0 { return "", kubeerr.NewBadRequest("Name parameter required.") } - if ok, msg := validation.IsValidPathSegmentName(name); !ok { - return "", kubeerr.NewBadRequest(fmt.Sprintf("Name parameter invalid: %v.", msg)) + if msgs := validation.IsValidPathSegmentName(name); len(msgs) != 0 { + return "", kubeerr.NewBadRequest(fmt.Sprintf("Name parameter invalid: %q: %s", name, strings.Join(msgs, ";"))) } key = key + "/" + name return key, nil @@ -149,8 +150,8 @@ func NoNamespaceKeyFunc(ctx api.Context, prefix string, name string) (string, er if len(name) == 0 { return "", kubeerr.NewBadRequest("Name parameter required.") } - if ok, msg := validation.IsValidPathSegmentName(name); !ok { - return "", kubeerr.NewBadRequest(fmt.Sprintf("Name parameter invalid: %v.", msg)) + if msgs := validation.IsValidPathSegmentName(name); len(msgs) != 0 { + return "", kubeerr.NewBadRequest(fmt.Sprintf("Name parameter invalid: %q: %s", name, strings.Join(msgs, ";"))) } key := prefix + "/" + name return key, nil diff --git a/vendor/k8s.io/kubernetes/pkg/volume/persistent_claim/doc.go b/vendor/k8s.io/kubernetes/pkg/registry/networkpolicy/doc.go similarity index 82% rename from vendor/k8s.io/kubernetes/pkg/volume/persistent_claim/doc.go rename to vendor/k8s.io/kubernetes/pkg/registry/networkpolicy/doc.go index fc1335a8ba..2cc5a21e9b 100644 --- a/vendor/k8s.io/kubernetes/pkg/volume/persistent_claim/doc.go +++ b/vendor/k8s.io/kubernetes/pkg/registry/networkpolicy/doc.go @@ -14,6 +14,4 @@ See the License for the specific language governing permissions and limitations under the License. */ -// Package persistent_claim contains the internal representation of persistent -// volume claims. -package persistent_claim +package networkpolicy diff --git a/vendor/k8s.io/kubernetes/pkg/registry/networkpolicy/etcd/etcd.go b/vendor/k8s.io/kubernetes/pkg/registry/networkpolicy/etcd/etcd.go new file mode 100644 index 0000000000..e3dea0f18c --- /dev/null +++ b/vendor/k8s.io/kubernetes/pkg/registry/networkpolicy/etcd/etcd.go @@ -0,0 +1,80 @@ +/* +Copyright 2015 The Kubernetes Authors All rights reserved. + +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 etcd + +import ( + "k8s.io/kubernetes/pkg/api" + extensionsapi "k8s.io/kubernetes/pkg/apis/extensions" + "k8s.io/kubernetes/pkg/fields" + "k8s.io/kubernetes/pkg/labels" + "k8s.io/kubernetes/pkg/registry/cachesize" + "k8s.io/kubernetes/pkg/registry/generic" + "k8s.io/kubernetes/pkg/registry/generic/registry" + "k8s.io/kubernetes/pkg/registry/networkpolicy" + "k8s.io/kubernetes/pkg/runtime" +) + +// rest implements a RESTStorage for network policies against etcd +type REST struct { + *registry.Store +} + +// NewREST returns a RESTStorage object that will work against network policies. +func NewREST(opts generic.RESTOptions) *REST { + prefix := "/networkpolicies" + + newListFunc := func() runtime.Object { return &extensionsapi.NetworkPolicyList{} } + storageInterface := opts.Decorator( + opts.Storage, cachesize.GetWatchCacheSizeByResource(cachesize.NetworkPolicys), &extensionsapi.NetworkPolicy{}, prefix, networkpolicy.Strategy, newListFunc) + + store := ®istry.Store{ + NewFunc: func() runtime.Object { return &extensionsapi.NetworkPolicy{} }, + + // NewListFunc returns an object capable of storing results of an etcd list. + NewListFunc: newListFunc, + // Produces a NetworkPolicy that etcd understands, to the root of the resource + // by combining the namespace in the context with the given prefix + KeyRootFunc: func(ctx api.Context) string { + return registry.NamespaceKeyRootFunc(ctx, prefix) + }, + // Produces a NetworkPolicy that etcd understands, to the resource by combining + // the namespace in the context with the given prefix + KeyFunc: func(ctx api.Context, name string) (string, error) { + return registry.NamespaceKeyFunc(ctx, prefix, name) + }, + // Retrieve the name field of a network policy + ObjectNameFunc: func(obj runtime.Object) (string, error) { + return obj.(*extensionsapi.NetworkPolicy).Name, nil + }, + // Used to match objects based on labels/fields for list and watch + PredicateFunc: func(label labels.Selector, field fields.Selector) generic.Matcher { + return networkpolicy.MatchNetworkPolicy(label, field) + }, + QualifiedResource: extensionsapi.Resource("networkpolicies"), + DeleteCollectionWorkers: opts.DeleteCollectionWorkers, + + // Used to validate controller creation + CreateStrategy: networkpolicy.Strategy, + + // Used to validate controller updates + UpdateStrategy: networkpolicy.Strategy, + DeleteStrategy: networkpolicy.Strategy, + + Storage: storageInterface, + } + return &REST{store} +} diff --git a/vendor/k8s.io/kubernetes/pkg/registry/networkpolicy/strategy.go b/vendor/k8s.io/kubernetes/pkg/registry/networkpolicy/strategy.go new file mode 100644 index 0000000000..b8217ac50c --- /dev/null +++ b/vendor/k8s.io/kubernetes/pkg/registry/networkpolicy/strategy.go @@ -0,0 +1,112 @@ +/* +Copyright 2014 The Kubernetes Authors All rights reserved. + +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 networkpolicy + +import ( + "fmt" + "reflect" + + "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/apis/extensions" + "k8s.io/kubernetes/pkg/apis/extensions/validation" + "k8s.io/kubernetes/pkg/fields" + "k8s.io/kubernetes/pkg/labels" + "k8s.io/kubernetes/pkg/registry/generic" + "k8s.io/kubernetes/pkg/runtime" + "k8s.io/kubernetes/pkg/util/validation/field" +) + +// networkPolicyStrategy implements verification logic for NetworkPolicys. +type networkPolicyStrategy struct { + runtime.ObjectTyper + api.NameGenerator +} + +// Strategy is the default logic that applies when creating and updating NetworkPolicy objects. +var Strategy = networkPolicyStrategy{api.Scheme, api.SimpleNameGenerator} + +// NamespaceScoped returns true because all NetworkPolicys need to be within a namespace. +func (networkPolicyStrategy) NamespaceScoped() bool { + return true +} + +// PrepareForCreate clears the status of an NetworkPolicy before creation. +func (networkPolicyStrategy) PrepareForCreate(obj runtime.Object) { + networkPolicy := obj.(*extensions.NetworkPolicy) + networkPolicy.Generation = 1 +} + +// PrepareForUpdate clears fields that are not allowed to be set by end users on update. +func (networkPolicyStrategy) PrepareForUpdate(obj, old runtime.Object) { + newNetworkPolicy := obj.(*extensions.NetworkPolicy) + oldNetworkPolicy := old.(*extensions.NetworkPolicy) + + // Any changes to the spec increment the generation number, any changes to the + // status should reflect the generation number of the corresponding object. + // See api.ObjectMeta description for more information on Generation. + if !reflect.DeepEqual(oldNetworkPolicy.Spec, newNetworkPolicy.Spec) { + newNetworkPolicy.Generation = oldNetworkPolicy.Generation + 1 + } +} + +// Validate validates a new NetworkPolicy. +func (networkPolicyStrategy) Validate(ctx api.Context, obj runtime.Object) field.ErrorList { + networkPolicy := obj.(*extensions.NetworkPolicy) + return validation.ValidateNetworkPolicy(networkPolicy) +} + +// Canonicalize normalizes the object after validation. +func (networkPolicyStrategy) Canonicalize(obj runtime.Object) { +} + +// AllowCreateOnUpdate is false for NetworkPolicy; this means you may not create one with a PUT request. +func (networkPolicyStrategy) AllowCreateOnUpdate() bool { + return false +} + +// ValidateUpdate is the default update validation for an end user. +func (networkPolicyStrategy) ValidateUpdate(ctx api.Context, obj, old runtime.Object) field.ErrorList { + validationErrorList := validation.ValidateNetworkPolicy(obj.(*extensions.NetworkPolicy)) + updateErrorList := validation.ValidateNetworkPolicyUpdate(obj.(*extensions.NetworkPolicy), old.(*extensions.NetworkPolicy)) + return append(validationErrorList, updateErrorList...) +} + +// AllowUnconditionalUpdate is the default update policy for NetworkPolicy objects. +func (networkPolicyStrategy) AllowUnconditionalUpdate() bool { + return true +} + +// NetworkPolicyToSelectableFields returns a field set that represents the object. +func NetworkPolicyToSelectableFields(networkPolicy *extensions.NetworkPolicy) fields.Set { + return generic.ObjectMetaFieldsSet(networkPolicy.ObjectMeta, true) +} + +// MatchNetworkPolicy is the filter used by the generic etcd backend to watch events +// from etcd to clients of the apiserver only interested in specific labels/fields. +func MatchNetworkPolicy(label labels.Selector, field fields.Selector) generic.Matcher { + return &generic.SelectionPredicate{ + Label: label, + Field: field, + GetAttrs: func(obj runtime.Object) (labels.Set, fields.Set, error) { + networkPolicy, ok := obj.(*extensions.NetworkPolicy) + if !ok { + return nil, nil, fmt.Errorf("given object is not a NetworkPolicy.") + } + return labels.Set(networkPolicy.ObjectMeta.Labels), NetworkPolicyToSelectableFields(networkPolicy), nil + }, + } +} diff --git a/vendor/k8s.io/kubernetes/pkg/registry/poddisruptionbudget/doc.go b/vendor/k8s.io/kubernetes/pkg/registry/poddisruptionbudget/doc.go new file mode 100644 index 0000000000..717f26d21d --- /dev/null +++ b/vendor/k8s.io/kubernetes/pkg/registry/poddisruptionbudget/doc.go @@ -0,0 +1,17 @@ +/* +Copyright 2015 The Kubernetes Authors All rights reserved. + +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 poddisruptionbudget diff --git a/vendor/k8s.io/kubernetes/pkg/registry/poddisruptionbudget/etcd/etcd.go b/vendor/k8s.io/kubernetes/pkg/registry/poddisruptionbudget/etcd/etcd.go new file mode 100644 index 0000000000..d148cb1887 --- /dev/null +++ b/vendor/k8s.io/kubernetes/pkg/registry/poddisruptionbudget/etcd/etcd.go @@ -0,0 +1,96 @@ +/* +Copyright 2015 The Kubernetes Authors All rights reserved. + +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 etcd + +import ( + "k8s.io/kubernetes/pkg/api" + policyapi "k8s.io/kubernetes/pkg/apis/policy" + "k8s.io/kubernetes/pkg/fields" + "k8s.io/kubernetes/pkg/labels" + "k8s.io/kubernetes/pkg/registry/cachesize" + "k8s.io/kubernetes/pkg/registry/generic" + "k8s.io/kubernetes/pkg/registry/generic/registry" + "k8s.io/kubernetes/pkg/registry/poddisruptionbudget" + "k8s.io/kubernetes/pkg/runtime" +) + +// rest implements a RESTStorage for pod disruption budgets against etcd +type REST struct { + *registry.Store +} + +// NewREST returns a RESTStorage object that will work against pod disruption budgets. +func NewREST(opts generic.RESTOptions) (*REST, *StatusREST) { + prefix := "/poddisruptionbudgets" + + newListFunc := func() runtime.Object { return &policyapi.PodDisruptionBudgetList{} } + storageInterface := opts.Decorator( + opts.Storage, cachesize.GetWatchCacheSizeByResource(cachesize.PodDisruptionBudget), &policyapi.PodDisruptionBudget{}, prefix, poddisruptionbudget.Strategy, newListFunc) + + store := ®istry.Store{ + NewFunc: func() runtime.Object { return &policyapi.PodDisruptionBudget{} }, + + // NewListFunc returns an object capable of storing results of an etcd list. + NewListFunc: newListFunc, + // Produces a podDisruptionBudget that etcd understands, to the root of the resource + // by combining the namespace in the context with the given prefix + KeyRootFunc: func(ctx api.Context) string { + return registry.NamespaceKeyRootFunc(ctx, prefix) + }, + // Produces a podDisruptionBudget that etcd understands, to the resource by combining + // the namespace in the context with the given prefix + KeyFunc: func(ctx api.Context, name string) (string, error) { + return registry.NamespaceKeyFunc(ctx, prefix, name) + }, + // Retrieve the name field of a pod disruption budget + ObjectNameFunc: func(obj runtime.Object) (string, error) { + return obj.(*policyapi.PodDisruptionBudget).Name, nil + }, + // Used to match objects based on labels/fields for list and watch + PredicateFunc: func(label labels.Selector, field fields.Selector) generic.Matcher { + return poddisruptionbudget.MatchPodDisruptionBudget(label, field) + }, + QualifiedResource: policyapi.Resource("poddisruptionbudgets"), + DeleteCollectionWorkers: opts.DeleteCollectionWorkers, + + // Used to validate controller creation + CreateStrategy: poddisruptionbudget.Strategy, + + // Used to validate controller updates + UpdateStrategy: poddisruptionbudget.Strategy, + DeleteStrategy: poddisruptionbudget.Strategy, + + Storage: storageInterface, + } + statusStore := *store + statusStore.UpdateStrategy = poddisruptionbudget.StatusStrategy + return &REST{store}, &StatusREST{store: &statusStore} +} + +// StatusREST implements the REST endpoint for changing the status of an podDisruptionBudget +type StatusREST struct { + store *registry.Store +} + +func (r *StatusREST) New() runtime.Object { + return &policyapi.PodDisruptionBudget{} +} + +// Update alters the status subset of an object. +func (r *StatusREST) Update(ctx api.Context, obj runtime.Object) (runtime.Object, bool, error) { + return r.store.Update(ctx, obj) +} diff --git a/vendor/k8s.io/kubernetes/pkg/registry/poddisruptionbudget/strategy.go b/vendor/k8s.io/kubernetes/pkg/registry/poddisruptionbudget/strategy.go new file mode 100644 index 0000000000..4b32b95326 --- /dev/null +++ b/vendor/k8s.io/kubernetes/pkg/registry/poddisruptionbudget/strategy.go @@ -0,0 +1,138 @@ +/* +Copyright 2014 The Kubernetes Authors All rights reserved. + +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 poddisruptionbudget + +import ( + "fmt" + "reflect" + + "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/apis/policy" + "k8s.io/kubernetes/pkg/apis/policy/validation" + "k8s.io/kubernetes/pkg/fields" + "k8s.io/kubernetes/pkg/labels" + "k8s.io/kubernetes/pkg/registry/generic" + "k8s.io/kubernetes/pkg/runtime" + "k8s.io/kubernetes/pkg/util/validation/field" +) + +// podDisruptionBudgetStrategy implements verification logic for PodDisruptionBudgets. +type podDisruptionBudgetStrategy struct { + runtime.ObjectTyper + api.NameGenerator +} + +// Strategy is the default logic that applies when creating and updating PodDisruptionBudget objects. +var Strategy = podDisruptionBudgetStrategy{api.Scheme, api.SimpleNameGenerator} + +// NamespaceScoped returns true because all PodDisruptionBudget' need to be within a namespace. +func (podDisruptionBudgetStrategy) NamespaceScoped() bool { + return true +} + +// PrepareForCreate clears the status of an PodDisruptionBudget before creation. +func (podDisruptionBudgetStrategy) PrepareForCreate(obj runtime.Object) { + podDisruptionBudget := obj.(*policy.PodDisruptionBudget) + // create cannot set status + podDisruptionBudget.Status = policy.PodDisruptionBudgetStatus{} + + podDisruptionBudget.Generation = 1 +} + +// PrepareForUpdate clears fields that are not allowed to be set by end users on update. +func (podDisruptionBudgetStrategy) PrepareForUpdate(obj, old runtime.Object) { + newPodDisruptionBudget := obj.(*policy.PodDisruptionBudget) + oldPodDisruptionBudget := old.(*policy.PodDisruptionBudget) + // Update is not allowed to set status + newPodDisruptionBudget.Status = oldPodDisruptionBudget.Status + + // Any changes to the spec increment the generation number, any changes to the + // status should reflect the generation number of the corresponding object. + // See api.ObjectMeta description for more information on Generation. + if !reflect.DeepEqual(oldPodDisruptionBudget.Spec, newPodDisruptionBudget.Spec) { + newPodDisruptionBudget.Generation = oldPodDisruptionBudget.Generation + 1 + } +} + +// Validate validates a new PodDisruptionBudget. +func (podDisruptionBudgetStrategy) Validate(ctx api.Context, obj runtime.Object) field.ErrorList { + podDisruptionBudget := obj.(*policy.PodDisruptionBudget) + return validation.ValidatePodDisruptionBudget(podDisruptionBudget) +} + +// Canonicalize normalizes the object after validation. +func (podDisruptionBudgetStrategy) Canonicalize(obj runtime.Object) { +} + +// AllowCreateOnUpdate is true for PodDisruptionBudget; this means you may create one with a PUT request. +func (podDisruptionBudgetStrategy) AllowCreateOnUpdate() bool { + return false +} + +// ValidateUpdate is the default update validation for an end user. +func (podDisruptionBudgetStrategy) ValidateUpdate(ctx api.Context, obj, old runtime.Object) field.ErrorList { + validationErrorList := validation.ValidatePodDisruptionBudget(obj.(*policy.PodDisruptionBudget)) + updateErrorList := validation.ValidatePodDisruptionBudgetUpdate(obj.(*policy.PodDisruptionBudget), old.(*policy.PodDisruptionBudget)) + return append(validationErrorList, updateErrorList...) +} + +// AllowUnconditionalUpdate is the default update policy for PodDisruptionBudget objects. +func (podDisruptionBudgetStrategy) AllowUnconditionalUpdate() bool { + return true +} + +// PodDisruptionBudgetToSelectableFields returns a field set that represents the object. +func PodDisruptionBudgetToSelectableFields(podDisruptionBudget *policy.PodDisruptionBudget) fields.Set { + return generic.ObjectMetaFieldsSet(podDisruptionBudget.ObjectMeta, true) +} + +// MatchPodDisruptionBudget is the filter used by the generic etcd backend to watch events +// from etcd to clients of the apiserver only interested in specific labels/fields. +func MatchPodDisruptionBudget(label labels.Selector, field fields.Selector) generic.Matcher { + return &generic.SelectionPredicate{ + Label: label, + Field: field, + GetAttrs: func(obj runtime.Object) (labels.Set, fields.Set, error) { + podDisruptionBudget, ok := obj.(*policy.PodDisruptionBudget) + if !ok { + return nil, nil, fmt.Errorf("given object is not a PodDisruptionBudget.") + } + return labels.Set(podDisruptionBudget.ObjectMeta.Labels), PodDisruptionBudgetToSelectableFields(podDisruptionBudget), nil + }, + } +} + +type podDisruptionBudgetStatusStrategy struct { + podDisruptionBudgetStrategy +} + +var StatusStrategy = podDisruptionBudgetStatusStrategy{Strategy} + +// PrepareForUpdate clears fields that are not allowed to be set by end users on update of status +func (podDisruptionBudgetStatusStrategy) PrepareForUpdate(obj, old runtime.Object) { + newPodDisruptionBudget := obj.(*policy.PodDisruptionBudget) + oldPodDisruptionBudget := old.(*policy.PodDisruptionBudget) + // status changes are not allowed to update spec + newPodDisruptionBudget.Spec = oldPodDisruptionBudget.Spec +} + +// ValidateUpdate is the default update validation for an end user updating status +func (podDisruptionBudgetStatusStrategy) ValidateUpdate(ctx api.Context, obj, old runtime.Object) field.ErrorList { + // TODO: Validate status updates. + return field.ErrorList{} + // return validation.ValidatePodDisruptionBudgetStatusUpdate(obj.(*policy.PodDisruptionBudget), old.(*policy.PodDisruptionBudget)) +} diff --git a/vendor/k8s.io/kubernetes/pkg/registry/thirdpartyresource/strategy.go b/vendor/k8s.io/kubernetes/pkg/registry/thirdpartyresource/strategy.go index 8a0ca2fcda..38a256d6d8 100644 --- a/vendor/k8s.io/kubernetes/pkg/registry/thirdpartyresource/strategy.go +++ b/vendor/k8s.io/kubernetes/pkg/registry/thirdpartyresource/strategy.go @@ -33,12 +33,11 @@ import ( // strategy implements behavior for ThirdPartyResource objects type strategy struct { runtime.ObjectTyper - api.NameGenerator } // Strategy is the default logic that applies when creating and updating ThirdPartyResource // objects via the REST API. -var Strategy = strategy{api.Scheme, api.SimpleNameGenerator} +var Strategy = strategy{api.Scheme} var _ = rest.RESTCreateStrategy(Strategy) @@ -48,6 +47,10 @@ func (strategy) NamespaceScoped() bool { return false } +func (strategy) GenerateName(base string) string { + return "" +} + func (strategy) PrepareForCreate(obj runtime.Object) { } diff --git a/vendor/k8s.io/kubernetes/pkg/runtime/helper.go b/vendor/k8s.io/kubernetes/pkg/runtime/helper.go index 4606ddea7c..dca37b8f4e 100644 --- a/vendor/k8s.io/kubernetes/pkg/runtime/helper.go +++ b/vendor/k8s.io/kubernetes/pkg/runtime/helper.go @@ -68,6 +68,47 @@ func UnsafeObjectConvertor(scheme *Scheme) ObjectConvertor { return unsafeObjectConvertor{scheme} } +// SetField puts the value of src, into fieldName, which must be a member of v. +// The value of src must be assignable to the field. +func SetField(src interface{}, v reflect.Value, fieldName string) error { + field := v.FieldByName(fieldName) + if !field.IsValid() { + return fmt.Errorf("couldn't find %v field in %#v", fieldName, v.Interface()) + } + srcValue := reflect.ValueOf(src) + if srcValue.Type().AssignableTo(field.Type()) { + field.Set(srcValue) + return nil + } + if srcValue.Type().ConvertibleTo(field.Type()) { + field.Set(srcValue.Convert(field.Type())) + return nil + } + return fmt.Errorf("couldn't assign/convert %v to %v", srcValue.Type(), field.Type()) +} + +// Field puts the value of fieldName, which must be a member of v, into dest, +// which must be a variable to which this field's value can be assigned. +func Field(v reflect.Value, fieldName string, dest interface{}) error { + field := v.FieldByName(fieldName) + if !field.IsValid() { + return fmt.Errorf("couldn't find %v field in %#v", fieldName, v.Interface()) + } + destValue, err := conversion.EnforcePtr(dest) + if err != nil { + return err + } + if field.Type().AssignableTo(destValue.Type()) { + destValue.Set(field) + return nil + } + if field.Type().ConvertibleTo(destValue.Type()) { + destValue.Set(field.Convert(destValue.Type())) + return nil + } + return fmt.Errorf("couldn't assign/convert %v to %v", field.Type(), destValue.Type()) +} + // fieldPtr puts the address of fieldName, which must be a member of v, // into dest, which must be an address of a variable to which this field's // address can be assigned. diff --git a/vendor/k8s.io/kubernetes/pkg/runtime/types.go b/vendor/k8s.io/kubernetes/pkg/runtime/types.go index 58b7843ffb..d50f642890 100644 --- a/vendor/k8s.io/kubernetes/pkg/runtime/types.go +++ b/vendor/k8s.io/kubernetes/pkg/runtime/types.go @@ -17,6 +17,11 @@ limitations under the License. package runtime import ( + "fmt" + + "github.com/golang/glog" + + "k8s.io/kubernetes/pkg/api/meta/metatypes" "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/types" ) @@ -196,6 +201,71 @@ func (u *Unstructured) setNestedMap(value map[string]string, fields ...string) { setNestedMap(u.Object, value, fields...) } +func extractOwnerReference(src interface{}) metatypes.OwnerReference { + v := src.(map[string]interface{}) + return metatypes.OwnerReference{ + Kind: getNestedString(v, "kind"), + Name: getNestedString(v, "name"), + APIVersion: getNestedString(v, "apiVersion"), + UID: (types.UID)(getNestedString(v, "uid")), + } +} + +func setOwnerReference(src metatypes.OwnerReference) map[string]interface{} { + ret := make(map[string]interface{}) + setNestedField(ret, src.Kind, "kind") + setNestedField(ret, src.Name, "name") + setNestedField(ret, src.APIVersion, "apiVersion") + setNestedField(ret, string(src.UID), "uid") + return ret +} + +func getOwnerReferences(object map[string]interface{}) ([]map[string]interface{}, error) { + field := getNestedField(object, "metadata", "ownerReferences") + if field == nil { + return nil, fmt.Errorf("cannot find field metadata.ownerReferences in %v", object) + } + ownerReferences, ok := field.([]map[string]interface{}) + if ok { + return ownerReferences, nil + } + // TODO: This is hacky... + interfaces, ok := field.([]interface{}) + if !ok { + return nil, fmt.Errorf("expect metadata.ownerReferences to be a slice in %#v", object) + } + ownerReferences = make([]map[string]interface{}, 0, len(interfaces)) + for i := 0; i < len(interfaces); i++ { + r, ok := interfaces[i].(map[string]interface{}) + if !ok { + return nil, fmt.Errorf("expect element metadata.ownerReferences to be a map[string]interface{} in %#v", object) + } + ownerReferences = append(ownerReferences, r) + } + return ownerReferences, nil +} + +func (u *Unstructured) GetOwnerReferences() []metatypes.OwnerReference { + original, err := getOwnerReferences(u.Object) + if err != nil { + glog.V(6).Info(err) + return nil + } + ret := make([]metatypes.OwnerReference, 0, len(original)) + for i := 0; i < len(original); i++ { + ret = append(ret, extractOwnerReference(original[i])) + } + return ret +} + +func (u *Unstructured) SetOwnerReferences(references []metatypes.OwnerReference) { + var newReferences = make([]map[string]interface{}, 0, len(references)) + for i := 0; i < len(references); i++ { + newReferences = append(newReferences, setOwnerReference(references[i])) + } + u.setNestedField(newReferences, "metadata", "ownerReferences") +} + func (u *Unstructured) GetAPIVersion() string { return getNestedString(u.Object, "apiVersion") } diff --git a/vendor/k8s.io/kubernetes/pkg/runtime/unstructured.go b/vendor/k8s.io/kubernetes/pkg/runtime/unstructured.go index 24fe1357ac..11a1e93628 100644 --- a/vendor/k8s.io/kubernetes/pkg/runtime/unstructured.go +++ b/vendor/k8s.io/kubernetes/pkg/runtime/unstructured.go @@ -18,7 +18,10 @@ package runtime import ( gojson "encoding/json" + "errors" + "fmt" "io" + "strings" "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/util/json" @@ -98,6 +101,13 @@ func (s unstructuredJSONScheme) decodeInto(data []byte, obj Object) error { return s.decodeToUnstructured(data, x) case *UnstructuredList: return s.decodeToList(data, x) + case *VersionedObjects: + u := new(Unstructured) + err := s.decodeToUnstructured(data, u) + if err == nil { + x.Objects = []Object{u} + } + return err default: return json.Unmarshal(data, x) } @@ -128,6 +138,12 @@ func (s unstructuredJSONScheme) decodeToList(data []byte, list *UnstructuredList return err } + // For typed lists, e.g., a PodList, API server doesn't set each item's + // APIVersion and Kind. We need to set it. + listAPIVersion := list.GetAPIVersion() + listKind := list.GetKind() + itemKind := strings.TrimSuffix(listKind, "List") + delete(list.Object, "items") list.Items = nil for _, i := range dList.Items { @@ -135,7 +151,49 @@ func (s unstructuredJSONScheme) decodeToList(data []byte, list *UnstructuredList if err := s.decodeToUnstructured([]byte(i), unstruct); err != nil { return err } + // This is hacky. Set the item's Kind and APIVersion to those inferred + // from the List. + if len(unstruct.GetKind()) == 0 && len(unstruct.GetAPIVersion()) == 0 { + unstruct.SetKind(itemKind) + unstruct.SetAPIVersion(listAPIVersion) + } list.Items = append(list.Items, unstruct) } return nil } + +// UnstructuredObjectConverter is an ObjectConverter for use with +// Unstructured objects. Since it has no schema or type information, +// it will only succeed for no-op conversions. This is provided as a +// sane implementation for APIs that require an object converter. +type UnstructuredObjectConverter struct{} + +func (UnstructuredObjectConverter) Convert(in, out interface{}) error { + unstructIn, ok := in.(*Unstructured) + if !ok { + return fmt.Errorf("input type %T in not valid for unstructured conversion", in) + } + + unstructOut, ok := out.(*Unstructured) + if !ok { + return fmt.Errorf("output type %T in not valid for unstructured conversion", out) + } + + // maybe deep copy the map? It is documented in the + // ObjectConverter interface that this function is not + // guaranteeed to not mutate the input. Or maybe set the input + // object to nil. + unstructOut.Object = unstructIn.Object + return nil +} + +func (UnstructuredObjectConverter) ConvertToVersion(in Object, outVersion unversioned.GroupVersion) (Object, error) { + if gvk := in.GetObjectKind().GroupVersionKind(); gvk.GroupVersion() != outVersion { + return nil, errors.New("unstructured converter cannot convert versions") + } + return in, nil +} + +func (UnstructuredObjectConverter) ConvertFieldLabel(version, kind, label, value string) (string, string, error) { + return "", "", errors.New("unstructured cannot convert field labels") +} diff --git a/vendor/k8s.io/kubernetes/pkg/security/podsecuritypolicy/util/util.go b/vendor/k8s.io/kubernetes/pkg/security/podsecuritypolicy/util/util.go index 4c2935b4cb..097b1a6c21 100644 --- a/vendor/k8s.io/kubernetes/pkg/security/podsecuritypolicy/util/util.go +++ b/vendor/k8s.io/kubernetes/pkg/security/podsecuritypolicy/util/util.go @@ -57,7 +57,8 @@ func GetAllFSTypesAsSet() sets.String { string(extensions.CephFS), string(extensions.DownwardAPI), string(extensions.FC), - string(extensions.ConfigMap)) + string(extensions.ConfigMap), + string(extensions.VsphereVolume)) return fstypes } @@ -102,6 +103,8 @@ func GetVolumeFSType(v api.Volume) (extensions.FSType, error) { return extensions.AzureFile, nil case v.ConfigMap != nil: return extensions.ConfigMap, nil + case v.VsphereVolume != nil: + return extensions.VsphereVolume, nil } return "", fmt.Errorf("unknown volume type for volume: %#v", v) diff --git a/vendor/k8s.io/kubernetes/pkg/serviceaccount/util.go b/vendor/k8s.io/kubernetes/pkg/serviceaccount/util.go index 6079123642..487b0f1569 100644 --- a/vendor/k8s.io/kubernetes/pkg/serviceaccount/util.go +++ b/vendor/k8s.io/kubernetes/pkg/serviceaccount/util.go @@ -52,10 +52,10 @@ func SplitUsername(username string) (string, string, error) { return "", "", invalidUsernameErr } namespace, name := parts[0], parts[1] - if ok, _ := validation.ValidateNamespaceName(namespace, false); !ok { + if len(validation.ValidateNamespaceName(namespace, false)) != 0 { return "", "", invalidUsernameErr } - if ok, _ := validation.ValidateServiceAccountName(name, false); !ok { + if len(validation.ValidateServiceAccountName(name, false)) != 0 { return "", "", invalidUsernameErr } return namespace, name, nil diff --git a/vendor/k8s.io/kubernetes/pkg/storage/etcd/etcd_helper.go b/vendor/k8s.io/kubernetes/pkg/storage/etcd/etcd_helper.go index 42f2bc83c5..40c9337a06 100644 --- a/vendor/k8s.io/kubernetes/pkg/storage/etcd/etcd_helper.go +++ b/vendor/k8s.io/kubernetes/pkg/storage/etcd/etcd_helper.go @@ -361,7 +361,7 @@ func (h *etcdHelper) GetToList(ctx context.Context, key string, filter storage.F // decodeNodeList walks the tree of each node in the list and decodes into the specified object func (h *etcdHelper) decodeNodeList(nodes []*etcd.Node, filter storage.FilterFunc, slicePtr interface{}) error { trace := util.NewTrace("decodeNodeList " + getTypeName(slicePtr)) - defer trace.LogIfLong(500 * time.Millisecond) + defer trace.LogIfLong(400 * time.Millisecond) v, err := conversion.EnforcePtr(slicePtr) if err != nil || v.Kind() != reflect.Slice { // This should not happen at runtime. @@ -406,7 +406,7 @@ func (h *etcdHelper) List(ctx context.Context, key string, resourceVersion strin glog.Errorf("Context is nil") } trace := util.NewTrace("List " + getTypeName(listObj)) - defer trace.LogIfLong(time.Second) + defer trace.LogIfLong(400 * time.Millisecond) listPtr, err := meta.GetItemsPtr(listObj) if err != nil { return err diff --git a/vendor/k8s.io/kubernetes/pkg/storage/etcd/etcd_watcher.go b/vendor/k8s.io/kubernetes/pkg/storage/etcd/etcd_watcher.go index 93c1f7a9ae..c856b59ccf 100644 --- a/vendor/k8s.io/kubernetes/pkg/storage/etcd/etcd_watcher.go +++ b/vendor/k8s.io/kubernetes/pkg/storage/etcd/etcd_watcher.go @@ -399,6 +399,9 @@ func (w *etcdWatcher) sendModify(res *etcd.Response) { if res.PrevNode != nil && res.PrevNode.Value != "" { // Ignore problems reading the old object. if oldObj, err = w.decodeObject(res.PrevNode); err == nil { + if err := w.versioner.UpdateObject(oldObj, res.Node.ModifiedIndex); err != nil { + utilruntime.HandleError(fmt.Errorf("failure to version api object (%d) %#v: %v", res.Node.ModifiedIndex, oldObj, err)) + } oldObjPasses = w.filter(oldObj) } } diff --git a/vendor/k8s.io/kubernetes/pkg/storage/etcd3/compact.go b/vendor/k8s.io/kubernetes/pkg/storage/etcd3/compact.go index cfe73c5970..ddd8e312c3 100644 --- a/vendor/k8s.io/kubernetes/pkg/storage/etcd3/compact.go +++ b/vendor/k8s.io/kubernetes/pkg/storage/etcd3/compact.go @@ -51,7 +51,7 @@ func StartCompactor(ctx context.Context, client *clientv3.Client) { var emptyStruct struct{} for _, ep := range client.Endpoints() { if _, ok := endpointsMap[ep]; ok { - glog.V(4).Infof("compactor already exists for endpoints %v") + glog.V(4).Infof("compactor already exists for endpoints %v", client.Endpoints()) return } } diff --git a/vendor/k8s.io/kubernetes/pkg/storage/storagebackend/config.go b/vendor/k8s.io/kubernetes/pkg/storage/storagebackend/config.go index 6d3b127e77..d1e17c87ca 100644 --- a/vendor/k8s.io/kubernetes/pkg/storage/storagebackend/config.go +++ b/vendor/k8s.io/kubernetes/pkg/storage/storagebackend/config.go @@ -16,13 +16,6 @@ limitations under the License. package storagebackend -import ( - "fmt" - - "k8s.io/kubernetes/pkg/runtime" - "k8s.io/kubernetes/pkg/storage" -) - const ( StorageTypeUnset = "" StorageTypeETCD2 = "etcd2" @@ -33,8 +26,6 @@ const ( type Config struct { // Type defines the type of storage backend, e.g. "etcd2", etcd3". Default ("") is "etcd2". Type string - // Codec is used to serialize/deserialize objects. - Codec runtime.Codec // Prefix is the prefix to all keys passed to storage.Interface methods. Prefix string // ServerList is the list of storage servers to connect with. @@ -50,19 +41,3 @@ type Config struct { // We will drop the cache once using protobuf. DeserializationCacheSize int } - -// Create creates a storage backend based on given config. -func Create(c Config) (storage.Interface, error) { - switch c.Type { - case StorageTypeUnset, StorageTypeETCD2: - return newETCD2Storage(c) - case StorageTypeETCD3: - // TODO: We have the following features to implement: - // - Support secure connection by using key, cert, and CA files. - // - Honor "https" scheme to support secure connection in gRPC. - // - Support non-quorum read. - return newETCD3Storage(c) - default: - return nil, fmt.Errorf("unknown storage type: %s", c.Type) - } -} diff --git a/vendor/k8s.io/kubernetes/pkg/storage/storagebackend/etdc2.go b/vendor/k8s.io/kubernetes/pkg/storage/storagebackend/factory/etcd2.go similarity index 86% rename from vendor/k8s.io/kubernetes/pkg/storage/storagebackend/etdc2.go rename to vendor/k8s.io/kubernetes/pkg/storage/storagebackend/factory/etcd2.go index b1176042ee..4ac526d999 100644 --- a/vendor/k8s.io/kubernetes/pkg/storage/storagebackend/etdc2.go +++ b/vendor/k8s.io/kubernetes/pkg/storage/storagebackend/factory/etcd2.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package storagebackend +package factory import ( "net" @@ -23,12 +23,15 @@ import ( etcd2client "github.com/coreos/etcd/client" "github.com/coreos/etcd/pkg/transport" + + "k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/storage" "k8s.io/kubernetes/pkg/storage/etcd" + "k8s.io/kubernetes/pkg/storage/storagebackend" utilnet "k8s.io/kubernetes/pkg/util/net" ) -func newETCD2Storage(c Config) (storage.Interface, error) { +func newETCD2Storage(c storagebackend.Config, codec runtime.Codec) (storage.Interface, error) { tr, err := newTransportForETCD2(c.CertFile, c.KeyFile, c.CAFile) if err != nil { return nil, err @@ -37,7 +40,7 @@ func newETCD2Storage(c Config) (storage.Interface, error) { if err != nil { return nil, err } - return etcd.NewEtcdStorage(client, c.Codec, c.Prefix, c.Quorum, c.DeserializationCacheSize), nil + return etcd.NewEtcdStorage(client, codec, c.Prefix, c.Quorum, c.DeserializationCacheSize), nil } func newETCD2Client(tr *http.Transport, serverList []string) (etcd2client.Client, error) { diff --git a/vendor/k8s.io/kubernetes/pkg/storage/storagebackend/etcd3.go b/vendor/k8s.io/kubernetes/pkg/storage/storagebackend/factory/etcd3.go similarity index 81% rename from vendor/k8s.io/kubernetes/pkg/storage/storagebackend/etcd3.go rename to vendor/k8s.io/kubernetes/pkg/storage/storagebackend/factory/etcd3.go index 7699eec7b3..add091a069 100644 --- a/vendor/k8s.io/kubernetes/pkg/storage/storagebackend/etcd3.go +++ b/vendor/k8s.io/kubernetes/pkg/storage/storagebackend/factory/etcd3.go @@ -14,18 +14,21 @@ See the License for the specific language governing permissions and limitations under the License. */ -package storagebackend +package factory import ( "strings" "github.com/coreos/etcd/clientv3" "golang.org/x/net/context" + + "k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/storage" "k8s.io/kubernetes/pkg/storage/etcd3" + "k8s.io/kubernetes/pkg/storage/storagebackend" ) -func newETCD3Storage(c Config) (storage.Interface, error) { +func newETCD3Storage(c storagebackend.Config, codec runtime.Codec) (storage.Interface, error) { endpoints := c.ServerList for i, s := range endpoints { endpoints[i] = strings.TrimLeft(s, "http://") @@ -38,5 +41,5 @@ func newETCD3Storage(c Config) (storage.Interface, error) { return nil, err } etcd3.StartCompactor(context.Background(), client) - return etcd3.New(client, c.Codec, c.Prefix), nil + return etcd3.New(client, codec, c.Prefix), nil } diff --git a/vendor/k8s.io/kubernetes/pkg/storage/storagebackend/factory/factory.go b/vendor/k8s.io/kubernetes/pkg/storage/storagebackend/factory/factory.go new file mode 100644 index 0000000000..cc7ae052e9 --- /dev/null +++ b/vendor/k8s.io/kubernetes/pkg/storage/storagebackend/factory/factory.go @@ -0,0 +1,41 @@ +/* +Copyright 2016 The Kubernetes Authors All rights reserved. + +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 factory + +import ( + "fmt" + + "k8s.io/kubernetes/pkg/runtime" + "k8s.io/kubernetes/pkg/storage" + "k8s.io/kubernetes/pkg/storage/storagebackend" +) + +// Create creates a storage backend based on given config. +func Create(c storagebackend.Config, codec runtime.Codec) (storage.Interface, error) { + switch c.Type { + case storagebackend.StorageTypeUnset, storagebackend.StorageTypeETCD2: + return newETCD2Storage(c, codec) + case storagebackend.StorageTypeETCD3: + // TODO: We have the following features to implement: + // - Support secure connection by using key, cert, and CA files. + // - Honor "https" scheme to support secure connection in gRPC. + // - Support non-quorum read. + return newETCD3Storage(c, codec) + default: + return nil, fmt.Errorf("unknown storage type: %s", c.Type) + } +} diff --git a/vendor/k8s.io/kubernetes/pkg/storage/util.go b/vendor/k8s.io/kubernetes/pkg/storage/util.go index c8f3b02f19..6595a67638 100644 --- a/vendor/k8s.io/kubernetes/pkg/storage/util.go +++ b/vendor/k8s.io/kubernetes/pkg/storage/util.go @@ -71,8 +71,8 @@ func NamespaceKeyFunc(prefix string, obj runtime.Object) (string, error) { return "", err } name := meta.GetName() - if ok, msg := validation.IsValidPathSegmentName(name); !ok { - return "", fmt.Errorf("invalid name: %v", msg) + if msgs := validation.IsValidPathSegmentName(name); len(msgs) != 0 { + return "", fmt.Errorf("invalid name: %v", msgs) } return prefix + "/" + meta.GetNamespace() + "/" + name, nil } @@ -83,8 +83,8 @@ func NoNamespaceKeyFunc(prefix string, obj runtime.Object) (string, error) { return "", err } name := meta.GetName() - if ok, msg := validation.IsValidPathSegmentName(name); !ok { - return "", fmt.Errorf("invalid name: %v", msg) + if msgs := validation.IsValidPathSegmentName(name); len(msgs) != 0 { + return "", fmt.Errorf("invalid name: %v", msgs) } return prefix + "/" + name, nil } diff --git a/vendor/k8s.io/kubernetes/pkg/storage/watch_cache.go b/vendor/k8s.io/kubernetes/pkg/storage/watch_cache.go index 3b34479fa2..3e5ce5d730 100644 --- a/vendor/k8s.io/kubernetes/pkg/storage/watch_cache.go +++ b/vendor/k8s.io/kubernetes/pkg/storage/watch_cache.go @@ -324,3 +324,8 @@ func (w *watchCache) GetAllEventsSince(resourceVersion uint64) ([]watchCacheEven defer w.RUnlock() return w.GetAllEventsSinceThreadUnsafe(resourceVersion) } + +func (w *watchCache) Resync() error { + // Nothing to do + return nil +} diff --git a/vendor/k8s.io/kubernetes/pkg/util/bandwidth/utils.go b/vendor/k8s.io/kubernetes/pkg/util/bandwidth/utils.go index 989096f934..b501e9b5c8 100644 --- a/vendor/k8s.io/kubernetes/pkg/util/bandwidth/utils.go +++ b/vendor/k8s.io/kubernetes/pkg/util/bandwidth/utils.go @@ -38,18 +38,22 @@ func validateBandwidthIsReasonable(rsrc *resource.Quantity) error { func ExtractPodBandwidthResources(podAnnotations map[string]string) (ingress, egress *resource.Quantity, err error) { str, found := podAnnotations["kubernetes.io/ingress-bandwidth"] if found { - if ingress, err = resource.ParseQuantity(str); err != nil { + ingressValue, err := resource.ParseQuantity(str) + if err != nil { return nil, nil, err } + ingress = &ingressValue if err := validateBandwidthIsReasonable(ingress); err != nil { return nil, nil, err } } str, found = podAnnotations["kubernetes.io/egress-bandwidth"] if found { - if egress, err = resource.ParseQuantity(str); err != nil { + egressValue, err := resource.ParseQuantity(str) + if err != nil { return nil, nil, err } + egress = &egressValue if err := validateBandwidthIsReasonable(egress); err != nil { return nil, nil, err } diff --git a/vendor/k8s.io/kubernetes/pkg/util/cache/lruexpirecache.go b/vendor/k8s.io/kubernetes/pkg/util/cache/lruexpirecache.go new file mode 100644 index 0000000000..22f7f27679 --- /dev/null +++ b/vendor/k8s.io/kubernetes/pkg/util/cache/lruexpirecache.go @@ -0,0 +1,66 @@ +/* +Copyright 2016 The Kubernetes Authors All rights reserved. + +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 cache + +import ( + "sync" + "time" + + "github.com/golang/groupcache/lru" +) + +type LRUExpireCache struct { + cache *lru.Cache + lock sync.RWMutex +} + +func NewLRUExpireCache(maxSize int) *LRUExpireCache { + return &LRUExpireCache{cache: lru.New(maxSize)} +} + +type cacheEntry struct { + value interface{} + expireTime time.Time +} + +func (c *LRUExpireCache) Add(key lru.Key, value interface{}, ttl time.Duration) { + c.lock.Lock() + defer c.lock.Unlock() + c.cache.Add(key, &cacheEntry{value, time.Now().Add(ttl)}) + // Remove entry from cache after ttl. + time.AfterFunc(ttl, func() { c.remove(key) }) +} + +func (c *LRUExpireCache) Get(key lru.Key) (interface{}, bool) { + c.lock.RLock() + defer c.lock.RUnlock() + e, ok := c.cache.Get(key) + if !ok { + return nil, false + } + if time.Now().After(e.(*cacheEntry).expireTime) { + go c.remove(key) + return nil, false + } + return e.(*cacheEntry).value, true +} + +func (c *LRUExpireCache) remove(key lru.Key) { + c.lock.Lock() + defer c.lock.Unlock() + c.cache.Remove(key) +} diff --git a/vendor/k8s.io/kubernetes/pkg/util/httpstream/spdy/roundtripper.go b/vendor/k8s.io/kubernetes/pkg/util/httpstream/spdy/roundtripper.go index ca7e9370ec..6091c4e4b1 100644 --- a/vendor/k8s.io/kubernetes/pkg/util/httpstream/spdy/roundtripper.go +++ b/vendor/k8s.io/kubernetes/pkg/util/httpstream/spdy/roundtripper.go @@ -125,6 +125,10 @@ func (s *SpdyRoundTripper) dial(req *http.Request) (net.Conn, error) { return nil, err } + if s.tlsConfig == nil { + s.tlsConfig = &tls.Config{} + } + if len(s.tlsConfig.ServerName) == 0 { s.tlsConfig.ServerName = host } diff --git a/vendor/k8s.io/kubernetes/pkg/util/net/http.go b/vendor/k8s.io/kubernetes/pkg/util/net/http.go index a5000a8b14..99d4cd2621 100644 --- a/vendor/k8s.io/kubernetes/pkg/util/net/http.go +++ b/vendor/k8s.io/kubernetes/pkg/util/net/http.go @@ -153,8 +153,14 @@ func GetClientIP(req *http.Request) net.IP { } // Fallback to Remote Address in request, which will give the correct client IP when there is no proxy. - ip := net.ParseIP(req.RemoteAddr) - return ip + // Remote Address in Go's HTTP server is in the form host:port so we need to split that first. + host, _, err := net.SplitHostPort(req.RemoteAddr) + if err == nil { + return net.ParseIP(host) + } + + // Fallback if Remote Address was just IP. + return net.ParseIP(req.RemoteAddr) } var defaultProxyFuncPointer = fmt.Sprintf("%p", http.ProxyFromEnvironment) diff --git a/vendor/k8s.io/kubernetes/pkg/util/rand/rand.go b/vendor/k8s.io/kubernetes/pkg/util/rand/rand.go index 6649f811b3..1f646fbd90 100644 --- a/vendor/k8s.io/kubernetes/pkg/util/rand/rand.go +++ b/vendor/k8s.io/kubernetes/pkg/util/rand/rand.go @@ -32,7 +32,7 @@ var rng = struct { rand: rand.New(rand.NewSource(time.Now().UTC().UnixNano())), } -// Intn generates an integer in range 0->max. +// Intn generates an integer in range [0,max). // By design this should panic if input is invalid, <= 0. func Intn(max int) int { rng.Lock() @@ -40,6 +40,22 @@ func Intn(max int) int { return rng.rand.Intn(max) } +// IntnRange generates an integer in range [min,max). +// By design this should panic if input is invalid, <= 0. +func IntnRange(min, max int) int { + rng.Lock() + defer rng.Unlock() + return rng.rand.Intn(max-min) + min +} + +// IntnRange generates an int64 integer in range [min,max). +// By design this should panic if input is invalid, <= 0. +func Int63nRange(min, max int64) int64 { + rng.Lock() + defer rng.Unlock() + return rng.rand.Int63n(max-min) + min +} + // Seed seeds the rng with the provided seed. func Seed(seed int64) { rng.Lock() diff --git a/vendor/k8s.io/kubernetes/pkg/util/system/system_utils.go b/vendor/k8s.io/kubernetes/pkg/util/system/system_utils.go new file mode 100644 index 0000000000..57576abebd --- /dev/null +++ b/vendor/k8s.io/kubernetes/pkg/util/system/system_utils.go @@ -0,0 +1,28 @@ +/* +Copyright 2016 The Kubernetes Authors All rights reserved. + +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 system + +import ( + "strings" + + "k8s.io/kubernetes/pkg/api" +) + +// TODO: find a better way of figuring out if given node is a registered master. +func IsMasterNode(node *api.Node) bool { + return strings.HasSuffix(node.Name, "master") +} diff --git a/vendor/k8s.io/kubernetes/pkg/util/validation/validation.go b/vendor/k8s.io/kubernetes/pkg/util/validation/validation.go index aada324655..9361a4bfac 100644 --- a/vendor/k8s.io/kubernetes/pkg/util/validation/validation.go +++ b/vendor/k8s.io/kubernetes/pkg/util/validation/validation.go @@ -17,6 +17,7 @@ limitations under the License. package validation import ( + "fmt" "math" "net" "regexp" @@ -25,12 +26,17 @@ import ( const qnameCharFmt string = "[A-Za-z0-9]" const qnameExtCharFmt string = "[-A-Za-z0-9_.]" -const QualifiedNameFmt string = "(" + qnameCharFmt + qnameExtCharFmt + "*)?" + qnameCharFmt -const QualifiedNameMaxLength int = 63 +const qualifiedNameFmt string = "(" + qnameCharFmt + qnameExtCharFmt + "*)?" + qnameCharFmt +const qualifiedNameMaxLength int = 63 -var qualifiedNameRegexp = regexp.MustCompile("^" + QualifiedNameFmt + "$") +var qualifiedNameRegexp = regexp.MustCompile("^" + qualifiedNameFmt + "$") -func IsQualifiedName(value string) bool { +// IsQualifiedName tests whether the value passed is what Kubernetes calls a +// "qualified name". This is a format used in various places throughout the +// system. If the value is not valid, a list of error strings is returned. +// Otherwise an empty list (or nil) is returned. +func IsQualifiedName(value string) []string { + var errs []string parts := strings.Split(value, "/") var name string switch len(parts) { @@ -39,23 +45,44 @@ func IsQualifiedName(value string) bool { case 2: var prefix string prefix, name = parts[0], parts[1] - if prefix == "" || !IsDNS1123Subdomain(prefix) { - return false + if len(prefix) == 0 { + errs = append(errs, "prefix part "+EmptyError()) + } else if msgs := IsDNS1123Subdomain(prefix); len(msgs) != 0 { + errs = append(errs, prefixEach(msgs, "prefix part ")...) } default: - return false + return append(errs, RegexError(qualifiedNameFmt, "MyName", "my.name", "123-abc")+ + " with an optional DNS subdomain prefix and '/' (e.g. 'example.com/MyName'") } - return name != "" && len(name) <= QualifiedNameMaxLength && qualifiedNameRegexp.MatchString(name) + if len(name) == 0 { + errs = append(errs, "name part "+EmptyError()) + } else if len(name) > qualifiedNameMaxLength { + errs = append(errs, "name part "+MaxLenError(qualifiedNameMaxLength)) + } + if !qualifiedNameRegexp.MatchString(name) { + errs = append(errs, "name part "+RegexError(qualifiedNameFmt, "MyName", "my.name", "123-abc")) + } + return errs } -const LabelValueFmt string = "(" + QualifiedNameFmt + ")?" +const labelValueFmt string = "(" + qualifiedNameFmt + ")?" const LabelValueMaxLength int = 63 -var labelValueRegexp = regexp.MustCompile("^" + LabelValueFmt + "$") +var labelValueRegexp = regexp.MustCompile("^" + labelValueFmt + "$") -func IsValidLabelValue(value string) bool { - return (len(value) <= LabelValueMaxLength && labelValueRegexp.MatchString(value)) +// IsValidLabelValue tests whether the value passed is a valid label value. If +// the value is not valid, a list of error strings is returned. Otherwise an +// empty list (or nil) is returned. +func IsValidLabelValue(value string) []string { + var errs []string + if len(value) > LabelValueMaxLength { + errs = append(errs, MaxLenError(LabelValueMaxLength)) + } + if !labelValueRegexp.MatchString(value) { + errs = append(errs, RegexError(labelValueFmt, "MyValue", "my_value", "12345")) + } + return errs } const DNS1123LabelFmt string = "[a-z0-9]([-a-z0-9]*[a-z0-9])?" @@ -65,8 +92,15 @@ var dns1123LabelRegexp = regexp.MustCompile("^" + DNS1123LabelFmt + "$") // IsDNS1123Label tests for a string that conforms to the definition of a label in // DNS (RFC 1123). -func IsDNS1123Label(value string) bool { - return len(value) <= DNS1123LabelMaxLength && dns1123LabelRegexp.MatchString(value) +func IsDNS1123Label(value string) []string { + var errs []string + if len(value) > DNS1123LabelMaxLength { + errs = append(errs, MaxLenError(DNS1123LabelMaxLength)) + } + if !dns1123LabelRegexp.MatchString(value) { + errs = append(errs, RegexError(DNS1123LabelFmt, "my-name", "123-abc")) + } + return errs } const DNS1123SubdomainFmt string = DNS1123LabelFmt + "(\\." + DNS1123LabelFmt + ")*" @@ -76,8 +110,15 @@ var dns1123SubdomainRegexp = regexp.MustCompile("^" + DNS1123SubdomainFmt + "$") // IsDNS1123Subdomain tests for a string that conforms to the definition of a // subdomain in DNS (RFC 1123). -func IsDNS1123Subdomain(value string) bool { - return len(value) <= DNS1123SubdomainMaxLength && dns1123SubdomainRegexp.MatchString(value) +func IsDNS1123Subdomain(value string) []string { + var errs []string + if len(value) > DNS1123SubdomainMaxLength { + errs = append(errs, MaxLenError(DNS1123SubdomainMaxLength)) + } + if !dns1123SubdomainRegexp.MatchString(value) { + errs = append(errs, RegexError(DNS1123SubdomainFmt, "example.com")) + } + return errs } const DNS952LabelFmt string = "[a-z]([-a-z0-9]*[a-z0-9])?" @@ -87,8 +128,15 @@ var dns952LabelRegexp = regexp.MustCompile("^" + DNS952LabelFmt + "$") // IsDNS952Label tests for a string that conforms to the definition of a label in // DNS (RFC 952). -func IsDNS952Label(value string) bool { - return len(value) <= DNS952LabelMaxLength && dns952LabelRegexp.MatchString(value) +func IsDNS952Label(value string) []string { + var errs []string + if len(value) > DNS952LabelMaxLength { + errs = append(errs, MaxLenError(DNS952LabelMaxLength)) + } + if !dns952LabelRegexp.MatchString(value) { + errs = append(errs, RegexError(DNS952LabelFmt, "my-name", "abc-123")) + } + return errs } const CIdentifierFmt string = "[A-Za-z_][A-Za-z0-9_]*" @@ -177,3 +225,38 @@ var httpHeaderNameRegexp = regexp.MustCompile("^" + HTTPHeaderNameFmt + "$") func IsHTTPHeaderName(value string) bool { return httpHeaderNameRegexp.MatchString(value) } + +// MaxLenError returns a string explanation of a "string too long" validation +// failure. +func MaxLenError(length int) string { + return fmt.Sprintf("must be no more than %d characters", length) +} + +// RegexError returns a string explanation of a regex validation failure. +func RegexError(fmt string, examples ...string) string { + s := "must match the regex " + fmt + if len(examples) == 0 { + return s + } + s += " (e.g. " + for i := range examples { + if i > 0 { + s += " or " + } + s += "'" + examples[i] + "'" + } + return s + ")" +} + +// EmptyError returns a string explanation of a "must not be empty" validation +// failure. +func EmptyError() string { + return "must be non-empty" +} + +func prefixEach(msgs []string, prefix string) []string { + for i := range msgs { + msgs[i] = prefix + msgs[i] + } + return msgs +} diff --git a/vendor/k8s.io/kubernetes/pkg/util/workqueue/default_rate_limiters.go b/vendor/k8s.io/kubernetes/pkg/util/workqueue/default_rate_limiters.go new file mode 100644 index 0000000000..6ca484b62c --- /dev/null +++ b/vendor/k8s.io/kubernetes/pkg/util/workqueue/default_rate_limiters.go @@ -0,0 +1,204 @@ +/* +Copyright 2016 The Kubernetes Authors All rights reserved. + +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 workqueue + +import ( + "math" + "sync" + "time" + + "github.com/juju/ratelimit" +) + +type RateLimiter interface { + // When gets an item and gets to decide how long that item should wait + When(item interface{}) time.Duration + // Forget indicates that an item is finished being retried. Doesn't matter whether its for perm failing + // or for success, we'll stop tracking it + Forget(item interface{}) + // NumRequeues returns back how many failures the item has had + NumRequeues(item interface{}) int +} + +// DefaultControllerRateLimiter is a no-arg constructor for a default rate limiter for a workqueue. It has +// both overall and per-item rate limitting. The overall is a token bucket and the per-item is exponential +func DefaultControllerRateLimiter() RateLimiter { + return NewMaxOfRateLimiter( + DefaultItemBasedRateLimiter(), + // 10 qps, 100 bucket size. This is only for retry speed and its only the overall factor (not per item) + &BucketRateLimiter{Bucket: ratelimit.NewBucketWithRate(float64(10), int64(100))}, + ) +} + +// BucketRateLimiter adapts a standard bucket to the workqueue ratelimiter API +type BucketRateLimiter struct { + *ratelimit.Bucket +} + +var _ RateLimiter = &BucketRateLimiter{} + +func (r *BucketRateLimiter) When(item interface{}) time.Duration { + return r.Bucket.Take(1) +} + +func (r *BucketRateLimiter) NumRequeues(item interface{}) int { + return 0 +} + +func (r *BucketRateLimiter) Forget(item interface{}) { +} + +// ItemExponentialFailureRateLimiter does a simple baseDelay*10^ limit +// dealing with max failures and expiration are up to the caller +type ItemExponentialFailureRateLimiter struct { + failuresLock sync.Mutex + failures map[interface{}]int + + baseDelay time.Duration + maxDelay time.Duration +} + +var _ RateLimiter = &ItemExponentialFailureRateLimiter{} + +func NewItemExponentialFailureRateLimiter(baseDelay time.Duration, maxDelay time.Duration) RateLimiter { + return &ItemExponentialFailureRateLimiter{ + failures: map[interface{}]int{}, + baseDelay: baseDelay, + maxDelay: maxDelay, + } +} + +func DefaultItemBasedRateLimiter() RateLimiter { + return NewItemExponentialFailureRateLimiter(1*time.Millisecond, 1000*time.Second) +} + +func (r *ItemExponentialFailureRateLimiter) When(item interface{}) time.Duration { + r.failuresLock.Lock() + defer r.failuresLock.Unlock() + + r.failures[item] = r.failures[item] + 1 + + calculated := r.baseDelay * time.Duration(math.Pow10(r.failures[item]-1)) + if calculated > r.maxDelay { + return r.maxDelay + } + + return calculated +} + +func (r *ItemExponentialFailureRateLimiter) NumRequeues(item interface{}) int { + r.failuresLock.Lock() + defer r.failuresLock.Unlock() + + return r.failures[item] +} + +func (r *ItemExponentialFailureRateLimiter) Forget(item interface{}) { + r.failuresLock.Lock() + defer r.failuresLock.Unlock() + + delete(r.failures, item) +} + +// ItemFastSlowRateLimiter does a quick retry for a certain number of attempts, then a slow retry after that +type ItemFastSlowRateLimiter struct { + failuresLock sync.Mutex + failures map[interface{}]int + + maxFastAttempts int + fastDelay time.Duration + slowDelay time.Duration +} + +var _ RateLimiter = &ItemFastSlowRateLimiter{} + +func NewItemFastSlowRateLimiter(fastDelay, slowDelay time.Duration, maxFastAttempts int) RateLimiter { + return &ItemFastSlowRateLimiter{ + failures: map[interface{}]int{}, + fastDelay: fastDelay, + slowDelay: slowDelay, + maxFastAttempts: maxFastAttempts, + } +} + +func (r *ItemFastSlowRateLimiter) When(item interface{}) time.Duration { + r.failuresLock.Lock() + defer r.failuresLock.Unlock() + + r.failures[item] = r.failures[item] + 1 + + if r.failures[item] <= r.maxFastAttempts { + return r.fastDelay + } + + return r.slowDelay +} + +func (r *ItemFastSlowRateLimiter) NumRequeues(item interface{}) int { + r.failuresLock.Lock() + defer r.failuresLock.Unlock() + + return r.failures[item] +} + +func (r *ItemFastSlowRateLimiter) Forget(item interface{}) { + r.failuresLock.Lock() + defer r.failuresLock.Unlock() + + delete(r.failures, item) +} + +// MaxOfRateLimiter calls every RateLimiter and returns the worst case response +// When used with a token bucket limiter, the burst could be apparently exceeded in cases where particular items +// were separately delayed a longer time. +type MaxOfRateLimiter struct { + limiters []RateLimiter +} + +func (r *MaxOfRateLimiter) When(item interface{}) time.Duration { + ret := time.Duration(0) + for _, limiter := range r.limiters { + curr := limiter.When(item) + if curr > ret { + ret = curr + } + } + + return ret +} + +func NewMaxOfRateLimiter(limiters ...RateLimiter) RateLimiter { + return &MaxOfRateLimiter{limiters: limiters} +} + +func (r *MaxOfRateLimiter) NumRequeues(item interface{}) int { + ret := 0 + for _, limiter := range r.limiters { + curr := limiter.NumRequeues(item) + if curr > ret { + ret = curr + } + } + + return ret +} + +func (r *MaxOfRateLimiter) Forget(item interface{}) { + for _, limiter := range r.limiters { + limiter.Forget(item) + } +} diff --git a/vendor/k8s.io/kubernetes/pkg/util/workqueue/rate_limitting_queue.go b/vendor/k8s.io/kubernetes/pkg/util/workqueue/rate_limitting_queue.go new file mode 100644 index 0000000000..272ba52d9e --- /dev/null +++ b/vendor/k8s.io/kubernetes/pkg/util/workqueue/rate_limitting_queue.go @@ -0,0 +1,61 @@ +/* +Copyright 2016 The Kubernetes Authors All rights reserved. + +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 workqueue + +// RateLimitingInterface is an Interface that can Add an item at a later time. This makes it easier to +// requeue items after failures without ending up in a hot-loop. +type RateLimitingInterface interface { + DelayingInterface + // AddRateLimited adds an item to the workqueue after the rate limiter says its ok + AddRateLimited(item interface{}) + + // Forget indicates that an item is finished being retried. Doesn't matter whether its for perm failing + // or for success, we'll stop the rate limiter from tracking it. This only clears the `rateLimiter`, you + // still have to call `Done` on the queue. + Forget(item interface{}) + // NumRequeues returns back how many times the item was requeued + NumRequeues(item interface{}) int +} + +// NewRateLimitingQueue constructs a new workqueue with rateLimited queuing ability +// Remember to call Forget! If you don't, you may end up tracking failures forever. +func NewRateLimitingQueue(rateLimiter RateLimiter) RateLimitingInterface { + return &rateLimitingType{ + DelayingInterface: NewDelayingQueue(), + rateLimiter: rateLimiter, + } +} + +// rateLimitingType wraps an Interface and provides rateLimited re-enquing +type rateLimitingType struct { + DelayingInterface + + rateLimiter RateLimiter +} + +// AddRateLimited AddAfter's the item based on the time when the rate limiter says its ok +func (q *rateLimitingType) AddRateLimited(item interface{}) { + q.DelayingInterface.AddAfter(item, q.rateLimiter.When(item)) +} + +func (q *rateLimitingType) NumRequeues(item interface{}) int { + return q.rateLimiter.NumRequeues(item) +} + +func (q *rateLimitingType) Forget(item interface{}) { + q.rateLimiter.Forget(item) +} diff --git a/vendor/k8s.io/kubernetes/pkg/volume/aws_ebs/aws_ebs.go b/vendor/k8s.io/kubernetes/pkg/volume/aws_ebs/aws_ebs.go index dfbdae8053..d21bf0cac1 100644 --- a/vendor/k8s.io/kubernetes/pkg/volume/aws_ebs/aws_ebs.go +++ b/vendor/k8s.io/kubernetes/pkg/volume/aws_ebs/aws_ebs.go @@ -408,14 +408,35 @@ type awsElasticBlockStoreProvisioner struct { var _ volume.Provisioner = &awsElasticBlockStoreProvisioner{} -func (c *awsElasticBlockStoreProvisioner) Provision(pv *api.PersistentVolume) error { +func (c *awsElasticBlockStoreProvisioner) Provision() (*api.PersistentVolume, error) { volumeID, sizeGB, labels, err := c.manager.CreateVolume(c) if err != nil { - return err + return nil, err } - pv.Spec.PersistentVolumeSource.AWSElasticBlockStore.VolumeID = volumeID - pv.Spec.Capacity = api.ResourceList{ - api.ResourceName(api.ResourceStorage): resource.MustParse(fmt.Sprintf("%dGi", sizeGB)), + + pv := &api.PersistentVolume{ + ObjectMeta: api.ObjectMeta{ + Name: c.options.PVName, + Labels: map[string]string{}, + Annotations: map[string]string{ + "kubernetes.io/createdby": "aws-ebs-dynamic-provisioner", + }, + }, + Spec: api.PersistentVolumeSpec{ + PersistentVolumeReclaimPolicy: c.options.PersistentVolumeReclaimPolicy, + AccessModes: c.options.AccessModes, + Capacity: api.ResourceList{ + api.ResourceName(api.ResourceStorage): resource.MustParse(fmt.Sprintf("%dGi", sizeGB)), + }, + PersistentVolumeSource: api.PersistentVolumeSource{ + AWSElasticBlockStore: &api.AWSElasticBlockStoreVolumeSource{ + VolumeID: volumeID, + FSType: "ext4", + Partition: 0, + ReadOnly: false, + }, + }, + }, } if len(labels) != 0 { @@ -427,34 +448,5 @@ func (c *awsElasticBlockStoreProvisioner) Provision(pv *api.PersistentVolume) er } } - return nil -} - -func (c *awsElasticBlockStoreProvisioner) NewPersistentVolumeTemplate() (*api.PersistentVolume, error) { - // Provide dummy api.PersistentVolume.Spec, it will be filled in - // awsElasticBlockStoreProvisioner.Provision() - return &api.PersistentVolume{ - ObjectMeta: api.ObjectMeta{ - GenerateName: "pv-aws-", - Labels: map[string]string{}, - Annotations: map[string]string{ - "kubernetes.io/createdby": "aws-ebs-dynamic-provisioner", - }, - }, - Spec: api.PersistentVolumeSpec{ - PersistentVolumeReclaimPolicy: c.options.PersistentVolumeReclaimPolicy, - AccessModes: c.options.AccessModes, - Capacity: api.ResourceList{ - api.ResourceName(api.ResourceStorage): c.options.Capacity, - }, - PersistentVolumeSource: api.PersistentVolumeSource{ - AWSElasticBlockStore: &api.AWSElasticBlockStoreVolumeSource{ - VolumeID: volume.ProvisionedVolumeName, - FSType: "ext4", - Partition: 0, - ReadOnly: false, - }, - }, - }, - }, nil + return pv, nil } diff --git a/vendor/k8s.io/kubernetes/pkg/volume/cinder/cinder.go b/vendor/k8s.io/kubernetes/pkg/volume/cinder/cinder.go index b4dcaedb8a..e680528c21 100644 --- a/vendor/k8s.io/kubernetes/pkg/volume/cinder/cinder.go +++ b/vendor/k8s.io/kubernetes/pkg/volume/cinder/cinder.go @@ -427,25 +427,16 @@ type cinderVolumeProvisioner struct { var _ volume.Provisioner = &cinderVolumeProvisioner{} -func (c *cinderVolumeProvisioner) Provision(pv *api.PersistentVolume) error { +func (c *cinderVolumeProvisioner) Provision() (*api.PersistentVolume, error) { volumeID, sizeGB, err := c.manager.CreateVolume(c) if err != nil { - return err + return nil, err } - pv.Spec.PersistentVolumeSource.Cinder.VolumeID = volumeID - pv.Spec.Capacity = api.ResourceList{ - api.ResourceName(api.ResourceStorage): resource.MustParse(fmt.Sprintf("%dGi", sizeGB)), - } - return nil -} -func (c *cinderVolumeProvisioner) NewPersistentVolumeTemplate() (*api.PersistentVolume, error) { - // Provide dummy api.PersistentVolume.Spec, it will be filled in - // cinderVolumeProvisioner.Provision() - return &api.PersistentVolume{ + pv := &api.PersistentVolume{ ObjectMeta: api.ObjectMeta{ - GenerateName: "pv-cinder-", - Labels: map[string]string{}, + Name: c.options.PVName, + Labels: map[string]string{}, Annotations: map[string]string{ "kubernetes.io/createdby": "cinder-dynamic-provisioner", }, @@ -454,16 +445,16 @@ func (c *cinderVolumeProvisioner) NewPersistentVolumeTemplate() (*api.Persistent PersistentVolumeReclaimPolicy: c.options.PersistentVolumeReclaimPolicy, AccessModes: c.options.AccessModes, Capacity: api.ResourceList{ - api.ResourceName(api.ResourceStorage): c.options.Capacity, + api.ResourceName(api.ResourceStorage): resource.MustParse(fmt.Sprintf("%dGi", sizeGB)), }, PersistentVolumeSource: api.PersistentVolumeSource{ Cinder: &api.CinderVolumeSource{ - VolumeID: volume.ProvisionedVolumeName, + VolumeID: volumeID, FSType: "ext4", ReadOnly: false, }, }, }, - }, nil - + } + return pv, nil } diff --git a/vendor/k8s.io/kubernetes/pkg/volume/downwardapi/downwardapi.go b/vendor/k8s.io/kubernetes/pkg/volume/downwardapi/downwardapi.go index ee1b8daedb..571172aba0 100644 --- a/vendor/k8s.io/kubernetes/pkg/volume/downwardapi/downwardapi.go +++ b/vendor/k8s.io/kubernetes/pkg/volume/downwardapi/downwardapi.go @@ -17,13 +17,10 @@ limitations under the License. package downwardapi import ( - "io/ioutil" - "os" + "fmt" "path" - "path/filepath" "sort" "strings" - "time" "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/fieldpath" @@ -31,6 +28,7 @@ import ( utilerrors "k8s.io/kubernetes/pkg/util/errors" utilstrings "k8s.io/kubernetes/pkg/util/strings" "k8s.io/kubernetes/pkg/volume" + volumeutil "k8s.io/kubernetes/pkg/volume/util" "github.com/golang/glog" ) @@ -151,17 +149,18 @@ func (b *downwardAPIVolumeMounter) SetUpAt(dir string, fsGroup *int64) error { return err } - if !b.isDataChanged(data) { - // No data changed: nothing to write - return nil - } - - if err := b.writeData(data); err != nil { - glog.Errorf("Unable to dump files for downwardAPI volume %v for pod %v/%v: %s", b.volName, b.pod.Namespace, b.pod.Name, err.Error()) + writerContext := fmt.Sprintf("pod %v/%v volume %v", b.pod.Namespace, b.pod.Name, b.volName) + writer, err := volumeutil.NewAtomicWriter(dir, writerContext) + if err != nil { + glog.Errorf("Error creating atomic writer: %v", err) return err } - glog.V(3).Infof("Data dumped for downwardAPI volume %v for pod %v/%v", b.volName, b.pod.Namespace, b.pod.Name) + err = writer.Write(data) + if err != nil { + glog.Errorf("Error writing payload to dir: %v", err) + return err + } volume.SetVolumeOwnership(b, fsGroup) @@ -171,179 +170,20 @@ func (b *downwardAPIVolumeMounter) SetUpAt(dir string, fsGroup *int64) error { // collectData collects requested downwardAPI in data map. // Map's key is the requested name of file to dump // Map's value is the (sorted) content of the field to be dumped in the file. -func (d *downwardAPIVolume) collectData() (map[string]string, error) { +func (d *downwardAPIVolume) collectData() (map[string][]byte, error) { errlist := []error{} - data := make(map[string]string) + data := make(map[string][]byte) for fieldReference, fileName := range d.fieldReferenceFileNames { if values, err := fieldpath.ExtractFieldPathAsString(d.pod, fieldReference); err != nil { glog.Errorf("Unable to extract field %s: %s", fieldReference, err.Error()) errlist = append(errlist, err) } else { - data[fileName] = sortLines(values) + data[fileName] = []byte(sortLines(values)) } } return data, utilerrors.NewAggregate(errlist) } -// isDataChanged iterate over all the entries to check whether at least one -// file needs to be updated. -func (d *downwardAPIVolume) isDataChanged(data map[string]string) bool { - for fileName, values := range data { - if isFileToGenerate(path.Join(d.GetPath(), fileName), values) { - return true - } - } - return false -} - -// isFileToGenerate compares actual file with the new values. If -// different (or the file does not exist) return true -func isFileToGenerate(fileName, values string) bool { - if _, err := os.Lstat(fileName); os.IsNotExist(err) { - return true - } - return readFile(fileName) != values -} - -const ( - downwardAPIDir = "..downwardapi" - downwardAPITmpDir = "..downwardapi_tmp" - // It seems reasonable to allow dot-files in the config, so we reserved double-dot-files for the implementation". -) - -// writeData writes requested downwardAPI in specified files. -// -// The file visible in this volume are symlinks to files in the '..downwardapi' -// directory. Actual files are stored in an hidden timestamped directory which is -// symlinked to by '..downwardapi'. The timestamped directory and '..downwardapi' symlink -// are created in the plugin root dir.  This scheme allows the files to be -// atomically updated by changing the target of the '..downwardapi' symlink.  When new -// data is available: -// -// 1.  A new timestamped dir is created by writeDataInTimestampDir and requested data -// is written inside new timestamped directory -// 2.  Symlinks and directory for new files are created (if needed). -// For example for files: -// /user_space/labels -// /k8s_space/annotations -// /podName -// This structure is created: -// /podName -> ..downwardapi/podName -// /user_space/labels -> ../..downwardapi/user_space/labels -// /k8s_space/annotations -> ../..downwardapi/k8s_space/annotations -// /..downwardapi -> ..downwardapi.12345678 -// where ..downwardapi.12345678 is a randomly generated directory which contains -// the real data. If a file has to be dumped in subdirectory (for example /user_space/labels) -// plugin builds a relative symlink (/user_space/labels -> ../..downwardapi/user_space/labels) -// 3.  The previous timestamped directory is detected reading the '..downwardapi' symlink -// 4.  In case no symlink exists then it's created -// 5.  In case symlink exists a new temporary symlink is created ..downwardapi_tmp -// 6.  ..downwardapi_tmp is renamed to ..downwardapi -// 7.  The previous timestamped directory is removed - -func (d *downwardAPIVolume) writeData(data map[string]string) error { - timestampDir, err := d.writeDataInTimestampDir(data) - if err != nil { - glog.Errorf("Unable to write data in temporary directory: %s", err.Error()) - return err - } - // update symbolic links for relative paths - if err = d.updateSymlinksToCurrentDir(); err != nil { - os.RemoveAll(timestampDir) - glog.Errorf("Unable to create symlinks and/or directory: %s", err.Error()) - return err - } - - _, timestampDirBaseName := filepath.Split(timestampDir) - var oldTimestampDirectory string - oldTimestampDirectory, err = os.Readlink(path.Join(d.GetPath(), downwardAPIDir)) - - if err = os.Symlink(timestampDirBaseName, path.Join(d.GetPath(), downwardAPITmpDir)); err != nil { - os.RemoveAll(timestampDir) - glog.Errorf("Unable to create symolic link: %s", err.Error()) - return err - } - - // Rename the symbolic link downwardAPITmpDir to downwardAPIDir - if err = os.Rename(path.Join(d.GetPath(), downwardAPITmpDir), path.Join(d.GetPath(), downwardAPIDir)); err != nil { - // in case of error remove latest data and downwardAPITmpDir - os.Remove(path.Join(d.GetPath(), downwardAPITmpDir)) - os.RemoveAll(timestampDir) - glog.Errorf("Unable to rename symbolic link: %s", err.Error()) - return err - } - // Remove oldTimestampDirectory - if len(oldTimestampDirectory) > 0 { - if err := os.RemoveAll(path.Join(d.GetPath(), oldTimestampDirectory)); err != nil { - glog.Errorf("Unable to remove directory: %s", err.Error()) - return err - } - } - return nil -} - -// writeDataInTimestampDir writes the latest data into a new temporary directory with a timestamp. -func (d *downwardAPIVolume) writeDataInTimestampDir(data map[string]string) (string, error) { - errlist := []error{} - timestampDir, err := ioutil.TempDir(d.GetPath(), ".."+time.Now().Format("2006_01_02_15_04_05")) - for fileName, values := range data { - fullPathFile := path.Join(timestampDir, fileName) - dir, _ := filepath.Split(fullPathFile) - if err = os.MkdirAll(dir, os.ModePerm); err != nil { - glog.Errorf("Unable to create directory `%s`: %s", dir, err.Error()) - return "", err - } - if err := ioutil.WriteFile(fullPathFile, []byte(values), 0644); err != nil { - glog.Errorf("Unable to write file `%s`: %s", fullPathFile, err.Error()) - errlist = append(errlist, err) - } - } - return timestampDir, utilerrors.NewAggregate(errlist) -} - -// updateSymlinksToCurrentDir creates the relative symlinks for all the files configured in this volume. -// If the directory in a file path does not exist, it is created. -// -// For example for files: "bar", "foo/bar", "baz/bar", "foo/baz/blah" -// the following symlinks and subdirectory are created: -// bar -> ..downwardapi/bar -// baz/bar -> ../..downwardapi/baz/bar -// foo/bar -> ../..downwardapi/foo/bar -// foo/baz/blah -> ../../..downwardapi/foo/baz/blah -func (d *downwardAPIVolume) updateSymlinksToCurrentDir() error { - for _, f := range d.fieldReferenceFileNames { - dir, _ := filepath.Split(f) - nbOfSubdir := 0 - if len(dir) > 0 { - // if dir is not empty f contains at least a subdirectory (for example: f="foo/bar") - // since filepath.Split leaves a trailing '/' we have dir="foo/" - // and since len(strings.Split"foo/")=2 to count the number - // of sub directory you need to remove 1 - nbOfSubdir = len(strings.Split(dir, "/")) - 1 - if err := os.MkdirAll(path.Join(d.GetPath(), dir), os.ModePerm); err != nil { - return err - } - } - if _, err := os.Readlink(path.Join(d.GetPath(), f)); err != nil { - // link does not exist create it - presentedFile := path.Join(strings.Repeat("../", nbOfSubdir), downwardAPIDir, f) - actualFile := path.Join(d.GetPath(), f) - if err := os.Symlink(presentedFile, actualFile); err != nil { - return err - } - } - } - return nil -} - -// readFile reads the file at the given path and returns the content as a string. -func readFile(path string) string { - if data, err := ioutil.ReadFile(path); err == nil { - return string(data) - } - return "" -} - // sortLines sorts the strings generated from map based data // (annotations and labels) func sortLines(values string) string { @@ -356,7 +196,7 @@ func (d *downwardAPIVolume) GetPath() string { return d.plugin.host.GetPodVolumeDir(d.podUID, utilstrings.EscapeQualifiedNameForDisk(downwardAPIPluginName), d.volName) } -// downwardAPIVolumeCleander handles cleaning up downwardAPI volumes +// downwardAPIVolumeCleaner handles cleaning up downwardAPI volumes type downwardAPIVolumeUnmounter struct { *downwardAPIVolume } diff --git a/vendor/k8s.io/kubernetes/pkg/volume/gce_pd/attacher.go b/vendor/k8s.io/kubernetes/pkg/volume/gce_pd/attacher.go new file mode 100644 index 0000000000..5ad0b77ad8 --- /dev/null +++ b/vendor/k8s.io/kubernetes/pkg/volume/gce_pd/attacher.go @@ -0,0 +1,220 @@ +/* +Copyright 2016 The Kubernetes Authors All rights reserved. + +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 gce_pd + +import ( + "fmt" + "os" + "path" + "path/filepath" + "strconv" + "time" + + "github.com/golang/glog" + "k8s.io/kubernetes/pkg/util/exec" + "k8s.io/kubernetes/pkg/util/keymutex" + "k8s.io/kubernetes/pkg/util/mount" + "k8s.io/kubernetes/pkg/util/sets" + "k8s.io/kubernetes/pkg/volume" +) + +type gcePersistentDiskAttacher struct { + host volume.VolumeHost +} + +var _ volume.Attacher = &gcePersistentDiskAttacher{} + +var _ volume.AttachableVolumePlugin = &gcePersistentDiskPlugin{} + +// Singleton key mutex for keeping attach/detach operations for the +// same PD atomic +// TODO(swagiaal): Once the Mount/Unmount manager is implemented this +// will no longer be needed and should be removed. +var attachDetachMutex = keymutex.NewKeyMutex() + +func (plugin *gcePersistentDiskPlugin) NewAttacher() (volume.Attacher, error) { + return &gcePersistentDiskAttacher{host: plugin.host}, nil +} + +func (attacher *gcePersistentDiskAttacher) Attach(spec *volume.Spec, hostName string) error { + volumeSource, readOnly := getVolumeSource(spec) + pdName := volumeSource.PDName + + // Block execution until any pending detach operations for this PD have completed + attachDetachMutex.LockKey(pdName) + defer attachDetachMutex.UnlockKey(pdName) + + gceCloud, err := getCloudProvider(attacher.host.GetCloudProvider()) + if err != nil { + return err + } + + for numRetries := 0; numRetries < maxRetries; numRetries++ { + if numRetries > 0 { + glog.Warningf("Retrying attach for GCE PD %q (retry count=%v).", pdName, numRetries) + } + + if err = gceCloud.AttachDisk(pdName, hostName, readOnly); err != nil { + glog.Errorf("Error attaching PD %q: %+v", pdName, err) + time.Sleep(errorSleepDuration) + continue + } + + return nil + } + + return err +} + +func (attacher *gcePersistentDiskAttacher) WaitForAttach(spec *volume.Spec, timeout time.Duration) (string, error) { + ticker := time.NewTicker(checkSleepDuration) + defer ticker.Stop() + timer := time.NewTimer(timeout) + defer timer.Stop() + + volumeSource, _ := getVolumeSource(spec) + pdName := volumeSource.PDName + partition := "" + if volumeSource.Partition != 0 { + partition = strconv.Itoa(int(volumeSource.Partition)) + } + + sdBefore, err := filepath.Glob(diskSDPattern) + if err != nil { + glog.Errorf("Error filepath.Glob(\"%s\"): %v\r\n", diskSDPattern, err) + } + sdBeforeSet := sets.NewString(sdBefore...) + + devicePaths := getDiskByIdPaths(pdName, partition) + for { + select { + case <-ticker.C: + glog.V(5).Infof("Checking GCE PD %q is attached.", pdName) + path, err := verifyDevicePath(devicePaths, sdBeforeSet) + if err != nil { + // Log error, if any, and continue checking periodically. See issue #11321 + glog.Errorf("Error verifying GCE PD (%q) is attached: %v", pdName, err) + } else if path != "" { + // A device path has successfully been created for the PD + glog.Infof("Successfully found attached GCE PD %q.", pdName) + return path, nil + } + case <-timer.C: + return "", fmt.Errorf("Could not find attached GCE PD %q. Timeout waiting for mount paths to be created.", pdName) + } + } +} + +func (attacher *gcePersistentDiskAttacher) GetDeviceMountPath(spec *volume.Spec) string { + volumeSource, _ := getVolumeSource(spec) + return makeGlobalPDName(attacher.host, volumeSource.PDName) +} + +func (attacher *gcePersistentDiskAttacher) MountDevice(spec *volume.Spec, devicePath string, deviceMountPath string, mounter mount.Interface) error { + // Only mount the PD globally once. + notMnt, err := mounter.IsLikelyNotMountPoint(deviceMountPath) + if err != nil { + if os.IsNotExist(err) { + if err := os.MkdirAll(deviceMountPath, 0750); err != nil { + return err + } + notMnt = true + } else { + return err + } + } + + volumeSource, readOnly := getVolumeSource(spec) + + options := []string{} + if readOnly { + options = append(options, "ro") + } + if notMnt { + diskMounter := &mount.SafeFormatAndMount{Interface: mounter, Runner: exec.New()} + err = diskMounter.FormatAndMount(devicePath, deviceMountPath, volumeSource.FSType, options) + if err != nil { + os.Remove(deviceMountPath) + return err + } + } + return nil +} + +type gcePersistentDiskDetacher struct { + host volume.VolumeHost +} + +var _ volume.Detacher = &gcePersistentDiskDetacher{} + +func (plugin *gcePersistentDiskPlugin) NewDetacher() (volume.Detacher, error) { + return &gcePersistentDiskDetacher{host: plugin.host}, nil +} + +func (detacher *gcePersistentDiskDetacher) Detach(deviceMountPath string, hostName string) error { + pdName := path.Base(deviceMountPath) + + // Block execution until any pending attach/detach operations for this PD have completed + attachDetachMutex.LockKey(pdName) + defer attachDetachMutex.UnlockKey(pdName) + + gceCloud, err := getCloudProvider(detacher.host.GetCloudProvider()) + if err != nil { + return err + } + + for numRetries := 0; numRetries < maxRetries; numRetries++ { + if numRetries > 0 { + glog.Warningf("Retrying detach for GCE PD %q (retry count=%v).", pdName, numRetries) + } + + if err = gceCloud.DetachDisk(pdName, hostName); err != nil { + glog.Errorf("Error detaching PD %q: %v", pdName, err) + time.Sleep(errorSleepDuration) + continue + } + + return nil + } + + return err +} + +func (detacher *gcePersistentDiskDetacher) WaitForDetach(devicePath string, timeout time.Duration) error { + ticker := time.NewTicker(checkSleepDuration) + defer ticker.Stop() + timer := time.NewTimer(timeout) + defer timer.Stop() + + for { + select { + case <-ticker.C: + glog.V(5).Infof("Checking device %q is detached.", devicePath) + if pathExists, err := pathExists(devicePath); err != nil { + return fmt.Errorf("Error checking if device path exists: %v", err) + } else if !pathExists { + return nil + } + case <-timer.C: + return fmt.Errorf("Timeout reached; PD Device %v is still attached", devicePath) + } + } +} + +func (detacher *gcePersistentDiskDetacher) UnmountDevice(deviceMountPath string, mounter mount.Interface) error { + return unmountPDAndRemoveGlobalPath(deviceMountPath, mounter) +} diff --git a/vendor/k8s.io/kubernetes/pkg/volume/gce_pd/gce_pd.go b/vendor/k8s.io/kubernetes/pkg/volume/gce_pd/gce_pd.go index 006ed57349..c923406574 100644 --- a/vendor/k8s.io/kubernetes/pkg/volume/gce_pd/gce_pd.go +++ b/vendor/k8s.io/kubernetes/pkg/volume/gce_pd/gce_pd.go @@ -26,7 +26,6 @@ import ( "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/resource" "k8s.io/kubernetes/pkg/types" - "k8s.io/kubernetes/pkg/util/exec" "k8s.io/kubernetes/pkg/util/mount" "k8s.io/kubernetes/pkg/util/strings" "k8s.io/kubernetes/pkg/volume" @@ -76,25 +75,30 @@ func (plugin *gcePersistentDiskPlugin) NewMounter(spec *volume.Spec, pod *api.Po return plugin.newMounterInternal(spec, pod.UID, &GCEDiskUtil{}, plugin.host.GetMounter()) } -func (plugin *gcePersistentDiskPlugin) newMounterInternal(spec *volume.Spec, podUID types.UID, manager pdManager, mounter mount.Interface) (volume.Mounter, error) { - // GCEPDs used directly in a pod have a ReadOnly flag set by the pod author. - // GCEPDs used as a PersistentVolume gets the ReadOnly flag indirectly through the persistent-claim volume used to mount the PV +func getVolumeSource(spec *volume.Spec) (*api.GCEPersistentDiskVolumeSource, bool) { var readOnly bool + var volumeSource *api.GCEPersistentDiskVolumeSource - var gce *api.GCEPersistentDiskVolumeSource if spec.Volume != nil && spec.Volume.GCEPersistentDisk != nil { - gce = spec.Volume.GCEPersistentDisk - readOnly = gce.ReadOnly + volumeSource = spec.Volume.GCEPersistentDisk + readOnly = volumeSource.ReadOnly } else { - gce = spec.PersistentVolume.Spec.GCEPersistentDisk + volumeSource = spec.PersistentVolume.Spec.GCEPersistentDisk readOnly = spec.ReadOnly } - pdName := gce.PDName - fsType := gce.FSType + return volumeSource, readOnly +} + +func (plugin *gcePersistentDiskPlugin) newMounterInternal(spec *volume.Spec, podUID types.UID, manager pdManager, mounter mount.Interface) (volume.Mounter, error) { + // GCEPDs used directly in a pod have a ReadOnly flag set by the pod author. + // GCEPDs used as a PersistentVolume gets the ReadOnly flag indirectly through the persistent-claim volume used to mount the PV + volumeSource, readOnly := getVolumeSource(spec) + + pdName := volumeSource.PDName partition := "" - if gce.Partition != 0 { - partition = strconv.Itoa(int(gce.Partition)) + if volumeSource.Partition != 0 { + partition = strconv.Itoa(int(volumeSource.Partition)) } return &gcePersistentDiskMounter{ @@ -107,9 +111,7 @@ func (plugin *gcePersistentDiskPlugin) newMounterInternal(spec *volume.Spec, pod manager: manager, plugin: plugin, }, - fsType: fsType, - readOnly: readOnly, - diskMounter: &mount.SafeFormatAndMount{Interface: mounter, Runner: exec.New()}}, nil + readOnly: readOnly}, nil } func (plugin *gcePersistentDiskPlugin) NewUnmounter(volName string, podUID types.UID) (volume.Unmounter, error) { @@ -163,10 +165,6 @@ func (plugin *gcePersistentDiskPlugin) newProvisionerInternal(options volume.Vol // Abstract interface to PD operations. type pdManager interface { - // Attaches the disk to the kubelet's host machine. - AttachAndMountDisk(b *gcePersistentDiskMounter, globalPDPath string) error - // Detaches the disk from the kubelet's host machine. - DetachDisk(c *gcePersistentDiskUnmounter) error // Creates a volume CreateVolume(provisioner *gcePersistentDiskProvisioner) (volumeID string, volumeSizeGB int, labels map[string]string, err error) // Deletes a volume @@ -182,7 +180,7 @@ type gcePersistentDisk struct { pdName string // Specifies the partition to mount partition string - // Utility interface that provides API calls to the provider to attach/detach disks. + // Utility interface to provision and delete disks manager pdManager // Mounter interface that provides system calls to mount the global path to the pod local path. mounter mount.Interface @@ -190,21 +188,10 @@ type gcePersistentDisk struct { volume.MetricsNil } -func detachDiskLogError(pd *gcePersistentDisk) { - err := pd.manager.DetachDisk(&gcePersistentDiskUnmounter{pd}) - if err != nil { - glog.Warningf("Failed to detach disk: %v (%v)", pd, err) - } -} - type gcePersistentDiskMounter struct { *gcePersistentDisk - // Filesystem type, optional. - fsType string - // Specifies whether the disk will be attached as read-only. + // Specifies whether the disk will be mounted as read-only. readOnly bool - // diskMounter provides the interface that is used to mount the actual block device. - diskMounter *mount.SafeFormatAndMount } var _ volume.Mounter = &gcePersistentDiskMounter{} @@ -217,12 +204,12 @@ func (b *gcePersistentDiskMounter) GetAttributes() volume.Attributes { } } -// SetUp attaches the disk and bind mounts to the volume path. +// SetUp bind mounts the disk global mount to the volume path. func (b *gcePersistentDiskMounter) SetUp(fsGroup *int64) error { return b.SetUpAt(b.GetPath(), fsGroup) } -// SetUpAt attaches the disk and bind mounts to the volume path. +// SetUp bind mounts the disk global mount to the give volume path. func (b *gcePersistentDiskMounter) SetUpAt(dir string, fsGroup *int64) error { // TODO: handle failed mounts here. notMnt, err := b.mounter.IsLikelyNotMountPoint(dir) @@ -234,14 +221,7 @@ func (b *gcePersistentDiskMounter) SetUpAt(dir string, fsGroup *int64) error { return nil } - globalPDPath := makeGlobalPDName(b.plugin.host, b.pdName) - if err := b.manager.AttachAndMountDisk(b, globalPDPath); err != nil { - return err - } - if err := os.MkdirAll(dir, 0750); err != nil { - // TODO: we should really eject the attach/detach out into its own control loop. - detachDiskLogError(b.gcePersistentDisk) return err } @@ -250,6 +230,8 @@ func (b *gcePersistentDiskMounter) SetUpAt(dir string, fsGroup *int64) error { if b.readOnly { options = append(options, "ro") } + + globalPDPath := makeGlobalPDName(b.plugin.host, b.pdName) err = b.mounter.Mount(globalPDPath, dir, "", options) if err != nil { notMnt, mntErr := b.mounter.IsLikelyNotMountPoint(dir) @@ -274,8 +256,6 @@ func (b *gcePersistentDiskMounter) SetUpAt(dir string, fsGroup *int64) error { } } os.Remove(dir) - // TODO: we should really eject the attach/detach out into its own control loop. - detachDiskLogError(b.gcePersistentDisk) return err } @@ -301,14 +281,12 @@ type gcePersistentDiskUnmounter struct { var _ volume.Unmounter = &gcePersistentDiskUnmounter{} -// Unmounts the bind mount, and detaches the disk only if the PD -// resource was the last reference to that disk on the kubelet. +// TearDown unmounts the bind mount func (c *gcePersistentDiskUnmounter) TearDown() error { return c.TearDownAt(c.GetPath()) } -// Unmounts the bind mount, and detaches the disk only if the PD -// resource was the last reference to that disk on the kubelet. +// TearDownAt unmounts the bind mount func (c *gcePersistentDiskUnmounter) TearDownAt(dir string) error { notMnt, err := c.mounter.IsLikelyNotMountPoint(dir) if err != nil { @@ -317,35 +295,18 @@ func (c *gcePersistentDiskUnmounter) TearDownAt(dir string) error { if notMnt { return os.Remove(dir) } - - refs, err := mount.GetMountRefs(c.mounter, dir) - if err != nil { - return err - } - // Unmount the bind-mount inside this pod if err := c.mounter.Unmount(dir); err != nil { return err } - // If len(refs) is 1, then all bind mounts have been removed, and the - // remaining reference is the global mount. It is safe to detach. - if len(refs) == 1 { - // c.pdName is not initially set for volume-unmounters, so set it here. - c.pdName = path.Base(refs[0]) - if err := c.manager.DetachDisk(c); err != nil { - return err - } - } notMnt, mntErr := c.mounter.IsLikelyNotMountPoint(dir) if mntErr != nil { glog.Errorf("IsLikelyNotMountPoint check failed: %v", mntErr) return err } if notMnt { - if err := os.Remove(dir); err != nil { - return err - } + return os.Remove(dir) } - return nil + return fmt.Errorf("Failed to unmount volume dir") } type gcePersistentDiskDeleter struct { @@ -370,14 +331,34 @@ type gcePersistentDiskProvisioner struct { var _ volume.Provisioner = &gcePersistentDiskProvisioner{} -func (c *gcePersistentDiskProvisioner) Provision(pv *api.PersistentVolume) error { +func (c *gcePersistentDiskProvisioner) Provision() (*api.PersistentVolume, error) { volumeID, sizeGB, labels, err := c.manager.CreateVolume(c) if err != nil { - return err + return nil, err } - pv.Spec.PersistentVolumeSource.GCEPersistentDisk.PDName = volumeID - pv.Spec.Capacity = api.ResourceList{ - api.ResourceName(api.ResourceStorage): resource.MustParse(fmt.Sprintf("%dGi", sizeGB)), + + pv := &api.PersistentVolume{ + ObjectMeta: api.ObjectMeta{ + Name: c.options.PVName, + Labels: map[string]string{}, + Annotations: map[string]string{ + "kubernetes.io/createdby": "gce-pd-dynamic-provisioner", + }, + }, + Spec: api.PersistentVolumeSpec{ + PersistentVolumeReclaimPolicy: c.options.PersistentVolumeReclaimPolicy, + AccessModes: c.options.AccessModes, + Capacity: api.ResourceList{ + api.ResourceName(api.ResourceStorage): resource.MustParse(fmt.Sprintf("%dGi", sizeGB)), + }, + PersistentVolumeSource: api.PersistentVolumeSource{ + GCEPersistentDisk: &api.GCEPersistentDiskVolumeSource{ + PDName: volumeID, + Partition: 0, + ReadOnly: false, + }, + }, + }, } if len(labels) != 0 { @@ -389,34 +370,5 @@ func (c *gcePersistentDiskProvisioner) Provision(pv *api.PersistentVolume) error } } - return nil -} - -func (c *gcePersistentDiskProvisioner) NewPersistentVolumeTemplate() (*api.PersistentVolume, error) { - // Provide dummy api.PersistentVolume.Spec, it will be filled in - // gcePersistentDiskProvisioner.Provision() - return &api.PersistentVolume{ - ObjectMeta: api.ObjectMeta{ - GenerateName: "pv-gce-", - Labels: map[string]string{}, - Annotations: map[string]string{ - "kubernetes.io/createdby": "gce-pd-dynamic-provisioner", - }, - }, - Spec: api.PersistentVolumeSpec{ - PersistentVolumeReclaimPolicy: c.options.PersistentVolumeReclaimPolicy, - AccessModes: c.options.AccessModes, - Capacity: api.ResourceList{ - api.ResourceName(api.ResourceStorage): c.options.Capacity, - }, - PersistentVolumeSource: api.PersistentVolumeSource{ - GCEPersistentDisk: &api.GCEPersistentDiskVolumeSource{ - PDName: volume.ProvisionedVolumeName, - FSType: "ext4", - Partition: 0, - ReadOnly: false, - }, - }, - }, - }, nil + return pv, nil } diff --git a/vendor/k8s.io/kubernetes/pkg/volume/gce_pd/gce_util.go b/vendor/k8s.io/kubernetes/pkg/volume/gce_pd/gce_util.go index af9171f76a..523262720a 100644 --- a/vendor/k8s.io/kubernetes/pkg/volume/gce_pd/gce_util.go +++ b/vendor/k8s.io/kubernetes/pkg/volume/gce_pd/gce_util.go @@ -25,10 +25,10 @@ import ( "time" "github.com/golang/glog" + "k8s.io/kubernetes/pkg/cloudprovider" gcecloud "k8s.io/kubernetes/pkg/cloudprovider/providers/gce" "k8s.io/kubernetes/pkg/util/exec" - "k8s.io/kubernetes/pkg/util/keymutex" - "k8s.io/kubernetes/pkg/util/runtime" + "k8s.io/kubernetes/pkg/util/mount" "k8s.io/kubernetes/pkg/util/sets" "k8s.io/kubernetes/pkg/volume" ) @@ -46,74 +46,10 @@ const ( errorSleepDuration = 5 * time.Second ) -// Singleton key mutex for keeping attach/detach operations for the same PD atomic -var attachDetachMutex = keymutex.NewKeyMutex() - type GCEDiskUtil struct{} -// Attaches a disk specified by a volume.GCEPersistentDisk to the current kubelet. -// Mounts the disk to it's global path. -func (diskUtil *GCEDiskUtil) AttachAndMountDisk(b *gcePersistentDiskMounter, globalPDPath string) error { - glog.V(5).Infof("AttachAndMountDisk(...) called for PD %q. Will block for existing operations, if any. (globalPDPath=%q)\r\n", b.pdName, globalPDPath) - - // Block execution until any pending detach operations for this PD have completed - attachDetachMutex.LockKey(b.pdName) - defer attachDetachMutex.UnlockKey(b.pdName) - - glog.V(5).Infof("AttachAndMountDisk(...) called for PD %q. Awake and ready to execute. (globalPDPath=%q)\r\n", b.pdName, globalPDPath) - - sdBefore, err := filepath.Glob(diskSDPattern) - if err != nil { - glog.Errorf("Error filepath.Glob(\"%s\"): %v\r\n", diskSDPattern, err) - } - sdBeforeSet := sets.NewString(sdBefore...) - - devicePath, err := attachDiskAndVerify(b, sdBeforeSet) - if err != nil { - return err - } - - // Only mount the PD globally once. - notMnt, err := b.mounter.IsLikelyNotMountPoint(globalPDPath) - if err != nil { - if os.IsNotExist(err) { - if err := os.MkdirAll(globalPDPath, 0750); err != nil { - return err - } - notMnt = true - } else { - return err - } - } - options := []string{} - if b.readOnly { - options = append(options, "ro") - } - if notMnt { - err = b.diskMounter.FormatAndMount(devicePath, globalPDPath, b.fsType, options) - if err != nil { - os.Remove(globalPDPath) - return err - } - } - return nil -} - -// Unmounts the device and detaches the disk from the kubelet's host machine. -func (util *GCEDiskUtil) DetachDisk(c *gcePersistentDiskUnmounter) error { - glog.V(5).Infof("DetachDisk(...) for PD %q\r\n", c.pdName) - - if err := unmountPDAndRemoveGlobalPath(c); err != nil { - glog.Errorf("Error unmounting PD %q: %v", c.pdName, err) - } - - // Detach disk asynchronously so that the kubelet sync loop is not blocked. - go detachDiskAndVerify(c) - return nil -} - func (util *GCEDiskUtil) DeleteVolume(d *gcePersistentDiskDeleter) error { - cloud, err := getCloudProvider(d.gcePersistentDisk.plugin) + cloud, err := getCloudProvider(d.gcePersistentDisk.plugin.host.GetCloudProvider()) if err != nil { return err } @@ -129,7 +65,7 @@ func (util *GCEDiskUtil) DeleteVolume(d *gcePersistentDiskDeleter) error { // CreateVolume creates a GCE PD. // Returns: volumeID, volumeSizeGB, labels, error func (gceutil *GCEDiskUtil) CreateVolume(c *gcePersistentDiskProvisioner) (string, int, map[string]string, error) { - cloud, err := getCloudProvider(c.gcePersistentDisk.plugin) + cloud, err := getCloudProvider(c.gcePersistentDisk.plugin.host.GetCloudProvider()) if err != nil { return "", 0, nil, err } @@ -163,46 +99,6 @@ func (gceutil *GCEDiskUtil) CreateVolume(c *gcePersistentDiskProvisioner) (strin return name, int(requestGB), labels, nil } -// Attaches the specified persistent disk device to node, verifies that it is attached, and retries if it fails. -func attachDiskAndVerify(b *gcePersistentDiskMounter, sdBeforeSet sets.String) (string, error) { - devicePaths := getDiskByIdPaths(b.gcePersistentDisk) - gceCloud, err := getCloudProvider(b.gcePersistentDisk.plugin) - if err != nil { - return "", err - } - - for numRetries := 0; numRetries < maxRetries; numRetries++ { - - if numRetries > 0 { - glog.Warningf("Retrying attach for GCE PD %q (retry count=%v).", b.pdName, numRetries) - } - - if err := gceCloud.AttachDisk(b.pdName, b.plugin.host.GetHostName(), b.readOnly); err != nil { - glog.Errorf("Error attaching PD %q: %v", b.pdName, err) - time.Sleep(errorSleepDuration) - continue - } - - for numChecks := 0; numChecks < maxChecks; numChecks++ { - path, err := verifyDevicePath(devicePaths, sdBeforeSet) - if err != nil { - // Log error, if any, and continue checking periodically. See issue #11321 - glog.Errorf("Error verifying GCE PD (%q) is attached: %v", b.pdName, err) - } else if path != "" { - // A device path has successfully been created for the PD - glog.Infof("Successfully attached GCE PD %q.", b.pdName) - return path, nil - } - - // Sleep then check again - glog.V(3).Infof("Waiting for GCE PD %q to attach.", b.pdName) - time.Sleep(checkSleepDuration) - } - } - - return "", fmt.Errorf("Could not attach GCE PD %q. Timeout waiting for mount paths to be created.", b.pdName) -} - // Returns the first path that exists, or empty string if none exist. func verifyDevicePath(devicePaths []string, sdBeforeSet sets.String) (string, error) { if err := udevadmChangeToNewDrives(sdBeforeSet); err != nil { @@ -221,65 +117,10 @@ func verifyDevicePath(devicePaths []string, sdBeforeSet sets.String) (string, er return "", nil } -// Detaches the specified persistent disk device from node, verifies that it is detached, and retries if it fails. -// This function is intended to be called asynchronously as a go routine. -func detachDiskAndVerify(c *gcePersistentDiskUnmounter) { - glog.V(5).Infof("detachDiskAndVerify(...) for pd %q. Will block for pending operations", c.pdName) - defer runtime.HandleCrash() - - // Block execution until any pending attach/detach operations for this PD have completed - attachDetachMutex.LockKey(c.pdName) - defer attachDetachMutex.UnlockKey(c.pdName) - - glog.V(5).Infof("detachDiskAndVerify(...) for pd %q. Awake and ready to execute.", c.pdName) - - devicePaths := getDiskByIdPaths(c.gcePersistentDisk) - gceCloud, err := getCloudProvider(c.gcePersistentDisk.plugin) - if err != nil { - glog.Errorf("Failed to get GCECloudProvider while detaching %v ", err) - return - } - - for numRetries := 0; numRetries < maxRetries; numRetries++ { - - if numRetries > 0 { - glog.Warningf("Retrying detach for GCE PD %q (retry count=%v).", c.pdName, numRetries) - } - - if err := gceCloud.DetachDisk(c.pdName, c.plugin.host.GetHostName()); err != nil { - glog.Errorf("Error detaching PD %q: %v", c.pdName, err) - time.Sleep(errorSleepDuration) - continue - } - - for numChecks := 0; numChecks < maxChecks; numChecks++ { - allPathsRemoved, err := verifyAllPathsRemoved(devicePaths) - if err != nil { - // Log error, if any, and continue checking periodically. - glog.Errorf("Error verifying GCE PD (%q) is detached: %v", c.pdName, err) - } else if allPathsRemoved { - // All paths to the PD have been successfully removed - unmountPDAndRemoveGlobalPath(c) - glog.Infof("Successfully detached GCE PD %q.", c.pdName) - return - } - - // Sleep then check again - glog.V(3).Infof("Waiting for GCE PD %q to detach.", c.pdName) - time.Sleep(checkSleepDuration) - } - - } - - glog.Errorf("Failed to detach GCE PD %q. One or more mount paths was not removed.", c.pdName) -} - // Unmount the global PD mount, which should be the only one, and delete it. -func unmountPDAndRemoveGlobalPath(c *gcePersistentDiskUnmounter) error { - globalPDPath := makeGlobalPDName(c.plugin.host, c.pdName) - - err := c.mounter.Unmount(globalPDPath) - os.Remove(globalPDPath) +func unmountPDAndRemoveGlobalPath(globalMountPath string, mounter mount.Interface) error { + err := mounter.Unmount(globalMountPath) + os.Remove(globalMountPath) return err } @@ -302,15 +143,15 @@ func verifyAllPathsRemoved(devicePaths []string) (bool, error) { } // Returns list of all /dev/disk/by-id/* paths for given PD. -func getDiskByIdPaths(pd *gcePersistentDisk) []string { +func getDiskByIdPaths(pdName string, partition string) []string { devicePaths := []string{ - path.Join(diskByIdPath, diskGooglePrefix+pd.pdName), - path.Join(diskByIdPath, diskScsiGooglePrefix+pd.pdName), + path.Join(diskByIdPath, diskGooglePrefix+pdName), + path.Join(diskByIdPath, diskScsiGooglePrefix+pdName), } - if pd.partition != "" { + if partition != "" { for i, path := range devicePaths { - devicePaths[i] = path + diskPartitionSuffix + pd.partition + devicePaths[i] = path + diskPartitionSuffix + partition } } @@ -330,17 +171,9 @@ func pathExists(path string) (bool, error) { } // Return cloud provider -func getCloudProvider(plugin *gcePersistentDiskPlugin) (*gcecloud.GCECloud, error) { - if plugin == nil { - return nil, fmt.Errorf("Failed to get GCE Cloud Provider. plugin object is nil.") - } - if plugin.host == nil { - return nil, fmt.Errorf("Failed to get GCE Cloud Provider. plugin.host object is nil.") - } - +func getCloudProvider(cloudProvider cloudprovider.Interface) (*gcecloud.GCECloud, error) { var err error for numRetries := 0; numRetries < maxRetries; numRetries++ { - cloudProvider := plugin.host.GetCloudProvider() gceCloudProvider, ok := cloudProvider.(*gcecloud.GCECloud) if !ok || gceCloudProvider == nil { // Retry on error. See issue #11321 @@ -355,8 +188,10 @@ func getCloudProvider(plugin *gcePersistentDiskPlugin) (*gcecloud.GCECloud, erro return nil, fmt.Errorf("Failed to get GCE GCECloudProvider with error %v", err) } -// Calls "udevadm trigger --action=change" for newly created "/dev/sd*" drives (exist only in after set). -// This is workaround for Issue #7972. Once the underlying issue has been resolved, this may be removed. +// Triggers the application of udev rules by calling "udevadm trigger +// --action=change" for newly created "/dev/sd*" drives (exist only in +// after set). This is workaround for Issue #7972. Once the underlying +// issue has been resolved, this may be removed. func udevadmChangeToNewDrives(sdBeforeSet sets.String) error { sdAfter, err := filepath.Glob(diskSDPattern) if err != nil { diff --git a/vendor/k8s.io/kubernetes/pkg/volume/host_path/host_path.go b/vendor/k8s.io/kubernetes/pkg/volume/host_path/host_path.go index b0ddb0aa02..8a6cae457d 100644 --- a/vendor/k8s.io/kubernetes/pkg/volume/host_path/host_path.go +++ b/vendor/k8s.io/kubernetes/pkg/volume/host_path/host_path.go @@ -43,7 +43,7 @@ func ProbeVolumePlugins(volumeConfig volume.VolumeConfig) []volume.VolumePlugin } } -func ProbeRecyclableVolumePlugins(recyclerFunc func(spec *volume.Spec, host volume.VolumeHost, volumeConfig volume.VolumeConfig) (volume.Recycler, error), volumeConfig volume.VolumeConfig) []volume.VolumePlugin { +func ProbeRecyclableVolumePlugins(recyclerFunc func(pvName string, spec *volume.Spec, host volume.VolumeHost, volumeConfig volume.VolumeConfig) (volume.Recycler, error), volumeConfig volume.VolumeConfig) []volume.VolumePlugin { return []volume.VolumePlugin{ &hostPathPlugin{ host: nil, @@ -57,7 +57,7 @@ func ProbeRecyclableVolumePlugins(recyclerFunc func(spec *volume.Spec, host volu type hostPathPlugin struct { host volume.VolumeHost // decouple creating Recyclers/Deleters/Provisioners by deferring to a function. Allows for easier testing. - newRecyclerFunc func(spec *volume.Spec, host volume.VolumeHost, volumeConfig volume.VolumeConfig) (volume.Recycler, error) + newRecyclerFunc func(pvName string, spec *volume.Spec, host volume.VolumeHost, volumeConfig volume.VolumeConfig) (volume.Recycler, error) newDeleterFunc func(spec *volume.Spec, host volume.VolumeHost) (volume.Deleter, error) newProvisionerFunc func(options volume.VolumeOptions, host volume.VolumeHost) (volume.Provisioner, error) config volume.VolumeConfig @@ -115,8 +115,8 @@ func (plugin *hostPathPlugin) NewUnmounter(volName string, podUID types.UID) (vo }}, nil } -func (plugin *hostPathPlugin) NewRecycler(spec *volume.Spec) (volume.Recycler, error) { - return plugin.newRecyclerFunc(spec, plugin.host, plugin.config) +func (plugin *hostPathPlugin) NewRecycler(pvName string, spec *volume.Spec) (volume.Recycler, error) { + return plugin.newRecyclerFunc(pvName, spec, plugin.host, plugin.config) } func (plugin *hostPathPlugin) NewDeleter(spec *volume.Spec) (volume.Deleter, error) { @@ -130,7 +130,7 @@ func (plugin *hostPathPlugin) NewProvisioner(options volume.VolumeOptions) (volu return plugin.newProvisionerFunc(options, plugin.host) } -func newRecycler(spec *volume.Spec, host volume.VolumeHost, config volume.VolumeConfig) (volume.Recycler, error) { +func newRecycler(pvName string, spec *volume.Spec, host volume.VolumeHost, config volume.VolumeConfig) (volume.Recycler, error) { if spec.PersistentVolume == nil || spec.PersistentVolume.Spec.HostPath == nil { return nil, fmt.Errorf("spec.PersistentVolumeSource.HostPath is nil") } @@ -141,6 +141,7 @@ func newRecycler(spec *volume.Spec, host volume.VolumeHost, config volume.Volume host: host, config: config, timeout: volume.CalculateTimeoutForVolume(config.RecyclerMinimumTimeout, config.RecyclerTimeoutIncrement, spec.PersistentVolume), + pvName: pvName, }, nil } @@ -221,6 +222,7 @@ type hostPathRecycler struct { config volume.VolumeConfig timeout int64 volume.MetricsNil + pvName string } func (r *hostPathRecycler) GetPath() string { @@ -234,13 +236,12 @@ func (r *hostPathRecycler) Recycle() error { pod := r.config.RecyclerPodTemplate // overrides pod.Spec.ActiveDeadlineSeconds = &r.timeout - pod.GenerateName = "pv-recycler-hostpath-" pod.Spec.Volumes[0].VolumeSource = api.VolumeSource{ HostPath: &api.HostPathVolumeSource{ Path: r.path, }, } - return volume.RecycleVolumeByWatchingPodUntilCompletion(pod, r.host.GetKubeClient()) + return volume.RecycleVolumeByWatchingPodUntilCompletion(r.pvName, pod, r.host.GetKubeClient()) } // hostPathProvisioner implements a Provisioner for the HostPath plugin @@ -252,18 +253,12 @@ type hostPathProvisioner struct { // Create for hostPath simply creates a local /tmp/hostpath_pv/%s directory as a new PersistentVolume. // This Provisioner is meant for development and testing only and WILL NOT WORK in a multi-node cluster. -func (r *hostPathProvisioner) Provision(pv *api.PersistentVolume) error { - if pv.Spec.HostPath == nil { - return fmt.Errorf("pv.Spec.HostPath cannot be nil") - } - return os.MkdirAll(pv.Spec.HostPath.Path, 0750) -} - -func (r *hostPathProvisioner) NewPersistentVolumeTemplate() (*api.PersistentVolume, error) { +func (r *hostPathProvisioner) Provision() (*api.PersistentVolume, error) { fullpath := fmt.Sprintf("/tmp/hostpath_pv/%s", util.NewUUID()) - return &api.PersistentVolume{ + + pv := &api.PersistentVolume{ ObjectMeta: api.ObjectMeta{ - GenerateName: "pv-hostpath-", + Name: r.options.PVName, Annotations: map[string]string{ "kubernetes.io/createdby": "hostpath-dynamic-provisioner", }, @@ -280,7 +275,9 @@ func (r *hostPathProvisioner) NewPersistentVolumeTemplate() (*api.PersistentVolu }, }, }, - }, nil + } + + return pv, os.MkdirAll(pv.Spec.HostPath.Path, 0750) } // hostPathDeleter deletes a hostPath PV from the cluster. diff --git a/vendor/k8s.io/kubernetes/pkg/volume/nfs/nfs.go b/vendor/k8s.io/kubernetes/pkg/volume/nfs/nfs.go index 09a6af5017..6b787c6bc3 100644 --- a/vendor/k8s.io/kubernetes/pkg/volume/nfs/nfs.go +++ b/vendor/k8s.io/kubernetes/pkg/volume/nfs/nfs.go @@ -46,7 +46,7 @@ func ProbeVolumePlugins(volumeConfig volume.VolumeConfig) []volume.VolumePlugin type nfsPlugin struct { host volume.VolumeHost // decouple creating recyclers by deferring to a function. Allows for easier testing. - newRecyclerFunc func(spec *volume.Spec, host volume.VolumeHost, volumeConfig volume.VolumeConfig) (volume.Recycler, error) + newRecyclerFunc func(pvName string, spec *volume.Spec, host volume.VolumeHost, volumeConfig volume.VolumeConfig) (volume.Recycler, error) config volume.VolumeConfig } @@ -120,8 +120,8 @@ func (plugin *nfsPlugin) newUnmounterInternal(volName string, podUID types.UID, }}, nil } -func (plugin *nfsPlugin) NewRecycler(spec *volume.Spec) (volume.Recycler, error) { - return plugin.newRecyclerFunc(spec, plugin.host, plugin.config) +func (plugin *nfsPlugin) NewRecycler(pvName string, spec *volume.Spec) (volume.Recycler, error) { + return plugin.newRecyclerFunc(pvName, spec, plugin.host, plugin.config) } // NFS volumes represent a bare host file or directory mount of an NFS export. @@ -250,7 +250,7 @@ func (c *nfsUnmounter) TearDownAt(dir string) error { return nil } -func newRecycler(spec *volume.Spec, host volume.VolumeHost, volumeConfig volume.VolumeConfig) (volume.Recycler, error) { +func newRecycler(pvName string, spec *volume.Spec, host volume.VolumeHost, volumeConfig volume.VolumeConfig) (volume.Recycler, error) { if spec.PersistentVolume == nil || spec.PersistentVolume.Spec.NFS == nil { return nil, fmt.Errorf("spec.PersistentVolumeSource.NFS is nil") } @@ -261,6 +261,7 @@ func newRecycler(spec *volume.Spec, host volume.VolumeHost, volumeConfig volume. host: host, config: volumeConfig, timeout: volume.CalculateTimeoutForVolume(volumeConfig.RecyclerMinimumTimeout, volumeConfig.RecyclerTimeoutIncrement, spec.PersistentVolume), + pvName: pvName, }, nil } @@ -273,6 +274,7 @@ type nfsRecycler struct { config volume.VolumeConfig timeout int64 volume.MetricsNil + pvName string } func (r *nfsRecycler) GetPath() string { @@ -292,5 +294,5 @@ func (r *nfsRecycler) Recycle() error { Path: r.path, }, } - return volume.RecycleVolumeByWatchingPodUntilCompletion(pod, r.host.GetKubeClient()) + return volume.RecycleVolumeByWatchingPodUntilCompletion(r.pvName, pod, r.host.GetKubeClient()) } diff --git a/vendor/k8s.io/kubernetes/pkg/volume/persistent_claim/OWNERS b/vendor/k8s.io/kubernetes/pkg/volume/persistent_claim/OWNERS deleted file mode 100644 index fdc2a40e07..0000000000 --- a/vendor/k8s.io/kubernetes/pkg/volume/persistent_claim/OWNERS +++ /dev/null @@ -1,2 +0,0 @@ -maintainers: -- childsb diff --git a/vendor/k8s.io/kubernetes/pkg/volume/persistent_claim/persistent_claim.go b/vendor/k8s.io/kubernetes/pkg/volume/persistent_claim/persistent_claim.go deleted file mode 100644 index ea593bd9a8..0000000000 --- a/vendor/k8s.io/kubernetes/pkg/volume/persistent_claim/persistent_claim.go +++ /dev/null @@ -1,109 +0,0 @@ -/* -Copyright 2014 The Kubernetes Authors All rights reserved. - -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 persistent_claim - -import ( - "fmt" - "strconv" - - "github.com/golang/glog" - "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/types" - "k8s.io/kubernetes/pkg/volume" -) - -func ProbeVolumePlugins() []volume.VolumePlugin { - return []volume.VolumePlugin{&persistentClaimPlugin{host: nil}} -} - -type persistentClaimPlugin struct { - host volume.VolumeHost - readOnly bool -} - -var _ volume.VolumePlugin = &persistentClaimPlugin{} - -const ( - persistentClaimPluginName = "kubernetes.io/persistent-claim" - volumeGidAnnotationKey = "pv.beta.kubernetes.io/gid" -) - -func (plugin *persistentClaimPlugin) Init(host volume.VolumeHost) error { - plugin.host = host - return nil -} - -func (plugin *persistentClaimPlugin) Name() string { - return persistentClaimPluginName -} - -func (plugin *persistentClaimPlugin) CanSupport(spec *volume.Spec) bool { - return spec.Volume != nil && spec.Volume.PersistentVolumeClaim != nil -} - -func (plugin *persistentClaimPlugin) NewMounter(spec *volume.Spec, pod *api.Pod, opts volume.VolumeOptions) (volume.Mounter, error) { - claim, err := plugin.host.GetKubeClient().Core().PersistentVolumeClaims(pod.Namespace).Get(spec.Volume.PersistentVolumeClaim.ClaimName) - if err != nil { - glog.Errorf("Error finding claim: %+v\n", spec.Volume.PersistentVolumeClaim.ClaimName) - return nil, err - } - - if claim.Spec.VolumeName == "" { - return nil, fmt.Errorf("The claim %+v is not yet bound to a volume", claim.Name) - } - - pv, err := plugin.host.GetKubeClient().Core().PersistentVolumes().Get(claim.Spec.VolumeName) - if err != nil { - glog.Errorf("Error finding persistent volume for claim: %+v\n", claim.Name) - return nil, err - } - - if pv.Spec.ClaimRef == nil { - glog.Errorf("The volume is not yet bound to the claim. Expected to find the bind on volume.Spec.ClaimRef: %+v", pv) - return nil, err - } - - if pv.Spec.ClaimRef.UID != claim.UID { - glog.Errorf("Expected volume.Spec.ClaimRef.UID %+v but have %+v", pv.Spec.ClaimRef.UID, claim.UID) - return nil, err - } - - // If a GID annotation is provided set the GID attribute. - if volumeGid, ok := pv.Annotations[volumeGidAnnotationKey]; ok { - gid, err := strconv.ParseInt(volumeGid, 10, 64) - if err != nil { - return nil, fmt.Errorf("Invalid value for %s %v", volumeGidAnnotationKey, err) - } - - if pod.Spec.SecurityContext == nil { - pod.Spec.SecurityContext = &api.PodSecurityContext{} - } - pod.Spec.SecurityContext.SupplementalGroups = append(pod.Spec.SecurityContext.SupplementalGroups, gid) - } - - mounter, err := plugin.host.NewWrapperMounter(claim.Spec.VolumeName, *volume.NewSpecFromPersistentVolume(pv, spec.ReadOnly), pod, opts) - if err != nil { - glog.Errorf("Error creating mounter for claim: %+v\n", claim.Name) - return nil, err - } - - return mounter, nil -} - -func (plugin *persistentClaimPlugin) NewUnmounter(_ string, _ types.UID) (volume.Unmounter, error) { - return nil, fmt.Errorf("This will never be called directly. The PV backing this claim has a unmounter. Kubelet uses that unmounter, not this one, when removing orphaned volumes.") -} diff --git a/vendor/k8s.io/kubernetes/pkg/volume/plugins.go b/vendor/k8s.io/kubernetes/pkg/volume/plugins.go index 190342cb36..31a69e1b17 100644 --- a/vendor/k8s.io/kubernetes/pkg/volume/plugins.go +++ b/vendor/k8s.io/kubernetes/pkg/volume/plugins.go @@ -101,7 +101,7 @@ type RecyclableVolumePlugin interface { VolumePlugin // NewRecycler creates a new volume.Recycler which knows how to reclaim this resource // after the volume's release from a PersistentVolumeClaim - NewRecycler(spec *Spec) (Recycler, error) + NewRecycler(pvName string, spec *Spec) (Recycler, error) } // DeletableVolumePlugin is an extended interface of VolumePlugin and is used by persistent volumes that want @@ -238,6 +238,9 @@ type VolumeConfig struct { // Example: 5Gi volume x 30s increment = 150s + 30s minimum = 180s ActiveDeadlineSeconds for recycler pod RecyclerTimeoutIncrement int + // PVName is name of the PersistentVolume instance that is being recycled. It is used to generate unique recycler pod name. + PVName string + // OtherAttributes stores config as strings. These strings are opaque to the system and only understood by the binary // hosting the plugin and the plugin itself. OtherAttributes map[string]string @@ -272,8 +275,8 @@ func (pm *VolumePluginMgr) InitPlugins(plugins []VolumePlugin, host VolumeHost) allErrs := []error{} for _, plugin := range plugins { name := plugin.Name() - if !validation.IsQualifiedName(name) { - allErrs = append(allErrs, fmt.Errorf("volume plugin has invalid name: %#v", plugin)) + if errs := validation.IsQualifiedName(name); len(errs) != 0 { + allErrs = append(allErrs, fmt.Errorf("volume plugin has invalid name: %q: %s", name, strings.Join(errs, ";"))) continue } diff --git a/vendor/k8s.io/kubernetes/pkg/volume/secret/secret.go b/vendor/k8s.io/kubernetes/pkg/volume/secret/secret.go index 4573441181..7a003c4795 100644 --- a/vendor/k8s.io/kubernetes/pkg/volume/secret/secret.go +++ b/vendor/k8s.io/kubernetes/pkg/volume/secret/secret.go @@ -18,8 +18,6 @@ package secret import ( "fmt" - "os" - "path" "github.com/golang/glog" "k8s.io/kubernetes/pkg/api" @@ -74,9 +72,9 @@ func (plugin *secretPlugin) NewMounter(spec *volume.Spec, pod *api.Pod, opts vol plugin.host.GetWriter(), volume.NewCachedMetrics(volume.NewMetricsDu(getPathFromHost(plugin.host, pod.UID, spec.Name()))), }, - secretName: spec.Volume.Secret.SecretName, - pod: *pod, - opts: &opts, + source: *spec.Volume.Secret, + pod: *pod, + opts: &opts, }, nil } @@ -117,9 +115,9 @@ func getPathFromHost(host volume.VolumeHost, podUID types.UID, volName string) s type secretVolumeMounter struct { *secretVolume - secretName string - pod api.Pod - opts *volume.VolumeOptions + source api.SecretVolumeSource + pod api.Pod + opts *volume.VolumeOptions } var _ volume.Mounter = &secretVolumeMounter{} @@ -135,24 +133,7 @@ func (b *secretVolumeMounter) SetUp(fsGroup *int64) error { return b.SetUpAt(b.GetPath(), fsGroup) } -func (b *secretVolumeMounter) getMetaDir() string { - return path.Join(b.plugin.host.GetPodPluginDir(b.podUID, strings.EscapeQualifiedNameForDisk(secretPluginName)), b.volName) -} - func (b *secretVolumeMounter) SetUpAt(dir string, fsGroup *int64) error { - notMnt, err := b.mounter.IsLikelyNotMountPoint(dir) - // Getting an os.IsNotExist err from is a contingency; the directory - // may not exist yet, in which case, setup should run. - if err != nil && !os.IsNotExist(err) { - return err - } - - // If the plugin readiness file is present for this volume and - // the setup dir is a mountpoint, this volume is already ready. - if volumeutil.IsReady(b.getMetaDir()) && !notMnt { - return nil - } - glog.V(3).Infof("Setting up volume %v for pod %v at %v", b.volName, b.pod.UID, dir) // Wrap EmptyDir, let it do the setup. @@ -169,34 +150,66 @@ func (b *secretVolumeMounter) SetUpAt(dir string, fsGroup *int64) error { return fmt.Errorf("Cannot setup secret volume %v because kube client is not configured", b.volName) } - secret, err := kubeClient.Core().Secrets(b.pod.Namespace).Get(b.secretName) + secret, err := kubeClient.Core().Secrets(b.pod.Namespace).Get(b.source.SecretName) if err != nil { - glog.Errorf("Couldn't get secret %v/%v", b.pod.Namespace, b.secretName) + glog.Errorf("Couldn't get secret %v/%v", b.pod.Namespace, b.source.SecretName) return err - } else { - totalBytes := totalSecretBytes(secret) - glog.V(3).Infof("Received secret %v/%v containing (%v) pieces of data, %v total bytes", - b.pod.Namespace, - b.secretName, - len(secret.Data), - totalBytes) } - for name, data := range secret.Data { - hostFilePath := path.Join(dir, name) - glog.V(3).Infof("Writing secret data %v/%v/%v (%v bytes) to host file %v", b.pod.Namespace, b.secretName, name, len(data), hostFilePath) - err := b.writer.WriteFile(hostFilePath, data, 0444) - if err != nil { - glog.Errorf("Error writing secret data to host path: %v, %v", hostFilePath, err) - return err + totalBytes := totalSecretBytes(secret) + glog.V(3).Infof("Received secret %v/%v containing (%v) pieces of data, %v total bytes", + b.pod.Namespace, + b.source.SecretName, + len(secret.Data), + totalBytes) + + payload, err := makePayload(b.source.Items, secret) + if err != nil { + return err + } + + writerContext := fmt.Sprintf("pod %v/%v volume %v", b.pod.Namespace, b.pod.Name, b.volName) + writer, err := volumeutil.NewAtomicWriter(dir, writerContext) + if err != nil { + glog.Errorf("Error creating atomic writer: %v", err) + return err + } + + err = writer.Write(payload) + if err != nil { + glog.Errorf("Error writing payload to dir: %v", err) + return err + } + + err = volume.SetVolumeOwnership(b, fsGroup) + if err != nil { + glog.Errorf("Error applying volume ownership settings for group: %v", fsGroup) + return err + } + + return nil +} + +func makePayload(mappings []api.KeyToPath, secret *api.Secret) (map[string][]byte, error) { + payload := make(map[string][]byte, len(secret.Data)) + + if len(mappings) == 0 { + for name, data := range secret.Data { + payload[name] = []byte(data) + } + } else { + for _, ktp := range mappings { + content, ok := secret.Data[ktp.Key] + if !ok { + glog.Errorf("references non-existent secret key") + return nil, fmt.Errorf("references non-existent secret key") + } + + payload[ktp.Path] = []byte(content) } } - volume.SetVolumeOwnership(b, fsGroup) - - volumeutil.SetReady(b.getMetaDir()) - - return nil + return payload, nil } func totalSecretBytes(secret *api.Secret) int { diff --git a/vendor/k8s.io/kubernetes/pkg/volume/util.go b/vendor/k8s.io/kubernetes/pkg/volume/util.go index 7dc454d3cd..c4a532fa16 100644 --- a/vendor/k8s.io/kubernetes/pkg/volume/util.go +++ b/vendor/k8s.io/kubernetes/pkg/volume/util.go @@ -28,31 +28,52 @@ import ( "k8s.io/kubernetes/pkg/watch" "github.com/golang/glog" + "k8s.io/kubernetes/pkg/api/errors" "k8s.io/kubernetes/pkg/api/resource" ) -// RecycleVolumeByWatchingPodUntilCompletion is intended for use with volume Recyclers. This function will -// save the given Pod to the API and watch it until it completes, fails, or the pod's ActiveDeadlineSeconds is exceeded, whichever comes first. -// An attempt to delete a recycler pod is always attempted before returning. -// pod - the pod designed by a volume plugin to recycle the volume +// RecycleVolumeByWatchingPodUntilCompletion is intended for use with volume +// Recyclers. This function will save the given Pod to the API and watch it +// until it completes, fails, or the pod's ActiveDeadlineSeconds is exceeded, +// whichever comes first. An attempt to delete a recycler pod is always +// attempted before returning. +// +// In case there is a pod with the same namespace+name already running, this +// function assumes it's an older instance of the recycler pod and watches this +// old pod instead of starting a new one. +// +// pod - the pod designed by a volume plugin to recycle the volume. pod.Name +// will be overwritten with unique name based on PV.Name. // client - kube client for API operations. -func RecycleVolumeByWatchingPodUntilCompletion(pod *api.Pod, kubeClient clientset.Interface) error { - return internalRecycleVolumeByWatchingPodUntilCompletion(pod, newRecyclerClient(kubeClient)) +func RecycleVolumeByWatchingPodUntilCompletion(pvName string, pod *api.Pod, kubeClient clientset.Interface) error { + return internalRecycleVolumeByWatchingPodUntilCompletion(pvName, pod, newRecyclerClient(kubeClient)) } // same as above func comments, except 'recyclerClient' is a narrower pod API interface to ease testing -func internalRecycleVolumeByWatchingPodUntilCompletion(pod *api.Pod, recyclerClient recyclerClient) error { - glog.V(5).Infof("Creating recycler pod for volume %s\n", pod.Name) - pod, err := recyclerClient.CreatePod(pod) - if err != nil { - return fmt.Errorf("Unexpected error creating recycler pod: %+v\n", err) - } +func internalRecycleVolumeByWatchingPodUntilCompletion(pvName string, pod *api.Pod, recyclerClient recyclerClient) error { + glog.V(5).Infof("creating recycler pod for volume %s\n", pod.Name) + // Generate unique name for the recycler pod - we need to get "already + // exists" error when a previous controller has already started recycling + // the volume. Here we assume that pv.Name is already unique. + pod.Name = "recycler-for-" + pvName + pod.GenerateName = "" + + // Start the pod + _, err := recyclerClient.CreatePod(pod) + if err != nil { + if errors.IsAlreadyExists(err) { + glog.V(5).Infof("old recycler pod %q found for volume", pod.Name) + } else { + return fmt.Errorf("Unexpected error creating recycler pod: %+v\n", err) + } + } defer recyclerClient.DeletePod(pod.Name, pod.Namespace) + // Now only the old pod or the new pod run. Watch it until it finishes. stopChannel := make(chan struct{}) defer close(stopChannel) - nextPod := recyclerClient.WatchPod(pod.Name, pod.Namespace, pod.ResourceVersion, stopChannel) + nextPod := recyclerClient.WatchPod(pod.Name, pod.Namespace, stopChannel) for { watchedPod := nextPod() @@ -65,7 +86,7 @@ func internalRecycleVolumeByWatchingPodUntilCompletion(pod *api.Pod, recyclerCli if watchedPod.Status.Message != "" { return fmt.Errorf(watchedPod.Status.Message) } else { - return fmt.Errorf("Pod failed, pod.Status.Message unknown.") + return fmt.Errorf("pod failed, pod.Status.Message unknown.") } } } @@ -77,7 +98,7 @@ type recyclerClient interface { CreatePod(pod *api.Pod) (*api.Pod, error) GetPod(name, namespace string) (*api.Pod, error) DeletePod(name, namespace string) error - WatchPod(name, namespace, resourceVersion string, stopChannel chan struct{}) func() *api.Pod + WatchPod(name, namespace string, stopChannel chan struct{}) func() *api.Pod } func newRecyclerClient(client clientset.Interface) recyclerClient { @@ -103,7 +124,7 @@ func (c *realRecyclerClient) DeletePod(name, namespace string) error { // WatchPod returns a ListWatch for watching a pod. The stopChannel is used // to close the reflector backing the watch. The caller is responsible for derring a close on the channel to // stop the reflector. -func (c *realRecyclerClient) WatchPod(name, namespace, resourceVersion string, stopChannel chan struct{}) func() *api.Pod { +func (c *realRecyclerClient) WatchPod(name, namespace string, stopChannel chan struct{}) func() *api.Pod { fieldSelector, _ := fields.ParseSelector("metadata.name=" + name) podLW := &cache.ListWatch{ diff --git a/vendor/k8s.io/kubernetes/pkg/volume/util/fs_darwin.go b/vendor/k8s.io/kubernetes/pkg/volume/util/fs_darwin.go index 91d5ef9707..ef7a161822 100644 --- a/vendor/k8s.io/kubernetes/pkg/volume/util/fs_darwin.go +++ b/vendor/k8s.io/kubernetes/pkg/volume/util/fs_darwin.go @@ -43,5 +43,5 @@ func Du(path string) (*resource.Quantity, error) { return nil, fmt.Errorf("failed to parse 'du' output %s due to error %v", out, err) } used.Format = resource.BinarySI - return used, nil + return &used, nil } diff --git a/vendor/k8s.io/kubernetes/pkg/volume/util/fs_linux.go b/vendor/k8s.io/kubernetes/pkg/volume/util/fs_linux.go index 39d1b0399a..5193c0a3fc 100644 --- a/vendor/k8s.io/kubernetes/pkg/volume/util/fs_linux.go +++ b/vendor/k8s.io/kubernetes/pkg/volume/util/fs_linux.go @@ -57,5 +57,5 @@ func Du(path string) (*resource.Quantity, error) { return nil, fmt.Errorf("failed to parse 'du' output %s due to error %v", out, err) } used.Format = resource.BinarySI - return used, nil + return &used, nil } diff --git a/vendor/k8s.io/kubernetes/pkg/volume/volume.go b/vendor/k8s.io/kubernetes/pkg/volume/volume.go index 91afb468f9..2ea77dbe39 100644 --- a/vendor/k8s.io/kubernetes/pkg/volume/volume.go +++ b/vendor/k8s.io/kubernetes/pkg/volume/volume.go @@ -111,13 +111,10 @@ type Recycler interface { // Provisioner is an interface that creates templates for PersistentVolumes and can create the volume // as a new resource in the infrastructure provider. type Provisioner interface { - // Provision creates the resource by allocating the underlying volume in a storage system. - // This method should block until completion. - Provision(*api.PersistentVolume) error - // NewPersistentVolumeTemplate creates a new PersistentVolume to be used as a template before saving. - // The provisioner will want to tweak its properties, assign correct annotations, etc. - // This func should *NOT* persist the PV in the API. That is left to the caller. - NewPersistentVolumeTemplate() (*api.PersistentVolume, error) + // Provision creates the resource by allocating the underlying volume in a + // storage system. This method should block until completion and returns + // PersistentVolume representing the created storage resource. + Provision() (*api.PersistentVolume, error) } // Deleter removes the resource from the underlying storage provider. Calls to this method should block until @@ -143,7 +140,7 @@ type Attacher interface { // GetDeviceMountPath returns a path where the device should // be mounted after it is attached. This is a global mount // point which should be bind mounted for individual volumes. - GetDeviceMountPath(host VolumeHost, spec *Spec) string + GetDeviceMountPath(spec *Spec) string // MountDevice mounts the disk to a global path which // individual pods can then bind mount diff --git a/vendor/k8s.io/kubernetes/pkg/volume/vsphere_volume/vsphere_volume.go b/vendor/k8s.io/kubernetes/pkg/volume/vsphere_volume/vsphere_volume.go new file mode 100644 index 0000000000..9de3fc33f9 --- /dev/null +++ b/vendor/k8s.io/kubernetes/pkg/volume/vsphere_volume/vsphere_volume.go @@ -0,0 +1,419 @@ +/* +Copyright 2016 The Kubernetes Authors All rights reserved. + +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 vsphere_volume + +import ( + "errors" + "fmt" + "os" + "path" + + "github.com/golang/glog" + "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/resource" + "k8s.io/kubernetes/pkg/cloudprovider/providers/vsphere" + "k8s.io/kubernetes/pkg/types" + "k8s.io/kubernetes/pkg/util/exec" + "k8s.io/kubernetes/pkg/util/mount" + utilstrings "k8s.io/kubernetes/pkg/util/strings" + "k8s.io/kubernetes/pkg/volume" +) + +// This is the primary entrypoint for volume plugins. +func ProbeVolumePlugins() []volume.VolumePlugin { + return []volume.VolumePlugin{&vsphereVolumePlugin{}} +} + +type vsphereVolumePlugin struct { + host volume.VolumeHost +} + +var _ volume.VolumePlugin = &vsphereVolumePlugin{} +var _ volume.PersistentVolumePlugin = &vsphereVolumePlugin{} +var _ volume.DeletableVolumePlugin = &vsphereVolumePlugin{} +var _ volume.ProvisionableVolumePlugin = &vsphereVolumePlugin{} + +const ( + vsphereVolumePluginName = "kubernetes.io/vsphere-volume" +) + +// vSphere Volume Plugin +func (plugin *vsphereVolumePlugin) Init(host volume.VolumeHost) error { + plugin.host = host + return nil +} + +func (plugin *vsphereVolumePlugin) Name() string { + return vsphereVolumePluginName +} + +func (plugin *vsphereVolumePlugin) CanSupport(spec *volume.Spec) bool { + return (spec.PersistentVolume != nil && spec.PersistentVolume.Spec.VsphereVolume != nil) || + (spec.Volume != nil && spec.Volume.VsphereVolume != nil) +} + +func (plugin *vsphereVolumePlugin) NewMounter(spec *volume.Spec, pod *api.Pod, _ volume.VolumeOptions) (volume.Mounter, error) { + return plugin.newMounterInternal(spec, pod.UID, &VsphereDiskUtil{}, plugin.host.GetMounter()) +} + +func (plugin *vsphereVolumePlugin) NewUnmounter(volName string, podUID types.UID) (volume.Unmounter, error) { + return plugin.newUnmounterInternal(volName, podUID, &VsphereDiskUtil{}, plugin.host.GetMounter()) +} + +func (plugin *vsphereVolumePlugin) newMounterInternal(spec *volume.Spec, podUID types.UID, manager vdManager, mounter mount.Interface) (volume.Mounter, error) { + var vvol *api.VsphereVirtualDiskVolumeSource + if spec.Volume != nil && spec.Volume.VsphereVolume != nil { + vvol = spec.Volume.VsphereVolume + } else { + vvol = spec.PersistentVolume.Spec.VsphereVolume + } + + volPath := vvol.VolumePath + fsType := vvol.FSType + + return &vsphereVolumeMounter{ + vsphereVolume: &vsphereVolume{ + podUID: podUID, + volName: spec.Name(), + volPath: volPath, + manager: manager, + mounter: mounter, + plugin: plugin, + }, + fsType: fsType, + diskMounter: &mount.SafeFormatAndMount{Interface: mounter, Runner: exec.New()}}, nil +} + +func (plugin *vsphereVolumePlugin) newUnmounterInternal(volName string, podUID types.UID, manager vdManager, mounter mount.Interface) (volume.Unmounter, error) { + return &vsphereVolumeUnmounter{ + &vsphereVolume{ + podUID: podUID, + volName: volName, + manager: manager, + mounter: mounter, + plugin: plugin, + }}, nil +} + +func (plugin *vsphereVolumePlugin) getCloudProvider() (*vsphere.VSphere, error) { + cloud := plugin.host.GetCloudProvider() + if cloud == nil { + glog.Errorf("Cloud provider not initialized properly") + return nil, errors.New("Cloud provider not initialized properly") + } + + vs := cloud.(*vsphere.VSphere) + if vs == nil { + return nil, errors.New("Invalid cloud provider: expected vSphere") + } + return vs, nil +} + +// Abstract interface to disk operations. +type vdManager interface { + // Attaches the disk to the kubelet's host machine. + AttachDisk(mounter *vsphereVolumeMounter, globalPDPath string) error + // Detaches the disk from the kubelet's host machine. + DetachDisk(unmounter *vsphereVolumeUnmounter) error + // Creates a volume + CreateVolume(provisioner *vsphereVolumeProvisioner) (vmDiskPath string, volumeSizeGB int, err error) + // Deletes a volume + DeleteVolume(deleter *vsphereVolumeDeleter) error +} + +// vspherePersistentDisk volumes are disk resources are attached to the kubelet's host machine and exposed to the pod. +type vsphereVolume struct { + volName string + podUID types.UID + // Unique identifier of the volume, used to find the disk resource in the provider. + volPath string + // Filesystem type, optional. + fsType string + //diskID for detach disk + diskID string + // Utility interface that provides API calls to the provider to attach/detach disks. + manager vdManager + // Mounter interface that provides system calls to mount the global path to the pod local path. + mounter mount.Interface + // diskMounter provides the interface that is used to mount the actual block device. + diskMounter mount.Interface + plugin *vsphereVolumePlugin + volume.MetricsNil +} + +func detachDiskLogError(vv *vsphereVolume) { + err := vv.manager.DetachDisk(&vsphereVolumeUnmounter{vv}) + if err != nil { + glog.Warningf("Failed to detach disk: %v (%v)", vv, err) + } +} + +var _ volume.Mounter = &vsphereVolumeMounter{} + +type vsphereVolumeMounter struct { + *vsphereVolume + fsType string + diskMounter *mount.SafeFormatAndMount +} + +func (b *vsphereVolumeMounter) GetAttributes() volume.Attributes { + return volume.Attributes{ + SupportsSELinux: true, + } +} + +// SetUp attaches the disk and bind mounts to the volume path. +func (b *vsphereVolumeMounter) SetUp(fsGroup *int64) error { + return b.SetUpAt(b.GetPath(), fsGroup) +} + +// SetUp attaches the disk and bind mounts to the volume path. +func (b *vsphereVolumeMounter) SetUpAt(dir string, fsGroup *int64) error { + glog.V(5).Infof("vSphere volume setup %s to %s", b.volPath, dir) + + // TODO: handle failed mounts here. + notmnt, err := b.mounter.IsLikelyNotMountPoint(dir) + if err != nil && !os.IsNotExist(err) { + glog.V(4).Infof("IsLikelyNotMountPoint failed: %v", err) + return err + } + if !notmnt { + glog.V(4).Infof("Something is already mounted to target %s", dir) + return nil + } + globalPDPath := makeGlobalPDPath(b.plugin.host, b.volPath) + if err := b.manager.AttachDisk(b, globalPDPath); err != nil { + glog.V(4).Infof("AttachDisk failed: %v", err) + return err + } + glog.V(3).Infof("vSphere volume %s attached", b.volPath) + + options := []string{"bind"} + + if err := os.MkdirAll(dir, 0750); err != nil { + // TODO: we should really eject the attach/detach out into its own control loop. + glog.V(4).Infof("Could not create directory %s: %v", dir, err) + detachDiskLogError(b.vsphereVolume) + return err + } + + // Perform a bind mount to the full path to allow duplicate mounts of the same PD. + err = b.mounter.Mount(globalPDPath, dir, "", options) + if err != nil { + notmnt, mntErr := b.mounter.IsLikelyNotMountPoint(dir) + if mntErr != nil { + glog.Errorf("IsLikelyNotMountPoint check failed: %v", mntErr) + return err + } + if !notmnt { + if mntErr = b.mounter.Unmount(dir); mntErr != nil { + glog.Errorf("Failed to unmount: %v", mntErr) + return err + } + notmnt, mntErr := b.mounter.IsLikelyNotMountPoint(dir) + if mntErr != nil { + glog.Errorf("IsLikelyNotMountPoint check failed: %v", mntErr) + return err + } + if !notmnt { + glog.Errorf("%s is still mounted, despite call to unmount(). Will try again next sync loop.", b.GetPath()) + return err + } + } + os.Remove(dir) + detachDiskLogError(b.vsphereVolume) + return err + } + glog.V(3).Infof("vSphere volume %s mounted to %s", b.volPath, dir) + + return nil +} + +var _ volume.Unmounter = &vsphereVolumeUnmounter{} + +type vsphereVolumeUnmounter struct { + *vsphereVolume +} + +// Unmounts the bind mount, and detaches the disk only if the PD +// resource was the last reference to that disk on the kubelet. +func (v *vsphereVolumeUnmounter) TearDown() error { + return v.TearDownAt(v.GetPath()) +} + +// Unmounts the bind mount, and detaches the disk only if the PD +// resource was the last reference to that disk on the kubelet. +func (v *vsphereVolumeUnmounter) TearDownAt(dir string) error { + glog.V(5).Infof("vSphere Volume TearDown of %s", dir) + notmnt, err := v.mounter.IsLikelyNotMountPoint(dir) + if err != nil { + glog.V(4).Infof("Error checking if mountpoint ", dir, ": ", err) + return err + } + if notmnt { + glog.V(4).Infof("Not mount point,deleting") + return os.Remove(dir) + } + + // Find vSphere volumeID to lock the right volume + refs, err := mount.GetMountRefs(v.mounter, dir) + if err != nil { + glog.V(4).Infof("Error getting mountrefs for ", dir, ": ", err) + return err + } + if len(refs) == 0 { + glog.V(4).Infof("Directory %s is not mounted", dir) + return fmt.Errorf("directory %s is not mounted", dir) + } + + v.volPath = path.Base(refs[0]) + glog.V(4).Infof("Found volume %s mounted to %s", v.volPath, dir) + + // Reload list of references, there might be SetUpAt finished in the meantime + refs, err = mount.GetMountRefs(v.mounter, dir) + if err != nil { + glog.V(4).Infof("GetMountRefs failed: %v", err) + return err + } + if err := v.mounter.Unmount(dir); err != nil { + glog.V(4).Infof("Unmount failed: %v", err) + return err + } + glog.V(3).Infof("Successfully unmounted: %s\n", dir) + + // If refCount is 1, then all bind mounts have been removed, and the + // remaining reference is the global mount. It is safe to detach. + if len(refs) == 1 { + if err := v.manager.DetachDisk(v); err != nil { + glog.V(4).Infof("DetachDisk failed: %v", err) + return err + } + glog.V(3).Infof("Volume %s detached", v.volPath) + } + notmnt, mntErr := v.mounter.IsLikelyNotMountPoint(dir) + if mntErr != nil { + glog.Errorf("IsLikelyNotMountPoint check failed: %v", mntErr) + return err + } + if notmnt { + if err := os.Remove(dir); err != nil { + glog.V(4).Infof("Failed to remove directory after unmount: %v", err) + return err + } + } + return nil +} + +func makeGlobalPDPath(host volume.VolumeHost, devName string) string { + return path.Join(host.GetPluginDir(vsphereVolumePluginName), "mounts", devName) +} + +func (vv *vsphereVolume) GetPath() string { + name := vsphereVolumePluginName + return vv.plugin.host.GetPodVolumeDir(vv.podUID, utilstrings.EscapeQualifiedNameForDisk(name), vv.volName) +} + +// vSphere Persistent Volume Plugin +func (plugin *vsphereVolumePlugin) GetAccessModes() []api.PersistentVolumeAccessMode { + return []api.PersistentVolumeAccessMode{ + api.ReadWriteOnce, + } +} + +// vSphere Deletable Volume Plugin +type vsphereVolumeDeleter struct { + *vsphereVolume +} + +var _ volume.Deleter = &vsphereVolumeDeleter{} + +func (plugin *vsphereVolumePlugin) NewDeleter(spec *volume.Spec) (volume.Deleter, error) { + return plugin.newDeleterInternal(spec, &VsphereDiskUtil{}) +} + +func (plugin *vsphereVolumePlugin) newDeleterInternal(spec *volume.Spec, manager vdManager) (volume.Deleter, error) { + if spec.PersistentVolume != nil && spec.PersistentVolume.Spec.VsphereVolume == nil { + return nil, fmt.Errorf("spec.PersistentVolumeSource.VsphereVolume is nil") + } + return &vsphereVolumeDeleter{ + &vsphereVolume{ + volName: spec.Name(), + volPath: spec.PersistentVolume.Spec.VsphereVolume.VolumePath, + manager: manager, + plugin: plugin, + }}, nil +} + +func (r *vsphereVolumeDeleter) Delete() error { + return r.manager.DeleteVolume(r) +} + +// vSphere Provisionable Volume Plugin +type vsphereVolumeProvisioner struct { + *vsphereVolume + options volume.VolumeOptions +} + +var _ volume.Provisioner = &vsphereVolumeProvisioner{} + +func (plugin *vsphereVolumePlugin) NewProvisioner(options volume.VolumeOptions) (volume.Provisioner, error) { + if len(options.AccessModes) == 0 { + options.AccessModes = plugin.GetAccessModes() + } + return plugin.newProvisionerInternal(options, &VsphereDiskUtil{}) +} + +func (plugin *vsphereVolumePlugin) newProvisionerInternal(options volume.VolumeOptions, manager vdManager) (volume.Provisioner, error) { + return &vsphereVolumeProvisioner{ + vsphereVolume: &vsphereVolume{ + manager: manager, + plugin: plugin, + }, + options: options, + }, nil +} + +func (v *vsphereVolumeProvisioner) Provision() (*api.PersistentVolume, error) { + vmDiskPath, sizeKB, err := v.manager.CreateVolume(v) + if err != nil { + return nil, err + } + + pv := &api.PersistentVolume{ + ObjectMeta: api.ObjectMeta{ + Name: v.options.PVName, + Labels: map[string]string{}, + Annotations: map[string]string{ + "kubernetes.io/createdby": "vsphere-volume-dynamic-provisioner", + }, + }, + Spec: api.PersistentVolumeSpec{ + PersistentVolumeReclaimPolicy: v.options.PersistentVolumeReclaimPolicy, + AccessModes: v.options.AccessModes, + Capacity: api.ResourceList{ + api.ResourceName(api.ResourceStorage): resource.MustParse(fmt.Sprintf("%dKi", sizeKB)), + }, + PersistentVolumeSource: api.PersistentVolumeSource{ + VsphereVolume: &api.VsphereVirtualDiskVolumeSource{ + VolumePath: vmDiskPath, + FSType: "ext4", + }, + }, + }, + } + return pv, nil +} diff --git a/vendor/k8s.io/kubernetes/pkg/volume/vsphere_volume/vsphere_volume_util.go b/vendor/k8s.io/kubernetes/pkg/volume/vsphere_volume/vsphere_volume_util.go new file mode 100644 index 0000000000..f2e20a6083 --- /dev/null +++ b/vendor/k8s.io/kubernetes/pkg/volume/vsphere_volume/vsphere_volume_util.go @@ -0,0 +1,199 @@ +/* +Copyright 2016 The Kubernetes Authors All rights reserved. + +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 vsphere_volume + +import ( + "errors" + "io/ioutil" + "os" + "path" + "strings" + "time" + + "github.com/golang/glog" + "k8s.io/kubernetes/pkg/util/exec" + "k8s.io/kubernetes/pkg/util/keymutex" + "k8s.io/kubernetes/pkg/volume" +) + +const ( + maxRetries = 10 +) + +// Singleton key mutex for keeping attach/detach operations for the same PD atomic +var attachDetachMutex = keymutex.NewKeyMutex() + +type VsphereDiskUtil struct{} + +// Attaches a disk to the current kubelet. +// Mounts the disk to it's global path. +func (util *VsphereDiskUtil) AttachDisk(vm *vsphereVolumeMounter, globalPDPath string) error { + options := []string{} + + // Block execution until any pending attach/detach operations for this PD have completed + attachDetachMutex.LockKey(vm.volPath) + defer attachDetachMutex.UnlockKey(vm.volPath) + + cloud, err := vm.plugin.getCloudProvider() + if err != nil { + return err + } + + diskID, diskUUID, attachError := cloud.AttachDisk(vm.volPath, "") + if attachError != nil { + return err + } else if diskUUID == "" { + return errors.New("Disk UUID has no value") + } + + // diskID for detach Disk + vm.diskID = diskID + + var devicePath string + numTries := 0 + for { + devicePath = verifyDevicePath(diskUUID) + // probe the attached vol so that symlink in /dev/disk/by-id is created + probeAttachedVolume() + + _, err := os.Stat(devicePath) + if err == nil { + break + } + if err != nil && !os.IsNotExist(err) { + return err + } + numTries++ + if numTries == maxRetries { + return errors.New("Could not attach disk: Timeout after 60s") + } + time.Sleep(time.Second * 60) + } + + notMnt, err := vm.mounter.IsLikelyNotMountPoint(globalPDPath) + if err != nil { + if os.IsNotExist(err) { + if err := os.MkdirAll(globalPDPath, 0750); err != nil { + return err + } + notMnt = true + } else { + return err + } + } + if notMnt { + err = vm.diskMounter.FormatAndMount(devicePath, globalPDPath, vm.fsType, options) + if err != nil { + os.Remove(globalPDPath) + return err + } + glog.V(2).Infof("Safe mount successful: %q\n", devicePath) + } + return nil +} + +func verifyDevicePath(diskUUID string) string { + files, _ := ioutil.ReadDir("/dev/disk/by-id/") + for _, f := range files { + // TODO: should support other controllers + if strings.Contains(f.Name(), "scsi-") { + devID := f.Name()[len("scsi-"):len(f.Name())] + if strings.Contains(diskUUID, devID) { + glog.V(4).Infof("Found disk attached as %q; full devicepath: %s\n", f.Name(), path.Join("/dev/disk/by-id/", f.Name())) + return path.Join("/dev/disk/by-id/", f.Name()) + } + } + } + glog.Warningf("Failed to find device for the diskid: %q\n", diskUUID) + return "" +} + +func probeAttachedVolume() error { + executor := exec.New() + args := []string{"trigger"} + cmd := executor.Command("/usr/bin/udevadm", args...) + _, err := cmd.CombinedOutput() + if err != nil { + glog.Errorf("error running udevadm trigger %v\n", err) + return err + } + glog.V(4).Infof("Successfully probed all attachments") + return nil +} + +// Unmounts the device and detaches the disk from the kubelet's host machine. +func (util *VsphereDiskUtil) DetachDisk(vu *vsphereVolumeUnmounter) error { + + // Block execution until any pending attach/detach operations for this PD have completed + attachDetachMutex.LockKey(vu.volPath) + defer attachDetachMutex.UnlockKey(vu.volPath) + + globalPDPath := makeGlobalPDPath(vu.plugin.host, vu.volPath) + if err := vu.mounter.Unmount(globalPDPath); err != nil { + return err + } + if err := os.Remove(globalPDPath); err != nil { + return err + } + glog.V(2).Infof("Successfully unmounted main device: %s\n", globalPDPath) + + cloud, err := vu.plugin.getCloudProvider() + if err != nil { + return err + } + + if err = cloud.DetachDisk(vu.diskID, ""); err != nil { + return err + } + glog.V(2).Infof("Successfully detached vSphere volume %s", vu.volPath) + return nil +} + +// CreateVolume creates a vSphere volume. +func (util *VsphereDiskUtil) CreateVolume(v *vsphereVolumeProvisioner) (vmDiskPath string, volumeSizeKB int, err error) { + cloud, err := v.plugin.getCloudProvider() + if err != nil { + return "", 0, err + } + + volSizeBytes := v.options.Capacity.Value() + // vSphere works with kilobytes, convert to KiB with rounding up + volSizeKB := int(volume.RoundUpSize(volSizeBytes, 1024)) + name := volume.GenerateVolumeName(v.options.ClusterName, v.options.PVName, 255) + vmDiskPath, err = cloud.CreateVolume(name, volSizeKB, v.options.CloudTags) + if err != nil { + glog.V(2).Infof("Error creating vsphere volume: %v", err) + return "", 0, err + } + glog.V(2).Infof("Successfully created vsphere volume %s", name) + return vmDiskPath, volSizeKB, nil +} + +// DeleteVolume deletes a vSphere volume. +func (util *VsphereDiskUtil) DeleteVolume(vd *vsphereVolumeDeleter) error { + cloud, err := vd.plugin.getCloudProvider() + if err != nil { + return err + } + + if err = cloud.DeleteVolume(vd.volPath); err != nil { + glog.V(2).Infof("Error deleting vsphere volume %s: %v", vd.volPath, err) + return err + } + glog.V(2).Infof("Successfully deleted vsphere volume %s", vd.volPath) + return nil +} diff --git a/vendor/k8s.io/kubernetes/plugin/cmd/kube-scheduler/app/options/options.go b/vendor/k8s.io/kubernetes/plugin/cmd/kube-scheduler/app/options/options.go index 542bf85757..b54bc1e2e7 100644 --- a/vendor/k8s.io/kubernetes/plugin/cmd/kube-scheduler/app/options/options.go +++ b/vendor/k8s.io/kubernetes/plugin/cmd/kube-scheduler/app/options/options.go @@ -63,7 +63,7 @@ func (s *SchedulerServer) AddFlags(fs *pflag.FlagSet) { var unusedBindPodsBurst int32 fs.Int32Var(&unusedBindPodsBurst, "bind-pods-burst", 0, "unused, use --kube-api-burst") fs.MarkDeprecated("bind-pods-burst", "flag is unused and will be removed. Use kube-api-burst instead.") - fs.StringVar(&s.ContentType, "kube-api-content-type", s.ContentType, "ContentType of requests sent to apiserver. Passing application/vnd.kubernetes.protobuf is an experimental feature now.") + fs.StringVar(&s.ContentType, "kube-api-content-type", s.ContentType, "Content type of requests sent to apiserver.") fs.Float32Var(&s.KubeAPIQPS, "kube-api-qps", s.KubeAPIQPS, "QPS to use while talking with kubernetes apiserver") fs.Int32Var(&s.KubeAPIBurst, "kube-api-burst", s.KubeAPIBurst, "Burst to use while talking with kubernetes apiserver") fs.StringVar(&s.SchedulerName, "scheduler-name", s.SchedulerName, "Name of the scheduler, used to select which pods will be processed by this scheduler, based on pod's annotation with key 'scheduler.alpha.kubernetes.io/name'") diff --git a/vendor/k8s.io/kubernetes/plugin/pkg/admission/alwayspullimages/admission.go b/vendor/k8s.io/kubernetes/plugin/pkg/admission/alwayspullimages/admission.go index 0feb6dc9ea..2d2b5147ef 100644 --- a/vendor/k8s.io/kubernetes/plugin/pkg/admission/alwayspullimages/admission.go +++ b/vendor/k8s.io/kubernetes/plugin/pkg/admission/alwayspullimages/admission.go @@ -56,6 +56,10 @@ func (a *alwaysPullImages) Admit(attributes admission.Attributes) (err error) { return apierrors.NewBadRequest("Resource was marked with kind Pod but was unable to be converted") } + for i := range pod.Spec.InitContainers { + pod.Spec.InitContainers[i].ImagePullPolicy = api.PullAlways + } + for i := range pod.Spec.Containers { pod.Spec.Containers[i].ImagePullPolicy = api.PullAlways } diff --git a/vendor/k8s.io/kubernetes/plugin/pkg/admission/exec/admission.go b/vendor/k8s.io/kubernetes/plugin/pkg/admission/exec/admission.go index 737ee69367..d98bff6759 100644 --- a/vendor/k8s.io/kubernetes/plugin/pkg/admission/exec/admission.go +++ b/vendor/k8s.io/kubernetes/plugin/pkg/admission/exec/admission.go @@ -108,6 +108,14 @@ func (d *denyExec) Admit(a admission.Attributes) (err error) { // isPrivileged will return true a pod has any privileged containers func isPrivileged(pod *api.Pod) bool { + for _, c := range pod.Spec.InitContainers { + if c.SecurityContext == nil { + continue + } + if *c.SecurityContext.Privileged { + return true + } + } for _, c := range pod.Spec.Containers { if c.SecurityContext == nil { continue diff --git a/vendor/k8s.io/kubernetes/plugin/pkg/admission/limitranger/admission.go b/vendor/k8s.io/kubernetes/plugin/pkg/admission/limitranger/admission.go index c8f3acd0cd..6b6d8331fe 100644 --- a/vendor/k8s.io/kubernetes/plugin/pkg/admission/limitranger/admission.go +++ b/vendor/k8s.io/kubernetes/plugin/pkg/admission/limitranger/admission.go @@ -208,45 +208,54 @@ func defaultContainerResourceRequirements(limitRange *api.LimitRange) api.Resour return requirements } +// mergeContainerResources handles defaulting all of the resources on a container. +func mergeContainerResources(container *api.Container, defaultRequirements *api.ResourceRequirements, annotationPrefix string, annotations []string) []string { + setRequests := []string{} + setLimits := []string{} + if container.Resources.Limits == nil { + container.Resources.Limits = api.ResourceList{} + } + if container.Resources.Requests == nil { + container.Resources.Requests = api.ResourceList{} + } + for k, v := range defaultRequirements.Limits { + _, found := container.Resources.Limits[k] + if !found { + container.Resources.Limits[k] = *v.Copy() + setLimits = append(setLimits, string(k)) + } + } + for k, v := range defaultRequirements.Requests { + _, found := container.Resources.Requests[k] + if !found { + container.Resources.Requests[k] = *v.Copy() + setRequests = append(setRequests, string(k)) + } + } + if len(setRequests) > 0 { + sort.Strings(setRequests) + a := strings.Join(setRequests, ", ") + fmt.Sprintf(" request for %s %s", annotationPrefix, container.Name) + annotations = append(annotations, a) + } + if len(setLimits) > 0 { + sort.Strings(setLimits) + a := strings.Join(setLimits, ", ") + fmt.Sprintf(" limit for %s %s", annotationPrefix, container.Name) + annotations = append(annotations, a) + } + return annotations +} + // mergePodResourceRequirements merges enumerated requirements with default requirements // it annotates the pod with information about what requirements were modified func mergePodResourceRequirements(pod *api.Pod, defaultRequirements *api.ResourceRequirements) { annotations := []string{} for i := range pod.Spec.Containers { - container := &pod.Spec.Containers[i] - setRequests := []string{} - setLimits := []string{} - if container.Resources.Limits == nil { - container.Resources.Limits = api.ResourceList{} - } - if container.Resources.Requests == nil { - container.Resources.Requests = api.ResourceList{} - } - for k, v := range defaultRequirements.Limits { - _, found := container.Resources.Limits[k] - if !found { - container.Resources.Limits[k] = *v.Copy() - setLimits = append(setLimits, string(k)) - } - } - for k, v := range defaultRequirements.Requests { - _, found := container.Resources.Requests[k] - if !found { - container.Resources.Requests[k] = *v.Copy() - setRequests = append(setRequests, string(k)) - } - } - if len(setRequests) > 0 { - sort.Strings(setRequests) - a := strings.Join(setRequests, ", ") + " request for container " + container.Name - annotations = append(annotations, a) - } - if len(setLimits) > 0 { - sort.Strings(setLimits) - a := strings.Join(setLimits, ", ") + " limit for container " + container.Name - annotations = append(annotations, a) - } + annotations = mergeContainerResources(&pod.Spec.Containers[i], defaultRequirements, "container", annotations) + } + + for i := range pod.Spec.InitContainers { + annotations = mergeContainerResources(&pod.Spec.InitContainers[i], defaultRequirements, "init container", annotations) } if len(annotations) > 0 { @@ -441,7 +450,7 @@ func PodLimitFunc(limitRange *api.LimitRange, pod *api.Pod) error { } } - // enforce pod limits + // enforce pod limits on init containers if limitType == api.LimitTypePod { containerRequests, containerLimits := []api.ResourceList{}, []api.ResourceList{} for j := range pod.Spec.Containers { @@ -451,6 +460,28 @@ func PodLimitFunc(limitRange *api.LimitRange, pod *api.Pod) error { } podRequests := sum(containerRequests) podLimits := sum(containerLimits) + for j := range pod.Spec.InitContainers { + container := &pod.Spec.InitContainers[j] + // take max(sum_containers, any_init_container) + for k, v := range container.Resources.Requests { + if v2, ok := podRequests[k]; ok { + if v.Cmp(v2) > 0 { + podRequests[k] = v + } + } else { + podRequests[k] = v + } + } + for k, v := range container.Resources.Limits { + if v2, ok := podLimits[k]; ok { + if v.Cmp(v2) > 0 { + podLimits[k] = v + } + } else { + podLimits[k] = v + } + } + } for k, v := range limit.Min { if err := minConstraint(limitType, k, v, podRequests, podLimits); err != nil { errs = append(errs, err) diff --git a/vendor/k8s.io/kubernetes/plugin/pkg/admission/security/podsecuritypolicy/admission.go b/vendor/k8s.io/kubernetes/plugin/pkg/admission/security/podsecuritypolicy/admission.go index acf8602a20..e3bc36805b 100644 --- a/vendor/k8s.io/kubernetes/plugin/pkg/admission/security/podsecuritypolicy/admission.go +++ b/vendor/k8s.io/kubernetes/plugin/pkg/admission/security/podsecuritypolicy/admission.go @@ -186,6 +186,7 @@ func (c *podSecurityPolicyPlugin) Admit(a admission.Attributes) error { // the same psp or is not considered valid. func assignSecurityContext(provider psp.Provider, pod *api.Pod, fldPath *field.Path) field.ErrorList { generatedSCs := make([]*api.SecurityContext, len(pod.Spec.Containers)) + var generatedInitSCs []*api.SecurityContext errs := field.ErrorList{} @@ -201,6 +202,26 @@ func assignSecurityContext(provider psp.Provider, pod *api.Pod, fldPath *field.P pod.Spec.SecurityContext = psc errs = append(errs, provider.ValidatePodSecurityContext(pod, field.NewPath("spec", "securityContext"))...) + // Note: this is not changing the original container, we will set container SCs later so long + // as all containers validated under the same PSP. + for i, containerCopy := range pod.Spec.InitContainers { + // We will determine the effective security context for the container and validate against that + // since that is how the sc provider will eventually apply settings in the runtime. + // This results in an SC that is based on the Pod's PSC with the set fields from the container + // overriding pod level settings. + containerCopy.SecurityContext = sc.DetermineEffectiveSecurityContext(pod, &containerCopy) + + sc, err := provider.CreateContainerSecurityContext(pod, &containerCopy) + if err != nil { + errs = append(errs, field.Invalid(field.NewPath("spec", "initContainers").Index(i).Child("securityContext"), "", err.Error())) + continue + } + generatedInitSCs = append(generatedInitSCs, sc) + + containerCopy.SecurityContext = sc + errs = append(errs, provider.ValidateContainerSecurityContext(pod, &containerCopy, field.NewPath("spec", "initContainers").Index(i).Child("securityContext"))...) + } + // Note: this is not changing the original container, we will set container SCs later so long // as all containers validated under the same PSP. for i, containerCopy := range pod.Spec.Containers { @@ -229,6 +250,9 @@ func assignSecurityContext(provider psp.Provider, pod *api.Pod, fldPath *field.P // if we've reached this code then we've generated and validated an SC for every container in the // pod so let's apply what we generated. Note: the psc is already applied. + for i, sc := range generatedInitSCs { + pod.Spec.InitContainers[i].SecurityContext = sc + } for i, sc := range generatedSCs { pod.Spec.Containers[i].SecurityContext = sc } diff --git a/vendor/k8s.io/kubernetes/plugin/pkg/admission/securitycontext/scdeny/admission.go b/vendor/k8s.io/kubernetes/plugin/pkg/admission/securitycontext/scdeny/admission.go index c2d7ca6126..c7fa390169 100644 --- a/vendor/k8s.io/kubernetes/plugin/pkg/admission/securitycontext/scdeny/admission.go +++ b/vendor/k8s.io/kubernetes/plugin/pkg/admission/securitycontext/scdeny/admission.go @@ -74,6 +74,17 @@ func (p *plugin) Admit(a admission.Attributes) (err error) { return apierrors.NewForbidden(a.GetResource().GroupResource(), pod.Name, fmt.Errorf("SecurityContext.FSGroup is forbidden")) } + for _, v := range pod.Spec.InitContainers { + if v.SecurityContext != nil { + if v.SecurityContext.SELinuxOptions != nil { + return apierrors.NewForbidden(a.GetResource().GroupResource(), pod.Name, fmt.Errorf("SecurityContext.SELinuxOptions is forbidden")) + } + if v.SecurityContext.RunAsUser != nil { + return apierrors.NewForbidden(a.GetResource().GroupResource(), pod.Name, fmt.Errorf("SecurityContext.RunAsUser is forbidden")) + } + } + } + for _, v := range pod.Spec.Containers { if v.SecurityContext != nil { if v.SecurityContext.SELinuxOptions != nil { diff --git a/vendor/k8s.io/kubernetes/plugin/pkg/admission/serviceaccount/admission.go b/vendor/k8s.io/kubernetes/plugin/pkg/admission/serviceaccount/admission.go index 55b7bfaa6f..82e1bfacca 100644 --- a/vendor/k8s.io/kubernetes/plugin/pkg/admission/serviceaccount/admission.go +++ b/vendor/k8s.io/kubernetes/plugin/pkg/admission/serviceaccount/admission.go @@ -28,6 +28,7 @@ import ( "k8s.io/kubernetes/pkg/admission" "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/errors" + "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/client/cache" "k8s.io/kubernetes/pkg/fields" kubelet "k8s.io/kubernetes/pkg/kubelet/types" @@ -199,6 +200,9 @@ func (s *serviceAccount) Admit(a admission.Attributes) (err error) { if s.MountServiceAccountToken { if err := s.mountServiceAccountToken(serviceAccount, pod); err != nil { + if _, ok := err.(errors.APIStatus); ok { + return err + } return admission.NewForbidden(a, err) } } @@ -324,6 +328,16 @@ func (s *serviceAccount) limitSecretReferences(serviceAccount *api.ServiceAccoun } } + for _, container := range pod.Spec.InitContainers { + for _, env := range container.Env { + if env.ValueFrom != nil && env.ValueFrom.SecretKeyRef != nil { + if !mountableSecrets.Has(env.ValueFrom.SecretKeyRef.Name) { + return fmt.Errorf("Init container %s with envVar %s referencing secret.secretName=\"%s\" is not allowed because service account %s does not reference that secret", container.Name, env.Name, env.ValueFrom.SecretKeyRef.Name, serviceAccount.Name) + } + } + } + } + for _, container := range pod.Spec.Containers { for _, env := range container.Env { if env.ValueFrom != nil && env.ValueFrom.SecretKeyRef != nil { @@ -357,8 +371,9 @@ func (s *serviceAccount) mountServiceAccountToken(serviceAccount *api.ServiceAcc // We don't have an API token to mount, so return if s.RequireAPIToken { // If a token is required, this is considered an error - // TODO: convert to a ServerTimeout error (or other error that sends a Retry-After header) - return fmt.Errorf("no API token found for service account %s/%s, retry after the token is automatically created and added to the service account", serviceAccount.Namespace, serviceAccount.Name) + err := errors.NewServerTimeout(unversioned.GroupResource{Resource: "serviceaccounts"}, "create pod", 1) + err.ErrStatus.Message = fmt.Sprintf("No API token found for service account %q, retry after the token is automatically created and added to the service account", serviceAccount.Name) + return err } return nil } @@ -394,6 +409,20 @@ func (s *serviceAccount) mountServiceAccountToken(serviceAccount *api.ServiceAcc // Ensure every container mounts the APISecret volume needsTokenVolume := false + for i, container := range pod.Spec.InitContainers { + existingContainerMount := false + for _, volumeMount := range container.VolumeMounts { + // Existing mounts at the default mount path prevent mounting of the API token + if volumeMount.MountPath == DefaultAPITokenMountPath { + existingContainerMount = true + break + } + } + if !existingContainerMount { + pod.Spec.InitContainers[i].VolumeMounts = append(pod.Spec.InitContainers[i].VolumeMounts, volumeMount) + needsTokenVolume = true + } + } for i, container := range pod.Spec.Containers { existingContainerMount := false for _, volumeMount := range container.VolumeMounts { diff --git a/vendor/k8s.io/kubernetes/plugin/pkg/auth/authenticator/token/webhook/webhook.go b/vendor/k8s.io/kubernetes/plugin/pkg/auth/authenticator/token/webhook/webhook.go index adc8e5fb36..ad298a39aa 100644 --- a/vendor/k8s.io/kubernetes/plugin/pkg/auth/authenticator/token/webhook/webhook.go +++ b/vendor/k8s.io/kubernetes/plugin/pkg/auth/authenticator/token/webhook/webhook.go @@ -18,10 +18,13 @@ limitations under the License. package webhook import ( + "time" + "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/apis/authentication.k8s.io/v1beta1" "k8s.io/kubernetes/pkg/auth/authenticator" "k8s.io/kubernetes/pkg/auth/user" + "k8s.io/kubernetes/pkg/util/cache" "k8s.io/kubernetes/plugin/pkg/webhook" _ "k8s.io/kubernetes/pkg/apis/authentication.k8s.io/install" @@ -36,30 +39,36 @@ var _ authenticator.Token = (*WebhookTokenAuthenticator)(nil) type WebhookTokenAuthenticator struct { *webhook.GenericWebhook + responseCache *cache.LRUExpireCache + ttl time.Duration } // New creates a new WebhookTokenAuthenticator from the provided kubeconfig file. -func New(kubeConfigFile string) (*WebhookTokenAuthenticator, error) { +func New(kubeConfigFile string, ttl time.Duration) (*WebhookTokenAuthenticator, error) { gw, err := webhook.NewGenericWebhook(kubeConfigFile, groupVersions) if err != nil { return nil, err } - return &WebhookTokenAuthenticator{gw}, nil + return &WebhookTokenAuthenticator{gw, cache.NewLRUExpireCache(1024), ttl}, nil } -// AuthenticateToken +// AuthenticateToken implements the authenticator.Token interface. func (w *WebhookTokenAuthenticator) AuthenticateToken(token string) (user.Info, bool, error) { r := &v1beta1.TokenReview{ - Spec: v1beta1.TokenReviewSpec{ - Token: token, - }, + Spec: v1beta1.TokenReviewSpec{Token: token}, } - result := w.RestClient.Post().Body(r).Do() - if err := result.Error(); err != nil { - return nil, false, err - } - if err := result.Into(r); err != nil { - return nil, false, err + if entry, ok := w.responseCache.Get(r.Spec); ok { + r.Status = entry.(v1beta1.TokenReviewStatus) + } else { + result := w.RestClient.Post().Body(r).Do() + if err := result.Error(); err != nil { + return nil, false, err + } + spec := r.Spec + if err := result.Into(r); err != nil { + return nil, false, err + } + go w.responseCache.Add(spec, r.Status, w.ttl) } if !r.Status.Authenticated { return nil, false, nil diff --git a/vendor/k8s.io/kubernetes/plugin/pkg/auth/authorizer/webhook/webhook.go b/vendor/k8s.io/kubernetes/plugin/pkg/auth/authorizer/webhook/webhook.go index 3d662f3352..eeaf2af1d3 100644 --- a/vendor/k8s.io/kubernetes/plugin/pkg/auth/authorizer/webhook/webhook.go +++ b/vendor/k8s.io/kubernetes/plugin/pkg/auth/authorizer/webhook/webhook.go @@ -18,11 +18,14 @@ limitations under the License. package webhook import ( + "encoding/json" "errors" + "time" "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/apis/authorization/v1beta1" "k8s.io/kubernetes/pkg/auth/authorizer" + "k8s.io/kubernetes/pkg/util/cache" "k8s.io/kubernetes/plugin/pkg/webhook" _ "k8s.io/kubernetes/pkg/apis/authorization/install" @@ -37,6 +40,9 @@ var _ authorizer.Authorizer = (*WebhookAuthorizer)(nil) type WebhookAuthorizer struct { *webhook.GenericWebhook + responseCache *cache.LRUExpireCache + authorizedTTL time.Duration + unauthorizedTTL time.Duration } // New creates a new WebhookAuthorizer from the provided kubeconfig file. @@ -59,12 +65,12 @@ type WebhookAuthorizer struct { // // For additional HTTP configuration, refer to the kubeconfig documentation // http://kubernetes.io/v1.1/docs/user-guide/kubeconfig-file.html. -func New(kubeConfigFile string) (*WebhookAuthorizer, error) { +func New(kubeConfigFile string, authorizedTTL, unauthorizedTTL time.Duration) (*WebhookAuthorizer, error) { gw, err := webhook.NewGenericWebhook(kubeConfigFile, groupVersions) if err != nil { return nil, err } - return &WebhookAuthorizer{gw}, nil + return &WebhookAuthorizer{gw, cache.NewLRUExpireCache(1024), authorizedTTL, unauthorizedTTL}, nil } // Authorize makes a REST request to the remote service describing the attempted action as a JSON @@ -134,13 +140,27 @@ func (w *WebhookAuthorizer) Authorize(attr authorizer.Attributes) (err error) { Verb: attr.GetVerb(), } } - result := w.RestClient.Post().Body(r).Do() - if err := result.Error(); err != nil { + key, err := json.Marshal(r.Spec) + if err != nil { return err } - - if err := result.Into(r); err != nil { - return err + if entry, ok := w.responseCache.Get(string(key)); ok { + r.Status = entry.(v1beta1.SubjectAccessReviewStatus) + } else { + result := w.RestClient.Post().Body(r).Do() + if err := result.Error(); err != nil { + return err + } + if err := result.Into(r); err != nil { + return err + } + go func() { + if r.Status.Allowed { + w.responseCache.Add(string(key), r.Status, w.authorizedTTL) + } else { + w.responseCache.Add(string(key), r.Status, w.unauthorizedTTL) + } + }() } if r.Status.Allowed { return nil diff --git a/vendor/k8s.io/kubernetes/plugin/pkg/client/auth/oidc/OWNERS b/vendor/k8s.io/kubernetes/plugin/pkg/client/auth/oidc/OWNERS new file mode 100644 index 0000000000..ecf3349934 --- /dev/null +++ b/vendor/k8s.io/kubernetes/plugin/pkg/client/auth/oidc/OWNERS @@ -0,0 +1,2 @@ +assignees: + - bobbyrullo diff --git a/vendor/k8s.io/kubernetes/plugin/pkg/client/auth/oidc/oidc.go b/vendor/k8s.io/kubernetes/plugin/pkg/client/auth/oidc/oidc.go new file mode 100644 index 0000000000..3ad279c106 --- /dev/null +++ b/vendor/k8s.io/kubernetes/plugin/pkg/client/auth/oidc/oidc.go @@ -0,0 +1,270 @@ +/* +Copyright 2016 The Kubernetes Authors All rights reserved. + +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 oidc + +import ( + "encoding/base64" + "errors" + "fmt" + "net/http" + "strings" + "time" + + "github.com/coreos/go-oidc/jose" + "github.com/coreos/go-oidc/oauth2" + "github.com/coreos/go-oidc/oidc" + "github.com/golang/glog" + + "k8s.io/kubernetes/pkg/client/restclient" + "k8s.io/kubernetes/pkg/util/wait" +) + +const ( + cfgIssuerUrl = "idp-issuer-url" + cfgClientID = "client-id" + cfgClientSecret = "client-secret" + cfgCertificateAuthority = "idp-certificate-authority" + cfgCertificateAuthorityData = "idp-certificate-authority-data" + cfgExtraScopes = "extra-scopes" + cfgIDToken = "id-token" + cfgRefreshToken = "refresh-token" +) + +var ( + backoff = wait.Backoff{ + Duration: 1 * time.Second, + Factor: 2, + Jitter: .1, + Steps: 5, + } +) + +func init() { + if err := restclient.RegisterAuthProviderPlugin("oidc", newOIDCAuthProvider); err != nil { + glog.Fatalf("Failed to register oidc auth plugin: %v", err) + } +} + +func newOIDCAuthProvider(_ string, cfg map[string]string, persister restclient.AuthProviderConfigPersister) (restclient.AuthProvider, error) { + issuer := cfg[cfgIssuerUrl] + if issuer == "" { + return nil, fmt.Errorf("Must provide %s", cfgIssuerUrl) + } + + clientID := cfg[cfgClientID] + if clientID == "" { + return nil, fmt.Errorf("Must provide %s", cfgClientID) + } + + clientSecret := cfg[cfgClientSecret] + if clientSecret == "" { + return nil, fmt.Errorf("Must provide %s", cfgClientSecret) + } + + var certAuthData []byte + var err error + if cfg[cfgCertificateAuthorityData] != "" { + certAuthData, err = base64.StdEncoding.DecodeString(cfg[cfgCertificateAuthorityData]) + if err != nil { + return nil, err + } + } + + clientConfig := restclient.Config{ + TLSClientConfig: restclient.TLSClientConfig{ + CAFile: cfg[cfgCertificateAuthority], + CAData: certAuthData, + }, + } + + trans, err := restclient.TransportFor(&clientConfig) + if err != nil { + return nil, err + } + hc := &http.Client{Transport: trans} + + providerCfg, err := oidc.FetchProviderConfig(hc, strings.TrimSuffix(issuer, "/")) + if err != nil { + return nil, fmt.Errorf("error fetching provider config: %v", err) + } + + scopes := strings.Split(cfg[cfgExtraScopes], ",") + oidcCfg := oidc.ClientConfig{ + HTTPClient: hc, + Credentials: oidc.ClientCredentials{ + ID: clientID, + Secret: clientSecret, + }, + ProviderConfig: providerCfg, + Scope: append(scopes, oidc.DefaultScope...), + } + + client, err := oidc.NewClient(oidcCfg) + if err != nil { + return nil, fmt.Errorf("error creating OIDC Client: %v", err) + } + + oClient := &oidcClient{client} + + var initialIDToken jose.JWT + if cfg[cfgIDToken] != "" { + initialIDToken, err = jose.ParseJWT(cfg[cfgIDToken]) + if err != nil { + return nil, err + } + } + + return &oidcAuthProvider{ + initialIDToken: initialIDToken, + refresher: &idTokenRefresher{ + client: oClient, + cfg: cfg, + persister: persister, + }, + }, nil +} + +type oidcAuthProvider struct { + refresher *idTokenRefresher + initialIDToken jose.JWT +} + +func (g *oidcAuthProvider) WrapTransport(rt http.RoundTripper) http.RoundTripper { + at := &oidc.AuthenticatedTransport{ + TokenRefresher: g.refresher, + RoundTripper: rt, + } + at.SetJWT(g.initialIDToken) + return &roundTripper{ + wrapped: at, + refresher: g.refresher, + } +} + +func (g *oidcAuthProvider) Login() error { + return errors.New("not yet implemented") +} + +type OIDCClient interface { + refreshToken(rt string) (oauth2.TokenResponse, error) + verifyJWT(jwt jose.JWT) error +} + +type roundTripper struct { + refresher *idTokenRefresher + wrapped *oidc.AuthenticatedTransport +} + +func (r *roundTripper) RoundTrip(req *http.Request) (*http.Response, error) { + var res *http.Response + var err error + firstTime := true + wait.ExponentialBackoff(backoff, func() (bool, error) { + if !firstTime { + var jwt jose.JWT + jwt, err = r.refresher.Refresh() + if err != nil { + return true, nil + } + r.wrapped.SetJWT(jwt) + } else { + firstTime = false + } + + res, err = r.wrapped.RoundTrip(req) + if err != nil { + return true, nil + } + if res.StatusCode == http.StatusUnauthorized { + return false, nil + } + return true, nil + }) + return res, err +} + +type idTokenRefresher struct { + cfg map[string]string + client OIDCClient + persister restclient.AuthProviderConfigPersister + intialIDToken jose.JWT +} + +func (r *idTokenRefresher) Verify(jwt jose.JWT) error { + claims, err := jwt.Claims() + if err != nil { + return err + } + + now := time.Now() + exp, ok, err := claims.TimeClaim("exp") + switch { + case err != nil: + return fmt.Errorf("failed to parse 'exp' claim: %v", err) + case !ok: + return errors.New("missing required 'exp' claim") + case exp.Before(now): + return fmt.Errorf("token already expired at: %v", exp) + } + + return nil +} + +func (r *idTokenRefresher) Refresh() (jose.JWT, error) { + rt, ok := r.cfg[cfgRefreshToken] + if !ok { + return jose.JWT{}, errors.New("No valid id-token, and cannot refresh without refresh-token") + } + + tokens, err := r.client.refreshToken(rt) + if err != nil { + return jose.JWT{}, fmt.Errorf("could not refresh token: %v", err) + } + jwt, err := jose.ParseJWT(tokens.IDToken) + if err != nil { + return jose.JWT{}, err + } + + if tokens.RefreshToken != "" && tokens.RefreshToken != rt { + r.cfg[cfgRefreshToken] = tokens.RefreshToken + } + r.cfg[cfgIDToken] = jwt.Encode() + + err = r.persister.Persist(r.cfg) + if err != nil { + return jose.JWT{}, fmt.Errorf("could not perist new tokens: %v", err) + } + + return jwt, r.client.verifyJWT(jwt) +} + +type oidcClient struct { + client *oidc.Client +} + +func (o *oidcClient) refreshToken(rt string) (oauth2.TokenResponse, error) { + oac, err := o.client.OAuthClient() + if err != nil { + return oauth2.TokenResponse{}, err + } + + return oac.RequestToken(oauth2.GrantTypeRefreshToken, rt) +} + +func (o *oidcClient) verifyJWT(jwt jose.JWT) error { + return o.client.VerifyJWT(jwt) +} diff --git a/vendor/k8s.io/kubernetes/plugin/pkg/client/auth/plugins.go b/vendor/k8s.io/kubernetes/plugin/pkg/client/auth/plugins.go index c93cfd1d93..2b422ddda0 100644 --- a/vendor/k8s.io/kubernetes/plugin/pkg/client/auth/plugins.go +++ b/vendor/k8s.io/kubernetes/plugin/pkg/client/auth/plugins.go @@ -19,4 +19,5 @@ package plugins import ( // Initialize all known client auth plugins. _ "k8s.io/kubernetes/plugin/pkg/client/auth/gcp" + _ "k8s.io/kubernetes/plugin/pkg/client/auth/oidc" ) diff --git a/vendor/k8s.io/kubernetes/plugin/pkg/scheduler/algorithm/predicates/error.go b/vendor/k8s.io/kubernetes/plugin/pkg/scheduler/algorithm/predicates/error.go index 9f6a0d1bb3..fd4777ccde 100644 --- a/vendor/k8s.io/kubernetes/plugin/pkg/scheduler/algorithm/predicates/error.go +++ b/vendor/k8s.io/kubernetes/plugin/pkg/scheduler/algorithm/predicates/error.go @@ -21,7 +21,7 @@ import "fmt" const ( podCountResourceName string = "PodCount" cpuResourceName string = "CPU" - memoryResoureceName string = "Memory" + memoryResourceName string = "Memory" nvidiaGpuResourceName string = "NvidiaGpu" ) @@ -32,11 +32,13 @@ var ( ErrVolumeZoneConflict = newPredicateFailureError("NoVolumeZoneConflict") ErrNodeSelectorNotMatch = newPredicateFailureError("MatchNodeSelector") ErrPodAffinityNotMatch = newPredicateFailureError("MatchInterPodAffinity") + ErrTaintsTolerationsNotMatch = newPredicateFailureError("PodToleratesNodeTaints") ErrPodNotMatchHostName = newPredicateFailureError("HostName") ErrPodNotFitsHostPorts = newPredicateFailureError("PodFitsHostPorts") ErrNodeLabelPresenceViolated = newPredicateFailureError("CheckNodeLabelPresence") ErrServiceAffinityViolated = newPredicateFailureError("CheckServiceAffinity") ErrMaxVolumeCountExceeded = newPredicateFailureError("MaxVolumeCount") + ErrNodeUnderMemoryPressure = newPredicateFailureError("NodeUnderMemoryPressure") // ErrFakePredicate is used for test only. The fake predicates returning false also returns error // as ErrFakePredicate. ErrFakePredicate = newPredicateFailureError("FakePredicateError") diff --git a/vendor/k8s.io/kubernetes/plugin/pkg/scheduler/algorithm/predicates/predicates.go b/vendor/k8s.io/kubernetes/plugin/pkg/scheduler/algorithm/predicates/predicates.go index 4b1c8c9b5d..a5c63f4a7c 100644 --- a/vendor/k8s.io/kubernetes/plugin/pkg/scheduler/algorithm/predicates/predicates.go +++ b/vendor/k8s.io/kubernetes/plugin/pkg/scheduler/algorithm/predicates/predicates.go @@ -23,6 +23,7 @@ import ( "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/client/cache" + qosutil "k8s.io/kubernetes/pkg/kubelet/qos/util" "k8s.io/kubernetes/pkg/labels" "k8s.io/kubernetes/plugin/pkg/scheduler/algorithm" priorityutil "k8s.io/kubernetes/plugin/pkg/scheduler/algorithm/priorities/util" @@ -359,6 +360,16 @@ func getResourceRequest(pod *api.Pod) resourceRequest { result.milliCPU += requests.Cpu().MilliValue() result.nvidiaGPU += requests.NvidiaGPU().Value() } + // take max_resource(sum_pod, any_init_container) + for _, container := range pod.Spec.InitContainers { + requests := container.Resources.Requests + if mem := requests.Memory().Value(); mem > result.memory { + result.memory = mem + } + if cpu := requests.Cpu().MilliValue(); cpu > result.milliCPU { + result.milliCPU = cpu + } + } return result } @@ -428,7 +439,7 @@ func PodFitsResources(pod *api.Pod, nodeInfo *schedulercache.NodeInfo) (bool, er } if totalMemory < podRequest.memory+nodeInfo.RequestedResource().Memory { return false, - newInsufficientResourceError(memoryResoureceName, podRequest.memory, nodeInfo.RequestedResource().Memory, totalMemory) + newInsufficientResourceError(memoryResourceName, podRequest.memory, nodeInfo.RequestedResource().Memory, totalMemory) } if totalNvidiaGPU < podRequest.nvidiaGPU+nodeInfo.RequestedResource().NvidiaGPU { return false, @@ -934,3 +945,86 @@ func (checker *PodAffinityChecker) NodeMatchPodAffinityAntiAffinity(pod *api.Pod } return true } + +type TolerationMatch struct { + info NodeInfo +} + +func NewTolerationMatchPredicate(info NodeInfo) algorithm.FitPredicate { + tolerationMatch := &TolerationMatch{ + info: info, + } + return tolerationMatch.PodToleratesNodeTaints +} + +func (t *TolerationMatch) PodToleratesNodeTaints(pod *api.Pod, nodeInfo *schedulercache.NodeInfo) (bool, error) { + node := nodeInfo.Node() + + taints, err := api.GetTaintsFromNodeAnnotations(node.Annotations) + if err != nil { + return false, err + } + + tolerations, err := api.GetTolerationsFromPodAnnotations(pod.Annotations) + if err != nil { + return false, err + } + + if tolerationsToleratesTaints(tolerations, taints) { + return true, nil + } + return false, ErrTaintsTolerationsNotMatch +} + +func tolerationsToleratesTaints(tolerations []api.Toleration, taints []api.Taint) bool { + // If the taint list is nil/empty, it is tolerated by all tolerations by default. + if len(taints) == 0 { + return true + } + + // The taint list isn't nil/empty, a nil/empty toleration list can't tolerate them. + if len(tolerations) == 0 { + return false + } + + for _, taint := range taints { + // skip taints that have effect PreferNoSchedule, since it is for priorities + if taint.Effect == api.TaintEffectPreferNoSchedule { + continue + } + + if !api.TaintToleratedByTolerations(taint, tolerations) { + return false + } + } + + return true +} + +// Determine if a pod is scheduled with best-effort QoS +func isPodBestEffort(pod *api.Pod) bool { + return qosutil.GetPodQos(pod) == qosutil.BestEffort +} + +// CheckNodeMemoryPressurePredicate checks if a pod can be scheduled on a node +// reporting memory pressure condition. +func CheckNodeMemoryPressurePredicate(pod *api.Pod, nodeInfo *schedulercache.NodeInfo) (bool, error) { + node := nodeInfo.Node() + if node == nil { + return false, fmt.Errorf("node not found") + } + + // pod is not BestEffort pod + if !isPodBestEffort(pod) { + return true, nil + } + + // is node under presure? + for _, cond := range node.Status.Conditions { + if cond.Type == api.NodeMemoryPressure && cond.Status == api.ConditionTrue { + return false, ErrNodeUnderMemoryPressure + } + } + + return true, nil +} diff --git a/vendor/k8s.io/kubernetes/plugin/pkg/scheduler/algorithm/priorities/taint_toleration.go b/vendor/k8s.io/kubernetes/plugin/pkg/scheduler/algorithm/priorities/taint_toleration.go new file mode 100644 index 0000000000..416baeb001 --- /dev/null +++ b/vendor/k8s.io/kubernetes/plugin/pkg/scheduler/algorithm/priorities/taint_toleration.go @@ -0,0 +1,110 @@ +/* +Copyright 2016 The Kubernetes Authors All rights reserved. + +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 priorities + +import ( + "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/plugin/pkg/scheduler/algorithm" + schedulerapi "k8s.io/kubernetes/plugin/pkg/scheduler/api" + "k8s.io/kubernetes/plugin/pkg/scheduler/schedulercache" +) + +// NodeTaints hold the node lister +type TaintToleration struct { + nodeLister algorithm.NodeLister +} + +// NewTaintTolerationPriority +func NewTaintTolerationPriority(nodeLister algorithm.NodeLister) algorithm.PriorityFunction { + taintToleration := &TaintToleration{ + nodeLister: nodeLister, + } + return taintToleration.ComputeTaintTolerationPriority +} + +// CountIntolerableTaintsPreferNoSchedule gives the count of intolerable taints of a pod with effect PreferNoSchedule +func countIntolerableTaintsPreferNoSchedule(taints []api.Taint, tolerations []api.Toleration) (intolerableTaints int) { + for _, taint := range taints { + // check only on taints that have effect PreferNoSchedule + if taint.Effect != api.TaintEffectPreferNoSchedule { + continue + } + + if !api.TaintToleratedByTolerations(taint, tolerations) { + intolerableTaints++ + } + } + return +} + +// getAllTolerationEffectPreferNoSchedule gets the list of all Toleration with Effect PreferNoSchedule +func getAllTolerationPreferNoSchedule(tolerations []api.Toleration) (tolerationList []api.Toleration) { + for _, toleration := range tolerations { + if len(toleration.Effect) == 0 || toleration.Effect == api.TaintEffectPreferNoSchedule { + tolerationList = append(tolerationList, toleration) + } + } + return +} + +// ComputeTaintTolerationPriority prepares the priority list for all the nodes based on the number of intolerable taints on the node +func (s *TaintToleration) ComputeTaintTolerationPriority(pod *api.Pod, nodeNameToInfo map[string]*schedulercache.NodeInfo, nodeLister algorithm.NodeLister) (schedulerapi.HostPriorityList, error) { + // counts hold the count of intolerable taints of a pod for a given node + counts := make(map[string]int) + + // the max value of counts + var maxCount int + + nodes, err := nodeLister.List() + if err != nil { + return nil, err + } + + tolerations, err := api.GetTolerationsFromPodAnnotations(pod.Annotations) + if err != nil { + return nil, err + } + // Fetch a list of all toleration with effect PreferNoSchedule + tolerationList := getAllTolerationPreferNoSchedule(tolerations) + + // calculate the intolerable taints for all the nodes + for _, node := range nodes.Items { + taints, err := api.GetTaintsFromNodeAnnotations(node.Annotations) + if err != nil { + return nil, err + } + + count := countIntolerableTaintsPreferNoSchedule(taints, tolerationList) + counts[node.Name] = count + if count > maxCount { + maxCount = count + } + } + + // The maximum priority value to give to a node + // Priority values range from 0 - maxPriority + const maxPriority = 10 + result := []schedulerapi.HostPriority{} + for _, node := range nodes.Items { + fScore := float64(maxPriority) + if maxCount > 0 { + fScore = (1.0 - float64(counts[node.Name])/float64(maxCount)) * 10 + } + result = append(result, schedulerapi.HostPriority{Host: node.Name, Score: int(fScore)}) + } + return result, nil +} diff --git a/vendor/k8s.io/kubernetes/plugin/pkg/scheduler/algorithmprovider/defaults/defaults.go b/vendor/k8s.io/kubernetes/plugin/pkg/scheduler/algorithmprovider/defaults/defaults.go index b9304cc7bc..21e8e22990 100644 --- a/vendor/k8s.io/kubernetes/plugin/pkg/scheduler/algorithmprovider/defaults/defaults.go +++ b/vendor/k8s.io/kubernetes/plugin/pkg/scheduler/algorithmprovider/defaults/defaults.go @@ -145,6 +145,17 @@ func defaultPredicates() sets.String { // GeneralPredicates are the predicates that are enforced by all Kubernetes components // (e.g. kubelet and all schedulers) factory.RegisterFitPredicate("GeneralPredicates", predicates.GeneralPredicates), + + // Fit is determined based on whether a pod can tolerate all of the node's taints + factory.RegisterFitPredicateFactory( + "PodToleratesNodeTaints", + func(args factory.PluginFactoryArgs) algorithm.FitPredicate { + return predicates.NewTolerationMatchPredicate(args.NodeInfo) + }, + ), + + // Fit is determined by node memory pressure condition. + factory.RegisterFitPredicate("CheckNodeMemoryPressure", predicates.CheckNodeMemoryPressurePredicate), ) } @@ -173,5 +184,14 @@ func defaultPriorities() sets.String { Weight: 1, }, ), + factory.RegisterPriorityConfigFactory( + "TaintTolerationPriority", + factory.PriorityConfigFactory{ + Function: func(args factory.PluginFactoryArgs) algorithm.PriorityFunction { + return priorities.NewTaintTolerationPriority(args.NodeLister) + }, + Weight: 1, + }, + ), ) } diff --git a/vendor/k8s.io/kubernetes/plugin/pkg/scheduler/factory/factory.go b/vendor/k8s.io/kubernetes/plugin/pkg/scheduler/factory/factory.go index e8aa6c0340..50f8a59cfb 100644 --- a/vendor/k8s.io/kubernetes/plugin/pkg/scheduler/factory/factory.go +++ b/vendor/k8s.io/kubernetes/plugin/pkg/scheduler/factory/factory.go @@ -307,8 +307,8 @@ func (f *ConfigFactory) CreateFromKeys(predicateKeys, priorityKeys sets.String, failureDomainArgs := strings.Split(f.FailureDomains, ",") for _, failureDomain := range failureDomainArgs { - if !utilvalidation.IsQualifiedName(failureDomain) { - return nil, fmt.Errorf("invalid failure domain: %s", failureDomain) + if errs := utilvalidation.IsQualifiedName(failureDomain); len(errs) != 0 { + return nil, fmt.Errorf("invalid failure domain: %q: %s", failureDomain, strings.Join(errs, ";")) } } diff --git a/vendor/k8s.io/kubernetes/plugin/pkg/scheduler/factory/plugins.go b/vendor/k8s.io/kubernetes/plugin/pkg/scheduler/factory/plugins.go index 1235075971..9744a49dff 100644 --- a/vendor/k8s.io/kubernetes/plugin/pkg/scheduler/factory/plugins.go +++ b/vendor/k8s.io/kubernetes/plugin/pkg/scheduler/factory/plugins.go @@ -121,6 +121,7 @@ func RegisterCustomFitPredicate(policy schedulerapi.PredicatePolicy) string { } else if predicateFactory, ok = fitPredicateMap[policy.Name]; ok { // checking to see if a pre-defined predicate is requested glog.V(2).Infof("Predicate type %s already registered, reusing.", policy.Name) + return policy.Name } if predicateFactory == nil { @@ -290,7 +291,7 @@ func validatePredicateOrDie(predicate schedulerapi.PredicatePolicy) { numArgs++ } if numArgs != 1 { - glog.Fatalf("Exactly 1 predicate argument is required, numArgs: %v", numArgs) + glog.Fatalf("Exactly 1 predicate argument is required, numArgs: %v, Predicate: %s", numArgs, predicate.Name) } } } @@ -305,7 +306,7 @@ func validatePriorityOrDie(priority schedulerapi.PriorityPolicy) { numArgs++ } if numArgs != 1 { - glog.Fatalf("Exactly 1 priority argument is required") + glog.Fatalf("Exactly 1 priority argument is required, numArgs: %v, Priority: %s", numArgs, priority.Name) } } } diff --git a/vendor/k8s.io/kubernetes/plugin/pkg/scheduler/scheduler.go b/vendor/k8s.io/kubernetes/plugin/pkg/scheduler/scheduler.go index 236b6ae2f0..8311462eeb 100644 --- a/vendor/k8s.io/kubernetes/plugin/pkg/scheduler/scheduler.go +++ b/vendor/k8s.io/kubernetes/plugin/pkg/scheduler/scheduler.go @@ -101,10 +101,9 @@ func (s *Scheduler) scheduleOne() { s.config.Error(pod, err) s.config.Recorder.Eventf(pod, api.EventTypeWarning, "FailedScheduling", "%v", err) s.config.PodConditionUpdater.Update(pod, &api.PodCondition{ - Type: api.PodScheduled, - Status: api.ConditionFalse, - Reason: "Unschedulable", - Message: err.Error(), + Type: api.PodScheduled, + Status: api.ConditionFalse, + Reason: "Unschedulable", }) return } @@ -138,14 +137,13 @@ func (s *Scheduler) scheduleOne() { // it's atomic with setting host. err := s.config.Binder.Bind(b) if err != nil { - glog.V(1).Infof("Failed to bind pod: %+v", err) + glog.V(1).Infof("Failed to bind pod: %v/%v", pod.Namespace, pod.Name) s.config.Error(pod, err) s.config.Recorder.Eventf(pod, api.EventTypeNormal, "FailedScheduling", "Binding rejected: %v", err) s.config.PodConditionUpdater.Update(pod, &api.PodCondition{ - Type: api.PodScheduled, - Status: api.ConditionFalse, - Reason: "BindingRejected", - Message: err.Error(), + Type: api.PodScheduled, + Status: api.ConditionFalse, + Reason: "BindingRejected", }) return } diff --git a/vendor/k8s.io/kubernetes/plugin/pkg/scheduler/schedulercache/node_info.go b/vendor/k8s.io/kubernetes/plugin/pkg/scheduler/schedulercache/node_info.go index 4b93005865..79890cd3d2 100644 --- a/vendor/k8s.io/kubernetes/plugin/pkg/scheduler/schedulercache/node_info.go +++ b/vendor/k8s.io/kubernetes/plugin/pkg/scheduler/schedulercache/node_info.go @@ -132,13 +132,6 @@ func (n *NodeInfo) removePod(pod *api.Pod) error { return err } - cpu, mem, nvidia_gpu, non0_cpu, non0_mem := calculateResource(pod) - n.requestedResource.MilliCPU -= cpu - n.requestedResource.Memory -= mem - n.requestedResource.NvidiaGPU -= nvidia_gpu - n.nonzeroRequest.MilliCPU -= non0_cpu - n.nonzeroRequest.Memory -= non0_mem - for i := range n.pods { k2, err := getPodKey(n.pods[i]) if err != nil { @@ -149,10 +142,17 @@ func (n *NodeInfo) removePod(pod *api.Pod) error { // delete the element n.pods[i] = n.pods[len(n.pods)-1] n.pods = n.pods[:len(n.pods)-1] + // reduce the resource data + cpu, mem, nvidia_gpu, non0_cpu, non0_mem := calculateResource(pod) + n.requestedResource.MilliCPU -= cpu + n.requestedResource.Memory -= mem + n.requestedResource.NvidiaGPU -= nvidia_gpu + n.nonzeroRequest.MilliCPU -= non0_cpu + n.nonzeroRequest.Memory -= non0_mem return nil } } - return fmt.Errorf("no corresponding pod in pods") + return fmt.Errorf("no corresponding pod %s in pods of node %s", pod.Name, n.node.Name) } func calculateResource(pod *api.Pod) (cpu int64, mem int64, nvidia_gpu int64, non0_cpu int64, non0_mem int64) {