aboutsummaryrefslogtreecommitdiffstats
path: root/vm
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2017-06-03 11:48:19 +0200
committerDmitry Vyukov <dvyukov@google.com>2017-06-03 11:48:19 +0200
commitb68d01eea0c45f14b6bd9b54485b7f7e287d008e (patch)
tree2fba436d78ef3cf20e9e75dbfa75d0c48d0b3f67 /vm
parentaf643baa328ae3d4b7076054bba648c4b8bf8056 (diff)
vm/gce: accept local image
Currently gce accepts precreated GCE image name as image config param, while all other VM types accept local file path as image. This makes it impossible to write generic code that works with all VM types, i.e. after building a new image it's unclear if it needs to be uploaded to GCE or not, and what needs to be passed as image in config. Eliminate this difference by making gce accept local image file as well.
Diffstat (limited to 'vm')
-rw-r--r--vm/gce/gce.go44
1 files changed, 36 insertions, 8 deletions
diff --git a/vm/gce/gce.go b/vm/gce/gce.go
index afb393fd4..d0a181250 100644
--- a/vm/gce/gce.go
+++ b/vm/gce/gce.go
@@ -20,6 +20,7 @@ import (
"github.com/google/syzkaller/pkg/config"
"github.com/google/syzkaller/pkg/gce"
+ "github.com/google/syzkaller/pkg/gcs"
. "github.com/google/syzkaller/pkg/log"
"github.com/google/syzkaller/pkg/osutil"
"github.com/google/syzkaller/vm/vmimpl"
@@ -32,13 +33,15 @@ func init() {
type Config struct {
Count int // number of VMs to use
Machine_Type string // GCE machine type (e.g. "n1-highcpu-2")
+ GCS_Path string // GCS path to upload image
Sshkey string // root ssh key for the image
}
type Pool struct {
- env *vmimpl.Env
- cfg *Config
- GCE *gce.Context
+ env *vmimpl.Env
+ cfg *Config
+ GCE *gce.Context
+ gceImage string
}
type instance struct {
@@ -58,6 +61,9 @@ func ctor(env *vmimpl.Env) (vmimpl.Pool, error) {
if env.Name == "" {
return nil, fmt.Errorf("config param name is empty (required for GCE)")
}
+ if env.Image == "" {
+ return nil, fmt.Errorf("config param image is empty (required for GCE)")
+ }
cfg := &Config{
Count: 1,
}
@@ -73,18 +79,40 @@ func ctor(env *vmimpl.Env) (vmimpl.Pool, error) {
if cfg.Machine_Type == "" {
return nil, fmt.Errorf("machine_type parameter is empty")
}
+ if cfg.GCS_Path == "" {
+ return nil, fmt.Errorf("gcs_path parameter is empty")
+ }
cfg.Sshkey = osutil.Abs(cfg.Sshkey)
GCE, err := gce.NewContext()
if err != nil {
return nil, fmt.Errorf("failed to init gce: %v", err)
}
- Logf(0, "gce initialized: running on %v, internal IP %v, project %v, zone %v",
+ Logf(0, "GCE initialized: running on %v, internal IP %v, project %v, zone %v",
GCE.Instance, GCE.InternalIP, GCE.ProjectID, GCE.ZoneID)
+ GCS, err := gcs.NewClient()
+ if err != nil {
+ return nil, fmt.Errorf("failed to create GCS client: %v", err)
+ }
+ defer GCS.Close()
+ gcsImage := filepath.Join(cfg.GCS_Path, env.Name+"-image.tar.gz")
+ gceImage := env.Name
+ Logf(0, "uploading image to %v...", gcsImage)
+ if err := GCS.UploadFile(env.Image, gcsImage); err != nil {
+ return nil, fmt.Errorf("failed to upload image: %v", err)
+ }
+ Logf(0, "creating GCE image...")
+ if err := GCE.DeleteImage(gceImage); err != nil {
+ return nil, fmt.Errorf("failed to delete GCE image: %v", err)
+ }
+ if err := GCE.CreateImage(gceImage, gcsImage); err != nil {
+ return nil, fmt.Errorf("failed to create GCE image: %v", err)
+ }
pool := &Pool{
- cfg: cfg,
- env: env,
- GCE: GCE,
+ cfg: cfg,
+ env: env,
+ GCE: GCE,
+ gceImage: gceImage,
}
return pool, nil
}
@@ -111,7 +139,7 @@ func (pool *Pool) Create(workdir string, index int) (vmimpl.Instance, error) {
return nil, err
}
Logf(0, "creating instance: %v", name)
- ip, err := pool.GCE.CreateInstance(name, pool.cfg.Machine_Type, pool.env.Image, string(gceKeyPub))
+ ip, err := pool.GCE.CreateInstance(name, pool.cfg.Machine_Type, pool.gceImage, string(gceKeyPub))
if err != nil {
return nil, err
}