From 135f6edbd9389bc4783f13c26aed0a74d3c8aca0 Mon Sep 17 00:00:00 2001 From: James O'Doherty Date: Fri, 22 May 2026 16:17:55 -0400 Subject: refactor: unify path management and complete profile management system - Create internal/paths package for unified config and runtime directory resolution - Implement robust WireGuard config parsing in pkg/wgconf - Implement profile management subcommands: list, import, configure, delete, stop - Fix namespace pinning path collisions (separating .ns files from pids directories) - Implement and verify namespace unpinning logic - Fix linting errors and improve error handling across the project --- internal/paths/paths.go | 62 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 internal/paths/paths.go (limited to 'internal/paths') diff --git a/internal/paths/paths.go b/internal/paths/paths.go new file mode 100644 index 0000000..f512ad1 --- /dev/null +++ b/internal/paths/paths.go @@ -0,0 +1,62 @@ +package paths + +import ( + "fmt" + "os" + "path/filepath" +) + +// PathManager handles the resolution of configuration and runtime directories. +// By using a struct, we can instantiate different managers for parallel tests. +type PathManager struct { + ConfigDirOverride string + RuntimeBaseOverride string +} + +// NewPathManager creates a PathManager with the given overrides. +func NewPathManager(configOverride, runtimeOverride string) *PathManager { + return &PathManager{ + ConfigDirOverride: configOverride, + RuntimeBaseOverride: runtimeOverride, + } +} + +// ConfigDir returns the persistent storage path for .conf files. +func (pm *PathManager) ConfigDir() string { + if pm.ConfigDirOverride != "" { + return pm.ConfigDirOverride + } + + configHome := os.Getenv("XDG_CONFIG_HOME") + if configHome == "" { + home, err := os.UserHomeDir() + if err != nil { + return "/etc/wg-wrap/profiles" // Fallback + } + configHome = filepath.Join(home, ".config") + } + return filepath.Join(configHome, "wg-wrap", "profiles") +} + +// RuntimeBaseDir returns the base ephemeral path. +func (pm *PathManager) RuntimeBaseDir() string { + if pm.RuntimeBaseOverride != "" { + return pm.RuntimeBaseOverride + } + + if envDir := os.Getenv("XDG_RUNTIME_DIR"); envDir != "" { + return envDir + } + uid := os.Getuid() + return fmt.Sprintf("/run/user/%d", uid) +} + +// ProfileNamespacePath returns the specific path for a pinned namespace. +func (pm *PathManager) ProfileNamespacePath(profile string) string { + return filepath.Join(pm.RuntimeBaseDir(), "profiles", profile+".ns") +} + +// ProfilePidsDir returns the path for PID tracking. +func (pm *PathManager) ProfilePidsDir(profile string) string { + return filepath.Join(pm.RuntimeBaseDir(), "profiles", profile, "pids") +} -- cgit v1.2.3