// Copyright (C) The Arvados Authors. All rights reserved. // // SPDX-License-Identifier: AGPL-3.0 package test import ( "fmt" "math/rand" "sync" "git.curoverse.com/arvados.git/lib/cloud" "git.curoverse.com/arvados.git/sdk/go/arvados" "golang.org/x/crypto/ssh" ) // LameInstanceSet creates instances that boot but can't run // containers. type LameInstanceSet struct { Hold chan bool // set to make(chan bool) to hold operations until Release is called mtx sync.Mutex instances map[*lameInstance]bool } // Create returns a new instance. func (p *LameInstanceSet) Create(instType arvados.InstanceType, imageID cloud.ImageID, tags cloud.InstanceTags, pubkey ssh.PublicKey) (cloud.Instance, error) { inst := &lameInstance{ p: p, id: cloud.InstanceID(fmt.Sprintf("lame-%x", rand.Uint64())), providerType: instType.ProviderType, } inst.SetTags(tags) if p.Hold != nil { p.Hold <- true } p.mtx.Lock() defer p.mtx.Unlock() if p.instances == nil { p.instances = map[*lameInstance]bool{} } p.instances[inst] = true return inst, nil } // Instances returns the instances that haven't been destroyed. func (p *LameInstanceSet) Instances(cloud.InstanceTags) ([]cloud.Instance, error) { p.mtx.Lock() defer p.mtx.Unlock() var instances []cloud.Instance for i := range p.instances { instances = append(instances, i) } return instances, nil } // Stop is a no-op, but exists to satisfy cloud.InstanceSet. func (p *LameInstanceSet) Stop() { } // Release n held calls. Blocks if n calls aren't already // waiting. Blocks forever if Hold is nil. func (p *LameInstanceSet) Release(n int) { for i := 0; i < n; i++ { <-p.Hold } } type lameInstance struct { p *LameInstanceSet id cloud.InstanceID providerType string tags cloud.InstanceTags } func (inst *lameInstance) ID() cloud.InstanceID { return inst.id } func (inst *lameInstance) String() string { return fmt.Sprint(inst.id) } func (inst *lameInstance) ProviderType() string { return inst.providerType } func (inst *lameInstance) Address() string { return "0.0.0.0:1234" } func (inst *lameInstance) SetTags(tags cloud.InstanceTags) error { inst.p.mtx.Lock() defer inst.p.mtx.Unlock() inst.tags = cloud.InstanceTags{} for k, v := range tags { inst.tags[k] = v } return nil } func (inst *lameInstance) Destroy() error { if inst.p.Hold != nil { inst.p.Hold <- true } inst.p.mtx.Lock() defer inst.p.mtx.Unlock() delete(inst.p.instances, inst) return nil } func (inst *lameInstance) Tags() cloud.InstanceTags { return inst.tags } func (inst *lameInstance) VerifyHostKey(ssh.PublicKey, *ssh.Client) error { return nil }