Skip to content

Commit

Permalink
GCP: Enable disk type and size customization
Browse files Browse the repository at this point in the history
Currently, the installer does not allow the users to customize the
type and size of the disks for the workers and control plane.
Added the option for the user to specify the type and the size of
the disks for both machines in GCP.

The user can specify two types of disks, pd-standard and pd-ssd disks
which are the options that GCP/Terraform provides. pd-standard is not
recommended for control planes and will not be allowed as a value in
the DefaultMachinePlatform and the master compute section.
  • Loading branch information
rna-afk committed May 13, 2020
1 parent e476c48 commit 00ade38
Show file tree
Hide file tree
Showing 6 changed files with 140 additions and 4 deletions.
12 changes: 12 additions & 0 deletions docs/user/gcp/customization.md
Expand Up @@ -13,6 +13,9 @@ Beyond the [platform-agnostic `install-config.yaml` properties](../customization

* `type` (optional string): The [GCP machine type][machine-type].
* `zones` (optional array of strings): The availability zones used for machines in the pool.
* `osDisk` (optional object):
* `diskSizeGB` (optional integer): The size of the disk in gigabytes (GB).
* `diskType` (optional string): The type of disk (allowed values are: `pd-ssd`, and `pd-standard`. Default: `pd-ssd`).

## Installing to Existing Networks & Subnetworks

Expand Down Expand Up @@ -44,6 +47,9 @@ platform:
gcp:
project: example-project
region: us-east1
osDisk:
diskType: pd-ssd
diskSizeGB: 120
pullSecret: '{"auths": ...}'
sshKey: ssh-ed25519 AAAA...
```
Expand All @@ -63,6 +69,9 @@ compute:
zones:
- us-central1-a
- us-central1-c
osDisk:
diskType: pd-standard
diskSizeGB: 128
replicas: 3
controlPlane:
name: master
Expand All @@ -72,6 +81,9 @@ controlPlane:
zones:
- us-central1-a
- us-central1-c
osDisk:
diskType: pd-ssd
diskSizeGB: 1024
replicas: 3
metadata:
name: example-cluster
Expand Down
13 changes: 11 additions & 2 deletions pkg/asset/machines/gcp/machines.go
Expand Up @@ -31,6 +31,7 @@ func Machines(clusterID string, config *types.InstallConfig, pool *types.Machine
if pool.Replicas != nil {
total = *pool.Replicas
}

var machines []machineapi.Machine
for idx := int64(0); idx < total; idx++ {
azIndex := int(idx) % len(azs)
Expand Down Expand Up @@ -74,6 +75,14 @@ func provider(clusterID string, platform *gcp.Platform, mpool *gcp.MachinePool,
return nil, err
}

if mpool.OSDisk.DiskType == "" {
mpool.OSDisk.DiskType = "pd-ssd"
}

if mpool.OSDisk.DiskSizeGB == 0 {
mpool.OSDisk.DiskSizeGB = 128
}

return &gcpprovider.GCPMachineProviderSpec{
TypeMeta: metav1.TypeMeta{
APIVersion: "gcpprovider.openshift.io/v1beta1",
Expand All @@ -84,8 +93,8 @@ func provider(clusterID string, platform *gcp.Platform, mpool *gcp.MachinePool,
Disks: []*gcpprovider.GCPDisk{{
AutoDelete: true,
Boot: true,
SizeGb: 128,
Type: "pd-ssd",
SizeGb: mpool.OSDisk.DiskSizeGB,
Type: mpool.OSDisk.DiskType,
Image: fmt.Sprintf("%s-rhcos-image", clusterID),
}},
NetworkInterfaces: []*gcpprovider.GCPNetworkInterface{{
Expand Down
27 changes: 27 additions & 0 deletions pkg/types/gcp/machinepools.go
Expand Up @@ -12,6 +12,25 @@ type MachinePool struct {
//
// +optional
InstanceType string `json:"type"`

// OSDisk defines the storage for instance.
//
// +optional
OSDisk `json:"osDisk"`
}

// OSDisk defines the disk for machines on GCP.
type OSDisk struct {
// DiskType defines the type of disk.
// The valid values are <pd-standard, pd-ssd>
// For master nodes, the valid values are <pd-ssd>.
// +optional
DiskType string `json:"DiskType"`

// DiskSizeGB defines the size of disk in GB.
//
// +kubebuilder:validation:Minimum=0
DiskSizeGB int64 `json:"DiskSizeGB"`
}

// Set sets the values from `required` to `a`.
Expand All @@ -27,4 +46,12 @@ func (a *MachinePool) Set(required *MachinePool) {
if required.InstanceType != "" {
a.InstanceType = required.InstanceType
}

if required.OSDisk.DiskSizeGB > 0 {
a.OSDisk.DiskSizeGB = required.OSDisk.DiskSizeGB
}

if required.OSDisk.DiskType != "" {
a.OSDisk.DiskType = required.OSDisk.DiskType
}
}
39 changes: 39 additions & 0 deletions pkg/types/gcp/validation/machinepool.go
Expand Up @@ -4,7 +4,9 @@ import (
"fmt"
"strings"

"github.com/openshift/installer/pkg/types"
"github.com/openshift/installer/pkg/types/gcp"
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/apimachinery/pkg/util/validation/field"
)

Expand All @@ -17,5 +19,42 @@ func ValidateMachinePool(platform *gcp.Platform, p *gcp.MachinePool, fldPath *fi
}
}

if p.OSDisk.DiskSizeGB < 0 {
allErrs = append(allErrs, field.Invalid(fldPath.Child("diskSizeGB"), p.OSDisk.DiskSizeGB, "Storage DiskSizeGB must be positive"))
}

if p.OSDisk.DiskType != "" {
diskTypes := sets.NewString("pd-standard", "pd-ssd")
if !diskTypes.Has(p.OSDisk.DiskType) {
allErrs = append(allErrs, field.NotSupported(fldPath.Child("diskType"), p.OSDisk.DiskType, diskTypes.List()))
}
}

return allErrs
}

// ValidateMasterDiskType checks that the specified disk type is valid for control plane.
func ValidateMasterDiskType(p *types.MachinePool, fldPath *field.Path) field.ErrorList {
allErrs := field.ErrorList{}

if p.Name == "master" && p.Platform.GCP.OSDisk.DiskType == "pd-standard" {
allErrs = append(allErrs, field.Invalid(fldPath.Child("diskType"), p.Platform.GCP.OSDisk.DiskType, fmt.Sprintf("%s not compatible with control planes.", p.Platform.GCP.OSDisk.DiskType)))
}

return allErrs
}

// ValidateDefaultDiskType checks that the specified disk type is valid for default GCP Machine Platform.
func ValidateDefaultDiskType(p *gcp.MachinePool, fldPath *field.Path) field.ErrorList {
allErrs := field.ErrorList{}

if p != nil && p.OSDisk.DiskType != "" {
diskTypes := sets.NewString("pd-ssd")

if !diskTypes.Has(p.OSDisk.DiskType) {
allErrs = append(allErrs, field.NotSupported(fldPath.Child("diskType"), p.OSDisk.DiskType, diskTypes.List()))
}
}

return allErrs
}
34 changes: 34 additions & 0 deletions pkg/types/gcp/validation/machinepool_test.go
Expand Up @@ -33,6 +33,40 @@ func TestValidateMachinePool(t *testing.T) {
},
expected: `^test-path\.zones\[1]: Invalid value: "us-central1-f": Zone not in configured region \(us-east1\)$`,
},
{
name: "valid disk type",
pool: &gcp.MachinePool{
OSDisk: gcp.OSDisk{
DiskType: "pd-standard",
},
},
},
{
name: "invalid disk type",
pool: &gcp.MachinePool{
OSDisk: gcp.OSDisk{
DiskType: "pd-",
},
},
expected: `^test-path\.diskType: Unsupported value: "pd-": supported values: "pd-ssd", "pd-standard"$`,
},
{
name: "valid disk size",
pool: &gcp.MachinePool{
OSDisk: gcp.OSDisk{
DiskSizeGB: 100,
},
},
},
{
name: "invalid disk type",
pool: &gcp.MachinePool{
OSDisk: gcp.OSDisk{
DiskSizeGB: -120,
},
},
expected: `^test-path\.diskSizeGB: Invalid value: -120: Storage DiskSizeGB must be positive$`,
},
}
for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) {
Expand Down
19 changes: 17 additions & 2 deletions pkg/types/validation/machinepools.go
Expand Up @@ -12,6 +12,8 @@ import (
azurevalidation "github.com/openshift/installer/pkg/types/azure/validation"
"github.com/openshift/installer/pkg/types/baremetal"
baremetalvalidation "github.com/openshift/installer/pkg/types/baremetal/validation"
"github.com/openshift/installer/pkg/types/gcp"
gcpvalidation "github.com/openshift/installer/pkg/types/gcp/validation"
"github.com/openshift/installer/pkg/types/libvirt"
libvirtvalidation "github.com/openshift/installer/pkg/types/libvirt/validation"
"github.com/openshift/installer/pkg/types/openstack"
Expand Down Expand Up @@ -63,11 +65,11 @@ func ValidateMachinePool(platform *types.Platform, p *types.MachinePool, fldPath
if !validArchitectures[p.Architecture] {
allErrs = append(allErrs, field.NotSupported(fldPath.Child("architecture"), p.Architecture, validArchitectureValues))
}
allErrs = append(allErrs, validateMachinePoolPlatform(platform, &p.Platform, fldPath.Child("platform"))...)
allErrs = append(allErrs, validateMachinePoolPlatform(platform, &p.Platform, p, fldPath.Child("platform"))...)
return allErrs
}

func validateMachinePoolPlatform(platform *types.Platform, p *types.MachinePoolPlatform, fldPath *field.Path) field.ErrorList {
func validateMachinePoolPlatform(platform *types.Platform, p *types.MachinePoolPlatform, pool *types.MachinePool, fldPath *field.Path) field.ErrorList {
allErrs := field.ErrorList{}
platformName := platform.Name()
validate := func(n string, value interface{}, validation func(*field.Path) field.ErrorList) {
Expand All @@ -84,6 +86,9 @@ func validateMachinePoolPlatform(platform *types.Platform, p *types.MachinePoolP
if p.Azure != nil {
validate(azure.Name, p.Azure, func(f *field.Path) field.ErrorList { return azurevalidation.ValidateMachinePool(p.Azure, f) })
}
if p.GCP != nil {
validate(gcp.Name, p.GCP, func(f *field.Path) field.ErrorList { return validateGCPMachinePool(platform, p, pool, f) })
}
if p.Libvirt != nil {
validate(libvirt.Name, p.Libvirt, func(f *field.Path) field.ErrorList { return libvirtvalidation.ValidateMachinePool(p.Libvirt, f) })
}
Expand All @@ -95,3 +100,13 @@ func validateMachinePoolPlatform(platform *types.Platform, p *types.MachinePoolP
}
return allErrs
}

func validateGCPMachinePool(platform *types.Platform, p *types.MachinePoolPlatform, pool *types.MachinePool, f *field.Path) field.ErrorList {
allErrs := field.ErrorList{}

allErrs = append(allErrs, gcpvalidation.ValidateMachinePool(platform.GCP, p.GCP, f)...)
allErrs = append(allErrs, gcpvalidation.ValidateMasterDiskType(pool, f)...)
allErrs = append(allErrs, gcpvalidation.ValidateDefaultDiskType(platform.GCP.DefaultMachinePlatform, f)...)

return allErrs
}

0 comments on commit 00ade38

Please sign in to comment.