Files
wehub-resource-sync 36b3af2e3d
PR Check / Code Quality: Format (push) Failing after 1s
PR Check / Code Quality: Lint (darwin) (push) Failing after 0s
PR Check / Code Quality: Lint (freebsd) (push) Failing after 1s
PR Check / Code Quality: Lint (windows) (push) Failing after 1s
PR Check / Code Quality: Lint (linux) (push) Failing after 1s
PR Check / Security: Vulnerability Scan (push) Failing after 0s
Update Documentation / update-docs (push) Failing after 2s
PR Check / Code Quality: Vendor (push) Failing after 1s
PR Check / Code Quality: Coverage (push) Failing after 0s
PR Check / Tests: Unit (macos-latest) (push) Has been cancelled
PR Check / Tests: Unit (ubuntu-24.04) (push) Has been cancelled
PR Check / Tests: Unit (ubuntu-24.04-arm) (push) Has been cancelled
PR Check / Tests: Unit (windows-latest) (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:22:06 +08:00

132 lines
3.3 KiB
Go

package proc
import (
"strings"
"github.com/pranshuparmar/witr/pkg/model"
)
// ContainerRuntime is a backend (docker, podman, …) that can list containers
// and resolve a container's main host PID.
type ContainerRuntime interface {
Name() string
Available() bool
List() []*model.ContainerMatch
HostPID(id string) int
}
var registeredRuntimes []ContainerRuntime
func registerRuntime(rt ContainerRuntime) {
registeredRuntimes = append(registeredRuntimes, rt)
}
// ResolveContainer queries every available container runtime and returns the
// merged set of matches against the query. Match predicate is substring
// (case-insensitive) across name, image, and command, unless exact is true in
// which case any of those fields must equal the query.
func ResolveContainer(query string, exact bool) []*model.ContainerMatch {
q := strings.ToLower(query)
var out []*model.ContainerMatch
seen := make(map[string]bool)
for _, rt := range registeredRuntimes {
if !rt.Available() {
continue
}
for _, c := range rt.List() {
if !matchContainer(c, q, exact) {
continue
}
key := rt.Name() + "|" + c.ID
if seen[key] {
continue
}
seen[key] = true
out = append(out, c)
}
}
return out
}
func matchContainer(c *model.ContainerMatch, query string, exact bool) bool {
fields := []string{
strings.ToLower(c.Name),
strings.ToLower(c.Image),
strings.ToLower(c.Command),
strings.ToLower(c.ComposeProject),
strings.ToLower(c.ComposeService),
}
for _, f := range fields {
if f == "" {
continue
}
if exact {
if f == query {
return true
}
} else if strings.Contains(f, query) {
return true
}
}
return false
}
// ListAllContainers returns every container reported by every available
// runtime, deduped by runtime|id. Used by the TUI's Containers tab.
func ListAllContainers() []*model.ContainerMatch {
var out []*model.ContainerMatch
seen := make(map[string]bool)
for _, rt := range registeredRuntimes {
if !rt.Available() {
continue
}
for _, c := range rt.List() {
key := rt.Name() + "|" + c.ID
if seen[key] {
continue
}
seen[key] = true
out = append(out, c)
}
}
return out
}
// ResolveContainerHostPID returns the PID of the container's main process on
// the host. Returns 0 if the runtime can't be reached or the PID isn't
// available (container not running, namespaced PID, etc.).
func ResolveContainerHostPID(runtime, id string) int {
for _, rt := range registeredRuntimes {
if rt.Name() == runtime && rt.Available() {
return rt.HostPID(id)
}
}
return 0
}
// enrichingRuntime is implemented by runtimes that can supply additional
// per-container details via a follow-up call, used when a single match is
// resolved and the caller wants richer metadata than the initial list scan
// produced.
type enrichingRuntime interface {
Enrich(*model.ContainerMatch)
}
// EnrichContainer asks the originating runtime to fill in any extra fields
// available via a per-container query (e.g. crictl inspect). No-op when the
// runtime doesn't expose extra detail.
func EnrichContainer(match *model.ContainerMatch) {
if match == nil {
return
}
for _, rt := range registeredRuntimes {
if rt.Name() != match.Runtime || !rt.Available() {
continue
}
if e, ok := rt.(enrichingRuntime); ok {
e.Enrich(match)
}
return
}
}