X-Git-Url: https://git.arvados.org/arvados.git/blobdiff_plain/b205525d0b7c7b9042513fe77d2e8061534208ae..a8fe18b2b941f31896033bb58b9056e7731581b7:/lib/dispatchcloud/driver.go diff --git a/lib/dispatchcloud/driver.go b/lib/dispatchcloud/driver.go index 295fd6105b..eb1e48737c 100644 --- a/lib/dispatchcloud/driver.go +++ b/lib/dispatchcloud/driver.go @@ -6,17 +6,53 @@ package dispatchcloud import ( "fmt" + "time" "git.curoverse.com/arvados.git/lib/cloud" + "git.curoverse.com/arvados.git/lib/cloud/azure" + "git.curoverse.com/arvados.git/lib/cloud/ec2" "git.curoverse.com/arvados.git/sdk/go/arvados" + "github.com/sirupsen/logrus" + "golang.org/x/crypto/ssh" ) -var drivers = map[string]cloud.Driver{} +var drivers = map[string]cloud.Driver{ + "azure": azure.Driver, + "ec2": ec2.Driver, +} -func newInstanceSet(cluster *arvados.Cluster, setID cloud.InstanceSetID) (cloud.InstanceSet, error) { +func newInstanceSet(cluster *arvados.Cluster, setID cloud.InstanceSetID, logger logrus.FieldLogger) (cloud.InstanceSet, error) { driver, ok := drivers[cluster.CloudVMs.Driver] if !ok { return nil, fmt.Errorf("unsupported cloud driver %q", cluster.CloudVMs.Driver) } - return driver.InstanceSet(cluster.CloudVMs.DriverParameters, setID) + is, err := driver.InstanceSet(cluster.CloudVMs.DriverParameters, setID, logger) + if maxops := cluster.CloudVMs.MaxCloudOpsPerSecond; maxops > 0 { + is = &rateLimitedInstanceSet{ + InstanceSet: is, + ticker: time.NewTicker(time.Second / time.Duration(maxops)), + } + } + return is, err +} + +type rateLimitedInstanceSet struct { + cloud.InstanceSet + ticker *time.Ticker +} + +func (is rateLimitedInstanceSet) Create(it arvados.InstanceType, image cloud.ImageID, tags cloud.InstanceTags, init cloud.InitCommand, pk ssh.PublicKey) (cloud.Instance, error) { + <-is.ticker.C + inst, err := is.InstanceSet.Create(it, image, tags, init, pk) + return &rateLimitedInstance{inst, is.ticker}, err +} + +type rateLimitedInstance struct { + cloud.Instance + ticker *time.Ticker +} + +func (inst *rateLimitedInstance) Destroy() error { + <-inst.ticker.C + return inst.Instance.Destroy() }