@pleri/olam-cli 0.1.159 → 0.1.161
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +11 -0
- package/dist/agent-stream/agent-sdk-to-chunks.js +3 -0
- package/dist/agent-stream/driver-runner.js +9 -4
- package/dist/agent-stream/host-driver-launch.js +48 -0
- package/dist/commands/bootstrap.d.ts +15 -0
- package/dist/commands/bootstrap.d.ts.map +1 -1
- package/dist/commands/bootstrap.js +30 -1
- package/dist/commands/bootstrap.js.map +1 -1
- package/dist/commands/flywheel/check-persona-skeleton.d.ts +30 -2
- package/dist/commands/flywheel/check-persona-skeleton.d.ts.map +1 -1
- package/dist/commands/flywheel/check-persona-skeleton.js +143 -6
- package/dist/commands/flywheel/check-persona-skeleton.js.map +1 -1
- package/dist/commands/flywheel/diversity-check.d.ts +12 -2
- package/dist/commands/flywheel/diversity-check.d.ts.map +1 -1
- package/dist/commands/flywheel/diversity-check.js +56 -6
- package/dist/commands/flywheel/diversity-check.js.map +1 -1
- package/dist/commands/flywheel/index.d.ts.map +1 -1
- package/dist/commands/flywheel/index.js +2 -0
- package/dist/commands/flywheel/index.js.map +1 -1
- package/dist/commands/flywheel/install-shims.d.ts +36 -3
- package/dist/commands/flywheel/install-shims.d.ts.map +1 -1
- package/dist/commands/flywheel/install-shims.js +118 -7
- package/dist/commands/flywheel/install-shims.js.map +1 -1
- package/dist/commands/flywheel/k10-measure.d.ts +12 -2
- package/dist/commands/flywheel/k10-measure.d.ts.map +1 -1
- package/dist/commands/flywheel/k10-measure.js +55 -6
- package/dist/commands/flywheel/k10-measure.js.map +1 -1
- package/dist/commands/flywheel/migrate-overlays.d.ts +115 -0
- package/dist/commands/flywheel/migrate-overlays.d.ts.map +1 -0
- package/dist/commands/flywheel/migrate-overlays.js +766 -0
- package/dist/commands/flywheel/migrate-overlays.js.map +1 -0
- package/dist/commands/flywheel/sanitize-persona-output.d.ts +33 -2
- package/dist/commands/flywheel/sanitize-persona-output.d.ts.map +1 -1
- package/dist/commands/flywheel/sanitize-persona-output.js +94 -6
- package/dist/commands/flywheel/sanitize-persona-output.js.map +1 -1
- package/dist/commands/memory/index.d.ts.map +1 -1
- package/dist/commands/memory/index.js +2 -0
- package/dist/commands/memory/index.js.map +1 -1
- package/dist/commands/memory/install-hooks.d.ts +22 -0
- package/dist/commands/memory/install-hooks.d.ts.map +1 -0
- package/dist/commands/memory/install-hooks.js +156 -0
- package/dist/commands/memory/install-hooks.js.map +1 -0
- package/dist/commands/skills-doctor.js +2 -2
- package/dist/commands/skills-doctor.js.map +1 -1
- package/dist/commands/skills-source.d.ts.map +1 -1
- package/dist/commands/skills-source.js +10 -0
- package/dist/commands/skills-source.js.map +1 -1
- package/dist/commands/skills.d.ts.map +1 -1
- package/dist/commands/skills.js +169 -1
- package/dist/commands/skills.js.map +1 -1
- package/dist/image-digests.json +7 -7
- package/dist/index.js +4361 -1768
- package/dist/lib/bootstrap-kubernetes.d.ts +42 -0
- package/dist/lib/bootstrap-kubernetes.d.ts.map +1 -0
- package/dist/lib/bootstrap-kubernetes.js +287 -0
- package/dist/lib/bootstrap-kubernetes.js.map +1 -0
- package/dist/lib/config.d.ts.map +1 -1
- package/dist/lib/config.js +6 -1
- package/dist/lib/config.js.map +1 -1
- package/dist/lib/flywheel-probes.d.ts +58 -0
- package/dist/lib/flywheel-probes.d.ts.map +1 -0
- package/dist/lib/flywheel-probes.js +163 -0
- package/dist/lib/flywheel-probes.js.map +1 -0
- package/dist/lib/shim-generator.d.ts +51 -0
- package/dist/lib/shim-generator.d.ts.map +1 -0
- package/dist/lib/shim-generator.js +88 -0
- package/dist/lib/shim-generator.js.map +1 -0
- package/dist/lib/skills-apply-overlays.d.ts +35 -0
- package/dist/lib/skills-apply-overlays.d.ts.map +1 -0
- package/dist/lib/skills-apply-overlays.js +243 -0
- package/dist/lib/skills-apply-overlays.js.map +1 -0
- package/dist/mcp-server.js +1106 -453
- package/hermes-bundle/version.json +1 -1
- package/host-cp/k8s/manifests/50-deployment.yaml +1 -1
- package/host-cp/k8s/manifests/auth-service/50-deployment.yaml +1 -1
- package/host-cp/k8s/manifests/kg-service/50-deployment.yaml +1 -1
- package/host-cp/k8s/manifests/mcp-auth-service/50-deployment.yaml +1 -1
- package/host-cp/k8s/manifests/memory-service/30-configmap.yaml +11 -0
- package/host-cp/k8s/manifests/memory-service/35-configmap-iii-config.yaml +76 -0
- package/host-cp/k8s/manifests/memory-service/50-deployment.yaml +11 -1
- package/host-cp/observability/grafana-port-forward.sh +273 -0
- package/host-cp/observability/kyverno-cardinality-mutate.sh +452 -0
- package/host-cp/observability/loki-ingest.sh +243 -0
- package/host-cp/observability/prom-no-double-grafana.sh +301 -0
- package/host-cp/src/crystallize-planning.mjs +261 -0
- package/host-cp/src/plan-chat-service.mjs +84 -2
- package/host-cp/src/planning-sessions.mjs +270 -0
- package/package.json +1 -1
|
@@ -111,7 +111,7 @@ spec:
|
|
|
111
111
|
# k3d), started by `olam upgrade` Step 0.7 — not inside this Pod.
|
|
112
112
|
containers:
|
|
113
113
|
- name: olam-host-cp
|
|
114
|
-
image: ghcr.io/pleri/olam-host-cp@sha256:
|
|
114
|
+
image: ghcr.io/pleri/olam-host-cp@sha256:a71a02ad25f03c1481d8b5a4f3cf50614eb1f9b02376935e4df5c65b9bd4fa8f
|
|
115
115
|
imagePullPolicy: IfNotPresent
|
|
116
116
|
securityContext:
|
|
117
117
|
runAsNonRoot: true
|
|
@@ -70,7 +70,7 @@ spec:
|
|
|
70
70
|
mountPath: /data
|
|
71
71
|
containers:
|
|
72
72
|
- name: olam-auth-service
|
|
73
|
-
image: ghcr.io/pleri/olam-auth@sha256:
|
|
73
|
+
image: ghcr.io/pleri/olam-auth@sha256:7ad7f92e5feafff3921f3219886a2aec312d83e00c66eaa568e53aac03b19b16
|
|
74
74
|
imagePullPolicy: IfNotPresent
|
|
75
75
|
securityContext:
|
|
76
76
|
runAsNonRoot: true
|
|
@@ -61,7 +61,7 @@ spec:
|
|
|
61
61
|
mountPath: /data
|
|
62
62
|
containers:
|
|
63
63
|
- name: olam-kg-service
|
|
64
|
-
image: ghcr.io/pleri/olam-kg-service@sha256:
|
|
64
|
+
image: ghcr.io/pleri/olam-kg-service@sha256:9c01fd288e136116abfd0e34c7230417a30c5036e411838b88a553c44a802f13
|
|
65
65
|
imagePullPolicy: IfNotPresent
|
|
66
66
|
securityContext:
|
|
67
67
|
runAsNonRoot: true
|
|
@@ -68,7 +68,7 @@ spec:
|
|
|
68
68
|
mountPath: /data
|
|
69
69
|
containers:
|
|
70
70
|
- name: olam-mcp-auth-service
|
|
71
|
-
image: ghcr.io/pleri/olam-mcp-auth@sha256:
|
|
71
|
+
image: ghcr.io/pleri/olam-mcp-auth@sha256:ddd15d5ee0b18ed36a8916c4d8d985182f6e32b57fc2625295f5db19a14b37a0
|
|
72
72
|
imagePullPolicy: IfNotPresent
|
|
73
73
|
securityContext:
|
|
74
74
|
runAsNonRoot: true
|
|
@@ -22,3 +22,14 @@ data:
|
|
|
22
22
|
# AGENTMEMORY_HOST=0.0.0.0 but ConfigMap override is explicit defense against
|
|
23
23
|
# a future image regression reverting to 127.0.0.1.
|
|
24
24
|
AGENTMEMORY_HOST: "0.0.0.0"
|
|
25
|
+
# III_REST_PORT is the env var the agentmemory CLI wrapper reads when it
|
|
26
|
+
# polls its iii subprocess for readiness (cli.mjs:155 — `process.env
|
|
27
|
+
# ["III_REST_PORT"] || "3111"`). The iii engine itself binds the port
|
|
28
|
+
# declared in iii-config.yaml's iii-http worker (overridden via the
|
|
29
|
+
# olam-memory-service-iii-config ConfigMap to 3110, so it does not
|
|
30
|
+
# collide with the metrics-proxy on 3111). Without this env var the
|
|
31
|
+
# wrapper polls 3111 forever, prints "iii-engine did not become ready",
|
|
32
|
+
# and exits — entrypoint propagates the exit, container restarts, and
|
|
33
|
+
# the liveness probe returns 502 from the proxy (its backend was never
|
|
34
|
+
# up). Must equal the iii-http port in 35-configmap-iii-config.yaml.
|
|
35
|
+
III_REST_PORT: "3110"
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# Overrides the iii-config.yaml shipped inside the agentmemory image so the
|
|
2
|
+
# iii engine binds the INTERNAL port (3110) instead of the EXTERNAL port
|
|
3
|
+
# (3111). The shipped yaml hardcodes `port: 3111` and the agentmemory CLI
|
|
4
|
+
# reads its bind from yaml (NOT from the AGENTMEMORY_PORT env var), so
|
|
5
|
+
# entrypoint.sh's `AGENTMEMORY_PORT=3110` override has no effect.
|
|
6
|
+
#
|
|
7
|
+
# Without this override, the engine and the metrics-proxy both try to bind
|
|
8
|
+
# 0.0.0.0:3111. The proxy starts first and wins the port; the engine fails
|
|
9
|
+
# silently. Probes to /agentmemory/livez hit the proxy and get forwarded to
|
|
10
|
+
# 127.0.0.1:3110, where nothing is listening — proxy returns 502, readiness
|
|
11
|
+
# fails, container restarts.
|
|
12
|
+
#
|
|
13
|
+
# Mounted at /usr/local/lib/node_modules/@agentmemory/agentmemory/dist/iii-config.yaml
|
|
14
|
+
# via subPath in 50-deployment.yaml.
|
|
15
|
+
apiVersion: v1
|
|
16
|
+
kind: ConfigMap
|
|
17
|
+
metadata:
|
|
18
|
+
name: olam-memory-service-iii-config
|
|
19
|
+
namespace: olam
|
|
20
|
+
labels:
|
|
21
|
+
app: olam-memory-service
|
|
22
|
+
olam.io/component: peripheral
|
|
23
|
+
data:
|
|
24
|
+
iii-config.yaml: |
|
|
25
|
+
workers:
|
|
26
|
+
- name: iii-http
|
|
27
|
+
config:
|
|
28
|
+
port: 3110
|
|
29
|
+
host: 0.0.0.0
|
|
30
|
+
default_timeout: 180000
|
|
31
|
+
cors:
|
|
32
|
+
allowed_origins: ["http://localhost:3111", "http://localhost:3113", "http://127.0.0.1:3111", "http://127.0.0.1:3113"]
|
|
33
|
+
allowed_methods: [GET, POST, PUT, DELETE, OPTIONS]
|
|
34
|
+
- name: iii-state
|
|
35
|
+
config:
|
|
36
|
+
adapter:
|
|
37
|
+
name: kv
|
|
38
|
+
config:
|
|
39
|
+
store_method: file_based
|
|
40
|
+
file_path: ./data/state_store.db
|
|
41
|
+
- name: iii-queue
|
|
42
|
+
config:
|
|
43
|
+
adapter:
|
|
44
|
+
name: builtin
|
|
45
|
+
- name: iii-pubsub
|
|
46
|
+
config:
|
|
47
|
+
adapter:
|
|
48
|
+
name: local
|
|
49
|
+
- name: iii-cron
|
|
50
|
+
config:
|
|
51
|
+
adapter:
|
|
52
|
+
name: kv
|
|
53
|
+
- name: iii-stream
|
|
54
|
+
config:
|
|
55
|
+
port: 3112
|
|
56
|
+
host: 0.0.0.0
|
|
57
|
+
adapter:
|
|
58
|
+
name: kv
|
|
59
|
+
config:
|
|
60
|
+
store_method: file_based
|
|
61
|
+
file_path: ./data/stream_store
|
|
62
|
+
- name: iii-observability
|
|
63
|
+
config:
|
|
64
|
+
enabled: true
|
|
65
|
+
service_name: agentmemory
|
|
66
|
+
exporter: memory
|
|
67
|
+
sampling_ratio: 1.0
|
|
68
|
+
metrics_enabled: true
|
|
69
|
+
logs_enabled: true
|
|
70
|
+
logs_console_output: true
|
|
71
|
+
- name: iii-exec
|
|
72
|
+
config:
|
|
73
|
+
watch:
|
|
74
|
+
- src/**/*.ts
|
|
75
|
+
exec:
|
|
76
|
+
- node dist/index.mjs
|
|
@@ -70,7 +70,7 @@ spec:
|
|
|
70
70
|
# bootstrap-placeholder comment + run `npm run refresh:manifest-digests`
|
|
71
71
|
# once ghcr.io/pleri/olam-memory-service has a real published digest.
|
|
72
72
|
# bootstrap-placeholder: pre-publish; refresh after first release
|
|
73
|
-
image: ghcr.io/pleri/olam-memory-service@sha256:
|
|
73
|
+
image: ghcr.io/pleri/olam-memory-service@sha256:8dd1593af37b345a9b9b741803355254f1f719d9bf23e56339d9baed8dea9ac1
|
|
74
74
|
imagePullPolicy: IfNotPresent
|
|
75
75
|
securityContext:
|
|
76
76
|
runAsNonRoot: true
|
|
@@ -93,6 +93,13 @@ spec:
|
|
|
93
93
|
mountPath: /data
|
|
94
94
|
- name: tmp
|
|
95
95
|
mountPath: /tmp
|
|
96
|
+
# Overrides the shipped iii-config.yaml so the engine binds the
|
|
97
|
+
# internal port (3110) instead of colliding with the metrics-proxy
|
|
98
|
+
# on 3111. See 35-configmap-iii-config.yaml for full rationale.
|
|
99
|
+
- name: iii-config-override
|
|
100
|
+
mountPath: /usr/local/lib/node_modules/@agentmemory/agentmemory/dist/iii-config.yaml
|
|
101
|
+
subPath: iii-config.yaml
|
|
102
|
+
readOnly: true
|
|
96
103
|
readinessProbe:
|
|
97
104
|
httpGet:
|
|
98
105
|
# D15 (LOAD-BEARING): memory-service health path is /agentmemory/livez.
|
|
@@ -126,3 +133,6 @@ spec:
|
|
|
126
133
|
claimName: olam-memory-data
|
|
127
134
|
- name: tmp
|
|
128
135
|
emptyDir: {}
|
|
136
|
+
- name: iii-config-override
|
|
137
|
+
configMap:
|
|
138
|
+
name: olam-memory-service-iii-config
|
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# grafana-port-forward.sh — e2e smoke test: Grafana installs via Helm,
|
|
3
|
+
# port-forward is accessible, Loki datasource
|
|
4
|
+
# is pre-wired and reachable.
|
|
5
|
+
#
|
|
6
|
+
# Usage: scripts/e2e/grafana-port-forward.sh
|
|
7
|
+
#
|
|
8
|
+
# Pre-conditions:
|
|
9
|
+
# - kubectl context is set to a live k8s cluster (does NOT spin up k3d)
|
|
10
|
+
# - helm binary available
|
|
11
|
+
# - jq binary available
|
|
12
|
+
# - grafana Helm repo added (helm repo add grafana https://grafana.github.io/helm-charts)
|
|
13
|
+
# - Loki is already installed (scripts/e2e/loki-ingest.sh ran successfully
|
|
14
|
+
# OR `helm status olam-loki -n monitoring` is healthy)
|
|
15
|
+
#
|
|
16
|
+
# Idempotency: `helm upgrade --install` is idempotent; re-runs succeed on an
|
|
17
|
+
# existing cluster. The Secret is applied via --dry-run | kubectl apply
|
|
18
|
+
# so re-runs update the password (useful for rotation testing).
|
|
19
|
+
# The olam-dashboards ConfigMap is applied before helm install so
|
|
20
|
+
# Grafana's volume mount finds the ConfigMap on first boot.
|
|
21
|
+
#
|
|
22
|
+
# Cleanup: port-forward is killed on exit; Helm release is left in place so
|
|
23
|
+
# downstream tasks can reuse the same cluster.
|
|
24
|
+
#
|
|
25
|
+
# Refs: docs/plans/k3s-ingress-observability/phase-b-tasks.md — Task B2, B3
|
|
26
|
+
# Chart: grafana/grafana 8.5.2 (pinned; latest stable 2026-05-20)
|
|
27
|
+
|
|
28
|
+
set -euo pipefail
|
|
29
|
+
|
|
30
|
+
NAMESPACE="monitoring"
|
|
31
|
+
GRAFANA_RELEASE="olam-grafana"
|
|
32
|
+
GRAFANA_CHART_VERSION="8.5.2"
|
|
33
|
+
LOCAL_PORT="3000"
|
|
34
|
+
GRAFANA_SVC_PORT="80"
|
|
35
|
+
PF_BIND_SECONDS=5
|
|
36
|
+
|
|
37
|
+
log() { printf '[grafana-port-forward] %s\n' "$*" >&2; }
|
|
38
|
+
fail() { printf '[grafana-port-forward] FAIL: %s\n' "$*" >&2; exit 1; }
|
|
39
|
+
|
|
40
|
+
# -------------------------------------------------------------------------
|
|
41
|
+
# Cleanup trap — kill port-forward on exit; leave Helm release in place
|
|
42
|
+
# -------------------------------------------------------------------------
|
|
43
|
+
PF_PID=""
|
|
44
|
+
cleanup() {
|
|
45
|
+
if [[ -n "$PF_PID" ]] && kill -0 "$PF_PID" 2>/dev/null; then
|
|
46
|
+
kill "$PF_PID" 2>/dev/null || true
|
|
47
|
+
fi
|
|
48
|
+
}
|
|
49
|
+
trap cleanup EXIT
|
|
50
|
+
|
|
51
|
+
# -------------------------------------------------------------------------
|
|
52
|
+
# Pre-flight
|
|
53
|
+
# -------------------------------------------------------------------------
|
|
54
|
+
command -v helm >/dev/null 2>&1 || fail "helm not installed"
|
|
55
|
+
command -v kubectl >/dev/null 2>&1 || fail "kubectl not installed"
|
|
56
|
+
command -v curl >/dev/null 2>&1 || fail "curl not installed"
|
|
57
|
+
command -v openssl >/dev/null 2>&1 || fail "openssl not installed"
|
|
58
|
+
command -v jq >/dev/null 2>&1 || fail "jq not installed (required for B3 dashboard assertion)"
|
|
59
|
+
kubectl cluster-info >/dev/null 2>&1 || fail "kubectl: no reachable cluster; set KUBECONFIG"
|
|
60
|
+
|
|
61
|
+
log "pre-flight checks passed"
|
|
62
|
+
|
|
63
|
+
# -------------------------------------------------------------------------
|
|
64
|
+
# Ensure grafana Helm repo is present (idempotent — safe to re-run)
|
|
65
|
+
# -------------------------------------------------------------------------
|
|
66
|
+
helm repo add grafana https://grafana.github.io/helm-charts 2>/dev/null || true
|
|
67
|
+
helm repo update grafana
|
|
68
|
+
|
|
69
|
+
# Verify Loki is already installed (B2 depends on B1)
|
|
70
|
+
if ! helm status "olam-loki" -n "$NAMESPACE" >/dev/null 2>&1; then
|
|
71
|
+
fail "olam-loki Helm release not found in namespace $NAMESPACE — run scripts/e2e/loki-ingest.sh first"
|
|
72
|
+
fi
|
|
73
|
+
log "Loki pre-condition satisfied (olam-loki release found)"
|
|
74
|
+
|
|
75
|
+
# -------------------------------------------------------------------------
|
|
76
|
+
# Step 1: Resolve admin password (preserve existing on idempotent re-run)
|
|
77
|
+
# -------------------------------------------------------------------------
|
|
78
|
+
# Grafana persists the admin password in its internal SQLite on first
|
|
79
|
+
# deploy. Subsequent helm upgrades do NOT re-read GF_SECURITY_ADMIN_PASSWORD
|
|
80
|
+
# from the env (env value is set once at pod-start and not refreshed). So
|
|
81
|
+
# on a re-run, rotating the Secret leaves the in-Grafana password stale
|
|
82
|
+
# and breaks API auth.
|
|
83
|
+
#
|
|
84
|
+
# Idempotency contract: if the Secret already exists, reuse its current
|
|
85
|
+
# password. The Secret's value matches Grafana's stored value (set in
|
|
86
|
+
# concert on first install). Only generate a new password when the
|
|
87
|
+
# Secret doesn't exist yet — i.e. true first deploy.
|
|
88
|
+
if kubectl get secret olam-grafana-admin -n "$NAMESPACE" >/dev/null 2>&1; then
|
|
89
|
+
log "reusing existing admin password from Secret olam-grafana-admin"
|
|
90
|
+
GRAFANA_ADMIN_PW=$(kubectl get secret olam-grafana-admin -n "$NAMESPACE" \
|
|
91
|
+
-o jsonpath='{.data.admin-password}' | base64 -d)
|
|
92
|
+
else
|
|
93
|
+
log "generating fresh admin password (first deploy)"
|
|
94
|
+
GRAFANA_ADMIN_PW=$(openssl rand -base64 24)
|
|
95
|
+
fi
|
|
96
|
+
export GRAFANA_ADMIN_PW
|
|
97
|
+
|
|
98
|
+
# -------------------------------------------------------------------------
|
|
99
|
+
# Step 2: Create / update the admin Secret idempotently
|
|
100
|
+
# -------------------------------------------------------------------------
|
|
101
|
+
log "applying Secret olam-grafana-admin in namespace $NAMESPACE"
|
|
102
|
+
kubectl create secret generic olam-grafana-admin \
|
|
103
|
+
--from-literal=admin-user=admin \
|
|
104
|
+
--from-literal=admin-password="$GRAFANA_ADMIN_PW" \
|
|
105
|
+
-n "$NAMESPACE" \
|
|
106
|
+
--dry-run=client -o yaml \
|
|
107
|
+
| kubectl apply -f -
|
|
108
|
+
|
|
109
|
+
log "Secret applied"
|
|
110
|
+
|
|
111
|
+
# -------------------------------------------------------------------------
|
|
112
|
+
# Step 3a: Apply olam-dashboards ConfigMap BEFORE helm install
|
|
113
|
+
# so Grafana's volume mount finds it on first boot (B3).
|
|
114
|
+
# The ConfigMap is generated from grafana-dashboards/*.json by
|
|
115
|
+
# packages/peripheral-services/scripts/sync-grafana-dashboards.sh.
|
|
116
|
+
# -------------------------------------------------------------------------
|
|
117
|
+
REPO_ROOT="$(git -C "$(dirname "$0")" rev-parse --show-toplevel 2>/dev/null || pwd)"
|
|
118
|
+
CONFIGMAP_MANIFEST="$REPO_ROOT/packages/peripheral-services/manifests/80-grafana-dashboard-configmap.yaml"
|
|
119
|
+
|
|
120
|
+
if [[ -f "$CONFIGMAP_MANIFEST" ]]; then
|
|
121
|
+
log "applying olam-dashboards ConfigMap from $CONFIGMAP_MANIFEST"
|
|
122
|
+
kubectl apply -f "$CONFIGMAP_MANIFEST"
|
|
123
|
+
log "ConfigMap applied"
|
|
124
|
+
else
|
|
125
|
+
log "WARN: $CONFIGMAP_MANIFEST not found — Grafana will warn 'ConfigMap not found' until B3 is deployed"
|
|
126
|
+
fi
|
|
127
|
+
|
|
128
|
+
# -------------------------------------------------------------------------
|
|
129
|
+
# Step 3: Helm upgrade --install
|
|
130
|
+
# -------------------------------------------------------------------------
|
|
131
|
+
log "installing grafana/grafana ($GRAFANA_RELEASE) in namespace $NAMESPACE"
|
|
132
|
+
helm upgrade --install "$GRAFANA_RELEASE" grafana/grafana \
|
|
133
|
+
--version "$GRAFANA_CHART_VERSION" \
|
|
134
|
+
--namespace "$NAMESPACE" \
|
|
135
|
+
--create-namespace \
|
|
136
|
+
-f "$REPO_ROOT/packages/peripheral-services/helm-values/grafana-values.yaml" \
|
|
137
|
+
--wait \
|
|
138
|
+
--timeout 300s
|
|
139
|
+
|
|
140
|
+
log "Grafana Helm install complete"
|
|
141
|
+
|
|
142
|
+
# -------------------------------------------------------------------------
|
|
143
|
+
# Step 4: Wait for Grafana pod Ready
|
|
144
|
+
# -------------------------------------------------------------------------
|
|
145
|
+
log "waiting for Grafana pod Ready (120s)"
|
|
146
|
+
kubectl wait \
|
|
147
|
+
--for=condition=ready pod \
|
|
148
|
+
-l "app.kubernetes.io/name=grafana" \
|
|
149
|
+
-n "$NAMESPACE" \
|
|
150
|
+
--timeout=120s
|
|
151
|
+
|
|
152
|
+
log "Grafana pod Ready"
|
|
153
|
+
|
|
154
|
+
# -------------------------------------------------------------------------
|
|
155
|
+
# Step 5: Start port-forward in background
|
|
156
|
+
# -------------------------------------------------------------------------
|
|
157
|
+
log "port-forwarding svc/$GRAFANA_RELEASE $LOCAL_PORT:$GRAFANA_SVC_PORT in namespace $NAMESPACE"
|
|
158
|
+
kubectl port-forward \
|
|
159
|
+
-n "$NAMESPACE" \
|
|
160
|
+
"svc/$GRAFANA_RELEASE" \
|
|
161
|
+
"${LOCAL_PORT}:${GRAFANA_SVC_PORT}" &
|
|
162
|
+
PF_PID=$!
|
|
163
|
+
|
|
164
|
+
log "port-forward PID $PF_PID; waiting ${PF_BIND_SECONDS}s for bind"
|
|
165
|
+
sleep "$PF_BIND_SECONDS"
|
|
166
|
+
|
|
167
|
+
# Verify the port-forward process is still alive after sleep
|
|
168
|
+
kill -0 "$PF_PID" 2>/dev/null || fail "port-forward process exited prematurely"
|
|
169
|
+
|
|
170
|
+
# -------------------------------------------------------------------------
|
|
171
|
+
# Diagnostic helper — called on assertion failure
|
|
172
|
+
# -------------------------------------------------------------------------
|
|
173
|
+
dump_diagnostics() {
|
|
174
|
+
log "DIAGNOSTIC: last 50 lines of Grafana pod logs:"
|
|
175
|
+
kubectl logs -n "$NAMESPACE" \
|
|
176
|
+
-l "app.kubernetes.io/name=grafana" \
|
|
177
|
+
--tail=50 2>&1 >&2 || true
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
# -------------------------------------------------------------------------
|
|
181
|
+
# Step 6: Assertion 1 — /api/health returns 200 with database: ok
|
|
182
|
+
# -------------------------------------------------------------------------
|
|
183
|
+
log "asserting Grafana health (GET /api/health)"
|
|
184
|
+
HEALTH_RESPONSE=$(
|
|
185
|
+
curl -sf \
|
|
186
|
+
-u "admin:${GRAFANA_ADMIN_PW}" \
|
|
187
|
+
"http://localhost:${LOCAL_PORT}/api/health" \
|
|
188
|
+
|| { dump_diagnostics; fail "GET /api/health failed — Grafana not reachable on port $LOCAL_PORT"; }
|
|
189
|
+
)
|
|
190
|
+
|
|
191
|
+
if ! echo "$HEALTH_RESPONSE" | jq -e '.database == "ok"' >/dev/null 2>&1; then
|
|
192
|
+
log "DIAGNOSTIC: /api/health response:"
|
|
193
|
+
echo "$HEALTH_RESPONSE" >&2
|
|
194
|
+
dump_diagnostics
|
|
195
|
+
fail '/api/health returned database != "ok" — Grafana DB layer not healthy'
|
|
196
|
+
fi
|
|
197
|
+
|
|
198
|
+
log "PASS: /api/health → database: ok"
|
|
199
|
+
|
|
200
|
+
# -------------------------------------------------------------------------
|
|
201
|
+
# Step 7: Assertion 2 — /api/datasources includes Loki entry with cluster URL
|
|
202
|
+
# -------------------------------------------------------------------------
|
|
203
|
+
log "asserting Loki datasource pre-wired (GET /api/datasources)"
|
|
204
|
+
DS_RESPONSE=$(
|
|
205
|
+
curl -sf \
|
|
206
|
+
-u "admin:${GRAFANA_ADMIN_PW}" \
|
|
207
|
+
"http://localhost:${LOCAL_PORT}/api/datasources" \
|
|
208
|
+
|| { dump_diagnostics; fail "GET /api/datasources failed"; }
|
|
209
|
+
)
|
|
210
|
+
|
|
211
|
+
EXPECTED_URL="olam-loki.monitoring.svc.cluster.local:3100"
|
|
212
|
+
|
|
213
|
+
if ! echo "$DS_RESPONSE" | jq -e 'map(select(.type == "loki")) | length >= 1' >/dev/null 2>&1; then
|
|
214
|
+
log "DIAGNOSTIC: /api/datasources response:"
|
|
215
|
+
echo "$DS_RESPONSE" >&2
|
|
216
|
+
dump_diagnostics
|
|
217
|
+
fail "datasources response contains no 'loki' type entry — datasource not provisioned"
|
|
218
|
+
fi
|
|
219
|
+
|
|
220
|
+
if ! echo "$DS_RESPONSE" | jq -e --arg url "$EXPECTED_URL" 'map(select(.type == "loki" and (.url | contains($url)))) | length >= 1' >/dev/null 2>&1; then
|
|
221
|
+
log "DIAGNOSTIC: /api/datasources response:"
|
|
222
|
+
echo "$DS_RESPONSE" >&2
|
|
223
|
+
dump_diagnostics
|
|
224
|
+
fail "Loki datasource URL does not contain '$EXPECTED_URL' — check grafana-values.yaml datasources block"
|
|
225
|
+
fi
|
|
226
|
+
|
|
227
|
+
log "PASS: Loki datasource found with cluster-local URL $EXPECTED_URL"
|
|
228
|
+
|
|
229
|
+
# -------------------------------------------------------------------------
|
|
230
|
+
# Step 7b: Assertion 2b — dashboard provider loaded olam-home (catches mount-path bugs)
|
|
231
|
+
# -------------------------------------------------------------------------
|
|
232
|
+
log "asserting olam-home dashboard visible in /api/search (catches ConfigMap mount failures)"
|
|
233
|
+
DASHBOARDS=$(
|
|
234
|
+
curl -sf \
|
|
235
|
+
-u "admin:${GRAFANA_ADMIN_PW}" \
|
|
236
|
+
"http://localhost:${LOCAL_PORT}/api/search?type=dash-db&query=olam" \
|
|
237
|
+
|| true
|
|
238
|
+
)
|
|
239
|
+
|
|
240
|
+
if ! echo "$DASHBOARDS" | jq -e 'map(select(.uid == "olam-home")) | length == 1' >/dev/null 2>&1; then
|
|
241
|
+
log "DIAGNOSTIC: /api/search response:"
|
|
242
|
+
echo "$DASHBOARDS" >&2
|
|
243
|
+
dump_diagnostics
|
|
244
|
+
fail "olam-home dashboard not found in /api/search — check ConfigMap mount path and dashboard provider config"
|
|
245
|
+
fi
|
|
246
|
+
|
|
247
|
+
log "PASS: olam-home dashboard found via /api/search"
|
|
248
|
+
|
|
249
|
+
# -------------------------------------------------------------------------
|
|
250
|
+
# Step 8: Assertion 3 — olam-home dashboard present (B3)
|
|
251
|
+
# -------------------------------------------------------------------------
|
|
252
|
+
log "asserting olam-home dashboard present (GET /api/dashboards/uid/olam-home)"
|
|
253
|
+
DASHBOARD_RESPONSE=$(
|
|
254
|
+
curl -sf \
|
|
255
|
+
-u "admin:${GRAFANA_ADMIN_PW}" \
|
|
256
|
+
"http://localhost:${LOCAL_PORT}/api/dashboards/uid/olam-home" \
|
|
257
|
+
|| { dump_diagnostics; fail "GET /api/dashboards/uid/olam-home failed — dashboard not found or Grafana unreachable"; }
|
|
258
|
+
)
|
|
259
|
+
|
|
260
|
+
if ! echo "$DASHBOARD_RESPONSE" | jq -e '.dashboard.uid == "olam-home"' >/dev/null 2>&1; then
|
|
261
|
+
log "DIAGNOSTIC: /api/dashboards/uid/olam-home response:"
|
|
262
|
+
echo "$DASHBOARD_RESPONSE" >&2
|
|
263
|
+
dump_diagnostics
|
|
264
|
+
fail "olam-home dashboard uid mismatch or missing — check ConfigMap provisioning and Grafana provider config"
|
|
265
|
+
fi
|
|
266
|
+
|
|
267
|
+
log "PASS: olam-home dashboard present with uid=olam-home"
|
|
268
|
+
|
|
269
|
+
# -------------------------------------------------------------------------
|
|
270
|
+
# Final
|
|
271
|
+
# -------------------------------------------------------------------------
|
|
272
|
+
log "PASS: Grafana port-forward accessible; Loki datasource pre-wired; olam-home dashboard provisioned — Tasks B2+B3 verified"
|
|
273
|
+
exit 0
|