summaryrefslogtreecommitdiff
path: root/internal
diff options
context:
space:
mode:
authorJames O'Doherty <james@theodohertyfamily.com>2026-06-04 00:21:56 -0400
committerJames O'Doherty <james@theodohertyfamily.com>2026-06-04 00:21:56 -0400
commitc53503b52b6fc6de37b6053719521054003fa50b (patch)
treeaaa6f3ff912365676261a48c39d325023d0a9c38 /internal
parent51a0845adba702ac02437405988b24b3b2c9fb45 (diff)
clean up debugging prints and silence successful execution output
- Remove leftover DEBUG prints from CLI and wireguard internal packages. - Silence stdout during successful command wrapping to ensure only the wrapped command's output is visible. - Redirect all warnings and internal errors to stderr. - Implement a verbose mode via `WG_WRAP_VERBOSE=1` to enable tunnel status messages. - Update E2E tests to use verbose mode for verification of tunnel lifecycle events. - Fix errcheck linting issue in wireguard.go and apply go fmt.
Diffstat (limited to 'internal')
-rw-r--r--internal/cli/cli.go33
-rw-r--r--internal/namespace/lifecycle_test.go6
-rw-r--r--internal/namespace/pinning.go2
-rw-r--r--internal/wireguard/wireguard.go16
4 files changed, 31 insertions, 26 deletions
diff --git a/internal/cli/cli.go b/internal/cli/cli.go
index 4b3e36a..edf6048 100644
--- a/internal/cli/cli.go
+++ b/internal/cli/cli.go
@@ -123,12 +123,10 @@ func (a *App) Run() error {
}
if namespace.IsIsolated() {
- fmt.Printf("DEBUG: IsIsolated=true, RuntimeBaseDir=%s\n", a.getPathManager().RuntimeBaseDir())
return a.ExecuteCommand(cfg)
}
pm := a.getPathManager()
- fmt.Printf("DEBUG: IsIsolated=false, RuntimeBaseDir=%s\n", pm.RuntimeBaseDir())
// Preserve the host runtime base dir in the environment before bootstrapping
_ = os.Setenv("WG_WRAP_HOST_RUNTIME_BASE_DIR", pm.RuntimeBaseDir())
@@ -146,7 +144,7 @@ func (a *App) Run() error {
// Release the lock before executing the command to allow others to join
namespace.ReleaseProfileLock(lockFile)
- // Register this PID before joining to prevent the race where the joining process
+ // Register this PID before joining to prevent the race where the joining process
// hasn't registered itself yet, causing the existing process to think it's the last one.
_ = namespace.RegisterProcess(pm, cfg.Profile)
@@ -163,6 +161,10 @@ func (a *App) Run() error {
return nil
}
+func (a *App) isVerbose() bool {
+ return os.Getenv("WG_WRAP_VERBOSE") == "1"
+}
+
func (a *App) ExecuteCommand(cfg *config.Config) error {
if !namespace.IsIsolated() {
return fmt.Errorf("ExecuteCommand called without namespace isolation")
@@ -182,7 +184,7 @@ func (a *App) ExecuteCommand(cfg *config.Config) error {
}
if err := namespace.PruneStalePids(pm, cfg.Profile); err != nil {
- fmt.Printf("failed to prune stale pids: %v\n", err)
+ fmt.Fprintf(os.Stderr, "failed to prune stale pids: %v\n", err)
}
if err := namespace.RegisterProcess(pm, cfg.Profile); err != nil {
return fmt.Errorf("failed to register process: %w", err)
@@ -203,20 +205,19 @@ func (a *App) ExecuteCommand(cfg *config.Config) error {
if cleanupErr == nil {
// 1. Unregister the process first.
if err := namespace.UnregisterProcess(pm, cfg.Profile); err != nil {
- fmt.Printf("failed to unregister process: %v\n", err)
+ fmt.Fprintf(os.Stderr, "failed to unregister process: %v\n", err)
}
// 2. Prune and check if we are the last process.
if err := namespace.PruneStalePids(pm, cfg.Profile); err != nil {
- fmt.Printf("failed to prune stale pids during cleanup: %v\n", err)
+ fmt.Fprintf(os.Stderr, "failed to prune stale pids during cleanup: %v\n", err)
}
last, lastErr := namespace.IsLastProcess(pm, cfg.Profile)
if lastErr == nil && last {
- fmt.Printf("Last process exiting. Cleaning up profile %s...\n", cfg.Profile)
if err := namespace.UnpinNamespace(pm, cfg.Profile); err != nil {
- fmt.Printf("failed to unpin namespace: %v\n", err)
+ fmt.Fprintf(os.Stderr, "failed to unpin namespace: %v\n", err)
}
}
if lockErr == nil && !lockFileReleased {
@@ -226,15 +227,19 @@ func (a *App) ExecuteCommand(cfg *config.Config) error {
} else {
// Fallback if lock fails to ensure we still unregister
if err := namespace.UnregisterProcess(pm, cfg.Profile); err != nil {
- fmt.Printf("failed to unregister process: %v\n", err)
+ fmt.Fprintf(os.Stderr, "failed to unregister process: %v\n", err)
}
}
}()
if os.Getenv("WG_WRAP_JOINED") == "1" {
- fmt.Printf("Joining active WireGuard tunnel session for profile %s...\n", cfg.Profile)
+ if a.isVerbose() {
+ fmt.Printf("Joining active WireGuard tunnel session for profile %s...\n", cfg.Profile)
+ }
} else {
- fmt.Printf("Initializing WireGuard tunnel for profile %s...\n", cfg.Profile)
+ if a.isVerbose() {
+ fmt.Printf("Initializing WireGuard tunnel for profile %s...\n", cfg.Profile)
+ }
// Parse the profile configuration
profilesDir := pm.ConfigDir()
@@ -268,7 +273,7 @@ func (a *App) ExecuteCommand(cfg *config.Config) error {
}
}
if !hasDefaultRoute {
- fmt.Printf("warning: Falling back to 1.1.1.1, but your profile does not route all traffic (0.0.0.0/0). DNS resolution may fail.\n")
+ fmt.Fprintf(os.Stderr, "warning: Falling back to 1.1.1.1, but your profile does not route all traffic (0.0.0.0/0). DNS resolution may fail.\n")
}
}
@@ -280,14 +285,14 @@ func (a *App) ExecuteCommand(cfg *config.Config) error {
// Pin the namespace so others can join it
if err := namespace.PinNamespace(pm, cfg.Profile); err != nil {
- fmt.Printf("warning: failed to pin namespace: %v\n", err)
+ fmt.Fprintf(os.Stderr, "warning: failed to pin namespace: %v\n", err)
}
} else {
// If profile is not default or it was explicitly requested but doesn't exist, we error
if cfg.Profile != "default" {
return fmt.Errorf("profile %s not found: %w", cfg.Profile, err)
}
- fmt.Printf("warning: default profile configuration not found. Executing command in bare isolation.\n")
+ fmt.Fprintf(os.Stderr, "warning: default profile configuration not found. Executing command in bare isolation.\n")
}
}
diff --git a/internal/namespace/lifecycle_test.go b/internal/namespace/lifecycle_test.go
index 9962e14..3e01ea9 100644
--- a/internal/namespace/lifecycle_test.go
+++ b/internal/namespace/lifecycle_test.go
@@ -87,7 +87,7 @@ func TestLifecycleReferenceCounting(t *testing.T) {
if err := RegisterProcess(pm, profile); err != nil {
t.Fatal(err)
}
-
+
// Simulate the application flow: Unregister before checking if we are the last one
if err := UnregisterProcess(pm, profile); err != nil {
t.Fatal(err)
@@ -102,12 +102,12 @@ func TestLifecycleReferenceCounting(t *testing.T) {
if err := os.WriteFile(filepath.Join(pidsDir, "1234567"), []byte(""), 0644); err != nil {
t.Fatal(err)
}
-
+
// Register a real process so that pruning has something to do
if err := RegisterProcess(pm, profile); err != nil {
t.Fatal(err)
}
-
+
// Prune the stale one
if err := PruneStalePids(pm, profile); err != nil {
t.Fatal(err)
diff --git a/internal/namespace/pinning.go b/internal/namespace/pinning.go
index 9bf4fee..00f7c9b 100644
--- a/internal/namespace/pinning.go
+++ b/internal/namespace/pinning.go
@@ -72,7 +72,7 @@ func UnpinNamespace(pm *paths.PathManager, profile string) error {
}
// 3. Unmount and clean up blocking services.
- // Since the block files are located within the profile directory,
+ // Since the block files are located within the profile directory,
// we must unmount them before we can remove the directory.
for _, p := range GetBlockPaths() {
_ = unix.Unmount(p, unix.MNT_DETACH)
diff --git a/internal/wireguard/wireguard.go b/internal/wireguard/wireguard.go
index 45e6292..0c341f2 100644
--- a/internal/wireguard/wireguard.go
+++ b/internal/wireguard/wireguard.go
@@ -25,9 +25,9 @@ import (
// Tunnel represents an active Userspace WireGuard tunnel inside a network namespace.
type Tunnel struct {
- Device *device.Device
- Tun tun.Device
- dnsFile string
+ Device *device.Device
+ Tun tun.Device
+ dnsFile string
}
// StartTunnel creates a TUN device, launches wireguard-go over it, and configures IPs/routes.
@@ -108,7 +108,9 @@ func StartTunnel(pm *paths.PathManager, profile string, cfg *wgconf.Config, dnsS
} else {
dnsFile = path
cleanups = append(cleanups, func() {
- UnmountResolvConf(dnsFile)
+ if err := UnmountResolvConf(dnsFile); err != nil {
+ fmt.Printf("warning: failed to unmount resolv.conf during cleanup: %v\n", err)
+ }
})
}
@@ -243,7 +245,7 @@ func ConfigureResolvConf(dns string, profileDir string) (string, error) {
if dns == "" {
return "", nil
}
-
+
// Create the temporary resolv.conf file within the profile directory
// so it can be cleaned up during namespace unpinning.
tmpFile, err := os.CreateTemp(profileDir, "resolvconf")
@@ -274,8 +276,6 @@ func UnmountResolvConf(path string) error {
return nil
}
- fmt.Printf("DEBUG: Unmounting resolv.conf file: %s\n", path)
-
// Attempt to unmount. If it fails, it might already be unmounted
// or the namespace might be gone.
_ = unix.Unmount("/etc/resolv.conf", unix.MNT_DETACH)
@@ -335,7 +335,7 @@ func (h *HostBind) Close() error { return ni
func (h *HostBind) SetMark(mark uint32) error { return nil }
func (h *HostBind) Send(bufs [][]byte, endpoint conn.Endpoint) error { return nil }
func (h *HostBind) ParseEndpoint(s string) (conn.Endpoint, error) { return nil, nil }
-func (h *HostBind) BatchSize() int { return 0}
+func (h *HostBind) BatchSize() int { return 0 }
type FDBind struct {
originalFd int