aboutsummaryrefslogtreecommitdiffstats
path: root/vm/vmimpl/vmimpl.go
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2017-06-02 20:09:00 +0200
committerDmitry Vyukov <dvyukov@google.com>2017-06-03 11:31:42 +0200
commitaf643baa328ae3d4b7076054bba648c4b8bf8056 (patch)
tree6e4687c745b63352dec21f6ac2a6a7d8fa1201c4 /vm/vmimpl/vmimpl.go
parent96b8d4e99c7812f91633ea6cd1aee5867965e742 (diff)
vm: overhaul
VM infrastructure currently has several problems: - Config struct is complete mess with a superset of params for all VM types - verification of Config is mess spread across several places - there is no place where VM code could do global initialization like creating GCE connection, uploading GCE image to GCS, matching adb devices with consoles, etc - it hard to add private VM implementations such impl would need to add code to config package which would lead to constant merge conflicts - interface for VM implementation is mixed with interface for VM users this does not allow to provide best interface for both of them - there is no way to add common code for all VM implementations This change solves these problems by: - splitting VM interface for users (vm package) and VM interface for VM implementations (vmimpl pacakge), this in turn allows to add common code - adding Pool concept that allows to do global initialization and config checking at the right time - decoupling manager config from VM-specific config each VM type now defines own config Note: manager configs need to be changed after this change: VM-specific parts are moved to own "vm" subobject. Note: this change also drops "local" VM type. Its story was long unclear and there is now syz-stress which solves the same problem.
Diffstat (limited to 'vm/vmimpl/vmimpl.go')
-rw-r--r--vm/vmimpl/vmimpl.go77
1 files changed, 77 insertions, 0 deletions
diff --git a/vm/vmimpl/vmimpl.go b/vm/vmimpl/vmimpl.go
new file mode 100644
index 000000000..4c542429c
--- /dev/null
+++ b/vm/vmimpl/vmimpl.go
@@ -0,0 +1,77 @@
+// Copyright 2017 syzkaller project authors. All rights reserved.
+// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
+
+// Package vmimpl provides an abstract test machine (VM, physical machine, etc)
+// interface for the rest of the system. For convenience test machines are subsequently
+// collectively called VMs.
+// The package also provides various utility functions for VM implementations.
+package vmimpl
+
+import (
+ "errors"
+ "fmt"
+ "time"
+)
+
+// Pool represents a set of test machines (VMs, physical devices, etc) of particular type.
+type Pool interface {
+ // Count returns total number of VMs in the pool.
+ Count() int
+
+ // Create creates and boots a new VM instance.
+ Create(workdir string, index int) (Instance, error)
+}
+
+// Instance represents a single VM.
+type Instance interface {
+ // Copy copies a hostSrc file into VM and returns file name in VM.
+ Copy(hostSrc string) (string, error)
+
+ // Forward setups forwarding from within VM to host port port
+ // and returns address to use in VM.
+ Forward(port int) (string, error)
+
+ // Run runs cmd inside of the VM (think of ssh cmd).
+ // outc receives combined cmd and kernel console output.
+ // errc receives either command Wait return error or vmimpl.TimeoutErr.
+ // Command is terminated after timeout. Send on the stop chan can be used to terminate it earlier.
+ Run(timeout time.Duration, stop <-chan bool, command string) (outc <-chan []byte, errc <-chan error, err error)
+
+ // Close stops and destroys the VM.
+ Close()
+}
+
+// Env contains global constant parameters for a pool of VMs.
+type Env struct {
+ // Unique name
+ // Can be used for VM name collision resolution if several pools share global name space.
+ Name string
+ Workdir string
+ Image string
+ Debug bool
+ Config []byte // json-serialized VM-type-specific config
+}
+
+// Create creates a VM type that can be used to create individual VMs.
+func Create(typ string, env *Env) (Pool, error) {
+ ctor := ctors[typ]
+ if ctor == nil {
+ return nil, fmt.Errorf("unknown instance type '%v'", typ)
+ }
+ return ctor(env)
+}
+
+// Register registers a new VM type within the package.
+func Register(typ string, ctor ctorFunc) {
+ ctors[typ] = ctor
+}
+
+var (
+ // Close to interrupt all pending operations in all VMs.
+ Shutdown = make(chan struct{})
+ TimeoutErr = errors.New("timeout")
+
+ ctors = make(map[string]ctorFunc)
+)
+
+type ctorFunc func(env *Env) (Pool, error)