-
Notifications
You must be signed in to change notification settings - Fork 18
/
parallels.go
81 lines (67 loc) · 2.13 KB
/
parallels.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
package parallels
import (
"context"
"errors"
"fmt"
"github.com/avast/retry-go"
"github.com/cirruslabs/cirrus-cli/internal/executor/instance/persistentworker/remoteagent"
"github.com/cirruslabs/cirrus-cli/internal/executor/instance/runconfig"
"github.com/cirruslabs/cirrus-cli/internal/executor/platform"
"github.com/cirruslabs/cirrus-cli/internal/logger"
)
var (
ErrFailed = errors.New("Parallels isolation failed")
)
type Parallels struct {
logger logger.Lightweight
vmImage string
sshUser string
sshPassword string
agentOS string
}
func New(vmImage, sshUser, sshPassword, agentOS string, opts ...Option) (*Parallels, error) {
parallels := &Parallels{
vmImage: vmImage,
sshUser: sshUser,
sshPassword: sshPassword,
agentOS: agentOS,
}
// Apply options
for _, opt := range opts {
opt(parallels)
}
// Apply default options (to cover those that weren't specified)
if parallels.logger == nil {
parallels.logger = &logger.LightweightStub{}
}
return parallels, nil
}
func (parallels *Parallels) Run(ctx context.Context, config *runconfig.RunConfig) (err error) {
vm, err := NewVMClonedFrom(ctx, parallels.vmImage)
if err != nil {
return fmt.Errorf("%w: failed to create VM cloned from %q: %v", ErrFailed, parallels.vmImage, err)
}
defer vm.Close()
if err := vm.Start(ctx); err != nil {
return fmt.Errorf("%w: failed to start VM %q: %v", ErrFailed, vm.Ident(), err)
}
// Wait for the VM to start and get it's DHCP address
var ip string
if err := retry.Do(func() error {
ip, err = vm.RetrieveIP(ctx)
return err
}, retry.Context(ctx), retry.RetryIf(func(err error) bool {
return errors.Is(err, ErrDHCPSnoopFailed)
})); err != nil {
return fmt.Errorf("%w: failed to retrieve VM %q IP-address: %v", ErrFailed, vm.name, err)
}
return remoteagent.WaitForAgent(ctx, parallels.logger, ip,
parallels.sshUser, parallels.sshPassword, parallels.agentOS, "amd64",
config, vm.ClonedFromSuspended())
}
func (parallels *Parallels) WorkingDirectory(projectDir string, dirtyMode bool) string {
return platform.NewUnix().GenericWorkingDir()
}
func (parallels *Parallels) Close() error {
return nil
}