Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
K
k3s
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Jacklull
k3s
Commits
b1e389e6
Commit
b1e389e6
authored
Mar 12, 2019
by
Hannes Hoerl
Browse files
Options
Browse Files
Download
Plain Diff
Merge remote-tracking branch 'origin/master' into release-1.14
parents
9ef24c9b
a213886f
Hide whitespace changes
Inline
Side-by-side
Showing
57 changed files
with
906 additions
and
122 deletions
+906
-122
config-default.sh
cluster/gce/config-default.sh
+8
-0
config-test.sh
cluster/gce/config-test.sh
+8
-0
configure-helper.sh
cluster/gce/gci/configure-helper.sh
+15
-0
cluster-autoscaler.manifest
cluster/gce/manifests/cluster-autoscaler.manifest
+1
-1
main.go
cmd/hyperkube/main.go
+1
-0
BUILD
cmd/kube-apiserver/app/BUILD
+1
-0
aggregator.go
cmd/kube-apiserver/app/aggregator.go
+2
-0
apiextensions.go
cmd/kube-apiserver/app/apiextensions.go
+3
-0
init.go
cmd/kubeadm/app/cmd/init.go
+5
-0
data.go
cmd/kubeadm/app/cmd/phases/init/data.go
+1
-0
data_test.go
cmd/kubeadm/app/cmd/phases/init/data_test.go
+1
-0
uploadcerts.go
cmd/kubeadm/app/cmd/phases/init/uploadcerts.go
+5
-2
copycerts.go
cmd/kubeadm/app/phases/copycerts/copycerts.go
+1
-1
pod_manager.go
pkg/kubelet/pod/pod_manager.go
+26
-6
cache_based_manager_test.go
pkg/kubelet/util/manager/cache_based_manager_test.go
+36
-1
manager.go
pkg/kubelet/util/manager/manager.go
+4
-0
BUILD
pkg/master/BUILD
+11
-0
master_test.go
pkg/master/master_test.go
+125
-1
BUILD
pkg/master/storageversionhashdata/BUILD
+23
-0
OWNERS
pkg/master/storageversionhashdata/OWNERS
+4
-0
data.go
pkg/master/storageversionhashdata/data.go
+111
-0
storage.go
pkg/registry/core/namespace/storage/storage.go
+6
-0
rest.go
pkg/registry/core/service/storage/rest.go
+9
-3
rest_test.go
pkg/registry/core/service/storage/rest_test.go
+4
-0
storage.go
pkg/registry/rbac/clusterrole/policybased/storage.go
+10
-0
storage.go
pkg/registry/rbac/clusterrolebinding/policybased/storage.go
+10
-0
storage.go
pkg/registry/rbac/role/policybased/storage.go
+10
-0
storage.go
pkg/registry/rbac/rolebinding/policybased/storage.go
+10
-0
BUILD
pkg/util/mount/BUILD
+3
-1
mount_helper_common.go
pkg/util/mount/mount_helper_common.go
+0
-21
mount_helper_unix.go
pkg/util/mount/mount_helper_unix.go
+44
-0
mount_helper_windows.go
pkg/util/mount/mount_helper_windows.go
+68
-0
mount_windows.go
pkg/util/mount/mount_windows.go
+6
-5
csi_block.go
pkg/volume/csi/csi_block.go
+17
-5
csi_client.go
pkg/volume/csi/csi_client.go
+34
-0
csi_mounter.go
pkg/volume/csi/csi_mounter.go
+11
-3
csi_plugin.go
pkg/volume/csi/csi_plugin.go
+4
-16
csi_plugin_test.go
pkg/volume/csi/csi_plugin_test.go
+11
-6
quobyte.go
pkg/volume/quobyte/quobyte.go
+1
-0
customresource_discovery_controller.go
...rver/pkg/apiserver/customresource_discovery_controller.go
+12
-7
BUILD
staging/src/k8s.io/apiserver/pkg/endpoints/discovery/BUILD
+1
-0
storageversionhash.go
...o/apiserver/pkg/endpoints/discovery/storageversionhash.go
+40
-0
installer.go
staging/src/k8s.io/apiserver/pkg/endpoints/installer.go
+27
-0
kube_features.go
staging/src/k8s.io/apiserver/pkg/features/kube_features.go
+8
-0
store.go
...c/k8s.io/apiserver/pkg/registry/generic/registry/store.go
+11
-0
rest.go
staging/src/k8s.io/apiserver/pkg/registry/rest/rest.go
+9
-0
storage_codec.go
.../src/k8s.io/apiserver/pkg/server/storage/storage_codec.go
+11
-9
storage_factory.go
...rc/k8s.io/apiserver/pkg/server/storage/storage_factory.go
+2
-2
config.go
...src/k8s.io/apiserver/pkg/storage/storagebackend/config.go
+5
-0
retrywatcher.go
staging/src/k8s.io/client-go/tools/watch/retrywatcher.go
+5
-1
BUILD
staging/src/k8s.io/sample-apiserver/pkg/cmd/server/BUILD
+3
-0
start.go
staging/src/k8s.io/sample-apiserver/pkg/cmd/server/start.go
+5
-1
BUILD
test/e2e/apimachinery/BUILD
+2
-0
discovery.go
test/e2e/apimachinery/discovery.go
+78
-0
node_lease.go
test/e2e/common/node_lease.go
+35
-28
Dockerfile
test/images/audit-proxy/Dockerfile
+1
-1
VERSION
test/images/audit-proxy/VERSION
+1
-1
No files found.
cluster/gce/config-default.sh
View file @
b1e389e6
...
@@ -413,6 +413,14 @@ if [[ -n "${LOGROTATE_MAX_SIZE:-}" ]]; then
...
@@ -413,6 +413,14 @@ if [[ -n "${LOGROTATE_MAX_SIZE:-}" ]]; then
PROVIDER_VARS
=
"
${
PROVIDER_VARS
:-}
LOGROTATE_MAX_SIZE"
PROVIDER_VARS
=
"
${
PROVIDER_VARS
:-}
LOGROTATE_MAX_SIZE"
fi
fi
if
[[
-n
"
${
POD_LOG_MAX_FILE
:-}
"
]]
;
then
PROVIDER_VARS
=
"
${
PROVIDER_VARS
:-}
POD_LOG_MAX_FILE"
fi
if
[[
-n
"
${
POD_LOG_MAX_SIZE
:-}
"
]]
;
then
PROVIDER_VARS
=
"
${
PROVIDER_VARS
:-}
POD_LOG_MAX_SIZE"
fi
# Fluentd requirements
# Fluentd requirements
# YAML exists to trigger a configuration refresh when changes are made.
# YAML exists to trigger a configuration refresh when changes are made.
FLUENTD_GCP_YAML_VERSION
=
"v3.2.0"
FLUENTD_GCP_YAML_VERSION
=
"v3.2.0"
...
...
cluster/gce/config-test.sh
View file @
b1e389e6
...
@@ -432,6 +432,14 @@ if [[ -n "${LOGROTATE_MAX_SIZE:-}" ]]; then
...
@@ -432,6 +432,14 @@ if [[ -n "${LOGROTATE_MAX_SIZE:-}" ]]; then
PROVIDER_VARS
=
"
${
PROVIDER_VARS
:-}
LOGROTATE_MAX_SIZE"
PROVIDER_VARS
=
"
${
PROVIDER_VARS
:-}
LOGROTATE_MAX_SIZE"
fi
fi
if
[[
-n
"
${
POD_LOG_MAX_FILE
:-}
"
]]
;
then
PROVIDER_VARS
=
"
${
PROVIDER_VARS
:-}
POD_LOG_MAX_FILE"
fi
if
[[
-n
"
${
POD_LOG_MAX_SIZE
:-}
"
]]
;
then
PROVIDER_VARS
=
"
${
PROVIDER_VARS
:-}
POD_LOG_MAX_SIZE"
fi
# Fluentd requirements
# Fluentd requirements
# YAML exists to trigger a configuration refresh when changes are made.
# YAML exists to trigger a configuration refresh when changes are made.
FLUENTD_GCP_YAML_VERSION
=
"v3.2.0"
FLUENTD_GCP_YAML_VERSION
=
"v3.2.0"
...
...
cluster/gce/gci/configure-helper.sh
View file @
b1e389e6
...
@@ -374,6 +374,21 @@ function setup-logrotate() {
...
@@ -374,6 +374,21 @@ function setup-logrotate() {
}
}
EOF
EOF
# Configure log rotation for pod logs in /var/log/pods/NAMESPACE_NAME_UID.
cat
>
/etc/logrotate.d/allpodlogs
<<
EOF
/var/log/pods/*/*.log {
rotate
${
POD_LOG_MAX_FILE
:-
5
}
copytruncate
missingok
notifempty
compress
maxsize
${
POD_LOG_MAX_SIZE
:-
5M
}
daily
dateext
dateformat -%Y%m%d-%s
create 0644 root root
}
EOF
}
}
# Finds the master PD device; returns it in MASTER_PD_DEVICE
# Finds the master PD device; returns it in MASTER_PD_DEVICE
...
...
cluster/gce/manifests/cluster-autoscaler.manifest
View file @
b1e389e6
...
@@ -17,7 +17,7 @@
...
@@ -17,7 +17,7 @@
"containers": [
"containers": [
{
{
"name": "cluster-autoscaler",
"name": "cluster-autoscaler",
"image": "k8s.gcr.io/cluster-autoscaler:v1.1
3.0
",
"image": "k8s.gcr.io/cluster-autoscaler:v1.1
4.0-beta.1
",
"livenessProbe": {
"livenessProbe": {
"httpGet": {
"httpGet": {
"path": "/health-check",
"path": "/health-check",
...
...
cmd/hyperkube/main.go
View file @
b1e389e6
...
@@ -142,6 +142,7 @@ func NewHyperKubeCommand(stopCh <-chan struct{}) (*cobra.Command, []func() *cobr
...
@@ -142,6 +142,7 @@ func NewHyperKubeCommand(stopCh <-chan struct{}) (*cobra.Command, []func() *cobr
}
}
cmd
.
Flags
()
.
BoolVar
(
&
makeSymlinksFlag
,
"make-symlinks"
,
makeSymlinksFlag
,
"create a symlink for each server in current directory"
)
cmd
.
Flags
()
.
BoolVar
(
&
makeSymlinksFlag
,
"make-symlinks"
,
makeSymlinksFlag
,
"create a symlink for each server in current directory"
)
cmd
.
Flags
()
.
MarkHidden
(
"make-symlinks"
)
// hide this flag from appearing in servers' usage output
cmd
.
Flags
()
.
MarkHidden
(
"make-symlinks"
)
// hide this flag from appearing in servers' usage output
cmd
.
Flags
()
.
MarkDeprecated
(
"make-symlinks"
,
"This feature will be removed in a later release."
)
for
i
:=
range
commandFns
{
for
i
:=
range
commandFns
{
cmd
.
AddCommand
(
commandFns
[
i
]())
cmd
.
AddCommand
(
commandFns
[
i
]())
...
...
cmd/kube-apiserver/app/BUILD
View file @
b1e389e6
...
@@ -39,6 +39,7 @@ go_library(
...
@@ -39,6 +39,7 @@ go_library(
"//staging/src/k8s.io/apiextensions-apiserver/pkg/client/informers/internalversion:go_default_library",
"//staging/src/k8s.io/apiextensions-apiserver/pkg/client/informers/internalversion:go_default_library",
"//staging/src/k8s.io/apiextensions-apiserver/pkg/cmd/server/options:go_default_library",
"//staging/src/k8s.io/apiextensions-apiserver/pkg/cmd/server/options:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/errors:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/errors:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/net:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/net:go_default_library",
...
...
cmd/kube-apiserver/app/aggregator.go
View file @
b1e389e6
...
@@ -30,6 +30,7 @@ import (
...
@@ -30,6 +30,7 @@ import (
apiextensionsinformers
"k8s.io/apiextensions-apiserver/pkg/client/informers/internalversion"
apiextensionsinformers
"k8s.io/apiextensions-apiserver/pkg/client/informers/internalversion"
metav1
"k8s.io/apimachinery/pkg/apis/meta/v1"
metav1
"k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/apiserver/pkg/admission"
"k8s.io/apiserver/pkg/admission"
...
@@ -79,6 +80,7 @@ func createAggregatorConfig(
...
@@ -79,6 +80,7 @@ func createAggregatorConfig(
etcdOptions
:=
*
commandOptions
.
Etcd
etcdOptions
:=
*
commandOptions
.
Etcd
etcdOptions
.
StorageConfig
.
Paging
=
utilfeature
.
DefaultFeatureGate
.
Enabled
(
features
.
APIListChunking
)
etcdOptions
.
StorageConfig
.
Paging
=
utilfeature
.
DefaultFeatureGate
.
Enabled
(
features
.
APIListChunking
)
etcdOptions
.
StorageConfig
.
Codec
=
aggregatorscheme
.
Codecs
.
LegacyCodec
(
v1beta1
.
SchemeGroupVersion
,
v1
.
SchemeGroupVersion
)
etcdOptions
.
StorageConfig
.
Codec
=
aggregatorscheme
.
Codecs
.
LegacyCodec
(
v1beta1
.
SchemeGroupVersion
,
v1
.
SchemeGroupVersion
)
etcdOptions
.
StorageConfig
.
EncodeVersioner
=
runtime
.
NewMultiGroupVersioner
(
v1beta1
.
SchemeGroupVersion
,
schema
.
GroupKind
{
Group
:
v1beta1
.
GroupName
})
genericConfig
.
RESTOptionsGetter
=
&
genericoptions
.
SimpleRestOptionsFactory
{
Options
:
etcdOptions
}
genericConfig
.
RESTOptionsGetter
=
&
genericoptions
.
SimpleRestOptionsFactory
{
Options
:
etcdOptions
}
// override MergedResourceConfig with aggregator defaults and registry
// override MergedResourceConfig with aggregator defaults and registry
...
...
cmd/kube-apiserver/app/apiextensions.go
View file @
b1e389e6
...
@@ -23,6 +23,8 @@ import (
...
@@ -23,6 +23,8 @@ import (
"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1"
"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1"
apiextensionsapiserver
"k8s.io/apiextensions-apiserver/pkg/apiserver"
apiextensionsapiserver
"k8s.io/apiextensions-apiserver/pkg/apiserver"
apiextensionsoptions
"k8s.io/apiextensions-apiserver/pkg/cmd/server/options"
apiextensionsoptions
"k8s.io/apiextensions-apiserver/pkg/cmd/server/options"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apiserver/pkg/admission"
"k8s.io/apiserver/pkg/admission"
"k8s.io/apiserver/pkg/features"
"k8s.io/apiserver/pkg/features"
genericapiserver
"k8s.io/apiserver/pkg/server"
genericapiserver
"k8s.io/apiserver/pkg/server"
...
@@ -61,6 +63,7 @@ func createAPIExtensionsConfig(
...
@@ -61,6 +63,7 @@ func createAPIExtensionsConfig(
etcdOptions
:=
*
commandOptions
.
Etcd
etcdOptions
:=
*
commandOptions
.
Etcd
etcdOptions
.
StorageConfig
.
Paging
=
utilfeature
.
DefaultFeatureGate
.
Enabled
(
features
.
APIListChunking
)
etcdOptions
.
StorageConfig
.
Paging
=
utilfeature
.
DefaultFeatureGate
.
Enabled
(
features
.
APIListChunking
)
etcdOptions
.
StorageConfig
.
Codec
=
apiextensionsapiserver
.
Codecs
.
LegacyCodec
(
v1beta1
.
SchemeGroupVersion
)
etcdOptions
.
StorageConfig
.
Codec
=
apiextensionsapiserver
.
Codecs
.
LegacyCodec
(
v1beta1
.
SchemeGroupVersion
)
etcdOptions
.
StorageConfig
.
EncodeVersioner
=
runtime
.
NewMultiGroupVersioner
(
v1beta1
.
SchemeGroupVersion
,
schema
.
GroupKind
{
Group
:
v1beta1
.
GroupName
})
genericConfig
.
RESTOptionsGetter
=
&
genericoptions
.
SimpleRestOptionsFactory
{
Options
:
etcdOptions
}
genericConfig
.
RESTOptionsGetter
=
&
genericoptions
.
SimpleRestOptionsFactory
{
Options
:
etcdOptions
}
// override MergedResourceConfig with apiextensions defaults and registry
// override MergedResourceConfig with apiextensions defaults and registry
...
...
cmd/kubeadm/app/cmd/init.go
View file @
b1e389e6
...
@@ -379,6 +379,11 @@ func (d *initData) SetCertificateKey(key string) {
...
@@ -379,6 +379,11 @@ func (d *initData) SetCertificateKey(key string) {
d
.
certificateKey
=
key
d
.
certificateKey
=
key
}
}
// SkipCertificateKeyPrint returns the skipCertificateKeyPrint flag.
func
(
d
*
initData
)
SkipCertificateKeyPrint
()
bool
{
return
d
.
skipCertificateKeyPrint
}
// Cfg returns initConfiguration.
// Cfg returns initConfiguration.
func
(
d
*
initData
)
Cfg
()
*
kubeadmapi
.
InitConfiguration
{
func
(
d
*
initData
)
Cfg
()
*
kubeadmapi
.
InitConfiguration
{
return
d
.
cfg
return
d
.
cfg
...
...
cmd/kubeadm/app/cmd/phases/init/data.go
View file @
b1e389e6
...
@@ -30,6 +30,7 @@ type InitData interface {
...
@@ -30,6 +30,7 @@ type InitData interface {
UploadCerts
()
bool
UploadCerts
()
bool
CertificateKey
()
string
CertificateKey
()
string
SetCertificateKey
(
key
string
)
SetCertificateKey
(
key
string
)
SkipCertificateKeyPrint
()
bool
Cfg
()
*
kubeadmapi
.
InitConfiguration
Cfg
()
*
kubeadmapi
.
InitConfiguration
DryRun
()
bool
DryRun
()
bool
SkipTokenPrint
()
bool
SkipTokenPrint
()
bool
...
...
cmd/kubeadm/app/cmd/phases/init/data_test.go
View file @
b1e389e6
...
@@ -33,6 +33,7 @@ var _ InitData = &testInitData{}
...
@@ -33,6 +33,7 @@ var _ InitData = &testInitData{}
func
(
t
*
testInitData
)
UploadCerts
()
bool
{
return
false
}
func
(
t
*
testInitData
)
UploadCerts
()
bool
{
return
false
}
func
(
t
*
testInitData
)
CertificateKey
()
string
{
return
""
}
func
(
t
*
testInitData
)
CertificateKey
()
string
{
return
""
}
func
(
t
*
testInitData
)
SetCertificateKey
(
key
string
)
{}
func
(
t
*
testInitData
)
SetCertificateKey
(
key
string
)
{}
func
(
t
*
testInitData
)
SkipCertificateKeyPrint
()
bool
{
return
false
}
func
(
t
*
testInitData
)
Cfg
()
*
kubeadmapi
.
InitConfiguration
{
return
nil
}
func
(
t
*
testInitData
)
Cfg
()
*
kubeadmapi
.
InitConfiguration
{
return
nil
}
func
(
t
*
testInitData
)
DryRun
()
bool
{
return
false
}
func
(
t
*
testInitData
)
DryRun
()
bool
{
return
false
}
func
(
t
*
testInitData
)
SkipTokenPrint
()
bool
{
return
false
}
func
(
t
*
testInitData
)
SkipTokenPrint
()
bool
{
return
false
}
...
...
cmd/kubeadm/app/cmd/phases/init/uploadcerts.go
View file @
b1e389e6
...
@@ -21,7 +21,6 @@ import (
...
@@ -21,7 +21,6 @@ import (
"github.com/pkg/errors"
"github.com/pkg/errors"
"k8s.io/klog"
"k8s.io/kubernetes/cmd/kubeadm/app/cmd/options"
"k8s.io/kubernetes/cmd/kubeadm/app/cmd/options"
"k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases/workflow"
"k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases/workflow"
cmdutil
"k8s.io/kubernetes/cmd/kubeadm/app/cmd/util"
cmdutil
"k8s.io/kubernetes/cmd/kubeadm/app/cmd/util"
...
@@ -40,6 +39,7 @@ func NewUploadCertsPhase() workflow.Phase {
...
@@ -40,6 +39,7 @@ func NewUploadCertsPhase() workflow.Phase {
options
.
CfgPath
,
options
.
CfgPath
,
options
.
UploadCerts
,
options
.
UploadCerts
,
options
.
CertificateKey
,
options
.
CertificateKey
,
options
.
SkipCertificateKeyPrint
,
},
},
}
}
}
}
...
@@ -51,7 +51,7 @@ func runUploadCerts(c workflow.RunData) error {
...
@@ -51,7 +51,7 @@ func runUploadCerts(c workflow.RunData) error {
}
}
if
!
data
.
UploadCerts
()
{
if
!
data
.
UploadCerts
()
{
klog
.
V
(
1
)
.
Infoln
(
"[upload-certs] Skipping certs upload"
)
fmt
.
Printf
(
"[upload-certs] Skipping phase. Please see --%s
\n
"
,
options
.
UploadCerts
)
return
nil
return
nil
}
}
client
,
err
:=
data
.
Client
()
client
,
err
:=
data
.
Client
()
...
@@ -70,5 +70,8 @@ func runUploadCerts(c workflow.RunData) error {
...
@@ -70,5 +70,8 @@ func runUploadCerts(c workflow.RunData) error {
if
err
:=
copycerts
.
UploadCerts
(
client
,
data
.
Cfg
(),
data
.
CertificateKey
());
err
!=
nil
{
if
err
:=
copycerts
.
UploadCerts
(
client
,
data
.
Cfg
(),
data
.
CertificateKey
());
err
!=
nil
{
return
errors
.
Wrap
(
err
,
"error uploading certs"
)
return
errors
.
Wrap
(
err
,
"error uploading certs"
)
}
}
if
!
data
.
SkipCertificateKeyPrint
()
{
fmt
.
Printf
(
"[upload-certs] Using certificate key:
\n
%s
\n
"
,
data
.
CertificateKey
())
}
return
nil
return
nil
}
}
cmd/kubeadm/app/phases/copycerts/copycerts.go
View file @
b1e389e6
...
@@ -85,7 +85,7 @@ func CreateCertificateKey() (string, error) {
...
@@ -85,7 +85,7 @@ func CreateCertificateKey() (string, error) {
//UploadCerts save certs needs to join a new control-plane on kubeadm-certs sercret.
//UploadCerts save certs needs to join a new control-plane on kubeadm-certs sercret.
func
UploadCerts
(
client
clientset
.
Interface
,
cfg
*
kubeadmapi
.
InitConfiguration
,
key
string
)
error
{
func
UploadCerts
(
client
clientset
.
Interface
,
cfg
*
kubeadmapi
.
InitConfiguration
,
key
string
)
error
{
fmt
.
Printf
(
"[upload-certs]
s
toring the certificates in ConfigMap %q in the %q Namespace
\n
"
,
kubeadmconstants
.
KubeadmCertsSecret
,
metav1
.
NamespaceSystem
)
fmt
.
Printf
(
"[upload-certs]
S
toring the certificates in ConfigMap %q in the %q Namespace
\n
"
,
kubeadmconstants
.
KubeadmCertsSecret
,
metav1
.
NamespaceSystem
)
decodedKey
,
err
:=
hex
.
DecodeString
(
key
)
decodedKey
,
err
:=
hex
.
DecodeString
(
key
)
if
err
!=
nil
{
if
err
!=
nil
{
return
err
return
err
...
...
pkg/kubelet/pod/pod_manager.go
View file @
b1e389e6
...
@@ -168,20 +168,40 @@ func (pm *basicManager) UpdatePod(pod *v1.Pod) {
...
@@ -168,20 +168,40 @@ func (pm *basicManager) UpdatePod(pod *v1.Pod) {
}
}
}
}
func
isPodInTerminatedState
(
pod
*
v1
.
Pod
)
bool
{
return
pod
.
Status
.
Phase
==
v1
.
PodFailed
||
pod
.
Status
.
Phase
==
v1
.
PodSucceeded
}
// updatePodsInternal replaces the given pods in the current state of the
// updatePodsInternal replaces the given pods in the current state of the
// manager, updating the various indices. The caller is assumed to hold the
// manager, updating the various indices. The caller is assumed to hold the
// lock.
// lock.
func
(
pm
*
basicManager
)
updatePodsInternal
(
pods
...*
v1
.
Pod
)
{
func
(
pm
*
basicManager
)
updatePodsInternal
(
pods
...*
v1
.
Pod
)
{
for
_
,
pod
:=
range
pods
{
for
_
,
pod
:=
range
pods
{
if
pm
.
secretManager
!=
nil
{
if
pm
.
secretManager
!=
nil
{
// TODO: Consider detecting only status update and in such case do
if
isPodInTerminatedState
(
pod
)
{
// not register pod, as it doesn't really matter.
// Pods that are in terminated state and no longer running can be
pm
.
secretManager
.
RegisterPod
(
pod
)
// ignored as they no longer require access to secrets.
// It is especially important in watch-based manager, to avoid
// unnecessary watches for terminated pods waiting for GC.
pm
.
secretManager
.
UnregisterPod
(
pod
)
}
else
{
// TODO: Consider detecting only status update and in such case do
// not register pod, as it doesn't really matter.
pm
.
secretManager
.
RegisterPod
(
pod
)
}
}
}
if
pm
.
configMapManager
!=
nil
{
if
pm
.
configMapManager
!=
nil
{
// TODO: Consider detecting only status update and in such case do
if
isPodInTerminatedState
(
pod
)
{
// not register pod, as it doesn't really matter.
// Pods that are in terminated state and no longer running can be
pm
.
configMapManager
.
RegisterPod
(
pod
)
// ignored as they no longer require access to configmaps.
// It is especially important in watch-based manager, to avoid
// unnecessary watches for terminated pods waiting for GC.
pm
.
configMapManager
.
UnregisterPod
(
pod
)
}
else
{
// TODO: Consider detecting only status update and in such case do
// not register pod, as it doesn't really matter.
pm
.
configMapManager
.
RegisterPod
(
pod
)
}
}
}
podFullName
:=
kubecontainer
.
GetPodFullName
(
pod
)
podFullName
:=
kubecontainer
.
GetPodFullName
(
pod
)
// This logic relies on a static pod and its mirror to have the same name.
// This logic relies on a static pod and its mirror to have the same name.
...
...
pkg/kubelet/util/manager/cache_based_manager_test.go
View file @
b1e389e6
...
@@ -24,7 +24,7 @@ import (
...
@@ -24,7 +24,7 @@ import (
"testing"
"testing"
"time"
"time"
"k8s.io/api/core/v1"
v1
"k8s.io/api/core/v1"
apierrors
"k8s.io/apimachinery/pkg/api/errors"
apierrors
"k8s.io/apimachinery/pkg/api/errors"
metav1
"k8s.io/apimachinery/pkg/apis/meta/v1"
metav1
"k8s.io/apimachinery/pkg/apis/meta/v1"
...
@@ -429,6 +429,41 @@ func TestCacheInvalidation(t *testing.T) {
...
@@ -429,6 +429,41 @@ func TestCacheInvalidation(t *testing.T) {
fakeClient
.
ClearActions
()
fakeClient
.
ClearActions
()
}
}
func
TestRegisterIdempotence
(
t
*
testing
.
T
)
{
fakeClient
:=
&
fake
.
Clientset
{}
fakeClock
:=
clock
.
NewFakeClock
(
time
.
Now
())
store
:=
newSecretStore
(
fakeClient
,
fakeClock
,
noObjectTTL
,
time
.
Minute
)
manager
:=
newCacheBasedSecretManager
(
store
)
s1
:=
secretsToAttach
{
imagePullSecretNames
:
[]
string
{
"s1"
},
}
refs
:=
func
(
ns
,
name
string
)
int
{
store
.
lock
.
Lock
()
defer
store
.
lock
.
Unlock
()
item
,
ok
:=
store
.
items
[
objectKey
{
ns
,
name
}]
if
!
ok
{
return
0
}
return
item
.
refCount
}
manager
.
RegisterPod
(
podWithSecrets
(
"ns1"
,
"name1"
,
s1
))
assert
.
Equal
(
t
,
1
,
refs
(
"ns1"
,
"s1"
))
manager
.
RegisterPod
(
podWithSecrets
(
"ns1"
,
"name1"
,
s1
))
assert
.
Equal
(
t
,
1
,
refs
(
"ns1"
,
"s1"
))
manager
.
RegisterPod
(
podWithSecrets
(
"ns1"
,
"name2"
,
s1
))
assert
.
Equal
(
t
,
2
,
refs
(
"ns1"
,
"s1"
))
manager
.
UnregisterPod
(
podWithSecrets
(
"ns1"
,
"name1"
,
s1
))
assert
.
Equal
(
t
,
1
,
refs
(
"ns1"
,
"s1"
))
manager
.
UnregisterPod
(
podWithSecrets
(
"ns1"
,
"name1"
,
s1
))
assert
.
Equal
(
t
,
1
,
refs
(
"ns1"
,
"s1"
))
manager
.
UnregisterPod
(
podWithSecrets
(
"ns1"
,
"name2"
,
s1
))
assert
.
Equal
(
t
,
0
,
refs
(
"ns1"
,
"s1"
))
}
func
TestCacheRefcounts
(
t
*
testing
.
T
)
{
func
TestCacheRefcounts
(
t
*
testing
.
T
)
{
fakeClient
:=
&
fake
.
Clientset
{}
fakeClient
:=
&
fake
.
Clientset
{}
fakeClock
:=
clock
.
NewFakeClock
(
time
.
Now
())
fakeClock
:=
clock
.
NewFakeClock
(
time
.
Now
())
...
...
pkg/kubelet/util/manager/manager.go
View file @
b1e389e6
...
@@ -32,10 +32,14 @@ type Manager interface {
...
@@ -32,10 +32,14 @@ type Manager interface {
// i.e. should not block on network operations.
// i.e. should not block on network operations.
// RegisterPod registers all objects referenced from a given pod.
// RegisterPod registers all objects referenced from a given pod.
//
// NOTE: All implementations of RegisterPod should be idempotent.
RegisterPod
(
pod
*
v1
.
Pod
)
RegisterPod
(
pod
*
v1
.
Pod
)
// UnregisterPod unregisters objects referenced from a given pod that are not
// UnregisterPod unregisters objects referenced from a given pod that are not
// used by any other registered pod.
// used by any other registered pod.
//
// NOTE: All implementations of UnregisterPod should be idempotent.
UnregisterPod
(
pod
*
v1
.
Pod
)
UnregisterPod
(
pod
*
v1
.
Pod
)
}
}
...
...
pkg/master/BUILD
View file @
b1e389e6
...
@@ -141,10 +141,13 @@ go_test(
...
@@ -141,10 +141,13 @@ go_test(
deps = [
deps = [
"//pkg/api/legacyscheme:go_default_library",
"//pkg/api/legacyscheme:go_default_library",
"//pkg/api/testapi:go_default_library",
"//pkg/api/testapi:go_default_library",
"//pkg/apis/batch:go_default_library",
"//pkg/apis/core:go_default_library",
"//pkg/apis/core:go_default_library",
"//pkg/apis/storage:go_default_library",
"//pkg/generated/openapi:go_default_library",
"//pkg/generated/openapi:go_default_library",
"//pkg/kubelet/client:go_default_library",
"//pkg/kubelet/client:go_default_library",
"//pkg/master/reconcilers:go_default_library",
"//pkg/master/reconcilers:go_default_library",
"//pkg/master/storageversionhashdata:go_default_library",
"//pkg/registry/certificates/rest:go_default_library",
"//pkg/registry/certificates/rest:go_default_library",
"//pkg/registry/core/rest:go_default_library",
"//pkg/registry/core/rest:go_default_library",
"//pkg/registry/registrytest:go_default_library",
"//pkg/registry/registrytest:go_default_library",
...
@@ -154,16 +157,23 @@ go_test(
...
@@ -154,16 +157,23 @@ go_test(
"//staging/src/k8s.io/apimachinery/pkg/api/apitesting/naming:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/api/apitesting/naming:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/diff:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/diff:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/intstr:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/intstr:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/net:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/net:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/version:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/version:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/authorization/authorizerfactory:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/endpoints/openapi:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/endpoints/openapi:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/features:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/server:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/server:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/server/options:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/server/options:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/server/resourceconfig:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/server/storage:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/server/storage:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/storage/etcd/testing:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/storage/etcd/testing:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/util/feature/testing:go_default_library",
"//staging/src/k8s.io/client-go/discovery:go_default_library",
"//staging/src/k8s.io/client-go/informers:go_default_library",
"//staging/src/k8s.io/client-go/informers:go_default_library",
"//staging/src/k8s.io/client-go/kubernetes:go_default_library",
"//staging/src/k8s.io/client-go/kubernetes:go_default_library",
"//staging/src/k8s.io/client-go/kubernetes/fake:go_default_library",
"//staging/src/k8s.io/client-go/kubernetes/fake:go_default_library",
...
@@ -191,6 +201,7 @@ filegroup(
...
@@ -191,6 +201,7 @@ filegroup(
"//pkg/master/controller/crdregistration:all-srcs",
"//pkg/master/controller/crdregistration:all-srcs",
"//pkg/master/ports:all-srcs",
"//pkg/master/ports:all-srcs",
"//pkg/master/reconcilers:all-srcs",
"//pkg/master/reconcilers:all-srcs",
"//pkg/master/storageversionhashdata:all-srcs",
"//pkg/master/tunneler:all-srcs",
"//pkg/master/tunneler:all-srcs",
],
],
tags = ["automanaged"],
tags = ["automanaged"],
...
...
pkg/master/master_test.go
View file @
b1e389e6
...
@@ -31,22 +31,32 @@ import (
...
@@ -31,22 +31,32 @@ import (
certificatesapiv1beta1
"k8s.io/api/certificates/v1beta1"
certificatesapiv1beta1
"k8s.io/api/certificates/v1beta1"
apiv1
"k8s.io/api/core/v1"
apiv1
"k8s.io/api/core/v1"
metav1
"k8s.io/apimachinery/pkg/apis/meta/v1"
metav1
"k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime/schema"
utilnet
"k8s.io/apimachinery/pkg/util/net"
utilnet
"k8s.io/apimachinery/pkg/util/net"
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/apimachinery/pkg/version"
"k8s.io/apimachinery/pkg/version"
"k8s.io/apiserver/pkg/authorization/authorizerfactory"
"k8s.io/apiserver/pkg/features"
genericapiserver
"k8s.io/apiserver/pkg/server"
genericapiserver
"k8s.io/apiserver/pkg/server"
"k8s.io/apiserver/pkg/server/options"
"k8s.io/apiserver/pkg/server/options"
"k8s.io/apiserver/pkg/server/resourceconfig"
serverstorage
"k8s.io/apiserver/pkg/server/storage"
serverstorage
"k8s.io/apiserver/pkg/server/storage"
etcdtesting
"k8s.io/apiserver/pkg/storage/etcd/testing"
etcdtesting
"k8s.io/apiserver/pkg/storage/etcd/testing"
utilfeature
"k8s.io/apiserver/pkg/util/feature"
utilfeaturetesting
"k8s.io/apiserver/pkg/util/feature/testing"
"k8s.io/client-go/discovery"
"k8s.io/client-go/informers"
"k8s.io/client-go/informers"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/kubernetes/fake"
"k8s.io/client-go/kubernetes/fake"
restclient
"k8s.io/client-go/rest"
restclient
"k8s.io/client-go/rest"
"k8s.io/kubernetes/pkg/api/legacyscheme"
"k8s.io/kubernetes/pkg/api/legacyscheme"
"k8s.io/kubernetes/pkg/api/testapi"
"k8s.io/kubernetes/pkg/api/testapi"
"k8s.io/kubernetes/pkg/apis/batch"
api
"k8s.io/kubernetes/pkg/apis/core"
api
"k8s.io/kubernetes/pkg/apis/core"
apisstorage
"k8s.io/kubernetes/pkg/apis/storage"
kubeletclient
"k8s.io/kubernetes/pkg/kubelet/client"
kubeletclient
"k8s.io/kubernetes/pkg/kubelet/client"
"k8s.io/kubernetes/pkg/master/reconcilers"
"k8s.io/kubernetes/pkg/master/reconcilers"
"k8s.io/kubernetes/pkg/master/storageversionhashdata"
certificatesrest
"k8s.io/kubernetes/pkg/registry/certificates/rest"
certificatesrest
"k8s.io/kubernetes/pkg/registry/certificates/rest"
corerest
"k8s.io/kubernetes/pkg/registry/core/rest"
corerest
"k8s.io/kubernetes/pkg/registry/core/rest"
"k8s.io/kubernetes/pkg/registry/registrytest"
"k8s.io/kubernetes/pkg/registry/registrytest"
...
@@ -70,6 +80,14 @@ func setUp(t *testing.T) (*etcdtesting.EtcdTestServer, Config, *assert.Assertion
...
@@ -70,6 +80,14 @@ func setUp(t *testing.T) (*etcdtesting.EtcdTestServer, Config, *assert.Assertion
}
}
resourceEncoding
:=
serverstorage
.
NewDefaultResourceEncodingConfig
(
legacyscheme
.
Scheme
)
resourceEncoding
:=
serverstorage
.
NewDefaultResourceEncodingConfig
(
legacyscheme
.
Scheme
)
// This configures the testing master the same way the real master is
// configured. The storage versions of these resources are different
// from the storage versions of other resources in their group.
resourceEncodingOverrides
:=
[]
schema
.
GroupVersionResource
{
batch
.
Resource
(
"cronjobs"
)
.
WithVersion
(
"v1beta1"
),
apisstorage
.
Resource
(
"volumeattachments"
)
.
WithVersion
(
"v1beta1"
),
}
resourceEncoding
=
resourceconfig
.
MergeResourceEncodingConfigs
(
resourceEncoding
,
resourceEncodingOverrides
)
storageFactory
:=
serverstorage
.
NewDefaultStorageFactory
(
*
storageConfig
,
testapi
.
StorageMediaType
(),
legacyscheme
.
Codecs
,
resourceEncoding
,
DefaultAPIResourceConfigSource
(),
nil
)
storageFactory
:=
serverstorage
.
NewDefaultStorageFactory
(
*
storageConfig
,
testapi
.
StorageMediaType
(),
legacyscheme
.
Codecs
,
resourceEncoding
,
DefaultAPIResourceConfigSource
(),
nil
)
etcdOptions
:=
options
.
NewEtcdOptions
(
storageConfig
)
etcdOptions
:=
options
.
NewEtcdOptions
(
storageConfig
)
...
@@ -81,12 +99,12 @@ func setUp(t *testing.T) (*etcdtesting.EtcdTestServer, Config, *assert.Assertion
...
@@ -81,12 +99,12 @@ func setUp(t *testing.T) (*etcdtesting.EtcdTestServer, Config, *assert.Assertion
}
}
kubeVersion
:=
kubeversion
.
Get
()
kubeVersion
:=
kubeversion
.
Get
()
config
.
GenericConfig
.
Authorization
.
Authorizer
=
authorizerfactory
.
NewAlwaysAllowAuthorizer
()
config
.
GenericConfig
.
Version
=
&
kubeVersion
config
.
GenericConfig
.
Version
=
&
kubeVersion
config
.
ExtraConfig
.
StorageFactory
=
storageFactory
config
.
ExtraConfig
.
StorageFactory
=
storageFactory
config
.
GenericConfig
.
LoopbackClientConfig
=
&
restclient
.
Config
{
APIPath
:
"/api"
,
ContentConfig
:
restclient
.
ContentConfig
{
NegotiatedSerializer
:
legacyscheme
.
Codecs
}}
config
.
GenericConfig
.
LoopbackClientConfig
=
&
restclient
.
Config
{
APIPath
:
"/api"
,
ContentConfig
:
restclient
.
ContentConfig
{
NegotiatedSerializer
:
legacyscheme
.
Codecs
}}
config
.
GenericConfig
.
PublicAddress
=
net
.
ParseIP
(
"192.168.10.4"
)
config
.
GenericConfig
.
PublicAddress
=
net
.
ParseIP
(
"192.168.10.4"
)
config
.
GenericConfig
.
LegacyAPIGroupPrefixes
=
sets
.
NewString
(
"/api"
)
config
.
GenericConfig
.
LegacyAPIGroupPrefixes
=
sets
.
NewString
(
"/api"
)
config
.
GenericConfig
.
LoopbackClientConfig
=
&
restclient
.
Config
{
APIPath
:
"/api"
,
ContentConfig
:
restclient
.
ContentConfig
{
NegotiatedSerializer
:
legacyscheme
.
Codecs
}}
config
.
ExtraConfig
.
KubeletClientConfig
=
kubeletclient
.
KubeletClientConfig
{
Port
:
10250
}
config
.
ExtraConfig
.
KubeletClientConfig
=
kubeletclient
.
KubeletClientConfig
{
Port
:
10250
}
config
.
ExtraConfig
.
ProxyTransport
=
utilnet
.
SetTransportDefaults
(
&
http
.
Transport
{
config
.
ExtraConfig
.
ProxyTransport
=
utilnet
.
SetTransportDefaults
(
&
http
.
Transport
{
DialContext
:
func
(
ctx
context
.
Context
,
network
,
addr
string
)
(
net
.
Conn
,
error
)
{
return
nil
,
nil
},
DialContext
:
func
(
ctx
context
.
Context
,
network
,
addr
string
)
(
net
.
Conn
,
error
)
{
return
nil
,
nil
},
...
@@ -363,6 +381,112 @@ func TestAPIVersionOfDiscoveryEndpoints(t *testing.T) {
...
@@ -363,6 +381,112 @@ func TestAPIVersionOfDiscoveryEndpoints(t *testing.T) {
}
}
// This test doesn't cover the apiregistration and apiextensions group, as they are installed by other apiservers.
func
TestStorageVersionHashes
(
t
*
testing
.
T
)
{
defer
utilfeaturetesting
.
SetFeatureGateDuringTest
(
t
,
utilfeature
.
DefaultFeatureGate
,
features
.
StorageVersionHash
,
true
)()
master
,
etcdserver
,
_
,
_
:=
newMaster
(
t
)
defer
etcdserver
.
Terminate
(
t
)
server
:=
httptest
.
NewServer
(
master
.
GenericAPIServer
.
Handler
.
GoRestfulContainer
.
ServeMux
)
c
:=
&
restclient
.
Config
{
Host
:
server
.
URL
,
APIPath
:
"/api"
,
ContentConfig
:
restclient
.
ContentConfig
{
NegotiatedSerializer
:
legacyscheme
.
Codecs
},
}
discover
:=
discovery
.
NewDiscoveryClientForConfigOrDie
(
c
)
all
,
err
:=
discover
.
ServerResources
()
if
err
!=
nil
{
t
.
Error
(
err
)
}
var
count
int
for
_
,
g
:=
range
all
{
for
_
,
r
:=
range
g
.
APIResources
{
if
strings
.
Contains
(
r
.
Name
,
"/"
)
||
storageversionhashdata
.
NoStorageVersionHash
.
Has
(
g
.
GroupVersion
+
"/"
+
r
.
Name
)
{
if
r
.
StorageVersionHash
!=
""
{
t
.
Errorf
(
"expect resource %s/%s to have empty storageVersionHash, got hash %q"
,
g
.
GroupVersion
,
r
.
Name
,
r
.
StorageVersionHash
)
}
continue
}
if
r
.
StorageVersionHash
==
""
{
t
.
Errorf
(
"expect the storageVersionHash of %s/%s to exist"
,
g
.
GroupVersion
,
r
.
Name
)
continue
}
// Uncomment the following line if you want to update storageversionhash/data.go
// fmt.Printf("\"%s/%s\": \"%s\",\n", g.GroupVersion, r.Name, r.StorageVersionHash)
expected
:=
storageversionhashdata
.
GVRToStorageVersionHash
[
g
.
GroupVersion
+
"/"
+
r
.
Name
]
if
r
.
StorageVersionHash
!=
expected
{
t
.
Errorf
(
"expect the storageVersionHash of %s/%s to be %q, got %q"
,
g
.
GroupVersion
,
r
.
Name
,
expected
,
r
.
StorageVersionHash
)
}
count
++
}
}
if
count
!=
len
(
storageversionhashdata
.
GVRToStorageVersionHash
)
{
t
.
Errorf
(
"please remove the redundant entries from GVRToStorageVersionHash"
)
}
}
func
TestStorageVersionHashEqualities
(
t
*
testing
.
T
)
{
defer
utilfeaturetesting
.
SetFeatureGateDuringTest
(
t
,
utilfeature
.
DefaultFeatureGate
,
features
.
StorageVersionHash
,
true
)()
master
,
etcdserver
,
_
,
assert
:=
newMaster
(
t
)
defer
etcdserver
.
Terminate
(
t
)
server
:=
httptest
.
NewServer
(
master
.
GenericAPIServer
.
Handler
.
GoRestfulContainer
.
ServeMux
)
// Test 1: extensions/v1beta1/replicasets and apps/v1/replicasets have
// the same storage version hash.
resp
,
err
:=
http
.
Get
(
server
.
URL
+
"/apis/extensions/v1beta1"
)
assert
.
Empty
(
err
)
extList
:=
metav1
.
APIResourceList
{}
assert
.
NoError
(
decodeResponse
(
resp
,
&
extList
))
var
extReplicasetHash
,
appsReplicasetHash
string
for
_
,
r
:=
range
extList
.
APIResources
{
if
r
.
Name
==
"replicasets"
{
extReplicasetHash
=
r
.
StorageVersionHash
}
}
assert
.
NotEmpty
(
extReplicasetHash
)
resp
,
err
=
http
.
Get
(
server
.
URL
+
"/apis/apps/v1"
)
assert
.
Empty
(
err
)
appsList
:=
metav1
.
APIResourceList
{}
assert
.
NoError
(
decodeResponse
(
resp
,
&
appsList
))
for
_
,
r
:=
range
appsList
.
APIResources
{
if
r
.
Name
==
"replicasets"
{
appsReplicasetHash
=
r
.
StorageVersionHash
}
}
assert
.
Equal
(
extReplicasetHash
,
appsReplicasetHash
)
// Test 2: batch/v1/jobs and batch/v1beta1/cronjobs have different
// storage version hashes.
resp
,
err
=
http
.
Get
(
server
.
URL
+
"/apis/batch/v1"
)
assert
.
Empty
(
err
)
batchv1
:=
metav1
.
APIResourceList
{}
assert
.
NoError
(
decodeResponse
(
resp
,
&
batchv1
))
var
jobsHash
string
for
_
,
r
:=
range
batchv1
.
APIResources
{
if
r
.
Name
==
"jobs"
{
jobsHash
=
r
.
StorageVersionHash
}
}
assert
.
NotEmpty
(
jobsHash
)
resp
,
err
=
http
.
Get
(
server
.
URL
+
"/apis/batch/v1beta1"
)
assert
.
Empty
(
err
)
batchv1beta1
:=
metav1
.
APIResourceList
{}
assert
.
NoError
(
decodeResponse
(
resp
,
&
batchv1beta1
))
var
cronjobsHash
string
for
_
,
r
:=
range
batchv1beta1
.
APIResources
{
if
r
.
Name
==
"cronjobs"
{
cronjobsHash
=
r
.
StorageVersionHash
}
}
assert
.
NotEmpty
(
cronjobsHash
)
assert
.
NotEqual
(
jobsHash
,
cronjobsHash
)
}
func
TestNoAlphaVersionsEnabledByDefault
(
t
*
testing
.
T
)
{
func
TestNoAlphaVersionsEnabledByDefault
(
t
*
testing
.
T
)
{
config
:=
DefaultAPIResourceConfigSource
()
config
:=
DefaultAPIResourceConfigSource
()
for
gv
,
enable
:=
range
config
.
GroupVersionConfigs
{
for
gv
,
enable
:=
range
config
.
GroupVersionConfigs
{
...
...
pkg/master/storageversionhashdata/BUILD
0 → 100644
View file @
b1e389e6
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = ["data.go"],
importpath = "k8s.io/kubernetes/pkg/master/storageversionhashdata",
visibility = ["//visibility:public"],
deps = ["//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library"],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)
pkg/master/storageversionhashdata/OWNERS
0 → 100644
View file @
b1e389e6
approvers:
- api-approvers
reviewers:
- api-reviewers
pkg/master/storageversionhashdata/data.go
0 → 100644
View file @
b1e389e6
/*
Copyright 2019 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Package storageversionhashdata is for test only.
package
storageversionhashdata
import
(
"k8s.io/apimachinery/pkg/util/sets"
)
// NoStorageVersionHash lists resources that legitimately with empty storage
// version hash.
var
NoStorageVersionHash
=
sets
.
NewString
(
"v1/bindings"
,
"v1/componentstatuses"
,
"authentication.k8s.io/v1/tokenreviews"
,
"authorization.k8s.io/v1/localsubjectaccessreviews"
,
"authorization.k8s.io/v1/selfsubjectaccessreviews"
,
"authorization.k8s.io/v1/selfsubjectrulesreviews"
,
"authorization.k8s.io/v1/subjectaccessreviews"
,
"authentication.k8s.io/v1beta1/tokenreviews"
,
"authorization.k8s.io/v1beta1/localsubjectaccessreviews"
,
"authorization.k8s.io/v1beta1/selfsubjectaccessreviews"
,
"authorization.k8s.io/v1beta1/selfsubjectrulesreviews"
,
"authorization.k8s.io/v1beta1/subjectaccessreviews"
,
"extensions/v1beta1/replicationcontrollers"
,
)
// GVRToStorageVersionHash shouldn't change unless we intentionally change the
// storage version of a resource.
var
GVRToStorageVersionHash
=
map
[
string
]
string
{
"v1/configmaps"
:
"qFsyl6wFWjQ="
,
"v1/endpoints"
:
"fWeeMqaN/OA="
,
"v1/events"
:
"r2yiGXH7wu8="
,
"v1/limitranges"
:
"EBKMFVe6cwo="
,
"v1/namespaces"
:
"Q3oi5N2YM8M="
,
"v1/nodes"
:
"XwShjMxG9Fs="
,
"v1/persistentvolumeclaims"
:
"QWTyNDq0dC4="
,
"v1/persistentvolumes"
:
"HN/zwEC+JgM="
,
"v1/pods"
:
"xPOwRZ+Yhw8="
,
"v1/podtemplates"
:
"LIXB2x4IFpk="
,
"v1/replicationcontrollers"
:
"Jond2If31h0="
,
"v1/resourcequotas"
:
"8uhSgffRX6w="
,
"v1/secrets"
:
"S6u1pOWzb84="
,
"v1/serviceaccounts"
:
"pbx9ZvyFpBE="
,
"v1/services"
:
"0/CO1lhkEBI="
,
"autoscaling/v1/horizontalpodautoscalers"
:
"oQlkt7f5j/A="
,
"autoscaling/v2beta1/horizontalpodautoscalers"
:
"oQlkt7f5j/A="
,
"autoscaling/v2beta2/horizontalpodautoscalers"
:
"oQlkt7f5j/A="
,
"batch/v1/jobs"
:
"mudhfqk/qZY="
,
"batch/v1beta1/cronjobs"
:
"h/JlFAZkyyY="
,
"certificates.k8s.io/v1beta1/certificatesigningrequests"
:
"UQh3YTCDIf0="
,
"coordination.k8s.io/v1beta1/leases"
:
"/sY7hl8ol1U="
,
"coordination.k8s.io/v1/leases"
:
"/sY7hl8ol1U="
,
"extensions/v1beta1/daemonsets"
:
"dd7pWHUlMKQ="
,
"extensions/v1beta1/deployments"
:
"8aSe+NMegvE="
,
"extensions/v1beta1/ingresses"
:
"Ejja63IbU0E="
,
"extensions/v1beta1/networkpolicies"
:
"YpfwF18m1G8="
,
"extensions/v1beta1/podsecuritypolicies"
:
"khBLobUXkqA="
,
"extensions/v1beta1/replicasets"
:
"P1RzHs8/mWQ="
,
"networking.k8s.io/v1/networkpolicies"
:
"YpfwF18m1G8="
,
"networking.k8s.io/v1beta1/ingresses"
:
"Ejja63IbU0E="
,
"node.k8s.io/v1beta1/runtimeclasses"
:
"8nMHWqj34s0="
,
"policy/v1beta1/poddisruptionbudgets"
:
"6BGBu0kpHtk="
,
"policy/v1beta1/podsecuritypolicies"
:
"khBLobUXkqA="
,
"rbac.authorization.k8s.io/v1/clusterrolebindings"
:
"48tpQ8gZHFc="
,
"rbac.authorization.k8s.io/v1/clusterroles"
:
"bYE5ZWDrJ44="
,
"rbac.authorization.k8s.io/v1/rolebindings"
:
"eGsCzGH6b1g="
,
"rbac.authorization.k8s.io/v1/roles"
:
"7FuwZcIIItM="
,
"rbac.authorization.k8s.io/v1beta1/clusterrolebindings"
:
"48tpQ8gZHFc="
,
"rbac.authorization.k8s.io/v1beta1/clusterroles"
:
"bYE5ZWDrJ44="
,
"rbac.authorization.k8s.io/v1beta1/rolebindings"
:
"eGsCzGH6b1g="
,
"rbac.authorization.k8s.io/v1beta1/roles"
:
"7FuwZcIIItM="
,
"scheduling.k8s.io/v1beta1/priorityclasses"
:
"D3vHs+OgrtA="
,
"scheduling.k8s.io/v1/priorityclasses"
:
"D3vHs+OgrtA="
,
"storage.k8s.io/v1/storageclasses"
:
"K+m6uJwbjGY="
,
"storage.k8s.io/v1/volumeattachments"
:
"vQAqD28V4AY="
,
"storage.k8s.io/v1beta1/csidrivers"
:
"hL6j/rwBV5w="
,
"storage.k8s.io/v1beta1/csinodes"
:
"Pe62DkZtjuo="
,
"storage.k8s.io/v1beta1/storageclasses"
:
"K+m6uJwbjGY="
,
"storage.k8s.io/v1beta1/volumeattachments"
:
"vQAqD28V4AY="
,
"apps/v1/controllerrevisions"
:
"85nkx63pcBU="
,
"apps/v1/daemonsets"
:
"dd7pWHUlMKQ="
,
"apps/v1/deployments"
:
"8aSe+NMegvE="
,
"apps/v1/replicasets"
:
"P1RzHs8/mWQ="
,
"apps/v1/statefulsets"
:
"H+vl74LkKdo="
,
"apps/v1beta2/controllerrevisions"
:
"85nkx63pcBU="
,
"apps/v1beta2/daemonsets"
:
"dd7pWHUlMKQ="
,
"apps/v1beta2/deployments"
:
"8aSe+NMegvE="
,
"apps/v1beta2/replicasets"
:
"P1RzHs8/mWQ="
,
"apps/v1beta2/statefulsets"
:
"H+vl74LkKdo="
,
"apps/v1beta1/controllerrevisions"
:
"85nkx63pcBU="
,
"apps/v1beta1/deployments"
:
"8aSe+NMegvE="
,
"apps/v1beta1/statefulsets"
:
"H+vl74LkKdo="
,
"admissionregistration.k8s.io/v1beta1/mutatingwebhookconfigurations"
:
"yxW1cpLtfp8="
,
"admissionregistration.k8s.io/v1beta1/validatingwebhookconfigurations"
:
"P9NhrezfnWE="
,
"events.k8s.io/v1beta1/events"
:
"r2yiGXH7wu8="
,
}
pkg/registry/core/namespace/storage/storage.go
View file @
b1e389e6
...
@@ -226,6 +226,12 @@ func (r *REST) ShortNames() []string {
...
@@ -226,6 +226,12 @@ func (r *REST) ShortNames() []string {
return
[]
string
{
"ns"
}
return
[]
string
{
"ns"
}
}
}
var
_
rest
.
StorageVersionProvider
=
&
REST
{}
func
(
r
*
REST
)
StorageVersion
()
runtime
.
GroupVersioner
{
return
r
.
store
.
StorageVersion
()
}
func
(
r
*
StatusREST
)
New
()
runtime
.
Object
{
func
(
r
*
StatusREST
)
New
()
runtime
.
Object
{
return
r
.
store
.
New
()
return
r
.
store
.
New
()
}
}
...
...
pkg/registry/core/service/storage/rest.go
View file @
b1e389e6
...
@@ -77,6 +77,7 @@ type ServiceStorage interface {
...
@@ -77,6 +77,7 @@ type ServiceStorage interface {
rest
.
Watcher
rest
.
Watcher
rest
.
TableConvertor
rest
.
TableConvertor
rest
.
Exporter
rest
.
Exporter
rest
.
StorageVersionProvider
}
}
type
EndpointsStorage
interface
{
type
EndpointsStorage
interface
{
...
@@ -108,11 +109,16 @@ func NewREST(
...
@@ -108,11 +109,16 @@ func NewREST(
}
}
var
(
var
(
_
ServiceStorage
=
&
REST
{}
_
ServiceStorage
=
&
REST
{}
_
rest
.
CategoriesProvider
=
&
REST
{}
_
rest
.
CategoriesProvider
=
&
REST
{}
_
rest
.
ShortNamesProvider
=
&
REST
{}
_
rest
.
ShortNamesProvider
=
&
REST
{}
_
rest
.
StorageVersionProvider
=
&
REST
{}
)
)
func
(
rs
*
REST
)
StorageVersion
()
runtime
.
GroupVersioner
{
return
rs
.
services
.
StorageVersion
()
}
// ShortNames implements the ShortNamesProvider interface. Returns a list of short names for a resource.
// ShortNames implements the ShortNamesProvider interface. Returns a list of short names for a resource.
func
(
rs
*
REST
)
ShortNames
()
[]
string
{
func
(
rs
*
REST
)
ShortNames
()
[]
string
{
return
[]
string
{
"svc"
}
return
[]
string
{
"svc"
}
...
...
pkg/registry/core/service/storage/rest_test.go
View file @
b1e389e6
...
@@ -159,6 +159,10 @@ func (s *serviceStorage) Export(ctx context.Context, name string, opts metav1.Ex
...
@@ -159,6 +159,10 @@ func (s *serviceStorage) Export(ctx context.Context, name string, opts metav1.Ex
panic
(
"not implemented"
)
panic
(
"not implemented"
)
}
}
func
(
s
*
serviceStorage
)
StorageVersion
()
runtime
.
GroupVersioner
{
panic
(
"not implemented"
)
}
func
generateRandomNodePort
()
int32
{
func
generateRandomNodePort
()
int32
{
return
int32
(
rand
.
IntnRange
(
30001
,
30999
))
return
int32
(
rand
.
IntnRange
(
30001
,
30999
))
}
}
...
...
pkg/registry/rbac/clusterrole/policybased/storage.go
View file @
b1e389e6
...
@@ -50,6 +50,16 @@ func (r *Storage) NamespaceScoped() bool {
...
@@ -50,6 +50,16 @@ func (r *Storage) NamespaceScoped() bool {
return
false
return
false
}
}
func
(
r
*
Storage
)
StorageVersion
()
runtime
.
GroupVersioner
{
svp
,
ok
:=
r
.
StandardStorage
.
(
rest
.
StorageVersionProvider
)
if
!
ok
{
return
nil
}
return
svp
.
StorageVersion
()
}
var
_
rest
.
StorageVersionProvider
=
&
Storage
{}
var
fullAuthority
=
[]
rbac
.
PolicyRule
{
var
fullAuthority
=
[]
rbac
.
PolicyRule
{
rbac
.
NewRule
(
"*"
)
.
Groups
(
"*"
)
.
Resources
(
"*"
)
.
RuleOrDie
(),
rbac
.
NewRule
(
"*"
)
.
Groups
(
"*"
)
.
Resources
(
"*"
)
.
RuleOrDie
(),
rbac
.
NewRule
(
"*"
)
.
URLs
(
"*"
)
.
RuleOrDie
(),
rbac
.
NewRule
(
"*"
)
.
URLs
(
"*"
)
.
RuleOrDie
(),
...
...
pkg/registry/rbac/clusterrolebinding/policybased/storage.go
View file @
b1e389e6
...
@@ -51,6 +51,16 @@ func (r *Storage) NamespaceScoped() bool {
...
@@ -51,6 +51,16 @@ func (r *Storage) NamespaceScoped() bool {
return
false
return
false
}
}
func
(
r
*
Storage
)
StorageVersion
()
runtime
.
GroupVersioner
{
svp
,
ok
:=
r
.
StandardStorage
.
(
rest
.
StorageVersionProvider
)
if
!
ok
{
return
nil
}
return
svp
.
StorageVersion
()
}
var
_
rest
.
StorageVersionProvider
=
&
Storage
{}
func
(
s
*
Storage
)
Create
(
ctx
context
.
Context
,
obj
runtime
.
Object
,
createValidation
rest
.
ValidateObjectFunc
,
options
*
metav1
.
CreateOptions
)
(
runtime
.
Object
,
error
)
{
func
(
s
*
Storage
)
Create
(
ctx
context
.
Context
,
obj
runtime
.
Object
,
createValidation
rest
.
ValidateObjectFunc
,
options
*
metav1
.
CreateOptions
)
(
runtime
.
Object
,
error
)
{
if
rbacregistry
.
EscalationAllowed
(
ctx
)
{
if
rbacregistry
.
EscalationAllowed
(
ctx
)
{
return
s
.
StandardStorage
.
Create
(
ctx
,
obj
,
createValidation
,
options
)
return
s
.
StandardStorage
.
Create
(
ctx
,
obj
,
createValidation
,
options
)
...
...
pkg/registry/rbac/role/policybased/storage.go
View file @
b1e389e6
...
@@ -49,6 +49,16 @@ func (r *Storage) NamespaceScoped() bool {
...
@@ -49,6 +49,16 @@ func (r *Storage) NamespaceScoped() bool {
return
true
return
true
}
}
func
(
r
*
Storage
)
StorageVersion
()
runtime
.
GroupVersioner
{
svp
,
ok
:=
r
.
StandardStorage
.
(
rest
.
StorageVersionProvider
)
if
!
ok
{
return
nil
}
return
svp
.
StorageVersion
()
}
var
_
rest
.
StorageVersionProvider
=
&
Storage
{}
func
(
s
*
Storage
)
Create
(
ctx
context
.
Context
,
obj
runtime
.
Object
,
createValidation
rest
.
ValidateObjectFunc
,
options
*
metav1
.
CreateOptions
)
(
runtime
.
Object
,
error
)
{
func
(
s
*
Storage
)
Create
(
ctx
context
.
Context
,
obj
runtime
.
Object
,
createValidation
rest
.
ValidateObjectFunc
,
options
*
metav1
.
CreateOptions
)
(
runtime
.
Object
,
error
)
{
if
rbacregistry
.
EscalationAllowed
(
ctx
)
||
rbacregistry
.
RoleEscalationAuthorized
(
ctx
,
s
.
authorizer
)
{
if
rbacregistry
.
EscalationAllowed
(
ctx
)
||
rbacregistry
.
RoleEscalationAuthorized
(
ctx
,
s
.
authorizer
)
{
return
s
.
StandardStorage
.
Create
(
ctx
,
obj
,
createValidation
,
options
)
return
s
.
StandardStorage
.
Create
(
ctx
,
obj
,
createValidation
,
options
)
...
...
pkg/registry/rbac/rolebinding/policybased/storage.go
View file @
b1e389e6
...
@@ -52,6 +52,16 @@ func (r *Storage) NamespaceScoped() bool {
...
@@ -52,6 +52,16 @@ func (r *Storage) NamespaceScoped() bool {
return
true
return
true
}
}
func
(
r
*
Storage
)
StorageVersion
()
runtime
.
GroupVersioner
{
svp
,
ok
:=
r
.
StandardStorage
.
(
rest
.
StorageVersionProvider
)
if
!
ok
{
return
nil
}
return
svp
.
StorageVersion
()
}
var
_
rest
.
StorageVersionProvider
=
&
Storage
{}
func
(
s
*
Storage
)
Create
(
ctx
context
.
Context
,
obj
runtime
.
Object
,
createValidation
rest
.
ValidateObjectFunc
,
options
*
metav1
.
CreateOptions
)
(
runtime
.
Object
,
error
)
{
func
(
s
*
Storage
)
Create
(
ctx
context
.
Context
,
obj
runtime
.
Object
,
createValidation
rest
.
ValidateObjectFunc
,
options
*
metav1
.
CreateOptions
)
(
runtime
.
Object
,
error
)
{
if
rbacregistry
.
EscalationAllowed
(
ctx
)
{
if
rbacregistry
.
EscalationAllowed
(
ctx
)
{
return
s
.
StandardStorage
.
Create
(
ctx
,
obj
,
createValidation
,
options
)
return
s
.
StandardStorage
.
Create
(
ctx
,
obj
,
createValidation
,
options
)
...
...
pkg/util/mount/BUILD
View file @
b1e389e6
...
@@ -9,7 +9,9 @@ go_library(
...
@@ -9,7 +9,9 @@ go_library(
"exec_mount_unsupported.go",
"exec_mount_unsupported.go",
"fake.go",
"fake.go",
"mount.go",
"mount.go",
"mount_helper.go",
"mount_helper_common.go",
"mount_helper_unix.go",
"mount_helper_windows.go",
"mount_linux.go",
"mount_linux.go",
"mount_unsupported.go",
"mount_unsupported.go",
"mount_windows.go",
"mount_windows.go",
...
...
pkg/util/mount/mount_helper.go
→
pkg/util/mount/mount_helper
_common
.go
View file @
b1e389e6
...
@@ -19,7 +19,6 @@ package mount
...
@@ -19,7 +19,6 @@ package mount
import
(
import
(
"fmt"
"fmt"
"os"
"os"
"syscall"
"k8s.io/klog"
"k8s.io/klog"
)
)
...
@@ -102,23 +101,3 @@ func PathExists(path string) (bool, error) {
...
@@ -102,23 +101,3 @@ func PathExists(path string) (bool, error) {
return
false
,
err
return
false
,
err
}
}
}
}
// IsCorruptedMnt return true if err is about corrupted mount point
func
IsCorruptedMnt
(
err
error
)
bool
{
if
err
==
nil
{
return
false
}
var
underlyingError
error
switch
pe
:=
err
.
(
type
)
{
case
nil
:
return
false
case
*
os
.
PathError
:
underlyingError
=
pe
.
Err
case
*
os
.
LinkError
:
underlyingError
=
pe
.
Err
case
*
os
.
SyscallError
:
underlyingError
=
pe
.
Err
}
return
underlyingError
==
syscall
.
ENOTCONN
||
underlyingError
==
syscall
.
ESTALE
||
underlyingError
==
syscall
.
EIO
||
underlyingError
==
syscall
.
EACCES
}
pkg/util/mount/mount_helper_unix.go
0 → 100644
View file @
b1e389e6
// +build !windows
/*
Copyright 2019 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package
mount
import
(
"os"
"syscall"
)
// IsCorruptedMnt return true if err is about corrupted mount point
func
IsCorruptedMnt
(
err
error
)
bool
{
if
err
==
nil
{
return
false
}
var
underlyingError
error
switch
pe
:=
err
.
(
type
)
{
case
nil
:
return
false
case
*
os
.
PathError
:
underlyingError
=
pe
.
Err
case
*
os
.
LinkError
:
underlyingError
=
pe
.
Err
case
*
os
.
SyscallError
:
underlyingError
=
pe
.
Err
}
return
underlyingError
==
syscall
.
ENOTCONN
||
underlyingError
==
syscall
.
ESTALE
||
underlyingError
==
syscall
.
EIO
||
underlyingError
==
syscall
.
EACCES
}
pkg/util/mount/mount_helper_windows.go
0 → 100644
View file @
b1e389e6
// +build windows
/*
Copyright 2019 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package
mount
import
(
"os"
"syscall"
"k8s.io/klog"
)
// following failure codes are from https://docs.microsoft.com/en-us/windows/desktop/debug/system-error-codes--1300-1699-
// ERROR_BAD_NETPATH = 53
// ERROR_NETWORK_BUSY = 54
// ERROR_UNEXP_NET_ERR = 59
// ERROR_NETNAME_DELETED = 64
// ERROR_NETWORK_ACCESS_DENIED = 65
// ERROR_BAD_DEV_TYPE = 66
// ERROR_BAD_NET_NAME = 67
// ERROR_SESSION_CREDENTIAL_CONFLICT = 1219
// ERROR_LOGON_FAILURE = 1326
var
errorNoList
=
[
...
]
int
{
53
,
54
,
59
,
64
,
65
,
66
,
67
,
1219
,
1326
}
// IsCorruptedMnt return true if err is about corrupted mount point
func
IsCorruptedMnt
(
err
error
)
bool
{
if
err
==
nil
{
return
false
}
var
underlyingError
error
switch
pe
:=
err
.
(
type
)
{
case
nil
:
return
false
case
*
os
.
PathError
:
underlyingError
=
pe
.
Err
case
*
os
.
LinkError
:
underlyingError
=
pe
.
Err
case
*
os
.
SyscallError
:
underlyingError
=
pe
.
Err
}
if
ee
,
ok
:=
underlyingError
.
(
syscall
.
Errno
);
ok
{
for
_
,
errno
:=
range
errorNoList
{
if
int
(
ee
)
==
errno
{
klog
.
Warningf
(
"IsCorruptedMnt failed with error: %v, error code: %v"
,
err
,
errno
)
return
true
}
}
}
return
false
}
pkg/util/mount/mount_windows.go
View file @
b1e389e6
...
@@ -378,14 +378,15 @@ func getAllParentLinks(path string) ([]string, error) {
...
@@ -378,14 +378,15 @@ func getAllParentLinks(path string) ([]string, error) {
// GetMountRefs : empty implementation here since there is no place to query all mount points on Windows
// GetMountRefs : empty implementation here since there is no place to query all mount points on Windows
func
(
mounter
*
Mounter
)
GetMountRefs
(
pathname
string
)
([]
string
,
error
)
{
func
(
mounter
*
Mounter
)
GetMountRefs
(
pathname
string
)
([]
string
,
error
)
{
pathExists
,
pathErr
:=
PathExists
(
normalizeWindowsPath
(
pathname
))
windowsPath
:=
normalizeWindowsPath
(
pathname
)
// TODO(#75012): Need a Windows specific IsCorruptedMnt function that checks against whatever errno's
pathExists
,
pathErr
:=
PathExists
(
windowsPath
)
// Windows emits when we try to Stat a corrupted mount
// https://golang.org/pkg/syscall/?GOOS=windows&GOARCH=amd64#Errno
if
!
pathExists
{
if
!
pathExists
{
return
[]
string
{},
nil
return
[]
string
{},
nil
}
else
if
IsCorruptedMnt
(
pathErr
)
{
klog
.
Warningf
(
"GetMountRefs found corrupted mount at %s, treating as unmounted path"
,
windowsPath
)
return
[]
string
{},
nil
}
else
if
pathErr
!=
nil
{
}
else
if
pathErr
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"error checking path %s: %v"
,
normalizeWindowsPath
(
pathname
)
,
pathErr
)
return
nil
,
fmt
.
Errorf
(
"error checking path %s: %v"
,
windowsPath
,
pathErr
)
}
}
return
[]
string
{
pathname
},
nil
return
[]
string
{
pathname
},
nil
}
}
...
...
pkg/volume/csi/csi_block.go
View file @
b1e389e6
...
@@ -37,8 +37,8 @@ import (
...
@@ -37,8 +37,8 @@ import (
)
)
type
csiBlockMapper
struct
{
type
csiBlockMapper
struct
{
csiClientGetter
k8s
kubernetes
.
Interface
k8s
kubernetes
.
Interface
csiClient
csiClient
plugin
*
csiPlugin
plugin
*
csiPlugin
driverName
csiDriverName
driverName
csiDriverName
specName
string
specName
string
...
@@ -247,14 +247,20 @@ func (m *csiBlockMapper) SetUpDevice() (string, error) {
...
@@ -247,14 +247,20 @@ func (m *csiBlockMapper) SetUpDevice() (string, error) {
ctx
,
cancel
:=
context
.
WithTimeout
(
context
.
Background
(),
csiTimeout
)
ctx
,
cancel
:=
context
.
WithTimeout
(
context
.
Background
(),
csiTimeout
)
defer
cancel
()
defer
cancel
()
csiClient
,
err
:=
m
.
csiClientGetter
.
Get
()
if
err
!=
nil
{
klog
.
Error
(
log
(
"blockMapper.SetUpDevice failed to get CSI client: %v"
,
err
))
return
""
,
err
}
// Call NodeStageVolume
// Call NodeStageVolume
stagingPath
,
err
:=
m
.
stageVolumeForBlock
(
ctx
,
m
.
csiClient
,
accessMode
,
csiSource
,
attachment
)
stagingPath
,
err
:=
m
.
stageVolumeForBlock
(
ctx
,
csiClient
,
accessMode
,
csiSource
,
attachment
)
if
err
!=
nil
{
if
err
!=
nil
{
return
""
,
err
return
""
,
err
}
}
// Call NodePublishVolume
// Call NodePublishVolume
publishPath
,
err
:=
m
.
publishVolumeForBlock
(
ctx
,
m
.
csiClient
,
accessMode
,
csiSource
,
attachment
,
stagingPath
)
publishPath
,
err
:=
m
.
publishVolumeForBlock
(
ctx
,
csiClient
,
accessMode
,
csiSource
,
attachment
,
stagingPath
)
if
err
!=
nil
{
if
err
!=
nil
{
return
""
,
err
return
""
,
err
}
}
...
@@ -326,6 +332,12 @@ func (m *csiBlockMapper) TearDownDevice(globalMapPath, devicePath string) error
...
@@ -326,6 +332,12 @@ func (m *csiBlockMapper) TearDownDevice(globalMapPath, devicePath string) error
ctx
,
cancel
:=
context
.
WithTimeout
(
context
.
Background
(),
csiTimeout
)
ctx
,
cancel
:=
context
.
WithTimeout
(
context
.
Background
(),
csiTimeout
)
defer
cancel
()
defer
cancel
()
csiClient
,
err
:=
m
.
csiClientGetter
.
Get
()
if
err
!=
nil
{
klog
.
Error
(
log
(
"blockMapper.TearDownDevice failed to get CSI client: %v"
,
err
))
return
err
}
// Call NodeUnpublishVolume
// Call NodeUnpublishVolume
publishPath
:=
m
.
getPublishPath
()
publishPath
:=
m
.
getPublishPath
()
if
_
,
err
:=
os
.
Stat
(
publishPath
);
err
!=
nil
{
if
_
,
err
:=
os
.
Stat
(
publishPath
);
err
!=
nil
{
...
@@ -335,7 +347,7 @@ func (m *csiBlockMapper) TearDownDevice(globalMapPath, devicePath string) error
...
@@ -335,7 +347,7 @@ func (m *csiBlockMapper) TearDownDevice(globalMapPath, devicePath string) error
return
err
return
err
}
}
}
else
{
}
else
{
err
:=
m
.
unpublishVolumeForBlock
(
ctx
,
m
.
csiClient
,
publishPath
)
err
:=
m
.
unpublishVolumeForBlock
(
ctx
,
csiClient
,
publishPath
)
if
err
!=
nil
{
if
err
!=
nil
{
return
err
return
err
}
}
...
@@ -350,7 +362,7 @@ func (m *csiBlockMapper) TearDownDevice(globalMapPath, devicePath string) error
...
@@ -350,7 +362,7 @@ func (m *csiBlockMapper) TearDownDevice(globalMapPath, devicePath string) error
return
err
return
err
}
}
}
else
{
}
else
{
err
:=
m
.
unstageVolumeForBlock
(
ctx
,
m
.
csiClient
,
stagingPath
)
err
:=
m
.
unstageVolumeForBlock
(
ctx
,
csiClient
,
stagingPath
)
if
err
!=
nil
{
if
err
!=
nil
{
return
err
return
err
}
}
...
...
pkg/volume/csi/csi_client.go
View file @
b1e389e6
...
@@ -23,6 +23,7 @@ import (
...
@@ -23,6 +23,7 @@ import (
"io"
"io"
"net"
"net"
"strings"
"strings"
"sync"
"time"
"time"
csipbv1
"github.com/container-storage-interface/spec/lib/go/csi"
csipbv1
"github.com/container-storage-interface/spec/lib/go/csi"
...
@@ -807,3 +808,36 @@ func versionRequiresV0Client(version *utilversion.Version) bool {
...
@@ -807,3 +808,36 @@ func versionRequiresV0Client(version *utilversion.Version) bool {
return
false
return
false
}
}
// CSI client getter with cache.
// This provides a method to initialize CSI client with driver name and caches
// it for later use. When CSI clients have not been discovered yet (e.g.
// on kubelet restart), client initialization will fail. Users of CSI client (e.g.
// mounter manager and block mapper) can use this to delay CSI client
// initialization until needed.
type
csiClientGetter
struct
{
sync
.
RWMutex
csiClient
csiClient
driverName
csiDriverName
}
func
(
c
*
csiClientGetter
)
Get
()
(
csiClient
,
error
)
{
c
.
RLock
()
if
c
.
csiClient
!=
nil
{
c
.
RUnlock
()
return
c
.
csiClient
,
nil
}
c
.
RUnlock
()
c
.
Lock
()
defer
c
.
Unlock
()
// Double-checking locking criterion.
if
c
.
csiClient
!=
nil
{
return
c
.
csiClient
,
nil
}
csi
,
err
:=
newCsiDriverClient
(
c
.
driverName
)
if
err
!=
nil
{
return
nil
,
err
}
c
.
csiClient
=
csi
return
c
.
csiClient
,
nil
}
pkg/volume/csi/csi_mounter.go
View file @
b1e389e6
...
@@ -56,7 +56,7 @@ var (
...
@@ -56,7 +56,7 @@ var (
)
)
type
csiMountMgr
struct
{
type
csiMountMgr
struct
{
csiClient
csiClient
csiClient
Getter
k8s
kubernetes
.
Interface
k8s
kubernetes
.
Interface
plugin
*
csiPlugin
plugin
*
csiPlugin
driverName
csiDriverName
driverName
csiDriverName
...
@@ -111,7 +111,11 @@ func (c *csiMountMgr) SetUpAt(dir string, fsGroup *int64) error {
...
@@ -111,7 +111,11 @@ func (c *csiMountMgr) SetUpAt(dir string, fsGroup *int64) error {
return
nil
return
nil
}
}
csi
:=
c
.
csiClient
csi
,
err
:=
c
.
csiClientGetter
.
Get
()
if
err
!=
nil
{
klog
.
Error
(
log
(
"mounter.SetUpAt failed to get CSI client: %v"
,
err
))
return
err
}
ctx
,
cancel
:=
context
.
WithTimeout
(
context
.
Background
(),
csiTimeout
)
ctx
,
cancel
:=
context
.
WithTimeout
(
context
.
Background
(),
csiTimeout
)
defer
cancel
()
defer
cancel
()
...
@@ -343,7 +347,11 @@ func (c *csiMountMgr) TearDownAt(dir string) error {
...
@@ -343,7 +347,11 @@ func (c *csiMountMgr) TearDownAt(dir string) error {
klog
.
V
(
4
)
.
Infof
(
log
(
"Unmounter.TearDown(%s)"
,
dir
))
klog
.
V
(
4
)
.
Infof
(
log
(
"Unmounter.TearDown(%s)"
,
dir
))
volID
:=
c
.
volumeID
volID
:=
c
.
volumeID
csi
:=
c
.
csiClient
csi
,
err
:=
c
.
csiClientGetter
.
Get
()
if
err
!=
nil
{
klog
.
Error
(
log
(
"mounter.SetUpAt failed to get CSI client: %v"
,
err
))
return
err
}
ctx
,
cancel
:=
context
.
WithTimeout
(
context
.
Background
(),
csiTimeout
)
ctx
,
cancel
:=
context
.
WithTimeout
(
context
.
Background
(),
csiTimeout
)
defer
cancel
()
defer
cancel
()
...
...
pkg/volume/csi/csi_plugin.go
View file @
b1e389e6
...
@@ -383,11 +383,6 @@ func (p *csiPlugin) NewMounter(
...
@@ -383,11 +383,6 @@ func (p *csiPlugin) NewMounter(
return
nil
,
errors
.
New
(
"failed to get a Kubernetes client"
)
return
nil
,
errors
.
New
(
"failed to get a Kubernetes client"
)
}
}
csi
,
err
:=
newCsiDriverClient
(
csiDriverName
(
driverName
))
if
err
!=
nil
{
return
nil
,
err
}
mounter
:=
&
csiMountMgr
{
mounter
:=
&
csiMountMgr
{
plugin
:
p
,
plugin
:
p
,
k8s
:
k8s
,
k8s
:
k8s
,
...
@@ -398,9 +393,9 @@ func (p *csiPlugin) NewMounter(
...
@@ -398,9 +393,9 @@ func (p *csiPlugin) NewMounter(
driverMode
:
driverMode
,
driverMode
:
driverMode
,
volumeID
:
volumeHandle
,
volumeID
:
volumeHandle
,
specVolumeID
:
spec
.
Name
(),
specVolumeID
:
spec
.
Name
(),
csiClient
:
csi
,
readOnly
:
readOnly
,
readOnly
:
readOnly
,
}
}
mounter
.
csiClientGetter
.
driverName
=
csiDriverName
(
driverName
)
// Save volume info in pod dir
// Save volume info in pod dir
dir
:=
mounter
.
GetPath
()
dir
:=
mounter
.
GetPath
()
...
@@ -458,10 +453,7 @@ func (p *csiPlugin) NewUnmounter(specName string, podUID types.UID) (volume.Unmo
...
@@ -458,10 +453,7 @@ func (p *csiPlugin) NewUnmounter(specName string, podUID types.UID) (volume.Unmo
}
}
unmounter
.
driverName
=
csiDriverName
(
data
[
volDataKey
.
driverName
])
unmounter
.
driverName
=
csiDriverName
(
data
[
volDataKey
.
driverName
])
unmounter
.
volumeID
=
data
[
volDataKey
.
volHandle
]
unmounter
.
volumeID
=
data
[
volDataKey
.
volHandle
]
unmounter
.
csiClient
,
err
=
newCsiDriverClient
(
unmounter
.
driverName
)
unmounter
.
csiClientGetter
.
driverName
=
unmounter
.
driverName
if
err
!=
nil
{
return
nil
,
err
}
return
unmounter
,
nil
return
unmounter
,
nil
}
}
...
@@ -638,10 +630,6 @@ func (p *csiPlugin) NewBlockVolumeMapper(spec *volume.Spec, podRef *api.Pod, opt
...
@@ -638,10 +630,6 @@ func (p *csiPlugin) NewBlockVolumeMapper(spec *volume.Spec, podRef *api.Pod, opt
}
}
klog
.
V
(
4
)
.
Info
(
log
(
"setting up block mapper for [volume=%v,driver=%v]"
,
pvSource
.
VolumeHandle
,
pvSource
.
Driver
))
klog
.
V
(
4
)
.
Info
(
log
(
"setting up block mapper for [volume=%v,driver=%v]"
,
pvSource
.
VolumeHandle
,
pvSource
.
Driver
))
client
,
err
:=
newCsiDriverClient
(
csiDriverName
(
pvSource
.
Driver
))
if
err
!=
nil
{
return
nil
,
err
}
k8s
:=
p
.
host
.
GetKubeClient
()
k8s
:=
p
.
host
.
GetKubeClient
()
if
k8s
==
nil
{
if
k8s
==
nil
{
...
@@ -650,7 +638,6 @@ func (p *csiPlugin) NewBlockVolumeMapper(spec *volume.Spec, podRef *api.Pod, opt
...
@@ -650,7 +638,6 @@ func (p *csiPlugin) NewBlockVolumeMapper(spec *volume.Spec, podRef *api.Pod, opt
}
}
mapper
:=
&
csiBlockMapper
{
mapper
:=
&
csiBlockMapper
{
csiClient
:
client
,
k8s
:
k8s
,
k8s
:
k8s
,
plugin
:
p
,
plugin
:
p
,
volumeID
:
pvSource
.
VolumeHandle
,
volumeID
:
pvSource
.
VolumeHandle
,
...
@@ -660,6 +647,7 @@ func (p *csiPlugin) NewBlockVolumeMapper(spec *volume.Spec, podRef *api.Pod, opt
...
@@ -660,6 +647,7 @@ func (p *csiPlugin) NewBlockVolumeMapper(spec *volume.Spec, podRef *api.Pod, opt
specName
:
spec
.
Name
(),
specName
:
spec
.
Name
(),
podUID
:
podRef
.
UID
,
podUID
:
podRef
.
UID
,
}
}
mapper
.
csiClientGetter
.
driverName
=
csiDriverName
(
pvSource
.
Driver
)
// Save volume info in pod dir
// Save volume info in pod dir
dataDir
:=
getVolumeDeviceDataDir
(
spec
.
Name
(),
p
.
host
)
dataDir
:=
getVolumeDeviceDataDir
(
spec
.
Name
(),
p
.
host
)
...
@@ -714,7 +702,7 @@ func (p *csiPlugin) NewBlockVolumeUnmapper(volName string, podUID types.UID) (vo
...
@@ -714,7 +702,7 @@ func (p *csiPlugin) NewBlockVolumeUnmapper(volName string, podUID types.UID) (vo
}
}
unmapper
.
driverName
=
csiDriverName
(
data
[
volDataKey
.
driverName
])
unmapper
.
driverName
=
csiDriverName
(
data
[
volDataKey
.
driverName
])
unmapper
.
volumeID
=
data
[
volDataKey
.
volHandle
]
unmapper
.
volumeID
=
data
[
volDataKey
.
volHandle
]
unmapper
.
csiClient
,
err
=
newCsiDriverClient
(
unmapper
.
driverName
)
unmapper
.
csiClient
Getter
.
driverName
=
unmapper
.
driverName
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
err
return
nil
,
err
}
}
...
...
pkg/volume/csi/csi_plugin_test.go
View file @
b1e389e6
...
@@ -614,7 +614,8 @@ func TestPluginNewMounter(t *testing.T) {
...
@@ -614,7 +614,8 @@ func TestPluginNewMounter(t *testing.T) {
if
string
(
csiMounter
.
podUID
)
!=
string
(
test
.
podUID
)
{
if
string
(
csiMounter
.
podUID
)
!=
string
(
test
.
podUID
)
{
t
.
Error
(
"mounter podUID not set"
)
t
.
Error
(
"mounter podUID not set"
)
}
}
if
csiMounter
.
csiClient
==
nil
{
csiClient
,
err
:=
csiMounter
.
csiClientGetter
.
Get
()
if
csiClient
==
nil
{
t
.
Error
(
"mounter csiClient is nil"
)
t
.
Error
(
"mounter csiClient is nil"
)
}
}
if
csiMounter
.
driverMode
!=
test
.
driverMode
{
if
csiMounter
.
driverMode
!=
test
.
driverMode
{
...
@@ -732,7 +733,8 @@ func TestPluginNewMounterWithInline(t *testing.T) {
...
@@ -732,7 +733,8 @@ func TestPluginNewMounterWithInline(t *testing.T) {
if
string
(
csiMounter
.
podUID
)
!=
string
(
test
.
podUID
)
{
if
string
(
csiMounter
.
podUID
)
!=
string
(
test
.
podUID
)
{
t
.
Error
(
"mounter podUID not set"
)
t
.
Error
(
"mounter podUID not set"
)
}
}
if
csiMounter
.
csiClient
==
nil
{
csiClient
,
err
:=
csiMounter
.
csiClientGetter
.
Get
()
if
csiClient
==
nil
{
t
.
Error
(
"mounter csiClient is nil"
)
t
.
Error
(
"mounter csiClient is nil"
)
}
}
if
csiMounter
.
driverMode
!=
test
.
driverMode
{
if
csiMounter
.
driverMode
!=
test
.
driverMode
{
...
@@ -815,8 +817,9 @@ func TestPluginNewUnmounter(t *testing.T) {
...
@@ -815,8 +817,9 @@ func TestPluginNewUnmounter(t *testing.T) {
t
.
Error
(
"podUID not set"
)
t
.
Error
(
"podUID not set"
)
}
}
if
csiUnmounter
.
csiClient
==
nil
{
csiClient
,
err
:=
csiUnmounter
.
csiClientGetter
.
Get
()
t
.
Error
(
"unmounter csiClient is nil"
)
if
csiClient
==
nil
{
t
.
Error
(
"mounter csiClient is nil"
)
}
}
}
}
...
@@ -932,7 +935,8 @@ func TestPluginNewBlockMapper(t *testing.T) {
...
@@ -932,7 +935,8 @@ func TestPluginNewBlockMapper(t *testing.T) {
if
csiMapper
.
podUID
==
types
.
UID
(
""
)
{
if
csiMapper
.
podUID
==
types
.
UID
(
""
)
{
t
.
Error
(
"CSI block mapper missing pod.UID"
)
t
.
Error
(
"CSI block mapper missing pod.UID"
)
}
}
if
csiMapper
.
csiClient
==
nil
{
csiClient
,
err
:=
csiMapper
.
csiClientGetter
.
Get
()
if
csiClient
==
nil
{
t
.
Error
(
"mapper csiClient is nil"
)
t
.
Error
(
"mapper csiClient is nil"
)
}
}
...
@@ -994,7 +998,8 @@ func TestPluginNewUnmapper(t *testing.T) {
...
@@ -994,7 +998,8 @@ func TestPluginNewUnmapper(t *testing.T) {
t
.
Error
(
"specName not set"
)
t
.
Error
(
"specName not set"
)
}
}
if
csiUnmapper
.
csiClient
==
nil
{
csiClient
,
err
:=
csiUnmapper
.
csiClientGetter
.
Get
()
if
csiClient
==
nil
{
t
.
Error
(
"unmapper csiClient is nil"
)
t
.
Error
(
"unmapper csiClient is nil"
)
}
}
...
...
pkg/volume/quobyte/quobyte.go
View file @
b1e389e6
...
@@ -254,6 +254,7 @@ func (mounter *quobyteMounter) SetUpAt(dir string, fsGroup *int64) error {
...
@@ -254,6 +254,7 @@ func (mounter *quobyteMounter) SetUpAt(dir string, fsGroup *int64) error {
os
.
MkdirAll
(
dir
,
0750
)
os
.
MkdirAll
(
dir
,
0750
)
var
options
[]
string
var
options
[]
string
options
=
append
(
options
,
"allow-usermapping-in-volumename"
)
if
mounter
.
readOnly
{
if
mounter
.
readOnly
{
options
=
append
(
options
,
"ro"
)
options
=
append
(
options
,
"ro"
)
}
}
...
...
staging/src/k8s.io/apiextensions-apiserver/pkg/apiserver/customresource_discovery_controller.go
View file @
b1e389e6
...
@@ -95,6 +95,7 @@ func (c *DiscoveryController) sync(version schema.GroupVersion) error {
...
@@ -95,6 +95,7 @@ func (c *DiscoveryController) sync(version schema.GroupVersion) error {
}
}
foundThisVersion
:=
false
foundThisVersion
:=
false
var
storageVersionHash
string
for
_
,
v
:=
range
crd
.
Spec
.
Versions
{
for
_
,
v
:=
range
crd
.
Spec
.
Versions
{
if
!
v
.
Served
{
if
!
v
.
Served
{
continue
continue
...
@@ -113,6 +114,9 @@ func (c *DiscoveryController) sync(version schema.GroupVersion) error {
...
@@ -113,6 +114,9 @@ func (c *DiscoveryController) sync(version schema.GroupVersion) error {
if
v
.
Name
==
version
.
Version
{
if
v
.
Name
==
version
.
Version
{
foundThisVersion
=
true
foundThisVersion
=
true
}
}
if
v
.
Storage
{
storageVersionHash
=
discovery
.
StorageVersionHash
(
gv
.
Group
,
gv
.
Version
,
crd
.
Spec
.
Names
.
Kind
)
}
}
}
if
!
foundThisVersion
{
if
!
foundThisVersion
{
...
@@ -127,13 +131,14 @@ func (c *DiscoveryController) sync(version schema.GroupVersion) error {
...
@@ -127,13 +131,14 @@ func (c *DiscoveryController) sync(version schema.GroupVersion) error {
}
}
apiResourcesForDiscovery
=
append
(
apiResourcesForDiscovery
,
metav1
.
APIResource
{
apiResourcesForDiscovery
=
append
(
apiResourcesForDiscovery
,
metav1
.
APIResource
{
Name
:
crd
.
Status
.
AcceptedNames
.
Plural
,
Name
:
crd
.
Status
.
AcceptedNames
.
Plural
,
SingularName
:
crd
.
Status
.
AcceptedNames
.
Singular
,
SingularName
:
crd
.
Status
.
AcceptedNames
.
Singular
,
Namespaced
:
crd
.
Spec
.
Scope
==
apiextensions
.
NamespaceScoped
,
Namespaced
:
crd
.
Spec
.
Scope
==
apiextensions
.
NamespaceScoped
,
Kind
:
crd
.
Status
.
AcceptedNames
.
Kind
,
Kind
:
crd
.
Status
.
AcceptedNames
.
Kind
,
Verbs
:
verbs
,
Verbs
:
verbs
,
ShortNames
:
crd
.
Status
.
AcceptedNames
.
ShortNames
,
ShortNames
:
crd
.
Status
.
AcceptedNames
.
ShortNames
,
Categories
:
crd
.
Status
.
AcceptedNames
.
Categories
,
Categories
:
crd
.
Status
.
AcceptedNames
.
Categories
,
StorageVersionHash
:
storageVersionHash
,
})
})
subresources
,
err
:=
apiextensions
.
GetSubresourcesForVersion
(
crd
,
version
.
Version
)
subresources
,
err
:=
apiextensions
.
GetSubresourcesForVersion
(
crd
,
version
.
Version
)
...
...
staging/src/k8s.io/apiserver/pkg/endpoints/discovery/BUILD
View file @
b1e389e6
...
@@ -32,6 +32,7 @@ go_library(
...
@@ -32,6 +32,7 @@ go_library(
"group.go",
"group.go",
"legacy.go",
"legacy.go",
"root.go",
"root.go",
"storageversionhash.go",
"util.go",
"util.go",
"version.go",
"version.go",
],
],
...
...
staging/src/k8s.io/apiserver/pkg/endpoints/discovery/storageversionhash.go
0 → 100644
View file @
b1e389e6
/*
Copyright 2019 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package
discovery
import
(
"crypto/sha256"
"encoding/base64"
)
// StorageVersionHash calculates the storage version hash for a
// <group/version/kind> tuple.
// WARNING: this function is subject to change. Clients shouldn't depend on
// this function.
func
StorageVersionHash
(
group
,
version
,
kind
string
)
string
{
gvk
:=
group
+
"/"
+
version
+
"/"
+
kind
if
gvk
==
""
{
return
""
}
bytes
:=
sha256
.
Sum256
([]
byte
(
gvk
))
// Assuming there are N kinds in the cluster, and the hash is X-byte long,
// the chance of colliding hash P(N,X) approximates to 1-e^(-(N^2)/2^(8X+1)).
// P(10,000, 8) ~= 2.7*10^(-12), which is low enough.
// See https://en.wikipedia.org/wiki/Birthday_problem#Approximations.
return
base64
.
StdEncoding
.
EncodeToString
(
bytes
[
:
8
])
}
staging/src/k8s.io/apiserver/pkg/endpoints/installer.go
View file @
b1e389e6
...
@@ -33,6 +33,7 @@ import (
...
@@ -33,6 +33,7 @@ import (
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/types"
"k8s.io/apiserver/pkg/admission"
"k8s.io/apiserver/pkg/admission"
"k8s.io/apiserver/pkg/endpoints/discovery"
"k8s.io/apiserver/pkg/endpoints/handlers"
"k8s.io/apiserver/pkg/endpoints/handlers"
"k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager"
"k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager"
"k8s.io/apiserver/pkg/endpoints/handlers/negotiation"
"k8s.io/apiserver/pkg/endpoints/handlers/negotiation"
...
@@ -133,6 +134,20 @@ func (a *APIInstaller) newWebService() *restful.WebService {
...
@@ -133,6 +134,20 @@ func (a *APIInstaller) newWebService() *restful.WebService {
return
ws
return
ws
}
}
// calculate the storage gvk, the gvk objects are converted to before persisted to the etcd.
func
getStorageVersionKind
(
storageVersioner
runtime
.
GroupVersioner
,
storage
rest
.
Storage
,
typer
runtime
.
ObjectTyper
)
(
schema
.
GroupVersionKind
,
error
)
{
object
:=
storage
.
New
()
fqKinds
,
_
,
err
:=
typer
.
ObjectKinds
(
object
)
if
err
!=
nil
{
return
schema
.
GroupVersionKind
{},
err
}
gvk
,
ok
:=
storageVersioner
.
KindForGroupVersionKinds
(
fqKinds
)
if
!
ok
{
return
schema
.
GroupVersionKind
{},
fmt
.
Errorf
(
"cannot find the storage version kind for %v"
,
reflect
.
TypeOf
(
object
))
}
return
gvk
,
nil
}
// GetResourceKind returns the external group version kind registered for the given storage
// GetResourceKind returns the external group version kind registered for the given storage
// object. If the storage object is a subresource and has an override supplied for it, it returns
// object. If the storage object is a subresource and has an override supplied for it, it returns
// the group version kind supplied in the override.
// the group version kind supplied in the override.
...
@@ -227,6 +242,7 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag
...
@@ -227,6 +242,7 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag
watcher
,
isWatcher
:=
storage
.
(
rest
.
Watcher
)
watcher
,
isWatcher
:=
storage
.
(
rest
.
Watcher
)
connecter
,
isConnecter
:=
storage
.
(
rest
.
Connecter
)
connecter
,
isConnecter
:=
storage
.
(
rest
.
Connecter
)
storageMeta
,
isMetadata
:=
storage
.
(
rest
.
StorageMetadata
)
storageMeta
,
isMetadata
:=
storage
.
(
rest
.
StorageMetadata
)
storageVersionProvider
,
isStorageVersionProvider
:=
storage
.
(
rest
.
StorageVersionProvider
)
if
!
isMetadata
{
if
!
isMetadata
{
storageMeta
=
defaultStorageMetadata
{}
storageMeta
=
defaultStorageMetadata
{}
}
}
...
@@ -365,6 +381,17 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag
...
@@ -365,6 +381,17 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag
tableProvider
,
_
:=
storage
.
(
rest
.
TableConvertor
)
tableProvider
,
_
:=
storage
.
(
rest
.
TableConvertor
)
var
apiResource
metav1
.
APIResource
var
apiResource
metav1
.
APIResource
if
utilfeature
.
DefaultFeatureGate
.
Enabled
(
features
.
StorageVersionHash
)
&&
isStorageVersionProvider
&&
storageVersionProvider
.
StorageVersion
()
!=
nil
{
versioner
:=
storageVersionProvider
.
StorageVersion
()
gvk
,
err
:=
getStorageVersionKind
(
versioner
,
storage
,
a
.
group
.
Typer
)
if
err
!=
nil
{
return
nil
,
err
}
apiResource
.
StorageVersionHash
=
discovery
.
StorageVersionHash
(
gvk
.
Group
,
gvk
.
Version
,
gvk
.
Kind
)
}
// Get the list of actions for the given scope.
// Get the list of actions for the given scope.
switch
{
switch
{
case
!
namespaceScoped
:
case
!
namespaceScoped
:
...
...
staging/src/k8s.io/apiserver/pkg/features/kube_features.go
View file @
b1e389e6
...
@@ -89,6 +89,13 @@ const (
...
@@ -89,6 +89,13 @@ const (
// Server-side apply. Merging happens on the server.
// Server-side apply. Merging happens on the server.
ServerSideApply
utilfeature
.
Feature
=
"ServerSideApply"
ServerSideApply
utilfeature
.
Feature
=
"ServerSideApply"
// owner: @caesarxuchao
// alpha: v1.14
//
// Allow apiservers to expose the storage version hash in the discovery
// document.
StorageVersionHash
utilfeature
.
Feature
=
"StorageVersionHash"
// owner: @ksubrmnn
// owner: @ksubrmnn
// alpha: v1.14
// alpha: v1.14
//
//
...
@@ -118,6 +125,7 @@ var defaultKubernetesFeatureGates = map[utilfeature.Feature]utilfeature.FeatureS
...
@@ -118,6 +125,7 @@ var defaultKubernetesFeatureGates = map[utilfeature.Feature]utilfeature.FeatureS
APIListChunking
:
{
Default
:
true
,
PreRelease
:
utilfeature
.
Beta
},
APIListChunking
:
{
Default
:
true
,
PreRelease
:
utilfeature
.
Beta
},
DryRun
:
{
Default
:
true
,
PreRelease
:
utilfeature
.
Beta
},
DryRun
:
{
Default
:
true
,
PreRelease
:
utilfeature
.
Beta
},
ServerSideApply
:
{
Default
:
false
,
PreRelease
:
utilfeature
.
Alpha
},
ServerSideApply
:
{
Default
:
false
,
PreRelease
:
utilfeature
.
Alpha
},
StorageVersionHash
:
{
Default
:
false
,
PreRelease
:
utilfeature
.
Alpha
},
WinOverlay
:
{
Default
:
false
,
PreRelease
:
utilfeature
.
Alpha
},
WinOverlay
:
{
Default
:
false
,
PreRelease
:
utilfeature
.
Alpha
},
WinDSR
:
{
Default
:
false
,
PreRelease
:
utilfeature
.
Alpha
},
WinDSR
:
{
Default
:
false
,
PreRelease
:
utilfeature
.
Alpha
},
}
}
staging/src/k8s.io/apiserver/pkg/registry/generic/registry/store.go
View file @
b1e389e6
...
@@ -177,6 +177,12 @@ type Store struct {
...
@@ -177,6 +177,12 @@ type Store struct {
// resource. It is wrapped into a "DryRunnableStorage" that will
// resource. It is wrapped into a "DryRunnableStorage" that will
// either pass-through or simply dry-run.
// either pass-through or simply dry-run.
Storage
DryRunnableStorage
Storage
DryRunnableStorage
// StorageVersioner outputs the <group/version/kind> an object will be
// converted to before persisted in etcd, given a list of possible
// kinds of the object.
// If the StorageVersioner is nil, apiserver will leave the
// storageVersionHash as empty in the discovery document.
StorageVersioner
runtime
.
GroupVersioner
// Called to cleanup clients used by the underlying Storage; optional.
// Called to cleanup clients used by the underlying Storage; optional.
DestroyFunc
func
()
DestroyFunc
func
()
}
}
...
@@ -1287,6 +1293,7 @@ func (e *Store) CompleteWithOptions(options *generic.StoreOptions) error {
...
@@ -1287,6 +1293,7 @@ func (e *Store) CompleteWithOptions(options *generic.StoreOptions) error {
attrFunc
,
attrFunc
,
triggerFunc
,
triggerFunc
,
)
)
e
.
StorageVersioner
=
opts
.
StorageConfig
.
EncodeVersioner
if
opts
.
CountMetricPollPeriod
>
0
{
if
opts
.
CountMetricPollPeriod
>
0
{
stopFunc
:=
e
.
startObservingCount
(
opts
.
CountMetricPollPeriod
)
stopFunc
:=
e
.
startObservingCount
(
opts
.
CountMetricPollPeriod
)
...
@@ -1327,3 +1334,7 @@ func (e *Store) ConvertToTable(ctx context.Context, object runtime.Object, table
...
@@ -1327,3 +1334,7 @@ func (e *Store) ConvertToTable(ctx context.Context, object runtime.Object, table
}
}
return
rest
.
NewDefaultTableConvertor
(
e
.
qualifiedResourceFromContext
(
ctx
))
.
ConvertToTable
(
ctx
,
object
,
tableOptions
)
return
rest
.
NewDefaultTableConvertor
(
e
.
qualifiedResourceFromContext
(
ctx
))
.
ConvertToTable
(
ctx
,
object
,
tableOptions
)
}
}
func
(
e
*
Store
)
StorageVersion
()
runtime
.
GroupVersioner
{
return
e
.
StorageVersioner
}
staging/src/k8s.io/apiserver/pkg/registry/rest/rest.go
View file @
b1e389e6
...
@@ -332,3 +332,12 @@ type StorageMetadata interface {
...
@@ -332,3 +332,12 @@ type StorageMetadata interface {
// it is not nil. Only the type of the return object matters, the value will be ignored.
// it is not nil. Only the type of the return object matters, the value will be ignored.
ProducesObject
(
verb
string
)
interface
{}
ProducesObject
(
verb
string
)
interface
{}
}
}
// StorageVersionProvider is an optional interface that a storage object can
// implement if it wishes to disclose its storage version.
type
StorageVersionProvider
interface
{
// StorageVersion returns a group versioner, which will outputs the gvk
// an object will be converted to before persisted in etcd, given a
// list of kinds the object might belong to.
StorageVersion
()
runtime
.
GroupVersioner
}
staging/src/k8s.io/apiserver/pkg/server/storage/storage_codec.go
View file @
b1e389e6
...
@@ -40,15 +40,15 @@ type StorageCodecConfig struct {
...
@@ -40,15 +40,15 @@ type StorageCodecConfig struct {
// NewStorageCodec assembles a storage codec for the provided storage media type, the provided serializer, and the requested
// NewStorageCodec assembles a storage codec for the provided storage media type, the provided serializer, and the requested
// storage and memory versions.
// storage and memory versions.
func
NewStorageCodec
(
opts
StorageCodecConfig
)
(
runtime
.
Codec
,
error
)
{
func
NewStorageCodec
(
opts
StorageCodecConfig
)
(
runtime
.
Codec
,
runtime
.
GroupVersioner
,
error
)
{
mediaType
,
_
,
err
:=
mime
.
ParseMediaType
(
opts
.
StorageMediaType
)
mediaType
,
_
,
err
:=
mime
.
ParseMediaType
(
opts
.
StorageMediaType
)
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"%q is not a valid mime-type"
,
opts
.
StorageMediaType
)
return
nil
,
nil
,
fmt
.
Errorf
(
"%q is not a valid mime-type"
,
opts
.
StorageMediaType
)
}
}
serializer
,
ok
:=
runtime
.
SerializerInfoForMediaType
(
opts
.
StorageSerializer
.
SupportedMediaTypes
(),
mediaType
)
serializer
,
ok
:=
runtime
.
SerializerInfoForMediaType
(
opts
.
StorageSerializer
.
SupportedMediaTypes
(),
mediaType
)
if
!
ok
{
if
!
ok
{
return
nil
,
fmt
.
Errorf
(
"unable to find serializer for %q"
,
mediaType
)
return
nil
,
nil
,
fmt
.
Errorf
(
"unable to find serializer for %q"
,
mediaType
)
}
}
s
:=
serializer
.
Serializer
s
:=
serializer
.
Serializer
...
@@ -74,14 +74,16 @@ func NewStorageCodec(opts StorageCodecConfig) (runtime.Codec, error) {
...
@@ -74,14 +74,16 @@ func NewStorageCodec(opts StorageCodecConfig) (runtime.Codec, error) {
decoders
=
opts
.
DecoderDecoratorFn
(
decoders
)
decoders
=
opts
.
DecoderDecoratorFn
(
decoders
)
}
}
encodeVersioner
:=
runtime
.
NewMultiGroupVersioner
(
opts
.
StorageVersion
,
schema
.
GroupKind
{
Group
:
opts
.
StorageVersion
.
Group
},
schema
.
GroupKind
{
Group
:
opts
.
MemoryVersion
.
Group
},
)
// Ensure the storage receives the correct version.
// Ensure the storage receives the correct version.
encoder
=
opts
.
StorageSerializer
.
EncoderForVersion
(
encoder
=
opts
.
StorageSerializer
.
EncoderForVersion
(
encoder
,
encoder
,
runtime
.
NewMultiGroupVersioner
(
encodeVersioner
,
opts
.
StorageVersion
,
schema
.
GroupKind
{
Group
:
opts
.
StorageVersion
.
Group
},
schema
.
GroupKind
{
Group
:
opts
.
MemoryVersion
.
Group
},
),
)
)
decoder
:=
opts
.
StorageSerializer
.
DecoderToVersion
(
decoder
:=
opts
.
StorageSerializer
.
DecoderToVersion
(
recognizer
.
NewDecoder
(
decoders
...
),
recognizer
.
NewDecoder
(
decoders
...
),
...
@@ -92,5 +94,5 @@ func NewStorageCodec(opts StorageCodecConfig) (runtime.Codec, error) {
...
@@ -92,5 +94,5 @@ func NewStorageCodec(opts StorageCodecConfig) (runtime.Codec, error) {
),
),
)
)
return
runtime
.
NewCodec
(
encoder
,
decoder
),
nil
return
runtime
.
NewCodec
(
encoder
,
decoder
),
encodeVersioner
,
nil
}
}
staging/src/k8s.io/apiserver/pkg/server/storage/storage_factory.go
View file @
b1e389e6
...
@@ -86,7 +86,7 @@ type DefaultStorageFactory struct {
...
@@ -86,7 +86,7 @@ type DefaultStorageFactory struct {
APIResourceConfigSource
APIResourceConfigSource
APIResourceConfigSource
APIResourceConfigSource
// newStorageCodecFn exists to be overwritten for unit testing.
// newStorageCodecFn exists to be overwritten for unit testing.
newStorageCodecFn
func
(
opts
StorageCodecConfig
)
(
codec
runtime
.
Codec
,
err
error
)
newStorageCodecFn
func
(
opts
StorageCodecConfig
)
(
codec
runtime
.
Codec
,
e
ncodeVersioner
runtime
.
GroupVersioner
,
e
rr
error
)
}
}
type
groupResourceOverrides
struct
{
type
groupResourceOverrides
struct
{
...
@@ -278,7 +278,7 @@ func (s *DefaultStorageFactory) NewConfig(groupResource schema.GroupResource) (*
...
@@ -278,7 +278,7 @@ func (s *DefaultStorageFactory) NewConfig(groupResource schema.GroupResource) (*
}
}
codecConfig
.
Config
=
storageConfig
codecConfig
.
Config
=
storageConfig
storageConfig
.
Codec
,
err
=
s
.
newStorageCodecFn
(
codecConfig
)
storageConfig
.
Codec
,
storageConfig
.
EncodeVersioner
,
err
=
s
.
newStorageCodecFn
(
codecConfig
)
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
err
return
nil
,
err
}
}
...
...
staging/src/k8s.io/apiserver/pkg/storage/storagebackend/config.go
View file @
b1e389e6
...
@@ -57,6 +57,11 @@ type Config struct {
...
@@ -57,6 +57,11 @@ type Config struct {
Paging
bool
Paging
bool
Codec
runtime
.
Codec
Codec
runtime
.
Codec
// EncodeVersioner is the same groupVersioner used to build the
// storage encoder. Given a list of kinds the input object might belong
// to, the EncodeVersioner outputs the gvk the object will be
// converted to before persisted in etcd.
EncodeVersioner
runtime
.
GroupVersioner
// Transformer allows the value to be transformed prior to persisting into etcd.
// Transformer allows the value to be transformed prior to persisting into etcd.
Transformer
value
.
Transformer
Transformer
value
.
Transformer
...
...
staging/src/k8s.io/client-go/tools/watch/retrywatcher.go
View file @
b1e389e6
...
@@ -184,13 +184,17 @@ func (rw *RetryWatcher) doReceive() (bool, time.Duration) {
...
@@ -184,13 +184,17 @@ func (rw *RetryWatcher) doReceive() (bool, time.Duration) {
continue
continue
case
watch
.
Error
:
case
watch
.
Error
:
status
,
ok
:=
event
.
Object
.
(
*
metav1
.
Status
)
// This round trip allows us to handle unstructured status
errObject
:=
apierrors
.
FromObject
(
event
.
Object
)
statusErr
,
ok
:=
errObject
.
(
*
apierrors
.
StatusError
)
if
!
ok
{
if
!
ok
{
klog
.
Error
(
spew
.
Sprintf
(
"Received an error which is not *metav1.Status but %#+v"
,
event
.
Object
))
klog
.
Error
(
spew
.
Sprintf
(
"Received an error which is not *metav1.Status but %#+v"
,
event
.
Object
))
// Retry unknown errors
// Retry unknown errors
return
false
,
0
return
false
,
0
}
}
status
:=
statusErr
.
ErrStatus
statusDelay
:=
time
.
Duration
(
0
)
statusDelay
:=
time
.
Duration
(
0
)
if
status
.
Details
!=
nil
{
if
status
.
Details
!=
nil
{
statusDelay
=
time
.
Duration
(
status
.
Details
.
RetryAfterSeconds
)
*
time
.
Second
statusDelay
=
time
.
Duration
(
status
.
Details
.
RetryAfterSeconds
)
*
time
.
Second
...
...
staging/src/k8s.io/sample-apiserver/pkg/cmd/server/BUILD
View file @
b1e389e6
...
@@ -11,10 +11,13 @@ go_library(
...
@@ -11,10 +11,13 @@ go_library(
importmap = "k8s.io/kubernetes/vendor/k8s.io/sample-apiserver/pkg/cmd/server",
importmap = "k8s.io/kubernetes/vendor/k8s.io/sample-apiserver/pkg/cmd/server",
importpath = "k8s.io/sample-apiserver/pkg/cmd/server",
importpath = "k8s.io/sample-apiserver/pkg/cmd/server",
deps = [
deps = [
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/errors:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/errors:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/admission:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/admission:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/server:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/server:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/server/options:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/server/options:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library",
"//staging/src/k8s.io/sample-apiserver/pkg/admission/plugin/banflunder:go_default_library",
"//staging/src/k8s.io/sample-apiserver/pkg/admission/plugin/banflunder:go_default_library",
"//staging/src/k8s.io/sample-apiserver/pkg/admission/wardleinitializer:go_default_library",
"//staging/src/k8s.io/sample-apiserver/pkg/admission/wardleinitializer:go_default_library",
"//staging/src/k8s.io/sample-apiserver/pkg/apis/wardle/v1alpha1:go_default_library",
"//staging/src/k8s.io/sample-apiserver/pkg/apis/wardle/v1alpha1:go_default_library",
...
...
staging/src/k8s.io/sample-apiserver/pkg/cmd/server/start.go
View file @
b1e389e6
...
@@ -23,10 +23,13 @@ import (
...
@@ -23,10 +23,13 @@ import (
"github.com/spf13/cobra"
"github.com/spf13/cobra"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
utilerrors
"k8s.io/apimachinery/pkg/util/errors"
utilerrors
"k8s.io/apimachinery/pkg/util/errors"
"k8s.io/apiserver/pkg/admission"
"k8s.io/apiserver/pkg/admission"
genericapiserver
"k8s.io/apiserver/pkg/server"
genericapiserver
"k8s.io/apiserver/pkg/server"
genericoptions
"k8s.io/apiserver/pkg/server/options"
genericoptions
"k8s.io/apiserver/pkg/server/options"
utilfeature
"k8s.io/apiserver/pkg/util/feature"
"k8s.io/sample-apiserver/pkg/admission/plugin/banflunder"
"k8s.io/sample-apiserver/pkg/admission/plugin/banflunder"
"k8s.io/sample-apiserver/pkg/admission/wardleinitializer"
"k8s.io/sample-apiserver/pkg/admission/wardleinitializer"
"k8s.io/sample-apiserver/pkg/apis/wardle/v1alpha1"
"k8s.io/sample-apiserver/pkg/apis/wardle/v1alpha1"
...
@@ -56,7 +59,7 @@ func NewWardleServerOptions(out, errOut io.Writer) *WardleServerOptions {
...
@@ -56,7 +59,7 @@ func NewWardleServerOptions(out, errOut io.Writer) *WardleServerOptions {
StdOut
:
out
,
StdOut
:
out
,
StdErr
:
errOut
,
StdErr
:
errOut
,
}
}
o
.
RecommendedOptions
.
Etcd
.
StorageConfig
.
EncodeVersioner
=
runtime
.
NewMultiGroupVersioner
(
v1alpha1
.
SchemeGroupVersion
,
schema
.
GroupKind
{
Group
:
v1alpha1
.
GroupName
})
return
o
return
o
}
}
...
@@ -83,6 +86,7 @@ func NewCommandStartWardleServer(defaults *WardleServerOptions, stopCh <-chan st
...
@@ -83,6 +86,7 @@ func NewCommandStartWardleServer(defaults *WardleServerOptions, stopCh <-chan st
flags
:=
cmd
.
Flags
()
flags
:=
cmd
.
Flags
()
o
.
RecommendedOptions
.
AddFlags
(
flags
)
o
.
RecommendedOptions
.
AddFlags
(
flags
)
utilfeature
.
DefaultMutableFeatureGate
.
AddFlag
(
flags
)
return
cmd
return
cmd
}
}
...
...
test/e2e/apimachinery/BUILD
View file @
b1e389e6
...
@@ -15,6 +15,7 @@ go_library(
...
@@ -15,6 +15,7 @@ go_library(
"crd_publish_openapi.go",
"crd_publish_openapi.go",
"crd_watch.go",
"crd_watch.go",
"custom_resource_definition.go",
"custom_resource_definition.go",
"discovery.go",
"etcd_failure.go",
"etcd_failure.go",
"framework.go",
"framework.go",
"garbage_collector.go",
"garbage_collector.go",
...
@@ -65,6 +66,7 @@ go_library(
...
@@ -65,6 +66,7 @@ go_library(
"//staging/src/k8s.io/apimachinery/pkg/util/wait:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/wait:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/yaml:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/yaml:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/watch:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/watch:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/endpoints/discovery:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/storage/names:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/storage/names:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/storage/storagebackend:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/storage/storagebackend:go_default_library",
"//staging/src/k8s.io/client-go/discovery:go_default_library",
"//staging/src/k8s.io/client-go/discovery:go_default_library",
...
...
test/e2e/apimachinery/discovery.go
0 → 100644
View file @
b1e389e6
/*
Copyright 2019 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package
apimachinery
import
(
utilversion
"k8s.io/apimachinery/pkg/util/version"
"k8s.io/apiserver/pkg/endpoints/discovery"
"k8s.io/kubernetes/test/e2e/framework"
.
"github.com/onsi/ginkgo"
)
var
storageVersionServerVersion
=
utilversion
.
MustParseSemantic
(
"v1.13.99"
)
var
_
=
SIGDescribe
(
"Discovery"
,
func
()
{
f
:=
framework
.
NewDefaultFramework
(
"discovery"
)
var
namespaceName
string
BeforeEach
(
func
()
{
namespaceName
=
f
.
Namespace
.
Name
framework
.
SkipUnlessServerVersionGTE
(
storageVersionServerVersion
,
f
.
ClientSet
.
Discovery
())
By
(
"Setting up server cert"
)
setupServerCert
(
namespaceName
,
serviceName
)
})
It
(
"[Feature:StorageVersionHash] Custom resource should have storage version hash"
,
func
()
{
testcrd
,
err
:=
framework
.
CreateTestCRD
(
f
)
if
err
!=
nil
{
return
}
defer
testcrd
.
CleanUp
()
spec
:=
testcrd
.
Crd
.
Spec
resources
,
err
:=
testcrd
.
ApiExtensionClient
.
Discovery
()
.
ServerResourcesForGroupVersion
(
spec
.
Group
+
"/"
+
spec
.
Versions
[
0
]
.
Name
)
if
err
!=
nil
{
framework
.
Failf
(
"failed to find the discovery doc for %v: %v"
,
resources
,
err
)
}
found
:=
false
var
storageVersion
string
for
_
,
v
:=
range
spec
.
Versions
{
if
v
.
Storage
{
storageVersion
=
v
.
Name
}
}
// DISCLAIMER: the algorithm of deriving the storageVersionHash
// is an implementation detail, which shouldn't be relied on by
// the clients. The following calculation is for test purpose
// only.
expected
:=
discovery
.
StorageVersionHash
(
spec
.
Group
,
storageVersion
,
spec
.
Names
.
Kind
)
for
_
,
r
:=
range
resources
.
APIResources
{
if
r
.
Name
==
spec
.
Names
.
Plural
{
found
=
true
if
r
.
StorageVersionHash
!=
expected
{
framework
.
Failf
(
"expected storageVersionHash of %s/%s/%s to be %s, got %s"
,
r
.
Group
,
r
.
Version
,
r
.
Name
,
expected
,
r
.
StorageVersionHash
)
}
}
}
if
!
found
{
framework
.
Failf
(
"didn't find resource %s in the discovery doc"
,
spec
.
Names
.
Plural
)
}
})
})
test/e2e/common/node_lease.go
View file @
b1e389e6
...
@@ -101,20 +101,37 @@ var _ = framework.KubeDescribe("NodeLease", func() {
...
@@ -101,20 +101,37 @@ var _ = framework.KubeDescribe("NodeLease", func() {
By
(
"verify NodeStatus report period is longer than lease duration"
)
By
(
"verify NodeStatus report period is longer than lease duration"
)
// NodeStatus is reported from node to master when there is some change or
// NodeStatus is reported from node to master when there is some change or
// enough time has passed. So for here, keep checking the time diff
// enough time has passed. So for here, keep checking the time diff
// between 2 NodeStatus report, until it is longer than lease duration (
// between 2 NodeStatus report, until it is longer than lease duration
// the same as nodeMonitorGracePeriod).
// (the same as nodeMonitorGracePeriod), or it doesn't change for at least leaseDuration
heartbeatTime
:=
getNextReadyConditionHeartbeatTime
(
f
.
ClientSet
,
nodeName
,
metav1
.
Time
{})
lastHeartbeatTime
:=
getReadyConditionHeartbeatTime
(
f
.
ClientSet
,
nodeName
)
lastObserved
:=
time
.
Now
()
Eventually
(
func
()
error
{
Eventually
(
func
()
error
{
nextHeartbeatTime
:=
getNextReadyConditionHeartbeatTime
(
f
.
ClientSet
,
nodeName
,
heartbeatTime
)
currentHeartbeatTime
:=
getReadyConditionHeartbeatTime
(
f
.
ClientSet
,
nodeName
)
currentObserved
:=
time
.
Now
()
if
nextHeartbeatTime
.
Time
.
After
(
heartbeatTime
.
Time
.
Add
(
leaseDuration
))
{
return
nil
switch
{
case
currentHeartbeatTime
==
lastHeartbeatTime
:
if
currentObserved
.
Sub
(
lastObserved
)
>
2
*
leaseDuration
{
// heartbeat hasn't changed while watching for at least 2*leaseDuration, success!
framework
.
Logf
(
"node status heartbeat is unchanged for %s, was waiting for at least %s, success!"
,
currentObserved
.
Sub
(
lastObserved
),
2
*
leaseDuration
)
return
nil
}
framework
.
Logf
(
"node status heartbeat is unchanged for %s, waiting for %s"
,
currentObserved
.
Sub
(
lastObserved
),
2
*
leaseDuration
)
return
fmt
.
Errorf
(
"node status heartbeat is unchanged for %s, waiting for %s"
,
currentObserved
.
Sub
(
lastObserved
),
2
*
leaseDuration
)
case
currentHeartbeatTime
!=
lastHeartbeatTime
:
if
currentHeartbeatTime
.
Sub
(
lastHeartbeatTime
)
>
leaseDuration
{
// heartbeat time changed, but the diff was greater than leaseDuration, success!
framework
.
Logf
(
"node status heartbeat changed in %s, was waiting for at least %s, success!"
,
currentHeartbeatTime
.
Sub
(
lastHeartbeatTime
),
leaseDuration
)
return
nil
}
lastHeartbeatTime
=
currentHeartbeatTime
lastObserved
=
currentObserved
framework
.
Logf
(
"node status heartbeat changed in %s, waiting for %s"
,
currentHeartbeatTime
.
Sub
(
lastHeartbeatTime
),
leaseDuration
)
return
fmt
.
Errorf
(
"node status heartbeat changed in %s, waiting for %s"
,
currentHeartbeatTime
.
Sub
(
lastHeartbeatTime
),
leaseDuration
)
}
}
heartbeatTime
=
nextHeartbeatTime
return
nil
return
fmt
.
Errorf
(
"node status report period is shorter than lease duration"
)
},
5
*
time
.
Minute
,
time
.
Second
)
.
Should
(
BeNil
())
// Enter next round immediately.
},
5
*
time
.
Minute
,
time
.
Nanosecond
)
.
Should
(
BeNil
())
By
(
"verify node is still in ready status even though node status report is infrequent"
)
By
(
"verify node is still in ready status even though node status report is infrequent"
)
// This check on node status is only meaningful when this e2e test is
// This check on node status is only meaningful when this e2e test is
...
@@ -128,22 +145,12 @@ var _ = framework.KubeDescribe("NodeLease", func() {
...
@@ -128,22 +145,12 @@ var _ = framework.KubeDescribe("NodeLease", func() {
})
})
})
})
func
getNextReadyConditionHeartbeatTime
(
clientSet
clientset
.
Interface
,
nodeName
string
,
prevHeartbeatTime
metav1
.
Time
)
metav1
.
Time
{
func
getReadyConditionHeartbeatTime
(
clientSet
clientset
.
Interface
,
nodeName
string
)
time
.
Time
{
var
newHeartbeatTime
metav1
.
Time
node
,
err
:=
clientSet
.
CoreV1
()
.
Nodes
()
.
Get
(
nodeName
,
metav1
.
GetOptions
{})
Eventually
(
func
()
error
{
Expect
(
err
)
.
To
(
BeNil
())
node
,
err
:=
clientSet
.
CoreV1
()
.
Nodes
()
.
Get
(
nodeName
,
metav1
.
GetOptions
{})
_
,
readyCondition
:=
testutils
.
GetNodeCondition
(
&
node
.
Status
,
corev1
.
NodeReady
)
if
err
!=
nil
{
Expect
(
readyCondition
.
Status
)
.
To
(
Equal
(
corev1
.
ConditionTrue
))
return
err
return
readyCondition
.
LastHeartbeatTime
.
Time
}
_
,
readyCondition
:=
testutils
.
GetNodeCondition
(
&
node
.
Status
,
corev1
.
NodeReady
)
Expect
(
readyCondition
.
Status
)
.
To
(
Equal
(
corev1
.
ConditionTrue
))
newHeartbeatTime
=
readyCondition
.
LastHeartbeatTime
if
prevHeartbeatTime
.
Before
(
&
newHeartbeatTime
)
{
return
nil
}
return
fmt
.
Errorf
(
"heartbeat has not changed yet"
)
},
5
*
time
.
Minute
,
5
*
time
.
Second
)
.
Should
(
BeNil
())
return
newHeartbeatTime
}
}
func
expectLease
(
lease
*
coordv1beta1
.
Lease
,
nodeName
string
)
error
{
func
expectLease
(
lease
*
coordv1beta1
.
Lease
,
nodeName
string
)
error
{
...
...
test/images/audit-proxy/Dockerfile
View file @
b1e389e6
...
@@ -12,6 +12,6 @@
...
@@ -12,6 +12,6 @@
# See the License for the specific language governing permissions and
# See the License for the specific language governing permissions and
# limitations under the License.
# limitations under the License.
FROM
scratch
FROM
gcr.io/distroless/static:latest
COPY
audit-proxy /
COPY
audit-proxy /
ENTRYPOINT
["/audit-proxy"]
ENTRYPOINT
["/audit-proxy"]
test/images/audit-proxy/VERSION
View file @
b1e389e6
1.
0
1.
1
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment