| ... | ... |
@@ -132,15 +132,21 @@ type NodeConfig struct {
|
| 132 | 132 |
IPTablesSyncPeriod string |
| 133 | 133 |
|
| 134 | 134 |
// VolumeConfig contains options for configuring volumes on the node. |
| 135 |
- VolumeConfig VolumeConfig |
|
| 135 |
+ VolumeConfig NodeVolumeConfig |
|
| 136 | 136 |
} |
| 137 | 137 |
|
| 138 |
-// VolumeConfig contains options for configuring volumes on the node. |
|
| 139 |
-type VolumeConfig struct {
|
|
| 138 |
+// NodeVolumeConfig contains options for configuring volumes on the node. |
|
| 139 |
+type NodeVolumeConfig struct {
|
|
| 140 | 140 |
// LocalQuota contains options for controlling local volume quota on the node. |
| 141 | 141 |
LocalQuota LocalQuota |
| 142 | 142 |
} |
| 143 | 143 |
|
| 144 |
+// MasterVolumeConfig contains options for configuring volume plugins in the master node. |
|
| 145 |
+type MasterVolumeConfig struct {
|
|
| 146 |
+ // DynamicProvisioningEnabled is a boolean that toggles dynamic provisioning off when false, defaults to true |
|
| 147 |
+ DynamicProvisioningEnabled bool |
|
| 148 |
+} |
|
| 149 |
+ |
|
| 144 | 150 |
// LocalQuota contains options for controlling local volume quota on the node. |
| 145 | 151 |
type LocalQuota struct {
|
| 146 | 152 |
// PerFSGroup can be specified to enable a quota on local storage use per unique FSGroup ID. |
| ... | ... |
@@ -279,6 +285,9 @@ type MasterConfig struct {
|
| 279 | 279 |
|
| 280 | 280 |
// NetworkConfig to be passed to the compiled in network plugin |
| 281 | 281 |
NetworkConfig MasterNetworkConfig |
| 282 |
+ |
|
| 283 |
+ // VolumeConfig contains options for configuring volumes on the node. |
|
| 284 |
+ VolumeConfig MasterVolumeConfig |
|
| 282 | 285 |
} |
| 283 | 286 |
|
| 284 | 287 |
type ImagePolicyConfig struct {
|
| ... | ... |
@@ -307,6 +307,15 @@ func addConversionFuncs(scheme *runtime.Scheme) {
|
| 307 | 307 |
out.Location = in.Location |
| 308 | 308 |
return nil |
| 309 | 309 |
}, |
| 310 |
+ func(in *MasterVolumeConfig, out *internal.MasterVolumeConfig, s conversion.Scope) error {
|
|
| 311 |
+ out.DynamicProvisioningEnabled = (in.DynamicProvisioningEnabled == nil) || (*in.DynamicProvisioningEnabled) |
|
| 312 |
+ return nil |
|
| 313 |
+ }, |
|
| 314 |
+ func(in *internal.MasterVolumeConfig, out *MasterVolumeConfig, s conversion.Scope) error {
|
|
| 315 |
+ enabled := in.DynamicProvisioningEnabled |
|
| 316 |
+ out.DynamicProvisioningEnabled = &enabled |
|
| 317 |
+ return nil |
|
| 318 |
+ }, |
|
| 310 | 319 |
api.Convert_resource_Quantity_To_resource_Quantity, |
| 311 | 320 |
) |
| 312 | 321 |
if err != nil {
|
| ... | ... |
@@ -408,6 +408,7 @@ var map_MasterConfig = map[string]string{
|
| 408 | 408 |
"projectConfig": "ProjectConfig holds information about project creation and defaults", |
| 409 | 409 |
"routingConfig": "RoutingConfig holds information about routing and route generation", |
| 410 | 410 |
"networkConfig": "NetworkConfig to be passed to the compiled in network plugin", |
| 411 |
+ "volumeConfig": "MasterVolumeConfig contains options for configuring volume plugins in the master node.", |
|
| 411 | 412 |
} |
| 412 | 413 |
|
| 413 | 414 |
func (MasterConfig) SwaggerDoc() map[string]string {
|
| ... | ... |
@@ -427,6 +428,15 @@ func (MasterNetworkConfig) SwaggerDoc() map[string]string {
|
| 427 | 427 |
return map_MasterNetworkConfig |
| 428 | 428 |
} |
| 429 | 429 |
|
| 430 |
+var map_MasterVolumeConfig = map[string]string{
|
|
| 431 |
+ "": "MasterVolumeConfig contains options for configuring volume plugins in the master node.", |
|
| 432 |
+ "dynamicProvisioningEnabled": "DynamicProvisioningEnabled is a boolean that toggles dynamic provisioning off when false, defaults to true", |
|
| 433 |
+} |
|
| 434 |
+ |
|
| 435 |
+func (MasterVolumeConfig) SwaggerDoc() map[string]string {
|
|
| 436 |
+ return map_MasterVolumeConfig |
|
| 437 |
+} |
|
| 438 |
+ |
|
| 430 | 439 |
var map_NamedCertificate = map[string]string{
|
| 431 | 440 |
"": "NamedCertificate specifies a certificate/key, and the names it should be served for", |
| 432 | 441 |
"names": "Names is a list of DNS names this certificate should be used to secure A name can be a normal DNS name, or can contain leading wildcard segments.", |
| ... | ... |
@@ -484,6 +494,15 @@ func (NodeNetworkConfig) SwaggerDoc() map[string]string {
|
| 484 | 484 |
return map_NodeNetworkConfig |
| 485 | 485 |
} |
| 486 | 486 |
|
| 487 |
+var map_NodeVolumeConfig = map[string]string{
|
|
| 488 |
+ "": "NodeVolumeConfig contains options for configuring volumes on the node.", |
|
| 489 |
+ "localQuota": "LocalQuota contains options for controlling local volume quota on the node.", |
|
| 490 |
+} |
|
| 491 |
+ |
|
| 492 |
+func (NodeVolumeConfig) SwaggerDoc() map[string]string {
|
|
| 493 |
+ return map_NodeVolumeConfig |
|
| 494 |
+} |
|
| 495 |
+ |
|
| 487 | 496 |
var map_OAuthConfig = map[string]string{
|
| 488 | 497 |
"": "OAuthConfig holds the necessary configuration options for OAuth authentication", |
| 489 | 498 |
"masterCA": "MasterCA is the CA for verifying the TLS connection back to the MasterURL.", |
| ... | ... |
@@ -762,12 +781,3 @@ var map_UserAgentMatchingConfig = map[string]string{
|
| 762 | 762 |
func (UserAgentMatchingConfig) SwaggerDoc() map[string]string {
|
| 763 | 763 |
return map_UserAgentMatchingConfig |
| 764 | 764 |
} |
| 765 |
- |
|
| 766 |
-var map_VolumeConfig = map[string]string{
|
|
| 767 |
- "": "VolumeConfig contains options for configuring volumes on the node.", |
|
| 768 |
- "localQuota": "LocalQuota contains options for controlling local volume quota on the node.", |
|
| 769 |
-} |
|
| 770 |
- |
|
| 771 |
-func (VolumeConfig) SwaggerDoc() map[string]string {
|
|
| 772 |
- return map_VolumeConfig |
|
| 773 |
-} |
| ... | ... |
@@ -71,15 +71,21 @@ type NodeConfig struct {
|
| 71 | 71 |
IPTablesSyncPeriod string `json:"iptablesSyncPeriod"` |
| 72 | 72 |
|
| 73 | 73 |
// VolumeConfig contains options for configuring volumes on the node. |
| 74 |
- VolumeConfig VolumeConfig `json:"volumeConfig"` |
|
| 74 |
+ VolumeConfig NodeVolumeConfig `json:"volumeConfig"` |
|
| 75 | 75 |
} |
| 76 | 76 |
|
| 77 |
-// VolumeConfig contains options for configuring volumes on the node. |
|
| 78 |
-type VolumeConfig struct {
|
|
| 77 |
+// NodeVolumeConfig contains options for configuring volumes on the node. |
|
| 78 |
+type NodeVolumeConfig struct {
|
|
| 79 | 79 |
// LocalQuota contains options for controlling local volume quota on the node. |
| 80 | 80 |
LocalQuota LocalQuota `json:"localQuota"` |
| 81 | 81 |
} |
| 82 | 82 |
|
| 83 |
+// MasterVolumeConfig contains options for configuring volume plugins in the master node. |
|
| 84 |
+type MasterVolumeConfig struct {
|
|
| 85 |
+ // DynamicProvisioningEnabled is a boolean that toggles dynamic provisioning off when false, defaults to true |
|
| 86 |
+ DynamicProvisioningEnabled *bool `json:"dynamicProvisioningEnabled"` |
|
| 87 |
+} |
|
| 88 |
+ |
|
| 83 | 89 |
// LocalQuota contains options for controlling local volume quota on the node. |
| 84 | 90 |
type LocalQuota struct {
|
| 85 | 91 |
// FSGroup can be specified to enable a quota on local storage use per unique FSGroup ID. |
| ... | ... |
@@ -219,6 +225,9 @@ type MasterConfig struct {
|
| 219 | 219 |
|
| 220 | 220 |
// NetworkConfig to be passed to the compiled in network plugin |
| 221 | 221 |
NetworkConfig MasterNetworkConfig `json:"networkConfig"` |
| 222 |
+ |
|
| 223 |
+ // MasterVolumeConfig contains options for configuring volume plugins in the master node. |
|
| 224 |
+ VolumeConfig MasterVolumeConfig `json:"volumeConfig"` |
|
| 222 | 225 |
} |
| 223 | 226 |
|
| 224 | 227 |
// ImagePolicyConfig holds the necessary configuration options for limits and behavior for importing images |
| ... | ... |
@@ -459,6 +459,8 @@ servingInfo: |
| 459 | 459 |
keyFile: "" |
| 460 | 460 |
names: null |
| 461 | 461 |
requestTimeoutSeconds: 0 |
| 462 |
+volumeConfig: |
|
| 463 |
+ dynamicProvisioningEnabled: false |
|
| 462 | 464 |
` |
| 463 | 465 |
) |
| 464 | 466 |
|
| ... | ... |
@@ -665,6 +667,9 @@ func TestMasterConfig(t *testing.T) {
|
| 665 | 665 |
}, |
| 666 | 666 |
PluginOrderOverride: []string{"plugin"}, // explicitly set this field because it's omitempty
|
| 667 | 667 |
}, |
| 668 |
+ VolumeConfig: internal.MasterVolumeConfig{
|
|
| 669 |
+ DynamicProvisioningEnabled: false, |
|
| 670 |
+ }, |
|
| 668 | 671 |
} |
| 669 | 672 |
serializedConfig, err := writeYAML(config) |
| 670 | 673 |
if err != nil {
|
| ... | ... |
@@ -116,7 +116,7 @@ func ValidateKubeletExtendedArguments(config api.ExtendedArguments, fldPath *fie |
| 116 | 116 |
return ValidateExtendedArguments(config, kubeletoptions.NewKubeletServer().AddFlags, fldPath) |
| 117 | 117 |
} |
| 118 | 118 |
|
| 119 |
-func ValidateVolumeConfig(config api.VolumeConfig, fldPath *field.Path) field.ErrorList {
|
|
| 119 |
+func ValidateVolumeConfig(config api.NodeVolumeConfig, fldPath *field.Path) field.ErrorList {
|
|
| 120 | 120 |
allErrs := field.ErrorList{}
|
| 121 | 121 |
|
| 122 | 122 |
if config.LocalQuota.PerFSGroup != nil && config.LocalQuota.PerFSGroup.Value() < 0 {
|
| ... | ... |
@@ -66,7 +66,7 @@ func TestFailingKubeletArgs(t *testing.T) {
|
| 66 | 66 |
func TestInvalidProjectEmptyDirQuota(t *testing.T) {
|
| 67 | 67 |
negQuota := resource.MustParse("-1000Mi")
|
| 68 | 68 |
nodeCfg := configapi.NodeConfig{
|
| 69 |
- VolumeConfig: configapi.VolumeConfig{
|
|
| 69 |
+ VolumeConfig: configapi.NodeVolumeConfig{
|
|
| 70 | 70 |
LocalQuota: configapi.LocalQuota{
|
| 71 | 71 |
PerFSGroup: &negQuota, |
| 72 | 72 |
}, |
| ... | ... |
@@ -253,6 +253,10 @@ func (args MasterArgs) BuildSerializeableMasterConfig() (*configapi.MasterConfig |
| 253 | 253 |
HostSubnetLength: args.NetworkArgs.HostSubnetLength, |
| 254 | 254 |
ServiceNetworkCIDR: args.NetworkArgs.ServiceNetworkCIDR, |
| 255 | 255 |
}, |
| 256 |
+ |
|
| 257 |
+ VolumeConfig: configapi.MasterVolumeConfig{
|
|
| 258 |
+ DynamicProvisioningEnabled: true, |
|
| 259 |
+ }, |
|
| 256 | 260 |
} |
| 257 | 261 |
|
| 258 | 262 |
if args.ListenArg.UseTLS() {
|
| ... | ... |
@@ -607,7 +607,9 @@ func startControllers(oc *origin.MasterConfig, kc *kubernetes.MasterConfig) erro |
| 607 | 607 |
kc.RunEndpointController() |
| 608 | 608 |
kc.RunNamespaceController(namespaceControllerClientSet, namespaceControllerClientPool) |
| 609 | 609 |
kc.RunPersistentVolumeClaimBinder(binderClient) |
| 610 |
- kc.RunPersistentVolumeProvisioner(provisionerClient) |
|
| 610 |
+ if oc.Options.VolumeConfig.DynamicProvisioningEnabled {
|
|
| 611 |
+ kc.RunPersistentVolumeProvisioner(provisionerClient) |
|
| 612 |
+ } |
|
| 611 | 613 |
kc.RunPersistentVolumeClaimRecycler(oc.ImageFor("recycler"), recyclerClient, oc.Options.PolicyConfig.OpenShiftInfrastructureNamespace)
|
| 612 | 614 |
kc.RunGCController(gcClient) |
| 613 | 615 |
|