P0 #2 — currentConfig data race
Manager.currentConfig was written without locking in Start/Reload but
read from the health-checker callback goroutine. All accesses now go
through workersMu (read or write as appropriate).
P0 #3 — Reload kills health checker permanently
Reload's zero-forward branch called m.Stop() which tore down the
health checker, watchdog, and event bus. After that, EnableForward
silently registered callbacks against dead components. Now the branch
stops only the running workers; the supervisory infrastructure stays
alive across config changes.
P0 #4 — rest.Config write-write race
executePortForward was mutating .Dial on the cached *rest.Config
shared by all forwards in the same kube context. Cloning the config
with rest.CopyConfig before mutation isolates per-forward dialers.
P0 #5 — ForwardWorker.Stop() double-close panic
close(w.stopChan) is now wrapped in sync.Once, so concurrent Stop
calls (Manager.Stop racing stopWorkerInternal) are safe.
New tests in internal/forward/concurrency_test.go exercise each fix
under -race: 16 concurrent worker Stops, repeated sequential Stops,
empty-Reload preserves infra pointers, and concurrent currentConfig
read/write.
CI runners have no kubeconfig, so clientcmd's loader returns an empty
config (no error) and CurrentContext == "". The previous assertion
'NotEmpty(context)' on the success branch was incorrect — an empty
current-context is valid for an empty kubeconfig.
Mirrors the looser pattern in TestDiscovery_ListContexts.
- [x] Add golangci-lint v2 configuration with formatters section
- [x] Reorganize linters-settings under linters section
- [x] Replace if-else chains with switch statements for clarity
- [x] Wrap all ignored error returns with `_ = ` pattern
- [x] Add OSC 8 hyperlink helper function for clickable ports
- [x] Add blank line in table styling function
- [x] Remove unnecessary type assertion in test
When user starts kportal for the first time, and there is no config file,
kportal should create an empty config file with default values and empty
forwarding rules, so that user can easily edit the config file and add their
own rules.
When adding a service via the wizard, resolve the service's targetPort to the actual pod container port instead of using the service port directly.
Problem: Service port 80 → Pod port 8000, but kportal was trying to forward to port 80 on the pod.
Solution: Look up the pod's actual containerPort when the service uses a named targetPort (like http), and use that for port-forwarding.
* Fix enter misbehaving.
* Cleanup after previous tui implementation.
* Fix race condition and improve logging
* Add filtering of the namespaces by text input in the wizard UI