123 lines
		
	
	
		
			3.7 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			123 lines
		
	
	
		
			3.7 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package config
 | |
| 
 | |
| import (
 | |
| 	"os"
 | |
| 	"path"
 | |
| 	"path/filepath"
 | |
| 
 | |
| 	"coopcloud.tech/abra/pkg/i18n"
 | |
| 	"coopcloud.tech/abra/pkg/log"
 | |
| 	"gopkg.in/yaml.v3"
 | |
| )
 | |
| 
 | |
| // LoadAbraConfig returns the abra configuration. It tries to find a abra
 | |
| // configuration file (see findAbraConfig for lookup logic). When no
 | |
| // configuration was found it returns the default config.
 | |
| func LoadAbraConfig() Abra {
 | |
| 	wd, _ := os.Getwd()
 | |
| 	configFile := findAbraConfig(wd)
 | |
| 	if configFile == "" {
 | |
| 		log.Debug(i18n.G("no config file found"))
 | |
| 		return Abra{}
 | |
| 	}
 | |
| 	data, err := os.ReadFile(configFile)
 | |
| 	if err != nil {
 | |
| 		// Do nothing, when an error occurs
 | |
| 		log.Debug(i18n.G("error reading config file: %s", err))
 | |
| 		return Abra{}
 | |
| 	}
 | |
| 
 | |
| 	config := Abra{}
 | |
| 	err = yaml.Unmarshal(data, &config)
 | |
| 	if err != nil {
 | |
| 		// Do nothing, when an error occurs
 | |
| 		log.Debug(i18n.G("error loading config file: %s", err))
 | |
| 		return Abra{}
 | |
| 	}
 | |
| 	log.Debug(i18n.G("config file loaded from: %s", configFile))
 | |
| 	config.configPath = filepath.Dir(configFile)
 | |
| 	return config
 | |
| }
 | |
| 
 | |
| // findAbraConfig recursively looks for a abra.y(a)ml file in the given directory.
 | |
| // When the file was not found it calls the function again with the parent
 | |
| // directory until the home directory is hit. When no abra config was found it
 | |
| // returns an empty string.
 | |
| func findAbraConfig(dir string) string {
 | |
| 	dir, err := filepath.Abs(dir)
 | |
| 	if err != nil {
 | |
| 		return ""
 | |
| 	}
 | |
| 	if dir == os.ExpandEnv("$HOME") || dir == "/" {
 | |
| 		return ""
 | |
| 	}
 | |
| 	p := path.Join(dir, "abra.yaml")
 | |
| 	if _, err := os.Stat(p); err == nil {
 | |
| 		return p
 | |
| 	}
 | |
| 	p = path.Join(dir, "abra.yml")
 | |
| 	if _, err := os.Stat(p); err == nil {
 | |
| 		return p
 | |
| 	}
 | |
| 	return findAbraConfig(filepath.Dir(dir))
 | |
| }
 | |
| 
 | |
| // Abra defines the configuration file for abra.
 | |
| type Abra struct {
 | |
| 	configPath string
 | |
| 	AbraDir    string `yaml:"abraDir"`
 | |
| }
 | |
| 
 | |
| // GetAbraDir returns the abra dir. It has the following logic:
 | |
| // 1. check if $ABRA_DIR is set
 | |
| // 2. check if abraDir was set in a config file
 | |
| // 3. use $HOME/.abra when above two options failed
 | |
| func (a Abra) GetAbraDir() string {
 | |
| 	if dir, exists := os.LookupEnv("ABRA_DIR"); exists && dir != "" {
 | |
| 		log.Debug(i18n.G("read abra dir from $ABRA_DIR"))
 | |
| 		return dir
 | |
| 	}
 | |
| 	if a.AbraDir != "" {
 | |
| 		log.Debug(i18n.G("read abra dir from config file"))
 | |
| 		if path.IsAbs(a.AbraDir) {
 | |
| 			return a.AbraDir
 | |
| 		}
 | |
| 		// Make the path absolute
 | |
| 		return path.Join(a.configPath, a.AbraDir)
 | |
| 	}
 | |
| 	log.Debug(i18n.G("using default abra dir"))
 | |
| 	return os.ExpandEnv("$HOME/.abra")
 | |
| }
 | |
| 
 | |
| func (a Abra) GetServersDir() string   { return path.Join(a.GetAbraDir(), "servers") }
 | |
| func (a Abra) GetRecipesDir() string   { return path.Join(a.GetAbraDir(), "recipes") }
 | |
| func (a Abra) GetLogsDir() string      { return path.Join(a.GetAbraDir(), "logs") }
 | |
| func (a Abra) GetCatalogueDir() string { return path.Join(a.GetAbraDir(), "catalogue") }
 | |
| 
 | |
| var config = LoadAbraConfig()
 | |
| 
 | |
| var (
 | |
| 	ABRA_DIR                  = config.GetAbraDir()
 | |
| 	SERVERS_DIR               = config.GetServersDir()
 | |
| 	RECIPES_DIR               = config.GetRecipesDir()
 | |
| 	LOGS_DIR                  = config.GetLogsDir()
 | |
| 	CATALOGUE_DIR             = config.GetCatalogueDir()
 | |
| 	RECIPES_JSON              = path.Join(config.GetCatalogueDir(), "recipes.json")
 | |
| 	REPOS_BASE_URL            = "https://git.coopcloud.tech/coop-cloud"
 | |
| 	CATALOGUE_JSON_REPO_NAME  = "recipes-catalogue-json"
 | |
| 	TOOLSHED_SSH_URL_TEMPLATE = "ssh://git@git.coopcloud.tech:2222/toolshed/%s.git"
 | |
| 	RECIPES_SSH_URL_TEMPLATE  = "ssh://git@git.coopcloud.tech:2222/coop-cloud/%s.git"
 | |
| 
 | |
| 	// NOTE(d1): please note, this was done purely out of laziness on our part
 | |
| 	// AFAICR. it's easy to punt the value into the label because that is what is
 | |
| 	// expects. it's not particularly useful in terms of UI/UX but hey, nobody
 | |
| 	// complained yet!
 | |
| 	CHAOS_DEFAULT = "false"
 | |
| 
 | |
| 	DIRTY_DEFAULT = "+U"
 | |
| 
 | |
| 	MISSING_DEFAULT = "-"
 | |
| 
 | |
| 	UNKNOWN_DEFAULT = "unknown"
 | |
| )
 |