Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 32 additions & 12 deletions pkg/asset/installconfig/gcp/validation.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,21 +85,18 @@ func validateInstanceAndDiskType(fldPath *field.Path, diskType, instanceType, ar
return nil
}

family, _, _ := strings.Cut(instanceType, "-")
if family == "custom" {
family = gcp.DefaultCustomInstanceType
}
diskTypes, ok := gcp.InstanceTypeToDiskTypeMap[family]
family := gcp.GetGCPInstanceFamily(instanceType)
diskTypes, ok := gcp.GetDiskTypes(instanceType)
if !ok {
return field.NotFound(fldPath.Child("type"), family)
logrus.Warnf("unrecognized instance type %s with family %s", instanceType, family)
}

acceptedArmFamilies := sets.New("c4a", "t2a")
acceptedArmFamilies := sets.New("c4a", "n4a", "t2a", "a4x")
if arch == types.ArchitectureARM64 && !acceptedArmFamilies.Has(family) {
return field.NotSupported(fldPath.Child("type"), family, sets.List(acceptedArmFamilies))
}

if diskType != "" {
if diskType != "" && len(diskTypes) > 0 {
if !sets.New(diskTypes...).Has(diskType) {
return field.Invalid(
fldPath.Child("diskType"),
Expand Down Expand Up @@ -234,6 +231,8 @@ func validateInstanceTypes(client API, ic *types.InstallConfig) field.ErrorList
defaultInstanceType = ic.GCP.DefaultMachinePlatform.InstanceType
if ic.GCP.DefaultMachinePlatform.DiskType != "" {
defaultDiskType = ic.GCP.DefaultMachinePlatform.DiskType
} else {
defaultDiskType = gcp.DefaultDiskTypeForInstance(defaultInstanceType)
}

if ic.GCP.DefaultMachinePlatform.OnHostMaintenance != "" {
Expand Down Expand Up @@ -282,6 +281,17 @@ func validateInstanceTypes(client API, ic *types.InstallConfig) field.ErrorList
}
if ic.ControlPlane.Platform.GCP.DiskType != "" {
cpDiskType = ic.ControlPlane.Platform.GCP.DiskType
} else {
// When the user-provided instance type is not recognized and
// the disk type is not specified, add an error asking for disk type.
family := gcp.GetGCPInstanceFamily(instanceType)
if _, ok := gcp.InstanceTypeToDiskTypeMap[family]; !ok {
return append(allErrs, field.Required(
field.NewPath("controlPlane", "diskType"),
fmt.Sprintf("instance type %s requires a disk type to be set", instanceType),
))
}
cpDiskType = gcp.DefaultDiskTypeForInstance(instanceType)
}
if ic.ControlPlane.Platform.GCP.OnHostMaintenance != "" {
cpOnHostMaintenance = ic.ControlPlane.Platform.GCP.OnHostMaintenance
Expand Down Expand Up @@ -343,10 +353,20 @@ func validateInstanceTypes(client API, ic *types.InstallConfig) field.ErrorList
if compute.Platform.GCP.ConfidentialCompute != "" {
confidentialCompute = compute.Platform.GCP.ConfidentialCompute
}
}

if compute.Platform.GCP != nil && compute.Platform.GCP.DiskType != "" {
diskType = compute.Platform.GCP.DiskType
if compute.Platform.GCP.DiskType != "" {
diskType = compute.Platform.GCP.DiskType
} else {
// When the user-provided instance type is not recognized and
// the disk type is not specified, add an error asking for disk type.
family := gcp.GetGCPInstanceFamily(instanceType)
if _, ok := gcp.InstanceTypeToDiskTypeMap[family]; !ok {
return append(allErrs, field.Required(
field.NewPath(fmt.Sprintf("compute[%d]", idx), "diskType"),
fmt.Sprintf("instance type %s requires a disk type to be set", instanceType),
))
}
diskType = gcp.DefaultDiskTypeForInstance(instanceType)
}
}

allErrs = append(allErrs,
Expand Down
5 changes: 3 additions & 2 deletions pkg/asset/machines/worker.go
Original file line number Diff line number Diff line change
Expand Up @@ -132,11 +132,12 @@ func defaultAzureMachinePoolPlatform(env azuretypes.CloudEnvironment) azuretypes
}

func defaultGCPMachinePoolPlatform(arch types.Architecture) gcptypes.MachinePool {
instanceType := icgcp.DefaultInstanceTypeForArch(arch)
return gcptypes.MachinePool{
InstanceType: icgcp.DefaultInstanceTypeForArch(arch),
InstanceType: instanceType,
OSDisk: gcptypes.OSDisk{
DiskSizeGB: powerOfTwoRootVolumeSize,
DiskType: "pd-ssd",
DiskType: gcptypes.DefaultDiskTypeForInstance(instanceType),
},
}
}
Expand Down
9 changes: 9 additions & 0 deletions pkg/types/gcp/defaults/machinepool.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,13 @@ func SetMachinePoolDefaults(platform *types.Platform, pool *gcp.MachinePool) {
}
}
}

// Set the default Disk Type for the Instance type when the instance type is provided
// by the user and the Disk type is not.
if pool.InstanceType != "" && pool.OSDisk.DiskType == "" {
family := gcp.GetGCPInstanceFamily(pool.InstanceType)
if _, ok := gcp.InstanceTypeToDiskTypeMap[family]; ok {
pool.OSDisk.DiskType = gcp.DefaultDiskTypeForInstance(pool.InstanceType)
}
}
}
103 changes: 91 additions & 12 deletions pkg/types/gcp/machinepools.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
package gcp

import "k8s.io/apimachinery/pkg/util/sets"
import (
"strings"

"k8s.io/apimachinery/pkg/util/sets"
)

// FeatureSwitch indicates whether the feature is enabled or disabled.
type FeatureSwitch string
Expand Down Expand Up @@ -37,23 +41,53 @@ var (
// InstanceTypeToDiskTypeMap contains a map where the key is the Instance Type, and the
// values are a list of disk types that are supported by the installer and correlate to the Instance Type.
InstanceTypeToDiskTypeMap = map[string][]string{
"a2": {PDStandard, PDSSD, PDBalanced},
"a3": {PDSSD, PDBalanced},
"c2": {PDStandard, PDSSD, PDBalanced},
"c2d": {PDStandard, PDSSD, PDBalanced},
"c3": {PDSSD, PDBalanced, HyperDiskBalanced},
"c3d": {PDSSD, PDBalanced, HyperDiskBalanced},
// General Purpose Machine Family
// https://docs.cloud.google.com/compute/docs/general-purpose-machines
"c4d": {HyperDiskBalanced},
"c4": {HyperDiskBalanced},
"c4a": {HyperDiskBalanced},
"e2": {PDStandard, PDSSD, PDBalanced},
"g2": {PDStandard, PDSSD, PDBalanced},
"m1": {PDSSD, PDBalanced, HyperDiskBalanced},
"n1": {PDStandard, PDSSD, PDBalanced},
"c3": {PDSSD, PDBalanced, HyperDiskBalanced},
"c3d": {PDSSD, PDBalanced, HyperDiskBalanced},
"n4": {HyperDiskBalanced},
"n4a": {HyperDiskBalanced},
"n4d": {HyperDiskBalanced},
"n2": {PDStandard, PDSSD, PDBalanced},
"n2d": {PDStandard, PDSSD, PDBalanced},
"n4": {HyperDiskBalanced},
"n1": {PDStandard, PDSSD, PDBalanced},
"e2": {PDStandard, PDSSD, PDBalanced},
"t2a": {PDStandard, PDSSD, PDBalanced},
"t2d": {PDStandard, PDSSD, PDBalanced},

// Storage Optimized Machine Family
// https://docs.cloud.google.com/compute/docs/storage-optimized-machines
"z3": {PDSSD, PDBalanced, HyperDiskBalanced},

// Compute Optimized Machine Family
// https://docs.cloud.google.com/compute/docs/compute-optimized-machines
"h4d": {HyperDiskBalanced},
"h3": {PDBalanced, HyperDiskBalanced},
"c2": {PDStandard, PDSSD, PDBalanced},
"c2d": {PDStandard, PDSSD, PDBalanced},

// Memory Optimized Machine Family
// https://docs.cloud.google.com/compute/docs/memory-optimized-machines
"x4": {HyperDiskBalanced},
"m4": {HyperDiskBalanced},
"m3": {PDSSD, PDBalanced, HyperDiskBalanced},
"m2": {PDSSD, PDBalanced, HyperDiskBalanced},
"m1": {PDSSD, PDBalanced, HyperDiskBalanced},

// Accelerator Optimized Machine Family
// https://docs.cloud.google.com/compute/docs/accelerator-optimized-machines
"a4x": {HyperDiskBalanced},
"a4": {HyperDiskBalanced},
// A3 machines are separated into A3 Ultra, A3 Mega, A3 High, and A3 Edge machine types. The
// A3 Ultra machines only support Hyperdisk Balanced, but all types listed below are available
// for the other A3 machine types.
"a3": {PDSSD, PDBalanced, HyperDiskBalanced},
"a2": {PDStandard, PDSSD, PDBalanced},
"g4": {HyperDiskBalanced},
"g2": {PDSSD, PDBalanced},
}
)

Expand Down Expand Up @@ -327,3 +361,48 @@ func (k *KMSKeyReference) Set(required *KMSKeyReference) {
k.Location = required.Location
}
}

// GetGCPInstanceFamily extracts the instance family from the instance type (for instance c4-standard-4 returns c4).
func GetGCPInstanceFamily(instanceType string) string {
family, _, _ := strings.Cut(instanceType, "-")
if family == "custom" {
family = DefaultCustomInstanceType
}
return family
}

// DefaultDiskTypeForInstance returns the default disk type for a GCP instance type. If instance type is not
// recognized, pd-ssd is return.
func DefaultDiskTypeForInstance(instanceType string) string {
defaultDiskType := PDSSD
diskTypes, ok := GetDiskTypes(instanceType)
if ok {
supportedDiskTypes := sets.New(diskTypes...)
switch {
case supportedDiskTypes.Has(PDSSD):
defaultDiskType = PDSSD
case supportedDiskTypes.Has(HyperDiskBalanced):
defaultDiskType = HyperDiskBalanced
default:
// this shouldn't happen because all supported instance types
// have either pd-ssd or hyperdisk balanced
defaultDiskType = diskTypes[0]
}
}
return defaultDiskType
}

// GetDiskTypes gets the disk types associated with a (supported) GCP instance type.
func GetDiskTypes(instanceType string) ([]string, bool) {
family := GetGCPInstanceFamily(instanceType)

// https://docs.cloud.google.com/compute/docs/accelerator-optimized-machines#a3-ultra
// a3-ultra machines are special, unlike a3-mega, a3-high, and a3-edge the only supported
// disk type is hyperdisk-balanced.
if family == "a3" && strings.Contains(instanceType, "ultra") {
return []string{HyperDiskBalanced}, true
}

diskTypes, ok := InstanceTypeToDiskTypeMap[family]
return diskTypes, ok
}