feat: introduce abra config file and load abra dir from it (!419)
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This is the first step to introduce a configuration file for abra. The config file must be named `abra.yaml` or àbra.yml`. abra look for the config file in the current directory and when not found traverses the directory tree up until it is found or the home/root directory is reached. For now there is only one setting that is made configurable: `abraDir`. The new logic for setting the abra dir is the following: 1. lookup `$ABRA_DIR` env 2. look for config file and take value from there 3. `$HOME/.abra` as fallback See coop-cloud/organising#303. Reviewed-on: coop-cloud/abra#419 Reviewed-by: decentral1se <decentral1se@noreply.git.coopcloud.tech> Co-authored-by: p4u1 <p4u1_f4u1@riseup.net> Co-committed-by: p4u1 <p4u1_f4u1@riseup.net>
This commit is contained in:
parent
ac87898005
commit
ac695ae28e
104
pkg/config/abra.go
Normal file
104
pkg/config/abra.go
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
package config
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"path"
|
||||||
|
"path/filepath"
|
||||||
|
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
|
"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 == "" {
|
||||||
|
logrus.Debugf("no config file found")
|
||||||
|
return Abra{}
|
||||||
|
}
|
||||||
|
data, err := os.ReadFile(configFile)
|
||||||
|
if err != nil {
|
||||||
|
// Do nothing, when an error occurs
|
||||||
|
logrus.Debugf("error reading config file: %s", err)
|
||||||
|
return Abra{}
|
||||||
|
}
|
||||||
|
|
||||||
|
config := Abra{}
|
||||||
|
err = yaml.Unmarshal(data, &config)
|
||||||
|
if err != nil {
|
||||||
|
// Do nothing, when an error occurs
|
||||||
|
logrus.Debugf("error loading config file: %s", err)
|
||||||
|
return Abra{}
|
||||||
|
}
|
||||||
|
logrus.Debugf("config file loaded from: %s", configFile)
|
||||||
|
config.configPath = 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 != "" {
|
||||||
|
logrus.Debug("read abra dir from $ABRA_DIR")
|
||||||
|
return dir
|
||||||
|
}
|
||||||
|
if a.AbraDir != "" {
|
||||||
|
logrus.Debug("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)
|
||||||
|
}
|
||||||
|
logrus.Debug("using default abra dir")
|
||||||
|
return os.ExpandEnv("$HOME/.abra")
|
||||||
|
}
|
||||||
|
|
||||||
|
var config = LoadAbraConfig()
|
||||||
|
|
||||||
|
var (
|
||||||
|
ABRA_DIR = config.GetAbraDir()
|
||||||
|
SERVERS_DIR = path.Join(ABRA_DIR, "servers")
|
||||||
|
RECIPES_DIR = path.Join(ABRA_DIR, "recipes")
|
||||||
|
VENDOR_DIR = path.Join(ABRA_DIR, "vendor")
|
||||||
|
BACKUP_DIR = path.Join(ABRA_DIR, "backups")
|
||||||
|
CATALOGUE_DIR = path.Join(ABRA_DIR, "catalogue")
|
||||||
|
RECIPES_JSON = path.Join(ABRA_DIR, "catalogue", "recipes.json")
|
||||||
|
REPOS_BASE_URL = "https://git.coopcloud.tech/coop-cloud"
|
||||||
|
CATALOGUE_JSON_REPO_NAME = "recipes-catalogue-json"
|
||||||
|
SSH_URL_TEMPLATE = "ssh://git@git.coopcloud.tech:2222/coop-cloud/%s.git"
|
||||||
|
)
|
103
pkg/config/abra_test.go
Normal file
103
pkg/config/abra_test.go
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
package config
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestFindAbraConfig(t *testing.T) {
|
||||||
|
wd, err := os.Getwd()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
Dir string
|
||||||
|
Config string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
Dir: "testdata/abraconfig1",
|
||||||
|
Config: filepath.Join(wd, "testdata/abraconfig1/abra.yaml"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Dir: "testdata/abraconfig1/subdir",
|
||||||
|
Config: filepath.Join(wd, "testdata/abraconfig1/abra.yaml"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Dir: "testdata/abraconfig2",
|
||||||
|
Config: filepath.Join(wd, "testdata/abraconfig2/abra.yml"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Dir: "testdata/abraconfig2/subdir",
|
||||||
|
Config: filepath.Join(wd, "testdata/abraconfig2/abra.yml"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Dir: "testdata",
|
||||||
|
Config: "",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tc := range tests {
|
||||||
|
t.Run(tc.Dir, func(t *testing.T) {
|
||||||
|
config := findAbraConfig(tc.Dir)
|
||||||
|
if config != tc.Config {
|
||||||
|
t.Errorf("\nwant: %s\ngot: %s", tc.Config, config)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestLoadAbraConfigGetAbraDir(t *testing.T) {
|
||||||
|
wd, err := os.Getwd()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
t.Setenv("ABRA_DIR", "")
|
||||||
|
|
||||||
|
t.Run("default", func(t *testing.T) {
|
||||||
|
cfg := LoadAbraConfig()
|
||||||
|
wantAbraDir := os.ExpandEnv("$HOME/.abra")
|
||||||
|
if cfg.GetAbraDir() != wantAbraDir {
|
||||||
|
t.Errorf("\nwant: %s\ngot: %s", wantAbraDir, cfg.GetAbraDir())
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("from config file", func(t *testing.T) {
|
||||||
|
t.Cleanup(func() { os.Chdir(wd) })
|
||||||
|
err = os.Chdir(filepath.Join(wd, "testdata/abraconfig1"))
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
cfg := LoadAbraConfig()
|
||||||
|
log.Println(cfg.GetAbraDir())
|
||||||
|
wantAbraDir := filepath.Join(wd, "testdata/abraconfig1/abra.yaml/foobar")
|
||||||
|
if cfg.GetAbraDir() != wantAbraDir {
|
||||||
|
t.Errorf("\nwant: %s\ngot: %s", wantAbraDir, cfg.GetAbraDir())
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("default when config file is empty", func(t *testing.T) {
|
||||||
|
t.Cleanup(func() { os.Chdir(wd) })
|
||||||
|
err := os.Chdir(filepath.Join(wd, "testdata/abraconfig2"))
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
cfg := LoadAbraConfig()
|
||||||
|
wantAbraDir := os.ExpandEnv("$HOME/.abra")
|
||||||
|
if cfg.GetAbraDir() != wantAbraDir {
|
||||||
|
t.Errorf("\nwant: %s\ngot: %s", wantAbraDir, cfg.GetAbraDir())
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("from env variable", func(t *testing.T) {
|
||||||
|
t.Setenv("ABRA_DIR", "foo")
|
||||||
|
cfg := LoadAbraConfig()
|
||||||
|
wantAbraDir := "foo"
|
||||||
|
if cfg.GetAbraDir() != wantAbraDir {
|
||||||
|
t.Errorf("\nwant: %s\ngot: %s", wantAbraDir, cfg.GetAbraDir())
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
@ -16,26 +16,6 @@ import (
|
|||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
// getBaseDir retrieves the Abra base directory.
|
|
||||||
func getBaseDir() string {
|
|
||||||
home := os.ExpandEnv("$HOME/.abra")
|
|
||||||
if customAbraDir, exists := os.LookupEnv("ABRA_DIR"); exists && customAbraDir != "" {
|
|
||||||
home = customAbraDir
|
|
||||||
}
|
|
||||||
return home
|
|
||||||
}
|
|
||||||
|
|
||||||
var ABRA_DIR = getBaseDir()
|
|
||||||
var SERVERS_DIR = path.Join(ABRA_DIR, "servers")
|
|
||||||
var RECIPES_DIR = path.Join(ABRA_DIR, "recipes")
|
|
||||||
var VENDOR_DIR = path.Join(ABRA_DIR, "vendor")
|
|
||||||
var BACKUP_DIR = path.Join(ABRA_DIR, "backups")
|
|
||||||
var CATALOGUE_DIR = path.Join(ABRA_DIR, "catalogue")
|
|
||||||
var RECIPES_JSON = path.Join(ABRA_DIR, "catalogue", "recipes.json")
|
|
||||||
var REPOS_BASE_URL = "https://git.coopcloud.tech/coop-cloud"
|
|
||||||
var CATALOGUE_JSON_REPO_NAME = "recipes-catalogue-json"
|
|
||||||
var SSH_URL_TEMPLATE = "ssh://git@git.coopcloud.tech:2222/coop-cloud/%s.git"
|
|
||||||
|
|
||||||
const MAX_SANITISED_APP_NAME_LENGTH = 45
|
const MAX_SANITISED_APP_NAME_LENGTH = 45
|
||||||
const MAX_DOCKER_SECRET_LENGTH = 64
|
const MAX_DOCKER_SECRET_LENGTH = 64
|
||||||
|
|
||||||
|
1
pkg/config/testdata/abraconfig1/abra.yaml
vendored
Normal file
1
pkg/config/testdata/abraconfig1/abra.yaml
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
abraDir: foobar
|
0
pkg/config/testdata/abraconfig1/subdir/.gitkeep
vendored
Normal file
0
pkg/config/testdata/abraconfig1/subdir/.gitkeep
vendored
Normal file
0
pkg/config/testdata/abraconfig2/abra.yml
vendored
Normal file
0
pkg/config/testdata/abraconfig2/abra.yml
vendored
Normal file
0
pkg/config/testdata/abraconfig2/subdir/.gitkeep
vendored
Normal file
0
pkg/config/testdata/abraconfig2/subdir/.gitkeep
vendored
Normal file
Loading…
x
Reference in New Issue
Block a user