Merge pull request #2302 from dave-tucker/mdgcp

linuxkit: Better GCP disk handling
This commit is contained in:
Justin Cormack 2017-08-07 16:01:53 +01:00 committed by GitHub
commit 73b516f09b
3 changed files with 60 additions and 33 deletions

View File

@ -178,7 +178,7 @@ func (g GCPClient) DeleteImage(name string) error {
} }
// CreateInstance creates and starts an instance on GCP // CreateInstance creates and starts an instance on GCP
func (g GCPClient) CreateInstance(name, image, zone, machineType string, diskSize int, replace bool) error { func (g GCPClient) CreateInstance(name, image, zone, machineType string, disks Disks, replace bool) error {
if replace { if replace {
if err := g.DeleteInstance(name, zone, true); err != nil { if err := g.DeleteInstance(name, zone, true); err != nil {
return err return err
@ -197,32 +197,47 @@ func (g GCPClient) CreateInstance(name, image, zone, machineType string, diskSiz
sshKey := new(string) sshKey := new(string)
*sshKey = fmt.Sprintf("moby:%s moby", string(ssh.MarshalAuthorizedKey(k))) *sshKey = fmt.Sprintf("moby:%s moby", string(ssh.MarshalAuthorizedKey(k)))
diskName := name + "-systemdisk" instanceDisks := []*compute.AttachedDisk{
diskOp, err := g.compute.Disks.Insert(g.projectName, zone, &compute.Disk{Name: diskName, SizeGb: int64(diskSize)}).Do() {
if err != nil { AutoDelete: true,
return err Boot: true,
InitializeParams: &compute.AttachedDiskInitializeParams{
SourceImage: fmt.Sprintf("global/images/%s", image),
},
},
} }
if err := g.pollZoneOperationStatus(diskOp.Name, zone); err != nil {
return err for i, disk := range disks {
var diskName string
if disk.Path != "" {
diskName = disk.Path
} else {
diskName = fmt.Sprintf("%s-disk-%d", name, i)
}
var diskSizeGb int64
if disk.Size == 0 {
diskSizeGb = int64(1)
} else {
diskSizeGb = int64(convertMBtoGB(disk.Size))
}
diskOp, err := g.compute.Disks.Insert(g.projectName, zone, &compute.Disk{Name: diskName, SizeGb: diskSizeGb}).Do()
if err != nil {
return err
}
if err := g.pollZoneOperationStatus(diskOp.Name, zone); err != nil {
return err
}
instanceDisks = append(instanceDisks, &compute.AttachedDisk{
AutoDelete: true,
Boot: false,
Source: fmt.Sprintf("zones/%s/disks/%s", zone, diskName),
})
} }
instanceObj := &compute.Instance{ instanceObj := &compute.Instance{
MachineType: fmt.Sprintf("zones/%s/machineTypes/%s", zone, machineType), MachineType: fmt.Sprintf("zones/%s/machineTypes/%s", zone, machineType),
Name: name, Name: name,
Disks: []*compute.AttachedDisk{ Disks: instanceDisks,
{
AutoDelete: true,
Boot: true,
InitializeParams: &compute.AttachedDiskInitializeParams{
SourceImage: fmt.Sprintf("global/images/%s", image),
},
},
{
AutoDelete: true,
Boot: false,
Source: fmt.Sprintf("zones/%s/disks/%s", zone, diskName),
},
},
NetworkInterfaces: []*compute.NetworkInterface{ NetworkInterfaces: []*compute.NetworkInterface{
{ {
Network: "global/networks/default", Network: "global/networks/default",

View File

@ -14,15 +14,14 @@ const (
defaultMachine = "g1-small" defaultMachine = "g1-small"
defaultDiskSize = 1 defaultDiskSize = 1
// Environment variables. Some are non-standard // Environment variables. Some are non-standard
zoneVar = "CLOUDSDK_COMPUTE_ZONE" zoneVar = "CLOUDSDK_COMPUTE_ZONE"
machineVar = "CLOUDSDK_COMPUTE_MACHINE" // non-standard machineVar = "CLOUDSDK_COMPUTE_MACHINE" // non-standard
keysVar = "CLOUDSDK_COMPUTE_KEYS" // non-standard keysVar = "CLOUDSDK_COMPUTE_KEYS" // non-standard
projectVar = "CLOUDSDK_CORE_PROJECT" projectVar = "CLOUDSDK_CORE_PROJECT"
bucketVar = "CLOUDSDK_IMAGE_BUCKET" // non-standard bucketVar = "CLOUDSDK_IMAGE_BUCKET" // non-standard
familyVar = "CLOUDSDK_IMAGE_FAMILY" // non-standard familyVar = "CLOUDSDK_IMAGE_FAMILY" // non-standard
publicVar = "CLOUDSDK_IMAGE_PUBLIC" // non-standard publicVar = "CLOUDSDK_IMAGE_PUBLIC" // non-standard
nameVar = "CLOUDSDK_IMAGE_NAME" // non-standard nameVar = "CLOUDSDK_IMAGE_NAME" // non-standard
diskSizeVar = "CLOUDSDK_DISK_SIZE" // non-standard
) )
// Process the run arguments and execute run // Process the run arguments and execute run
@ -41,7 +40,9 @@ func runGcp(args []string) {
machineFlag := flags.String("machine", defaultMachine, "GCP Machine Type") machineFlag := flags.String("machine", defaultMachine, "GCP Machine Type")
keysFlag := flags.String("keys", "", "Path to Service Account JSON key file") keysFlag := flags.String("keys", "", "Path to Service Account JSON key file")
projectFlag := flags.String("project", "", "GCP Project Name") projectFlag := flags.String("project", "", "GCP Project Name")
diskSizeFlag := flags.Int("disk-size", 0, "Size of system disk in GB") var disks Disks
flags.Var(&disks, "disk", "Disk config, may be repeated. [file=]diskName[,size=1G]")
skipCleanup := flags.Bool("skip-cleanup", false, "Don't remove images or VMs") skipCleanup := flags.Bool("skip-cleanup", false, "Don't remove images or VMs")
if err := flags.Parse(args); err != nil { if err := flags.Parse(args); err != nil {
@ -60,14 +61,13 @@ func runGcp(args []string) {
machine := getStringValue(machineVar, *machineFlag, defaultMachine) machine := getStringValue(machineVar, *machineFlag, defaultMachine)
keys := getStringValue(keysVar, *keysFlag, "") keys := getStringValue(keysVar, *keysFlag, "")
project := getStringValue(projectVar, *projectFlag, "") project := getStringValue(projectVar, *projectFlag, "")
diskSize := getIntValue(diskSizeVar, *diskSizeFlag, defaultDiskSize)
client, err := NewGCPClient(keys, project) client, err := NewGCPClient(keys, project)
if err != nil { if err != nil {
log.Fatalf("Unable to connect to GCP") log.Fatalf("Unable to connect to GCP")
} }
if err = client.CreateInstance(name, name, zone, machine, diskSize, true); err != nil { if err = client.CreateInstance(name, name, zone, machine, disks, true); err != nil {
log.Fatal(err) log.Fatal(err)
} }

View File

@ -135,6 +135,18 @@ func getDiskSizeMB(s string) (int, error) {
return 1024 * i, nil return 1024 * i, nil
} }
func convertMBtoGB(i int) int {
if i < 1024 {
return 1
}
if i%1024 == 0 {
return i / 1024
}
return (i + (1024 - i%1024)) / 1024
}
// DiskConfig is the config for a disk // DiskConfig is the config for a disk
type DiskConfig struct { type DiskConfig struct {
Path string Path string