diff --git a/src/cmd/linuxkit/gcp.go b/src/cmd/linuxkit/gcp.go index 18d217d13..a315de50b 100644 --- a/src/cmd/linuxkit/gcp.go +++ b/src/cmd/linuxkit/gcp.go @@ -123,7 +123,7 @@ func (g GCPClient) UploadFile(src, dst, bucketName string, public bool) error { } // CreateImage creates a GCP image using the a source from Google Storage -func (g GCPClient) CreateImage(name, storageURL, family string, replace bool) error { +func (g GCPClient) CreateImage(name, storageURL, family string, nested, replace bool) error { if replace { if err := g.DeleteImage(name); err != nil { return err @@ -142,6 +142,10 @@ func (g GCPClient) CreateImage(name, storageURL, family string, replace bool) er imgObj.Family = family } + if nested { + imgObj.Licenses = []string{"projects/vm-options/global/licenses/enable-vmx"} + } + op, err := g.compute.Images.Insert(g.projectName, imgObj).Do() if err != nil { return err @@ -178,7 +182,7 @@ func (g GCPClient) DeleteImage(name string) error { } // CreateInstance creates and starts an instance on GCP -func (g GCPClient) CreateInstance(name, image, zone, machineType string, disks Disks, replace bool) error { +func (g GCPClient) CreateInstance(name, image, zone, machineType string, disks Disks, nested, replace bool) error { if replace { if err := g.DeleteInstance(name, zone, true); err != nil { return err @@ -262,6 +266,11 @@ func (g GCPClient) CreateInstance(name, image, zone, machineType string, disks D }, } + if nested { + // TODO(rn): We could/should check here if the image has nested virt enabled + instanceObj.MinCpuPlatform = "Intel Haswell" + } + // Don't wait for operation to complete! // A headstart is needed as by the time we've polled for this event to be // completed, the instance may have already terminated diff --git a/src/cmd/linuxkit/push_gcp.go b/src/cmd/linuxkit/push_gcp.go index 20c74cb4a..826c86da1 100644 --- a/src/cmd/linuxkit/push_gcp.go +++ b/src/cmd/linuxkit/push_gcp.go @@ -25,6 +25,7 @@ func pushGcp(args []string) { publicFlag := flags.Bool("public", false, "Select if file on GCS should be public. *Optional*") familyFlag := flags.String("family", "", "GCP Image Family. A group of images where the family name points to the most recent image. *Optional*") nameFlag := flags.String("img-name", "", "Overrides the name used to identify the file in Google Storage and the VM image. Defaults to the base of 'path' with the '.img.tar.gz' suffix removed") + nestedVirt := flags.Bool("nested-virt", false, "Enabled nested virtualization for the image") if err := flags.Parse(args); err != nil { log.Fatal("Unable to parse args") @@ -64,7 +65,7 @@ func pushGcp(args []string) { if err != nil { log.Fatalf("Error copying to Google Storage: %v", err) } - err = client.CreateImage(name, "https://storage.googleapis.com/"+bucket+"/"+name+suffix, family, true) + err = client.CreateImage(name, "https://storage.googleapis.com/"+bucket+"/"+name+suffix, family, *nestedVirt, true) if err != nil { log.Fatalf("Error creating Google Compute Image: %v", err) } diff --git a/src/cmd/linuxkit/run_gcp.go b/src/cmd/linuxkit/run_gcp.go index ef19acd75..1e7c2a820 100644 --- a/src/cmd/linuxkit/run_gcp.go +++ b/src/cmd/linuxkit/run_gcp.go @@ -43,6 +43,7 @@ func runGcp(args []string) { 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") + nestedVirt := flags.Bool("nested-virt", false, "Enabled nested virtualization") if err := flags.Parse(args); err != nil { log.Fatal("Unable to parse args") @@ -66,7 +67,7 @@ func runGcp(args []string) { log.Fatalf("Unable to connect to GCP") } - if err = client.CreateInstance(name, name, zone, machine, disks, true); err != nil { + if err = client.CreateInstance(name, name, zone, machine, disks, *nestedVirt, true); err != nil { log.Fatal(err) }