feat(agent): UPDATE_TIMEOUT and DOCKER_CONFIG settings (#7)

This commit is contained in:
2026-10-12 18:40:15 +02:00
parent c9c4e0cadb
commit e2b73dfd81
35 changed files with 104 additions and 2161 deletions
+42
View File
@@ -2,10 +2,14 @@
package config
import (
"encoding/json"
"errors"
"fmt"
"os"
"path/filepath"
"regexp"
"strings"
"time"
)
var masterKeyPattern = regexp.MustCompile(`^sha256:[0-9a-f]{64}$`)
@@ -17,8 +21,17 @@ type Config struct {
Token string // AGENT_TOKEN, shown once when the agent was added
SelfID string // SELF_ID, defaults to the hostname (= container ID prefix)
LogLevel string // LOG_LEVEL, default info
// UpdateTimeout bounds one update job (UPDATE_TIMEOUT, default 5m).
UpdateTimeout time.Duration
// DockerConfig is the directory holding config.json with registry
// credentials (DOCKER_CONFIG). Empty means anonymous registry access.
DockerConfig string
}
// defaultUpdateTimeout is used when UPDATE_TIMEOUT is unset.
const defaultUpdateTimeout = 5 * time.Minute
// Load reads and validates the agent configuration. It fails fast so a
// misconfigured agent never starts dialling.
func Load() (*Config, error) {
@@ -28,6 +41,9 @@ func Load() (*Config, error) {
Token: os.Getenv("AGENT_TOKEN"),
SelfID: os.Getenv("SELF_ID"),
LogLevel: os.Getenv("LOG_LEVEL"),
UpdateTimeout: defaultUpdateTimeout,
DockerConfig: os.Getenv("DOCKER_CONFIG"),
}
switch {
case cfg.MasterURL == "":
@@ -41,6 +57,18 @@ func Load() (*Config, error) {
case cfg.Token == "":
return nil, errors.New("AGENT_TOKEN is required")
}
if v := os.Getenv("UPDATE_TIMEOUT"); v != "" {
d, err := time.ParseDuration(v)
if err != nil || d <= 0 {
return nil, fmt.Errorf("UPDATE_TIMEOUT must be a positive duration such as 5m, got %q", v)
}
cfg.UpdateTimeout = d
}
if cfg.DockerConfig != "" {
if err := checkDockerConfig(cfg.DockerConfig); err != nil {
return nil, err
}
}
if cfg.SelfID == "" {
cfg.SelfID, _ = os.Hostname()
}
@@ -49,3 +77,17 @@ func Load() (*Config, error) {
}
return cfg, nil
}
// checkDockerConfig fails when DOCKER_CONFIG is set but its config.json is
// missing or not JSON, so a typo does not silently turn into anonymous pulls.
func checkDockerConfig(dir string) error {
path := filepath.Join(dir, "config.json")
raw, err := os.ReadFile(path)
if err != nil {
return fmt.Errorf("DOCKER_CONFIG: read %s: %w", path, err)
}
if !json.Valid(raw) {
return fmt.Errorf("DOCKER_CONFIG: %s is not valid JSON", path)
}
return nil
}