1 // Copyright (C) The Arvados Authors. All rights reserved.
3 // SPDX-License-Identifier: Apache-2.0
13 "git.curoverse.com/arvados.git/sdk/go/config"
16 const DefaultConfigFile = "/etc/arvados/config.yml"
19 Clusters map[string]Cluster
22 // GetConfig returns the current system config, loading it from
23 // configFile if needed.
24 func GetConfig(configFile string) (*Config, error) {
26 err := config.LoadFile(&cfg, configFile)
30 // GetCluster returns the cluster ID and config for the given
31 // cluster, or the default/only configured cluster if clusterID is "".
32 func (sc *Config) GetCluster(clusterID string) (*Cluster, error) {
34 if len(sc.Clusters) == 0 {
35 return nil, fmt.Errorf("no clusters configured")
36 } else if len(sc.Clusters) > 1 {
37 return nil, fmt.Errorf("multiple clusters configured, cannot choose")
39 for id, cc := range sc.Clusters {
45 if cc, ok := sc.Clusters[clusterID]; !ok {
46 return nil, fmt.Errorf("cluster %q is not configured", clusterID)
48 cc.ClusterID = clusterID
54 ClusterID string `json:"-"`
55 ManagementToken string
56 SystemRootToken string
58 InstanceTypes InstanceTypeMap
59 Containers ContainersConfig
60 RemoteClusters map[string]RemoteCluster
64 AsyncPermissionsUpdateInterval Duration
66 MaxIndexDatabaseRead int
67 MaxItemsPerResponse int
68 MaxRequestAmplification int
70 RailsSessionSecretToken string
71 RequestTimeout Duration
76 UnloggedAttributes []string
81 DefaultReplication int
82 BlobSigningTTL Duration
83 DefaultTrashLifetime Duration
84 TrashSweepInterval Duration
85 CollectionVersioning bool
86 PreserveVersionIfIdle Duration
92 ProviderAppSecret string
96 MailchimpAPIKey string
97 MailchimpListID string
98 SendUserSetupNotificationEmail string
99 IssueReporterEmailFrom string
100 IssueReporterEmailTo string
101 SupportEmailAddress string
107 MaxRequestLogParamsSize int
115 AdminNotifierEmailFrom string
116 AutoAdminFirstUser bool
117 AutoAdminUserWithEmail string
118 AutoSetupNewUsers bool
119 AutoSetupNewUsersWithRepository bool
120 AutoSetupNewUsersWithVmUUID string
121 AutoSetupUsernameBlacklist []string
122 EmailSubjectPrefix string
123 NewInactiveUserNotificationRecipients []string
124 NewUserNotificationRecipients []string
125 NewUsersAreActive bool
126 UserNotifierEmailFrom string
127 UserProfileNotificationAddress string
130 ActivationContactLink string
131 APIClientConnectTimeout Duration
132 APIClientReceiveTimeout Duration
133 APIResponseCompression bool
134 ApplicationMimetypesWithViewIcon map[string]struct{}
135 ArvadosDocsite string
136 ArvadosPublicDataDocURL string
137 EnableGettingStartedPopup bool
138 EnablePublicProjectsPage bool
139 FileViewersConfigURL string
140 LogViewerMaxBytes ByteSize
143 RepositoryCache string
144 RunningJobLogRecordsToFetch int
147 ShowRecentCollectionsOnDashboard bool
148 ShowUserAgreementInline bool
149 ShowUserNotifications bool
152 UserProfileFormFields map[string]struct {
154 FormFieldTitle string
155 FormFieldDescription string
158 UserProfileFormMessage string
162 EnableBetaController14287 bool
165 type Services struct {
168 DispatchCloud Service
178 WebDAVDownload Service
186 type Service struct {
187 InternalURLs map[URL]ServiceInstance
191 // URL is a url.URL that is also usable as a JSON key/value.
194 // UnmarshalText implements encoding.TextUnmarshaler so URL can be
195 // used as a JSON key/value.
196 func (su *URL) UnmarshalText(text []byte) error {
197 u, err := url.Parse(string(text))
204 func (su URL) MarshalText() ([]byte, error) {
205 return []byte(fmt.Sprintf("%s", (*url.URL)(&su).String())), nil
208 type ServiceInstance struct{}
210 type PostgreSQL struct {
211 Connection PostgreSQLConnection
215 type PostgreSQLConnection map[string]string
217 type RemoteCluster struct {
225 type InstanceType struct {
231 IncludedScratch ByteSize
232 AddedScratch ByteSize
237 type ContainersConfig struct {
238 CloudVMs CloudVMsConfig
239 DefaultKeepCacheRAM ByteSize
240 DispatchPrivateKey string
241 LogReuseDecisions bool
243 MaxDispatchAttempts int
245 StaleLockTimeout Duration
246 SupportedDockerImageFormats []string
247 UsePreemptibleInstances bool
251 GitInternalDir string
252 DefaultDockerImage string
253 CrunchJobWrapper string
255 CrunchRefreshTrigger string
256 ReuseJobIfOutputsDiffer bool
261 LogSecondsBetweenEvents int
262 LogThrottlePeriod Duration
265 LimitLogBytesPerJob int
266 LogPartialLineThrottlePeriod Duration
267 LogUpdatePeriod Duration
268 LogUpdateSize ByteSize
272 DNSServerConfDir string
273 DNSServerConfTemplate string
274 DNSServerReloadCommand string
275 DNSServerUpdateCommand string
276 ComputeNodeDomain string
277 ComputeNodeNameservers []string
278 AssignNodeHostname string
283 type CloudVMsConfig struct {
286 BootProbeCommand string
288 MaxCloudOpsPerSecond int
289 MaxProbesPerSecond int
290 PollInterval Duration
291 ProbeInterval Duration
293 SyncInterval Duration
294 TimeoutBooting Duration
296 TimeoutProbe Duration
297 TimeoutShutdown Duration
298 TimeoutSignal Duration
300 ResourceTags map[string]string
304 DriverParameters json.RawMessage
307 type InstanceTypeMap map[string]InstanceType
309 var errDuplicateInstanceTypeName = errors.New("duplicate instance type name")
311 // UnmarshalJSON handles old config files that provide an array of
312 // instance types instead of a hash.
313 func (it *InstanceTypeMap) UnmarshalJSON(data []byte) error {
314 if len(data) > 0 && data[0] == '[' {
315 var arr []InstanceType
316 err := json.Unmarshal(data, &arr)
324 *it = make(map[string]InstanceType, len(arr))
325 for _, t := range arr {
326 if _, ok := (*it)[t.Name]; ok {
327 return errDuplicateInstanceTypeName
329 if t.ProviderType == "" {
330 t.ProviderType = t.Name
333 t.Scratch = t.IncludedScratch + t.AddedScratch
334 } else if t.AddedScratch == 0 {
335 t.AddedScratch = t.Scratch - t.IncludedScratch
336 } else if t.IncludedScratch == 0 {
337 t.IncludedScratch = t.Scratch - t.AddedScratch
340 if t.Scratch != (t.IncludedScratch + t.AddedScratch) {
341 return fmt.Errorf("%v: Scratch != (IncludedScratch + AddedScratch)", t.Name)
347 var hash map[string]InstanceType
348 err := json.Unmarshal(data, &hash)
352 // Fill in Name field (and ProviderType field, if not
353 // specified) using hash key.
354 *it = InstanceTypeMap(hash)
355 for name, t := range *it {
357 if t.ProviderType == "" {
358 t.ProviderType = name
365 type ServiceName string
368 ServiceNameRailsAPI ServiceName = "arvados-api-server"
369 ServiceNameController ServiceName = "arvados-controller"
370 ServiceNameDispatchCloud ServiceName = "arvados-dispatch-cloud"
371 ServiceNameHealth ServiceName = "arvados-health"
372 ServiceNameNodemanager ServiceName = "arvados-node-manager"
373 ServiceNameWorkbench1 ServiceName = "arvados-workbench1"
374 ServiceNameWorkbench2 ServiceName = "arvados-workbench2"
375 ServiceNameWebsocket ServiceName = "arvados-ws"
376 ServiceNameKeepbalance ServiceName = "keep-balance"
377 ServiceNameKeepweb ServiceName = "keep-web"
378 ServiceNameKeepproxy ServiceName = "keepproxy"
379 ServiceNameKeepstore ServiceName = "keepstore"
382 // Map returns all services as a map, suitable for iterating over all
383 // services or looking up a service by name.
384 func (svcs Services) Map() map[ServiceName]Service {
385 return map[ServiceName]Service{
386 ServiceNameRailsAPI: svcs.RailsAPI,
387 ServiceNameController: svcs.Controller,
388 ServiceNameDispatchCloud: svcs.DispatchCloud,
389 ServiceNameHealth: svcs.Health,
390 ServiceNameNodemanager: svcs.Nodemanager,
391 ServiceNameWorkbench1: svcs.Workbench1,
392 ServiceNameWorkbench2: svcs.Workbench2,
393 ServiceNameWebsocket: svcs.Websocket,
394 ServiceNameKeepbalance: svcs.Keepbalance,
395 ServiceNameKeepweb: svcs.WebDAV,
396 ServiceNameKeepproxy: svcs.Keepproxy,
397 ServiceNameKeepstore: svcs.Keepstore,