-
Notifications
You must be signed in to change notification settings - Fork 168
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
gcp: support additionalDisks
for GCP instance
#3477
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -17,9 +17,11 @@ package gcloud | |
import ( | ||
"crypto/rand" | ||
"fmt" | ||
"strconv" | ||
"strings" | ||
"time" | ||
|
||
"github.com/coreos/coreos-assembler/mantle/platform" | ||
"github.com/coreos/coreos-assembler/mantle/util" | ||
"golang.org/x/crypto/ssh/agent" | ||
"google.golang.org/api/compute/v1" | ||
|
@@ -33,8 +35,48 @@ func (a *API) vmname() string { | |
return fmt.Sprintf("%s-%x", a.options.BaseName, b) | ||
} | ||
|
||
// ["5G:interface=NVME"], by default the disk type is local-ssd | ||
func ParseDiskSpec(spec string, zone string) (*compute.AttachedDisk, error) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Optional, but I think it'd be pretty easy to have a unit test or two for this function. |
||
split := strings.Split(spec, ":") | ||
var diskinterface string | ||
var disksize string | ||
if len(split) == 1 { | ||
disksize = split[0] | ||
} else if len(split) == 2 { | ||
disksize = split[0] | ||
for _, opt := range strings.Split(split[1], ",") { | ||
if strings.HasPrefix(opt, "interface=") { | ||
diskinterface = strings.TrimPrefix(opt, "interface=") | ||
if diskinterface == "" || (diskinterface != "NVME" && diskinterface != "SCSI") { | ||
return nil, fmt.Errorf("invalid interface opt %s", opt) | ||
} | ||
} else { | ||
return nil, fmt.Errorf("unknown disk option %s", opt) | ||
} | ||
} | ||
} else { | ||
return nil, fmt.Errorf("invalid disk spec %s", spec) | ||
} | ||
disksize = strings.TrimSuffix(disksize, "G") | ||
size, err := strconv.ParseInt(disksize, 10, 32) | ||
if err != nil { | ||
return nil, fmt.Errorf("invalid size opt %s: %w", disksize, err) | ||
} | ||
|
||
return &compute.AttachedDisk{ | ||
AutoDelete: true, | ||
Boot: false, | ||
Type: "SCRATCH", | ||
Interface: diskinterface, | ||
InitializeParams: &compute.AttachedDiskInitializeParams{ | ||
DiskType: "/zones/" + zone + "/diskTypes/local-ssd", | ||
DiskSizeGb: size, | ||
}, | ||
}, nil | ||
} | ||
|
||
// Taken from: https://github.com/golang/build/blob/master/buildlet/gce.go | ||
func (a *API) mkinstance(userdata, name string, keys []*agent.Key, useServiceAcct bool) *compute.Instance { | ||
func (a *API) mkinstance(userdata, name string, keys []*agent.Key, opts platform.MachineOptions, useServiceAcct bool) (*compute.Instance, error) { | ||
mantle := "mantle" | ||
metadataItems := []*compute.MetadataItems{ | ||
{ | ||
|
@@ -120,14 +162,27 @@ func (a *API) mkinstance(userdata, name string, keys []*agent.Key, useServiceAcc | |
OnHostMaintenance: "TERMINATE", | ||
} | ||
} | ||
return instance | ||
|
||
// attach aditional disk | ||
if len(opts.AdditionalDisks) > 0 { | ||
for _, spec := range opts.AdditionalDisks { | ||
Comment on lines
+166
to
+167
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Completely minor nit, but is the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. (With stuff like this, feel free to merge as is. Minor fixups like this can be done as a followup alongside other cleanups) |
||
plog.Debugf("Parsing disk spec %q\n", spec) | ||
disk, err := ParseDiskSpec(spec, a.options.Zone) | ||
if err != nil { | ||
return nil, fmt.Errorf("failed to parse spec %s: %w", spec, err) | ||
} | ||
instance.Disks = append(instance.Disks, disk) | ||
} | ||
} | ||
return instance, nil | ||
} | ||
|
||
// CreateInstance creates a Google Compute Engine instance. | ||
func (a *API) CreateInstance(userdata string, keys []*agent.Key, useServiceAcct bool) (*compute.Instance, error) { | ||
func (a *API) CreateInstance(userdata string, keys []*agent.Key, opts platform.MachineOptions, useServiceAcct bool) (*compute.Instance, error) { | ||
name := a.vmname() | ||
inst := a.mkinstance(userdata, name, keys, useServiceAcct) | ||
inst, err := a.mkinstance(userdata, name, keys, opts, useServiceAcct) | ||
if err != nil { | ||
return nil, fmt.Errorf("failed to create instance %q: %w", name, err) | ||
} | ||
|
||
plog.Debugf("Creating instance %q", name) | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it's fine for now to have this here, but we should ideally dedupe this with the one in
qemu.go
. We can have a generic parser that returns the size in gigabytes as auint
and any options in amap[string]string
.But again, I'm OK to duplicate for now! Maybe let's add a comment in that case?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can I understand that it should return like
map[string]string{"size": "5G", "interface": "NVME"}
after parsing ? Might do this in the later patch.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was thinking more something like:
?
Where the
uint
is the disk size in gigabytes. Since it's a required argument, we can enforce proper typing for it. Also, some cloud API bindings may take it directly as an integer (like GCP here) too which is nice. Others might require a string but suffixed differently (e.g. "GB" vs "G"), which would have to live in the cloud-specific code.