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 // PublicURL is the public URL of the SSH server.
18 PublicURL string `env:"PUBLIC_URL" envDefault:"ssh://localhost:23231"`
19
20 // KeyPath is the path to the SSH server's private key.
21 KeyPath string `env:"KEY_PATH"`
22
23 // MaxTimeout is the maximum number of seconds a connection can take.
24 MaxTimeout int `env:"MAX_TIMEOUT" envDefault:"0"`
25
26 // IdleTimeout is the number of seconds a connection can be idle before it is closed.
27 IdleTimeout int `env:"IDLE_TIMEOUT" envDefault:"120"`
28}
29
30// GitConfig is the Git daemon configuration for the server.
31type GitConfig struct {
32 // ListenAddr is the address on which the Git daemon will listen.
33 ListenAddr string `env:"LISTEN_ADDR" envDefault:":9418"`
34
35 // MaxTimeout is the maximum number of seconds a connection can take.
36 MaxTimeout int `env:"MAX_TIMEOUT" envDefault:"0"`
37
38 // IdleTimeout is the number of seconds a connection can be idle before it is closed.
39 IdleTimeout int `env:"IDLE_TIMEOUT" envDefault:"3"`
40
41 // MaxConnections is the maximum number of concurrent connections.
42 MaxConnections int `env:"MAX_CONNECTIONS" envDefault:"32"`
43}
44
45// HTTPConfig is the HTTP configuration for the server.
46type HTTPConfig struct {
47 // ListenAddr is the address on which the HTTP server will listen.
48 ListenAddr string `env:"LISTEN_ADDR" envDefault:":8080"`
49
50 // PublicURL is the public URL of the HTTP server.
51 PublicURL string `env:"PUBLIC_URL" envDefault:"http://localhost:8080"`
52}
53
54// Config is the configuration for Soft Serve.
55type Config struct {
56 // Name is the name of the server.
57 Name string `env:"NAME" envDefault:"Soft Serve"`
58
59 // SSH is the configuration for the SSH server.
60 SSH SSHConfig `envPrefix:"SSH_"`
61
62 // Git is the configuration for the Git daemon.
63 Git GitConfig `envPrefix:"GIT_"`
64
65 // HTTP is the configuration for the HTTP server.
66 HTTP HTTPConfig `envPrefix:"HTTP_"`
67
68 // InitialAdminKeys is a list of public keys that will be added to the list of admins.
69 InitialAdminKeys []string `env:"INITIAL_ADMIN_KEY" envSeparator:"\n"`
70
71 // DataPath is the path to the directory where Soft Serve will store its data.
72 DataPath string `env:"DATA_PATH" envDefault:"data"`
73
74 // Backend is the Git backend to use.
75 Backend backend.Backend
76
77 // Access is the access control backend to use.
78 Access backend.AccessMethod
79}
80
81// DefaultConfig returns a Config with the values populated with the defaults
82// or specified environment variables.
83func DefaultConfig() *Config {
84 cfg := &Config{}
85 if err := env.Parse(cfg, env.Options{
86 Prefix: "SOFT_SERVE_",
87 }); err != nil {
88 log.Fatal(err)
89 }
90 if cfg.SSH.KeyPath == "" {
91 cfg.SSH.KeyPath = filepath.Join(cfg.DataPath, "ssh", "soft_serve")
92 }
93 fb, err := file.NewFileBackend(cfg.DataPath)
94 if err != nil {
95 log.Fatal(err)
96 }
97 // Add the initial admin keys to the list of admins.
98 fb.AdditionalAdmins = cfg.InitialAdminKeys
99 return cfg.WithBackend(fb).WithAccessMethod(fb)
100}
101
102// WithBackend sets the backend for the configuration.
103func (c *Config) WithBackend(backend backend.Backend) *Config {
104 c.Backend = backend
105 return c
106}
107
108// WithAccessMethod sets the access control method for the configuration.
109func (c *Config) WithAccessMethod(access backend.AccessMethod) *Config {
110 c.Access = access
111 return c
112}