Files
BlackBean/internal/agent/docker_config.go
T
2026-08-14 23:41:57 +08:00

100 lines
2.4 KiB
Go

package agent
import (
"encoding/json"
"os"
"path/filepath"
"runtime"
"sync"
)
// DockerConfig 是用户可配置的 Docker 连接信息。
type DockerConfig struct {
// Socket 是用户配置的 Docker 连接地址,支持
// unix:///var/run/docker.sock、npipe:////./pipe/docker_engine、tcp://host:2375 等。
// 为空时使用默认的本地 Docker。
Socket string `json:"socket,omitempty"`
}
// DockerConfigStore 持久化用户的 Docker socket 配置,并给出默认值。
type DockerConfigStore struct {
mu sync.RWMutex
path string
config DockerConfig
defaultSocket string
}
func NewDockerConfigStore(dataDir string) (*DockerConfigStore, error) {
defaultSocket := getenv("AGENT_DOCKER_SOCKET", "")
if defaultSocket == "" {
defaultSocket = defaultDockerSocket()
}
store := &DockerConfigStore{
path: filepath.Join(dataDir, "docker-config.json"),
defaultSocket: defaultSocket,
}
store.load()
return store, nil
}
func defaultDockerSocket() string {
if runtime.GOOS == "windows" {
return "npipe:////./pipe/docker_engine"
}
return "unix:///var/run/docker.sock"
}
func (s *DockerConfigStore) load() {
data, err := os.ReadFile(s.path)
if err != nil {
return
}
if len(data) == 0 {
return
}
var config DockerConfig
if err := json.Unmarshal(data, &config); err != nil {
return
}
s.config = config
}
// Socket 返回当前生效的 docker 连接地址:用户配置优先,否则使用默认本地 Docker。
func (s *DockerConfigStore) Socket() string {
s.mu.RLock()
defer s.mu.RUnlock()
if s.config.Socket != "" {
return s.config.Socket
}
return s.defaultSocket
}
// DefaultSocket 返回未配置时使用的默认地址。
func (s *DockerConfigStore) DefaultSocket() string {
return s.defaultSocket
}
// IsConfigured 报告用户是否手动配置过 socket。
func (s *DockerConfigStore) IsConfigured() bool {
s.mu.RLock()
defer s.mu.RUnlock()
return s.config.Socket != ""
}
// SetSocket 保存用户的 socket 配置;传入空字符串表示清除配置、恢复默认。
func (s *DockerConfigStore) SetSocket(socket string) error {
s.mu.Lock()
defer s.mu.Unlock()
s.config.Socket = socket
data, err := json.MarshalIndent(s.config, "", " ")
if err != nil {
return err
}
tmp := s.path + ".tmp"
if err := os.WriteFile(tmp, data, 0o600); err != nil {
return err
}
return os.Rename(tmp, s.path)
}