1package config
2
3import (
4 "path/filepath"
5
6 "github.com/caarlos0/env/v6"
7 "github.com/charmbracelet/log"
8 "github.com/charmbracelet/soft-serve/server/backend"
9 "github.com/charmbracelet/soft-serve/server/backend/file"
10)
11
12// SSHConfig is the configuration for the SSH server.
13type SSHConfig struct {
14 // ListenAddr is the address on which the SSH server will listen.
15 ListenAddr string `env:"LISTEN_ADDR" envDefault:":23231"`
16
17 // KeyPath is the path to the SSH server's private key.
18 KeyPath string `env:"KEY_PATH"`
19
20 // MaxTimeout is the maximum number of seconds a connection can take.
21 MaxTimeout int `env:"MAX_TIMEOUT" envDefault:"0"`
22
23 // IdleTimeout is the number of seconds a connection can be idle before it is closed.
24 IdleTimeout int `env:"IDLE_TIMEOUT" envDefault:"120"`
25}
26
27// GitConfig is the Git daemon configuration for the server.
28type GitConfig struct {
29 // ListenAddr is the address on which the Git daemon will listen.
30 ListenAddr string `env:"LISTEN_ADDR" envDefault:":9418"`
31
32 // MaxTimeout is the maximum number of seconds a connection can take.
33 MaxTimeout int `env:"MAX_TIMEOUT" envDefault:"0"`
34
35 // IdleTimeout is the number of seconds a connection can be idle before it is closed.
36 IdleTimeout int `env:"IDLE_TIMEOUT" envDefault:"3"`
37
38 // MaxConnections is the maximum number of concurrent connections.
39 MaxConnections int `env:"MAX_CONNECTIONS" envDefault:"32"`
40}
41
42// Config is the configuration for Soft Serve.
43type Config struct {
44 // SSH is the configuration for the SSH server.
45 SSH SSHConfig `envPrefix:"SSH_"`
46
47 // Git is the configuration for the Git daemon.
48 Git GitConfig `envPrefix:"GIT_"`
49
50 // InitialAdminKeys is a list of public keys that will be added to the list of admins.
51 InitialAdminKeys []string `env:"INITIAL_ADMIN_KEY" envSeparator:"\n"`
52
53 // DataPath is the path to the directory where Soft Serve will store its data.
54 DataPath string `env:"DATA_PATH" envDefault:"data"`
55
56 // Backend is the Git backend to use.
57 Backend backend.Backend
58
59 // Access is the access control backend to use.
60 Access backend.AccessMethod
61}
62
63// DefaultConfig returns a Config with the values populated with the defaults
64// or specified environment variables.
65func DefaultConfig() *Config {
66 cfg := &Config{}
67 if err := env.Parse(cfg, env.Options{
68 Prefix: "SOFT_SERVE_",
69 }); err != nil {
70 log.Fatal(err)
71 }
72 if cfg.SSH.KeyPath == "" {
73 cfg.SSH.KeyPath = filepath.Join(cfg.DataPath, "ssh", "soft_serve")
74 }
75 fb, err := file.NewFileBackend(cfg.DataPath)
76 if err != nil {
77 log.Fatal(err)
78 }
79 // Add the initial admin keys to the list of admins.
80 fb.AdditionalAdmins = cfg.InitialAdminKeys
81 return cfg.WithBackend(fb).WithAccessMethod(fb)
82}
83
84// WithBackend sets the backend for the configuration.
85func (c *Config) WithBackend(backend backend.Backend) *Config {
86 c.Backend = backend
87 return c
88}
89
90// WithAccessMethod sets the access control method for the configuration.
91func (c *Config) WithAccessMethod(access backend.AccessMethod) *Config {
92 c.Access = access
93 return c
94}