sketch: exclude internal processes (headless-chrome) from port monitoring
Add SKETCH_IGNORE_PORTS environment variable to headless-shell browser processes
and modify port monitoring to exclude processes with this variable.
Co-Authored-By: sketch <hello@sketch.dev>
Change-ID: sff3b145df27ee3bek
diff --git a/loop/port_monitor.go b/loop/port_monitor.go
index 7eaa98f..14869da 100644
--- a/loop/port_monitor.go
+++ b/loop/port_monitor.go
@@ -4,7 +4,9 @@
"context"
"fmt"
"log/slog"
+ "os"
"sort"
+ "strings"
"sync"
"time"
@@ -178,6 +180,11 @@
return
}
+ // Skip processes with SKETCH_IGNORE_PORTS environment variable
+ if pm.shouldIgnoreProcess(port.Pid) {
+ return
+ }
+
// TODO: Structure this so that UI can display it more nicely.
content := fmt.Sprintf("Port %s: %s:%d", event, port.Proto, port.Port)
if port.Process != "" {
@@ -244,3 +251,28 @@
}
return removed
}
+
+// shouldIgnoreProcess checks if a process should be ignored based on its environment variables.
+func (pm *PortMonitor) shouldIgnoreProcess(pid int) bool {
+ if pid <= 0 {
+ return false
+ }
+
+ // Read the process environment from /proc/[pid]/environ
+ envFile := fmt.Sprintf("/proc/%d/environ", pid)
+ envData, err := os.ReadFile(envFile)
+ if err != nil {
+ // If we can't read the environment, don't ignore the process
+ return false
+ }
+
+ // Parse the environment variables (null-separated)
+ envVars := strings.Split(string(envData), "\x00")
+ for _, envVar := range envVars {
+ if envVar == "SKETCH_IGNORE_PORTS=1" {
+ return true
+ }
+ }
+
+ return false
+}
diff --git a/loop/port_monitor_test.go b/loop/port_monitor_test.go
index 1339720..ec847bd 100644
--- a/loop/port_monitor_test.go
+++ b/loop/port_monitor_test.go
@@ -2,6 +2,8 @@
import (
"context"
+ "os"
+ "os/exec"
"testing"
"time"
@@ -224,6 +226,42 @@
}
}
+// TestPortMonitor_ShouldIgnoreProcess tests the shouldIgnoreProcess function.
+func TestPortMonitor_ShouldIgnoreProcess(t *testing.T) {
+ agent := createTestAgent(t)
+ pm := NewPortMonitor(agent, 100*time.Millisecond)
+
+ // Test with current process (should not be ignored)
+ currentPid := os.Getpid()
+ if pm.shouldIgnoreProcess(currentPid) {
+ t.Errorf("current process should not be ignored")
+ }
+
+ // Test with invalid PID
+ if pm.shouldIgnoreProcess(0) {
+ t.Errorf("invalid PID should not be ignored")
+ }
+ if pm.shouldIgnoreProcess(-1) {
+ t.Errorf("negative PID should not be ignored")
+ }
+
+ // Test with a process that has SKETCH_IGNORE_PORTS=1
+ cmd := exec.Command("sleep", "5")
+ cmd.Env = append(os.Environ(), "SKETCH_IGNORE_PORTS=1")
+ err := cmd.Start()
+ if err != nil {
+ t.Fatalf("failed to start test process: %v", err)
+ }
+ defer cmd.Process.Kill()
+
+ // Allow a moment for the process to start
+ time.Sleep(100 * time.Millisecond)
+
+ if !pm.shouldIgnoreProcess(cmd.Process.Pid) {
+ t.Errorf("process with SKETCH_IGNORE_PORTS=1 should be ignored")
+ }
+}
+
// createTestAgent creates a minimal test agent for testing.
func createTestAgent(t *testing.T) *Agent {
// Create a minimal agent for testing