Adding GuestAccelerators to InstanceTemplate

This commit is contained in:
Ivan Volynkin 2022-06-23 10:00:02 +03:00
parent 1c3512daea
commit 4264d78839
12 changed files with 306 additions and 0 deletions

View File

@ -222,6 +222,18 @@ spec:
type: array
type: object
type: array
guestAccelerators:
description: GuestAccelerators configures additional accelerators
items:
description: AcceleratorConfig defines an accelerator config
properties:
acceleratorCount:
format: int64
type: integer
acceleratorType:
type: string
type: object
type: array
hooks:
description: 'Hooks is a list of hooks for this instanceGroup, note:
these can override the cluster wide ones if required'

View File

@ -194,6 +194,8 @@ type InstanceGroupSpec struct {
Containerd *ContainerdConfig `json:"containerd,omitempty"`
// Packages specifies additional packages to be installed.
Packages []string `json:"packages,omitempty"`
// GuestAccelerators configures additional accelerators
GuestAccelerators []AcceleratorConfig `json:"guestAccelerators,omitempty"`
}
const (
@ -363,3 +365,9 @@ type LoadBalancer struct {
// TargetGroupARN to associate with this instance group (AWS ALB/NLB)
TargetGroupARN *string `json:"targetGroupARN,omitempty"`
}
// AcceleratorConfig defines an accelerator config
type AcceleratorConfig struct {
AcceleratorCount int64 `json:"acceleratorCount,omitempty"`
AcceleratorType string `json:"acceleratorType,omitempty"`
}

View File

@ -160,6 +160,8 @@ type InstanceGroupSpec struct {
Containerd *ContainerdConfig `json:"containerd,omitempty"`
// Packages specifies additional packages to be installed.
Packages []string `json:"packages,omitempty"`
// GuestAccelerators configures additional accelerators
GuestAccelerators []AcceleratorConfig `json:"guestAccelerators,omitempty"`
}
// InstanceMetadataOptions defines the EC2 instance metadata service options (AWS Only)
@ -268,3 +270,9 @@ type LoadBalancer struct {
// TargetGroupARN to associate with this instance group (AWS ALB/NLB)
TargetGroupARN *string `json:"targetGroupArn,omitempty"`
}
// AcceleratorConfig defines an accelerator config
type AcceleratorConfig struct {
AcceleratorCount int64 `json:"acceleratorCount,omitempty"`
AcceleratorType string `json:"acceleratorType,omitempty"`
}

View File

@ -84,6 +84,16 @@ func RegisterConversions(s *runtime.Scheme) error {
}); err != nil {
return err
}
if err := s.AddGeneratedConversionFunc((*AcceleratorConfig)(nil), (*kops.AcceleratorConfig)(nil), func(a, b interface{}, scope conversion.Scope) error {
return Convert_v1alpha2_AcceleratorConfig_To_kops_AcceleratorConfig(a.(*AcceleratorConfig), b.(*kops.AcceleratorConfig), scope)
}); err != nil {
return err
}
if err := s.AddGeneratedConversionFunc((*kops.AcceleratorConfig)(nil), (*AcceleratorConfig)(nil), func(a, b interface{}, scope conversion.Scope) error {
return Convert_kops_AcceleratorConfig_To_v1alpha2_AcceleratorConfig(a.(*kops.AcceleratorConfig), b.(*AcceleratorConfig), scope)
}); err != nil {
return err
}
if err := s.AddGeneratedConversionFunc((*AccessLogSpec)(nil), (*kops.AccessLogSpec)(nil), func(a, b interface{}, scope conversion.Scope) error {
return Convert_v1alpha2_AccessLogSpec_To_kops_AccessLogSpec(a.(*AccessLogSpec), b.(*kops.AccessLogSpec), scope)
}); err != nil {
@ -1369,6 +1379,28 @@ func Convert_kops_AWSPermission_To_v1alpha2_AWSPermission(in *kops.AWSPermission
return autoConvert_kops_AWSPermission_To_v1alpha2_AWSPermission(in, out, s)
}
func autoConvert_v1alpha2_AcceleratorConfig_To_kops_AcceleratorConfig(in *AcceleratorConfig, out *kops.AcceleratorConfig, s conversion.Scope) error {
out.AcceleratorCount = in.AcceleratorCount
out.AcceleratorType = in.AcceleratorType
return nil
}
// Convert_v1alpha2_AcceleratorConfig_To_kops_AcceleratorConfig is an autogenerated conversion function.
func Convert_v1alpha2_AcceleratorConfig_To_kops_AcceleratorConfig(in *AcceleratorConfig, out *kops.AcceleratorConfig, s conversion.Scope) error {
return autoConvert_v1alpha2_AcceleratorConfig_To_kops_AcceleratorConfig(in, out, s)
}
func autoConvert_kops_AcceleratorConfig_To_v1alpha2_AcceleratorConfig(in *kops.AcceleratorConfig, out *AcceleratorConfig, s conversion.Scope) error {
out.AcceleratorCount = in.AcceleratorCount
out.AcceleratorType = in.AcceleratorType
return nil
}
// Convert_kops_AcceleratorConfig_To_v1alpha2_AcceleratorConfig is an autogenerated conversion function.
func Convert_kops_AcceleratorConfig_To_v1alpha2_AcceleratorConfig(in *kops.AcceleratorConfig, out *AcceleratorConfig, s conversion.Scope) error {
return autoConvert_kops_AcceleratorConfig_To_v1alpha2_AcceleratorConfig(in, out, s)
}
func autoConvert_v1alpha2_AccessLogSpec_To_kops_AccessLogSpec(in *AccessLogSpec, out *kops.AccessLogSpec, s conversion.Scope) error {
out.Interval = in.Interval
out.Bucket = in.Bucket
@ -4426,6 +4458,17 @@ func autoConvert_v1alpha2_InstanceGroupSpec_To_kops_InstanceGroupSpec(in *Instan
out.Containerd = nil
}
out.Packages = in.Packages
if in.GuestAccelerators != nil {
in, out := &in.GuestAccelerators, &out.GuestAccelerators
*out = make([]kops.AcceleratorConfig, len(*in))
for i := range *in {
if err := Convert_v1alpha2_AcceleratorConfig_To_kops_AcceleratorConfig(&(*in)[i], &(*out)[i], s); err != nil {
return err
}
}
} else {
out.GuestAccelerators = nil
}
return nil
}
@ -4598,6 +4641,17 @@ func autoConvert_kops_InstanceGroupSpec_To_v1alpha2_InstanceGroupSpec(in *kops.I
out.Containerd = nil
}
out.Packages = in.Packages
if in.GuestAccelerators != nil {
in, out := &in.GuestAccelerators, &out.GuestAccelerators
*out = make([]AcceleratorConfig, len(*in))
for i := range *in {
if err := Convert_kops_AcceleratorConfig_To_v1alpha2_AcceleratorConfig(&(*in)[i], &(*out)[i], s); err != nil {
return err
}
}
} else {
out.GuestAccelerators = nil
}
return nil
}

View File

@ -177,6 +177,22 @@ func (in *AWSPermission) DeepCopy() *AWSPermission {
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *AcceleratorConfig) DeepCopyInto(out *AcceleratorConfig) {
*out = *in
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AcceleratorConfig.
func (in *AcceleratorConfig) DeepCopy() *AcceleratorConfig {
if in == nil {
return nil
}
out := new(AcceleratorConfig)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *AccessLogSpec) DeepCopyInto(out *AccessLogSpec) {
*out = *in
@ -2513,6 +2529,11 @@ func (in *InstanceGroupSpec) DeepCopyInto(out *InstanceGroupSpec) {
*out = make([]string, len(*in))
copy(*out, *in)
}
if in.GuestAccelerators != nil {
in, out := &in.GuestAccelerators, &out.GuestAccelerators
*out = make([]AcceleratorConfig, len(*in))
copy(*out, *in)
}
return
}

View File

@ -157,6 +157,8 @@ type InstanceGroupSpec struct {
Containerd *ContainerdConfig `json:"containerd,omitempty"`
// Packages specifies additional packages to be installed.
Packages []string `json:"packages,omitempty"`
// GuestAccelerators configures additional accelerators
GuestAccelerators []AcceleratorConfig `json:"guestAccelerators,omitempty"`
}
// InstanceMetadataOptions defines the EC2 instance metadata service options (AWS Only)
@ -265,3 +267,9 @@ type LoadBalancer struct {
// TargetGroupARN to associate with this instance group (AWS ALB/NLB)
TargetGroupARN *string `json:"targetGroupARN,omitempty"`
}
// AcceleratorConfig defines an accelerator config
type AcceleratorConfig struct {
AcceleratorCount int64 `json:"acceleratorCount,omitempty"`
AcceleratorType string `json:"acceleratorType,omitempty"`
}

View File

@ -94,6 +94,16 @@ func RegisterConversions(s *runtime.Scheme) error {
}); err != nil {
return err
}
if err := s.AddGeneratedConversionFunc((*AcceleratorConfig)(nil), (*kops.AcceleratorConfig)(nil), func(a, b interface{}, scope conversion.Scope) error {
return Convert_v1alpha3_AcceleratorConfig_To_kops_AcceleratorConfig(a.(*AcceleratorConfig), b.(*kops.AcceleratorConfig), scope)
}); err != nil {
return err
}
if err := s.AddGeneratedConversionFunc((*kops.AcceleratorConfig)(nil), (*AcceleratorConfig)(nil), func(a, b interface{}, scope conversion.Scope) error {
return Convert_kops_AcceleratorConfig_To_v1alpha3_AcceleratorConfig(a.(*kops.AcceleratorConfig), b.(*AcceleratorConfig), scope)
}); err != nil {
return err
}
if err := s.AddGeneratedConversionFunc((*AccessLogSpec)(nil), (*kops.AccessLogSpec)(nil), func(a, b interface{}, scope conversion.Scope) error {
return Convert_v1alpha3_AccessLogSpec_To_kops_AccessLogSpec(a.(*AccessLogSpec), b.(*kops.AccessLogSpec), scope)
}); err != nil {
@ -1387,6 +1397,28 @@ func Convert_kops_AWSSpec_To_v1alpha3_AWSSpec(in *kops.AWSSpec, out *AWSSpec, s
return autoConvert_kops_AWSSpec_To_v1alpha3_AWSSpec(in, out, s)
}
func autoConvert_v1alpha3_AcceleratorConfig_To_kops_AcceleratorConfig(in *AcceleratorConfig, out *kops.AcceleratorConfig, s conversion.Scope) error {
out.AcceleratorCount = in.AcceleratorCount
out.AcceleratorType = in.AcceleratorType
return nil
}
// Convert_v1alpha3_AcceleratorConfig_To_kops_AcceleratorConfig is an autogenerated conversion function.
func Convert_v1alpha3_AcceleratorConfig_To_kops_AcceleratorConfig(in *AcceleratorConfig, out *kops.AcceleratorConfig, s conversion.Scope) error {
return autoConvert_v1alpha3_AcceleratorConfig_To_kops_AcceleratorConfig(in, out, s)
}
func autoConvert_kops_AcceleratorConfig_To_v1alpha3_AcceleratorConfig(in *kops.AcceleratorConfig, out *AcceleratorConfig, s conversion.Scope) error {
out.AcceleratorCount = in.AcceleratorCount
out.AcceleratorType = in.AcceleratorType
return nil
}
// Convert_kops_AcceleratorConfig_To_v1alpha3_AcceleratorConfig is an autogenerated conversion function.
func Convert_kops_AcceleratorConfig_To_v1alpha3_AcceleratorConfig(in *kops.AcceleratorConfig, out *AcceleratorConfig, s conversion.Scope) error {
return autoConvert_kops_AcceleratorConfig_To_v1alpha3_AcceleratorConfig(in, out, s)
}
func autoConvert_v1alpha3_AccessLogSpec_To_kops_AccessLogSpec(in *AccessLogSpec, out *kops.AccessLogSpec, s conversion.Scope) error {
out.Interval = in.Interval
out.Bucket = in.Bucket
@ -4565,6 +4597,17 @@ func autoConvert_v1alpha3_InstanceGroupSpec_To_kops_InstanceGroupSpec(in *Instan
out.Containerd = nil
}
out.Packages = in.Packages
if in.GuestAccelerators != nil {
in, out := &in.GuestAccelerators, &out.GuestAccelerators
*out = make([]kops.AcceleratorConfig, len(*in))
for i := range *in {
if err := Convert_v1alpha3_AcceleratorConfig_To_kops_AcceleratorConfig(&(*in)[i], &(*out)[i], s); err != nil {
return err
}
}
} else {
out.GuestAccelerators = nil
}
return nil
}
@ -4737,6 +4780,17 @@ func autoConvert_kops_InstanceGroupSpec_To_v1alpha3_InstanceGroupSpec(in *kops.I
out.Containerd = nil
}
out.Packages = in.Packages
if in.GuestAccelerators != nil {
in, out := &in.GuestAccelerators, &out.GuestAccelerators
*out = make([]AcceleratorConfig, len(*in))
for i := range *in {
if err := Convert_kops_AcceleratorConfig_To_v1alpha3_AcceleratorConfig(&(*in)[i], &(*out)[i], s); err != nil {
return err
}
}
} else {
out.GuestAccelerators = nil
}
return nil
}

View File

@ -194,6 +194,22 @@ func (in *AWSSpec) DeepCopy() *AWSSpec {
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *AcceleratorConfig) DeepCopyInto(out *AcceleratorConfig) {
*out = *in
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AcceleratorConfig.
func (in *AcceleratorConfig) DeepCopy() *AcceleratorConfig {
if in == nil {
return nil
}
out := new(AcceleratorConfig)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *AccessLogSpec) DeepCopyInto(out *AccessLogSpec) {
*out = *in
@ -2519,6 +2535,11 @@ func (in *InstanceGroupSpec) DeepCopyInto(out *InstanceGroupSpec) {
*out = make([]string, len(*in))
copy(*out, *in)
}
if in.GuestAccelerators != nil {
in, out := &in.GuestAccelerators, &out.GuestAccelerators
*out = make([]AcceleratorConfig, len(*in))
copy(*out, *in)
}
return
}

View File

@ -193,6 +193,22 @@ func (in *AWSSpec) DeepCopy() *AWSSpec {
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *AcceleratorConfig) DeepCopyInto(out *AcceleratorConfig) {
*out = *in
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AcceleratorConfig.
func (in *AcceleratorConfig) DeepCopy() *AcceleratorConfig {
if in == nil {
return nil
}
out := new(AcceleratorConfig)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *AccessLogSpec) DeepCopyInto(out *AccessLogSpec) {
*out = *in
@ -2682,6 +2698,11 @@ func (in *InstanceGroupSpec) DeepCopyInto(out *InstanceGroupSpec) {
*out = make([]string, len(*in))
copy(*out, *in)
}
if in.GuestAccelerators != nil {
in, out := &in.GuestAccelerators, &out.GuestAccelerators
*out = make([]AcceleratorConfig, len(*in))
copy(*out, *in)
}
return
}

View File

@ -168,6 +168,14 @@ func (b *AutoscalingGroupModelBuilder) buildInstanceTemplate(c *fi.ModelBuilderC
//}
//t.Labels = labels
t.GuestAccelerators = []gcetasks.AcceleratorConfig{}
for _, accelerator := range ig.Spec.GuestAccelerators {
t.GuestAccelerators = append(t.GuestAccelerators, gcetasks.AcceleratorConfig{
AcceleratorCount: accelerator.AcceleratorCount,
AcceleratorType: accelerator.AcceleratorType,
})
}
return t, nil
}
}

View File

@ -0,0 +1,47 @@
/*
Copyright 2022 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 gcetasks
import (
"fmt"
"k8s.io/kops/upup/pkg/fi"
)
// AcceleratorConfig defines an accelerator config
type AcceleratorConfig struct {
AcceleratorCount int64 `json:"acceleratorCount,omitempty"`
AcceleratorType string `json:"acceleratorType,omitempty"`
}
var (
_ fi.HasDependencies = &AcceleratorConfig{}
)
func (a *AcceleratorConfig) GetDependencies(tasks map[string]fi.Task) []fi.Task {
return nil
}
func (_ *AcceleratorConfig) ShouldCreate(a, e, changes *AcceleratorConfig) (bool, error) {
if e.AcceleratorCount < 0 {
return false, fmt.Errorf("acceleratorCount must be positive or 0")
}
if e.AcceleratorType == "" {
return false, fmt.Errorf("acceleratorType must not be empty")
}
return true, nil
}

View File

@ -75,6 +75,8 @@ type InstanceTemplate struct {
// ID is the actual name
ID *string
GuestAccelerators []AcceleratorConfig
}
var (
@ -211,6 +213,14 @@ func (e *InstanceTemplate) Find(c *fi.Context) (*InstanceTemplate, error) {
// System fields
actual.Lifecycle = e.Lifecycle
actual.GuestAccelerators = []AcceleratorConfig{}
for _, accelerator := range p.GuestAccelerators {
actual.GuestAccelerators = append(actual.GuestAccelerators, AcceleratorConfig{
AcceleratorCount: accelerator.AcceleratorCount,
AcceleratorType: accelerator.AcceleratorType,
})
}
return actual, nil
}
@ -250,6 +260,11 @@ func (e *InstanceTemplate) mapToGCE(project string, region string) (*compute.Ins
}
}
if len(e.GuestAccelerators) > 0 {
// Instances with accelerators cannot be migrated.
scheduling.OnHostMaintenance = "TERMINATE"
}
var disks []*compute.AttachedDisk
disks = append(disks, &compute.AttachedDisk{
Kind: "compute#attachedDisk",
@ -335,6 +350,17 @@ func (e *InstanceTemplate) mapToGCE(project string, region string) (*compute.Ins
})
}
var accelerators []*compute.AcceleratorConfig
if len(e.GuestAccelerators) > 0 {
accelerators = []*compute.AcceleratorConfig{}
for _, accelerator := range e.GuestAccelerators {
accelerators = append(accelerators, &compute.AcceleratorConfig{
AcceleratorCount: accelerator.AcceleratorCount,
AcceleratorType: accelerator.AcceleratorType,
})
}
}
i := &compute.InstanceTemplate{
Kind: "compute#instanceTemplate",
Properties: &compute.InstanceProperties{
@ -342,6 +368,8 @@ func (e *InstanceTemplate) mapToGCE(project string, region string) (*compute.Ins
Disks: disks,
GuestAccelerators: accelerators,
MachineType: *e.MachineType,
Metadata: &compute.Metadata{
@ -459,6 +487,7 @@ type terraformInstanceTemplate struct {
Metadata map[string]*terraformWriter.Literal `cty:"metadata"`
MetadataStartupScript *terraformWriter.Literal `cty:"metadata_startup_script"`
Tags []string `cty:"tags"`
GuestAccelerator []*terraformGuestAccelerator `cty:"guest_accelerator"`
}
type terraformTemplateServiceAccount struct {
@ -498,6 +527,11 @@ type terraformAccessConfig struct {
NatIP *terraformWriter.Literal `cty:"nat_ip"`
}
type terraformGuestAccelerator struct {
Type string `cty:"type"`
Count int64 `cty:"count"`
}
func addNetworks(network *Network, subnet *Subnet, networkInterfaces []*compute.NetworkInterface) []*terraformNetworkInterface {
ni := make([]*terraformNetworkInterface, 0)
for _, g := range networkInterfaces {
@ -616,6 +650,16 @@ func (_ *InstanceTemplate) RenderTerraform(t *terraform.TerraformTarget, a, e, c
}
}
if len(i.Properties.GuestAccelerators) > 0 {
tf.GuestAccelerator = []*terraformGuestAccelerator{}
for _, accelerator := range i.Properties.GuestAccelerators {
tf.GuestAccelerator = append(tf.GuestAccelerator, &terraformGuestAccelerator{
Count: accelerator.AcceleratorCount,
Type: accelerator.AcceleratorType,
})
}
}
return t.RenderResource("google_compute_instance_template", name, tf)
}