From 293110c7c0e0c6986dfc4e550cfc664958879426 Mon Sep 17 00:00:00 2001 From: Dan Gillespie Date: Wed, 30 Mar 2016 17:22:42 -0700 Subject: [PATCH] moved localkube controller to localkube repo + kubernetes 1.2 --- Godeps/Godeps.json | 436 +-- cli/cluster.go | 227 +- vendor/github.com/Sirupsen/logrus/.gitignore | 1 + vendor/github.com/Sirupsen/logrus/.travis.yml | 10 + vendor/github.com/Sirupsen/logrus/LICENSE | 21 + vendor/github.com/Sirupsen/logrus/README.md | 352 +++ vendor/github.com/Sirupsen/logrus/entry.go | 248 ++ vendor/github.com/Sirupsen/logrus/exported.go | 182 ++ .../github.com/Sirupsen/logrus/formatter.go | 44 + vendor/github.com/Sirupsen/logrus/hooks.go | 34 + .../Sirupsen/logrus/json_formatter.go | 26 + vendor/github.com/Sirupsen/logrus/logger.go | 161 ++ vendor/github.com/Sirupsen/logrus/logrus.go | 94 + .../Sirupsen/logrus/terminal_darwin.go | 12 + .../Sirupsen/logrus/terminal_freebsd.go | 20 + .../Sirupsen/logrus/terminal_linux.go | 12 + .../Sirupsen/logrus/terminal_notwindows.go | 21 + .../Sirupsen/logrus/terminal_windows.go | 27 + .../Sirupsen/logrus/text_formatter.go | 124 + .../docker/pkg/jsonmessage/jsonmessage.go | 172 ++ .../docker/docker/pkg/term/tc_linux_cgo.go | 48 + .../docker/docker/pkg/term/tc_other.go | 19 + .../github.com/docker/docker/pkg/term/term.go | 118 + .../docker/docker/pkg/term/term_windows.go | 139 + .../docker/docker/pkg/term/termios_darwin.go | 65 + .../docker/docker/pkg/term/termios_freebsd.go | 65 + .../docker/docker/pkg/term/termios_linux.go | 46 + .../pkg/term/winconsole/console_windows.go | 1053 ++++++++ .../pkg/term/winconsole/term_emulator.go | 234 ++ .../docker/docker/pkg/timeutils/json.go | 26 + .../docker/docker/pkg/timeutils/utils.go | 36 + .../docker/docker/pkg/units/duration.go | 31 + .../docker/docker/pkg/units/size.go | 93 + vendor/github.com/golang/groupcache/LICENSE | 191 ++ .../github.com/golang/groupcache/lru/lru.go | 121 + .../google/cadvisor/info/v1/container.go | 8 + .../google/cadvisor/info/v1/machine.go | 24 +- vendor/k8s.io/kubernetes/pkg/api/OWNERS | 6 + .../kubernetes/pkg/api/deep_copy_generated.go | 1 + .../kubernetes/pkg/api/endpoints/util.go | 236 ++ vendor/k8s.io/kubernetes/pkg/api/helpers.go | 13 + vendor/k8s.io/kubernetes/pkg/api/pod/util.go | 59 + .../kubernetes/pkg/api/service/annotations.go | 28 + .../k8s.io/kubernetes/pkg/api/service/util.go | 54 + .../kubernetes/pkg/api/types.generated.go | 98 +- vendor/k8s.io/kubernetes/pkg/api/types.go | 7 +- .../pkg/api/unversioned/group_version.go | 15 + .../kubernetes/pkg/api/unversioned/helpers.go | 62 +- .../kubernetes/pkg/api/unversioned/types.go | 12 +- .../types_swagger_doc_generated.go | 12 +- .../pkg/api/v1/conversion_generated.go | 2 + .../pkg/api/v1/deep_copy_generated.go | 1 + .../kubernetes/pkg/api/v1/types.generated.go | 96 +- vendor/k8s.io/kubernetes/pkg/api/v1/types.go | 394 +-- .../pkg/api/v1/types_swagger_doc_generated.go | 393 +-- .../kubernetes/pkg/api/validation/schema.go | 10 +- .../pkg/api/validation/validation.go | 111 +- .../kubernetes/pkg/apis/autoscaling/types.go | 8 +- .../pkg/apis/autoscaling/v1/types.go | 17 +- .../v1/types_swagger_doc_generated.go | 18 +- .../kubernetes/pkg/apis/batch/v1/types.go | 20 +- .../batch/v1/types_swagger_doc_generated.go | 20 +- .../apis/componentconfig/types.generated.go | 2394 +++++++++-------- .../pkg/apis/componentconfig/types.go | 11 +- .../kubernetes/pkg/apis/extensions/helpers.go | 47 - .../pkg/apis/extensions/types.generated.go | 226 +- .../kubernetes/pkg/apis/extensions/types.go | 84 +- .../pkg/apis/extensions/v1beta1/conversion.go | 73 +- .../v1beta1/conversion_generated.go | 81 +- .../extensions/v1beta1/deep_copy_generated.go | 21 +- .../pkg/apis/extensions/v1beta1/defaults.go | 15 +- .../extensions/v1beta1/types.generated.go | 292 +- .../pkg/apis/extensions/v1beta1/types.go | 125 +- .../v1beta1/types_swagger_doc_generated.go | 130 +- .../kubernetes/pkg/client/cache/delta_fifo.go | 550 ++++ .../k8s.io/kubernetes/pkg/client/cache/doc.go | 24 + .../pkg/client/cache/expiration_cache.go | 202 ++ .../client/cache/expiration_cache_fakes.go | 54 + .../kubernetes/pkg/client/cache/fifo.go | 254 ++ .../kubernetes/pkg/client/cache/index.go | 72 + .../kubernetes/pkg/client/cache/listers.go | 558 ++++ .../kubernetes/pkg/client/cache/listwatch.go | 86 + .../kubernetes/pkg/client/cache/reflector.go | 382 +++ .../kubernetes/pkg/client/cache/store.go | 225 ++ .../pkg/client/cache/thread_safe_store.go | 248 ++ .../pkg/client/cache/undelta_store.go | 83 + .../internalclientset/clientset.go | 14 +- .../internalclientset/clientset_adaption.go | 5 +- .../kubernetes/pkg/client/record/doc.go | 18 + .../kubernetes/pkg/client/record/event.go | 310 +++ .../pkg/client/record/events_cache.go | 360 +++ .../kubernetes/pkg/client/record/fake.go | 40 + .../pkg/client/restclient/request.go | 2 +- .../discovery}/discovery_client.go | 18 +- .../pkg/client/unversioned/client.go | 16 +- .../client/unversioned/clientcmd/api/types.go | 6 +- .../unversioned/clientcmd/api/v1/types.go | 6 +- .../unversioned/clientcmd/client_config.go | 8 - .../client/unversioned/clientcmd/overrides.go | 4 +- .../pkg/client/unversioned/conditions.go | 8 +- .../pkg/client/unversioned/helper.go | 15 +- .../k8s.io/kubernetes/pkg/controller/OWNERS | 5 + .../pkg/controller/controller_utils.go | 647 +++++ .../k8s.io/kubernetes/pkg/controller/doc.go | 19 + .../pkg/controller/framework/controller.go | 321 +++ .../pkg/controller/framework/doc.go | 18 + .../framework/fake_controller_source.go | 188 ++ .../kubernetes/pkg/controller/lookup_cache.go | 90 + .../k8s.io/kubernetes/pkg/conversion/OWNERS | 5 + .../kubernetes/pkg/credentialprovider/OWNERS | 3 + vendor/k8s.io/kubernetes/pkg/kubectl/OWNERS | 7 + .../pkg/kubectl/cmd/config/create_cluster.go | 5 +- .../pkg/kubectl/cmd/util/factory.go | 104 +- .../pkg/kubectl/cmd/util/printing.go | 4 +- .../k8s.io/kubernetes/pkg/kubectl/describe.go | 47 +- .../k8s.io/kubernetes/pkg/kubectl/history.go | 2 +- .../pkg/kubectl/resource/builder.go | 38 +- .../kubernetes/pkg/kubectl/resource/mapper.go | 47 +- .../pkg/kubectl/resource/visitor.go | 31 +- .../pkg/kubectl/resource_printer.go | 176 +- .../kubernetes/pkg/kubectl/rolling_updater.go | 26 +- vendor/k8s.io/kubernetes/pkg/kubectl/run.go | 254 +- .../k8s.io/kubernetes/pkg/labels/selector.go | 35 +- vendor/k8s.io/kubernetes/pkg/runtime/OWNERS | 5 + .../kubernetes/pkg/types/unix_user_id.go | 23 + .../pkg/util/deployment/deployment.go | 323 +-- .../kubernetes/pkg/util/errors/errors.go | 8 +- .../kubernetes/pkg/util/labels/labels.go | 4 +- .../kubernetes/pkg/util/net/sets/README.md | 17 + .../kubernetes/pkg/util/net/sets/ipnet.go | 119 + vendor/k8s.io/kubernetes/pkg/util/pod/pod.go | 59 + .../kubernetes/pkg/util/runtime/runtime.go | 11 + vendor/k8s.io/kubernetes/pkg/version/base.go | 6 +- vendor/rsprd.com/localkube/LICENSE | 191 ++ .../localkube/pkg/localkubectl/context.go | 83 + .../localkube/pkg/localkubectl/controller.go | 219 ++ .../pkg/localkubectl/localkubectl.go | 171 ++ 137 files changed, 13589 insertions(+), 3023 deletions(-) create mode 100644 vendor/github.com/Sirupsen/logrus/.gitignore create mode 100644 vendor/github.com/Sirupsen/logrus/.travis.yml create mode 100644 vendor/github.com/Sirupsen/logrus/LICENSE create mode 100644 vendor/github.com/Sirupsen/logrus/README.md create mode 100644 vendor/github.com/Sirupsen/logrus/entry.go create mode 100644 vendor/github.com/Sirupsen/logrus/exported.go create mode 100644 vendor/github.com/Sirupsen/logrus/formatter.go create mode 100644 vendor/github.com/Sirupsen/logrus/hooks.go create mode 100644 vendor/github.com/Sirupsen/logrus/json_formatter.go create mode 100644 vendor/github.com/Sirupsen/logrus/logger.go create mode 100644 vendor/github.com/Sirupsen/logrus/logrus.go create mode 100644 vendor/github.com/Sirupsen/logrus/terminal_darwin.go create mode 100644 vendor/github.com/Sirupsen/logrus/terminal_freebsd.go create mode 100644 vendor/github.com/Sirupsen/logrus/terminal_linux.go create mode 100644 vendor/github.com/Sirupsen/logrus/terminal_notwindows.go create mode 100644 vendor/github.com/Sirupsen/logrus/terminal_windows.go create mode 100644 vendor/github.com/Sirupsen/logrus/text_formatter.go create mode 100644 vendor/github.com/docker/docker/pkg/jsonmessage/jsonmessage.go create mode 100644 vendor/github.com/docker/docker/pkg/term/tc_linux_cgo.go create mode 100644 vendor/github.com/docker/docker/pkg/term/tc_other.go create mode 100644 vendor/github.com/docker/docker/pkg/term/term.go create mode 100644 vendor/github.com/docker/docker/pkg/term/term_windows.go create mode 100644 vendor/github.com/docker/docker/pkg/term/termios_darwin.go create mode 100644 vendor/github.com/docker/docker/pkg/term/termios_freebsd.go create mode 100644 vendor/github.com/docker/docker/pkg/term/termios_linux.go create mode 100644 vendor/github.com/docker/docker/pkg/term/winconsole/console_windows.go create mode 100644 vendor/github.com/docker/docker/pkg/term/winconsole/term_emulator.go create mode 100644 vendor/github.com/docker/docker/pkg/timeutils/json.go create mode 100644 vendor/github.com/docker/docker/pkg/timeutils/utils.go create mode 100644 vendor/github.com/docker/docker/pkg/units/duration.go create mode 100644 vendor/github.com/docker/docker/pkg/units/size.go create mode 100644 vendor/github.com/golang/groupcache/LICENSE create mode 100644 vendor/github.com/golang/groupcache/lru/lru.go create mode 100644 vendor/k8s.io/kubernetes/pkg/api/OWNERS create mode 100644 vendor/k8s.io/kubernetes/pkg/api/endpoints/util.go create mode 100644 vendor/k8s.io/kubernetes/pkg/api/pod/util.go create mode 100644 vendor/k8s.io/kubernetes/pkg/api/service/annotations.go create mode 100644 vendor/k8s.io/kubernetes/pkg/api/service/util.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/apis/extensions/helpers.go create mode 100644 vendor/k8s.io/kubernetes/pkg/client/cache/delta_fifo.go create mode 100644 vendor/k8s.io/kubernetes/pkg/client/cache/doc.go create mode 100644 vendor/k8s.io/kubernetes/pkg/client/cache/expiration_cache.go create mode 100644 vendor/k8s.io/kubernetes/pkg/client/cache/expiration_cache_fakes.go create mode 100644 vendor/k8s.io/kubernetes/pkg/client/cache/fifo.go create mode 100644 vendor/k8s.io/kubernetes/pkg/client/cache/index.go create mode 100644 vendor/k8s.io/kubernetes/pkg/client/cache/listers.go create mode 100644 vendor/k8s.io/kubernetes/pkg/client/cache/listwatch.go create mode 100644 vendor/k8s.io/kubernetes/pkg/client/cache/reflector.go create mode 100644 vendor/k8s.io/kubernetes/pkg/client/cache/store.go create mode 100644 vendor/k8s.io/kubernetes/pkg/client/cache/thread_safe_store.go create mode 100644 vendor/k8s.io/kubernetes/pkg/client/cache/undelta_store.go create mode 100644 vendor/k8s.io/kubernetes/pkg/client/record/doc.go create mode 100644 vendor/k8s.io/kubernetes/pkg/client/record/event.go create mode 100644 vendor/k8s.io/kubernetes/pkg/client/record/events_cache.go create mode 100644 vendor/k8s.io/kubernetes/pkg/client/record/fake.go rename vendor/k8s.io/kubernetes/pkg/client/{unversioned => typed/discovery}/discovery_client.go (95%) create mode 100644 vendor/k8s.io/kubernetes/pkg/controller/OWNERS create mode 100644 vendor/k8s.io/kubernetes/pkg/controller/controller_utils.go create mode 100644 vendor/k8s.io/kubernetes/pkg/controller/doc.go create mode 100644 vendor/k8s.io/kubernetes/pkg/controller/framework/controller.go create mode 100644 vendor/k8s.io/kubernetes/pkg/controller/framework/doc.go create mode 100644 vendor/k8s.io/kubernetes/pkg/controller/framework/fake_controller_source.go create mode 100644 vendor/k8s.io/kubernetes/pkg/controller/lookup_cache.go create mode 100644 vendor/k8s.io/kubernetes/pkg/conversion/OWNERS create mode 100644 vendor/k8s.io/kubernetes/pkg/credentialprovider/OWNERS create mode 100644 vendor/k8s.io/kubernetes/pkg/kubectl/OWNERS create mode 100644 vendor/k8s.io/kubernetes/pkg/runtime/OWNERS create mode 100644 vendor/k8s.io/kubernetes/pkg/types/unix_user_id.go create mode 100644 vendor/k8s.io/kubernetes/pkg/util/net/sets/README.md create mode 100644 vendor/k8s.io/kubernetes/pkg/util/net/sets/ipnet.go create mode 100644 vendor/rsprd.com/localkube/LICENSE create mode 100644 vendor/rsprd.com/localkube/pkg/localkubectl/context.go create mode 100644 vendor/rsprd.com/localkube/pkg/localkubectl/controller.go create mode 100644 vendor/rsprd.com/localkube/pkg/localkubectl/localkubectl.go diff --git a/Godeps/Godeps.json b/Godeps/Godeps.json index 4d0bd13..ca1ded5 100644 --- a/Godeps/Godeps.json +++ b/Godeps/Godeps.json @@ -13,6 +13,11 @@ "Comment": "null-5", "Rev": "'75cd24fc2f2c2a2088577d12123ddee5f54e0675'" }, + { + "ImportPath": "github.com/Sirupsen/logrus", + "Comment": "v0.6.2-10-g51fe59a", + "Rev": "51fe59aca108dc5680109e7b2051cbdcfa5a253c" + }, { "ImportPath": "github.com/beorn7/perks/quantile", "Rev": "b965b613227fddccbfffe13eae360ed3fa822f8d" @@ -46,6 +51,11 @@ "Comment": "v2.3.0-rc.2-52-g55fbf54", "Rev": "55fbf54da00e98865f233bff65c4c57112101405" }, + { + "ImportPath": "github.com/docker/docker/pkg/jsonmessage", + "Comment": "v1.4.1-4831-g0f5c9d3", + "Rev": "0f5c9d301b9b1cca66b3ea0f9dec3b5317d3686d" + }, { "ImportPath": "github.com/docker/docker/pkg/mount", "Comment": "v1.4.1-4831-g0f5c9d3", @@ -56,6 +66,26 @@ "Comment": "v1.4.1-4831-g0f5c9d3", "Rev": "0f5c9d301b9b1cca66b3ea0f9dec3b5317d3686d" }, + { + "ImportPath": "github.com/docker/docker/pkg/term", + "Comment": "v1.4.1-4831-g0f5c9d3", + "Rev": "0f5c9d301b9b1cca66b3ea0f9dec3b5317d3686d" + }, + { + "ImportPath": "github.com/docker/docker/pkg/term/winconsole", + "Comment": "v1.4.1-4831-g0f5c9d3", + "Rev": "0f5c9d301b9b1cca66b3ea0f9dec3b5317d3686d" + }, + { + "ImportPath": "github.com/docker/docker/pkg/timeutils", + "Comment": "v1.4.1-4831-g0f5c9d3", + "Rev": "0f5c9d301b9b1cca66b3ea0f9dec3b5317d3686d" + }, + { + "ImportPath": "github.com/docker/docker/pkg/units", + "Comment": "v1.4.1-4831-g0f5c9d3", + "Rev": "0f5c9d301b9b1cca66b3ea0f9dec3b5317d3686d" + }, { "ImportPath": "github.com/docker/go-units", "Comment": "v0.1.0-21-g0bbddae", @@ -160,14 +190,18 @@ "ImportPath": "github.com/golang/glog", "Rev": "44145f04b68cf362d9c4df2182967c2275eaefed" }, + { + "ImportPath": "github.com/golang/groupcache/lru", + "Rev": "604ed5785183e59ae2789449d89e73f3a2a77987" + }, { "ImportPath": "github.com/golang/protobuf/proto", "Rev": "b982704f8bb716bb608144408cff30e15fbde841" }, { "ImportPath": "github.com/google/cadvisor/info/v1", - "Comment": "v0.21.1", - "Rev": "49a08d5139ae0111757a110ea3b55fe9a607873d" + "Comment": "v0.22.2", + "Rev": "546a3771589bdb356777c646c6eca24914fdd48b" }, { "ImportPath": "github.com/google/gofuzz", @@ -280,438 +314,488 @@ }, { "ImportPath": "k8s.io/kubernetes/pkg/api", - "Comment": "v1.2.0-alpha.7-1869-g47fda63", - "Rev": "47fda638b6777a69b83fa6509c855472993b9cb7" + "Comment": "v1.2.0", + "Rev": "5cb86ee022267586db386f62781338b0483733b3" + }, + { + "ImportPath": "k8s.io/kubernetes/pkg/api/endpoints", + "Comment": "v1.2.0", + "Rev": "5cb86ee022267586db386f62781338b0483733b3" }, { "ImportPath": "k8s.io/kubernetes/pkg/api/errors", - "Comment": "v1.2.0-alpha.7-1869-g47fda63", - "Rev": "47fda638b6777a69b83fa6509c855472993b9cb7" + "Comment": "v1.2.0", + "Rev": "5cb86ee022267586db386f62781338b0483733b3" }, { "ImportPath": "k8s.io/kubernetes/pkg/api/install", - "Comment": "v1.2.0-alpha.7-1869-g47fda63", - "Rev": "47fda638b6777a69b83fa6509c855472993b9cb7" + "Comment": "v1.2.0", + "Rev": "5cb86ee022267586db386f62781338b0483733b3" }, { "ImportPath": "k8s.io/kubernetes/pkg/api/meta", - "Comment": "v1.2.0-alpha.7-1869-g47fda63", - "Rev": "47fda638b6777a69b83fa6509c855472993b9cb7" + "Comment": "v1.2.0", + "Rev": "5cb86ee022267586db386f62781338b0483733b3" + }, + { + "ImportPath": "k8s.io/kubernetes/pkg/api/pod", + "Comment": "v1.2.0", + "Rev": "5cb86ee022267586db386f62781338b0483733b3" }, { "ImportPath": "k8s.io/kubernetes/pkg/api/resource", - "Comment": "v1.2.0-alpha.7-1869-g47fda63", - "Rev": "47fda638b6777a69b83fa6509c855472993b9cb7" + "Comment": "v1.2.0", + "Rev": "5cb86ee022267586db386f62781338b0483733b3" + }, + { + "ImportPath": "k8s.io/kubernetes/pkg/api/service", + "Comment": "v1.2.0", + "Rev": "5cb86ee022267586db386f62781338b0483733b3" }, { "ImportPath": "k8s.io/kubernetes/pkg/api/unversioned", - "Comment": "v1.2.0-alpha.7-1869-g47fda63", - "Rev": "47fda638b6777a69b83fa6509c855472993b9cb7" + "Comment": "v1.2.0", + "Rev": "5cb86ee022267586db386f62781338b0483733b3" }, { "ImportPath": "k8s.io/kubernetes/pkg/api/util", - "Comment": "v1.2.0-alpha.7-1869-g47fda63", - "Rev": "47fda638b6777a69b83fa6509c855472993b9cb7" + "Comment": "v1.2.0", + "Rev": "5cb86ee022267586db386f62781338b0483733b3" }, { "ImportPath": "k8s.io/kubernetes/pkg/api/v1", - "Comment": "v1.2.0-alpha.7-1869-g47fda63", - "Rev": "47fda638b6777a69b83fa6509c855472993b9cb7" + "Comment": "v1.2.0", + "Rev": "5cb86ee022267586db386f62781338b0483733b3" }, { "ImportPath": "k8s.io/kubernetes/pkg/api/validation", - "Comment": "v1.2.0-alpha.7-1869-g47fda63", - "Rev": "47fda638b6777a69b83fa6509c855472993b9cb7" + "Comment": "v1.2.0", + "Rev": "5cb86ee022267586db386f62781338b0483733b3" }, { "ImportPath": "k8s.io/kubernetes/pkg/apimachinery", - "Comment": "v1.2.0-alpha.7-1869-g47fda63", - "Rev": "47fda638b6777a69b83fa6509c855472993b9cb7" + "Comment": "v1.2.0", + "Rev": "5cb86ee022267586db386f62781338b0483733b3" }, { "ImportPath": "k8s.io/kubernetes/pkg/apimachinery/registered", - "Comment": "v1.2.0-alpha.7-1869-g47fda63", - "Rev": "47fda638b6777a69b83fa6509c855472993b9cb7" + "Comment": "v1.2.0", + "Rev": "5cb86ee022267586db386f62781338b0483733b3" }, { "ImportPath": "k8s.io/kubernetes/pkg/apis/authorization", - "Comment": "v1.2.0-alpha.7-1869-g47fda63", - "Rev": "47fda638b6777a69b83fa6509c855472993b9cb7" + "Comment": "v1.2.0", + "Rev": "5cb86ee022267586db386f62781338b0483733b3" }, { "ImportPath": "k8s.io/kubernetes/pkg/apis/authorization/install", - "Comment": "v1.2.0-alpha.7-1869-g47fda63", - "Rev": "47fda638b6777a69b83fa6509c855472993b9cb7" + "Comment": "v1.2.0", + "Rev": "5cb86ee022267586db386f62781338b0483733b3" }, { "ImportPath": "k8s.io/kubernetes/pkg/apis/authorization/v1beta1", - "Comment": "v1.2.0-alpha.7-1869-g47fda63", - "Rev": "47fda638b6777a69b83fa6509c855472993b9cb7" + "Comment": "v1.2.0", + "Rev": "5cb86ee022267586db386f62781338b0483733b3" }, { "ImportPath": "k8s.io/kubernetes/pkg/apis/autoscaling", - "Comment": "v1.2.0-alpha.7-1869-g47fda63", - "Rev": "47fda638b6777a69b83fa6509c855472993b9cb7" + "Comment": "v1.2.0", + "Rev": "5cb86ee022267586db386f62781338b0483733b3" }, { "ImportPath": "k8s.io/kubernetes/pkg/apis/autoscaling/install", - "Comment": "v1.2.0-alpha.7-1869-g47fda63", - "Rev": "47fda638b6777a69b83fa6509c855472993b9cb7" + "Comment": "v1.2.0", + "Rev": "5cb86ee022267586db386f62781338b0483733b3" }, { "ImportPath": "k8s.io/kubernetes/pkg/apis/autoscaling/v1", - "Comment": "v1.2.0-alpha.7-1869-g47fda63", - "Rev": "47fda638b6777a69b83fa6509c855472993b9cb7" + "Comment": "v1.2.0", + "Rev": "5cb86ee022267586db386f62781338b0483733b3" }, { "ImportPath": "k8s.io/kubernetes/pkg/apis/batch", - "Comment": "v1.2.0-alpha.7-1869-g47fda63", - "Rev": "47fda638b6777a69b83fa6509c855472993b9cb7" + "Comment": "v1.2.0", + "Rev": "5cb86ee022267586db386f62781338b0483733b3" }, { "ImportPath": "k8s.io/kubernetes/pkg/apis/batch/install", - "Comment": "v1.2.0-alpha.7-1869-g47fda63", - "Rev": "47fda638b6777a69b83fa6509c855472993b9cb7" + "Comment": "v1.2.0", + "Rev": "5cb86ee022267586db386f62781338b0483733b3" }, { "ImportPath": "k8s.io/kubernetes/pkg/apis/batch/v1", - "Comment": "v1.2.0-alpha.7-1869-g47fda63", - "Rev": "47fda638b6777a69b83fa6509c855472993b9cb7" + "Comment": "v1.2.0", + "Rev": "5cb86ee022267586db386f62781338b0483733b3" }, { "ImportPath": "k8s.io/kubernetes/pkg/apis/componentconfig", - "Comment": "v1.2.0-alpha.7-1869-g47fda63", - "Rev": "47fda638b6777a69b83fa6509c855472993b9cb7" + "Comment": "v1.2.0", + "Rev": "5cb86ee022267586db386f62781338b0483733b3" }, { "ImportPath": "k8s.io/kubernetes/pkg/apis/componentconfig/install", - "Comment": "v1.2.0-alpha.7-1869-g47fda63", - "Rev": "47fda638b6777a69b83fa6509c855472993b9cb7" + "Comment": "v1.2.0", + "Rev": "5cb86ee022267586db386f62781338b0483733b3" }, { "ImportPath": "k8s.io/kubernetes/pkg/apis/componentconfig/v1alpha1", - "Comment": "v1.2.0-alpha.7-1869-g47fda63", - "Rev": "47fda638b6777a69b83fa6509c855472993b9cb7" + "Comment": "v1.2.0", + "Rev": "5cb86ee022267586db386f62781338b0483733b3" }, { "ImportPath": "k8s.io/kubernetes/pkg/apis/extensions", - "Comment": "v1.2.0-alpha.7-1869-g47fda63", - "Rev": "47fda638b6777a69b83fa6509c855472993b9cb7" + "Comment": "v1.2.0", + "Rev": "5cb86ee022267586db386f62781338b0483733b3" }, { "ImportPath": "k8s.io/kubernetes/pkg/apis/extensions/install", - "Comment": "v1.2.0-alpha.7-1869-g47fda63", - "Rev": "47fda638b6777a69b83fa6509c855472993b9cb7" + "Comment": "v1.2.0", + "Rev": "5cb86ee022267586db386f62781338b0483733b3" }, { "ImportPath": "k8s.io/kubernetes/pkg/apis/extensions/v1beta1", - "Comment": "v1.2.0-alpha.7-1869-g47fda63", - "Rev": "47fda638b6777a69b83fa6509c855472993b9cb7" + "Comment": "v1.2.0", + "Rev": "5cb86ee022267586db386f62781338b0483733b3" }, { "ImportPath": "k8s.io/kubernetes/pkg/apis/metrics", - "Comment": "v1.2.0-alpha.7-1869-g47fda63", - "Rev": "47fda638b6777a69b83fa6509c855472993b9cb7" + "Comment": "v1.2.0", + "Rev": "5cb86ee022267586db386f62781338b0483733b3" }, { "ImportPath": "k8s.io/kubernetes/pkg/apis/metrics/install", - "Comment": "v1.2.0-alpha.7-1869-g47fda63", - "Rev": "47fda638b6777a69b83fa6509c855472993b9cb7" + "Comment": "v1.2.0", + "Rev": "5cb86ee022267586db386f62781338b0483733b3" }, { "ImportPath": "k8s.io/kubernetes/pkg/apis/metrics/v1alpha1", - "Comment": "v1.2.0-alpha.7-1869-g47fda63", - "Rev": "47fda638b6777a69b83fa6509c855472993b9cb7" + "Comment": "v1.2.0", + "Rev": "5cb86ee022267586db386f62781338b0483733b3" }, { "ImportPath": "k8s.io/kubernetes/pkg/auth/user", - "Comment": "v1.2.0-alpha.7-1869-g47fda63", - "Rev": "47fda638b6777a69b83fa6509c855472993b9cb7" + "Comment": "v1.2.0", + "Rev": "5cb86ee022267586db386f62781338b0483733b3" }, { "ImportPath": "k8s.io/kubernetes/pkg/capabilities", - "Comment": "v1.2.0-alpha.7-1869-g47fda63", - "Rev": "47fda638b6777a69b83fa6509c855472993b9cb7" + "Comment": "v1.2.0", + "Rev": "5cb86ee022267586db386f62781338b0483733b3" + }, + { + "ImportPath": "k8s.io/kubernetes/pkg/client/cache", + "Comment": "v1.2.0", + "Rev": "5cb86ee022267586db386f62781338b0483733b3" }, { "ImportPath": "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset", - "Comment": "v1.2.0-alpha.7-1869-g47fda63", - "Rev": "47fda638b6777a69b83fa6509c855472993b9cb7" + "Comment": "v1.2.0", + "Rev": "5cb86ee022267586db386f62781338b0483733b3" }, { "ImportPath": "k8s.io/kubernetes/pkg/client/metrics", - "Comment": "v1.2.0-alpha.7-1869-g47fda63", - "Rev": "47fda638b6777a69b83fa6509c855472993b9cb7" + "Comment": "v1.2.0", + "Rev": "5cb86ee022267586db386f62781338b0483733b3" + }, + { + "ImportPath": "k8s.io/kubernetes/pkg/client/record", + "Comment": "v1.2.0", + "Rev": "5cb86ee022267586db386f62781338b0483733b3" }, { "ImportPath": "k8s.io/kubernetes/pkg/client/restclient", - "Comment": "v1.2.0-alpha.7-1869-g47fda63", - "Rev": "47fda638b6777a69b83fa6509c855472993b9cb7" + "Comment": "v1.2.0", + "Rev": "5cb86ee022267586db386f62781338b0483733b3" }, { "ImportPath": "k8s.io/kubernetes/pkg/client/transport", - "Comment": "v1.2.0-alpha.7-1869-g47fda63", - "Rev": "47fda638b6777a69b83fa6509c855472993b9cb7" + "Comment": "v1.2.0", + "Rev": "5cb86ee022267586db386f62781338b0483733b3" + }, + { + "ImportPath": "k8s.io/kubernetes/pkg/client/typed/discovery", + "Comment": "v1.2.0", + "Rev": "5cb86ee022267586db386f62781338b0483733b3" }, { "ImportPath": "k8s.io/kubernetes/pkg/client/typed/generated/core/unversioned", - "Comment": "v1.2.0-alpha.7-1869-g47fda63", - "Rev": "47fda638b6777a69b83fa6509c855472993b9cb7" + "Comment": "v1.2.0", + "Rev": "5cb86ee022267586db386f62781338b0483733b3" }, { "ImportPath": "k8s.io/kubernetes/pkg/client/typed/generated/extensions/unversioned", - "Comment": "v1.2.0-alpha.7-1869-g47fda63", - "Rev": "47fda638b6777a69b83fa6509c855472993b9cb7" + "Comment": "v1.2.0", + "Rev": "5cb86ee022267586db386f62781338b0483733b3" }, { "ImportPath": "k8s.io/kubernetes/pkg/client/unversioned", - "Comment": "v1.2.0-alpha.7-1869-g47fda63", - "Rev": "47fda638b6777a69b83fa6509c855472993b9cb7" + "Comment": "v1.2.0", + "Rev": "5cb86ee022267586db386f62781338b0483733b3" }, { "ImportPath": "k8s.io/kubernetes/pkg/client/unversioned/auth", - "Comment": "v1.2.0-alpha.7-1869-g47fda63", - "Rev": "47fda638b6777a69b83fa6509c855472993b9cb7" + "Comment": "v1.2.0", + "Rev": "5cb86ee022267586db386f62781338b0483733b3" }, { "ImportPath": "k8s.io/kubernetes/pkg/client/unversioned/clientcmd", - "Comment": "v1.2.0-alpha.7-1869-g47fda63", - "Rev": "47fda638b6777a69b83fa6509c855472993b9cb7" + "Comment": "v1.2.0", + "Rev": "5cb86ee022267586db386f62781338b0483733b3" }, { "ImportPath": "k8s.io/kubernetes/pkg/client/unversioned/clientcmd/api", - "Comment": "v1.2.0-alpha.7-1869-g47fda63", - "Rev": "47fda638b6777a69b83fa6509c855472993b9cb7" + "Comment": "v1.2.0", + "Rev": "5cb86ee022267586db386f62781338b0483733b3" }, { "ImportPath": "k8s.io/kubernetes/pkg/client/unversioned/clientcmd/api/latest", - "Comment": "v1.2.0-alpha.7-1869-g47fda63", - "Rev": "47fda638b6777a69b83fa6509c855472993b9cb7" + "Comment": "v1.2.0", + "Rev": "5cb86ee022267586db386f62781338b0483733b3" }, { "ImportPath": "k8s.io/kubernetes/pkg/client/unversioned/clientcmd/api/v1", - "Comment": "v1.2.0-alpha.7-1869-g47fda63", - "Rev": "47fda638b6777a69b83fa6509c855472993b9cb7" + "Comment": "v1.2.0", + "Rev": "5cb86ee022267586db386f62781338b0483733b3" + }, + { + "ImportPath": "k8s.io/kubernetes/pkg/controller", + "Comment": "v1.2.0", + "Rev": "5cb86ee022267586db386f62781338b0483733b3" + }, + { + "ImportPath": "k8s.io/kubernetes/pkg/controller/framework", + "Comment": "v1.2.0", + "Rev": "5cb86ee022267586db386f62781338b0483733b3" }, { "ImportPath": "k8s.io/kubernetes/pkg/conversion", - "Comment": "v1.2.0-alpha.7-1869-g47fda63", - "Rev": "47fda638b6777a69b83fa6509c855472993b9cb7" + "Comment": "v1.2.0", + "Rev": "5cb86ee022267586db386f62781338b0483733b3" }, { "ImportPath": "k8s.io/kubernetes/pkg/conversion/queryparams", - "Comment": "v1.2.0-alpha.7-1869-g47fda63", - "Rev": "47fda638b6777a69b83fa6509c855472993b9cb7" + "Comment": "v1.2.0", + "Rev": "5cb86ee022267586db386f62781338b0483733b3" }, { "ImportPath": "k8s.io/kubernetes/pkg/credentialprovider", - "Comment": "v1.2.0-alpha.7-1869-g47fda63", - "Rev": "47fda638b6777a69b83fa6509c855472993b9cb7" + "Comment": "v1.2.0", + "Rev": "5cb86ee022267586db386f62781338b0483733b3" }, { "ImportPath": "k8s.io/kubernetes/pkg/fieldpath", - "Comment": "v1.2.0-alpha.7-1869-g47fda63", - "Rev": "47fda638b6777a69b83fa6509c855472993b9cb7" + "Comment": "v1.2.0", + "Rev": "5cb86ee022267586db386f62781338b0483733b3" }, { "ImportPath": "k8s.io/kubernetes/pkg/fields", - "Comment": "v1.2.0-alpha.7-1869-g47fda63", - "Rev": "47fda638b6777a69b83fa6509c855472993b9cb7" + "Comment": "v1.2.0", + "Rev": "5cb86ee022267586db386f62781338b0483733b3" }, { "ImportPath": "k8s.io/kubernetes/pkg/kubectl", - "Comment": "v1.2.0-alpha.7-1869-g47fda63", - "Rev": "47fda638b6777a69b83fa6509c855472993b9cb7" + "Comment": "v1.2.0", + "Rev": "5cb86ee022267586db386f62781338b0483733b3" }, { "ImportPath": "k8s.io/kubernetes/pkg/kubectl/cmd/config", - "Comment": "v1.2.0-alpha.7-1869-g47fda63", - "Rev": "47fda638b6777a69b83fa6509c855472993b9cb7" + "Comment": "v1.2.0", + "Rev": "5cb86ee022267586db386f62781338b0483733b3" }, { "ImportPath": "k8s.io/kubernetes/pkg/kubectl/cmd/util", - "Comment": "v1.2.0-alpha.7-1869-g47fda63", - "Rev": "47fda638b6777a69b83fa6509c855472993b9cb7" + "Comment": "v1.2.0", + "Rev": "5cb86ee022267586db386f62781338b0483733b3" }, { "ImportPath": "k8s.io/kubernetes/pkg/kubectl/resource", - "Comment": "v1.2.0-alpha.7-1869-g47fda63", - "Rev": "47fda638b6777a69b83fa6509c855472993b9cb7" + "Comment": "v1.2.0", + "Rev": "5cb86ee022267586db386f62781338b0483733b3" }, { "ImportPath": "k8s.io/kubernetes/pkg/kubelet/qos", - "Comment": "v1.2.0-alpha.7-1869-g47fda63", - "Rev": "47fda638b6777a69b83fa6509c855472993b9cb7" + "Comment": "v1.2.0", + "Rev": "5cb86ee022267586db386f62781338b0483733b3" }, { "ImportPath": "k8s.io/kubernetes/pkg/kubelet/qos/util", - "Comment": "v1.2.0-alpha.7-1869-g47fda63", - "Rev": "47fda638b6777a69b83fa6509c855472993b9cb7" + "Comment": "v1.2.0", + "Rev": "5cb86ee022267586db386f62781338b0483733b3" }, { "ImportPath": "k8s.io/kubernetes/pkg/labels", - "Comment": "v1.2.0-alpha.7-1869-g47fda63", - "Rev": "47fda638b6777a69b83fa6509c855472993b9cb7" + "Comment": "v1.2.0", + "Rev": "5cb86ee022267586db386f62781338b0483733b3" }, { "ImportPath": "k8s.io/kubernetes/pkg/master/ports", - "Comment": "v1.2.0-alpha.7-1869-g47fda63", - "Rev": "47fda638b6777a69b83fa6509c855472993b9cb7" + "Comment": "v1.2.0", + "Rev": "5cb86ee022267586db386f62781338b0483733b3" }, { "ImportPath": "k8s.io/kubernetes/pkg/runtime", - "Comment": "v1.2.0-alpha.7-1869-g47fda63", - "Rev": "47fda638b6777a69b83fa6509c855472993b9cb7" + "Comment": "v1.2.0", + "Rev": "5cb86ee022267586db386f62781338b0483733b3" }, { "ImportPath": "k8s.io/kubernetes/pkg/runtime/serializer", - "Comment": "v1.2.0-alpha.7-1869-g47fda63", - "Rev": "47fda638b6777a69b83fa6509c855472993b9cb7" + "Comment": "v1.2.0", + "Rev": "5cb86ee022267586db386f62781338b0483733b3" }, { "ImportPath": "k8s.io/kubernetes/pkg/runtime/serializer/json", - "Comment": "v1.2.0-alpha.7-1869-g47fda63", - "Rev": "47fda638b6777a69b83fa6509c855472993b9cb7" + "Comment": "v1.2.0", + "Rev": "5cb86ee022267586db386f62781338b0483733b3" }, { "ImportPath": "k8s.io/kubernetes/pkg/runtime/serializer/recognizer", - "Comment": "v1.2.0-alpha.7-1869-g47fda63", - "Rev": "47fda638b6777a69b83fa6509c855472993b9cb7" + "Comment": "v1.2.0", + "Rev": "5cb86ee022267586db386f62781338b0483733b3" }, { "ImportPath": "k8s.io/kubernetes/pkg/runtime/serializer/versioning", - "Comment": "v1.2.0-alpha.7-1869-g47fda63", - "Rev": "47fda638b6777a69b83fa6509c855472993b9cb7" + "Comment": "v1.2.0", + "Rev": "5cb86ee022267586db386f62781338b0483733b3" }, { "ImportPath": "k8s.io/kubernetes/pkg/types", - "Comment": "v1.2.0-alpha.7-1869-g47fda63", - "Rev": "47fda638b6777a69b83fa6509c855472993b9cb7" + "Comment": "v1.2.0", + "Rev": "5cb86ee022267586db386f62781338b0483733b3" }, { "ImportPath": "k8s.io/kubernetes/pkg/util", - "Comment": "v1.2.0-alpha.7-1869-g47fda63", - "Rev": "47fda638b6777a69b83fa6509c855472993b9cb7" + "Comment": "v1.2.0", + "Rev": "5cb86ee022267586db386f62781338b0483733b3" }, { "ImportPath": "k8s.io/kubernetes/pkg/util/deployment", - "Comment": "v1.2.0-alpha.7-1869-g47fda63", - "Rev": "47fda638b6777a69b83fa6509c855472993b9cb7" + "Comment": "v1.2.0", + "Rev": "5cb86ee022267586db386f62781338b0483733b3" }, { "ImportPath": "k8s.io/kubernetes/pkg/util/errors", - "Comment": "v1.2.0-alpha.7-1869-g47fda63", - "Rev": "47fda638b6777a69b83fa6509c855472993b9cb7" + "Comment": "v1.2.0", + "Rev": "5cb86ee022267586db386f62781338b0483733b3" }, { "ImportPath": "k8s.io/kubernetes/pkg/util/hash", - "Comment": "v1.2.0-alpha.7-1869-g47fda63", - "Rev": "47fda638b6777a69b83fa6509c855472993b9cb7" + "Comment": "v1.2.0", + "Rev": "5cb86ee022267586db386f62781338b0483733b3" }, { "ImportPath": "k8s.io/kubernetes/pkg/util/integer", - "Comment": "v1.2.0-alpha.7-1869-g47fda63", - "Rev": "47fda638b6777a69b83fa6509c855472993b9cb7" + "Comment": "v1.2.0", + "Rev": "5cb86ee022267586db386f62781338b0483733b3" }, { "ImportPath": "k8s.io/kubernetes/pkg/util/intstr", - "Comment": "v1.2.0-alpha.7-1869-g47fda63", - "Rev": "47fda638b6777a69b83fa6509c855472993b9cb7" + "Comment": "v1.2.0", + "Rev": "5cb86ee022267586db386f62781338b0483733b3" }, { "ImportPath": "k8s.io/kubernetes/pkg/util/jsonpath", - "Comment": "v1.2.0-alpha.7-1869-g47fda63", - "Rev": "47fda638b6777a69b83fa6509c855472993b9cb7" + "Comment": "v1.2.0", + "Rev": "5cb86ee022267586db386f62781338b0483733b3" }, { "ImportPath": "k8s.io/kubernetes/pkg/util/labels", - "Comment": "v1.2.0-alpha.7-1869-g47fda63", - "Rev": "47fda638b6777a69b83fa6509c855472993b9cb7" + "Comment": "v1.2.0", + "Rev": "5cb86ee022267586db386f62781338b0483733b3" }, { "ImportPath": "k8s.io/kubernetes/pkg/util/net", - "Comment": "v1.2.0-alpha.7-1869-g47fda63", - "Rev": "47fda638b6777a69b83fa6509c855472993b9cb7" + "Comment": "v1.2.0", + "Rev": "5cb86ee022267586db386f62781338b0483733b3" + }, + { + "ImportPath": "k8s.io/kubernetes/pkg/util/net/sets", + "Comment": "v1.2.0", + "Rev": "5cb86ee022267586db386f62781338b0483733b3" }, { "ImportPath": "k8s.io/kubernetes/pkg/util/parsers", - "Comment": "v1.2.0-alpha.7-1869-g47fda63", - "Rev": "47fda638b6777a69b83fa6509c855472993b9cb7" + "Comment": "v1.2.0", + "Rev": "5cb86ee022267586db386f62781338b0483733b3" }, { "ImportPath": "k8s.io/kubernetes/pkg/util/pod", - "Comment": "v1.2.0-alpha.7-1869-g47fda63", - "Rev": "47fda638b6777a69b83fa6509c855472993b9cb7" + "Comment": "v1.2.0", + "Rev": "5cb86ee022267586db386f62781338b0483733b3" }, { "ImportPath": "k8s.io/kubernetes/pkg/util/rand", - "Comment": "v1.2.0-alpha.7-1869-g47fda63", - "Rev": "47fda638b6777a69b83fa6509c855472993b9cb7" + "Comment": "v1.2.0", + "Rev": "5cb86ee022267586db386f62781338b0483733b3" }, { "ImportPath": "k8s.io/kubernetes/pkg/util/runtime", - "Comment": "v1.2.0-alpha.7-1869-g47fda63", - "Rev": "47fda638b6777a69b83fa6509c855472993b9cb7" + "Comment": "v1.2.0", + "Rev": "5cb86ee022267586db386f62781338b0483733b3" }, { "ImportPath": "k8s.io/kubernetes/pkg/util/sets", - "Comment": "v1.2.0-alpha.7-1869-g47fda63", - "Rev": "47fda638b6777a69b83fa6509c855472993b9cb7" + "Comment": "v1.2.0", + "Rev": "5cb86ee022267586db386f62781338b0483733b3" }, { "ImportPath": "k8s.io/kubernetes/pkg/util/strategicpatch", - "Comment": "v1.2.0-alpha.7-1869-g47fda63", - "Rev": "47fda638b6777a69b83fa6509c855472993b9cb7" + "Comment": "v1.2.0", + "Rev": "5cb86ee022267586db386f62781338b0483733b3" }, { "ImportPath": "k8s.io/kubernetes/pkg/util/validation", - "Comment": "v1.2.0-alpha.7-1869-g47fda63", - "Rev": "47fda638b6777a69b83fa6509c855472993b9cb7" + "Comment": "v1.2.0", + "Rev": "5cb86ee022267586db386f62781338b0483733b3" }, { "ImportPath": "k8s.io/kubernetes/pkg/util/validation/field", - "Comment": "v1.2.0-alpha.7-1869-g47fda63", - "Rev": "47fda638b6777a69b83fa6509c855472993b9cb7" + "Comment": "v1.2.0", + "Rev": "5cb86ee022267586db386f62781338b0483733b3" }, { "ImportPath": "k8s.io/kubernetes/pkg/util/wait", - "Comment": "v1.2.0-alpha.7-1869-g47fda63", - "Rev": "47fda638b6777a69b83fa6509c855472993b9cb7" + "Comment": "v1.2.0", + "Rev": "5cb86ee022267586db386f62781338b0483733b3" }, { "ImportPath": "k8s.io/kubernetes/pkg/util/yaml", - "Comment": "v1.2.0-alpha.7-1869-g47fda63", - "Rev": "47fda638b6777a69b83fa6509c855472993b9cb7" + "Comment": "v1.2.0", + "Rev": "5cb86ee022267586db386f62781338b0483733b3" }, { "ImportPath": "k8s.io/kubernetes/pkg/version", - "Comment": "v1.2.0-alpha.7-1869-g47fda63", - "Rev": "47fda638b6777a69b83fa6509c855472993b9cb7" + "Comment": "v1.2.0", + "Rev": "5cb86ee022267586db386f62781338b0483733b3" }, { "ImportPath": "k8s.io/kubernetes/pkg/watch", - "Comment": "v1.2.0-alpha.7-1869-g47fda63", - "Rev": "47fda638b6777a69b83fa6509c855472993b9cb7" + "Comment": "v1.2.0", + "Rev": "5cb86ee022267586db386f62781338b0483733b3" }, { "ImportPath": "k8s.io/kubernetes/pkg/watch/json", - "Comment": "v1.2.0-alpha.7-1869-g47fda63", - "Rev": "47fda638b6777a69b83fa6509c855472993b9cb7" + "Comment": "v1.2.0", + "Rev": "5cb86ee022267586db386f62781338b0483733b3" }, { "ImportPath": "k8s.io/kubernetes/third_party/forked/json", - "Comment": "v1.2.0-alpha.7-1869-g47fda63", - "Rev": "47fda638b6777a69b83fa6509c855472993b9cb7" + "Comment": "v1.2.0", + "Rev": "5cb86ee022267586db386f62781338b0483733b3" }, { "ImportPath": "k8s.io/kubernetes/third_party/forked/reflect", - "Comment": "v1.2.0-alpha.7-1869-g47fda63", - "Rev": "47fda638b6777a69b83fa6509c855472993b9cb7" + "Comment": "v1.2.0", + "Rev": "5cb86ee022267586db386f62781338b0483733b3" }, { "ImportPath": "k8s.io/kubernetes/third_party/golang/template", - "Comment": "v1.2.0-alpha.7-1869-g47fda63", - "Rev": "47fda638b6777a69b83fa6509c855472993b9cb7" + "Comment": "v1.2.0", + "Rev": "5cb86ee022267586db386f62781338b0483733b3" + }, + { + "ImportPath": "rsprd.com/localkube/pkg/localkubectl", + "Comment": "v1.2.0-v1-11-g89c7799", + "Rev": "89c779965c17ff8fb01886012c4432500a4de3c0" }, { "ImportPath": "speter.net/go/exp/math/dec/inf", diff --git a/cli/cluster.go b/cli/cluster.go index fcf614f..dc3a277 100644 --- a/cli/cluster.go +++ b/cli/cluster.go @@ -1,237 +1,14 @@ package cli import ( - "fmt" - "strings" + "rsprd.com/localkube/pkg/localkubectl" "github.com/codegangsta/cli" - docker "github.com/fsouza/go-dockerclient" - "github.com/mitchellh/go-homedir" - kubectlapi "k8s.io/kubernetes/pkg/client/unversioned/clientcmd/api" - kubectlcfg "k8s.io/kubernetes/pkg/kubectl/cmd/config" ) -const ( - LocalkubeContainerName = "/localkube" - LocalkubeImageName = "redspreadapps/localkube" - LocalkubeDefaultTag = "latest" - - DefaultHostDataDir = "~/.localkube/data" - ContainerDataDir = "/var/localkube/data" - KubectlName = "localkube" -) // Cluster manages the localkube Kubernetes development environment. func (s SpreadCli) Cluster() *cli.Command { - return &cli.Command{ - Name: "cluster", - Usage: "spread cluster [-a] [-t ] [ClusterDataDirectory]", - Description: "Manages localkube Kubernetes development environment", - ArgsUsage: "-a will attach to the process and print logs to stdout, -t specfies localkube tag to use, default is latest.", - Action: func(c *cli.Context) { - action := strings.ToLower(c.Args().First()) - switch { - case "start" == action: - s.startLocalkube(c) - case "stop" == action: - s.stopLocalkube(c) - default: - s.printf("Invalid option `%s`, must choose start or stop", action) - } - }, - } -} - -func (s SpreadCli) startLocalkube(c *cli.Context) { - client := s.dockerOrErr() - - dataDir := c.Args().Get(1) - if len(dataDir) == 0 { - var err error - dataDir, err = homedir.Expand(DefaultHostDataDir) - if err != nil { - s.fatalf("Unable to expand home directory: %v", err) - } - } - - tag := c.String("t") - if len(tag) == 0 { - tag = LocalkubeDefaultTag - } - - ctrOpts := localkube(c.Bool("a"), dataDir, tag) - ctr, err := client.CreateContainer(ctrOpts) - if err != nil { - if err.Error() == "no such image" { - s.printf("Pulling localkube image...") - err = client.PullImage(docker.PullImageOptions{ - Repository: LocalkubeImageName, - Tag: tag, - }, docker.AuthConfiguration{}) - if err != nil { - s.fatalf("Failed to pull localkube image: %v", err) - } - - s.startLocalkube(c) - return - } else if err.Error() == "container already exists" { - // replace container if already exists - err = client.RemoveContainer(docker.RemoveContainerOptions{ - ID: LocalkubeContainerName, - }) - if err != nil { - s.fatalf("Failed to start container: %v", err) - } - s.startLocalkube(c) - return - } - s.fatalf("Failed to create localkube container: %v", err) - - } - - binds := []string{ - "/sys:/sys:rw", - "/var/lib/docker:/var/lib/docker", - "/mnt/sda1/var/lib/docker:/mnt/sda1/var/lib/docker", - "/var/lib/kubelet:/var/lib/kubelet", - "/var/run:/var/run:rw", - "/:/rootfs:ro", - } - - // if provided mount etcd data dir - if len(dataDir) != 0 { - dataBind := fmt.Sprintf("%s:%s", dataDir, ContainerDataDir) - binds = append(binds, dataBind) - } - - hostConfig := &docker.HostConfig{ - Binds: binds, - NetworkMode: "host", - RestartPolicy: docker.AlwaysRestart(), - PidMode: "host", - Privileged: true, - } - err = client.StartContainer(ctr.ID, hostConfig) - if err != nil { - s.fatalf("Failed to start localkube: %v", err) - } - - s.printf("Started localkube...") - - err = setupContext(client.Endpoint()) - if err != nil { - s.fatalf("Could not configure kubectl context.") - } - s.printf("Setup and using kubectl `%s` context.", KubectlName) - return + return localkubectl.Command(s.out) } -func (s SpreadCli) stopLocalkube(c *cli.Context) { - client := s.dockerOrErr() - - ctrs, err := client.ListContainers(docker.ListContainersOptions{ - All: true, - Filters: map[string][]string{ - "label": []string{"rsprd.com/name=localkube"}, - }, - }) - if err != nil { - s.fatalf("Could not list containers: %v", err) - } - - for _, ctr := range ctrs { - if strings.HasPrefix(ctr.Status, "Up") { - s.printf("Stopping container `%s`...\n", ctr.ID) - if err := client.StopContainer(ctr.ID, 5); err != nil { - s.fatalf("Could not kill container: %v", err) - } - } - - if err := client.RemoveContainer(docker.RemoveContainerOptions{ID: ctr.ID}); err != nil { - s.fatalf("Could not remove container: %v", err) - } - } -} - -func (s SpreadCli) dockerOrErr() *docker.Client { - client, err := docker.NewClientFromEnv() - if err != nil { - s.fatalf("Could not create Docker client: %v", err) - } - - _, err = client.Version() - if err != nil { - s.fatalf("Unable to establish connection with Docker daemon: %v", err) - } - return client -} - -func localkube(attach bool, dataDir, tag string) docker.CreateContainerOptions { - return docker.CreateContainerOptions{ - Name: LocalkubeContainerName, - Config: &docker.Config{ - Hostname: "localkube", - AttachStderr: attach, - AttachStdout: attach, - Image: fmt.Sprintf("%s:%s", LocalkubeImageName, tag), - Env: []string{ - fmt.Sprintf("KUBE_ETCD_DATA_DIRECTORY=%s", ContainerDataDir), - }, - Labels: map[string]string{ - "rsprd.com/name": "localkube", - }, - StopSignal: "SIGINT", - }, - } -} - -func identifyHost(endpoint string) (string, error) { - beginPort := strings.LastIndex(endpoint, ":") - switch { - // if using TCP use provided host - case strings.HasPrefix(endpoint, "tcp://"): - return endpoint[6:beginPort], nil - // assuming localhost if Unix - // TODO: Make this customizable - case strings.HasPrefix(endpoint, "unix://"): - return "127.0.0.1", nil - } - return "", fmt.Errorf("Could not determine localkube API server from endpoint `%s`", endpoint) -} - -func setupContext(endpoint string) error { - host, err := identifyHost(endpoint) - if err != nil { - return fmt.Errorf("Could not identify host: %v", err) - } - - pathOpts := kubectlcfg.NewDefaultPathOptions() - - config, err := pathOpts.GetStartingConfig() - if err != nil { - return fmt.Errorf("could not setup config: %v", err) - } - - cluster, exists := config.Clusters[KubectlName] - if !exists { - cluster = kubectlapi.NewCluster() - } - - // configure cluster - cluster.Server = fmt.Sprintf("%s:8080", host) - cluster.InsecureSkipTLSVerify = true - config.Clusters[KubectlName] = cluster - - context, exists := config.Contexts[KubectlName] - if !exists { - context = kubectlapi.NewContext() - } - - // configure context - context.Cluster = KubectlName - config.Contexts[KubectlName] = context - - config.CurrentContext = KubectlName - - return kubectlcfg.ModifyConfig(pathOpts, *config, true) -} diff --git a/vendor/github.com/Sirupsen/logrus/.gitignore b/vendor/github.com/Sirupsen/logrus/.gitignore new file mode 100644 index 0000000..66be63a --- /dev/null +++ b/vendor/github.com/Sirupsen/logrus/.gitignore @@ -0,0 +1 @@ +logrus diff --git a/vendor/github.com/Sirupsen/logrus/.travis.yml b/vendor/github.com/Sirupsen/logrus/.travis.yml new file mode 100644 index 0000000..c3af3ce --- /dev/null +++ b/vendor/github.com/Sirupsen/logrus/.travis.yml @@ -0,0 +1,10 @@ +language: go +go: + - 1.2 + - 1.3 + - tip +install: + - go get github.com/stretchr/testify + - go get github.com/stvp/go-udp-testing + - go get github.com/tobi/airbrake-go + - go get github.com/getsentry/raven-go diff --git a/vendor/github.com/Sirupsen/logrus/LICENSE b/vendor/github.com/Sirupsen/logrus/LICENSE new file mode 100644 index 0000000..f090cb4 --- /dev/null +++ b/vendor/github.com/Sirupsen/logrus/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2014 Simon Eskildsen + +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/Sirupsen/logrus/README.md b/vendor/github.com/Sirupsen/logrus/README.md new file mode 100644 index 0000000..b6aa84c --- /dev/null +++ b/vendor/github.com/Sirupsen/logrus/README.md @@ -0,0 +1,352 @@ +# Logrus :walrus: [![Build Status](https://travis-ci.org/Sirupsen/logrus.svg?branch=master)](https://travis-ci.org/Sirupsen/logrus) + +Logrus is a structured logger for Go (golang), completely API compatible with +the standard library logger. [Godoc][godoc]. **Please note the Logrus API is not +yet stable (pre 1.0), the core API is unlikely change much but please version +control your Logrus to make sure you aren't fetching latest `master` on every +build.** + +Nicely color-coded in development (when a TTY is attached, otherwise just +plain text): + +![Colored](http://i.imgur.com/PY7qMwd.png) + +With `log.Formatter = new(logrus.JSONFormatter)`, for easy parsing by logstash +or Splunk: + +```json +{"animal":"walrus","level":"info","msg":"A group of walrus emerges from the +ocean","size":10,"time":"2014-03-10 19:57:38.562264131 -0400 EDT"} + +{"level":"warning","msg":"The group's number increased tremendously!", +"number":122,"omg":true,"time":"2014-03-10 19:57:38.562471297 -0400 EDT"} + +{"animal":"walrus","level":"info","msg":"A giant walrus appears!", +"size":10,"time":"2014-03-10 19:57:38.562500591 -0400 EDT"} + +{"animal":"walrus","level":"info","msg":"Tremendously sized cow enters the ocean.", +"size":9,"time":"2014-03-10 19:57:38.562527896 -0400 EDT"} + +{"level":"fatal","msg":"The ice breaks!","number":100,"omg":true, +"time":"2014-03-10 19:57:38.562543128 -0400 EDT"} +``` + +With the default `log.Formatter = new(logrus.TextFormatter)` when a TTY is not +attached, the output is compatible with the +[l2met](http://r.32k.io/l2met-introduction) format: + +```text +time="2014-04-20 15:36:23.830442383 -0400 EDT" level="info" msg="A group of walrus emerges from the ocean" animal="walrus" size=10 +time="2014-04-20 15:36:23.830584199 -0400 EDT" level="warning" msg="The group's number increased tremendously!" omg=true number=122 +time="2014-04-20 15:36:23.830596521 -0400 EDT" level="info" msg="A giant walrus appears!" animal="walrus" size=10 +time="2014-04-20 15:36:23.830611837 -0400 EDT" level="info" msg="Tremendously sized cow enters the ocean." animal="walrus" size=9 +time="2014-04-20 15:36:23.830626464 -0400 EDT" level="fatal" msg="The ice breaks!" omg=true number=100 +``` + +#### Example + +The simplest way to use Logrus is simply the package-level exported logger: + +```go +package main + +import ( + log "github.com/Sirupsen/logrus" +) + +func main() { + log.WithFields(log.Fields{ + "animal": "walrus", + }).Info("A walrus appears") +} +``` + +Note that it's completely api-compatible with the stdlib logger, so you can +replace your `log` imports everywhere with `log "github.com/Sirupsen/logrus"` +and you'll now have the flexibility of Logrus. You can customize it all you +want: + +```go +package main + +import ( + "os" + log "github.com/Sirupsen/logrus" + "github.com/Sirupsen/logrus/hooks/airbrake" +) + +func init() { + // Log as JSON instead of the default ASCII formatter. + log.SetFormatter(&log.JSONFormatter{}) + + // Use the Airbrake hook to report errors that have Error severity or above to + // an exception tracker. You can create custom hooks, see the Hooks section. + log.AddHook(&logrus_airbrake.AirbrakeHook{}) + + // Output to stderr instead of stdout, could also be a file. + log.SetOutput(os.Stderr) + + // Only log the warning severity or above. + log.SetLevel(log.WarnLevel) +} + +func main() { + log.WithFields(log.Fields{ + "animal": "walrus", + "size": 10, + }).Info("A group of walrus emerges from the ocean") + + log.WithFields(log.Fields{ + "omg": true, + "number": 122, + }).Warn("The group's number increased tremendously!") + + log.WithFields(log.Fields{ + "omg": true, + "number": 100, + }).Fatal("The ice breaks!") +} +``` + +For more advanced usage such as logging to multiple locations from the same +application, you can also create an instance of the `logrus` Logger: + +```go +package main + +import ( + "github.com/Sirupsen/logrus" +) + +// Create a new instance of the logger. You can have any number of instances. +var log = logrus.New() + +func main() { + // The API for setting attributes is a little different than the package level + // exported logger. See Godoc. + log.Out = os.Stderr + + log.WithFields(logrus.Fields{ + "animal": "walrus", + "size": 10, + }).Info("A group of walrus emerges from the ocean") +} +``` + +#### Fields + +Logrus encourages careful, structured logging though logging fields instead of +long, unparseable error messages. For example, instead of: `log.Fatalf("Failed +to send event %s to topic %s with key %d")`, you should log the much more +discoverable: + +```go +log.WithFields(log.Fields{ + "event": event, + "topic": topic, + "key": key, +}).Fatal("Failed to send event") +``` + +We've found this API forces you to think about logging in a way that produces +much more useful logging messages. We've been in countless situations where just +a single added field to a log statement that was already there would've saved us +hours. The `WithFields` call is optional. + +In general, with Logrus using any of the `printf`-family functions should be +seen as a hint you should add a field, however, you can still use the +`printf`-family functions with Logrus. + +#### Hooks + +You can add hooks for logging levels. For example to send errors to an exception +tracking service on `Error`, `Fatal` and `Panic`, info to StatsD or log to +multiple places simultaneously, e.g. syslog. + +```go +// Not the real implementation of the Airbrake hook. Just a simple sample. +import ( + log "github.com/Sirupsen/logrus" +) + +func init() { + log.AddHook(new(AirbrakeHook)) +} + +type AirbrakeHook struct{} + +// `Fire()` takes the entry that the hook is fired for. `entry.Data[]` contains +// the fields for the entry. See the Fields section of the README. +func (hook *AirbrakeHook) Fire(entry *logrus.Entry) error { + err := airbrake.Notify(entry.Data["error"].(error)) + if err != nil { + log.WithFields(log.Fields{ + "source": "airbrake", + "endpoint": airbrake.Endpoint, + }).Info("Failed to send error to Airbrake") + } + + return nil +} + +// `Levels()` returns a slice of `Levels` the hook is fired for. +func (hook *AirbrakeHook) Levels() []log.Level { + return []log.Level{ + log.ErrorLevel, + log.FatalLevel, + log.PanicLevel, + } +} +``` + +Logrus comes with built-in hooks. Add those, or your custom hook, in `init`: + +```go +import ( + log "github.com/Sirupsen/logrus" + "github.com/Sirupsen/logrus/hooks/airbrake" + "github.com/Sirupsen/logrus/hooks/syslog" + "log/syslog" +) + +func init() { + log.AddHook(new(logrus_airbrake.AirbrakeHook)) + + hook, err := logrus_syslog.NewSyslogHook("udp", "localhost:514", syslog.LOG_INFO, "") + if err != nil { + log.Error("Unable to connect to local syslog daemon") + } else { + log.AddHook(hook) + } +} +``` + +* [`github.com/Sirupsen/logrus/hooks/airbrake`](https://github.com/Sirupsen/logrus/blob/master/hooks/airbrake/airbrake.go) + Send errors to an exception tracking service compatible with the Airbrake API. + Uses [`airbrake-go`](https://github.com/tobi/airbrake-go) behind the scenes. + +* [`github.com/Sirupsen/logrus/hooks/papertrail`](https://github.com/Sirupsen/logrus/blob/master/hooks/papertrail/papertrail.go) + Send errors to the Papertrail hosted logging service via UDP. + +* [`github.com/Sirupsen/logrus/hooks/syslog`](https://github.com/Sirupsen/logrus/blob/master/hooks/syslog/syslog.go) + Send errors to remote syslog server. + Uses standard library `log/syslog` behind the scenes. + +* [`github.com/nubo/hiprus`](https://github.com/nubo/hiprus) + Send errors to a channel in hipchat. + +* [`github.com/sebest/logrusly`](https://github.com/sebest/logrusly) + Send logs to Loggly (https://www.loggly.com/) + +#### Level logging + +Logrus has six logging levels: Debug, Info, Warning, Error, Fatal and Panic. + +```go +log.Debug("Useful debugging information.") +log.Info("Something noteworthy happened!") +log.Warn("You should probably take a look at this.") +log.Error("Something failed but I'm not quitting.") +// Calls os.Exit(1) after logging +log.Fatal("Bye.") +// Calls panic() after logging +log.Panic("I'm bailing.") +``` + +You can set the logging level on a `Logger`, then it will only log entries with +that severity or anything above it: + +```go +// Will log anything that is info or above (warn, error, fatal, panic). Default. +log.SetLevel(log.InfoLevel) +``` + +It may be useful to set `log.Level = logrus.DebugLevel` in a debug or verbose +environment if your application has that. + +#### Entries + +Besides the fields added with `WithField` or `WithFields` some fields are +automatically added to all logging events: + +1. `time`. The timestamp when the entry was created. +2. `msg`. The logging message passed to `{Info,Warn,Error,Fatal,Panic}` after + the `AddFields` call. E.g. `Failed to send event.` +3. `level`. The logging level. E.g. `info`. + +#### Environments + +Logrus has no notion of environment. + +If you wish for hooks and formatters to only be used in specific environments, +you should handle that yourself. For example, if your application has a global +variable `Environment`, which is a string representation of the environment you +could do: + +```go +import ( + log "github.com/Sirupsen/logrus" +) + +init() { + // do something here to set environment depending on an environment variable + // or command-line flag + if Environment == "production" { + log.SetFormatter(logrus.JSONFormatter) + } else { + // The TextFormatter is default, you don't actually have to do this. + log.SetFormatter(logrus.TextFormatter) + } +} +``` + +This configuration is how `logrus` was intended to be used, but JSON in +production is mostly only useful if you do log aggregation with tools like +Splunk or Logstash. + +#### Formatters + +The built-in logging formatters are: + +* `logrus.TextFormatter`. Logs the event in colors if stdout is a tty, otherwise + without colors. + * *Note:* to force colored output when there is no TTY, set the `ForceColors` + field to `true`. To force no colored output even if there is a TTY set the + `DisableColors` field to `true` +* `logrus.JSONFormatter`. Logs fields as JSON. + +Third party logging formatters: + +* [`zalgo`](https://github.com/aybabtme/logzalgo): invoking the P͉̫o̳̼̊w̖͈̰͎e̬͔̭͂r͚̼̹̲ ̫͓͉̳͈ō̠͕͖̚f̝͍̠ ͕̲̞͖͑Z̖̫̤̫ͪa͉̬͈̗l͖͎g̳̥o̰̥̅!̣͔̲̻͊̄ ̙̘̦̹̦. + +You can define your formatter by implementing the `Formatter` interface, +requiring a `Format` method. `Format` takes an `*Entry`. `entry.Data` is a +`Fields` type (`map[string]interface{}`) with all your fields as well as the +default ones (see Entries section above): + +```go +type MyJSONFormatter struct { +} + +log.SetFormatter(new(MyJSONFormatter)) + +func (f *JSONFormatter) Format(entry *Entry) ([]byte, error) { + // Note this doesn't include Time, Level and Message which are available on + // the Entry. Consult `godoc` on information about those fields or read the + // source of the official loggers. + serialized, err := json.Marshal(entry.Data) + if err != nil { + return nil, fmt.Errorf("Failed to marshal fields to JSON, %v", err) + } + return append(serialized, '\n'), nil +} +``` + +#### Rotation + +Log rotation is not provided with Logrus. Log rotation should be done by an +external program (like `logrotated(8)`) that can compress and delete old log +entries. It should not be a feature of the application-level logger. + + +[godoc]: https://godoc.org/github.com/Sirupsen/logrus diff --git a/vendor/github.com/Sirupsen/logrus/entry.go b/vendor/github.com/Sirupsen/logrus/entry.go new file mode 100644 index 0000000..e164eec --- /dev/null +++ b/vendor/github.com/Sirupsen/logrus/entry.go @@ -0,0 +1,248 @@ +package logrus + +import ( + "bytes" + "fmt" + "io" + "os" + "time" +) + +// An entry is the final or intermediate Logrus logging entry. It contains all +// the fields passed with WithField{,s}. It's finally logged when Debug, Info, +// Warn, Error, Fatal or Panic is called on it. These objects can be reused and +// passed around as much as you wish to avoid field duplication. +type Entry struct { + Logger *Logger + + // Contains all the fields set by the user. + Data Fields + + // Time at which the log entry was created + Time time.Time + + // Level the log entry was logged at: Debug, Info, Warn, Error, Fatal or Panic + Level Level + + // Message passed to Debug, Info, Warn, Error, Fatal or Panic + Message string +} + +func NewEntry(logger *Logger) *Entry { + return &Entry{ + Logger: logger, + // Default is three fields, give a little extra room + Data: make(Fields, 5), + } +} + +// Returns a reader for the entry, which is a proxy to the formatter. +func (entry *Entry) Reader() (*bytes.Buffer, error) { + serialized, err := entry.Logger.Formatter.Format(entry) + return bytes.NewBuffer(serialized), err +} + +// Returns the string representation from the reader and ultimately the +// formatter. +func (entry *Entry) String() (string, error) { + reader, err := entry.Reader() + if err != nil { + return "", err + } + + return reader.String(), err +} + +// Add a single field to the Entry. +func (entry *Entry) WithField(key string, value interface{}) *Entry { + return entry.WithFields(Fields{key: value}) +} + +// Add a map of fields to the Entry. +func (entry *Entry) WithFields(fields Fields) *Entry { + data := Fields{} + for k, v := range entry.Data { + data[k] = v + } + for k, v := range fields { + data[k] = v + } + return &Entry{Logger: entry.Logger, Data: data} +} + +func (entry *Entry) log(level Level, msg string) { + entry.Time = time.Now() + entry.Level = level + entry.Message = msg + + if err := entry.Logger.Hooks.Fire(level, entry); err != nil { + entry.Logger.mu.Lock() + fmt.Fprintf(os.Stderr, "Failed to fire hook: %v\n", err) + entry.Logger.mu.Unlock() + } + + reader, err := entry.Reader() + if err != nil { + entry.Logger.mu.Lock() + fmt.Fprintf(os.Stderr, "Failed to obtain reader, %v\n", err) + entry.Logger.mu.Unlock() + } + + entry.Logger.mu.Lock() + defer entry.Logger.mu.Unlock() + + _, err = io.Copy(entry.Logger.Out, reader) + if err != nil { + fmt.Fprintf(os.Stderr, "Failed to write to log, %v\n", err) + } + + // To avoid Entry#log() returning a value that only would make sense for + // panic() to use in Entry#Panic(), we avoid the allocation by checking + // directly here. + if level <= PanicLevel { + panic(entry) + } +} + +func (entry *Entry) Debug(args ...interface{}) { + if entry.Logger.Level >= DebugLevel { + entry.log(DebugLevel, fmt.Sprint(args...)) + } +} + +func (entry *Entry) Print(args ...interface{}) { + entry.Info(args...) +} + +func (entry *Entry) Info(args ...interface{}) { + if entry.Logger.Level >= InfoLevel { + entry.log(InfoLevel, fmt.Sprint(args...)) + } +} + +func (entry *Entry) Warn(args ...interface{}) { + if entry.Logger.Level >= WarnLevel { + entry.log(WarnLevel, fmt.Sprint(args...)) + } +} + +func (entry *Entry) Error(args ...interface{}) { + if entry.Logger.Level >= ErrorLevel { + entry.log(ErrorLevel, fmt.Sprint(args...)) + } +} + +func (entry *Entry) Fatal(args ...interface{}) { + if entry.Logger.Level >= FatalLevel { + entry.log(FatalLevel, fmt.Sprint(args...)) + } + os.Exit(1) +} + +func (entry *Entry) Panic(args ...interface{}) { + if entry.Logger.Level >= PanicLevel { + entry.log(PanicLevel, fmt.Sprint(args...)) + } + panic(fmt.Sprint(args...)) +} + +// Entry Printf family functions + +func (entry *Entry) Debugf(format string, args ...interface{}) { + if entry.Logger.Level >= DebugLevel { + entry.Debug(fmt.Sprintf(format, args...)) + } +} + +func (entry *Entry) Infof(format string, args ...interface{}) { + if entry.Logger.Level >= InfoLevel { + entry.Info(fmt.Sprintf(format, args...)) + } +} + +func (entry *Entry) Printf(format string, args ...interface{}) { + entry.Infof(format, args...) +} + +func (entry *Entry) Warnf(format string, args ...interface{}) { + if entry.Logger.Level >= WarnLevel { + entry.Warn(fmt.Sprintf(format, args...)) + } +} + +func (entry *Entry) Warningf(format string, args ...interface{}) { + entry.Warnf(format, args...) +} + +func (entry *Entry) Errorf(format string, args ...interface{}) { + if entry.Logger.Level >= ErrorLevel { + entry.Error(fmt.Sprintf(format, args...)) + } +} + +func (entry *Entry) Fatalf(format string, args ...interface{}) { + if entry.Logger.Level >= FatalLevel { + entry.Fatal(fmt.Sprintf(format, args...)) + } +} + +func (entry *Entry) Panicf(format string, args ...interface{}) { + if entry.Logger.Level >= PanicLevel { + entry.Panic(fmt.Sprintf(format, args...)) + } +} + +// Entry Println family functions + +func (entry *Entry) Debugln(args ...interface{}) { + if entry.Logger.Level >= DebugLevel { + entry.Debug(entry.sprintlnn(args...)) + } +} + +func (entry *Entry) Infoln(args ...interface{}) { + if entry.Logger.Level >= InfoLevel { + entry.Info(entry.sprintlnn(args...)) + } +} + +func (entry *Entry) Println(args ...interface{}) { + entry.Infoln(args...) +} + +func (entry *Entry) Warnln(args ...interface{}) { + if entry.Logger.Level >= WarnLevel { + entry.Warn(entry.sprintlnn(args...)) + } +} + +func (entry *Entry) Warningln(args ...interface{}) { + entry.Warnln(args...) +} + +func (entry *Entry) Errorln(args ...interface{}) { + if entry.Logger.Level >= ErrorLevel { + entry.Error(entry.sprintlnn(args...)) + } +} + +func (entry *Entry) Fatalln(args ...interface{}) { + if entry.Logger.Level >= FatalLevel { + entry.Fatal(entry.sprintlnn(args...)) + } +} + +func (entry *Entry) Panicln(args ...interface{}) { + if entry.Logger.Level >= PanicLevel { + entry.Panic(entry.sprintlnn(args...)) + } +} + +// Sprintlnn => Sprint no newline. This is to get the behavior of how +// fmt.Sprintln where spaces are always added between operands, regardless of +// their type. Instead of vendoring the Sprintln implementation to spare a +// string allocation, we do the simplest thing. +func (entry *Entry) sprintlnn(args ...interface{}) string { + msg := fmt.Sprintln(args...) + return msg[:len(msg)-1] +} diff --git a/vendor/github.com/Sirupsen/logrus/exported.go b/vendor/github.com/Sirupsen/logrus/exported.go new file mode 100644 index 0000000..d087124 --- /dev/null +++ b/vendor/github.com/Sirupsen/logrus/exported.go @@ -0,0 +1,182 @@ +package logrus + +import ( + "io" +) + +var ( + // std is the name of the standard logger in stdlib `log` + std = New() +) + +// SetOutput sets the standard logger output. +func SetOutput(out io.Writer) { + std.mu.Lock() + defer std.mu.Unlock() + std.Out = out +} + +// SetFormatter sets the standard logger formatter. +func SetFormatter(formatter Formatter) { + std.mu.Lock() + defer std.mu.Unlock() + std.Formatter = formatter +} + +// SetLevel sets the standard logger level. +func SetLevel(level Level) { + std.mu.Lock() + defer std.mu.Unlock() + std.Level = level +} + +// GetLevel returns the standard logger level. +func GetLevel() Level { + return std.Level +} + +// AddHook adds a hook to the standard logger hooks. +func AddHook(hook Hook) { + std.mu.Lock() + defer std.mu.Unlock() + std.Hooks.Add(hook) +} + +// WithField creates an entry from the standard logger and adds a field to +// it. If you want multiple fields, use `WithFields`. +// +// Note that it doesn't log until you call Debug, Print, Info, Warn, Fatal +// or Panic on the Entry it returns. +func WithField(key string, value interface{}) *Entry { + return std.WithField(key, value) +} + +// WithFields creates an entry from the standard logger and adds multiple +// fields to it. This is simply a helper for `WithField`, invoking it +// once for each field. +// +// Note that it doesn't log until you call Debug, Print, Info, Warn, Fatal +// or Panic on the Entry it returns. +func WithFields(fields Fields) *Entry { + return std.WithFields(fields) +} + +// Debug logs a message at level Debug on the standard logger. +func Debug(args ...interface{}) { + std.Debug(args...) +} + +// Print logs a message at level Info on the standard logger. +func Print(args ...interface{}) { + std.Print(args...) +} + +// Info logs a message at level Info on the standard logger. +func Info(args ...interface{}) { + std.Info(args...) +} + +// Warn logs a message at level Warn on the standard logger. +func Warn(args ...interface{}) { + std.Warn(args...) +} + +// Warning logs a message at level Warn on the standard logger. +func Warning(args ...interface{}) { + std.Warning(args...) +} + +// Error logs a message at level Error on the standard logger. +func Error(args ...interface{}) { + std.Error(args...) +} + +// Panic logs a message at level Panic on the standard logger. +func Panic(args ...interface{}) { + std.Panic(args...) +} + +// Fatal logs a message at level Fatal on the standard logger. +func Fatal(args ...interface{}) { + std.Fatal(args...) +} + +// Debugf logs a message at level Debug on the standard logger. +func Debugf(format string, args ...interface{}) { + std.Debugf(format, args...) +} + +// Printf logs a message at level Info on the standard logger. +func Printf(format string, args ...interface{}) { + std.Printf(format, args...) +} + +// Infof logs a message at level Info on the standard logger. +func Infof(format string, args ...interface{}) { + std.Infof(format, args...) +} + +// Warnf logs a message at level Warn on the standard logger. +func Warnf(format string, args ...interface{}) { + std.Warnf(format, args...) +} + +// Warningf logs a message at level Warn on the standard logger. +func Warningf(format string, args ...interface{}) { + std.Warningf(format, args...) +} + +// Errorf logs a message at level Error on the standard logger. +func Errorf(format string, args ...interface{}) { + std.Errorf(format, args...) +} + +// Panicf logs a message at level Panic on the standard logger. +func Panicf(format string, args ...interface{}) { + std.Panicf(format, args...) +} + +// Fatalf logs a message at level Fatal on the standard logger. +func Fatalf(format string, args ...interface{}) { + std.Fatalf(format, args...) +} + +// Debugln logs a message at level Debug on the standard logger. +func Debugln(args ...interface{}) { + std.Debugln(args...) +} + +// Println logs a message at level Info on the standard logger. +func Println(args ...interface{}) { + std.Println(args...) +} + +// Infoln logs a message at level Info on the standard logger. +func Infoln(args ...interface{}) { + std.Infoln(args...) +} + +// Warnln logs a message at level Warn on the standard logger. +func Warnln(args ...interface{}) { + std.Warnln(args...) +} + +// Warningln logs a message at level Warn on the standard logger. +func Warningln(args ...interface{}) { + std.Warningln(args...) +} + +// Errorln logs a message at level Error on the standard logger. +func Errorln(args ...interface{}) { + std.Errorln(args...) +} + +// Panicln logs a message at level Panic on the standard logger. +func Panicln(args ...interface{}) { + std.Panicln(args...) +} + +// Fatalln logs a message at level Fatal on the standard logger. +func Fatalln(args ...interface{}) { + std.Fatalln(args...) +} diff --git a/vendor/github.com/Sirupsen/logrus/formatter.go b/vendor/github.com/Sirupsen/logrus/formatter.go new file mode 100644 index 0000000..038ce9f --- /dev/null +++ b/vendor/github.com/Sirupsen/logrus/formatter.go @@ -0,0 +1,44 @@ +package logrus + +// The Formatter interface is used to implement a custom Formatter. It takes an +// `Entry`. It exposes all the fields, including the default ones: +// +// * `entry.Data["msg"]`. The message passed from Info, Warn, Error .. +// * `entry.Data["time"]`. The timestamp. +// * `entry.Data["level"]. The level the entry was logged at. +// +// Any additional fields added with `WithField` or `WithFields` are also in +// `entry.Data`. Format is expected to return an array of bytes which are then +// logged to `logger.Out`. +type Formatter interface { + Format(*Entry) ([]byte, error) +} + +// This is to not silently overwrite `time`, `msg` and `level` fields when +// dumping it. If this code wasn't there doing: +// +// logrus.WithField("level", 1).Info("hello") +// +// Would just silently drop the user provided level. Instead with this code +// it'll logged as: +// +// {"level": "info", "fields.level": 1, "msg": "hello", "time": "..."} +// +// It's not exported because it's still using Data in an opinionated way. It's to +// avoid code duplication between the two default formatters. +func prefixFieldClashes(data Fields) { + _, ok := data["time"] + if ok { + data["fields.time"] = data["time"] + } + + _, ok = data["msg"] + if ok { + data["fields.msg"] = data["msg"] + } + + _, ok = data["level"] + if ok { + data["fields.level"] = data["level"] + } +} diff --git a/vendor/github.com/Sirupsen/logrus/hooks.go b/vendor/github.com/Sirupsen/logrus/hooks.go new file mode 100644 index 0000000..0da2b36 --- /dev/null +++ b/vendor/github.com/Sirupsen/logrus/hooks.go @@ -0,0 +1,34 @@ +package logrus + +// A hook to be fired when logging on the logging levels returned from +// `Levels()` on your implementation of the interface. Note that this is not +// fired in a goroutine or a channel with workers, you should handle such +// functionality yourself if your call is non-blocking and you don't wish for +// the logging calls for levels returned from `Levels()` to block. +type Hook interface { + Levels() []Level + Fire(*Entry) error +} + +// Internal type for storing the hooks on a logger instance. +type levelHooks map[Level][]Hook + +// Add a hook to an instance of logger. This is called with +// `log.Hooks.Add(new(MyHook))` where `MyHook` implements the `Hook` interface. +func (hooks levelHooks) Add(hook Hook) { + for _, level := range hook.Levels() { + hooks[level] = append(hooks[level], hook) + } +} + +// Fire all the hooks for the passed level. Used by `entry.log` to fire +// appropriate hooks for a log entry. +func (hooks levelHooks) Fire(level Level, entry *Entry) error { + for _, hook := range hooks[level] { + if err := hook.Fire(entry); err != nil { + return err + } + } + + return nil +} diff --git a/vendor/github.com/Sirupsen/logrus/json_formatter.go b/vendor/github.com/Sirupsen/logrus/json_formatter.go new file mode 100644 index 0000000..b09227c --- /dev/null +++ b/vendor/github.com/Sirupsen/logrus/json_formatter.go @@ -0,0 +1,26 @@ +package logrus + +import ( + "encoding/json" + "fmt" + "time" +) + +type JSONFormatter struct{} + +func (f *JSONFormatter) Format(entry *Entry) ([]byte, error) { + data := make(Fields, len(entry.Data)+3) + for k, v := range entry.Data { + data[k] = v + } + prefixFieldClashes(data) + data["time"] = entry.Time.Format(time.RFC3339) + data["msg"] = entry.Message + data["level"] = entry.Level.String() + + serialized, err := json.Marshal(data) + if err != nil { + return nil, fmt.Errorf("Failed to marshal fields to JSON, %v", err) + } + return append(serialized, '\n'), nil +} diff --git a/vendor/github.com/Sirupsen/logrus/logger.go b/vendor/github.com/Sirupsen/logrus/logger.go new file mode 100644 index 0000000..b392e54 --- /dev/null +++ b/vendor/github.com/Sirupsen/logrus/logger.go @@ -0,0 +1,161 @@ +package logrus + +import ( + "io" + "os" + "sync" +) + +type Logger struct { + // The logs are `io.Copy`'d to this in a mutex. It's common to set this to a + // file, or leave it default which is `os.Stdout`. You can also set this to + // something more adventorous, such as logging to Kafka. + Out io.Writer + // Hooks for the logger instance. These allow firing events based on logging + // levels and log entries. For example, to send errors to an error tracking + // service, log to StatsD or dump the core on fatal errors. + Hooks levelHooks + // All log entries pass through the formatter before logged to Out. The + // included formatters are `TextFormatter` and `JSONFormatter` for which + // TextFormatter is the default. In development (when a TTY is attached) it + // logs with colors, but to a file it wouldn't. You can easily implement your + // own that implements the `Formatter` interface, see the `README` or included + // formatters for examples. + Formatter Formatter + // The logging level the logger should log at. This is typically (and defaults + // to) `logrus.Info`, which allows Info(), Warn(), Error() and Fatal() to be + // logged. `logrus.Debug` is useful in + Level Level + // Used to sync writing to the log. + mu sync.Mutex +} + +// Creates a new logger. Configuration should be set by changing `Formatter`, +// `Out` and `Hooks` directly on the default logger instance. You can also just +// instantiate your own: +// +// var log = &Logger{ +// Out: os.Stderr, +// Formatter: new(JSONFormatter), +// Hooks: make(levelHooks), +// Level: logrus.DebugLevel, +// } +// +// It's recommended to make this a global instance called `log`. +func New() *Logger { + return &Logger{ + Out: os.Stdout, + Formatter: new(TextFormatter), + Hooks: make(levelHooks), + Level: InfoLevel, + } +} + +// Adds a field to the log entry, note that you it doesn't log until you call +// Debug, Print, Info, Warn, Fatal or Panic. It only creates a log entry. +// Ff you want multiple fields, use `WithFields`. +func (logger *Logger) WithField(key string, value interface{}) *Entry { + return NewEntry(logger).WithField(key, value) +} + +// Adds a struct of fields to the log entry. All it does is call `WithField` for +// each `Field`. +func (logger *Logger) WithFields(fields Fields) *Entry { + return NewEntry(logger).WithFields(fields) +} + +func (logger *Logger) Debugf(format string, args ...interface{}) { + NewEntry(logger).Debugf(format, args...) +} + +func (logger *Logger) Infof(format string, args ...interface{}) { + NewEntry(logger).Infof(format, args...) +} + +func (logger *Logger) Printf(format string, args ...interface{}) { + NewEntry(logger).Printf(format, args...) +} + +func (logger *Logger) Warnf(format string, args ...interface{}) { + NewEntry(logger).Warnf(format, args...) +} + +func (logger *Logger) Warningf(format string, args ...interface{}) { + NewEntry(logger).Warnf(format, args...) +} + +func (logger *Logger) Errorf(format string, args ...interface{}) { + NewEntry(logger).Errorf(format, args...) +} + +func (logger *Logger) Fatalf(format string, args ...interface{}) { + NewEntry(logger).Fatalf(format, args...) +} + +func (logger *Logger) Panicf(format string, args ...interface{}) { + NewEntry(logger).Panicf(format, args...) +} + +func (logger *Logger) Debug(args ...interface{}) { + NewEntry(logger).Debug(args...) +} + +func (logger *Logger) Info(args ...interface{}) { + NewEntry(logger).Info(args...) +} + +func (logger *Logger) Print(args ...interface{}) { + NewEntry(logger).Info(args...) +} + +func (logger *Logger) Warn(args ...interface{}) { + NewEntry(logger).Warn(args...) +} + +func (logger *Logger) Warning(args ...interface{}) { + NewEntry(logger).Warn(args...) +} + +func (logger *Logger) Error(args ...interface{}) { + NewEntry(logger).Error(args...) +} + +func (logger *Logger) Fatal(args ...interface{}) { + NewEntry(logger).Fatal(args...) +} + +func (logger *Logger) Panic(args ...interface{}) { + NewEntry(logger).Panic(args...) +} + +func (logger *Logger) Debugln(args ...interface{}) { + NewEntry(logger).Debugln(args...) +} + +func (logger *Logger) Infoln(args ...interface{}) { + NewEntry(logger).Infoln(args...) +} + +func (logger *Logger) Println(args ...interface{}) { + NewEntry(logger).Println(args...) +} + +func (logger *Logger) Warnln(args ...interface{}) { + NewEntry(logger).Warnln(args...) +} + +func (logger *Logger) Warningln(args ...interface{}) { + NewEntry(logger).Warnln(args...) +} + +func (logger *Logger) Errorln(args ...interface{}) { + NewEntry(logger).Errorln(args...) +} + +func (logger *Logger) Fatalln(args ...interface{}) { + NewEntry(logger).Fatalln(args...) +} + +func (logger *Logger) Panicln(args ...interface{}) { + NewEntry(logger).Panicln(args...) +} diff --git a/vendor/github.com/Sirupsen/logrus/logrus.go b/vendor/github.com/Sirupsen/logrus/logrus.go new file mode 100644 index 0000000..43ee12e --- /dev/null +++ b/vendor/github.com/Sirupsen/logrus/logrus.go @@ -0,0 +1,94 @@ +package logrus + +import ( + "fmt" + "log" +) + +// Fields type, used to pass to `WithFields`. +type Fields map[string]interface{} + +// Level type +type Level uint8 + +// Convert the Level to a string. E.g. PanicLevel becomes "panic". +func (level Level) String() string { + switch level { + case DebugLevel: + return "debug" + case InfoLevel: + return "info" + case WarnLevel: + return "warning" + case ErrorLevel: + return "error" + case FatalLevel: + return "fatal" + case PanicLevel: + return "panic" + } + + return "unknown" +} + +// ParseLevel takes a string level and returns the Logrus log level constant. +func ParseLevel(lvl string) (Level, error) { + switch lvl { + case "panic": + return PanicLevel, nil + case "fatal": + return FatalLevel, nil + case "error": + return ErrorLevel, nil + case "warn", "warning": + return WarnLevel, nil + case "info": + return InfoLevel, nil + case "debug": + return DebugLevel, nil + } + + var l Level + return l, fmt.Errorf("not a valid logrus Level: %q", lvl) +} + +// These are the different logging levels. You can set the logging level to log +// on your instance of logger, obtained with `logrus.New()`. +const ( + // PanicLevel level, highest level of severity. Logs and then calls panic with the + // message passed to Debug, Info, ... + PanicLevel Level = iota + // FatalLevel level. Logs and then calls `os.Exit(1)`. It will exit even if the + // logging level is set to Panic. + FatalLevel + // ErrorLevel level. Logs. Used for errors that should definitely be noted. + // Commonly used for hooks to send errors to an error tracking service. + ErrorLevel + // WarnLevel level. Non-critical entries that deserve eyes. + WarnLevel + // InfoLevel level. General operational entries about what's going on inside the + // application. + InfoLevel + // DebugLevel level. Usually only enabled when debugging. Very verbose logging. + DebugLevel +) + +// Won't compile if StdLogger can't be realized by a log.Logger +var _ StdLogger = &log.Logger{} + +// StdLogger is what your logrus-enabled library should take, that way +// it'll accept a stdlib logger and a logrus logger. There's no standard +// interface, this is the closest we get, unfortunately. +type StdLogger interface { + Print(...interface{}) + Printf(string, ...interface{}) + Println(...interface{}) + + Fatal(...interface{}) + Fatalf(string, ...interface{}) + Fatalln(...interface{}) + + Panic(...interface{}) + Panicf(string, ...interface{}) + Panicln(...interface{}) +} diff --git a/vendor/github.com/Sirupsen/logrus/terminal_darwin.go b/vendor/github.com/Sirupsen/logrus/terminal_darwin.go new file mode 100644 index 0000000..8fe02a4 --- /dev/null +++ b/vendor/github.com/Sirupsen/logrus/terminal_darwin.go @@ -0,0 +1,12 @@ +// Based on ssh/terminal: +// Copyright 2013 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package logrus + +import "syscall" + +const ioctlReadTermios = syscall.TIOCGETA + +type Termios syscall.Termios diff --git a/vendor/github.com/Sirupsen/logrus/terminal_freebsd.go b/vendor/github.com/Sirupsen/logrus/terminal_freebsd.go new file mode 100644 index 0000000..0428ee5 --- /dev/null +++ b/vendor/github.com/Sirupsen/logrus/terminal_freebsd.go @@ -0,0 +1,20 @@ +/* + Go 1.2 doesn't include Termios for FreeBSD. This should be added in 1.3 and this could be merged with terminal_darwin. +*/ +package logrus + +import ( + "syscall" +) + +const ioctlReadTermios = syscall.TIOCGETA + +type Termios struct { + Iflag uint32 + Oflag uint32 + Cflag uint32 + Lflag uint32 + Cc [20]uint8 + Ispeed uint32 + Ospeed uint32 +} diff --git a/vendor/github.com/Sirupsen/logrus/terminal_linux.go b/vendor/github.com/Sirupsen/logrus/terminal_linux.go new file mode 100644 index 0000000..a2c0b40 --- /dev/null +++ b/vendor/github.com/Sirupsen/logrus/terminal_linux.go @@ -0,0 +1,12 @@ +// Based on ssh/terminal: +// Copyright 2013 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package logrus + +import "syscall" + +const ioctlReadTermios = syscall.TCGETS + +type Termios syscall.Termios diff --git a/vendor/github.com/Sirupsen/logrus/terminal_notwindows.go b/vendor/github.com/Sirupsen/logrus/terminal_notwindows.go new file mode 100644 index 0000000..276447b --- /dev/null +++ b/vendor/github.com/Sirupsen/logrus/terminal_notwindows.go @@ -0,0 +1,21 @@ +// Based on ssh/terminal: +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build linux,!appengine darwin freebsd + +package logrus + +import ( + "syscall" + "unsafe" +) + +// IsTerminal returns true if the given file descriptor is a terminal. +func IsTerminal() bool { + fd := syscall.Stdout + var termios Termios + _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), ioctlReadTermios, uintptr(unsafe.Pointer(&termios)), 0, 0, 0) + return err == 0 +} diff --git a/vendor/github.com/Sirupsen/logrus/terminal_windows.go b/vendor/github.com/Sirupsen/logrus/terminal_windows.go new file mode 100644 index 0000000..2e09f6f --- /dev/null +++ b/vendor/github.com/Sirupsen/logrus/terminal_windows.go @@ -0,0 +1,27 @@ +// Based on ssh/terminal: +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build windows + +package logrus + +import ( + "syscall" + "unsafe" +) + +var kernel32 = syscall.NewLazyDLL("kernel32.dll") + +var ( + procGetConsoleMode = kernel32.NewProc("GetConsoleMode") +) + +// IsTerminal returns true if the given file descriptor is a terminal. +func IsTerminal() bool { + fd := syscall.Stdout + var st uint32 + r, _, e := syscall.Syscall(procGetConsoleMode.Addr(), 2, uintptr(fd), uintptr(unsafe.Pointer(&st)), 0) + return r != 0 && e == 0 +} diff --git a/vendor/github.com/Sirupsen/logrus/text_formatter.go b/vendor/github.com/Sirupsen/logrus/text_formatter.go new file mode 100644 index 0000000..78e7889 --- /dev/null +++ b/vendor/github.com/Sirupsen/logrus/text_formatter.go @@ -0,0 +1,124 @@ +package logrus + +import ( + "bytes" + "fmt" + "regexp" + "sort" + "strings" + "time" +) + +const ( + nocolor = 0 + red = 31 + green = 32 + yellow = 33 + blue = 34 +) + +var ( + baseTimestamp time.Time + isTerminal bool + noQuoteNeeded *regexp.Regexp +) + +func init() { + baseTimestamp = time.Now() + isTerminal = IsTerminal() +} + +func miniTS() int { + return int(time.Since(baseTimestamp) / time.Second) +} + +type TextFormatter struct { + // Set to true to bypass checking for a TTY before outputting colors. + ForceColors bool + DisableColors bool + // Set to true to disable timestamp logging (useful when the output + // is redirected to a logging system already adding a timestamp) + DisableTimestamp bool +} + +func (f *TextFormatter) Format(entry *Entry) ([]byte, error) { + + var keys []string + for k := range entry.Data { + keys = append(keys, k) + } + sort.Strings(keys) + + b := &bytes.Buffer{} + + prefixFieldClashes(entry.Data) + + isColored := (f.ForceColors || isTerminal) && !f.DisableColors + + if isColored { + printColored(b, entry, keys) + } else { + if !f.DisableTimestamp { + f.appendKeyValue(b, "time", entry.Time.Format(time.RFC3339)) + } + f.appendKeyValue(b, "level", entry.Level.String()) + f.appendKeyValue(b, "msg", entry.Message) + for _, key := range keys { + f.appendKeyValue(b, key, entry.Data[key]) + } + } + + b.WriteByte('\n') + return b.Bytes(), nil +} + +func printColored(b *bytes.Buffer, entry *Entry, keys []string) { + var levelColor int + switch entry.Level { + case WarnLevel: + levelColor = yellow + case ErrorLevel, FatalLevel, PanicLevel: + levelColor = red + default: + levelColor = blue + } + + levelText := strings.ToUpper(entry.Level.String())[0:4] + + fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m[%04d] %-44s ", levelColor, levelText, miniTS(), entry.Message) + for _, k := range keys { + v := entry.Data[k] + fmt.Fprintf(b, " \x1b[%dm%s\x1b[0m=%v", levelColor, k, v) + } +} + +func needsQuoting(text string) bool { + for _, ch := range text { + if !((ch >= 'a' && ch <= 'z') || + (ch >= 'A' && ch <= 'Z') || + (ch >= '0' && ch < '9') || + ch == '-' || ch == '.') { + return false + } + } + return true +} + +func (f *TextFormatter) appendKeyValue(b *bytes.Buffer, key, value interface{}) { + switch value.(type) { + case string: + if needsQuoting(value.(string)) { + fmt.Fprintf(b, "%v=%s ", key, value) + } else { + fmt.Fprintf(b, "%v=%q ", key, value) + } + case error: + if needsQuoting(value.(error).Error()) { + fmt.Fprintf(b, "%v=%s ", key, value) + } else { + fmt.Fprintf(b, "%v=%q ", key, value) + } + default: + fmt.Fprintf(b, "%v=%v ", key, value) + } +} diff --git a/vendor/github.com/docker/docker/pkg/jsonmessage/jsonmessage.go b/vendor/github.com/docker/docker/pkg/jsonmessage/jsonmessage.go new file mode 100644 index 0000000..7db1626 --- /dev/null +++ b/vendor/github.com/docker/docker/pkg/jsonmessage/jsonmessage.go @@ -0,0 +1,172 @@ +package jsonmessage + +import ( + "encoding/json" + "fmt" + "io" + "strings" + "time" + + "github.com/docker/docker/pkg/term" + "github.com/docker/docker/pkg/timeutils" + "github.com/docker/docker/pkg/units" +) + +type JSONError struct { + Code int `json:"code,omitempty"` + Message string `json:"message,omitempty"` +} + +func (e *JSONError) Error() string { + return e.Message +} + +type JSONProgress struct { + terminalFd uintptr + Current int `json:"current,omitempty"` + Total int `json:"total,omitempty"` + Start int64 `json:"start,omitempty"` +} + +func (p *JSONProgress) String() string { + var ( + width = 200 + pbBox string + numbersBox string + timeLeftBox string + ) + + ws, err := term.GetWinsize(p.terminalFd) + if err == nil { + width = int(ws.Width) + } + + if p.Current <= 0 && p.Total <= 0 { + return "" + } + current := units.HumanSize(float64(p.Current)) + if p.Total <= 0 { + return fmt.Sprintf("%8v", current) + } + total := units.HumanSize(float64(p.Total)) + percentage := int(float64(p.Current)/float64(p.Total)*100) / 2 + if percentage > 50 { + percentage = 50 + } + if width > 110 { + // this number can't be negetive gh#7136 + numSpaces := 0 + if 50-percentage > 0 { + numSpaces = 50 - percentage + } + pbBox = fmt.Sprintf("[%s>%s] ", strings.Repeat("=", percentage), strings.Repeat(" ", numSpaces)) + } + numbersBox = fmt.Sprintf("%8v/%v", current, total) + + if p.Current > 0 && p.Start > 0 && percentage < 50 { + fromStart := time.Now().UTC().Sub(time.Unix(int64(p.Start), 0)) + perEntry := fromStart / time.Duration(p.Current) + left := time.Duration(p.Total-p.Current) * perEntry + left = (left / time.Second) * time.Second + + if width > 50 { + timeLeftBox = " " + left.String() + } + } + return pbBox + numbersBox + timeLeftBox +} + +type JSONMessage struct { + Stream string `json:"stream,omitempty"` + Status string `json:"status,omitempty"` + Progress *JSONProgress `json:"progressDetail,omitempty"` + ProgressMessage string `json:"progress,omitempty"` //deprecated + ID string `json:"id,omitempty"` + From string `json:"from,omitempty"` + Time int64 `json:"time,omitempty"` + Error *JSONError `json:"errorDetail,omitempty"` + ErrorMessage string `json:"error,omitempty"` //deprecated +} + +func (jm *JSONMessage) Display(out io.Writer, isTerminal bool) error { + if jm.Error != nil { + if jm.Error.Code == 401 { + return fmt.Errorf("Authentication is required.") + } + return jm.Error + } + var endl string + if isTerminal && jm.Stream == "" && jm.Progress != nil { + // [2K = erase entire current line + fmt.Fprintf(out, "%c[2K\r", 27) + endl = "\r" + } else if jm.Progress != nil && jm.Progress.String() != "" { //disable progressbar in non-terminal + return nil + } + if jm.Time != 0 { + fmt.Fprintf(out, "%s ", time.Unix(jm.Time, 0).Format(timeutils.RFC3339NanoFixed)) + } + if jm.ID != "" { + fmt.Fprintf(out, "%s: ", jm.ID) + } + if jm.From != "" { + fmt.Fprintf(out, "(from %s) ", jm.From) + } + if jm.Progress != nil && isTerminal { + fmt.Fprintf(out, "%s %s%s", jm.Status, jm.Progress.String(), endl) + } else if jm.ProgressMessage != "" { //deprecated + fmt.Fprintf(out, "%s %s%s", jm.Status, jm.ProgressMessage, endl) + } else if jm.Stream != "" { + fmt.Fprintf(out, "%s%s", jm.Stream, endl) + } else { + fmt.Fprintf(out, "%s%s\n", jm.Status, endl) + } + return nil +} + +func DisplayJSONMessagesStream(in io.Reader, out io.Writer, terminalFd uintptr, isTerminal bool) error { + var ( + dec = json.NewDecoder(in) + ids = make(map[string]int) + diff = 0 + ) + for { + var jm JSONMessage + if err := dec.Decode(&jm); err != nil { + if err == io.EOF { + break + } + return err + } + + if jm.Progress != nil { + jm.Progress.terminalFd = terminalFd + } + if jm.ID != "" && (jm.Progress != nil || jm.ProgressMessage != "") { + line, ok := ids[jm.ID] + if !ok { + line = len(ids) + ids[jm.ID] = line + if isTerminal { + fmt.Fprintf(out, "\n") + } + diff = 0 + } else { + diff = len(ids) - line + } + if jm.ID != "" && isTerminal { + // [{diff}A = move cursor up diff rows + fmt.Fprintf(out, "%c[%dA", 27, diff) + } + } + err := jm.Display(out, isTerminal) + if jm.ID != "" && isTerminal { + // [{diff}B = move cursor down diff rows + fmt.Fprintf(out, "%c[%dB", 27, diff) + } + if err != nil { + return err + } + } + return nil +} diff --git a/vendor/github.com/docker/docker/pkg/term/tc_linux_cgo.go b/vendor/github.com/docker/docker/pkg/term/tc_linux_cgo.go new file mode 100644 index 0000000..d47cf59 --- /dev/null +++ b/vendor/github.com/docker/docker/pkg/term/tc_linux_cgo.go @@ -0,0 +1,48 @@ +// +build linux,cgo + +package term + +import ( + "syscall" + "unsafe" +) + +// #include +import "C" + +type Termios syscall.Termios + +// MakeRaw put the terminal connected to the given file descriptor into raw +// mode and returns the previous state of the terminal so that it can be +// restored. +func MakeRaw(fd uintptr) (*State, error) { + var oldState State + if err := tcget(fd, &oldState.termios); err != 0 { + return nil, err + } + + newState := oldState.termios + + C.cfmakeraw((*C.struct_termios)(unsafe.Pointer(&newState))) + newState.Oflag = newState.Oflag | C.OPOST + if err := tcset(fd, &newState); err != 0 { + return nil, err + } + return &oldState, nil +} + +func tcget(fd uintptr, p *Termios) syscall.Errno { + ret, err := C.tcgetattr(C.int(fd), (*C.struct_termios)(unsafe.Pointer(p))) + if ret != 0 { + return err.(syscall.Errno) + } + return 0 +} + +func tcset(fd uintptr, p *Termios) syscall.Errno { + ret, err := C.tcsetattr(C.int(fd), C.TCSANOW, (*C.struct_termios)(unsafe.Pointer(p))) + if ret != 0 { + return err.(syscall.Errno) + } + return 0 +} diff --git a/vendor/github.com/docker/docker/pkg/term/tc_other.go b/vendor/github.com/docker/docker/pkg/term/tc_other.go new file mode 100644 index 0000000..266039b --- /dev/null +++ b/vendor/github.com/docker/docker/pkg/term/tc_other.go @@ -0,0 +1,19 @@ +// +build !windows +// +build !linux !cgo + +package term + +import ( + "syscall" + "unsafe" +) + +func tcget(fd uintptr, p *Termios) syscall.Errno { + _, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, uintptr(getTermios), uintptr(unsafe.Pointer(p))) + return err +} + +func tcset(fd uintptr, p *Termios) syscall.Errno { + _, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, setTermios, uintptr(unsafe.Pointer(p))) + return err +} diff --git a/vendor/github.com/docker/docker/pkg/term/term.go b/vendor/github.com/docker/docker/pkg/term/term.go new file mode 100644 index 0000000..b945a3d --- /dev/null +++ b/vendor/github.com/docker/docker/pkg/term/term.go @@ -0,0 +1,118 @@ +// +build !windows + +package term + +import ( + "errors" + "io" + "os" + "os/signal" + "syscall" + "unsafe" +) + +var ( + ErrInvalidState = errors.New("Invalid terminal state") +) + +type State struct { + termios Termios +} + +type Winsize struct { + Height uint16 + Width uint16 + x uint16 + y uint16 +} + +func StdStreams() (stdIn io.ReadCloser, stdOut, stdErr io.Writer) { + return os.Stdin, os.Stdout, os.Stderr +} + +func GetFdInfo(in interface{}) (uintptr, bool) { + var inFd uintptr + var isTerminalIn bool + if file, ok := in.(*os.File); ok { + inFd = file.Fd() + isTerminalIn = IsTerminal(inFd) + } + return inFd, isTerminalIn +} + +func GetWinsize(fd uintptr) (*Winsize, error) { + ws := &Winsize{} + _, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, uintptr(syscall.TIOCGWINSZ), uintptr(unsafe.Pointer(ws))) + // Skipp errno = 0 + if err == 0 { + return ws, nil + } + return ws, err +} + +func SetWinsize(fd uintptr, ws *Winsize) error { + _, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, uintptr(syscall.TIOCSWINSZ), uintptr(unsafe.Pointer(ws))) + // Skipp errno = 0 + if err == 0 { + return nil + } + return err +} + +// IsTerminal returns true if the given file descriptor is a terminal. +func IsTerminal(fd uintptr) bool { + var termios Termios + return tcget(fd, &termios) == 0 +} + +// Restore restores the terminal connected to the given file descriptor to a +// previous state. +func RestoreTerminal(fd uintptr, state *State) error { + if state == nil { + return ErrInvalidState + } + if err := tcset(fd, &state.termios); err != 0 { + return err + } + return nil +} + +func SaveState(fd uintptr) (*State, error) { + var oldState State + if err := tcget(fd, &oldState.termios); err != 0 { + return nil, err + } + + return &oldState, nil +} + +func DisableEcho(fd uintptr, state *State) error { + newState := state.termios + newState.Lflag &^= syscall.ECHO + + if err := tcset(fd, &newState); err != 0 { + return err + } + handleInterrupt(fd, state) + return nil +} + +func SetRawTerminal(fd uintptr) (*State, error) { + oldState, err := MakeRaw(fd) + if err != nil { + return nil, err + } + handleInterrupt(fd, oldState) + return oldState, err +} + +func handleInterrupt(fd uintptr, state *State) { + sigchan := make(chan os.Signal, 1) + signal.Notify(sigchan, os.Interrupt) + + go func() { + _ = <-sigchan + RestoreTerminal(fd, state) + os.Exit(0) + }() +} diff --git a/vendor/github.com/docker/docker/pkg/term/term_windows.go b/vendor/github.com/docker/docker/pkg/term/term_windows.go new file mode 100644 index 0000000..f7fa1b3 --- /dev/null +++ b/vendor/github.com/docker/docker/pkg/term/term_windows.go @@ -0,0 +1,139 @@ +// +build windows + +package term + +import ( + "io" + "os" + + "github.com/Sirupsen/logrus" + "github.com/docker/docker/pkg/term/winconsole" +) + +// State holds the console mode for the terminal. +type State struct { + mode uint32 +} + +// Winsize is used for window size. +type Winsize struct { + Height uint16 + Width uint16 + x uint16 + y uint16 +} + +func StdStreams() (stdIn io.ReadCloser, stdOut, stdErr io.Writer) { + switch { + case os.Getenv("ConEmuANSI") == "ON": + // The ConEmu shell emulates ANSI well by default. + return os.Stdin, os.Stdout, os.Stderr + case os.Getenv("MSYSTEM") != "": + // MSYS (mingw) does not emulate ANSI well. + return winconsole.WinConsoleStreams() + default: + return winconsole.WinConsoleStreams() + } +} + +// GetFdInfo returns file descriptor and bool indicating whether the file is a terminal. +func GetFdInfo(in interface{}) (uintptr, bool) { + return winconsole.GetHandleInfo(in) +} + +// GetWinsize retrieves the window size of the terminal connected to the passed file descriptor. +func GetWinsize(fd uintptr) (*Winsize, error) { + info, err := winconsole.GetConsoleScreenBufferInfo(fd) + if err != nil { + return nil, err + } + + // TODO(azlinux): Set the pixel width / height of the console (currently unused by any caller) + return &Winsize{ + Width: uint16(info.Window.Right - info.Window.Left + 1), + Height: uint16(info.Window.Bottom - info.Window.Top + 1), + x: 0, + y: 0}, nil +} + +// SetWinsize sets the size of the given terminal connected to the passed file descriptor. +func SetWinsize(fd uintptr, ws *Winsize) error { + // TODO(azlinux): Implement SetWinsize + logrus.Debugf("[windows] SetWinsize: WARNING -- Unsupported method invoked") + return nil +} + +// IsTerminal returns true if the given file descriptor is a terminal. +func IsTerminal(fd uintptr) bool { + return winconsole.IsConsole(fd) +} + +// RestoreTerminal restores the terminal connected to the given file descriptor to a +// previous state. +func RestoreTerminal(fd uintptr, state *State) error { + return winconsole.SetConsoleMode(fd, state.mode) +} + +// SaveState saves the state of the terminal connected to the given file descriptor. +func SaveState(fd uintptr) (*State, error) { + mode, e := winconsole.GetConsoleMode(fd) + if e != nil { + return nil, e + } + return &State{mode}, nil +} + +// DisableEcho disables echo for the terminal connected to the given file descriptor. +// -- See http://msdn.microsoft.com/en-us/library/windows/desktop/ms683462(v=vs.85).aspx +func DisableEcho(fd uintptr, state *State) error { + mode := state.mode + mode &^= winconsole.ENABLE_ECHO_INPUT + mode |= winconsole.ENABLE_PROCESSED_INPUT | winconsole.ENABLE_LINE_INPUT + // TODO(azlinux): Core code registers a goroutine to catch os.Interrupt and reset the terminal state. + return winconsole.SetConsoleMode(fd, mode) +} + +// SetRawTerminal puts the terminal connected to the given file descriptor into raw +// mode and returns the previous state of the terminal so that it can be +// restored. +func SetRawTerminal(fd uintptr) (*State, error) { + state, err := MakeRaw(fd) + if err != nil { + return nil, err + } + // TODO(azlinux): Core code registers a goroutine to catch os.Interrupt and reset the terminal state. + return state, err +} + +// MakeRaw puts the terminal connected to the given file descriptor into raw +// mode and returns the previous state of the terminal so that it can be +// restored. +func MakeRaw(fd uintptr) (*State, error) { + state, err := SaveState(fd) + if err != nil { + return nil, err + } + + // See + // -- https://msdn.microsoft.com/en-us/library/windows/desktop/ms686033(v=vs.85).aspx + // -- https://msdn.microsoft.com/en-us/library/windows/desktop/ms683462(v=vs.85).aspx + mode := state.mode + + // Disable these modes + mode &^= winconsole.ENABLE_ECHO_INPUT + mode &^= winconsole.ENABLE_LINE_INPUT + mode &^= winconsole.ENABLE_MOUSE_INPUT + mode &^= winconsole.ENABLE_WINDOW_INPUT + mode &^= winconsole.ENABLE_PROCESSED_INPUT + + // Enable these modes + mode |= winconsole.ENABLE_EXTENDED_FLAGS + mode |= winconsole.ENABLE_INSERT_MODE + mode |= winconsole.ENABLE_QUICK_EDIT_MODE + + err = winconsole.SetConsoleMode(fd, mode) + if err != nil { + return nil, err + } + return state, nil +} diff --git a/vendor/github.com/docker/docker/pkg/term/termios_darwin.go b/vendor/github.com/docker/docker/pkg/term/termios_darwin.go new file mode 100644 index 0000000..11cd70d --- /dev/null +++ b/vendor/github.com/docker/docker/pkg/term/termios_darwin.go @@ -0,0 +1,65 @@ +package term + +import ( + "syscall" + "unsafe" +) + +const ( + getTermios = syscall.TIOCGETA + setTermios = syscall.TIOCSETA + + IGNBRK = syscall.IGNBRK + PARMRK = syscall.PARMRK + INLCR = syscall.INLCR + IGNCR = syscall.IGNCR + ECHONL = syscall.ECHONL + CSIZE = syscall.CSIZE + ICRNL = syscall.ICRNL + ISTRIP = syscall.ISTRIP + PARENB = syscall.PARENB + ECHO = syscall.ECHO + ICANON = syscall.ICANON + ISIG = syscall.ISIG + IXON = syscall.IXON + BRKINT = syscall.BRKINT + INPCK = syscall.INPCK + OPOST = syscall.OPOST + CS8 = syscall.CS8 + IEXTEN = syscall.IEXTEN +) + +type Termios struct { + Iflag uint64 + Oflag uint64 + Cflag uint64 + Lflag uint64 + Cc [20]byte + Ispeed uint64 + Ospeed uint64 +} + +// MakeRaw put the terminal connected to the given file descriptor into raw +// mode and returns the previous state of the terminal so that it can be +// restored. +func MakeRaw(fd uintptr) (*State, error) { + var oldState State + if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, uintptr(getTermios), uintptr(unsafe.Pointer(&oldState.termios))); err != 0 { + return nil, err + } + + newState := oldState.termios + newState.Iflag &^= (IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON) + newState.Oflag &^= OPOST + newState.Lflag &^= (ECHO | ECHONL | ICANON | ISIG | IEXTEN) + newState.Cflag &^= (CSIZE | PARENB) + newState.Cflag |= CS8 + newState.Cc[syscall.VMIN] = 1 + newState.Cc[syscall.VTIME] = 0 + + if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, uintptr(setTermios), uintptr(unsafe.Pointer(&newState))); err != 0 { + return nil, err + } + + return &oldState, nil +} diff --git a/vendor/github.com/docker/docker/pkg/term/termios_freebsd.go b/vendor/github.com/docker/docker/pkg/term/termios_freebsd.go new file mode 100644 index 0000000..ed36595 --- /dev/null +++ b/vendor/github.com/docker/docker/pkg/term/termios_freebsd.go @@ -0,0 +1,65 @@ +package term + +import ( + "syscall" + "unsafe" +) + +const ( + getTermios = syscall.TIOCGETA + setTermios = syscall.TIOCSETA + + IGNBRK = syscall.IGNBRK + PARMRK = syscall.PARMRK + INLCR = syscall.INLCR + IGNCR = syscall.IGNCR + ECHONL = syscall.ECHONL + CSIZE = syscall.CSIZE + ICRNL = syscall.ICRNL + ISTRIP = syscall.ISTRIP + PARENB = syscall.PARENB + ECHO = syscall.ECHO + ICANON = syscall.ICANON + ISIG = syscall.ISIG + IXON = syscall.IXON + BRKINT = syscall.BRKINT + INPCK = syscall.INPCK + OPOST = syscall.OPOST + CS8 = syscall.CS8 + IEXTEN = syscall.IEXTEN +) + +type Termios struct { + Iflag uint32 + Oflag uint32 + Cflag uint32 + Lflag uint32 + Cc [20]byte + Ispeed uint32 + Ospeed uint32 +} + +// MakeRaw put the terminal connected to the given file descriptor into raw +// mode and returns the previous state of the terminal so that it can be +// restored. +func MakeRaw(fd uintptr) (*State, error) { + var oldState State + if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, uintptr(getTermios), uintptr(unsafe.Pointer(&oldState.termios))); err != 0 { + return nil, err + } + + newState := oldState.termios + newState.Iflag &^= (IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON) + newState.Oflag &^= OPOST + newState.Lflag &^= (ECHO | ECHONL | ICANON | ISIG | IEXTEN) + newState.Cflag &^= (CSIZE | PARENB) + newState.Cflag |= CS8 + newState.Cc[syscall.VMIN] = 1 + newState.Cc[syscall.VTIME] = 0 + + if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, uintptr(setTermios), uintptr(unsafe.Pointer(&newState))); err != 0 { + return nil, err + } + + return &oldState, nil +} diff --git a/vendor/github.com/docker/docker/pkg/term/termios_linux.go b/vendor/github.com/docker/docker/pkg/term/termios_linux.go new file mode 100644 index 0000000..024187f --- /dev/null +++ b/vendor/github.com/docker/docker/pkg/term/termios_linux.go @@ -0,0 +1,46 @@ +// +build !cgo + +package term + +import ( + "syscall" + "unsafe" +) + +const ( + getTermios = syscall.TCGETS + setTermios = syscall.TCSETS +) + +type Termios struct { + Iflag uint32 + Oflag uint32 + Cflag uint32 + Lflag uint32 + Cc [20]byte + Ispeed uint32 + Ospeed uint32 +} + +// MakeRaw put the terminal connected to the given file descriptor into raw +// mode and returns the previous state of the terminal so that it can be +// restored. +func MakeRaw(fd uintptr) (*State, error) { + var oldState State + if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, getTermios, uintptr(unsafe.Pointer(&oldState.termios))); err != 0 { + return nil, err + } + + newState := oldState.termios + + newState.Iflag &^= (syscall.IGNBRK | syscall.BRKINT | syscall.PARMRK | syscall.ISTRIP | syscall.INLCR | syscall.IGNCR | syscall.ICRNL | syscall.IXON) + newState.Oflag &^= syscall.OPOST + newState.Lflag &^= (syscall.ECHO | syscall.ECHONL | syscall.ICANON | syscall.ISIG | syscall.IEXTEN) + newState.Cflag &^= (syscall.CSIZE | syscall.PARENB) + newState.Cflag |= syscall.CS8 + + if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, setTermios, uintptr(unsafe.Pointer(&newState))); err != 0 { + return nil, err + } + return &oldState, nil +} diff --git a/vendor/github.com/docker/docker/pkg/term/winconsole/console_windows.go b/vendor/github.com/docker/docker/pkg/term/winconsole/console_windows.go new file mode 100644 index 0000000..ce40a93 --- /dev/null +++ b/vendor/github.com/docker/docker/pkg/term/winconsole/console_windows.go @@ -0,0 +1,1053 @@ +// +build windows + +package winconsole + +import ( + "bytes" + "fmt" + "io" + "os" + "strconv" + "strings" + "sync" + "syscall" + "unsafe" + + "github.com/Sirupsen/logrus" +) + +const ( + // Consts for Get/SetConsoleMode function + // -- See https://msdn.microsoft.com/en-us/library/windows/desktop/ms686033(v=vs.85).aspx + ENABLE_PROCESSED_INPUT = 0x0001 + ENABLE_LINE_INPUT = 0x0002 + ENABLE_ECHO_INPUT = 0x0004 + ENABLE_WINDOW_INPUT = 0x0008 + ENABLE_MOUSE_INPUT = 0x0010 + ENABLE_INSERT_MODE = 0x0020 + ENABLE_QUICK_EDIT_MODE = 0x0040 + ENABLE_EXTENDED_FLAGS = 0x0080 + + // If parameter is a screen buffer handle, additional values + ENABLE_PROCESSED_OUTPUT = 0x0001 + ENABLE_WRAP_AT_EOL_OUTPUT = 0x0002 + + //http://msdn.microsoft.com/en-us/library/windows/desktop/ms682088(v=vs.85).aspx#_win32_character_attributes + FOREGROUND_BLUE = 1 + FOREGROUND_GREEN = 2 + FOREGROUND_RED = 4 + FOREGROUND_INTENSITY = 8 + FOREGROUND_MASK_SET = 0x000F + FOREGROUND_MASK_UNSET = 0xFFF0 + + BACKGROUND_BLUE = 16 + BACKGROUND_GREEN = 32 + BACKGROUND_RED = 64 + BACKGROUND_INTENSITY = 128 + BACKGROUND_MASK_SET = 0x00F0 + BACKGROUND_MASK_UNSET = 0xFF0F + + COMMON_LVB_REVERSE_VIDEO = 0x4000 + COMMON_LVB_UNDERSCORE = 0x8000 + + // http://man7.org/linux/man-pages/man4/console_codes.4.html + // ECMA-48 Set Graphics Rendition + ANSI_ATTR_RESET = 0 + ANSI_ATTR_BOLD = 1 + ANSI_ATTR_DIM = 2 + ANSI_ATTR_UNDERLINE = 4 + ANSI_ATTR_BLINK = 5 + ANSI_ATTR_REVERSE = 7 + ANSI_ATTR_INVISIBLE = 8 + + ANSI_ATTR_UNDERLINE_OFF = 24 + ANSI_ATTR_BLINK_OFF = 25 + ANSI_ATTR_REVERSE_OFF = 27 + ANSI_ATTR_INVISIBLE_OFF = 8 + + ANSI_FOREGROUND_BLACK = 30 + ANSI_FOREGROUND_RED = 31 + ANSI_FOREGROUND_GREEN = 32 + ANSI_FOREGROUND_YELLOW = 33 + ANSI_FOREGROUND_BLUE = 34 + ANSI_FOREGROUND_MAGENTA = 35 + ANSI_FOREGROUND_CYAN = 36 + ANSI_FOREGROUND_WHITE = 37 + ANSI_FOREGROUND_DEFAULT = 39 + + ANSI_BACKGROUND_BLACK = 40 + ANSI_BACKGROUND_RED = 41 + ANSI_BACKGROUND_GREEN = 42 + ANSI_BACKGROUND_YELLOW = 43 + ANSI_BACKGROUND_BLUE = 44 + ANSI_BACKGROUND_MAGENTA = 45 + ANSI_BACKGROUND_CYAN = 46 + ANSI_BACKGROUND_WHITE = 47 + ANSI_BACKGROUND_DEFAULT = 49 + + ANSI_MAX_CMD_LENGTH = 256 + + MAX_INPUT_EVENTS = 128 + MAX_INPUT_BUFFER = 1024 + DEFAULT_WIDTH = 80 + DEFAULT_HEIGHT = 24 +) + +// http://msdn.microsoft.com/en-us/library/windows/desktop/dd375731(v=vs.85).aspx +const ( + VK_PRIOR = 0x21 // PAGE UP key + VK_NEXT = 0x22 // PAGE DOWN key + VK_END = 0x23 // END key + VK_HOME = 0x24 // HOME key + VK_LEFT = 0x25 // LEFT ARROW key + VK_UP = 0x26 // UP ARROW key + VK_RIGHT = 0x27 // RIGHT ARROW key + VK_DOWN = 0x28 // DOWN ARROW key + VK_SELECT = 0x29 // SELECT key + VK_PRINT = 0x2A // PRINT key + VK_EXECUTE = 0x2B // EXECUTE key + VK_SNAPSHOT = 0x2C // PRINT SCREEN key + VK_INSERT = 0x2D // INS key + VK_DELETE = 0x2E // DEL key + VK_HELP = 0x2F // HELP key + VK_F1 = 0x70 // F1 key + VK_F2 = 0x71 // F2 key + VK_F3 = 0x72 // F3 key + VK_F4 = 0x73 // F4 key + VK_F5 = 0x74 // F5 key + VK_F6 = 0x75 // F6 key + VK_F7 = 0x76 // F7 key + VK_F8 = 0x77 // F8 key + VK_F9 = 0x78 // F9 key + VK_F10 = 0x79 // F10 key + VK_F11 = 0x7A // F11 key + VK_F12 = 0x7B // F12 key +) + +var kernel32DLL = syscall.NewLazyDLL("kernel32.dll") + +var ( + setConsoleModeProc = kernel32DLL.NewProc("SetConsoleMode") + getConsoleScreenBufferInfoProc = kernel32DLL.NewProc("GetConsoleScreenBufferInfo") + setConsoleCursorPositionProc = kernel32DLL.NewProc("SetConsoleCursorPosition") + setConsoleTextAttributeProc = kernel32DLL.NewProc("SetConsoleTextAttribute") + fillConsoleOutputCharacterProc = kernel32DLL.NewProc("FillConsoleOutputCharacterW") + writeConsoleOutputProc = kernel32DLL.NewProc("WriteConsoleOutputW") + readConsoleInputProc = kernel32DLL.NewProc("ReadConsoleInputW") + getNumberOfConsoleInputEventsProc = kernel32DLL.NewProc("GetNumberOfConsoleInputEvents") + getConsoleCursorInfoProc = kernel32DLL.NewProc("GetConsoleCursorInfo") + setConsoleCursorInfoProc = kernel32DLL.NewProc("SetConsoleCursorInfo") + setConsoleWindowInfoProc = kernel32DLL.NewProc("SetConsoleWindowInfo") + setConsoleScreenBufferSizeProc = kernel32DLL.NewProc("SetConsoleScreenBufferSize") +) + +// types for calling various windows API +// see http://msdn.microsoft.com/en-us/library/windows/desktop/ms682093(v=vs.85).aspx +type ( + SHORT int16 + BOOL int32 + WORD uint16 + WCHAR uint16 + DWORD uint32 + + SMALL_RECT struct { + Left SHORT + Top SHORT + Right SHORT + Bottom SHORT + } + + COORD struct { + X SHORT + Y SHORT + } + + CONSOLE_SCREEN_BUFFER_INFO struct { + Size COORD + CursorPosition COORD + Attributes WORD + Window SMALL_RECT + MaximumWindowSize COORD + } + + CONSOLE_CURSOR_INFO struct { + Size DWORD + Visible BOOL + } + + // http://msdn.microsoft.com/en-us/library/windows/desktop/ms684166(v=vs.85).aspx + KEY_EVENT_RECORD struct { + KeyDown BOOL + RepeatCount WORD + VirtualKeyCode WORD + VirtualScanCode WORD + UnicodeChar WCHAR + ControlKeyState DWORD + } + + INPUT_RECORD struct { + EventType WORD + KeyEvent KEY_EVENT_RECORD + } + + CHAR_INFO struct { + UnicodeChar WCHAR + Attributes WORD + } +) + +// TODO(azlinux): Basic type clean-up +// -- Convert all uses of uintptr to syscall.Handle to be consistent with Windows syscall +// -- Convert, as appropriate, types to use defined Windows types (e.g., DWORD instead of uint32) + +// Implements the TerminalEmulator interface +type WindowsTerminal struct { + outMutex sync.Mutex + inMutex sync.Mutex + inputBuffer []byte + inputSize int + inputEvents []INPUT_RECORD + screenBufferInfo *CONSOLE_SCREEN_BUFFER_INFO + inputEscapeSequence []byte +} + +func getStdHandle(stdhandle int) uintptr { + handle, err := syscall.GetStdHandle(stdhandle) + if err != nil { + panic(fmt.Errorf("could not get standard io handle %d", stdhandle)) + } + return uintptr(handle) +} + +func WinConsoleStreams() (stdIn io.ReadCloser, stdOut, stdErr io.Writer) { + handler := &WindowsTerminal{ + inputBuffer: make([]byte, MAX_INPUT_BUFFER), + inputEscapeSequence: []byte(KEY_ESC_CSI), + inputEvents: make([]INPUT_RECORD, MAX_INPUT_EVENTS), + } + + if IsConsole(os.Stdin.Fd()) { + stdIn = &terminalReader{ + wrappedReader: os.Stdin, + emulator: handler, + command: make([]byte, 0, ANSI_MAX_CMD_LENGTH), + fd: getStdHandle(syscall.STD_INPUT_HANDLE), + } + } else { + stdIn = os.Stdin + } + + if IsConsole(os.Stdout.Fd()) { + stdoutHandle := getStdHandle(syscall.STD_OUTPUT_HANDLE) + + // Save current screen buffer info + screenBufferInfo, err := GetConsoleScreenBufferInfo(stdoutHandle) + if err != nil { + // If GetConsoleScreenBufferInfo returns a nil error, it usually means that stdout is not a TTY. + // However, this is in the branch where stdout is a TTY, hence the panic. + panic("could not get console screen buffer info") + } + handler.screenBufferInfo = screenBufferInfo + + buffer = make([]CHAR_INFO, screenBufferInfo.MaximumWindowSize.X*screenBufferInfo.MaximumWindowSize.Y) + + stdOut = &terminalWriter{ + wrappedWriter: os.Stdout, + emulator: handler, + command: make([]byte, 0, ANSI_MAX_CMD_LENGTH), + fd: stdoutHandle, + } + } else { + stdOut = os.Stdout + } + + if IsConsole(os.Stderr.Fd()) { + stdErr = &terminalWriter{ + wrappedWriter: os.Stderr, + emulator: handler, + command: make([]byte, 0, ANSI_MAX_CMD_LENGTH), + fd: getStdHandle(syscall.STD_ERROR_HANDLE), + } + } else { + stdErr = os.Stderr + } + + return stdIn, stdOut, stdErr +} + +// GetHandleInfo returns file descriptor and bool indicating whether the file is a console. +func GetHandleInfo(in interface{}) (uintptr, bool) { + var inFd uintptr + var isTerminalIn bool + + switch t := in.(type) { + case *terminalReader: + in = t.wrappedReader + case *terminalWriter: + in = t.wrappedWriter + } + + if file, ok := in.(*os.File); ok { + inFd = file.Fd() + isTerminalIn = IsConsole(inFd) + } + return inFd, isTerminalIn +} + +func getError(r1, r2 uintptr, lastErr error) error { + // If the function fails, the return value is zero. + if r1 == 0 { + if lastErr != nil { + return lastErr + } + return syscall.EINVAL + } + return nil +} + +// GetConsoleMode gets the console mode for given file descriptor +// http://msdn.microsoft.com/en-us/library/windows/desktop/ms683167(v=vs.85).aspx +func GetConsoleMode(handle uintptr) (uint32, error) { + var mode uint32 + err := syscall.GetConsoleMode(syscall.Handle(handle), &mode) + return mode, err +} + +// SetConsoleMode sets the console mode for given file descriptor +// http://msdn.microsoft.com/en-us/library/windows/desktop/ms686033(v=vs.85).aspx +func SetConsoleMode(handle uintptr, mode uint32) error { + return getError(setConsoleModeProc.Call(handle, uintptr(mode), 0)) +} + +// SetCursorVisible sets the cursor visbility +// http://msdn.microsoft.com/en-us/library/windows/desktop/ms686019(v=vs.85).aspx +func SetCursorVisible(handle uintptr, isVisible BOOL) (bool, error) { + var cursorInfo *CONSOLE_CURSOR_INFO = &CONSOLE_CURSOR_INFO{} + if err := getError(getConsoleCursorInfoProc.Call(handle, uintptr(unsafe.Pointer(cursorInfo)), 0)); err != nil { + return false, err + } + cursorInfo.Visible = isVisible + if err := getError(setConsoleCursorInfoProc.Call(handle, uintptr(unsafe.Pointer(cursorInfo)), 0)); err != nil { + return false, err + } + return true, nil +} + +// SetWindowSize sets the size of the console window. +func SetWindowSize(handle uintptr, width, height, max SHORT) (bool, error) { + window := SMALL_RECT{Left: 0, Top: 0, Right: width - 1, Bottom: height - 1} + coord := COORD{X: width - 1, Y: max} + if err := getError(setConsoleWindowInfoProc.Call(handle, uintptr(1), uintptr(unsafe.Pointer(&window)))); err != nil { + return false, err + } + if err := getError(setConsoleScreenBufferSizeProc.Call(handle, marshal(coord))); err != nil { + return false, err + } + return true, nil +} + +// GetConsoleScreenBufferInfo retrieves information about the specified console screen buffer. +// http://msdn.microsoft.com/en-us/library/windows/desktop/ms683171(v=vs.85).aspx +func GetConsoleScreenBufferInfo(handle uintptr) (*CONSOLE_SCREEN_BUFFER_INFO, error) { + var info CONSOLE_SCREEN_BUFFER_INFO + if err := getError(getConsoleScreenBufferInfoProc.Call(handle, uintptr(unsafe.Pointer(&info)), 0)); err != nil { + return nil, err + } + return &info, nil +} + +// setConsoleTextAttribute sets the attributes of characters written to the +// console screen buffer by the WriteFile or WriteConsole function, +// http://msdn.microsoft.com/en-us/library/windows/desktop/ms686047(v=vs.85).aspx +func setConsoleTextAttribute(handle uintptr, attribute WORD) error { + return getError(setConsoleTextAttributeProc.Call(handle, uintptr(attribute), 0)) +} + +func writeConsoleOutput(handle uintptr, buffer []CHAR_INFO, bufferSize COORD, bufferCoord COORD, writeRegion *SMALL_RECT) (bool, error) { + if err := getError(writeConsoleOutputProc.Call(handle, uintptr(unsafe.Pointer(&buffer[0])), marshal(bufferSize), marshal(bufferCoord), uintptr(unsafe.Pointer(writeRegion)))); err != nil { + return false, err + } + return true, nil +} + +// http://msdn.microsoft.com/en-us/library/windows/desktop/ms682663(v=vs.85).aspx +func fillConsoleOutputCharacter(handle uintptr, fillChar byte, length uint32, writeCord COORD) (bool, error) { + out := int64(0) + if err := getError(fillConsoleOutputCharacterProc.Call(handle, uintptr(fillChar), uintptr(length), marshal(writeCord), uintptr(unsafe.Pointer(&out)))); err != nil { + return false, err + } + return true, nil +} + +// Gets the number of space characters to write for "clearing" the section of terminal +func getNumberOfChars(fromCoord COORD, toCoord COORD, screenSize COORD) uint32 { + // must be valid cursor position + if fromCoord.X < 0 || fromCoord.Y < 0 || toCoord.X < 0 || toCoord.Y < 0 { + return 0 + } + if fromCoord.X >= screenSize.X || fromCoord.Y >= screenSize.Y || toCoord.X >= screenSize.X || toCoord.Y >= screenSize.Y { + return 0 + } + // can't be backwards + if fromCoord.Y > toCoord.Y { + return 0 + } + // same line + if fromCoord.Y == toCoord.Y { + return uint32(toCoord.X-fromCoord.X) + 1 + } + // spans more than one line + if fromCoord.Y < toCoord.Y { + // from start till end of line for first line + from start of line till end + retValue := uint32(screenSize.X-fromCoord.X) + uint32(toCoord.X) + 1 + // don't count first and last line + linesBetween := toCoord.Y - fromCoord.Y - 1 + if linesBetween > 0 { + retValue = retValue + uint32(linesBetween*screenSize.X) + } + return retValue + } + return 0 +} + +var buffer []CHAR_INFO + +func clearDisplayRect(handle uintptr, attributes WORD, fromCoord COORD, toCoord COORD) (uint32, error) { + var writeRegion SMALL_RECT + writeRegion.Left = fromCoord.X + writeRegion.Top = fromCoord.Y + writeRegion.Right = toCoord.X + writeRegion.Bottom = toCoord.Y + + // allocate and initialize buffer + width := toCoord.X - fromCoord.X + 1 + height := toCoord.Y - fromCoord.Y + 1 + size := uint32(width) * uint32(height) + if size > 0 { + buffer := make([]CHAR_INFO, size) + for i := range buffer { + buffer[i] = CHAR_INFO{WCHAR(' '), attributes} + } + + // Write to buffer + r, err := writeConsoleOutput(handle, buffer, COORD{X: width, Y: height}, COORD{X: 0, Y: 0}, &writeRegion) + if !r { + if err != nil { + return 0, err + } + return 0, syscall.EINVAL + } + } + return uint32(size), nil +} + +func clearDisplayRange(handle uintptr, attributes WORD, fromCoord COORD, toCoord COORD) (uint32, error) { + nw := uint32(0) + // start and end on same line + if fromCoord.Y == toCoord.Y { + return clearDisplayRect(handle, attributes, fromCoord, toCoord) + } + // TODO(azlinux): if full screen, optimize + + // spans more than one line + if fromCoord.Y < toCoord.Y { + // from start position till end of line for first line + n, err := clearDisplayRect(handle, attributes, fromCoord, COORD{X: toCoord.X, Y: fromCoord.Y}) + if err != nil { + return nw, err + } + nw += n + // lines between + linesBetween := toCoord.Y - fromCoord.Y - 1 + if linesBetween > 0 { + n, err = clearDisplayRect(handle, attributes, COORD{X: 0, Y: fromCoord.Y + 1}, COORD{X: toCoord.X, Y: toCoord.Y - 1}) + if err != nil { + return nw, err + } + nw += n + } + // lines at end + n, err = clearDisplayRect(handle, attributes, COORD{X: 0, Y: toCoord.Y}, toCoord) + if err != nil { + return nw, err + } + nw += n + } + return nw, nil +} + +// setConsoleCursorPosition sets the console cursor position +// Note The X and Y are zero based +// If relative is true then the new position is relative to current one +func setConsoleCursorPosition(handle uintptr, isRelative bool, column int16, line int16) error { + screenBufferInfo, err := GetConsoleScreenBufferInfo(handle) + if err != nil { + return err + } + var position COORD + if isRelative { + position.X = screenBufferInfo.CursorPosition.X + SHORT(column) + position.Y = screenBufferInfo.CursorPosition.Y + SHORT(line) + } else { + position.X = SHORT(column) + position.Y = SHORT(line) + } + return getError(setConsoleCursorPositionProc.Call(handle, marshal(position), 0)) +} + +// http://msdn.microsoft.com/en-us/library/windows/desktop/ms683207(v=vs.85).aspx +func getNumberOfConsoleInputEvents(handle uintptr) (uint16, error) { + var n DWORD + if err := getError(getNumberOfConsoleInputEventsProc.Call(handle, uintptr(unsafe.Pointer(&n)))); err != nil { + return 0, err + } + return uint16(n), nil +} + +//http://msdn.microsoft.com/en-us/library/windows/desktop/ms684961(v=vs.85).aspx +func readConsoleInputKey(handle uintptr, inputBuffer []INPUT_RECORD) (int, error) { + var nr DWORD + if err := getError(readConsoleInputProc.Call(handle, uintptr(unsafe.Pointer(&inputBuffer[0])), uintptr(len(inputBuffer)), uintptr(unsafe.Pointer(&nr)))); err != nil { + return 0, err + } + return int(nr), nil +} + +func getWindowsTextAttributeForAnsiValue(originalFlag WORD, defaultValue WORD, ansiValue int16) (WORD, error) { + flag := WORD(originalFlag) + if flag == 0 { + flag = defaultValue + } + switch ansiValue { + case ANSI_ATTR_RESET: + flag &^= COMMON_LVB_UNDERSCORE + flag &^= BACKGROUND_INTENSITY + flag = flag | FOREGROUND_INTENSITY + case ANSI_ATTR_INVISIBLE: + // TODO: how do you reset reverse? + case ANSI_ATTR_UNDERLINE: + flag = flag | COMMON_LVB_UNDERSCORE + case ANSI_ATTR_BLINK: + // seems like background intenisty is blink + flag = flag | BACKGROUND_INTENSITY + case ANSI_ATTR_UNDERLINE_OFF: + flag &^= COMMON_LVB_UNDERSCORE + case ANSI_ATTR_BLINK_OFF: + // seems like background intenisty is blink + flag &^= BACKGROUND_INTENSITY + case ANSI_ATTR_BOLD: + flag = flag | FOREGROUND_INTENSITY + case ANSI_ATTR_DIM: + flag &^= FOREGROUND_INTENSITY + case ANSI_ATTR_REVERSE, ANSI_ATTR_REVERSE_OFF: + // swap forground and background bits + foreground := flag & FOREGROUND_MASK_SET + background := flag & BACKGROUND_MASK_SET + flag = (flag & BACKGROUND_MASK_UNSET & FOREGROUND_MASK_UNSET) | (foreground << 4) | (background >> 4) + + // FOREGROUND + case ANSI_FOREGROUND_DEFAULT: + flag = (flag & FOREGROUND_MASK_UNSET) | (defaultValue & FOREGROUND_MASK_SET) + case ANSI_FOREGROUND_BLACK: + flag = flag ^ (FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE) + case ANSI_FOREGROUND_RED: + flag = (flag & FOREGROUND_MASK_UNSET) | FOREGROUND_RED + case ANSI_FOREGROUND_GREEN: + flag = (flag & FOREGROUND_MASK_UNSET) | FOREGROUND_GREEN + case ANSI_FOREGROUND_YELLOW: + flag = (flag & FOREGROUND_MASK_UNSET) | FOREGROUND_RED | FOREGROUND_GREEN + case ANSI_FOREGROUND_BLUE: + flag = (flag & FOREGROUND_MASK_UNSET) | FOREGROUND_BLUE + case ANSI_FOREGROUND_MAGENTA: + flag = (flag & FOREGROUND_MASK_UNSET) | FOREGROUND_RED | FOREGROUND_BLUE + case ANSI_FOREGROUND_CYAN: + flag = (flag & FOREGROUND_MASK_UNSET) | FOREGROUND_GREEN | FOREGROUND_BLUE + case ANSI_FOREGROUND_WHITE: + flag = (flag & FOREGROUND_MASK_UNSET) | FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE + + // Background + case ANSI_BACKGROUND_DEFAULT: + // Black with no intensity + flag = (flag & BACKGROUND_MASK_UNSET) | (defaultValue & BACKGROUND_MASK_SET) + case ANSI_BACKGROUND_BLACK: + flag = (flag & BACKGROUND_MASK_UNSET) + case ANSI_BACKGROUND_RED: + flag = (flag & BACKGROUND_MASK_UNSET) | BACKGROUND_RED + case ANSI_BACKGROUND_GREEN: + flag = (flag & BACKGROUND_MASK_UNSET) | BACKGROUND_GREEN + case ANSI_BACKGROUND_YELLOW: + flag = (flag & BACKGROUND_MASK_UNSET) | BACKGROUND_RED | BACKGROUND_GREEN + case ANSI_BACKGROUND_BLUE: + flag = (flag & BACKGROUND_MASK_UNSET) | BACKGROUND_BLUE + case ANSI_BACKGROUND_MAGENTA: + flag = (flag & BACKGROUND_MASK_UNSET) | BACKGROUND_RED | BACKGROUND_BLUE + case ANSI_BACKGROUND_CYAN: + flag = (flag & BACKGROUND_MASK_UNSET) | BACKGROUND_GREEN | BACKGROUND_BLUE + case ANSI_BACKGROUND_WHITE: + flag = (flag & BACKGROUND_MASK_UNSET) | BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE + } + return flag, nil +} + +// HandleOutputCommand interpretes the Ansi commands and then makes appropriate Win32 calls +func (term *WindowsTerminal) HandleOutputCommand(handle uintptr, command []byte) (n int, err error) { + // always consider all the bytes in command, processed + n = len(command) + + parsedCommand := parseAnsiCommand(command) + logrus.Debugf("[windows] HandleOutputCommand: %v", parsedCommand) + + // console settings changes need to happen in atomic way + term.outMutex.Lock() + defer term.outMutex.Unlock() + + switch parsedCommand.Command { + case "m": + // [Value;...;Valuem + // Set Graphics Mode: + // Calls the graphics functions specified by the following values. + // These specified functions remain active until the next occurrence of this escape sequence. + // Graphics mode changes the colors and attributes of text (such as bold and underline) displayed on the screen. + screenBufferInfo, err := GetConsoleScreenBufferInfo(handle) + if err != nil { + return n, err + } + flag := screenBufferInfo.Attributes + for _, e := range parsedCommand.Parameters { + value, _ := strconv.ParseInt(e, 10, 16) // base 10, 16 bit + if value == ANSI_ATTR_RESET { + flag = term.screenBufferInfo.Attributes // reset + } else { + flag, err = getWindowsTextAttributeForAnsiValue(flag, term.screenBufferInfo.Attributes, int16(value)) + if err != nil { + return n, err + } + } + } + if err := setConsoleTextAttribute(handle, flag); err != nil { + return n, err + } + case "H", "f": + // [line;columnH + // [line;columnf + // Moves the cursor to the specified position (coordinates). + // If you do not specify a position, the cursor moves to the home position at the upper-left corner of the screen (line 0, column 0). + screenBufferInfo, err := GetConsoleScreenBufferInfo(handle) + if err != nil { + return n, err + } + line, err := parseInt16OrDefault(parsedCommand.getParam(0), 1) + if err != nil { + return n, err + } + if line > int16(screenBufferInfo.Window.Bottom) { + line = int16(screenBufferInfo.Window.Bottom) + 1 + } + column, err := parseInt16OrDefault(parsedCommand.getParam(1), 1) + if err != nil { + return n, err + } + if column > int16(screenBufferInfo.Window.Right) { + column = int16(screenBufferInfo.Window.Right) + 1 + } + // The numbers are not 0 based, but 1 based + logrus.Debugf("[windows] HandleOutputCommmand: Moving cursor to (%v,%v)", column-1, line-1) + if err := setConsoleCursorPosition(handle, false, column-1, line-1); err != nil { + return n, err + } + + case "A": + // [valueA + // Moves the cursor up by the specified number of lines without changing columns. + // If the cursor is already on the top line, ignores this sequence. + value, err := parseInt16OrDefault(parsedCommand.getParam(0), 1) + if err != nil { + return len(command), err + } + if err := setConsoleCursorPosition(handle, true, 0, -value); err != nil { + return n, err + } + case "B": + // [valueB + // Moves the cursor down by the specified number of lines without changing columns. + // If the cursor is already on the bottom line, ignores this sequence. + value, err := parseInt16OrDefault(parsedCommand.getParam(0), 1) + if err != nil { + return n, err + } + if err := setConsoleCursorPosition(handle, true, 0, value); err != nil { + return n, err + } + case "C": + // [valueC + // Moves the cursor forward by the specified number of columns without changing lines. + // If the cursor is already in the rightmost column, ignores this sequence. + value, err := parseInt16OrDefault(parsedCommand.getParam(0), 1) + if err != nil { + return n, err + } + if err := setConsoleCursorPosition(handle, true, value, 0); err != nil { + return n, err + } + case "D": + // [valueD + // Moves the cursor back by the specified number of columns without changing lines. + // If the cursor is already in the leftmost column, ignores this sequence. + value, err := parseInt16OrDefault(parsedCommand.getParam(0), 1) + if err != nil { + return n, err + } + if err := setConsoleCursorPosition(handle, true, -value, 0); err != nil { + return n, err + } + case "J": + // [J Erases from the cursor to the end of the screen, including the cursor position. + // [1J Erases from the beginning of the screen to the cursor, including the cursor position. + // [2J Erases the complete display. The cursor does not move. + // Clears the screen and moves the cursor to the home position (line 0, column 0). + value, err := parseInt16OrDefault(parsedCommand.getParam(0), 0) + if err != nil { + return n, err + } + var start COORD + var cursor COORD + var end COORD + screenBufferInfo, err := GetConsoleScreenBufferInfo(handle) + if err != nil { + return n, err + } + switch value { + case 0: + start = screenBufferInfo.CursorPosition + // end of the buffer + end.X = screenBufferInfo.Size.X - 1 + end.Y = screenBufferInfo.Size.Y - 1 + // cursor + cursor = screenBufferInfo.CursorPosition + case 1: + + // start of the screen + start.X = 0 + start.Y = 0 + // end of the screen + end = screenBufferInfo.CursorPosition + // cursor + cursor = screenBufferInfo.CursorPosition + case 2: + // start of the screen + start.X = 0 + start.Y = 0 + // end of the buffer + end.X = screenBufferInfo.Size.X - 1 + end.Y = screenBufferInfo.Size.Y - 1 + // cursor + cursor.X = 0 + cursor.Y = 0 + } + if _, err := clearDisplayRange(uintptr(handle), term.screenBufferInfo.Attributes, start, end); err != nil { + return n, err + } + // remember the the cursor position is 1 based + if err := setConsoleCursorPosition(handle, false, int16(cursor.X), int16(cursor.Y)); err != nil { + return n, err + } + + case "K": + // [K + // Clears all characters from the cursor position to the end of the line (including the character at the cursor position). + // [K Erases from the cursor to the end of the line, including the cursor position. + // [1K Erases from the beginning of the line to the cursor, including the cursor position. + // [2K Erases the complete line. + value, err := parseInt16OrDefault(parsedCommand.getParam(0), 0) + var start COORD + var cursor COORD + var end COORD + screenBufferInfo, err := GetConsoleScreenBufferInfo(uintptr(handle)) + if err != nil { + return n, err + } + switch value { + case 0: + // start is where cursor is + start = screenBufferInfo.CursorPosition + // end of line + end.X = screenBufferInfo.Size.X - 1 + end.Y = screenBufferInfo.CursorPosition.Y + // cursor remains the same + cursor = screenBufferInfo.CursorPosition + + case 1: + // beginning of line + start.X = 0 + start.Y = screenBufferInfo.CursorPosition.Y + // until cursor + end = screenBufferInfo.CursorPosition + // cursor remains the same + cursor = screenBufferInfo.CursorPosition + case 2: + // start of the line + start.X = 0 + start.Y = screenBufferInfo.CursorPosition.Y - 1 + // end of the line + end.X = screenBufferInfo.Size.X - 1 + end.Y = screenBufferInfo.CursorPosition.Y - 1 + // cursor + cursor.X = 0 + cursor.Y = screenBufferInfo.CursorPosition.Y - 1 + } + if _, err := clearDisplayRange(uintptr(handle), term.screenBufferInfo.Attributes, start, end); err != nil { + return n, err + } + // remember the the cursor position is 1 based + if err := setConsoleCursorPosition(uintptr(handle), false, int16(cursor.X), int16(cursor.Y)); err != nil { + return n, err + } + + case "l": + for _, value := range parsedCommand.Parameters { + switch value { + case "?25", "25": + SetCursorVisible(uintptr(handle), BOOL(0)) + case "?1049", "1049": + // TODO (azlinux): Restore terminal + case "?1", "1": + // If the DECCKM function is reset, then the arrow keys send ANSI cursor sequences to the host. + term.inputEscapeSequence = []byte(KEY_ESC_CSI) + } + } + case "h": + for _, value := range parsedCommand.Parameters { + switch value { + case "?25", "25": + SetCursorVisible(uintptr(handle), BOOL(1)) + case "?1049", "1049": + // TODO (azlinux): Save terminal + case "?1", "1": + // If the DECCKM function is set, then the arrow keys send application sequences to the host. + // DECCKM (default off): When set, the cursor keys send an ESC O prefix, rather than ESC [. + term.inputEscapeSequence = []byte(KEY_ESC_O) + } + } + + case "]": + /* + TODO (azlinux): + Linux Console Private CSI Sequences + + The following sequences are neither ECMA-48 nor native VT102. They are + native to the Linux console driver. Colors are in SGR parameters: 0 = + black, 1 = red, 2 = green, 3 = brown, 4 = blue, 5 = magenta, 6 = cyan, + 7 = white. + + ESC [ 1 ; n ] Set color n as the underline color + ESC [ 2 ; n ] Set color n as the dim color + ESC [ 8 ] Make the current color pair the default attributes. + ESC [ 9 ; n ] Set screen blank timeout to n minutes. + ESC [ 10 ; n ] Set bell frequency in Hz. + ESC [ 11 ; n ] Set bell duration in msec. + ESC [ 12 ; n ] Bring specified console to the front. + ESC [ 13 ] Unblank the screen. + ESC [ 14 ; n ] Set the VESA powerdown interval in minutes. + + */ + } + return n, nil +} + +// WriteChars writes the bytes to given writer. +func (term *WindowsTerminal) WriteChars(fd uintptr, w io.Writer, p []byte) (n int, err error) { + if len(p) == 0 { + return 0, nil + } + return w.Write(p) +} + +const ( + CAPSLOCK_ON = 0x0080 //The CAPS LOCK light is on. + ENHANCED_KEY = 0x0100 //The key is enhanced. + LEFT_ALT_PRESSED = 0x0002 //The left ALT key is pressed. + LEFT_CTRL_PRESSED = 0x0008 //The left CTRL key is pressed. + NUMLOCK_ON = 0x0020 //The NUM LOCK light is on. + RIGHT_ALT_PRESSED = 0x0001 //The right ALT key is pressed. + RIGHT_CTRL_PRESSED = 0x0004 //The right CTRL key is pressed. + SCROLLLOCK_ON = 0x0040 //The SCROLL LOCK light is on. + SHIFT_PRESSED = 0x0010 // The SHIFT key is pressed. +) + +const ( + KEY_CONTROL_PARAM_2 = ";2" + KEY_CONTROL_PARAM_3 = ";3" + KEY_CONTROL_PARAM_4 = ";4" + KEY_CONTROL_PARAM_5 = ";5" + KEY_CONTROL_PARAM_6 = ";6" + KEY_CONTROL_PARAM_7 = ";7" + KEY_CONTROL_PARAM_8 = ";8" + KEY_ESC_CSI = "\x1B[" + KEY_ESC_N = "\x1BN" + KEY_ESC_O = "\x1BO" +) + +var keyMapPrefix = map[WORD]string{ + VK_UP: "\x1B[%sA", + VK_DOWN: "\x1B[%sB", + VK_RIGHT: "\x1B[%sC", + VK_LEFT: "\x1B[%sD", + VK_HOME: "\x1B[1%s~", // showkey shows ^[[1 + VK_END: "\x1B[4%s~", // showkey shows ^[[4 + VK_INSERT: "\x1B[2%s~", + VK_DELETE: "\x1B[3%s~", + VK_PRIOR: "\x1B[5%s~", + VK_NEXT: "\x1B[6%s~", + VK_F1: "", + VK_F2: "", + VK_F3: "\x1B[13%s~", + VK_F4: "\x1B[14%s~", + VK_F5: "\x1B[15%s~", + VK_F6: "\x1B[17%s~", + VK_F7: "\x1B[18%s~", + VK_F8: "\x1B[19%s~", + VK_F9: "\x1B[20%s~", + VK_F10: "\x1B[21%s~", + VK_F11: "\x1B[23%s~", + VK_F12: "\x1B[24%s~", +} + +var arrowKeyMapPrefix = map[WORD]string{ + VK_UP: "%s%sA", + VK_DOWN: "%s%sB", + VK_RIGHT: "%s%sC", + VK_LEFT: "%s%sD", +} + +func getControlStateParameter(shift, alt, control, meta bool) string { + if shift && alt && control { + return KEY_CONTROL_PARAM_8 + } + if alt && control { + return KEY_CONTROL_PARAM_7 + } + if shift && control { + return KEY_CONTROL_PARAM_6 + } + if control { + return KEY_CONTROL_PARAM_5 + } + if shift && alt { + return KEY_CONTROL_PARAM_4 + } + if alt { + return KEY_CONTROL_PARAM_3 + } + if shift { + return KEY_CONTROL_PARAM_2 + } + return "" +} + +func getControlKeys(controlState DWORD) (shift, alt, control bool) { + shift = 0 != (controlState & SHIFT_PRESSED) + alt = 0 != (controlState & (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED)) + control = 0 != (controlState & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)) + return shift, alt, control +} + +func charSequenceForKeys(key WORD, controlState DWORD, escapeSequence []byte) string { + i, ok := arrowKeyMapPrefix[key] + if ok { + shift, alt, control := getControlKeys(controlState) + modifier := getControlStateParameter(shift, alt, control, false) + return fmt.Sprintf(i, escapeSequence, modifier) + } + + i, ok = keyMapPrefix[key] + if ok { + shift, alt, control := getControlKeys(controlState) + modifier := getControlStateParameter(shift, alt, control, false) + return fmt.Sprintf(i, modifier) + } + + return "" +} + +// mapKeystokeToTerminalString maps the given input event record to string +func mapKeystokeToTerminalString(keyEvent *KEY_EVENT_RECORD, escapeSequence []byte) string { + _, alt, control := getControlKeys(keyEvent.ControlKeyState) + if keyEvent.UnicodeChar == 0 { + return charSequenceForKeys(keyEvent.VirtualKeyCode, keyEvent.ControlKeyState, escapeSequence) + } + if control { + // TODO(azlinux): Implement following control sequences + // -D Signals the end of input from the keyboard; also exits current shell. + // -H Deletes the first character to the left of the cursor. Also called the ERASE key. + // -Q Restarts printing after it has been stopped with -s. + // -S Suspends printing on the screen (does not stop the program). + // -U Deletes all characters on the current line. Also called the KILL key. + // -E Quits current command and creates a core + + } + // +Key generates ESC N Key + if !control && alt { + return KEY_ESC_N + strings.ToLower(string(keyEvent.UnicodeChar)) + } + return string(keyEvent.UnicodeChar) +} + +// getAvailableInputEvents polls the console for availble events +// The function does not return until at least one input record has been read. +func getAvailableInputEvents(handle uintptr, inputEvents []INPUT_RECORD) (n int, err error) { + // TODO(azlinux): Why is there a for loop? Seems to me, that `n` cannot be negative. - tibor + for { + // Read number of console events available + n, err = readConsoleInputKey(handle, inputEvents) + if err != nil || n >= 0 { + return n, err + } + } +} + +// getTranslatedKeyCodes converts the input events into the string of characters +// The ansi escape sequence are used to map key strokes to the strings +func getTranslatedKeyCodes(inputEvents []INPUT_RECORD, escapeSequence []byte) string { + var buf bytes.Buffer + for i := 0; i < len(inputEvents); i++ { + input := inputEvents[i] + if input.EventType == KEY_EVENT && input.KeyEvent.KeyDown != 0 { + keyString := mapKeystokeToTerminalString(&input.KeyEvent, escapeSequence) + buf.WriteString(keyString) + } + } + return buf.String() +} + +// ReadChars reads the characters from the given reader +func (term *WindowsTerminal) ReadChars(fd uintptr, r io.Reader, p []byte) (n int, err error) { + for term.inputSize == 0 { + nr, err := getAvailableInputEvents(fd, term.inputEvents) + if nr == 0 && nil != err { + return n, err + } + if nr > 0 { + keyCodes := getTranslatedKeyCodes(term.inputEvents[:nr], term.inputEscapeSequence) + term.inputSize = copy(term.inputBuffer, keyCodes) + } + } + n = copy(p, term.inputBuffer[:term.inputSize]) + term.inputSize -= n + return n, nil +} + +// HandleInputSequence interprets the input sequence command +func (term *WindowsTerminal) HandleInputSequence(fd uintptr, command []byte) (n int, err error) { + return 0, nil +} + +func marshal(c COORD) uintptr { + return uintptr(*((*DWORD)(unsafe.Pointer(&c)))) +} + +// IsConsole returns true if the given file descriptor is a terminal. +// -- The code assumes that GetConsoleMode will return an error for file descriptors that are not a console. +func IsConsole(fd uintptr) bool { + _, e := GetConsoleMode(fd) + return e == nil +} diff --git a/vendor/github.com/docker/docker/pkg/term/winconsole/term_emulator.go b/vendor/github.com/docker/docker/pkg/term/winconsole/term_emulator.go new file mode 100644 index 0000000..2d5edc0 --- /dev/null +++ b/vendor/github.com/docker/docker/pkg/term/winconsole/term_emulator.go @@ -0,0 +1,234 @@ +package winconsole + +import ( + "fmt" + "io" + "strconv" + "strings" +) + +// http://manpages.ubuntu.com/manpages/intrepid/man4/console_codes.4.html +const ( + ANSI_ESCAPE_PRIMARY = 0x1B + ANSI_ESCAPE_SECONDARY = 0x5B + ANSI_COMMAND_FIRST = 0x40 + ANSI_COMMAND_LAST = 0x7E + ANSI_PARAMETER_SEP = ";" + ANSI_CMD_G0 = '(' + ANSI_CMD_G1 = ')' + ANSI_CMD_G2 = '*' + ANSI_CMD_G3 = '+' + ANSI_CMD_DECPNM = '>' + ANSI_CMD_DECPAM = '=' + ANSI_CMD_OSC = ']' + ANSI_CMD_STR_TERM = '\\' + ANSI_BEL = 0x07 + KEY_EVENT = 1 +) + +// Interface that implements terminal handling +type terminalEmulator interface { + HandleOutputCommand(fd uintptr, command []byte) (n int, err error) + HandleInputSequence(fd uintptr, command []byte) (n int, err error) + WriteChars(fd uintptr, w io.Writer, p []byte) (n int, err error) + ReadChars(fd uintptr, w io.Reader, p []byte) (n int, err error) +} + +type terminalWriter struct { + wrappedWriter io.Writer + emulator terminalEmulator + command []byte + inSequence bool + fd uintptr +} + +type terminalReader struct { + wrappedReader io.ReadCloser + emulator terminalEmulator + command []byte + inSequence bool + fd uintptr +} + +// http://manpages.ubuntu.com/manpages/intrepid/man4/console_codes.4.html +func isAnsiCommandChar(b byte) bool { + switch { + case ANSI_COMMAND_FIRST <= b && b <= ANSI_COMMAND_LAST && b != ANSI_ESCAPE_SECONDARY: + return true + case b == ANSI_CMD_G1 || b == ANSI_CMD_OSC || b == ANSI_CMD_DECPAM || b == ANSI_CMD_DECPNM: + // non-CSI escape sequence terminator + return true + case b == ANSI_CMD_STR_TERM || b == ANSI_BEL: + // String escape sequence terminator + return true + } + return false +} + +func isCharacterSelectionCmdChar(b byte) bool { + return (b == ANSI_CMD_G0 || b == ANSI_CMD_G1 || b == ANSI_CMD_G2 || b == ANSI_CMD_G3) +} + +func isXtermOscSequence(command []byte, current byte) bool { + return (len(command) >= 2 && command[0] == ANSI_ESCAPE_PRIMARY && command[1] == ANSI_CMD_OSC && current != ANSI_BEL) +} + +// Write writes len(p) bytes from p to the underlying data stream. +// http://golang.org/pkg/io/#Writer +func (tw *terminalWriter) Write(p []byte) (n int, err error) { + if len(p) == 0 { + return 0, nil + } + if tw.emulator == nil { + return tw.wrappedWriter.Write(p) + } + // Emulate terminal by extracting commands and executing them + totalWritten := 0 + start := 0 // indicates start of the next chunk + end := len(p) + for current := 0; current < end; current++ { + if tw.inSequence { + // inside escape sequence + tw.command = append(tw.command, p[current]) + if isAnsiCommandChar(p[current]) { + if !isXtermOscSequence(tw.command, p[current]) { + // found the last command character. + // Now we have a complete command. + nchar, err := tw.emulator.HandleOutputCommand(tw.fd, tw.command) + totalWritten += nchar + if err != nil { + return totalWritten, err + } + + // clear the command + // don't include current character again + tw.command = tw.command[:0] + start = current + 1 + tw.inSequence = false + } + } + } else { + if p[current] == ANSI_ESCAPE_PRIMARY { + // entering escape sequnce + tw.inSequence = true + // indicates end of "normal sequence", write whatever you have so far + if len(p[start:current]) > 0 { + nw, err := tw.emulator.WriteChars(tw.fd, tw.wrappedWriter, p[start:current]) + totalWritten += nw + if err != nil { + return totalWritten, err + } + } + // include the current character as part of the next sequence + tw.command = append(tw.command, p[current]) + } + } + } + // note that so far, start of the escape sequence triggers writing out of bytes to console. + // For the part _after_ the end of last escape sequence, it is not written out yet. So write it out + if !tw.inSequence { + // assumption is that we can't be inside sequence and therefore command should be empty + if len(p[start:]) > 0 { + nw, err := tw.emulator.WriteChars(tw.fd, tw.wrappedWriter, p[start:]) + totalWritten += nw + if err != nil { + return totalWritten, err + } + } + } + return totalWritten, nil + +} + +// Read reads up to len(p) bytes into p. +// http://golang.org/pkg/io/#Reader +func (tr *terminalReader) Read(p []byte) (n int, err error) { + //Implementations of Read are discouraged from returning a zero byte count + // with a nil error, except when len(p) == 0. + if len(p) == 0 { + return 0, nil + } + if nil == tr.emulator { + return tr.readFromWrappedReader(p) + } + return tr.emulator.ReadChars(tr.fd, tr.wrappedReader, p) +} + +// Close the underlying stream +func (tr *terminalReader) Close() (err error) { + return tr.wrappedReader.Close() +} + +func (tr *terminalReader) readFromWrappedReader(p []byte) (n int, err error) { + return tr.wrappedReader.Read(p) +} + +type ansiCommand struct { + CommandBytes []byte + Command string + Parameters []string + IsSpecial bool +} + +func parseAnsiCommand(command []byte) *ansiCommand { + if isCharacterSelectionCmdChar(command[1]) { + // Is Character Set Selection commands + return &ansiCommand{ + CommandBytes: command, + Command: string(command), + IsSpecial: true, + } + } + // last char is command character + lastCharIndex := len(command) - 1 + + retValue := &ansiCommand{ + CommandBytes: command, + Command: string(command[lastCharIndex]), + IsSpecial: false, + } + // more than a single escape + if lastCharIndex != 0 { + start := 1 + // skip if double char escape sequence + if command[0] == ANSI_ESCAPE_PRIMARY && command[1] == ANSI_ESCAPE_SECONDARY { + start++ + } + // convert this to GetNextParam method + retValue.Parameters = strings.Split(string(command[start:lastCharIndex]), ANSI_PARAMETER_SEP) + } + return retValue +} + +func (c *ansiCommand) getParam(index int) string { + if len(c.Parameters) > index { + return c.Parameters[index] + } + return "" +} + +func (ac *ansiCommand) String() string { + return fmt.Sprintf("0x%v \"%v\" (\"%v\")", + bytesToHex(ac.CommandBytes), + ac.Command, + strings.Join(ac.Parameters, "\",\"")) +} + +func bytesToHex(b []byte) string { + hex := make([]string, len(b)) + for i, ch := range b { + hex[i] = fmt.Sprintf("%X", ch) + } + return strings.Join(hex, "") +} + +func parseInt16OrDefault(s string, defaultValue int16) (n int16, err error) { + if s == "" { + return defaultValue, nil + } + parsedValue, err := strconv.ParseInt(s, 10, 16) + if err != nil { + return defaultValue, err + } + return int16(parsedValue), nil +} diff --git a/vendor/github.com/docker/docker/pkg/timeutils/json.go b/vendor/github.com/docker/docker/pkg/timeutils/json.go new file mode 100644 index 0000000..8043d69 --- /dev/null +++ b/vendor/github.com/docker/docker/pkg/timeutils/json.go @@ -0,0 +1,26 @@ +package timeutils + +import ( + "errors" + "time" +) + +const ( + // RFC3339NanoFixed is our own version of RFC339Nano because we want one + // that pads the nano seconds part with zeros to ensure + // the timestamps are aligned in the logs. + RFC3339NanoFixed = "2006-01-02T15:04:05.000000000Z07:00" + // JSONFormat is the format used by FastMarshalJSON + JSONFormat = `"` + time.RFC3339Nano + `"` +) + +// FastMarshalJSON avoids one of the extra allocations that +// time.MarshalJSON is making. +func FastMarshalJSON(t time.Time) (string, error) { + if y := t.Year(); y < 0 || y >= 10000 { + // RFC 3339 is clear that years are 4 digits exactly. + // See golang.org/issue/4556#c15 for more discussion. + return "", errors.New("time.MarshalJSON: year outside of range [0,9999]") + } + return t.Format(JSONFormat), nil +} diff --git a/vendor/github.com/docker/docker/pkg/timeutils/utils.go b/vendor/github.com/docker/docker/pkg/timeutils/utils.go new file mode 100644 index 0000000..8437f12 --- /dev/null +++ b/vendor/github.com/docker/docker/pkg/timeutils/utils.go @@ -0,0 +1,36 @@ +package timeutils + +import ( + "strconv" + "strings" + "time" +) + +// GetTimestamp tries to parse given string as golang duration, +// then RFC3339 time and finally as a Unix timestamp. If +// any of these were successful, it returns a Unix timestamp +// as string otherwise returns the given value back. +// In case of duration input, the returned timestamp is computed +// as the given reference time minus the amount of the duration. +func GetTimestamp(value string, reference time.Time) string { + if d, err := time.ParseDuration(value); value != "0" && err == nil { + return strconv.FormatInt(reference.Add(-d).Unix(), 10) + } + + var format string + if strings.Contains(value, ".") { + format = time.RFC3339Nano + } else { + format = time.RFC3339 + } + + loc := time.FixedZone(time.Now().Zone()) + if len(value) < len(format) { + format = format[:len(value)] + } + t, err := time.ParseInLocation(format, value, loc) + if err != nil { + return value + } + return strconv.FormatInt(t.Unix(), 10) +} diff --git a/vendor/github.com/docker/docker/pkg/units/duration.go b/vendor/github.com/docker/docker/pkg/units/duration.go new file mode 100644 index 0000000..44012aa --- /dev/null +++ b/vendor/github.com/docker/docker/pkg/units/duration.go @@ -0,0 +1,31 @@ +package units + +import ( + "fmt" + "time" +) + +// HumanDuration returns a human-readable approximation of a duration +// (eg. "About a minute", "4 hours ago", etc.) +func HumanDuration(d time.Duration) string { + if seconds := int(d.Seconds()); seconds < 1 { + return "Less than a second" + } else if seconds < 60 { + return fmt.Sprintf("%d seconds", seconds) + } else if minutes := int(d.Minutes()); minutes == 1 { + return "About a minute" + } else if minutes < 60 { + return fmt.Sprintf("%d minutes", minutes) + } else if hours := int(d.Hours()); hours == 1 { + return "About an hour" + } else if hours < 48 { + return fmt.Sprintf("%d hours", hours) + } else if hours < 24*7*2 { + return fmt.Sprintf("%d days", hours/24) + } else if hours < 24*30*3 { + return fmt.Sprintf("%d weeks", hours/24/7) + } else if hours < 24*365*2 { + return fmt.Sprintf("%d months", hours/24/30) + } + return fmt.Sprintf("%d years", int(d.Hours())/24/365) +} diff --git a/vendor/github.com/docker/docker/pkg/units/size.go b/vendor/github.com/docker/docker/pkg/units/size.go new file mode 100644 index 0000000..9e84697 --- /dev/null +++ b/vendor/github.com/docker/docker/pkg/units/size.go @@ -0,0 +1,93 @@ +package units + +import ( + "fmt" + "regexp" + "strconv" + "strings" +) + +// See: http://en.wikipedia.org/wiki/Binary_prefix +const ( + // Decimal + + KB = 1000 + MB = 1000 * KB + GB = 1000 * MB + TB = 1000 * GB + PB = 1000 * TB + + // Binary + + KiB = 1024 + MiB = 1024 * KiB + GiB = 1024 * MiB + TiB = 1024 * GiB + PiB = 1024 * TiB +) + +type unitMap map[string]int64 + +var ( + decimalMap = unitMap{"k": KB, "m": MB, "g": GB, "t": TB, "p": PB} + binaryMap = unitMap{"k": KiB, "m": MiB, "g": GiB, "t": TiB, "p": PiB} + sizeRegex = regexp.MustCompile(`^(\d+)([kKmMgGtTpP])?[bB]?$`) +) + +var decimapAbbrs = []string{"B", "kB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"} +var binaryAbbrs = []string{"B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB"} + +// CustomSize returns a human-readable approximation of a size +// using custom format +func CustomSize(format string, size float64, base float64, _map []string) string { + i := 0 + for size >= base { + size = size / base + i++ + } + return fmt.Sprintf(format, size, _map[i]) +} + +// HumanSize returns a human-readable approximation of a size +// using SI standard (eg. "44kB", "17MB") +func HumanSize(size float64) string { + return CustomSize("%.4g %s", size, 1000.0, decimapAbbrs) +} + +func BytesSize(size float64) string { + return CustomSize("%.4g %s", size, 1024.0, binaryAbbrs) +} + +// FromHumanSize returns an integer from a human-readable specification of a +// size using SI standard (eg. "44kB", "17MB") +func FromHumanSize(size string) (int64, error) { + return parseSize(size, decimalMap) +} + +// RAMInBytes parses a human-readable string representing an amount of RAM +// in bytes, kibibytes, mebibytes, gibibytes, or tebibytes and +// returns the number of bytes, or -1 if the string is unparseable. +// Units are case-insensitive, and the 'b' suffix is optional. +func RAMInBytes(size string) (int64, error) { + return parseSize(size, binaryMap) +} + +// Parses the human-readable size string into the amount it represents +func parseSize(sizeStr string, uMap unitMap) (int64, error) { + matches := sizeRegex.FindStringSubmatch(sizeStr) + if len(matches) != 3 { + return -1, fmt.Errorf("invalid size: '%s'", sizeStr) + } + + size, err := strconv.ParseInt(matches[1], 10, 0) + if err != nil { + return -1, err + } + + unitPrefix := strings.ToLower(matches[2]) + if mul, ok := uMap[unitPrefix]; ok { + size *= mul + } + + return size, nil +} diff --git a/vendor/github.com/golang/groupcache/LICENSE b/vendor/github.com/golang/groupcache/LICENSE new file mode 100644 index 0000000..37ec93a --- /dev/null +++ b/vendor/github.com/golang/groupcache/LICENSE @@ -0,0 +1,191 @@ +Apache License +Version 2.0, January 2004 +http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + +"License" shall mean the terms and conditions for use, reproduction, and +distribution as defined by Sections 1 through 9 of this document. + +"Licensor" shall mean the copyright owner or entity authorized by the copyright +owner that is granting the License. + +"Legal Entity" shall mean the union of the acting entity and all other entities +that control, are controlled by, or are under common control with that entity. +For the purposes of this definition, "control" means (i) the power, direct or +indirect, to cause the direction or management of such entity, whether by +contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the +outstanding shares, or (iii) beneficial ownership of such entity. + +"You" (or "Your") shall mean an individual or Legal Entity exercising +permissions granted by this License. + +"Source" form shall mean the preferred form for making modifications, including +but not limited to software source code, documentation source, and configuration +files. + +"Object" form shall mean any form resulting from mechanical transformation or +translation of a Source form, including but not limited to compiled object code, +generated documentation, and conversions to other media types. + +"Work" shall mean the work of authorship, whether in Source or Object form, made +available under the License, as indicated by a copyright notice that is included +in or attached to the work (an example is provided in the Appendix below). + +"Derivative Works" shall mean any work, whether in Source or Object form, that +is based on (or derived from) the Work and for which the editorial revisions, +annotations, elaborations, or other modifications represent, as a whole, an +original work of authorship. For the purposes of this License, Derivative Works +shall not include works that remain separable from, or merely link (or bind by +name) to the interfaces of, the Work and Derivative Works thereof. + +"Contribution" shall mean any work of authorship, including the original version +of the Work and any modifications or additions to that Work or Derivative Works +thereof, that is intentionally submitted to Licensor for inclusion in the Work +by the copyright owner or by an individual or Legal Entity authorized to submit +on behalf of the copyright owner. For the purposes of this definition, +"submitted" means any form of electronic, verbal, or written communication sent +to the Licensor or its representatives, including but not limited to +communication on electronic mailing lists, source code control systems, and +issue tracking systems that are managed by, or on behalf of, the Licensor for +the purpose of discussing and improving the Work, but excluding communication +that is conspicuously marked or otherwise designated in writing by the copyright +owner as "Not a Contribution." + +"Contributor" shall mean Licensor and any individual or Legal Entity on behalf +of whom a Contribution has been received by Licensor and subsequently +incorporated within the Work. + +2. Grant of Copyright License. + +Subject to the terms and conditions of this License, each Contributor hereby +grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, +irrevocable copyright license to reproduce, prepare Derivative Works of, +publicly display, publicly perform, sublicense, and distribute the Work and such +Derivative Works in Source or Object form. + +3. Grant of Patent License. + +Subject to the terms and conditions of this License, each Contributor hereby +grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, +irrevocable (except as stated in this section) patent license to make, have +made, use, offer to sell, sell, import, and otherwise transfer the Work, where +such license applies only to those patent claims licensable by such Contributor +that are necessarily infringed by their Contribution(s) alone or by combination +of their Contribution(s) with the Work to which such Contribution(s) was +submitted. If You institute patent litigation against any entity (including a +cross-claim or counterclaim in a lawsuit) alleging that the Work or a +Contribution incorporated within the Work constitutes direct or contributory +patent infringement, then any patent licenses granted to You under this License +for that Work shall terminate as of the date such litigation is filed. + +4. Redistribution. + +You may reproduce and distribute copies of the Work or Derivative Works thereof +in any medium, with or without modifications, and in Source or Object form, +provided that You meet the following conditions: + +You must give any other recipients of the Work or Derivative Works a copy of +this License; and +You must cause any modified files to carry prominent notices stating that You +changed the files; and +You must retain, in the Source form of any Derivative Works that You distribute, +all copyright, patent, trademark, and attribution notices from the Source form +of the Work, excluding those notices that do not pertain to any part of the +Derivative Works; and +If the Work includes a "NOTICE" text file as part of its distribution, then any +Derivative Works that You distribute must include a readable copy of the +attribution notices contained within such NOTICE file, excluding those notices +that do not pertain to any part of the Derivative Works, in at least one of the +following places: within a NOTICE text file distributed as part of the +Derivative Works; within the Source form or documentation, if provided along +with the Derivative Works; or, within a display generated by the Derivative +Works, if and wherever such third-party notices normally appear. The contents of +the NOTICE file are for informational purposes only and do not modify the +License. You may add Your own attribution notices within Derivative Works that +You distribute, alongside or as an addendum to the NOTICE text from the Work, +provided that such additional attribution notices cannot be construed as +modifying the License. +You may add Your own copyright statement to Your modifications and may provide +additional or different license terms and conditions for use, reproduction, or +distribution of Your modifications, or for any such Derivative Works as a whole, +provided Your use, reproduction, and distribution of the Work otherwise complies +with the conditions stated in this License. + +5. Submission of Contributions. + +Unless You explicitly state otherwise, any Contribution intentionally submitted +for inclusion in the Work by You to the Licensor shall be under the terms and +conditions of this License, without any additional terms or conditions. +Notwithstanding the above, nothing herein shall supersede or modify the terms of +any separate license agreement you may have executed with Licensor regarding +such Contributions. + +6. Trademarks. + +This License does not grant permission to use the trade names, trademarks, +service marks, or product names of the Licensor, except as required for +reasonable and customary use in describing the origin of the Work and +reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. + +Unless required by applicable law or agreed to in writing, Licensor provides the +Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, +including, without limitation, any warranties or conditions of TITLE, +NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are +solely responsible for determining the appropriateness of using or +redistributing the Work and assume any risks associated with Your exercise of +permissions under this License. + +8. Limitation of Liability. + +In no event and under no legal theory, whether in tort (including negligence), +contract, or otherwise, unless required by applicable law (such as deliberate +and grossly negligent acts) or agreed to in writing, shall any Contributor be +liable to You for damages, including any direct, indirect, special, incidental, +or consequential damages of any character arising as a result of this License or +out of the use or inability to use the Work (including but not limited to +damages for loss of goodwill, work stoppage, computer failure or malfunction, or +any and all other commercial damages or losses), even if such Contributor has +been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. + +While redistributing the Work or Derivative Works thereof, You may choose to +offer, and charge a fee for, acceptance of support, warranty, indemnity, or +other liability obligations and/or rights consistent with this License. However, +in accepting such obligations, You may act only on Your own behalf and on Your +sole responsibility, not on behalf of any other Contributor, and only if You +agree to indemnify, defend, and hold each Contributor harmless for any liability +incurred by, or claims asserted against, such Contributor by reason of your +accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work + +To apply the Apache License to your work, attach the following boilerplate +notice, with the fields enclosed by brackets "[]" replaced with your own +identifying information. (Don't include the brackets!) The text should be +enclosed in the appropriate comment syntax for the file format. We also +recommend that a file or class name and description of purpose be included on +the same "printed page" as the copyright notice for easier identification within +third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. diff --git a/vendor/github.com/golang/groupcache/lru/lru.go b/vendor/github.com/golang/groupcache/lru/lru.go new file mode 100644 index 0000000..cdfe299 --- /dev/null +++ b/vendor/github.com/golang/groupcache/lru/lru.go @@ -0,0 +1,121 @@ +/* +Copyright 2013 Google Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + 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 lru implements an LRU cache. +package lru + +import "container/list" + +// Cache is an LRU cache. It is not safe for concurrent access. +type Cache struct { + // MaxEntries is the maximum number of cache entries before + // an item is evicted. Zero means no limit. + MaxEntries int + + // OnEvicted optionally specificies a callback function to be + // executed when an entry is purged from the cache. + OnEvicted func(key Key, value interface{}) + + ll *list.List + cache map[interface{}]*list.Element +} + +// A Key may be any value that is comparable. See http://golang.org/ref/spec#Comparison_operators +type Key interface{} + +type entry struct { + key Key + value interface{} +} + +// New creates a new Cache. +// If maxEntries is zero, the cache has no limit and it's assumed +// that eviction is done by the caller. +func New(maxEntries int) *Cache { + return &Cache{ + MaxEntries: maxEntries, + ll: list.New(), + cache: make(map[interface{}]*list.Element), + } +} + +// Add adds a value to the cache. +func (c *Cache) Add(key Key, value interface{}) { + if c.cache == nil { + c.cache = make(map[interface{}]*list.Element) + c.ll = list.New() + } + if ee, ok := c.cache[key]; ok { + c.ll.MoveToFront(ee) + ee.Value.(*entry).value = value + return + } + ele := c.ll.PushFront(&entry{key, value}) + c.cache[key] = ele + if c.MaxEntries != 0 && c.ll.Len() > c.MaxEntries { + c.RemoveOldest() + } +} + +// Get looks up a key's value from the cache. +func (c *Cache) Get(key Key) (value interface{}, ok bool) { + if c.cache == nil { + return + } + if ele, hit := c.cache[key]; hit { + c.ll.MoveToFront(ele) + return ele.Value.(*entry).value, true + } + return +} + +// Remove removes the provided key from the cache. +func (c *Cache) Remove(key Key) { + if c.cache == nil { + return + } + if ele, hit := c.cache[key]; hit { + c.removeElement(ele) + } +} + +// RemoveOldest removes the oldest item from the cache. +func (c *Cache) RemoveOldest() { + if c.cache == nil { + return + } + ele := c.ll.Back() + if ele != nil { + c.removeElement(ele) + } +} + +func (c *Cache) removeElement(e *list.Element) { + c.ll.Remove(e) + kv := e.Value.(*entry) + delete(c.cache, kv.key) + if c.OnEvicted != nil { + c.OnEvicted(kv.key, kv.value) + } +} + +// Len returns the number of items in the cache. +func (c *Cache) Len() int { + if c.cache == nil { + return 0 + } + return c.ll.Len() +} diff --git a/vendor/github.com/google/cadvisor/info/v1/container.go b/vendor/github.com/google/cadvisor/info/v1/container.go index bb4fc32..6e7e658 100644 --- a/vendor/github.com/google/cadvisor/info/v1/container.go +++ b/vendor/github.com/google/cadvisor/info/v1/container.go @@ -23,6 +23,8 @@ type CpuSpec struct { Limit uint64 `json:"limit"` MaxLimit uint64 `json:"max_limit"` Mask string `json:"mask,omitempty"` + Quota uint64 `json:"quota,omitempty"` + Period uint64 `json:"period,omitempty"` } type MemorySpec struct { @@ -397,6 +399,9 @@ type FsStats struct { // The block device name associated with the filesystem. Device string `json:"device,omitempty"` + // Type of the filesytem. + Type string `json:"type"` + // Number of bytes that can be consumed by the container on this filesystem. Limit uint64 `json:"capacity"` @@ -410,6 +415,9 @@ type FsStats struct { // Number of bytes available for non-root user. Available uint64 `json:"available"` + // Number of available Inodes + InodesFree uint64 `json:"inodes_free"` + // Number of reads completed // This is the total number of reads completed successfully. ReadsCompleted uint64 `json:"reads_completed"` diff --git a/vendor/github.com/google/cadvisor/info/v1/machine.go b/vendor/github.com/google/cadvisor/info/v1/machine.go index f26291c..74a5df4 100644 --- a/vendor/github.com/google/cadvisor/info/v1/machine.go +++ b/vendor/github.com/google/cadvisor/info/v1/machine.go @@ -20,6 +20,12 @@ type FsInfo struct { // Total number of bytes available on the filesystem. Capacity uint64 `json:"capacity"` + + // Type of device. + Type string `json:"type"` + + // Total number of inodes available on the filesystem. + Inodes uint64 `json:"inodes"` } type Node struct { @@ -115,10 +121,11 @@ type NetInfo struct { type CloudProvider string const ( - GCE CloudProvider = "GCE" - AWS = "AWS" - Baremetal = "Baremetal" - UnkownProvider = "Unknown" + GCE CloudProvider = "GCE" + AWS = "AWS" + Azure = "Azure" + Baremetal = "Baremetal" + UnknownProvider = "Unknown" ) type InstanceType string @@ -128,6 +135,12 @@ const ( UnknownInstance = "Unknown" ) +type InstanceID string + +const ( + UnNamedInstance InstanceID = "None" +) + type MachineInfo struct { // The number of cores in this machine. NumCores int `json:"num_cores"` @@ -165,6 +178,9 @@ type MachineInfo struct { // Type of cloud instance (e.g. GCE standard) the machine is. InstanceType InstanceType `json:"instance_type"` + + // ID of cloud instance (e.g. instance-1) given to it by the cloud provider. + InstanceID InstanceID `json:"instance_id"` } type VersionInfo struct { diff --git a/vendor/k8s.io/kubernetes/pkg/api/OWNERS b/vendor/k8s.io/kubernetes/pkg/api/OWNERS new file mode 100644 index 0000000..d28472e --- /dev/null +++ b/vendor/k8s.io/kubernetes/pkg/api/OWNERS @@ -0,0 +1,6 @@ +assignees: + - bgrant0607 + - erictune + - lavalamp + - smarterclayton + - thockin 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 27252ae..aa2712e 100644 --- a/vendor/k8s.io/kubernetes/pkg/api/deep_copy_generated.go +++ b/vendor/k8s.io/kubernetes/pkg/api/deep_copy_generated.go @@ -2400,6 +2400,7 @@ func DeepCopy_api_ReplicationControllerSpec(in ReplicationControllerSpec, out *R func DeepCopy_api_ReplicationControllerStatus(in ReplicationControllerStatus, out *ReplicationControllerStatus, c *conversion.Cloner) error { out.Replicas = in.Replicas + out.FullyLabeledReplicas = in.FullyLabeledReplicas out.ObservedGeneration = in.ObservedGeneration return nil } diff --git a/vendor/k8s.io/kubernetes/pkg/api/endpoints/util.go b/vendor/k8s.io/kubernetes/pkg/api/endpoints/util.go new file mode 100644 index 0000000..7758434 --- /dev/null +++ b/vendor/k8s.io/kubernetes/pkg/api/endpoints/util.go @@ -0,0 +1,236 @@ +/* +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 endpoints + +import ( + "bytes" + "crypto/md5" + "encoding/hex" + "hash" + "sort" + + "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/types" + hashutil "k8s.io/kubernetes/pkg/util/hash" +) + +const ( + // Its value is the json representation of map[string(IP)][HostRecord] + // example: '{"10.245.1.6":{"HostName":"my-webserver"}}' + PodHostnamesAnnotation = "endpoints.beta.kubernetes.io/hostnames-map" +) + +type HostRecord struct { + HostName string +} + +// RepackSubsets takes a slice of EndpointSubset objects, expands it to the full +// representation, and then repacks that into the canonical layout. This +// ensures that code which operates on these objects can rely on the common +// form for things like comparison. The result is a newly allocated slice. +func RepackSubsets(subsets []api.EndpointSubset) []api.EndpointSubset { + // First map each unique port definition to the sets of hosts that + // offer it. + allAddrs := map[addressKey]*api.EndpointAddress{} + portToAddrReadyMap := map[api.EndpointPort]addressSet{} + for i := range subsets { + for _, port := range subsets[i].Ports { + for k := range subsets[i].Addresses { + mapAddressByPort(&subsets[i].Addresses[k], port, true, allAddrs, portToAddrReadyMap) + } + for k := range subsets[i].NotReadyAddresses { + mapAddressByPort(&subsets[i].NotReadyAddresses[k], port, false, allAddrs, portToAddrReadyMap) + } + } + } + + // Next, map the sets of hosts to the sets of ports they offer. + // Go does not allow maps or slices as keys to maps, so we have + // to synthesize an artificial key and do a sort of 2-part + // associative entity. + type keyString string + keyToAddrReadyMap := map[keyString]addressSet{} + addrReadyMapKeyToPorts := map[keyString][]api.EndpointPort{} + for port, addrs := range portToAddrReadyMap { + key := keyString(hashAddresses(addrs)) + keyToAddrReadyMap[key] = addrs + addrReadyMapKeyToPorts[key] = append(addrReadyMapKeyToPorts[key], port) + } + + // Next, build the N-to-M association the API wants. + final := []api.EndpointSubset{} + for key, ports := range addrReadyMapKeyToPorts { + var readyAddrs, notReadyAddrs []api.EndpointAddress + for addr, ready := range keyToAddrReadyMap[key] { + if ready { + readyAddrs = append(readyAddrs, *addr) + } else { + notReadyAddrs = append(notReadyAddrs, *addr) + } + } + final = append(final, api.EndpointSubset{Addresses: readyAddrs, NotReadyAddresses: notReadyAddrs, Ports: ports}) + } + + // Finally, sort it. + return SortSubsets(final) +} + +// The sets of hosts must be de-duped, using IP+UID as the key. +type addressKey struct { + ip string + uid types.UID +} + +// mapAddressByPort adds an address into a map by its ports, registering the address with a unique pointer, and preserving +// any existing ready state. +func mapAddressByPort(addr *api.EndpointAddress, port api.EndpointPort, ready bool, allAddrs map[addressKey]*api.EndpointAddress, portToAddrReadyMap map[api.EndpointPort]addressSet) *api.EndpointAddress { + // use addressKey to distinguish between two endpoints that are identical addresses + // but may have come from different hosts, for attribution. For instance, Mesos + // assigns pods the node IP, but the pods are distinct. + key := addressKey{ip: addr.IP} + if addr.TargetRef != nil { + key.uid = addr.TargetRef.UID + } + + // Accumulate the address. The full EndpointAddress structure is preserved for use when + // we rebuild the subsets so that the final TargetRef has all of the necessary data. + existingAddress := allAddrs[key] + if existingAddress == nil { + // Make a copy so we don't write to the + // input args of this function. + existingAddress = &api.EndpointAddress{} + *existingAddress = *addr + allAddrs[key] = existingAddress + } + + // Remember that this port maps to this address. + if _, found := portToAddrReadyMap[port]; !found { + portToAddrReadyMap[port] = addressSet{} + } + // if we have not yet recorded this port for this address, or if the previous + // state was ready, write the current ready state. not ready always trumps + // ready. + if wasReady, found := portToAddrReadyMap[port][existingAddress]; !found || wasReady { + portToAddrReadyMap[port][existingAddress] = ready + } + return existingAddress +} + +type addressSet map[*api.EndpointAddress]bool + +type addrReady struct { + addr *api.EndpointAddress + ready bool +} + +func hashAddresses(addrs addressSet) string { + // Flatten the list of addresses into a string so it can be used as a + // map key. Unfortunately, DeepHashObject is implemented in terms of + // spew, and spew does not handle non-primitive map keys well. So + // first we collapse it into a slice, sort the slice, then hash that. + slice := make([]addrReady, 0, len(addrs)) + for k, ready := range addrs { + slice = append(slice, addrReady{k, ready}) + } + sort.Sort(addrsReady(slice)) + hasher := md5.New() + hashutil.DeepHashObject(hasher, slice) + return hex.EncodeToString(hasher.Sum(nil)[0:]) +} + +func lessAddrReady(a, b addrReady) bool { + // ready is not significant to hashing since we can't have duplicate addresses + return LessEndpointAddress(a.addr, b.addr) +} + +type addrsReady []addrReady + +func (sl addrsReady) Len() int { return len(sl) } +func (sl addrsReady) Swap(i, j int) { sl[i], sl[j] = sl[j], sl[i] } +func (sl addrsReady) Less(i, j int) bool { + return lessAddrReady(sl[i], sl[j]) +} + +func LessEndpointAddress(a, b *api.EndpointAddress) bool { + ipComparison := bytes.Compare([]byte(a.IP), []byte(b.IP)) + if ipComparison != 0 { + return ipComparison < 0 + } + if b.TargetRef == nil { + return false + } + if a.TargetRef == nil { + return true + } + return a.TargetRef.UID < b.TargetRef.UID +} + +type addrPtrsByIpAndUID []*api.EndpointAddress + +func (sl addrPtrsByIpAndUID) Len() int { return len(sl) } +func (sl addrPtrsByIpAndUID) Swap(i, j int) { sl[i], sl[j] = sl[j], sl[i] } +func (sl addrPtrsByIpAndUID) Less(i, j int) bool { + return LessEndpointAddress(sl[i], sl[j]) +} + +// SortSubsets sorts an array of EndpointSubset objects in place. For ease of +// use it returns the input slice. +func SortSubsets(subsets []api.EndpointSubset) []api.EndpointSubset { + for i := range subsets { + ss := &subsets[i] + sort.Sort(addrsByIpAndUID(ss.Addresses)) + sort.Sort(addrsByIpAndUID(ss.NotReadyAddresses)) + sort.Sort(portsByHash(ss.Ports)) + } + sort.Sort(subsetsByHash(subsets)) + return subsets +} + +func hashObject(hasher hash.Hash, obj interface{}) []byte { + hashutil.DeepHashObject(hasher, obj) + return hasher.Sum(nil) +} + +type subsetsByHash []api.EndpointSubset + +func (sl subsetsByHash) Len() int { return len(sl) } +func (sl subsetsByHash) Swap(i, j int) { sl[i], sl[j] = sl[j], sl[i] } +func (sl subsetsByHash) Less(i, j int) bool { + hasher := md5.New() + h1 := hashObject(hasher, sl[i]) + h2 := hashObject(hasher, sl[j]) + return bytes.Compare(h1, h2) < 0 +} + +type addrsByIpAndUID []api.EndpointAddress + +func (sl addrsByIpAndUID) Len() int { return len(sl) } +func (sl addrsByIpAndUID) Swap(i, j int) { sl[i], sl[j] = sl[j], sl[i] } +func (sl addrsByIpAndUID) Less(i, j int) bool { + return LessEndpointAddress(&sl[i], &sl[j]) +} + +type portsByHash []api.EndpointPort + +func (sl portsByHash) Len() int { return len(sl) } +func (sl portsByHash) Swap(i, j int) { sl[i], sl[j] = sl[j], sl[i] } +func (sl portsByHash) Less(i, j int) bool { + hasher := md5.New() + h1 := hashObject(hasher, sl[i]) + h2 := hashObject(hasher, sl[j]) + return bytes.Compare(h1, h2) < 0 +} diff --git a/vendor/k8s.io/kubernetes/pkg/api/helpers.go b/vendor/k8s.io/kubernetes/pkg/api/helpers.go index b037b53..aed3c5a 100644 --- a/vendor/k8s.io/kubernetes/pkg/api/helpers.go +++ b/vendor/k8s.io/kubernetes/pkg/api/helpers.go @@ -127,6 +127,16 @@ func IsStandardContainerResourceName(str string) bool { return standardContainerResources.Has(str) } +var standardLimitRangeTypes = sets.NewString( + string(LimitTypePod), + string(LimitTypeContainer), +) + +// IsStandardLimitRangeType returns true if the type is Pod or Container +func IsStandardLimitRangeType(str string) bool { + return standardLimitRangeTypes.Has(str) +} + var standardQuotaResources = sets.NewString( string(ResourceCPU), string(ResourceMemory), @@ -140,6 +150,7 @@ var standardQuotaResources = sets.NewString( string(ResourceReplicationControllers), string(ResourceSecrets), string(ResourcePersistentVolumeClaims), + string(ResourceConfigMaps), ) // IsStandardQuotaResourceName returns true if the resource is known to @@ -160,6 +171,7 @@ var standardResources = sets.NewString( string(ResourceServices), string(ResourceReplicationControllers), string(ResourceSecrets), + string(ResourceConfigMaps), string(ResourcePersistentVolumeClaims), string(ResourceStorage), ) @@ -175,6 +187,7 @@ var integerResources = sets.NewString( string(ResourceServices), string(ResourceReplicationControllers), string(ResourceSecrets), + string(ResourceConfigMaps), string(ResourcePersistentVolumeClaims), ) diff --git a/vendor/k8s.io/kubernetes/pkg/api/pod/util.go b/vendor/k8s.io/kubernetes/pkg/api/pod/util.go new file mode 100644 index 0000000..6b00c7e --- /dev/null +++ b/vendor/k8s.io/kubernetes/pkg/api/pod/util.go @@ -0,0 +1,59 @@ +/* +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 pod + +import ( + "fmt" + + "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/util/intstr" +) + +const ( + // The annotation value is a string specifying the hostname to be used for the pod e.g 'my-webserver-1' + PodHostnameAnnotation = "pod.beta.kubernetes.io/hostname" + + // The annotation value is a string specifying the subdomain e.g. "my-web-service" + // If specified, on the the pod itself, ".my-web-service..svc." would resolve to + // the pod's IP. + // If there is a headless service named "my-web-service" in the same namespace as the pod, then, + // .my-web-service..svc." would be resolved by the cluster DNS Server. + PodSubdomainAnnotation = "pod.beta.kubernetes.io/subdomain" +) + +// FindPort locates the container port for the given pod and portName. If the +// targetPort is a number, use that. If the targetPort is a string, look that +// string up in all named ports in all containers in the target pod. If no +// match is found, fail. +func FindPort(pod *api.Pod, svcPort *api.ServicePort) (int, error) { + portName := svcPort.TargetPort + switch portName.Type { + case intstr.String: + name := portName.StrVal + for _, container := range pod.Spec.Containers { + for _, port := range container.Ports { + if port.Name == name && port.Protocol == svcPort.Protocol { + return port.ContainerPort, nil + } + } + } + case intstr.Int: + return portName.IntValue(), nil + } + + return 0, fmt.Errorf("no suitable port for manifest: %s", pod.UID) +} diff --git a/vendor/k8s.io/kubernetes/pkg/api/service/annotations.go b/vendor/k8s.io/kubernetes/pkg/api/service/annotations.go new file mode 100644 index 0000000..9d57fa4 --- /dev/null +++ b/vendor/k8s.io/kubernetes/pkg/api/service/annotations.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 service + +const ( + // AnnotationLoadBalancerSourceRangesKey is the key of the annotation on a service to set allowed ingress ranges on their LoadBalancers + // + // It should be a comma-separated list of CIDRs, e.g. `0.0.0.0/0` to + // allow full access (the default) or `18.0.0.0/8,56.0.0.0/8` to allow + // access only from the CIDRs currently allocated to MIT & the USPS. + // + // Not all cloud providers support this annotation, though AWS & GCE do. + AnnotationLoadBalancerSourceRangesKey = "service.beta.kubernetes.io/load-balancer-source-ranges" +) diff --git a/vendor/k8s.io/kubernetes/pkg/api/service/util.go b/vendor/k8s.io/kubernetes/pkg/api/service/util.go new file mode 100644 index 0000000..a77e5b9 --- /dev/null +++ b/vendor/k8s.io/kubernetes/pkg/api/service/util.go @@ -0,0 +1,54 @@ +/* +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 service + +import ( + "fmt" + "strings" + + netsets "k8s.io/kubernetes/pkg/util/net/sets" +) + +const ( + defaultLoadBalancerSourceRanges = "0.0.0.0/0" +) + +// IsAllowAll checks whether the netsets.IPNet allows traffic from 0.0.0.0/0 +func IsAllowAll(ipnets netsets.IPNet) bool { + for _, s := range ipnets.StringSlice() { + if s == "0.0.0.0/0" { + return true + } + } + return false +} + +// GetLoadBalancerSourceRanges verifies and parses the AnnotationLoadBalancerSourceRangesKey annotation from a service, +// extracting the source ranges to allow, and if not present returns a default (allow-all) value. +func GetLoadBalancerSourceRanges(annotations map[string]string) (netsets.IPNet, error) { + val := annotations[AnnotationLoadBalancerSourceRangesKey] + val = strings.TrimSpace(val) + if val == "" { + val = defaultLoadBalancerSourceRanges + } + specs := strings.Split(val, ",") + ipnets, err := netsets.ParseIPNets(specs...) + if err != nil { + return nil, fmt.Errorf("Service annotation %s:%s is not valid. Expecting a comma-separated list of source IP ranges. For example, 10.0.0.0/24,192.168.2.0/24", AnnotationLoadBalancerSourceRangesKey, val) + } + return ipnets, nil +} diff --git a/vendor/k8s.io/kubernetes/pkg/api/types.generated.go b/vendor/k8s.io/kubernetes/pkg/api/types.generated.go index e90d805..b4ccb56 100644 --- a/vendor/k8s.io/kubernetes/pkg/api/types.generated.go +++ b/vendor/k8s.io/kubernetes/pkg/api/types.generated.go @@ -26953,13 +26953,14 @@ func (x *ReplicationControllerStatus) CodecEncodeSelf(e *codec1978.Encoder) { } else { yysep2 := !z.EncBinary() yy2arr2 := z.EncBasicHandle().StructToArray - var yyq2 [2]bool + var yyq2 [3]bool _, _, _ = yysep2, yyq2, yy2arr2 const yyr2 bool = false - yyq2[1] = x.ObservedGeneration != 0 + yyq2[1] = x.FullyLabeledReplicas != 0 + yyq2[2] = x.ObservedGeneration != 0 var yynn2 int if yyr2 || yy2arr2 { - r.EncodeArrayStart(2) + r.EncodeArrayStart(3) } else { yynn2 = 1 for _, b := range yyq2 { @@ -26996,7 +26997,7 @@ func (x *ReplicationControllerStatus) CodecEncodeSelf(e *codec1978.Encoder) { _ = yym7 if false { } else { - r.EncodeInt(int64(x.ObservedGeneration)) + r.EncodeInt(int64(x.FullyLabeledReplicas)) } } else { r.EncodeInt(0) @@ -27004,11 +27005,36 @@ func (x *ReplicationControllerStatus) CodecEncodeSelf(e *codec1978.Encoder) { } else { if yyq2[1] { z.EncSendContainerState(codecSelfer_containerMapKey1234) - r.EncodeString(codecSelferC_UTF81234, string("observedGeneration")) + r.EncodeString(codecSelferC_UTF81234, string("fullyLabeledReplicas")) z.EncSendContainerState(codecSelfer_containerMapValue1234) yym8 := z.EncBinary() _ = yym8 if false { + } else { + r.EncodeInt(int64(x.FullyLabeledReplicas)) + } + } + } + if yyr2 || yy2arr2 { + z.EncSendContainerState(codecSelfer_containerArrayElem1234) + if yyq2[2] { + yym10 := z.EncBinary() + _ = yym10 + if false { + } else { + r.EncodeInt(int64(x.ObservedGeneration)) + } + } else { + r.EncodeInt(0) + } + } else { + if yyq2[2] { + z.EncSendContainerState(codecSelfer_containerMapKey1234) + r.EncodeString(codecSelferC_UTF81234, string("observedGeneration")) + z.EncSendContainerState(codecSelfer_containerMapValue1234) + yym11 := z.EncBinary() + _ = yym11 + if false { } else { r.EncodeInt(int64(x.ObservedGeneration)) } @@ -27081,6 +27107,12 @@ func (x *ReplicationControllerStatus) codecDecodeSelfFromMap(l int, d *codec1978 } else { x.Replicas = int(r.DecodeInt(codecSelferBitsize1234)) } + case "fullyLabeledReplicas": + if r.TryDecodeAsNil() { + x.FullyLabeledReplicas = 0 + } else { + x.FullyLabeledReplicas = int(r.DecodeInt(codecSelferBitsize1234)) + } case "observedGeneration": if r.TryDecodeAsNil() { x.ObservedGeneration = 0 @@ -27098,16 +27130,16 @@ func (x *ReplicationControllerStatus) codecDecodeSelfFromArray(l int, d *codec19 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 + var yyj7 int + var yyb7 bool + var yyhl7 bool = l >= 0 + yyj7++ + if yyhl7 { + yyb7 = yyj7 > l } else { - yyb6 = r.CheckBreak() + yyb7 = r.CheckBreak() } - if yyb6 { + if yyb7 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -27117,13 +27149,29 @@ func (x *ReplicationControllerStatus) codecDecodeSelfFromArray(l int, d *codec19 } else { x.Replicas = int(r.DecodeInt(codecSelferBitsize1234)) } - yyj6++ - if yyhl6 { - yyb6 = yyj6 > l + yyj7++ + if yyhl7 { + yyb7 = yyj7 > l } else { - yyb6 = r.CheckBreak() + yyb7 = r.CheckBreak() } - if yyb6 { + if yyb7 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) + return + } + z.DecSendContainerState(codecSelfer_containerArrayElem1234) + if r.TryDecodeAsNil() { + x.FullyLabeledReplicas = 0 + } else { + x.FullyLabeledReplicas = int(r.DecodeInt(codecSelferBitsize1234)) + } + yyj7++ + if yyhl7 { + yyb7 = yyj7 > l + } else { + yyb7 = r.CheckBreak() + } + if yyb7 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -27134,17 +27182,17 @@ func (x *ReplicationControllerStatus) codecDecodeSelfFromArray(l int, d *codec19 x.ObservedGeneration = int64(r.DecodeInt(64)) } for { - yyj6++ - if yyhl6 { - yyb6 = yyj6 > l + yyj7++ + if yyhl7 { + yyb7 = yyj7 > l } else { - yyb6 = r.CheckBreak() + yyb7 = r.CheckBreak() } - if yyb6 { + if yyb7 { break } z.DecSendContainerState(codecSelfer_containerArrayElem1234) - z.DecStructFieldNotFound(yyj6-1, "") + z.DecStructFieldNotFound(yyj7-1, "") } z.DecSendContainerState(codecSelfer_containerArrayEnd1234) } @@ -51389,7 +51437,7 @@ func (x codecSelfer1234) decSliceReplicationController(v *[]ReplicationControlle yyrg1 := len(yyv1) > 0 yyv21 := yyv1 - yyrl1, yyrt1 = z.DecInferLen(yyl1, z.DecBasicHandle().MaxInitLen, 232) + yyrl1, yyrt1 = z.DecInferLen(yyl1, z.DecBasicHandle().MaxInitLen, 240) if yyrt1 { if yyrl1 <= cap(yyv1) { yyv1 = yyv1[:yyrl1] diff --git a/vendor/k8s.io/kubernetes/pkg/api/types.go b/vendor/k8s.io/kubernetes/pkg/api/types.go index b8693cf..a82aa45 100644 --- a/vendor/k8s.io/kubernetes/pkg/api/types.go +++ b/vendor/k8s.io/kubernetes/pkg/api/types.go @@ -742,7 +742,7 @@ type VolumeMount struct { Name string `json:"name"` // Optional: Defaults to false (read-write). ReadOnly bool `json:"readOnly,omitempty"` - // Required. + // Required. Must not contain ':'. MountPath string `json:"mountPath"` } @@ -1380,6 +1380,9 @@ type ReplicationControllerStatus struct { // Replicas is the number of actual replicas. Replicas int `json:"replicas"` + // The number of pods that have labels matching the labels of the pod template of the replication controller. + FullyLabeledReplicas int `json:"fullyLabeledReplicas,omitempty"` + // ObservedGeneration is the most recent generation observed by the controller. ObservedGeneration int64 `json:"observedGeneration,omitempty"` } @@ -2187,6 +2190,8 @@ const ( ResourceQuotas ResourceName = "resourcequotas" // ResourceSecrets, number ResourceSecrets ResourceName = "secrets" + // ResourceConfigMaps, number + ResourceConfigMaps ResourceName = "configmaps" // ResourcePersistentVolumeClaims, number ResourcePersistentVolumeClaims ResourceName = "persistentvolumeclaims" // CPU request, in cores. (500m = .5 cores) 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 49155e6..5d35043 100644 --- a/vendor/k8s.io/kubernetes/pkg/api/unversioned/group_version.go +++ b/vendor/k8s.io/kubernetes/pkg/api/unversioned/group_version.go @@ -22,6 +22,21 @@ import ( "strings" ) +// ParseResourceArg takes the common style of string which may be either `resource.group.com` or `resource.version.group.com` +// and parses it out into both possibilities. This code takes no responsibility for knowing which representation was intended +// but with a knowledge of all GroupVersions, calling code can take a very good guess. If there are only two segments, then +// `*GroupVersionResource` is nil. +// `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 { + gvr = &GroupVersionResource{Group: s[2], Version: s[1], Resource: s[0]} + } + + return gvr, ParseGroupResource(arg) +} + // GroupResource specifies a Group and a Resource, but does not force a version. This is useful for identifying // concepts during lookup stages without having partially valid types // diff --git a/vendor/k8s.io/kubernetes/pkg/api/unversioned/helpers.go b/vendor/k8s.io/kubernetes/pkg/api/unversioned/helpers.go index b26948b..b71297e 100644 --- a/vendor/k8s.io/kubernetes/pkg/api/unversioned/helpers.go +++ b/vendor/k8s.io/kubernetes/pkg/api/unversioned/helpers.go @@ -25,6 +25,7 @@ import ( // LabelSelectorAsSelector converts the LabelSelector api type into a struct that implements // labels.Selector +// Note: This function should be kept in sync with the selector methods in pkg/labels/selector.go func LabelSelectorAsSelector(ps *LabelSelector) (labels.Selector, error) { if ps == nil { return labels.Nothing(), nil @@ -34,7 +35,7 @@ func LabelSelectorAsSelector(ps *LabelSelector) (labels.Selector, error) { } selector := labels.NewSelector() for k, v := range ps.MatchLabels { - r, err := labels.NewRequirement(k, labels.InOperator, sets.NewString(v)) + r, err := labels.NewRequirement(k, labels.EqualsOperator, sets.NewString(v)) if err != nil { return nil, err } @@ -63,6 +64,55 @@ func LabelSelectorAsSelector(ps *LabelSelector) (labels.Selector, error) { return selector, nil } +// ParseToLabelSelector parses a string representing a selector into a LabelSelector object. +// Note: This function should be kept in sync with the parser in pkg/labels/selector.go +func ParseToLabelSelector(selector string) (*LabelSelector, error) { + reqs, err := labels.ParseToRequirements(selector) + if err != nil { + return nil, fmt.Errorf("couldn't parse the selector string \"%s\": %v", selector, err) + } + + labelSelector := &LabelSelector{ + MatchLabels: map[string]string{}, + MatchExpressions: []LabelSelectorRequirement{}, + } + for _, req := range reqs { + var op LabelSelectorOperator + switch req.Operator() { + case labels.EqualsOperator, labels.DoubleEqualsOperator: + vals := req.Values() + if vals.Len() != 1 { + return nil, fmt.Errorf("equals operator must have exactly one value") + } + val, ok := vals.PopAny() + if !ok { + return nil, fmt.Errorf("equals operator has exactly one value but it cannot be retrieved") + } + labelSelector.MatchLabels[req.Key()] = val + continue + case labels.InOperator: + op = LabelSelectorOpIn + case labels.NotInOperator: + op = LabelSelectorOpNotIn + case labels.ExistsOperator: + op = LabelSelectorOpExists + case labels.DoesNotExistOperator: + op = LabelSelectorOpDoesNotExist + case labels.GreaterThanOperator, labels.LessThanOperator: + // Adding a separate case for these operators to indicate that this is deliberate + return nil, fmt.Errorf("%q isn't supported in label selectors", req.Operator()) + default: + return nil, fmt.Errorf("%q is not a valid label selector operator", req.Operator()) + } + labelSelector.MatchExpressions = append(labelSelector.MatchExpressions, LabelSelectorRequirement{ + Key: req.Key(), + Operator: op, + Values: req.Values().List(), + }) + } + return labelSelector, nil +} + // SetAsLabelSelector converts the labels.Set object into a LabelSelector api object. func SetAsLabelSelector(ls labels.Set) *LabelSelector { if ls == nil { @@ -92,3 +142,13 @@ func FormatLabelSelector(labelSelector *LabelSelector) string { } return l } + +func ExtractGroupVersions(l *APIGroupList) []string { + var groupVersions []string + for _, g := range l.Groups { + for _, gv := range g.Versions { + groupVersions = append(groupVersions, gv.GroupVersion) + } + } + return groupVersions +} diff --git a/vendor/k8s.io/kubernetes/pkg/api/unversioned/types.go b/vendor/k8s.io/kubernetes/pkg/api/unversioned/types.go index 4d7a8f7..786be86 100644 --- a/vendor/k8s.io/kubernetes/pkg/api/unversioned/types.go +++ b/vendor/k8s.io/kubernetes/pkg/api/unversioned/types.go @@ -35,13 +35,13 @@ type TypeMeta struct { // Servers may infer this from the endpoint the client submits requests to. // Cannot be updated. // In CamelCase. - // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds + // More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#types-kinds Kind string `json:"kind,omitempty"` // APIVersion defines the versioned schema of this representation of an object. // Servers should convert recognized schemas to the latest internal value, and // may reject unrecognized values. - // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources + // More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#resources APIVersion string `json:"apiVersion,omitempty"` } @@ -58,7 +58,7 @@ type ListMeta struct { // Value must be treated as opaque by clients and passed unmodified back to the server. // Populated by the system. // Read-only. - // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#concurrency-control-and-consistency + // More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#concurrency-control-and-consistency ResourceVersion string `json:"resourceVersion,omitempty"` } @@ -75,12 +75,12 @@ type ExportOptions struct { type Status struct { TypeMeta `json:",inline"` // Standard list metadata. - // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds + // More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#types-kinds ListMeta `json:"metadata,omitempty"` // Status of the operation. // One of: "Success" or "Failure". - // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#spec-and-status + // More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#spec-and-status Status string `json:"status,omitempty"` // A human-readable description of the status of this operation. Message string `json:"message,omitempty"` @@ -112,7 +112,7 @@ type StatusDetails struct { Group string `json:"group,omitempty"` // The kind attribute of the resource associated with the status StatusReason. // On some operations may differ from the requested resource Kind. - // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds + // More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#types-kinds Kind string `json:"kind,omitempty"` // The Causes array includes more details associated with the StatusReason // failure. Not all StatusReasons may provide detailed causes. 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 e0e74da..b45a46e 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 @@ -123,7 +123,7 @@ func (LabelSelectorRequirement) SwaggerDoc() map[string]string { var map_ListMeta = map[string]string{ "": "ListMeta describes metadata that synthetic resources must have, including lists and various status objects. A resource may have only one of {ObjectMeta, ListMeta}.", "selfLink": "SelfLink is a URL representing this object. Populated by the system. Read-only.", - "resourceVersion": "String that identifies the server's internal version of this object that can be used by clients to determine when objects have changed. Value must be treated as opaque by clients and passed unmodified back to the server. Populated by the system. Read-only. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#concurrency-control-and-consistency", + "resourceVersion": "String that identifies the server's internal version of this object that can be used by clients to determine when objects have changed. Value must be treated as opaque by clients and passed unmodified back to the server. Populated by the system. Read-only. More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#concurrency-control-and-consistency", } func (ListMeta) SwaggerDoc() map[string]string { @@ -159,8 +159,8 @@ func (ServerAddressByClientCIDR) SwaggerDoc() map[string]string { var map_Status = map[string]string{ "": "Status is a return value for calls that don't return other objects.", - "metadata": "Standard list metadata. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds", - "status": "Status of the operation. One of: \"Success\" or \"Failure\". More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#spec-and-status", + "metadata": "Standard list metadata. More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#types-kinds", + "status": "Status of the operation. One of: \"Success\" or \"Failure\". More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#spec-and-status", "message": "A human-readable description of the status of this operation.", "reason": "A machine-readable description of why this operation is in the \"Failure\" status. If this value is empty there is no information available. A Reason clarifies an HTTP status code but does not override it.", "details": "Extended data associated with the reason. Each reason may define its own extended details. This field is optional and the data returned is not guaranteed to conform to any schema except that defined by the reason type.", @@ -186,7 +186,7 @@ var map_StatusDetails = map[string]string{ "": "StatusDetails is a set of additional properties that MAY be set by the server to provide additional information about a response. The Reason field of a Status object defines what attributes will be set. Clients must ignore fields that do not match the defined type of each attribute, and should assume that any attribute may be empty, invalid, or under defined.", "name": "The name attribute of the resource associated with the status StatusReason (when there is a single name which can be described).", "group": "The group attribute of the resource associated with the status StatusReason.", - "kind": "The kind attribute of the resource associated with the status StatusReason. On some operations may differ from the requested resource Kind. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds", + "kind": "The kind attribute of the resource associated with the status StatusReason. On some operations may differ from the requested resource Kind. More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#types-kinds", "causes": "The Causes array includes more details associated with the StatusReason failure. Not all StatusReasons may provide detailed causes.", "retryAfterSeconds": "If specified, the time in seconds before the operation should be retried.", } @@ -197,8 +197,8 @@ func (StatusDetails) SwaggerDoc() map[string]string { var map_TypeMeta = map[string]string{ "": "TypeMeta describes an individual object in an API response or request with strings representing the type of the object and its API schema version. Structures that are versioned or persisted should inline TypeMeta.", - "kind": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds", - "apiVersion": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources", + "kind": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#types-kinds", + "apiVersion": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#resources", } func (TypeMeta) SwaggerDoc() map[string]string { 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 8cb6297..687da42 100644 --- a/vendor/k8s.io/kubernetes/pkg/api/v1/conversion_generated.go +++ b/vendor/k8s.io/kubernetes/pkg/api/v1/conversion_generated.go @@ -2598,6 +2598,7 @@ func autoConvert_api_ReplicationControllerStatus_To_v1_ReplicationControllerStat defaulting.(func(*api.ReplicationControllerStatus))(in) } out.Replicas = int32(in.Replicas) + out.FullyLabeledReplicas = int32(in.FullyLabeledReplicas) out.ObservedGeneration = in.ObservedGeneration return nil } @@ -5836,6 +5837,7 @@ func autoConvert_v1_ReplicationControllerStatus_To_api_ReplicationControllerStat defaulting.(func(*ReplicationControllerStatus))(in) } out.Replicas = int(in.Replicas) + out.FullyLabeledReplicas = int(in.FullyLabeledReplicas) out.ObservedGeneration = in.ObservedGeneration return 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 7916939..1252bf4 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 @@ -2031,6 +2031,7 @@ func deepCopy_v1_ReplicationControllerSpec(in ReplicationControllerSpec, out *Re func deepCopy_v1_ReplicationControllerStatus(in ReplicationControllerStatus, out *ReplicationControllerStatus, c *conversion.Cloner) error { out.Replicas = in.Replicas + out.FullyLabeledReplicas = in.FullyLabeledReplicas out.ObservedGeneration = in.ObservedGeneration return nil } 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 92aaa07..1dc4938 100644 --- a/vendor/k8s.io/kubernetes/pkg/api/v1/types.generated.go +++ b/vendor/k8s.io/kubernetes/pkg/api/v1/types.generated.go @@ -26683,13 +26683,14 @@ func (x *ReplicationControllerStatus) CodecEncodeSelf(e *codec1978.Encoder) { } else { yysep2 := !z.EncBinary() yy2arr2 := z.EncBasicHandle().StructToArray - var yyq2 [2]bool + var yyq2 [3]bool _, _, _ = yysep2, yyq2, yy2arr2 const yyr2 bool = false - yyq2[1] = x.ObservedGeneration != 0 + yyq2[1] = x.FullyLabeledReplicas != 0 + yyq2[2] = x.ObservedGeneration != 0 var yynn2 int if yyr2 || yy2arr2 { - r.EncodeArrayStart(2) + r.EncodeArrayStart(3) } else { yynn2 = 1 for _, b := range yyq2 { @@ -26726,7 +26727,7 @@ func (x *ReplicationControllerStatus) CodecEncodeSelf(e *codec1978.Encoder) { _ = yym7 if false { } else { - r.EncodeInt(int64(x.ObservedGeneration)) + r.EncodeInt(int64(x.FullyLabeledReplicas)) } } else { r.EncodeInt(0) @@ -26734,11 +26735,36 @@ func (x *ReplicationControllerStatus) CodecEncodeSelf(e *codec1978.Encoder) { } else { if yyq2[1] { z.EncSendContainerState(codecSelfer_containerMapKey1234) - r.EncodeString(codecSelferC_UTF81234, string("observedGeneration")) + r.EncodeString(codecSelferC_UTF81234, string("fullyLabeledReplicas")) z.EncSendContainerState(codecSelfer_containerMapValue1234) yym8 := z.EncBinary() _ = yym8 if false { + } else { + r.EncodeInt(int64(x.FullyLabeledReplicas)) + } + } + } + if yyr2 || yy2arr2 { + z.EncSendContainerState(codecSelfer_containerArrayElem1234) + if yyq2[2] { + yym10 := z.EncBinary() + _ = yym10 + if false { + } else { + r.EncodeInt(int64(x.ObservedGeneration)) + } + } else { + r.EncodeInt(0) + } + } else { + if yyq2[2] { + z.EncSendContainerState(codecSelfer_containerMapKey1234) + r.EncodeString(codecSelferC_UTF81234, string("observedGeneration")) + z.EncSendContainerState(codecSelfer_containerMapValue1234) + yym11 := z.EncBinary() + _ = yym11 + if false { } else { r.EncodeInt(int64(x.ObservedGeneration)) } @@ -26811,6 +26837,12 @@ func (x *ReplicationControllerStatus) codecDecodeSelfFromMap(l int, d *codec1978 } else { x.Replicas = int32(r.DecodeInt(32)) } + case "fullyLabeledReplicas": + if r.TryDecodeAsNil() { + x.FullyLabeledReplicas = 0 + } else { + x.FullyLabeledReplicas = int32(r.DecodeInt(32)) + } case "observedGeneration": if r.TryDecodeAsNil() { x.ObservedGeneration = 0 @@ -26828,16 +26860,16 @@ func (x *ReplicationControllerStatus) codecDecodeSelfFromArray(l int, d *codec19 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 + var yyj7 int + var yyb7 bool + var yyhl7 bool = l >= 0 + yyj7++ + if yyhl7 { + yyb7 = yyj7 > l } else { - yyb6 = r.CheckBreak() + yyb7 = r.CheckBreak() } - if yyb6 { + if yyb7 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -26847,13 +26879,29 @@ func (x *ReplicationControllerStatus) codecDecodeSelfFromArray(l int, d *codec19 } else { x.Replicas = int32(r.DecodeInt(32)) } - yyj6++ - if yyhl6 { - yyb6 = yyj6 > l + yyj7++ + if yyhl7 { + yyb7 = yyj7 > l } else { - yyb6 = r.CheckBreak() + yyb7 = r.CheckBreak() } - if yyb6 { + if yyb7 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) + return + } + z.DecSendContainerState(codecSelfer_containerArrayElem1234) + if r.TryDecodeAsNil() { + x.FullyLabeledReplicas = 0 + } else { + x.FullyLabeledReplicas = int32(r.DecodeInt(32)) + } + yyj7++ + if yyhl7 { + yyb7 = yyj7 > l + } else { + yyb7 = r.CheckBreak() + } + if yyb7 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -26864,17 +26912,17 @@ func (x *ReplicationControllerStatus) codecDecodeSelfFromArray(l int, d *codec19 x.ObservedGeneration = int64(r.DecodeInt(64)) } for { - yyj6++ - if yyhl6 { - yyb6 = yyj6 > l + yyj7++ + if yyhl7 { + yyb7 = yyj7 > l } else { - yyb6 = r.CheckBreak() + yyb7 = r.CheckBreak() } - if yyb6 { + if yyb7 { break } z.DecSendContainerState(codecSelfer_containerArrayElem1234) - z.DecStructFieldNotFound(yyj6-1, "") + z.DecStructFieldNotFound(yyj7-1, "") } z.DecSendContainerState(codecSelfer_containerArrayEnd1234) } diff --git a/vendor/k8s.io/kubernetes/pkg/api/v1/types.go b/vendor/k8s.io/kubernetes/pkg/api/v1/types.go index 0dea6b4..12ad831 100644 --- a/vendor/k8s.io/kubernetes/pkg/api/v1/types.go +++ b/vendor/k8s.io/kubernetes/pkg/api/v1/types.go @@ -71,7 +71,7 @@ type ObjectMeta struct { // automatically. Name is primarily intended for creation idempotence and configuration // definition. // Cannot be updated. - // More info: http://releases.k8s.io/HEAD/docs/user-guide/identifiers.md#names + // More info: http://releases.k8s.io/release-1.2/docs/user-guide/identifiers.md#names Name string `json:"name,omitempty"` // GenerateName is an optional prefix, used by the server, to generate a unique @@ -88,7 +88,7 @@ type ObjectMeta struct { // should retry (optionally after the time indicated in the Retry-After header). // // Applied only if Name is not specified. - // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#idempotency + // More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#idempotency GenerateName string `json:"generateName,omitempty"` // Namespace defines the space within each name must be unique. An empty namespace is @@ -98,7 +98,7 @@ type ObjectMeta struct { // // Must be a DNS_LABEL. // Cannot be updated. - // More info: http://releases.k8s.io/HEAD/docs/user-guide/namespaces.md + // More info: http://releases.k8s.io/release-1.2/docs/user-guide/namespaces.md Namespace string `json:"namespace,omitempty"` // SelfLink is a URL representing this object. @@ -112,7 +112,7 @@ type ObjectMeta struct { // // Populated by the system. // Read-only. - // More info: http://releases.k8s.io/HEAD/docs/user-guide/identifiers.md#uids + // More info: http://releases.k8s.io/release-1.2/docs/user-guide/identifiers.md#uids UID types.UID `json:"uid,omitempty"` // An opaque value that represents the internal version of this object that can @@ -124,7 +124,7 @@ type ObjectMeta struct { // Populated by the system. // Read-only. // Value must be treated as opaque by clients and . - // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#concurrency-control-and-consistency + // More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#concurrency-control-and-consistency ResourceVersion string `json:"resourceVersion,omitempty"` // A sequence number representing a specific generation of the desired state. @@ -138,7 +138,7 @@ type ObjectMeta struct { // Populated by the system. // Read-only. // Null for lists. - // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata + // More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#metadata CreationTimestamp unversioned.Time `json:"creationTimestamp,omitempty"` // DeletionTimestamp is RFC 3339 date and time at which this resource will be deleted. This @@ -154,7 +154,7 @@ type ObjectMeta struct { // // Populated by the system when a graceful deletion is requested. // Read-only. - // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata + // More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#metadata DeletionTimestamp *unversioned.Time `json:"deletionTimestamp,omitempty"` // Number of seconds allowed for this object to gracefully terminate before @@ -166,14 +166,14 @@ type ObjectMeta struct { // Map of string keys and values that can be used to organize and categorize // (scope and select) objects. May match selectors of replication controllers // and services. - // More info: http://releases.k8s.io/HEAD/docs/user-guide/labels.md + // More info: http://releases.k8s.io/release-1.2/docs/user-guide/labels.md // TODO: replace map[string]string with labels.LabelSet type Labels map[string]string `json:"labels,omitempty"` // Annotations is an unstructured key value map stored with a resource that may be // set by external tools to store and retrieve arbitrary metadata. They are not // queryable and should be preserved when modifying objects. - // More info: http://releases.k8s.io/HEAD/docs/user-guide/annotations.md + // More info: http://releases.k8s.io/release-1.2/docs/user-guide/annotations.md Annotations map[string]string `json:"annotations,omitempty"` } @@ -188,7 +188,7 @@ const ( type Volume struct { // 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 + // More info: http://releases.k8s.io/release-1.2/docs/user-guide/identifiers.md#names Name string `json:"name"` // VolumeSource represents the location and type of the mounted volume. // If not specified, the Volume is implied to be an EmptyDir. @@ -203,50 +203,50 @@ type VolumeSource struct { // machine that is directly exposed to the container. This is generally // used for system agents or other privileged things that are allowed // to see the host machine. Most containers will NOT need this. - // More info: http://releases.k8s.io/HEAD/docs/user-guide/volumes.md#hostpath + // More info: http://releases.k8s.io/release-1.2/docs/user-guide/volumes.md#hostpath // --- // TODO(jonesdl) We need to restrict who can use host directory mounts and who can/can not // mount host directories as read/write. HostPath *HostPathVolumeSource `json:"hostPath,omitempty"` // EmptyDir represents a temporary directory that shares a pod's lifetime. - // More info: http://releases.k8s.io/HEAD/docs/user-guide/volumes.md#emptydir + // More info: http://releases.k8s.io/release-1.2/docs/user-guide/volumes.md#emptydir EmptyDir *EmptyDirVolumeSource `json:"emptyDir,omitempty"` // GCEPersistentDisk represents a GCE Disk resource that is attached to a // kubelet's host machine and then exposed to the pod. - // More info: http://releases.k8s.io/HEAD/docs/user-guide/volumes.md#gcepersistentdisk + // More info: http://releases.k8s.io/release-1.2/docs/user-guide/volumes.md#gcepersistentdisk GCEPersistentDisk *GCEPersistentDiskVolumeSource `json:"gcePersistentDisk,omitempty"` // AWSElasticBlockStore represents an AWS Disk resource that is attached to a // kubelet's host machine and then exposed to the pod. - // More info: http://releases.k8s.io/HEAD/docs/user-guide/volumes.md#awselasticblockstore + // More info: http://releases.k8s.io/release-1.2/docs/user-guide/volumes.md#awselasticblockstore AWSElasticBlockStore *AWSElasticBlockStoreVolumeSource `json:"awsElasticBlockStore,omitempty"` // GitRepo represents a git repository at a particular revision. GitRepo *GitRepoVolumeSource `json:"gitRepo,omitempty"` // Secret represents a secret that should populate this volume. - // More info: http://releases.k8s.io/HEAD/docs/user-guide/volumes.md#secrets + // More info: http://releases.k8s.io/release-1.2/docs/user-guide/volumes.md#secrets Secret *SecretVolumeSource `json:"secret,omitempty"` // NFS represents an NFS mount on the host that shares a pod's lifetime - // More info: http://releases.k8s.io/HEAD/docs/user-guide/volumes.md#nfs + // More info: http://releases.k8s.io/release-1.2/docs/user-guide/volumes.md#nfs NFS *NFSVolumeSource `json:"nfs,omitempty"` // 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 + // More info: http://releases.k8s.io/release-1.2/examples/iscsi/README.md ISCSI *ISCSIVolumeSource `json:"iscsi,omitempty"` // 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 + // More info: http://releases.k8s.io/release-1.2/examples/glusterfs/README.md Glusterfs *GlusterfsVolumeSource `json:"glusterfs,omitempty"` // 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 + // More info: http://releases.k8s.io/release-1.2/docs/user-guide/persistent-volumes.md#persistentvolumeclaims PersistentVolumeClaim *PersistentVolumeClaimVolumeSource `json:"persistentVolumeClaim,omitempty"` // 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 + // More info: http://releases.k8s.io/release-1.2/examples/rbd/README.md RBD *RBDVolumeSource `json:"rbd,omitempty"` // 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. FlexVolume *FlexVolumeSource `json:"flexVolume,omitempty"` // 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 + // More info: http://releases.k8s.io/release-1.2/examples/mysql-cinder-pd/README.md Cinder *CinderVolumeSource `json:"cinder,omitempty"` // CephFS represents a Ceph FS mount on the host that shares a pod's lifetime @@ -271,7 +271,7 @@ type VolumeSource struct { // type of volume that is owned by someone else (the system). type PersistentVolumeClaimVolumeSource struct { // ClaimName is the name of a PersistentVolumeClaim in the same namespace as the pod using this volume. - // More info: http://releases.k8s.io/HEAD/docs/user-guide/persistent-volumes.md#persistentvolumeclaims + // More info: http://releases.k8s.io/release-1.2/docs/user-guide/persistent-volumes.md#persistentvolumeclaims ClaimName string `json:"claimName"` // Will force the ReadOnly setting in VolumeMounts. // Default false. @@ -283,33 +283,33 @@ type PersistentVolumeClaimVolumeSource struct { type PersistentVolumeSource struct { // GCEPersistentDisk represents a GCE Disk resource that is attached to a // kubelet's host machine and then exposed to the pod. Provisioned by an admin. - // More info: http://releases.k8s.io/HEAD/docs/user-guide/volumes.md#gcepersistentdisk + // More info: http://releases.k8s.io/release-1.2/docs/user-guide/volumes.md#gcepersistentdisk GCEPersistentDisk *GCEPersistentDiskVolumeSource `json:"gcePersistentDisk,omitempty"` // AWSElasticBlockStore represents an AWS Disk resource that is attached to a // kubelet's host machine and then exposed to the pod. - // More info: http://releases.k8s.io/HEAD/docs/user-guide/volumes.md#awselasticblockstore + // More info: http://releases.k8s.io/release-1.2/docs/user-guide/volumes.md#awselasticblockstore AWSElasticBlockStore *AWSElasticBlockStoreVolumeSource `json:"awsElasticBlockStore,omitempty"` // HostPath represents a directory on the host. // Provisioned by a developer or tester. // This is useful for single-node development and testing only! // On-host storage is not supported in any way and WILL NOT WORK in a multi-node cluster. - // More info: http://releases.k8s.io/HEAD/docs/user-guide/volumes.md#hostpath + // More info: http://releases.k8s.io/release-1.2/docs/user-guide/volumes.md#hostpath HostPath *HostPathVolumeSource `json:"hostPath,omitempty"` // Glusterfs represents a Glusterfs volume that is attached to a host and // exposed to the pod. Provisioned by an admin. - // More info: http://releases.k8s.io/HEAD/examples/glusterfs/README.md + // More info: http://releases.k8s.io/release-1.2/examples/glusterfs/README.md Glusterfs *GlusterfsVolumeSource `json:"glusterfs,omitempty"` // NFS represents an NFS mount on the host. Provisioned by an admin. - // More info: http://releases.k8s.io/HEAD/docs/user-guide/volumes.md#nfs + // More info: http://releases.k8s.io/release-1.2/docs/user-guide/volumes.md#nfs NFS *NFSVolumeSource `json:"nfs,omitempty"` // 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 + // More info: http://releases.k8s.io/release-1.2/examples/rbd/README.md RBD *RBDVolumeSource `json:"rbd,omitempty"` // ISCSI represents an ISCSI Disk resource that is attached to a // kubelet's host machine and then exposed to the pod. Provisioned by an admin. ISCSI *ISCSIVolumeSource `json:"iscsi,omitempty"` // 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 + // More info: http://releases.k8s.io/release-1.2/examples/mysql-cinder-pd/README.md Cinder *CinderVolumeSource `json:"cinder,omitempty"` // CephFS represents a Ceph FS mount on the host that shares a pod's lifetime CephFS *CephFSVolumeSource `json:"cephfs,omitempty"` @@ -329,44 +329,44 @@ type PersistentVolumeSource struct { // PersistentVolume (PV) is a storage resource provisioned by an administrator. // It is analogous to a node. -// More info: http://releases.k8s.io/HEAD/docs/user-guide/persistent-volumes.md +// More info: http://releases.k8s.io/release-1.2/docs/user-guide/persistent-volumes.md type PersistentVolume struct { unversioned.TypeMeta `json:",inline"` // Standard object's metadata. - // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata + // More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#metadata ObjectMeta `json:"metadata,omitempty"` // Spec defines a specification of a persistent volume owned by the cluster. // Provisioned by an administrator. - // More info: http://releases.k8s.io/HEAD/docs/user-guide/persistent-volumes.md#persistent-volumes + // More info: http://releases.k8s.io/release-1.2/docs/user-guide/persistent-volumes.md#persistent-volumes Spec PersistentVolumeSpec `json:"spec,omitempty"` // Status represents the current information/status for the persistent volume. // Populated by the system. // Read-only. - // More info: http://releases.k8s.io/HEAD/docs/user-guide/persistent-volumes.md#persistent-volumes + // More info: http://releases.k8s.io/release-1.2/docs/user-guide/persistent-volumes.md#persistent-volumes Status PersistentVolumeStatus `json:"status,omitempty"` } // PersistentVolumeSpec is the specification of a persistent volume. type PersistentVolumeSpec struct { // A description of the persistent volume's resources and capacity. - // More info: http://releases.k8s.io/HEAD/docs/user-guide/persistent-volumes.md#capacity + // More info: http://releases.k8s.io/release-1.2/docs/user-guide/persistent-volumes.md#capacity Capacity ResourceList `json:"capacity,omitempty"` // The actual volume backing the persistent volume. PersistentVolumeSource `json:",inline"` // AccessModes contains all ways the volume can be mounted. - // More info: http://releases.k8s.io/HEAD/docs/user-guide/persistent-volumes.md#access-modes + // More info: http://releases.k8s.io/release-1.2/docs/user-guide/persistent-volumes.md#access-modes AccessModes []PersistentVolumeAccessMode `json:"accessModes,omitempty"` // ClaimRef is part of a bi-directional binding between PersistentVolume and PersistentVolumeClaim. // Expected to be non-nil when bound. // claim.VolumeName is the authoritative bind between PV and PVC. - // More info: http://releases.k8s.io/HEAD/docs/user-guide/persistent-volumes.md#binding + // More info: http://releases.k8s.io/release-1.2/docs/user-guide/persistent-volumes.md#binding ClaimRef *ObjectReference `json:"claimRef,omitempty"` // What happens to a persistent volume when released from its claim. // Valid options are Retain (default) and Recycle. // Recyling must be supported by the volume plugin underlying this persistent volume. - // More info: http://releases.k8s.io/HEAD/docs/user-guide/persistent-volumes.md#recycling-policy + // More info: http://releases.k8s.io/release-1.2/docs/user-guide/persistent-volumes.md#recycling-policy PersistentVolumeReclaimPolicy PersistentVolumeReclaimPolicy `json:"persistentVolumeReclaimPolicy,omitempty"` } @@ -388,7 +388,7 @@ const ( // PersistentVolumeStatus is the current status of a persistent volume. type PersistentVolumeStatus struct { // Phase indicates if a volume is available, bound to a claim, or released by a claim. - // More info: http://releases.k8s.io/HEAD/docs/user-guide/persistent-volumes.md#phase + // More info: http://releases.k8s.io/release-1.2/docs/user-guide/persistent-volumes.md#phase Phase PersistentVolumePhase `json:"phase,omitempty"` // A human-readable message indicating details about why the volume is in this state. Message string `json:"message,omitempty"` @@ -401,10 +401,10 @@ type PersistentVolumeStatus struct { type PersistentVolumeList struct { unversioned.TypeMeta `json:",inline"` // Standard list metadata. - // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds + // More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#types-kinds unversioned.ListMeta `json:"metadata,omitempty"` // List of persistent volumes. - // More info: http://releases.k8s.io/HEAD/docs/user-guide/persistent-volumes.md + // More info: http://releases.k8s.io/release-1.2/docs/user-guide/persistent-volumes.md Items []PersistentVolume `json:"items"` } @@ -412,16 +412,16 @@ type PersistentVolumeList struct { type PersistentVolumeClaim struct { unversioned.TypeMeta `json:",inline"` // Standard object's metadata. - // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata + // More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#metadata ObjectMeta `json:"metadata,omitempty"` // Spec defines the desired characteristics of a volume requested by a pod author. - // More info: http://releases.k8s.io/HEAD/docs/user-guide/persistent-volumes.md#persistentvolumeclaims + // More info: http://releases.k8s.io/release-1.2/docs/user-guide/persistent-volumes.md#persistentvolumeclaims Spec PersistentVolumeClaimSpec `json:"spec,omitempty"` // Status represents the current information/status of a persistent volume claim. // Read-only. - // More info: http://releases.k8s.io/HEAD/docs/user-guide/persistent-volumes.md#persistentvolumeclaims + // More info: http://releases.k8s.io/release-1.2/docs/user-guide/persistent-volumes.md#persistentvolumeclaims Status PersistentVolumeClaimStatus `json:"status,omitempty"` } @@ -429,10 +429,10 @@ type PersistentVolumeClaim struct { type PersistentVolumeClaimList struct { unversioned.TypeMeta `json:",inline"` // Standard list metadata. - // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds + // More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#types-kinds unversioned.ListMeta `json:"metadata,omitempty"` // A list of persistent volume claims. - // More info: http://releases.k8s.io/HEAD/docs/user-guide/persistent-volumes.md#persistentvolumeclaims + // More info: http://releases.k8s.io/release-1.2/docs/user-guide/persistent-volumes.md#persistentvolumeclaims Items []PersistentVolumeClaim `json:"items"` } @@ -440,10 +440,10 @@ type PersistentVolumeClaimList struct { // and allows a Source for provider-specific attributes type PersistentVolumeClaimSpec struct { // AccessModes contains the desired access modes the volume should have. - // More info: http://releases.k8s.io/HEAD/docs/user-guide/persistent-volumes.md#access-modes-1 + // More info: http://releases.k8s.io/release-1.2/docs/user-guide/persistent-volumes.md#access-modes-1 AccessModes []PersistentVolumeAccessMode `json:"accessModes,omitempty"` // Resources represents the minimum resources the volume should have. - // More info: http://releases.k8s.io/HEAD/docs/user-guide/persistent-volumes.md#resources + // More info: http://releases.k8s.io/release-1.2/docs/user-guide/persistent-volumes.md#resources Resources ResourceRequirements `json:"resources,omitempty"` // VolumeName is the binding reference to the PersistentVolume backing this claim. VolumeName string `json:"volumeName,omitempty"` @@ -454,7 +454,7 @@ type PersistentVolumeClaimStatus struct { // Phase represents the current phase of PersistentVolumeClaim. Phase PersistentVolumeClaimPhase `json:"phase,omitempty"` // AccessModes contains the actual access modes the volume backing the PVC has. - // More info: http://releases.k8s.io/HEAD/docs/user-guide/persistent-volumes.md#access-modes-1 + // More info: http://releases.k8s.io/release-1.2/docs/user-guide/persistent-volumes.md#access-modes-1 AccessModes []PersistentVolumeAccessMode `json:"accessModes,omitempty"` // Represents the actual resources of the underlying volume. Capacity ResourceList `json:"capacity,omitempty"` @@ -502,7 +502,7 @@ const ( // Host path volumes do not support ownership management or SELinux relabeling. type HostPathVolumeSource struct { // Path of the directory on the host. - // More info: http://releases.k8s.io/HEAD/docs/user-guide/volumes.md#hostpath + // More info: http://releases.k8s.io/release-1.2/docs/user-guide/volumes.md#hostpath Path string `json:"path"` } @@ -512,7 +512,7 @@ type EmptyDirVolumeSource struct { // What type of storage medium should back this directory. // The default is "" which means to use the node's default medium. // Must be an empty string (default) or Memory. - // More info: http://releases.k8s.io/HEAD/docs/user-guide/volumes.md#emptydir + // More info: http://releases.k8s.io/release-1.2/docs/user-guide/volumes.md#emptydir Medium StorageMedium `json:"medium,omitempty"` } @@ -520,16 +520,16 @@ type EmptyDirVolumeSource struct { // Glusterfs volumes do not support ownership management or SELinux relabeling. type GlusterfsVolumeSource struct { // EndpointsName is the endpoint name that details Glusterfs topology. - // More info: http://releases.k8s.io/HEAD/examples/glusterfs/README.md#create-a-pod + // More info: http://releases.k8s.io/release-1.2/examples/glusterfs/README.md#create-a-pod EndpointsName string `json:"endpoints"` // Path is the Glusterfs volume path. - // More info: http://releases.k8s.io/HEAD/examples/glusterfs/README.md#create-a-pod + // More info: http://releases.k8s.io/release-1.2/examples/glusterfs/README.md#create-a-pod Path string `json:"path"` // ReadOnly here will force the Glusterfs volume to be mounted with read-only permissions. // Defaults to false. - // More info: http://releases.k8s.io/HEAD/examples/glusterfs/README.md#create-a-pod + // More info: http://releases.k8s.io/release-1.2/examples/glusterfs/README.md#create-a-pod ReadOnly bool `json:"readOnly,omitempty"` } @@ -537,37 +537,37 @@ type GlusterfsVolumeSource struct { // RBD volumes support ownership management and SELinux relabeling. type RBDVolumeSource struct { // A collection of Ceph monitors. - // More info: http://releases.k8s.io/HEAD/examples/rbd/README.md#how-to-use-it + // More info: http://releases.k8s.io/release-1.2/examples/rbd/README.md#how-to-use-it CephMonitors []string `json:"monitors"` // The rados image name. - // More info: http://releases.k8s.io/HEAD/examples/rbd/README.md#how-to-use-it + // More info: http://releases.k8s.io/release-1.2/examples/rbd/README.md#how-to-use-it RBDImage string `json:"image"` // Filesystem type of the volume that you want to mount. // Tip: Ensure that the filesystem type is supported by the host operating system. // Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. - // More info: http://releases.k8s.io/HEAD/docs/user-guide/volumes.md#rbd + // More info: http://releases.k8s.io/release-1.2/docs/user-guide/volumes.md#rbd // TODO: how do we prevent errors in the filesystem from compromising the machine FSType string `json:"fsType,omitempty"` // The rados pool name. // Default is rbd. - // More info: http://releases.k8s.io/HEAD/examples/rbd/README.md#how-to-use-it. + // More info: http://releases.k8s.io/release-1.2/examples/rbd/README.md#how-to-use-it. RBDPool string `json:"pool"` // The rados user name. // Default is admin. - // More info: http://releases.k8s.io/HEAD/examples/rbd/README.md#how-to-use-it + // More info: http://releases.k8s.io/release-1.2/examples/rbd/README.md#how-to-use-it RadosUser string `json:"user"` // Keyring is the path to key ring for RBDUser. // Default is /etc/ceph/keyring. - // More info: http://releases.k8s.io/HEAD/examples/rbd/README.md#how-to-use-it + // More info: http://releases.k8s.io/release-1.2/examples/rbd/README.md#how-to-use-it Keyring string `json:"keyring"` // SecretRef is name of the authentication secret for RBDUser. If provided // overrides keyring. // Default is empty. - // More info: http://releases.k8s.io/HEAD/examples/rbd/README.md#how-to-use-it + // More info: http://releases.k8s.io/release-1.2/examples/rbd/README.md#how-to-use-it SecretRef *LocalObjectReference `json:"secretRef"` // ReadOnly here will force the ReadOnly setting in VolumeMounts. // Defaults to false. - // More info: http://releases.k8s.io/HEAD/examples/rbd/README.md#how-to-use-it + // More info: http://releases.k8s.io/release-1.2/examples/rbd/README.md#how-to-use-it ReadOnly bool `json:"readOnly,omitempty"` } @@ -577,16 +577,16 @@ type RBDVolumeSource struct { // Cinder volumes support ownership management and SELinux relabeling. type CinderVolumeSource struct { // volume id used to identify the volume in cinder - // More info: http://releases.k8s.io/HEAD/examples/mysql-cinder-pd/README.md + // More info: http://releases.k8s.io/release-1.2/examples/mysql-cinder-pd/README.md VolumeID string `json:"volumeID"` // Filesystem type to mount. // Must be a filesystem type supported by the host operating system. // Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. - // More info: http://releases.k8s.io/HEAD/examples/mysql-cinder-pd/README.md + // More info: http://releases.k8s.io/release-1.2/examples/mysql-cinder-pd/README.md FSType string `json:"fsType,omitempty"` // Optional: Defaults to false (read/write). ReadOnly here will force // the ReadOnly setting in VolumeMounts. - // More info: http://releases.k8s.io/HEAD/examples/mysql-cinder-pd/README.md + // More info: http://releases.k8s.io/release-1.2/examples/mysql-cinder-pd/README.md ReadOnly bool `json:"readOnly,omitempty"` } @@ -594,22 +594,22 @@ type CinderVolumeSource struct { // Cephfs volumes do not support ownership management or SELinux relabeling. type CephFSVolumeSource struct { // Required: Monitors is a collection of Ceph monitors - // More info: http://releases.k8s.io/HEAD/examples/cephfs/README.md#how-to-use-it + // More info: http://releases.k8s.io/release-1.2/examples/cephfs/README.md#how-to-use-it Monitors []string `json:"monitors"` // Optional: Used as the mounted root, rather than the full Ceph tree, default is / Path string `json:"path,omitempty"` // Optional: User is the rados user name, default is admin - // More info: http://releases.k8s.io/HEAD/examples/cephfs/README.md#how-to-use-it + // More info: http://releases.k8s.io/release-1.2/examples/cephfs/README.md#how-to-use-it User string `json:"user,omitempty"` // Optional: SecretFile is the path to key ring for User, default is /etc/ceph/user.secret - // More info: http://releases.k8s.io/HEAD/examples/cephfs/README.md#how-to-use-it + // More info: http://releases.k8s.io/release-1.2/examples/cephfs/README.md#how-to-use-it SecretFile string `json:"secretFile,omitempty"` // Optional: SecretRef is reference to the authentication secret for User, default is empty. - // More info: http://releases.k8s.io/HEAD/examples/cephfs/README.md#how-to-use-it + // More info: http://releases.k8s.io/release-1.2/examples/cephfs/README.md#how-to-use-it SecretRef *LocalObjectReference `json:"secretRef,omitempty"` // Optional: Defaults to false (read/write). ReadOnly here will force // the ReadOnly setting in VolumeMounts. - // More info: http://releases.k8s.io/HEAD/examples/cephfs/README.md#how-to-use-it + // More info: http://releases.k8s.io/release-1.2/examples/cephfs/README.md#how-to-use-it ReadOnly bool `json:"readOnly,omitempty"` } @@ -646,23 +646,23 @@ const ( // PDs support ownership management and SELinux relabeling. type GCEPersistentDiskVolumeSource struct { // Unique name of the PD resource in GCE. Used to identify the disk in GCE. - // More info: http://releases.k8s.io/HEAD/docs/user-guide/volumes.md#gcepersistentdisk + // More info: http://releases.k8s.io/release-1.2/docs/user-guide/volumes.md#gcepersistentdisk PDName string `json:"pdName"` // Filesystem type of the volume that you want to mount. // Tip: Ensure that the filesystem type is supported by the host operating system. // Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. - // More info: http://releases.k8s.io/HEAD/docs/user-guide/volumes.md#gcepersistentdisk + // More info: http://releases.k8s.io/release-1.2/docs/user-guide/volumes.md#gcepersistentdisk // TODO: how do we prevent errors in the filesystem from compromising the machine FSType string `json:"fsType,omitempty"` // The partition in the volume that you want to mount. // If omitted, the default is to mount by volume name. // Examples: For volume /dev/sda1, you specify the partition as "1". // Similarly, the volume partition for /dev/sda is "0" (or you can leave the property empty). - // More info: http://releases.k8s.io/HEAD/docs/user-guide/volumes.md#gcepersistentdisk + // More info: http://releases.k8s.io/release-1.2/docs/user-guide/volumes.md#gcepersistentdisk Partition int32 `json:"partition,omitempty"` // ReadOnly here will force the ReadOnly setting in VolumeMounts. // Defaults to false. - // More info: http://releases.k8s.io/HEAD/docs/user-guide/volumes.md#gcepersistentdisk + // More info: http://releases.k8s.io/release-1.2/docs/user-guide/volumes.md#gcepersistentdisk ReadOnly bool `json:"readOnly,omitempty"` } @@ -692,12 +692,12 @@ type FlexVolumeSource struct { // ownership management and SELinux relabeling. type AWSElasticBlockStoreVolumeSource struct { // Unique ID of the persistent disk resource in AWS (Amazon EBS volume). - // More info: http://releases.k8s.io/HEAD/docs/user-guide/volumes.md#awselasticblockstore + // More info: http://releases.k8s.io/release-1.2/docs/user-guide/volumes.md#awselasticblockstore VolumeID string `json:"volumeID"` // Filesystem type of the volume that you want to mount. // Tip: Ensure that the filesystem type is supported by the host operating system. // Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. - // More info: http://releases.k8s.io/HEAD/docs/user-guide/volumes.md#awselasticblockstore + // More info: http://releases.k8s.io/release-1.2/docs/user-guide/volumes.md#awselasticblockstore // TODO: how do we prevent errors in the filesystem from compromising the machine FSType string `json:"fsType,omitempty"` // The partition in the volume that you want to mount. @@ -707,7 +707,7 @@ type AWSElasticBlockStoreVolumeSource struct { Partition int32 `json:"partition,omitempty"` // Specify "true" to force and set the ReadOnly property in VolumeMounts to "true". // If omitted, the default is "false". - // More info: http://releases.k8s.io/HEAD/docs/user-guide/volumes.md#awselasticblockstore + // More info: http://releases.k8s.io/release-1.2/docs/user-guide/volumes.md#awselasticblockstore ReadOnly bool `json:"readOnly,omitempty"` } @@ -733,7 +733,7 @@ type GitRepoVolumeSource struct { // Secret volumes support ownership management and SELinux relabeling. 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 + // More info: http://releases.k8s.io/release-1.2/docs/user-guide/volumes.md#secrets SecretName string `json:"secretName,omitempty"` } @@ -741,17 +741,17 @@ type SecretVolumeSource struct { // NFS volumes do not support ownership management or SELinux relabeling. type NFSVolumeSource struct { // Server is the hostname or IP address of the NFS server. - // More info: http://releases.k8s.io/HEAD/docs/user-guide/volumes.md#nfs + // More info: http://releases.k8s.io/release-1.2/docs/user-guide/volumes.md#nfs Server string `json:"server"` // Path that is exported by the NFS server. - // More info: http://releases.k8s.io/HEAD/docs/user-guide/volumes.md#nfs + // More info: http://releases.k8s.io/release-1.2/docs/user-guide/volumes.md#nfs Path string `json:"path"` // ReadOnly here will force // the NFS export to be mounted with read-only permissions. // Defaults to false. - // More info: http://releases.k8s.io/HEAD/docs/user-guide/volumes.md#nfs + // More info: http://releases.k8s.io/release-1.2/docs/user-guide/volumes.md#nfs ReadOnly bool `json:"readOnly,omitempty"` } @@ -771,7 +771,7 @@ type ISCSIVolumeSource struct { // Filesystem type of the volume that you want to mount. // Tip: Ensure that the filesystem type is supported by the host operating system. // Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. - // More info: http://releases.k8s.io/HEAD/docs/user-guide/volumes.md#iscsi + // More info: http://releases.k8s.io/release-1.2/docs/user-guide/volumes.md#iscsi // TODO: how do we prevent errors in the filesystem from compromising the machine FSType string `json:"fsType,omitempty"` // ReadOnly here will force the ReadOnly setting in VolumeMounts. @@ -866,7 +866,8 @@ type VolumeMount struct { // Mounted read-only if true, read-write otherwise (false or unspecified). // Defaults to false. ReadOnly bool `json:"readOnly,omitempty"` - // Path within the container at which the volume should be mounted. + // Path within the container at which the volume should be mounted. Must + // not contain ':'. MountPath string `json:"mountPath"` } @@ -984,11 +985,11 @@ type Probe struct { // The action taken to determine the health of a container Handler `json:",inline"` // Number of seconds after the container has started before liveness probes are initiated. - // More info: http://releases.k8s.io/HEAD/docs/user-guide/pod-states.md#container-probes + // More info: http://releases.k8s.io/release-1.2/docs/user-guide/pod-states.md#container-probes InitialDelaySeconds int32 `json:"initialDelaySeconds,omitempty"` // Number of seconds after which the probe times out. // Defaults to 1 second. Minimum value is 1. - // More info: http://releases.k8s.io/HEAD/docs/user-guide/pod-states.md#container-probes + // More info: http://releases.k8s.io/release-1.2/docs/user-guide/pod-states.md#container-probes TimeoutSeconds int32 `json:"timeoutSeconds,omitempty"` // How often (in seconds) to perform the probe. // Default to 10 seconds. Minimum value is 1. @@ -1027,12 +1028,12 @@ type Capabilities struct { // ResourceRequirements describes the compute resource requirements. type ResourceRequirements struct { // Limits describes the maximum amount of compute resources allowed. - // More info: http://releases.k8s.io/HEAD/docs/design/resources.md#resource-specifications + // More info: http://releases.k8s.io/release-1.2/docs/design/resources.md#resource-specifications Limits ResourceList `json:"limits,omitempty"` // Requests describes the minimum amount of compute resources required. // If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, // otherwise to an implementation-defined value. - // More info: http://releases.k8s.io/HEAD/docs/design/resources.md#resource-specifications + // More info: http://releases.k8s.io/release-1.2/docs/design/resources.md#resource-specifications Requests ResourceList `json:"requests,omitempty"` } @@ -1048,7 +1049,7 @@ type Container struct { // Cannot be updated. Name string `json:"name"` // Docker image name. - // More info: http://releases.k8s.io/HEAD/docs/user-guide/images.md + // More info: http://releases.k8s.io/release-1.2/docs/user-guide/images.md Image string `json:"image,omitempty"` // Entrypoint array. Not executed within a shell. // The docker image's ENTRYPOINT is used if this is not provided. @@ -1057,7 +1058,7 @@ type Container struct { // can be escaped with a double $$, ie: $$(VAR_NAME). Escaped references will never be expanded, // regardless of whether the variable exists or not. // Cannot be updated. - // More info: http://releases.k8s.io/HEAD/docs/user-guide/containers.md#containers-and-commands + // More info: http://releases.k8s.io/release-1.2/docs/user-guide/containers.md#containers-and-commands Command []string `json:"command,omitempty"` // Arguments to the entrypoint. // The docker image's CMD is used if this is not provided. @@ -1066,7 +1067,7 @@ type Container struct { // can be escaped with a double $$, ie: $$(VAR_NAME). Escaped references will never be expanded, // regardless of whether the variable exists or not. // Cannot be updated. - // More info: http://releases.k8s.io/HEAD/docs/user-guide/containers.md#containers-and-commands + // More info: http://releases.k8s.io/release-1.2/docs/user-guide/containers.md#containers-and-commands Args []string `json:"args,omitempty"` // Container's working directory. // If not specified, the container runtime's default will be used, which @@ -1086,7 +1087,7 @@ type Container struct { Env []EnvVar `json:"env,omitempty" patchStrategy:"merge" patchMergeKey:"name"` // Compute Resources required by this container. // Cannot be updated. - // More info: http://releases.k8s.io/HEAD/docs/user-guide/persistent-volumes.md#resources + // More info: http://releases.k8s.io/release-1.2/docs/user-guide/persistent-volumes.md#resources Resources ResourceRequirements `json:"resources,omitempty"` // Pod volumes to mount into the container's filesyste. // Cannot be updated. @@ -1094,12 +1095,12 @@ type Container struct { // 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 + // More info: http://releases.k8s.io/release-1.2/docs/user-guide/pod-states.md#container-probes LivenessProbe *Probe `json:"livenessProbe,omitempty"` // 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 + // More info: http://releases.k8s.io/release-1.2/docs/user-guide/pod-states.md#container-probes ReadinessProbe *Probe `json:"readinessProbe,omitempty"` // Actions that the management system should take in response to container lifecycle events. // Cannot be updated. @@ -1114,10 +1115,10 @@ type Container struct { // One of Always, Never, IfNotPresent. // Defaults to Always if :latest tag is specified, or IfNotPresent otherwise. // Cannot be updated. - // More info: http://releases.k8s.io/HEAD/docs/user-guide/images.md#updating-images + // More info: http://releases.k8s.io/release-1.2/docs/user-guide/images.md#updating-images ImagePullPolicy PullPolicy `json:"imagePullPolicy,omitempty"` // Security options the pod should run with. - // More info: http://releases.k8s.io/HEAD/docs/design/security_context.md + // More info: http://releases.k8s.io/release-1.2/docs/design/security_context.md SecurityContext *SecurityContext `json:"securityContext,omitempty"` // Variables for interactive containers, these have very specialized use-cases (e.g. debugging) @@ -1161,14 +1162,14 @@ type Lifecycle struct { // PostStart is called immediately after a container is created. If the handler fails, // the container is terminated and restarted according to its restart policy. // Other management of the container blocks until the hook completes. - // More info: http://releases.k8s.io/HEAD/docs/user-guide/container-environment.md#hook-details + // More info: http://releases.k8s.io/release-1.2/docs/user-guide/container-environment.md#hook-details PostStart *Handler `json:"postStart,omitempty"` // PreStop is called immediately before a container is terminated. // The container is terminated after the handler completes. // The reason for termination is passed to the handler. // Regardless of the outcome of the handler, the container is eventually terminated. // Other management of the container blocks until the hook completes. - // More info: http://releases.k8s.io/HEAD/docs/user-guide/container-environment.md#hook-details + // More info: http://releases.k8s.io/release-1.2/docs/user-guide/container-environment.md#hook-details PreStop *Handler `json:"preStop,omitempty"` } @@ -1245,13 +1246,13 @@ type ContainerStatus struct { // garbage collection. This value will get capped at 5 by GC. RestartCount int32 `json:"restartCount"` // The image the container is running. - // More info: http://releases.k8s.io/HEAD/docs/user-guide/images.md + // More info: http://releases.k8s.io/release-1.2/docs/user-guide/images.md // TODO(dchen1107): Which image the container is running with? Image string `json:"image"` // ImageID of the container's image. ImageID string `json:"imageID"` // Container's ID in the format 'docker://'. - // More info: http://releases.k8s.io/HEAD/docs/user-guide/container-environment.md#container-information + // More info: http://releases.k8s.io/release-1.2/docs/user-guide/container-environment.md#container-information ContainerID string `json:"containerID,omitempty"` } @@ -1292,11 +1293,11 @@ const ( type PodCondition struct { // Type is the type of the condition. // Currently only Ready. - // More info: http://releases.k8s.io/HEAD/docs/user-guide/pod-states.md#pod-conditions + // More info: http://releases.k8s.io/release-1.2/docs/user-guide/pod-states.md#pod-conditions Type PodConditionType `json:"type"` // Status is the status of the condition. // Can be True, False, Unknown. - // More info: http://releases.k8s.io/HEAD/docs/user-guide/pod-states.md#pod-conditions + // More info: http://releases.k8s.io/release-1.2/docs/user-guide/pod-states.md#pod-conditions Status ConditionStatus `json:"status"` // Last time we probed the condition. LastProbeTime unversioned.Time `json:"lastProbeTime,omitempty"` @@ -1426,18 +1427,18 @@ type PreferredSchedulingTerm struct { // 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 + // More info: http://releases.k8s.io/release-1.2/docs/user-guide/volumes.md Volumes []Volume `json:"volumes,omitempty" 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. // Cannot be updated. - // More info: http://releases.k8s.io/HEAD/docs/user-guide/containers.md + // More info: http://releases.k8s.io/release-1.2/docs/user-guide/containers.md Containers []Container `json:"containers" patchStrategy:"merge" patchMergeKey:"name"` // Restart policy for all containers within the pod. // One of Always, OnFailure, Never. // Default to Always. - // More info: http://releases.k8s.io/HEAD/docs/user-guide/pod-states.md#restartpolicy + // More info: http://releases.k8s.io/release-1.2/docs/user-guide/pod-states.md#restartpolicy RestartPolicy RestartPolicy `json:"restartPolicy,omitempty"` // Optional duration in seconds the pod needs to terminate gracefully. May be decreased in delete request. // Value must be non-negative integer. The value zero indicates delete immediately. @@ -1457,11 +1458,11 @@ type PodSpec struct { DNSPolicy DNSPolicy `json:"dnsPolicy,omitempty"` // NodeSelector is a selector which must be true for the pod to fit on a node. // Selector which must match a node's labels for the pod to be scheduled on that node. - // More info: http://releases.k8s.io/HEAD/docs/user-guide/node-selection/README.md + // More info: http://releases.k8s.io/release-1.2/docs/user-guide/node-selection/README.md NodeSelector map[string]string `json:"nodeSelector,omitempty"` // ServiceAccountName is the name of the ServiceAccount to use to run this pod. - // More info: http://releases.k8s.io/HEAD/docs/design/service_accounts.md + // More info: http://releases.k8s.io/release-1.2/docs/design/service_accounts.md ServiceAccountName string `json:"serviceAccountName,omitempty"` // DeprecatedServiceAccount is a depreciated alias for ServiceAccountName. // Deprecated: Use serviceAccountName instead. @@ -1487,7 +1488,7 @@ type PodSpec struct { // ImagePullSecrets is an optional list of references to secrets in the same namespace to use for pulling any of the images used by this PodSpec. // If specified, these secrets will be passed to individual puller implementations for them to use. For example, // in the case of docker, only DockerConfig type secrets are honored. - // More info: http://releases.k8s.io/HEAD/docs/user-guide/images.md#specifying-imagepullsecrets-on-a-pod + // More info: http://releases.k8s.io/release-1.2/docs/user-guide/images.md#specifying-imagepullsecrets-on-a-pod ImagePullSecrets []LocalObjectReference `json:"imagePullSecrets,omitempty" patchStrategy:"merge" patchMergeKey:"name"` } @@ -1534,10 +1535,10 @@ type PodSecurityContext struct { // state of a system. type PodStatus struct { // Current condition of the pod. - // More info: http://releases.k8s.io/HEAD/docs/user-guide/pod-states.md#pod-phase + // More info: http://releases.k8s.io/release-1.2/docs/user-guide/pod-states.md#pod-phase Phase PodPhase `json:"phase,omitempty"` // Current service state of pod. - // More info: http://releases.k8s.io/HEAD/docs/user-guide/pod-states.md#pod-conditions + // More info: http://releases.k8s.io/release-1.2/docs/user-guide/pod-states.md#pod-conditions Conditions []PodCondition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type"` // A human readable message indicating details about why the pod is in this condition. Message string `json:"message,omitempty"` @@ -1557,7 +1558,7 @@ type PodStatus struct { // 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 + // More info: http://releases.k8s.io/release-1.2/docs/user-guide/pod-states.md#container-statuses ContainerStatuses []ContainerStatus `json:"containerStatuses,omitempty"` } @@ -1565,13 +1566,13 @@ type PodStatus struct { type PodStatusResult struct { unversioned.TypeMeta `json:",inline"` // Standard object's metadata. - // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata + // More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#metadata ObjectMeta `json:"metadata,omitempty"` // Most recently observed status of the pod. // This data may not be up to date. // Populated by the system. // Read-only. - // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#spec-and-status + // More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#spec-and-status Status PodStatus `json:"status,omitempty"` } @@ -1582,18 +1583,18 @@ type PodStatusResult struct { type Pod struct { unversioned.TypeMeta `json:",inline"` // Standard object's metadata. - // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata + // More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#metadata ObjectMeta `json:"metadata,omitempty"` // Specification of the desired behavior of the pod. - // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#spec-and-status + // More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#spec-and-status Spec PodSpec `json:"spec,omitempty"` // Most recently observed status of the pod. // This data may not be up to date. // Populated by the system. // Read-only. - // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#spec-and-status + // More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#spec-and-status Status PodStatus `json:"status,omitempty"` } @@ -1601,22 +1602,22 @@ type Pod struct { type PodList struct { unversioned.TypeMeta `json:",inline"` // Standard list metadata. - // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds + // More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#types-kinds unversioned.ListMeta `json:"metadata,omitempty"` // List of pods. - // More info: http://releases.k8s.io/HEAD/docs/user-guide/pods.md + // More info: http://releases.k8s.io/release-1.2/docs/user-guide/pods.md Items []Pod `json:"items"` } // PodTemplateSpec describes the data a pod should have when created from a template type PodTemplateSpec struct { // Standard object's metadata. - // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata + // More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#metadata ObjectMeta `json:"metadata,omitempty"` // Specification of the desired behavior of the pod. - // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#spec-and-status + // More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#spec-and-status Spec PodSpec `json:"spec,omitempty"` } @@ -1626,11 +1627,11 @@ type PodTemplateSpec struct { type PodTemplate struct { unversioned.TypeMeta `json:",inline"` // Standard object's metadata. - // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata + // More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#metadata ObjectMeta `json:"metadata,omitempty"` // Template defines the pods that will be created from this pod template. - // http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#spec-and-status + // http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#spec-and-status Template PodTemplateSpec `json:"template,omitempty"` } @@ -1638,7 +1639,7 @@ type PodTemplate struct { type PodTemplateList struct { unversioned.TypeMeta `json:",inline"` // Standard list metadata. - // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds + // More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#types-kinds unversioned.ListMeta `json:"metadata,omitempty"` // List of pod templates @@ -1650,14 +1651,14 @@ type ReplicationControllerSpec struct { // Replicas is the number of desired replicas. // This is a pointer to distinguish between explicit zero and unspecified. // Defaults to 1. - // More info: http://releases.k8s.io/HEAD/docs/user-guide/replication-controller.md#what-is-a-replication-controller + // More info: http://releases.k8s.io/release-1.2/docs/user-guide/replication-controller.md#what-is-a-replication-controller Replicas *int32 `json:"replicas,omitempty"` // Selector is a label query over pods that should match the Replicas count. // If Selector is empty, it is defaulted to the labels present on the Pod template. // Label keys and values that must match in order to be controlled by this replication // controller, if empty defaulted to labels on Pod template. - // More info: http://releases.k8s.io/HEAD/docs/user-guide/labels.md#label-selectors + // More info: http://releases.k8s.io/release-1.2/docs/user-guide/labels.md#label-selectors Selector map[string]string `json:"selector,omitempty"` // TemplateRef is a reference to an object that describes the pod that will be created if @@ -1667,7 +1668,7 @@ type ReplicationControllerSpec struct { // Template is the object that describes the pod that will be created if // insufficient replicas are detected. This takes precedence over a TemplateRef. - // More info: http://releases.k8s.io/HEAD/docs/user-guide/replication-controller.md#pod-template + // More info: http://releases.k8s.io/release-1.2/docs/user-guide/replication-controller.md#pod-template Template *PodTemplateSpec `json:"template,omitempty"` } @@ -1675,9 +1676,12 @@ type ReplicationControllerSpec struct { // controller. type ReplicationControllerStatus struct { // Replicas is the most recently oberved number of replicas. - // More info: http://releases.k8s.io/HEAD/docs/user-guide/replication-controller.md#what-is-a-replication-controller + // More info: http://releases.k8s.io/release-1.2/docs/user-guide/replication-controller.md#what-is-a-replication-controller Replicas int32 `json:"replicas"` + // The number of pods that have labels matching the labels of the pod template of the replication controller. + FullyLabeledReplicas int32 `json:"fullyLabeledReplicas,omitempty"` + // ObservedGeneration reflects the generation of the most recently observed replication controller. ObservedGeneration int64 `json:"observedGeneration,omitempty"` } @@ -1690,18 +1694,18 @@ type ReplicationController struct { // If the Labels of a ReplicationController are empty, they are defaulted to // be the same as the Pod(s) that the replication controller manages. - // Standard object's metadata. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata + // Standard object's metadata. More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#metadata ObjectMeta `json:"metadata,omitempty"` // Spec defines the specification of the desired behavior of the replication controller. - // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#spec-and-status + // More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#spec-and-status Spec ReplicationControllerSpec `json:"spec,omitempty"` // Status is the most recently observed status of the replication controller. // This data may be out of date by some window of time. // Populated by the system. // Read-only. - // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#spec-and-status + // More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#spec-and-status Status ReplicationControllerStatus `json:"status,omitempty"` } @@ -1709,11 +1713,11 @@ type ReplicationController struct { type ReplicationControllerList struct { unversioned.TypeMeta `json:",inline"` // Standard list metadata. - // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds + // More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#types-kinds unversioned.ListMeta `json:"metadata,omitempty"` // List of replication controllers. - // More info: http://releases.k8s.io/HEAD/docs/user-guide/replication-controller.md + // More info: http://releases.k8s.io/release-1.2/docs/user-guide/replication-controller.md Items []ReplicationController `json:"items"` } @@ -1775,13 +1779,13 @@ type LoadBalancerIngress struct { // ServiceSpec describes the attributes that a user creates on a service. type ServiceSpec struct { // The list of ports that are exposed by this service. - // More info: http://releases.k8s.io/HEAD/docs/user-guide/services.md#virtual-ips-and-service-proxies + // More info: http://releases.k8s.io/release-1.2/docs/user-guide/services.md#virtual-ips-and-service-proxies Ports []ServicePort `json:"ports"` // This service will route traffic to pods having labels matching this selector. // Label keys and values that must match in order to receive traffic for this service. // If empty, all pods are selected, if not specified, endpoints must be manually specified. - // More info: http://releases.k8s.io/HEAD/docs/user-guide/services.md#overview + // More info: http://releases.k8s.io/release-1.2/docs/user-guide/services.md#overview Selector map[string]string `json:"selector,omitempty"` // ClusterIP is usually assigned by the master and is the IP address of the service. @@ -1790,12 +1794,12 @@ type ServiceSpec struct { // Valid values are None, empty string (""), or a valid IP address. // 'None' can be specified for a headless service when proxying is not required. // Cannot be updated. - // More info: http://releases.k8s.io/HEAD/docs/user-guide/services.md#virtual-ips-and-service-proxies + // More info: http://releases.k8s.io/release-1.2/docs/user-guide/services.md#virtual-ips-and-service-proxies ClusterIP string `json:"clusterIP,omitempty"` // Type of exposed service. Must be ClusterIP, NodePort, or LoadBalancer. // Defaults to ClusterIP. - // More info: http://releases.k8s.io/HEAD/docs/user-guide/services.md#external-services + // More info: http://releases.k8s.io/release-1.2/docs/user-guide/services.md#external-services Type ServiceType `json:"type,omitempty"` // externalIPs is a list of IP addresses for which nodes in the cluster @@ -1818,7 +1822,7 @@ type ServiceSpec struct { // Enable client IP based session affinity. // Must be ClientIP or None. // Defaults to None. - // More info: http://releases.k8s.io/HEAD/docs/user-guide/services.md#virtual-ips-and-service-proxies + // More info: http://releases.k8s.io/release-1.2/docs/user-guide/services.md#virtual-ips-and-service-proxies SessionAffinity ServiceAffinity `json:"sessionAffinity,omitempty"` // Only applies to Service Type: LoadBalancer @@ -1851,14 +1855,14 @@ type ServicePort struct { // of the 'port' field is used (an identity map). // This field is ignored for services with clusterIP=None, and should be // omitted or set equal to the 'port' field. - // More info: http://releases.k8s.io/HEAD/docs/user-guide/services.md#defining-a-service + // More info: http://releases.k8s.io/release-1.2/docs/user-guide/services.md#defining-a-service TargetPort intstr.IntOrString `json:"targetPort,omitempty"` // The port on each node on which this service is exposed when type=NodePort or LoadBalancer. // Usually assigned by the system. If specified, it will be allocated to the service // if unused or else creation of the service will fail. // Default is to auto-allocate a port if the ServiceType of this Service requires one. - // More info: http://releases.k8s.io/HEAD/docs/user-guide/services.md#type--nodeport + // More info: http://releases.k8s.io/release-1.2/docs/user-guide/services.md#type--nodeport NodePort int32 `json:"nodePort,omitempty"` } @@ -1870,17 +1874,17 @@ type ServicePort struct { type Service struct { unversioned.TypeMeta `json:",inline"` // Standard object's metadata. - // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata + // More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#metadata ObjectMeta `json:"metadata,omitempty"` // Spec defines the behavior of a service. - // http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#spec-and-status + // http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#spec-and-status Spec ServiceSpec `json:"spec,omitempty"` // Most recently observed status of the service. // Populated by the system. // Read-only. - // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#spec-and-status + // More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#spec-and-status Status ServiceStatus `json:"status,omitempty"` } @@ -1894,7 +1898,7 @@ const ( type ServiceList struct { unversioned.TypeMeta `json:",inline"` // Standard list metadata. - // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds + // More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#types-kinds unversioned.ListMeta `json:"metadata,omitempty"` // List of services @@ -1910,17 +1914,17 @@ type ServiceList struct { type ServiceAccount struct { unversioned.TypeMeta `json:",inline"` // Standard object's metadata. - // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata + // More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#metadata ObjectMeta `json:"metadata,omitempty"` // Secrets is the list of secrets allowed to be used by pods running using this ServiceAccount. - // More info: http://releases.k8s.io/HEAD/docs/user-guide/secrets.md + // More info: http://releases.k8s.io/release-1.2/docs/user-guide/secrets.md Secrets []ObjectReference `json:"secrets,omitempty" patchStrategy:"merge" patchMergeKey:"name"` // ImagePullSecrets is a list of references to secrets in the same namespace to use for pulling any images // in pods that reference this ServiceAccount. ImagePullSecrets are distinct from Secrets because Secrets // can be mounted in the pod, but ImagePullSecrets are only accessed by the kubelet. - // More info: http://releases.k8s.io/HEAD/docs/user-guide/secrets.md#manually-specifying-an-imagepullsecret + // More info: http://releases.k8s.io/release-1.2/docs/user-guide/secrets.md#manually-specifying-an-imagepullsecret ImagePullSecrets []LocalObjectReference `json:"imagePullSecrets,omitempty"` } @@ -1928,11 +1932,11 @@ type ServiceAccount struct { type ServiceAccountList struct { unversioned.TypeMeta `json:",inline"` // Standard list metadata. - // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds + // More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#types-kinds unversioned.ListMeta `json:"metadata,omitempty"` // List of ServiceAccounts. - // More info: http://releases.k8s.io/HEAD/docs/design/service_accounts.md#service-accounts + // More info: http://releases.k8s.io/release-1.2/docs/design/service_accounts.md#service-accounts Items []ServiceAccount `json:"items"` } @@ -1953,7 +1957,7 @@ type ServiceAccountList struct { type Endpoints struct { unversioned.TypeMeta `json:",inline"` // Standard object's metadata. - // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata + // More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#metadata ObjectMeta `json:"metadata,omitempty"` // The set of all endpoints is the union of all subsets. Addresses are placed into @@ -2020,7 +2024,7 @@ type EndpointPort struct { type EndpointsList struct { unversioned.TypeMeta `json:",inline"` // Standard list metadata. - // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds + // More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#types-kinds unversioned.ListMeta `json:"metadata,omitempty"` // List of endpoints. @@ -2037,7 +2041,7 @@ type NodeSpec struct { // ID of the node assigned by the cloud provider in the format: :// ProviderID string `json:"providerID,omitempty"` // Unschedulable controls node schedulability of new pods. By default, node is schedulable. - // More info: http://releases.k8s.io/HEAD/docs/admin/node.md#manual-node-administration"` + // More info: http://releases.k8s.io/release-1.2/docs/admin/node.md#manual-node-administration"` Unschedulable bool `json:"unschedulable,omitempty"` } @@ -2076,25 +2080,25 @@ type NodeSystemInfo struct { // NodeStatus is information about the current status of a node. type NodeStatus struct { // Capacity represents the total resources of a node. - // More info: http://releases.k8s.io/HEAD/docs/user-guide/persistent-volumes.md#capacity for more details. + // More info: http://releases.k8s.io/release-1.2/docs/user-guide/persistent-volumes.md#capacity for more details. Capacity ResourceList `json:"capacity,omitempty"` // Allocatable represents the resources of a node that are available for scheduling. // Defaults to Capacity. Allocatable ResourceList `json:"allocatable,omitempty"` // NodePhase is the recently observed lifecycle phase of the node. - // More info: http://releases.k8s.io/HEAD/docs/admin/node.md#node-phase + // More info: http://releases.k8s.io/release-1.2/docs/admin/node.md#node-phase Phase NodePhase `json:"phase,omitempty"` // Conditions is an array of current observed node conditions. - // More info: http://releases.k8s.io/HEAD/docs/admin/node.md#node-condition + // More info: http://releases.k8s.io/release-1.2/docs/admin/node.md#node-condition Conditions []NodeCondition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type"` // List of addresses reachable to the node. // Queried from cloud provider, if available. - // More info: http://releases.k8s.io/HEAD/docs/admin/node.md#node-addresses + // More info: http://releases.k8s.io/release-1.2/docs/admin/node.md#node-addresses Addresses []NodeAddress `json:"addresses,omitempty" patchStrategy:"merge" patchMergeKey:"type"` // Endpoints of daemons running on the Node. DaemonEndpoints NodeDaemonEndpoints `json:"daemonEndpoints,omitempty"` // Set of ids/uuids to uniquely identify the node. - // More info: http://releases.k8s.io/HEAD/docs/admin/node.md#node-info + // More info: http://releases.k8s.io/release-1.2/docs/admin/node.md#node-info NodeInfo NodeSystemInfo `json:"nodeInfo,omitempty"` // List of container images on this node Images []ContainerImage `json:"images",omitempty` @@ -2189,17 +2193,17 @@ type ResourceList map[ResourceName]resource.Quantity type Node struct { unversioned.TypeMeta `json:",inline"` // Standard object's metadata. - // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata + // More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#metadata ObjectMeta `json:"metadata,omitempty"` // Spec defines the behavior of a node. - // http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#spec-and-status + // http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#spec-and-status Spec NodeSpec `json:"spec,omitempty"` // Most recently observed status of the node. // Populated by the system. // Read-only. - // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#spec-and-status + // More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#spec-and-status Status NodeStatus `json:"status,omitempty"` } @@ -2207,7 +2211,7 @@ type Node struct { type NodeList struct { unversioned.TypeMeta `json:",inline"` // Standard list metadata. - // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds + // More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#types-kinds unversioned.ListMeta `json:"metadata,omitempty"` // List of nodes @@ -2224,14 +2228,14 @@ const ( // NamespaceSpec describes the attributes on a Namespace. type NamespaceSpec struct { // Finalizers is an opaque list of values that must be empty to permanently remove object from storage. - // More info: http://releases.k8s.io/HEAD/docs/design/namespaces.md#finalizers + // More info: http://releases.k8s.io/release-1.2/docs/design/namespaces.md#finalizers Finalizers []FinalizerName `json:"finalizers,omitempty"` } // NamespaceStatus is information about the current status of a Namespace. type NamespaceStatus struct { // Phase is the current lifecycle phase of the namespace. - // More info: http://releases.k8s.io/HEAD/docs/design/namespaces.md#phases + // More info: http://releases.k8s.io/release-1.2/docs/design/namespaces.md#phases Phase NamespacePhase `json:"phase,omitempty"` } @@ -2252,15 +2256,15 @@ const ( type Namespace struct { unversioned.TypeMeta `json:",inline"` // Standard object's metadata. - // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata + // More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#metadata ObjectMeta `json:"metadata,omitempty"` // Spec defines the behavior of the Namespace. - // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#spec-and-status + // More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#spec-and-status Spec NamespaceSpec `json:"spec,omitempty"` // Status describes the current status of a Namespace. - // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#spec-and-status + // More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#spec-and-status Status NamespaceStatus `json:"status,omitempty"` } @@ -2268,11 +2272,11 @@ type Namespace struct { type NamespaceList struct { unversioned.TypeMeta `json:",inline"` // Standard list metadata. - // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds + // More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#types-kinds unversioned.ListMeta `json:"metadata,omitempty"` // Items is the list of Namespace objects in the list. - // More info: http://releases.k8s.io/HEAD/docs/user-guide/namespaces.md + // More info: http://releases.k8s.io/release-1.2/docs/user-guide/namespaces.md Items []Namespace `json:"items"` } @@ -2281,7 +2285,7 @@ type NamespaceList struct { type Binding struct { unversioned.TypeMeta `json:",inline"` // Standard object's metadata. - // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata + // More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#metadata ObjectMeta `json:"metadata,omitempty"` // The target object that you want to bind to the standard object. @@ -2453,21 +2457,21 @@ type ServiceProxyOptions struct { // ObjectReference contains enough information to let you inspect or modify the referred object. type ObjectReference struct { // Kind of the referent. - // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds + // More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#types-kinds Kind string `json:"kind,omitempty"` // Namespace of the referent. - // More info: http://releases.k8s.io/HEAD/docs/user-guide/namespaces.md + // More info: http://releases.k8s.io/release-1.2/docs/user-guide/namespaces.md Namespace string `json:"namespace,omitempty"` // Name of the referent. - // More info: http://releases.k8s.io/HEAD/docs/user-guide/identifiers.md#names + // More info: http://releases.k8s.io/release-1.2/docs/user-guide/identifiers.md#names Name string `json:"name,omitempty"` // UID of the referent. - // More info: http://releases.k8s.io/HEAD/docs/user-guide/identifiers.md#uids + // More info: http://releases.k8s.io/release-1.2/docs/user-guide/identifiers.md#uids UID types.UID `json:"uid,omitempty"` // API version of the referent. APIVersion string `json:"apiVersion,omitempty"` // Specific resourceVersion to which this reference is made, if any. - // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#concurrency-control-and-consistency + // More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#concurrency-control-and-consistency ResourceVersion string `json:"resourceVersion,omitempty"` // If referring to a piece of an object instead of an entire object, this string @@ -2485,7 +2489,7 @@ type ObjectReference struct { // referenced object inside the same namespace. type LocalObjectReference struct { // Name of the referent. - // More info: http://releases.k8s.io/HEAD/docs/user-guide/identifiers.md#names + // More info: http://releases.k8s.io/release-1.2/docs/user-guide/identifiers.md#names // TODO: Add other useful fields. apiVersion, kind, uid? Name string `json:"name,omitempty"` } @@ -2520,7 +2524,7 @@ const ( type Event struct { unversioned.TypeMeta `json:",inline"` // Standard object's metadata. - // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata + // More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#metadata ObjectMeta `json:"metadata"` // The object that this event is about. @@ -2555,7 +2559,7 @@ type Event struct { type EventList struct { unversioned.TypeMeta `json:",inline"` // Standard list metadata. - // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds + // More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#types-kinds unversioned.ListMeta `json:"metadata,omitempty"` // List of events @@ -2566,7 +2570,7 @@ type EventList struct { type List struct { unversioned.TypeMeta `json:",inline"` // Standard list metadata. - // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds + // More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#types-kinds unversioned.ListMeta `json:"metadata,omitempty"` // List of objects @@ -2611,11 +2615,11 @@ type LimitRangeSpec struct { type LimitRange struct { unversioned.TypeMeta `json:",inline"` // Standard object's metadata. - // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata + // More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#metadata ObjectMeta `json:"metadata,omitempty"` // Spec defines the limits enforced. - // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#spec-and-status + // More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#spec-and-status Spec LimitRangeSpec `json:"spec,omitempty"` } @@ -2623,11 +2627,11 @@ type LimitRange struct { type LimitRangeList struct { unversioned.TypeMeta `json:",inline"` // Standard list metadata. - // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds + // More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#types-kinds unversioned.ListMeta `json:"metadata,omitempty"` // Items is a list of LimitRange objects. - // More info: http://releases.k8s.io/HEAD/docs/design/admission_control_limit_range.md + // More info: http://releases.k8s.io/release-1.2/docs/design/admission_control_limit_range.md Items []LimitRange `json:"items"` } @@ -2643,6 +2647,8 @@ const ( ResourceQuotas ResourceName = "resourcequotas" // ResourceSecrets, number ResourceSecrets ResourceName = "secrets" + // ResourceConfigMaps, number + ResourceConfigMaps ResourceName = "configmaps" // ResourcePersistentVolumeClaims, number ResourcePersistentVolumeClaims ResourceName = "persistentvolumeclaims" // CPU request, in cores. (500m = .5 cores) @@ -2672,7 +2678,7 @@ const ( // ResourceQuotaSpec defines the desired hard limits to enforce for Quota. type ResourceQuotaSpec struct { // Hard is the set of desired hard limits for each named resource. - // More info: http://releases.k8s.io/HEAD/docs/design/admission_control_resource_quota.md#admissioncontrol-plugin-resourcequota + // More info: http://releases.k8s.io/release-1.2/docs/design/admission_control_resource_quota.md#admissioncontrol-plugin-resourcequota Hard ResourceList `json:"hard,omitempty"` // A collection of filters that must match each object tracked by a quota. // If not specified, the quota matches all objects. @@ -2682,7 +2688,7 @@ type ResourceQuotaSpec struct { // ResourceQuotaStatus defines the enforced hard limits and observed use. type ResourceQuotaStatus struct { // Hard is the set of enforced hard limits for each named resource. - // More info: http://releases.k8s.io/HEAD/docs/design/admission_control_resource_quota.md#admissioncontrol-plugin-resourcequota + // More info: http://releases.k8s.io/release-1.2/docs/design/admission_control_resource_quota.md#admissioncontrol-plugin-resourcequota Hard ResourceList `json:"hard,omitempty"` // Used is the current observed total usage of the resource in the namespace. Used ResourceList `json:"used,omitempty"` @@ -2694,15 +2700,15 @@ type ResourceQuotaStatus struct { type ResourceQuota struct { unversioned.TypeMeta `json:",inline"` // Standard object's metadata. - // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata + // More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#metadata ObjectMeta `json:"metadata,omitempty"` // Spec defines the desired quota. - // http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#spec-and-status + // http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#spec-and-status Spec ResourceQuotaSpec `json:"spec,omitempty"` // Status defines the actual enforced quota and its current usage. - // http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#spec-and-status + // http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#spec-and-status Status ResourceQuotaStatus `json:"status,omitempty"` } @@ -2710,11 +2716,11 @@ type ResourceQuota struct { type ResourceQuotaList struct { unversioned.TypeMeta `json:",inline"` // Standard list metadata. - // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds + // More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#types-kinds unversioned.ListMeta `json:"metadata,omitempty"` // Items is a list of ResourceQuota objects. - // More info: http://releases.k8s.io/HEAD/docs/design/admission_control_resource_quota.md#admissioncontrol-plugin-resourcequota + // More info: http://releases.k8s.io/release-1.2/docs/design/admission_control_resource_quota.md#admissioncontrol-plugin-resourcequota Items []ResourceQuota `json:"items"` } @@ -2725,7 +2731,7 @@ type ResourceQuotaList struct { type Secret struct { unversioned.TypeMeta `json:",inline"` // Standard object's metadata. - // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata + // More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#metadata ObjectMeta `json:"metadata,omitempty"` // Data contains the secret data. Each key must be a valid DNS_SUBDOMAIN @@ -2797,11 +2803,11 @@ const ( type SecretList struct { unversioned.TypeMeta `json:",inline"` // Standard list metadata. - // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds + // More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#types-kinds unversioned.ListMeta `json:"metadata,omitempty"` // Items is a list of secret objects. - // More info: http://releases.k8s.io/HEAD/docs/user-guide/secrets.md + // More info: http://releases.k8s.io/release-1.2/docs/user-guide/secrets.md Items []Secret `json:"items"` } @@ -2811,7 +2817,7 @@ type SecretList struct { type ConfigMap struct { unversioned.TypeMeta `json:",inline"` // Standard object's metadata. - // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata + // More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#metadata ObjectMeta `json:"metadata,omitempty"` // Data contains the configuration data. @@ -2823,7 +2829,7 @@ type ConfigMap struct { type ConfigMapList struct { unversioned.TypeMeta `json:",inline"` - // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata + // More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#metadata unversioned.ListMeta `json:"metadata,omitempty"` // Items is the list of ConfigMaps. @@ -2860,7 +2866,7 @@ type ComponentCondition struct { type ComponentStatus struct { unversioned.TypeMeta `json:",inline"` // Standard object's metadata. - // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata + // More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#metadata ObjectMeta `json:"metadata,omitempty"` // List of component conditions observed @@ -2871,7 +2877,7 @@ type ComponentStatus struct { type ComponentStatusList struct { unversioned.TypeMeta `json:",inline"` // Standard list metadata. - // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds + // More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#types-kinds unversioned.ListMeta `json:"metadata,omitempty"` // List of ComponentStatus objects. @@ -2942,7 +2948,7 @@ type SELinuxOptions struct { type RangeAllocation struct { unversioned.TypeMeta `json:",inline"` // Standard object's metadata. - // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata + // More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#metadata ObjectMeta `json:"metadata,omitempty"` // Range is string that identifies the range represented by 'data'. 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 31c1021..f1878b5 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 @@ -29,10 +29,10 @@ package v1 // AUTO-GENERATED FUNCTIONS START HERE var map_AWSElasticBlockStoreVolumeSource = map[string]string{ "": "Represents a Persistent Disk resource in AWS.\n\nAn AWS EBS disk must exist before mounting to a container. The disk must also be in the same AWS zone as the kubelet. An AWS EBS disk can only be mounted as read/write once. AWS EBS volumes support ownership management and SELinux relabeling.", - "volumeID": "Unique ID of the persistent disk resource in AWS (Amazon EBS volume). More info: http://releases.k8s.io/HEAD/docs/user-guide/volumes.md#awselasticblockstore", - "fsType": "Filesystem type of the volume that you want to mount. Tip: Ensure that the filesystem type is supported by the host operating system. Examples: \"ext4\", \"xfs\", \"ntfs\". Implicitly inferred to be \"ext4\" if unspecified. More info: http://releases.k8s.io/HEAD/docs/user-guide/volumes.md#awselasticblockstore", + "volumeID": "Unique ID of the persistent disk resource in AWS (Amazon EBS volume). More info: http://releases.k8s.io/release-1.2/docs/user-guide/volumes.md#awselasticblockstore", + "fsType": "Filesystem type of the volume that you want to mount. Tip: Ensure that the filesystem type is supported by the host operating system. Examples: \"ext4\", \"xfs\", \"ntfs\". Implicitly inferred to be \"ext4\" if unspecified. More info: http://releases.k8s.io/release-1.2/docs/user-guide/volumes.md#awselasticblockstore", "partition": "The partition in the volume that you want to mount. If omitted, the default is to mount by volume name. Examples: For volume /dev/sda1, you specify the partition as \"1\". Similarly, the volume partition for /dev/sda is \"0\" (or you can leave the property empty).", - "readOnly": "Specify \"true\" to force and set the ReadOnly property in VolumeMounts to \"true\". If omitted, the default is \"false\". More info: http://releases.k8s.io/HEAD/docs/user-guide/volumes.md#awselasticblockstore", + "readOnly": "Specify \"true\" to force and set the ReadOnly property in VolumeMounts to \"true\". If omitted, the default is \"false\". More info: http://releases.k8s.io/release-1.2/docs/user-guide/volumes.md#awselasticblockstore", } func (AWSElasticBlockStoreVolumeSource) SwaggerDoc() map[string]string { @@ -61,7 +61,7 @@ func (AzureFileVolumeSource) SwaggerDoc() map[string]string { var map_Binding = map[string]string{ "": "Binding ties one object to another. For example, a pod is bound to a node by a scheduler.", - "metadata": "Standard object's metadata. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata", + "metadata": "Standard object's metadata. More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#metadata", "target": "The target object that you want to bind to the standard object.", } @@ -81,12 +81,12 @@ func (Capabilities) SwaggerDoc() map[string]string { var map_CephFSVolumeSource = map[string]string{ "": "Represents a Ceph Filesystem mount that lasts the lifetime of a pod Cephfs volumes do not support ownership management or SELinux relabeling.", - "monitors": "Required: Monitors is a collection of Ceph monitors More info: http://releases.k8s.io/HEAD/examples/cephfs/README.md#how-to-use-it", + "monitors": "Required: Monitors is a collection of Ceph monitors More info: http://releases.k8s.io/release-1.2/examples/cephfs/README.md#how-to-use-it", "path": "Optional: Used as the mounted root, rather than the full Ceph tree, default is /", - "user": "Optional: User is the rados user name, default is admin More info: http://releases.k8s.io/HEAD/examples/cephfs/README.md#how-to-use-it", - "secretFile": "Optional: SecretFile is the path to key ring for User, default is /etc/ceph/user.secret More info: http://releases.k8s.io/HEAD/examples/cephfs/README.md#how-to-use-it", - "secretRef": "Optional: SecretRef is reference to the authentication secret for User, default is empty. More info: http://releases.k8s.io/HEAD/examples/cephfs/README.md#how-to-use-it", - "readOnly": "Optional: Defaults to false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts. More info: http://releases.k8s.io/HEAD/examples/cephfs/README.md#how-to-use-it", + "user": "Optional: User is the rados user name, default is admin More info: http://releases.k8s.io/release-1.2/examples/cephfs/README.md#how-to-use-it", + "secretFile": "Optional: SecretFile is the path to key ring for User, default is /etc/ceph/user.secret More info: http://releases.k8s.io/release-1.2/examples/cephfs/README.md#how-to-use-it", + "secretRef": "Optional: SecretRef is reference to the authentication secret for User, default is empty. More info: http://releases.k8s.io/release-1.2/examples/cephfs/README.md#how-to-use-it", + "readOnly": "Optional: Defaults to false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts. More info: http://releases.k8s.io/release-1.2/examples/cephfs/README.md#how-to-use-it", } func (CephFSVolumeSource) SwaggerDoc() map[string]string { @@ -95,9 +95,9 @@ func (CephFSVolumeSource) SwaggerDoc() map[string]string { var map_CinderVolumeSource = map[string]string{ "": "Represents a cinder volume resource in Openstack. A Cinder volume must exist before mounting to a container. The volume must also be in the same region as the kubelet. Cinder volumes support ownership management and SELinux relabeling.", - "volumeID": "volume id used to identify the volume in cinder More info: http://releases.k8s.io/HEAD/examples/mysql-cinder-pd/README.md", - "fsType": "Filesystem type to mount. Must be a filesystem type supported by the host operating system. Examples: \"ext4\", \"xfs\", \"ntfs\". Implicitly inferred to be \"ext4\" if unspecified. More info: http://releases.k8s.io/HEAD/examples/mysql-cinder-pd/README.md", - "readOnly": "Optional: Defaults to false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts. More info: http://releases.k8s.io/HEAD/examples/mysql-cinder-pd/README.md", + "volumeID": "volume id used to identify the volume in cinder More info: http://releases.k8s.io/release-1.2/examples/mysql-cinder-pd/README.md", + "fsType": "Filesystem type to mount. Must be a filesystem type supported by the host operating system. Examples: \"ext4\", \"xfs\", \"ntfs\". Implicitly inferred to be \"ext4\" if unspecified. More info: http://releases.k8s.io/release-1.2/examples/mysql-cinder-pd/README.md", + "readOnly": "Optional: Defaults to false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts. More info: http://releases.k8s.io/release-1.2/examples/mysql-cinder-pd/README.md", } func (CinderVolumeSource) SwaggerDoc() map[string]string { @@ -118,7 +118,7 @@ func (ComponentCondition) SwaggerDoc() map[string]string { var map_ComponentStatus = map[string]string{ "": "ComponentStatus (and ComponentStatusList) holds the cluster validation info.", - "metadata": "Standard object's metadata. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata", + "metadata": "Standard object's metadata. More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#metadata", "conditions": "List of component conditions observed", } @@ -128,7 +128,7 @@ func (ComponentStatus) SwaggerDoc() map[string]string { var map_ComponentStatusList = map[string]string{ "": "Status of all the conditions for the component as a list of ComponentStatus objects.", - "metadata": "Standard list metadata. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds", + "metadata": "Standard list metadata. More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#types-kinds", "items": "List of ComponentStatus objects.", } @@ -138,7 +138,7 @@ func (ComponentStatusList) SwaggerDoc() map[string]string { var map_ConfigMap = map[string]string{ "": "ConfigMap holds configuration data for pods to consume.", - "metadata": "Standard object's metadata. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata", + "metadata": "Standard object's metadata. More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#metadata", "data": "Data contains the configuration data. Each key must be a valid DNS_SUBDOMAIN with an optional leading dot.", } @@ -157,7 +157,7 @@ func (ConfigMapKeySelector) SwaggerDoc() map[string]string { var map_ConfigMapList = map[string]string{ "": "ConfigMapList is a resource containing a list of ConfigMap objects.", - "metadata": "More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata", + "metadata": "More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#metadata", "items": "Items is the list of ConfigMaps.", } @@ -177,20 +177,20 @@ func (ConfigMapVolumeSource) SwaggerDoc() map[string]string { var map_Container = map[string]string{ "": "A single application container that you want to run within a pod.", "name": "Name of the container specified as a DNS_LABEL. Each container in a pod must have a unique name (DNS_LABEL). Cannot be updated.", - "image": "Docker image name. More info: http://releases.k8s.io/HEAD/docs/user-guide/images.md", - "command": "Entrypoint array. Not executed within a shell. The docker image's ENTRYPOINT is used if this is not provided. Variable references $(VAR_NAME) are expanded using the container's environment. If a variable cannot be resolved, the reference in the input string will be unchanged. The $(VAR_NAME) syntax can be escaped with a double $$, ie: $$(VAR_NAME). Escaped references will never be expanded, regardless of whether the variable exists or not. Cannot be updated. More info: http://releases.k8s.io/HEAD/docs/user-guide/containers.md#containers-and-commands", - "args": "Arguments to the entrypoint. The docker image's CMD is used if this is not provided. Variable references $(VAR_NAME) are expanded using the container's environment. If a variable cannot be resolved, the reference in the input string will be unchanged. The $(VAR_NAME) syntax can be escaped with a double $$, ie: $$(VAR_NAME). Escaped references will never be expanded, regardless of whether the variable exists or not. Cannot be updated. More info: http://releases.k8s.io/HEAD/docs/user-guide/containers.md#containers-and-commands", + "image": "Docker image name. More info: http://releases.k8s.io/release-1.2/docs/user-guide/images.md", + "command": "Entrypoint array. Not executed within a shell. The docker image's ENTRYPOINT is used if this is not provided. Variable references $(VAR_NAME) are expanded using the container's environment. If a variable cannot be resolved, the reference in the input string will be unchanged. The $(VAR_NAME) syntax can be escaped with a double $$, ie: $$(VAR_NAME). Escaped references will never be expanded, regardless of whether the variable exists or not. Cannot be updated. More info: http://releases.k8s.io/release-1.2/docs/user-guide/containers.md#containers-and-commands", + "args": "Arguments to the entrypoint. The docker image's CMD is used if this is not provided. Variable references $(VAR_NAME) are expanded using the container's environment. If a variable cannot be resolved, the reference in the input string will be unchanged. The $(VAR_NAME) syntax can be escaped with a double $$, ie: $$(VAR_NAME). Escaped references will never be expanded, regardless of whether the variable exists or not. Cannot be updated. More info: http://releases.k8s.io/release-1.2/docs/user-guide/containers.md#containers-and-commands", "workingDir": "Container's working directory. If not specified, the container runtime's default will be used, which might be configured in the container image. Cannot be updated.", "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", + "resources": "Compute Resources required by this container. Cannot be updated. More info: http://releases.k8s.io/release-1.2/docs/user-guide/persistent-volumes.md#resources", "volumeMounts": "Pod volumes to mount into the container's filesyste. 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", + "livenessProbe": "Periodic probe of container liveness. Container will be restarted if the probe fails. Cannot be updated. More info: http://releases.k8s.io/release-1.2/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/release-1.2/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.", "terminationMessagePath": "Optional: Path at which the file to which the container's termination message will be written is mounted into the container's filesystem. Message written is intended to be brief final status, such as an assertion failure message. Defaults to /dev/termination-log. Cannot be updated.", - "imagePullPolicy": "Image pull policy. One of Always, Never, IfNotPresent. Defaults to Always if :latest tag is specified, or IfNotPresent otherwise. Cannot be updated. More info: http://releases.k8s.io/HEAD/docs/user-guide/images.md#updating-images", - "securityContext": "Security options the pod should run with. More info: http://releases.k8s.io/HEAD/docs/design/security_context.md", + "imagePullPolicy": "Image pull policy. One of Always, Never, IfNotPresent. Defaults to Always if :latest tag is specified, or IfNotPresent otherwise. Cannot be updated. More info: http://releases.k8s.io/release-1.2/docs/user-guide/images.md#updating-images", + "securityContext": "Security options the pod should run with. More info: http://releases.k8s.io/release-1.2/docs/design/security_context.md", "stdin": "Whether this container should allocate a buffer for stdin in the container runtime. If this is not set, reads from stdin in the container will always result in EOF. Default is false.", "stdinOnce": "Whether the container runtime should close the stdin channel after it has been opened by a single attach. When stdin is true the stdin stream will remain open across multiple attach sessions. If stdinOnce is set to true, stdin is opened on container start, is empty until the first client attaches to stdin, and then remains open and accepts data until the client disconnects, at which time stdin is closed and remains closed until the container is restarted. If this flag is false, a container processes that reads from stdin will never receive an EOF. Default is false", "tty": "Whether this container should allocate a TTY for itself, also requires 'stdin' to be true. Default is false.", @@ -275,9 +275,9 @@ var map_ContainerStatus = map[string]string{ "lastState": "Details about the container's last termination condition.", "ready": "Specifies whether the container has passed its readiness probe.", "restartCount": "The number of times the container has been restarted, currently based on the number of dead containers that have not yet been removed. Note that this is calculated from dead containers. But those containers are subject to garbage collection. This value will get capped at 5 by GC.", - "image": "The image the container is running. More info: http://releases.k8s.io/HEAD/docs/user-guide/images.md", + "image": "The image the container is running. More info: http://releases.k8s.io/release-1.2/docs/user-guide/images.md", "imageID": "ImageID of the container's image.", - "containerID": "Container's ID in the format 'docker://'. More info: http://releases.k8s.io/HEAD/docs/user-guide/container-environment.md#container-information", + "containerID": "Container's ID in the format 'docker://'. More info: http://releases.k8s.io/release-1.2/docs/user-guide/container-environment.md#container-information", } func (ContainerStatus) SwaggerDoc() map[string]string { @@ -323,7 +323,7 @@ func (DownwardAPIVolumeSource) SwaggerDoc() map[string]string { var map_EmptyDirVolumeSource = map[string]string{ "": "Represents an empty directory for a pod. Empty directory volumes support ownership management and SELinux relabeling.", - "medium": "What type of storage medium should back this directory. The default is \"\" which means to use the node's default medium. Must be an empty string (default) or Memory. More info: http://releases.k8s.io/HEAD/docs/user-guide/volumes.md#emptydir", + "medium": "What type of storage medium should back this directory. The default is \"\" which means to use the node's default medium. Must be an empty string (default) or Memory. More info: http://releases.k8s.io/release-1.2/docs/user-guide/volumes.md#emptydir", } func (EmptyDirVolumeSource) SwaggerDoc() map[string]string { @@ -364,7 +364,7 @@ func (EndpointSubset) SwaggerDoc() map[string]string { var map_Endpoints = map[string]string{ "": "Endpoints is a collection of endpoints that implement the actual service. Example:\n Name: \"mysvc\",\n Subsets: [\n {\n Addresses: [{\"ip\": \"10.10.1.1\"}, {\"ip\": \"10.10.2.2\"}],\n Ports: [{\"name\": \"a\", \"port\": 8675}, {\"name\": \"b\", \"port\": 309}]\n },\n {\n Addresses: [{\"ip\": \"10.10.3.3\"}],\n Ports: [{\"name\": \"a\", \"port\": 93}, {\"name\": \"b\", \"port\": 76}]\n },\n ]", - "metadata": "Standard object's metadata. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata", + "metadata": "Standard object's metadata. More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#metadata", "subsets": "The set of all endpoints is the union of all subsets. Addresses are placed into subsets according to the IPs they share. A single address with multiple ports, some of which are ready and some of which are not (because they come from different containers) will result in the address being displayed in different subsets for the different ports. No address will appear in both Addresses and NotReadyAddresses in the same subset. Sets of addresses and ports that comprise a service.", } @@ -374,7 +374,7 @@ func (Endpoints) SwaggerDoc() map[string]string { var map_EndpointsList = map[string]string{ "": "EndpointsList is a list of endpoints.", - "metadata": "Standard list metadata. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds", + "metadata": "Standard list metadata. More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#types-kinds", "items": "List of endpoints.", } @@ -406,7 +406,7 @@ func (EnvVarSource) SwaggerDoc() map[string]string { var map_Event = map[string]string{ "": "Event is a report of an event somewhere in the cluster.", - "metadata": "Standard object's metadata. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata", + "metadata": "Standard object's metadata. More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#metadata", "involvedObject": "The object that this event is about.", "reason": "This should be a short, machine understandable string that gives the reason for the transition into the object's current status.", "message": "A human-readable description of the status of this operation.", @@ -423,7 +423,7 @@ func (Event) SwaggerDoc() map[string]string { var map_EventList = map[string]string{ "": "EventList is a list of events.", - "metadata": "Standard list metadata. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds", + "metadata": "Standard list metadata. More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#types-kinds", "items": "List of events", } @@ -496,10 +496,10 @@ func (FlockerVolumeSource) SwaggerDoc() map[string]string { var map_GCEPersistentDiskVolumeSource = map[string]string{ "": "Represents a Persistent Disk resource in Google Compute Engine.\n\nA GCE PD must exist before mounting to a container. The disk must also be in the same GCE project and zone as the kubelet. A GCE PD can only be mounted as read/write once or read-only many times. GCE PDs support ownership management and SELinux relabeling.", - "pdName": "Unique name of the PD resource in GCE. Used to identify the disk in GCE. More info: http://releases.k8s.io/HEAD/docs/user-guide/volumes.md#gcepersistentdisk", - "fsType": "Filesystem type of the volume that you want to mount. Tip: Ensure that the filesystem type is supported by the host operating system. Examples: \"ext4\", \"xfs\", \"ntfs\". Implicitly inferred to be \"ext4\" if unspecified. More info: http://releases.k8s.io/HEAD/docs/user-guide/volumes.md#gcepersistentdisk", - "partition": "The partition in the volume that you want to mount. If omitted, the default is to mount by volume name. Examples: For volume /dev/sda1, you specify the partition as \"1\". Similarly, the volume partition for /dev/sda is \"0\" (or you can leave the property empty). More info: http://releases.k8s.io/HEAD/docs/user-guide/volumes.md#gcepersistentdisk", - "readOnly": "ReadOnly here will force the ReadOnly setting in VolumeMounts. Defaults to false. More info: http://releases.k8s.io/HEAD/docs/user-guide/volumes.md#gcepersistentdisk", + "pdName": "Unique name of the PD resource in GCE. Used to identify the disk in GCE. More info: http://releases.k8s.io/release-1.2/docs/user-guide/volumes.md#gcepersistentdisk", + "fsType": "Filesystem type of the volume that you want to mount. Tip: Ensure that the filesystem type is supported by the host operating system. Examples: \"ext4\", \"xfs\", \"ntfs\". Implicitly inferred to be \"ext4\" if unspecified. More info: http://releases.k8s.io/release-1.2/docs/user-guide/volumes.md#gcepersistentdisk", + "partition": "The partition in the volume that you want to mount. If omitted, the default is to mount by volume name. Examples: For volume /dev/sda1, you specify the partition as \"1\". Similarly, the volume partition for /dev/sda is \"0\" (or you can leave the property empty). More info: http://releases.k8s.io/release-1.2/docs/user-guide/volumes.md#gcepersistentdisk", + "readOnly": "ReadOnly here will force the ReadOnly setting in VolumeMounts. Defaults to false. More info: http://releases.k8s.io/release-1.2/docs/user-guide/volumes.md#gcepersistentdisk", } func (GCEPersistentDiskVolumeSource) SwaggerDoc() map[string]string { @@ -519,9 +519,9 @@ func (GitRepoVolumeSource) SwaggerDoc() map[string]string { var map_GlusterfsVolumeSource = map[string]string{ "": "Represents a Glusterfs mount that lasts the lifetime of a pod. Glusterfs volumes do not support ownership management or SELinux relabeling.", - "endpoints": "EndpointsName is the endpoint name that details Glusterfs topology. More info: http://releases.k8s.io/HEAD/examples/glusterfs/README.md#create-a-pod", - "path": "Path is the Glusterfs volume path. More info: http://releases.k8s.io/HEAD/examples/glusterfs/README.md#create-a-pod", - "readOnly": "ReadOnly here will force the Glusterfs volume to be mounted with read-only permissions. Defaults to false. More info: http://releases.k8s.io/HEAD/examples/glusterfs/README.md#create-a-pod", + "endpoints": "EndpointsName is the endpoint name that details Glusterfs topology. More info: http://releases.k8s.io/release-1.2/examples/glusterfs/README.md#create-a-pod", + "path": "Path is the Glusterfs volume path. More info: http://releases.k8s.io/release-1.2/examples/glusterfs/README.md#create-a-pod", + "readOnly": "ReadOnly here will force the Glusterfs volume to be mounted with read-only permissions. Defaults to false. More info: http://releases.k8s.io/release-1.2/examples/glusterfs/README.md#create-a-pod", } func (GlusterfsVolumeSource) SwaggerDoc() map[string]string { @@ -564,7 +564,7 @@ func (Handler) SwaggerDoc() map[string]string { var map_HostPathVolumeSource = map[string]string{ "": "Represents a host path mapped into a pod. Host path volumes do not support ownership management or SELinux relabeling.", - "path": "Path of the directory on the host. More info: http://releases.k8s.io/HEAD/docs/user-guide/volumes.md#hostpath", + "path": "Path of the directory on the host. More info: http://releases.k8s.io/release-1.2/docs/user-guide/volumes.md#hostpath", } func (HostPathVolumeSource) SwaggerDoc() map[string]string { @@ -577,7 +577,7 @@ var map_ISCSIVolumeSource = map[string]string{ "iqn": "Target iSCSI Qualified Name.", "lun": "iSCSI target lun number.", "iscsiInterface": "Optional: Defaults to 'default' (tcp). iSCSI interface name that uses an iSCSI transport.", - "fsType": "Filesystem type of the volume that you want to mount. Tip: Ensure that the filesystem type is supported by the host operating system. Examples: \"ext4\", \"xfs\", \"ntfs\". Implicitly inferred to be \"ext4\" if unspecified. More info: http://releases.k8s.io/HEAD/docs/user-guide/volumes.md#iscsi", + "fsType": "Filesystem type of the volume that you want to mount. Tip: Ensure that the filesystem type is supported by the host operating system. Examples: \"ext4\", \"xfs\", \"ntfs\". Implicitly inferred to be \"ext4\" if unspecified. More info: http://releases.k8s.io/release-1.2/docs/user-guide/volumes.md#iscsi", "readOnly": "ReadOnly here will force the ReadOnly setting in VolumeMounts. Defaults to false.", } @@ -597,8 +597,8 @@ func (KeyToPath) SwaggerDoc() map[string]string { var map_Lifecycle = map[string]string{ "": "Lifecycle describes actions that the management system should take in response to container lifecycle events. For the PostStart and PreStop lifecycle handlers, management of the container blocks until the action is complete, unless the container process fails, in which case the handler is aborted.", - "postStart": "PostStart is called immediately after a container is created. If the handler fails, the container is terminated and restarted according to its restart policy. Other management of the container blocks until the hook completes. More info: http://releases.k8s.io/HEAD/docs/user-guide/container-environment.md#hook-details", - "preStop": "PreStop is called immediately before a container is terminated. The container is terminated after the handler completes. The reason for termination is passed to the handler. Regardless of the outcome of the handler, the container is eventually terminated. Other management of the container blocks until the hook completes. More info: http://releases.k8s.io/HEAD/docs/user-guide/container-environment.md#hook-details", + "postStart": "PostStart is called immediately after a container is created. If the handler fails, the container is terminated and restarted according to its restart policy. Other management of the container blocks until the hook completes. More info: http://releases.k8s.io/release-1.2/docs/user-guide/container-environment.md#hook-details", + "preStop": "PreStop is called immediately before a container is terminated. The container is terminated after the handler completes. The reason for termination is passed to the handler. Regardless of the outcome of the handler, the container is eventually terminated. Other management of the container blocks until the hook completes. More info: http://releases.k8s.io/release-1.2/docs/user-guide/container-environment.md#hook-details", } func (Lifecycle) SwaggerDoc() map[string]string { @@ -607,8 +607,8 @@ func (Lifecycle) SwaggerDoc() map[string]string { var map_LimitRange = map[string]string{ "": "LimitRange sets resource usage limits for each kind of resource in a Namespace.", - "metadata": "Standard object's metadata. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata", - "spec": "Spec defines the limits enforced. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#spec-and-status", + "metadata": "Standard object's metadata. More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#metadata", + "spec": "Spec defines the limits enforced. More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#spec-and-status", } func (LimitRange) SwaggerDoc() map[string]string { @@ -631,8 +631,8 @@ func (LimitRangeItem) SwaggerDoc() map[string]string { var map_LimitRangeList = map[string]string{ "": "LimitRangeList is a list of LimitRange items.", - "metadata": "Standard list metadata. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds", - "items": "Items is a list of LimitRange objects. More info: http://releases.k8s.io/HEAD/docs/design/admission_control_limit_range.md", + "metadata": "Standard list metadata. More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#types-kinds", + "items": "Items is a list of LimitRange objects. More info: http://releases.k8s.io/release-1.2/docs/design/admission_control_limit_range.md", } func (LimitRangeList) SwaggerDoc() map[string]string { @@ -650,7 +650,7 @@ func (LimitRangeSpec) SwaggerDoc() map[string]string { var map_List = map[string]string{ "": "List holds a list of objects, which may not be known by the server.", - "metadata": "Standard list metadata. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds", + "metadata": "Standard list metadata. More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#types-kinds", "items": "List of objects", } @@ -692,7 +692,7 @@ func (LoadBalancerStatus) SwaggerDoc() map[string]string { var map_LocalObjectReference = map[string]string{ "": "LocalObjectReference contains enough information to let you locate the referenced object inside the same namespace.", - "name": "Name of the referent. More info: http://releases.k8s.io/HEAD/docs/user-guide/identifiers.md#names", + "name": "Name of the referent. More info: http://releases.k8s.io/release-1.2/docs/user-guide/identifiers.md#names", } func (LocalObjectReference) SwaggerDoc() map[string]string { @@ -701,9 +701,9 @@ func (LocalObjectReference) SwaggerDoc() map[string]string { var map_NFSVolumeSource = map[string]string{ "": "Represents an NFS mount that lasts the lifetime of a pod. NFS volumes do not support ownership management or SELinux relabeling.", - "server": "Server is the hostname or IP address of the NFS server. More info: http://releases.k8s.io/HEAD/docs/user-guide/volumes.md#nfs", - "path": "Path that is exported by the NFS server. More info: http://releases.k8s.io/HEAD/docs/user-guide/volumes.md#nfs", - "readOnly": "ReadOnly here will force the NFS export to be mounted with read-only permissions. Defaults to false. More info: http://releases.k8s.io/HEAD/docs/user-guide/volumes.md#nfs", + "server": "Server is the hostname or IP address of the NFS server. More info: http://releases.k8s.io/release-1.2/docs/user-guide/volumes.md#nfs", + "path": "Path that is exported by the NFS server. More info: http://releases.k8s.io/release-1.2/docs/user-guide/volumes.md#nfs", + "readOnly": "ReadOnly here will force the NFS export to be mounted with read-only permissions. Defaults to false. More info: http://releases.k8s.io/release-1.2/docs/user-guide/volumes.md#nfs", } func (NFSVolumeSource) SwaggerDoc() map[string]string { @@ -712,9 +712,9 @@ func (NFSVolumeSource) SwaggerDoc() map[string]string { var map_Namespace = map[string]string{ "": "Namespace provides a scope for Names. Use of multiple namespaces is optional.", - "metadata": "Standard object's metadata. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata", - "spec": "Spec defines the behavior of the Namespace. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#spec-and-status", - "status": "Status describes the current status of a Namespace. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#spec-and-status", + "metadata": "Standard object's metadata. More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#metadata", + "spec": "Spec defines the behavior of the Namespace. More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#spec-and-status", + "status": "Status describes the current status of a Namespace. More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#spec-and-status", } func (Namespace) SwaggerDoc() map[string]string { @@ -723,8 +723,8 @@ func (Namespace) SwaggerDoc() map[string]string { var map_NamespaceList = map[string]string{ "": "NamespaceList is a list of Namespaces.", - "metadata": "Standard list metadata. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds", - "items": "Items is the list of Namespace objects in the list. More info: http://releases.k8s.io/HEAD/docs/user-guide/namespaces.md", + "metadata": "Standard list metadata. More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#types-kinds", + "items": "Items is the list of Namespace objects in the list. More info: http://releases.k8s.io/release-1.2/docs/user-guide/namespaces.md", } func (NamespaceList) SwaggerDoc() map[string]string { @@ -733,7 +733,7 @@ func (NamespaceList) SwaggerDoc() map[string]string { var map_NamespaceSpec = map[string]string{ "": "NamespaceSpec describes the attributes on a Namespace.", - "finalizers": "Finalizers is an opaque list of values that must be empty to permanently remove object from storage. More info: http://releases.k8s.io/HEAD/docs/design/namespaces.md#finalizers", + "finalizers": "Finalizers is an opaque list of values that must be empty to permanently remove object from storage. More info: http://releases.k8s.io/release-1.2/docs/design/namespaces.md#finalizers", } func (NamespaceSpec) SwaggerDoc() map[string]string { @@ -742,7 +742,7 @@ func (NamespaceSpec) SwaggerDoc() map[string]string { var map_NamespaceStatus = map[string]string{ "": "NamespaceStatus is information about the current status of a Namespace.", - "phase": "Phase is the current lifecycle phase of the namespace. More info: http://releases.k8s.io/HEAD/docs/design/namespaces.md#phases", + "phase": "Phase is the current lifecycle phase of the namespace. More info: http://releases.k8s.io/release-1.2/docs/design/namespaces.md#phases", } func (NamespaceStatus) SwaggerDoc() map[string]string { @@ -751,9 +751,9 @@ func (NamespaceStatus) SwaggerDoc() map[string]string { var map_Node = map[string]string{ "": "Node is a worker node in Kubernetes, formerly known as minion. Each node will have a unique identifier in the cache (i.e. in etcd).", - "metadata": "Standard object's metadata. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata", - "spec": "Spec defines the behavior of a node. http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#spec-and-status", - "status": "Most recently observed status of the node. Populated by the system. Read-only. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#spec-and-status", + "metadata": "Standard object's metadata. More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#metadata", + "spec": "Spec defines the behavior of a node. http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#spec-and-status", + "status": "Most recently observed status of the node. Populated by the system. Read-only. More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#spec-and-status", } func (Node) SwaggerDoc() map[string]string { @@ -805,7 +805,7 @@ func (NodeDaemonEndpoints) SwaggerDoc() map[string]string { var map_NodeList = map[string]string{ "": "NodeList is the whole list of all Nodes which have been registered with master.", - "metadata": "Standard list metadata. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds", + "metadata": "Standard list metadata. More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#types-kinds", "items": "List of nodes", } @@ -856,7 +856,7 @@ var map_NodeSpec = map[string]string{ "podCIDR": "PodCIDR represents the pod IP range assigned to the node.", "externalID": "External ID of the node assigned by some machine database (e.g. a cloud provider). Deprecated.", "providerID": "ID of the node assigned by the cloud provider in the format: ://", - "unschedulable": "Unschedulable controls node schedulability of new pods. By default, node is schedulable. More info: http://releases.k8s.io/HEAD/docs/admin/node.md#manual-node-administration\"`", + "unschedulable": "Unschedulable controls node schedulability of new pods. By default, node is schedulable. More info: http://releases.k8s.io/release-1.2/docs/admin/node.md#manual-node-administration\"`", } func (NodeSpec) SwaggerDoc() map[string]string { @@ -865,13 +865,13 @@ func (NodeSpec) SwaggerDoc() map[string]string { var map_NodeStatus = map[string]string{ "": "NodeStatus is information about the current status of a node.", - "capacity": "Capacity represents the total resources of a node. More info: http://releases.k8s.io/HEAD/docs/user-guide/persistent-volumes.md#capacity for more details.", + "capacity": "Capacity represents the total resources of a node. More info: http://releases.k8s.io/release-1.2/docs/user-guide/persistent-volumes.md#capacity for more details.", "allocatable": "Allocatable represents the resources of a node that are available for scheduling. Defaults to Capacity.", - "phase": "NodePhase is the recently observed lifecycle phase of the node. More info: http://releases.k8s.io/HEAD/docs/admin/node.md#node-phase", - "conditions": "Conditions is an array of current observed node conditions. More info: http://releases.k8s.io/HEAD/docs/admin/node.md#node-condition", - "addresses": "List of addresses reachable to the node. Queried from cloud provider, if available. More info: http://releases.k8s.io/HEAD/docs/admin/node.md#node-addresses", + "phase": "NodePhase is the recently observed lifecycle phase of the node. More info: http://releases.k8s.io/release-1.2/docs/admin/node.md#node-phase", + "conditions": "Conditions is an array of current observed node conditions. More info: http://releases.k8s.io/release-1.2/docs/admin/node.md#node-condition", + "addresses": "List of addresses reachable to the node. Queried from cloud provider, if available. More info: http://releases.k8s.io/release-1.2/docs/admin/node.md#node-addresses", "daemonEndpoints": "Endpoints of daemons running on the Node.", - "nodeInfo": "Set of ids/uuids to uniquely identify the node. More info: http://releases.k8s.io/HEAD/docs/admin/node.md#node-info", + "nodeInfo": "Set of ids/uuids to uniquely identify the node. More info: http://releases.k8s.io/release-1.2/docs/admin/node.md#node-info", "images": "List of container images on this node", } @@ -907,18 +907,18 @@ func (ObjectFieldSelector) SwaggerDoc() map[string]string { var map_ObjectMeta = map[string]string{ "": "ObjectMeta is metadata that all persisted resources must have, which includes all objects users must create.", - "name": "Name must be unique within a namespace. Is required when creating resources, although some resources may allow a client to request the generation of an appropriate name automatically. Name is primarily intended for creation idempotence and configuration definition. Cannot be updated. More info: http://releases.k8s.io/HEAD/docs/user-guide/identifiers.md#names", - "generateName": "GenerateName is an optional prefix, used by the server, to generate a unique name ONLY IF the Name field has not been provided. If this field is used, the name returned to the client will be different than the name passed. This value will also be combined with a unique suffix. The provided value has the same validation rules as the Name field, and may be truncated by the length of the suffix required to make the value unique on the server.\n\nIf this field is specified and the generated name exists, the server will NOT return a 409 - instead, it will either return 201 Created or 500 with Reason ServerTimeout indicating a unique name could not be found in the time allotted, and the client should retry (optionally after the time indicated in the Retry-After header).\n\nApplied only if Name is not specified. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#idempotency", - "namespace": "Namespace defines the space within each name must be unique. An empty namespace is equivalent to the \"default\" namespace, but \"default\" is the canonical representation. Not all objects are required to be scoped to a namespace - the value of this field for those objects will be empty.\n\nMust be a DNS_LABEL. Cannot be updated. More info: http://releases.k8s.io/HEAD/docs/user-guide/namespaces.md", + "name": "Name must be unique within a namespace. Is required when creating resources, although some resources may allow a client to request the generation of an appropriate name automatically. Name is primarily intended for creation idempotence and configuration definition. Cannot be updated. More info: http://releases.k8s.io/release-1.2/docs/user-guide/identifiers.md#names", + "generateName": "GenerateName is an optional prefix, used by the server, to generate a unique name ONLY IF the Name field has not been provided. If this field is used, the name returned to the client will be different than the name passed. This value will also be combined with a unique suffix. The provided value has the same validation rules as the Name field, and may be truncated by the length of the suffix required to make the value unique on the server.\n\nIf this field is specified and the generated name exists, the server will NOT return a 409 - instead, it will either return 201 Created or 500 with Reason ServerTimeout indicating a unique name could not be found in the time allotted, and the client should retry (optionally after the time indicated in the Retry-After header).\n\nApplied only if Name is not specified. More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#idempotency", + "namespace": "Namespace defines the space within each name must be unique. An empty namespace is equivalent to the \"default\" namespace, but \"default\" is the canonical representation. Not all objects are required to be scoped to a namespace - the value of this field for those objects will be empty.\n\nMust be a DNS_LABEL. Cannot be updated. More info: http://releases.k8s.io/release-1.2/docs/user-guide/namespaces.md", "selfLink": "SelfLink is a URL representing this object. Populated by the system. Read-only.", - "uid": "UID is the unique in time and space value for this object. It is typically generated by the server on successful creation of a resource and is not allowed to change on PUT operations.\n\nPopulated by the system. Read-only. More info: http://releases.k8s.io/HEAD/docs/user-guide/identifiers.md#uids", - "resourceVersion": "An opaque value that represents the internal version of this object that can be used by clients to determine when objects have changed. May be used for optimistic concurrency, change detection, and the watch operation on a resource or set of resources. Clients must treat these values as opaque and passed unmodified back to the server. They may only be valid for a particular resource or set of resources.\n\nPopulated by the system. Read-only. Value must be treated as opaque by clients and . More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#concurrency-control-and-consistency", + "uid": "UID is the unique in time and space value for this object. It is typically generated by the server on successful creation of a resource and is not allowed to change on PUT operations.\n\nPopulated by the system. Read-only. More info: http://releases.k8s.io/release-1.2/docs/user-guide/identifiers.md#uids", + "resourceVersion": "An opaque value that represents the internal version of this object that can be used by clients to determine when objects have changed. May be used for optimistic concurrency, change detection, and the watch operation on a resource or set of resources. Clients must treat these values as opaque and passed unmodified back to the server. They may only be valid for a particular resource or set of resources.\n\nPopulated by the system. Read-only. Value must be treated as opaque by clients and . More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#concurrency-control-and-consistency", "generation": "A sequence number representing a specific generation of the desired state. Populated by the system. Read-only.", - "creationTimestamp": "CreationTimestamp is a timestamp representing the server time when this object was created. It is not guaranteed to be set in happens-before order across separate operations. Clients may not set this value. It is represented in RFC3339 form and is in UTC.\n\nPopulated by the system. Read-only. Null for lists. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata", - "deletionTimestamp": "DeletionTimestamp is RFC 3339 date and time at which this resource will be deleted. This field is set by the server when a graceful deletion is requested by the user, and is not directly settable by a client. The resource will be deleted (no longer visible from resource lists, and not reachable by name) after the time in this field. Once set, this value may not be unset or be set further into the future, although it may be shortened or the resource may be deleted prior to this time. For example, a user may request that a pod is deleted in 30 seconds. The Kubelet will react by sending a graceful termination signal to the containers in the pod. Once the resource is deleted in the API, the Kubelet will send a hard termination signal to the container. If not set, graceful deletion of the object has not been requested.\n\nPopulated by the system when a graceful deletion is requested. Read-only. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata", + "creationTimestamp": "CreationTimestamp is a timestamp representing the server time when this object was created. It is not guaranteed to be set in happens-before order across separate operations. Clients may not set this value. It is represented in RFC3339 form and is in UTC.\n\nPopulated by the system. Read-only. Null for lists. More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#metadata", + "deletionTimestamp": "DeletionTimestamp is RFC 3339 date and time at which this resource will be deleted. This field is set by the server when a graceful deletion is requested by the user, and is not directly settable by a client. The resource will be deleted (no longer visible from resource lists, and not reachable by name) after the time in this field. Once set, this value may not be unset or be set further into the future, although it may be shortened or the resource may be deleted prior to this time. For example, a user may request that a pod is deleted in 30 seconds. The Kubelet will react by sending a graceful termination signal to the containers in the pod. Once the resource is deleted in the API, the Kubelet will send a hard termination signal to the container. If not set, graceful deletion of the object has not been requested.\n\nPopulated by the system when a graceful deletion is requested. Read-only. More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#metadata", "deletionGracePeriodSeconds": "Number of seconds allowed for this object to gracefully terminate before it will be removed from the system. Only set when deletionTimestamp is also set. May only be shortened. Read-only.", - "labels": "Map of string keys and values that can be used to organize and categorize (scope and select) objects. May match selectors of replication controllers and services. More info: http://releases.k8s.io/HEAD/docs/user-guide/labels.md", - "annotations": "Annotations is an unstructured key value map stored with a resource that may be set by external tools to store and retrieve arbitrary metadata. They are not queryable and should be preserved when modifying objects. More info: http://releases.k8s.io/HEAD/docs/user-guide/annotations.md", + "labels": "Map of string keys and values that can be used to organize and categorize (scope and select) objects. May match selectors of replication controllers and services. More info: http://releases.k8s.io/release-1.2/docs/user-guide/labels.md", + "annotations": "Annotations is an unstructured key value map stored with a resource that may be set by external tools to store and retrieve arbitrary metadata. They are not queryable and should be preserved when modifying objects. More info: http://releases.k8s.io/release-1.2/docs/user-guide/annotations.md", } func (ObjectMeta) SwaggerDoc() map[string]string { @@ -927,12 +927,12 @@ func (ObjectMeta) SwaggerDoc() map[string]string { var map_ObjectReference = map[string]string{ "": "ObjectReference contains enough information to let you inspect or modify the referred object.", - "kind": "Kind of the referent. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds", - "namespace": "Namespace of the referent. More info: http://releases.k8s.io/HEAD/docs/user-guide/namespaces.md", - "name": "Name of the referent. More info: http://releases.k8s.io/HEAD/docs/user-guide/identifiers.md#names", - "uid": "UID of the referent. More info: http://releases.k8s.io/HEAD/docs/user-guide/identifiers.md#uids", + "kind": "Kind of the referent. More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#types-kinds", + "namespace": "Namespace of the referent. More info: http://releases.k8s.io/release-1.2/docs/user-guide/namespaces.md", + "name": "Name of the referent. More info: http://releases.k8s.io/release-1.2/docs/user-guide/identifiers.md#names", + "uid": "UID of the referent. More info: http://releases.k8s.io/release-1.2/docs/user-guide/identifiers.md#uids", "apiVersion": "API version of the referent.", - "resourceVersion": "Specific resourceVersion to which this reference is made, if any. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#concurrency-control-and-consistency", + "resourceVersion": "Specific resourceVersion to which this reference is made, if any. More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#concurrency-control-and-consistency", "fieldPath": "If referring to a piece of an object instead of an entire object, this string should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. For example, if the object reference is to a container within a pod, this would take on a value like: \"spec.containers{name}\" (where \"name\" refers to the name of the container that triggered the event) or if no container name is specified \"spec.containers[2]\" (container with index 2 in this pod). This syntax is chosen only to have some well-defined way of referencing a part of an object.", } @@ -941,10 +941,10 @@ func (ObjectReference) SwaggerDoc() map[string]string { } var map_PersistentVolume = map[string]string{ - "": "PersistentVolume (PV) is a storage resource provisioned by an administrator. It is analogous to a node. More info: http://releases.k8s.io/HEAD/docs/user-guide/persistent-volumes.md", - "metadata": "Standard object's metadata. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata", - "spec": "Spec defines a specification of a persistent volume owned by the cluster. Provisioned by an administrator. More info: http://releases.k8s.io/HEAD/docs/user-guide/persistent-volumes.md#persistent-volumes", - "status": "Status represents the current information/status for the persistent volume. Populated by the system. Read-only. More info: http://releases.k8s.io/HEAD/docs/user-guide/persistent-volumes.md#persistent-volumes", + "": "PersistentVolume (PV) is a storage resource provisioned by an administrator. It is analogous to a node. More info: http://releases.k8s.io/release-1.2/docs/user-guide/persistent-volumes.md", + "metadata": "Standard object's metadata. More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#metadata", + "spec": "Spec defines a specification of a persistent volume owned by the cluster. Provisioned by an administrator. More info: http://releases.k8s.io/release-1.2/docs/user-guide/persistent-volumes.md#persistent-volumes", + "status": "Status represents the current information/status for the persistent volume. Populated by the system. Read-only. More info: http://releases.k8s.io/release-1.2/docs/user-guide/persistent-volumes.md#persistent-volumes", } func (PersistentVolume) SwaggerDoc() map[string]string { @@ -953,9 +953,9 @@ func (PersistentVolume) SwaggerDoc() map[string]string { var map_PersistentVolumeClaim = map[string]string{ "": "PersistentVolumeClaim is a user's request for and claim to a persistent volume", - "metadata": "Standard object's metadata. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata", - "spec": "Spec defines the desired characteristics of a volume requested by a pod author. More info: http://releases.k8s.io/HEAD/docs/user-guide/persistent-volumes.md#persistentvolumeclaims", - "status": "Status represents the current information/status of a persistent volume claim. Read-only. More info: http://releases.k8s.io/HEAD/docs/user-guide/persistent-volumes.md#persistentvolumeclaims", + "metadata": "Standard object's metadata. More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#metadata", + "spec": "Spec defines the desired characteristics of a volume requested by a pod author. More info: http://releases.k8s.io/release-1.2/docs/user-guide/persistent-volumes.md#persistentvolumeclaims", + "status": "Status represents the current information/status of a persistent volume claim. Read-only. More info: http://releases.k8s.io/release-1.2/docs/user-guide/persistent-volumes.md#persistentvolumeclaims", } func (PersistentVolumeClaim) SwaggerDoc() map[string]string { @@ -964,8 +964,8 @@ func (PersistentVolumeClaim) SwaggerDoc() map[string]string { var map_PersistentVolumeClaimList = map[string]string{ "": "PersistentVolumeClaimList is a list of PersistentVolumeClaim items.", - "metadata": "Standard list metadata. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds", - "items": "A list of persistent volume claims. More info: http://releases.k8s.io/HEAD/docs/user-guide/persistent-volumes.md#persistentvolumeclaims", + "metadata": "Standard list metadata. More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#types-kinds", + "items": "A list of persistent volume claims. More info: http://releases.k8s.io/release-1.2/docs/user-guide/persistent-volumes.md#persistentvolumeclaims", } func (PersistentVolumeClaimList) SwaggerDoc() map[string]string { @@ -974,8 +974,8 @@ func (PersistentVolumeClaimList) SwaggerDoc() map[string]string { var map_PersistentVolumeClaimSpec = map[string]string{ "": "PersistentVolumeClaimSpec describes the common attributes of storage devices and allows a Source for provider-specific attributes", - "accessModes": "AccessModes contains the desired access modes the volume should have. More info: http://releases.k8s.io/HEAD/docs/user-guide/persistent-volumes.md#access-modes-1", - "resources": "Resources represents the minimum resources the volume should have. More info: http://releases.k8s.io/HEAD/docs/user-guide/persistent-volumes.md#resources", + "accessModes": "AccessModes contains the desired access modes the volume should have. More info: http://releases.k8s.io/release-1.2/docs/user-guide/persistent-volumes.md#access-modes-1", + "resources": "Resources represents the minimum resources the volume should have. More info: http://releases.k8s.io/release-1.2/docs/user-guide/persistent-volumes.md#resources", "volumeName": "VolumeName is the binding reference to the PersistentVolume backing this claim.", } @@ -986,7 +986,7 @@ func (PersistentVolumeClaimSpec) SwaggerDoc() map[string]string { var map_PersistentVolumeClaimStatus = map[string]string{ "": "PersistentVolumeClaimStatus is the current status of a persistent volume claim.", "phase": "Phase represents the current phase of PersistentVolumeClaim.", - "accessModes": "AccessModes contains the actual access modes the volume backing the PVC has. More info: http://releases.k8s.io/HEAD/docs/user-guide/persistent-volumes.md#access-modes-1", + "accessModes": "AccessModes contains the actual access modes the volume backing the PVC has. More info: http://releases.k8s.io/release-1.2/docs/user-guide/persistent-volumes.md#access-modes-1", "capacity": "Represents the actual resources of the underlying volume.", } @@ -996,7 +996,7 @@ func (PersistentVolumeClaimStatus) SwaggerDoc() map[string]string { var map_PersistentVolumeClaimVolumeSource = map[string]string{ "": "PersistentVolumeClaimVolumeSource references the user's PVC in the same namespace. This volume finds the bound PV and mounts that volume for the pod. A PersistentVolumeClaimVolumeSource is, essentially, a wrapper around another type of volume that is owned by someone else (the system).", - "claimName": "ClaimName is the name of a PersistentVolumeClaim in the same namespace as the pod using this volume. More info: http://releases.k8s.io/HEAD/docs/user-guide/persistent-volumes.md#persistentvolumeclaims", + "claimName": "ClaimName is the name of a PersistentVolumeClaim in the same namespace as the pod using this volume. More info: http://releases.k8s.io/release-1.2/docs/user-guide/persistent-volumes.md#persistentvolumeclaims", "readOnly": "Will force the ReadOnly setting in VolumeMounts. Default false.", } @@ -1006,8 +1006,8 @@ func (PersistentVolumeClaimVolumeSource) SwaggerDoc() map[string]string { var map_PersistentVolumeList = map[string]string{ "": "PersistentVolumeList is a list of PersistentVolume items.", - "metadata": "Standard list metadata. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds", - "items": "List of persistent volumes. More info: http://releases.k8s.io/HEAD/docs/user-guide/persistent-volumes.md", + "metadata": "Standard list metadata. More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#types-kinds", + "items": "List of persistent volumes. More info: http://releases.k8s.io/release-1.2/docs/user-guide/persistent-volumes.md", } func (PersistentVolumeList) SwaggerDoc() map[string]string { @@ -1016,14 +1016,14 @@ func (PersistentVolumeList) SwaggerDoc() map[string]string { var map_PersistentVolumeSource = map[string]string{ "": "PersistentVolumeSource is similar to VolumeSource but meant for the administrator who creates PVs. Exactly one of its members must be set.", - "gcePersistentDisk": "GCEPersistentDisk represents a GCE Disk resource that is attached to a kubelet's host machine and then exposed to the pod. Provisioned by an admin. More info: http://releases.k8s.io/HEAD/docs/user-guide/volumes.md#gcepersistentdisk", - "awsElasticBlockStore": "AWSElasticBlockStore represents an AWS Disk resource that is attached to a kubelet's host machine and then exposed to the pod. More info: http://releases.k8s.io/HEAD/docs/user-guide/volumes.md#awselasticblockstore", - "hostPath": "HostPath represents a directory on the host. Provisioned by a developer or tester. This is useful for single-node development and testing only! On-host storage is not supported in any way and WILL NOT WORK in a multi-node cluster. More info: http://releases.k8s.io/HEAD/docs/user-guide/volumes.md#hostpath", - "glusterfs": "Glusterfs represents a Glusterfs volume that is attached to a host and exposed to the pod. Provisioned by an admin. More info: http://releases.k8s.io/HEAD/examples/glusterfs/README.md", - "nfs": "NFS represents an NFS mount on the host. Provisioned by an admin. More info: http://releases.k8s.io/HEAD/docs/user-guide/volumes.md#nfs", - "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", + "gcePersistentDisk": "GCEPersistentDisk represents a GCE Disk resource that is attached to a kubelet's host machine and then exposed to the pod. Provisioned by an admin. More info: http://releases.k8s.io/release-1.2/docs/user-guide/volumes.md#gcepersistentdisk", + "awsElasticBlockStore": "AWSElasticBlockStore represents an AWS Disk resource that is attached to a kubelet's host machine and then exposed to the pod. More info: http://releases.k8s.io/release-1.2/docs/user-guide/volumes.md#awselasticblockstore", + "hostPath": "HostPath represents a directory on the host. Provisioned by a developer or tester. This is useful for single-node development and testing only! On-host storage is not supported in any way and WILL NOT WORK in a multi-node cluster. More info: http://releases.k8s.io/release-1.2/docs/user-guide/volumes.md#hostpath", + "glusterfs": "Glusterfs represents a Glusterfs volume that is attached to a host and exposed to the pod. Provisioned by an admin. More info: http://releases.k8s.io/release-1.2/examples/glusterfs/README.md", + "nfs": "NFS represents an NFS mount on the host. Provisioned by an admin. More info: http://releases.k8s.io/release-1.2/docs/user-guide/volumes.md#nfs", + "rbd": "RBD represents a Rados Block Device mount on the host that shares a pod's lifetime. More info: http://releases.k8s.io/release-1.2/examples/rbd/README.md", "iscsi": "ISCSI represents an ISCSI Disk resource that is attached to a kubelet's host machine and then exposed to the pod. Provisioned by an admin.", - "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", + "cinder": "Cinder represents a cinder volume attached and mounted on kubelets host machine More info: http://releases.k8s.io/release-1.2/examples/mysql-cinder-pd/README.md", "cephfs": "CephFS represents a Ceph FS mount on the host that shares a pod's lifetime", "fc": "FC represents a Fibre Channel resource that is attached to a kubelet's host machine and then exposed to the pod.", "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", @@ -1037,10 +1037,10 @@ func (PersistentVolumeSource) SwaggerDoc() map[string]string { var map_PersistentVolumeSpec = map[string]string{ "": "PersistentVolumeSpec is the specification of a persistent volume.", - "capacity": "A description of the persistent volume's resources and capacity. More info: http://releases.k8s.io/HEAD/docs/user-guide/persistent-volumes.md#capacity", - "accessModes": "AccessModes contains all ways the volume can be mounted. More info: http://releases.k8s.io/HEAD/docs/user-guide/persistent-volumes.md#access-modes", - "claimRef": "ClaimRef is part of a bi-directional binding between PersistentVolume and PersistentVolumeClaim. Expected to be non-nil when bound. claim.VolumeName is the authoritative bind between PV and PVC. More info: http://releases.k8s.io/HEAD/docs/user-guide/persistent-volumes.md#binding", - "persistentVolumeReclaimPolicy": "What happens to a persistent volume when released from its claim. Valid options are Retain (default) and Recycle. Recyling must be supported by the volume plugin underlying this persistent volume. More info: http://releases.k8s.io/HEAD/docs/user-guide/persistent-volumes.md#recycling-policy", + "capacity": "A description of the persistent volume's resources and capacity. More info: http://releases.k8s.io/release-1.2/docs/user-guide/persistent-volumes.md#capacity", + "accessModes": "AccessModes contains all ways the volume can be mounted. More info: http://releases.k8s.io/release-1.2/docs/user-guide/persistent-volumes.md#access-modes", + "claimRef": "ClaimRef is part of a bi-directional binding between PersistentVolume and PersistentVolumeClaim. Expected to be non-nil when bound. claim.VolumeName is the authoritative bind between PV and PVC. More info: http://releases.k8s.io/release-1.2/docs/user-guide/persistent-volumes.md#binding", + "persistentVolumeReclaimPolicy": "What happens to a persistent volume when released from its claim. Valid options are Retain (default) and Recycle. Recyling must be supported by the volume plugin underlying this persistent volume. More info: http://releases.k8s.io/release-1.2/docs/user-guide/persistent-volumes.md#recycling-policy", } func (PersistentVolumeSpec) SwaggerDoc() map[string]string { @@ -1049,7 +1049,7 @@ func (PersistentVolumeSpec) SwaggerDoc() map[string]string { var map_PersistentVolumeStatus = map[string]string{ "": "PersistentVolumeStatus is the current status of a persistent volume.", - "phase": "Phase indicates if a volume is available, bound to a claim, or released by a claim. More info: http://releases.k8s.io/HEAD/docs/user-guide/persistent-volumes.md#phase", + "phase": "Phase indicates if a volume is available, bound to a claim, or released by a claim. More info: http://releases.k8s.io/release-1.2/docs/user-guide/persistent-volumes.md#phase", "message": "A human-readable message indicating details about why the volume is in this state.", "reason": "Reason is a brief CamelCase string that describes any failure and is meant for machine parsing and tidy display in the CLI.", } @@ -1060,9 +1060,9 @@ func (PersistentVolumeStatus) SwaggerDoc() map[string]string { var map_Pod = map[string]string{ "": "Pod is a collection of containers that can run on a host. This resource is created by clients and scheduled onto hosts.", - "metadata": "Standard object's metadata. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata", - "spec": "Specification of the desired behavior of the pod. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#spec-and-status", - "status": "Most recently observed status of the pod. This data may not be up to date. Populated by the system. Read-only. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#spec-and-status", + "metadata": "Standard object's metadata. More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#metadata", + "spec": "Specification of the desired behavior of the pod. More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#spec-and-status", + "status": "Most recently observed status of the pod. This data may not be up to date. Populated by the system. Read-only. More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#spec-and-status", } func (Pod) SwaggerDoc() map[string]string { @@ -1084,8 +1084,8 @@ func (PodAttachOptions) SwaggerDoc() map[string]string { var map_PodCondition = map[string]string{ "": "PodCondition contains details for the current condition of this pod.", - "type": "Type is the type of the condition. Currently only Ready. More info: http://releases.k8s.io/HEAD/docs/user-guide/pod-states.md#pod-conditions", - "status": "Status is the status of the condition. Can be True, False, Unknown. More info: http://releases.k8s.io/HEAD/docs/user-guide/pod-states.md#pod-conditions", + "type": "Type is the type of the condition. Currently only Ready. More info: http://releases.k8s.io/release-1.2/docs/user-guide/pod-states.md#pod-conditions", + "status": "Status is the status of the condition. Can be True, False, Unknown. More info: http://releases.k8s.io/release-1.2/docs/user-guide/pod-states.md#pod-conditions", "lastProbeTime": "Last time we probed the condition.", "lastTransitionTime": "Last time the condition transitioned from one status to another.", "reason": "Unique, one-word, CamelCase reason for the condition's last transition.", @@ -1112,8 +1112,8 @@ func (PodExecOptions) SwaggerDoc() map[string]string { var map_PodList = map[string]string{ "": "PodList is a list of Pods.", - "metadata": "Standard list metadata. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds", - "items": "List of pods. More info: http://releases.k8s.io/HEAD/docs/user-guide/pods.md", + "metadata": "Standard list metadata. More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#types-kinds", + "items": "List of pods. More info: http://releases.k8s.io/release-1.2/docs/user-guide/pods.md", } func (PodList) SwaggerDoc() map[string]string { @@ -1160,21 +1160,21 @@ func (PodSecurityContext) SwaggerDoc() map[string]string { var map_PodSpec = map[string]string{ "": "PodSpec is a description of a pod.", - "volumes": "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", - "containers": "List of containers belonging to the pod. Containers cannot currently be added or removed. There must be at least one container in a Pod. Cannot be updated. More info: http://releases.k8s.io/HEAD/docs/user-guide/containers.md", - "restartPolicy": "Restart policy for all containers within the pod. One of Always, OnFailure, Never. Default to Always. More info: http://releases.k8s.io/HEAD/docs/user-guide/pod-states.md#restartpolicy", + "volumes": "List of volumes that can be mounted by containers belonging to the pod. More info: http://releases.k8s.io/release-1.2/docs/user-guide/volumes.md", + "containers": "List of containers belonging to the pod. Containers cannot currently be added or removed. There must be at least one container in a Pod. Cannot be updated. More info: http://releases.k8s.io/release-1.2/docs/user-guide/containers.md", + "restartPolicy": "Restart policy for all containers within the pod. One of Always, OnFailure, Never. Default to Always. More info: http://releases.k8s.io/release-1.2/docs/user-guide/pod-states.md#restartpolicy", "terminationGracePeriodSeconds": "Optional duration in seconds the pod needs to terminate gracefully. May be decreased in delete request. Value must be non-negative integer. The value zero indicates delete immediately. If this value is nil, the default grace period will be used instead. The grace period is the duration in seconds after the processes running in the pod are sent a termination signal and the time when the processes are forcibly halted with a kill signal. Set this value longer than the expected cleanup time for your process. Defaults to 30 seconds.", "activeDeadlineSeconds": "Optional duration in seconds the pod may be active on the node relative to StartTime before the system will actively try to mark it failed and kill associated containers. Value must be a positive integer.", "dnsPolicy": "Set DNS policy for containers within the pod. One of 'ClusterFirst' or 'Default'. Defaults to \"ClusterFirst\".", - "nodeSelector": "NodeSelector is a selector which must be true for the pod to fit on a node. Selector which must match a node's labels for the pod to be scheduled on that node. More info: http://releases.k8s.io/HEAD/docs/user-guide/node-selection/README.md", - "serviceAccountName": "ServiceAccountName is the name of the ServiceAccount to use to run this pod. More info: http://releases.k8s.io/HEAD/docs/design/service_accounts.md", + "nodeSelector": "NodeSelector is a selector which must be true for the pod to fit on a node. Selector which must match a node's labels for the pod to be scheduled on that node. More info: http://releases.k8s.io/release-1.2/docs/user-guide/node-selection/README.md", + "serviceAccountName": "ServiceAccountName is the name of the ServiceAccount to use to run this pod. More info: http://releases.k8s.io/release-1.2/docs/design/service_accounts.md", "serviceAccount": "DeprecatedServiceAccount is a depreciated alias for ServiceAccountName. Deprecated: Use serviceAccountName instead.", "nodeName": "NodeName is a request to schedule this pod onto a specific node. If it is non-empty, the scheduler simply schedules this pod onto that node, assuming that it fits resource requirements.", "hostNetwork": "Host networking requested for this pod. Use the host's network namespace. If this option is set, the ports that will be used must be specified. Default to false.", "hostPID": "Use the host's pid namespace. Optional: Default to false.", "hostIPC": "Use the host's ipc namespace. Optional: Default to false.", "securityContext": "SecurityContext holds pod-level security attributes and common container settings. Optional: Defaults to empty. See type description for default values of each field.", - "imagePullSecrets": "ImagePullSecrets is an optional list of references to secrets in the same namespace to use for pulling any of the images used by this PodSpec. If specified, these secrets will be passed to individual puller implementations for them to use. For example, in the case of docker, only DockerConfig type secrets are honored. More info: http://releases.k8s.io/HEAD/docs/user-guide/images.md#specifying-imagepullsecrets-on-a-pod", + "imagePullSecrets": "ImagePullSecrets is an optional list of references to secrets in the same namespace to use for pulling any of the images used by this PodSpec. If specified, these secrets will be passed to individual puller implementations for them to use. For example, in the case of docker, only DockerConfig type secrets are honored. More info: http://releases.k8s.io/release-1.2/docs/user-guide/images.md#specifying-imagepullsecrets-on-a-pod", } func (PodSpec) SwaggerDoc() map[string]string { @@ -1183,14 +1183,14 @@ func (PodSpec) SwaggerDoc() map[string]string { var map_PodStatus = map[string]string{ "": "PodStatus represents information about the status of a pod. Status may trail the actual state of a system.", - "phase": "Current condition of the pod. More info: http://releases.k8s.io/HEAD/docs/user-guide/pod-states.md#pod-phase", - "conditions": "Current service state of pod. More info: http://releases.k8s.io/HEAD/docs/user-guide/pod-states.md#pod-conditions", + "phase": "Current condition of the pod. More info: http://releases.k8s.io/release-1.2/docs/user-guide/pod-states.md#pod-phase", + "conditions": "Current service state of pod. More info: http://releases.k8s.io/release-1.2/docs/user-guide/pod-states.md#pod-conditions", "message": "A human readable message indicating details about why the pod is in this condition.", "reason": "A brief CamelCase message indicating details about why the pod is in this state. e.g. 'OutOfDisk'", "hostIP": "IP address of the host to which the pod is assigned. Empty if not yet scheduled.", "podIP": "IP address allocated to the pod. Routable at least within the cluster. Empty if not yet allocated.", "startTime": "RFC 3339 date and time at which the object was acknowledged by the Kubelet. This is before the Kubelet pulled the container image(s) for the pod.", - "containerStatuses": "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", + "containerStatuses": "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/release-1.2/docs/user-guide/pod-states.md#container-statuses", } func (PodStatus) SwaggerDoc() map[string]string { @@ -1199,8 +1199,8 @@ func (PodStatus) SwaggerDoc() map[string]string { var map_PodStatusResult = map[string]string{ "": "PodStatusResult is a wrapper for PodStatus returned by kubelet that can be encode/decoded", - "metadata": "Standard object's metadata. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata", - "status": "Most recently observed status of the pod. This data may not be up to date. Populated by the system. Read-only. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#spec-and-status", + "metadata": "Standard object's metadata. More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#metadata", + "status": "Most recently observed status of the pod. This data may not be up to date. Populated by the system. Read-only. More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#spec-and-status", } func (PodStatusResult) SwaggerDoc() map[string]string { @@ -1209,8 +1209,8 @@ func (PodStatusResult) SwaggerDoc() map[string]string { var map_PodTemplate = map[string]string{ "": "PodTemplate describes a template for creating copies of a predefined pod.", - "metadata": "Standard object's metadata. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata", - "template": "Template defines the pods that will be created from this pod template. http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#spec-and-status", + "metadata": "Standard object's metadata. More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#metadata", + "template": "Template defines the pods that will be created from this pod template. http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#spec-and-status", } func (PodTemplate) SwaggerDoc() map[string]string { @@ -1219,7 +1219,7 @@ func (PodTemplate) SwaggerDoc() map[string]string { var map_PodTemplateList = map[string]string{ "": "PodTemplateList is a list of PodTemplates.", - "metadata": "Standard list metadata. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds", + "metadata": "Standard list metadata. More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#types-kinds", "items": "List of pod templates", } @@ -1229,8 +1229,8 @@ func (PodTemplateList) SwaggerDoc() map[string]string { var map_PodTemplateSpec = map[string]string{ "": "PodTemplateSpec describes the data a pod should have when created from a template", - "metadata": "Standard object's metadata. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata", - "spec": "Specification of the desired behavior of the pod. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#spec-and-status", + "metadata": "Standard object's metadata. More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#metadata", + "spec": "Specification of the desired behavior of the pod. More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#spec-and-status", } func (PodTemplateSpec) SwaggerDoc() map[string]string { @@ -1249,8 +1249,8 @@ func (PreferredSchedulingTerm) SwaggerDoc() map[string]string { var map_Probe = map[string]string{ "": "Probe describes a health check to be performed against a container to determine whether it is alive or ready to receive traffic.", - "initialDelaySeconds": "Number of seconds after the container has started before liveness probes are initiated. More info: http://releases.k8s.io/HEAD/docs/user-guide/pod-states.md#container-probes", - "timeoutSeconds": "Number of seconds after which the probe times out. Defaults to 1 second. Minimum value is 1. More info: http://releases.k8s.io/HEAD/docs/user-guide/pod-states.md#container-probes", + "initialDelaySeconds": "Number of seconds after the container has started before liveness probes are initiated. More info: http://releases.k8s.io/release-1.2/docs/user-guide/pod-states.md#container-probes", + "timeoutSeconds": "Number of seconds after which the probe times out. Defaults to 1 second. Minimum value is 1. More info: http://releases.k8s.io/release-1.2/docs/user-guide/pod-states.md#container-probes", "periodSeconds": "How often (in seconds) to perform the probe. Default to 10 seconds. Minimum value is 1.", "successThreshold": "Minimum consecutive successes for the probe to be considered successful after having failed. Defaults to 1. Must be 1 for liveness. Minimum value is 1.", "failureThreshold": "Minimum consecutive failures for the probe to be considered failed after having succeeded. Defaults to 3. Minimum value is 1.", @@ -1262,14 +1262,14 @@ func (Probe) SwaggerDoc() map[string]string { var map_RBDVolumeSource = map[string]string{ "": "Represents a Rados Block Device mount that lasts the lifetime of a pod. RBD volumes support ownership management and SELinux relabeling.", - "monitors": "A collection of Ceph monitors. More info: http://releases.k8s.io/HEAD/examples/rbd/README.md#how-to-use-it", - "image": "The rados image name. More info: http://releases.k8s.io/HEAD/examples/rbd/README.md#how-to-use-it", - "fsType": "Filesystem type of the volume that you want to mount. Tip: Ensure that the filesystem type is supported by the host operating system. Examples: \"ext4\", \"xfs\", \"ntfs\". Implicitly inferred to be \"ext4\" if unspecified. More info: http://releases.k8s.io/HEAD/docs/user-guide/volumes.md#rbd", - "pool": "The rados pool name. Default is rbd. More info: http://releases.k8s.io/HEAD/examples/rbd/README.md#how-to-use-it.", - "user": "The rados user name. Default is admin. More info: http://releases.k8s.io/HEAD/examples/rbd/README.md#how-to-use-it", - "keyring": "Keyring is the path to key ring for RBDUser. Default is /etc/ceph/keyring. More info: http://releases.k8s.io/HEAD/examples/rbd/README.md#how-to-use-it", - "secretRef": "SecretRef is name of the authentication secret for RBDUser. If provided overrides keyring. Default is empty. More info: http://releases.k8s.io/HEAD/examples/rbd/README.md#how-to-use-it", - "readOnly": "ReadOnly here will force the ReadOnly setting in VolumeMounts. Defaults to false. More info: http://releases.k8s.io/HEAD/examples/rbd/README.md#how-to-use-it", + "monitors": "A collection of Ceph monitors. More info: http://releases.k8s.io/release-1.2/examples/rbd/README.md#how-to-use-it", + "image": "The rados image name. More info: http://releases.k8s.io/release-1.2/examples/rbd/README.md#how-to-use-it", + "fsType": "Filesystem type of the volume that you want to mount. Tip: Ensure that the filesystem type is supported by the host operating system. Examples: \"ext4\", \"xfs\", \"ntfs\". Implicitly inferred to be \"ext4\" if unspecified. More info: http://releases.k8s.io/release-1.2/docs/user-guide/volumes.md#rbd", + "pool": "The rados pool name. Default is rbd. More info: http://releases.k8s.io/release-1.2/examples/rbd/README.md#how-to-use-it.", + "user": "The rados user name. Default is admin. More info: http://releases.k8s.io/release-1.2/examples/rbd/README.md#how-to-use-it", + "keyring": "Keyring is the path to key ring for RBDUser. Default is /etc/ceph/keyring. More info: http://releases.k8s.io/release-1.2/examples/rbd/README.md#how-to-use-it", + "secretRef": "SecretRef is name of the authentication secret for RBDUser. If provided overrides keyring. Default is empty. More info: http://releases.k8s.io/release-1.2/examples/rbd/README.md#how-to-use-it", + "readOnly": "ReadOnly here will force the ReadOnly setting in VolumeMounts. Defaults to false. More info: http://releases.k8s.io/release-1.2/examples/rbd/README.md#how-to-use-it", } func (RBDVolumeSource) SwaggerDoc() map[string]string { @@ -1278,7 +1278,7 @@ func (RBDVolumeSource) SwaggerDoc() map[string]string { var map_RangeAllocation = map[string]string{ "": "RangeAllocation is not a public type.", - "metadata": "Standard object's metadata. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata", + "metadata": "Standard object's metadata. More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#metadata", "range": "Range is string that identifies the range represented by 'data'.", "data": "Data is a bit array containing all allocated addresses in the previous segment.", } @@ -1289,9 +1289,9 @@ func (RangeAllocation) SwaggerDoc() map[string]string { var map_ReplicationController = map[string]string{ "": "ReplicationController represents the configuration of a replication controller.", - "metadata": "If the Labels of a ReplicationController are empty, they are defaulted to be the same as the Pod(s) that the replication controller manages. Standard object's metadata. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata", - "spec": "Spec defines the specification of the desired behavior of the replication controller. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#spec-and-status", - "status": "Status is the most recently observed status of the replication controller. This data may be out of date by some window of time. Populated by the system. Read-only. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#spec-and-status", + "metadata": "If the Labels of a ReplicationController are empty, they are defaulted to be the same as the Pod(s) that the replication controller manages. Standard object's metadata. More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#metadata", + "spec": "Spec defines the specification of the desired behavior of the replication controller. More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#spec-and-status", + "status": "Status is the most recently observed status of the replication controller. This data may be out of date by some window of time. Populated by the system. Read-only. More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#spec-and-status", } func (ReplicationController) SwaggerDoc() map[string]string { @@ -1300,8 +1300,8 @@ func (ReplicationController) SwaggerDoc() map[string]string { var map_ReplicationControllerList = map[string]string{ "": "ReplicationControllerList is a collection of replication controllers.", - "metadata": "Standard list metadata. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds", - "items": "List of replication controllers. More info: http://releases.k8s.io/HEAD/docs/user-guide/replication-controller.md", + "metadata": "Standard list metadata. More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#types-kinds", + "items": "List of replication controllers. More info: http://releases.k8s.io/release-1.2/docs/user-guide/replication-controller.md", } func (ReplicationControllerList) SwaggerDoc() map[string]string { @@ -1310,9 +1310,9 @@ func (ReplicationControllerList) SwaggerDoc() map[string]string { var map_ReplicationControllerSpec = map[string]string{ "": "ReplicationControllerSpec is the specification of a replication controller.", - "replicas": "Replicas is the number of desired replicas. This is a pointer to distinguish between explicit zero and unspecified. Defaults to 1. More info: http://releases.k8s.io/HEAD/docs/user-guide/replication-controller.md#what-is-a-replication-controller", - "selector": "Selector is a label query over pods that should match the Replicas count. If Selector is empty, it is defaulted to the labels present on the Pod template. Label keys and values that must match in order to be controlled by this replication controller, if empty defaulted to labels on Pod template. More info: http://releases.k8s.io/HEAD/docs/user-guide/labels.md#label-selectors", - "template": "Template is the object that describes the pod that will be created if insufficient replicas are detected. This takes precedence over a TemplateRef. More info: http://releases.k8s.io/HEAD/docs/user-guide/replication-controller.md#pod-template", + "replicas": "Replicas is the number of desired replicas. This is a pointer to distinguish between explicit zero and unspecified. Defaults to 1. More info: http://releases.k8s.io/release-1.2/docs/user-guide/replication-controller.md#what-is-a-replication-controller", + "selector": "Selector is a label query over pods that should match the Replicas count. If Selector is empty, it is defaulted to the labels present on the Pod template. Label keys and values that must match in order to be controlled by this replication controller, if empty defaulted to labels on Pod template. More info: http://releases.k8s.io/release-1.2/docs/user-guide/labels.md#label-selectors", + "template": "Template is the object that describes the pod that will be created if insufficient replicas are detected. This takes precedence over a TemplateRef. More info: http://releases.k8s.io/release-1.2/docs/user-guide/replication-controller.md#pod-template", } func (ReplicationControllerSpec) SwaggerDoc() map[string]string { @@ -1320,9 +1320,10 @@ func (ReplicationControllerSpec) SwaggerDoc() map[string]string { } var map_ReplicationControllerStatus = map[string]string{ - "": "ReplicationControllerStatus represents the current status of a replication controller.", - "replicas": "Replicas is the most recently oberved number of replicas. More info: http://releases.k8s.io/HEAD/docs/user-guide/replication-controller.md#what-is-a-replication-controller", - "observedGeneration": "ObservedGeneration reflects the generation of the most recently observed replication controller.", + "": "ReplicationControllerStatus represents the current status of a replication controller.", + "replicas": "Replicas is the most recently oberved number of replicas. More info: http://releases.k8s.io/release-1.2/docs/user-guide/replication-controller.md#what-is-a-replication-controller", + "fullyLabeledReplicas": "The number of pods that have labels matching the labels of the pod template of the replication controller.", + "observedGeneration": "ObservedGeneration reflects the generation of the most recently observed replication controller.", } func (ReplicationControllerStatus) SwaggerDoc() map[string]string { @@ -1331,9 +1332,9 @@ func (ReplicationControllerStatus) SwaggerDoc() map[string]string { var map_ResourceQuota = map[string]string{ "": "ResourceQuota sets aggregate quota restrictions enforced per namespace", - "metadata": "Standard object's metadata. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata", - "spec": "Spec defines the desired quota. http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#spec-and-status", - "status": "Status defines the actual enforced quota and its current usage. http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#spec-and-status", + "metadata": "Standard object's metadata. More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#metadata", + "spec": "Spec defines the desired quota. http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#spec-and-status", + "status": "Status defines the actual enforced quota and its current usage. http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#spec-and-status", } func (ResourceQuota) SwaggerDoc() map[string]string { @@ -1342,8 +1343,8 @@ func (ResourceQuota) SwaggerDoc() map[string]string { var map_ResourceQuotaList = map[string]string{ "": "ResourceQuotaList is a list of ResourceQuota items.", - "metadata": "Standard list metadata. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds", - "items": "Items is a list of ResourceQuota objects. More info: http://releases.k8s.io/HEAD/docs/design/admission_control_resource_quota.md#admissioncontrol-plugin-resourcequota", + "metadata": "Standard list metadata. More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#types-kinds", + "items": "Items is a list of ResourceQuota objects. More info: http://releases.k8s.io/release-1.2/docs/design/admission_control_resource_quota.md#admissioncontrol-plugin-resourcequota", } func (ResourceQuotaList) SwaggerDoc() map[string]string { @@ -1352,7 +1353,7 @@ func (ResourceQuotaList) SwaggerDoc() map[string]string { var map_ResourceQuotaSpec = map[string]string{ "": "ResourceQuotaSpec defines the desired hard limits to enforce for Quota.", - "hard": "Hard is the set of desired hard limits for each named resource. More info: http://releases.k8s.io/HEAD/docs/design/admission_control_resource_quota.md#admissioncontrol-plugin-resourcequota", + "hard": "Hard is the set of desired hard limits for each named resource. More info: http://releases.k8s.io/release-1.2/docs/design/admission_control_resource_quota.md#admissioncontrol-plugin-resourcequota", "scopes": "A collection of filters that must match each object tracked by a quota. If not specified, the quota matches all objects.", } @@ -1362,7 +1363,7 @@ func (ResourceQuotaSpec) SwaggerDoc() map[string]string { var map_ResourceQuotaStatus = map[string]string{ "": "ResourceQuotaStatus defines the enforced hard limits and observed use.", - "hard": "Hard is the set of enforced hard limits for each named resource. More info: http://releases.k8s.io/HEAD/docs/design/admission_control_resource_quota.md#admissioncontrol-plugin-resourcequota", + "hard": "Hard is the set of enforced hard limits for each named resource. More info: http://releases.k8s.io/release-1.2/docs/design/admission_control_resource_quota.md#admissioncontrol-plugin-resourcequota", "used": "Used is the current observed total usage of the resource in the namespace.", } @@ -1372,8 +1373,8 @@ func (ResourceQuotaStatus) SwaggerDoc() map[string]string { var map_ResourceRequirements = map[string]string{ "": "ResourceRequirements describes the compute resource requirements.", - "limits": "Limits describes the maximum amount of compute resources allowed. More info: http://releases.k8s.io/HEAD/docs/design/resources.md#resource-specifications", - "requests": "Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined value. More info: http://releases.k8s.io/HEAD/docs/design/resources.md#resource-specifications", + "limits": "Limits describes the maximum amount of compute resources allowed. More info: http://releases.k8s.io/release-1.2/docs/design/resources.md#resource-specifications", + "requests": "Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined value. More info: http://releases.k8s.io/release-1.2/docs/design/resources.md#resource-specifications", } func (ResourceRequirements) SwaggerDoc() map[string]string { @@ -1394,7 +1395,7 @@ func (SELinuxOptions) SwaggerDoc() map[string]string { var map_Secret = map[string]string{ "": "Secret holds secret data of a certain type. The total bytes of the values in the Data field must be less than MaxSecretSize bytes.", - "metadata": "Standard object's metadata. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata", + "metadata": "Standard object's metadata. More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#metadata", "data": "Data contains the secret data. Each key must be a valid DNS_SUBDOMAIN or leading dot followed by valid DNS_SUBDOMAIN. The serialized form of the secret data is a base64 encoded string, representing the arbitrary (possibly non-string) data value here. Described in https://tools.ietf.org/html/rfc4648#section-4", "type": "Used to facilitate programmatic handling of secret data.", } @@ -1414,8 +1415,8 @@ func (SecretKeySelector) SwaggerDoc() map[string]string { var map_SecretList = map[string]string{ "": "SecretList is a list of Secret.", - "metadata": "Standard list metadata. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds", - "items": "Items is a list of secret objects. More info: http://releases.k8s.io/HEAD/docs/user-guide/secrets.md", + "metadata": "Standard list metadata. More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#types-kinds", + "items": "Items is a list of secret objects. More info: http://releases.k8s.io/release-1.2/docs/user-guide/secrets.md", } func (SecretList) SwaggerDoc() map[string]string { @@ -1424,7 +1425,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", + "secretName": "Name of the secret in the pod's namespace to use. More info: http://releases.k8s.io/release-1.2/docs/user-guide/volumes.md#secrets", } func (SecretVolumeSource) SwaggerDoc() map[string]string { @@ -1456,9 +1457,9 @@ func (SerializedReference) SwaggerDoc() map[string]string { var map_Service = map[string]string{ "": "Service is a named abstraction of software service (for example, mysql) consisting of local port (for example 3306) that the proxy listens on, and the selector that determines which pods will answer requests sent through the proxy.", - "metadata": "Standard object's metadata. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata", - "spec": "Spec defines the behavior of a service. http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#spec-and-status", - "status": "Most recently observed status of the service. Populated by the system. Read-only. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#spec-and-status", + "metadata": "Standard object's metadata. More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#metadata", + "spec": "Spec defines the behavior of a service. http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#spec-and-status", + "status": "Most recently observed status of the service. Populated by the system. Read-only. More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#spec-and-status", } func (Service) SwaggerDoc() map[string]string { @@ -1467,9 +1468,9 @@ func (Service) SwaggerDoc() map[string]string { var map_ServiceAccount = map[string]string{ "": "ServiceAccount binds together: * a name, understood by users, and perhaps by peripheral systems, for an identity * a principal that can be authenticated and authorized * a set of secrets", - "metadata": "Standard object's metadata. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata", - "secrets": "Secrets is the list of secrets allowed to be used by pods running using this ServiceAccount. More info: http://releases.k8s.io/HEAD/docs/user-guide/secrets.md", - "imagePullSecrets": "ImagePullSecrets is a list of references to secrets in the same namespace to use for pulling any images in pods that reference this ServiceAccount. ImagePullSecrets are distinct from Secrets because Secrets can be mounted in the pod, but ImagePullSecrets are only accessed by the kubelet. More info: http://releases.k8s.io/HEAD/docs/user-guide/secrets.md#manually-specifying-an-imagepullsecret", + "metadata": "Standard object's metadata. More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#metadata", + "secrets": "Secrets is the list of secrets allowed to be used by pods running using this ServiceAccount. More info: http://releases.k8s.io/release-1.2/docs/user-guide/secrets.md", + "imagePullSecrets": "ImagePullSecrets is a list of references to secrets in the same namespace to use for pulling any images in pods that reference this ServiceAccount. ImagePullSecrets are distinct from Secrets because Secrets can be mounted in the pod, but ImagePullSecrets are only accessed by the kubelet. More info: http://releases.k8s.io/release-1.2/docs/user-guide/secrets.md#manually-specifying-an-imagepullsecret", } func (ServiceAccount) SwaggerDoc() map[string]string { @@ -1478,8 +1479,8 @@ func (ServiceAccount) SwaggerDoc() map[string]string { var map_ServiceAccountList = map[string]string{ "": "ServiceAccountList is a list of ServiceAccount objects", - "metadata": "Standard list metadata. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds", - "items": "List of ServiceAccounts. More info: http://releases.k8s.io/HEAD/docs/design/service_accounts.md#service-accounts", + "metadata": "Standard list metadata. More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#types-kinds", + "items": "List of ServiceAccounts. More info: http://releases.k8s.io/release-1.2/docs/design/service_accounts.md#service-accounts", } func (ServiceAccountList) SwaggerDoc() map[string]string { @@ -1488,7 +1489,7 @@ func (ServiceAccountList) SwaggerDoc() map[string]string { var map_ServiceList = map[string]string{ "": "ServiceList holds a list of services.", - "metadata": "Standard list metadata. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds", + "metadata": "Standard list metadata. More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#types-kinds", "items": "List of services", } @@ -1501,8 +1502,8 @@ var map_ServicePort = map[string]string{ "name": "The name of this port within the service. This must be a DNS_LABEL. All ports within a ServiceSpec must have unique names. This maps to the 'Name' field in EndpointPort objects. Optional if only one ServicePort is defined on this service.", "protocol": "The IP protocol for this port. Supports \"TCP\" and \"UDP\". Default is TCP.", "port": "The port that will be exposed by this service.", - "targetPort": "Number or name of the port to access on the pods targeted by the service. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. If this is a string, it will be looked up as a named port in the target Pod's container ports. If this is not specified, the value of the 'port' field is used (an identity map). This field is ignored for services with clusterIP=None, and should be omitted or set equal to the 'port' field. More info: http://releases.k8s.io/HEAD/docs/user-guide/services.md#defining-a-service", - "nodePort": "The port on each node on which this service is exposed when type=NodePort or LoadBalancer. Usually assigned by the system. If specified, it will be allocated to the service if unused or else creation of the service will fail. Default is to auto-allocate a port if the ServiceType of this Service requires one. More info: http://releases.k8s.io/HEAD/docs/user-guide/services.md#type--nodeport", + "targetPort": "Number or name of the port to access on the pods targeted by the service. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. If this is a string, it will be looked up as a named port in the target Pod's container ports. If this is not specified, the value of the 'port' field is used (an identity map). This field is ignored for services with clusterIP=None, and should be omitted or set equal to the 'port' field. More info: http://releases.k8s.io/release-1.2/docs/user-guide/services.md#defining-a-service", + "nodePort": "The port on each node on which this service is exposed when type=NodePort or LoadBalancer. Usually assigned by the system. If specified, it will be allocated to the service if unused or else creation of the service will fail. Default is to auto-allocate a port if the ServiceType of this Service requires one. More info: http://releases.k8s.io/release-1.2/docs/user-guide/services.md#type--nodeport", } func (ServicePort) SwaggerDoc() map[string]string { @@ -1520,13 +1521,13 @@ func (ServiceProxyOptions) SwaggerDoc() map[string]string { var map_ServiceSpec = map[string]string{ "": "ServiceSpec describes the attributes that a user creates on a service.", - "ports": "The list of ports that are exposed by this service. More info: http://releases.k8s.io/HEAD/docs/user-guide/services.md#virtual-ips-and-service-proxies", - "selector": "This service will route traffic to pods having labels matching this selector. Label keys and values that must match in order to receive traffic for this service. If empty, all pods are selected, if not specified, endpoints must be manually specified. More info: http://releases.k8s.io/HEAD/docs/user-guide/services.md#overview", - "clusterIP": "ClusterIP is usually assigned by the master and is the IP address of the service. If specified, it will be allocated to the service if it is unused or else creation of the service will fail. Valid values are None, empty string (\"\"), or a valid IP address. 'None' can be specified for a headless service when proxying is not required. Cannot be updated. More info: http://releases.k8s.io/HEAD/docs/user-guide/services.md#virtual-ips-and-service-proxies", - "type": "Type of exposed service. Must be ClusterIP, NodePort, or LoadBalancer. Defaults to ClusterIP. More info: http://releases.k8s.io/HEAD/docs/user-guide/services.md#external-services", + "ports": "The list of ports that are exposed by this service. More info: http://releases.k8s.io/release-1.2/docs/user-guide/services.md#virtual-ips-and-service-proxies", + "selector": "This service will route traffic to pods having labels matching this selector. Label keys and values that must match in order to receive traffic for this service. If empty, all pods are selected, if not specified, endpoints must be manually specified. More info: http://releases.k8s.io/release-1.2/docs/user-guide/services.md#overview", + "clusterIP": "ClusterIP is usually assigned by the master and is the IP address of the service. If specified, it will be allocated to the service if it is unused or else creation of the service will fail. Valid values are None, empty string (\"\"), or a valid IP address. 'None' can be specified for a headless service when proxying is not required. Cannot be updated. More info: http://releases.k8s.io/release-1.2/docs/user-guide/services.md#virtual-ips-and-service-proxies", + "type": "Type of exposed service. Must be ClusterIP, NodePort, or LoadBalancer. Defaults to ClusterIP. More info: http://releases.k8s.io/release-1.2/docs/user-guide/services.md#external-services", "externalIPs": "externalIPs is a list of IP addresses for which nodes in the cluster will also accept traffic for this service. These IPs are not managed by Kubernetes. The user is responsible for ensuring that traffic arrives at a node with this IP. A common example is external load-balancers that are not part of the Kubernetes system. A previous form of this functionality exists as the deprecatedPublicIPs field. When using this field, callers should also clear the deprecatedPublicIPs field.", "deprecatedPublicIPs": "deprecatedPublicIPs is deprecated and replaced by the externalIPs field with almost the exact same semantics. This field is retained in the v1 API for compatibility until at least 8/20/2016. It will be removed from any new API revisions. If both deprecatedPublicIPs *and* externalIPs are set, deprecatedPublicIPs is used.", - "sessionAffinity": "Supports \"ClientIP\" and \"None\". Used to maintain session affinity. Enable client IP based session affinity. Must be ClientIP or None. Defaults to None. More info: http://releases.k8s.io/HEAD/docs/user-guide/services.md#virtual-ips-and-service-proxies", + "sessionAffinity": "Supports \"ClientIP\" and \"None\". Used to maintain session affinity. Enable client IP based session affinity. Must be ClientIP or None. Defaults to None. More info: http://releases.k8s.io/release-1.2/docs/user-guide/services.md#virtual-ips-and-service-proxies", "loadBalancerIP": "Only applies to Service Type: LoadBalancer LoadBalancer will get created with the IP specified in this field. This feature depends on whether the underlying cloud-provider supports specifying the loadBalancerIP when a load balancer is created. This field will be ignored if the cloud-provider does not support the feature.", } @@ -1554,7 +1555,7 @@ func (TCPSocketAction) SwaggerDoc() map[string]string { 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", + "name": "Volume's name. Must be a DNS_LABEL and unique within the pod. More info: http://releases.k8s.io/release-1.2/docs/user-guide/identifiers.md#names", } func (Volume) SwaggerDoc() map[string]string { @@ -1565,7 +1566,7 @@ var map_VolumeMount = map[string]string{ "": "VolumeMount describes a mounting of a Volume within a container.", "name": "This must match the Name of a Volume.", "readOnly": "Mounted read-only if true, read-write otherwise (false or unspecified). Defaults to false.", - "mountPath": "Path within the container at which the volume should be mounted.", + "mountPath": "Path within the container at which the volume should be mounted. Must not contain ':'.", } func (VolumeMount) SwaggerDoc() map[string]string { @@ -1574,19 +1575,19 @@ func (VolumeMount) SwaggerDoc() map[string]string { var map_VolumeSource = map[string]string{ "": "Represents the source of a volume to mount. Only one of its members may be specified.", - "hostPath": "HostPath represents a pre-existing file or directory on the host machine that is directly exposed to the container. This is generally used for system agents or other privileged things that are allowed to see the host machine. Most containers will NOT need this. More info: http://releases.k8s.io/HEAD/docs/user-guide/volumes.md#hostpath", - "emptyDir": "EmptyDir represents a temporary directory that shares a pod's lifetime. More info: http://releases.k8s.io/HEAD/docs/user-guide/volumes.md#emptydir", - "gcePersistentDisk": "GCEPersistentDisk represents a GCE Disk resource that is attached to a kubelet's host machine and then exposed to the pod. More info: http://releases.k8s.io/HEAD/docs/user-guide/volumes.md#gcepersistentdisk", - "awsElasticBlockStore": "AWSElasticBlockStore represents an AWS Disk resource that is attached to a kubelet's host machine and then exposed to the pod. More info: http://releases.k8s.io/HEAD/docs/user-guide/volumes.md#awselasticblockstore", + "hostPath": "HostPath represents a pre-existing file or directory on the host machine that is directly exposed to the container. This is generally used for system agents or other privileged things that are allowed to see the host machine. Most containers will NOT need this. More info: http://releases.k8s.io/release-1.2/docs/user-guide/volumes.md#hostpath", + "emptyDir": "EmptyDir represents a temporary directory that shares a pod's lifetime. More info: http://releases.k8s.io/release-1.2/docs/user-guide/volumes.md#emptydir", + "gcePersistentDisk": "GCEPersistentDisk represents a GCE Disk resource that is attached to a kubelet's host machine and then exposed to the pod. More info: http://releases.k8s.io/release-1.2/docs/user-guide/volumes.md#gcepersistentdisk", + "awsElasticBlockStore": "AWSElasticBlockStore represents an AWS Disk resource that is attached to a kubelet's host machine and then exposed to the pod. More info: http://releases.k8s.io/release-1.2/docs/user-guide/volumes.md#awselasticblockstore", "gitRepo": "GitRepo represents a git repository at a particular revision.", - "secret": "Secret represents a secret that should populate this volume. More info: http://releases.k8s.io/HEAD/docs/user-guide/volumes.md#secrets", - "nfs": "NFS represents an NFS mount on the host that shares a pod's lifetime More info: http://releases.k8s.io/HEAD/docs/user-guide/volumes.md#nfs", - "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", + "secret": "Secret represents a secret that should populate this volume. More info: http://releases.k8s.io/release-1.2/docs/user-guide/volumes.md#secrets", + "nfs": "NFS represents an NFS mount on the host that shares a pod's lifetime More info: http://releases.k8s.io/release-1.2/docs/user-guide/volumes.md#nfs", + "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/release-1.2/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/release-1.2/examples/glusterfs/README.md", + "persistentVolumeClaim": "PersistentVolumeClaimVolumeSource represents a reference to a PersistentVolumeClaim in the same namespace. More info: http://releases.k8s.io/release-1.2/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/release-1.2/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", + "cinder": "Cinder represents a cinder volume attached and mounted on kubelets host machine More info: http://releases.k8s.io/release-1.2/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", diff --git a/vendor/k8s.io/kubernetes/pkg/api/validation/schema.go b/vendor/k8s.io/kubernetes/pkg/api/validation/schema.go index 24c1e26..6c55bc4 100644 --- a/vendor/k8s.io/kubernetes/pkg/api/validation/schema.go +++ b/vendor/k8s.io/kubernetes/pkg/api/validation/schema.go @@ -44,6 +44,14 @@ func NewInvalidTypeError(expected reflect.Kind, observed reflect.Kind, fieldName return &InvalidTypeError{expected, observed, fieldName} } +// TypeNotFoundError is returned when specified type +// can not found in schema +type TypeNotFoundError string + +func (tnfe TypeNotFoundError) Error() string { + return fmt.Sprintf("couldn't find type: %s", string(tnfe)) +} + // Schema is an interface that knows how to validate an API object serialized to a byte array. type Schema interface { ValidateBytes(data []byte) error @@ -164,7 +172,7 @@ func (s *SwaggerSchema) ValidateObject(obj interface{}, fieldName, typeName stri models := s.api.Models model, ok := models.At(typeName) if !ok { - return append(allErrs, fmt.Errorf("couldn't find type: %s", typeName)) + return append(allErrs, TypeNotFoundError(typeName)) } properties := model.Properties if len(properties.List) == 0 { diff --git a/vendor/k8s.io/kubernetes/pkg/api/validation/validation.go b/vendor/k8s.io/kubernetes/pkg/api/validation/validation.go index 5f0d876..3d4d906 100644 --- a/vendor/k8s.io/kubernetes/pkg/api/validation/validation.go +++ b/vendor/k8s.io/kubernetes/pkg/api/validation/validation.go @@ -27,16 +27,18 @@ import ( "regexp" "strings" + "github.com/golang/glog" "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/endpoints" + utilpod "k8s.io/kubernetes/pkg/api/pod" "k8s.io/kubernetes/pkg/api/resource" + apiservice "k8s.io/kubernetes/pkg/api/service" "k8s.io/kubernetes/pkg/capabilities" "k8s.io/kubernetes/pkg/labels" "k8s.io/kubernetes/pkg/util/intstr" "k8s.io/kubernetes/pkg/util/sets" "k8s.io/kubernetes/pkg/util/validation" "k8s.io/kubernetes/pkg/util/validation/field" - - "github.com/golang/glog" ) // TODO: delete this global variable when we enable the validation of common @@ -112,10 +114,34 @@ func ValidateAnnotations(annotations map[string]string, fldPath *field.Path) fie if totalSize > (int64)(totalAnnotationSizeLimitB) { allErrs = append(allErrs, field.TooLong(fldPath, "", totalAnnotationSizeLimitB)) } + return allErrs +} +func ValidatePodSpecificAnnotations(annotations map[string]string, fldPath *field.Path) field.ErrorList { + allErrs := field.ErrorList{} if annotations[api.AffinityAnnotationKey] != "" { 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 subdomain, exists := annotations[utilpod.PodSubdomainAnnotation]; exists && !validation.IsDNS1123Label(subdomain) { + allErrs = append(allErrs, field.Invalid(fldPath, utilpod.PodSubdomainAnnotation, DNS1123LabelErrorMsg)) + } + + return allErrs +} + +func ValidateEndpointsSpecificAnnotations(annotations map[string]string, fldPath *field.Path) field.ErrorList { + allErrs := field.ErrorList{} + hostnamesMap, exists := annotations[endpoints.PodHostnamesAnnotation] + if exists && !isValidHostnamesMap(hostnamesMap) { + allErrs = append(allErrs, field.Invalid(fldPath, endpoints.PodHostnamesAnnotation, + `must be a valid json representation of map[string(IP)][HostRecord] e.g. "{"10.245.1.6":{"HostName":"my-webserver"}}"`)) + } + return allErrs } @@ -1091,6 +1117,8 @@ func validateVolumeMounts(mounts []api.VolumeMount, volumes sets.String, fldPath } if len(mnt.MountPath) == 0 { allErrs = append(allErrs, field.Required(idxPath.Child("mountPath"), "")) + } else if strings.Contains(mnt.MountPath, ":") { + allErrs = append(allErrs, field.Invalid(idxPath.Child("mountPath"), mnt.MountPath, "must not contain ':'")) } } return allErrs @@ -1353,7 +1381,9 @@ func validateImagePullSecrets(imagePullSecrets []api.LocalObjectReference, fldPa // ValidatePod tests if required fields in the pod are set. func ValidatePod(pod *api.Pod) field.ErrorList { - allErrs := ValidateObjectMeta(&pod.ObjectMeta, true, ValidatePodName, field.NewPath("metadata")) + fldPath := field.NewPath("metadata") + allErrs := ValidateObjectMeta(&pod.ObjectMeta, true, ValidatePodName, fldPath) + allErrs = append(allErrs, ValidatePodSpecificAnnotations(pod.ObjectMeta.Annotations, fldPath.Child("annotations"))...) allErrs = append(allErrs, ValidatePodSpec(&pod.Spec, field.NewPath("spec"))...) return allErrs } @@ -1517,8 +1547,9 @@ func ValidatePodSecurityContext(securityContext *api.PodSecurityContext, spec *a // ValidatePodUpdate tests to see if the update is legal for an end user to make. newPod is updated with fields // that cannot be changed. func ValidatePodUpdate(newPod, oldPod *api.Pod) field.ErrorList { - allErrs := ValidateObjectMetaUpdate(&newPod.ObjectMeta, &oldPod.ObjectMeta, field.NewPath("metadata")) - + fldPath := field.NewPath("metadata") + allErrs := ValidateObjectMetaUpdate(&newPod.ObjectMeta, &oldPod.ObjectMeta, fldPath) + allErrs = append(allErrs, ValidatePodSpecificAnnotations(newPod.ObjectMeta.Annotations, fldPath.Child("annotations"))...) specPath := field.NewPath("spec") if len(newPod.Spec.Containers) != len(oldPod.Spec.Containers) { //TODO: Pinpoint the specific container that causes the invalid error after we have strategic merge diff @@ -1736,6 +1767,12 @@ func ValidateService(service *api.Service) field.ErrorList { nodePorts[key] = true } + _, err := apiservice.GetLoadBalancerSourceRanges(service.Annotations) + if err != nil { + v := service.Annotations[apiservice.AnnotationLoadBalancerSourceRangesKey] + allErrs = append(allErrs, field.Invalid(field.NewPath("metadata", "annotations").Key(apiservice.AnnotationLoadBalancerSourceRangesKey), v, "must be a comma separated list of CIDRs e.g. 192.168.0.0/16,10.0.0.0/8")) + } + return allErrs } @@ -1821,6 +1858,7 @@ func ValidateReplicationControllerStatusUpdate(controller, oldController *api.Re allErrs := ValidateObjectMetaUpdate(&controller.ObjectMeta, &oldController.ObjectMeta, field.NewPath("metadata")) statusPath := field.NewPath("status") allErrs = append(allErrs, ValidateNonnegativeField(int64(controller.Status.Replicas), statusPath.Child("replicas"))...) + allErrs = append(allErrs, ValidateNonnegativeField(int64(controller.Status.FullyLabeledReplicas), statusPath.Child("fullyLabeledReplicas"))...) allErrs = append(allErrs, ValidateNonnegativeField(int64(controller.Status.ObservedGeneration), statusPath.Child("observedGeneration"))...) return allErrs } @@ -1875,6 +1913,7 @@ func ValidatePodTemplateSpec(spec *api.PodTemplateSpec, fldPath *field.Path) fie allErrs := field.ErrorList{} allErrs = append(allErrs, ValidateLabels(spec.Labels, fldPath.Child("labels"))...) allErrs = append(allErrs, ValidateAnnotations(spec.Annotations, fldPath.Child("annotations"))...) + allErrs = append(allErrs, ValidatePodSpecificAnnotations(spec.Annotations, fldPath.Child("annotations"))...) allErrs = append(allErrs, ValidatePodSpec(&spec.Spec, fldPath.Child("spec"))...) return allErrs } @@ -1996,6 +2035,33 @@ func validateResourceQuotaResourceName(value string, fldPath *field.Path) field. return field.ErrorList{} } +// 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)) + } + + if len(strings.Split(value, "/")) == 1 { + if !api.IsStandardLimitRangeType(value) { + return append(allErrs, field.Invalid(fldPath, value, "must be a standard limit type or fully qualified")) + } + } + + return allErrs +} + +// Validate limit range resource name +// limit types (other than Pod/Container) could contain storage not just cpu or memory +func validateLimitRangeResourceName(limitType api.LimitType, value string, fldPath *field.Path) field.ErrorList { + switch limitType { + case api.LimitTypePod, api.LimitTypeContainer: + return validateContainerResourceName(value, fldPath) + default: + return validateResourceName(value, fldPath) + } +} + // ValidateLimitRange tests if required fields in the LimitRange are set. func ValidateLimitRange(limitRange *api.LimitRange) field.ErrorList { allErrs := ValidateObjectMeta(&limitRange.ObjectMeta, true, ValidateLimitRangeName, field.NewPath("metadata")) @@ -2006,6 +2072,8 @@ func ValidateLimitRange(limitRange *api.LimitRange) field.ErrorList { for i := range limitRange.Spec.Limits { idxPath := fldPath.Index(i) limit := &limitRange.Spec.Limits[i] + allErrs = append(allErrs, validateLimitRangeTypeName(string(limit.Type), idxPath.Child("type"))...) + _, found := limitTypeSet[limit.Type] if found { allErrs = append(allErrs, field.Duplicate(idxPath.Child("type"), limit.Type)) @@ -2020,12 +2088,12 @@ func ValidateLimitRange(limitRange *api.LimitRange) field.ErrorList { maxLimitRequestRatios := map[string]resource.Quantity{} for k, q := range limit.Max { - allErrs = append(allErrs, validateContainerResourceName(string(k), idxPath.Child("max").Key(string(k)))...) + allErrs = append(allErrs, validateLimitRangeResourceName(limit.Type, string(k), idxPath.Child("max").Key(string(k)))...) keys.Insert(string(k)) max[string(k)] = q } for k, q := range limit.Min { - allErrs = append(allErrs, validateContainerResourceName(string(k), idxPath.Child("min").Key(string(k)))...) + allErrs = append(allErrs, validateLimitRangeResourceName(limit.Type, string(k), idxPath.Child("min").Key(string(k)))...) keys.Insert(string(k)) min[string(k)] = q } @@ -2039,19 +2107,19 @@ func ValidateLimitRange(limitRange *api.LimitRange) field.ErrorList { } } else { for k, q := range limit.Default { - allErrs = append(allErrs, validateContainerResourceName(string(k), idxPath.Child("default").Key(string(k)))...) + allErrs = append(allErrs, validateLimitRangeResourceName(limit.Type, string(k), idxPath.Child("default").Key(string(k)))...) keys.Insert(string(k)) defaults[string(k)] = q } for k, q := range limit.DefaultRequest { - allErrs = append(allErrs, validateContainerResourceName(string(k), idxPath.Child("defaultRequest").Key(string(k)))...) + allErrs = append(allErrs, validateLimitRangeResourceName(limit.Type, string(k), idxPath.Child("defaultRequest").Key(string(k)))...) keys.Insert(string(k)) defaultRequests[string(k)] = q } } for k, q := range limit.MaxLimitRequestRatio { - allErrs = append(allErrs, validateContainerResourceName(string(k), idxPath.Child("maxLimitRequestRatio").Key(string(k)))...) + allErrs = append(allErrs, validateLimitRangeResourceName(limit.Type, string(k), idxPath.Child("maxLimitRequestRatio").Key(string(k)))...) keys.Insert(string(k)) maxLimitRequestRatios[string(k)] = q } @@ -2494,6 +2562,7 @@ func ValidateNamespaceFinalizeUpdate(newNamespace, oldNamespace *api.Namespace) // ValidateEndpoints tests if required fields are set. func ValidateEndpoints(endpoints *api.Endpoints) field.ErrorList { allErrs := ValidateObjectMeta(&endpoints.ObjectMeta, true, ValidateEndpointsName, field.NewPath("metadata")) + allErrs = append(allErrs, ValidateEndpointsSpecificAnnotations(endpoints.Annotations, field.NewPath("annotations"))...) allErrs = append(allErrs, validateEndpointSubsets(endpoints.Subsets, field.NewPath("subsets"))...) return allErrs } @@ -2577,6 +2646,7 @@ func validateEndpointPort(port *api.EndpointPort, requireName bool, fldPath *fie func ValidateEndpointsUpdate(newEndpoints, oldEndpoints *api.Endpoints) field.ErrorList { allErrs := ValidateObjectMetaUpdate(&newEndpoints.ObjectMeta, &oldEndpoints.ObjectMeta, field.NewPath("metadata")) allErrs = append(allErrs, validateEndpointSubsets(newEndpoints.Subsets, field.NewPath("subsets"))...) + allErrs = append(allErrs, ValidateEndpointsSpecificAnnotations(newEndpoints.Annotations, field.NewPath("annotations"))...) return allErrs } @@ -2642,3 +2712,24 @@ func ValidateLoadBalancerStatus(status *api.LoadBalancerStatus, fldPath *field.P } return allErrs } + +func isValidHostnamesMap(serializedPodHostNames string) bool { + if len(serializedPodHostNames) == 0 { + return false + } + podHostNames := map[string]endpoints.HostRecord{} + err := json.Unmarshal([]byte(serializedPodHostNames), &podHostNames) + if err != nil { + return false + } + + for ip, hostRecord := range podHostNames { + if !validation.IsDNS1123Label(hostRecord.HostName) { + return false + } + if net.ParseIP(ip) == nil { + return false + } + } + return true +} diff --git a/vendor/k8s.io/kubernetes/pkg/apis/autoscaling/types.go b/vendor/k8s.io/kubernetes/pkg/apis/autoscaling/types.go index a521fee..99080a8 100644 --- a/vendor/k8s.io/kubernetes/pkg/apis/autoscaling/types.go +++ b/vendor/k8s.io/kubernetes/pkg/apis/autoscaling/types.go @@ -24,13 +24,13 @@ import ( // Scale represents a scaling request for a resource. type Scale struct { unversioned.TypeMeta `json:",inline"` - // Standard object metadata; More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata. + // Standard object metadata; More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#metadata. api.ObjectMeta `json:"metadata,omitempty"` - // defines the behavior of the scale. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#spec-and-status. + // defines the behavior of the scale. More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#spec-and-status. Spec ScaleSpec `json:"spec,omitempty"` - // current status of the scale. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#spec-and-status. Read-only. + // current status of the scale. More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#spec-and-status. Read-only. Status ScaleStatus `json:"status,omitempty"` } @@ -48,6 +48,6 @@ type ScaleStatus struct { // label query over pods that should match the replicas count. This is same // as the label selector but in the string format to avoid introspection // by clients. The string will be in the same format as the query-param syntax. - // More info: http://releases.k8s.io/HEAD/docs/user-guide/labels.md#label-selectors + // More info: http://releases.k8s.io/release-1.2/docs/user-guide/labels.md#label-selectors Selector string `json:"selector,omitempty"` } diff --git a/vendor/k8s.io/kubernetes/pkg/apis/autoscaling/v1/types.go b/vendor/k8s.io/kubernetes/pkg/apis/autoscaling/v1/types.go index ff53a5d..20b9672 100644 --- a/vendor/k8s.io/kubernetes/pkg/apis/autoscaling/v1/types.go +++ b/vendor/k8s.io/kubernetes/pkg/apis/autoscaling/v1/types.go @@ -23,9 +23,9 @@ import ( // CrossVersionObjectReference contains enough information to let you identify the referred resource. type CrossVersionObjectReference struct { - // Kind of the referent; More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" + // Kind of the referent; More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#types-kinds" Kind string `json:"kind"` - // Name of the referent; More info: http://releases.k8s.io/HEAD/docs/user-guide/identifiers.md#names + // Name of the referent; More info: http://releases.k8s.io/release-1.2/docs/user-guide/identifiers.md#names Name string `json:"name"` // API version of the referent APIVersion string `json:"apiVersion,omitempty"` @@ -41,6 +41,7 @@ type HorizontalPodAutoscalerSpec struct { // upper limit for the number of pods that can be set by the autoscaler; cannot be smaller than MinReplicas. MaxReplicas int32 `json:"maxReplicas"` // target average CPU utilization (represented as a percentage of requested CPU) over all the pods; + // if not specified the default autoscaling policy will be used. TargetCPUUtilizationPercentage *int32 `json:"targetCPUUtilizationPercentage,omitempty"` } @@ -67,10 +68,10 @@ type HorizontalPodAutoscalerStatus struct { // configuration of a horizontal pod autoscaler. type HorizontalPodAutoscaler struct { unversioned.TypeMeta `json:",inline"` - // Standard object metadata. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata + // Standard object metadata. More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#metadata v1.ObjectMeta `json:"metadata,omitempty"` - // behaviour of autoscaler. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#spec-and-status. + // behaviour of autoscaler. More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#spec-and-status. Spec HorizontalPodAutoscalerSpec `json:"spec,omitempty"` // current information about the autoscaler. @@ -90,13 +91,13 @@ type HorizontalPodAutoscalerList struct { // Scale represents a scaling request for a resource. type Scale struct { unversioned.TypeMeta `json:",inline"` - // Standard object metadata; More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata. + // Standard object metadata; More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#metadata. v1.ObjectMeta `json:"metadata,omitempty"` - // defines the behavior of the scale. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#spec-and-status. + // defines the behavior of the scale. More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#spec-and-status. Spec ScaleSpec `json:"spec,omitempty"` - // current status of the scale. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#spec-and-status. Read-only. + // current status of the scale. More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#spec-and-status. Read-only. Status ScaleStatus `json:"status,omitempty"` } @@ -114,6 +115,6 @@ type ScaleStatus struct { // label query over pods that should match the replicas count. This is same // as the label selector but in the string format to avoid introspection // by clients. The string will be in the same format as the query-param syntax. - // More info about label selectors: http://releases.k8s.io/HEAD/docs/user-guide/labels.md#label-selectors + // More info about label selectors: http://releases.k8s.io/release-1.2/docs/user-guide/labels.md#label-selectors Selector string `json:"selector,omitempty"` } 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 9fb4bec..537dafb 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 @@ -29,8 +29,8 @@ package v1 // AUTO-GENERATED FUNCTIONS START HERE var map_CrossVersionObjectReference = map[string]string{ "": "CrossVersionObjectReference contains enough information to let you identify the referred resource.", - "kind": "Kind of the referent; More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds\"", - "name": "Name of the referent; More info: http://releases.k8s.io/HEAD/docs/user-guide/identifiers.md#names", + "kind": "Kind of the referent; More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#types-kinds\"", + "name": "Name of the referent; More info: http://releases.k8s.io/release-1.2/docs/user-guide/identifiers.md#names", "apiVersion": "API version of the referent", } @@ -40,8 +40,8 @@ func (CrossVersionObjectReference) SwaggerDoc() map[string]string { var map_HorizontalPodAutoscaler = map[string]string{ "": "configuration of a horizontal pod autoscaler.", - "metadata": "Standard object metadata. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata", - "spec": "behaviour of autoscaler. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#spec-and-status.", + "metadata": "Standard object metadata. More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#metadata", + "spec": "behaviour of autoscaler. More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#spec-and-status.", "status": "current information about the autoscaler.", } @@ -64,7 +64,7 @@ var map_HorizontalPodAutoscalerSpec = map[string]string{ "scaleTargetRef": "reference to scaled resource; horizontal pod autoscaler will learn the current resource consumption and will set the desired number of pods by using its Scale subresource.", "minReplicas": "lower limit for the number of pods that can be set by the autoscaler, default 1.", "maxReplicas": "upper limit for the number of pods that can be set by the autoscaler; cannot be smaller than MinReplicas.", - "targetCPUUtilizationPercentage": "target average CPU utilization (represented as a percentage of requested CPU) over all the pods;", + "targetCPUUtilizationPercentage": "target average CPU utilization (represented as a percentage of requested CPU) over all the pods; if not specified the default autoscaling policy will be used.", } func (HorizontalPodAutoscalerSpec) SwaggerDoc() map[string]string { @@ -86,9 +86,9 @@ func (HorizontalPodAutoscalerStatus) SwaggerDoc() map[string]string { var map_Scale = map[string]string{ "": "Scale represents a scaling request for a resource.", - "metadata": "Standard object metadata; More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata.", - "spec": "defines the behavior of the scale. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#spec-and-status.", - "status": "current status of the scale. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#spec-and-status. Read-only.", + "metadata": "Standard object metadata; More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#metadata.", + "spec": "defines the behavior of the scale. More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#spec-and-status.", + "status": "current status of the scale. More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#spec-and-status. Read-only.", } func (Scale) SwaggerDoc() map[string]string { @@ -107,7 +107,7 @@ func (ScaleSpec) SwaggerDoc() map[string]string { var map_ScaleStatus = map[string]string{ "": "ScaleStatus represents the current status of a scale subresource.", "replicas": "actual number of observed instances of the scaled object.", - "selector": "label query over pods that should match the replicas count. This is same as the label selector but in the string format to avoid introspection by clients. The string will be in the same format as the query-param syntax. More info about label selectors: http://releases.k8s.io/HEAD/docs/user-guide/labels.md#label-selectors", + "selector": "label query over pods that should match the replicas count. This is same as the label selector but in the string format to avoid introspection by clients. The string will be in the same format as the query-param syntax. More info about label selectors: http://releases.k8s.io/release-1.2/docs/user-guide/labels.md#label-selectors", } func (ScaleStatus) SwaggerDoc() map[string]string { diff --git a/vendor/k8s.io/kubernetes/pkg/apis/batch/v1/types.go b/vendor/k8s.io/kubernetes/pkg/apis/batch/v1/types.go index 9dfe0d3..214ffe6 100644 --- a/vendor/k8s.io/kubernetes/pkg/apis/batch/v1/types.go +++ b/vendor/k8s.io/kubernetes/pkg/apis/batch/v1/types.go @@ -25,15 +25,15 @@ import ( type Job struct { unversioned.TypeMeta `json:",inline"` // Standard object's metadata. - // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata + // More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#metadata v1.ObjectMeta `json:"metadata,omitempty"` // Spec is a structure defining the expected behavior of a job. - // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#spec-and-status + // More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#spec-and-status Spec JobSpec `json:"spec,omitempty"` // Status is a structure describing current status of a job. - // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#spec-and-status + // More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#spec-and-status Status JobStatus `json:"status,omitempty"` } @@ -41,7 +41,7 @@ type Job struct { type JobList struct { unversioned.TypeMeta `json:",inline"` // Standard list metadata - // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata + // More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#metadata unversioned.ListMeta `json:"metadata,omitempty"` // Items is the list of Job. @@ -55,7 +55,7 @@ type JobSpec struct { // run at any given time. The actual number of pods running in steady state will // be less than this number when ((.spec.completions - .status.successful) < .spec.parallelism), // i.e. when the work left to do is less than max parallelism. - // More info: http://releases.k8s.io/HEAD/docs/user-guide/jobs.md + // More info: http://releases.k8s.io/release-1.2/docs/user-guide/jobs.md Parallelism *int32 `json:"parallelism,omitempty"` // Completions specifies the desired number of successfully finished pods the @@ -63,7 +63,7 @@ type JobSpec struct { // pod signals the success of all pods, and allows parallelism to have any positive // value. Setting to 1 means that parallelism is limited to 1 and the success of that // pod signals the success of the job. - // More info: http://releases.k8s.io/HEAD/docs/user-guide/jobs.md + // More info: http://releases.k8s.io/release-1.2/docs/user-guide/jobs.md Completions *int32 `json:"completions,omitempty"` // Optional duration in seconds relative to the startTime that the job may be active @@ -72,7 +72,7 @@ type JobSpec struct { // Selector is a label query over pods that should match the pod count. // Normally, the system sets this field for you. - // More info: http://releases.k8s.io/HEAD/docs/user-guide/labels.md#label-selectors + // More info: http://releases.k8s.io/release-1.2/docs/user-guide/labels.md#label-selectors Selector *LabelSelector `json:"selector,omitempty"` // ManualSelector controls generation of pod labels and pod selectors. @@ -84,12 +84,12 @@ type JobSpec struct { // and other jobs to not function correctly. However, You may see // `manualSelector=true` in jobs that were created with the old `extensions/v1beta1` // API. - // More info: http://releases.k8s.io/HEAD/docs/design/selector-generation.md + // More info: http://releases.k8s.io/release-1.2/docs/design/selector-generation.md ManualSelector *bool `json:"manualSelector,omitempty"` // Template is the object that describes the pod that will be created when // executing a job. - // More info: http://releases.k8s.io/HEAD/docs/user-guide/jobs.md + // More info: http://releases.k8s.io/release-1.2/docs/user-guide/jobs.md Template v1.PodTemplateSpec `json:"template"` } @@ -97,7 +97,7 @@ type JobSpec struct { type JobStatus struct { // Conditions represent the latest available observations of an object's current state. - // More info: http://releases.k8s.io/HEAD/docs/user-guide/jobs.md + // More info: http://releases.k8s.io/release-1.2/docs/user-guide/jobs.md Conditions []JobCondition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type"` // StartTime represents time when the job was acknowledged by the Job Manager. 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 8b52558..32e278e 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 @@ -29,9 +29,9 @@ package v1 // AUTO-GENERATED FUNCTIONS START HERE var map_Job = map[string]string{ "": "Job represents the configuration of a single job.", - "metadata": "Standard object's metadata. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata", - "spec": "Spec is a structure defining the expected behavior of a job. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#spec-and-status", - "status": "Status is a structure describing current status of a job. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#spec-and-status", + "metadata": "Standard object's metadata. More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#metadata", + "spec": "Spec is a structure defining the expected behavior of a job. More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#spec-and-status", + "status": "Status is a structure describing current status of a job. More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#spec-and-status", } func (Job) SwaggerDoc() map[string]string { @@ -54,7 +54,7 @@ func (JobCondition) SwaggerDoc() map[string]string { var map_JobList = map[string]string{ "": "JobList is a collection of jobs.", - "metadata": "Standard list metadata More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata", + "metadata": "Standard list metadata More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#metadata", "items": "Items is the list of Job.", } @@ -64,12 +64,12 @@ func (JobList) SwaggerDoc() map[string]string { var map_JobSpec = map[string]string{ "": "JobSpec describes how the job execution will look like.", - "parallelism": "Parallelism specifies the maximum desired number of pods the job should run at any given time. The actual number of pods running in steady state will be less than this number when ((.spec.completions - .status.successful) < .spec.parallelism), i.e. when the work left to do is less than max parallelism. More info: http://releases.k8s.io/HEAD/docs/user-guide/jobs.md", - "completions": "Completions specifies the desired number of successfully finished pods the job should be run with. Setting to nil means that the success of any pod signals the success of all pods, and allows parallelism to have any positive value. Setting to 1 means that parallelism is limited to 1 and the success of that pod signals the success of the job. More info: http://releases.k8s.io/HEAD/docs/user-guide/jobs.md", + "parallelism": "Parallelism specifies the maximum desired number of pods the job should run at any given time. The actual number of pods running in steady state will be less than this number when ((.spec.completions - .status.successful) < .spec.parallelism), i.e. when the work left to do is less than max parallelism. More info: http://releases.k8s.io/release-1.2/docs/user-guide/jobs.md", + "completions": "Completions specifies the desired number of successfully finished pods the job should be run with. Setting to nil means that the success of any pod signals the success of all pods, and allows parallelism to have any positive value. Setting to 1 means that parallelism is limited to 1 and the success of that pod signals the success of the job. More info: http://releases.k8s.io/release-1.2/docs/user-guide/jobs.md", "activeDeadlineSeconds": "Optional duration in seconds relative to the startTime that the job may be active before the system tries to terminate it; value must be positive integer", - "selector": "Selector is a label query over pods that should match the pod count. Normally, the system sets this field for you. More info: http://releases.k8s.io/HEAD/docs/user-guide/labels.md#label-selectors", - "manualSelector": "ManualSelector controls generation of pod labels and pod selectors. Leave `manualSelector` unset unless you are certain what you are doing. When false or unset, the system pick labels unique to this job and appends those labels to the pod template. When true, the user is responsible for picking unique labels and specifying the selector. Failure to pick a unique label may cause this and other jobs to not function correctly. However, You may see `manualSelector=true` in jobs that were created with the old `extensions/v1beta1` API. More info: http://releases.k8s.io/HEAD/docs/design/selector-generation.md", - "template": "Template is the object that describes the pod that will be created when executing a job. More info: http://releases.k8s.io/HEAD/docs/user-guide/jobs.md", + "selector": "Selector is a label query over pods that should match the pod count. Normally, the system sets this field for you. More info: http://releases.k8s.io/release-1.2/docs/user-guide/labels.md#label-selectors", + "manualSelector": "ManualSelector controls generation of pod labels and pod selectors. Leave `manualSelector` unset unless you are certain what you are doing. When false or unset, the system pick labels unique to this job and appends those labels to the pod template. When true, the user is responsible for picking unique labels and specifying the selector. Failure to pick a unique label may cause this and other jobs to not function correctly. However, You may see `manualSelector=true` in jobs that were created with the old `extensions/v1beta1` API. More info: http://releases.k8s.io/release-1.2/docs/design/selector-generation.md", + "template": "Template is the object that describes the pod that will be created when executing a job. More info: http://releases.k8s.io/release-1.2/docs/user-guide/jobs.md", } func (JobSpec) SwaggerDoc() map[string]string { @@ -78,7 +78,7 @@ func (JobSpec) SwaggerDoc() map[string]string { var map_JobStatus = map[string]string{ "": "JobStatus represents the current state of a Job.", - "conditions": "Conditions represent the latest available observations of an object's current state. More info: http://releases.k8s.io/HEAD/docs/user-guide/jobs.md", + "conditions": "Conditions represent the latest available observations of an object's current state. More info: http://releases.k8s.io/release-1.2/docs/user-guide/jobs.md", "startTime": "StartTime represents time when the job was acknowledged by the Job Manager. It is not guaranteed to be set in happens-before order across separate operations. It is represented in RFC3339 form and is in UTC.", "completionTime": "CompletionTime represents time when the job was completed. It is not guaranteed to be set in happens-before order across separate operations. It is represented in RFC3339 form and is in UTC.", "active": "Active is the number of actively running pods.", 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 cfc883d..f3f5462 100644 --- a/vendor/k8s.io/kubernetes/pkg/apis/componentconfig/types.generated.go +++ b/vendor/k8s.io/kubernetes/pkg/apis/componentconfig/types.generated.go @@ -1134,7 +1134,7 @@ func (x *KubeletConfiguration) CodecEncodeSelf(e *codec1978.Encoder) { } else { yysep2 := !z.EncBinary() yy2arr2 := z.EncBasicHandle().StructToArray - var yyq2 [77]bool + var yyq2 [78]bool _, _, _ = yysep2, yyq2, yy2arr2 const yyr2 bool = false yyq2[47] = x.CloudProvider != "" @@ -1145,13 +1145,13 @@ func (x *KubeletConfiguration) CodecEncodeSelf(e *codec1978.Encoder) { yyq2[52] = x.CgroupRoot != "" yyq2[54] = x.RktPath != "" yyq2[56] = x.RktStage1Image != "" - yyq2[72] = true - yyq2[73] = x.NodeIP != "" + yyq2[73] = true + yyq2[74] = x.NodeIP != "" var yynn2 int if yyr2 || yy2arr2 { - r.EncodeArrayStart(77) + r.EncodeArrayStart(78) } else { - yynn2 = 67 + yynn2 = 68 for _, b := range yyq2 { if b { yynn2++ @@ -2399,17 +2399,17 @@ func (x *KubeletConfiguration) CodecEncodeSelf(e *codec1978.Encoder) { _ = yym197 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) yym198 := z.EncBinary() _ = yym198 if false { } else { - r.EncodeInt(int64(x.MaxPods)) + r.EncodeBool(bool(x.BabysitDaemons)) } } if yyr2 || yy2arr2 { @@ -2418,17 +2418,17 @@ func (x *KubeletConfiguration) CodecEncodeSelf(e *codec1978.Encoder) { _ = yym200 if false { } else { - r.EncodeString(codecSelferC_UTF81234, string(x.DockerExecHandlerName)) + r.EncodeInt(int64(x.MaxPods)) } } else { z.EncSendContainerState(codecSelfer_containerMapKey1234) - r.EncodeString(codecSelferC_UTF81234, string("dockerExecHandlerName")) + r.EncodeString(codecSelferC_UTF81234, string("maxPods")) z.EncSendContainerState(codecSelfer_containerMapValue1234) yym201 := z.EncBinary() _ = yym201 if false { } else { - r.EncodeString(codecSelferC_UTF81234, string(x.DockerExecHandlerName)) + r.EncodeInt(int64(x.MaxPods)) } } if yyr2 || yy2arr2 { @@ -2437,17 +2437,17 @@ func (x *KubeletConfiguration) CodecEncodeSelf(e *codec1978.Encoder) { _ = yym203 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) yym204 := z.EncBinary() _ = yym204 if false { } else { - r.EncodeString(codecSelferC_UTF81234, string(x.PodCIDR)) + r.EncodeString(codecSelferC_UTF81234, string(x.DockerExecHandlerName)) } } if yyr2 || yy2arr2 { @@ -2456,17 +2456,17 @@ func (x *KubeletConfiguration) CodecEncodeSelf(e *codec1978.Encoder) { _ = yym206 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) yym207 := z.EncBinary() _ = yym207 if false { } else { - r.EncodeString(codecSelferC_UTF81234, string(x.ResolverConfig)) + r.EncodeString(codecSelferC_UTF81234, string(x.PodCIDR)) } } if yyr2 || yy2arr2 { @@ -2475,17 +2475,17 @@ func (x *KubeletConfiguration) CodecEncodeSelf(e *codec1978.Encoder) { _ = yym209 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) yym210 := z.EncBinary() _ = yym210 if false { } else { - r.EncodeBool(bool(x.CPUCFSQuota)) + r.EncodeString(codecSelferC_UTF81234, string(x.ResolverConfig)) } } if yyr2 || yy2arr2 { @@ -2494,17 +2494,17 @@ func (x *KubeletConfiguration) CodecEncodeSelf(e *codec1978.Encoder) { _ = yym212 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) yym213 := z.EncBinary() _ = yym213 if false { } else { - r.EncodeBool(bool(x.Containerized)) + r.EncodeBool(bool(x.CPUCFSQuota)) } } if yyr2 || yy2arr2 { @@ -2513,17 +2513,17 @@ func (x *KubeletConfiguration) CodecEncodeSelf(e *codec1978.Encoder) { _ = yym215 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) yym216 := z.EncBinary() _ = yym216 if false { } else { - r.EncodeUint(uint64(x.MaxOpenFiles)) + r.EncodeBool(bool(x.Containerized)) } } if yyr2 || yy2arr2 { @@ -2532,17 +2532,17 @@ func (x *KubeletConfiguration) CodecEncodeSelf(e *codec1978.Encoder) { _ = yym218 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) yym219 := z.EncBinary() _ = yym219 if false { } else { - r.EncodeBool(bool(x.ReconcileCIDR)) + r.EncodeUint(uint64(x.MaxOpenFiles)) } } if yyr2 || yy2arr2 { @@ -2551,17 +2551,17 @@ func (x *KubeletConfiguration) CodecEncodeSelf(e *codec1978.Encoder) { _ = yym221 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) yym222 := z.EncBinary() _ = yym222 if false { } else { - r.EncodeBool(bool(x.RegisterSchedulable)) + r.EncodeBool(bool(x.ReconcileCIDR)) } } if yyr2 || yy2arr2 { @@ -2570,17 +2570,17 @@ func (x *KubeletConfiguration) CodecEncodeSelf(e *codec1978.Encoder) { _ = yym224 if false { } else { - r.EncodeFloat32(float32(x.KubeAPIQPS)) + r.EncodeBool(bool(x.RegisterSchedulable)) } } else { z.EncSendContainerState(codecSelfer_containerMapKey1234) - r.EncodeString(codecSelferC_UTF81234, string("kubeAPIQPS")) + r.EncodeString(codecSelferC_UTF81234, string("registerSchedulable")) z.EncSendContainerState(codecSelfer_containerMapValue1234) yym225 := z.EncBinary() _ = yym225 if false { } else { - r.EncodeFloat32(float32(x.KubeAPIQPS)) + r.EncodeBool(bool(x.RegisterSchedulable)) } } if yyr2 || yy2arr2 { @@ -2589,17 +2589,17 @@ func (x *KubeletConfiguration) CodecEncodeSelf(e *codec1978.Encoder) { _ = yym227 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) yym228 := z.EncBinary() _ = yym228 if false { } else { - r.EncodeInt(int64(x.KubeAPIBurst)) + r.EncodeFloat32(float32(x.KubeAPIQPS)) } } if yyr2 || yy2arr2 { @@ -2608,17 +2608,17 @@ func (x *KubeletConfiguration) CodecEncodeSelf(e *codec1978.Encoder) { _ = yym230 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) yym231 := z.EncBinary() _ = yym231 if false { } else { - r.EncodeBool(bool(x.SerializeImagePulls)) + r.EncodeInt(int64(x.KubeAPIBurst)) } } if yyr2 || yy2arr2 { @@ -2627,57 +2627,76 @@ func (x *KubeletConfiguration) CodecEncodeSelf(e *codec1978.Encoder) { _ = yym233 if false { } else { - r.EncodeBool(bool(x.ExperimentalFlannelOverlay)) + r.EncodeBool(bool(x.SerializeImagePulls)) } } else { z.EncSendContainerState(codecSelfer_containerMapKey1234) - r.EncodeString(codecSelferC_UTF81234, string("experimentalFlannelOverlay")) + r.EncodeString(codecSelferC_UTF81234, string("serializeImagePulls")) z.EncSendContainerState(codecSelfer_containerMapValue1234) yym234 := z.EncBinary() _ = yym234 if false { + } else { + r.EncodeBool(bool(x.SerializeImagePulls)) + } + } + if yyr2 || yy2arr2 { + z.EncSendContainerState(codecSelfer_containerArrayElem1234) + yym236 := z.EncBinary() + _ = yym236 + if false { + } else { + r.EncodeBool(bool(x.ExperimentalFlannelOverlay)) + } + } else { + z.EncSendContainerState(codecSelfer_containerMapKey1234) + r.EncodeString(codecSelferC_UTF81234, string("experimentalFlannelOverlay")) + z.EncSendContainerState(codecSelfer_containerMapValue1234) + yym237 := z.EncBinary() + _ = yym237 + if false { } else { r.EncodeBool(bool(x.ExperimentalFlannelOverlay)) } } if yyr2 || yy2arr2 { z.EncSendContainerState(codecSelfer_containerArrayElem1234) - if yyq2[72] { - yy236 := &x.OutOfDiskTransitionFrequency - yym237 := z.EncBinary() - _ = yym237 + if yyq2[73] { + yy239 := &x.OutOfDiskTransitionFrequency + yym240 := z.EncBinary() + _ = yym240 if false { - } else if z.HasExtensions() && z.EncExt(yy236) { - } else if !yym237 && z.IsJSONHandle() { - z.EncJSONMarshal(yy236) + } else if z.HasExtensions() && z.EncExt(yy239) { + } else if !yym240 && z.IsJSONHandle() { + z.EncJSONMarshal(yy239) } else { - z.EncFallback(yy236) + z.EncFallback(yy239) } } else { r.EncodeNil() } } else { - if yyq2[72] { + if yyq2[73] { z.EncSendContainerState(codecSelfer_containerMapKey1234) r.EncodeString(codecSelferC_UTF81234, string("outOfDiskTransitionFrequency")) z.EncSendContainerState(codecSelfer_containerMapValue1234) - yy238 := &x.OutOfDiskTransitionFrequency - yym239 := z.EncBinary() - _ = yym239 + yy241 := &x.OutOfDiskTransitionFrequency + yym242 := z.EncBinary() + _ = yym242 if false { - } else if z.HasExtensions() && z.EncExt(yy238) { - } else if !yym239 && z.IsJSONHandle() { - z.EncJSONMarshal(yy238) + } else if z.HasExtensions() && z.EncExt(yy241) { + } else if !yym242 && z.IsJSONHandle() { + z.EncJSONMarshal(yy241) } else { - z.EncFallback(yy238) + z.EncFallback(yy241) } } } if yyr2 || yy2arr2 { z.EncSendContainerState(codecSelfer_containerArrayElem1234) - if yyq2[73] { - yym241 := z.EncBinary() - _ = yym241 + if yyq2[74] { + yym244 := z.EncBinary() + _ = yym244 if false { } else { r.EncodeString(codecSelferC_UTF81234, string(x.NodeIP)) @@ -2686,12 +2705,12 @@ func (x *KubeletConfiguration) CodecEncodeSelf(e *codec1978.Encoder) { r.EncodeString(codecSelferC_UTF81234, "") } } else { - if yyq2[73] { + if yyq2[74] { z.EncSendContainerState(codecSelfer_containerMapKey1234) r.EncodeString(codecSelferC_UTF81234, string("nodeIP")) z.EncSendContainerState(codecSelfer_containerMapValue1234) - yym242 := z.EncBinary() - _ = yym242 + yym245 := z.EncBinary() + _ = yym245 if false { } else { r.EncodeString(codecSelferC_UTF81234, string(x.NodeIP)) @@ -2703,8 +2722,8 @@ func (x *KubeletConfiguration) CodecEncodeSelf(e *codec1978.Encoder) { if x.NodeLabels == nil { r.EncodeNil() } else { - yym244 := z.EncBinary() - _ = yym244 + yym247 := z.EncBinary() + _ = yym247 if false { } else { z.F.EncMapStringStringV(x.NodeLabels, false, e) @@ -2717,8 +2736,8 @@ func (x *KubeletConfiguration) CodecEncodeSelf(e *codec1978.Encoder) { if x.NodeLabels == nil { r.EncodeNil() } else { - yym245 := z.EncBinary() - _ = yym245 + yym248 := z.EncBinary() + _ = yym248 if false { } else { z.F.EncMapStringStringV(x.NodeLabels, false, e) @@ -2727,8 +2746,8 @@ func (x *KubeletConfiguration) CodecEncodeSelf(e *codec1978.Encoder) { } if yyr2 || yy2arr2 { z.EncSendContainerState(codecSelfer_containerArrayElem1234) - yym247 := z.EncBinary() - _ = yym247 + yym250 := z.EncBinary() + _ = yym250 if false { } else { r.EncodeString(codecSelferC_UTF81234, string(x.NonMasqueradeCIDR)) @@ -2737,8 +2756,8 @@ func (x *KubeletConfiguration) CodecEncodeSelf(e *codec1978.Encoder) { z.EncSendContainerState(codecSelfer_containerMapKey1234) r.EncodeString(codecSelferC_UTF81234, string("nonMasqueradeCIDR")) z.EncSendContainerState(codecSelfer_containerMapValue1234) - yym248 := z.EncBinary() - _ = yym248 + yym251 := z.EncBinary() + _ = yym251 if false { } else { r.EncodeString(codecSelferC_UTF81234, string(x.NonMasqueradeCIDR)) @@ -2746,8 +2765,8 @@ func (x *KubeletConfiguration) CodecEncodeSelf(e *codec1978.Encoder) { } if yyr2 || yy2arr2 { z.EncSendContainerState(codecSelfer_containerArrayElem1234) - yym250 := z.EncBinary() - _ = yym250 + yym253 := z.EncBinary() + _ = yym253 if false { } else { r.EncodeBool(bool(x.EnableCustomMetrics)) @@ -2756,8 +2775,8 @@ func (x *KubeletConfiguration) CodecEncodeSelf(e *codec1978.Encoder) { z.EncSendContainerState(codecSelfer_containerMapKey1234) r.EncodeString(codecSelferC_UTF81234, string("enableCustomMetrics")) z.EncSendContainerState(codecSelfer_containerMapValue1234) - yym251 := z.EncBinary() - _ = yym251 + yym254 := z.EncBinary() + _ = yym254 if false { } else { r.EncodeBool(bool(x.EnableCustomMetrics)) @@ -3250,6 +3269,12 @@ func (x *KubeletConfiguration) codecDecodeSelfFromMap(l int, d *codec1978.Decode } else { x.HairpinMode = string(r.DecodeString()) } + case "babysitDaemons": + if r.TryDecodeAsNil() { + x.BabysitDaemons = false + } else { + x.BabysitDaemons = bool(r.DecodeBool()) + } case "maxPods": if r.TryDecodeAsNil() { x.MaxPods = 0 @@ -3332,15 +3357,15 @@ func (x *KubeletConfiguration) codecDecodeSelfFromMap(l int, d *codec1978.Decode if r.TryDecodeAsNil() { x.OutOfDiskTransitionFrequency = pkg1_unversioned.Duration{} } else { - yyv84 := &x.OutOfDiskTransitionFrequency - yym85 := z.DecBinary() - _ = yym85 + yyv85 := &x.OutOfDiskTransitionFrequency + yym86 := z.DecBinary() + _ = yym86 if false { - } else if z.HasExtensions() && z.DecExt(yyv84) { - } else if !yym85 && z.IsJSONHandle() { - z.DecJSONUnmarshal(yyv84) + } else if z.HasExtensions() && z.DecExt(yyv85) { + } else if !yym86 && z.IsJSONHandle() { + z.DecJSONUnmarshal(yyv85) } else { - z.DecFallback(yyv84, false) + z.DecFallback(yyv85, false) } } case "nodeIP": @@ -3353,12 +3378,12 @@ func (x *KubeletConfiguration) codecDecodeSelfFromMap(l int, d *codec1978.Decode if r.TryDecodeAsNil() { x.NodeLabels = nil } else { - yyv87 := &x.NodeLabels - yym88 := z.DecBinary() - _ = yym88 + yyv88 := &x.NodeLabels + yym89 := z.DecBinary() + _ = yym89 if false { } else { - z.F.DecMapStringStringX(yyv87, false, d) + z.F.DecMapStringStringX(yyv88, false, d) } } case "nonMasqueradeCIDR": @@ -3384,16 +3409,16 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco var h codecSelfer1234 z, r := codec1978.GenHelperDecoder(d) _, _, _ = h, z, r - var yyj91 int - var yyb91 bool - var yyhl91 bool = l >= 0 - yyj91++ - if yyhl91 { - yyb91 = yyj91 > l + var yyj92 int + var yyb92 bool + var yyhl92 bool = l >= 0 + yyj92++ + if yyhl92 { + yyb92 = yyj92 > l } else { - yyb91 = r.CheckBreak() + yyb92 = r.CheckBreak() } - if yyb91 { + if yyb92 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -3403,13 +3428,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.Config = string(r.DecodeString()) } - yyj91++ - if yyhl91 { - yyb91 = yyj91 > l + yyj92++ + if yyhl92 { + yyb92 = yyj92 > l } else { - yyb91 = r.CheckBreak() + yyb92 = r.CheckBreak() } - if yyb91 { + if yyb92 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -3417,24 +3442,24 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco if r.TryDecodeAsNil() { x.SyncFrequency = pkg1_unversioned.Duration{} } else { - yyv93 := &x.SyncFrequency - yym94 := z.DecBinary() - _ = yym94 + yyv94 := &x.SyncFrequency + yym95 := z.DecBinary() + _ = yym95 if false { - } else if z.HasExtensions() && z.DecExt(yyv93) { - } else if !yym94 && z.IsJSONHandle() { - z.DecJSONUnmarshal(yyv93) + } else if z.HasExtensions() && z.DecExt(yyv94) { + } else if !yym95 && z.IsJSONHandle() { + z.DecJSONUnmarshal(yyv94) } else { - z.DecFallback(yyv93, false) + z.DecFallback(yyv94, false) } } - yyj91++ - if yyhl91 { - yyb91 = yyj91 > l + yyj92++ + if yyhl92 { + yyb92 = yyj92 > l } else { - yyb91 = r.CheckBreak() + yyb92 = r.CheckBreak() } - if yyb91 { + if yyb92 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -3442,24 +3467,24 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco if r.TryDecodeAsNil() { x.FileCheckFrequency = pkg1_unversioned.Duration{} } else { - yyv95 := &x.FileCheckFrequency - yym96 := z.DecBinary() - _ = yym96 + yyv96 := &x.FileCheckFrequency + yym97 := z.DecBinary() + _ = yym97 if false { - } else if z.HasExtensions() && z.DecExt(yyv95) { - } else if !yym96 && z.IsJSONHandle() { - z.DecJSONUnmarshal(yyv95) + } else if z.HasExtensions() && z.DecExt(yyv96) { + } else if !yym97 && z.IsJSONHandle() { + z.DecJSONUnmarshal(yyv96) } else { - z.DecFallback(yyv95, false) + z.DecFallback(yyv96, false) } } - yyj91++ - if yyhl91 { - yyb91 = yyj91 > l + yyj92++ + if yyhl92 { + yyb92 = yyj92 > l } else { - yyb91 = r.CheckBreak() + yyb92 = r.CheckBreak() } - if yyb91 { + if yyb92 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -3467,24 +3492,24 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco if r.TryDecodeAsNil() { x.HTTPCheckFrequency = pkg1_unversioned.Duration{} } else { - yyv97 := &x.HTTPCheckFrequency - yym98 := z.DecBinary() - _ = yym98 + yyv98 := &x.HTTPCheckFrequency + yym99 := z.DecBinary() + _ = yym99 if false { - } else if z.HasExtensions() && z.DecExt(yyv97) { - } else if !yym98 && z.IsJSONHandle() { - z.DecJSONUnmarshal(yyv97) + } else if z.HasExtensions() && z.DecExt(yyv98) { + } else if !yym99 && z.IsJSONHandle() { + z.DecJSONUnmarshal(yyv98) } else { - z.DecFallback(yyv97, false) + z.DecFallback(yyv98, false) } } - yyj91++ - if yyhl91 { - yyb91 = yyj91 > l + yyj92++ + if yyhl92 { + yyb92 = yyj92 > l } else { - yyb91 = r.CheckBreak() + yyb92 = r.CheckBreak() } - if yyb91 { + if yyb92 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -3494,13 +3519,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.ManifestURL = string(r.DecodeString()) } - yyj91++ - if yyhl91 { - yyb91 = yyj91 > l + yyj92++ + if yyhl92 { + yyb92 = yyj92 > l } else { - yyb91 = r.CheckBreak() + yyb92 = r.CheckBreak() } - if yyb91 { + if yyb92 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -3510,13 +3535,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.ManifestURLHeader = string(r.DecodeString()) } - yyj91++ - if yyhl91 { - yyb91 = yyj91 > l + yyj92++ + if yyhl92 { + yyb92 = yyj92 > l } else { - yyb91 = r.CheckBreak() + yyb92 = r.CheckBreak() } - if yyb91 { + if yyb92 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -3526,13 +3551,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.EnableServer = bool(r.DecodeBool()) } - yyj91++ - if yyhl91 { - yyb91 = yyj91 > l + yyj92++ + if yyhl92 { + yyb92 = yyj92 > l } else { - yyb91 = r.CheckBreak() + yyb92 = r.CheckBreak() } - if yyb91 { + if yyb92 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -3542,13 +3567,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.Address = string(r.DecodeString()) } - yyj91++ - if yyhl91 { - yyb91 = yyj91 > l + yyj92++ + if yyhl92 { + yyb92 = yyj92 > l } else { - yyb91 = r.CheckBreak() + yyb92 = r.CheckBreak() } - if yyb91 { + if yyb92 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -3558,13 +3583,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.Port = uint(r.DecodeUint(codecSelferBitsize1234)) } - yyj91++ - if yyhl91 { - yyb91 = yyj91 > l + yyj92++ + if yyhl92 { + yyb92 = yyj92 > l } else { - yyb91 = r.CheckBreak() + yyb92 = r.CheckBreak() } - if yyb91 { + if yyb92 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -3574,13 +3599,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.ReadOnlyPort = uint(r.DecodeUint(codecSelferBitsize1234)) } - yyj91++ - if yyhl91 { - yyb91 = yyj91 > l + yyj92++ + if yyhl92 { + yyb92 = yyj92 > l } else { - yyb91 = r.CheckBreak() + yyb92 = r.CheckBreak() } - if yyb91 { + if yyb92 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -3590,13 +3615,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.TLSCertFile = string(r.DecodeString()) } - yyj91++ - if yyhl91 { - yyb91 = yyj91 > l + yyj92++ + if yyhl92 { + yyb92 = yyj92 > l } else { - yyb91 = r.CheckBreak() + yyb92 = r.CheckBreak() } - if yyb91 { + if yyb92 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -3606,13 +3631,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.TLSPrivateKeyFile = string(r.DecodeString()) } - yyj91++ - if yyhl91 { - yyb91 = yyj91 > l + yyj92++ + if yyhl92 { + yyb92 = yyj92 > l } else { - yyb91 = r.CheckBreak() + yyb92 = r.CheckBreak() } - if yyb91 { + if yyb92 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -3622,13 +3647,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.CertDirectory = string(r.DecodeString()) } - yyj91++ - if yyhl91 { - yyb91 = yyj91 > l + yyj92++ + if yyhl92 { + yyb92 = yyj92 > l } else { - yyb91 = r.CheckBreak() + yyb92 = r.CheckBreak() } - if yyb91 { + if yyb92 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -3638,13 +3663,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.HostnameOverride = string(r.DecodeString()) } - yyj91++ - if yyhl91 { - yyb91 = yyj91 > l + yyj92++ + if yyhl92 { + yyb92 = yyj92 > l } else { - yyb91 = r.CheckBreak() + yyb92 = r.CheckBreak() } - if yyb91 { + if yyb92 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -3654,13 +3679,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.PodInfraContainerImage = string(r.DecodeString()) } - yyj91++ - if yyhl91 { - yyb91 = yyj91 > l + yyj92++ + if yyhl92 { + yyb92 = yyj92 > l } else { - yyb91 = r.CheckBreak() + yyb92 = r.CheckBreak() } - if yyb91 { + if yyb92 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -3670,13 +3695,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.DockerEndpoint = string(r.DecodeString()) } - yyj91++ - if yyhl91 { - yyb91 = yyj91 > l + yyj92++ + if yyhl92 { + yyb92 = yyj92 > l } else { - yyb91 = r.CheckBreak() + yyb92 = r.CheckBreak() } - if yyb91 { + if yyb92 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -3686,13 +3711,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.RootDirectory = string(r.DecodeString()) } - yyj91++ - if yyhl91 { - yyb91 = yyj91 > l + yyj92++ + if yyhl92 { + yyb92 = yyj92 > l } else { - yyb91 = r.CheckBreak() + yyb92 = r.CheckBreak() } - if yyb91 { + if yyb92 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -3702,13 +3727,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.AllowPrivileged = bool(r.DecodeBool()) } - yyj91++ - if yyhl91 { - yyb91 = yyj91 > l + yyj92++ + if yyhl92 { + yyb92 = yyj92 > l } else { - yyb91 = r.CheckBreak() + yyb92 = r.CheckBreak() } - if yyb91 { + if yyb92 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -3718,13 +3743,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.HostNetworkSources = string(r.DecodeString()) } - yyj91++ - if yyhl91 { - yyb91 = yyj91 > l + yyj92++ + if yyhl92 { + yyb92 = yyj92 > l } else { - yyb91 = r.CheckBreak() + yyb92 = r.CheckBreak() } - if yyb91 { + if yyb92 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -3734,13 +3759,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.HostPIDSources = string(r.DecodeString()) } - yyj91++ - if yyhl91 { - yyb91 = yyj91 > l + yyj92++ + if yyhl92 { + yyb92 = yyj92 > l } else { - yyb91 = r.CheckBreak() + yyb92 = r.CheckBreak() } - if yyb91 { + if yyb92 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -3750,13 +3775,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.HostIPCSources = string(r.DecodeString()) } - yyj91++ - if yyhl91 { - yyb91 = yyj91 > l + yyj92++ + if yyhl92 { + yyb92 = yyj92 > l } else { - yyb91 = r.CheckBreak() + yyb92 = r.CheckBreak() } - if yyb91 { + if yyb92 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -3766,13 +3791,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.RegistryPullQPS = float64(r.DecodeFloat(false)) } - yyj91++ - if yyhl91 { - yyb91 = yyj91 > l + yyj92++ + if yyhl92 { + yyb92 = yyj92 > l } else { - yyb91 = r.CheckBreak() + yyb92 = r.CheckBreak() } - if yyb91 { + if yyb92 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -3782,13 +3807,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.RegistryBurst = int(r.DecodeInt(codecSelferBitsize1234)) } - yyj91++ - if yyhl91 { - yyb91 = yyj91 > l + yyj92++ + if yyhl92 { + yyb92 = yyj92 > l } else { - yyb91 = r.CheckBreak() + yyb92 = r.CheckBreak() } - if yyb91 { + if yyb92 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -3798,13 +3823,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.EventRecordQPS = float32(r.DecodeFloat(true)) } - yyj91++ - if yyhl91 { - yyb91 = yyj91 > l + yyj92++ + if yyhl92 { + yyb92 = yyj92 > l } else { - yyb91 = r.CheckBreak() + yyb92 = r.CheckBreak() } - if yyb91 { + if yyb92 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -3814,13 +3839,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.EventBurst = int(r.DecodeInt(codecSelferBitsize1234)) } - yyj91++ - if yyhl91 { - yyb91 = yyj91 > l + yyj92++ + if yyhl92 { + yyb92 = yyj92 > l } else { - yyb91 = r.CheckBreak() + yyb92 = r.CheckBreak() } - if yyb91 { + if yyb92 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -3830,13 +3855,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.EnableDebuggingHandlers = bool(r.DecodeBool()) } - yyj91++ - if yyhl91 { - yyb91 = yyj91 > l + yyj92++ + if yyhl92 { + yyb92 = yyj92 > l } else { - yyb91 = r.CheckBreak() + yyb92 = r.CheckBreak() } - if yyb91 { + if yyb92 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -3844,24 +3869,24 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco if r.TryDecodeAsNil() { x.MinimumGCAge = pkg1_unversioned.Duration{} } else { - yyv121 := &x.MinimumGCAge - yym122 := z.DecBinary() - _ = yym122 + yyv122 := &x.MinimumGCAge + yym123 := z.DecBinary() + _ = yym123 if false { - } else if z.HasExtensions() && z.DecExt(yyv121) { - } else if !yym122 && z.IsJSONHandle() { - z.DecJSONUnmarshal(yyv121) + } else if z.HasExtensions() && z.DecExt(yyv122) { + } else if !yym123 && z.IsJSONHandle() { + z.DecJSONUnmarshal(yyv122) } else { - z.DecFallback(yyv121, false) + z.DecFallback(yyv122, false) } } - yyj91++ - if yyhl91 { - yyb91 = yyj91 > l + yyj92++ + if yyhl92 { + yyb92 = yyj92 > l } else { - yyb91 = r.CheckBreak() + yyb92 = r.CheckBreak() } - if yyb91 { + if yyb92 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -3871,13 +3896,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.MaxPerPodContainerCount = int(r.DecodeInt(codecSelferBitsize1234)) } - yyj91++ - if yyhl91 { - yyb91 = yyj91 > l + yyj92++ + if yyhl92 { + yyb92 = yyj92 > l } else { - yyb91 = r.CheckBreak() + yyb92 = r.CheckBreak() } - if yyb91 { + if yyb92 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -3887,13 +3912,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.MaxContainerCount = int(r.DecodeInt(codecSelferBitsize1234)) } - yyj91++ - if yyhl91 { - yyb91 = yyj91 > l + yyj92++ + if yyhl92 { + yyb92 = yyj92 > l } else { - yyb91 = r.CheckBreak() + yyb92 = r.CheckBreak() } - if yyb91 { + if yyb92 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -3903,13 +3928,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.CAdvisorPort = uint(r.DecodeUint(codecSelferBitsize1234)) } - yyj91++ - if yyhl91 { - yyb91 = yyj91 > l + yyj92++ + if yyhl92 { + yyb92 = yyj92 > l } else { - yyb91 = r.CheckBreak() + yyb92 = r.CheckBreak() } - if yyb91 { + if yyb92 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -3919,13 +3944,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.HealthzPort = int(r.DecodeInt(codecSelferBitsize1234)) } - yyj91++ - if yyhl91 { - yyb91 = yyj91 > l + yyj92++ + if yyhl92 { + yyb92 = yyj92 > l } else { - yyb91 = r.CheckBreak() + yyb92 = r.CheckBreak() } - if yyb91 { + if yyb92 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -3935,13 +3960,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.HealthzBindAddress = string(r.DecodeString()) } - yyj91++ - if yyhl91 { - yyb91 = yyj91 > l + yyj92++ + if yyhl92 { + yyb92 = yyj92 > l } else { - yyb91 = r.CheckBreak() + yyb92 = r.CheckBreak() } - if yyb91 { + if yyb92 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -3951,13 +3976,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.OOMScoreAdj = int(r.DecodeInt(codecSelferBitsize1234)) } - yyj91++ - if yyhl91 { - yyb91 = yyj91 > l + yyj92++ + if yyhl92 { + yyb92 = yyj92 > l } else { - yyb91 = r.CheckBreak() + yyb92 = r.CheckBreak() } - if yyb91 { + if yyb92 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -3967,13 +3992,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.RegisterNode = bool(r.DecodeBool()) } - yyj91++ - if yyhl91 { - yyb91 = yyj91 > l + yyj92++ + if yyhl92 { + yyb92 = yyj92 > l } else { - yyb91 = r.CheckBreak() + yyb92 = r.CheckBreak() } - if yyb91 { + if yyb92 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -3983,13 +4008,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.ClusterDomain = string(r.DecodeString()) } - yyj91++ - if yyhl91 { - yyb91 = yyj91 > l + yyj92++ + if yyhl92 { + yyb92 = yyj92 > l } else { - yyb91 = r.CheckBreak() + yyb92 = r.CheckBreak() } - if yyb91 { + if yyb92 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -3999,13 +4024,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.MasterServiceNamespace = string(r.DecodeString()) } - yyj91++ - if yyhl91 { - yyb91 = yyj91 > l + yyj92++ + if yyhl92 { + yyb92 = yyj92 > l } else { - yyb91 = r.CheckBreak() + yyb92 = r.CheckBreak() } - if yyb91 { + if yyb92 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -4015,13 +4040,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.ClusterDNS = string(r.DecodeString()) } - yyj91++ - if yyhl91 { - yyb91 = yyj91 > l + yyj92++ + if yyhl92 { + yyb92 = yyj92 > l } else { - yyb91 = r.CheckBreak() + yyb92 = r.CheckBreak() } - if yyb91 { + if yyb92 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -4029,24 +4054,24 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco if r.TryDecodeAsNil() { x.StreamingConnectionIdleTimeout = pkg1_unversioned.Duration{} } else { - yyv133 := &x.StreamingConnectionIdleTimeout - yym134 := z.DecBinary() - _ = yym134 + yyv134 := &x.StreamingConnectionIdleTimeout + yym135 := z.DecBinary() + _ = yym135 if false { - } else if z.HasExtensions() && z.DecExt(yyv133) { - } else if !yym134 && z.IsJSONHandle() { - z.DecJSONUnmarshal(yyv133) + } else if z.HasExtensions() && z.DecExt(yyv134) { + } else if !yym135 && z.IsJSONHandle() { + z.DecJSONUnmarshal(yyv134) } else { - z.DecFallback(yyv133, false) + z.DecFallback(yyv134, false) } } - yyj91++ - if yyhl91 { - yyb91 = yyj91 > l + yyj92++ + if yyhl92 { + yyb92 = yyj92 > l } else { - yyb91 = r.CheckBreak() + yyb92 = r.CheckBreak() } - if yyb91 { + if yyb92 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -4054,24 +4079,24 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco if r.TryDecodeAsNil() { x.NodeStatusUpdateFrequency = pkg1_unversioned.Duration{} } else { - yyv135 := &x.NodeStatusUpdateFrequency - yym136 := z.DecBinary() - _ = yym136 + yyv136 := &x.NodeStatusUpdateFrequency + yym137 := z.DecBinary() + _ = yym137 if false { - } else if z.HasExtensions() && z.DecExt(yyv135) { - } else if !yym136 && z.IsJSONHandle() { - z.DecJSONUnmarshal(yyv135) + } else if z.HasExtensions() && z.DecExt(yyv136) { + } else if !yym137 && z.IsJSONHandle() { + z.DecJSONUnmarshal(yyv136) } else { - z.DecFallback(yyv135, false) + z.DecFallback(yyv136, false) } } - yyj91++ - if yyhl91 { - yyb91 = yyj91 > l + yyj92++ + if yyhl92 { + yyb92 = yyj92 > l } else { - yyb91 = r.CheckBreak() + yyb92 = r.CheckBreak() } - if yyb91 { + if yyb92 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -4079,24 +4104,24 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco if r.TryDecodeAsNil() { x.ImageMinimumGCAge = pkg1_unversioned.Duration{} } else { - yyv137 := &x.ImageMinimumGCAge - yym138 := z.DecBinary() - _ = yym138 + yyv138 := &x.ImageMinimumGCAge + yym139 := z.DecBinary() + _ = yym139 if false { - } else if z.HasExtensions() && z.DecExt(yyv137) { - } else if !yym138 && z.IsJSONHandle() { - z.DecJSONUnmarshal(yyv137) + } else if z.HasExtensions() && z.DecExt(yyv138) { + } else if !yym139 && z.IsJSONHandle() { + z.DecJSONUnmarshal(yyv138) } else { - z.DecFallback(yyv137, false) + z.DecFallback(yyv138, false) } } - yyj91++ - if yyhl91 { - yyb91 = yyj91 > l + yyj92++ + if yyhl92 { + yyb92 = yyj92 > l } else { - yyb91 = r.CheckBreak() + yyb92 = r.CheckBreak() } - if yyb91 { + if yyb92 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -4106,13 +4131,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.ImageGCHighThresholdPercent = int(r.DecodeInt(codecSelferBitsize1234)) } - yyj91++ - if yyhl91 { - yyb91 = yyj91 > l + yyj92++ + if yyhl92 { + yyb92 = yyj92 > l } else { - yyb91 = r.CheckBreak() + yyb92 = r.CheckBreak() } - if yyb91 { + if yyb92 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -4122,13 +4147,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.ImageGCLowThresholdPercent = int(r.DecodeInt(codecSelferBitsize1234)) } - yyj91++ - if yyhl91 { - yyb91 = yyj91 > l + yyj92++ + if yyhl92 { + yyb92 = yyj92 > l } else { - yyb91 = r.CheckBreak() + yyb92 = r.CheckBreak() } - if yyb91 { + if yyb92 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -4138,13 +4163,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.LowDiskSpaceThresholdMB = int(r.DecodeInt(codecSelferBitsize1234)) } - yyj91++ - if yyhl91 { - yyb91 = yyj91 > l + yyj92++ + if yyhl92 { + yyb92 = yyj92 > l } else { - yyb91 = r.CheckBreak() + yyb92 = r.CheckBreak() } - if yyb91 { + if yyb92 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -4152,24 +4177,24 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco if r.TryDecodeAsNil() { x.VolumeStatsAggPeriod = pkg1_unversioned.Duration{} } else { - yyv142 := &x.VolumeStatsAggPeriod - yym143 := z.DecBinary() - _ = yym143 + yyv143 := &x.VolumeStatsAggPeriod + yym144 := z.DecBinary() + _ = yym144 if false { - } else if z.HasExtensions() && z.DecExt(yyv142) { - } else if !yym143 && z.IsJSONHandle() { - z.DecJSONUnmarshal(yyv142) + } else if z.HasExtensions() && z.DecExt(yyv143) { + } else if !yym144 && z.IsJSONHandle() { + z.DecJSONUnmarshal(yyv143) } else { - z.DecFallback(yyv142, false) + z.DecFallback(yyv143, false) } } - yyj91++ - if yyhl91 { - yyb91 = yyj91 > l + yyj92++ + if yyhl92 { + yyb92 = yyj92 > l } else { - yyb91 = r.CheckBreak() + yyb92 = r.CheckBreak() } - if yyb91 { + if yyb92 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -4179,13 +4204,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.NetworkPluginName = string(r.DecodeString()) } - yyj91++ - if yyhl91 { - yyb91 = yyj91 > l + yyj92++ + if yyhl92 { + yyb92 = yyj92 > l } else { - yyb91 = r.CheckBreak() + yyb92 = r.CheckBreak() } - if yyb91 { + if yyb92 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -4195,13 +4220,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.NetworkPluginDir = string(r.DecodeString()) } - yyj91++ - if yyhl91 { - yyb91 = yyj91 > l + yyj92++ + if yyhl92 { + yyb92 = yyj92 > l } else { - yyb91 = r.CheckBreak() + yyb92 = r.CheckBreak() } - if yyb91 { + if yyb92 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -4211,13 +4236,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.VolumePluginDir = string(r.DecodeString()) } - yyj91++ - if yyhl91 { - yyb91 = yyj91 > l + yyj92++ + if yyhl92 { + yyb92 = yyj92 > l } else { - yyb91 = r.CheckBreak() + yyb92 = r.CheckBreak() } - if yyb91 { + if yyb92 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -4227,13 +4252,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.CloudProvider = string(r.DecodeString()) } - yyj91++ - if yyhl91 { - yyb91 = yyj91 > l + yyj92++ + if yyhl92 { + yyb92 = yyj92 > l } else { - yyb91 = r.CheckBreak() + yyb92 = r.CheckBreak() } - if yyb91 { + if yyb92 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -4243,13 +4268,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.CloudConfigFile = string(r.DecodeString()) } - yyj91++ - if yyhl91 { - yyb91 = yyj91 > l + yyj92++ + if yyhl92 { + yyb92 = yyj92 > l } else { - yyb91 = r.CheckBreak() + yyb92 = r.CheckBreak() } - if yyb91 { + if yyb92 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -4259,13 +4284,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.KubeletCgroups = string(r.DecodeString()) } - yyj91++ - if yyhl91 { - yyb91 = yyj91 > l + yyj92++ + if yyhl92 { + yyb92 = yyj92 > l } else { - yyb91 = r.CheckBreak() + yyb92 = r.CheckBreak() } - if yyb91 { + if yyb92 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -4275,13 +4300,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.RuntimeCgroups = string(r.DecodeString()) } - yyj91++ - if yyhl91 { - yyb91 = yyj91 > l + yyj92++ + if yyhl92 { + yyb92 = yyj92 > l } else { - yyb91 = r.CheckBreak() + yyb92 = r.CheckBreak() } - if yyb91 { + if yyb92 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -4291,13 +4316,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.SystemCgroups = string(r.DecodeString()) } - yyj91++ - if yyhl91 { - yyb91 = yyj91 > l + yyj92++ + if yyhl92 { + yyb92 = yyj92 > l } else { - yyb91 = r.CheckBreak() + yyb92 = r.CheckBreak() } - if yyb91 { + if yyb92 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -4307,13 +4332,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.CgroupRoot = string(r.DecodeString()) } - yyj91++ - if yyhl91 { - yyb91 = yyj91 > l + yyj92++ + if yyhl92 { + yyb92 = yyj92 > l } else { - yyb91 = r.CheckBreak() + yyb92 = r.CheckBreak() } - if yyb91 { + if yyb92 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -4323,13 +4348,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.ContainerRuntime = string(r.DecodeString()) } - yyj91++ - if yyhl91 { - yyb91 = yyj91 > l + yyj92++ + if yyhl92 { + yyb92 = yyj92 > l } else { - yyb91 = r.CheckBreak() + yyb92 = r.CheckBreak() } - if yyb91 { + if yyb92 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -4339,13 +4364,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.RktPath = string(r.DecodeString()) } - yyj91++ - if yyhl91 { - yyb91 = yyj91 > l + yyj92++ + if yyhl92 { + yyb92 = yyj92 > l } else { - yyb91 = r.CheckBreak() + yyb92 = r.CheckBreak() } - if yyb91 { + if yyb92 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -4355,13 +4380,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.LockFilePath = string(r.DecodeString()) } - yyj91++ - if yyhl91 { - yyb91 = yyj91 > l + yyj92++ + if yyhl92 { + yyb92 = yyj92 > l } else { - yyb91 = r.CheckBreak() + yyb92 = r.CheckBreak() } - if yyb91 { + if yyb92 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -4371,13 +4396,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.RktStage1Image = string(r.DecodeString()) } - yyj91++ - if yyhl91 { - yyb91 = yyj91 > l + yyj92++ + if yyhl92 { + yyb92 = yyj92 > l } else { - yyb91 = r.CheckBreak() + yyb92 = r.CheckBreak() } - if yyb91 { + if yyb92 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -4387,13 +4412,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.ConfigureCBR0 = bool(r.DecodeBool()) } - yyj91++ - if yyhl91 { - yyb91 = yyj91 > l + yyj92++ + if yyhl92 { + yyb92 = yyj92 > l } else { - yyb91 = r.CheckBreak() + yyb92 = r.CheckBreak() } - if yyb91 { + if yyb92 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -4403,13 +4428,29 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.HairpinMode = string(r.DecodeString()) } - yyj91++ - if yyhl91 { - yyb91 = yyj91 > l + yyj92++ + if yyhl92 { + yyb92 = yyj92 > l + } else { + yyb92 = r.CheckBreak() + } + if yyb92 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) + return + } + z.DecSendContainerState(codecSelfer_containerArrayElem1234) + if r.TryDecodeAsNil() { + x.BabysitDaemons = false + } else { + x.BabysitDaemons = bool(r.DecodeBool()) + } + yyj92++ + if yyhl92 { + yyb92 = yyj92 > l } else { - yyb91 = r.CheckBreak() + yyb92 = r.CheckBreak() } - if yyb91 { + if yyb92 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -4419,13 +4460,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.MaxPods = int(r.DecodeInt(codecSelferBitsize1234)) } - yyj91++ - if yyhl91 { - yyb91 = yyj91 > l + yyj92++ + if yyhl92 { + yyb92 = yyj92 > l } else { - yyb91 = r.CheckBreak() + yyb92 = r.CheckBreak() } - if yyb91 { + if yyb92 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -4435,13 +4476,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.DockerExecHandlerName = string(r.DecodeString()) } - yyj91++ - if yyhl91 { - yyb91 = yyj91 > l + yyj92++ + if yyhl92 { + yyb92 = yyj92 > l } else { - yyb91 = r.CheckBreak() + yyb92 = r.CheckBreak() } - if yyb91 { + if yyb92 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -4451,13 +4492,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.PodCIDR = string(r.DecodeString()) } - yyj91++ - if yyhl91 { - yyb91 = yyj91 > l + yyj92++ + if yyhl92 { + yyb92 = yyj92 > l } else { - yyb91 = r.CheckBreak() + yyb92 = r.CheckBreak() } - if yyb91 { + if yyb92 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -4467,13 +4508,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.ResolverConfig = string(r.DecodeString()) } - yyj91++ - if yyhl91 { - yyb91 = yyj91 > l + yyj92++ + if yyhl92 { + yyb92 = yyj92 > l } else { - yyb91 = r.CheckBreak() + yyb92 = r.CheckBreak() } - if yyb91 { + if yyb92 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -4483,13 +4524,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.CPUCFSQuota = bool(r.DecodeBool()) } - yyj91++ - if yyhl91 { - yyb91 = yyj91 > l + yyj92++ + if yyhl92 { + yyb92 = yyj92 > l } else { - yyb91 = r.CheckBreak() + yyb92 = r.CheckBreak() } - if yyb91 { + if yyb92 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -4499,13 +4540,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.Containerized = bool(r.DecodeBool()) } - yyj91++ - if yyhl91 { - yyb91 = yyj91 > l + yyj92++ + if yyhl92 { + yyb92 = yyj92 > l } else { - yyb91 = r.CheckBreak() + yyb92 = r.CheckBreak() } - if yyb91 { + if yyb92 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -4515,13 +4556,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.MaxOpenFiles = uint64(r.DecodeUint(64)) } - yyj91++ - if yyhl91 { - yyb91 = yyj91 > l + yyj92++ + if yyhl92 { + yyb92 = yyj92 > l } else { - yyb91 = r.CheckBreak() + yyb92 = r.CheckBreak() } - if yyb91 { + if yyb92 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -4531,13 +4572,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.ReconcileCIDR = bool(r.DecodeBool()) } - yyj91++ - if yyhl91 { - yyb91 = yyj91 > l + yyj92++ + if yyhl92 { + yyb92 = yyj92 > l } else { - yyb91 = r.CheckBreak() + yyb92 = r.CheckBreak() } - if yyb91 { + if yyb92 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -4547,13 +4588,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.RegisterSchedulable = bool(r.DecodeBool()) } - yyj91++ - if yyhl91 { - yyb91 = yyj91 > l + yyj92++ + if yyhl92 { + yyb92 = yyj92 > l } else { - yyb91 = r.CheckBreak() + yyb92 = r.CheckBreak() } - if yyb91 { + if yyb92 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -4563,13 +4604,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.KubeAPIQPS = float32(r.DecodeFloat(true)) } - yyj91++ - if yyhl91 { - yyb91 = yyj91 > l + yyj92++ + if yyhl92 { + yyb92 = yyj92 > l } else { - yyb91 = r.CheckBreak() + yyb92 = r.CheckBreak() } - if yyb91 { + if yyb92 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -4579,13 +4620,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.KubeAPIBurst = int(r.DecodeInt(codecSelferBitsize1234)) } - yyj91++ - if yyhl91 { - yyb91 = yyj91 > l + yyj92++ + if yyhl92 { + yyb92 = yyj92 > l } else { - yyb91 = r.CheckBreak() + yyb92 = r.CheckBreak() } - if yyb91 { + if yyb92 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -4595,13 +4636,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.SerializeImagePulls = bool(r.DecodeBool()) } - yyj91++ - if yyhl91 { - yyb91 = yyj91 > l + yyj92++ + if yyhl92 { + yyb92 = yyj92 > l } else { - yyb91 = r.CheckBreak() + yyb92 = r.CheckBreak() } - if yyb91 { + if yyb92 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -4611,13 +4652,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.ExperimentalFlannelOverlay = bool(r.DecodeBool()) } - yyj91++ - if yyhl91 { - yyb91 = yyj91 > l + yyj92++ + if yyhl92 { + yyb92 = yyj92 > l } else { - yyb91 = r.CheckBreak() + yyb92 = r.CheckBreak() } - if yyb91 { + if yyb92 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -4625,24 +4666,24 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco if r.TryDecodeAsNil() { x.OutOfDiskTransitionFrequency = pkg1_unversioned.Duration{} } else { - yyv172 := &x.OutOfDiskTransitionFrequency - yym173 := z.DecBinary() - _ = yym173 + yyv174 := &x.OutOfDiskTransitionFrequency + yym175 := z.DecBinary() + _ = yym175 if false { - } else if z.HasExtensions() && z.DecExt(yyv172) { - } else if !yym173 && z.IsJSONHandle() { - z.DecJSONUnmarshal(yyv172) + } else if z.HasExtensions() && z.DecExt(yyv174) { + } else if !yym175 && z.IsJSONHandle() { + z.DecJSONUnmarshal(yyv174) } else { - z.DecFallback(yyv172, false) + z.DecFallback(yyv174, false) } } - yyj91++ - if yyhl91 { - yyb91 = yyj91 > l + yyj92++ + if yyhl92 { + yyb92 = yyj92 > l } else { - yyb91 = r.CheckBreak() + yyb92 = r.CheckBreak() } - if yyb91 { + if yyb92 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -4652,13 +4693,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.NodeIP = string(r.DecodeString()) } - yyj91++ - if yyhl91 { - yyb91 = yyj91 > l + yyj92++ + if yyhl92 { + yyb92 = yyj92 > l } else { - yyb91 = r.CheckBreak() + yyb92 = r.CheckBreak() } - if yyb91 { + if yyb92 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -4666,21 +4707,21 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco if r.TryDecodeAsNil() { x.NodeLabels = nil } else { - yyv175 := &x.NodeLabels - yym176 := z.DecBinary() - _ = yym176 + yyv177 := &x.NodeLabels + yym178 := z.DecBinary() + _ = yym178 if false { } else { - z.F.DecMapStringStringX(yyv175, false, d) + z.F.DecMapStringStringX(yyv177, false, d) } } - yyj91++ - if yyhl91 { - yyb91 = yyj91 > l + yyj92++ + if yyhl92 { + yyb92 = yyj92 > l } else { - yyb91 = r.CheckBreak() + yyb92 = r.CheckBreak() } - if yyb91 { + if yyb92 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -4690,13 +4731,13 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco } else { x.NonMasqueradeCIDR = string(r.DecodeString()) } - yyj91++ - if yyhl91 { - yyb91 = yyj91 > l + yyj92++ + if yyhl92 { + yyb92 = yyj92 > l } else { - yyb91 = r.CheckBreak() + yyb92 = r.CheckBreak() } - if yyb91 { + if yyb92 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -4707,17 +4748,17 @@ func (x *KubeletConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.Deco x.EnableCustomMetrics = bool(r.DecodeBool()) } for { - yyj91++ - if yyhl91 { - yyb91 = yyj91 > l + yyj92++ + if yyhl92 { + yyb92 = yyj92 > l } else { - yyb91 = r.CheckBreak() + yyb92 = r.CheckBreak() } - if yyb91 { + if yyb92 { break } z.DecSendContainerState(codecSelfer_containerArrayElem1234) - z.DecStructFieldNotFound(yyj91-1, "") + z.DecStructFieldNotFound(yyj92-1, "") } z.DecSendContainerState(codecSelfer_containerArrayEnd1234) } @@ -5679,16 +5720,16 @@ func (x *KubeControllerManagerConfiguration) CodecEncodeSelf(e *codec1978.Encode } else { yysep2 := !z.EncBinary() yy2arr2 := z.EncBasicHandle().StructToArray - var yyq2 [42]bool + var yyq2 [43]bool _, _, _ = yysep2, yyq2, yy2arr2 const yyr2 bool = false - yyq2[40] = x.Kind != "" - yyq2[41] = x.APIVersion != "" + yyq2[41] = x.Kind != "" + yyq2[42] = x.APIVersion != "" var yynn2 int if yyr2 || yy2arr2 { - r.EncodeArrayStart(42) + r.EncodeArrayStart(43) } else { - yynn2 = 40 + yynn2 = 41 for _, b := range yyq2 { if b { yynn2++ @@ -5965,34 +6006,40 @@ func (x *KubeControllerManagerConfiguration) CodecEncodeSelf(e *codec1978.Encode } if yyr2 || yy2arr2 { z.EncSendContainerState(codecSelfer_containerArrayElem1234) - yy46 := &x.ServiceSyncPeriod - yym47 := z.EncBinary() - _ = yym47 + yym46 := z.EncBinary() + _ = yym46 if false { - } else if z.HasExtensions() && z.EncExt(yy46) { - } else if !yym47 && z.IsJSONHandle() { - z.EncJSONMarshal(yy46) } else { - z.EncFallback(yy46) + r.EncodeInt(int64(x.LookupCacheSizeForDaemonSet)) } } else { z.EncSendContainerState(codecSelfer_containerMapKey1234) - r.EncodeString(codecSelferC_UTF81234, string("serviceSyncPeriod")) + r.EncodeString(codecSelferC_UTF81234, string("lookupCacheSizeForDaemonSet")) z.EncSendContainerState(codecSelfer_containerMapValue1234) - yy48 := &x.ServiceSyncPeriod - yym49 := z.EncBinary() - _ = yym49 + yym47 := z.EncBinary() + _ = yym47 if false { - } else if z.HasExtensions() && z.EncExt(yy48) { - } else if !yym49 && z.IsJSONHandle() { - z.EncJSONMarshal(yy48) } else { - z.EncFallback(yy48) + r.EncodeInt(int64(x.LookupCacheSizeForDaemonSet)) } } if yyr2 || yy2arr2 { z.EncSendContainerState(codecSelfer_containerArrayElem1234) - yy51 := &x.NodeSyncPeriod + yy49 := &x.ServiceSyncPeriod + yym50 := z.EncBinary() + _ = yym50 + if false { + } else if z.HasExtensions() && z.EncExt(yy49) { + } else if !yym50 && z.IsJSONHandle() { + z.EncJSONMarshal(yy49) + } else { + z.EncFallback(yy49) + } + } else { + z.EncSendContainerState(codecSelfer_containerMapKey1234) + r.EncodeString(codecSelferC_UTF81234, string("serviceSyncPeriod")) + z.EncSendContainerState(codecSelfer_containerMapValue1234) + yy51 := &x.ServiceSyncPeriod yym52 := z.EncBinary() _ = yym52 if false { @@ -6002,24 +6049,24 @@ func (x *KubeControllerManagerConfiguration) CodecEncodeSelf(e *codec1978.Encode } else { z.EncFallback(yy51) } + } + if yyr2 || yy2arr2 { + z.EncSendContainerState(codecSelfer_containerArrayElem1234) + yy54 := &x.NodeSyncPeriod + yym55 := z.EncBinary() + _ = yym55 + if false { + } else if z.HasExtensions() && z.EncExt(yy54) { + } else if !yym55 && z.IsJSONHandle() { + z.EncJSONMarshal(yy54) + } else { + z.EncFallback(yy54) + } } else { z.EncSendContainerState(codecSelfer_containerMapKey1234) r.EncodeString(codecSelferC_UTF81234, string("nodeSyncPeriod")) z.EncSendContainerState(codecSelfer_containerMapValue1234) - yy53 := &x.NodeSyncPeriod - yym54 := z.EncBinary() - _ = yym54 - if false { - } else if z.HasExtensions() && z.EncExt(yy53) { - } else if !yym54 && z.IsJSONHandle() { - z.EncJSONMarshal(yy53) - } else { - z.EncFallback(yy53) - } - } - if yyr2 || yy2arr2 { - z.EncSendContainerState(codecSelfer_containerArrayElem1234) - yy56 := &x.ResourceQuotaSyncPeriod + yy56 := &x.NodeSyncPeriod yym57 := z.EncBinary() _ = yym57 if false { @@ -6029,24 +6076,24 @@ func (x *KubeControllerManagerConfiguration) CodecEncodeSelf(e *codec1978.Encode } else { z.EncFallback(yy56) } + } + if yyr2 || yy2arr2 { + z.EncSendContainerState(codecSelfer_containerArrayElem1234) + yy59 := &x.ResourceQuotaSyncPeriod + yym60 := z.EncBinary() + _ = yym60 + if false { + } else if z.HasExtensions() && z.EncExt(yy59) { + } else if !yym60 && z.IsJSONHandle() { + z.EncJSONMarshal(yy59) + } else { + z.EncFallback(yy59) + } } else { z.EncSendContainerState(codecSelfer_containerMapKey1234) r.EncodeString(codecSelferC_UTF81234, string("resourceQuotaSyncPeriod")) z.EncSendContainerState(codecSelfer_containerMapValue1234) - yy58 := &x.ResourceQuotaSyncPeriod - yym59 := z.EncBinary() - _ = yym59 - if false { - } else if z.HasExtensions() && z.EncExt(yy58) { - } else if !yym59 && z.IsJSONHandle() { - z.EncJSONMarshal(yy58) - } else { - z.EncFallback(yy58) - } - } - if yyr2 || yy2arr2 { - z.EncSendContainerState(codecSelfer_containerArrayElem1234) - yy61 := &x.NamespaceSyncPeriod + yy61 := &x.ResourceQuotaSyncPeriod yym62 := z.EncBinary() _ = yym62 if false { @@ -6056,24 +6103,24 @@ func (x *KubeControllerManagerConfiguration) CodecEncodeSelf(e *codec1978.Encode } else { z.EncFallback(yy61) } + } + if yyr2 || yy2arr2 { + z.EncSendContainerState(codecSelfer_containerArrayElem1234) + yy64 := &x.NamespaceSyncPeriod + yym65 := z.EncBinary() + _ = yym65 + if false { + } else if z.HasExtensions() && z.EncExt(yy64) { + } else if !yym65 && z.IsJSONHandle() { + z.EncJSONMarshal(yy64) + } else { + z.EncFallback(yy64) + } } else { z.EncSendContainerState(codecSelfer_containerMapKey1234) r.EncodeString(codecSelferC_UTF81234, string("namespaceSyncPeriod")) z.EncSendContainerState(codecSelfer_containerMapValue1234) - yy63 := &x.NamespaceSyncPeriod - yym64 := z.EncBinary() - _ = yym64 - if false { - } else if z.HasExtensions() && z.EncExt(yy63) { - } else if !yym64 && z.IsJSONHandle() { - z.EncJSONMarshal(yy63) - } else { - z.EncFallback(yy63) - } - } - if yyr2 || yy2arr2 { - z.EncSendContainerState(codecSelfer_containerArrayElem1234) - yy66 := &x.PVClaimBinderSyncPeriod + yy66 := &x.NamespaceSyncPeriod yym67 := z.EncBinary() _ = yym67 if false { @@ -6083,24 +6130,24 @@ func (x *KubeControllerManagerConfiguration) CodecEncodeSelf(e *codec1978.Encode } else { z.EncFallback(yy66) } + } + if yyr2 || yy2arr2 { + z.EncSendContainerState(codecSelfer_containerArrayElem1234) + yy69 := &x.PVClaimBinderSyncPeriod + yym70 := z.EncBinary() + _ = yym70 + if false { + } else if z.HasExtensions() && z.EncExt(yy69) { + } else if !yym70 && z.IsJSONHandle() { + z.EncJSONMarshal(yy69) + } else { + z.EncFallback(yy69) + } } else { z.EncSendContainerState(codecSelfer_containerMapKey1234) r.EncodeString(codecSelferC_UTF81234, string("pvClaimBinderSyncPeriod")) z.EncSendContainerState(codecSelfer_containerMapValue1234) - yy68 := &x.PVClaimBinderSyncPeriod - yym69 := z.EncBinary() - _ = yym69 - if false { - } else if z.HasExtensions() && z.EncExt(yy68) { - } else if !yym69 && z.IsJSONHandle() { - z.EncJSONMarshal(yy68) - } else { - z.EncFallback(yy68) - } - } - if yyr2 || yy2arr2 { - z.EncSendContainerState(codecSelfer_containerArrayElem1234) - yy71 := &x.MinResyncPeriod + yy71 := &x.PVClaimBinderSyncPeriod yym72 := z.EncBinary() _ = yym72 if false { @@ -6110,25 +6157,38 @@ func (x *KubeControllerManagerConfiguration) CodecEncodeSelf(e *codec1978.Encode } else { z.EncFallback(yy71) } + } + if yyr2 || yy2arr2 { + z.EncSendContainerState(codecSelfer_containerArrayElem1234) + yy74 := &x.MinResyncPeriod + yym75 := z.EncBinary() + _ = yym75 + if false { + } else if z.HasExtensions() && z.EncExt(yy74) { + } else if !yym75 && z.IsJSONHandle() { + z.EncJSONMarshal(yy74) + } else { + z.EncFallback(yy74) + } } else { z.EncSendContainerState(codecSelfer_containerMapKey1234) r.EncodeString(codecSelferC_UTF81234, string("minResyncPeriod")) z.EncSendContainerState(codecSelfer_containerMapValue1234) - yy73 := &x.MinResyncPeriod - yym74 := z.EncBinary() - _ = yym74 + yy76 := &x.MinResyncPeriod + yym77 := z.EncBinary() + _ = yym77 if false { - } else if z.HasExtensions() && z.EncExt(yy73) { - } else if !yym74 && z.IsJSONHandle() { - z.EncJSONMarshal(yy73) + } else if z.HasExtensions() && z.EncExt(yy76) { + } else if !yym77 && z.IsJSONHandle() { + z.EncJSONMarshal(yy76) } else { - z.EncFallback(yy73) + z.EncFallback(yy76) } } if yyr2 || yy2arr2 { z.EncSendContainerState(codecSelfer_containerArrayElem1234) - yym76 := z.EncBinary() - _ = yym76 + yym79 := z.EncBinary() + _ = yym79 if false { } else { r.EncodeInt(int64(x.TerminatedPodGCThreshold)) @@ -6137,8 +6197,8 @@ func (x *KubeControllerManagerConfiguration) CodecEncodeSelf(e *codec1978.Encode z.EncSendContainerState(codecSelfer_containerMapKey1234) r.EncodeString(codecSelferC_UTF81234, string("terminatedPodGCThreshold")) z.EncSendContainerState(codecSelfer_containerMapValue1234) - yym77 := z.EncBinary() - _ = yym77 + yym80 := z.EncBinary() + _ = yym80 if false { } else { r.EncodeInt(int64(x.TerminatedPodGCThreshold)) @@ -6146,34 +6206,21 @@ func (x *KubeControllerManagerConfiguration) CodecEncodeSelf(e *codec1978.Encode } if yyr2 || yy2arr2 { z.EncSendContainerState(codecSelfer_containerArrayElem1234) - yy79 := &x.HorizontalPodAutoscalerSyncPeriod - yym80 := z.EncBinary() - _ = yym80 + yy82 := &x.HorizontalPodAutoscalerSyncPeriod + yym83 := z.EncBinary() + _ = yym83 if false { - } else if z.HasExtensions() && z.EncExt(yy79) { - } else if !yym80 && z.IsJSONHandle() { - z.EncJSONMarshal(yy79) + } else if z.HasExtensions() && z.EncExt(yy82) { + } else if !yym83 && z.IsJSONHandle() { + z.EncJSONMarshal(yy82) } else { - z.EncFallback(yy79) + z.EncFallback(yy82) } } else { z.EncSendContainerState(codecSelfer_containerMapKey1234) r.EncodeString(codecSelferC_UTF81234, string("horizontalPodAutoscalerSyncPeriod")) z.EncSendContainerState(codecSelfer_containerMapValue1234) - yy81 := &x.HorizontalPodAutoscalerSyncPeriod - yym82 := z.EncBinary() - _ = yym82 - if false { - } else if z.HasExtensions() && z.EncExt(yy81) { - } else if !yym82 && z.IsJSONHandle() { - z.EncJSONMarshal(yy81) - } else { - z.EncFallback(yy81) - } - } - if yyr2 || yy2arr2 { - z.EncSendContainerState(codecSelfer_containerArrayElem1234) - yy84 := &x.DeploymentControllerSyncPeriod + yy84 := &x.HorizontalPodAutoscalerSyncPeriod yym85 := z.EncBinary() _ = yym85 if false { @@ -6183,24 +6230,24 @@ func (x *KubeControllerManagerConfiguration) CodecEncodeSelf(e *codec1978.Encode } else { z.EncFallback(yy84) } - } else { - z.EncSendContainerState(codecSelfer_containerMapKey1234) - r.EncodeString(codecSelferC_UTF81234, string("deploymentControllerSyncPeriod")) - z.EncSendContainerState(codecSelfer_containerMapValue1234) - yy86 := &x.DeploymentControllerSyncPeriod - yym87 := z.EncBinary() - _ = yym87 - if false { - } else if z.HasExtensions() && z.EncExt(yy86) { - } else if !yym87 && z.IsJSONHandle() { - z.EncJSONMarshal(yy86) - } else { - z.EncFallback(yy86) - } } if yyr2 || yy2arr2 { z.EncSendContainerState(codecSelfer_containerArrayElem1234) - yy89 := &x.PodEvictionTimeout + yy87 := &x.DeploymentControllerSyncPeriod + yym88 := z.EncBinary() + _ = yym88 + if false { + } else if z.HasExtensions() && z.EncExt(yy87) { + } else if !yym88 && z.IsJSONHandle() { + z.EncJSONMarshal(yy87) + } else { + z.EncFallback(yy87) + } + } else { + z.EncSendContainerState(codecSelfer_containerMapKey1234) + r.EncodeString(codecSelferC_UTF81234, string("deploymentControllerSyncPeriod")) + z.EncSendContainerState(codecSelfer_containerMapValue1234) + yy89 := &x.DeploymentControllerSyncPeriod yym90 := z.EncBinary() _ = yym90 if false { @@ -6210,25 +6257,38 @@ func (x *KubeControllerManagerConfiguration) CodecEncodeSelf(e *codec1978.Encode } else { z.EncFallback(yy89) } + } + if yyr2 || yy2arr2 { + z.EncSendContainerState(codecSelfer_containerArrayElem1234) + yy92 := &x.PodEvictionTimeout + yym93 := z.EncBinary() + _ = yym93 + if false { + } else if z.HasExtensions() && z.EncExt(yy92) { + } else if !yym93 && z.IsJSONHandle() { + z.EncJSONMarshal(yy92) + } else { + z.EncFallback(yy92) + } } else { z.EncSendContainerState(codecSelfer_containerMapKey1234) r.EncodeString(codecSelferC_UTF81234, string("podEvictionTimeout")) z.EncSendContainerState(codecSelfer_containerMapValue1234) - yy91 := &x.PodEvictionTimeout - yym92 := z.EncBinary() - _ = yym92 + yy94 := &x.PodEvictionTimeout + yym95 := z.EncBinary() + _ = yym95 if false { - } else if z.HasExtensions() && z.EncExt(yy91) { - } else if !yym92 && z.IsJSONHandle() { - z.EncJSONMarshal(yy91) + } else if z.HasExtensions() && z.EncExt(yy94) { + } else if !yym95 && z.IsJSONHandle() { + z.EncJSONMarshal(yy94) } else { - z.EncFallback(yy91) + z.EncFallback(yy94) } } if yyr2 || yy2arr2 { z.EncSendContainerState(codecSelfer_containerArrayElem1234) - yym94 := z.EncBinary() - _ = yym94 + yym97 := z.EncBinary() + _ = yym97 if false { } else { r.EncodeFloat32(float32(x.DeletingPodsQps)) @@ -6237,8 +6297,8 @@ func (x *KubeControllerManagerConfiguration) CodecEncodeSelf(e *codec1978.Encode z.EncSendContainerState(codecSelfer_containerMapKey1234) r.EncodeString(codecSelferC_UTF81234, string("deletingPodsQps")) z.EncSendContainerState(codecSelfer_containerMapValue1234) - yym95 := z.EncBinary() - _ = yym95 + yym98 := z.EncBinary() + _ = yym98 if false { } else { r.EncodeFloat32(float32(x.DeletingPodsQps)) @@ -6246,8 +6306,8 @@ func (x *KubeControllerManagerConfiguration) CodecEncodeSelf(e *codec1978.Encode } if yyr2 || yy2arr2 { z.EncSendContainerState(codecSelfer_containerArrayElem1234) - yym97 := z.EncBinary() - _ = yym97 + yym100 := z.EncBinary() + _ = yym100 if false { } else { r.EncodeInt(int64(x.DeletingPodsBurst)) @@ -6256,8 +6316,8 @@ func (x *KubeControllerManagerConfiguration) CodecEncodeSelf(e *codec1978.Encode z.EncSendContainerState(codecSelfer_containerMapKey1234) r.EncodeString(codecSelferC_UTF81234, string("deletingPodsBurst")) z.EncSendContainerState(codecSelfer_containerMapValue1234) - yym98 := z.EncBinary() - _ = yym98 + yym101 := z.EncBinary() + _ = yym101 if false { } else { r.EncodeInt(int64(x.DeletingPodsBurst)) @@ -6265,35 +6325,35 @@ func (x *KubeControllerManagerConfiguration) CodecEncodeSelf(e *codec1978.Encode } if yyr2 || yy2arr2 { z.EncSendContainerState(codecSelfer_containerArrayElem1234) - yy100 := &x.NodeMonitorGracePeriod - yym101 := z.EncBinary() - _ = yym101 + yy103 := &x.NodeMonitorGracePeriod + yym104 := z.EncBinary() + _ = yym104 if false { - } else if z.HasExtensions() && z.EncExt(yy100) { - } else if !yym101 && z.IsJSONHandle() { - z.EncJSONMarshal(yy100) + } else if z.HasExtensions() && z.EncExt(yy103) { + } else if !yym104 && z.IsJSONHandle() { + z.EncJSONMarshal(yy103) } else { - z.EncFallback(yy100) + z.EncFallback(yy103) } } else { z.EncSendContainerState(codecSelfer_containerMapKey1234) r.EncodeString(codecSelferC_UTF81234, string("nodeMonitorGracePeriod")) z.EncSendContainerState(codecSelfer_containerMapValue1234) - yy102 := &x.NodeMonitorGracePeriod - yym103 := z.EncBinary() - _ = yym103 + yy105 := &x.NodeMonitorGracePeriod + yym106 := z.EncBinary() + _ = yym106 if false { - } else if z.HasExtensions() && z.EncExt(yy102) { - } else if !yym103 && z.IsJSONHandle() { - z.EncJSONMarshal(yy102) + } else if z.HasExtensions() && z.EncExt(yy105) { + } else if !yym106 && z.IsJSONHandle() { + z.EncJSONMarshal(yy105) } else { - z.EncFallback(yy102) + z.EncFallback(yy105) } } if yyr2 || yy2arr2 { z.EncSendContainerState(codecSelfer_containerArrayElem1234) - yym105 := z.EncBinary() - _ = yym105 + yym108 := z.EncBinary() + _ = yym108 if false { } else { r.EncodeInt(int64(x.RegisterRetryCount)) @@ -6302,8 +6362,8 @@ func (x *KubeControllerManagerConfiguration) CodecEncodeSelf(e *codec1978.Encode z.EncSendContainerState(codecSelfer_containerMapKey1234) r.EncodeString(codecSelferC_UTF81234, string("registerRetryCount")) z.EncSendContainerState(codecSelfer_containerMapValue1234) - yym106 := z.EncBinary() - _ = yym106 + yym109 := z.EncBinary() + _ = yym109 if false { } else { r.EncodeInt(int64(x.RegisterRetryCount)) @@ -6311,34 +6371,21 @@ func (x *KubeControllerManagerConfiguration) CodecEncodeSelf(e *codec1978.Encode } if yyr2 || yy2arr2 { z.EncSendContainerState(codecSelfer_containerArrayElem1234) - yy108 := &x.NodeStartupGracePeriod - yym109 := z.EncBinary() - _ = yym109 + yy111 := &x.NodeStartupGracePeriod + yym112 := z.EncBinary() + _ = yym112 if false { - } else if z.HasExtensions() && z.EncExt(yy108) { - } else if !yym109 && z.IsJSONHandle() { - z.EncJSONMarshal(yy108) + } else if z.HasExtensions() && z.EncExt(yy111) { + } else if !yym112 && z.IsJSONHandle() { + z.EncJSONMarshal(yy111) } else { - z.EncFallback(yy108) + z.EncFallback(yy111) } } else { z.EncSendContainerState(codecSelfer_containerMapKey1234) r.EncodeString(codecSelferC_UTF81234, string("nodeStartupGracePeriod")) z.EncSendContainerState(codecSelfer_containerMapValue1234) - yy110 := &x.NodeStartupGracePeriod - yym111 := z.EncBinary() - _ = yym111 - if false { - } else if z.HasExtensions() && z.EncExt(yy110) { - } else if !yym111 && z.IsJSONHandle() { - z.EncJSONMarshal(yy110) - } else { - z.EncFallback(yy110) - } - } - if yyr2 || yy2arr2 { - z.EncSendContainerState(codecSelfer_containerArrayElem1234) - yy113 := &x.NodeMonitorPeriod + yy113 := &x.NodeStartupGracePeriod yym114 := z.EncBinary() _ = yym114 if false { @@ -6348,38 +6395,32 @@ func (x *KubeControllerManagerConfiguration) CodecEncodeSelf(e *codec1978.Encode } else { z.EncFallback(yy113) } - } else { - z.EncSendContainerState(codecSelfer_containerMapKey1234) - r.EncodeString(codecSelferC_UTF81234, string("nodeMonitorPeriod")) - z.EncSendContainerState(codecSelfer_containerMapValue1234) - yy115 := &x.NodeMonitorPeriod - yym116 := z.EncBinary() - _ = yym116 - if false { - } else if z.HasExtensions() && z.EncExt(yy115) { - } else if !yym116 && z.IsJSONHandle() { - z.EncJSONMarshal(yy115) - } else { - z.EncFallback(yy115) - } } if yyr2 || yy2arr2 { z.EncSendContainerState(codecSelfer_containerArrayElem1234) - yym118 := z.EncBinary() - _ = yym118 + yy116 := &x.NodeMonitorPeriod + yym117 := z.EncBinary() + _ = yym117 if false { + } else if z.HasExtensions() && z.EncExt(yy116) { + } else if !yym117 && z.IsJSONHandle() { + z.EncJSONMarshal(yy116) } else { - r.EncodeString(codecSelferC_UTF81234, string(x.ServiceAccountKeyFile)) + z.EncFallback(yy116) } } else { z.EncSendContainerState(codecSelfer_containerMapKey1234) - r.EncodeString(codecSelferC_UTF81234, string("serviceAccountKeyFile")) + r.EncodeString(codecSelferC_UTF81234, string("nodeMonitorPeriod")) z.EncSendContainerState(codecSelfer_containerMapValue1234) + yy118 := &x.NodeMonitorPeriod yym119 := z.EncBinary() _ = yym119 if false { + } else if z.HasExtensions() && z.EncExt(yy118) { + } else if !yym119 && z.IsJSONHandle() { + z.EncJSONMarshal(yy118) } else { - r.EncodeString(codecSelferC_UTF81234, string(x.ServiceAccountKeyFile)) + z.EncFallback(yy118) } } if yyr2 || yy2arr2 { @@ -6388,17 +6429,17 @@ func (x *KubeControllerManagerConfiguration) CodecEncodeSelf(e *codec1978.Encode _ = yym121 if false { } else { - r.EncodeBool(bool(x.EnableProfiling)) + r.EncodeString(codecSelferC_UTF81234, string(x.ServiceAccountKeyFile)) } } else { z.EncSendContainerState(codecSelfer_containerMapKey1234) - r.EncodeString(codecSelferC_UTF81234, string("enableProfiling")) + r.EncodeString(codecSelferC_UTF81234, string("serviceAccountKeyFile")) z.EncSendContainerState(codecSelfer_containerMapValue1234) yym122 := z.EncBinary() _ = yym122 if false { } else { - r.EncodeBool(bool(x.EnableProfiling)) + r.EncodeString(codecSelferC_UTF81234, string(x.ServiceAccountKeyFile)) } } if yyr2 || yy2arr2 { @@ -6407,17 +6448,17 @@ func (x *KubeControllerManagerConfiguration) CodecEncodeSelf(e *codec1978.Encode _ = yym124 if false { } else { - r.EncodeString(codecSelferC_UTF81234, string(x.ClusterName)) + r.EncodeBool(bool(x.EnableProfiling)) } } else { z.EncSendContainerState(codecSelfer_containerMapKey1234) - r.EncodeString(codecSelferC_UTF81234, string("clusterName")) + r.EncodeString(codecSelferC_UTF81234, string("enableProfiling")) z.EncSendContainerState(codecSelfer_containerMapValue1234) yym125 := z.EncBinary() _ = yym125 if false { } else { - r.EncodeString(codecSelferC_UTF81234, string(x.ClusterName)) + r.EncodeBool(bool(x.EnableProfiling)) } } if yyr2 || yy2arr2 { @@ -6426,17 +6467,17 @@ func (x *KubeControllerManagerConfiguration) CodecEncodeSelf(e *codec1978.Encode _ = yym127 if false { } else { - r.EncodeString(codecSelferC_UTF81234, string(x.ClusterCIDR)) + r.EncodeString(codecSelferC_UTF81234, string(x.ClusterName)) } } else { z.EncSendContainerState(codecSelfer_containerMapKey1234) - r.EncodeString(codecSelferC_UTF81234, string("clusterCIDR")) + r.EncodeString(codecSelferC_UTF81234, string("clusterName")) z.EncSendContainerState(codecSelfer_containerMapValue1234) yym128 := z.EncBinary() _ = yym128 if false { } else { - r.EncodeString(codecSelferC_UTF81234, string(x.ClusterCIDR)) + r.EncodeString(codecSelferC_UTF81234, string(x.ClusterName)) } } if yyr2 || yy2arr2 { @@ -6445,17 +6486,17 @@ func (x *KubeControllerManagerConfiguration) CodecEncodeSelf(e *codec1978.Encode _ = yym130 if false { } else { - r.EncodeBool(bool(x.AllocateNodeCIDRs)) + r.EncodeString(codecSelferC_UTF81234, string(x.ClusterCIDR)) } } else { z.EncSendContainerState(codecSelfer_containerMapKey1234) - r.EncodeString(codecSelferC_UTF81234, string("allocateNodeCIDRs")) + r.EncodeString(codecSelferC_UTF81234, string("clusterCIDR")) z.EncSendContainerState(codecSelfer_containerMapValue1234) yym131 := z.EncBinary() _ = yym131 if false { } else { - r.EncodeBool(bool(x.AllocateNodeCIDRs)) + r.EncodeString(codecSelferC_UTF81234, string(x.ClusterCIDR)) } } if yyr2 || yy2arr2 { @@ -6464,17 +6505,17 @@ func (x *KubeControllerManagerConfiguration) CodecEncodeSelf(e *codec1978.Encode _ = yym133 if false { } else { - r.EncodeString(codecSelferC_UTF81234, string(x.RootCAFile)) + r.EncodeBool(bool(x.AllocateNodeCIDRs)) } } else { z.EncSendContainerState(codecSelfer_containerMapKey1234) - r.EncodeString(codecSelferC_UTF81234, string("rootCAFile")) + r.EncodeString(codecSelferC_UTF81234, string("allocateNodeCIDRs")) z.EncSendContainerState(codecSelfer_containerMapValue1234) yym134 := z.EncBinary() _ = yym134 if false { } else { - r.EncodeString(codecSelferC_UTF81234, string(x.RootCAFile)) + r.EncodeBool(bool(x.AllocateNodeCIDRs)) } } if yyr2 || yy2arr2 { @@ -6483,17 +6524,17 @@ func (x *KubeControllerManagerConfiguration) CodecEncodeSelf(e *codec1978.Encode _ = yym136 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) yym137 := z.EncBinary() _ = yym137 if false { } else { - r.EncodeFloat32(float32(x.KubeAPIQPS)) + r.EncodeString(codecSelferC_UTF81234, string(x.RootCAFile)) } } if yyr2 || yy2arr2 { @@ -6502,46 +6543,65 @@ func (x *KubeControllerManagerConfiguration) CodecEncodeSelf(e *codec1978.Encode _ = yym139 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) yym140 := z.EncBinary() _ = yym140 if false { + } else { + r.EncodeFloat32(float32(x.KubeAPIQPS)) + } + } + if yyr2 || yy2arr2 { + z.EncSendContainerState(codecSelfer_containerArrayElem1234) + yym142 := z.EncBinary() + _ = yym142 + if false { + } else { + r.EncodeInt(int64(x.KubeAPIBurst)) + } + } else { + z.EncSendContainerState(codecSelfer_containerMapKey1234) + r.EncodeString(codecSelferC_UTF81234, string("kubeAPIBurst")) + z.EncSendContainerState(codecSelfer_containerMapValue1234) + yym143 := z.EncBinary() + _ = yym143 + if false { } else { r.EncodeInt(int64(x.KubeAPIBurst)) } } if yyr2 || yy2arr2 { z.EncSendContainerState(codecSelfer_containerArrayElem1234) - yy142 := &x.LeaderElection - yy142.CodecEncodeSelf(e) + yy145 := &x.LeaderElection + yy145.CodecEncodeSelf(e) } else { z.EncSendContainerState(codecSelfer_containerMapKey1234) r.EncodeString(codecSelferC_UTF81234, string("leaderElection")) z.EncSendContainerState(codecSelfer_containerMapValue1234) - yy144 := &x.LeaderElection - yy144.CodecEncodeSelf(e) + yy147 := &x.LeaderElection + yy147.CodecEncodeSelf(e) } if yyr2 || yy2arr2 { z.EncSendContainerState(codecSelfer_containerArrayElem1234) - yy147 := &x.VolumeConfiguration - yy147.CodecEncodeSelf(e) + yy150 := &x.VolumeConfiguration + yy150.CodecEncodeSelf(e) } else { z.EncSendContainerState(codecSelfer_containerMapKey1234) r.EncodeString(codecSelferC_UTF81234, string("volumeConfiguration")) z.EncSendContainerState(codecSelfer_containerMapValue1234) - yy149 := &x.VolumeConfiguration - yy149.CodecEncodeSelf(e) + yy152 := &x.VolumeConfiguration + yy152.CodecEncodeSelf(e) } if yyr2 || yy2arr2 { z.EncSendContainerState(codecSelfer_containerArrayElem1234) - if yyq2[40] { - yym152 := z.EncBinary() - _ = yym152 + if yyq2[41] { + yym155 := z.EncBinary() + _ = yym155 if false { } else { r.EncodeString(codecSelferC_UTF81234, string(x.Kind)) @@ -6550,12 +6610,12 @@ func (x *KubeControllerManagerConfiguration) CodecEncodeSelf(e *codec1978.Encode r.EncodeString(codecSelferC_UTF81234, "") } } else { - if yyq2[40] { + if yyq2[41] { z.EncSendContainerState(codecSelfer_containerMapKey1234) r.EncodeString(codecSelferC_UTF81234, string("kind")) z.EncSendContainerState(codecSelfer_containerMapValue1234) - yym153 := z.EncBinary() - _ = yym153 + yym156 := z.EncBinary() + _ = yym156 if false { } else { r.EncodeString(codecSelferC_UTF81234, string(x.Kind)) @@ -6564,9 +6624,9 @@ func (x *KubeControllerManagerConfiguration) CodecEncodeSelf(e *codec1978.Encode } if yyr2 || yy2arr2 { z.EncSendContainerState(codecSelfer_containerArrayElem1234) - if yyq2[41] { - yym155 := z.EncBinary() - _ = yym155 + if yyq2[42] { + yym158 := z.EncBinary() + _ = yym158 if false { } else { r.EncodeString(codecSelferC_UTF81234, string(x.APIVersion)) @@ -6575,12 +6635,12 @@ func (x *KubeControllerManagerConfiguration) CodecEncodeSelf(e *codec1978.Encode r.EncodeString(codecSelferC_UTF81234, "") } } else { - if yyq2[41] { + if yyq2[42] { z.EncSendContainerState(codecSelfer_containerMapKey1234) r.EncodeString(codecSelferC_UTF81234, string("apiVersion")) z.EncSendContainerState(codecSelfer_containerMapValue1234) - yym156 := z.EncBinary() - _ = yym156 + yym159 := z.EncBinary() + _ = yym159 if false { } else { r.EncodeString(codecSelferC_UTF81234, string(x.APIVersion)) @@ -6732,94 +6792,100 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromMap(l int, d *co } else { x.LookupCacheSizeForRS = int(r.DecodeInt(codecSelferBitsize1234)) } + case "lookupCacheSizeForDaemonSet": + if r.TryDecodeAsNil() { + x.LookupCacheSizeForDaemonSet = 0 + } else { + x.LookupCacheSizeForDaemonSet = int(r.DecodeInt(codecSelferBitsize1234)) + } case "serviceSyncPeriod": if r.TryDecodeAsNil() { x.ServiceSyncPeriod = pkg1_unversioned.Duration{} } else { - yyv18 := &x.ServiceSyncPeriod - yym19 := z.DecBinary() - _ = yym19 + yyv19 := &x.ServiceSyncPeriod + yym20 := z.DecBinary() + _ = yym20 if false { - } else if z.HasExtensions() && z.DecExt(yyv18) { - } else if !yym19 && z.IsJSONHandle() { - z.DecJSONUnmarshal(yyv18) + } else if z.HasExtensions() && z.DecExt(yyv19) { + } else if !yym20 && z.IsJSONHandle() { + z.DecJSONUnmarshal(yyv19) } else { - z.DecFallback(yyv18, false) + z.DecFallback(yyv19, false) } } case "nodeSyncPeriod": if r.TryDecodeAsNil() { x.NodeSyncPeriod = pkg1_unversioned.Duration{} } else { - yyv20 := &x.NodeSyncPeriod - yym21 := z.DecBinary() - _ = yym21 + yyv21 := &x.NodeSyncPeriod + yym22 := z.DecBinary() + _ = yym22 if false { - } else if z.HasExtensions() && z.DecExt(yyv20) { - } else if !yym21 && z.IsJSONHandle() { - z.DecJSONUnmarshal(yyv20) + } else if z.HasExtensions() && z.DecExt(yyv21) { + } else if !yym22 && z.IsJSONHandle() { + z.DecJSONUnmarshal(yyv21) } else { - z.DecFallback(yyv20, false) + z.DecFallback(yyv21, false) } } case "resourceQuotaSyncPeriod": if r.TryDecodeAsNil() { x.ResourceQuotaSyncPeriod = pkg1_unversioned.Duration{} } else { - yyv22 := &x.ResourceQuotaSyncPeriod - yym23 := z.DecBinary() - _ = yym23 + yyv23 := &x.ResourceQuotaSyncPeriod + yym24 := z.DecBinary() + _ = yym24 if false { - } else if z.HasExtensions() && z.DecExt(yyv22) { - } else if !yym23 && z.IsJSONHandle() { - z.DecJSONUnmarshal(yyv22) + } else if z.HasExtensions() && z.DecExt(yyv23) { + } else if !yym24 && z.IsJSONHandle() { + z.DecJSONUnmarshal(yyv23) } else { - z.DecFallback(yyv22, false) + z.DecFallback(yyv23, false) } } case "namespaceSyncPeriod": if r.TryDecodeAsNil() { x.NamespaceSyncPeriod = pkg1_unversioned.Duration{} } else { - yyv24 := &x.NamespaceSyncPeriod - yym25 := z.DecBinary() - _ = yym25 + yyv25 := &x.NamespaceSyncPeriod + yym26 := z.DecBinary() + _ = yym26 if false { - } else if z.HasExtensions() && z.DecExt(yyv24) { - } else if !yym25 && z.IsJSONHandle() { - z.DecJSONUnmarshal(yyv24) + } else if z.HasExtensions() && z.DecExt(yyv25) { + } else if !yym26 && z.IsJSONHandle() { + z.DecJSONUnmarshal(yyv25) } else { - z.DecFallback(yyv24, false) + z.DecFallback(yyv25, false) } } case "pvClaimBinderSyncPeriod": if r.TryDecodeAsNil() { x.PVClaimBinderSyncPeriod = pkg1_unversioned.Duration{} } else { - yyv26 := &x.PVClaimBinderSyncPeriod - yym27 := z.DecBinary() - _ = yym27 + yyv27 := &x.PVClaimBinderSyncPeriod + yym28 := z.DecBinary() + _ = yym28 if false { - } else if z.HasExtensions() && z.DecExt(yyv26) { - } else if !yym27 && z.IsJSONHandle() { - z.DecJSONUnmarshal(yyv26) + } else if z.HasExtensions() && z.DecExt(yyv27) { + } else if !yym28 && z.IsJSONHandle() { + z.DecJSONUnmarshal(yyv27) } else { - z.DecFallback(yyv26, false) + z.DecFallback(yyv27, false) } } case "minResyncPeriod": if r.TryDecodeAsNil() { x.MinResyncPeriod = pkg1_unversioned.Duration{} } else { - yyv28 := &x.MinResyncPeriod - yym29 := z.DecBinary() - _ = yym29 + yyv29 := &x.MinResyncPeriod + yym30 := z.DecBinary() + _ = yym30 if false { - } else if z.HasExtensions() && z.DecExt(yyv28) { - } else if !yym29 && z.IsJSONHandle() { - z.DecJSONUnmarshal(yyv28) + } else if z.HasExtensions() && z.DecExt(yyv29) { + } else if !yym30 && z.IsJSONHandle() { + z.DecJSONUnmarshal(yyv29) } else { - z.DecFallback(yyv28, false) + z.DecFallback(yyv29, false) } } case "terminatedPodGCThreshold": @@ -6832,45 +6898,45 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromMap(l int, d *co if r.TryDecodeAsNil() { x.HorizontalPodAutoscalerSyncPeriod = pkg1_unversioned.Duration{} } else { - yyv31 := &x.HorizontalPodAutoscalerSyncPeriod - yym32 := z.DecBinary() - _ = yym32 + yyv32 := &x.HorizontalPodAutoscalerSyncPeriod + yym33 := z.DecBinary() + _ = yym33 if false { - } else if z.HasExtensions() && z.DecExt(yyv31) { - } else if !yym32 && z.IsJSONHandle() { - z.DecJSONUnmarshal(yyv31) + } else if z.HasExtensions() && z.DecExt(yyv32) { + } else if !yym33 && z.IsJSONHandle() { + z.DecJSONUnmarshal(yyv32) } else { - z.DecFallback(yyv31, false) + z.DecFallback(yyv32, false) } } case "deploymentControllerSyncPeriod": if r.TryDecodeAsNil() { x.DeploymentControllerSyncPeriod = pkg1_unversioned.Duration{} } else { - yyv33 := &x.DeploymentControllerSyncPeriod - yym34 := z.DecBinary() - _ = yym34 + yyv34 := &x.DeploymentControllerSyncPeriod + yym35 := z.DecBinary() + _ = yym35 if false { - } else if z.HasExtensions() && z.DecExt(yyv33) { - } else if !yym34 && z.IsJSONHandle() { - z.DecJSONUnmarshal(yyv33) + } else if z.HasExtensions() && z.DecExt(yyv34) { + } else if !yym35 && z.IsJSONHandle() { + z.DecJSONUnmarshal(yyv34) } else { - z.DecFallback(yyv33, false) + z.DecFallback(yyv34, false) } } case "podEvictionTimeout": if r.TryDecodeAsNil() { x.PodEvictionTimeout = pkg1_unversioned.Duration{} } else { - yyv35 := &x.PodEvictionTimeout - yym36 := z.DecBinary() - _ = yym36 + yyv36 := &x.PodEvictionTimeout + yym37 := z.DecBinary() + _ = yym37 if false { - } else if z.HasExtensions() && z.DecExt(yyv35) { - } else if !yym36 && z.IsJSONHandle() { - z.DecJSONUnmarshal(yyv35) + } else if z.HasExtensions() && z.DecExt(yyv36) { + } else if !yym37 && z.IsJSONHandle() { + z.DecJSONUnmarshal(yyv36) } else { - z.DecFallback(yyv35, false) + z.DecFallback(yyv36, false) } } case "deletingPodsQps": @@ -6889,15 +6955,15 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromMap(l int, d *co if r.TryDecodeAsNil() { x.NodeMonitorGracePeriod = pkg1_unversioned.Duration{} } else { - yyv39 := &x.NodeMonitorGracePeriod - yym40 := z.DecBinary() - _ = yym40 + yyv40 := &x.NodeMonitorGracePeriod + yym41 := z.DecBinary() + _ = yym41 if false { - } else if z.HasExtensions() && z.DecExt(yyv39) { - } else if !yym40 && z.IsJSONHandle() { - z.DecJSONUnmarshal(yyv39) + } else if z.HasExtensions() && z.DecExt(yyv40) { + } else if !yym41 && z.IsJSONHandle() { + z.DecJSONUnmarshal(yyv40) } else { - z.DecFallback(yyv39, false) + z.DecFallback(yyv40, false) } } case "registerRetryCount": @@ -6910,30 +6976,30 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromMap(l int, d *co if r.TryDecodeAsNil() { x.NodeStartupGracePeriod = pkg1_unversioned.Duration{} } else { - yyv42 := &x.NodeStartupGracePeriod - yym43 := z.DecBinary() - _ = yym43 + yyv43 := &x.NodeStartupGracePeriod + yym44 := z.DecBinary() + _ = yym44 if false { - } else if z.HasExtensions() && z.DecExt(yyv42) { - } else if !yym43 && z.IsJSONHandle() { - z.DecJSONUnmarshal(yyv42) + } else if z.HasExtensions() && z.DecExt(yyv43) { + } else if !yym44 && z.IsJSONHandle() { + z.DecJSONUnmarshal(yyv43) } else { - z.DecFallback(yyv42, false) + z.DecFallback(yyv43, false) } } case "nodeMonitorPeriod": if r.TryDecodeAsNil() { x.NodeMonitorPeriod = pkg1_unversioned.Duration{} } else { - yyv44 := &x.NodeMonitorPeriod - yym45 := z.DecBinary() - _ = yym45 + yyv45 := &x.NodeMonitorPeriod + yym46 := z.DecBinary() + _ = yym46 if false { - } else if z.HasExtensions() && z.DecExt(yyv44) { - } else if !yym45 && z.IsJSONHandle() { - z.DecJSONUnmarshal(yyv44) + } else if z.HasExtensions() && z.DecExt(yyv45) { + } else if !yym46 && z.IsJSONHandle() { + z.DecJSONUnmarshal(yyv45) } else { - z.DecFallback(yyv44, false) + z.DecFallback(yyv45, false) } } case "serviceAccountKeyFile": @@ -6988,15 +7054,15 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromMap(l int, d *co if r.TryDecodeAsNil() { x.LeaderElection = LeaderElectionConfiguration{} } else { - yyv54 := &x.LeaderElection - yyv54.CodecDecodeSelf(d) + yyv55 := &x.LeaderElection + yyv55.CodecDecodeSelf(d) } case "volumeConfiguration": if r.TryDecodeAsNil() { x.VolumeConfiguration = VolumeConfiguration{} } else { - yyv55 := &x.VolumeConfiguration - yyv55.CodecDecodeSelf(d) + yyv56 := &x.VolumeConfiguration + yyv56.CodecDecodeSelf(d) } case "kind": if r.TryDecodeAsNil() { @@ -7021,16 +7087,16 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromArray(l int, d * var h codecSelfer1234 z, r := codec1978.GenHelperDecoder(d) _, _, _ = h, z, r - var yyj58 int - var yyb58 bool - var yyhl58 bool = l >= 0 - yyj58++ - if yyhl58 { - yyb58 = yyj58 > l + var yyj59 int + var yyb59 bool + var yyhl59 bool = l >= 0 + yyj59++ + if yyhl59 { + yyb59 = yyj59 > l } else { - yyb58 = r.CheckBreak() + yyb59 = r.CheckBreak() } - if yyb58 { + if yyb59 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -7040,13 +7106,13 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromArray(l int, d * } else { x.Port = int(r.DecodeInt(codecSelferBitsize1234)) } - yyj58++ - if yyhl58 { - yyb58 = yyj58 > l + yyj59++ + if yyhl59 { + yyb59 = yyj59 > l } else { - yyb58 = r.CheckBreak() + yyb59 = r.CheckBreak() } - if yyb58 { + if yyb59 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -7056,13 +7122,13 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromArray(l int, d * } else { x.Address = string(r.DecodeString()) } - yyj58++ - if yyhl58 { - yyb58 = yyj58 > l + yyj59++ + if yyhl59 { + yyb59 = yyj59 > l } else { - yyb58 = r.CheckBreak() + yyb59 = r.CheckBreak() } - if yyb58 { + if yyb59 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -7072,13 +7138,13 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromArray(l int, d * } else { x.CloudProvider = string(r.DecodeString()) } - yyj58++ - if yyhl58 { - yyb58 = yyj58 > l + yyj59++ + if yyhl59 { + yyb59 = yyj59 > l } else { - yyb58 = r.CheckBreak() + yyb59 = r.CheckBreak() } - if yyb58 { + if yyb59 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -7088,13 +7154,13 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromArray(l int, d * } else { x.CloudConfigFile = string(r.DecodeString()) } - yyj58++ - if yyhl58 { - yyb58 = yyj58 > l + yyj59++ + if yyhl59 { + yyb59 = yyj59 > l } else { - yyb58 = r.CheckBreak() + yyb59 = r.CheckBreak() } - if yyb58 { + if yyb59 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -7104,13 +7170,13 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromArray(l int, d * } else { x.ConcurrentEndpointSyncs = int(r.DecodeInt(codecSelferBitsize1234)) } - yyj58++ - if yyhl58 { - yyb58 = yyj58 > l + yyj59++ + if yyhl59 { + yyb59 = yyj59 > l } else { - yyb58 = r.CheckBreak() + yyb59 = r.CheckBreak() } - if yyb58 { + if yyb59 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -7120,13 +7186,13 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromArray(l int, d * } else { x.ConcurrentRSSyncs = int(r.DecodeInt(codecSelferBitsize1234)) } - yyj58++ - if yyhl58 { - yyb58 = yyj58 > l + yyj59++ + if yyhl59 { + yyb59 = yyj59 > l } else { - yyb58 = r.CheckBreak() + yyb59 = r.CheckBreak() } - if yyb58 { + if yyb59 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -7136,13 +7202,13 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromArray(l int, d * } else { x.ConcurrentRCSyncs = int(r.DecodeInt(codecSelferBitsize1234)) } - yyj58++ - if yyhl58 { - yyb58 = yyj58 > l + yyj59++ + if yyhl59 { + yyb59 = yyj59 > l } else { - yyb58 = r.CheckBreak() + yyb59 = r.CheckBreak() } - if yyb58 { + if yyb59 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -7152,13 +7218,13 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromArray(l int, d * } else { x.ConcurrentResourceQuotaSyncs = int(r.DecodeInt(codecSelferBitsize1234)) } - yyj58++ - if yyhl58 { - yyb58 = yyj58 > l + yyj59++ + if yyhl59 { + yyb59 = yyj59 > l } else { - yyb58 = r.CheckBreak() + yyb59 = r.CheckBreak() } - if yyb58 { + if yyb59 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -7168,13 +7234,13 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromArray(l int, d * } else { x.ConcurrentDeploymentSyncs = int(r.DecodeInt(codecSelferBitsize1234)) } - yyj58++ - if yyhl58 { - yyb58 = yyj58 > l + yyj59++ + if yyhl59 { + yyb59 = yyj59 > l } else { - yyb58 = r.CheckBreak() + yyb59 = r.CheckBreak() } - if yyb58 { + if yyb59 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -7184,13 +7250,13 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromArray(l int, d * } else { x.ConcurrentDaemonSetSyncs = int(r.DecodeInt(codecSelferBitsize1234)) } - yyj58++ - if yyhl58 { - yyb58 = yyj58 > l + yyj59++ + if yyhl59 { + yyb59 = yyj59 > l } else { - yyb58 = r.CheckBreak() + yyb59 = r.CheckBreak() } - if yyb58 { + if yyb59 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -7200,13 +7266,13 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromArray(l int, d * } else { x.ConcurrentJobSyncs = int(r.DecodeInt(codecSelferBitsize1234)) } - yyj58++ - if yyhl58 { - yyb58 = yyj58 > l + yyj59++ + if yyhl59 { + yyb59 = yyj59 > l } else { - yyb58 = r.CheckBreak() + yyb59 = r.CheckBreak() } - if yyb58 { + if yyb59 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -7216,13 +7282,13 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromArray(l int, d * } else { x.ConcurrentNamespaceSyncs = int(r.DecodeInt(codecSelferBitsize1234)) } - yyj58++ - if yyhl58 { - yyb58 = yyj58 > l + yyj59++ + if yyhl59 { + yyb59 = yyj59 > l } else { - yyb58 = r.CheckBreak() + yyb59 = r.CheckBreak() } - if yyb58 { + if yyb59 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -7232,13 +7298,13 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromArray(l int, d * } else { x.LookupCacheSizeForRC = int(r.DecodeInt(codecSelferBitsize1234)) } - yyj58++ - if yyhl58 { - yyb58 = yyj58 > l + yyj59++ + if yyhl59 { + yyb59 = yyj59 > l } else { - yyb58 = r.CheckBreak() + yyb59 = r.CheckBreak() } - if yyb58 { + if yyb59 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -7248,46 +7314,37 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromArray(l int, d * } else { x.LookupCacheSizeForRS = int(r.DecodeInt(codecSelferBitsize1234)) } - yyj58++ - if yyhl58 { - yyb58 = yyj58 > l + yyj59++ + if yyhl59 { + yyb59 = yyj59 > l } else { - yyb58 = r.CheckBreak() + yyb59 = r.CheckBreak() } - if yyb58 { + if yyb59 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } z.DecSendContainerState(codecSelfer_containerArrayElem1234) if r.TryDecodeAsNil() { - x.ServiceSyncPeriod = pkg1_unversioned.Duration{} + x.LookupCacheSizeForDaemonSet = 0 } else { - yyv73 := &x.ServiceSyncPeriod - yym74 := z.DecBinary() - _ = yym74 - if false { - } else if z.HasExtensions() && z.DecExt(yyv73) { - } else if !yym74 && z.IsJSONHandle() { - z.DecJSONUnmarshal(yyv73) - } else { - z.DecFallback(yyv73, false) - } + x.LookupCacheSizeForDaemonSet = int(r.DecodeInt(codecSelferBitsize1234)) } - yyj58++ - if yyhl58 { - yyb58 = yyj58 > l + yyj59++ + if yyhl59 { + yyb59 = yyj59 > l } else { - yyb58 = r.CheckBreak() + yyb59 = r.CheckBreak() } - if yyb58 { + if yyb59 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } z.DecSendContainerState(codecSelfer_containerArrayElem1234) if r.TryDecodeAsNil() { - x.NodeSyncPeriod = pkg1_unversioned.Duration{} + x.ServiceSyncPeriod = pkg1_unversioned.Duration{} } else { - yyv75 := &x.NodeSyncPeriod + yyv75 := &x.ServiceSyncPeriod yym76 := z.DecBinary() _ = yym76 if false { @@ -7298,21 +7355,21 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromArray(l int, d * z.DecFallback(yyv75, false) } } - yyj58++ - if yyhl58 { - yyb58 = yyj58 > l + yyj59++ + if yyhl59 { + yyb59 = yyj59 > l } else { - yyb58 = r.CheckBreak() + yyb59 = r.CheckBreak() } - if yyb58 { + if yyb59 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } z.DecSendContainerState(codecSelfer_containerArrayElem1234) if r.TryDecodeAsNil() { - x.ResourceQuotaSyncPeriod = pkg1_unversioned.Duration{} + x.NodeSyncPeriod = pkg1_unversioned.Duration{} } else { - yyv77 := &x.ResourceQuotaSyncPeriod + yyv77 := &x.NodeSyncPeriod yym78 := z.DecBinary() _ = yym78 if false { @@ -7323,21 +7380,21 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromArray(l int, d * z.DecFallback(yyv77, false) } } - yyj58++ - if yyhl58 { - yyb58 = yyj58 > l + yyj59++ + if yyhl59 { + yyb59 = yyj59 > l } else { - yyb58 = r.CheckBreak() + yyb59 = r.CheckBreak() } - if yyb58 { + if yyb59 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } z.DecSendContainerState(codecSelfer_containerArrayElem1234) if r.TryDecodeAsNil() { - x.NamespaceSyncPeriod = pkg1_unversioned.Duration{} + x.ResourceQuotaSyncPeriod = pkg1_unversioned.Duration{} } else { - yyv79 := &x.NamespaceSyncPeriod + yyv79 := &x.ResourceQuotaSyncPeriod yym80 := z.DecBinary() _ = yym80 if false { @@ -7348,21 +7405,21 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromArray(l int, d * z.DecFallback(yyv79, false) } } - yyj58++ - if yyhl58 { - yyb58 = yyj58 > l + yyj59++ + if yyhl59 { + yyb59 = yyj59 > l } else { - yyb58 = r.CheckBreak() + yyb59 = r.CheckBreak() } - if yyb58 { + if yyb59 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } z.DecSendContainerState(codecSelfer_containerArrayElem1234) if r.TryDecodeAsNil() { - x.PVClaimBinderSyncPeriod = pkg1_unversioned.Duration{} + x.NamespaceSyncPeriod = pkg1_unversioned.Duration{} } else { - yyv81 := &x.PVClaimBinderSyncPeriod + yyv81 := &x.NamespaceSyncPeriod yym82 := z.DecBinary() _ = yym82 if false { @@ -7373,21 +7430,21 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromArray(l int, d * z.DecFallback(yyv81, false) } } - yyj58++ - if yyhl58 { - yyb58 = yyj58 > l + yyj59++ + if yyhl59 { + yyb59 = yyj59 > l } else { - yyb58 = r.CheckBreak() + yyb59 = r.CheckBreak() } - if yyb58 { + if yyb59 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } z.DecSendContainerState(codecSelfer_containerArrayElem1234) if r.TryDecodeAsNil() { - x.MinResyncPeriod = pkg1_unversioned.Duration{} + x.PVClaimBinderSyncPeriod = pkg1_unversioned.Duration{} } else { - yyv83 := &x.MinResyncPeriod + yyv83 := &x.PVClaimBinderSyncPeriod yym84 := z.DecBinary() _ = yym84 if false { @@ -7398,62 +7455,62 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromArray(l int, d * z.DecFallback(yyv83, false) } } - yyj58++ - if yyhl58 { - yyb58 = yyj58 > l + yyj59++ + if yyhl59 { + yyb59 = yyj59 > l } else { - yyb58 = r.CheckBreak() + yyb59 = r.CheckBreak() } - if yyb58 { + if yyb59 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } z.DecSendContainerState(codecSelfer_containerArrayElem1234) if r.TryDecodeAsNil() { - x.TerminatedPodGCThreshold = 0 + x.MinResyncPeriod = pkg1_unversioned.Duration{} } else { - x.TerminatedPodGCThreshold = int(r.DecodeInt(codecSelferBitsize1234)) + yyv85 := &x.MinResyncPeriod + yym86 := z.DecBinary() + _ = yym86 + if false { + } else if z.HasExtensions() && z.DecExt(yyv85) { + } else if !yym86 && z.IsJSONHandle() { + z.DecJSONUnmarshal(yyv85) + } else { + z.DecFallback(yyv85, false) + } } - yyj58++ - if yyhl58 { - yyb58 = yyj58 > l + yyj59++ + if yyhl59 { + yyb59 = yyj59 > l } else { - yyb58 = r.CheckBreak() + yyb59 = r.CheckBreak() } - if yyb58 { + if yyb59 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } z.DecSendContainerState(codecSelfer_containerArrayElem1234) if r.TryDecodeAsNil() { - x.HorizontalPodAutoscalerSyncPeriod = pkg1_unversioned.Duration{} + x.TerminatedPodGCThreshold = 0 } else { - yyv86 := &x.HorizontalPodAutoscalerSyncPeriod - yym87 := z.DecBinary() - _ = yym87 - if false { - } else if z.HasExtensions() && z.DecExt(yyv86) { - } else if !yym87 && z.IsJSONHandle() { - z.DecJSONUnmarshal(yyv86) - } else { - z.DecFallback(yyv86, false) - } + x.TerminatedPodGCThreshold = int(r.DecodeInt(codecSelferBitsize1234)) } - yyj58++ - if yyhl58 { - yyb58 = yyj58 > l + yyj59++ + if yyhl59 { + yyb59 = yyj59 > l } else { - yyb58 = r.CheckBreak() + yyb59 = r.CheckBreak() } - if yyb58 { + if yyb59 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } z.DecSendContainerState(codecSelfer_containerArrayElem1234) if r.TryDecodeAsNil() { - x.DeploymentControllerSyncPeriod = pkg1_unversioned.Duration{} + x.HorizontalPodAutoscalerSyncPeriod = pkg1_unversioned.Duration{} } else { - yyv88 := &x.DeploymentControllerSyncPeriod + yyv88 := &x.HorizontalPodAutoscalerSyncPeriod yym89 := z.DecBinary() _ = yym89 if false { @@ -7464,21 +7521,21 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromArray(l int, d * z.DecFallback(yyv88, false) } } - yyj58++ - if yyhl58 { - yyb58 = yyj58 > l + yyj59++ + if yyhl59 { + yyb59 = yyj59 > l } else { - yyb58 = r.CheckBreak() + yyb59 = r.CheckBreak() } - if yyb58 { + if yyb59 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } z.DecSendContainerState(codecSelfer_containerArrayElem1234) if r.TryDecodeAsNil() { - x.PodEvictionTimeout = pkg1_unversioned.Duration{} + x.DeploymentControllerSyncPeriod = pkg1_unversioned.Duration{} } else { - yyv90 := &x.PodEvictionTimeout + yyv90 := &x.DeploymentControllerSyncPeriod yym91 := z.DecBinary() _ = yym91 if false { @@ -7489,13 +7546,38 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromArray(l int, d * z.DecFallback(yyv90, false) } } - yyj58++ - if yyhl58 { - yyb58 = yyj58 > l + yyj59++ + if yyhl59 { + yyb59 = yyj59 > l + } else { + yyb59 = r.CheckBreak() + } + if yyb59 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) + return + } + z.DecSendContainerState(codecSelfer_containerArrayElem1234) + if r.TryDecodeAsNil() { + x.PodEvictionTimeout = pkg1_unversioned.Duration{} + } else { + yyv92 := &x.PodEvictionTimeout + yym93 := z.DecBinary() + _ = yym93 + if false { + } else if z.HasExtensions() && z.DecExt(yyv92) { + } else if !yym93 && z.IsJSONHandle() { + z.DecJSONUnmarshal(yyv92) + } else { + z.DecFallback(yyv92, false) + } + } + yyj59++ + if yyhl59 { + yyb59 = yyj59 > l } else { - yyb58 = r.CheckBreak() + yyb59 = r.CheckBreak() } - if yyb58 { + if yyb59 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -7505,13 +7587,13 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromArray(l int, d * } else { x.DeletingPodsQps = float32(r.DecodeFloat(true)) } - yyj58++ - if yyhl58 { - yyb58 = yyj58 > l + yyj59++ + if yyhl59 { + yyb59 = yyj59 > l } else { - yyb58 = r.CheckBreak() + yyb59 = r.CheckBreak() } - if yyb58 { + if yyb59 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -7521,13 +7603,13 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromArray(l int, d * } else { x.DeletingPodsBurst = int(r.DecodeInt(codecSelferBitsize1234)) } - yyj58++ - if yyhl58 { - yyb58 = yyj58 > l + yyj59++ + if yyhl59 { + yyb59 = yyj59 > l } else { - yyb58 = r.CheckBreak() + yyb59 = r.CheckBreak() } - if yyb58 { + if yyb59 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -7535,24 +7617,24 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromArray(l int, d * if r.TryDecodeAsNil() { x.NodeMonitorGracePeriod = pkg1_unversioned.Duration{} } else { - yyv94 := &x.NodeMonitorGracePeriod - yym95 := z.DecBinary() - _ = yym95 + yyv96 := &x.NodeMonitorGracePeriod + yym97 := z.DecBinary() + _ = yym97 if false { - } else if z.HasExtensions() && z.DecExt(yyv94) { - } else if !yym95 && z.IsJSONHandle() { - z.DecJSONUnmarshal(yyv94) + } else if z.HasExtensions() && z.DecExt(yyv96) { + } else if !yym97 && z.IsJSONHandle() { + z.DecJSONUnmarshal(yyv96) } else { - z.DecFallback(yyv94, false) + z.DecFallback(yyv96, false) } } - yyj58++ - if yyhl58 { - yyb58 = yyj58 > l + yyj59++ + if yyhl59 { + yyb59 = yyj59 > l } else { - yyb58 = r.CheckBreak() + yyb59 = r.CheckBreak() } - if yyb58 { + if yyb59 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -7562,13 +7644,13 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromArray(l int, d * } else { x.RegisterRetryCount = int(r.DecodeInt(codecSelferBitsize1234)) } - yyj58++ - if yyhl58 { - yyb58 = yyj58 > l + yyj59++ + if yyhl59 { + yyb59 = yyj59 > l } else { - yyb58 = r.CheckBreak() + yyb59 = r.CheckBreak() } - if yyb58 { + if yyb59 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -7576,24 +7658,24 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromArray(l int, d * if r.TryDecodeAsNil() { x.NodeStartupGracePeriod = pkg1_unversioned.Duration{} } else { - yyv97 := &x.NodeStartupGracePeriod - yym98 := z.DecBinary() - _ = yym98 + yyv99 := &x.NodeStartupGracePeriod + yym100 := z.DecBinary() + _ = yym100 if false { - } else if z.HasExtensions() && z.DecExt(yyv97) { - } else if !yym98 && z.IsJSONHandle() { - z.DecJSONUnmarshal(yyv97) + } else if z.HasExtensions() && z.DecExt(yyv99) { + } else if !yym100 && z.IsJSONHandle() { + z.DecJSONUnmarshal(yyv99) } else { - z.DecFallback(yyv97, false) + z.DecFallback(yyv99, false) } } - yyj58++ - if yyhl58 { - yyb58 = yyj58 > l + yyj59++ + if yyhl59 { + yyb59 = yyj59 > l } else { - yyb58 = r.CheckBreak() + yyb59 = r.CheckBreak() } - if yyb58 { + if yyb59 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -7601,24 +7683,24 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromArray(l int, d * if r.TryDecodeAsNil() { x.NodeMonitorPeriod = pkg1_unversioned.Duration{} } else { - yyv99 := &x.NodeMonitorPeriod - yym100 := z.DecBinary() - _ = yym100 + yyv101 := &x.NodeMonitorPeriod + 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) } } - yyj58++ - if yyhl58 { - yyb58 = yyj58 > l + yyj59++ + if yyhl59 { + yyb59 = yyj59 > l } else { - yyb58 = r.CheckBreak() + yyb59 = r.CheckBreak() } - if yyb58 { + if yyb59 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -7628,13 +7710,13 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromArray(l int, d * } else { x.ServiceAccountKeyFile = string(r.DecodeString()) } - yyj58++ - if yyhl58 { - yyb58 = yyj58 > l + yyj59++ + if yyhl59 { + yyb59 = yyj59 > l } else { - yyb58 = r.CheckBreak() + yyb59 = r.CheckBreak() } - if yyb58 { + if yyb59 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -7644,13 +7726,13 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromArray(l int, d * } else { x.EnableProfiling = bool(r.DecodeBool()) } - yyj58++ - if yyhl58 { - yyb58 = yyj58 > l + yyj59++ + if yyhl59 { + yyb59 = yyj59 > l } else { - yyb58 = r.CheckBreak() + yyb59 = r.CheckBreak() } - if yyb58 { + if yyb59 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -7660,13 +7742,13 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromArray(l int, d * } else { x.ClusterName = string(r.DecodeString()) } - yyj58++ - if yyhl58 { - yyb58 = yyj58 > l + yyj59++ + if yyhl59 { + yyb59 = yyj59 > l } else { - yyb58 = r.CheckBreak() + yyb59 = r.CheckBreak() } - if yyb58 { + if yyb59 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -7676,13 +7758,13 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromArray(l int, d * } else { x.ClusterCIDR = string(r.DecodeString()) } - yyj58++ - if yyhl58 { - yyb58 = yyj58 > l + yyj59++ + if yyhl59 { + yyb59 = yyj59 > l } else { - yyb58 = r.CheckBreak() + yyb59 = r.CheckBreak() } - if yyb58 { + if yyb59 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -7692,13 +7774,13 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromArray(l int, d * } else { x.AllocateNodeCIDRs = bool(r.DecodeBool()) } - yyj58++ - if yyhl58 { - yyb58 = yyj58 > l + yyj59++ + if yyhl59 { + yyb59 = yyj59 > l } else { - yyb58 = r.CheckBreak() + yyb59 = r.CheckBreak() } - if yyb58 { + if yyb59 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -7708,13 +7790,13 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromArray(l int, d * } else { x.RootCAFile = string(r.DecodeString()) } - yyj58++ - if yyhl58 { - yyb58 = yyj58 > l + yyj59++ + if yyhl59 { + yyb59 = yyj59 > l } else { - yyb58 = r.CheckBreak() + yyb59 = r.CheckBreak() } - if yyb58 { + if yyb59 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -7724,13 +7806,13 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromArray(l int, d * } else { x.KubeAPIQPS = float32(r.DecodeFloat(true)) } - yyj58++ - if yyhl58 { - yyb58 = yyj58 > l + yyj59++ + if yyhl59 { + yyb59 = yyj59 > l } else { - yyb58 = r.CheckBreak() + yyb59 = r.CheckBreak() } - if yyb58 { + if yyb59 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -7740,13 +7822,13 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromArray(l int, d * } else { x.KubeAPIBurst = int(r.DecodeInt(codecSelferBitsize1234)) } - yyj58++ - if yyhl58 { - yyb58 = yyj58 > l + yyj59++ + if yyhl59 { + yyb59 = yyj59 > l } else { - yyb58 = r.CheckBreak() + yyb59 = r.CheckBreak() } - if yyb58 { + if yyb59 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -7754,16 +7836,16 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromArray(l int, d * if r.TryDecodeAsNil() { x.LeaderElection = LeaderElectionConfiguration{} } else { - yyv109 := &x.LeaderElection - yyv109.CodecDecodeSelf(d) + yyv111 := &x.LeaderElection + yyv111.CodecDecodeSelf(d) } - yyj58++ - if yyhl58 { - yyb58 = yyj58 > l + yyj59++ + if yyhl59 { + yyb59 = yyj59 > l } else { - yyb58 = r.CheckBreak() + yyb59 = r.CheckBreak() } - if yyb58 { + if yyb59 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -7771,16 +7853,16 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromArray(l int, d * if r.TryDecodeAsNil() { x.VolumeConfiguration = VolumeConfiguration{} } else { - yyv110 := &x.VolumeConfiguration - yyv110.CodecDecodeSelf(d) + yyv112 := &x.VolumeConfiguration + yyv112.CodecDecodeSelf(d) } - yyj58++ - if yyhl58 { - yyb58 = yyj58 > l + yyj59++ + if yyhl59 { + yyb59 = yyj59 > l } else { - yyb58 = r.CheckBreak() + yyb59 = r.CheckBreak() } - if yyb58 { + if yyb59 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -7790,13 +7872,13 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromArray(l int, d * } else { x.Kind = string(r.DecodeString()) } - yyj58++ - if yyhl58 { - yyb58 = yyj58 > l + yyj59++ + if yyhl59 { + yyb59 = yyj59 > l } else { - yyb58 = r.CheckBreak() + yyb59 = r.CheckBreak() } - if yyb58 { + if yyb59 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -7807,17 +7889,17 @@ func (x *KubeControllerManagerConfiguration) codecDecodeSelfFromArray(l int, d * x.APIVersion = string(r.DecodeString()) } for { - yyj58++ - if yyhl58 { - yyb58 = yyj58 > l + yyj59++ + if yyhl59 { + yyb59 = yyj59 > l } else { - yyb58 = r.CheckBreak() + yyb59 = r.CheckBreak() } - if yyb58 { + if yyb59 { break } z.DecSendContainerState(codecSelfer_containerArrayElem1234) - z.DecStructFieldNotFound(yyj58-1, "") + z.DecStructFieldNotFound(yyj59-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 1d587ef..fa52286 100644 --- a/vendor/k8s.io/kubernetes/pkg/apis/componentconfig/types.go +++ b/vendor/k8s.io/kubernetes/pkg/apis/componentconfig/types.go @@ -280,6 +280,8 @@ type KubeletConfiguration struct { // one must set --hairpin-mode=veth-flag, because bridge assumes the // existence of a container bridge named cbr0. HairpinMode string `json:"hairpinMode"` + // The node has babysitter process monitoring docker and kubelet. + BabysitDaemons bool `json:"babysitDaemons"` // maxPods is the number of pods that can run on this Kubelet. MaxPods int `json:"maxPods"` // dockerExecHandlerName is the handler to use when executing a command @@ -415,7 +417,7 @@ type KubeControllerManagerConfiguration struct { // but more CPU (and network) load. ConcurrentDeploymentSyncs int `json:"concurrentDeploymentSyncs"` // concurrentDaemonSetSyncs is the number of daemonset objects that are - // allowed to sync concurrently. Larger number = more responsive DaemonSet, + // allowed to sync concurrently. Larger number = more responsive daemonset, // but more CPU (and network) load. ConcurrentDaemonSetSyncs int `json:"concurrentDaemonSetSyncs"` // concurrentJobSyncs is the number of job objects that are @@ -425,12 +427,15 @@ type KubeControllerManagerConfiguration struct { // concurrentNamespaceSyncs is the number of namespace objects that are // allowed to sync concurrently. ConcurrentNamespaceSyncs int `json:"concurrentNamespaceSyncs"` - // LookupCacheSizeForRC is the size of lookup cache for replication controllers. + // lookupCacheSizeForRC is the size of lookup cache for replication controllers. // Larger number = more responsive replica management, but more MEM load. LookupCacheSizeForRC int `json:"lookupCacheSizeForRC"` - // LookupCacheSizeForRS is the size of lookup cache for replicatsets. + // lookupCacheSizeForRS is the size of lookup cache for replicatsets. // Larger number = more responsive replica management, but more MEM load. LookupCacheSizeForRS int `json:"lookupCacheSizeForRS"` + // lookupCacheSizeForDaemonSet is the size of lookup cache for daemonsets. + // Larger number = more responsive daemonset, but more MEM load. + LookupCacheSizeForDaemonSet int `json:"lookupCacheSizeForDaemonSet"` // serviceSyncPeriod is the period for syncing services with their external // load balancers. ServiceSyncPeriod unversioned.Duration `json:"serviceSyncPeriod"` diff --git a/vendor/k8s.io/kubernetes/pkg/apis/extensions/helpers.go b/vendor/k8s.io/kubernetes/pkg/apis/extensions/helpers.go deleted file mode 100644 index c6d79d6..0000000 --- a/vendor/k8s.io/kubernetes/pkg/apis/extensions/helpers.go +++ /dev/null @@ -1,47 +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 extensions - -// TODO(madhusudancs): Fix this when Scale group issues are resolved (see issue #18528). -// import ( -// "fmt" - -// "k8s.io/kubernetes/pkg/api" -// "k8s.io/kubernetes/pkg/api/unversioned" -// ) - -// // ScaleFromDeployment returns a scale subresource for a deployment. -// func ScaleFromDeployment(deployment *Deployment) (*Scale, error) { -// selector, err := unversioned.LabelSelectorAsSelector(deployment.Spec.Selector) -// if err != nil { -// return nil, fmt.Errorf("invalid label selector: %v", err) -// } -// return &Scale{ -// ObjectMeta: api.ObjectMeta{ -// Name: deployment.Name, -// Namespace: deployment.Namespace, -// CreationTimestamp: deployment.CreationTimestamp, -// }, -// Spec: ScaleSpec{ -// Replicas: deployment.Spec.Replicas, -// }, -// Status: ScaleStatus{ -// Replicas: deployment.Status.Replicas, -// Selector: selector.String(), -// }, -// }, nil -// } 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 51067f2..2df9498 100644 --- a/vendor/k8s.io/kubernetes/pkg/apis/extensions/types.generated.go +++ b/vendor/k8s.io/kubernetes/pkg/apis/extensions/types.generated.go @@ -68,7 +68,7 @@ func init() { if false { // reference the types, but skip this branch at build/run time var v0 pkg2_api.ObjectMeta var v1 pkg4_resource.Quantity - var v2 pkg1_unversioned.TypeMeta + var v2 pkg1_unversioned.LabelSelector var v3 pkg3_types.UID var v4 pkg6_intstr.IntOrString var v5 pkg5_inf.Dec @@ -263,7 +263,7 @@ func (x *ScaleStatus) CodecEncodeSelf(e *codec1978.Encoder) { var yyq2 [2]bool _, _, _ = yysep2, yyq2, yy2arr2 const yyr2 bool = false - yyq2[1] = len(x.Selector) != 0 + yyq2[1] = x.Selector != nil var yynn2 int if yyr2 || yy2arr2 { r.EncodeArrayStart(2) @@ -305,8 +305,9 @@ func (x *ScaleStatus) CodecEncodeSelf(e *codec1978.Encoder) { yym7 := z.EncBinary() _ = yym7 if false { + } else if z.HasExtensions() && z.EncExt(x.Selector) { } else { - z.F.EncMapStringStringV(x.Selector, false, e) + z.EncFallback(x.Selector) } } } else { @@ -323,8 +324,9 @@ func (x *ScaleStatus) CodecEncodeSelf(e *codec1978.Encoder) { yym8 := z.EncBinary() _ = yym8 if false { + } else if z.HasExtensions() && z.EncExt(x.Selector) { } else { - z.F.EncMapStringStringV(x.Selector, false, e) + z.EncFallback(x.Selector) } } } @@ -398,14 +400,19 @@ func (x *ScaleStatus) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) { } case "selector": if r.TryDecodeAsNil() { - x.Selector = nil + if x.Selector != nil { + x.Selector = nil + } } else { - yyv5 := &x.Selector + if x.Selector == nil { + x.Selector = new(pkg1_unversioned.LabelSelector) + } yym6 := z.DecBinary() _ = yym6 if false { + } else if z.HasExtensions() && z.DecExt(x.Selector) { } else { - z.F.DecMapStringStringX(yyv5, false, d) + z.DecFallback(x.Selector, false) } } default: @@ -450,14 +457,19 @@ func (x *ScaleStatus) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { } z.DecSendContainerState(codecSelfer_containerArrayElem1234) if r.TryDecodeAsNil() { - x.Selector = nil + if x.Selector != nil { + x.Selector = nil + } } else { - yyv9 := &x.Selector + if x.Selector == nil { + x.Selector = new(pkg1_unversioned.LabelSelector) + } yym10 := z.DecBinary() _ = yym10 if false { + } else if z.HasExtensions() && z.DecExt(x.Selector) { } else { - z.F.DecMapStringStringX(yyv9, false, d) + z.DecFallback(x.Selector, false) } } for { @@ -14597,7 +14609,7 @@ func (x *ReplicaSetSpec) CodecEncodeSelf(e *codec1978.Encoder) { _, _, _ = yysep2, yyq2, yy2arr2 const yyr2 bool = false yyq2[1] = x.Selector != nil - yyq2[2] = x.Template != nil + yyq2[2] = true var yynn2 int if yyr2 || yy2arr2 { r.EncodeArrayStart(3) @@ -14668,11 +14680,8 @@ func (x *ReplicaSetSpec) CodecEncodeSelf(e *codec1978.Encoder) { if yyr2 || yy2arr2 { z.EncSendContainerState(codecSelfer_containerArrayElem1234) if yyq2[2] { - if x.Template == nil { - r.EncodeNil() - } else { - x.Template.CodecEncodeSelf(e) - } + yy10 := &x.Template + yy10.CodecEncodeSelf(e) } else { r.EncodeNil() } @@ -14681,11 +14690,8 @@ func (x *ReplicaSetSpec) CodecEncodeSelf(e *codec1978.Encoder) { z.EncSendContainerState(codecSelfer_containerMapKey1234) r.EncodeString(codecSelferC_UTF81234, string("template")) z.EncSendContainerState(codecSelfer_containerMapValue1234) - if x.Template == nil { - r.EncodeNil() - } else { - x.Template.CodecEncodeSelf(e) - } + yy12 := &x.Template + yy12.CodecEncodeSelf(e) } } if yyr2 || yy2arr2 { @@ -14774,14 +14780,10 @@ func (x *ReplicaSetSpec) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) { } case "template": if r.TryDecodeAsNil() { - if x.Template != nil { - x.Template = nil - } + x.Template = pkg2_api.PodTemplateSpec{} } else { - if x.Template == nil { - x.Template = new(pkg2_api.PodTemplateSpec) - } - x.Template.CodecDecodeSelf(d) + yyv7 := &x.Template + yyv7.CodecDecodeSelf(d) } default: z.DecStructFieldNotFound(-1, yys3) @@ -14852,14 +14854,10 @@ func (x *ReplicaSetSpec) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { } z.DecSendContainerState(codecSelfer_containerArrayElem1234) if r.TryDecodeAsNil() { - if x.Template != nil { - x.Template = nil - } + x.Template = pkg2_api.PodTemplateSpec{} } else { - if x.Template == nil { - x.Template = new(pkg2_api.PodTemplateSpec) - } - x.Template.CodecDecodeSelf(d) + yyv12 := &x.Template + yyv12.CodecDecodeSelf(d) } for { yyj8++ @@ -14891,13 +14889,14 @@ func (x *ReplicaSetStatus) CodecEncodeSelf(e *codec1978.Encoder) { } else { yysep2 := !z.EncBinary() yy2arr2 := z.EncBasicHandle().StructToArray - var yyq2 [2]bool + var yyq2 [3]bool _, _, _ = yysep2, yyq2, yy2arr2 const yyr2 bool = false - yyq2[1] = x.ObservedGeneration != 0 + yyq2[1] = x.FullyLabeledReplicas != 0 + yyq2[2] = x.ObservedGeneration != 0 var yynn2 int if yyr2 || yy2arr2 { - r.EncodeArrayStart(2) + r.EncodeArrayStart(3) } else { yynn2 = 1 for _, b := range yyq2 { @@ -14934,7 +14933,7 @@ func (x *ReplicaSetStatus) CodecEncodeSelf(e *codec1978.Encoder) { _ = yym7 if false { } else { - r.EncodeInt(int64(x.ObservedGeneration)) + r.EncodeInt(int64(x.FullyLabeledReplicas)) } } else { r.EncodeInt(0) @@ -14942,11 +14941,36 @@ func (x *ReplicaSetStatus) CodecEncodeSelf(e *codec1978.Encoder) { } else { if yyq2[1] { z.EncSendContainerState(codecSelfer_containerMapKey1234) - r.EncodeString(codecSelferC_UTF81234, string("observedGeneration")) + r.EncodeString(codecSelferC_UTF81234, string("fullyLabeledReplicas")) z.EncSendContainerState(codecSelfer_containerMapValue1234) yym8 := z.EncBinary() _ = yym8 if false { + } else { + r.EncodeInt(int64(x.FullyLabeledReplicas)) + } + } + } + if yyr2 || yy2arr2 { + z.EncSendContainerState(codecSelfer_containerArrayElem1234) + if yyq2[2] { + yym10 := z.EncBinary() + _ = yym10 + if false { + } else { + r.EncodeInt(int64(x.ObservedGeneration)) + } + } else { + r.EncodeInt(0) + } + } else { + if yyq2[2] { + z.EncSendContainerState(codecSelfer_containerMapKey1234) + r.EncodeString(codecSelferC_UTF81234, string("observedGeneration")) + z.EncSendContainerState(codecSelfer_containerMapValue1234) + yym11 := z.EncBinary() + _ = yym11 + if false { } else { r.EncodeInt(int64(x.ObservedGeneration)) } @@ -15019,6 +15043,12 @@ func (x *ReplicaSetStatus) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) { } else { x.Replicas = int(r.DecodeInt(codecSelferBitsize1234)) } + case "fullyLabeledReplicas": + if r.TryDecodeAsNil() { + x.FullyLabeledReplicas = 0 + } else { + x.FullyLabeledReplicas = int(r.DecodeInt(codecSelferBitsize1234)) + } case "observedGeneration": if r.TryDecodeAsNil() { x.ObservedGeneration = 0 @@ -15036,16 +15066,16 @@ func (x *ReplicaSetStatus) 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 + var yyj7 int + var yyb7 bool + var yyhl7 bool = l >= 0 + yyj7++ + if yyhl7 { + yyb7 = yyj7 > l } else { - yyb6 = r.CheckBreak() + yyb7 = r.CheckBreak() } - if yyb6 { + if yyb7 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -15055,13 +15085,29 @@ func (x *ReplicaSetStatus) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) } else { x.Replicas = int(r.DecodeInt(codecSelferBitsize1234)) } - yyj6++ - if yyhl6 { - yyb6 = yyj6 > l + yyj7++ + if yyhl7 { + yyb7 = yyj7 > l } else { - yyb6 = r.CheckBreak() + yyb7 = r.CheckBreak() } - if yyb6 { + if yyb7 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) + return + } + z.DecSendContainerState(codecSelfer_containerArrayElem1234) + if r.TryDecodeAsNil() { + x.FullyLabeledReplicas = 0 + } else { + x.FullyLabeledReplicas = int(r.DecodeInt(codecSelferBitsize1234)) + } + yyj7++ + if yyhl7 { + yyb7 = yyj7 > l + } else { + yyb7 = r.CheckBreak() + } + if yyb7 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -15072,17 +15118,17 @@ func (x *ReplicaSetStatus) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) x.ObservedGeneration = int64(r.DecodeInt(64)) } for { - yyj6++ - if yyhl6 { - yyb6 = yyj6 > l + yyj7++ + if yyhl7 { + yyb7 = yyj7 > l } else { - yyb6 = r.CheckBreak() + yyb7 = r.CheckBreak() } - if yyb6 { + if yyb7 { break } z.DecSendContainerState(codecSelfer_containerArrayElem1234) - z.DecStructFieldNotFound(yyj6-1, "") + z.DecStructFieldNotFound(yyj7-1, "") } z.DecSendContainerState(codecSelfer_containerArrayEnd1234) } @@ -15629,7 +15675,7 @@ func (x *PodSecurityPolicySpec) CodecEncodeSelf(e *codec1978.Encoder) { if yyr2 || yy2arr2 { z.EncSendContainerState(codecSelfer_containerArrayElem1234) if yyq2[7] { - yy25 := &x.SELinuxContext + yy25 := &x.SELinux yy25.CodecEncodeSelf(e) } else { r.EncodeNil() @@ -15637,9 +15683,9 @@ func (x *PodSecurityPolicySpec) CodecEncodeSelf(e *codec1978.Encoder) { } else { if yyq2[7] { z.EncSendContainerState(codecSelfer_containerMapKey1234) - r.EncodeString(codecSelferC_UTF81234, string("seLinuxContext")) + r.EncodeString(codecSelferC_UTF81234, string("seLinux")) z.EncSendContainerState(codecSelfer_containerMapValue1234) - yy27 := &x.SELinuxContext + yy27 := &x.SELinux yy27.CodecEncodeSelf(e) } } @@ -15781,11 +15827,11 @@ func (x *PodSecurityPolicySpec) codecDecodeSelfFromMap(l int, d *codec1978.Decod } else { x.HostIPC = bool(r.DecodeBool()) } - case "seLinuxContext": + case "seLinux": if r.TryDecodeAsNil() { - x.SELinuxContext = SELinuxContextStrategyOptions{} + x.SELinux = SELinuxStrategyOptions{} } else { - yyv14 := &x.SELinuxContext + yyv14 := &x.SELinux yyv14.CodecDecodeSelf(d) } case "runAsUser": @@ -15951,9 +15997,9 @@ func (x *PodSecurityPolicySpec) codecDecodeSelfFromArray(l int, d *codec1978.Dec } z.DecSendContainerState(codecSelfer_containerArrayElem1234) if r.TryDecodeAsNil() { - x.SELinuxContext = SELinuxContextStrategyOptions{} + x.SELinux = SELinuxStrategyOptions{} } else { - yyv27 := &x.SELinuxContext + yyv27 := &x.SELinux yyv27.CodecDecodeSelf(d) } yyj16++ @@ -16218,7 +16264,7 @@ func (x *FSType) CodecDecodeSelf(d *codec1978.Decoder) { } } -func (x *SELinuxContextStrategyOptions) CodecEncodeSelf(e *codec1978.Encoder) { +func (x *SELinuxStrategyOptions) CodecEncodeSelf(e *codec1978.Encoder) { var h codecSelfer1234 z, r := codec1978.GenHelperEncoder(e) _, _, _ = h, z, r @@ -16251,12 +16297,12 @@ func (x *SELinuxContextStrategyOptions) CodecEncodeSelf(e *codec1978.Encoder) { } if yyr2 || yy2arr2 { z.EncSendContainerState(codecSelfer_containerArrayElem1234) - x.Type.CodecEncodeSelf(e) + x.Rule.CodecEncodeSelf(e) } else { z.EncSendContainerState(codecSelfer_containerMapKey1234) - r.EncodeString(codecSelferC_UTF81234, string("type")) + r.EncodeString(codecSelferC_UTF81234, string("rule")) z.EncSendContainerState(codecSelfer_containerMapValue1234) - x.Type.CodecEncodeSelf(e) + x.Rule.CodecEncodeSelf(e) } if yyr2 || yy2arr2 { z.EncSendContainerState(codecSelfer_containerArrayElem1234) @@ -16290,7 +16336,7 @@ func (x *SELinuxContextStrategyOptions) CodecEncodeSelf(e *codec1978.Encoder) { } } -func (x *SELinuxContextStrategyOptions) CodecDecodeSelf(d *codec1978.Decoder) { +func (x *SELinuxStrategyOptions) CodecDecodeSelf(d *codec1978.Decoder) { var h codecSelfer1234 z, r := codec1978.GenHelperDecoder(d) _, _, _ = h, z, r @@ -16320,7 +16366,7 @@ func (x *SELinuxContextStrategyOptions) CodecDecodeSelf(d *codec1978.Decoder) { } } -func (x *SELinuxContextStrategyOptions) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) { +func (x *SELinuxStrategyOptions) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) { var h codecSelfer1234 z, r := codec1978.GenHelperDecoder(d) _, _, _ = h, z, r @@ -16342,11 +16388,11 @@ func (x *SELinuxContextStrategyOptions) codecDecodeSelfFromMap(l int, d *codec19 yys3 := string(yys3Slc) z.DecSendContainerState(codecSelfer_containerMapValue1234) switch yys3 { - case "type": + case "rule": if r.TryDecodeAsNil() { - x.Type = "" + x.Rule = "" } else { - x.Type = SELinuxContextStrategy(r.DecodeString()) + x.Rule = SELinuxStrategy(r.DecodeString()) } case "seLinuxOptions": if r.TryDecodeAsNil() { @@ -16366,7 +16412,7 @@ func (x *SELinuxContextStrategyOptions) codecDecodeSelfFromMap(l int, d *codec19 z.DecSendContainerState(codecSelfer_containerMapEnd1234) } -func (x *SELinuxContextStrategyOptions) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { +func (x *SELinuxStrategyOptions) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { var h codecSelfer1234 z, r := codec1978.GenHelperDecoder(d) _, _, _ = h, z, r @@ -16385,9 +16431,9 @@ func (x *SELinuxContextStrategyOptions) codecDecodeSelfFromArray(l int, d *codec } z.DecSendContainerState(codecSelfer_containerArrayElem1234) if r.TryDecodeAsNil() { - x.Type = "" + x.Rule = "" } else { - x.Type = SELinuxContextStrategy(r.DecodeString()) + x.Rule = SELinuxStrategy(r.DecodeString()) } yyj6++ if yyhl6 { @@ -16426,7 +16472,7 @@ func (x *SELinuxContextStrategyOptions) codecDecodeSelfFromArray(l int, d *codec z.DecSendContainerState(codecSelfer_containerArrayEnd1234) } -func (x SELinuxContextStrategy) CodecEncodeSelf(e *codec1978.Encoder) { +func (x SELinuxStrategy) CodecEncodeSelf(e *codec1978.Encoder) { var h codecSelfer1234 z, r := codec1978.GenHelperEncoder(e) _, _, _ = h, z, r @@ -16439,7 +16485,7 @@ func (x SELinuxContextStrategy) CodecEncodeSelf(e *codec1978.Encoder) { } } -func (x *SELinuxContextStrategy) CodecDecodeSelf(d *codec1978.Decoder) { +func (x *SELinuxStrategy) CodecDecodeSelf(d *codec1978.Decoder) { var h codecSelfer1234 z, r := codec1978.GenHelperDecoder(d) _, _, _ = h, z, r @@ -16485,12 +16531,12 @@ func (x *RunAsUserStrategyOptions) CodecEncodeSelf(e *codec1978.Encoder) { } if yyr2 || yy2arr2 { z.EncSendContainerState(codecSelfer_containerArrayElem1234) - x.Type.CodecEncodeSelf(e) + x.Rule.CodecEncodeSelf(e) } else { z.EncSendContainerState(codecSelfer_containerMapKey1234) - r.EncodeString(codecSelferC_UTF81234, string("type")) + r.EncodeString(codecSelferC_UTF81234, string("rule")) z.EncSendContainerState(codecSelfer_containerMapValue1234) - x.Type.CodecEncodeSelf(e) + x.Rule.CodecEncodeSelf(e) } if yyr2 || yy2arr2 { z.EncSendContainerState(codecSelfer_containerArrayElem1234) @@ -16586,11 +16632,11 @@ func (x *RunAsUserStrategyOptions) codecDecodeSelfFromMap(l int, d *codec1978.De yys3 := string(yys3Slc) z.DecSendContainerState(codecSelfer_containerMapValue1234) switch yys3 { - case "type": + case "rule": if r.TryDecodeAsNil() { - x.Type = "" + x.Rule = "" } else { - x.Type = RunAsUserStrategy(r.DecodeString()) + x.Rule = RunAsUserStrategy(r.DecodeString()) } case "ranges": if r.TryDecodeAsNil() { @@ -16630,9 +16676,9 @@ func (x *RunAsUserStrategyOptions) codecDecodeSelfFromArray(l int, d *codec1978. } z.DecSendContainerState(codecSelfer_containerArrayElem1234) if r.TryDecodeAsNil() { - x.Type = "" + x.Rule = "" } else { - x.Type = RunAsUserStrategy(r.DecodeString()) + x.Rule = RunAsUserStrategy(r.DecodeString()) } yyj7++ if yyhl7 { @@ -18950,7 +18996,7 @@ func (x codecSelfer1234) decSliceReplicaSet(v *[]ReplicaSet, d *codec1978.Decode yyrg1 := len(yyv1) > 0 yyv21 := yyv1 - yyrl1, yyrt1 = z.DecInferLen(yyl1, z.DecBasicHandle().MaxInitLen, 232) + yyrl1, yyrt1 = z.DecInferLen(yyl1, z.DecBasicHandle().MaxInitLen, 560) if yyrt1 { if yyrl1 <= cap(yyv1) { yyv1 = yyv1[:yyrl1] diff --git a/vendor/k8s.io/kubernetes/pkg/apis/extensions/types.go b/vendor/k8s.io/kubernetes/pkg/apis/extensions/types.go index 176349c..f8a736b 100644 --- a/vendor/k8s.io/kubernetes/pkg/apis/extensions/types.go +++ b/vendor/k8s.io/kubernetes/pkg/apis/extensions/types.go @@ -46,8 +46,9 @@ type ScaleStatus struct { // actual number of observed instances of the scaled object. Replicas int `json:"replicas"` - // label query over pods that should match the replicas count. More info: http://releases.k8s.io/HEAD/docs/user-guide/labels.md#label-selectors - Selector map[string]string `json:"selector,omitempty"` + // label query over pods that should match the replicas count. + // More info: http://releases.k8s.io/release-1.2/docs/user-guide/labels.md#label-selectors + Selector *unversioned.LabelSelector `json:"selector,omitempty"` } // +genclient=true,noMethods=true @@ -55,13 +56,13 @@ type ScaleStatus struct { // represents a scaling request for a resource. type Scale struct { unversioned.TypeMeta `json:",inline"` - // Standard object metadata; More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata. + // Standard object metadata; More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#metadata. api.ObjectMeta `json:"metadata,omitempty"` - // defines the behavior of the scale. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#spec-and-status. + // defines the behavior of the scale. More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#spec-and-status. Spec ScaleSpec `json:"spec,omitempty"` - // current status of the scale. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#spec-and-status. Read-only. + // current status of the scale. More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#spec-and-status. Read-only. Status ScaleStatus `json:"status,omitempty"` } @@ -72,9 +73,9 @@ type ReplicationControllerDummy struct { // SubresourceReference contains enough information to let you inspect or modify the referred subresource. type SubresourceReference struct { - // Kind of the referent; More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" + // Kind of the referent; More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#types-kinds" Kind string `json:"kind,omitempty"` - // Name of the referent; More info: http://releases.k8s.io/HEAD/docs/user-guide/identifiers.md#names + // Name of the referent; More info: http://releases.k8s.io/release-1.2/docs/user-guide/identifiers.md#names Name string `json:"name,omitempty"` // API version of the referent APIVersion string `json:"apiVersion,omitempty"` @@ -152,7 +153,7 @@ type HorizontalPodAutoscaler struct { unversioned.TypeMeta `json:",inline"` api.ObjectMeta `json:"metadata,omitempty"` - // behaviour of autoscaler. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#spec-and-status. + // behaviour of autoscaler. More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#spec-and-status. Spec HorizontalPodAutoscalerSpec `json:"spec,omitempty"` // current information about the autoscaler. @@ -407,14 +408,14 @@ type DaemonSetSpec struct { // Selector is a label query over pods that are managed by the daemon set. // Must match in order to be controlled. // If empty, defaulted to labels on Pod template. - // More info: http://releases.k8s.io/HEAD/docs/user-guide/labels.md#label-selectors + // More info: http://releases.k8s.io/release-1.2/docs/user-guide/labels.md#label-selectors Selector *unversioned.LabelSelector `json:"selector,omitempty"` // Template is the object that describes the pod that will be created. // The DaemonSet will create exactly one copy of this pod on every node // that matches the template's node selector (or on every node if no node // selector is specified). - // More info: http://releases.k8s.io/HEAD/docs/user-guide/replication-controller.md#pod-template + // More info: http://releases.k8s.io/release-1.2/docs/user-guide/replication-controller.md#pod-template Template api.PodTemplateSpec `json:"template"` // TODO(madhusudancs): Uncomment while implementing DaemonSet updates. @@ -461,18 +462,18 @@ type DaemonSetStatus struct { type DaemonSet struct { unversioned.TypeMeta `json:",inline"` // Standard object's metadata. - // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata + // More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#metadata api.ObjectMeta `json:"metadata,omitempty"` // Spec defines the desired behavior of this daemon set. - // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#spec-and-status + // More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#spec-and-status Spec DaemonSetSpec `json:"spec,omitempty"` // Status is the current status of this daemon set. This data may be // out of date by some window of time. // Populated by the system. // Read-only. - // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#spec-and-status + // More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#spec-and-status Status DaemonSetStatus `json:"status,omitempty"` } @@ -480,7 +481,7 @@ type DaemonSet struct { type DaemonSetList struct { unversioned.TypeMeta `json:",inline"` // Standard list metadata. - // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata + // More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#metadata unversioned.ListMeta `json:"metadata,omitempty"` // Items is a list of daemon sets. @@ -490,7 +491,7 @@ type DaemonSetList struct { type ThirdPartyResourceDataList struct { unversioned.TypeMeta `json:",inline"` // Standard list metadata - // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata + // More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#metadata unversioned.ListMeta `json:"metadata,omitempty"` // Items is a list of third party objects Items []ThirdPartyResourceData `json:"items"` @@ -502,15 +503,15 @@ type ThirdPartyResourceDataList struct { type Job struct { unversioned.TypeMeta `json:",inline"` // Standard object's metadata. - // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata + // More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#metadata api.ObjectMeta `json:"metadata,omitempty"` // Spec is a structure defining the expected behavior of a job. - // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#spec-and-status + // More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#spec-and-status Spec JobSpec `json:"spec,omitempty"` // Status is a structure describing current status of a job. - // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#spec-and-status + // More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#spec-and-status Status JobStatus `json:"status,omitempty"` } @@ -518,7 +519,7 @@ type Job struct { type JobList struct { unversioned.TypeMeta `json:",inline"` // Standard list metadata - // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata + // More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#metadata unversioned.ListMeta `json:"metadata,omitempty"` // Items is the list of Job. @@ -626,15 +627,15 @@ type JobCondition struct { type Ingress struct { unversioned.TypeMeta `json:",inline"` // Standard object's metadata. - // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata + // More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#metadata api.ObjectMeta `json:"metadata,omitempty"` // Spec is the desired state of the Ingress. - // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#spec-and-status + // More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#spec-and-status Spec IngressSpec `json:"spec,omitempty"` // Status is the current state of the Ingress. - // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#spec-and-status + // More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#spec-and-status Status IngressStatus `json:"status,omitempty"` } @@ -642,7 +643,7 @@ type Ingress struct { type IngressList struct { unversioned.TypeMeta `json:",inline"` // Standard object's metadata. - // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata + // More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#metadata unversioned.ListMeta `json:"metadata,omitempty"` // Items is the list of Ingress. @@ -801,12 +802,12 @@ type ReplicaSetSpec struct { // Selector is a label query over pods that should match the replica count. // Must match in order to be controlled. // If empty, defaulted to labels on pod template. - // More info: http://releases.k8s.io/HEAD/docs/user-guide/labels.md#label-selectors + // More info: http://releases.k8s.io/release-1.2/docs/user-guide/labels.md#label-selectors Selector *unversioned.LabelSelector `json:"selector,omitempty"` // Template is the object that describes the pod that will be created if // insufficient replicas are detected. - Template *api.PodTemplateSpec `json:"template,omitempty"` + Template api.PodTemplateSpec `json:"template,omitempty"` } // ReplicaSetStatus represents the current status of a ReplicaSet. @@ -814,6 +815,9 @@ type ReplicaSetStatus struct { // Replicas is the number of actual replicas. Replicas int `json:"replicas"` + // The number of pods that have labels matching the labels of the pod template of the replicaset. + FullyLabeledReplicas int `json:"fullyLabeledReplicas,omitempty"` + // ObservedGeneration is the most recent generation observed by the controller. ObservedGeneration int64 `json:"observedGeneration,omitempty"` } @@ -845,8 +849,8 @@ type PodSecurityPolicySpec struct { HostPID bool `json:"hostPID,omitempty"` // HostIPC determines if the policy allows the use of HostIPC in the pod spec. HostIPC bool `json:"hostIPC,omitempty"` - // SELinuxContext is the strategy that will dictate the allowable labels that may be set. - SELinuxContext SELinuxContextStrategyOptions `json:"seLinuxContext,omitempty"` + // SELinux is the strategy that will dictate the allowable labels that may be set. + SELinux SELinuxStrategyOptions `json:"seLinux,omitempty"` // RunAsUser is the strategy that will dictate the allowable RunAsUser values that may be set. RunAsUser RunAsUserStrategyOptions `json:"runAsUser,omitempty"` } @@ -881,30 +885,30 @@ var ( FC FSType = "fc" ) -// SELinuxContextStrategyOptions defines the strategy type and any options used to create the strategy. -type SELinuxContextStrategyOptions struct { - // Type is the strategy that will dictate the allowable labels that may be set. - Type SELinuxContextStrategy `json:"type"` +// SELinuxStrategyOptions defines the strategy type and any options used to create the strategy. +type SELinuxStrategyOptions struct { + // Rule is the strategy that will dictate the allowable labels that may be set. + Rule SELinuxStrategy `json:"rule"` // seLinuxOptions required to run as; required for MustRunAs - // More info: http://releases.k8s.io/HEAD/docs/design/security_context.md#security-context + // More info: http://releases.k8s.io/release-1.2/docs/design/security_context.md#security-context SELinuxOptions *api.SELinuxOptions `json:"seLinuxOptions,omitempty"` } -// SELinuxContextStrategyType denotes strategy types for generating SELinux options for a -// SecurityContext. -type SELinuxContextStrategy string +// SELinuxStrategy denotes strategy types for generating SELinux options for a +// Security. +type SELinuxStrategy string const ( // container must have SELinux labels of X applied. - SELinuxStrategyMustRunAs SELinuxContextStrategy = "MustRunAs" + SELinuxStrategyMustRunAs SELinuxStrategy = "MustRunAs" // container may make requests for any SELinux context labels. - SELinuxStrategyRunAsAny SELinuxContextStrategy = "RunAsAny" + SELinuxStrategyRunAsAny SELinuxStrategy = "RunAsAny" ) // RunAsUserStrategyOptions defines the strategy type and any options used to create the strategy. type RunAsUserStrategyOptions struct { - // Type is the strategy that will dictate the allowable RunAsUser values that may be set. - Type RunAsUserStrategy `json:"type"` + // Rule is the strategy that will dictate the allowable RunAsUser values that may be set. + Rule RunAsUserStrategy `json:"rule"` // Ranges are the allowed ranges of uids that may be used. Ranges []IDRange `json:"ranges,omitempty"` } @@ -917,7 +921,7 @@ type IDRange struct { Max int64 `json:"max"` } -// RunAsUserStrategyType denotes strategy types for generating RunAsUser values for a +// RunAsUserStrategy denotes strategy types for generating RunAsUser values for a // SecurityContext. type RunAsUserStrategy string diff --git a/vendor/k8s.io/kubernetes/pkg/apis/extensions/v1beta1/conversion.go b/vendor/k8s.io/kubernetes/pkg/apis/extensions/v1beta1/conversion.go index 198ed3f..5f4841c 100644 --- a/vendor/k8s.io/kubernetes/pkg/apis/extensions/v1beta1/conversion.go +++ b/vendor/k8s.io/kubernetes/pkg/apis/extensions/v1beta1/conversion.go @@ -34,6 +34,8 @@ func addConversionFuncs(scheme *runtime.Scheme) { err := scheme.AddConversionFuncs( Convert_api_PodSpec_To_v1_PodSpec, Convert_v1_PodSpec_To_api_PodSpec, + Convert_extensions_ScaleStatus_To_v1beta1_ScaleStatus, + Convert_v1beta1_ScaleStatus_To_extensions_ScaleStatus, Convert_extensions_DeploymentSpec_To_v1beta1_DeploymentSpec, Convert_v1beta1_DeploymentSpec_To_extensions_DeploymentSpec, Convert_extensions_DeploymentStrategy_To_v1beta1_DeploymentStrategy, @@ -93,6 +95,58 @@ func Convert_v1_PodSpec_To_api_PodSpec(in *v1.PodSpec, out *api.PodSpec, s conve return v1.Convert_v1_PodSpec_To_api_PodSpec(in, out, s) } +func Convert_extensions_ScaleStatus_To_v1beta1_ScaleStatus(in *extensions.ScaleStatus, out *ScaleStatus, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*extensions.ScaleStatus))(in) + } + out.Replicas = int32(in.Replicas) + + out.Selector = nil + out.TargetSelector = "" + if in.Selector != nil { + if in.Selector.MatchExpressions == nil || len(in.Selector.MatchExpressions) == 0 { + out.Selector = in.Selector.MatchLabels + } + + selector, err := unversioned.LabelSelectorAsSelector(in.Selector) + if err != nil { + return fmt.Errorf("invalid label selector: %v", err) + } + out.TargetSelector = selector.String() + } + return nil +} + +func Convert_v1beta1_ScaleStatus_To_extensions_ScaleStatus(in *ScaleStatus, out *extensions.ScaleStatus, s conversion.Scope) error { + if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { + defaulting.(func(*ScaleStatus))(in) + } + out.Replicas = int(in.Replicas) + + // Normally when 2 fields map to the same internal value we favor the old field, since + // old clients can't be expected to know about new fields but clients that know about the + // new field can be expected to know about the old field (though that's not quite true, due + // to kubectl apply). However, these fields are readonly, so any non-nil value should work. + if in.TargetSelector != "" { + labelSelector, err := unversioned.ParseToLabelSelector(in.TargetSelector) + if err != nil { + out.Selector = nil + return fmt.Errorf("failed to parse target selector: %v", err) + } + out.Selector = labelSelector + } else if in.Selector != nil { + out.Selector = new(unversioned.LabelSelector) + selector := make(map[string]string) + for key, val := range in.Selector { + selector[key] = val + } + out.Selector.MatchLabels = selector + } else { + out.Selector = nil + } + return nil +} + func Convert_extensions_DeploymentSpec_To_v1beta1_DeploymentSpec(in *extensions.DeploymentSpec, out *DeploymentSpec, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*extensions.DeploymentSpec))(in) @@ -243,13 +297,9 @@ func Convert_extensions_ReplicaSetSpec_To_v1beta1_ReplicaSetSpec(in *extensions. } else { out.Selector = nil } - if in.Template != nil { - out.Template = new(v1.PodTemplateSpec) - if err := v1.Convert_api_PodTemplateSpec_To_v1_PodTemplateSpec(in.Template, out.Template, s); err != nil { - return err - } - } else { - out.Template = nil + + if err := v1.Convert_api_PodTemplateSpec_To_v1_PodTemplateSpec(&in.Template, &out.Template, s); err != nil { + return err } return nil } @@ -269,13 +319,8 @@ func Convert_v1beta1_ReplicaSetSpec_To_extensions_ReplicaSetSpec(in *ReplicaSetS } else { out.Selector = nil } - if in.Template != nil { - out.Template = new(api.PodTemplateSpec) - if err := v1.Convert_v1_PodTemplateSpec_To_api_PodTemplateSpec(in.Template, out.Template, s); err != nil { - return err - } - } else { - out.Template = nil + if err := v1.Convert_v1_PodTemplateSpec_To_api_PodTemplateSpec(&in.Template, &out.Template, s); err != nil { + return err } return nil } 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 fed21a1..26ba97e 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 @@ -3520,7 +3520,7 @@ func autoConvert_extensions_PodSecurityPolicySpec_To_v1beta1_PodSecurityPolicySp } out.HostPID = in.HostPID out.HostIPC = in.HostIPC - if err := Convert_extensions_SELinuxContextStrategyOptions_To_v1beta1_SELinuxContextStrategyOptions(&in.SELinuxContext, &out.SELinuxContext, s); err != nil { + if err := Convert_extensions_SELinuxStrategyOptions_To_v1beta1_SELinuxStrategyOptions(&in.SELinux, &out.SELinux, s); err != nil { return err } if err := Convert_extensions_RunAsUserStrategyOptions_To_v1beta1_RunAsUserStrategyOptions(&in.RunAsUser, &out.RunAsUser, s); err != nil { @@ -3599,14 +3599,8 @@ func autoConvert_extensions_ReplicaSetSpec_To_v1beta1_ReplicaSetSpec(in *extensi } else { out.Selector = nil } - // unable to generate simple pointer conversion for api.PodTemplateSpec -> v1.PodTemplateSpec - if in.Template != nil { - out.Template = new(v1.PodTemplateSpec) - if err := Convert_api_PodTemplateSpec_To_v1_PodTemplateSpec(in.Template, out.Template, s); err != nil { - return err - } - } else { - out.Template = nil + if err := Convert_api_PodTemplateSpec_To_v1_PodTemplateSpec(&in.Template, &out.Template, s); err != nil { + return err } return nil } @@ -3616,6 +3610,7 @@ func autoConvert_extensions_ReplicaSetStatus_To_v1beta1_ReplicaSetStatus(in *ext defaulting.(func(*extensions.ReplicaSetStatus))(in) } out.Replicas = int32(in.Replicas) + out.FullyLabeledReplicas = int32(in.FullyLabeledReplicas) out.ObservedGeneration = in.ObservedGeneration return nil } @@ -3667,7 +3662,7 @@ func autoConvert_extensions_RunAsUserStrategyOptions_To_v1beta1_RunAsUserStrateg if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*extensions.RunAsUserStrategyOptions))(in) } - out.Type = RunAsUserStrategy(in.Type) + out.Rule = RunAsUserStrategy(in.Rule) if in.Ranges != nil { out.Ranges = make([]IDRange, len(in.Ranges)) for i := range in.Ranges { @@ -3685,11 +3680,11 @@ func Convert_extensions_RunAsUserStrategyOptions_To_v1beta1_RunAsUserStrategyOpt return autoConvert_extensions_RunAsUserStrategyOptions_To_v1beta1_RunAsUserStrategyOptions(in, out, s) } -func autoConvert_extensions_SELinuxContextStrategyOptions_To_v1beta1_SELinuxContextStrategyOptions(in *extensions.SELinuxContextStrategyOptions, out *SELinuxContextStrategyOptions, s conversion.Scope) error { +func autoConvert_extensions_SELinuxStrategyOptions_To_v1beta1_SELinuxStrategyOptions(in *extensions.SELinuxStrategyOptions, out *SELinuxStrategyOptions, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*extensions.SELinuxContextStrategyOptions))(in) + defaulting.(func(*extensions.SELinuxStrategyOptions))(in) } - out.Type = SELinuxContextStrategy(in.Type) + out.Rule = SELinuxStrategy(in.Rule) // unable to generate simple pointer conversion for api.SELinuxOptions -> v1.SELinuxOptions if in.SELinuxOptions != nil { out.SELinuxOptions = new(v1.SELinuxOptions) @@ -3702,8 +3697,8 @@ func autoConvert_extensions_SELinuxContextStrategyOptions_To_v1beta1_SELinuxCont return nil } -func Convert_extensions_SELinuxContextStrategyOptions_To_v1beta1_SELinuxContextStrategyOptions(in *extensions.SELinuxContextStrategyOptions, out *SELinuxContextStrategyOptions, s conversion.Scope) error { - return autoConvert_extensions_SELinuxContextStrategyOptions_To_v1beta1_SELinuxContextStrategyOptions(in, out, s) +func Convert_extensions_SELinuxStrategyOptions_To_v1beta1_SELinuxStrategyOptions(in *extensions.SELinuxStrategyOptions, out *SELinuxStrategyOptions, s conversion.Scope) error { + return autoConvert_extensions_SELinuxStrategyOptions_To_v1beta1_SELinuxStrategyOptions(in, out, s) } func autoConvert_extensions_Scale_To_v1beta1_Scale(in *extensions.Scale, out *Scale, s conversion.Scope) error { @@ -3746,21 +3741,10 @@ func autoConvert_extensions_ScaleStatus_To_v1beta1_ScaleStatus(in *extensions.Sc defaulting.(func(*extensions.ScaleStatus))(in) } out.Replicas = int32(in.Replicas) - if in.Selector != nil { - out.Selector = make(map[string]string) - for key, val := range in.Selector { - out.Selector[key] = val - } - } else { - out.Selector = nil - } + // in.Selector has no peer in out return nil } -func Convert_extensions_ScaleStatus_To_v1beta1_ScaleStatus(in *extensions.ScaleStatus, out *ScaleStatus, s conversion.Scope) error { - return autoConvert_extensions_ScaleStatus_To_v1beta1_ScaleStatus(in, out, s) -} - func autoConvert_extensions_SubresourceReference_To_v1beta1_SubresourceReference(in *extensions.SubresourceReference, out *SubresourceReference, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*extensions.SubresourceReference))(in) @@ -4782,7 +4766,7 @@ func autoConvert_v1beta1_PodSecurityPolicySpec_To_extensions_PodSecurityPolicySp } out.HostPID = in.HostPID out.HostIPC = in.HostIPC - if err := Convert_v1beta1_SELinuxContextStrategyOptions_To_extensions_SELinuxContextStrategyOptions(&in.SELinuxContext, &out.SELinuxContext, s); err != nil { + if err := Convert_v1beta1_SELinuxStrategyOptions_To_extensions_SELinuxStrategyOptions(&in.SELinux, &out.SELinux, s); err != nil { return err } if err := Convert_v1beta1_RunAsUserStrategyOptions_To_extensions_RunAsUserStrategyOptions(&in.RunAsUser, &out.RunAsUser, s); err != nil { @@ -4859,14 +4843,8 @@ func autoConvert_v1beta1_ReplicaSetSpec_To_extensions_ReplicaSetSpec(in *Replica } else { out.Selector = nil } - // unable to generate simple pointer conversion for v1.PodTemplateSpec -> api.PodTemplateSpec - if in.Template != nil { - out.Template = new(api.PodTemplateSpec) - if err := Convert_v1_PodTemplateSpec_To_api_PodTemplateSpec(in.Template, out.Template, s); err != nil { - return err - } - } else { - out.Template = nil + if err := Convert_v1_PodTemplateSpec_To_api_PodTemplateSpec(&in.Template, &out.Template, s); err != nil { + return err } return nil } @@ -4876,6 +4854,7 @@ func autoConvert_v1beta1_ReplicaSetStatus_To_extensions_ReplicaSetStatus(in *Rep defaulting.(func(*ReplicaSetStatus))(in) } out.Replicas = int(in.Replicas) + out.FullyLabeledReplicas = int(in.FullyLabeledReplicas) out.ObservedGeneration = in.ObservedGeneration return nil } @@ -4923,7 +4902,7 @@ func autoConvert_v1beta1_RunAsUserStrategyOptions_To_extensions_RunAsUserStrateg if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*RunAsUserStrategyOptions))(in) } - out.Type = extensions.RunAsUserStrategy(in.Type) + out.Rule = extensions.RunAsUserStrategy(in.Rule) if in.Ranges != nil { out.Ranges = make([]extensions.IDRange, len(in.Ranges)) for i := range in.Ranges { @@ -4941,11 +4920,11 @@ func Convert_v1beta1_RunAsUserStrategyOptions_To_extensions_RunAsUserStrategyOpt return autoConvert_v1beta1_RunAsUserStrategyOptions_To_extensions_RunAsUserStrategyOptions(in, out, s) } -func autoConvert_v1beta1_SELinuxContextStrategyOptions_To_extensions_SELinuxContextStrategyOptions(in *SELinuxContextStrategyOptions, out *extensions.SELinuxContextStrategyOptions, s conversion.Scope) error { +func autoConvert_v1beta1_SELinuxStrategyOptions_To_extensions_SELinuxStrategyOptions(in *SELinuxStrategyOptions, out *extensions.SELinuxStrategyOptions, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { - defaulting.(func(*SELinuxContextStrategyOptions))(in) + defaulting.(func(*SELinuxStrategyOptions))(in) } - out.Type = extensions.SELinuxContextStrategy(in.Type) + out.Rule = extensions.SELinuxStrategy(in.Rule) // unable to generate simple pointer conversion for v1.SELinuxOptions -> api.SELinuxOptions if in.SELinuxOptions != nil { out.SELinuxOptions = new(api.SELinuxOptions) @@ -4958,8 +4937,8 @@ func autoConvert_v1beta1_SELinuxContextStrategyOptions_To_extensions_SELinuxCont return nil } -func Convert_v1beta1_SELinuxContextStrategyOptions_To_extensions_SELinuxContextStrategyOptions(in *SELinuxContextStrategyOptions, out *extensions.SELinuxContextStrategyOptions, s conversion.Scope) error { - return autoConvert_v1beta1_SELinuxContextStrategyOptions_To_extensions_SELinuxContextStrategyOptions(in, out, s) +func Convert_v1beta1_SELinuxStrategyOptions_To_extensions_SELinuxStrategyOptions(in *SELinuxStrategyOptions, out *extensions.SELinuxStrategyOptions, s conversion.Scope) error { + return autoConvert_v1beta1_SELinuxStrategyOptions_To_extensions_SELinuxStrategyOptions(in, out, s) } func autoConvert_v1beta1_Scale_To_extensions_Scale(in *Scale, out *extensions.Scale, s conversion.Scope) error { @@ -5002,21 +4981,11 @@ func autoConvert_v1beta1_ScaleStatus_To_extensions_ScaleStatus(in *ScaleStatus, defaulting.(func(*ScaleStatus))(in) } out.Replicas = int(in.Replicas) - if in.Selector != nil { - out.Selector = make(map[string]string) - for key, val := range in.Selector { - out.Selector[key] = val - } - } else { - out.Selector = nil - } + // in.Selector has no peer in out + // in.TargetSelector has no peer in out return nil } -func Convert_v1beta1_ScaleStatus_To_extensions_ScaleStatus(in *ScaleStatus, out *extensions.ScaleStatus, s conversion.Scope) error { - return autoConvert_v1beta1_ScaleStatus_To_extensions_ScaleStatus(in, out, s) -} - func autoConvert_v1beta1_SubresourceReference_To_extensions_SubresourceReference(in *SubresourceReference, out *extensions.SubresourceReference, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*SubresourceReference))(in) @@ -5229,7 +5198,7 @@ func init() { autoConvert_extensions_RollbackConfig_To_v1beta1_RollbackConfig, autoConvert_extensions_RollingUpdateDeployment_To_v1beta1_RollingUpdateDeployment, autoConvert_extensions_RunAsUserStrategyOptions_To_v1beta1_RunAsUserStrategyOptions, - autoConvert_extensions_SELinuxContextStrategyOptions_To_v1beta1_SELinuxContextStrategyOptions, + autoConvert_extensions_SELinuxStrategyOptions_To_v1beta1_SELinuxStrategyOptions, autoConvert_extensions_ScaleSpec_To_v1beta1_ScaleSpec, autoConvert_extensions_ScaleStatus_To_v1beta1_ScaleStatus, autoConvert_extensions_Scale_To_v1beta1_Scale, @@ -5334,7 +5303,7 @@ func init() { autoConvert_v1beta1_RollbackConfig_To_extensions_RollbackConfig, autoConvert_v1beta1_RollingUpdateDeployment_To_extensions_RollingUpdateDeployment, autoConvert_v1beta1_RunAsUserStrategyOptions_To_extensions_RunAsUserStrategyOptions, - autoConvert_v1beta1_SELinuxContextStrategyOptions_To_extensions_SELinuxContextStrategyOptions, + autoConvert_v1beta1_SELinuxStrategyOptions_To_extensions_SELinuxStrategyOptions, autoConvert_v1beta1_ScaleSpec_To_extensions_ScaleSpec, autoConvert_v1beta1_ScaleStatus_To_extensions_ScaleStatus, autoConvert_v1beta1_Scale_To_extensions_Scale, 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 abe7d2f..845e4dd 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 @@ -1678,7 +1678,7 @@ func deepCopy_v1beta1_PodSecurityPolicySpec(in PodSecurityPolicySpec, out *PodSe } out.HostPID = in.HostPID out.HostIPC = in.HostIPC - if err := deepCopy_v1beta1_SELinuxContextStrategyOptions(in.SELinuxContext, &out.SELinuxContext, c); err != nil { + if err := deepCopy_v1beta1_SELinuxStrategyOptions(in.SELinux, &out.SELinux, c); err != nil { return err } if err := deepCopy_v1beta1_RunAsUserStrategyOptions(in.RunAsUser, &out.RunAsUser, c); err != nil { @@ -1738,19 +1738,15 @@ func deepCopy_v1beta1_ReplicaSetSpec(in ReplicaSetSpec, out *ReplicaSetSpec, c * } else { out.Selector = nil } - if in.Template != nil { - out.Template = new(v1.PodTemplateSpec) - if err := deepCopy_v1_PodTemplateSpec(*in.Template, out.Template, c); err != nil { - return err - } - } else { - out.Template = nil + if err := deepCopy_v1_PodTemplateSpec(in.Template, &out.Template, c); err != nil { + return err } return nil } func deepCopy_v1beta1_ReplicaSetStatus(in ReplicaSetStatus, out *ReplicaSetStatus, c *conversion.Cloner) error { out.Replicas = in.Replicas + out.FullyLabeledReplicas = in.FullyLabeledReplicas out.ObservedGeneration = in.ObservedGeneration return nil } @@ -1788,7 +1784,7 @@ func deepCopy_v1beta1_RollingUpdateDeployment(in RollingUpdateDeployment, out *R } func deepCopy_v1beta1_RunAsUserStrategyOptions(in RunAsUserStrategyOptions, out *RunAsUserStrategyOptions, c *conversion.Cloner) error { - out.Type = in.Type + out.Rule = in.Rule if in.Ranges != nil { out.Ranges = make([]IDRange, len(in.Ranges)) for i := range in.Ranges { @@ -1802,8 +1798,8 @@ func deepCopy_v1beta1_RunAsUserStrategyOptions(in RunAsUserStrategyOptions, out return nil } -func deepCopy_v1beta1_SELinuxContextStrategyOptions(in SELinuxContextStrategyOptions, out *SELinuxContextStrategyOptions, c *conversion.Cloner) error { - out.Type = in.Type +func deepCopy_v1beta1_SELinuxStrategyOptions(in SELinuxStrategyOptions, out *SELinuxStrategyOptions, c *conversion.Cloner) error { + out.Rule = in.Rule if in.SELinuxOptions != nil { out.SELinuxOptions = new(v1.SELinuxOptions) if err := deepCopy_v1_SELinuxOptions(*in.SELinuxOptions, out.SELinuxOptions, c); err != nil { @@ -1846,6 +1842,7 @@ func deepCopy_v1beta1_ScaleStatus(in ScaleStatus, out *ScaleStatus, c *conversio } else { out.Selector = nil } + out.TargetSelector = in.TargetSelector return nil } @@ -2045,7 +2042,7 @@ func init() { deepCopy_v1beta1_RollbackConfig, deepCopy_v1beta1_RollingUpdateDeployment, deepCopy_v1beta1_RunAsUserStrategyOptions, - deepCopy_v1beta1_SELinuxContextStrategyOptions, + deepCopy_v1beta1_SELinuxStrategyOptions, deepCopy_v1beta1_Scale, deepCopy_v1beta1_ScaleSpec, deepCopy_v1beta1_ScaleStatus, 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 cb197a9..46d4c37 100644 --- a/vendor/k8s.io/kubernetes/pkg/apis/extensions/v1beta1/defaults.go +++ b/vendor/k8s.io/kubernetes/pkg/apis/extensions/v1beta1/defaults.go @@ -86,7 +86,14 @@ func addDefaultingFuncs(scheme *runtime.Scheme) { labels := obj.Spec.Template.Labels // TODO: support templates defined elsewhere when we support them in the API if labels != nil { - if obj.Spec.Selector == nil { + // if an autoselector is requested, we'll build the selector later with controller-uid and job-name + autoSelector := bool(obj.Spec.AutoSelector != nil && *obj.Spec.AutoSelector) + + // otherwise, we are using a manual selector + manualSelector := !autoSelector + + // and default behavior for an unspecified manual selector is to use the pod template labels + if manualSelector && obj.Spec.Selector == nil { obj.Spec.Selector = &LabelSelector{ MatchLabels: labels, } @@ -118,10 +125,8 @@ func addDefaultingFuncs(scheme *runtime.Scheme) { } }, func(obj *ReplicaSet) { - var labels map[string]string - if obj.Spec.Template != nil { - labels = obj.Spec.Template.Labels - } + labels := obj.Spec.Template.Labels + // TODO: support templates defined elsewhere when we support them in the API if labels != nil { if obj.Spec.Selector == nil { 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 71bafcc..ffdeebc 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 @@ -260,13 +260,14 @@ func (x *ScaleStatus) CodecEncodeSelf(e *codec1978.Encoder) { } else { yysep2 := !z.EncBinary() yy2arr2 := z.EncBasicHandle().StructToArray - var yyq2 [2]bool + var yyq2 [3]bool _, _, _ = yysep2, yyq2, yy2arr2 const yyr2 bool = false yyq2[1] = len(x.Selector) != 0 + yyq2[2] = x.TargetSelector != "" var yynn2 int if yyr2 || yy2arr2 { - r.EncodeArrayStart(2) + r.EncodeArrayStart(3) } else { yynn2 = 1 for _, b := range yyq2 { @@ -329,6 +330,31 @@ func (x *ScaleStatus) CodecEncodeSelf(e *codec1978.Encoder) { } } } + if yyr2 || yy2arr2 { + z.EncSendContainerState(codecSelfer_containerArrayElem1234) + if yyq2[2] { + yym10 := z.EncBinary() + _ = yym10 + if false { + } else { + r.EncodeString(codecSelferC_UTF81234, string(x.TargetSelector)) + } + } else { + r.EncodeString(codecSelferC_UTF81234, "") + } + } else { + if yyq2[2] { + z.EncSendContainerState(codecSelfer_containerMapKey1234) + r.EncodeString(codecSelferC_UTF81234, string("targetSelector")) + z.EncSendContainerState(codecSelfer_containerMapValue1234) + yym11 := z.EncBinary() + _ = yym11 + if false { + } else { + r.EncodeString(codecSelferC_UTF81234, string(x.TargetSelector)) + } + } + } if yyr2 || yy2arr2 { z.EncSendContainerState(codecSelfer_containerArrayEnd1234) } else { @@ -408,6 +434,12 @@ func (x *ScaleStatus) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) { z.F.DecMapStringStringX(yyv5, false, d) } } + case "targetSelector": + if r.TryDecodeAsNil() { + x.TargetSelector = "" + } else { + x.TargetSelector = string(r.DecodeString()) + } default: z.DecStructFieldNotFound(-1, yys3) } // end switch yys3 @@ -419,16 +451,16 @@ func (x *ScaleStatus) 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 + var yyj8 int + var yyb8 bool + var yyhl8 bool = l >= 0 + yyj8++ + if yyhl8 { + yyb8 = yyj8 > l } else { - yyb7 = r.CheckBreak() + yyb8 = r.CheckBreak() } - if yyb7 { + if yyb8 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -438,13 +470,13 @@ func (x *ScaleStatus) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { } else { x.Replicas = int32(r.DecodeInt(32)) } - yyj7++ - if yyhl7 { - yyb7 = yyj7 > l + yyj8++ + if yyhl8 { + yyb8 = yyj8 > l } else { - yyb7 = r.CheckBreak() + yyb8 = r.CheckBreak() } - if yyb7 { + if yyb8 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -452,26 +484,42 @@ func (x *ScaleStatus) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { if r.TryDecodeAsNil() { x.Selector = nil } else { - yyv9 := &x.Selector - yym10 := z.DecBinary() - _ = yym10 + yyv10 := &x.Selector + yym11 := z.DecBinary() + _ = yym11 if false { } else { - z.F.DecMapStringStringX(yyv9, false, d) + z.F.DecMapStringStringX(yyv10, false, 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.TargetSelector = "" + } else { + x.TargetSelector = string(r.DecodeString()) + } for { - yyj7++ - if yyhl7 { - yyb7 = yyj7 > l + yyj8++ + if yyhl8 { + yyb8 = yyj8 > l } else { - yyb7 = r.CheckBreak() + yyb8 = r.CheckBreak() } - if yyb7 { + if yyb8 { break } z.DecSendContainerState(codecSelfer_containerArrayElem1234) - z.DecStructFieldNotFound(yyj7-1, "") + z.DecStructFieldNotFound(yyj8-1, "") } z.DecSendContainerState(codecSelfer_containerArrayEnd1234) } @@ -15914,7 +15962,7 @@ func (x *ReplicaSetSpec) CodecEncodeSelf(e *codec1978.Encoder) { const yyr2 bool = false yyq2[0] = x.Replicas != nil yyq2[1] = x.Selector != nil - yyq2[2] = x.Template != nil + yyq2[2] = true var yynn2 int if yyr2 || yy2arr2 { r.EncodeArrayStart(3) @@ -15989,11 +16037,8 @@ func (x *ReplicaSetSpec) CodecEncodeSelf(e *codec1978.Encoder) { if yyr2 || yy2arr2 { z.EncSendContainerState(codecSelfer_containerArrayElem1234) if yyq2[2] { - if x.Template == nil { - r.EncodeNil() - } else { - x.Template.CodecEncodeSelf(e) - } + yy12 := &x.Template + yy12.CodecEncodeSelf(e) } else { r.EncodeNil() } @@ -16002,11 +16047,8 @@ func (x *ReplicaSetSpec) CodecEncodeSelf(e *codec1978.Encoder) { z.EncSendContainerState(codecSelfer_containerMapKey1234) r.EncodeString(codecSelferC_UTF81234, string("template")) z.EncSendContainerState(codecSelfer_containerMapValue1234) - if x.Template == nil { - r.EncodeNil() - } else { - x.Template.CodecEncodeSelf(e) - } + yy14 := &x.Template + yy14.CodecEncodeSelf(e) } } if yyr2 || yy2arr2 { @@ -16099,14 +16141,10 @@ func (x *ReplicaSetSpec) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) { } case "template": if r.TryDecodeAsNil() { - if x.Template != nil { - x.Template = nil - } + x.Template = pkg2_v1.PodTemplateSpec{} } else { - if x.Template == nil { - x.Template = new(pkg2_v1.PodTemplateSpec) - } - x.Template.CodecDecodeSelf(d) + yyv7 := &x.Template + yyv7.CodecDecodeSelf(d) } default: z.DecStructFieldNotFound(-1, yys3) @@ -16181,14 +16219,10 @@ func (x *ReplicaSetSpec) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { } z.DecSendContainerState(codecSelfer_containerArrayElem1234) if r.TryDecodeAsNil() { - if x.Template != nil { - x.Template = nil - } + x.Template = pkg2_v1.PodTemplateSpec{} } else { - if x.Template == nil { - x.Template = new(pkg2_v1.PodTemplateSpec) - } - x.Template.CodecDecodeSelf(d) + yyv12 := &x.Template + yyv12.CodecDecodeSelf(d) } for { yyj8++ @@ -16220,13 +16254,14 @@ func (x *ReplicaSetStatus) CodecEncodeSelf(e *codec1978.Encoder) { } else { yysep2 := !z.EncBinary() yy2arr2 := z.EncBasicHandle().StructToArray - var yyq2 [2]bool + var yyq2 [3]bool _, _, _ = yysep2, yyq2, yy2arr2 const yyr2 bool = false - yyq2[1] = x.ObservedGeneration != 0 + yyq2[1] = x.FullyLabeledReplicas != 0 + yyq2[2] = x.ObservedGeneration != 0 var yynn2 int if yyr2 || yy2arr2 { - r.EncodeArrayStart(2) + r.EncodeArrayStart(3) } else { yynn2 = 1 for _, b := range yyq2 { @@ -16263,7 +16298,7 @@ func (x *ReplicaSetStatus) CodecEncodeSelf(e *codec1978.Encoder) { _ = yym7 if false { } else { - r.EncodeInt(int64(x.ObservedGeneration)) + r.EncodeInt(int64(x.FullyLabeledReplicas)) } } else { r.EncodeInt(0) @@ -16271,11 +16306,36 @@ func (x *ReplicaSetStatus) CodecEncodeSelf(e *codec1978.Encoder) { } else { if yyq2[1] { z.EncSendContainerState(codecSelfer_containerMapKey1234) - r.EncodeString(codecSelferC_UTF81234, string("observedGeneration")) + r.EncodeString(codecSelferC_UTF81234, string("fullyLabeledReplicas")) z.EncSendContainerState(codecSelfer_containerMapValue1234) yym8 := z.EncBinary() _ = yym8 if false { + } else { + r.EncodeInt(int64(x.FullyLabeledReplicas)) + } + } + } + if yyr2 || yy2arr2 { + z.EncSendContainerState(codecSelfer_containerArrayElem1234) + if yyq2[2] { + yym10 := z.EncBinary() + _ = yym10 + if false { + } else { + r.EncodeInt(int64(x.ObservedGeneration)) + } + } else { + r.EncodeInt(0) + } + } else { + if yyq2[2] { + z.EncSendContainerState(codecSelfer_containerMapKey1234) + r.EncodeString(codecSelferC_UTF81234, string("observedGeneration")) + z.EncSendContainerState(codecSelfer_containerMapValue1234) + yym11 := z.EncBinary() + _ = yym11 + if false { } else { r.EncodeInt(int64(x.ObservedGeneration)) } @@ -16348,6 +16408,12 @@ func (x *ReplicaSetStatus) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) { } else { x.Replicas = int32(r.DecodeInt(32)) } + case "fullyLabeledReplicas": + if r.TryDecodeAsNil() { + x.FullyLabeledReplicas = 0 + } else { + x.FullyLabeledReplicas = int32(r.DecodeInt(32)) + } case "observedGeneration": if r.TryDecodeAsNil() { x.ObservedGeneration = 0 @@ -16365,16 +16431,16 @@ func (x *ReplicaSetStatus) 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 + var yyj7 int + var yyb7 bool + var yyhl7 bool = l >= 0 + yyj7++ + if yyhl7 { + yyb7 = yyj7 > l } else { - yyb6 = r.CheckBreak() + yyb7 = r.CheckBreak() } - if yyb6 { + if yyb7 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -16384,13 +16450,29 @@ func (x *ReplicaSetStatus) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) } else { x.Replicas = int32(r.DecodeInt(32)) } - yyj6++ - if yyhl6 { - yyb6 = yyj6 > l + yyj7++ + if yyhl7 { + yyb7 = yyj7 > l } else { - yyb6 = r.CheckBreak() + yyb7 = r.CheckBreak() } - if yyb6 { + if yyb7 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) + return + } + z.DecSendContainerState(codecSelfer_containerArrayElem1234) + if r.TryDecodeAsNil() { + x.FullyLabeledReplicas = 0 + } else { + x.FullyLabeledReplicas = int32(r.DecodeInt(32)) + } + yyj7++ + if yyhl7 { + yyb7 = yyj7 > l + } else { + yyb7 = r.CheckBreak() + } + if yyb7 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -16401,17 +16483,17 @@ func (x *ReplicaSetStatus) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) x.ObservedGeneration = int64(r.DecodeInt(64)) } for { - yyj6++ - if yyhl6 { - yyb6 = yyj6 > l + yyj7++ + if yyhl7 { + yyb7 = yyj7 > l } else { - yyb6 = r.CheckBreak() + yyb7 = r.CheckBreak() } - if yyb6 { + if yyb7 { break } z.DecSendContainerState(codecSelfer_containerArrayElem1234) - z.DecStructFieldNotFound(yyj6-1, "") + z.DecStructFieldNotFound(yyj7-1, "") } z.DecSendContainerState(codecSelfer_containerArrayEnd1234) } @@ -16958,7 +17040,7 @@ func (x *PodSecurityPolicySpec) CodecEncodeSelf(e *codec1978.Encoder) { if yyr2 || yy2arr2 { z.EncSendContainerState(codecSelfer_containerArrayElem1234) if yyq2[7] { - yy25 := &x.SELinuxContext + yy25 := &x.SELinux yy25.CodecEncodeSelf(e) } else { r.EncodeNil() @@ -16966,9 +17048,9 @@ func (x *PodSecurityPolicySpec) CodecEncodeSelf(e *codec1978.Encoder) { } else { if yyq2[7] { z.EncSendContainerState(codecSelfer_containerMapKey1234) - r.EncodeString(codecSelferC_UTF81234, string("seLinuxContext")) + r.EncodeString(codecSelferC_UTF81234, string("seLinux")) z.EncSendContainerState(codecSelfer_containerMapValue1234) - yy27 := &x.SELinuxContext + yy27 := &x.SELinux yy27.CodecEncodeSelf(e) } } @@ -17110,11 +17192,11 @@ func (x *PodSecurityPolicySpec) codecDecodeSelfFromMap(l int, d *codec1978.Decod } else { x.HostIPC = bool(r.DecodeBool()) } - case "seLinuxContext": + case "seLinux": if r.TryDecodeAsNil() { - x.SELinuxContext = SELinuxContextStrategyOptions{} + x.SELinux = SELinuxStrategyOptions{} } else { - yyv14 := &x.SELinuxContext + yyv14 := &x.SELinux yyv14.CodecDecodeSelf(d) } case "runAsUser": @@ -17280,9 +17362,9 @@ func (x *PodSecurityPolicySpec) codecDecodeSelfFromArray(l int, d *codec1978.Dec } z.DecSendContainerState(codecSelfer_containerArrayElem1234) if r.TryDecodeAsNil() { - x.SELinuxContext = SELinuxContextStrategyOptions{} + x.SELinux = SELinuxStrategyOptions{} } else { - yyv27 := &x.SELinuxContext + yyv27 := &x.SELinux yyv27.CodecDecodeSelf(d) } yyj16++ @@ -17547,7 +17629,7 @@ func (x *HostPortRange) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) } -func (x *SELinuxContextStrategyOptions) CodecEncodeSelf(e *codec1978.Encoder) { +func (x *SELinuxStrategyOptions) CodecEncodeSelf(e *codec1978.Encoder) { var h codecSelfer1234 z, r := codec1978.GenHelperEncoder(e) _, _, _ = h, z, r @@ -17580,12 +17662,12 @@ func (x *SELinuxContextStrategyOptions) CodecEncodeSelf(e *codec1978.Encoder) { } if yyr2 || yy2arr2 { z.EncSendContainerState(codecSelfer_containerArrayElem1234) - x.Type.CodecEncodeSelf(e) + x.Rule.CodecEncodeSelf(e) } else { z.EncSendContainerState(codecSelfer_containerMapKey1234) - r.EncodeString(codecSelferC_UTF81234, string("type")) + r.EncodeString(codecSelferC_UTF81234, string("rule")) z.EncSendContainerState(codecSelfer_containerMapValue1234) - x.Type.CodecEncodeSelf(e) + x.Rule.CodecEncodeSelf(e) } if yyr2 || yy2arr2 { z.EncSendContainerState(codecSelfer_containerArrayElem1234) @@ -17619,7 +17701,7 @@ func (x *SELinuxContextStrategyOptions) CodecEncodeSelf(e *codec1978.Encoder) { } } -func (x *SELinuxContextStrategyOptions) CodecDecodeSelf(d *codec1978.Decoder) { +func (x *SELinuxStrategyOptions) CodecDecodeSelf(d *codec1978.Decoder) { var h codecSelfer1234 z, r := codec1978.GenHelperDecoder(d) _, _, _ = h, z, r @@ -17649,7 +17731,7 @@ func (x *SELinuxContextStrategyOptions) CodecDecodeSelf(d *codec1978.Decoder) { } } -func (x *SELinuxContextStrategyOptions) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) { +func (x *SELinuxStrategyOptions) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) { var h codecSelfer1234 z, r := codec1978.GenHelperDecoder(d) _, _, _ = h, z, r @@ -17671,11 +17753,11 @@ func (x *SELinuxContextStrategyOptions) codecDecodeSelfFromMap(l int, d *codec19 yys3 := string(yys3Slc) z.DecSendContainerState(codecSelfer_containerMapValue1234) switch yys3 { - case "type": + case "rule": if r.TryDecodeAsNil() { - x.Type = "" + x.Rule = "" } else { - x.Type = SELinuxContextStrategy(r.DecodeString()) + x.Rule = SELinuxStrategy(r.DecodeString()) } case "seLinuxOptions": if r.TryDecodeAsNil() { @@ -17695,7 +17777,7 @@ func (x *SELinuxContextStrategyOptions) codecDecodeSelfFromMap(l int, d *codec19 z.DecSendContainerState(codecSelfer_containerMapEnd1234) } -func (x *SELinuxContextStrategyOptions) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { +func (x *SELinuxStrategyOptions) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { var h codecSelfer1234 z, r := codec1978.GenHelperDecoder(d) _, _, _ = h, z, r @@ -17714,9 +17796,9 @@ func (x *SELinuxContextStrategyOptions) codecDecodeSelfFromArray(l int, d *codec } z.DecSendContainerState(codecSelfer_containerArrayElem1234) if r.TryDecodeAsNil() { - x.Type = "" + x.Rule = "" } else { - x.Type = SELinuxContextStrategy(r.DecodeString()) + x.Rule = SELinuxStrategy(r.DecodeString()) } yyj6++ if yyhl6 { @@ -17755,7 +17837,7 @@ func (x *SELinuxContextStrategyOptions) codecDecodeSelfFromArray(l int, d *codec z.DecSendContainerState(codecSelfer_containerArrayEnd1234) } -func (x SELinuxContextStrategy) CodecEncodeSelf(e *codec1978.Encoder) { +func (x SELinuxStrategy) CodecEncodeSelf(e *codec1978.Encoder) { var h codecSelfer1234 z, r := codec1978.GenHelperEncoder(e) _, _, _ = h, z, r @@ -17768,7 +17850,7 @@ func (x SELinuxContextStrategy) CodecEncodeSelf(e *codec1978.Encoder) { } } -func (x *SELinuxContextStrategy) CodecDecodeSelf(d *codec1978.Decoder) { +func (x *SELinuxStrategy) CodecDecodeSelf(d *codec1978.Decoder) { var h codecSelfer1234 z, r := codec1978.GenHelperDecoder(d) _, _, _ = h, z, r @@ -17814,12 +17896,12 @@ func (x *RunAsUserStrategyOptions) CodecEncodeSelf(e *codec1978.Encoder) { } if yyr2 || yy2arr2 { z.EncSendContainerState(codecSelfer_containerArrayElem1234) - x.Type.CodecEncodeSelf(e) + x.Rule.CodecEncodeSelf(e) } else { z.EncSendContainerState(codecSelfer_containerMapKey1234) - r.EncodeString(codecSelferC_UTF81234, string("type")) + r.EncodeString(codecSelferC_UTF81234, string("rule")) z.EncSendContainerState(codecSelfer_containerMapValue1234) - x.Type.CodecEncodeSelf(e) + x.Rule.CodecEncodeSelf(e) } if yyr2 || yy2arr2 { z.EncSendContainerState(codecSelfer_containerArrayElem1234) @@ -17915,11 +17997,11 @@ func (x *RunAsUserStrategyOptions) codecDecodeSelfFromMap(l int, d *codec1978.De yys3 := string(yys3Slc) z.DecSendContainerState(codecSelfer_containerMapValue1234) switch yys3 { - case "type": + case "rule": if r.TryDecodeAsNil() { - x.Type = "" + x.Rule = "" } else { - x.Type = RunAsUserStrategy(r.DecodeString()) + x.Rule = RunAsUserStrategy(r.DecodeString()) } case "ranges": if r.TryDecodeAsNil() { @@ -17959,9 +18041,9 @@ func (x *RunAsUserStrategyOptions) codecDecodeSelfFromArray(l int, d *codec1978. } z.DecSendContainerState(codecSelfer_containerArrayElem1234) if r.TryDecodeAsNil() { - x.Type = "" + x.Rule = "" } else { - x.Type = RunAsUserStrategy(r.DecodeString()) + x.Rule = RunAsUserStrategy(r.DecodeString()) } yyj7++ if yyhl7 { @@ -20398,7 +20480,7 @@ func (x codecSelfer1234) decSliceReplicaSet(v *[]ReplicaSet, d *codec1978.Decode yyrg1 := len(yyv1) > 0 yyv21 := yyv1 - yyrl1, yyrt1 = z.DecInferLen(yyl1, z.DecBasicHandle().MaxInitLen, 232) + yyrl1, yyrt1 = z.DecInferLen(yyl1, z.DecBasicHandle().MaxInitLen, 576) if yyrt1 { if yyrl1 <= cap(yyv1) { yyv1 = yyv1[:yyrl1] 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 36fc26f..1a67438 100644 --- a/vendor/k8s.io/kubernetes/pkg/apis/extensions/v1beta1/types.go +++ b/vendor/k8s.io/kubernetes/pkg/apis/extensions/v1beta1/types.go @@ -34,8 +34,16 @@ type ScaleStatus struct { // actual number of observed instances of the scaled object. Replicas int32 `json:"replicas"` - // label query over pods that should match the replicas count. More info: http://releases.k8s.io/HEAD/docs/user-guide/labels.md#label-selectors + // label query over pods that should match the replicas count. More info: http://releases.k8s.io/release-1.2/docs/user-guide/labels.md#label-selectors Selector map[string]string `json:"selector,omitempty"` + + // label selector for pods that should match the replicas count. This is a serializated + // version of both map-based and more expressive set-based selectors. This is done to + // avoid introspection in the clients. The string will be in the same format as the + // query-param syntax. If the target type only supports map-based selectors, both this + // field and map-based selector field are populated. + // More info: http://releases.k8s.io/release-1.2/docs/user-guide/labels.md#label-selectors + TargetSelector string `json:"targetSelector,omitempty"` } // +genclient=true,noMethods=true @@ -43,13 +51,13 @@ type ScaleStatus struct { // represents a scaling request for a resource. type Scale struct { unversioned.TypeMeta `json:",inline"` - // Standard object metadata; More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata. + // Standard object metadata; More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#metadata. v1.ObjectMeta `json:"metadata,omitempty"` - // defines the behavior of the scale. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#spec-and-status. + // defines the behavior of the scale. More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#spec-and-status. Spec ScaleSpec `json:"spec,omitempty"` - // current status of the scale. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#spec-and-status. Read-only. + // current status of the scale. More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#spec-and-status. Read-only. Status ScaleStatus `json:"status,omitempty"` } @@ -60,9 +68,9 @@ type ReplicationControllerDummy struct { // SubresourceReference contains enough information to let you inspect or modify the referred subresource. type SubresourceReference struct { - // Kind of the referent; More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds" + // Kind of the referent; More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#types-kinds" Kind string `json:"kind,omitempty"` - // Name of the referent; More info: http://releases.k8s.io/HEAD/docs/user-guide/identifiers.md#names + // Name of the referent; More info: http://releases.k8s.io/release-1.2/docs/user-guide/identifiers.md#names Name string `json:"name,omitempty"` // API version of the referent APIVersion string `json:"apiVersion,omitempty"` @@ -138,10 +146,10 @@ type HorizontalPodAutoscalerStatus struct { // configuration of a horizontal pod autoscaler. type HorizontalPodAutoscaler struct { unversioned.TypeMeta `json:",inline"` - // Standard object metadata. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata + // Standard object metadata. More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#metadata v1.ObjectMeta `json:"metadata,omitempty"` - // behaviour of autoscaler. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#spec-and-status. + // behaviour of autoscaler. More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#spec-and-status. Spec HorizontalPodAutoscalerSpec `json:"spec,omitempty"` // current information about the autoscaler. @@ -405,14 +413,14 @@ type DaemonSetSpec struct { // Selector is a label query over pods that are managed by the daemon set. // Must match in order to be controlled. // If empty, defaulted to labels on Pod template. - // More info: http://releases.k8s.io/HEAD/docs/user-guide/labels.md#label-selectors + // More info: http://releases.k8s.io/release-1.2/docs/user-guide/labels.md#label-selectors Selector *LabelSelector `json:"selector,omitempty"` // Template is the object that describes the pod that will be created. // The DaemonSet will create exactly one copy of this pod on every node // that matches the template's node selector (or on every node if no node // selector is specified). - // More info: http://releases.k8s.io/HEAD/docs/user-guide/replication-controller.md#pod-template + // More info: http://releases.k8s.io/release-1.2/docs/user-guide/replication-controller.md#pod-template Template v1.PodTemplateSpec `json:"template"` // TODO(madhusudancs): Uncomment while implementing DaemonSet updates. @@ -442,17 +450,17 @@ const ( type DaemonSetStatus struct { // CurrentNumberScheduled is the number of nodes that are running at least 1 // daemon pod and are supposed to run the daemon pod. - // More info: http://releases.k8s.io/HEAD/docs/admin/daemon.md + // More info: http://releases.k8s.io/release-1.2/docs/admin/daemons.md CurrentNumberScheduled int32 `json:"currentNumberScheduled"` // NumberMisscheduled is the number of nodes that are running the daemon pod, but are // not supposed to run the daemon pod. - // More info: http://releases.k8s.io/HEAD/docs/admin/daemon.md + // More info: http://releases.k8s.io/release-1.2/docs/admin/daemons.md NumberMisscheduled int32 `json:"numberMisscheduled"` // DesiredNumberScheduled is the total number of nodes that should be running the daemon // pod (including nodes correctly running the daemon pod). - // More info: http://releases.k8s.io/HEAD/docs/admin/daemon.md + // More info: http://releases.k8s.io/release-1.2/docs/admin/daemons.md DesiredNumberScheduled int32 `json:"desiredNumberScheduled"` } @@ -462,18 +470,18 @@ type DaemonSetStatus struct { type DaemonSet struct { unversioned.TypeMeta `json:",inline"` // Standard object's metadata. - // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata + // More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#metadata v1.ObjectMeta `json:"metadata,omitempty"` // Spec defines the desired behavior of this daemon set. - // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#spec-and-status + // More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#spec-and-status Spec DaemonSetSpec `json:"spec,omitempty"` // Status is the current status of this daemon set. This data may be // out of date by some window of time. // Populated by the system. // Read-only. - // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#spec-and-status + // More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#spec-and-status Status DaemonSetStatus `json:"status,omitempty"` } @@ -481,7 +489,7 @@ type DaemonSet struct { type DaemonSetList struct { unversioned.TypeMeta `json:",inline"` // Standard list metadata. - // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata + // More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#metadata unversioned.ListMeta `json:"metadata,omitempty"` // Items is a list of daemon sets. @@ -492,7 +500,7 @@ type DaemonSetList struct { type ThirdPartyResourceDataList struct { unversioned.TypeMeta `json:",inline"` // Standard list metadata - // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata + // More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#metadata unversioned.ListMeta `json:"metadata,omitempty"` // Items is the list of ThirdpartyResourceData. @@ -505,15 +513,15 @@ type ThirdPartyResourceDataList struct { type Job struct { unversioned.TypeMeta `json:",inline"` // Standard object's metadata. - // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata + // More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#metadata v1.ObjectMeta `json:"metadata,omitempty"` // Spec is a structure defining the expected behavior of a job. - // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#spec-and-status + // More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#spec-and-status Spec JobSpec `json:"spec,omitempty"` // Status is a structure describing current status of a job. - // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#spec-and-status + // More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#spec-and-status Status JobStatus `json:"status,omitempty"` } @@ -521,7 +529,7 @@ type Job struct { type JobList struct { unversioned.TypeMeta `json:",inline"` // Standard list metadata - // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata + // More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#metadata unversioned.ListMeta `json:"metadata,omitempty"` // Items is the list of Job. @@ -535,7 +543,7 @@ type JobSpec struct { // run at any given time. The actual number of pods running in steady state will // be less than this number when ((.spec.completions - .status.successful) < .spec.parallelism), // i.e. when the work left to do is less than max parallelism. - // More info: http://releases.k8s.io/HEAD/docs/user-guide/jobs.md + // More info: http://releases.k8s.io/release-1.2/docs/user-guide/jobs.md Parallelism *int32 `json:"parallelism,omitempty"` // Completions specifies the desired number of successfully finished pods the @@ -543,7 +551,7 @@ type JobSpec struct { // pod signals the success of all pods, and allows parallelism to have any positive // value. Setting to 1 means that parallelism is limited to 1 and the success of that // pod signals the success of the job. - // More info: http://releases.k8s.io/HEAD/docs/user-guide/jobs.md + // More info: http://releases.k8s.io/release-1.2/docs/user-guide/jobs.md Completions *int32 `json:"completions,omitempty"` // Optional duration in seconds relative to the startTime that the job may be active @@ -552,19 +560,19 @@ type JobSpec struct { // Selector is a label query over pods that should match the pod count. // Normally, the system sets this field for you. - // More info: http://releases.k8s.io/HEAD/docs/user-guide/labels.md#label-selectors + // More info: http://releases.k8s.io/release-1.2/docs/user-guide/labels.md#label-selectors Selector *LabelSelector `json:"selector,omitempty"` // AutoSelector controls generation of pod labels and pod selectors. // It was not present in the original extensions/v1beta1 Job definition, but exists // to allow conversion from batch/v1 Jobs, where it corresponds to, but has the opposite // meaning as, ManualSelector. - // More info: http://releases.k8s.io/HEAD/docs/design/selector-generation.md + // More info: http://releases.k8s.io/release-1.2/docs/design/selector-generation.md AutoSelector *bool `json:"autoSelector,omitempty"` // Template is the object that describes the pod that will be created when // executing a job. - // More info: http://releases.k8s.io/HEAD/docs/user-guide/jobs.md + // More info: http://releases.k8s.io/release-1.2/docs/user-guide/jobs.md Template v1.PodTemplateSpec `json:"template"` } @@ -572,7 +580,7 @@ type JobSpec struct { type JobStatus struct { // Conditions represent the latest available observations of an object's current state. - // More info: http://releases.k8s.io/HEAD/docs/user-guide/jobs.md + // More info: http://releases.k8s.io/release-1.2/docs/user-guide/jobs.md Conditions []JobCondition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type"` // StartTime represents time when the job was acknowledged by the Job Manager. @@ -630,15 +638,15 @@ type JobCondition struct { type Ingress struct { unversioned.TypeMeta `json:",inline"` // Standard object's metadata. - // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata + // More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#metadata v1.ObjectMeta `json:"metadata,omitempty"` // Spec is the desired state of the Ingress. - // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#spec-and-status + // More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#spec-and-status Spec IngressSpec `json:"spec,omitempty"` // Status is the current state of the Ingress. - // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#spec-and-status + // More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#spec-and-status Status IngressStatus `json:"status,omitempty"` } @@ -646,7 +654,7 @@ type Ingress struct { type IngressList struct { unversioned.TypeMeta `json:",inline"` // Standard object's metadata. - // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata + // More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#metadata unversioned.ListMeta `json:"metadata,omitempty"` // Items is the list of Ingress. @@ -846,18 +854,18 @@ type ReplicaSet struct { // If the Labels of a ReplicaSet are empty, they are defaulted to // be the same as the Pod(s) that the ReplicaSet manages. - // Standard object's metadata. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata + // Standard object's metadata. More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#metadata v1.ObjectMeta `json:"metadata,omitempty"` // Spec defines the specification of the desired behavior of the ReplicaSet. - // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#spec-and-status + // More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#spec-and-status Spec ReplicaSetSpec `json:"spec,omitempty"` // Status is the most recently observed status of the ReplicaSet. // This data may be out of date by some window of time. // Populated by the system. // Read-only. - // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#spec-and-status + // More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#spec-and-status Status ReplicaSetStatus `json:"status,omitempty"` } @@ -865,11 +873,11 @@ type ReplicaSet struct { type ReplicaSetList struct { unversioned.TypeMeta `json:",inline"` // Standard list metadata. - // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds + // More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#types-kinds unversioned.ListMeta `json:"metadata,omitempty"` // List of ReplicaSets. - // More info: http://releases.k8s.io/HEAD/docs/user-guide/replication-controller.md + // More info: http://releases.k8s.io/release-1.2/docs/user-guide/replication-controller.md Items []ReplicaSet `json:"items"` } @@ -878,27 +886,30 @@ type ReplicaSetSpec struct { // Replicas is the number of desired replicas. // This is a pointer to distinguish between explicit zero and unspecified. // Defaults to 1. - // More info: http://releases.k8s.io/HEAD/docs/user-guide/replication-controller.md#what-is-a-replication-controller + // More info: http://releases.k8s.io/release-1.2/docs/user-guide/replication-controller.md#what-is-a-replication-controller Replicas *int32 `json:"replicas,omitempty"` // Selector is a label query over pods that should match the replica count. // If the selector is empty, it is defaulted to the labels present on the pod template. // Label keys and values that must match in order to be controlled by this replica set. - // More info: http://releases.k8s.io/HEAD/docs/user-guide/labels.md#label-selectors + // More info: http://releases.k8s.io/release-1.2/docs/user-guide/labels.md#label-selectors Selector *LabelSelector `json:"selector,omitempty"` // Template is the object that describes the pod that will be created if // insufficient replicas are detected. - // More info: http://releases.k8s.io/HEAD/docs/user-guide/replication-controller.md#pod-template - Template *v1.PodTemplateSpec `json:"template,omitempty"` + // More info: http://releases.k8s.io/release-1.2/docs/user-guide/replication-controller.md#pod-template + Template v1.PodTemplateSpec `json:"template,omitempty"` } // ReplicaSetStatus represents the current status of a ReplicaSet. type ReplicaSetStatus struct { // Replicas is the most recently oberved number of replicas. - // More info: http://releases.k8s.io/HEAD/docs/user-guide/replication-controller.md#what-is-a-replication-controller + // More info: http://releases.k8s.io/release-1.2/docs/user-guide/replication-controller.md#what-is-a-replication-controller Replicas int32 `json:"replicas"` + // The number of pods that have labels matching the labels of the pod template of the replicaset. + FullyLabeledReplicas int32 `json:"fullyLabeledReplicas,omitempty"` + // ObservedGeneration reflects the generation of the most recently observed ReplicaSet. ObservedGeneration int64 `json:"observedGeneration,omitempty"` } @@ -908,7 +919,7 @@ type ReplicaSetStatus struct { type PodSecurityPolicy struct { unversioned.TypeMeta `json:",inline"` // Standard object's metadata. - // More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata + // More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#metadata v1.ObjectMeta `json:"metadata,omitempty"` // spec defines the policy enforced. @@ -932,8 +943,8 @@ type PodSecurityPolicySpec struct { HostPID bool `json:"hostPID,omitempty"` // hostIPC determines if the policy allows the use of HostIPC in the pod spec. HostIPC bool `json:"hostIPC,omitempty"` - // seLinuxContext is the strategy that will dictate the allowable labels that may be set. - SELinuxContext SELinuxContextStrategyOptions `json:"seLinuxContext,omitempty"` + // seLinux is the strategy that will dictate the allowable labels that may be set. + SELinux SELinuxStrategyOptions `json:"seLinux,omitempty"` // runAsUser is the strategy that will dictate the allowable RunAsUser values that may be set. RunAsUser RunAsUserStrategyOptions `json:"runAsUser,omitempty"` } @@ -968,30 +979,30 @@ type HostPortRange struct { Max int32 `json:"max"` } -// SELinux Context Strategy Options defines the strategy type and any options used to create the strategy. -type SELinuxContextStrategyOptions struct { +// SELinux Strategy Options defines the strategy type and any options used to create the strategy. +type SELinuxStrategyOptions struct { // type is the strategy that will dictate the allowable labels that may be set. - Type SELinuxContextStrategy `json:"type"` + Rule SELinuxStrategy `json:"rule"` // seLinuxOptions required to run as; required for MustRunAs - // More info: http://releases.k8s.io/HEAD/docs/design/security_context.md#security-context + // More info: http://releases.k8s.io/release-1.2/docs/design/security_context.md#security-context SELinuxOptions *v1.SELinuxOptions `json:"seLinuxOptions,omitempty"` } -// SELinux Context Strategy Type denotes strategy types for generating SELinux options for a +// SELinuxStrategy denotes strategy types for generating SELinux options for a // Security Context. -type SELinuxContextStrategy string +type SELinuxStrategy string const ( // container must have SELinux labels of X applied. - SELinuxStrategyMustRunAs SELinuxContextStrategy = "MustRunAs" + SELinuxStrategyMustRunAs SELinuxStrategy = "MustRunAs" // container may make requests for any SELinux context labels. - SELinuxStrategyRunAsAny SELinuxContextStrategy = "RunAsAny" + SELinuxStrategyRunAsAny SELinuxStrategy = "RunAsAny" ) // Run A sUser Strategy Options defines the strategy type and any options used to create the strategy. type RunAsUserStrategyOptions struct { - // type is the strategy that will dictate the allowable RunAsUser values that may be set. - Type RunAsUserStrategy `json:"type"` + // Rule is the strategy that will dictate the allowable RunAsUser values that may be set. + Rule RunAsUserStrategy `json:"rule"` // Ranges are the allowed ranges of uids that may be used. Ranges []IDRange `json:"ranges,omitempty"` } @@ -1004,7 +1015,7 @@ type IDRange struct { Max int64 `json:"max"` } -// Run As User Strategy Type denotes strategy types for generating RunAsUser values for a +// RunAsUserStrategy denotes strategy types for generating RunAsUser values for a // Security Context. type RunAsUserStrategy string @@ -1021,7 +1032,7 @@ const ( type PodSecurityPolicyList struct { unversioned.TypeMeta `json:",inline"` // Standard list metadata. - // More info: http://docs.k8s.io/api-conventions.md#metadata + // More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#metadata unversioned.ListMeta `json:"metadata,omitempty"` // Items is a list of schema objects. 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 1cd5d3f..44e4462 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 @@ -66,9 +66,9 @@ func (CustomMetricTarget) SwaggerDoc() map[string]string { var map_DaemonSet = map[string]string{ "": "DaemonSet represents the configuration of a daemon set.", - "metadata": "Standard object's metadata. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata", - "spec": "Spec defines the desired behavior of this daemon set. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#spec-and-status", - "status": "Status is the current status of this daemon set. This data may be out of date by some window of time. Populated by the system. Read-only. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#spec-and-status", + "metadata": "Standard object's metadata. More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#metadata", + "spec": "Spec defines the desired behavior of this daemon set. More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#spec-and-status", + "status": "Status is the current status of this daemon set. This data may be out of date by some window of time. Populated by the system. Read-only. More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#spec-and-status", } func (DaemonSet) SwaggerDoc() map[string]string { @@ -77,7 +77,7 @@ func (DaemonSet) SwaggerDoc() map[string]string { var map_DaemonSetList = map[string]string{ "": "DaemonSetList is a collection of daemon sets.", - "metadata": "Standard list metadata. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata", + "metadata": "Standard list metadata. More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#metadata", "items": "Items is a list of daemon sets.", } @@ -87,8 +87,8 @@ func (DaemonSetList) SwaggerDoc() map[string]string { var map_DaemonSetSpec = map[string]string{ "": "DaemonSetSpec is the specification of a daemon set.", - "selector": "Selector is a label query over pods that are managed by the daemon set. Must match in order to be controlled. If empty, defaulted to labels on Pod template. More info: http://releases.k8s.io/HEAD/docs/user-guide/labels.md#label-selectors", - "template": "Template is the object that describes the pod that will be created. The DaemonSet will create exactly one copy of this pod on every node that matches the template's node selector (or on every node if no node selector is specified). More info: http://releases.k8s.io/HEAD/docs/user-guide/replication-controller.md#pod-template", + "selector": "Selector is a label query over pods that are managed by the daemon set. Must match in order to be controlled. If empty, defaulted to labels on Pod template. More info: http://releases.k8s.io/release-1.2/docs/user-guide/labels.md#label-selectors", + "template": "Template is the object that describes the pod that will be created. The DaemonSet will create exactly one copy of this pod on every node that matches the template's node selector (or on every node if no node selector is specified). More info: http://releases.k8s.io/release-1.2/docs/user-guide/replication-controller.md#pod-template", } func (DaemonSetSpec) SwaggerDoc() map[string]string { @@ -97,9 +97,9 @@ func (DaemonSetSpec) SwaggerDoc() map[string]string { var map_DaemonSetStatus = map[string]string{ "": "DaemonSetStatus represents the current status of a daemon set.", - "currentNumberScheduled": "CurrentNumberScheduled is the number of nodes that are running at least 1 daemon pod and are supposed to run the daemon pod. More info: http://releases.k8s.io/HEAD/docs/admin/daemon.md", - "numberMisscheduled": "NumberMisscheduled is the number of nodes that are running the daemon pod, but are not supposed to run the daemon pod. More info: http://releases.k8s.io/HEAD/docs/admin/daemon.md", - "desiredNumberScheduled": "DesiredNumberScheduled is the total number of nodes that should be running the daemon pod (including nodes correctly running the daemon pod). More info: http://releases.k8s.io/HEAD/docs/admin/daemon.md", + "currentNumberScheduled": "CurrentNumberScheduled is the number of nodes that are running at least 1 daemon pod and are supposed to run the daemon pod. More info: http://releases.k8s.io/release-1.2/docs/admin/daemons.md", + "numberMisscheduled": "NumberMisscheduled is the number of nodes that are running the daemon pod, but are not supposed to run the daemon pod. More info: http://releases.k8s.io/release-1.2/docs/admin/daemons.md", + "desiredNumberScheduled": "DesiredNumberScheduled is the total number of nodes that should be running the daemon pod (including nodes correctly running the daemon pod). More info: http://releases.k8s.io/release-1.2/docs/admin/daemons.md", } func (DaemonSetStatus) SwaggerDoc() map[string]string { @@ -208,8 +208,8 @@ func (HTTPIngressRuleValue) SwaggerDoc() map[string]string { var map_HorizontalPodAutoscaler = map[string]string{ "": "configuration of a horizontal pod autoscaler.", - "metadata": "Standard object metadata. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata", - "spec": "behaviour of autoscaler. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#spec-and-status.", + "metadata": "Standard object metadata. More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#metadata", + "spec": "behaviour of autoscaler. More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#spec-and-status.", "status": "current information about the autoscaler.", } @@ -274,9 +274,9 @@ func (IDRange) SwaggerDoc() map[string]string { var map_Ingress = map[string]string{ "": "Ingress is a collection of rules that allow inbound connections to reach the endpoints defined by a backend. An Ingress can be configured to give services externally-reachable urls, load balance traffic, terminate SSL, offer name based virtual hosting etc.", - "metadata": "Standard object's metadata. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata", - "spec": "Spec is the desired state of the Ingress. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#spec-and-status", - "status": "Status is the current state of the Ingress. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#spec-and-status", + "metadata": "Standard object's metadata. More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#metadata", + "spec": "Spec is the desired state of the Ingress. More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#spec-and-status", + "status": "Status is the current state of the Ingress. More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#spec-and-status", } func (Ingress) SwaggerDoc() map[string]string { @@ -295,7 +295,7 @@ func (IngressBackend) SwaggerDoc() map[string]string { var map_IngressList = map[string]string{ "": "IngressList is a collection of Ingress.", - "metadata": "Standard object's metadata. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata", + "metadata": "Standard object's metadata. More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#metadata", "items": "Items is the list of Ingress.", } @@ -352,9 +352,9 @@ func (IngressTLS) SwaggerDoc() map[string]string { var map_Job = map[string]string{ "": "Job represents the configuration of a single job.", - "metadata": "Standard object's metadata. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata", - "spec": "Spec is a structure defining the expected behavior of a job. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#spec-and-status", - "status": "Status is a structure describing current status of a job. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#spec-and-status", + "metadata": "Standard object's metadata. More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#metadata", + "spec": "Spec is a structure defining the expected behavior of a job. More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#spec-and-status", + "status": "Status is a structure describing current status of a job. More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#spec-and-status", } func (Job) SwaggerDoc() map[string]string { @@ -377,7 +377,7 @@ func (JobCondition) SwaggerDoc() map[string]string { var map_JobList = map[string]string{ "": "JobList is a collection of jobs.", - "metadata": "Standard list metadata More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata", + "metadata": "Standard list metadata More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#metadata", "items": "Items is the list of Job.", } @@ -387,12 +387,12 @@ func (JobList) SwaggerDoc() map[string]string { var map_JobSpec = map[string]string{ "": "JobSpec describes how the job execution will look like.", - "parallelism": "Parallelism specifies the maximum desired number of pods the job should run at any given time. The actual number of pods running in steady state will be less than this number when ((.spec.completions - .status.successful) < .spec.parallelism), i.e. when the work left to do is less than max parallelism. More info: http://releases.k8s.io/HEAD/docs/user-guide/jobs.md", - "completions": "Completions specifies the desired number of successfully finished pods the job should be run with. Setting to nil means that the success of any pod signals the success of all pods, and allows parallelism to have any positive value. Setting to 1 means that parallelism is limited to 1 and the success of that pod signals the success of the job. More info: http://releases.k8s.io/HEAD/docs/user-guide/jobs.md", + "parallelism": "Parallelism specifies the maximum desired number of pods the job should run at any given time. The actual number of pods running in steady state will be less than this number when ((.spec.completions - .status.successful) < .spec.parallelism), i.e. when the work left to do is less than max parallelism. More info: http://releases.k8s.io/release-1.2/docs/user-guide/jobs.md", + "completions": "Completions specifies the desired number of successfully finished pods the job should be run with. Setting to nil means that the success of any pod signals the success of all pods, and allows parallelism to have any positive value. Setting to 1 means that parallelism is limited to 1 and the success of that pod signals the success of the job. More info: http://releases.k8s.io/release-1.2/docs/user-guide/jobs.md", "activeDeadlineSeconds": "Optional duration in seconds relative to the startTime that the job may be active before the system tries to terminate it; value must be positive integer", - "selector": "Selector is a label query over pods that should match the pod count. Normally, the system sets this field for you. More info: http://releases.k8s.io/HEAD/docs/user-guide/labels.md#label-selectors", - "autoSelector": "AutoSelector controls generation of pod labels and pod selectors. It was not present in the original extensions/v1beta1 Job definition, but exists to allow conversion from batch/v1 Jobs, where it corresponds to, but has the opposite meaning as, ManualSelector. More info: http://releases.k8s.io/HEAD/docs/design/selector-generation.md", - "template": "Template is the object that describes the pod that will be created when executing a job. More info: http://releases.k8s.io/HEAD/docs/user-guide/jobs.md", + "selector": "Selector is a label query over pods that should match the pod count. Normally, the system sets this field for you. More info: http://releases.k8s.io/release-1.2/docs/user-guide/labels.md#label-selectors", + "autoSelector": "AutoSelector controls generation of pod labels and pod selectors. It was not present in the original extensions/v1beta1 Job definition, but exists to allow conversion from batch/v1 Jobs, where it corresponds to, but has the opposite meaning as, ManualSelector. More info: http://releases.k8s.io/release-1.2/docs/design/selector-generation.md", + "template": "Template is the object that describes the pod that will be created when executing a job. More info: http://releases.k8s.io/release-1.2/docs/user-guide/jobs.md", } func (JobSpec) SwaggerDoc() map[string]string { @@ -401,7 +401,7 @@ func (JobSpec) SwaggerDoc() map[string]string { var map_JobStatus = map[string]string{ "": "JobStatus represents the current state of a Job.", - "conditions": "Conditions represent the latest available observations of an object's current state. More info: http://releases.k8s.io/HEAD/docs/user-guide/jobs.md", + "conditions": "Conditions represent the latest available observations of an object's current state. More info: http://releases.k8s.io/release-1.2/docs/user-guide/jobs.md", "startTime": "StartTime represents time when the job was acknowledged by the Job Manager. It is not guaranteed to be set in happens-before order across separate operations. It is represented in RFC3339 form and is in UTC.", "completionTime": "CompletionTime represents time when the job was completed. It is not guaranteed to be set in happens-before order across separate operations. It is represented in RFC3339 form and is in UTC.", "active": "Active is the number of actively running pods.", @@ -449,7 +449,7 @@ func (ListOptions) SwaggerDoc() map[string]string { 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", + "metadata": "Standard object's metadata. More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#metadata", "spec": "spec defines the policy enforced.", } @@ -459,7 +459,7 @@ func (PodSecurityPolicy) SwaggerDoc() map[string]string { var map_PodSecurityPolicyList = map[string]string{ "": "Pod Security Policy List is a list of PodSecurityPolicy objects.", - "metadata": "Standard list metadata. More info: http://docs.k8s.io/api-conventions.md#metadata", + "metadata": "Standard list metadata. More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#metadata", "items": "Items is a list of schema objects.", } @@ -468,16 +468,16 @@ func (PodSecurityPolicyList) SwaggerDoc() map[string]string { } var map_PodSecurityPolicySpec = map[string]string{ - "": "Pod Security Policy Spec defines the policy enforced.", - "privileged": "privileged determines if a pod can request to be run as privileged.", - "capabilities": "capabilities is a list of capabilities that can be added.", - "volumes": "volumes is a white list of allowed volume plugins. Empty indicates that all plugins may be used.", - "hostNetwork": "hostNetwork determines if the policy allows the use of HostNetwork in the pod spec.", - "hostPorts": "hostPorts determines which host port ranges are allowed to be exposed.", - "hostPID": "hostPID determines if the policy allows the use of HostPID in the pod spec.", - "hostIPC": "hostIPC determines if the policy allows the use of HostIPC in the pod spec.", - "seLinuxContext": "seLinuxContext is the strategy that will dictate the allowable labels that may be set.", - "runAsUser": "runAsUser is the strategy that will dictate the allowable RunAsUser values that may be set.", + "": "Pod Security Policy Spec defines the policy enforced.", + "privileged": "privileged determines if a pod can request to be run as privileged.", + "capabilities": "capabilities is a list of capabilities that can be added.", + "volumes": "volumes is a white list of allowed volume plugins. Empty indicates that all plugins may be used.", + "hostNetwork": "hostNetwork determines if the policy allows the use of HostNetwork in the pod spec.", + "hostPorts": "hostPorts determines which host port ranges are allowed to be exposed.", + "hostPID": "hostPID determines if the policy allows the use of HostPID in the pod spec.", + "hostIPC": "hostIPC determines if the policy allows the use of HostIPC in the pod spec.", + "seLinux": "seLinux is the strategy that will dictate the allowable labels that may be set.", + "runAsUser": "runAsUser is the strategy that will dictate the allowable RunAsUser values that may be set.", } func (PodSecurityPolicySpec) SwaggerDoc() map[string]string { @@ -486,9 +486,9 @@ func (PodSecurityPolicySpec) SwaggerDoc() map[string]string { var map_ReplicaSet = map[string]string{ "": "ReplicaSet represents the configuration of a ReplicaSet.", - "metadata": "If the Labels of a ReplicaSet are empty, they are defaulted to be the same as the Pod(s) that the ReplicaSet manages. Standard object's metadata. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata", - "spec": "Spec defines the specification of the desired behavior of the ReplicaSet. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#spec-and-status", - "status": "Status is the most recently observed status of the ReplicaSet. This data may be out of date by some window of time. Populated by the system. Read-only. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#spec-and-status", + "metadata": "If the Labels of a ReplicaSet are empty, they are defaulted to be the same as the Pod(s) that the ReplicaSet manages. Standard object's metadata. More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#metadata", + "spec": "Spec defines the specification of the desired behavior of the ReplicaSet. More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#spec-and-status", + "status": "Status is the most recently observed status of the ReplicaSet. This data may be out of date by some window of time. Populated by the system. Read-only. More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#spec-and-status", } func (ReplicaSet) SwaggerDoc() map[string]string { @@ -497,8 +497,8 @@ func (ReplicaSet) SwaggerDoc() map[string]string { var map_ReplicaSetList = map[string]string{ "": "ReplicaSetList is a collection of ReplicaSets.", - "metadata": "Standard list metadata. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds", - "items": "List of ReplicaSets. More info: http://releases.k8s.io/HEAD/docs/user-guide/replication-controller.md", + "metadata": "Standard list metadata. More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#types-kinds", + "items": "List of ReplicaSets. More info: http://releases.k8s.io/release-1.2/docs/user-guide/replication-controller.md", } func (ReplicaSetList) SwaggerDoc() map[string]string { @@ -507,9 +507,9 @@ func (ReplicaSetList) SwaggerDoc() map[string]string { var map_ReplicaSetSpec = map[string]string{ "": "ReplicaSetSpec is the specification of a ReplicaSet.", - "replicas": "Replicas is the number of desired replicas. This is a pointer to distinguish between explicit zero and unspecified. Defaults to 1. More info: http://releases.k8s.io/HEAD/docs/user-guide/replication-controller.md#what-is-a-replication-controller", - "selector": "Selector is a label query over pods that should match the replica count. If the selector is empty, it is defaulted to the labels present on the pod template. Label keys and values that must match in order to be controlled by this replica set. More info: http://releases.k8s.io/HEAD/docs/user-guide/labels.md#label-selectors", - "template": "Template is the object that describes the pod that will be created if insufficient replicas are detected. More info: http://releases.k8s.io/HEAD/docs/user-guide/replication-controller.md#pod-template", + "replicas": "Replicas is the number of desired replicas. This is a pointer to distinguish between explicit zero and unspecified. Defaults to 1. More info: http://releases.k8s.io/release-1.2/docs/user-guide/replication-controller.md#what-is-a-replication-controller", + "selector": "Selector is a label query over pods that should match the replica count. If the selector is empty, it is defaulted to the labels present on the pod template. Label keys and values that must match in order to be controlled by this replica set. More info: http://releases.k8s.io/release-1.2/docs/user-guide/labels.md#label-selectors", + "template": "Template is the object that describes the pod that will be created if insufficient replicas are detected. More info: http://releases.k8s.io/release-1.2/docs/user-guide/replication-controller.md#pod-template", } func (ReplicaSetSpec) SwaggerDoc() map[string]string { @@ -517,9 +517,10 @@ func (ReplicaSetSpec) SwaggerDoc() map[string]string { } var map_ReplicaSetStatus = map[string]string{ - "": "ReplicaSetStatus represents the current status of a ReplicaSet.", - "replicas": "Replicas is the most recently oberved number of replicas. More info: http://releases.k8s.io/HEAD/docs/user-guide/replication-controller.md#what-is-a-replication-controller", - "observedGeneration": "ObservedGeneration reflects the generation of the most recently observed ReplicaSet.", + "": "ReplicaSetStatus represents the current status of a ReplicaSet.", + "replicas": "Replicas is the most recently oberved number of replicas. More info: http://releases.k8s.io/release-1.2/docs/user-guide/replication-controller.md#what-is-a-replication-controller", + "fullyLabeledReplicas": "The number of pods that have labels matching the labels of the pod template of the replicaset.", + "observedGeneration": "ObservedGeneration reflects the generation of the most recently observed ReplicaSet.", } func (ReplicaSetStatus) SwaggerDoc() map[string]string { @@ -554,7 +555,7 @@ func (RollingUpdateDeployment) SwaggerDoc() map[string]string { var map_RunAsUserStrategyOptions = map[string]string{ "": "Run A sUser Strategy Options defines the strategy type and any options used to create the strategy.", - "type": "type is the strategy that will dictate the allowable RunAsUser values that may be set.", + "rule": "Rule is the strategy that will dictate the allowable RunAsUser values that may be set.", "ranges": "Ranges are the allowed ranges of uids that may be used.", } @@ -562,21 +563,21 @@ func (RunAsUserStrategyOptions) SwaggerDoc() map[string]string { return map_RunAsUserStrategyOptions } -var map_SELinuxContextStrategyOptions = map[string]string{ - "": "SELinux Context Strategy Options defines the strategy type and any options used to create the strategy.", - "type": "type is the strategy that will dictate the allowable labels that may be set.", - "seLinuxOptions": "seLinuxOptions required to run as; required for MustRunAs More info: http://releases.k8s.io/HEAD/docs/design/security_context.md#security-context", +var map_SELinuxStrategyOptions = map[string]string{ + "": "SELinux Strategy Options defines the strategy type and any options used to create the strategy.", + "rule": "type is the strategy that will dictate the allowable labels that may be set.", + "seLinuxOptions": "seLinuxOptions required to run as; required for MustRunAs More info: http://releases.k8s.io/release-1.2/docs/design/security_context.md#security-context", } -func (SELinuxContextStrategyOptions) SwaggerDoc() map[string]string { - return map_SELinuxContextStrategyOptions +func (SELinuxStrategyOptions) SwaggerDoc() map[string]string { + return map_SELinuxStrategyOptions } var map_Scale = map[string]string{ "": "represents a scaling request for a resource.", - "metadata": "Standard object metadata; More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata.", - "spec": "defines the behavior of the scale. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#spec-and-status.", - "status": "current status of the scale. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#spec-and-status. Read-only.", + "metadata": "Standard object metadata; More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#metadata.", + "spec": "defines the behavior of the scale. More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#spec-and-status.", + "status": "current status of the scale. More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#spec-and-status. Read-only.", } func (Scale) SwaggerDoc() map[string]string { @@ -593,9 +594,10 @@ func (ScaleSpec) SwaggerDoc() map[string]string { } var map_ScaleStatus = map[string]string{ - "": "represents the current status of a scale subresource.", - "replicas": "actual number of observed instances of the scaled object.", - "selector": "label query over pods that should match the replicas count. More info: http://releases.k8s.io/HEAD/docs/user-guide/labels.md#label-selectors", + "": "represents the current status of a scale subresource.", + "replicas": "actual number of observed instances of the scaled object.", + "selector": "label query over pods that should match the replicas count. More info: http://releases.k8s.io/release-1.2/docs/user-guide/labels.md#label-selectors", + "targetSelector": "label selector for pods that should match the replicas count. This is a serializated version of both map-based and more expressive set-based selectors. This is done to avoid introspection in the clients. The string will be in the same format as the query-param syntax. If the target type only supports map-based selectors, both this field and map-based selector field are populated. More info: http://releases.k8s.io/release-1.2/docs/user-guide/labels.md#label-selectors", } func (ScaleStatus) SwaggerDoc() map[string]string { @@ -604,8 +606,8 @@ func (ScaleStatus) SwaggerDoc() map[string]string { var map_SubresourceReference = map[string]string{ "": "SubresourceReference contains enough information to let you inspect or modify the referred subresource.", - "kind": "Kind of the referent; More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds\"", - "name": "Name of the referent; More info: http://releases.k8s.io/HEAD/docs/user-guide/identifiers.md#names", + "kind": "Kind of the referent; More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#types-kinds\"", + "name": "Name of the referent; More info: http://releases.k8s.io/release-1.2/docs/user-guide/identifiers.md#names", "apiVersion": "API version of the referent", "subresource": "Subresource name of the referent", } @@ -637,7 +639,7 @@ func (ThirdPartyResourceData) SwaggerDoc() map[string]string { var map_ThirdPartyResourceDataList = map[string]string{ "": "ThirdPartyResrouceDataList is a list of ThirdPartyResourceData.", - "metadata": "Standard list metadata More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata", + "metadata": "Standard list metadata More info: http://releases.k8s.io/release-1.2/docs/devel/api-conventions.md#metadata", "items": "Items is the list of ThirdpartyResourceData.", } diff --git a/vendor/k8s.io/kubernetes/pkg/client/cache/delta_fifo.go b/vendor/k8s.io/kubernetes/pkg/client/cache/delta_fifo.go new file mode 100644 index 0000000..e7cc1aa --- /dev/null +++ b/vendor/k8s.io/kubernetes/pkg/client/cache/delta_fifo.go @@ -0,0 +1,550 @@ +/* +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 cache + +import ( + "errors" + "fmt" + "sync" + + "k8s.io/kubernetes/pkg/util/sets" + + "github.com/golang/glog" +) + +// NewDeltaFIFO returns a Store which can be used process changes to items. +// +// keyFunc is used to figure out what key an object should have. (It's +// exposed in the returned DeltaFIFO's KeyOf() method, with bonus features.) +// +// 'compressor' may compress as many or as few items as it wants +// (including returning an empty slice), but it should do what it +// does quickly since it is called while the queue is locked. +// 'compressor' may be nil if you don't want any delta compression. +// +// 'keyLister' is expected to return a list of keys that the consumer of +// this queue "knows about". It is used to decide which items are missing +// when Replace() is called; 'Deleted' deltas are produced for these items. +// It may be nil if you don't need to detect all deletions. +// TODO: consider merging keyLister with this object, tracking a list of +// "known" keys when Pop() is called. Have to think about how that +// affects error retrying. +// TODO(lavalamp): I believe there is a possible race only when using an +// external known object source that the above TODO would +// fix. +// +// Also see the comment on DeltaFIFO. +func NewDeltaFIFO(keyFunc KeyFunc, compressor DeltaCompressor, knownObjects KeyListerGetter) *DeltaFIFO { + f := &DeltaFIFO{ + items: map[string]Deltas{}, + queue: []string{}, + keyFunc: keyFunc, + deltaCompressor: compressor, + knownObjects: knownObjects, + } + f.cond.L = &f.lock + return f +} + +// DeltaFIFO is like FIFO, but allows you to process deletes. +// +// DeltaFIFO is a producer-consumer queue, where a Reflector is +// intended to be the producer, and the consumer is whatever calls +// the Pop() method. +// +// DeltaFIFO solves this use case: +// * You want to process every object change (delta) at most once. +// * When you process an object, you want to see everything +// that's happened to it since you last processed it. +// * You want to process the deletion of objects. +// * You might want to periodically reprocess objects. +// +// DeltaFIFO's Pop(), Get(), and GetByKey() methods return +// interface{} to satisfy the Store/Queue interfaces, but it +// will always return an object of type Deltas. +// +// A note on threading: If you call Pop() in parallel from multiple +// threads, you could end up with multiple threads processing slightly +// different versions of the same object. +// +// A note on the KeyLister used by the DeltaFIFO: It's main purpose is +// to list keys that are "known", for the puspose of figuring out which +// items have been deleted when Replace() or Delete() are called. The deleted +// objet will be included in the DeleteFinalStateUnknown markers. These objects +// could be stale. +// +// You may provide a function to compress deltas (e.g., represent a +// series of Updates as a single Update). +type DeltaFIFO struct { + // lock/cond protects access to 'items' and 'queue'. + lock sync.RWMutex + cond sync.Cond + + // We depend on the property that items in the set are in + // the queue and vice versa, and that all Deltas in this + // map have at least one Delta. + items map[string]Deltas + queue []string + + // populated is true if the first batch of items inserted by Replace() has been populated + // or Delete/Add/Update was called first. + populated bool + // initialPopulationCount is the number of items inserted by the first call of Replace() + initialPopulationCount int + + // keyFunc is used to make the key used for queued item + // insertion and retrieval, and should be deterministic. + keyFunc KeyFunc + + // deltaCompressor tells us how to combine two or more + // deltas. It may be nil. + deltaCompressor DeltaCompressor + + // knownObjects list keys that are "known", for the + // purpose of figuring out which items have been deleted + // when Replace() or Delete() is called. + knownObjects KeyListerGetter +} + +var ( + _ = Queue(&DeltaFIFO{}) // DeltaFIFO is a Queue +) + +var ( + // ErrZeroLengthDeltasObject is returned in a KeyError if a Deltas + // object with zero length is encountered (should be impossible, + // even if such an object is accidentally produced by a DeltaCompressor-- + // but included for completeness). + ErrZeroLengthDeltasObject = errors.New("0 length Deltas object; can't get key") +) + +// KeyOf exposes f's keyFunc, but also detects the key of a Deltas object or +// DeletedFinalStateUnknown objects. +func (f *DeltaFIFO) KeyOf(obj interface{}) (string, error) { + if d, ok := obj.(Deltas); ok { + if len(d) == 0 { + return "", KeyError{obj, ErrZeroLengthDeltasObject} + } + obj = d.Newest().Object + } + if d, ok := obj.(DeletedFinalStateUnknown); ok { + return d.Key, nil + } + return f.keyFunc(obj) +} + +// Return true if an Add/Update/Delete/AddIfNotPresent are called first, +// or an Update called first but the first batch of items inserted by Replace() has been popped +func (f *DeltaFIFO) HasSynced() bool { + f.lock.Lock() + defer f.lock.Unlock() + return f.populated && f.initialPopulationCount == 0 +} + +// Add inserts an item, and puts it in the queue. The item is only enqueued +// if it doesn't already exist in the set. +func (f *DeltaFIFO) Add(obj interface{}) error { + f.lock.Lock() + defer f.lock.Unlock() + f.populated = true + return f.queueActionLocked(Added, obj) +} + +// Update is just like Add, but makes an Updated Delta. +func (f *DeltaFIFO) Update(obj interface{}) error { + f.lock.Lock() + defer f.lock.Unlock() + f.populated = true + return f.queueActionLocked(Updated, obj) +} + +// Delete is just like Add, but makes an Deleted Delta. If the item does not +// already exist, it will be ignored. (It may have already been deleted by a +// Replace (re-list), for example. +func (f *DeltaFIFO) Delete(obj interface{}) error { + id, err := f.KeyOf(obj) + if err != nil { + return KeyError{obj, err} + } + f.lock.Lock() + defer f.lock.Unlock() + f.populated = true + if f.knownObjects == nil { + if _, exists := f.items[id]; !exists { + // Presumably, this was deleted when a relist happened. + // Don't provide a second report of the same deletion. + return nil + } + } else if _, exists, err := f.knownObjects.GetByKey(id); err == nil && !exists { + // Presumably, this was deleted when a relist happened. + // Don't provide a second report of the same deletion. + // TODO(lavalamp): This may be racy-- we aren't properly locked + // with knownObjects. + return nil + } + + return f.queueActionLocked(Deleted, obj) +} + +// AddIfNotPresent inserts an item, and puts it in the queue. If the item is already +// present in the set, it is neither enqueued nor added to the set. +// +// This is useful in a single producer/consumer scenario so that the consumer can +// safely retry items without contending with the producer and potentially enqueueing +// stale items. +// +// Important: obj must be a Deltas (the output of the Pop() function). Yes, this is +// different from the Add/Update/Delete functions. +func (f *DeltaFIFO) AddIfNotPresent(obj interface{}) error { + deltas, ok := obj.(Deltas) + if !ok { + return fmt.Errorf("object must be of type deltas, but got: %#v", obj) + } + id, err := f.KeyOf(deltas.Newest().Object) + if err != nil { + return KeyError{obj, err} + } + f.lock.Lock() + defer f.lock.Unlock() + f.populated = true + if _, exists := f.items[id]; exists { + return nil + } + + f.queue = append(f.queue, id) + f.items[id] = deltas + f.cond.Broadcast() + return nil +} + +// re-listing and watching can deliver the same update multiple times in any +// order. This will combine the most recent two deltas if they are the same. +func dedupDeltas(deltas Deltas) Deltas { + n := len(deltas) + if n < 2 { + return deltas + } + a := &deltas[n-1] + b := &deltas[n-2] + if out := isDup(a, b); out != nil { + d := append(Deltas{}, deltas[:n-2]...) + return append(d, *out) + } + return deltas +} + +// If a & b represent the same event, returns the delta that ought to be kept. +// Otherwise, returns nil. +// TODO: is there anything other than deletions that need deduping? +func isDup(a, b *Delta) *Delta { + if out := isDeletionDup(a, b); out != nil { + return out + } + // TODO: Detect other duplicate situations? Are there any? + return nil +} + +// keep the one with the most information if both are deletions. +func isDeletionDup(a, b *Delta) *Delta { + if b.Type != Deleted || a.Type != Deleted { + return nil + } + // Do more sophisticated checks, or is this sufficient? + if _, ok := b.Object.(DeletedFinalStateUnknown); ok { + return a + } + return b +} + +// queueActionLocked appends to the delta list for the object, calling +// f.deltaCompressor if needed. Caller must lock first. +func (f *DeltaFIFO) queueActionLocked(actionType DeltaType, obj interface{}) error { + id, err := f.KeyOf(obj) + if err != nil { + return KeyError{obj, err} + } + newDeltas := append(f.items[id], Delta{actionType, obj}) + newDeltas = dedupDeltas(newDeltas) + if f.deltaCompressor != nil { + newDeltas = f.deltaCompressor.Compress(newDeltas) + } + + _, exists := f.items[id] + if len(newDeltas) > 0 { + if !exists { + f.queue = append(f.queue, id) + } + f.items[id] = newDeltas + f.cond.Broadcast() + } else if exists { + // The compression step removed all deltas, so + // we need to remove this from our map (extra items + // in the queue are ignored if they are not in the + // map). + delete(f.items, id) + } + return nil +} + +// List returns a list of all the items; it returns the object +// from the most recent Delta. +// You should treat the items returned inside the deltas as immutable. +func (f *DeltaFIFO) List() []interface{} { + f.lock.RLock() + defer f.lock.RUnlock() + list := make([]interface{}, 0, len(f.items)) + for _, item := range f.items { + // Copy item's slice so operations on this slice (delta + // compression) won't interfere with the object we return. + item = copyDeltas(item) + list = append(list, item.Newest().Object) + } + return list +} + +// ListKeys returns a list of all the keys of the objects currently +// in the FIFO. +func (f *DeltaFIFO) ListKeys() []string { + f.lock.RLock() + defer f.lock.RUnlock() + list := make([]string, 0, len(f.items)) + for key := range f.items { + list = append(list, key) + } + return list +} + +// Get returns the complete list of deltas for the requested item, +// or sets exists=false. +// You should treat the items returned inside the deltas as immutable. +func (f *DeltaFIFO) Get(obj interface{}) (item interface{}, exists bool, err error) { + key, err := f.KeyOf(obj) + if err != nil { + return nil, false, KeyError{obj, err} + } + return f.GetByKey(key) +} + +// GetByKey returns the complete list of deltas for the requested item, +// setting exists=false if that list is empty. +// You should treat the items returned inside the deltas as immutable. +func (f *DeltaFIFO) GetByKey(key string) (item interface{}, exists bool, err error) { + f.lock.RLock() + defer f.lock.RUnlock() + d, exists := f.items[key] + if exists { + // Copy item's slice so operations on this slice (delta + // compression) won't interfere with the object we return. + d = copyDeltas(d) + } + return d, exists, nil +} + +// Pop blocks until an item is added to the queue, and then returns it. If +// multiple items are ready, they are returned in the order in which they were +// added/updated. The item is removed from the queue (and the store) before it +// is returned, so if you don't successfully process it, you need to add it back +// with AddIfNotPresent(). +// +// Pop returns a 'Deltas', which has a complete list of all the things +// that happened to the object (deltas) while it was sitting in the queue. +func (f *DeltaFIFO) Pop() interface{} { + f.lock.Lock() + defer f.lock.Unlock() + for { + for len(f.queue) == 0 { + f.cond.Wait() + } + id := f.queue[0] + f.queue = f.queue[1:] + item, ok := f.items[id] + if f.initialPopulationCount > 0 { + f.initialPopulationCount-- + } + if !ok { + // Item may have been deleted subsequently. + continue + } + delete(f.items, id) + // Don't need to copyDeltas here, because we're transferring + // ownership to the caller. + return item + } +} + +// Replace will delete the contents of 'f', using instead the given map. +// 'f' takes ownership of the map, you should not reference the map again +// after calling this function. f's queue is reset, too; upon return, it +// will contain the items in the map, in no particular order. +func (f *DeltaFIFO) Replace(list []interface{}, resourceVersion string) error { + f.lock.Lock() + defer f.lock.Unlock() + keys := make(sets.String, len(list)) + + if !f.populated { + f.populated = true + f.initialPopulationCount = len(list) + } + + for _, item := range list { + key, err := f.KeyOf(item) + if err != nil { + return KeyError{item, err} + } + keys.Insert(key) + if err := f.queueActionLocked(Sync, item); err != nil { + return fmt.Errorf("couldn't enqueue object: %v", err) + } + } + + if f.knownObjects == nil { + // Do deletion detection against our own list. + for k, oldItem := range f.items { + if keys.Has(k) { + continue + } + var deletedObj interface{} + if n := oldItem.Newest(); n != nil { + deletedObj = n.Object + } + if err := f.queueActionLocked(Deleted, DeletedFinalStateUnknown{k, deletedObj}); err != nil { + return err + } + } + return nil + } + + // Detect deletions not already in the queue. + // TODO(lavalamp): This may be racy-- we aren't properly locked + // with knownObjects. Unproven. + knownKeys := f.knownObjects.ListKeys() + for _, k := range knownKeys { + if keys.Has(k) { + continue + } + + deletedObj, exists, err := f.knownObjects.GetByKey(k) + if err != nil { + deletedObj = nil + glog.Errorf("Unexpected error %v during lookup of key %v, placing DeleteFinalStateUnknown marker without object", err, k) + } else if !exists { + deletedObj = nil + glog.Infof("Key %v does not exist in known objects store, placing DeleteFinalStateUnknown marker without object", k) + } + if err := f.queueActionLocked(Deleted, DeletedFinalStateUnknown{k, deletedObj}); err != nil { + return err + } + } + return nil +} + +// A KeyListerGetter is anything that knows how to list its keys and look up by key. +type KeyListerGetter interface { + KeyLister + KeyGetter +} + +// A KeyLister is anything that knows how to list its keys. +type KeyLister interface { + ListKeys() []string +} + +// A KeyGetter is anything that knows how to get the value stored under a given key. +type KeyGetter interface { + GetByKey(key string) (interface{}, bool, error) +} + +// DeltaCompressor is an algorithm that removes redundant changes. +type DeltaCompressor interface { + Compress(Deltas) Deltas +} + +// DeltaCompressorFunc should remove redundant changes; but changes that +// are redundant depend on one's desired semantics, so this is an +// injectable function. +// +// DeltaCompressorFunc adapts a raw function to be a DeltaCompressor. +type DeltaCompressorFunc func(Deltas) Deltas + +// Compress just calls dc. +func (dc DeltaCompressorFunc) Compress(d Deltas) Deltas { + return dc(d) +} + +// DeltaType is the type of a change (addition, deletion, etc) +type DeltaType string + +const ( + Added DeltaType = "Added" + Updated DeltaType = "Updated" + Deleted DeltaType = "Deleted" + // The other types are obvious. You'll get Sync deltas when: + // * A watch expires/errors out and a new list/watch cycle is started. + // * You've turned on periodic syncs. + // (Anything that trigger's DeltaFIFO's Replace() method.) + Sync DeltaType = "Sync" +) + +// Delta is the type stored by a DeltaFIFO. It tells you what change +// happened, and the object's state after* that change. +// +// [*] Unless the change is a deletion, and then you'll get the final +// state of the object before it was deleted. +type Delta struct { + Type DeltaType + Object interface{} +} + +// Deltas is a list of one or more 'Delta's to an individual object. +// The oldest delta is at index 0, the newest delta is the last one. +type Deltas []Delta + +// Oldest is a convenience function that returns the oldest delta, or +// nil if there are no deltas. +func (d Deltas) Oldest() *Delta { + if len(d) > 0 { + return &d[0] + } + return nil +} + +// Newest is a convenience function that returns the newest delta, or +// nil if there are no deltas. +func (d Deltas) Newest() *Delta { + if n := len(d); n > 0 { + return &d[n-1] + } + return nil +} + +// copyDeltas returns a shallow copy of d; that is, it copies the slice but not +// the objects in the slice. This allows Get/List to return an object that we +// know won't be clobbered by a subsequent call to a delta compressor. +func copyDeltas(d Deltas) Deltas { + d2 := make(Deltas, len(d)) + copy(d2, d) + return d2 +} + +// DeletedFinalStateUnknown is placed into a DeltaFIFO in the case where +// an object was deleted but the watch deletion event was missed. In this +// case we don't know the final "resting" state of the object, so there's +// a chance the included `Obj` is stale. +type DeletedFinalStateUnknown struct { + Key string + Obj interface{} +} diff --git a/vendor/k8s.io/kubernetes/pkg/client/cache/doc.go b/vendor/k8s.io/kubernetes/pkg/client/cache/doc.go new file mode 100644 index 0000000..16600cf --- /dev/null +++ b/vendor/k8s.io/kubernetes/pkg/client/cache/doc.go @@ -0,0 +1,24 @@ +/* +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 cache is a client-side caching mechanism. It is useful for +// reducing the number of server calls you'd otherwise need to make. +// Reflector watches a server and updates a Store. Two stores are provided; +// one that simply caches objects (for example, to allow a scheduler to +// list currently available nodes), and one that additionally acts as +// a FIFO queue (for example, to allow a scheduler to process incoming +// pods). +package cache diff --git a/vendor/k8s.io/kubernetes/pkg/client/cache/expiration_cache.go b/vendor/k8s.io/kubernetes/pkg/client/cache/expiration_cache.go new file mode 100644 index 0000000..964deda --- /dev/null +++ b/vendor/k8s.io/kubernetes/pkg/client/cache/expiration_cache.go @@ -0,0 +1,202 @@ +/* +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 cache + +import ( + "sync" + "time" + + "github.com/golang/glog" + "k8s.io/kubernetes/pkg/util" +) + +// ExpirationCache implements the store interface +// 1. All entries are automatically time stamped on insert +// a. The key is computed based off the original item/keyFunc +// b. The value inserted under that key is the timestamped item +// 2. Expiration happens lazily on read based on the expiration policy +// a. No item can be inserted into the store while we're expiring +// *any* item in the cache. +// 3. Time-stamps are stripped off unexpired entries before return +// Note that the ExpirationCache is inherently slower than a normal +// threadSafeStore because it takes a write lock every time it checks if +// an item has expired. +type ExpirationCache struct { + cacheStorage ThreadSafeStore + keyFunc KeyFunc + clock util.Clock + expirationPolicy ExpirationPolicy + // expirationLock is a write lock used to guarantee that we don't clobber + // newly inserted objects because of a stale expiration timestamp comparison + expirationLock sync.Mutex +} + +// ExpirationPolicy dictates when an object expires. Currently only abstracted out +// so unittests don't rely on the system clock. +type ExpirationPolicy interface { + IsExpired(obj *timestampedEntry) bool +} + +// TTLPolicy implements a ttl based ExpirationPolicy. +type TTLPolicy struct { + // >0: Expire entries with an age > ttl + // <=0: Don't expire any entry + Ttl time.Duration + + // Clock used to calculate ttl expiration + Clock util.Clock +} + +// IsExpired returns true if the given object is older than the ttl, or it can't +// determine its age. +func (p *TTLPolicy) IsExpired(obj *timestampedEntry) bool { + return p.Ttl > 0 && p.Clock.Since(obj.timestamp) > p.Ttl +} + +// timestampedEntry is the only type allowed in a ExpirationCache. +type timestampedEntry struct { + obj interface{} + timestamp time.Time +} + +// getTimestampedEntry returnes the timestampedEntry stored under the given key. +func (c *ExpirationCache) getTimestampedEntry(key string) (*timestampedEntry, bool) { + item, _ := c.cacheStorage.Get(key) + if tsEntry, ok := item.(*timestampedEntry); ok { + return tsEntry, true + } + return nil, false +} + +// getOrExpire retrieves the object from the timestampedEntry if and only if it hasn't +// already expired. It holds a write lock across deletion. +func (c *ExpirationCache) getOrExpire(key string) (interface{}, bool) { + // Prevent all inserts from the time we deem an item as "expired" to when we + // delete it, so an un-expired item doesn't sneak in under the same key, just + // before the Delete. + c.expirationLock.Lock() + defer c.expirationLock.Unlock() + timestampedItem, exists := c.getTimestampedEntry(key) + if !exists { + return nil, false + } + if c.expirationPolicy.IsExpired(timestampedItem) { + glog.V(4).Infof("Entry %v: %+v has expired", key, timestampedItem.obj) + c.cacheStorage.Delete(key) + return nil, false + } + return timestampedItem.obj, true +} + +// GetByKey returns the item stored under the key, or sets exists=false. +func (c *ExpirationCache) GetByKey(key string) (interface{}, bool, error) { + obj, exists := c.getOrExpire(key) + return obj, exists, nil +} + +// Get returns unexpired items. It purges the cache of expired items in the +// process. +func (c *ExpirationCache) Get(obj interface{}) (interface{}, bool, error) { + key, err := c.keyFunc(obj) + if err != nil { + return nil, false, KeyError{obj, err} + } + obj, exists := c.getOrExpire(key) + return obj, exists, nil +} + +// List retrieves a list of unexpired items. It purges the cache of expired +// items in the process. +func (c *ExpirationCache) List() []interface{} { + items := c.cacheStorage.List() + + list := make([]interface{}, 0, len(items)) + for _, item := range items { + obj := item.(*timestampedEntry).obj + if key, err := c.keyFunc(obj); err != nil { + list = append(list, obj) + } else if obj, exists := c.getOrExpire(key); exists { + list = append(list, obj) + } + } + return list +} + +// ListKeys returns a list of all keys in the expiration cache. +func (c *ExpirationCache) ListKeys() []string { + return c.cacheStorage.ListKeys() +} + +// Add timestamps an item and inserts it into the cache, overwriting entries +// that might exist under the same key. +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} + } + c.cacheStorage.Add(key, ×tampedEntry{obj, c.clock.Now()}) + return nil +} + +// Update has not been implemented yet for lack of a use case, so this method +// simply calls `Add`. This effectively refreshes the timestamp. +func (c *ExpirationCache) Update(obj interface{}) error { + return c.Add(obj) +} + +// Delete removes an item from the cache. +func (c *ExpirationCache) Delete(obj interface{}) error { + c.expirationLock.Lock() + defer c.expirationLock.Unlock() + key, err := c.keyFunc(obj) + if err != nil { + return KeyError{obj, err} + } + c.cacheStorage.Delete(key) + return nil +} + +// Replace will convert all items in the given list to TimestampedEntries +// before attempting the replace operation. The replace operation will +// delete the contents of the ExpirationCache `c`. +func (c *ExpirationCache) Replace(list []interface{}, resourceVersion string) error { + c.expirationLock.Lock() + defer c.expirationLock.Unlock() + items := map[string]interface{}{} + ts := c.clock.Now() + for _, item := range list { + key, err := c.keyFunc(item) + if err != nil { + return KeyError{item, err} + } + items[key] = ×tampedEntry{item, ts} + } + c.cacheStorage.Replace(items, resourceVersion) + return nil +} + +// NewTTLStore creates and returns a ExpirationCache with a TTLPolicy +func NewTTLStore(keyFunc KeyFunc, ttl time.Duration) Store { + return &ExpirationCache{ + cacheStorage: NewThreadSafeStore(Indexers{}, Indices{}), + keyFunc: keyFunc, + clock: util.RealClock{}, + expirationPolicy: &TTLPolicy{ttl, util.RealClock{}}, + } +} diff --git a/vendor/k8s.io/kubernetes/pkg/client/cache/expiration_cache_fakes.go b/vendor/k8s.io/kubernetes/pkg/client/cache/expiration_cache_fakes.go new file mode 100644 index 0000000..3b95977 --- /dev/null +++ b/vendor/k8s.io/kubernetes/pkg/client/cache/expiration_cache_fakes.go @@ -0,0 +1,54 @@ +/* +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 cache + +import ( + "k8s.io/kubernetes/pkg/util" + "k8s.io/kubernetes/pkg/util/sets" +) + +type fakeThreadSafeMap struct { + ThreadSafeStore + deletedKeys chan<- string +} + +func (c *fakeThreadSafeMap) Delete(key string) { + if c.deletedKeys != nil { + c.ThreadSafeStore.Delete(key) + c.deletedKeys <- key + } +} + +type FakeExpirationPolicy struct { + NeverExpire sets.String + RetrieveKeyFunc KeyFunc +} + +func (p *FakeExpirationPolicy) IsExpired(obj *timestampedEntry) bool { + key, _ := p.RetrieveKeyFunc(obj) + return !p.NeverExpire.Has(key) +} + +func NewFakeExpirationStore(keyFunc KeyFunc, deletedKeys chan<- string, expirationPolicy ExpirationPolicy, cacheClock util.Clock) Store { + cacheStorage := NewThreadSafeStore(Indexers{}, Indices{}) + return &ExpirationCache{ + cacheStorage: &fakeThreadSafeMap{cacheStorage, deletedKeys}, + keyFunc: keyFunc, + clock: cacheClock, + expirationPolicy: expirationPolicy, + } +} diff --git a/vendor/k8s.io/kubernetes/pkg/client/cache/fifo.go b/vendor/k8s.io/kubernetes/pkg/client/cache/fifo.go new file mode 100644 index 0000000..d4076a3 --- /dev/null +++ b/vendor/k8s.io/kubernetes/pkg/client/cache/fifo.go @@ -0,0 +1,254 @@ +/* +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 cache + +import ( + "sync" +) + +// Queue is exactly like a Store, but has a Pop() method too. +type Queue interface { + Store + + // Pop blocks until it has something to return. + Pop() interface{} + + // AddIfNotPresent adds a value previously + // returned by Pop back into the queue as long + // as nothing else (presumably more recent) + // has since been added. + AddIfNotPresent(interface{}) error + + // Return true if the first batch of items has been popped + HasSynced() bool +} + +// FIFO receives adds and updates from a Reflector, and puts them in a queue for +// FIFO order processing. If multiple adds/updates of a single item happen while +// an item is in the queue before it has been processed, it will only be +// processed once, and when it is processed, the most recent version will be +// processed. This can't be done with a channel. +// +// FIFO solves this use case: +// * You want to process every object (exactly) once. +// * You want to process the most recent version of the object when you process it. +// * You do not want to process deleted objects, they should be removed from the queue. +// * You do not want to periodically reprocess objects. +// Compare with DeltaFIFO for other use cases. +type FIFO struct { + lock sync.RWMutex + cond sync.Cond + // We depend on the property that items in the set are in the queue and vice versa. + items map[string]interface{} + queue []string + + // populated is true if the first batch of items inserted by Replace() has been populated + // or Delete/Add/Update was called first. + populated bool + // initialPopulationCount is the number of items inserted by the first call of Replace() + initialPopulationCount int + + // keyFunc is used to make the key used for queued item insertion and retrieval, and + // should be deterministic. + keyFunc KeyFunc +} + +var ( + _ = Queue(&FIFO{}) // FIFO is a Queue +) + +// Return true if an Add/Update/Delete/AddIfNotPresent are called first, +// or an Update called first but the first batch of items inserted by Replace() has been popped +func (f *FIFO) HasSynced() bool { + f.lock.Lock() + defer f.lock.Unlock() + return f.populated && f.initialPopulationCount == 0 +} + +// Add inserts an item, and puts it in the queue. The item is only enqueued +// if it doesn't already exist in the set. +func (f *FIFO) Add(obj interface{}) error { + id, err := f.keyFunc(obj) + if err != nil { + return KeyError{obj, err} + } + f.lock.Lock() + defer f.lock.Unlock() + f.populated = true + if _, exists := f.items[id]; !exists { + f.queue = append(f.queue, id) + } + f.items[id] = obj + f.cond.Broadcast() + return nil +} + +// AddIfNotPresent inserts an item, and puts it in the queue. If the item is already +// present in the set, it is neither enqueued nor added to the set. +// +// This is useful in a single producer/consumer scenario so that the consumer can +// safely retry items without contending with the producer and potentially enqueueing +// stale items. +func (f *FIFO) AddIfNotPresent(obj interface{}) error { + id, err := f.keyFunc(obj) + if err != nil { + return KeyError{obj, err} + } + f.lock.Lock() + defer f.lock.Unlock() + f.populated = true + if _, exists := f.items[id]; exists { + return nil + } + + f.queue = append(f.queue, id) + f.items[id] = obj + f.cond.Broadcast() + return nil +} + +// Update is the same as Add in this implementation. +func (f *FIFO) Update(obj interface{}) error { + return f.Add(obj) +} + +// Delete removes an item. It doesn't add it to the queue, because +// this implementation assumes the consumer only cares about the objects, +// not the order in which they were created/added. +func (f *FIFO) Delete(obj interface{}) error { + id, err := f.keyFunc(obj) + if err != nil { + return KeyError{obj, err} + } + f.lock.Lock() + defer f.lock.Unlock() + f.populated = true + delete(f.items, id) + return err +} + +// List returns a list of all the items. +func (f *FIFO) List() []interface{} { + f.lock.RLock() + defer f.lock.RUnlock() + list := make([]interface{}, 0, len(f.items)) + for _, item := range f.items { + list = append(list, item) + } + return list +} + +// ListKeys returns a list of all the keys of the objects currently +// in the FIFO. +func (f *FIFO) ListKeys() []string { + f.lock.RLock() + defer f.lock.RUnlock() + list := make([]string, 0, len(f.items)) + for key := range f.items { + list = append(list, key) + } + return list +} + +// Get returns the requested item, or sets exists=false. +func (f *FIFO) Get(obj interface{}) (item interface{}, exists bool, err error) { + key, err := f.keyFunc(obj) + if err != nil { + return nil, false, KeyError{obj, err} + } + return f.GetByKey(key) +} + +// GetByKey returns the requested item, or sets exists=false. +func (f *FIFO) GetByKey(key string) (item interface{}, exists bool, err error) { + f.lock.RLock() + defer f.lock.RUnlock() + item, exists = f.items[key] + return item, exists, nil +} + +// Pop waits until an item is ready and returns it. If multiple items are +// ready, they are returned in the order in which they were added/updated. +// The item is removed from the queue (and the store) before it is returned, +// so if you don't successfully process it, you need to add it back with +// AddIfNotPresent(). +func (f *FIFO) Pop() interface{} { + f.lock.Lock() + defer f.lock.Unlock() + for { + for len(f.queue) == 0 { + f.cond.Wait() + } + id := f.queue[0] + f.queue = f.queue[1:] + if f.initialPopulationCount > 0 { + f.initialPopulationCount-- + } + item, ok := f.items[id] + if !ok { + // Item may have been deleted subsequently. + continue + } + delete(f.items, id) + return item + } +} + +// Replace will delete the contents of 'f', using instead the given map. +// 'f' takes ownership of the map, you should not reference the map again +// after calling this function. f's queue is reset, too; upon return, it +// will contain the items in the map, in no particular order. +func (f *FIFO) Replace(list []interface{}, resourceVersion string) error { + items := map[string]interface{}{} + for _, item := range list { + key, err := f.keyFunc(item) + if err != nil { + return KeyError{item, err} + } + items[key] = item + } + + f.lock.Lock() + defer f.lock.Unlock() + + if !f.populated { + f.populated = true + f.initialPopulationCount = len(items) + } + + f.items = items + f.queue = f.queue[:0] + for id := range items { + 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 { + f := &FIFO{ + items: map[string]interface{}{}, + queue: []string{}, + keyFunc: keyFunc, + } + f.cond.L = &f.lock + return f +} diff --git a/vendor/k8s.io/kubernetes/pkg/client/cache/index.go b/vendor/k8s.io/kubernetes/pkg/client/cache/index.go new file mode 100644 index 0000000..a0c0c28 --- /dev/null +++ b/vendor/k8s.io/kubernetes/pkg/client/cache/index.go @@ -0,0 +1,72 @@ +/* +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 cache + +import ( + "fmt" + + "k8s.io/kubernetes/pkg/api/meta" + "k8s.io/kubernetes/pkg/util/sets" +) + +// Indexer is a storage interface that lets you list objects using multiple indexing functions +type Indexer interface { + Store + // Retrieve list of objects that match on the named indexing function + Index(indexName string, obj interface{}) ([]interface{}, error) + // ListIndexFuncValues returns the list of generated values of an Index func + ListIndexFuncValues(indexName string) []string + // ByIndex lists object that match on the named indexing function with the exact key + ByIndex(indexName, indexKey string) ([]interface{}, error) +} + +// IndexFunc knows how to provide an indexed value for an object. +type IndexFunc func(obj interface{}) ([]string, error) + +// IndexFuncToKeyFuncAdapter adapts an indexFunc to a keyFunc. This is only useful if your index function returns +// unique values for every object. This is conversion can create errors when more than one key is found. You +// should prefer to make proper key and index functions. +func IndexFuncToKeyFuncAdapter(indexFunc IndexFunc) KeyFunc { + return func(obj interface{}) (string, error) { + indexKeys, err := indexFunc(obj) + if err != nil { + return "", err + } + if len(indexKeys) > 1 { + return "", fmt.Errorf("too many keys: %v", indexKeys) + } + return indexKeys[0], nil + } +} + +// MetaNamespaceIndexFunc is a default index function that indexes based on an object's namespace +func MetaNamespaceIndexFunc(obj interface{}) ([]string, error) { + meta, err := meta.Accessor(obj) + if err != nil { + return []string{""}, fmt.Errorf("object has no meta: %v", err) + } + return []string{meta.GetNamespace()}, nil +} + +// Index maps the indexed value to a set of keys in the store that match on that value +type Index map[string]sets.String + +// Indexers maps a name to a IndexFunc +type Indexers map[string]IndexFunc + +// Indices maps a name to an Index +type Indices map[string]Index diff --git a/vendor/k8s.io/kubernetes/pkg/client/cache/listers.go b/vendor/k8s.io/kubernetes/pkg/client/cache/listers.go new file mode 100644 index 0000000..3963a69 --- /dev/null +++ b/vendor/k8s.io/kubernetes/pkg/client/cache/listers.go @@ -0,0 +1,558 @@ +/* +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 cache + +import ( + "fmt" + + "github.com/golang/glog" + "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/unversioned" + "k8s.io/kubernetes/pkg/apis/extensions" + "k8s.io/kubernetes/pkg/labels" +) + +// TODO: generate these classes and methods for all resources of interest using +// a script. Can use "go generate" once 1.4 is supported by all users. + +// StoreToPodLister makes a Store have the List method of the client.PodInterface +// The Store must contain (only) Pods. +// +// Example: +// s := cache.NewStore() +// lw := cache.ListWatch{Client: c, FieldSelector: sel, Resource: "pods"} +// r := cache.NewReflector(lw, &api.Pod{}, s).Run() +// l := StoreToPodLister{s} +// l.List() +type StoreToPodLister struct { + Store +} + +// Please note that selector is filtering among the pods that have gotten into +// the store; there may have been some filtering that already happened before +// that. +// +// TODO: converge on the interface in pkg/client. +func (s *StoreToPodLister) List(selector labels.Selector) (pods []*api.Pod, err error) { + // TODO: it'd be great to just call + // s.Pods(api.NamespaceAll).List(selector), however then we'd have to + // remake the list.Items as a []*api.Pod. So leave this separate for + // now. + for _, m := range s.Store.List() { + pod := m.(*api.Pod) + if selector.Matches(labels.Set(pod.Labels)) { + pods = append(pods, pod) + } + } + return pods, nil +} + +// Pods is taking baby steps to be more like the api in pkg/client +func (s *StoreToPodLister) Pods(namespace string) storePodsNamespacer { + return storePodsNamespacer{s.Store, namespace} +} + +type storePodsNamespacer struct { + store Store + namespace string +} + +// Please note that selector is filtering among the pods that have gotten into +// the store; there may have been some filtering that already happened before +// that. +func (s storePodsNamespacer) List(selector labels.Selector) (pods api.PodList, err error) { + list := api.PodList{} + for _, m := range s.store.List() { + pod := m.(*api.Pod) + if s.namespace == api.NamespaceAll || s.namespace == pod.Namespace { + if selector.Matches(labels.Set(pod.Labels)) { + list.Items = append(list.Items, *pod) + } + } + } + return list, nil +} + +// Exists returns true if a pod matching the namespace/name of the given pod exists in the store. +func (s *StoreToPodLister) Exists(pod *api.Pod) (bool, error) { + _, exists, err := s.Store.Get(pod) + if err != nil { + return false, err + } + return exists, nil +} + +// NodeConditionPredicate is a function that indicates whether the given node's conditions meet +// some set of criteria defined by the function. +type NodeConditionPredicate func(node api.Node) bool + +// StoreToNodeLister makes a Store have the List method of the client.NodeInterface +// The Store must contain (only) Nodes. +type StoreToNodeLister struct { + Store +} + +func (s *StoreToNodeLister) List() (machines api.NodeList, err error) { + for _, m := range s.Store.List() { + machines.Items = append(machines.Items, *(m.(*api.Node))) + } + return machines, nil +} + +// NodeCondition returns a storeToNodeConditionLister +func (s *StoreToNodeLister) NodeCondition(predicate NodeConditionPredicate) storeToNodeConditionLister { + // TODO: Move this filtering server side. Currently our selectors don't facilitate searching through a list so we + // have the reflector filter out the Unschedulable field and sift through node conditions in the lister. + return storeToNodeConditionLister{s.Store, predicate} +} + +// storeToNodeConditionLister filters and returns nodes matching the given type and status from the store. +type storeToNodeConditionLister struct { + store Store + predicate NodeConditionPredicate +} + +// List returns a list of nodes that match the conditions defined by the predicate functions in the storeToNodeConditionLister. +func (s storeToNodeConditionLister) List() (nodes api.NodeList, err error) { + for _, m := range s.store.List() { + node := *m.(*api.Node) + if s.predicate(node) { + nodes.Items = append(nodes.Items, node) + } else { + glog.V(5).Infof("Node %s matches none of the conditions", node.Name) + } + } + return +} + +// StoreToReplicationControllerLister gives a store List and Exists methods. The store must contain only ReplicationControllers. +type StoreToReplicationControllerLister struct { + Store +} + +// Exists checks if the given rc exists in the store. +func (s *StoreToReplicationControllerLister) Exists(controller *api.ReplicationController) (bool, error) { + _, exists, err := s.Store.Get(controller) + if err != nil { + return false, err + } + return exists, nil +} + +// StoreToReplicationControllerLister lists all controllers in the store. +// TODO: converge on the interface in pkg/client +func (s *StoreToReplicationControllerLister) List() (controllers []api.ReplicationController, err error) { + for _, c := range s.Store.List() { + controllers = append(controllers, *(c.(*api.ReplicationController))) + } + return controllers, nil +} + +func (s *StoreToReplicationControllerLister) ReplicationControllers(namespace string) storeReplicationControllersNamespacer { + return storeReplicationControllersNamespacer{s.Store, namespace} +} + +type storeReplicationControllersNamespacer struct { + store Store + namespace string +} + +func (s storeReplicationControllersNamespacer) List(selector labels.Selector) (controllers []api.ReplicationController, err error) { + for _, c := range s.store.List() { + rc := *(c.(*api.ReplicationController)) + if s.namespace == api.NamespaceAll || s.namespace == rc.Namespace { + if selector.Matches(labels.Set(rc.Labels)) { + controllers = append(controllers, rc) + } + } + } + return +} + +// GetPodControllers returns a list of replication controllers managing a pod. Returns an error only if no matching controllers are found. +func (s *StoreToReplicationControllerLister) GetPodControllers(pod *api.Pod) (controllers []api.ReplicationController, err error) { + var selector labels.Selector + var rc api.ReplicationController + + if len(pod.Labels) == 0 { + err = fmt.Errorf("no controllers found for pod %v because it has no labels", pod.Name) + return + } + + for _, m := range s.Store.List() { + rc = *m.(*api.ReplicationController) + if rc.Namespace != pod.Namespace { + continue + } + labelSet := labels.Set(rc.Spec.Selector) + selector = labels.Set(rc.Spec.Selector).AsSelector() + + // If an rc with a nil or empty selector creeps in, it should match nothing, not everything. + if labelSet.AsSelector().Empty() || !selector.Matches(labels.Set(pod.Labels)) { + continue + } + controllers = append(controllers, rc) + } + if len(controllers) == 0 { + err = fmt.Errorf("could not find controller for pod %s in namespace %s with labels: %v", pod.Name, pod.Namespace, pod.Labels) + } + return +} + +// StoreToDeploymentLister gives a store List and Exists methods. The store must contain only Deployments. +type StoreToDeploymentLister struct { + Store +} + +// Exists checks if the given deployment exists in the store. +func (s *StoreToDeploymentLister) Exists(deployment *extensions.Deployment) (bool, error) { + _, exists, err := s.Store.Get(deployment) + if err != nil { + return false, err + } + return exists, nil +} + +// StoreToDeploymentLister lists all deployments in the store. +// TODO: converge on the interface in pkg/client +func (s *StoreToDeploymentLister) List() (deployments []extensions.Deployment, err error) { + for _, c := range s.Store.List() { + deployments = append(deployments, *(c.(*extensions.Deployment))) + } + return deployments, nil +} + +// GetDeploymentsForReplicaSet returns a list of deployments managing a replica set. Returns an error only if no matching deployments are found. +func (s *StoreToDeploymentLister) GetDeploymentsForReplicaSet(rs *extensions.ReplicaSet) (deployments []extensions.Deployment, err error) { + var d extensions.Deployment + + if len(rs.Labels) == 0 { + err = fmt.Errorf("no deployments found for ReplicaSet %v because it has no labels", rs.Name) + return + } + + // TODO: MODIFY THIS METHOD so that it checks for the podTemplateSpecHash label + for _, m := range s.Store.List() { + d = *m.(*extensions.Deployment) + if d.Namespace != rs.Namespace { + continue + } + + selector, err := unversioned.LabelSelectorAsSelector(d.Spec.Selector) + if err != nil { + return nil, fmt.Errorf("invalid label selector: %v", err) + } + // If a deployment with a nil or empty selector creeps in, it should match nothing, not everything. + if selector.Empty() || !selector.Matches(labels.Set(rs.Labels)) { + continue + } + deployments = append(deployments, d) + } + if len(deployments) == 0 { + err = fmt.Errorf("could not find deployments set for ReplicaSet %s in namespace %s with labels: %v", rs.Name, rs.Namespace, rs.Labels) + } + return +} + +// StoreToReplicaSetLister gives a store List and Exists methods. The store must contain only ReplicaSets. +type StoreToReplicaSetLister struct { + Store +} + +// Exists checks if the given ReplicaSet exists in the store. +func (s *StoreToReplicaSetLister) Exists(rs *extensions.ReplicaSet) (bool, error) { + _, exists, err := s.Store.Get(rs) + if err != nil { + return false, err + } + return exists, nil +} + +// List lists all ReplicaSets in the store. +// TODO: converge on the interface in pkg/client +func (s *StoreToReplicaSetLister) List() (rss []extensions.ReplicaSet, err error) { + for _, rs := range s.Store.List() { + rss = append(rss, *(rs.(*extensions.ReplicaSet))) + } + return rss, nil +} + +type storeReplicaSetsNamespacer struct { + store Store + namespace string +} + +func (s storeReplicaSetsNamespacer) List(selector labels.Selector) (rss []extensions.ReplicaSet, err error) { + for _, c := range s.store.List() { + rs := *(c.(*extensions.ReplicaSet)) + if s.namespace == api.NamespaceAll || s.namespace == rs.Namespace { + if selector.Matches(labels.Set(rs.Labels)) { + rss = append(rss, rs) + } + } + } + return +} + +func (s *StoreToReplicaSetLister) ReplicaSets(namespace string) storeReplicaSetsNamespacer { + return storeReplicaSetsNamespacer{s.Store, namespace} +} + +// GetPodReplicaSets returns a list of ReplicaSets managing a pod. Returns an error only if no matching ReplicaSets are found. +func (s *StoreToReplicaSetLister) GetPodReplicaSets(pod *api.Pod) (rss []extensions.ReplicaSet, err error) { + var selector labels.Selector + var rs extensions.ReplicaSet + + if len(pod.Labels) == 0 { + err = fmt.Errorf("no ReplicaSets found for pod %v because it has no labels", pod.Name) + return + } + + for _, m := range s.Store.List() { + rs = *m.(*extensions.ReplicaSet) + if rs.Namespace != pod.Namespace { + continue + } + selector, err = unversioned.LabelSelectorAsSelector(rs.Spec.Selector) + if err != nil { + err = fmt.Errorf("invalid selector: %v", err) + return + } + + // If a ReplicaSet with a nil or empty selector creeps in, it should match nothing, not everything. + if selector.Empty() || !selector.Matches(labels.Set(pod.Labels)) { + continue + } + rss = append(rss, rs) + } + if len(rss) == 0 { + err = fmt.Errorf("could not find ReplicaSet for pod %s in namespace %s with labels: %v", pod.Name, pod.Namespace, pod.Labels) + } + return +} + +// StoreToDaemonSetLister gives a store List and Exists methods. The store must contain only DaemonSets. +type StoreToDaemonSetLister struct { + Store +} + +// Exists checks if the given daemon set exists in the store. +func (s *StoreToDaemonSetLister) Exists(ds *extensions.DaemonSet) (bool, error) { + _, exists, err := s.Store.Get(ds) + if err != nil { + return false, err + } + return exists, nil +} + +// List lists all daemon sets in the store. +// TODO: converge on the interface in pkg/client +func (s *StoreToDaemonSetLister) List() (dss extensions.DaemonSetList, err error) { + for _, c := range s.Store.List() { + dss.Items = append(dss.Items, *(c.(*extensions.DaemonSet))) + } + return dss, nil +} + +// GetPodDaemonSets returns a list of daemon sets managing a pod. +// Returns an error if and only if no matching daemon sets are found. +func (s *StoreToDaemonSetLister) GetPodDaemonSets(pod *api.Pod) (daemonSets []extensions.DaemonSet, err error) { + var selector labels.Selector + var daemonSet extensions.DaemonSet + + if len(pod.Labels) == 0 { + err = fmt.Errorf("no daemon sets found for pod %v because it has no labels", pod.Name) + return + } + + for _, m := range s.Store.List() { + daemonSet = *m.(*extensions.DaemonSet) + if daemonSet.Namespace != pod.Namespace { + continue + } + selector, err = unversioned.LabelSelectorAsSelector(daemonSet.Spec.Selector) + if err != nil { + // this should not happen if the DaemonSet passed validation + return nil, err + } + + // If a daemonSet with a nil or empty selector creeps in, it should match nothing, not everything. + if selector.Empty() || !selector.Matches(labels.Set(pod.Labels)) { + continue + } + daemonSets = append(daemonSets, daemonSet) + } + if len(daemonSets) == 0 { + err = fmt.Errorf("could not find daemon set for pod %s in namespace %s with labels: %v", pod.Name, pod.Namespace, pod.Labels) + } + return +} + +// StoreToServiceLister makes a Store that has the List method of the client.ServiceInterface +// The Store must contain (only) Services. +type StoreToServiceLister struct { + Store +} + +func (s *StoreToServiceLister) List() (services api.ServiceList, err error) { + for _, m := range s.Store.List() { + services.Items = append(services.Items, *(m.(*api.Service))) + } + return services, nil +} + +// TODO: Move this back to scheduler as a helper function that takes a Store, +// rather than a method of StoreToServiceLister. +func (s *StoreToServiceLister) GetPodServices(pod *api.Pod) (services []api.Service, err error) { + var selector labels.Selector + var service api.Service + + for _, m := range s.Store.List() { + service = *m.(*api.Service) + // consider only services that are in the same namespace as the pod + if service.Namespace != pod.Namespace { + continue + } + if service.Spec.Selector == nil { + // services with nil selectors match nothing, not everything. + continue + } + selector = labels.Set(service.Spec.Selector).AsSelector() + if selector.Matches(labels.Set(pod.Labels)) { + services = append(services, service) + } + } + if len(services) == 0 { + err = fmt.Errorf("could not find service for pod %s in namespace %s with labels: %v", pod.Name, pod.Namespace, pod.Labels) + } + + return +} + +// StoreToEndpointsLister makes a Store that lists endpoints. +type StoreToEndpointsLister struct { + Store +} + +// List lists all endpoints in the store. +func (s *StoreToEndpointsLister) List() (services api.EndpointsList, err error) { + for _, m := range s.Store.List() { + services.Items = append(services.Items, *(m.(*api.Endpoints))) + } + return services, nil +} + +// GetServiceEndpoints returns the endpoints of a service, matched on service name. +func (s *StoreToEndpointsLister) GetServiceEndpoints(svc *api.Service) (ep api.Endpoints, err error) { + for _, m := range s.Store.List() { + ep = *m.(*api.Endpoints) + if svc.Name == ep.Name && svc.Namespace == ep.Namespace { + return ep, nil + } + } + err = fmt.Errorf("could not find endpoints for service: %v", svc.Name) + return +} + +// StoreToJobLister gives a store List and Exists methods. The store must contain only Jobs. +type StoreToJobLister struct { + Store +} + +// Exists checks if the given job exists in the store. +func (s *StoreToJobLister) Exists(job *extensions.Job) (bool, error) { + _, exists, err := s.Store.Get(job) + if err != nil { + return false, err + } + return exists, nil +} + +// StoreToJobLister lists all jobs in the store. +func (s *StoreToJobLister) List() (jobs extensions.JobList, err error) { + for _, c := range s.Store.List() { + jobs.Items = append(jobs.Items, *(c.(*extensions.Job))) + } + return jobs, nil +} + +// GetPodJobs returns a list of jobs managing a pod. Returns an error only if no matching jobs are found. +func (s *StoreToJobLister) GetPodJobs(pod *api.Pod) (jobs []extensions.Job, err error) { + var selector labels.Selector + var job extensions.Job + + if len(pod.Labels) == 0 { + err = fmt.Errorf("no jobs found for pod %v because it has no labels", pod.Name) + return + } + + for _, m := range s.Store.List() { + job = *m.(*extensions.Job) + if job.Namespace != pod.Namespace { + continue + } + + selector, _ = unversioned.LabelSelectorAsSelector(job.Spec.Selector) + if !selector.Matches(labels.Set(pod.Labels)) { + continue + } + jobs = append(jobs, job) + } + if len(jobs) == 0 { + err = fmt.Errorf("could not find jobs for pod %s in namespace %s with labels: %v", pod.Name, pod.Namespace, pod.Labels) + } + return +} + +// Typed wrapper around a store of PersistentVolumes +type StoreToPVFetcher struct { + Store +} + +// GetPersistentVolumeInfo returns cached data for the PersistentVolume 'id'. +func (s *StoreToPVFetcher) GetPersistentVolumeInfo(id string) (*api.PersistentVolume, error) { + o, exists, err := s.Get(&api.PersistentVolume{ObjectMeta: api.ObjectMeta{Name: id}}) + + if err != nil { + return nil, fmt.Errorf("error retrieving PersistentVolume '%v' from cache: %v", id, err) + } + + if !exists { + return nil, fmt.Errorf("PersistentVolume '%v' is not in cache", id) + } + + return o.(*api.PersistentVolume), nil +} + +// Typed wrapper around a store of PersistentVolumeClaims +type StoreToPVCFetcher struct { + Store +} + +// GetPersistentVolumeClaimInfo returns cached data for the PersistentVolumeClaim 'id'. +func (s *StoreToPVCFetcher) GetPersistentVolumeClaimInfo(namespace string, id string) (*api.PersistentVolumeClaim, error) { + o, exists, err := s.Get(&api.PersistentVolumeClaim{ObjectMeta: api.ObjectMeta{Namespace: namespace, Name: id}}) + if err != nil { + return nil, fmt.Errorf("error retrieving PersistentVolumeClaim '%s/%s' from cache: %v", namespace, id, err) + } + + if !exists { + return nil, fmt.Errorf("PersistentVolumeClaim '%s/%s' is not in cache", namespace, id) + } + + return o.(*api.PersistentVolumeClaim), nil +} diff --git a/vendor/k8s.io/kubernetes/pkg/client/cache/listwatch.go b/vendor/k8s.io/kubernetes/pkg/client/cache/listwatch.go new file mode 100644 index 0000000..06c2f61 --- /dev/null +++ b/vendor/k8s.io/kubernetes/pkg/client/cache/listwatch.go @@ -0,0 +1,86 @@ +/* +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 cache + +import ( + "time" + + "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/client/restclient" + "k8s.io/kubernetes/pkg/fields" + "k8s.io/kubernetes/pkg/runtime" + "k8s.io/kubernetes/pkg/watch" +) + +// ListFunc knows how to list resources +type ListFunc func(options api.ListOptions) (runtime.Object, error) + +// WatchFunc knows how to watch resources +type WatchFunc func(options api.ListOptions) (watch.Interface, error) + +// ListWatch knows how to list and watch a set of apiserver resources. It satisfies the ListerWatcher interface. +// It is a convenience function for users of NewReflector, etc. +// ListFunc and WatchFunc must not be nil +type ListWatch struct { + ListFunc ListFunc + WatchFunc WatchFunc +} + +// Getter interface knows how to access Get method from RESTClient. +type Getter interface { + Get() *restclient.Request +} + +// NewListWatchFromClient creates a new ListWatch from the specified client, resource, namespace and field selector. +func NewListWatchFromClient(c Getter, resource string, namespace string, fieldSelector fields.Selector) *ListWatch { + listFunc := func(options api.ListOptions) (runtime.Object, error) { + return c.Get(). + Namespace(namespace). + Resource(resource). + VersionedParams(&options, api.ParameterCodec). + FieldsSelectorParam(fieldSelector). + Do(). + Get() + } + watchFunc := func(options api.ListOptions) (watch.Interface, error) { + return c.Get(). + Prefix("watch"). + Namespace(namespace). + Resource(resource). + VersionedParams(&options, api.ParameterCodec). + FieldsSelectorParam(fieldSelector). + Watch() + } + return &ListWatch{ListFunc: listFunc, WatchFunc: watchFunc} +} + +func timeoutFromListOptions(options api.ListOptions) time.Duration { + if options.TimeoutSeconds != nil { + return time.Duration(*options.TimeoutSeconds) * time.Second + } + return 0 +} + +// List a set of apiserver resources +func (lw *ListWatch) List(options api.ListOptions) (runtime.Object, error) { + return lw.ListFunc(options) +} + +// Watch a set of apiserver resources +func (lw *ListWatch) Watch(options api.ListOptions) (watch.Interface, error) { + return lw.WatchFunc(options) +} diff --git a/vendor/k8s.io/kubernetes/pkg/client/cache/reflector.go b/vendor/k8s.io/kubernetes/pkg/client/cache/reflector.go new file mode 100644 index 0000000..31b076b --- /dev/null +++ b/vendor/k8s.io/kubernetes/pkg/client/cache/reflector.go @@ -0,0 +1,382 @@ +/* +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 cache + +import ( + "errors" + "fmt" + "io" + "math/rand" + "net" + "net/url" + "reflect" + goruntime "runtime" + "strings" + "sync" + "syscall" + "time" + + "github.com/golang/glog" + "k8s.io/kubernetes/pkg/api" + apierrs "k8s.io/kubernetes/pkg/api/errors" + "k8s.io/kubernetes/pkg/api/meta" + "k8s.io/kubernetes/pkg/runtime" + utilruntime "k8s.io/kubernetes/pkg/util/runtime" + "k8s.io/kubernetes/pkg/util/wait" + "k8s.io/kubernetes/pkg/watch" +) + +// ListerWatcher is any object that knows how to perform an initial list and start a watch on a resource. +type ListerWatcher interface { + // List should return a list type object; the Items field will be extracted, and the + // ResourceVersion field will be used to start the watch in the right place. + List(options api.ListOptions) (runtime.Object, error) + // Watch should begin a watch at the specified version. + Watch(options api.ListOptions) (watch.Interface, error) +} + +// Reflector watches a specified resource and causes all changes to be reflected in the given store. +type Reflector struct { + // name identifies this reflector. By default it will be a file:line if possible. + name string + + // The type of object we expect to place in the store. + expectedType reflect.Type + // The destination to sync up with the watch source + store Store + // listerWatcher is used to perform lists and watches. + listerWatcher ListerWatcher + // period controls timing between one watch ending and + // the beginning of the next one. + period time.Duration + resyncPeriod time.Duration + // now() returns current time - exposed for testing purposes + now func() time.Time + // nextResync is approximate time of next resync (0 if not scheduled) + nextResync time.Time + // lastSyncResourceVersion is the resource version token last + // observed when doing a sync with the underlying store + // it is thread safe, but not synchronized with the underlying store + lastSyncResourceVersion string + // lastSyncResourceVersionMutex guards read/write access to lastSyncResourceVersion + lastSyncResourceVersionMutex sync.RWMutex +} + +var ( + // We try to spread the load on apiserver by setting timeouts for + // watch requests - it is random in [minWatchTimeout, 2*minWatchTimeout]. + // However, it can be modified to avoid periodic resync to break the + // TCP connection. + minWatchTimeout = 5 * time.Minute + // If we are within 'forceResyncThreshold' from the next planned resync + // and are just before issuing Watch(), resync will be forced now. + forceResyncThreshold = 3 * time.Second + // We try to set timeouts for Watch() so that we will finish about + // than 'timeoutThreshold' from next planned periodic resync. + timeoutThreshold = 1 * time.Second +) + +// NewNamespaceKeyedIndexerAndReflector creates an Indexer and a Reflector +// The indexer is configured to key on namespace +func NewNamespaceKeyedIndexerAndReflector(lw ListerWatcher, expectedType interface{}, resyncPeriod time.Duration) (indexer Indexer, reflector *Reflector) { + indexer = NewIndexer(MetaNamespaceKeyFunc, Indexers{"namespace": MetaNamespaceIndexFunc}) + reflector = NewReflector(lw, expectedType, indexer, resyncPeriod) + return indexer, reflector +} + +// NewReflector creates a new Reflector object which will keep the given store up to +// date with the server's contents for the given resource. Reflector promises to +// only put things in the store that have the type of expectedType, unless expectedType +// is nil. If resyncPeriod is non-zero, then lists will be executed after every +// resyncPeriod, so that you can use reflectors to periodically process everything as +// well as incrementally processing the things that change. +func NewReflector(lw ListerWatcher, expectedType interface{}, store Store, resyncPeriod time.Duration) *Reflector { + return NewNamedReflector(getDefaultReflectorName(internalPackages...), lw, expectedType, store, resyncPeriod) +} + +// NewNamedReflector same as NewReflector, but with a specified name for logging +func NewNamedReflector(name string, lw ListerWatcher, expectedType interface{}, store Store, resyncPeriod time.Duration) *Reflector { + r := &Reflector{ + name: name, + listerWatcher: lw, + store: store, + expectedType: reflect.TypeOf(expectedType), + period: time.Second, + resyncPeriod: resyncPeriod, + now: time.Now, + } + return r +} + +// internalPackages are packages that ignored when creating a default reflector name. These packages are in the common +// call chains to NewReflector, so they'd be low entropy names for reflectors +var internalPackages = []string{"kubernetes/pkg/client/cache/", "kubernetes/pkg/controller/framework/"} + +// getDefaultReflectorName walks back through the call stack until we find a caller from outside of the ignoredPackages +// it returns back a shortpath/filename:line to aid in identification of this reflector when it starts logging +func getDefaultReflectorName(ignoredPackages ...string) string { + name := "????" +outer: + for i := 1; i < 10; i++ { + _, file, line, ok := goruntime.Caller(i) + if !ok { + break + } + for _, ignoredPackage := range ignoredPackages { + if strings.Contains(file, ignoredPackage) { + continue outer + } + + } + + pkgLocation := strings.LastIndex(file, "/pkg/") + if pkgLocation >= 0 { + file = file[pkgLocation+1:] + } + name = fmt.Sprintf("%s:%d", file, line) + break + } + + return name +} + +// Run starts a watch and handles watch events. Will restart the watch if it is closed. +// Run starts a goroutine and returns immediately. +func (r *Reflector) Run() { + go wait.Until(func() { r.ListAndWatch(wait.NeverStop) }, r.period, wait.NeverStop) +} + +// RunUntil starts a watch and handles watch events. Will restart the watch if it is closed. +// RunUntil starts a goroutine and returns immediately. It will exit when stopCh is closed. +func (r *Reflector) RunUntil(stopCh <-chan struct{}) { + go wait.Until(func() { r.ListAndWatch(stopCh) }, r.period, stopCh) +} + +var ( + // nothing will ever be sent down this channel + neverExitWatch <-chan time.Time = make(chan time.Time) + + // Used to indicate that watching stopped so that a resync could happen. + errorResyncRequested = errors.New("resync channel fired") + + // Used to indicate that watching stopped because of a signal from the stop + // channel passed in from a client of the reflector. + errorStopRequested = errors.New("Stop requested") +) + +// resyncChan returns a channel which will receive something when a resync is +// required, and a cleanup function. +func (r *Reflector) resyncChan() (<-chan time.Time, func() bool) { + if r.resyncPeriod == 0 { + r.nextResync = time.Time{} + return neverExitWatch, func() bool { return false } + } + // The cleanup function is required: imagine the scenario where watches + // always fail so we end up listing frequently. Then, if we don't + // manually stop the timer, we could end up with many timers active + // concurrently. + r.nextResync = r.now().Add(r.resyncPeriod) + t := time.NewTimer(r.resyncPeriod) + 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. +func (r *Reflector) ListAndWatch(stopCh <-chan struct{}) error { + var resourceVersion string + resyncCh, cleanup := r.resyncChan() + defer cleanup() + + // Explicitly set "0" as resource version - it's fine for the List() + // to be served from cache and potentially be delayed relative to + // etcd contents. Reflector framework will catch up via Watch() eventually. + options := api.ListOptions{ResourceVersion: "0"} + list, err := r.listerWatcher.List(options) + if err != nil { + return fmt.Errorf("%s: Failed to list %v: %v", r.name, r.expectedType, err) + } + metaInterface, err := meta.Accessor(list) + if err != nil { + return fmt.Errorf("%s: Unable to understand list result %#v", r.name, list) + } + resourceVersion = metaInterface.GetResourceVersion() + items, err := meta.ExtractList(list) + if err != nil { + return fmt.Errorf("%s: Unable to understand list result %#v (%v)", r.name, list, err) + } + if err := r.syncWith(items, resourceVersion); err != nil { + return fmt.Errorf("%s: Unable to sync list result: %v", r.name, err) + } + 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(), + } + w, err := r.listerWatcher.Watch(options) + if err != nil { + switch err { + case io.EOF: + // watch closed normally + case io.ErrUnexpectedEOF: + glog.V(1).Infof("%s: Watch for %v closed with unexpected EOF: %v", r.name, r.expectedType, err) + default: + utilruntime.HandleError(fmt.Errorf("%s: Failed to watch %v: %v", r.name, r.expectedType, err)) + } + // If this is "connection refused" error, it means that most likely apiserver is not responsive. + // It doesn't make sense to re-list all objects because most likely we will be able to restart + // watch where we ended. + // If that's the case wait and resend watch request. + if urlError, ok := err.(*url.Error); ok { + if opError, ok := urlError.Err.(*net.OpError); ok { + if errno, ok := opError.Err.(syscall.Errno); ok && errno == syscall.ECONNREFUSED { + time.Sleep(time.Second) + continue + } + } + } + return nil + } + if err := r.watchHandler(w, &resourceVersion, resyncCh, stopCh); err != nil { + if err != errorResyncRequested && 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 + } + } +} + +// syncWith replaces the store's items with the given list. +func (r *Reflector) syncWith(items []runtime.Object, resourceVersion string) error { + found := make([]interface{}, 0, len(items)) + for _, item := range items { + found = append(found, item) + } + return r.store.Replace(found, resourceVersion) +} + +// 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 { + start := time.Now() + eventCount := 0 + + // Stopping the watcher should be idempotent and if we return from this function there's no way + // we're coming back in with the same watch interface. + defer w.Stop() + +loop: + for { + select { + case <-stopCh: + return errorStopRequested + case <-resyncCh: + return errorResyncRequested + case event, ok := <-w.ResultChan(): + if !ok { + break loop + } + if event.Type == watch.Error { + return apierrs.FromObject(event.Object) + } + if e, a := r.expectedType, reflect.TypeOf(event.Object); e != nil && e != a { + utilruntime.HandleError(fmt.Errorf("%s: expected type %v, but watch event object had type %v", r.name, e, a)) + continue + } + meta, err := meta.Accessor(event.Object) + if err != nil { + utilruntime.HandleError(fmt.Errorf("%s: unable to understand watch event %#v", r.name, event)) + continue + } + newResourceVersion := meta.GetResourceVersion() + switch event.Type { + case watch.Added: + r.store.Add(event.Object) + case watch.Modified: + r.store.Update(event.Object) + case watch.Deleted: + // TODO: Will any consumers need access to the "last known + // state", which is passed in event.Object? If so, may need + // to change this. + r.store.Delete(event.Object) + default: + utilruntime.HandleError(fmt.Errorf("%s: unable to understand watch event %#v", r.name, event)) + } + *resourceVersion = newResourceVersion + r.setLastSyncResourceVersion(newResourceVersion) + eventCount++ + } + } + + watchDuration := time.Now().Sub(start) + if watchDuration < 1*time.Second && eventCount == 0 { + glog.V(4).Infof("%s: Unexpected watch close - watch lasted less than a second and no items received", r.name) + return errors.New("very short watch") + } + glog.V(4).Infof("%s: Watch close - %v total %v items received", r.name, r.expectedType, eventCount) + return nil +} + +// LastSyncResourceVersion is the resource version observed when last sync with the underlying store +// The value returned is not synchronized with access to the underlying store and is not thread-safe +func (r *Reflector) LastSyncResourceVersion() string { + r.lastSyncResourceVersionMutex.RLock() + defer r.lastSyncResourceVersionMutex.RUnlock() + return r.lastSyncResourceVersion +} + +func (r *Reflector) setLastSyncResourceVersion(v string) { + r.lastSyncResourceVersionMutex.Lock() + defer r.lastSyncResourceVersionMutex.Unlock() + r.lastSyncResourceVersion = v +} diff --git a/vendor/k8s.io/kubernetes/pkg/client/cache/store.go b/vendor/k8s.io/kubernetes/pkg/client/cache/store.go new file mode 100644 index 0000000..17a360f --- /dev/null +++ b/vendor/k8s.io/kubernetes/pkg/client/cache/store.go @@ -0,0 +1,225 @@ +/* +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 cache + +import ( + "fmt" + "strings" + + "k8s.io/kubernetes/pkg/api/meta" +) + +// Store is a generic object storage interface. Reflector knows how to watch a server +// and update a store. A generic store is provided, which allows Reflector to be used +// as a local caching system, and an LRU store, which allows Reflector to work like a +// queue of items yet to be processed. +// +// Store makes no assumptions about stored object identity; it is the responsibility +// of a Store implementation to provide a mechanism to correctly key objects and to +// define the contract for obtaining objects by some arbitrary key type. +type Store interface { + Add(obj interface{}) error + Update(obj interface{}) error + Delete(obj interface{}) error + List() []interface{} + ListKeys() []string + Get(obj interface{}) (item interface{}, exists bool, err error) + GetByKey(key string) (item interface{}, exists bool, err error) + + // Replace will delete the contents of the store, using instead the + // given list. Store takes ownership of the list, you should not reference + // it after calling this function. + Replace([]interface{}, string) error +} + +// KeyFunc knows how to make a key from an object. Implementations should be deterministic. +type KeyFunc func(obj interface{}) (string, error) + +// KeyError will be returned any time a KeyFunc gives an error; it includes the object +// at fault. +type KeyError struct { + Obj interface{} + Err error +} + +// Error gives a human-readable description of the error. +func (k KeyError) Error() string { + return fmt.Sprintf("couldn't create key for object %+v: %v", k.Obj, k.Err) +} + +// ExplicitKey can be passed to MetaNamespaceKeyFunc if you have the key for +// the object but not the object itself. +type ExplicitKey string + +// MetaNamespaceKeyFunc is a convenient default KeyFunc which knows how to make +// keys for API objects which implement meta.Interface. +// The key uses the format / unless is empty, then +// it's just . +// +// TODO: replace key-as-string with a key-as-struct so that this +// packing/unpacking won't be necessary. +func MetaNamespaceKeyFunc(obj interface{}) (string, error) { + if key, ok := obj.(ExplicitKey); ok { + return string(key), nil + } + meta, err := meta.Accessor(obj) + if err != nil { + return "", fmt.Errorf("object has no meta: %v", err) + } + if len(meta.GetNamespace()) > 0 { + return meta.GetNamespace() + "/" + meta.GetName(), nil + } + return meta.GetName(), nil +} + +// SplitMetaNamespaceKey returns the namespace and name that +// MetaNamespaceKeyFunc encoded into key. +// +// TODO: replace key-as-string with a key-as-struct so that this +// packing/unpacking won't be necessary. +func SplitMetaNamespaceKey(key string) (namespace, name string, err error) { + parts := strings.Split(key, "/") + switch len(parts) { + case 1: + // name only, no namespace + return "", parts[0], nil + case 2: + // name and namespace + return parts[0], parts[1], nil + } + + return "", "", fmt.Errorf("unexpected key format: %q", key) +} + +// cache responsibilities are limited to: +// 1. Computing keys for objects via keyFunc +// 2. Invoking methods of a ThreadSafeStorage interface +type cache struct { + // cacheStorage bears the burden of thread safety for the cache + cacheStorage ThreadSafeStore + // keyFunc is used to make the key for objects stored in and retrieved from items, and + // should be deterministic. + keyFunc KeyFunc +} + +var _ Store = &cache{} + +// Add inserts an item into the cache. +func (c *cache) Add(obj interface{}) error { + key, err := c.keyFunc(obj) + if err != nil { + return KeyError{obj, err} + } + c.cacheStorage.Add(key, obj) + return nil +} + +// Update sets an item in the cache to its updated state. +func (c *cache) Update(obj interface{}) error { + key, err := c.keyFunc(obj) + if err != nil { + return KeyError{obj, err} + } + c.cacheStorage.Update(key, obj) + return nil +} + +// Delete removes an item from the cache. +func (c *cache) Delete(obj interface{}) error { + key, err := c.keyFunc(obj) + if err != nil { + return KeyError{obj, err} + } + c.cacheStorage.Delete(key) + return nil +} + +// List returns a list of all the items. +// List is completely threadsafe as long as you treat all items as immutable. +func (c *cache) List() []interface{} { + return c.cacheStorage.List() +} + +// ListKeys returns a list of all the keys of the objects currently +// in the cache. +func (c *cache) ListKeys() []string { + return c.cacheStorage.ListKeys() +} + +// Index returns a list of items that match on the index function +// Index is thread-safe so long as you treat all items as immutable +func (c *cache) Index(indexName string, obj interface{}) ([]interface{}, error) { + return c.cacheStorage.Index(indexName, obj) +} + +// ListIndexFuncValues returns the list of generated values of an Index func +func (c *cache) ListIndexFuncValues(indexName string) []string { + return c.cacheStorage.ListIndexFuncValues(indexName) +} + +func (c *cache) ByIndex(indexName, indexKey string) ([]interface{}, error) { + return c.cacheStorage.ByIndex(indexName, indexKey) +} + +// 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) { + key, err := c.keyFunc(obj) + if err != nil { + return nil, false, KeyError{obj, err} + } + return c.GetByKey(key) +} + +// GetByKey returns the request item, or exists=false. +// GetByKey is completely threadsafe as long as you treat all items as immutable. +func (c *cache) GetByKey(key string) (item interface{}, exists bool, err error) { + item, exists = c.cacheStorage.Get(key) + return item, exists, nil +} + +// Replace will delete the contents of 'c', using instead the given list. +// 'c' takes ownership of the list, you should not reference the list again +// after calling this function. +func (c *cache) Replace(list []interface{}, resourceVersion string) error { + items := map[string]interface{}{} + for _, item := range list { + key, err := c.keyFunc(item) + if err != nil { + return KeyError{item, err} + } + items[key] = item + } + c.cacheStorage.Replace(items, resourceVersion) + return nil +} + +// NewStore returns a Store implemented simply with a map and a lock. +func NewStore(keyFunc KeyFunc) Store { + return &cache{ + cacheStorage: NewThreadSafeStore(Indexers{}, Indices{}), + keyFunc: keyFunc, + } +} + +// NewIndexer returns an Indexer implemented simply with a map and a lock. +func NewIndexer(keyFunc KeyFunc, indexers Indexers) Indexer { + return &cache{ + cacheStorage: NewThreadSafeStore(indexers, Indices{}), + keyFunc: keyFunc, + } +} 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 new file mode 100644 index 0000000..ae4b802 --- /dev/null +++ b/vendor/k8s.io/kubernetes/pkg/client/cache/thread_safe_store.go @@ -0,0 +1,248 @@ +/* +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 cache + +import ( + "fmt" + "sync" + + "k8s.io/kubernetes/pkg/util/sets" +) + +// ThreadSafeStore is an interface that allows concurrent access to a storage backend. +// TL;DR caveats: you must not modify anything returned by Get or List as it will break +// the indexing feature in addition to not being thread safe. +// +// The guarantees of thread safety provided by List/Get are only valid if the caller +// treats returned items as read-only. For example, a pointer inserted in the store +// through `Add` will be returned as is by `Get`. Multiple clients might invoke `Get` +// on the same key and modify the pointer in a non-thread-safe way. Also note that +// modifying objects stored by the indexers (if any) will *not* automatically lead +// to a re-index. So it's not a good idea to directly modify the objects returned by +// Get/List, in general. +type ThreadSafeStore interface { + Add(key string, obj interface{}) + Update(key string, obj interface{}) + Delete(key string) + Get(key string) (item interface{}, exists bool) + List() []interface{} + ListKeys() []string + Replace(map[string]interface{}, string) + Index(indexName string, obj interface{}) ([]interface{}, error) + ListIndexFuncValues(name string) []string + ByIndex(indexName, indexKey string) ([]interface{}, error) +} + +// threadSafeMap implements ThreadSafeStore +type threadSafeMap struct { + lock sync.RWMutex + items map[string]interface{} + + // indexers maps a name to an IndexFunc + indexers Indexers + // indices maps a name to an Index + indices Indices +} + +func (c *threadSafeMap) Add(key string, obj interface{}) { + c.lock.Lock() + defer c.lock.Unlock() + oldObject := c.items[key] + c.items[key] = obj + c.updateIndices(oldObject, obj, key) +} + +func (c *threadSafeMap) Update(key string, obj interface{}) { + c.lock.Lock() + defer c.lock.Unlock() + oldObject := c.items[key] + c.items[key] = obj + c.updateIndices(oldObject, obj, key) +} + +func (c *threadSafeMap) Delete(key string) { + c.lock.Lock() + defer c.lock.Unlock() + if obj, exists := c.items[key]; exists { + c.deleteFromIndices(obj, key) + delete(c.items, key) + } +} + +func (c *threadSafeMap) Get(key string) (item interface{}, exists bool) { + c.lock.RLock() + defer c.lock.RUnlock() + item, exists = c.items[key] + return item, exists +} + +func (c *threadSafeMap) List() []interface{} { + c.lock.RLock() + defer c.lock.RUnlock() + list := make([]interface{}, 0, len(c.items)) + for _, item := range c.items { + list = append(list, item) + } + return list +} + +// ListKeys returns a list of all the keys of the objects currently +// in the threadSafeMap. +func (c *threadSafeMap) ListKeys() []string { + c.lock.RLock() + defer c.lock.RUnlock() + list := make([]string, 0, len(c.items)) + for key := range c.items { + list = append(list, key) + } + return list +} + +func (c *threadSafeMap) Replace(items map[string]interface{}, resourceVersion string) { + c.lock.Lock() + defer c.lock.Unlock() + c.items = items + + // rebuild any index + c.indices = Indices{} + for key, item := range c.items { + c.updateIndices(nil, item, key) + } +} + +// Index returns a list of items that match on the index function +// Index is thread-safe so long as you treat all items as immutable +func (c *threadSafeMap) Index(indexName string, obj interface{}) ([]interface{}, error) { + c.lock.RLock() + defer c.lock.RUnlock() + + indexFunc := c.indexers[indexName] + if indexFunc == nil { + return nil, fmt.Errorf("Index with name %s does not exist", indexName) + } + + indexKeys, err := indexFunc(obj) + if err != nil { + return nil, err + } + index := c.indices[indexName] + + // need to de-dupe the return list. Since multiple keys are allowed, this can happen. + returnKeySet := sets.String{} + for _, indexKey := range indexKeys { + set := index[indexKey] + for _, key := range set.List() { + returnKeySet.Insert(key) + } + } + + list := make([]interface{}, 0, returnKeySet.Len()) + for absoluteKey := range returnKeySet { + list = append(list, c.items[absoluteKey]) + } + return list, nil +} + +// ByIndex returns a list of items that match an exact value on the index function +func (c *threadSafeMap) ByIndex(indexName, indexKey string) ([]interface{}, error) { + c.lock.RLock() + defer c.lock.RUnlock() + + indexFunc := c.indexers[indexName] + if indexFunc == nil { + return nil, fmt.Errorf("Index with name %s does not exist", indexName) + } + + index := c.indices[indexName] + + set := index[indexKey] + list := make([]interface{}, 0, set.Len()) + for _, key := range set.List() { + list = append(list, c.items[key]) + } + + return list, nil +} + +func (c *threadSafeMap) ListIndexFuncValues(indexName string) []string { + index := c.indices[indexName] + names := make([]string, 0, len(index)) + for key := range index { + names = append(names, key) + } + return names +} + +// 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 { + // if we got an old object, we need to remove it before we add it again + if oldObj != nil { + c.deleteFromIndices(oldObj, key) + } + for name, indexFunc := range c.indexers { + indexValues, err := indexFunc(newObj) + if err != nil { + return err + } + index := c.indices[name] + if index == nil { + index = Index{} + c.indices[name] = index + } + + for _, indexValue := range indexValues { + set := index[indexValue] + if set == nil { + set = sets.String{} + index[indexValue] = set + } + set.Insert(key) + } + } + return nil +} + +// deleteFromIndices removes the object from each of the managed indexes +// it is intended to be called from a function that already has a lock on the cache +func (c *threadSafeMap) deleteFromIndices(obj interface{}, key string) error { + for name, indexFunc := range c.indexers { + indexValues, err := indexFunc(obj) + if err != nil { + return err + } + + index := c.indices[name] + for _, indexValue := range indexValues { + if index != nil { + set := index[indexValue] + if set != nil { + set.Delete(key) + } + } + } + } + return nil +} + +func NewThreadSafeStore(indexers Indexers, indices Indices) ThreadSafeStore { + return &threadSafeMap{ + items: map[string]interface{}{}, + indexers: indexers, + indices: indices, + } +} diff --git a/vendor/k8s.io/kubernetes/pkg/client/cache/undelta_store.go b/vendor/k8s.io/kubernetes/pkg/client/cache/undelta_store.go new file mode 100644 index 0000000..4a8a450 --- /dev/null +++ b/vendor/k8s.io/kubernetes/pkg/client/cache/undelta_store.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 cache + +// UndeltaStore listens to incremental updates and sends complete state on every change. +// It implements the Store interface so that it can receive a stream of mirrored objects +// from Reflector. Whenever it receives any complete (Store.Replace) or incremental change +// (Store.Add, Store.Update, Store.Delete), it sends the complete state by calling PushFunc. +// It is thread-safe. It guarantees that every change (Add, Update, Replace, Delete) results +// in one call to PushFunc, but sometimes PushFunc may be called twice with the same values. +// PushFunc should be thread safe. +type UndeltaStore struct { + Store + PushFunc func([]interface{}) +} + +// Assert that it implements the Store interface. +var _ Store = &UndeltaStore{} + +// Note about thread safety. The Store implementation (cache.cache) uses a lock for all methods. +// In the functions below, the lock gets released and reacquired betweend the {Add,Delete,etc} +// and the List. So, the following can happen, resulting in two identical calls to PushFunc. +// time thread 1 thread 2 +// 0 UndeltaStore.Add(a) +// 1 UndeltaStore.Add(b) +// 2 Store.Add(a) +// 3 Store.Add(b) +// 4 Store.List() -> [a,b] +// 5 Store.List() -> [a,b] + +func (u *UndeltaStore) Add(obj interface{}) error { + if err := u.Store.Add(obj); err != nil { + return err + } + u.PushFunc(u.Store.List()) + return nil +} + +func (u *UndeltaStore) Update(obj interface{}) error { + if err := u.Store.Update(obj); err != nil { + return err + } + u.PushFunc(u.Store.List()) + return nil +} + +func (u *UndeltaStore) Delete(obj interface{}) error { + if err := u.Store.Delete(obj); err != nil { + return err + } + u.PushFunc(u.Store.List()) + return nil +} + +func (u *UndeltaStore) Replace(list []interface{}, resourceVersion string) error { + if err := u.Store.Replace(list, resourceVersion); err != nil { + return err + } + u.PushFunc(u.Store.List()) + return nil +} + +// NewUndeltaStore returns an UndeltaStore implemented with a Store. +func NewUndeltaStore(pushFunc func([]interface{}), keyFunc KeyFunc) *UndeltaStore { + return &UndeltaStore{ + Store: NewStore(keyFunc), + PushFunc: pushFunc, + } +} diff --git a/vendor/k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/clientset.go b/vendor/k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/clientset.go index ff14a31..599a0c4 100644 --- a/vendor/k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/clientset.go +++ b/vendor/k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/clientset.go @@ -19,13 +19,13 @@ package internalclientset import ( "github.com/golang/glog" restclient "k8s.io/kubernetes/pkg/client/restclient" + discovery "k8s.io/kubernetes/pkg/client/typed/discovery" unversionedcore "k8s.io/kubernetes/pkg/client/typed/generated/core/unversioned" unversionedextensions "k8s.io/kubernetes/pkg/client/typed/generated/extensions/unversioned" - unversioned "k8s.io/kubernetes/pkg/client/unversioned" ) type Interface interface { - Discovery() unversioned.DiscoveryInterface + Discovery() discovery.DiscoveryInterface Core() unversionedcore.CoreInterface Extensions() unversionedextensions.ExtensionsInterface } @@ -33,7 +33,7 @@ type Interface interface { // Clientset contains the clients for groups. Each group has exactly one // version included in a Clientset. type Clientset struct { - *unversioned.DiscoveryClient + *discovery.DiscoveryClient *unversionedcore.CoreClient *unversionedextensions.ExtensionsClient } @@ -49,7 +49,7 @@ func (c *Clientset) Extensions() unversionedextensions.ExtensionsInterface { } // Discovery retrieves the DiscoveryClient -func (c *Clientset) Discovery() unversioned.DiscoveryInterface { +func (c *Clientset) Discovery() discovery.DiscoveryInterface { return c.DiscoveryClient } @@ -66,7 +66,7 @@ func NewForConfig(c *restclient.Config) (*Clientset, error) { return &clientset, err } - clientset.DiscoveryClient, err = unversioned.NewDiscoveryClientForConfig(c) + clientset.DiscoveryClient, err = discovery.NewDiscoveryClientForConfig(c) if err != nil { glog.Errorf("failed to create the DiscoveryClient: %v", err) } @@ -80,7 +80,7 @@ func NewForConfigOrDie(c *restclient.Config) *Clientset { clientset.CoreClient = unversionedcore.NewForConfigOrDie(c) clientset.ExtensionsClient = unversionedextensions.NewForConfigOrDie(c) - clientset.DiscoveryClient = unversioned.NewDiscoveryClientForConfigOrDie(c) + clientset.DiscoveryClient = discovery.NewDiscoveryClientForConfigOrDie(c) return &clientset } @@ -90,6 +90,6 @@ func New(c *restclient.RESTClient) *Clientset { clientset.CoreClient = unversionedcore.New(c) clientset.ExtensionsClient = unversionedextensions.New(c) - clientset.DiscoveryClient = unversioned.NewDiscoveryClient(c) + clientset.DiscoveryClient = discovery.NewDiscoveryClient(c) return &clientset } diff --git a/vendor/k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/clientset_adaption.go b/vendor/k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/clientset_adaption.go index 28c9454..2e1214a 100644 --- a/vendor/k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/clientset_adaption.go +++ b/vendor/k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/clientset_adaption.go @@ -17,6 +17,7 @@ limitations under the License. package internalclientset import ( + "k8s.io/kubernetes/pkg/client/typed/discovery" unversionedcore "k8s.io/kubernetes/pkg/client/typed/generated/core/unversioned" unversionedextensions "k8s.io/kubernetes/pkg/client/typed/generated/extensions/unversioned" "k8s.io/kubernetes/pkg/client/unversioned" @@ -39,9 +40,9 @@ func FromUnversionedClient(c *unversioned.Client) *Clientset { } if c != nil && c.DiscoveryClient != nil { - clientset.DiscoveryClient = unversioned.NewDiscoveryClient(c.DiscoveryClient.RESTClient) + clientset.DiscoveryClient = discovery.NewDiscoveryClient(c.DiscoveryClient.RESTClient) } else { - clientset.DiscoveryClient = unversioned.NewDiscoveryClient(nil) + clientset.DiscoveryClient = discovery.NewDiscoveryClient(nil) } return &clientset diff --git a/vendor/k8s.io/kubernetes/pkg/client/record/doc.go b/vendor/k8s.io/kubernetes/pkg/client/record/doc.go new file mode 100644 index 0000000..d955154 --- /dev/null +++ b/vendor/k8s.io/kubernetes/pkg/client/record/doc.go @@ -0,0 +1,18 @@ +/* +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 record has all client logic for recording and reporting events. +package record diff --git a/vendor/k8s.io/kubernetes/pkg/client/record/event.go b/vendor/k8s.io/kubernetes/pkg/client/record/event.go new file mode 100644 index 0000000..a478682 --- /dev/null +++ b/vendor/k8s.io/kubernetes/pkg/client/record/event.go @@ -0,0 +1,310 @@ +/* +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 record + +import ( + "fmt" + "math/rand" + "time" + + "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/errors" + "k8s.io/kubernetes/pkg/api/unversioned" + "k8s.io/kubernetes/pkg/client/restclient" + "k8s.io/kubernetes/pkg/runtime" + "k8s.io/kubernetes/pkg/util" + utilruntime "k8s.io/kubernetes/pkg/util/runtime" + "k8s.io/kubernetes/pkg/watch" + + "github.com/golang/glog" +) + +const maxTriesPerEvent = 12 + +var sleepDuration = 10 * time.Second + +const maxQueuedEvents = 1000 + +// EventSink knows how to store events (client.Client implements it.) +// EventSink must respect the namespace that will be embedded in 'event'. +// It is assumed that EventSink will return the same sorts of errors as +// pkg/client's REST client. +type EventSink interface { + Create(event *api.Event) (*api.Event, error) + Update(event *api.Event) (*api.Event, error) + Patch(oldEvent *api.Event, data []byte) (*api.Event, error) +} + +// EventRecorder knows how to record events on behalf of an EventSource. +type EventRecorder interface { + // Event constructs an event from the given information and puts it in the queue for sending. + // 'object' is the object this event is about. Event will make a reference-- or you may also + // pass a reference to the object directly. + // 'type' of this event, and can be one of Normal, Warning. New types could be added in future + // 'reason' is the reason this event is generated. 'reason' should be short and unique; it + // should be in UpperCamelCase format (starting with a capital letter). "reason" will be used + // to automate handling of events, so imagine people writing switch statements to handle them. + // You want to make that easy. + // 'message' is intended to be human readable. + // + // The resulting event will be created in the same namespace as the reference object. + Event(object runtime.Object, eventtype, reason, message string) + + // Eventf is just like Event, but with Sprintf for the message field. + Eventf(object runtime.Object, eventtype, reason, messageFmt string, args ...interface{}) + + // PastEventf is just like Eventf, but with an option to specify the event's 'timestamp' field. + PastEventf(object runtime.Object, timestamp unversioned.Time, eventtype, reason, messageFmt string, args ...interface{}) +} + +// EventBroadcaster knows how to receive events and send them to any EventSink, watcher, or log. +type EventBroadcaster interface { + // StartEventWatcher starts sending events received from this EventBroadcaster to the given + // event handler function. The return value can be ignored or used to stop recording, if + // desired. + StartEventWatcher(eventHandler func(*api.Event)) watch.Interface + + // StartRecordingToSink starts sending events received from this EventBroadcaster to the given + // sink. The return value can be ignored or used to stop recording, if desired. + StartRecordingToSink(sink EventSink) watch.Interface + + // StartLogging starts sending events received from this EventBroadcaster to the given logging + // function. The return value can be ignored or used to stop recording, if desired. + StartLogging(logf func(format string, args ...interface{})) watch.Interface + + // NewRecorder returns an EventRecorder that can be used to send events to this EventBroadcaster + // with the event source set to the given event source. + NewRecorder(source api.EventSource) EventRecorder +} + +// Creates a new event broadcaster. +func NewBroadcaster() EventBroadcaster { + return &eventBroadcasterImpl{watch.NewBroadcaster(maxQueuedEvents, watch.DropIfChannelFull)} +} + +type eventBroadcasterImpl struct { + *watch.Broadcaster +} + +// StartRecordingToSink starts sending events received from the specified eventBroadcaster to the given sink. +// The return value can be ignored or used to stop recording, if desired. +// TODO: make me an object with parameterizable queue length and retry interval +func (eventBroadcaster *eventBroadcasterImpl) StartRecordingToSink(sink EventSink) watch.Interface { + // The default math/rand package functions aren't thread safe, so create a + // new Rand object for each StartRecording call. + randGen := rand.New(rand.NewSource(time.Now().UnixNano())) + eventCorrelator := NewEventCorrelator(util.RealClock{}) + return eventBroadcaster.StartEventWatcher( + func(event *api.Event) { + recordToSink(sink, event, eventCorrelator, randGen) + }) +} + +func recordToSink(sink EventSink, event *api.Event, eventCorrelator *EventCorrelator, randGen *rand.Rand) { + // Make a copy before modification, because there could be multiple listeners. + // Events are safe to copy like this. + eventCopy := *event + event = &eventCopy + result, err := eventCorrelator.EventCorrelate(event) + if err != nil { + utilruntime.HandleError(err) + } + if result.Skip { + return + } + tries := 0 + for { + if recordEvent(sink, result.Event, result.Patch, result.Event.Count > 1, eventCorrelator) { + break + } + tries++ + if tries >= maxTriesPerEvent { + glog.Errorf("Unable to write event '%#v' (retry limit exceeded!)", event) + break + } + // Randomize the first sleep so that various clients won't all be + // synced up if the master goes down. + if tries == 1 { + time.Sleep(time.Duration(float64(sleepDuration) * randGen.Float64())) + } else { + time.Sleep(sleepDuration) + } + } +} + +func isKeyNotFoundError(err error) bool { + statusErr, _ := err.(*errors.StatusError) + // At the moment the server is returning 500 instead of a more specific + // error. When changing this remember that it should be backward compatible + // with old api servers that may be still returning 500. + if statusErr != nil && statusErr.Status().Code == 500 { + return true + } + return false +} + +// recordEvent attempts to write event to a sink. It returns true if the event +// was successfully recorded or discarded, false if it should be retried. +// If updateExistingEvent is false, it creates a new event, otherwise it updates +// existing event. +func recordEvent(sink EventSink, event *api.Event, patch []byte, updateExistingEvent bool, eventCorrelator *EventCorrelator) bool { + var newEvent *api.Event + var err error + if updateExistingEvent { + newEvent, err = sink.Patch(event, patch) + } + // Update can fail because the event may have been removed and it no longer exists. + if !updateExistingEvent || (updateExistingEvent && isKeyNotFoundError(err)) { + // Making sure that ResourceVersion is empty on creation + event.ResourceVersion = "" + newEvent, err = sink.Create(event) + } + if err == nil { + // we need to update our event correlator with the server returned state to handle name/resourceversion + eventCorrelator.UpdateState(newEvent) + return true + } + + // If we can't contact the server, then hold everything while we keep trying. + // Otherwise, something about the event is malformed and we should abandon it. + switch err.(type) { + case *restclient.RequestConstructionError: + // We will construct the request the same next time, so don't keep trying. + glog.Errorf("Unable to construct event '%#v': '%v' (will not retry!)", event, err) + return true + case *errors.StatusError: + if errors.IsAlreadyExists(err) { + glog.V(5).Infof("Server rejected event '%#v': '%v' (will not retry!)", event, err) + } else { + glog.Errorf("Server rejected event '%#v': '%v' (will not retry!)", event, err) + } + return true + case *errors.UnexpectedObjectError: + // We don't expect this; it implies the server's response didn't match a + // known pattern. Go ahead and retry. + default: + // This case includes actual http transport errors. Go ahead and retry. + } + glog.Errorf("Unable to write event: '%v' (may retry after sleeping)", err) + return false +} + +// StartLogging starts sending events received from this EventBroadcaster to the given logging function. +// The return value can be ignored or used to stop recording, if desired. +func (eventBroadcaster *eventBroadcasterImpl) StartLogging(logf func(format string, args ...interface{})) watch.Interface { + return eventBroadcaster.StartEventWatcher( + func(e *api.Event) { + logf("Event(%#v): type: '%v' reason: '%v' %v", e.InvolvedObject, e.Type, e.Reason, e.Message) + }) +} + +// StartEventWatcher starts sending events received from this EventBroadcaster to the given event handler function. +// The return value can be ignored or used to stop recording, if desired. +func (eventBroadcaster *eventBroadcasterImpl) StartEventWatcher(eventHandler func(*api.Event)) watch.Interface { + watcher := eventBroadcaster.Watch() + go func() { + defer utilruntime.HandleCrash() + for { + watchEvent, open := <-watcher.ResultChan() + if !open { + return + } + event, ok := watchEvent.Object.(*api.Event) + if !ok { + // This is all local, so there's no reason this should + // ever happen. + continue + } + eventHandler(event) + } + }() + return watcher +} + +// NewRecorder returns an EventRecorder that records events with the given event source. +func (eventBroadcaster *eventBroadcasterImpl) NewRecorder(source api.EventSource) EventRecorder { + return &recorderImpl{source, eventBroadcaster.Broadcaster, util.RealClock{}} +} + +type recorderImpl struct { + source api.EventSource + *watch.Broadcaster + clock util.Clock +} + +func (recorder *recorderImpl) generateEvent(object runtime.Object, timestamp unversioned.Time, eventtype, reason, message string) { + ref, err := api.GetReference(object) + if err != nil { + glog.Errorf("Could not construct reference to: '%#v' due to: '%v'. Will not report event: '%v' '%v' '%v'", object, err, eventtype, reason, message) + return + } + + if !validateEventType(eventtype) { + glog.Errorf("Unsupported event type: '%v'", eventtype) + return + } + + event := recorder.makeEvent(ref, eventtype, reason, message) + event.Source = recorder.source + + go func() { + // NOTE: events should be a non-blocking operation + defer utilruntime.HandleCrash() + recorder.Action(watch.Added, event) + }() +} + +func validateEventType(eventtype string) bool { + switch eventtype { + case api.EventTypeNormal, api.EventTypeWarning: + return true + } + return false +} + +func (recorder *recorderImpl) Event(object runtime.Object, eventtype, reason, message string) { + recorder.generateEvent(object, unversioned.Now(), eventtype, reason, message) +} + +func (recorder *recorderImpl) Eventf(object runtime.Object, eventtype, reason, messageFmt string, args ...interface{}) { + recorder.Event(object, eventtype, reason, fmt.Sprintf(messageFmt, args...)) +} + +func (recorder *recorderImpl) PastEventf(object runtime.Object, timestamp unversioned.Time, eventtype, reason, messageFmt string, args ...interface{}) { + recorder.generateEvent(object, timestamp, eventtype, reason, fmt.Sprintf(messageFmt, args...)) +} + +func (recorder *recorderImpl) makeEvent(ref *api.ObjectReference, eventtype, reason, message string) *api.Event { + t := unversioned.Time{recorder.clock.Now()} + namespace := ref.Namespace + if namespace == "" { + namespace = api.NamespaceDefault + } + return &api.Event{ + ObjectMeta: api.ObjectMeta{ + Name: fmt.Sprintf("%v.%x", ref.Name, t.UnixNano()), + Namespace: namespace, + }, + InvolvedObject: *ref, + Reason: reason, + Message: message, + FirstTimestamp: t, + LastTimestamp: t, + Count: 1, + Type: eventtype, + } +} diff --git a/vendor/k8s.io/kubernetes/pkg/client/record/events_cache.go b/vendor/k8s.io/kubernetes/pkg/client/record/events_cache.go new file mode 100644 index 0000000..5d93ba6 --- /dev/null +++ b/vendor/k8s.io/kubernetes/pkg/client/record/events_cache.go @@ -0,0 +1,360 @@ +/* +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 record + +import ( + "encoding/json" + "fmt" + "strings" + "sync" + "time" + + "github.com/golang/groupcache/lru" + + "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/unversioned" + "k8s.io/kubernetes/pkg/util" + "k8s.io/kubernetes/pkg/util/sets" + "k8s.io/kubernetes/pkg/util/strategicpatch" +) + +const ( + maxLruCacheEntries = 4096 + + // if we see the same event that varies only by message + // more than 10 times in a 10 minute period, aggregate the event + defaultAggregateMaxEvents = 10 + defaultAggregateIntervalInSeconds = 600 +) + +// getEventKey builds unique event key based on source, involvedObject, reason, message +func getEventKey(event *api.Event) string { + return strings.Join([]string{ + event.Source.Component, + event.Source.Host, + event.InvolvedObject.Kind, + event.InvolvedObject.Namespace, + event.InvolvedObject.Name, + string(event.InvolvedObject.UID), + event.InvolvedObject.APIVersion, + event.Type, + event.Reason, + event.Message, + }, + "") +} + +// EventFilterFunc is a function that returns true if the event should be skipped +type EventFilterFunc func(event *api.Event) bool + +// DefaultEventFilterFunc returns false for all incoming events +func DefaultEventFilterFunc(event *api.Event) bool { + return false +} + +// EventAggregatorKeyFunc is responsible for grouping events for aggregation +// It returns a tuple of the following: +// aggregateKey - key the identifies the aggregate group to bucket this event +// localKey - key that makes this event in the local group +type EventAggregatorKeyFunc func(event *api.Event) (aggregateKey string, localKey string) + +// EventAggregatorByReasonFunc aggregates events by exact match on event.Source, event.InvolvedObject, event.Type and event.Reason +func EventAggregatorByReasonFunc(event *api.Event) (string, string) { + return strings.Join([]string{ + event.Source.Component, + event.Source.Host, + event.InvolvedObject.Kind, + event.InvolvedObject.Namespace, + event.InvolvedObject.Name, + string(event.InvolvedObject.UID), + event.InvolvedObject.APIVersion, + event.Type, + event.Reason, + }, + ""), event.Message +} + +// EventAggregatorMessageFunc is responsible for producing an aggregation message +type EventAggregatorMessageFunc func(event *api.Event) string + +// EventAggregratorByReasonMessageFunc returns an aggregate message by prefixing the incoming message +func EventAggregatorByReasonMessageFunc(event *api.Event) string { + return "(events with common reason combined)" +} + +// EventAggregator identifies similar events and aggregates them into a single event +type EventAggregator struct { + sync.RWMutex + + // The cache that manages aggregation state + cache *lru.Cache + + // The function that groups events for aggregation + keyFunc EventAggregatorKeyFunc + + // The function that generates a message for an aggregate event + messageFunc EventAggregatorMessageFunc + + // The maximum number of events in the specified interval before aggregation occurs + maxEvents int + + // The amount of time in seconds that must transpire since the last occurrence of a similar event before it's considered new + maxIntervalInSeconds int + + // clock is used to allow for testing over a time interval + clock util.Clock +} + +// NewEventAggregator returns a new instance of an EventAggregator +func NewEventAggregator(lruCacheSize int, keyFunc EventAggregatorKeyFunc, messageFunc EventAggregatorMessageFunc, + maxEvents int, maxIntervalInSeconds int, clock util.Clock) *EventAggregator { + return &EventAggregator{ + cache: lru.New(lruCacheSize), + keyFunc: keyFunc, + messageFunc: messageFunc, + maxEvents: maxEvents, + maxIntervalInSeconds: maxIntervalInSeconds, + clock: clock, + } +} + +// aggregateRecord holds data used to perform aggregation decisions +type aggregateRecord struct { + // we track the number of unique local keys we have seen in the aggregate set to know when to actually aggregate + // if the size of this set exceeds the max, we know we need to aggregate + localKeys sets.String + // The last time at which the aggregate was recorded + lastTimestamp unversioned.Time +} + +// EventAggregate identifies similar events and groups into a common event if required +func (e *EventAggregator) EventAggregate(newEvent *api.Event) (*api.Event, error) { + aggregateKey, localKey := e.keyFunc(newEvent) + now := unversioned.NewTime(e.clock.Now()) + record := aggregateRecord{localKeys: sets.NewString(), lastTimestamp: now} + e.Lock() + defer e.Unlock() + value, found := e.cache.Get(aggregateKey) + if found { + record = value.(aggregateRecord) + } + + // if the last event was far enough in the past, it is not aggregated, and we must reset state + maxInterval := time.Duration(e.maxIntervalInSeconds) * time.Second + interval := now.Time.Sub(record.lastTimestamp.Time) + if interval > maxInterval { + record = aggregateRecord{localKeys: sets.NewString()} + } + record.localKeys.Insert(localKey) + record.lastTimestamp = now + e.cache.Add(aggregateKey, record) + + if record.localKeys.Len() < e.maxEvents { + return newEvent, nil + } + + // do not grow our local key set any larger than max + record.localKeys.PopAny() + + // create a new aggregate event + eventCopy := &api.Event{ + ObjectMeta: api.ObjectMeta{ + Name: fmt.Sprintf("%v.%x", newEvent.InvolvedObject.Name, now.UnixNano()), + Namespace: newEvent.Namespace, + }, + Count: 1, + FirstTimestamp: now, + InvolvedObject: newEvent.InvolvedObject, + LastTimestamp: now, + Message: e.messageFunc(newEvent), + Type: newEvent.Type, + Reason: newEvent.Reason, + Source: newEvent.Source, + } + return eventCopy, nil +} + +// eventLog records data about when an event was observed +type eventLog struct { + // The number of times the event has occurred since first occurrence. + count int + + // The time at which the event was first recorded. + firstTimestamp unversioned.Time + + // The unique name of the first occurrence of this event + name string + + // Resource version returned from previous interaction with server + resourceVersion string +} + +// eventLogger logs occurrences of an event +type eventLogger struct { + sync.RWMutex + cache *lru.Cache + clock util.Clock +} + +// newEventLogger observes events and counts their frequencies +func newEventLogger(lruCacheEntries int, clock util.Clock) *eventLogger { + return &eventLogger{cache: lru.New(lruCacheEntries), clock: clock} +} + +// eventObserve records the event, and determines if its frequency should update +func (e *eventLogger) eventObserve(newEvent *api.Event) (*api.Event, []byte, error) { + var ( + patch []byte + err error + ) + key := getEventKey(newEvent) + eventCopy := *newEvent + event := &eventCopy + + e.Lock() + defer e.Unlock() + + lastObservation := e.lastEventObservationFromCache(key) + + // we have seen this event before, so we must prepare a patch + if lastObservation.count > 0 { + // update the event based on the last observation so patch will work as desired + event.Name = lastObservation.name + event.ResourceVersion = lastObservation.resourceVersion + event.FirstTimestamp = lastObservation.firstTimestamp + event.Count = lastObservation.count + 1 + + eventCopy2 := *event + eventCopy2.Count = 0 + eventCopy2.LastTimestamp = unversioned.NewTime(time.Unix(0, 0)) + + newData, _ := json.Marshal(event) + oldData, _ := json.Marshal(eventCopy2) + patch, err = strategicpatch.CreateStrategicMergePatch(oldData, newData, event) + } + + // record our new observation + e.cache.Add( + key, + eventLog{ + count: event.Count, + firstTimestamp: event.FirstTimestamp, + name: event.Name, + resourceVersion: event.ResourceVersion, + }, + ) + return event, patch, err +} + +// updateState updates its internal tracking information based on latest server state +func (e *eventLogger) updateState(event *api.Event) { + key := getEventKey(event) + e.Lock() + defer e.Unlock() + // record our new observation + e.cache.Add( + key, + eventLog{ + count: event.Count, + firstTimestamp: event.FirstTimestamp, + name: event.Name, + resourceVersion: event.ResourceVersion, + }, + ) +} + +// lastEventObservationFromCache returns the event from the cache, reads must be protected via external lock +func (e *eventLogger) lastEventObservationFromCache(key string) eventLog { + value, ok := e.cache.Get(key) + if ok { + observationValue, ok := value.(eventLog) + if ok { + return observationValue + } + } + return eventLog{} +} + +// EventCorrelator processes all incoming events and performs analysis to avoid overwhelming the system. It can filter all +// incoming events to see if the event should be filtered from further processing. It can aggregate similar events that occur +// frequently to protect the system from spamming events that are difficult for users to distinguish. It performs de-duplication +// to ensure events that are observed multiple times are compacted into a single event with increasing counts. +type EventCorrelator struct { + // the function to filter the event + filterFunc EventFilterFunc + // the object that performs event aggregation + aggregator *EventAggregator + // the object that observes events as they come through + logger *eventLogger +} + +// EventCorrelateResult is the result of a Correlate +type EventCorrelateResult struct { + // the event after correlation + Event *api.Event + // if provided, perform a strategic patch when updating the record on the server + Patch []byte + // if true, do no further processing of the event + Skip bool +} + +// NewEventCorrelator returns an EventCorrelator configured with default values. +// +// The EventCorrelator is responsible for event filtering, aggregating, and counting +// prior to interacting with the API server to record the event. +// +// The default behavior is as follows: +// * No events are filtered from being recorded +// * Aggregation is performed if a similar event is recorded 10 times in a +// in a 10 minute rolling interval. A similar event is an event that varies only by +// the Event.Message field. Rather than recording the precise event, aggregation +// will create a new event whose message reports that it has combined events with +// the same reason. +// * Events are incrementally counted if the exact same event is encountered multiple +// times. +func NewEventCorrelator(clock util.Clock) *EventCorrelator { + cacheSize := maxLruCacheEntries + return &EventCorrelator{ + filterFunc: DefaultEventFilterFunc, + aggregator: NewEventAggregator( + cacheSize, + EventAggregatorByReasonFunc, + EventAggregatorByReasonMessageFunc, + defaultAggregateMaxEvents, + defaultAggregateIntervalInSeconds, + clock), + logger: newEventLogger(cacheSize, clock), + } +} + +// EventCorrelate filters, aggregates, counts, and de-duplicates all incoming events +func (c *EventCorrelator) EventCorrelate(newEvent *api.Event) (*EventCorrelateResult, error) { + if c.filterFunc(newEvent) { + return &EventCorrelateResult{Skip: true}, nil + } + aggregateEvent, err := c.aggregator.EventAggregate(newEvent) + if err != nil { + return &EventCorrelateResult{}, err + } + observedEvent, patch, err := c.logger.eventObserve(aggregateEvent) + return &EventCorrelateResult{Event: observedEvent, Patch: patch}, err +} + +// UpdateState based on the latest observed state from server +func (c *EventCorrelator) UpdateState(event *api.Event) { + c.logger.updateState(event) +} diff --git a/vendor/k8s.io/kubernetes/pkg/client/record/fake.go b/vendor/k8s.io/kubernetes/pkg/client/record/fake.go new file mode 100644 index 0000000..7afe1ba --- /dev/null +++ b/vendor/k8s.io/kubernetes/pkg/client/record/fake.go @@ -0,0 +1,40 @@ +/* +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 record + +import ( + "fmt" + + "k8s.io/kubernetes/pkg/api/unversioned" + "k8s.io/kubernetes/pkg/runtime" +) + +// FakeRecorder is used as a fake during tests. +type FakeRecorder struct { + Events []string +} + +func (f *FakeRecorder) Event(object runtime.Object, eventtype, reason, message string) { + f.Events = append(f.Events, fmt.Sprintf("%s %s %s", eventtype, reason, message)) +} + +func (f *FakeRecorder) Eventf(object runtime.Object, eventtype, reason, messageFmt string, args ...interface{}) { + f.Events = append(f.Events, fmt.Sprintf(eventtype+" "+reason+" "+messageFmt, args...)) +} + +func (f *FakeRecorder) PastEventf(object runtime.Object, timestamp unversioned.Time, eventtype, reason, messageFmt string, args ...interface{}) { +} diff --git a/vendor/k8s.io/kubernetes/pkg/client/restclient/request.go b/vendor/k8s.io/kubernetes/pkg/client/restclient/request.go index 07c036e..0c9a10b 100644 --- a/vendor/k8s.io/kubernetes/pkg/client/restclient/request.go +++ b/vendor/k8s.io/kubernetes/pkg/client/restclient/request.go @@ -624,7 +624,7 @@ func (r *Request) tryThrottle() { r.throttle.Accept() } if latency := time.Since(now); latency > longThrottleLatency { - glog.Warningf("Throttling request took %v, request: %s", latency, r.URL().String()) + glog.Warningf("Throttling request took %v, request: %s:%s", latency, r.verb, r.URL().String()) } } diff --git a/vendor/k8s.io/kubernetes/pkg/client/unversioned/discovery_client.go b/vendor/k8s.io/kubernetes/pkg/client/typed/discovery/discovery_client.go similarity index 95% rename from vendor/k8s.io/kubernetes/pkg/client/unversioned/discovery_client.go rename to vendor/k8s.io/kubernetes/pkg/client/typed/discovery/discovery_client.go index 9de8b55..fa4d94a 100644 --- a/vendor/k8s.io/kubernetes/pkg/client/unversioned/discovery_client.go +++ b/vendor/k8s.io/kubernetes/pkg/client/typed/discovery/discovery_client.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package unversioned +package discovery import ( "encoding/json" @@ -148,7 +148,7 @@ func (d *DiscoveryClient) ServerResources() (map[string]*unversioned.APIResource if err != nil { return nil, err } - groupVersions := ExtractGroupVersions(apiGroups) + groupVersions := unversioned.ExtractGroupVersions(apiGroups) result := map[string]*unversioned.APIResourceList{} for _, groupVersion := range groupVersions { resources, err := d.ServerResourcesForGroupVersion(groupVersion) @@ -184,7 +184,7 @@ func (d *DiscoveryClient) SwaggerSchema(version unversioned.GroupVersion) (*swag if err != nil { return nil, err } - groupVersions := ExtractGroupVersions(groupList) + groupVersions := unversioned.ExtractGroupVersions(groupList) // This check also takes care the case that kubectl is newer than the running endpoint if stringDoesntExistIn(version.String(), groupVersions) { return nil, fmt.Errorf("API version: %v is not supported by the server. Use one of: %v", version, groupVersions) @@ -212,6 +212,9 @@ func setDiscoveryDefaults(config *restclient.Config) error { config.APIPath = "" config.GroupVersion = nil config.Codec = runtime.NoopEncoder{api.Codecs.UniversalDecoder()} + if len(config.UserAgent) == 0 { + config.UserAgent = restclient.DefaultKubernetesUserAgent() + } return nil } @@ -241,3 +244,12 @@ func NewDiscoveryClientForConfigOrDie(c *restclient.Config) *DiscoveryClient { func NewDiscoveryClient(c *restclient.RESTClient) *DiscoveryClient { return &DiscoveryClient{c} } + +func stringDoesntExistIn(str string, slice []string) bool { + for _, s := range slice { + if s == str { + return false + } + } + return true +} diff --git a/vendor/k8s.io/kubernetes/pkg/client/unversioned/client.go b/vendor/k8s.io/kubernetes/pkg/client/unversioned/client.go index 114f660..b897bc2 100644 --- a/vendor/k8s.io/kubernetes/pkg/client/unversioned/client.go +++ b/vendor/k8s.io/kubernetes/pkg/client/unversioned/client.go @@ -22,6 +22,7 @@ import ( "strings" "k8s.io/kubernetes/pkg/client/restclient" + "k8s.io/kubernetes/pkg/client/typed/discovery" ) // Interface holds the methods for clients of Kubernetes, @@ -46,7 +47,7 @@ type Interface interface { Autoscaling() AutoscalingInterface Batch() BatchInterface Extensions() ExtensionsInterface - Discovery() DiscoveryInterface + Discovery() discovery.DiscoveryInterface } func (c *Client) ReplicationControllers(namespace string) ReplicationControllerInterface { @@ -118,16 +119,7 @@ type Client struct { *AutoscalingClient *BatchClient *ExtensionsClient - *DiscoveryClient -} - -func stringDoesntExistIn(str string, slice []string) bool { - for _, s := range slice { - if s == str { - return false - } - } - return true + *discovery.DiscoveryClient } // IsTimeout tests if this is a timeout error in the underlying transport. @@ -164,6 +156,6 @@ func (c *Client) Extensions() ExtensionsInterface { return c.ExtensionsClient } -func (c *Client) Discovery() DiscoveryInterface { +func (c *Client) Discovery() discovery.DiscoveryInterface { return c.DiscoveryClient } diff --git a/vendor/k8s.io/kubernetes/pkg/client/unversioned/clientcmd/api/types.go b/vendor/k8s.io/kubernetes/pkg/client/unversioned/clientcmd/api/types.go index 4a1dc36..7e2bfcf 100644 --- a/vendor/k8s.io/kubernetes/pkg/client/unversioned/clientcmd/api/types.go +++ b/vendor/k8s.io/kubernetes/pkg/client/unversioned/clientcmd/api/types.go @@ -29,7 +29,11 @@ type Config struct { // Legacy field from pkg/api/types.go TypeMeta. // TODO(jlowdermilk): remove this after eliminating downstream dependencies. Kind string `json:"kind,omitempty"` - // Version of the schema for this config object. + // DEPRECATED: APIVersion is the preferred api version for communicating with the kubernetes cluster (v1, v2, etc). + // Because a cluster can run multiple API groups and potentially multiple versions of each, it no longer makes sense to specify + // a single value for the cluster version. + // This field isnt really needed anyway, so we are deprecating it without replacement. + // It will be ignored if it is present. APIVersion string `json:"apiVersion,omitempty"` // Preferences holds general information to be use for cli interactions Preferences Preferences `json:"preferences"` diff --git a/vendor/k8s.io/kubernetes/pkg/client/unversioned/clientcmd/api/v1/types.go b/vendor/k8s.io/kubernetes/pkg/client/unversioned/clientcmd/api/v1/types.go index e04f131..c9b4ab5 100644 --- a/vendor/k8s.io/kubernetes/pkg/client/unversioned/clientcmd/api/v1/types.go +++ b/vendor/k8s.io/kubernetes/pkg/client/unversioned/clientcmd/api/v1/types.go @@ -28,7 +28,11 @@ type Config struct { // Legacy field from pkg/api/types.go TypeMeta. // TODO(jlowdermilk): remove this after eliminating downstream dependencies. Kind string `json:"kind,omitempty"` - // Version of the schema for this config object. + // DEPRECATED: APIVersion is the preferred api version for communicating with the kubernetes cluster (v1, v2, etc). + // Because a cluster can run multiple API groups and potentially multiple versions of each, it no longer makes sense to specify + // a single value for the cluster version. + // This field isnt really needed anyway, so we are deprecating it without replacement. + // It will be ignored if it is present. APIVersion string `json:"apiVersion,omitempty"` // Preferences holds general information to be use for cli interactions Preferences Preferences `json:"preferences"` diff --git a/vendor/k8s.io/kubernetes/pkg/client/unversioned/clientcmd/client_config.go b/vendor/k8s.io/kubernetes/pkg/client/unversioned/clientcmd/client_config.go index 60a25b9..9ff259e 100644 --- a/vendor/k8s.io/kubernetes/pkg/client/unversioned/clientcmd/client_config.go +++ b/vendor/k8s.io/kubernetes/pkg/client/unversioned/clientcmd/client_config.go @@ -28,7 +28,6 @@ import ( "github.com/imdario/mergo" "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/client/restclient" clientauth "k8s.io/kubernetes/pkg/client/unversioned/auth" clientcmdapi "k8s.io/kubernetes/pkg/client/unversioned/clientcmd/api" @@ -100,13 +99,6 @@ func (config *DirectClientConfig) ClientConfig() (*restclient.Config, error) { u.Fragment = "" clientConfig.Host = u.String() } - if len(configClusterInfo.APIVersion) != 0 { - gv, err := unversioned.ParseGroupVersion(configClusterInfo.APIVersion) - if err != nil { - return nil, err - } - clientConfig.GroupVersion = &gv - } // only try to read the auth information if we are secure if restclient.IsConfigTransportTLS(*clientConfig) { diff --git a/vendor/k8s.io/kubernetes/pkg/client/unversioned/clientcmd/overrides.go b/vendor/k8s.io/kubernetes/pkg/client/unversioned/clientcmd/overrides.go index d6bc496..9996d2f 100644 --- a/vendor/k8s.io/kubernetes/pkg/client/unversioned/clientcmd/overrides.go +++ b/vendor/k8s.io/kubernetes/pkg/client/unversioned/clientcmd/overrides.go @@ -134,7 +134,7 @@ func RecommendedAuthOverrideFlags(prefix string) AuthOverrideFlags { func RecommendedClusterOverrideFlags(prefix string) ClusterOverrideFlags { return ClusterOverrideFlags{ APIServer: FlagInfo{prefix + FlagAPIServer, "", "", "The address and port of the Kubernetes API server"}, - APIVersion: FlagInfo{prefix + FlagAPIVersion, "", "", "The API version to use when talking to the server"}, + APIVersion: FlagInfo{prefix + FlagAPIVersion, "", "", "DEPRECATED: The API version to use when talking to the server"}, CertificateAuthority: FlagInfo{prefix + FlagCAFile, "", "", "Path to a cert. file for the certificate authority."}, InsecureSkipTLSVerify: FlagInfo{prefix + FlagInsecure, "", "false", "If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure."}, } @@ -171,7 +171,9 @@ func BindAuthInfoFlags(authInfo *clientcmdapi.AuthInfo, flags *pflag.FlagSet, fl // BindClusterFlags is a convenience method to bind the specified flags to their associated variables func BindClusterFlags(clusterInfo *clientcmdapi.Cluster, flags *pflag.FlagSet, flagNames ClusterOverrideFlags) { flagNames.APIServer.BindStringFlag(flags, &clusterInfo.Server) + // TODO: remove --api-version flag in 1.3. flagNames.APIVersion.BindStringFlag(flags, &clusterInfo.APIVersion) + flags.MarkDeprecated(FlagAPIVersion, "flag is no longer respected and will be deleted in the next release") flagNames.CertificateAuthority.BindStringFlag(flags, &clusterInfo.CertificateAuthority) flagNames.InsecureSkipTLSVerify.BindBoolFlag(flags, &clusterInfo.InsecureSkipTLSVerify) } diff --git a/vendor/k8s.io/kubernetes/pkg/client/unversioned/conditions.go b/vendor/k8s.io/kubernetes/pkg/client/unversioned/conditions.go index 7102c81..5087baa 100644 --- a/vendor/k8s.io/kubernetes/pkg/client/unversioned/conditions.go +++ b/vendor/k8s.io/kubernetes/pkg/client/unversioned/conditions.go @@ -153,12 +153,18 @@ func JobHasDesiredParallelism(c ExtensionsInterface, job *extensions.Job) wait.C // the desired replica count for a deployment equals its updated replicas count. // (non-terminated pods that have the desired template spec). func DeploymentHasDesiredReplicas(c ExtensionsInterface, deployment *extensions.Deployment) wait.ConditionFunc { + // If we're given a deployment where the status lags the spec, it either + // means that the deployment is stale, or that the deployment manager hasn't + // noticed the update yet. Polling status.Replicas is not safe in the latter + // case. + desiredGeneration := deployment.Generation return func() (bool, error) { deployment, err := c.Deployments(deployment.Namespace).Get(deployment.Name) if err != nil { return false, err } - return deployment.Status.UpdatedReplicas == deployment.Spec.Replicas, nil + return deployment.Status.ObservedGeneration >= desiredGeneration && + deployment.Status.UpdatedReplicas == deployment.Spec.Replicas, nil } } diff --git a/vendor/k8s.io/kubernetes/pkg/client/unversioned/helper.go b/vendor/k8s.io/kubernetes/pkg/client/unversioned/helper.go index 70ff902..3ee6d6e 100644 --- a/vendor/k8s.io/kubernetes/pkg/client/unversioned/helper.go +++ b/vendor/k8s.io/kubernetes/pkg/client/unversioned/helper.go @@ -27,6 +27,7 @@ import ( "k8s.io/kubernetes/pkg/apis/batch" "k8s.io/kubernetes/pkg/apis/extensions" "k8s.io/kubernetes/pkg/client/restclient" + "k8s.io/kubernetes/pkg/client/typed/discovery" "k8s.io/kubernetes/pkg/util/sets" "k8s.io/kubernetes/pkg/version" ) @@ -51,7 +52,7 @@ func New(c *restclient.Config) (*Client, error) { } discoveryConfig := *c - discoveryClient, err := NewDiscoveryClientForConfig(&discoveryConfig) + discoveryClient, err := discovery.NewDiscoveryClientForConfig(&discoveryConfig) if err != nil { return nil, err } @@ -109,16 +110,6 @@ func MatchesServerVersion(client *Client, c *restclient.Config) error { return nil } -func ExtractGroupVersions(l *unversioned.APIGroupList) []string { - var groupVersions []string - for _, g := range l.Groups { - for _, gv := range g.Versions { - groupVersions = append(groupVersions, gv.GroupVersion) - } - } - return groupVersions -} - // NegotiateVersion queries the server's supported api versions to find // a version that both client and server support. // - If no version is provided, try registered client versions in order of @@ -146,7 +137,7 @@ func NegotiateVersion(client *Client, c *restclient.Config, requestedGV *unversi // not a negotiation specific error. return nil, err } - versions := ExtractGroupVersions(groups) + versions := unversioned.ExtractGroupVersions(groups) serverVersions := sets.String{} for _, v := range versions { serverVersions.Insert(v) diff --git a/vendor/k8s.io/kubernetes/pkg/controller/OWNERS b/vendor/k8s.io/kubernetes/pkg/controller/OWNERS new file mode 100644 index 0000000..35859cd --- /dev/null +++ b/vendor/k8s.io/kubernetes/pkg/controller/OWNERS @@ -0,0 +1,5 @@ +assignees: + - bprashanth + - davidopp + - derekwaynecarr + - mikedanese diff --git a/vendor/k8s.io/kubernetes/pkg/controller/controller_utils.go b/vendor/k8s.io/kubernetes/pkg/controller/controller_utils.go new file mode 100644 index 0000000..fc37713 --- /dev/null +++ b/vendor/k8s.io/kubernetes/pkg/controller/controller_utils.go @@ -0,0 +1,647 @@ +/* +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 controller + +import ( + "fmt" + "sync" + "sync/atomic" + "time" + + "github.com/golang/glog" + "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/unversioned" + "k8s.io/kubernetes/pkg/api/validation" + "k8s.io/kubernetes/pkg/apis/extensions" + "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/controller/framework" + "k8s.io/kubernetes/pkg/labels" + "k8s.io/kubernetes/pkg/runtime" + "k8s.io/kubernetes/pkg/util" + "k8s.io/kubernetes/pkg/util/integer" + "k8s.io/kubernetes/pkg/util/sets" +) + +const ( + CreatedByAnnotation = "kubernetes.io/created-by" + + // If a watch drops a delete event for a pod, it'll take this long + // before a dormant controller waiting for those packets is woken up anyway. It is + // specifically targeted at the case where some problem prevents an update + // of expectations, without it the controller could stay asleep forever. This should + // be set based on the expected latency of watch events. + // + // Currently a controller can service (create *and* observe the watch events for said + // creation) about 10 pods a second, so it takes about 1 min to service + // 500 pods. Just creation is limited to 20qps, and watching happens with ~10-30s + // latency/pod at the scale of 3000 pods over 100 nodes. + ExpectationsTimeout = 5 * time.Minute +) + +var ( + KeyFunc = framework.DeletionHandlingMetaNamespaceKeyFunc +) + +type ResyncPeriodFunc func() time.Duration + +// Returns 0 for resyncPeriod in case resyncing is not needed. +func NoResyncPeriodFunc() time.Duration { + return 0 +} + +// StaticResyncPeriodFunc returns the resync period specified +func StaticResyncPeriodFunc(resyncPeriod time.Duration) ResyncPeriodFunc { + return func() time.Duration { + return resyncPeriod + } +} + +// Expectations are a way for controllers to tell the controller manager what they expect. eg: +// ControllerExpectations: { +// controller1: expects 2 adds in 2 minutes +// controller2: expects 2 dels in 2 minutes +// controller3: expects -1 adds in 2 minutes => controller3's expectations have already been met +// } +// +// Implementation: +// ControlleeExpectation = pair of atomic counters to track controllee's creation/deletion +// ControllerExpectationsStore = TTLStore + a ControlleeExpectation per controller +// +// * Once set expectations can only be lowered +// * A controller isn't synced till its expectations are either fulfilled, or expire +// * Controllers that don't set expectations will get woken up for every matching controllee + +// ExpKeyFunc to parse out the key from a ControlleeExpectation +var ExpKeyFunc = func(obj interface{}) (string, error) { + if e, ok := obj.(*ControlleeExpectations); ok { + return e.key, nil + } + return "", fmt.Errorf("Could not find key for obj %#v", obj) +} + +// ControllerExpectationsInterface is an interface that allows users to set and wait on expectations. +// Only abstracted out for testing. +// Warning: if using KeyFunc it is not safe to use a single ControllerExpectationsInterface with different +// types of controllers, because the keys might conflict across types. +type ControllerExpectationsInterface interface { + GetExpectations(controllerKey string) (*ControlleeExpectations, bool, error) + SatisfiedExpectations(controllerKey string) bool + DeleteExpectations(controllerKey string) + SetExpectations(controllerKey string, add, del int) error + ExpectCreations(controllerKey string, adds int) error + ExpectDeletions(controllerKey string, dels int) error + CreationObserved(controllerKey string) + DeletionObserved(controllerKey string) + RaiseExpectations(controllerKey string, add, del int) + LowerExpectations(controllerKey string, add, del int) +} + +// ControllerExpectations is a cache mapping controllers to what they expect to see before being woken up for a sync. +type ControllerExpectations struct { + cache.Store +} + +// GetExpectations returns the ControlleeExpectations of the given controller. +func (r *ControllerExpectations) GetExpectations(controllerKey string) (*ControlleeExpectations, bool, error) { + if exp, exists, err := r.GetByKey(controllerKey); err == nil && exists { + return exp.(*ControlleeExpectations), true, nil + } else { + return nil, false, err + } +} + +// DeleteExpectations deletes the expectations of the given controller from the TTLStore. +func (r *ControllerExpectations) DeleteExpectations(controllerKey string) { + if exp, exists, err := r.GetByKey(controllerKey); err == nil && exists { + if err := r.Delete(exp); err != nil { + glog.V(2).Infof("Error deleting expectations for controller %v: %v", controllerKey, err) + } + } +} + +// SatisfiedExpectations returns true if the required adds/dels for the given controller have been observed. +// Add/del counts are established by the controller at sync time, and updated as controllees are observed by the controller +// manager. +func (r *ControllerExpectations) SatisfiedExpectations(controllerKey string) bool { + if exp, exists, err := r.GetExpectations(controllerKey); exists { + if exp.Fulfilled() { + return true + } else if exp.isExpired() { + glog.V(4).Infof("Controller expectations expired %#v", exp) + return true + } else { + glog.V(4).Infof("Controller still waiting on expectations %#v", exp) + return false + } + } else if err != nil { + glog.V(2).Infof("Error encountered while checking expectations %#v, forcing sync", err) + } else { + // When a new controller is created, it doesn't have expectations. + // When it doesn't see expected watch events for > TTL, the expectations expire. + // - In this case it wakes up, creates/deletes controllees, and sets expectations again. + // When it has satisfied expectations and no controllees need to be created/destroyed > TTL, the expectations expire. + // - In this case it continues without setting expectations till it needs to create/delete controllees. + glog.V(4).Infof("Controller %v either never recorded expectations, or the ttl expired.", controllerKey) + } + // Trigger a sync if we either encountered and error (which shouldn't happen since we're + // getting from local store) or this controller hasn't established expectations. + return true +} + +// TODO: Extend ExpirationCache to support explicit expiration. +// TODO: Make this possible to disable in tests. +// TODO: Support injection of clock. +func (exp *ControlleeExpectations) isExpired() bool { + return util.RealClock{}.Since(exp.timestamp) > ExpectationsTimeout +} + +// SetExpectations registers new expectations for the given controller. Forgets existing expectations. +func (r *ControllerExpectations) SetExpectations(controllerKey string, add, del int) error { + exp := &ControlleeExpectations{add: int64(add), del: int64(del), key: controllerKey, timestamp: util.RealClock{}.Now()} + glog.V(4).Infof("Setting expectations %+v", exp) + return r.Add(exp) +} + +func (r *ControllerExpectations) ExpectCreations(controllerKey string, adds int) error { + return r.SetExpectations(controllerKey, adds, 0) +} + +func (r *ControllerExpectations) ExpectDeletions(controllerKey string, dels int) error { + return r.SetExpectations(controllerKey, 0, dels) +} + +// Decrements the expectation counts of the given controller. +func (r *ControllerExpectations) LowerExpectations(controllerKey string, add, del int) { + if exp, exists, err := r.GetExpectations(controllerKey); err == nil && exists { + exp.Add(int64(-add), int64(-del)) + // The expectations might've been modified since the update on the previous line. + glog.V(4).Infof("Lowered expectations %+v", exp) + } +} + +// Increments the expectation counts of the given controller. +func (r *ControllerExpectations) RaiseExpectations(controllerKey string, add, del int) { + if exp, exists, err := r.GetExpectations(controllerKey); err == nil && exists { + exp.Add(int64(add), int64(del)) + // The expectations might've been modified since the update on the previous line. + glog.V(4).Infof("Raised expectations %+v", exp) + } +} + +// CreationObserved atomically decrements the `add` expecation count of the given controller. +func (r *ControllerExpectations) CreationObserved(controllerKey string) { + r.LowerExpectations(controllerKey, 1, 0) +} + +// DeletionObserved atomically decrements the `del` expectation count of the given controller. +func (r *ControllerExpectations) DeletionObserved(controllerKey string) { + r.LowerExpectations(controllerKey, 0, 1) +} + +// Expectations are either fulfilled, or expire naturally. +type Expectations interface { + Fulfilled() bool +} + +// ControlleeExpectations track controllee creates/deletes. +type ControlleeExpectations struct { + add int64 + del int64 + key string + timestamp time.Time +} + +// Add increments the add and del counters. +func (e *ControlleeExpectations) Add(add, del int64) { + atomic.AddInt64(&e.add, add) + atomic.AddInt64(&e.del, del) +} + +// Fulfilled returns true if this expectation has been fulfilled. +func (e *ControlleeExpectations) Fulfilled() bool { + // TODO: think about why this line being atomic doesn't matter + return atomic.LoadInt64(&e.add) <= 0 && atomic.LoadInt64(&e.del) <= 0 +} + +// GetExpectations returns the add and del expectations of the controllee. +func (e *ControlleeExpectations) GetExpectations() (int64, int64) { + return atomic.LoadInt64(&e.add), atomic.LoadInt64(&e.del) +} + +// NewControllerExpectations returns a store for ControllerExpectations. +func NewControllerExpectations() *ControllerExpectations { + return &ControllerExpectations{cache.NewStore(ExpKeyFunc)} +} + +// UIDSetKeyFunc to parse out the key from a UIDSet. +var UIDSetKeyFunc = func(obj interface{}) (string, error) { + if u, ok := obj.(*UIDSet); ok { + return u.key, nil + } + return "", fmt.Errorf("Could not find key for obj %#v", obj) +} + +// UIDSet holds a key and a set of UIDs. Used by the +// UIDTrackingControllerExpectations to remember which UID it has seen/still +// waiting for. +type UIDSet struct { + sets.String + key string +} + +// UIDTrackingControllerExpectations tracks the UID of the pods it deletes. +// This cache is needed over plain old expectations to safely handle graceful +// deletion. The desired behavior is to treat an update that sets the +// DeletionTimestamp on an object as a delete. To do so consistenly, one needs +// to remember the expected deletes so they aren't double counted. +// TODO: Track creates as well (#22599) +type UIDTrackingControllerExpectations struct { + ControllerExpectationsInterface + // TODO: There is a much nicer way to do this that involves a single store, + // a lock per entry, and a ControlleeExpectationsInterface type. + uidStoreLock sync.Mutex + // Store used for the UIDs associated with any expectation tracked via the + // ControllerExpectationsInterface. + uidStore cache.Store +} + +// GetUIDs is a convenience method to avoid exposing the set of expected uids. +// The returned set is not thread safe, all modifications must be made holding +// the uidStoreLock. +func (u *UIDTrackingControllerExpectations) GetUIDs(controllerKey string) sets.String { + if uid, exists, err := u.uidStore.GetByKey(controllerKey); err == nil && exists { + return uid.(*UIDSet).String + } + return nil +} + +// ExpectDeletions records expectations for the given deleteKeys, against the given controller. +func (u *UIDTrackingControllerExpectations) ExpectDeletions(rcKey string, deletedKeys []string) error { + u.uidStoreLock.Lock() + defer u.uidStoreLock.Unlock() + + if existing := u.GetUIDs(rcKey); existing != nil && existing.Len() != 0 { + glog.Errorf("Clobbering existing delete keys: %+v", existing) + } + expectedUIDs := sets.NewString() + for _, k := range deletedKeys { + expectedUIDs.Insert(k) + } + glog.V(4).Infof("Controller %v waiting on deletions for: %+v", rcKey, deletedKeys) + if err := u.uidStore.Add(&UIDSet{expectedUIDs, rcKey}); err != nil { + return err + } + return u.ControllerExpectationsInterface.ExpectDeletions(rcKey, expectedUIDs.Len()) +} + +// DeletionObserved records the given deleteKey as a deletion, for the given rc. +func (u *UIDTrackingControllerExpectations) DeletionObserved(rcKey, deleteKey string) { + u.uidStoreLock.Lock() + defer u.uidStoreLock.Unlock() + + uids := u.GetUIDs(rcKey) + if uids != nil && uids.Has(deleteKey) { + glog.V(4).Infof("Controller %v received delete for pod %v", rcKey, deleteKey) + u.ControllerExpectationsInterface.DeletionObserved(rcKey) + uids.Delete(deleteKey) + } +} + +// DeleteExpectations deletes the UID set and invokes DeleteExpectations on the +// underlying ControllerExpectationsInterface. +func (u *UIDTrackingControllerExpectations) DeleteExpectations(rcKey string) { + u.uidStoreLock.Lock() + defer u.uidStoreLock.Unlock() + + u.ControllerExpectationsInterface.DeleteExpectations(rcKey) + if uidExp, exists, err := u.uidStore.GetByKey(rcKey); err == nil && exists { + if err := u.uidStore.Delete(uidExp); err != nil { + glog.V(2).Infof("Error deleting uid expectations for controller %v: %v", rcKey, err) + } + } +} + +// NewUIDTrackingControllerExpectations returns a wrapper around +// ControllerExpectations that is aware of deleteKeys. +func NewUIDTrackingControllerExpectations(ce ControllerExpectationsInterface) *UIDTrackingControllerExpectations { + return &UIDTrackingControllerExpectations{ControllerExpectationsInterface: ce, uidStore: cache.NewStore(UIDSetKeyFunc)} +} + +// PodControlInterface is an interface that knows how to add or delete pods +// created as an interface to allow testing. +type PodControlInterface interface { + // CreatePods creates new pods according to the spec. + CreatePods(namespace string, template *api.PodTemplateSpec, object runtime.Object) error + // CreatePodsOnNode creates a new pod accorting to the spec on the specified node. + CreatePodsOnNode(nodeName, namespace string, template *api.PodTemplateSpec, object runtime.Object) error + // DeletePod deletes the pod identified by podID. + DeletePod(namespace string, podID string, object runtime.Object) error +} + +// RealPodControl is the default implementation of PodControlInterface. +type RealPodControl struct { + KubeClient clientset.Interface + Recorder record.EventRecorder +} + +var _ PodControlInterface = &RealPodControl{} + +func getPodsLabelSet(template *api.PodTemplateSpec) labels.Set { + desiredLabels := make(labels.Set) + for k, v := range template.Labels { + desiredLabels[k] = v + } + return desiredLabels +} + +func getPodsAnnotationSet(template *api.PodTemplateSpec, object runtime.Object) (labels.Set, error) { + desiredAnnotations := make(labels.Set) + for k, v := range template.Annotations { + desiredAnnotations[k] = v + } + createdByRef, err := api.GetReference(object) + if err != nil { + return desiredAnnotations, fmt.Errorf("unable to get controller reference: %v", err) + } + + // TODO: this code was not safe previously - as soon as new code came along that switched to v2, old clients + // would be broken upon reading it. This is explicitly hardcoded to v1 to guarantee predictable deployment. + // We need to consistently handle this case of annotation versioning. + codec := api.Codecs.LegacyCodec(unversioned.GroupVersion{Group: api.GroupName, Version: "v1"}) + + createdByRefJson, err := runtime.Encode(codec, &api.SerializedReference{ + Reference: *createdByRef, + }) + if err != nil { + return desiredAnnotations, fmt.Errorf("unable to serialize controller reference: %v", err) + } + desiredAnnotations[CreatedByAnnotation] = string(createdByRefJson) + return desiredAnnotations, nil +} + +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 { + prefix = controllerName + } + return prefix +} + +func (r RealPodControl) CreatePods(namespace string, template *api.PodTemplateSpec, object runtime.Object) error { + return r.createPods("", namespace, template, object) +} + +func (r RealPodControl) CreatePodsOnNode(nodeName, namespace string, template *api.PodTemplateSpec, object runtime.Object) error { + return r.createPods(nodeName, namespace, template, object) +} + +func (r RealPodControl) createPods(nodeName, namespace string, template *api.PodTemplateSpec, object runtime.Object) error { + desiredLabels := getPodsLabelSet(template) + desiredAnnotations, err := getPodsAnnotationSet(template, object) + if err != nil { + return err + } + meta, err := api.ObjectMetaFor(object) + if err != nil { + return fmt.Errorf("object does not have ObjectMeta, %v", err) + } + prefix := getPodsPrefix(meta.Name) + + pod := &api.Pod{ + ObjectMeta: api.ObjectMeta{ + Labels: desiredLabels, + Annotations: desiredAnnotations, + GenerateName: prefix, + }, + } + if err := api.Scheme.Convert(&template.Spec, &pod.Spec); err != nil { + return fmt.Errorf("unable to convert pod template: %v", err) + } + if len(nodeName) != 0 { + pod.Spec.NodeName = nodeName + } + if labels.Set(pod.Labels).AsSelector().Empty() { + return fmt.Errorf("unable to create pods, no labels") + } + if newPod, err := r.KubeClient.Core().Pods(namespace).Create(pod); err != nil { + r.Recorder.Eventf(object, api.EventTypeWarning, "FailedCreate", "Error creating: %v", err) + return fmt.Errorf("unable to create pods: %v", err) + } else { + glog.V(4).Infof("Controller %v created pod %v", meta.Name, newPod.Name) + r.Recorder.Eventf(object, api.EventTypeNormal, "SuccessfulCreate", "Created pod: %v", newPod.Name) + } + return nil +} + +func (r RealPodControl) DeletePod(namespace string, podID string, object runtime.Object) error { + meta, err := api.ObjectMetaFor(object) + if err != nil { + return fmt.Errorf("object does not have ObjectMeta, %v", err) + } + if err := r.KubeClient.Core().Pods(namespace).Delete(podID, nil); err != nil { + r.Recorder.Eventf(object, api.EventTypeWarning, "FailedDelete", "Error deleting: %v", err) + return fmt.Errorf("unable to delete pods: %v", err) + } else { + glog.V(4).Infof("Controller %v deleted pod %v", meta.Name, podID) + r.Recorder.Eventf(object, api.EventTypeNormal, "SuccessfulDelete", "Deleted pod: %v", podID) + } + return nil +} + +type FakePodControl struct { + sync.Mutex + Templates []api.PodTemplateSpec + DeletePodName []string + Err error +} + +var _ PodControlInterface = &FakePodControl{} + +func (f *FakePodControl) CreatePods(namespace string, spec *api.PodTemplateSpec, object runtime.Object) error { + f.Lock() + defer f.Unlock() + if f.Err != nil { + return f.Err + } + f.Templates = append(f.Templates, *spec) + return nil +} + +func (f *FakePodControl) CreatePodsOnNode(nodeName, namespace string, template *api.PodTemplateSpec, object runtime.Object) error { + f.Lock() + defer f.Unlock() + if f.Err != nil { + return f.Err + } + f.Templates = append(f.Templates, *template) + return nil +} + +func (f *FakePodControl) DeletePod(namespace string, podID string, object runtime.Object) error { + f.Lock() + defer f.Unlock() + if f.Err != nil { + return f.Err + } + f.DeletePodName = append(f.DeletePodName, podID) + return nil +} + +func (f *FakePodControl) Clear() { + f.Lock() + defer f.Unlock() + f.DeletePodName = []string{} + f.Templates = []api.PodTemplateSpec{} +} + +// ActivePods type allows custom sorting of pods so a controller can pick the best ones to delete. +type ActivePods []*api.Pod + +func (s ActivePods) Len() int { return len(s) } +func (s ActivePods) Swap(i, j int) { s[i], s[j] = s[j], s[i] } + +func (s ActivePods) Less(i, j int) bool { + // 1. Unassigned < assigned + // If only one of the pods is unassigned, the unassigned one is smaller + if s[i].Spec.NodeName != s[j].Spec.NodeName && (len(s[i].Spec.NodeName) == 0 || len(s[j].Spec.NodeName) == 0) { + return len(s[i].Spec.NodeName) == 0 + } + // 2. PodPending < PodUnknown < PodRunning + m := map[api.PodPhase]int{api.PodPending: 0, api.PodUnknown: 1, api.PodRunning: 2} + if m[s[i].Status.Phase] != m[s[j].Status.Phase] { + return m[s[i].Status.Phase] < m[s[j].Status.Phase] + } + // 3. Not ready < ready + // If only one of the pods is not ready, the not ready one is smaller + if api.IsPodReady(s[i]) != api.IsPodReady(s[j]) { + return !api.IsPodReady(s[i]) + } + // TODO: take availability into account when we push minReadySeconds information from deployment into pods, + // see https://github.com/kubernetes/kubernetes/issues/22065 + // 4. Been ready for empty time < less time < more time + // If both pods are ready, the latest ready one is smaller + if api.IsPodReady(s[i]) && api.IsPodReady(s[j]) && !podReadyTime(s[i]).Equal(podReadyTime(s[j])) { + return afterOrZero(podReadyTime(s[i]), podReadyTime(s[j])) + } + // 5. Pods with containers with higher restart counts < lower restart counts + if maxContainerRestarts(s[i]) != maxContainerRestarts(s[j]) { + return maxContainerRestarts(s[i]) > maxContainerRestarts(s[j]) + } + // 6. Empty creation time pods < newer pods < older pods + if !s[i].CreationTimestamp.Equal(s[j].CreationTimestamp) { + return afterOrZero(s[i].CreationTimestamp, s[j].CreationTimestamp) + } + return false +} + +// afterOrZero checks if time t1 is after time t2; if one of them +// is zero, the zero time is seen as after non-zero time. +func afterOrZero(t1, t2 unversioned.Time) bool { + if t1.Time.IsZero() || t2.Time.IsZero() { + return t1.Time.IsZero() + } + return t1.After(t2.Time) +} + +func podReadyTime(pod *api.Pod) unversioned.Time { + if api.IsPodReady(pod) { + for _, c := range pod.Status.Conditions { + // we only care about pod ready conditions + if c.Type == api.PodReady && c.Status == api.ConditionTrue { + return c.LastTransitionTime + } + } + } + return unversioned.Time{} +} + +func maxContainerRestarts(pod *api.Pod) int { + maxRestarts := 0 + for _, c := range pod.Status.ContainerStatuses { + maxRestarts = integer.IntMax(maxRestarts, c.RestartCount) + } + return maxRestarts +} + +// FilterActivePods returns pods that have not terminated. +func FilterActivePods(pods []api.Pod) []*api.Pod { + var result []*api.Pod + for i := range pods { + p := pods[i] + if IsPodActive(p) { + result = append(result, &p) + } else { + glog.V(4).Infof("Ignoring inactive pod %v/%v in state %v, deletion time %v", + p.Namespace, p.Name, p.Status.Phase, p.DeletionTimestamp) + } + } + return result +} + +func IsPodActive(p api.Pod) bool { + return api.PodSucceeded != p.Status.Phase && + api.PodFailed != p.Status.Phase && + p.DeletionTimestamp == nil +} + +// FilterActiveReplicaSets returns replica sets that have (or at least ought to have) pods. +func FilterActiveReplicaSets(replicaSets []*extensions.ReplicaSet) []*extensions.ReplicaSet { + active := []*extensions.ReplicaSet{} + for i := range replicaSets { + if replicaSets[i].Spec.Replicas > 0 { + active = append(active, replicaSets[i]) + } + } + return active +} + +// PodKey returns a key unique to the given pod within a cluster. +// It's used so we consistently use the same key scheme in this module. +// It does exactly what cache.MetaNamespaceKeyFunc would have done +// expcept there's not possibility for error since we know the exact type. +func PodKey(pod *api.Pod) string { + return fmt.Sprintf("%v/%v", pod.Namespace, pod.Name) +} + +// ControllersByCreationTimestamp sorts a list of ReplicationControllers by creation timestamp, using their names as a tie breaker. +type ControllersByCreationTimestamp []*api.ReplicationController + +func (o ControllersByCreationTimestamp) Len() int { return len(o) } +func (o ControllersByCreationTimestamp) Swap(i, j int) { o[i], o[j] = o[j], o[i] } + +func (o ControllersByCreationTimestamp) Less(i, j int) bool { + if o[i].CreationTimestamp.Equal(o[j].CreationTimestamp) { + return o[i].Name < o[j].Name + } + return o[i].CreationTimestamp.Before(o[j].CreationTimestamp) +} + +// ReplicaSetsByCreationTimestamp sorts a list of ReplicationSets by creation timestamp, using their names as a tie breaker. +type ReplicaSetsByCreationTimestamp []*extensions.ReplicaSet + +func (o ReplicaSetsByCreationTimestamp) Len() int { return len(o) } +func (o ReplicaSetsByCreationTimestamp) Swap(i, j int) { o[i], o[j] = o[j], o[i] } + +func (o ReplicaSetsByCreationTimestamp) Less(i, j int) bool { + if o[i].CreationTimestamp.Equal(o[j].CreationTimestamp) { + return o[i].Name < o[j].Name + } + return o[i].CreationTimestamp.Before(o[j].CreationTimestamp) +} diff --git a/vendor/k8s.io/kubernetes/pkg/controller/doc.go b/vendor/k8s.io/kubernetes/pkg/controller/doc.go new file mode 100644 index 0000000..1e310b4 --- /dev/null +++ b/vendor/k8s.io/kubernetes/pkg/controller/doc.go @@ -0,0 +1,19 @@ +/* +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 controller contains code for controllers (like the replication +// controller). +package controller diff --git a/vendor/k8s.io/kubernetes/pkg/controller/framework/controller.go b/vendor/k8s.io/kubernetes/pkg/controller/framework/controller.go new file mode 100644 index 0000000..ed81952 --- /dev/null +++ b/vendor/k8s.io/kubernetes/pkg/controller/framework/controller.go @@ -0,0 +1,321 @@ +/* +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 framework + +import ( + "sync" + "time" + + "k8s.io/kubernetes/pkg/client/cache" + "k8s.io/kubernetes/pkg/runtime" + utilruntime "k8s.io/kubernetes/pkg/util/runtime" + "k8s.io/kubernetes/pkg/util/wait" +) + +// Config contains all the settings for a Controller. +type Config struct { + // The queue for your objects; either a cache.FIFO or + // a cache.DeltaFIFO. Your Process() function should accept + // the output of this Oueue's Pop() method. + cache.Queue + + // Something that can list and watch your objects. + cache.ListerWatcher + + // Something that can process your objects. + Process ProcessFunc + + // The type of your objects. + ObjectType runtime.Object + + // Reprocess everything at least this often. + // Note that if it takes longer for you to clear the queue than this + // period, you will end up processing items in the order determined + // by cache.FIFO.Replace(). Currently, this is random. If this is a + // problem, we can change that replacement policy to append new + // things to the end of the queue instead of replacing the entire + // queue. + FullResyncPeriod time.Duration + + // If true, when Process() returns an error, re-enqueue the object. + // TODO: add interface to let you inject a delay/backoff or drop + // the object completely if desired. Pass the object in + // question to this interface as a parameter. + RetryOnError bool +} + +// ProcessFunc processes a single object. +type ProcessFunc func(obj interface{}) error + +// Controller is a generic controller framework. +type Controller struct { + config Config + reflector *cache.Reflector + reflectorMutex sync.RWMutex +} + +// New makes a new Controller from the given Config. +func New(c *Config) *Controller { + ctlr := &Controller{ + config: *c, + } + return ctlr +} + +// Run begins processing items, and will continue until a value is sent down stopCh. +// It's an error to call Run more than once. +// Run blocks; call via go. +func (c *Controller) Run(stopCh <-chan struct{}) { + defer utilruntime.HandleCrash() + r := cache.NewReflector( + c.config.ListerWatcher, + c.config.ObjectType, + c.config.Queue, + c.config.FullResyncPeriod, + ) + + c.reflectorMutex.Lock() + c.reflector = r + c.reflectorMutex.Unlock() + + r.RunUntil(stopCh) + + wait.Until(c.processLoop, time.Second, stopCh) +} + +// Returns true once this controller has completed an initial resource listing +func (c *Controller) HasSynced() bool { + return c.config.Queue.HasSynced() +} + +// Requeue adds the provided object back into the queue if it does not already exist. +func (c *Controller) Requeue(obj interface{}) error { + return c.config.Queue.AddIfNotPresent(cache.Deltas{ + cache.Delta{ + Type: cache.Sync, + Object: obj, + }, + }) +} + +// processLoop drains the work queue. +// TODO: Consider doing the processing in parallel. This will require a little thought +// to make sure that we don't end up processing the same object multiple times +// concurrently. +func (c *Controller) processLoop() { + for { + obj := c.config.Queue.Pop() + err := c.config.Process(obj) + if err != nil { + if c.config.RetryOnError { + // This is the safe way to re-enqueue. + c.config.Queue.AddIfNotPresent(obj) + } + } + } +} + +// ResourceEventHandler can handle notifications for events that happen to a +// resource. The events are informational only, so you can't return an +// error. +// * OnAdd is called when an object is added. +// * OnUpdate is called when an object is modified. Note that oldObj is the +// last known state of the object-- it is possible that several changes +// were combined together, so you can't use this to see every single +// change. OnUpdate is also called when a re-list happens, and it will +// get called even if nothing changed. This is useful for periodically +// evaluating or syncing something. +// * OnDelete will get the final state of the item if it is known, otherwise +// it will get an object of type cache.DeletedFinalStateUnknown. This can +// happen if the watch is closed and misses the delete event and we don't +// notice the deletion until the subsequent re-list. +type ResourceEventHandler interface { + OnAdd(obj interface{}) + OnUpdate(oldObj, newObj interface{}) + OnDelete(obj interface{}) +} + +// ResourceEventHandlerFuncs is an adaptor to let you easily specify as many or +// as few of the notification functions as you want while still implementing +// ResourceEventHandler. +type ResourceEventHandlerFuncs struct { + AddFunc func(obj interface{}) + UpdateFunc func(oldObj, newObj interface{}) + DeleteFunc func(obj interface{}) +} + +// OnAdd calls AddFunc if it's not nil. +func (r ResourceEventHandlerFuncs) OnAdd(obj interface{}) { + if r.AddFunc != nil { + r.AddFunc(obj) + } +} + +// OnUpdate calls UpdateFunc if it's not nil. +func (r ResourceEventHandlerFuncs) OnUpdate(oldObj, newObj interface{}) { + if r.UpdateFunc != nil { + r.UpdateFunc(oldObj, newObj) + } +} + +// OnDelete calls DeleteFunc if it's not nil. +func (r ResourceEventHandlerFuncs) OnDelete(obj interface{}) { + if r.DeleteFunc != nil { + r.DeleteFunc(obj) + } +} + +// DeletionHandlingMetaNamespaceKeyFunc checks for +// cache.DeletedFinalStateUnknown objects before calling +// cache.MetaNamespaceKeyFunc. +func DeletionHandlingMetaNamespaceKeyFunc(obj interface{}) (string, error) { + if d, ok := obj.(cache.DeletedFinalStateUnknown); ok { + return d.Key, nil + } + return cache.MetaNamespaceKeyFunc(obj) +} + +// NewInformer returns a cache.Store and a controller for populating the store +// while also providing event notifications. You should only used the returned +// cache.Store for Get/List operations; Add/Modify/Deletes will cause the event +// notifications to be faulty. +// +// Parameters: +// * lw is list and watch functions for the source of the resource you want to +// be informed of. +// * objType is an object of the type that you expect to receive. +// * resyncPeriod: if non-zero, will re-list this often (you will get OnUpdate +// calls, even if nothing changed). Otherwise, re-list will be delayed as +// long as possible (until the upstream source closes the watch or times out, +// or you stop the controller). +// * h is the object you want notifications sent to. +// +func NewInformer( + lw cache.ListerWatcher, + objType runtime.Object, + resyncPeriod time.Duration, + h ResourceEventHandler, +) (cache.Store, *Controller) { + // This will hold the client state, as we know it. + clientState := cache.NewStore(DeletionHandlingMetaNamespaceKeyFunc) + + // This will hold incoming changes. Note how we pass clientState in as a + // KeyLister, that way resync operations will result in the correct set + // of update/delete deltas. + fifo := cache.NewDeltaFIFO(cache.MetaNamespaceKeyFunc, nil, clientState) + + cfg := &Config{ + Queue: fifo, + ListerWatcher: lw, + ObjectType: objType, + FullResyncPeriod: resyncPeriod, + RetryOnError: false, + + Process: func(obj interface{}) error { + // from oldest to newest + for _, d := range obj.(cache.Deltas) { + switch d.Type { + case cache.Sync, cache.Added, cache.Updated: + if old, exists, err := clientState.Get(d.Object); err == nil && exists { + if err := clientState.Update(d.Object); err != nil { + return err + } + h.OnUpdate(old, d.Object) + } else { + if err := clientState.Add(d.Object); err != nil { + return err + } + h.OnAdd(d.Object) + } + case cache.Deleted: + if err := clientState.Delete(d.Object); err != nil { + return err + } + h.OnDelete(d.Object) + } + } + return nil + }, + } + return clientState, New(cfg) +} + +// NewIndexerInformer returns a cache.Indexer and a controller for populating the index +// while also providing event notifications. You should only used the returned +// cache.Index for Get/List operations; Add/Modify/Deletes will cause the event +// notifications to be faulty. +// +// Parameters: +// * lw is list and watch functions for the source of the resource you want to +// be informed of. +// * objType is an object of the type that you expect to receive. +// * resyncPeriod: if non-zero, will re-list this often (you will get OnUpdate +// calls, even if nothing changed). Otherwise, re-list will be delayed as +// long as possible (until the upstream source closes the watch or times out, +// or you stop the controller). +// * h is the object you want notifications sent to. +// +func NewIndexerInformer( + lw cache.ListerWatcher, + objType runtime.Object, + resyncPeriod time.Duration, + h ResourceEventHandler, + indexers cache.Indexers, +) (cache.Indexer, *Controller) { + // This will hold the client state, as we know it. + clientState := cache.NewIndexer(DeletionHandlingMetaNamespaceKeyFunc, indexers) + + // This will hold incoming changes. Note how we pass clientState in as a + // KeyLister, that way resync operations will result in the correct set + // of update/delete deltas. + fifo := cache.NewDeltaFIFO(cache.MetaNamespaceKeyFunc, nil, clientState) + + cfg := &Config{ + Queue: fifo, + ListerWatcher: lw, + ObjectType: objType, + FullResyncPeriod: resyncPeriod, + RetryOnError: false, + + Process: func(obj interface{}) error { + // from oldest to newest + for _, d := range obj.(cache.Deltas) { + switch d.Type { + case cache.Sync, cache.Added, cache.Updated: + if old, exists, err := clientState.Get(d.Object); err == nil && exists { + if err := clientState.Update(d.Object); err != nil { + return err + } + h.OnUpdate(old, d.Object) + } else { + if err := clientState.Add(d.Object); err != nil { + return err + } + h.OnAdd(d.Object) + } + case cache.Deleted: + if err := clientState.Delete(d.Object); err != nil { + return err + } + h.OnDelete(d.Object) + } + } + return nil + }, + } + return clientState, New(cfg) +} diff --git a/vendor/k8s.io/kubernetes/pkg/controller/framework/doc.go b/vendor/k8s.io/kubernetes/pkg/controller/framework/doc.go new file mode 100644 index 0000000..ecd3cf2 --- /dev/null +++ b/vendor/k8s.io/kubernetes/pkg/controller/framework/doc.go @@ -0,0 +1,18 @@ +/* +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 framework implements all the grunt work involved in running a simple controller. +package framework diff --git a/vendor/k8s.io/kubernetes/pkg/controller/framework/fake_controller_source.go b/vendor/k8s.io/kubernetes/pkg/controller/framework/fake_controller_source.go new file mode 100644 index 0000000..fa28171 --- /dev/null +++ b/vendor/k8s.io/kubernetes/pkg/controller/framework/fake_controller_source.go @@ -0,0 +1,188 @@ +/* +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 framework + +import ( + "errors" + "math/rand" + "strconv" + "sync" + + "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/meta" + "k8s.io/kubernetes/pkg/runtime" + "k8s.io/kubernetes/pkg/types" + "k8s.io/kubernetes/pkg/watch" +) + +func NewFakeControllerSource() *FakeControllerSource { + return &FakeControllerSource{ + items: map[nnu]runtime.Object{}, + broadcaster: watch.NewBroadcaster(100, watch.WaitIfChannelFull), + } +} + +// FakeControllerSource implements listing/watching for testing. +type FakeControllerSource struct { + lock sync.RWMutex + items map[nnu]runtime.Object + changes []watch.Event // one change per resourceVersion + broadcaster *watch.Broadcaster +} + +// namespace, name, uid to be used as a key. +type nnu struct { + namespace, name string + uid types.UID +} + +// Add adds an object to the set and sends an add event to watchers. +// obj's ResourceVersion is set. +func (f *FakeControllerSource) Add(obj runtime.Object) { + f.Change(watch.Event{Type: watch.Added, Object: obj}, 1) +} + +// Modify updates an object in the set and sends a modified event to watchers. +// obj's ResourceVersion is set. +func (f *FakeControllerSource) Modify(obj runtime.Object) { + f.Change(watch.Event{Type: watch.Modified, Object: obj}, 1) +} + +// Delete deletes an object from the set and sends a delete event to watchers. +// obj's ResourceVersion is set. +func (f *FakeControllerSource) Delete(lastValue runtime.Object) { + f.Change(watch.Event{Type: watch.Deleted, Object: lastValue}, 1) +} + +// AddDropWatch adds an object to the set but forgets to send an add event to +// watchers. +// obj's ResourceVersion is set. +func (f *FakeControllerSource) AddDropWatch(obj runtime.Object) { + f.Change(watch.Event{Type: watch.Added, Object: obj}, 0) +} + +// ModifyDropWatch updates an object in the set but forgets to send a modify +// event to watchers. +// obj's ResourceVersion is set. +func (f *FakeControllerSource) ModifyDropWatch(obj runtime.Object) { + f.Change(watch.Event{Type: watch.Modified, Object: obj}, 0) +} + +// DeleteDropWatch deletes an object from the set but forgets to send a delete +// event to watchers. +// obj's ResourceVersion is set. +func (f *FakeControllerSource) DeleteDropWatch(lastValue runtime.Object) { + f.Change(watch.Event{Type: watch.Deleted, Object: lastValue}, 0) +} + +func (f *FakeControllerSource) key(meta *api.ObjectMeta) nnu { + return nnu{meta.Namespace, meta.Name, meta.UID} +} + +// Change records the given event (setting the object's resource version) and +// sends a watch event with the specified probability. +func (f *FakeControllerSource) Change(e watch.Event, watchProbability float64) { + f.lock.Lock() + defer f.lock.Unlock() + + objMeta, err := api.ObjectMetaFor(e.Object) + if err != nil { + panic(err) // this is test code only + } + + resourceVersion := len(f.changes) + 1 + objMeta.ResourceVersion = strconv.Itoa(resourceVersion) + f.changes = append(f.changes, e) + key := f.key(objMeta) + switch e.Type { + case watch.Added, watch.Modified: + f.items[key] = e.Object + case watch.Deleted: + delete(f.items, key) + } + + if rand.Float64() < watchProbability { + f.broadcaster.Action(e.Type, e.Object) + } +} + +// List returns a list object, with its resource version set. +func (f *FakeControllerSource) List(options api.ListOptions) (runtime.Object, error) { + f.lock.RLock() + defer f.lock.RUnlock() + list := make([]runtime.Object, 0, len(f.items)) + for _, obj := range f.items { + // Must make a copy to allow clients to modify the object. + // Otherwise, if they make a change and write it back, they + // will inadvertently change our canonical copy (in + // addition to racing with other clients). + objCopy, err := api.Scheme.DeepCopy(obj) + if err != nil { + return nil, err + } + list = append(list, objCopy.(runtime.Object)) + } + listObj := &api.List{} + if err := meta.SetList(listObj, list); err != nil { + return nil, err + } + objMeta, err := api.ListMetaFor(listObj) + if err != nil { + return nil, err + } + resourceVersion := len(f.changes) + objMeta.ResourceVersion = strconv.Itoa(resourceVersion) + return listObj, nil +} + +// Watch returns a watch, which will be pre-populated with all changes +// after resourceVersion. +func (f *FakeControllerSource) Watch(options api.ListOptions) (watch.Interface, error) { + f.lock.RLock() + defer f.lock.RUnlock() + rc, err := strconv.Atoi(options.ResourceVersion) + if err != nil { + return nil, err + } + if rc < len(f.changes) { + changes := []watch.Event{} + for _, c := range f.changes[rc:] { + // Must make a copy to allow clients to modify the + // object. Otherwise, if they make a change and write + // it back, they will inadvertently change the our + // canonical copy (in addition to racing with other + // clients). + objCopy, err := api.Scheme.DeepCopy(c.Object) + if err != nil { + return nil, err + } + changes = append(changes, watch.Event{Type: c.Type, Object: objCopy.(runtime.Object)}) + } + return f.broadcaster.WatchWithPrefix(changes), nil + } else if rc > len(f.changes) { + return nil, errors.New("resource version in the future not supported by this fake") + } + return f.broadcaster.Watch(), nil +} + +// Shutdown closes the underlying broadcaster, waiting for events to be +// delivered. It's an error to call any method after calling shutdown. This is +// enforced by Shutdown() leaving f locked. +func (f *FakeControllerSource) Shutdown() { + f.lock.Lock() // Purposely no unlock. + f.broadcaster.Shutdown() +} diff --git a/vendor/k8s.io/kubernetes/pkg/controller/lookup_cache.go b/vendor/k8s.io/kubernetes/pkg/controller/lookup_cache.go new file mode 100644 index 0000000..5d82908 --- /dev/null +++ b/vendor/k8s.io/kubernetes/pkg/controller/lookup_cache.go @@ -0,0 +1,90 @@ +/* +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 controller + +import ( + "hash/adler32" + "sync" + + "github.com/golang/groupcache/lru" + "k8s.io/kubernetes/pkg/api/meta" + hashutil "k8s.io/kubernetes/pkg/util/hash" +) + +type objectWithMeta interface { + meta.Object +} + +// keyFunc returns the key of an object, which is used to look up in the cache for it's matching object. +// Since we match objects by namespace and Labels/Selector, so if two objects have the same namespace and labels, +// they will have the same key. +func keyFunc(obj objectWithMeta) uint64 { + hash := adler32.New() + hashutil.DeepHashObject(hash, &equivalenceLabelObj{ + namespace: obj.GetNamespace(), + labels: obj.GetLabels(), + }) + return uint64(hash.Sum32()) +} + +type equivalenceLabelObj struct { + namespace string + labels map[string]string +} + +// MatchingCache save label and selector matching relationship +type MatchingCache struct { + mutex sync.RWMutex + cache *lru.Cache +} + +// NewMatchingCache return a NewMatchingCache, which save label and selector matching relationship. +func NewMatchingCache(maxCacheEntries int) *MatchingCache { + return &MatchingCache{ + cache: lru.New(maxCacheEntries), + } +} + +// Add will add matching information to the cache. +func (c *MatchingCache) Add(labelObj objectWithMeta, selectorObj objectWithMeta) { + key := keyFunc(labelObj) + c.mutex.Lock() + defer c.mutex.Unlock() + c.cache.Add(key, selectorObj) +} + +// GetMatchingObject lookup the matching object for a given object. +// Note: the cache information may be invalid since the controller may be deleted or updated, +// 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() + return c.cache.Get(key) +} + +// Update update the cached matching information. +func (c *MatchingCache) Update(labelObj objectWithMeta, selectorObj objectWithMeta) { + c.Add(labelObj, selectorObj) +} + +// InvalidateAll invalidate the whole cache. +func (c *MatchingCache) InvalidateAll() { + c.mutex.Lock() + defer c.mutex.Unlock() + c.cache = lru.New(c.cache.MaxEntries) +} diff --git a/vendor/k8s.io/kubernetes/pkg/conversion/OWNERS b/vendor/k8s.io/kubernetes/pkg/conversion/OWNERS new file mode 100644 index 0000000..a046efc --- /dev/null +++ b/vendor/k8s.io/kubernetes/pkg/conversion/OWNERS @@ -0,0 +1,5 @@ +assignees: + - derekwaynecarr + - lavalamp + - smarterclayton + - wojtek-t diff --git a/vendor/k8s.io/kubernetes/pkg/credentialprovider/OWNERS b/vendor/k8s.io/kubernetes/pkg/credentialprovider/OWNERS new file mode 100644 index 0000000..766c481 --- /dev/null +++ b/vendor/k8s.io/kubernetes/pkg/credentialprovider/OWNERS @@ -0,0 +1,3 @@ +assignees: + - erictune + - liggitt diff --git a/vendor/k8s.io/kubernetes/pkg/kubectl/OWNERS b/vendor/k8s.io/kubernetes/pkg/kubectl/OWNERS new file mode 100644 index 0000000..66431dd --- /dev/null +++ b/vendor/k8s.io/kubernetes/pkg/kubectl/OWNERS @@ -0,0 +1,7 @@ +assignees: + - bgrant0607 + - brendandburns + - deads2k + - janetkuo + - jlowdermilk + - smarterclayton diff --git a/vendor/k8s.io/kubernetes/pkg/kubectl/cmd/config/create_cluster.go b/vendor/k8s.io/kubernetes/pkg/kubectl/cmd/config/create_cluster.go index 30d1543..79edfd0 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubectl/cmd/config/create_cluster.go +++ b/vendor/k8s.io/kubernetes/pkg/kubectl/cmd/config/create_cluster.go @@ -57,7 +57,7 @@ func NewCmdConfigSetCluster(out io.Writer, configAccess ConfigAccess) *cobra.Com options := &createClusterOptions{configAccess: configAccess} cmd := &cobra.Command{ - Use: fmt.Sprintf("set-cluster NAME [--%v=server] [--%v=path/to/certficate/authority] [--%v=apiversion] [--%v=true]", clientcmd.FlagAPIServer, clientcmd.FlagCAFile, clientcmd.FlagAPIVersion, clientcmd.FlagInsecure), + Use: fmt.Sprintf("set-cluster NAME [--%v=server] [--%v=path/to/certficate/authority] [--%v=true]", clientcmd.FlagAPIServer, clientcmd.FlagCAFile, clientcmd.FlagInsecure), Short: "Sets a cluster entry in kubeconfig", Long: create_cluster_long, Example: create_cluster_example, @@ -120,9 +120,6 @@ func (o *createClusterOptions) modifyCluster(existingCluster clientcmdapi.Cluste if o.server.Provided() { modifiedCluster.Server = o.server.Value() } - if o.apiVersion.Provided() { - modifiedCluster.APIVersion = o.apiVersion.Value() - } if o.insecureSkipTLSVerify.Provided() { modifiedCluster.InsecureSkipTLSVerify = o.insecureSkipTLSVerify.Value() // Specifying insecure mode clears any certificate authority diff --git a/vendor/k8s.io/kubernetes/pkg/kubectl/cmd/util/factory.go b/vendor/k8s.io/kubernetes/pkg/kubectl/cmd/util/factory.go index 974c034..78b2503 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubectl/cmd/util/factory.go +++ b/vendor/k8s.io/kubernetes/pkg/kubectl/cmd/util/factory.go @@ -143,6 +143,7 @@ const ( HorizontalPodAutoscalerV1Beta1GeneratorName = "horizontalpodautoscaler/v1beta1" DeploymentV1Beta1GeneratorName = "deployment/v1beta1" JobV1Beta1GeneratorName = "job/v1beta1" + JobV1GeneratorName = "job/v1" NamespaceV1GeneratorName = "namespace/v1" SecretV1GeneratorName = "secret/v1" SecretForDockerRegistryV1GeneratorName = "secret-for-docker-registry/v1" @@ -161,6 +162,7 @@ func DefaultGenerators(cmdName string) map[string]kubectl.Generator { RunPodV1GeneratorName: kubectl.BasicPod{}, DeploymentV1Beta1GeneratorName: kubectl.DeploymentV1Beta1{}, JobV1Beta1GeneratorName: kubectl.JobV1Beta1{}, + JobV1GeneratorName: kubectl.JobV1{}, } generators["autoscale"] = map[string]kubectl.Generator{ HorizontalPodAutoscalerV1Beta1GeneratorName: kubectl.HorizontalPodAutoscalerV1Beta1{}, @@ -380,6 +382,42 @@ func NewFactory(optionalClientConfig clientcmd.ClientConfig) *Factory { return nil, errors.New("provided options object is not a PodLogOptions") } return c.Pods(t.Namespace).GetLogs(t.Name, opts), nil + + case *api.ReplicationController: + opts, ok := options.(*api.PodLogOptions) + if !ok { + return nil, errors.New("provided options object is not a PodLogOptions") + } + selector := labels.SelectorFromSet(t.Spec.Selector) + pod, numPods, err := GetFirstPod(c, t.Namespace, selector) + if err != nil { + return nil, err + } + if numPods > 1 { + fmt.Fprintf(os.Stderr, "Found %v pods, using pod/%v\n", numPods, pod.Name) + } + + return c.Pods(pod.Namespace).GetLogs(pod.Name, opts), nil + + case *extensions.ReplicaSet: + opts, ok := options.(*api.PodLogOptions) + if !ok { + return nil, errors.New("provided options object is not a PodLogOptions") + } + selector, err := unversioned.LabelSelectorAsSelector(t.Spec.Selector) + if err != nil { + return nil, fmt.Errorf("invalid label selector: %v", err) + } + pod, numPods, err := GetFirstPod(c, t.Namespace, selector) + if err != nil { + return nil, err + } + if numPods > 1 { + fmt.Fprintf(os.Stderr, "Found %v pods, using pod/%v\n", numPods, pod.Name) + } + + return c.Pods(pod.Namespace).GetLogs(pod.Name, opts), nil + default: gvk, err := api.Scheme.ObjectKind(object) if err != nil { @@ -512,7 +550,7 @@ func NewFactory(optionalClientConfig clientcmd.ClientConfig) *Factory { }, CanBeAutoscaled: func(kind unversioned.GroupKind) error { switch kind { - case api.Kind("ReplicationController"), extensions.Kind("Deployment"): + case api.Kind("ReplicationController"), extensions.Kind("Deployment"), extensions.Kind("ReplicaSet"): // nothing to do here default: return fmt.Errorf("cannot autoscale a %v", kind) @@ -527,19 +565,22 @@ func NewFactory(optionalClientConfig clientcmd.ClientConfig) *Factory { switch t := object.(type) { case *api.ReplicationController: selector := labels.SelectorFromSet(t.Spec.Selector) - return GetFirstPod(client, t.Namespace, selector) + pod, _, err := GetFirstPod(client, t.Namespace, selector) + return pod, err case *extensions.Deployment: selector, err := unversioned.LabelSelectorAsSelector(t.Spec.Selector) if err != nil { return nil, fmt.Errorf("invalid label selector: %v", err) } - return GetFirstPod(client, t.Namespace, selector) + pod, _, err := GetFirstPod(client, t.Namespace, selector) + return pod, err case *extensions.Job: selector, err := unversioned.LabelSelectorAsSelector(t.Spec.Selector) if err != nil { return nil, fmt.Errorf("invalid label selector: %v", err) } - return GetFirstPod(client, t.Namespace, selector) + pod, _, err := GetFirstPod(client, t.Namespace, selector) + return pod, err case *api.Pod: return t, nil default: @@ -556,21 +597,21 @@ func NewFactory(optionalClientConfig clientcmd.ClientConfig) *Factory { } } -// GetFirstPod returns the first pod of an object from its namespace and selector -func GetFirstPod(client *client.Client, namespace string, selector labels.Selector) (*api.Pod, error) { +// GetFirstPod returns the first pod of an object from its namespace and selector and the number of matching pods +func GetFirstPod(client *client.Client, namespace string, selector labels.Selector) (*api.Pod, int, error) { var pods *api.PodList for pods == nil || len(pods.Items) == 0 { var err error options := api.ListOptions{LabelSelector: selector} if pods, err = client.Pods(namespace).List(options); err != nil { - return nil, err + return nil, 0, err } if len(pods.Items) == 0 { time.Sleep(2 * time.Second) } } pod := &pods.Items[0] - return pod, nil + return pod, len(pods.Items), nil } // Command will stringify and return all environment arguments ie. a command run by a client @@ -690,6 +731,7 @@ func writeSchemaFile(schemaData []byte, cacheDir, cacheFile, prefix, groupVersio func getSchemaAndValidate(c schemaClient, data []byte, prefix, groupVersion, cacheDir string) (err error) { var schemaData []byte + var firstSeen bool fullDir, err := substituteUserHome(cacheDir) if err != nil { return err @@ -702,24 +744,50 @@ func getSchemaAndValidate(c schemaClient, data []byte, prefix, groupVersion, cac } } if schemaData == nil { - schemaData, err = c.Get(). - AbsPath("/swaggerapi", prefix, groupVersion). - Do(). - Raw() + firstSeen = true + schemaData, err = downloadSchemaAndStore(c, cacheDir, fullDir, cacheFile, prefix, groupVersion) if err != nil { return err } - if len(cacheDir) != 0 { - if err := writeSchemaFile(schemaData, fullDir, cacheFile, prefix, groupVersion); err != nil { - return err - } - } } schema, err := validation.NewSwaggerSchemaFromBytes(schemaData) if err != nil { return err } - return schema.ValidateBytes(data) + err = schema.ValidateBytes(data) + if _, ok := err.(validation.TypeNotFoundError); ok && !firstSeen { + // As a temporay hack, kubectl would re-get the schema if validation + // fails for type not found reason. + // TODO: runtime-config settings needs to make into the file's name + schemaData, err = downloadSchemaAndStore(c, cacheDir, fullDir, cacheFile, prefix, groupVersion) + if err != nil { + return err + } + schema, err := validation.NewSwaggerSchemaFromBytes(schemaData) + if err != nil { + return err + } + return schema.ValidateBytes(data) + } + + return err +} + +// Download swagger schema from apiserver and store it to file. +func downloadSchemaAndStore(c schemaClient, cacheDir, fullDir, cacheFile, prefix, groupVersion string) (schemaData []byte, err error) { + schemaData, err = c.Get(). + AbsPath("/swaggerapi", prefix, groupVersion). + Do(). + Raw() + if err != nil { + return + } + if len(cacheDir) != 0 { + if err = writeSchemaFile(schemaData, fullDir, cacheFile, prefix, groupVersion); err != nil { + return + } + } + return } func (c *clientSwaggerSchema) ValidateBytes(data []byte) error { diff --git a/vendor/k8s.io/kubernetes/pkg/kubectl/cmd/util/printing.go b/vendor/k8s.io/kubernetes/pkg/kubectl/cmd/util/printing.go index 88af6fa..c953372 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubectl/cmd/util/printing.go +++ b/vendor/k8s.io/kubernetes/pkg/kubectl/cmd/util/printing.go @@ -30,8 +30,8 @@ import ( // AddPrinterFlags adds printing related flags to a command (e.g. output format, no headers, template path) func AddPrinterFlags(cmd *cobra.Command) { - cmd.Flags().StringP("output", "o", "", "Output format. One of: json|yaml|wide|name|go-template=...|go-template-file=...|jsonpath=...|jsonpath-file=... See golang template [http://golang.org/pkg/text/template/#pkg-overview] and jsonpath template [http://releases.k8s.io/HEAD/docs/user-guide/jsonpath.md].") - cmd.Flags().String("output-version", "", "Output the formatted object with the given version (default api-version).") + cmd.Flags().StringP("output", "o", "", "Output format. One of: json|yaml|wide|name|go-template=...|go-template-file=...|jsonpath=...|jsonpath-file=... See golang template [http://golang.org/pkg/text/template/#pkg-overview] and jsonpath template [http://releases.k8s.io/release-1.2/docs/user-guide/jsonpath.md].") + cmd.Flags().String("output-version", "", "Output the formatted object with the given group version (for ex: 'extensions/v1beta1').") cmd.Flags().Bool("no-headers", false, "When using the default output, don't print headers.") cmd.Flags().Bool("show-labels", false, "When printing, show all labels as the last column (default hide labels column)") // template shorthand -t is deprecated to support -t for --tty diff --git a/vendor/k8s.io/kubernetes/pkg/kubectl/describe.go b/vendor/k8s.io/kubernetes/pkg/kubectl/describe.go index af1dba1..0a09b3a 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubectl/describe.go +++ b/vendor/k8s.io/kubernetes/pkg/kubectl/describe.go @@ -574,8 +574,10 @@ func describeVolumes(volumes []api.Volume, out io.Writer) { printPersistentVolumeClaimVolumeSource(volume.VolumeSource.PersistentVolumeClaim, out) case volume.VolumeSource.RBD != nil: printRBDVolumeSource(volume.VolumeSource.RBD, out) + case volume.VolumeSource.DownwardAPI != nil: + printDownwardAPIVolumeSource(volume.VolumeSource.DownwardAPI, out) default: - fmt.Fprintf(out, " \n") + fmt.Fprintf(out, " \n") } } } @@ -672,6 +674,13 @@ func printRBDVolumeSource(rbd *api.RBDVolumeSource, out io.Writer) { rbd.CephMonitors, rbd.RBDImage, rbd.FSType, rbd.RBDPool, rbd.RadosUser, rbd.Keyring, rbd.SecretRef, rbd.ReadOnly) } +func printDownwardAPIVolumeSource(d *api.DownwardAPIVolumeSource, out io.Writer) { + fmt.Fprintf(out, " Type:\tDownwardAPI (a volume populated by information about the pod)\n Items:\n") + for _, mapping := range d.Items { + fmt.Fprintf(out, " %v -> %v\n", mapping.FieldRef.FieldPath, mapping.Path) + } +} + type PersistentVolumeDescriber struct { client.Interface } @@ -774,6 +783,12 @@ func DescribeContainers(containers []api.Container, containerStatuses []api.Cont if ok { fmt.Fprintf(out, " Image ID:\t%s\n", status.ImageID) } + portString := describeContainerPorts(container.Ports) + if strings.Contains(portString, ",") { + fmt.Fprintf(out, " Ports:\t%s\n", portString) + } else { + fmt.Fprintf(out, " Port:\t%s\n", portString) + } if len(container.Command) > 0 { fmt.Fprintf(out, " Command:\n") @@ -842,6 +857,14 @@ func DescribeContainers(containers []api.Container, containerStatuses []api.Cont } } +func describeContainerPorts(cPorts []api.ContainerPort) string { + ports := []string{} + for _, cPort := range cPorts { + ports = append(ports, fmt.Sprintf("%d/%s", cPort.ContainerPort, cPort.Protocol)) + } + return strings.Join(ports, ", ") +} + // DescribeProbe is exported for consumers in other API groups that have probes func DescribeProbe(probe *api.Probe) string { attrs := fmt.Sprintf("delay=%ds timeout=%ds period=%ds #success=%d #failure=%d", probe.InitialDelaySeconds, probe.TimeoutSeconds, probe.PeriodSeconds, probe.SuccessThreshold, probe.FailureThreshold) @@ -952,7 +975,7 @@ func describeReplicationController(controller *api.ReplicationController, events if controller.Spec.Template != nil { fmt.Fprintf(out, "Image(s):\t%s\n", makeImageList(&controller.Spec.Template.Spec)) } else { - fmt.Fprintf(out, "Image(s):\t%s\n", "") + fmt.Fprintf(out, "Image(s):\t%s\n", "") } fmt.Fprintf(out, "Selector:\t%s\n", labels.FormatLabels(controller.Spec.Selector)) fmt.Fprintf(out, "Labels:\t%s\n", labels.FormatLabels(controller.Labels)) @@ -971,7 +994,7 @@ func describeReplicationController(controller *api.ReplicationController, events func DescribePodTemplate(template *api.PodTemplateSpec) (string, error) { return tabbedString(func(out io.Writer) error { if template == nil { - fmt.Fprintf(out, "") + fmt.Fprintf(out, "") return nil } fmt.Fprintf(out, "Labels:\t%s\n", labels.FormatLabels(template.Labels)) @@ -1015,18 +1038,12 @@ func describeReplicaSet(rs *extensions.ReplicaSet, events *api.EventList, runnin return tabbedString(func(out io.Writer) error { fmt.Fprintf(out, "Name:\t%s\n", rs.Name) fmt.Fprintf(out, "Namespace:\t%s\n", rs.Namespace) - if rs.Spec.Template != nil { - fmt.Fprintf(out, "Image(s):\t%s\n", makeImageList(&rs.Spec.Template.Spec)) - } else { - fmt.Fprintf(out, "Image(s):\t%s\n", "") - } + fmt.Fprintf(out, "Image(s):\t%s\n", makeImageList(&rs.Spec.Template.Spec)) fmt.Fprintf(out, "Selector:\t%s\n", unversioned.FormatLabelSelector(rs.Spec.Selector)) fmt.Fprintf(out, "Labels:\t%s\n", labels.FormatLabels(rs.Labels)) fmt.Fprintf(out, "Replicas:\t%d current / %d desired\n", rs.Status.Replicas, rs.Spec.Replicas) fmt.Fprintf(out, "Pods Status:\t%d Running / %d Waiting / %d Succeeded / %d Failed\n", running, waiting, succeeded, failed) - if rs.Spec.Template != nil { - describeVolumes(rs.Spec.Template.Spec.Volumes, out) - } + describeVolumes(rs.Spec.Template.Spec.Volumes, out) if events != nil { DescribeEvents(events, out) } @@ -1061,7 +1078,7 @@ func describeJob(job *extensions.Job, events *api.EventList) (string, error) { if job.Spec.Completions != nil { fmt.Fprintf(out, "Completions:\t%d\n", *job.Spec.Completions) } else { - fmt.Fprintf(out, "Completions:\tNot Set\n") + fmt.Fprintf(out, "Completions:\t\n") } if job.Status.StartTime != nil { fmt.Fprintf(out, "Start Time:\t%s\n", job.Status.StartTime.Time.Format(time.RFC1123Z)) @@ -1320,7 +1337,7 @@ func describeService(service *api.Service, endpoints *api.Endpoints, events *api name := sp.Name if name == "" { - name = "" + name = "" } fmt.Fprintf(out, "Port:\t%s\t%d/%s\n", name, sp.Port, sp.Protocol) if sp.NodePort != 0 { @@ -1391,7 +1408,7 @@ func describeEndpoints(ep *api.Endpoints, events *api.EventList) (string, error) for _, port := range subset.Ports { name := port.Name if len(name) == 0 { - name = "" + name = "" } fmt.Fprintf(out, " %s\t%d\t%s\n", name, port.Port, port.Protocol) } @@ -1613,7 +1630,7 @@ func (d *HorizontalPodAutoscalerDescriber) Describe(namespace, name string) (str if hpa.Status.CurrentCPUUtilizationPercentage != nil { fmt.Fprintf(out, "%d%%\n", *hpa.Status.CurrentCPUUtilizationPercentage) } else { - fmt.Fprintf(out, "\n") + fmt.Fprintf(out, "\n") } } minReplicas := "" diff --git a/vendor/k8s.io/kubernetes/pkg/kubectl/history.go b/vendor/k8s.io/kubernetes/pkg/kubectl/history.go index 4ee41fa..37cb9e0 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubectl/history.go +++ b/vendor/k8s.io/kubernetes/pkg/kubectl/history.go @@ -81,7 +81,7 @@ func (h *DeploymentHistoryViewer) History(namespace, name string) (HistoryInfo, if err != nil { continue } - historyInfo.RevisionToTemplate[v] = rs.Spec.Template + historyInfo.RevisionToTemplate[v] = &rs.Spec.Template changeCause := getChangeCause(rs) if historyInfo.RevisionToTemplate[v].Annotations == nil { historyInfo.RevisionToTemplate[v].Annotations = make(map[string]string) diff --git a/vendor/k8s.io/kubernetes/pkg/kubectl/resource/builder.go b/vendor/k8s.io/kubernetes/pkg/kubectl/resource/builder.go index 3025a4c..7b7bc15 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubectl/resource/builder.go +++ b/vendor/k8s.io/kubernetes/pkg/kubectl/resource/builder.go @@ -126,9 +126,8 @@ func (b *Builder) FilenameParam(enforceNamespace bool, paths ...string) *Builder func (b *Builder) URL(urls ...*url.URL) *Builder { for _, u := range urls { b.paths = append(b.paths, &URLVisitor{ - Mapper: b.mapper, - URL: u, - Schema: b.schema, + URL: u, + StreamVisitor: NewStreamVisitor(nil, b.mapper, u.String(), b.schema), }) } return b @@ -434,20 +433,36 @@ func (b *Builder) SingleResourceType() *Builder { return b } +// mappingFor returns the RESTMapping for the Kind referenced by the resource. +// prefers a fully specified GroupVersionResource match. If we don't have one match on GroupResource +func (b *Builder) mappingFor(resourceArg string) (*meta.RESTMapping, error) { + fullySpecifiedGVR, groupResource := unversioned.ParseResourceArg(resourceArg) + gvk := unversioned.GroupVersionKind{} + if fullySpecifiedGVR != nil { + gvk, _ = b.mapper.KindFor(*fullySpecifiedGVR) + } + if gvk.IsEmpty() { + var err error + gvk, err = b.mapper.KindFor(groupResource.WithVersion("")) + if err != nil { + return nil, err + } + } + + return b.mapper.RESTMapping(gvk.GroupKind(), gvk.Version) +} + func (b *Builder) resourceMappings() ([]*meta.RESTMapping, error) { if len(b.resources) > 1 && b.singleResourceType { return nil, fmt.Errorf("you may only specify a single resource type") } mappings := []*meta.RESTMapping{} for _, r := range b.resources { - gvk, err := b.mapper.KindFor(unversioned.ParseGroupResource(r).WithVersion("")) - if err != nil { - return nil, err - } - mapping, err := b.mapper.RESTMapping(gvk.GroupKind(), gvk.Version) + mapping, err := b.mappingFor(r) if err != nil { return nil, err } + mappings = append(mappings, mapping) } return mappings, nil @@ -460,14 +475,11 @@ func (b *Builder) resourceTupleMappings() (map[string]*meta.RESTMapping, error) if _, ok := mappings[r.Resource]; ok { continue } - gvk, err := b.mapper.KindFor(unversioned.ParseGroupResource(r.Resource).WithVersion("")) - if err != nil { - return nil, err - } - mapping, err := b.mapper.RESTMapping(gvk.GroupKind(), gvk.Version) + mapping, err := b.mappingFor(r.Resource) if err != nil { return nil, err } + mappings[mapping.Resource] = mapping mappings[r.Resource] = mapping canonical[mapping.Resource] = struct{}{} diff --git a/vendor/k8s.io/kubernetes/pkg/kubectl/resource/mapper.go b/vendor/k8s.io/kubernetes/pkg/kubectl/resource/mapper.go index 0839ca4..25fd97d 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubectl/resource/mapper.go +++ b/vendor/k8s.io/kubernetes/pkg/kubectl/resource/mapper.go @@ -21,6 +21,7 @@ import ( "reflect" "k8s.io/kubernetes/pkg/api/meta" + "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/runtime" ) @@ -85,11 +86,17 @@ func (m *Mapper) InfoForData(data []byte, source string) (*Info, error) { // InfoForObject creates an Info object for the given Object. An error is returned // if the object cannot be introspected. Name and namespace will be set into Info // if the mapping's MetadataAccessor can retrieve them. -func (m *Mapper) InfoForObject(obj runtime.Object) (*Info, error) { - groupVersionKind, err := m.ObjectKind(obj) +func (m *Mapper) InfoForObject(obj runtime.Object, preferredGVKs []unversioned.GroupVersionKind) (*Info, error) { + groupVersionKinds, err := m.ObjectKinds(obj) if err != nil { return nil, fmt.Errorf("unable to get type info from the object %q: %v", reflect.TypeOf(obj), err) } + + groupVersionKind := groupVersionKinds[0] + if len(groupVersionKinds) > 1 && len(preferredGVKs) > 0 { + groupVersionKind = preferredObjectKind(groupVersionKinds, preferredGVKs) + } + mapping, err := m.RESTMapping(groupVersionKind.GroupKind(), groupVersionKind.Version) if err != nil { return nil, fmt.Errorf("unable to recognize %v: %v", groupVersionKind, err) @@ -111,3 +118,39 @@ func (m *Mapper) InfoForObject(obj runtime.Object) (*Info, error) { ResourceVersion: resourceVersion, }, nil } + +// preferredObjectKind picks the possibility that most closely matches the priority list in this order: +// GroupVersionKind matches (exact match) +// GroupKind matches +// Group matches +func preferredObjectKind(possibilities []unversioned.GroupVersionKind, preferences []unversioned.GroupVersionKind) unversioned.GroupVersionKind { + // Exact match + for _, priority := range preferences { + for _, possibility := range possibilities { + if possibility == priority { + return possibility + } + } + } + + // GroupKind match + for _, priority := range preferences { + for _, possibility := range possibilities { + if possibility.GroupKind() == priority.GroupKind() { + return possibility + } + } + } + + // Group match + for _, priority := range preferences { + for _, possibility := range possibilities { + if possibility.Group == priority.Group { + return possibility + } + } + } + + // Just pick the first + return possibilities[0] +} diff --git a/vendor/k8s.io/kubernetes/pkg/kubectl/resource/visitor.go b/vendor/k8s.io/kubernetes/pkg/kubectl/resource/visitor.go index a187919..7656938 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubectl/resource/visitor.go +++ b/vendor/k8s.io/kubernetes/pkg/kubectl/resource/visitor.go @@ -20,13 +20,13 @@ import ( "bytes" "fmt" "io" - "io/ioutil" "net/http" "net/url" "os" "path/filepath" "k8s.io/kubernetes/pkg/api/meta" + "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/api/validation" "k8s.io/kubernetes/pkg/runtime" utilerrors "k8s.io/kubernetes/pkg/util/errors" @@ -219,9 +219,8 @@ func ValidateSchema(data []byte, schema validation.Schema) error { // URLVisitor downloads the contents of a URL, and if successful, returns // an info object representing the downloaded object. type URLVisitor struct { - *Mapper - URL *url.URL - Schema validation.Schema + URL *url.URL + *StreamVisitor } func (v *URLVisitor) Visit(fn VisitorFunc) error { @@ -233,18 +232,9 @@ func (v *URLVisitor) Visit(fn VisitorFunc) error { if res.StatusCode != 200 { return fmt.Errorf("unable to read URL %q, server reported %d %s", v.URL, res.StatusCode, res.Status) } - data, err := ioutil.ReadAll(res.Body) - if err != nil { - return fmt.Errorf("unable to read URL %q: %v\n", v.URL, err) - } - if err := ValidateSchema(data, v.Schema); err != nil { - return fmt.Errorf("error validating %q: %v", v.URL, err) - } - info, err := v.Mapper.InfoForData(data, v.URL.String()) - if err != nil { - return err - } - return fn(info, nil) + + v.StreamVisitor.Reader = res.Body + return v.StreamVisitor.Visit(fn) } // DecoratedVisitor will invoke the decorators in order prior to invoking the visitor function @@ -348,8 +338,15 @@ func (v FlattenListVisitor) Visit(fn VisitorFunc) error { }{v.Mapper, v.Mapper.Decoder}); len(errs) > 0 { return utilerrors.NewAggregate(errs) } + + // If we have a GroupVersionKind on the list, prioritize that when asking for info on the objects contained in the list + var preferredGVKs []unversioned.GroupVersionKind + if info.Mapping != nil && !info.Mapping.GroupVersionKind.IsEmpty() { + preferredGVKs = append(preferredGVKs, info.Mapping.GroupVersionKind) + } + for i := range items { - item, err := v.InfoForObject(items[i]) + item, err := v.InfoForObject(items[i], preferredGVKs) if err != nil { return err } diff --git a/vendor/k8s.io/kubernetes/pkg/kubectl/resource_printer.go b/vendor/k8s.io/kubernetes/pkg/kubectl/resource_printer.go index 5d58ebb..7f9d4ab 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubectl/resource_printer.go +++ b/vendor/k8s.io/kubernetes/pkg/kubectl/resource_printer.go @@ -638,22 +638,19 @@ func printPodTemplate(pod *api.PodTemplate, w io.Writer, options PrintOptions) e namespace := pod.Namespace containers := pod.Template.Spec.Containers - var firstContainer api.Container - if len(containers) > 0 { - firstContainer, containers = containers[0], containers[1:] - } if options.WithNamespace { if _, err := fmt.Fprintf(w, "%s\t", namespace); err != nil { return err } } - if _, err := fmt.Fprintf(w, "%s\t%s\t%s\t%s", - name, - firstContainer.Name, - firstContainer.Image, - labels.FormatLabels(pod.Template.Labels), - ); err != nil { + if _, err := fmt.Fprintf(w, "%s", name); err != nil { + return err + } + if err := layoutContainers(containers, w); err != nil { + return err + } + if _, err := fmt.Fprintf(w, "\t%s", labels.FormatLabels(pod.Template.Labels)); err != nil { return err } if _, err := fmt.Fprint(w, appendLabels(pod.Labels, options.ColumnLabels)); err != nil { @@ -663,20 +660,6 @@ func printPodTemplate(pod *api.PodTemplate, w io.Writer, options PrintOptions) e return err } - // Lay out all the other containers on separate lines. - extraLinePrefix := "\t" - if options.WithNamespace { - extraLinePrefix = "\t\t" - } - for _, container := range containers { - _, err := fmt.Fprintf(w, "%s%s\t%s\t%s", extraLinePrefix, container.Name, container.Image, "") - if err != nil { - return err - } - if _, err := fmt.Fprint(w, appendLabelTabs(options.ColumnLabels)); err != nil { - return err - } - } return nil } @@ -689,14 +672,11 @@ func printPodTemplateList(podList *api.PodTemplateList, w io.Writer, options Pri return nil } +// TODO(AdoHe): try to put wide output in a single method func printReplicationController(controller *api.ReplicationController, w io.Writer, options PrintOptions) error { name := controller.Name namespace := controller.Namespace containers := controller.Spec.Template.Spec.Containers - var firstContainer api.Container - if len(containers) > 0 { - firstContainer, containers = containers[0], containers[1:] - } if options.WithNamespace { if _, err := fmt.Fprintf(w, "%s\t", namespace); err != nil { @@ -714,12 +694,12 @@ func printReplicationController(controller *api.ReplicationController, w io.Writ ); err != nil { return err } + if options.Wide { - if _, err := fmt.Fprintf(w, "\t%s\t%s\t%s", - firstContainer.Name, - firstContainer.Image, - labels.FormatLabels(controller.Spec.Selector), - ); err != nil { + if err := layoutContainers(containers, w); err != nil { + return err + } + if _, err := fmt.Fprintf(w, "\t%s", labels.FormatLabels(controller.Spec.Selector)); err != nil { return err } } @@ -730,20 +710,6 @@ func printReplicationController(controller *api.ReplicationController, w io.Writ return err } - // Lay out all the other containers on separate lines. - extraLinePrefix := "\t" - if options.WithNamespace { - extraLinePrefix = "\t\t" - } - for _, container := range containers { - _, err := fmt.Fprintf(w, "%s%s\t%s\t%s\t%s", extraLinePrefix, container.Name, container.Image, "", "") - if err != nil { - return err - } - if _, err := fmt.Fprint(w, appendLabelTabs(options.ColumnLabels)); err != nil { - return err - } - } return nil } @@ -760,10 +726,6 @@ func printReplicaSet(rs *extensions.ReplicaSet, w io.Writer, options PrintOption name := rs.Name namespace := rs.Namespace containers := rs.Spec.Template.Spec.Containers - var firstContainer api.Container - if len(containers) > 0 { - firstContainer, containers = containers[0], containers[1:] - } if options.WithNamespace { if _, err := fmt.Fprintf(w, "%s\t", namespace); err != nil { @@ -782,11 +744,10 @@ func printReplicaSet(rs *extensions.ReplicaSet, w io.Writer, options PrintOption return err } if options.Wide { - if _, err := fmt.Fprintf(w, "\t%s\t%s\t%s", - firstContainer.Name, - firstContainer.Image, - unversioned.FormatLabelSelector(rs.Spec.Selector), - ); err != nil { + if err := layoutContainers(containers, w); err != nil { + return err + } + if _, err := fmt.Fprintf(w, "\t%s", unversioned.FormatLabelSelector(rs.Spec.Selector)); err != nil { return err } } @@ -797,20 +758,6 @@ func printReplicaSet(rs *extensions.ReplicaSet, w io.Writer, options PrintOption return err } - // Lay out all the other containers on separate lines. - extraLinePrefix := "\t" - if options.WithNamespace { - extraLinePrefix = "\t\t" - } - for _, container := range containers { - _, err := fmt.Fprintf(w, "%s%s\t%s\t%s\t%s", extraLinePrefix, container.Name, container.Image, "", "") - if err != nil { - return err - } - if _, err := fmt.Fprint(w, appendLabelTabs(options.ColumnLabels)); err != nil { - return err - } - } return nil } @@ -827,17 +774,18 @@ func printJob(job *extensions.Job, w io.Writer, options PrintOptions) error { name := job.Name namespace := job.Namespace containers := job.Spec.Template.Spec.Containers - var firstContainer api.Container - if len(containers) > 0 { - firstContainer, containers = containers[0], containers[1:] - } + if options.WithNamespace { if _, err := fmt.Fprintf(w, "%s\t", namespace); err != nil { return err } } - selector, _ := unversioned.LabelSelectorAsSelector(job.Spec.Selector) + selector, err := unversioned.LabelSelectorAsSelector(job.Spec.Selector) + if err != nil { + // this shouldn't happen if LabelSelector passed validation + return err + } if job.Spec.Completions != nil { if _, err := fmt.Fprintf(w, "%s\t%d\t%d\t%s", name, @@ -858,11 +806,10 @@ func printJob(job *extensions.Job, w io.Writer, options PrintOptions) error { } } if options.Wide { - if _, err := fmt.Fprintf(w, "\t%s\t%s\t%s", - firstContainer.Name, - firstContainer.Image, - selector.String(), - ); err != nil { + if err := layoutContainers(containers, w); err != nil { + return err + } + if _, err := fmt.Fprintf(w, "\t%s", selector.String()); err != nil { return err } } @@ -873,20 +820,6 @@ func printJob(job *extensions.Job, w io.Writer, options PrintOptions) error { return err } - // Lay out all the other containers on separate lines. - extraLinePrefix := "\t" - if options.WithNamespace { - extraLinePrefix = "\t\t" - } - for _, container := range containers { - _, err := fmt.Fprintf(w, "%s%s\t%s\t%s\t%s", extraLinePrefix, container.Name, container.Image, "", "") - if err != nil { - return err - } - if _, err := fmt.Fprint(w, appendLabelTabs(options.ColumnLabels)); err != nil { - return err - } - } return nil } @@ -1021,7 +954,8 @@ func printIngress(ingress *extensions.Ingress, w io.Writer, options PrintOptions return err } - // Lay out all the rules on separate lines. + // Lay out all the rules on separate lines if use wide output. + // TODO(AdoHe): improve ingress output extraLinePrefix := "" if options.WithNamespace { extraLinePrefix = "\t" @@ -1047,6 +981,7 @@ func printIngress(ingress *extensions.Ingress, w io.Writer, options PrintOptions } } } + return nil } @@ -1064,10 +999,6 @@ func printDaemonSet(ds *extensions.DaemonSet, w io.Writer, options PrintOptions) namespace := ds.Namespace containers := ds.Spec.Template.Spec.Containers - var firstContainer api.Container - if len(containers) > 0 { - firstContainer, containers = containers[0], containers[1:] - } if options.WithNamespace { if _, err := fmt.Fprintf(w, "%s\t", namespace); err != nil { @@ -1092,11 +1023,10 @@ func printDaemonSet(ds *extensions.DaemonSet, w io.Writer, options PrintOptions) return err } if options.Wide { - if _, err := fmt.Fprintf(w, "\t%s\t%s\t%s", - firstContainer.Name, - firstContainer.Image, - selector, - ); err != nil { + if err := layoutContainers(containers, w); err != nil { + return err + } + if _, err := fmt.Fprintf(w, "\t%s", selector.String()); err != nil { return err } } @@ -1107,20 +1037,6 @@ func printDaemonSet(ds *extensions.DaemonSet, w io.Writer, options PrintOptions) return err } - // Lay out all the other containers on separate lines. - extraLinePrefix := "\t" - if options.WithNamespace { - extraLinePrefix = "\t\t" - } - for _, container := range containers { - _, err := fmt.Fprintf(w, "%s%s\t%s\t%s\t%s", extraLinePrefix, container.Name, container.Image, "", "") - if err != nil { - return err - } - if _, err := fmt.Fprint(w, appendLabelTabs(options.ColumnLabels)); err != nil { - return err - } - } return nil } @@ -1669,8 +1585,8 @@ func printConfigMapList(list *api.ConfigMapList, w io.Writer, options PrintOptio func printPodSecurityPolicy(item *extensions.PodSecurityPolicy, w io.Writer, options PrintOptions) error { _, err := fmt.Fprintf(w, "%s\t%t\t%v\t%t\t%s\t%s\n", item.Name, item.Spec.Privileged, - item.Spec.Capabilities, item.Spec.Volumes, item.Spec.SELinuxContext.Type, - item.Spec.RunAsUser.Type) + item.Spec.Capabilities, item.Spec.Volumes, item.Spec.SELinux.Rule, + item.Spec.RunAsUser.Rule) return err } @@ -1729,6 +1645,26 @@ func appendLabelTabs(columnLabels []string) string { return buffer.String() } +// Lay out all the containers on one line if use wide output. +func layoutContainers(containers []api.Container, w io.Writer) error { + var namesBuffer bytes.Buffer + var imagesBuffer bytes.Buffer + + for i, container := range containers { + namesBuffer.WriteString(container.Name) + imagesBuffer.WriteString(container.Image) + if i != len(containers)-1 { + namesBuffer.WriteString(",") + imagesBuffer.WriteString(",") + } + } + _, err := fmt.Fprintf(w, "\t%s\t%s", namesBuffer.String(), imagesBuffer.String()) + if err != nil { + return err + } + return nil +} + func formatLabelHeaders(columnLabels []string) []string { formHead := make([]string, len(columnLabels)) for i, l := range columnLabels { diff --git a/vendor/k8s.io/kubernetes/pkg/kubectl/rolling_updater.go b/vendor/k8s.io/kubernetes/pkg/kubectl/rolling_updater.go index 625ea65..e69d889 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubectl/rolling_updater.go +++ b/vendor/k8s.io/kubernetes/pkg/kubectl/rolling_updater.go @@ -29,6 +29,7 @@ import ( client "k8s.io/kubernetes/pkg/client/unversioned" "k8s.io/kubernetes/pkg/labels" "k8s.io/kubernetes/pkg/runtime" + "k8s.io/kubernetes/pkg/util/deployment" "k8s.io/kubernetes/pkg/util/integer" "k8s.io/kubernetes/pkg/util/intstr" "k8s.io/kubernetes/pkg/util/wait" @@ -191,18 +192,9 @@ func (r *RollingUpdater) Update(config *RollingUpdaterConfig) error { } oldRc = updated } - original, err := strconv.Atoi(oldRc.Annotations[originalReplicasAnnotation]) - if err != nil { - return fmt.Errorf("Unable to parse annotation for %s: %s=%s\n", - oldRc.Name, originalReplicasAnnotation, oldRc.Annotations[originalReplicasAnnotation]) - } - // The maximum pods which can go unavailable during the update. - maxUnavailable, err := intstr.GetValueFromIntOrPercent(&config.MaxUnavailable, desired, false) - if err != nil { - return err - } - // The maximum scaling increment. - maxSurge, err := intstr.GetValueFromIntOrPercent(&config.MaxSurge, desired, true) + // maxSurge is the maximum scaling increment and maxUnavailable are the maximum pods + // that can be unavailable during a rollout. + maxSurge, maxUnavailable, err := deployment.ResolveFenceposts(&config.MaxSurge, &config.MaxUnavailable, desired) if err != nil { return err } @@ -217,12 +209,12 @@ func (r *RollingUpdater) Update(config *RollingUpdaterConfig) error { // the effective scale of the old RC regardless of the configuration // (equivalent to 100% maxUnavailable). if desired == 0 { - maxUnavailable = original + maxUnavailable = oldRc.Spec.Replicas minAvailable = 0 } fmt.Fprintf(out, "Scaling up %s from %d to %d, scaling down %s from %d to 0 (keep %d pods available, don't exceed %d pods)\n", - newRc.Name, newRc.Spec.Replicas, desired, oldRc.Name, oldRc.Spec.Replicas, minAvailable, original+maxSurge) + newRc.Name, newRc.Spec.Replicas, desired, oldRc.Name, oldRc.Spec.Replicas, minAvailable, desired+maxSurge) // Scale newRc and oldRc until newRc has the desired number of replicas and // oldRc has 0 replicas. @@ -233,7 +225,7 @@ func (r *RollingUpdater) Update(config *RollingUpdaterConfig) error { oldReplicas := oldRc.Spec.Replicas // Scale up as much as possible. - scaledRc, err := r.scaleUp(newRc, oldRc, original, desired, maxSurge, maxUnavailable, scaleRetryParams, config) + scaledRc, err := r.scaleUp(newRc, oldRc, desired, maxSurge, maxUnavailable, scaleRetryParams, config) if err != nil { return err } @@ -266,14 +258,14 @@ func (r *RollingUpdater) Update(config *RollingUpdaterConfig) error { // scaleUp scales up newRc to desired by whatever increment is possible given // the configured surge threshold. scaleUp will safely no-op as necessary when // it detects redundancy or other relevant conditions. -func (r *RollingUpdater) scaleUp(newRc, oldRc *api.ReplicationController, original, desired, maxSurge, maxUnavailable int, scaleRetryParams *RetryParams, config *RollingUpdaterConfig) (*api.ReplicationController, error) { +func (r *RollingUpdater) scaleUp(newRc, oldRc *api.ReplicationController, desired, maxSurge, maxUnavailable int, scaleRetryParams *RetryParams, config *RollingUpdaterConfig) (*api.ReplicationController, error) { // If we're already at the desired, do nothing. if newRc.Spec.Replicas == desired { return newRc, nil } // Scale up as far as we can based on the surge limit. - increment := (original + maxSurge) - (oldRc.Spec.Replicas + newRc.Spec.Replicas) + increment := (desired + maxSurge) - (oldRc.Spec.Replicas + newRc.Spec.Replicas) // If the old is already scaled down, go ahead and scale all the way up. if oldRc.Spec.Replicas == 0 { increment = desired - newRc.Spec.Replicas diff --git a/vendor/k8s.io/kubernetes/pkg/kubectl/run.go b/vendor/k8s.io/kubernetes/pkg/kubectl/run.go index 8cf4325..688b570 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubectl/run.go +++ b/vendor/k8s.io/kubernetes/pkg/kubectl/run.go @@ -24,6 +24,8 @@ import ( "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/resource" "k8s.io/kubernetes/pkg/api/unversioned" + "k8s.io/kubernetes/pkg/api/v1" + batchv1 "k8s.io/kubernetes/pkg/apis/batch/v1" "k8s.io/kubernetes/pkg/apis/extensions" "k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/util/validation" @@ -187,6 +189,24 @@ func getEnvs(genericParams map[string]interface{}) ([]api.EnvVar, error) { return envs, nil } +func getV1Envs(genericParams map[string]interface{}) ([]v1.EnvVar, error) { + var envs []v1.EnvVar + envStrings, found := genericParams["env"] + if found { + if envStringArray, isArray := envStrings.([]string); isArray { + var err error + envs, err = parseV1Envs(envStringArray) + if err != nil { + return nil, err + } + delete(genericParams, "env") + } else { + return nil, fmt.Errorf("expected []string, found: %v", envStrings) + } + } + return envs, nil +} + type JobV1Beta1 struct{} func (JobV1Beta1) ParamNames() []GeneratorParam { @@ -256,7 +276,7 @@ func (JobV1Beta1) Generate(genericParams map[string]interface{}) (runtime.Object restartPolicy := api.RestartPolicy(params["restart"]) if len(restartPolicy) == 0 { - restartPolicy = api.RestartPolicyAlways + restartPolicy = api.RestartPolicyNever } podSpec.RestartPolicy = restartPolicy @@ -282,6 +302,97 @@ func (JobV1Beta1) Generate(genericParams map[string]interface{}) (runtime.Object return &job, nil } +type JobV1 struct{} + +func (JobV1) ParamNames() []GeneratorParam { + return []GeneratorParam{ + {"labels", false}, + {"default-name", false}, + {"name", true}, + {"image", true}, + {"port", false}, + {"hostport", false}, + {"stdin", false}, + {"leave-stdin-open", false}, + {"tty", false}, + {"command", false}, + {"args", false}, + {"env", false}, + {"requests", false}, + {"limits", false}, + {"restart", false}, + } +} + +func (JobV1) Generate(genericParams map[string]interface{}) (runtime.Object, error) { + args, err := getArgs(genericParams) + if err != nil { + return nil, err + } + + envs, err := getV1Envs(genericParams) + if err != nil { + return nil, err + } + + params, err := getParams(genericParams) + if err != nil { + return nil, err + } + + name, err := getName(params) + if err != nil { + return nil, err + } + + labels, err := getLabels(params, true, name) + if err != nil { + return nil, err + } + + podSpec, err := makeV1PodSpec(params, name) + if err != nil { + return nil, err + } + + if err = updateV1PodContainers(params, args, envs, podSpec); err != nil { + return nil, err + } + + leaveStdinOpen, err := GetBool(params, "leave-stdin-open", false) + if err != nil { + return nil, err + } + podSpec.Containers[0].StdinOnce = !leaveStdinOpen && podSpec.Containers[0].Stdin + + if err := updateV1PodPorts(params, podSpec); err != nil { + return nil, err + } + + restartPolicy := v1.RestartPolicy(params["restart"]) + if len(restartPolicy) == 0 { + restartPolicy = v1.RestartPolicyNever + } + podSpec.RestartPolicy = restartPolicy + + job := batchv1.Job{ + ObjectMeta: v1.ObjectMeta{ + Name: name, + Labels: labels, + }, + Spec: batchv1.JobSpec{ + Template: v1.PodTemplateSpec{ + ObjectMeta: v1.ObjectMeta{ + Labels: labels, + }, + Spec: *podSpec, + }, + }, + } + + return &job, nil +} + type BasicReplicationController struct{} func (BasicReplicationController) ParamNames() []GeneratorParam { @@ -327,6 +438,30 @@ func populateResourceList(spec string) (api.ResourceList, error) { return result, nil } +// populateResourceList takes strings of form =,= +func populateV1ResourceList(spec string) (v1.ResourceList, error) { + // empty input gets a nil response to preserve generator test expected behaviors + if spec == "" { + return nil, nil + } + + result := v1.ResourceList{} + resourceStatements := strings.Split(spec, ",") + for _, resourceStatement := range resourceStatements { + parts := strings.Split(resourceStatement, "=") + if len(parts) != 2 { + return nil, fmt.Errorf("Invalid argument syntax %v, expected =", resourceStatement) + } + resourceName := v1.ResourceName(parts[0]) + resourceQuantity, err := resource.ParseQuantity(parts[1]) + if err != nil { + return nil, err + } + result[resourceName] = *resourceQuantity + } + return result, nil +} + // HandleResourceRequirements parses the limits and requests parameters if specified func HandleResourceRequirements(params map[string]string) (api.ResourceRequirements, error) { result := api.ResourceRequirements{} @@ -343,6 +478,22 @@ func HandleResourceRequirements(params map[string]string) (api.ResourceRequireme return result, nil } +// HandleResourceRequirements parses the limits and requests parameters if specified +func handleV1ResourceRequirements(params map[string]string) (v1.ResourceRequirements, error) { + result := v1.ResourceRequirements{} + limits, err := populateV1ResourceList(params["limits"]) + if err != nil { + return result, err + } + result.Limits = limits + requests, err := populateV1ResourceList(params["requests"]) + if err != nil { + return result, err + } + result.Requests = requests + return result, nil +} + func makePodSpec(params map[string]string, name string) (*api.PodSpec, error) { stdin, err := GetBool(params, "stdin", false) if err != nil { @@ -373,6 +524,36 @@ func makePodSpec(params map[string]string, name string) (*api.PodSpec, error) { return &spec, nil } +func makeV1PodSpec(params map[string]string, name string) (*v1.PodSpec, error) { + stdin, err := GetBool(params, "stdin", false) + if err != nil { + return nil, err + } + + tty, err := GetBool(params, "tty", false) + if err != nil { + return nil, err + } + + resourceRequirements, err := handleV1ResourceRequirements(params) + if err != nil { + return nil, err + } + + spec := v1.PodSpec{ + Containers: []v1.Container{ + { + Name: name, + Image: params["image"], + Stdin: stdin, + TTY: tty, + Resources: resourceRequirements, + }, + }, + } + return &spec, nil +} + func (BasicReplicationController) Generate(genericParams map[string]interface{}) (runtime.Object, error) { args, err := getArgs(genericParams) if err != nil { @@ -455,6 +636,25 @@ func updatePodContainers(params map[string]string, args []string, envs []api.Env return nil } +func updateV1PodContainers(params map[string]string, args []string, envs []v1.EnvVar, podSpec *v1.PodSpec) error { + if len(args) > 0 { + command, err := GetBool(params, "command", false) + if err != nil { + return err + } + if command { + podSpec.Containers[0].Command = args + } else { + podSpec.Containers[0].Args = args + } + } + + if len(envs) > 0 { + podSpec.Containers[0].Env = envs + } + return nil +} + func updatePodPorts(params map[string]string, podSpec *api.PodSpec) (err error) { port := -1 hostPort := -1 @@ -489,6 +689,40 @@ func updatePodPorts(params map[string]string, podSpec *api.PodSpec) (err error) return nil } +func updateV1PodPorts(params map[string]string, podSpec *v1.PodSpec) (err error) { + port := -1 + hostPort := -1 + if len(params["port"]) > 0 { + port, err = strconv.Atoi(params["port"]) + if err != nil { + return err + } + } + + if len(params["hostport"]) > 0 { + hostPort, err = strconv.Atoi(params["hostport"]) + if err != nil { + return err + } + if hostPort > 0 && port < 0 { + return fmt.Errorf("--hostport requires --port to be specified") + } + } + + // Don't include the port if it was not specified. + if port > 0 { + podSpec.Containers[0].Ports = []v1.ContainerPort{ + { + ContainerPort: int32(port), + }, + } + if hostPort > 0 { + podSpec.Containers[0].Ports[0].HostPort = int32(hostPort) + } + } + return nil +} + type BasicPod struct{} func (BasicPod) ParamNames() []GeneratorParam { @@ -609,6 +843,24 @@ func parseEnvs(envArray []string) ([]api.EnvVar, error) { return envs, nil } +func parseV1Envs(envArray []string) ([]v1.EnvVar, error) { + envs := []v1.EnvVar{} + for _, env := range envArray { + pos := strings.Index(env, "=") + if pos == -1 { + return nil, fmt.Errorf("invalid env: %v", env) + } + name := env[:pos] + value := env[pos+1:] + if len(name) == 0 || !validation.IsCIdentifier(name) || len(value) == 0 { + return nil, fmt.Errorf("invalid env: %v", env) + } + envVar := v1.EnvVar{Name: name, Value: value} + envs = append(envs, envVar) + } + return envs, nil +} + func newBool(val bool) *bool { p := new(bool) *p = val diff --git a/vendor/k8s.io/kubernetes/pkg/labels/selector.go b/vendor/k8s.io/kubernetes/pkg/labels/selector.go index 5203774..fb48b10 100644 --- a/vendor/k8s.io/kubernetes/pkg/labels/selector.go +++ b/vendor/k8s.io/kubernetes/pkg/labels/selector.go @@ -72,8 +72,8 @@ const ( NotEqualsOperator Operator = "!=" NotInOperator Operator = "notin" ExistsOperator Operator = "exists" - GreaterThanOperator Operator = "Gt" - LessThanOperator Operator = "Lt" + GreaterThanOperator Operator = "gt" + LessThanOperator Operator = "lt" ) func NewSelector() Selector { @@ -743,13 +743,25 @@ func (p *Parser) parseExactValue() (sets.String, error) { // (5) A requirement with just !KEY requires that the KEY not exist. // func Parse(selector string) (Selector, error) { + parsedSelector, err := parse(selector) + if err == nil { + return parsedSelector, nil + } + return nil, err +} + +// parse parses the string representation of the selector and returns the internalSelector struct. +// The callers of this method can then decide how to return the internalSelector struct to their +// callers. This function has two callers now, one returns a Selector interface and the other +// returns a list of requirements. +func parse(selector string) (internalSelector, error) { p := &Parser{l: &Lexer{s: selector, pos: 0}} - items, error := p.parse() - if error == nil { - sort.Sort(ByKey(items)) // sort to grant determistic parsing - return internalSelector(items), error + items, err := p.parse() + if err != nil { + return nil, err } - return nil, error + sort.Sort(ByKey(items)) // sort to grant determistic parsing + 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) @@ -788,3 +800,12 @@ func SelectorFromSet(ls Set) Selector { sort.Sort(ByKey(requirements)) return internalSelector(requirements) } + +// ParseToRequirements takes a string representing a selector and returns a list of +// requirements. This function is suitable for those callers that perform additional +// processing on selector requirements. +// See the documentation for Parse() function for more details. +// TODO: Consider exporting the internalSelector type instead. +func ParseToRequirements(selector string) ([]Requirement, error) { + return parse(selector) +} diff --git a/vendor/k8s.io/kubernetes/pkg/runtime/OWNERS b/vendor/k8s.io/kubernetes/pkg/runtime/OWNERS new file mode 100644 index 0000000..d038b5e --- /dev/null +++ b/vendor/k8s.io/kubernetes/pkg/runtime/OWNERS @@ -0,0 +1,5 @@ +assignees: + - caesarxuchao + - deads2k + - lavalamp + - smarterclayton diff --git a/vendor/k8s.io/kubernetes/pkg/types/unix_user_id.go b/vendor/k8s.io/kubernetes/pkg/types/unix_user_id.go new file mode 100644 index 0000000..b59792a --- /dev/null +++ b/vendor/k8s.io/kubernetes/pkg/types/unix_user_id.go @@ -0,0 +1,23 @@ +/* +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 types + +// int64 is used as a safe bet against wrap-around (uid's are general +// int32) and to support uid_t -1, and -2. + +type UnixUserID int64 +type UnixGroupID int64 diff --git a/vendor/k8s.io/kubernetes/pkg/util/deployment/deployment.go b/vendor/k8s.io/kubernetes/pkg/util/deployment/deployment.go index 27a5a31..6160f5d 100644 --- a/vendor/k8s.io/kubernetes/pkg/util/deployment/deployment.go +++ b/vendor/k8s.io/kubernetes/pkg/util/deployment/deployment.go @@ -27,9 +27,9 @@ import ( "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/apis/extensions" clientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" - unversionedcore "k8s.io/kubernetes/pkg/client/typed/generated/core/unversioned" - unversionedextensions "k8s.io/kubernetes/pkg/client/typed/generated/extensions/unversioned" + "k8s.io/kubernetes/pkg/controller" "k8s.io/kubernetes/pkg/labels" + "k8s.io/kubernetes/pkg/util/errors" "k8s.io/kubernetes/pkg/util/integer" intstrutil "k8s.io/kubernetes/pkg/util/intstr" labelsutil "k8s.io/kubernetes/pkg/util/labels" @@ -50,32 +50,87 @@ const ( // GetOldReplicaSets returns the old replica sets targeted by the given Deployment; get PodList and ReplicaSetList from client interface. // Note that the first set of old replica sets doesn't include the ones with no pods, and the second set of old replica sets include all old replica sets. func GetOldReplicaSets(deployment *extensions.Deployment, c clientset.Interface) ([]*extensions.ReplicaSet, []*extensions.ReplicaSet, error) { - return GetOldReplicaSetsFromLists(deployment, c, + rsList, err := ListReplicaSets(deployment, + func(namespace string, options api.ListOptions) ([]extensions.ReplicaSet, error) { + rsList, err := c.Extensions().ReplicaSets(namespace).List(options) + return rsList.Items, err + }) + if err != nil { + return nil, nil, fmt.Errorf("error listing ReplicaSets: %v", err) + } + podList, err := ListPods(deployment, func(namespace string, options api.ListOptions) (*api.PodList, error) { return c.Core().Pods(namespace).List(options) - }, + }) + if err != nil { + return nil, nil, fmt.Errorf("error listing Pods: %v", err) + } + return FindOldReplicaSets(deployment, rsList, podList) +} + +// GetNewReplicaSet returns a replica set that matches the intent of the given deployment; get ReplicaSetList from client interface. +// Returns nil if the new replica set doesn't exist yet. +func GetNewReplicaSet(deployment *extensions.Deployment, c clientset.Interface) (*extensions.ReplicaSet, error) { + rsList, err := ListReplicaSets(deployment, func(namespace string, options api.ListOptions) ([]extensions.ReplicaSet, error) { rsList, err := c.Extensions().ReplicaSets(namespace).List(options) return rsList.Items, err }) + if err != nil { + return nil, fmt.Errorf("error listing ReplicaSets: %v", err) + } + return FindNewReplicaSet(deployment, rsList) } // TODO: switch this to full namespacers type rsListFunc func(string, api.ListOptions) ([]extensions.ReplicaSet, error) type podListFunc func(string, api.ListOptions) (*api.PodList, error) -// GetOldReplicaSetsFromLists returns two sets of old replica sets targeted by the given Deployment; get PodList and ReplicaSetList with input functions. +// ListReplicaSets returns a slice of RSes the given deployment targets. +func ListReplicaSets(deployment *extensions.Deployment, getRSList rsListFunc) ([]extensions.ReplicaSet, error) { + // TODO: Right now we list replica sets by their labels. We should list them by selector, i.e. the replica set's selector + // should be a superset of the deployment's selector, see https://github.com/kubernetes/kubernetes/issues/19830; + // or use controllerRef, see https://github.com/kubernetes/kubernetes/issues/2210 + namespace := deployment.Namespace + selector, err := unversioned.LabelSelectorAsSelector(deployment.Spec.Selector) + if err != nil { + return nil, err + } + options := api.ListOptions{LabelSelector: selector} + return getRSList(namespace, options) +} + +// ListPods returns a list of pods the given deployment targets. +func ListPods(deployment *extensions.Deployment, getPodList podListFunc) (*api.PodList, error) { + namespace := deployment.Namespace + selector, err := unversioned.LabelSelectorAsSelector(deployment.Spec.Selector) + if err != nil { + return nil, err + } + options := api.ListOptions{LabelSelector: selector} + return getPodList(namespace, options) +} + +// FindNewReplicaSet returns the new RS this given deployment targets (the one with the same pod template). +func FindNewReplicaSet(deployment *extensions.Deployment, rsList []extensions.ReplicaSet) (*extensions.ReplicaSet, error) { + newRSTemplate := GetNewReplicaSetTemplate(deployment) + for i := range rsList { + if api.Semantic.DeepEqual(rsList[i].Spec.Template, newRSTemplate) { + // This is the new ReplicaSet. + return &rsList[i], nil + } + } + // new ReplicaSet does not exist. + return nil, nil +} + +// FindOldReplicaSets returns the old replica sets targeted by the given Deployment, with the given PodList and slice of RSes. // Note that the first set of old replica sets doesn't include the ones with no pods, and the second set of old replica sets include all old replica sets. -func GetOldReplicaSetsFromLists(deployment *extensions.Deployment, c clientset.Interface, getPodList podListFunc, getRSList rsListFunc) ([]*extensions.ReplicaSet, []*extensions.ReplicaSet, error) { +func FindOldReplicaSets(deployment *extensions.Deployment, rsList []extensions.ReplicaSet, podList *api.PodList) ([]*extensions.ReplicaSet, []*extensions.ReplicaSet, error) { // Find all pods whose labels match deployment.Spec.Selector, and corresponding replica sets for pods in podList. // All pods and replica sets are labeled with pod-template-hash to prevent overlapping - // TODO: Right now we list all replica sets and then filter. We should add an API for this. oldRSs := map[string]extensions.ReplicaSet{} allOldRSs := map[string]extensions.ReplicaSet{} - rsList, podList, err := rsAndPodsWithHashKeySynced(deployment, c, getRSList, getPodList) - if err != nil { - return nil, nil, fmt.Errorf("error labeling replica sets and pods with pod-template-hash: %v", err) - } newRSTemplate := GetNewReplicaSetTemplate(deployment) for _, pod := range podList.Items { podLabelsSelector := labels.Set(pod.ObjectMeta.Labels) @@ -85,7 +140,7 @@ func GetOldReplicaSetsFromLists(deployment *extensions.Deployment, c clientset.I return nil, nil, fmt.Errorf("invalid label selector: %v", err) } // Filter out replica set that has the same pod template spec as the deployment - that is the new replica set. - if api.Semantic.DeepEqual(rs.Spec.Template, &newRSTemplate) { + if api.Semantic.DeepEqual(rs.Spec.Template, newRSTemplate) { continue } allOldRSs[rs.ObjectMeta.Name] = rs @@ -107,203 +162,54 @@ func GetOldReplicaSetsFromLists(deployment *extensions.Deployment, c clientset.I return requiredRSs, allRSs, nil } -// GetNewReplicaSet returns a replica set that matches the intent of the given deployment; get ReplicaSetList from client interface. -// Returns nil if the new replica set doesn't exist yet. -func GetNewReplicaSet(deployment *extensions.Deployment, c clientset.Interface) (*extensions.ReplicaSet, error) { - return GetNewReplicaSetFromList(deployment, c, - func(namespace string, options api.ListOptions) (*api.PodList, error) { - return c.Core().Pods(namespace).List(options) - }, - func(namespace string, options api.ListOptions) ([]extensions.ReplicaSet, error) { - rsList, err := c.Extensions().ReplicaSets(namespace).List(options) - return rsList.Items, err - }) -} - -// GetNewReplicaSetFromList returns a replica set that matches the intent of the given deployment; get ReplicaSetList with the input function. -// Returns nil if the new replica set doesn't exist yet. -func GetNewReplicaSetFromList(deployment *extensions.Deployment, c clientset.Interface, getPodList podListFunc, getRSList rsListFunc) (*extensions.ReplicaSet, error) { - rsList, _, err := rsAndPodsWithHashKeySynced(deployment, c, getRSList, getPodList) - if err != nil { - return nil, fmt.Errorf("error listing ReplicaSets: %v", err) - } - newRSTemplate := GetNewReplicaSetTemplate(deployment) - - for i := range rsList { - if api.Semantic.DeepEqual(rsList[i].Spec.Template, &newRSTemplate) { - // This is the new ReplicaSet. - return &rsList[i], nil - } - } - // new ReplicaSet does not exist. - return nil, nil -} - -// rsAndPodsWithHashKeySynced returns the RSs and pods the given deployment targets, with pod-template-hash information synced. -func rsAndPodsWithHashKeySynced(deployment *extensions.Deployment, c clientset.Interface, getRSList rsListFunc, getPodList podListFunc) ([]extensions.ReplicaSet, *api.PodList, error) { - namespace := deployment.Namespace - selector, err := unversioned.LabelSelectorAsSelector(deployment.Spec.Selector) - if err != nil { - return nil, nil, err - } - options := api.ListOptions{LabelSelector: selector} - rsList, err := getRSList(namespace, options) - if err != nil { - return nil, nil, err - } - syncedRSList := []extensions.ReplicaSet{} - for _, rs := range rsList { - // Add pod-template-hash information if it's not in the RS. - // Otherwise, new RS produced by Deployment will overlap with pre-existing ones - // that aren't constrained by the pod-template-hash. - syncedRS, err := addHashKeyToRSAndPods(deployment, c, rs, getPodList) - if err != nil { - return nil, nil, err - } - syncedRSList = append(syncedRSList, *syncedRS) - } - syncedPodList, err := getPodList(namespace, options) - if err != nil { - return nil, nil, err - } - return syncedRSList, syncedPodList, nil -} - -// addHashKeyToRSAndPods adds pod-template-hash information to the given rs, if it's not already there, with the following steps: -// 1. Add hash label to the rs's pod template, and make sure the controller sees this update so that no orphaned pods will be created -// 2. Add hash label to all pods this rs owns -// 3. Add hash label to the rs's label and selector -func addHashKeyToRSAndPods(deployment *extensions.Deployment, c clientset.Interface, rs extensions.ReplicaSet, getPodList podListFunc) (updatedRS *extensions.ReplicaSet, err error) { - updatedRS = &rs - // If the rs already has the new hash label in its selector, it's done syncing - if labelsutil.SelectorHasLabel(rs.Spec.Selector, extensions.DefaultDeploymentUniqueLabelKey) { - return - } - namespace := deployment.Namespace - meta := rs.Spec.Template.ObjectMeta - meta.Labels = labelsutil.CloneAndRemoveLabel(meta.Labels, extensions.DefaultDeploymentUniqueLabelKey) - hash := fmt.Sprintf("%d", podutil.GetPodTemplateSpecHash(api.PodTemplateSpec{ - ObjectMeta: meta, - Spec: rs.Spec.Template.Spec, - })) - // 1. Add hash template label to the rs. This ensures that any newly created pods will have the new label. - if len(updatedRS.Spec.Template.Labels[extensions.DefaultDeploymentUniqueLabelKey]) == 0 { - updatedRS, err = updateRSWithRetries(c.Extensions().ReplicaSets(namespace), updatedRS, func(updated *extensions.ReplicaSet) { - updated.Spec.Template.Labels = labelsutil.AddLabel(updated.Spec.Template.Labels, extensions.DefaultDeploymentUniqueLabelKey, hash) - }) +func WaitForReplicaSetUpdated(c clientset.Interface, desiredGeneration int64, namespace, name string) error { + return wait.Poll(10*time.Millisecond, 1*time.Minute, func() (bool, error) { + rs, err := c.Extensions().ReplicaSets(namespace).Get(name) if err != nil { - return nil, fmt.Errorf("error updating rs %s pod template label with template hash: %v", updatedRS.Name, err) - } - // Make sure rs pod template is updated so that it won't create pods without the new label (orphaned pods). - if updatedRS.Generation > updatedRS.Status.ObservedGeneration { - if err = waitForReplicaSetUpdated(c, updatedRS.Generation, namespace, updatedRS.Name); err != nil { - return nil, fmt.Errorf("error waiting for rs %s generation %d observed by controller: %v", updatedRS.Name, updatedRS.Generation, err) - } + return false, err } - glog.V(4).Infof("Observed the update of rs %s's pod template with hash %s.", rs.Name, hash) - } - - // 2. Update all pods managed by the rs to have the new hash label, so they will be correctly adopted. - selector, err := unversioned.LabelSelectorAsSelector(updatedRS.Spec.Selector) - if err != nil { - return nil, err - } - options := api.ListOptions{LabelSelector: selector} - podList, err := getPodList(namespace, options) - if err != nil { - return nil, err - } - if err = labelPodsWithHash(podList, c, namespace, hash); err != nil { - return nil, err - } - glog.V(4).Infof("Labeled rs %s's pods with hash %s.", rs.Name, hash) - - // 3. Update rs label and selector to include the new hash label - // Copy the old selector, so that we can scrub out any orphaned pods - if updatedRS, err = updateRSWithRetries(c.Extensions().ReplicaSets(namespace), updatedRS, func(updated *extensions.ReplicaSet) { - updated.Labels = labelsutil.AddLabel(updated.Labels, extensions.DefaultDeploymentUniqueLabelKey, hash) - updated.Spec.Selector = labelsutil.AddLabelToSelector(updated.Spec.Selector, extensions.DefaultDeploymentUniqueLabelKey, hash) - }); err != nil { - return nil, fmt.Errorf("error updating rs %s label and selector with template hash: %v", updatedRS.Name, err) - } - glog.V(4).Infof("Updated rs %s's selector and label with hash %s.", rs.Name, hash) - - // TODO: look for orphaned pods and label them in the background somewhere else periodically - - return updatedRS, nil + return rs.Status.ObservedGeneration >= desiredGeneration, nil + }) } -func waitForReplicaSetUpdated(c clientset.Interface, desiredGeneration int64, namespace, name string) error { - return wait.Poll(10*time.Millisecond, 1*time.Minute, func() (bool, error) { +func WaitForPodsHashPopulated(c clientset.Interface, desiredGeneration int64, namespace, name string) error { + return wait.Poll(1*time.Second, 1*time.Minute, func() (bool, error) { rs, err := c.Extensions().ReplicaSets(namespace).Get(name) if err != nil { return false, err } - return rs.Status.ObservedGeneration >= desiredGeneration, nil + return rs.Status.ObservedGeneration >= desiredGeneration && + rs.Status.FullyLabeledReplicas == rs.Spec.Replicas, nil }) } -// labelPodsWithHash labels all pods in the given podList with the new hash label. -func labelPodsWithHash(podList *api.PodList, c clientset.Interface, namespace, hash string) error { +// LabelPodsWithHash labels all pods in the given podList with the new hash label. +// The returned bool value can be used to tell if all pods are actually labeled. +func LabelPodsWithHash(podList *api.PodList, rs *extensions.ReplicaSet, c clientset.Interface, namespace, hash string) (bool, error) { + allPodsLabeled := true for _, pod := range podList.Items { // Only label the pod that doesn't already have the new hash if pod.Labels[extensions.DefaultDeploymentUniqueLabelKey] != hash { - if _, err := updatePodWithRetries(c.Core().Pods(namespace), &pod, func(updated *api.Pod) { - pod.Labels = labelsutil.AddLabel(pod.Labels, extensions.DefaultDeploymentUniqueLabelKey, hash) - }); err != nil { - return err + if _, podUpdated, err := podutil.UpdatePodWithRetries(c.Core().Pods(namespace), &pod, + func(podToUpdate *api.Pod) error { + // Precondition: the pod doesn't contain the new hash in its label. + if podToUpdate.Labels[extensions.DefaultDeploymentUniqueLabelKey] == hash { + return errors.ErrPreconditionViolated + } + podToUpdate.Labels = labelsutil.AddLabel(podToUpdate.Labels, extensions.DefaultDeploymentUniqueLabelKey, hash) + return nil + }); err != nil { + return false, fmt.Errorf("error in adding template hash label %s to pod %+v: %s", hash, pod, err) + } else if podUpdated { + glog.V(4).Infof("Labeled %s %s/%s of %s %s/%s with hash %s.", pod.Kind, pod.Namespace, pod.Name, rs.Kind, rs.Namespace, rs.Name, hash) + } else { + // If the pod wasn't updated but didn't return error when we try to update it, we've hit "pod not found" or "precondition violated" error. + // Then we can't say all pods are labeled + allPodsLabeled = false } - glog.V(4).Infof("Labeled pod %s with hash %s.", pod.Name, hash) } } - return nil -} - -// TODO: use client library instead when it starts to support update retries -// see https://github.com/kubernetes/kubernetes/issues/21479 -type updateRSFunc func(rs *extensions.ReplicaSet) - -func updateRSWithRetries(rsClient unversionedextensions.ReplicaSetInterface, rs *extensions.ReplicaSet, applyUpdate updateRSFunc) (*extensions.ReplicaSet, error) { - var err error - oldRs := rs - err = wait.Poll(10*time.Millisecond, 1*time.Minute, func() (bool, error) { - // Apply the update, then attempt to push it to the apiserver. - applyUpdate(rs) - if rs, err = rsClient.Update(rs); err == nil { - // rs contains the latest controller post update - return true, nil - } - // Update the controller with the latest resource version, if the update failed we - // can't trust rs so use oldRs.Name. - if rs, err = rsClient.Get(oldRs.Name); err != nil { - // The Get failed: Value in rs cannot be trusted. - rs = oldRs - } - // The Get passed: rs contains the latest controller, expect a poll for the update. - return false, nil - }) - // If the error is non-nil the returned controller cannot be trusted, if it is nil, the returned - // controller contains the applied update. - return rs, err -} - -type updatePodFunc func(pod *api.Pod) - -func updatePodWithRetries(podClient unversionedcore.PodInterface, pod *api.Pod, applyUpdate updatePodFunc) (*api.Pod, error) { - var err error - oldPod := pod - err = wait.Poll(10*time.Millisecond, 1*time.Minute, func() (bool, error) { - // Apply the update, then attempt to push it to the apiserver. - applyUpdate(pod) - if pod, err = podClient.Update(pod); err == nil { - return true, nil - } - if pod, err = podClient.Get(oldPod.Name); err != nil { - pod = oldPod - } - return false, nil - }) - return pod, err + return allPodsLabeled, nil } // Returns the desired PodTemplateSpec for the new ReplicaSet corresponding to the given ReplicaSet. @@ -372,6 +278,9 @@ func getReadyPodsCount(pods []api.Pod, minReadySeconds int) int { } func IsPodAvailable(pod *api.Pod, minReadySeconds int) bool { + if !controller.IsPodActive(*pod) { + return false + } // Check if we've passed minReadySeconds since LastTransitionTime // If so, this pod is ready for _, c := range pod.Status.Conditions { @@ -470,3 +379,33 @@ func WaitForObservedDeployment(getDeploymentFunc func() (*extensions.Deployment, return deployment.Status.ObservedGeneration >= desiredGeneration, nil }) } + +// ResolveFenceposts resolves both maxSurge and maxUnavailable. This needs to happen in one +// step. For example: +// +// 2 desired, max unavailable 1%, surge 0% - should scale old(-1), then new(+1), then old(-1), then new(+1) +// 1 desired, max unavailable 1%, surge 0% - should scale old(-1), then new(+1) +// 2 desired, max unavailable 25%, surge 1% - should scale new(+1), then old(-1), then new(+1), then old(-1) +// 1 desired, max unavailable 25%, surge 1% - should scale new(+1), then old(-1) +// 2 desired, max unavailable 0%, surge 1% - should scale new(+1), then old(-1), then new(+1), then old(-1) +// 1 desired, max unavailable 0%, surge 1% - should scale new(+1), then old(-1) +func ResolveFenceposts(maxSurge, maxUnavailable *intstrutil.IntOrString, desired int) (int, int, error) { + surge, err := intstrutil.GetValueFromIntOrPercent(maxSurge, desired, true) + if err != nil { + return 0, 0, err + } + unavailable, err := intstrutil.GetValueFromIntOrPercent(maxUnavailable, desired, false) + if err != nil { + return 0, 0, err + } + + if surge == 0 && unavailable == 0 { + // Validation should never allow the user to explicitly use zero values for both maxSurge + // maxUnavailable. Due to rounding down maxUnavailable though, it may resolve to zero. + // If both fenceposts resolve to zero, then we should set maxUnavailable to 1 on the + // theory that surge might not work due to quota. + unavailable = 1 + } + + return surge, unavailable, nil +} diff --git a/vendor/k8s.io/kubernetes/pkg/util/errors/errors.go b/vendor/k8s.io/kubernetes/pkg/util/errors/errors.go index a1a8e7a..df3adaf 100644 --- a/vendor/k8s.io/kubernetes/pkg/util/errors/errors.go +++ b/vendor/k8s.io/kubernetes/pkg/util/errors/errors.go @@ -16,7 +16,10 @@ limitations under the License. package errors -import "fmt" +import ( + "errors" + "fmt" +) // Aggregate represents an object that contains multiple errors, but does not // necessarily have singular semantic meaning. @@ -148,3 +151,6 @@ func AggregateGoroutines(funcs ...func() error) Aggregate { } return NewAggregate(errs) } + +// ErrPreconditionViolated is returned when the precondition is violated +var ErrPreconditionViolated = errors.New("precondition is violated") diff --git a/vendor/k8s.io/kubernetes/pkg/util/labels/labels.go b/vendor/k8s.io/kubernetes/pkg/util/labels/labels.go index 2160e37..624d5ad 100644 --- a/vendor/k8s.io/kubernetes/pkg/util/labels/labels.go +++ b/vendor/k8s.io/kubernetes/pkg/util/labels/labels.go @@ -57,7 +57,7 @@ func CloneAndRemoveLabel(labels map[string]string, labelKey string) map[string]s // AddLabel returns a map with the given key and value added to the given map. func AddLabel(labels map[string]string, labelKey string, labelValue string) map[string]string { if labelKey == "" { - // Dont need to add a label. + // Don't need to add a label. return labels } if labels == nil { @@ -110,7 +110,7 @@ func CloneSelectorAndAddLabel(selector *unversioned.LabelSelector, labelKey stri // AddLabelToSelector returns a selector with the given key and value added to the given selector's MatchLabels. func AddLabelToSelector(selector *unversioned.LabelSelector, labelKey string, labelValue string) *unversioned.LabelSelector { if labelKey == "" { - // Dont need to add a label. + // Don't need to add a label. return selector } if selector.MatchLabels == nil { diff --git a/vendor/k8s.io/kubernetes/pkg/util/net/sets/README.md b/vendor/k8s.io/kubernetes/pkg/util/net/sets/README.md new file mode 100644 index 0000000..b0f238a --- /dev/null +++ b/vendor/k8s.io/kubernetes/pkg/util/net/sets/README.md @@ -0,0 +1,17 @@ +This package contains hand-coded set implementations that should be similar to +the autogenerated ones in `pkg/util/sets`. + +We can't simply use net.IPNet as a map-key in Go (because it contains a +`[]byte`). + +We could use the same workaround we use here (a string representation as the +key) to autogenerate sets. If we do that, or decide on an alternate approach, +we should replace the implementations in this package with the autogenerated +versions. + +It is expected that callers will alias this import as `netsets` +i.e. `import netsets "k8s.io/kubernetes/pkg/util/net/sets"` + + + +[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/pkg/util/net/sets/README.md?pixel)]() diff --git a/vendor/k8s.io/kubernetes/pkg/util/net/sets/ipnet.go b/vendor/k8s.io/kubernetes/pkg/util/net/sets/ipnet.go new file mode 100644 index 0000000..db117f6 --- /dev/null +++ b/vendor/k8s.io/kubernetes/pkg/util/net/sets/ipnet.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 sets + +import ( + "net" + "strings" +) + +type IPNet map[string]*net.IPNet + +func ParseIPNets(specs ...string) (IPNet, error) { + ipnetset := make(IPNet) + for _, spec := range specs { + spec = strings.TrimSpace(spec) + _, ipnet, err := net.ParseCIDR(spec) + if err != nil { + return nil, err + } + k := ipnet.String() // In case of normalization + ipnetset[k] = ipnet + } + return ipnetset, nil +} + +// Insert adds items to the set. +func (s IPNet) Insert(items ...*net.IPNet) { + for _, item := range items { + s[item.String()] = item + } +} + +// Delete removes all items from the set. +func (s IPNet) Delete(items ...*net.IPNet) { + for _, item := range items { + delete(s, item.String()) + } +} + +// Has returns true if and only if item is contained in the set. +func (s IPNet) Has(item *net.IPNet) bool { + _, contained := s[item.String()] + return contained +} + +// HasAll returns true if and only if all items are contained in the set. +func (s IPNet) HasAll(items ...*net.IPNet) bool { + for _, item := range items { + if !s.Has(item) { + return false + } + } + return true +} + +// Difference returns a set of objects that are not in s2 +// For example: +// s1 = {a1, a2, a3} +// s2 = {a1, a2, a4, a5} +// s1.Difference(s2) = {a3} +// s2.Difference(s1) = {a4, a5} +func (s IPNet) Difference(s2 IPNet) IPNet { + result := make(IPNet) + for k, i := range s { + _, found := s2[k] + if found { + continue + } + result[k] = i + } + return result +} + +// StringSlice returns a []string with the String representation of each element in the set. +// Order is undefined. +func (s IPNet) StringSlice() []string { + a := make([]string, 0, len(s)) + for k := range s { + a = append(a, k) + } + return a +} + +// IsSuperset returns true if and only if s1 is a superset of s2. +func (s1 IPNet) IsSuperset(s2 IPNet) bool { + for k := range s2 { + _, found := s1[k] + if !found { + return false + } + } + return true +} + +// Equal returns true if and only if s1 is equal (as a set) to s2. +// Two sets are equal if their membership is identical. +// (In practice, this means same elements, order doesn't matter) +func (s1 IPNet) Equal(s2 IPNet) bool { + return len(s1) == len(s2) && s1.IsSuperset(s2) +} + +// Len returns the size of the set. +func (s IPNet) Len() int { + return len(s) +} diff --git a/vendor/k8s.io/kubernetes/pkg/util/pod/pod.go b/vendor/k8s.io/kubernetes/pkg/util/pod/pod.go index 576b0cd..8fb5cad 100644 --- a/vendor/k8s.io/kubernetes/pkg/util/pod/pod.go +++ b/vendor/k8s.io/kubernetes/pkg/util/pod/pod.go @@ -17,10 +17,18 @@ limitations under the License. package pod import ( + "fmt" "hash/adler32" + "time" + + "github.com/golang/glog" "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/errors" + unversionedcore "k8s.io/kubernetes/pkg/client/typed/generated/core/unversioned" + errorsutil "k8s.io/kubernetes/pkg/util/errors" hashutil "k8s.io/kubernetes/pkg/util/hash" + "k8s.io/kubernetes/pkg/util/wait" ) func GetPodTemplateSpecHash(template api.PodTemplateSpec) uint32 { @@ -28,3 +36,54 @@ func GetPodTemplateSpecHash(template api.PodTemplateSpec) uint32 { hashutil.DeepHashObject(podTemplateSpecHasher, template) return podTemplateSpecHasher.Sum32() } + +// TODO: use client library instead when it starts to support update retries +// see https://github.com/kubernetes/kubernetes/issues/21479 +type updatePodFunc func(pod *api.Pod) error + +// UpdatePodWithRetries updates a pod with given applyUpdate function. Note that pod not found error is ignored. +// The returned bool value can be used to tell if the pod is actually updated. +func UpdatePodWithRetries(podClient unversionedcore.PodInterface, pod *api.Pod, applyUpdate updatePodFunc) (*api.Pod, bool, error) { + var err error + var podUpdated bool + oldPod := pod + if err = wait.Poll(10*time.Millisecond, 1*time.Minute, func() (bool, error) { + pod, err = podClient.Get(oldPod.Name) + if err != nil { + return false, err + } + // Apply the update, then attempt to push it to the apiserver. + if err = applyUpdate(pod); err != nil { + return false, err + } + if pod, err = podClient.Update(pod); err == nil { + // Update successful. + return true, nil + } + // TODO: don't retry on perm-failed errors and handle them gracefully + // Update could have failed due to conflict error. Try again. + return false, nil + }); err == nil { + // When there's no error, we've updated this pod. + podUpdated = true + } + + // Handle returned error from wait poll + if err == wait.ErrWaitTimeout { + err = fmt.Errorf("timed out trying to update pod: %+v", oldPod) + } + // Ignore the pod not found error, but the pod isn't updated. + if errors.IsNotFound(err) { + glog.V(4).Infof("%s %s/%s is not found, skip updating it.", oldPod.Kind, oldPod.Namespace, oldPod.Name) + err = nil + } + // Ignore the precondition violated error, but the pod isn't updated. + if err == errorsutil.ErrPreconditionViolated { + glog.V(4).Infof("%s %s/%s precondition doesn't hold, skip updating it.", oldPod.Kind, oldPod.Namespace, oldPod.Name) + err = nil + } + + // If the error is non-nil the returned pod cannot be trusted; if podUpdated is false, the pod isn't updated; + // if the error is nil and podUpdated is true, the returned pod contains the applied update. + return pod, podUpdated, err +} diff --git a/vendor/k8s.io/kubernetes/pkg/util/runtime/runtime.go b/vendor/k8s.io/kubernetes/pkg/util/runtime/runtime.go index 76d7cb4..32b1c71 100644 --- a/vendor/k8s.io/kubernetes/pkg/util/runtime/runtime.go +++ b/vendor/k8s.io/kubernetes/pkg/util/runtime/runtime.go @@ -76,3 +76,14 @@ func HandleError(err error) { func logError(err error) { glog.ErrorDepth(2, err) } + +// GetCaller returns the caller of the function that calls it. +func GetCaller() string { + var pc [1]uintptr + runtime.Callers(3, pc[:]) + f := runtime.FuncForPC(pc[0]) + if f == nil { + return fmt.Sprintf("Unable to find caller") + } + return f.Name() +} diff --git a/vendor/k8s.io/kubernetes/pkg/version/base.go b/vendor/k8s.io/kubernetes/pkg/version/base.go index e00792d..0cf1993 100644 --- a/vendor/k8s.io/kubernetes/pkg/version/base.go +++ b/vendor/k8s.io/kubernetes/pkg/version/base.go @@ -39,8 +39,8 @@ var ( // them irrelevant. (Next we'll take it out, which may muck with // scripts consuming the kubectl version output - but most of // these should be looking at gitVersion already anyways.) - gitMajor string = "" // major version, always numeric - gitMinor string = "" // minor version, numeric possibly followed by "+" + gitMajor string = "1" // major version, always numeric + gitMinor string = "2" // minor version, numeric possibly followed by "+" // semantic version, dervied by build scripts (see // https://github.com/kubernetes/kubernetes/blob/master/docs/design/versioning.md @@ -51,7 +51,7 @@ var ( // semantic version is a git hash, but the version itself is no // longer the direct output of "git describe", but a slight // translation to be semver compliant. - gitVersion string = "v0.0.0-master+$Format:%h$" + gitVersion string = "v1.2.0+$Format:%h$" gitCommit string = "$Format:%H$" // sha1 from git, output of $(git rev-parse HEAD) gitTreeState string = "not a git tree" // state of git tree, either "clean" or "dirty" ) diff --git a/vendor/rsprd.com/localkube/LICENSE b/vendor/rsprd.com/localkube/LICENSE new file mode 100644 index 0000000..5352658 --- /dev/null +++ b/vendor/rsprd.com/localkube/LICENSE @@ -0,0 +1,191 @@ + + Apache License + Version 2.0, January 2004 + https://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + Copyright 2016 Redspread, Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/vendor/rsprd.com/localkube/pkg/localkubectl/context.go b/vendor/rsprd.com/localkube/pkg/localkubectl/context.go new file mode 100644 index 0000000..2d13332 --- /dev/null +++ b/vendor/rsprd.com/localkube/pkg/localkubectl/context.go @@ -0,0 +1,83 @@ +package localkubectl + +import ( + "fmt" + + kubecfg "k8s.io/kubernetes/pkg/client/unversioned/clientcmd/api" + kubectlcfg "k8s.io/kubernetes/pkg/kubectl/cmd/config" +) + +// getConfig gets the kubectl client configuration using defaults +func getConfig(pathOpts *kubectlcfg.PathOptions) (*kubecfg.Config, error) { + config, err := pathOpts.GetStartingConfig() + if err != nil { + return nil, fmt.Errorf("could not get config: %v", err) + } + + return config, nil +} + +// SetupContext creates a new cluster and context in ~/.kube using the provided API Server. If setCurrent is true, it is made the current context. +func SetupContext(clusterName, contextName, kubeAPIServer string, setCurrent bool) error { + pathOpts := kubectlcfg.NewDefaultPathOptions() + config, err := getConfig(pathOpts) + if err != nil { + return err + } + + cluster, exists := config.Clusters[clusterName] + if !exists { + cluster = kubecfg.NewCluster() + } + + // configure cluster + cluster.Server = kubeAPIServer + cluster.InsecureSkipTLSVerify = true + config.Clusters[clusterName] = cluster + + context, exists := config.Contexts[contextName] + if !exists { + context = kubecfg.NewContext() + } + + // configure context + context.Cluster = clusterName + config.Contexts[contextName] = context + + // set as current if requested + if setCurrent { + config.CurrentContext = contextName + } + + return kubectlcfg.ModifyConfig(pathOpts, *config, true) +} + +// GetCurrentContext returns the context currently being used by kubectl +func GetCurrentContext() (string, error) { + pathOpts := kubectlcfg.NewDefaultPathOptions() + config, err := getConfig(pathOpts) + if err != nil { + return "", err + } + + return config.CurrentContext, nil +} + +// SetCurrentContext changes the kubectl context to the given value +func SetCurrentContext(context string) error { + pathOpts := kubectlcfg.NewDefaultPathOptions() + config, err := getConfig(pathOpts) + if err != nil { + return err + } + + config.CurrentContext = context + return kubectlcfg.ModifyConfig(pathOpts, *config, true) +} + +// SwitchContextInstructions returns instructions about how to switch kubectl to use the given context +func SwitchContextInstructions(contextName string) string { + l1 := "To setup kubectl to use localkube run:\n" + l2 := fmt.Sprintf("kubectl config use-context %s\n", contextName) + return l1 + l2 +} diff --git a/vendor/rsprd.com/localkube/pkg/localkubectl/controller.go b/vendor/rsprd.com/localkube/pkg/localkubectl/controller.go new file mode 100644 index 0000000..04aab1b --- /dev/null +++ b/vendor/rsprd.com/localkube/pkg/localkubectl/controller.go @@ -0,0 +1,219 @@ +package localkubectl + +import ( + "errors" + "fmt" + "io" + "log" + "strings" + + "github.com/docker/docker/pkg/jsonmessage" + "github.com/docker/docker/pkg/term" + docker "github.com/fsouza/go-dockerclient" +) + +var ( + // LocalkubeLabel is the label that identifies localkube containers + LocalkubeLabel = "rsprd.com/name=localkube" + + // LocalkubeContainerName is the name of the container that localkube runs in + LocalkubeContainerName = "localkube" + + // LocalkubeImageName is the image of localkube that is started + LocalkubeImageName = "redspreadapps/localkube" + + // ContainerDataDir is the path inside the container for etcd data + ContainerDataDir = "/var/localkube/data" + + // RedspreadName is a Redspread specific identifier for Name + RedspreadName = "rsprd.com/name" +) + +// Controller provides a wrapper around the Docker client for easy control of localkube. +type Controller struct { + *docker.Client + log *log.Logger + out io.Writer +} + +// NewController returns a localkube Docker client from a created *docker.Client +func NewController(client *docker.Client, out io.Writer) (*Controller, error) { + _, err := client.Version() + if err != nil { + return nil, fmt.Errorf("Unable to establish connection with Docker daemon: %v", err) + } + + logger := log.New(out, "", 0) + + return &Controller{ + Client: client, + log: logger, + out: out, + }, nil +} + +// NewControllerFromEnv creates a new Docker client using environment clues. +func NewControllerFromEnv(out io.Writer) (*Controller, error) { + client, err := docker.NewClientFromEnv() + if err != nil { + return nil, fmt.Errorf("could not create Docker client: %v", err) + } + + return NewController(client, out) +} + +// ListLocalkubeCtrs returns a list of localkube containers on this Docker daemon. If a is true only non-running containers will also be displayed +func (d *Controller) ListLocalkubeCtrs(all bool) ([]docker.APIContainers, error) { + ctrs, err := d.ListContainers(docker.ListContainersOptions{ + All: all, + Filters: map[string][]string{ + "label": {LocalkubeLabel}, + }, + }) + + if err != nil { + return nil, fmt.Errorf("could not list containers: %v", err) + } + + return ctrs, nil +} + +// OnlyLocalkubeCtr returns the localkube container. If there are multiple possible containers an error is returned +func (d *Controller) OnlyLocalkubeCtr() (ctrId string, running bool, err error) { + ctrs, err := d.ListLocalkubeCtrs(true) + if err != nil { + return "", false, err + } else if len(ctrs) < 1 { + return "", false, ErrNoContainer + } else if len(ctrs) > 1 { + return "", false, ErrTooManyLocalkubes + } + + ctr := ctrs[0] + return ctr.ID, runningStatus(ctr.Status), nil +} + +// CreateCtr creates the localkube container. The image is pulled if it doesn't already exist. +func (d *Controller) CreateCtr(name, imageTag string) (ctrId string, running bool, err error) { + image := fmt.Sprintf("%s:%s", LocalkubeImageName, imageTag) + ctrOpts := docker.CreateContainerOptions{ + Name: name, + Config: &docker.Config{ + Hostname: name, + Image: image, + Env: []string{ + fmt.Sprintf("KUBE_ETCD_DATA_DIRECTORY=%s", ContainerDataDir), + }, + Labels: map[string]string{ + RedspreadName: name, + }, + StopSignal: "SIGINT", + }, + } + + d.log.Println("Creating localkube container...") + ctr, err := d.CreateContainer(ctrOpts) + if err != nil { + if err == docker.ErrNoSuchImage { + // if image does not exist, pull it + d.log.Printf("Localkube image '%s' not found, pulling now:\n", image) + if pullErr := d.PullImage(imageTag, false); pullErr != nil { + return "", false, pullErr + } + return d.CreateCtr(name, imageTag) + } + return "", false, fmt.Errorf("could not create locakube container: %v", err) + } + return ctr.ID, ctr.State.Running, nil +} + +// PullImage will pull the localkube image on the connected Docker daemon +func (d *Controller) PullImage(imageTag string, silent bool) error { + pullOpts := docker.PullImageOptions{ + Repository: LocalkubeImageName, + Tag: imageTag, + } + + in, out := io.Pipe() + // print pull progress if not silent + if !silent { + pullOpts.RawJSONStream = true + pullOpts.OutputStream = out + outFd, isTerminal := term.GetFdInfo(d.out) + go jsonmessage.DisplayJSONMessagesStream(in, d.out, outFd, isTerminal) + } + + err := d.Client.PullImage(pullOpts, docker.AuthConfiguration{}) + if err != nil { + return fmt.Errorf("failed to pull localkube image: %v", err) + } + return nil +} + +// StartCtr starts the specified Container with options specific to localkube. If etcdDataDir is empty, no directory will be mounted for etcd. +func (d *Controller) StartCtr(ctrId, etcdDataDir string) error { + binds := []string{ + "/sys:/sys:rw", + "/var/lib/docker:/var/lib/docker", + "/mnt/sda1/var/lib/docker:/mnt/sda1/var/lib/docker", + "/var/lib/kubelet:/var/lib/kubelet", + "/var/run:/var/run:rw", + "/:/rootfs:ro", + } + + // if provided mount etcd data dir + if len(etcdDataDir) != 0 { + dataBind := fmt.Sprintf("%s:%s", etcdDataDir, ContainerDataDir) + binds = append(binds, dataBind) + } + + hostCfg := &docker.HostConfig{ + Binds: binds, + RestartPolicy: docker.AlwaysRestart(), + NetworkMode: "host", + PidMode: "host", + Privileged: true, + } + + d.log.Println("Starting localkube container...") + err := d.StartContainer(ctrId, hostCfg) + if err != nil { + return fmt.Errorf("could not start container `%s`: %v", ctrId, err) + } + return nil +} + +// StopCtr stops the container with the given id. If delete is true, deletes container after stopping. +func (d *Controller) StopCtr(ctrId string, remove bool) error { + d.log.Printf("Stopping container '%s'\n", ctrId) + err := d.StopContainer(ctrId, 5) + if err != nil && !remove { + return fmt.Errorf("unable to stop localkube container: %v", err) + } + + if remove { + removeCtrOpts := docker.RemoveContainerOptions{ + ID: ctrId, + } + + d.log.Printf("Removing container '%s'\n", ctrId) + err = d.RemoveContainer(removeCtrOpts) + if err != nil { + return fmt.Errorf("unable to remove localkube container: %v", err) + } + } + return nil +} + +// runningStatus returns true if a Docker status string indicates the container is running +func runningStatus(status string) bool { + return strings.HasPrefix(status, "Up") +} + +var ( + // ErrNoContainer is returned when the localkube container hasn't been created yet + ErrNoContainer = errors.New("localkube container doesn't exist") + + // ErrTooManyLocalkubes is returned when there are more than one localkube containers on the Docker daemon + ErrTooManyLocalkubes = errors.New("multiple localkube containers have been started") +) diff --git a/vendor/rsprd.com/localkube/pkg/localkubectl/localkubectl.go b/vendor/rsprd.com/localkube/pkg/localkubectl/localkubectl.go new file mode 100644 index 0000000..5d8811c --- /dev/null +++ b/vendor/rsprd.com/localkube/pkg/localkubectl/localkubectl.go @@ -0,0 +1,171 @@ +// Package localkubectl allows the lifecycle of the localkube container to be controlled +package localkubectl + +import ( + "fmt" + "io" + "log" + "strings" + + "github.com/codegangsta/cli" + "github.com/mitchellh/go-homedir" +) + +var ( + // DefaultHostDataDir is the directory on the host which is mounted for localkube data if no directory is specified + DefaultHostDataDir = "~/.localkube/data" + + // LocalkubeDefaultTag is the tag to use for the localkube image + LocalkubeDefaultTag = "latest" + + // LocalkubeClusterName is the name the cluster configuration is stored under + LocalkubeClusterName = "localkube" + + // LocalkubeContext is the name of the context used by localkube + LocalkubeContext = "localkube" +) + +// Command returns a Command with subcommands for starting and stopping a localkube cluster +func Command(out io.Writer) *cli.Command { + l := log.New(out, "", 0) + return &cli.Command{ + Name: "cluster", + Description: "Manages localkube Kubernetes development environment", + Subcommands: []cli.Command{ + { + Name: "start", + Usage: "spread cluster start [-t ] [ClusterDataDirectory]", + Description: "Starts the localkube cluster", + ArgsUsage: "-t specifies localkube image tag to use, default is latest", + Action: func(c *cli.Context) { + // create new Docker client + ctlr, err := NewControllerFromEnv(out) + if err != nil { + l.Fatal(err) + } + + // create (if needed) and start localkube container + err = startCluster(ctlr, l, c) + if err != nil { + l.Fatalf("could not start localkube: %v", err) + } + + // guess which IP the API server will be on + host, err := identifyHost(ctlr.Endpoint()) + if err != nil { + l.Fatal(err) + } + + // use default port + host = fmt.Sprintf("%s:8080", host) + + // setup localkube kubectl context + currentContext, err := GetCurrentContext() + if err != nil { + l.Fatal(err) + } + + // set as current if no CurrentContext is set + setCurrent := (len(currentContext) == 0) + + err = SetupContext(LocalkubeClusterName, LocalkubeContext, host, setCurrent) + if err != nil { + l.Fatal(err) + } + + // display help text messages if context change + if setCurrent { + l.Printf("Created `%s` context and set it as current.\n", LocalkubeContext) + } else if currentContext != LocalkubeContext { + l.Println(SwitchContextInstructions(LocalkubeContext)) + } + }, + }, + { + Name: "stop", + Usage: "spread cluster stop [-r]", + Description: "Stops the localkube cluster", + ArgsUsage: "-r removes container", + Action: func(c *cli.Context) { + ctlr, err := NewControllerFromEnv(out) + if err != nil { + l.Fatal(err) + } + + remove := c.Bool("r") + + ctrs, err := ctlr.ListLocalkubeCtrs(true) + if err != nil { + l.Fatal(err) + } + + for _, ctr := range ctrs { + if remove || runningStatus(ctr.Status) { + ctlr.StopCtr(ctr.ID, remove) + } + } + }, + }, + }, + } +} + +// startCluster configures and starts a cluster using command line parameters +func startCluster(ctlr *Controller, log *log.Logger, c *cli.Context) error { + var err error + + // set data directory + dataDir := c.Args().First() + if len(dataDir) == 0 { + dataDir, err = homedir.Expand(DefaultHostDataDir) + if err != nil { + return fmt.Errorf("Unable to expand home directory: %v", err) + } + } + + // set tag + tag := c.String("t") + if len(tag) == 0 { + tag = LocalkubeDefaultTag + } + + // check if localkube container exists + ctrId, running, err := ctlr.OnlyLocalkubeCtr() + if err != nil { + if err == ErrNoContainer { + // if container doesn't exist, create + ctrId, running, err = ctlr.CreateCtr(LocalkubeContainerName, tag) + if err != nil { + return err + } + } else { + // stop for all other errors + return err + } + } + + // start container if not running + if !running { + err = ctlr.StartCtr(ctrId, dataDir) + if err != nil { + return err + } + } else { + log.Println("Localkube is already running") + } + return nil +} + +func identifyHost(endpoint string) (string, error) { + beginPort := strings.LastIndex(endpoint, ":") + switch { + // if using TCP use provided host + case strings.HasPrefix(endpoint, "tcp://"): + return endpoint[6:beginPort], nil + // assuming localhost if Unix + // TODO: Make this customizable + case strings.HasPrefix(endpoint, "unix://"): + return "127.0.0.1", nil + } + return "", fmt.Errorf("Could not determine localkube API server from endpoint `%s`", endpoint) +}