1package common
2
3import (
4 "errors"
5 "fmt"
6 "io/fs"
7 "os"
8 "path/filepath"
9 "runtime"
10
11 "github.com/bnema/gordon/pkg/docker"
12 "github.com/bnema/gordon/pkg/parser"
13)
14
15type Config struct {
16 General GeneralConfig `yaml:"General"`
17 Http HttpConfig `yaml:"Http"`
18 Admin AdminConfig `yaml:"Admin"`
19 ContainerEngine ContainerEngineConfig `yaml:"ContainerEngine"`
20 Build BuildConfig `yaml:"-"`
21}
22
23type BuildConfig struct {
24 RunEnv string `yaml:"-"` // come from env
25 BuildVersion string `yaml:"-"` // come from build ldflags
26 BuildCommit string `yaml:"-"` // come from build ldflags
27 BuildDate string `yaml:"-"` // come from build ldflags
28 ProxyURL string `yaml:"-"`
29}
30
31type AdminConfig struct {
32 Path string `yaml:"path"`
33}
34
35type GeneralConfig struct {
36 StorageDir string `yaml:"storageDir"`
37 Token string `yaml:"token"`
38}
39type HttpConfig struct {
40 Port string `yaml:"port"`
41 Domain string `yaml:"domain"`
42 SubDomain string `yaml:"subDomain"`
43 BackendURL string `yaml:"backendURL"`
44 Https bool `yaml:"https"`
45}
46
47type ContainerEngineConfig struct {
48 Sock string `yaml:"dockersock"`
49 PodmanSock string `yaml:"podmansock"`
50 Podman bool `yaml:"podman"`
51 Network string `yaml:"network"`
52}
53
54// Default values
55var (
56 sock = "/var/run/docker.sock"
57 podmansock = "/run/user/1000/podman/podman.sock"
58)
59
60func getConfigDir() (string, error) {
61
62 if docker.IsRunningInContainer() {
63 return "/.", nil
64 }
65
66 // Get the user's home directory for non-container environments
67 homeDir, err := os.UserHomeDir()
68 if err != nil {
69 return "", fmt.Errorf("error getting user's home directory: %w", err)
70 }
71
72 // Select the configuration directory based on the OS
73 configDir := filepath.Join(homeDir, ".config", "Gordon")
74 if runtime.GOOS == "windows" {
75 configDir = filepath.Join(homeDir, "AppData", "Roaming", "Gordon")
76 }
77
78 return configDir, nil
79}
80
81func readAndUnmarshalConfig(fs fs.FS, filePath string, config *Config) error {
82 err := parser.ParseYAMLFile(fs, filePath, config)
83 if err != nil {
84 return fmt.Errorf("error reading and unmarshaling configuration file: %w", err)
85 }
86 return nil
87}
88
89func (config *Config) LoadConfig() (*Config, error) {
90 configDir, err := getConfigDir()
91 if err != nil {
92 return nil, fmt.Errorf("error getting configuration directory: %w", err)
93 }
94
95 configFilePath := filepath.Join(configDir, "config.yml")
96
97 _, err = os.Stat(configFilePath)
98 if errors.Is(err, fs.ErrNotExist) {
99 fmt.Printf("Config file not found, creating it at %s\n", configFilePath)
100
101 // Create config dir if it doesn't exist
102 err = os.MkdirAll(configDir, 0755)
103 if err != nil {
104 return nil, fmt.Errorf("error creating configuration directory: %w", err)
105 }
106
107 // Create config file with the default values of ContainerEngineConfig
108 config = &Config{
109 ContainerEngine: ContainerEngineConfig{
110 Sock: sock,
111 PodmanSock: podmansock,
112 Podman: ReadUserInput("Are you using podman ? (y/n)") == "y",
113 },
114 }
115
116 err = config.SaveConfig()
117 if err != nil {
118 return nil, fmt.Errorf("error saving new configuration: %w", err)
119 }
120 return config, nil
121 }
122
123 if err != nil {
124 return nil, fmt.Errorf("error checking configuration file: %w", err)
125 }
126
127 err = readAndUnmarshalConfig(os.DirFS(configDir), "config.yml", config)
128 if err != nil {
129 return nil, err
130 }
131
132 // Load run env
133 config.Build.RunEnv = os.Getenv("RUN_ENV")
134
135 if config.Build.RunEnv == "" {
136 config.Build.RunEnv = "prod"
137 }
138
139 return config, nil
140}
141
142func (config *Config) SaveConfig() error {
143 configDir, err := getConfigDir()
144 if err != nil {
145 return fmt.Errorf("error getting configuration directory: %w", err)
146 }
147 configFilePath := filepath.Join(configDir, "config.yml")
148
149 err = parser.WriteYAMLFile(configFilePath, config)
150 if err != nil {
151 return fmt.Errorf("error writing configuration file: %w", err)
152 }
153
154 fmt.Printf("Configuration saved to %s\n", configFilePath)
155 return nil
156}
157
158func (config *Config) GetToken() (string, error) {
159 token := config.General.Token
160 if token == "" {
161 return "", fmt.Errorf("no token found in config.yml")
162 }
163
164 return token, nil
165
166}
167
168// GetRunEnv returns the run environment
169func (config *BuildConfig) GetRunEnv() string {
170 return config.RunEnv
171}
172
173// GetVersion returns the version
174func (config *Config) GetVersion() string {
175 return config.Build.BuildVersion
176}
177
178// get storage dir
179func (config *Config) GetStorageDir() string {
180 return config.General.StorageDir
181}