-
Notifications
You must be signed in to change notification settings - Fork 18
/
instance.go
121 lines (111 loc) · 4.04 KB
/
instance.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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
package instance
import (
"errors"
"fmt"
"github.com/cirruslabs/cirrus-ci-agent/api"
"github.com/cirruslabs/cirrus-cli/internal/executor/instance/abstract"
"github.com/cirruslabs/cirrus-cli/internal/executor/instance/container"
"github.com/cirruslabs/cirrus-cli/internal/executor/instance/persistentworker"
"github.com/cirruslabs/cirrus-cli/internal/executor/instance/persistentworker/isolation/tart"
"github.com/cirruslabs/cirrus-cli/internal/executor/platform"
"github.com/cirruslabs/cirrus-cli/internal/logger"
"github.com/cirruslabs/cirrus-cli/internal/worker/security"
"github.com/golang/protobuf/ptypes/any"
"golang.org/x/text/cases"
"golang.org/x/text/language"
"google.golang.org/protobuf/proto"
"google.golang.org/protobuf/types/known/anypb"
"path"
"runtime"
"strings"
)
var (
ErrFailedToCreateInstance = errors.New("failed to create instance")
ErrUnsupportedInstance = errors.New("unsupported instance type")
)
func NewFromProto(
anyInstance *any.Any,
commands []*api.Command,
customWorkingDir string,
logger logger.Lightweight,
) (abstract.Instance, error) {
if anyInstance == nil {
return &UnsupportedInstance{
err: fmt.Errorf("%w: got nil instance which means it's probably not supported by the CLI",
ErrUnsupportedInstance),
}, nil
}
dynamicInstance, err := anypb.UnmarshalNew(anyInstance, proto.UnmarshalOptions{})
if err != nil {
return nil, fmt.Errorf("%w: failed to unmarshal task's instance: %v",
ErrFailedToCreateInstance, err)
}
switch instance := dynamicInstance.(type) {
case *api.ContainerInstance:
var containerPlatform platform.Platform
var architecture *api.Architecture
switch instance.Platform {
case api.Platform_LINUX:
containerPlatform = platform.NewUnix()
architecture = &instance.Architecture
case api.Platform_WINDOWS:
containerPlatform = platform.NewWindows(instance.OsVersion)
default:
return nil, fmt.Errorf("%w: unsupported container instance platform: %s",
ErrFailedToCreateInstance, instance.Platform.String())
}
return &container.Instance{
Image: instance.Image,
CPU: instance.Cpu,
Memory: instance.Memory,
AdditionalContainers: instance.AdditionalContainers,
Platform: containerPlatform,
Architecture: architecture,
CustomWorkingDir: customWorkingDir,
}, nil
case *api.PipeInstance:
stages, err := PipeStagesFromCommands(commands)
if err != nil {
return nil, err
}
return &PipeInstance{
CPU: instance.Cpu,
Memory: instance.Memory,
Stages: stages,
CustomWorkingDir: customWorkingDir,
}, nil
case *api.PrebuiltImageInstance:
// PrebuiltImageInstance is currently missing the domain part to craft the full image name
// used in the follow-up tasks.
//
// However, since currently the only possible value is "gcr.io",
// we simply craft the image name manually using that hardcoded value.
image := path.Join("gcr.io", instance.Repository) + ":" + instance.Reference
return &PrebuiltInstance{
Image: image,
Dockerfile: instance.Dockerfile,
Arguments: instance.Arguments,
}, nil
case *api.PersistentWorkerInstance:
return persistentworker.New(instance.Isolation, security.NoSecurityAllowAllVolumes(), logger)
case *api.DockerBuilder:
// Ensures that we're not trying to run e.g. Windows-specific scripts on macOS
instanceOS := strings.ToLower(instance.Platform.String())
if runtime.GOOS != instanceOS {
return nil, fmt.Errorf("%w: cannot run %s Docker Builder instance on this platform",
ErrFailedToCreateInstance, cases.Title(language.AmericanEnglish).String(instanceOS))
}
return persistentworker.New(&api.Isolation{
Type: &api.Isolation_None_{
None: &api.Isolation_None{},
},
}, security.NoSecurity(), logger)
case *api.MacOSInstance:
return tart.New(instance.Image, instance.User, instance.Password, 22,
instance.Cpu, instance.Memory, tart.WithLogger(logger))
default:
return &UnsupportedInstance{
err: fmt.Errorf("%w: %T", ErrUnsupportedInstance, instance),
}, nil
}
}