X-Git-Url: https://git.arvados.org/arvados.git/blobdiff_plain/443a0b96316ed46600dc5035193adae6ac4d1f74..903b27b2f4b8b00c11525ff6c2f4eb383709d074:/lib/cloud/interfaces.go diff --git a/lib/cloud/interfaces.go b/lib/cloud/interfaces.go index 969a4bc2dd..792e737a91 100644 --- a/lib/cloud/interfaces.go +++ b/lib/cloud/interfaces.go @@ -5,6 +5,8 @@ package cloud import ( + "encoding/json" + "errors" "io" "time" @@ -56,17 +58,25 @@ type Executor interface { Execute(cmd string, stdin io.Reader) (stdout, stderr []byte, err error) } +var ErrNotImplemented = errors.New("not implemented") + // An ExecutorTarget is a remote command execution service. type ExecutorTarget interface { // SSH server hostname or IP address, or empty string if // unknown while instance is booting. Address() string + // Remote username to send during SSH authentication. + RemoteUser() string + // Return nil if the given public key matches the instance's // SSH server key. If the provided Dialer is not nil, // VerifyHostKey can use it to make outgoing network // connections from the instance -- e.g., to use the cloud's // "this instance's metadata" API. + // + // Return ErrNotImplemented if no verification mechanism is + // available. VerifyHostKey(ssh.PublicKey, *ssh.Client) error } @@ -101,12 +111,18 @@ type Instance interface { // All public methods of an InstanceSet, and all public methods of the // instances it returns, are goroutine safe. type InstanceSet interface { - // Create a new instance. If supported by the driver, add the + // Create a new instance with the given type, image, and + // initial set of tags. If supported by the driver, add the // provided public key to /root/.ssh/authorized_keys. // + // The given InitCommand should be executed on the newly + // created instance. This is optional for a driver whose + // instances' VerifyHostKey() method never returns + // ErrNotImplemented. InitCommand will be under 1 KiB. + // // The returned error should implement RateLimitError and // QuotaError where applicable. - Create(arvados.InstanceType, ImageID, InstanceTags, ssh.PublicKey) (Instance, error) + Create(arvados.InstanceType, ImageID, InstanceTags, InitCommand, ssh.PublicKey) (Instance, error) // Return all instances, including ones that are booting or // shutting down. Optionally, filter out nodes that don't have @@ -124,6 +140,8 @@ type InstanceSet interface { Stop() } +type InitCommand string + // A Driver returns an InstanceSet that uses the given InstanceSetID // and driver-dependent configuration parameters. // @@ -153,9 +171,9 @@ type InstanceSet interface { // // type exampleDriver struct {} // -// func (*exampleDriver) InstanceSet(config map[string]interface{}, id InstanceSetID) (InstanceSet, error) { +// func (*exampleDriver) InstanceSet(config json.RawMessage, id InstanceSetID) (InstanceSet, error) { // var is exampleInstanceSet -// if err := mapstructure.Decode(config, &is); err != nil { +// if err := json.Unmarshal(config, &is); err != nil { // return nil, err // } // is.ownID = id @@ -164,17 +182,17 @@ type InstanceSet interface { // // var _ = registerCloudDriver("example", &exampleDriver{}) type Driver interface { - InstanceSet(config map[string]interface{}, id InstanceSetID, logger logrus.FieldLogger) (InstanceSet, error) + InstanceSet(config json.RawMessage, id InstanceSetID, logger logrus.FieldLogger) (InstanceSet, error) } // DriverFunc makes a Driver using the provided function as its // InstanceSet method. This is similar to http.HandlerFunc. -func DriverFunc(fn func(config map[string]interface{}, id InstanceSetID, logger logrus.FieldLogger) (InstanceSet, error)) Driver { +func DriverFunc(fn func(config json.RawMessage, id InstanceSetID, logger logrus.FieldLogger) (InstanceSet, error)) Driver { return driverFunc(fn) } -type driverFunc func(config map[string]interface{}, id InstanceSetID, logger logrus.FieldLogger) (InstanceSet, error) +type driverFunc func(config json.RawMessage, id InstanceSetID, logger logrus.FieldLogger) (InstanceSet, error) -func (df driverFunc) InstanceSet(config map[string]interface{}, id InstanceSetID, logger logrus.FieldLogger) (InstanceSet, error) { +func (df driverFunc) InstanceSet(config json.RawMessage, id InstanceSetID, logger logrus.FieldLogger) (InstanceSet, error) { return df(config, id, logger) }