Files
foxhunt/docs/plans/2026-03-04-pods-panel-versioning-design.md
jgrusewski 7c8fa991cc feat(infra): standalone Prometheus deployment for foxhunt namespace
- ServiceAccount + ClusterRole (nodes, pods, endpoints, metrics)
- ConfigMap with 7 scrape jobs: self, foxhunt-services, annotated-pods,
  gitlab-annotated-pods, node-exporter, kube-state-metrics, dcgm-exporter,
  pushgateway
- Deployment (Prometheus v3.8.1, 14d retention, 1500MB size limit)
- PVC (2Gi scw-bssd), Service (port 80 → 9090)

Also includes pods-panel-versioning design doc.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 13:24:52 +01:00

3.8 KiB

Pods Panel, CalVer Versioning & Cluster Resources Fix

Date: 2026-03-04 Status: Approved

1. CalVer Auto-Versioning

Scheme: YYYY.MM.PIPELINE_IID (e.g. 2026.03.408)

Flow

  1. CI compile jobs compute FOXHUNT_VERSION from CI_COMMIT_TIMESTAMP year.month + CI_PIPELINE_IID
  2. Passed to rustc via FOXHUNT_BUILD_VERSION env var
  3. common/src/build_info.rs exposes pub fn version() -> &'static str using option_env!("FOXHUNT_BUILD_VERSION").unwrap_or(env!("CARGO_PKG_VERSION"))
  4. Each service populates ServiceStatus.version from build_info::version()
  5. fxt shows version in TUI header bar and Services cockpit column

Files changed

  • .gitlab-ci.yml: compute + export FOXHUNT_BUILD_VERSION in compile jobs (~10 lines)
  • crates/common/src/build_info.rs: new module, version() function
  • crates/common/src/lib.rs: re-export build_info
  • services/api_gateway/src/grpc/monitoring_handler.rs: populate version field from build_info::version()
  • All 7 service main.rs files: log version at startup
  • bin/fxt/src/tui/cockpits/overview.rs: show fxt version in header

2. Pods Cockpit (Key 7)

Proto

New streaming RPC in monitoring.proto:

rpc SubscribeClusterPods(SubscribeClusterPodsRequest) returns (stream ClusterPodsResponse);

message SubscribeClusterPodsRequest {
  uint32 interval_seconds = 1;  // default 5
}

message ClusterPodsResponse {
  repeated PodInfo pods = 1;
  int64 timestamp = 2;
}

message PodInfo {
  string name = 1;
  string service = 2;        // app.kubernetes.io/name label
  string status = 3;         // Running/Pending/CrashLoopBackOff/Completed/etc
  int32 restarts = 4;
  string age = 5;
  string node = 6;
  float cpu_millicores = 7;  // from metrics-server (0 if unavailable)
  float memory_mb = 8;       // from metrics-server (0 if unavailable)
  bool ready = 9;
  string version = 10;       // from FOXHUNT_BUILD_VERSION env or image tag
}

api_gateway implementation

  • Add kube crate dependency (K8s client library for Rust)
  • New pods_handler.rs module: list/watch pods in foxhunt namespace via K8s API
  • Extracts app.kubernetes.io/name label as service grouping key
  • Streams pod state every 5s (default interval)
  • Pod CPU/memory from metrics-server API (/apis/metrics.k8s.io/v1beta1/namespaces/foxhunt/pods)

TUI cockpit

  • New cockpits/pods.rs as 7th cockpit (key 7)
  • Default view: service-grouped summary rows (api-gateway: 1/1 Running, v2026.03.408)
  • Expanded view: Tab/Enter on a service row expands to show individual pod rows with name, restarts, age, node, CPU/mem
  • Navigation: Up/Down to select service, Enter to expand/collapse

NetworkPolicy

  • api-gateway.yaml: add egress to K8s API (172.16.0.0/16:6443) for pod listing

RBAC

  • New Role + RoleBinding granting api_gateway SA get/list/watch on pods in foxhunt namespace

3. Cluster Resources Fix

Root cause

monitoring_handler.rs:372-375 hardcodes cpu_percent: 0.0, memory_used_mb: 0.0, memory_total_mb: 0.0 with comment "not yet scraped".

Fix

Query Prometheus for node-exporter metrics:

  • CPU: sum(rate(node_cpu_seconds_total{mode!="idle"}[2m])) / count(node_cpu_seconds_total{mode="idle"}) * 100
  • RAM used: sum(node_memory_MemTotal_bytes - node_memory_MemAvailable_bytes) / 1024 / 1024
  • RAM total: sum(node_memory_MemTotal_bytes) / 1024 / 1024

Pre-requisite

Prometheus NetworkPolicy needs egress to node IPs on port 9100 (node-exporter). Currently these targets are DOWN due to missing egress rule. Add ipBlock: 172.16.0.0/16 port 9100 to prometheus NetworkPolicy.

Dependencies

  • Prometheus networking fixes (completed 2026-03-04): Service selector, NetworkPolicy, api_gateway egress
  • node-exporter egress fix (part of this work)
  • kube crate added to api_gateway