/
runconfig.go
259 lines (212 loc) · 7.31 KB
/
runconfig.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
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
package types
import (
"encoding/json"
"time"
"github.com/mitchellh/copystructure"
"github.com/sorintlab/errors"
"agola.io/agola/internal/sqlg"
"agola.io/agola/internal/sqlg/sql"
stypes "agola.io/agola/services/types"
"agola.io/agola/util"
)
// RunConfig
// RunConfig is the run configuration.
// It contains everything that isn't a state (that is contained in a Run) and
// that may use a lot of space. There is a RunConfig for every Run.
type RunConfig struct {
sqlg.ObjectMeta
Name string `json:"name,omitempty"`
// Group is the run group of the run. Every run is assigned to a specific group
// The format is /$grouptypes/groupname(/$grouptype/groupname ...)
// i.e. /project/$projectid/branch/$branchname
// /project/$projectid/pr/$prid
Group string `json:"group,omitempty"`
// A list of setup errors when the run is in phase setuperror
SetupErrors []string `json:"setup_errors,omitempty"`
// Annotations contain custom run annotations
// Note: Annotations are currently both saved in a Run and in RunConfig to
// easily return them without loading RunConfig from the lts
Annotations map[string]string `json:"annotations,omitempty"`
// StaticEnvironment contains all environment variables that won't change when
// generating a new run (like COMMIT_SHA, BRANCH, REPOSITORY_URL etc...)
StaticEnvironment map[string]string `json:"static_environment,omitempty"`
// Environment contains all environment variables that are different between
// runs recreations (like secrets that may change or user provided enviroment
// specific to this run)
Environment map[string]string `json:"environment,omitempty"`
Tasks map[string]*RunConfigTask `json:"tasks,omitempty"`
// CacheGroup is the cache group where the run caches belongs
CacheGroup string `json:"cache_group,omitempty"`
}
func (rc *RunConfig) DeepCopy() *RunConfig {
nrc, err := copystructure.Copy(rc)
if err != nil {
panic(err)
}
return nrc.(*RunConfig)
}
type RunConfigTask struct {
Level int `json:"level,omitempty"`
ID string `json:"id,omitempty"`
Name string `json:"name,omitempty"`
Depends map[string]*RunConfigTaskDepend `json:"depends"`
Runtime *Runtime `json:"runtime,omitempty"`
Environment map[string]string `json:"environment,omitempty"`
WorkingDir string `json:"working_dir,omitempty"`
Shell string `json:"shell,omitempty"`
User string `json:"user,omitempty"`
Steps Steps `json:"steps,omitempty"`
IgnoreFailure bool `json:"ignore_failure,omitempty"`
NeedsApproval bool `json:"needs_approval,omitempty"`
Skip bool `json:"skip,omitempty"`
DockerRegistriesAuth map[string]DockerRegistryAuth `json:"docker_registries_auth"`
TaskTimeoutInterval time.Duration `json:"task_timeout_interval"`
}
func (rct *RunConfigTask) DeepCopy() *RunConfigTask {
nrct, err := copystructure.Copy(rct)
if err != nil {
panic(err)
}
return nrct.(*RunConfigTask)
}
type RunConfigTaskDependCondition string
const (
RunConfigTaskDependConditionOnSuccess RunConfigTaskDependCondition = "on_success"
RunConfigTaskDependConditionOnFailure RunConfigTaskDependCondition = "on_failure"
RunConfigTaskDependConditionOnSkipped RunConfigTaskDependCondition = "on_skipped"
)
type RunConfigTaskDepend struct {
TaskID string `json:"task_id,omitempty"`
Conditions []RunConfigTaskDependCondition `json:"conditions,omitempty"`
}
type RuntimeType string
const (
RuntimeTypePod RuntimeType = "pod"
)
type DockerRegistryAuthType string
const (
DockerRegistryAuthTypeBasic DockerRegistryAuthType = "basic"
DockerRegistryAuthTypeEncodedAuth DockerRegistryAuthType = "encodedauth"
)
type DockerRegistryAuth struct {
Type DockerRegistryAuthType `json:"type"`
// basic auth
Username string `json:"username"`
Password string `json:"password"`
// encoded auth string
Auth string `json:"auth"`
// future auths like aws ecr auth
}
type Runtime struct {
Type RuntimeType `json:"type,omitempty"`
Arch stypes.Arch `json:"arch,omitempty"`
Containers []*Container `json:"containers,omitempty"`
}
type Container struct {
Image string `json:"image,omitempty"`
Environment map[string]string `json:"environment,omitempty"`
User string `json:"user,omitempty"`
Privileged bool `json:"privileged"`
Entrypoint string `json:"entrypoint"`
Volumes []Volume `json:"volumes"`
}
type Volume struct {
Path string `json:"path"`
TmpFS *VolumeTmpFS `json:"tmpfs"`
}
type VolumeTmpFS struct {
Size int64 `json:"size"`
}
type Step interface{}
type Steps []Step
type BaseStep struct {
Type string `json:"type,omitempty"`
Name string `json:"name,omitempty"`
}
type RunStep struct {
BaseStep
Command string `json:"command,omitempty"`
Environment map[string]string `json:"environment,omitempty"`
WorkingDir string `json:"working_dir,omitempty"`
Shell string `json:"shell,omitempty"`
Tty *bool `json:"tty,omitempty"`
}
type SaveContent struct {
SourceDir string `json:"source_dir,omitempty"`
DestDir string `json:"dest_dir,omitempty"`
Paths []string `json:"paths,omitempty"`
}
type SaveToWorkspaceStep struct {
BaseStep
Contents []SaveContent `json:"contents,omitempty"`
}
type RestoreWorkspaceStep struct {
BaseStep
DestDir string `json:"dest_dir,omitempty"`
}
type SaveCacheStep struct {
BaseStep
Key string `json:"key,omitempty"`
Contents []SaveContent `json:"contents,omitempty"`
}
type RestoreCacheStep struct {
BaseStep
Keys []string `json:"keys,omitempty"`
DestDir string `json:"dest_dir,omitempty"`
}
func (et *Steps) UnmarshalJSON(b []byte) error {
type rawSteps []json.RawMessage
var rs rawSteps
if err := json.Unmarshal(b, &rs); err != nil {
return errors.WithStack(err)
}
steps := make(Steps, len(rs))
for i, step := range rs {
var bs BaseStep
if err := json.Unmarshal(step, &bs); err != nil {
return errors.WithStack(err)
}
switch bs.Type {
case "run":
var s RunStep
if err := json.Unmarshal(step, &s); err != nil {
return errors.WithStack(err)
}
if s.Tty == nil {
s.Tty = util.BoolP(true)
}
steps[i] = &s
case "save_to_workspace":
var s SaveToWorkspaceStep
if err := json.Unmarshal(step, &s); err != nil {
return errors.WithStack(err)
}
steps[i] = &s
case "restore_workspace":
var s RestoreWorkspaceStep
if err := json.Unmarshal(step, &s); err != nil {
return errors.WithStack(err)
}
steps[i] = &s
case "save_cache":
var s SaveCacheStep
if err := json.Unmarshal(step, &s); err != nil {
return errors.WithStack(err)
}
steps[i] = &s
case "restore_cache":
var s RestoreCacheStep
if err := json.Unmarshal(step, &s); err != nil {
return errors.WithStack(err)
}
steps[i] = &s
}
}
*et = steps
return nil
}
func NewRunConfig(tx *sql.Tx) *RunConfig {
return &RunConfig{
ObjectMeta: sqlg.NewObjectMeta(tx),
}
}