From e2da49c7e27610552def1b26d087a32fe29db4b4 Mon Sep 17 00:00:00 2001
From: Dave Tucker
Date: Fri, 7 Apr 2017 14:39:13 +0100
Subject: [PATCH] moby: Add -img-name flag to moby run gcp
This allows overriding the name used of the file in google storage,
image name or instance name. This will vary depending on how much `moby
run` is doing which is goverened by whether the positional argument
contains an `.img.tar.gz` or not.
For example:
`moby run gcp -img-name test-ea34d1 test` creates an instance called
`test-ea34d1` from the image `test`
`moby run gcp -img-name test-ea34d1` test.img.tar.gz` will upload the
file as `test-ea34d1.tar.gz`, create image `test-ea34d1` and create an
instance called `test-ea34d1`.
The use case for this is for CI to be able to spawn many concurrent test
machines and provide it's own name for them.
Signed-off-by: Dave Tucker
---
src/cmd/moby/gcp.go | 34 +++++++++++++++++-----------------
src/cmd/moby/output.go | 4 ++--
src/cmd/moby/run_gcp.go | 25 +++++++++++++++++++------
3 files changed, 38 insertions(+), 25 deletions(-)
diff --git a/src/cmd/moby/gcp.go b/src/cmd/moby/gcp.go
index 80d2f435f..d3e3b9ca9 100644
--- a/src/cmd/moby/gcp.go
+++ b/src/cmd/moby/gcp.go
@@ -99,15 +99,15 @@ func NewGCPClient(keys, projectName string) (*GCPClient, error) {
}
// UploadFile uploads a file to Google Storage
-func (g GCPClient) UploadFile(filename, bucketName string, public bool) error {
- log.Infof("Uploading file %s to Google Storage", filename)
- f, err := os.Open(filename)
+func (g GCPClient) UploadFile(src, dst, bucketName string, public bool) error {
+ log.Infof("Uploading file %s to Google Storage as %s", src, dst)
+ f, err := os.Open(src)
if err != nil {
return err
}
defer f.Close()
- objectCall := g.storage.Objects.Insert(bucketName, &storage.Object{Name: filename}).Media(f)
+ objectCall := g.storage.Objects.Insert(bucketName, &storage.Object{Name: dst}).Media(f)
if public {
objectCall.PredefinedAcl("publicRead")
@@ -118,24 +118,24 @@ func (g GCPClient) UploadFile(filename, bucketName string, public bool) error {
return err
}
log.Infof("Upload Complete!")
- fmt.Println("gs://" + bucketName + "/" + filename)
+ fmt.Println("gs://" + bucketName + "/" + dst)
return nil
}
// CreateImage creates a GCP image using the a source from Google Storage
-func (g GCPClient) CreateImage(filename, storageURL, family string, replace bool) error {
+func (g GCPClient) CreateImage(name, storageURL, family string, replace bool) error {
if replace {
- if err := g.DeleteImage(filename); err != nil {
+ if err := g.DeleteImage(name); err != nil {
return err
}
}
- log.Infof("Creating image: %s", filename)
+ log.Infof("Creating image: %s", name)
imgObj := &compute.Image{
RawDisk: &compute.ImageRawDisk{
Source: storageURL,
},
- Name: filename,
+ Name: name,
}
if family != "" {
@@ -150,14 +150,14 @@ func (g GCPClient) CreateImage(filename, storageURL, family string, replace bool
if err := g.pollOperationStatus(op.Name); err != nil {
return err
}
- log.Infof("Image %s created", filename)
+ log.Infof("Image %s created", name)
return nil
}
// DeleteImage deletes and image
-func (g GCPClient) DeleteImage(filename string) error {
+func (g GCPClient) DeleteImage(name string) error {
var notFound bool
- op, err := g.compute.Images.Delete(g.projectName, filename).Do()
+ op, err := g.compute.Images.Delete(g.projectName, name).Do()
if err != nil {
if err.(*googleapi.Error).Code != 404 {
return err
@@ -169,20 +169,20 @@ func (g GCPClient) DeleteImage(filename string) error {
if err := g.pollOperationStatus(op.Name); err != nil {
return err
}
- log.Infof("Image %s deleted", filename)
+ log.Infof("Image %s deleted", name)
}
return nil
}
// CreateInstance creates and starts an instance on GCP
-func (g GCPClient) CreateInstance(image, zone, machineType string, replace bool) error {
+func (g GCPClient) CreateInstance(name, image, zone, machineType string, replace bool) error {
if replace {
- if err := g.DeleteInstance(image, zone, true); err != nil {
+ if err := g.DeleteInstance(name, zone, true); err != nil {
return err
}
}
- log.Infof("Creating instance %s", image)
+ log.Infof("Creating instance %s from image %s", name, image)
enabled := new(string)
*enabled = "1"
@@ -195,7 +195,7 @@ func (g GCPClient) CreateInstance(image, zone, machineType string, replace bool)
instanceObj := &compute.Instance{
MachineType: fmt.Sprintf("zones/%s/machineTypes/%s", zone, machineType),
- Name: image,
+ Name: name,
Disks: []*compute.AttachedDisk{
{
AutoDelete: true,
diff --git a/src/cmd/moby/output.go b/src/cmd/moby/output.go
index 5d7bf1d5a..a51d49444 100644
--- a/src/cmd/moby/output.go
+++ b/src/cmd/moby/output.go
@@ -55,7 +55,7 @@ func outputs(m *Moby, base string, bzimage []byte, initrd []byte) error {
if err != nil {
return fmt.Errorf("Unable to connect to GCP")
}
- err = gClient.UploadFile(base+".img.tar.gz", o.Bucket, o.Public)
+ err = gClient.UploadFile(base+".img.tar.gz", base+".img.tar.gz", o.Bucket, o.Public)
if err != nil {
return fmt.Errorf("Error copying to Google Storage: %v", err)
}
@@ -71,7 +71,7 @@ func outputs(m *Moby, base string, bzimage []byte, initrd []byte) error {
if err != nil {
return fmt.Errorf("Unable to connect to GCP")
}
- err = gClient.UploadFile(base+".img.tar.gz", o.Bucket, o.Public)
+ err = gClient.UploadFile(base+".img.tar.gz", base+".img.tar.gz", o.Bucket, o.Public)
if err != nil {
return fmt.Errorf("Error copying to Google Storage: %v", err)
}
diff --git a/src/cmd/moby/run_gcp.go b/src/cmd/moby/run_gcp.go
index 856944a00..9b88ebf95 100644
--- a/src/cmd/moby/run_gcp.go
+++ b/src/cmd/moby/run_gcp.go
@@ -19,6 +19,7 @@ const (
bucketVar = "MOBY_GCP_BUCKET"
familyVar = "MOBY_GCP_FAMILY"
publicVar = "MOBY_GCP_PUBLIC"
+ nameVar = "MOBY_GCP_IMAGE_NAME"
)
// Process the run arguments and execute run
@@ -39,7 +40,9 @@ func runGcp(args []string) {
bucketFlag := gcpCmd.String("bucket", "", "GS Bucket to upload to. *Required* when 'prefix' is a filename")
publicFlag := gcpCmd.Bool("public", false, "Select if file on GS should be public. *Optional* when 'prefix' is a filename")
familyFlag := gcpCmd.String("family", "", "GCP Image Family. A group of images where the family name points to the most recent image. *Optional* when 'prefix' is a filename")
+ nameFlag := gcpCmd.String("img-name", "", "Overrides the Name used to identify the file in Google Storage, Image and Instance. Defaults to [name]")
gcpCmd.Parse(args)
+
remArgs := gcpCmd.Args()
if len(remArgs) == 0 {
fmt.Printf("Please specify the prefix to the image to boot\n")
@@ -55,6 +58,7 @@ func runGcp(args []string) {
bucket := getStringValue(bucketVar, *bucketFlag, "")
public := getBoolValue(publicVar, *publicFlag)
family := getStringValue(familyVar, *familyFlag, "")
+ name := getStringValue(nameVar, *nameFlag, "")
client, err := NewGCPClient(keys, project)
if err != nil {
@@ -63,12 +67,16 @@ func runGcp(args []string) {
suffix := ".img.tar.gz"
if strings.HasSuffix(prefix, suffix) {
- filename := prefix
- prefix = prefix[:len(prefix)-len(suffix)]
+ src := prefix
+ if name != "" {
+ prefix = name
+ } else {
+ prefix = prefix[:len(prefix)-len(suffix)]
+ }
if bucket == "" {
log.Fatalf("No bucket specified. Please provide one using the -bucket flag")
}
- err = client.UploadFile(filename, bucket, public)
+ err = client.UploadFile(src, prefix+suffix, bucket, public)
if err != nil {
log.Fatalf("Error copying to Google Storage: %v", err)
}
@@ -78,15 +86,20 @@ func runGcp(args []string) {
}
}
- if err = client.CreateInstance(prefix, zone, machine, true); err != nil {
+ // If no name was supplied, use the prefix
+ if name == "" {
+ name = prefix
+ }
+
+ if err = client.CreateInstance(name, prefix, zone, machine, true); err != nil {
log.Fatal(err)
}
- if err = client.ConnectToInstanceSerialPort(prefix, zone); err != nil {
+ if err = client.ConnectToInstanceSerialPort(name, zone); err != nil {
log.Fatal(err)
}
- if err = client.DeleteInstance(prefix, zone, true); err != nil {
+ if err = client.DeleteInstance(name, zone, true); err != nil {
log.Fatal(err)
}
}