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 BlobSigningTTL Duration
82 CollectionVersioning bool
83 DefaultTrashLifetime Duration
84 DefaultReplication int
85 ManagedProperties map[string]interface{}
86 PreserveVersionIfIdle Duration
87 TrashSweepInterval Duration
93 ProviderAppSecret string
97 MailchimpAPIKey string
98 MailchimpListID string
99 SendUserSetupNotificationEmail string
100 IssueReporterEmailFrom string
101 IssueReporterEmailTo string
102 SupportEmailAddress string
108 MaxRequestLogParamsSize int
116 AdminNotifierEmailFrom string
117 AutoAdminFirstUser bool
118 AutoAdminUserWithEmail string
119 AutoSetupNewUsers bool
120 AutoSetupNewUsersWithRepository bool
121 AutoSetupNewUsersWithVmUUID string
122 AutoSetupUsernameBlacklist []string
123 EmailSubjectPrefix string
124 NewInactiveUserNotificationRecipients []string
125 NewUserNotificationRecipients []string
126 NewUsersAreActive bool
127 UserNotifierEmailFrom string
128 UserProfileNotificationAddress string
131 ActivationContactLink string
132 APIClientConnectTimeout Duration
133 APIClientReceiveTimeout Duration
134 APIResponseCompression bool
135 ApplicationMimetypesWithViewIcon map[string]struct{}
136 ArvadosDocsite string
137 ArvadosPublicDataDocURL string
138 EnableGettingStartedPopup bool
139 EnablePublicProjectsPage bool
140 FileViewersConfigURL string
141 LogViewerMaxBytes ByteSize
144 RepositoryCache string
145 RunningJobLogRecordsToFetch int
148 ShowRecentCollectionsOnDashboard bool
149 ShowUserAgreementInline bool
150 ShowUserNotifications bool
153 UserProfileFormFields map[string]struct {
155 FormFieldTitle string
156 FormFieldDescription string
159 UserProfileFormMessage string
163 EnableBetaController14287 bool
166 type Services struct {
169 DispatchCloud Service
179 WebDAVDownload Service
187 type Service struct {
188 InternalURLs map[URL]ServiceInstance
192 // URL is a url.URL that is also usable as a JSON key/value.
195 // UnmarshalText implements encoding.TextUnmarshaler so URL can be
196 // used as a JSON key/value.
197 func (su *URL) UnmarshalText(text []byte) error {
198 u, err := url.Parse(string(text))
205 func (su URL) MarshalText() ([]byte, error) {
206 return []byte(fmt.Sprintf("%s", (*url.URL)(&su).String())), nil
209 type ServiceInstance struct{}
211 type PostgreSQL struct {
212 Connection PostgreSQLConnection
216 type PostgreSQLConnection map[string]string
218 type RemoteCluster struct {
226 type InstanceType struct {
232 IncludedScratch ByteSize
233 AddedScratch ByteSize
238 type ContainersConfig struct {
239 CloudVMs CloudVMsConfig
240 DefaultKeepCacheRAM ByteSize
241 DispatchPrivateKey string
242 LogReuseDecisions bool
244 MaxDispatchAttempts int
246 StaleLockTimeout Duration
247 SupportedDockerImageFormats []string
248 UsePreemptibleInstances bool
252 GitInternalDir string
253 DefaultDockerImage string
254 CrunchJobWrapper string
256 CrunchRefreshTrigger string
257 ReuseJobIfOutputsDiffer bool
262 LogSecondsBetweenEvents int
263 LogThrottlePeriod Duration
266 LimitLogBytesPerJob int
267 LogPartialLineThrottlePeriod Duration
268 LogUpdatePeriod Duration
269 LogUpdateSize ByteSize
273 DNSServerConfDir string
274 DNSServerConfTemplate string
275 DNSServerReloadCommand string
276 DNSServerUpdateCommand string
277 ComputeNodeDomain string
278 ComputeNodeNameservers []string
279 AssignNodeHostname string
284 type CloudVMsConfig struct {
287 BootProbeCommand string
289 MaxCloudOpsPerSecond int
290 MaxProbesPerSecond int
291 PollInterval Duration
292 ProbeInterval Duration
294 SyncInterval Duration
295 TimeoutBooting Duration
297 TimeoutProbe Duration
298 TimeoutShutdown Duration
299 TimeoutSignal Duration
301 ResourceTags map[string]string
305 DriverParameters json.RawMessage
308 type InstanceTypeMap map[string]InstanceType
310 var errDuplicateInstanceTypeName = errors.New("duplicate instance type name")
312 // UnmarshalJSON handles old config files that provide an array of
313 // instance types instead of a hash.
314 func (it *InstanceTypeMap) UnmarshalJSON(data []byte) error {
315 if len(data) > 0 && data[0] == '[' {
316 var arr []InstanceType
317 err := json.Unmarshal(data, &arr)
325 *it = make(map[string]InstanceType, len(arr))
326 for _, t := range arr {
327 if _, ok := (*it)[t.Name]; ok {
328 return errDuplicateInstanceTypeName
330 if t.ProviderType == "" {
331 t.ProviderType = t.Name
334 t.Scratch = t.IncludedScratch + t.AddedScratch
335 } else if t.AddedScratch == 0 {
336 t.AddedScratch = t.Scratch - t.IncludedScratch
337 } else if t.IncludedScratch == 0 {
338 t.IncludedScratch = t.Scratch - t.AddedScratch
341 if t.Scratch != (t.IncludedScratch + t.AddedScratch) {
342 return fmt.Errorf("%v: Scratch != (IncludedScratch + AddedScratch)", t.Name)
348 var hash map[string]InstanceType
349 err := json.Unmarshal(data, &hash)
353 // Fill in Name field (and ProviderType field, if not
354 // specified) using hash key.
355 *it = InstanceTypeMap(hash)
356 for name, t := range *it {
358 if t.ProviderType == "" {
359 t.ProviderType = name
366 type ServiceName string
369 ServiceNameRailsAPI ServiceName = "arvados-api-server"
370 ServiceNameController ServiceName = "arvados-controller"
371 ServiceNameDispatchCloud ServiceName = "arvados-dispatch-cloud"
372 ServiceNameHealth ServiceName = "arvados-health"
373 ServiceNameNodemanager ServiceName = "arvados-node-manager"
374 ServiceNameWorkbench1 ServiceName = "arvados-workbench1"
375 ServiceNameWorkbench2 ServiceName = "arvados-workbench2"
376 ServiceNameWebsocket ServiceName = "arvados-ws"
377 ServiceNameKeepbalance ServiceName = "keep-balance"
378 ServiceNameKeepweb ServiceName = "keep-web"
379 ServiceNameKeepproxy ServiceName = "keepproxy"
380 ServiceNameKeepstore ServiceName = "keepstore"
383 // Map returns all services as a map, suitable for iterating over all
384 // services or looking up a service by name.
385 func (svcs Services) Map() map[ServiceName]Service {
386 return map[ServiceName]Service{
387 ServiceNameRailsAPI: svcs.RailsAPI,
388 ServiceNameController: svcs.Controller,
389 ServiceNameDispatchCloud: svcs.DispatchCloud,
390 ServiceNameHealth: svcs.Health,
391 ServiceNameNodemanager: svcs.Nodemanager,
392 ServiceNameWorkbench1: svcs.Workbench1,
393 ServiceNameWorkbench2: svcs.Workbench2,
394 ServiceNameWebsocket: svcs.Websocket,
395 ServiceNameKeepbalance: svcs.Keepbalance,
396 ServiceNameKeepweb: svcs.WebDAV,
397 ServiceNameKeepproxy: svcs.Keepproxy,
398 ServiceNameKeepstore: svcs.Keepstore,