-
Notifications
You must be signed in to change notification settings - Fork 168
/
config.go
202 lines (180 loc) · 7.74 KB
/
config.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
package controller
import (
"encoding/json"
"fmt"
"os"
"time"
log "github.com/sirupsen/logrus"
corev1 "k8s.io/api/core/v1"
)
const (
// DevModeEnvName determines whether workflow controller is in development mode.
// In development mode, resource resolver containers, coordinator containers will
// have image pull policy being 'Always', otherwise it's 'IfNotPresent'.
DevModeEnvName = "DEVELOP_MODE"
// ConfigFileKey is key of config file in ConfigMap
ConfigFileKey = "workflow-controller.json"
// CoordinatorImage is key of coordinator image in config file
CoordinatorImage = "coordinator"
// GCImage is key of the GC image in config file
GCImage = "gc"
// DindImage is key of the docker-in-docker image in config file
DindImage = "dind"
// ToolboxImage is key of the cyclone toolbox image in config file
ToolboxImage = "toolbox"
)
// WorkflowControllerConfig configures Workflow Controller
type WorkflowControllerConfig struct {
// Images that used in controller, such as gc image.
Images map[string]string `json:"images"`
// Logging configuration, such as log level.
Logging LoggingConfig `json:"logging"`
// GC configuration
GC GCConfig `json:"gc"`
// Limits of each resources should be retained
Limits LimitsConfig `json:"limits"`
// Parallelism configures how many WorkflowRun allows to run in parallel
Parallelism *ParallelismConfig `json:"parallelism"`
// ResourceRequirements is default resource requirements for containers in stage Pod
ResourceRequirements corev1.ResourceRequirements `json:"default_resource_quota"`
// ExecutionContext defines default namespace and pvc used to run workflow.
ExecutionContext ExecutionContext `json:"execution_context"`
// CycloneServerAddr is address of the Cyclone Server
CycloneServerAddr string `json:"cyclone_server_addr"`
// NotificationURL represents the config to send notifications after workflowruns finish.
// It can be configured as Cyclone server notification URL to take advantage of its scenarized functions.
NotificationURL string `json:"notification_url"`
// DindSettings is settings for Docker in Docker
DindSettings DindSettings `json:"dind"`
// WorkersNumber defines workers number for various controller
WorkersNumber WorkersNumber `json:"workers_number"`
// ResyncPeriodSeconds defines resync period in seconds for controllers
ResyncPeriodSeconds time.Duration `json:"resync_period_seconds"`
}
// LoggingConfig configures logging
type LoggingConfig struct {
Level string `json:"level"`
}
// ExecutionContext defines default namespace and pvc used to run workflow.
type ExecutionContext struct {
// Namespace is namespace where to run workflow.
Namespace string `json:"namespace"`
// PVC is pvc used to run workflow. It's used to transfer artifacts in WorkflowRun, and
// also to help share resources among stages within WorkflowRun. If no PVC is given here,
// input resources won't be shared among stages, but need to be pulled every time it's needed.
// And also if no PVC given, artifacts are not supported.
PVC string `json:"pvc"`
// ServiceAccount is the service account applied to the pod runed
ServiceAccount string `json:"service_account"`
}
// GCConfig configures GC
type GCConfig struct {
// Enabled controllers whether GC is enabled, if set to false, no GC would happen.
Enabled bool `json:"enabled"`
// DelaySeconds defines the time after a WorkflowRun terminated to perform GC. When configured to 0.
// it equals to gc immediately.
DelaySeconds time.Duration `json:"delay_seconds"`
// RetryCount defines how many times to retry when GC failed, 0 means no retry.
RetryCount int `json:"retry"`
// ResourceRequirements is default resource requirements for the gc Pod
ResourceRequirements corev1.ResourceRequirements `json:"resource_quota"`
}
// LimitsConfig configures maximum WorkflowRun to keep for each Workflow
type LimitsConfig struct {
// Maximum WorkflowRuns to be kept for each Workflow
MaxWorkflowRuns int `json:"max_workflowruns"`
}
// ParallelismConstraint puts constraints on parallelism
type ParallelismConstraint struct {
// MaxParallel specifies max number of WorkflowRun allows to run in parallel
MaxParallel int64 `json:"max_parallel"`
// MaxQueueSize specifies max number WorkflowRun allows to wait for running in queue
MaxQueueSize int64 `json:"max_queue_size"`
}
// ParallelismConfig configures how many WorkflowRun allows to run in parallel. If maximum parallelism exceeded,
// new WorkflowRun will wait in waiting queue. Waiting queue will also have a maxinum size, if maxinum size exceeded,
// new WorkflowRun will fail directly.
type ParallelismConfig struct {
// Overall controls overall parallelism of WorkflowRun executions
Overall ParallelismConstraint `json:"overall"`
// SingleWorkflow controls parallelism of WorkflowRun executions for single Workflow
SingleWorkflow ParallelismConstraint `json:"single_workflow"`
}
// DindSettings is settings for Docker in Docker.
type DindSettings struct {
// InsecureRegistries is list of insecure registries, for docker registries with
// self-signed certs, it's useful to bypass the cert check.
InsecureRegistries []string `json:"insecure_registries"`
// Bip specifies IP subnet used for docker0 bridge
Bip string `json:"bip"`
}
// WorkersNumber defines workers number for various controller
type WorkersNumber struct {
ExecutionCluster int `json:"execution_cluster"`
WorkflowTrigger int `json:"workflow_trigger"`
WorkflowRun int `json:"workflow_run"`
Pod int `json:"pod"`
}
// Config is Workflow Controller config instance
var Config WorkflowControllerConfig
// LoadConfig loads configuration from ConfigMap
func LoadConfig(cm *corev1.ConfigMap) error {
data, ok := cm.Data[ConfigFileKey]
if !ok {
return fmt.Errorf("ConfigMap '%s' doesn't have data key '%s'", cm.Name, ConfigFileKey)
}
err := json.Unmarshal([]byte(data), &Config)
if err != nil {
log.WithField("data", data).Debug("Unmarshal config data error: ", err)
return err
}
defaultValues(&Config)
if !validate(&Config) {
return fmt.Errorf("validate config failed")
}
InitLogger(&Config.Logging)
log.Infof("ResyncPeriod is %s", Config.ResyncPeriodSeconds*time.Second)
return nil
}
// validate validates some required configurations.
func validate(config *WorkflowControllerConfig) bool {
if config.ExecutionContext.PVC == "" {
log.Warn("PVC not configured, resources won't be shared among stages and artifacts unsupported.")
}
if config.ResyncPeriodSeconds < 0 {
log.Errorf("Invalid ResyncPeriodSeconds: %d", config.ResyncPeriodSeconds)
return false
}
return true
}
// defaultValues give the config some default value if they are not set.
func defaultValues(config *WorkflowControllerConfig) {
if config.ResyncPeriodSeconds == 0 {
config.ResyncPeriodSeconds = 180
log.Info("ResyncPeriodSeconds not configured, will use default value '180'")
}
if config.WorkersNumber.ExecutionCluster == 0 {
config.WorkersNumber.ExecutionCluster = 1
log.Info("WorkersNumber.ExecutionCluster not configured, will use default value '1'")
}
if config.WorkersNumber.Pod == 0 {
config.WorkersNumber.Pod = 1
log.Info("WorkersNumber.Pod not configured, will use default value '1'")
}
if config.WorkersNumber.WorkflowTrigger == 0 {
config.WorkersNumber.WorkflowTrigger = 1
log.Info("WorkersNumber.WorkflowTrigger not configured, will use default value '1'")
}
if config.WorkersNumber.WorkflowRun == 0 {
config.WorkersNumber.WorkflowRun = 1
log.Info("WorkersNumber.WorkflowRun not configured, will use default value '1'")
}
}
// ImagePullPolicy determines image pull policy based on environment variable DEVELOP_MODE
// This pull policy will be used in image resolver containers and coordinator containers.
func ImagePullPolicy() corev1.PullPolicy {
if os.Getenv(DevModeEnvName) == "true" {
return corev1.PullAlways
}
return corev1.PullIfNotPresent
}