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 NodeProfiles map[string]NodeProfile
57 InstanceTypes InstanceTypeMap
58 HTTPRequestTimeout Duration
61 type InstanceType struct {
71 type InstanceTypeMap map[string]InstanceType
73 var errDuplicateInstanceTypeName = errors.New("duplicate instance type name")
75 // UnmarshalJSON handles old config files that provide an array of
76 // instance types instead of a hash.
77 func (it *InstanceTypeMap) UnmarshalJSON(data []byte) error {
78 if len(data) > 0 && data[0] == '[' {
79 var arr []InstanceType
80 err := json.Unmarshal(data, &arr)
88 *it = make(map[string]InstanceType, len(arr))
89 for _, t := range arr {
90 if _, ok := (*it)[t.Name]; ok {
91 return errDuplicateInstanceTypeName
97 var hash map[string]InstanceType
98 err := json.Unmarshal(data, &hash)
102 // Fill in Name field using hash key.
103 *it = InstanceTypeMap(hash)
104 for name, t := range *it {
111 // GetNodeProfile returns a NodeProfile for the given hostname. An
112 // error is returned if the appropriate configuration can't be
113 // determined (e.g., this does not appear to be a system node). If
114 // node is empty, use the OS-reported hostname.
115 func (cc *Cluster) GetNodeProfile(node string) (*NodeProfile, error) {
117 hostname, err := os.Hostname()
123 if cfg, ok := cc.NodeProfiles[node]; ok {
126 // If node is not listed, but "*" gives a default system node
127 // config, use the default config.
128 if cfg, ok := cc.NodeProfiles["*"]; ok {
131 return nil, fmt.Errorf("config does not provision host %q as a system node", node)
134 type NodeProfile struct {
135 Controller SystemServiceInstance `json:"arvados-controller"`
136 Health SystemServiceInstance `json:"arvados-health"`
137 Keepproxy SystemServiceInstance `json:"keepproxy"`
138 Keepstore SystemServiceInstance `json:"keepstore"`
139 Keepweb SystemServiceInstance `json:"keep-web"`
140 Nodemanager SystemServiceInstance `json:"arvados-node-manager"`
141 RailsAPI SystemServiceInstance `json:"arvados-api-server"`
142 Websocket SystemServiceInstance `json:"arvados-ws"`
143 Workbench SystemServiceInstance `json:"arvados-workbench"`
146 type ServiceName string
149 ServiceNameRailsAPI ServiceName = "arvados-api-server"
150 ServiceNameController ServiceName = "arvados-controller"
151 ServiceNameNodemanager ServiceName = "arvados-node-manager"
152 ServiceNameWorkbench ServiceName = "arvados-workbench"
153 ServiceNameWebsocket ServiceName = "arvados-ws"
154 ServiceNameKeepweb ServiceName = "keep-web"
155 ServiceNameKeepproxy ServiceName = "keepproxy"
156 ServiceNameKeepstore ServiceName = "keepstore"
159 // ServicePorts returns the configured listening address (or "" if
160 // disabled) for each service on the node.
161 func (np *NodeProfile) ServicePorts() map[ServiceName]string {
162 return map[ServiceName]string{
163 ServiceNameRailsAPI: np.RailsAPI.Listen,
164 ServiceNameController: np.Controller.Listen,
165 ServiceNameNodemanager: np.Nodemanager.Listen,
166 ServiceNameWorkbench: np.Workbench.Listen,
167 ServiceNameWebsocket: np.Websocket.Listen,
168 ServiceNameKeepweb: np.Keepweb.Listen,
169 ServiceNameKeepproxy: np.Keepproxy.Listen,
170 ServiceNameKeepstore: np.Keepstore.Listen,
174 type SystemServiceInstance struct {