isle/entrypoint/src/bootstrap/hosts.go

82 lines
1.8 KiB
Go
Raw Normal View History

package bootstrap
import (
"fmt"
"io/fs"
"path/filepath"
"strings"
"gopkg.in/yaml.v3"
)
const (
hostsDirPath = "hosts"
)
// NebulaHost describes the nebula configuration of a Host which is relevant for
// other hosts to know.
type NebulaHost struct {
IP string `yaml:"ip"`
PublicAddr string `yaml:"public_addr,omitempty"`
}
// GarageHost describes a single garage instance in the GarageHost.
type GarageHostInstance struct {
RPCPort int `yaml:"rpc_port"`
S3APIPort int `yaml:"s3_api_port"`
}
// GarageHost describes the garage configuration of a Host which is relevant for
// other hosts to know.
type GarageHost struct {
Instances []GarageHostInstance `yaml:"instances"`
}
// Host consolidates all information about a single host from the bootstrap
// file.
type Host struct {
Name string `yaml:"name"`
Nebula NebulaHost `yaml:"nebula"`
Garage *GarageHost `yaml:"garage,omitempty"`
}
func loadHosts(bootstrapFS fs.FS) (map[string]Host, error) {
hosts := map[string]Host{}
readAsYaml := func(into interface{}, path string) error {
b, err := fs.ReadFile(bootstrapFS, path)
if err != nil {
return fmt.Errorf("reading file from fs: %w", err)
}
return yaml.Unmarshal(b, into)
}
globPath := filepath.Join(hostsDirPath, "*.yml")
hostPaths, err := fs.Glob(bootstrapFS, globPath)
if err != nil {
return nil, fmt.Errorf("listing host files at %q in fs: %w", globPath, err)
}
for _, hostPath := range hostPaths {
hostName := filepath.Base(hostPath)
hostName = strings.TrimSuffix(hostName, filepath.Ext(hostName))
var host Host
if err := readAsYaml(&host, hostPath); err != nil {
return nil, fmt.Errorf("reading %q as yaml: %w", hostPath, err)
}
hosts[hostName] = host
}
if len(hosts) == 0 {
return nil, fmt.Errorf("failed to load any hosts from fs")
}
return hosts, nil
}