Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion apps/dashboard/vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import react from '@vitejs/plugin-react'
export default defineConfig({
plugins: [react()],
server: {
port: 5174,
port: 5173,
strictPort: true,
},
})
12 changes: 7 additions & 5 deletions argocd/app-of-apps.yaml
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
# Root Application — manages all child Applications via App-of-Apps pattern
# Legacy app-of-apps pointing to argocd/environments.
# The canonical root Application is k8s/argocd/app-of-apps.yaml (name: grainguard-apps).
# This file uses a distinct name to avoid last-write-wins identity collision.
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: grainguard-apps
name: grainguard-apps-legacy
namespace: argocd
# Cascade delete: removing this app also removes all children
finalizers:
- resources-finalizer.argocd.argoproj.io
spec:
project: default
project: grainguard
source:
repoURL: https://github.com/your-org/grainguard
repoURL: https://github.com/pahuldeepp/GrainGuard-.git
Comment thread
coderabbitai[bot] marked this conversation as resolved.
targetRevision: HEAD
path: argocd/environments # folder containing per-env Application manifests
destination:
Expand All @@ -21,4 +23,4 @@ spec:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
- CreateNamespace=true
10 changes: 5 additions & 5 deletions argocd/environments/dev.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,15 @@ metadata:
finalizers:
- resources-finalizer.argocd.argoproj.io
spec:
project: default
project: grainguard
source:
repoURL: https://github.com/your-org/grainguard
repoURL: https://github.com/pahuldeepp/GrainGuard-.git
targetRevision: HEAD
path: helm/grainguard
path: k8s/helm/grainguard
helm:
valueFiles:
- values.yaml
- values.dev.yaml
- values-dev.yaml
# Override image tags per deploy — CI will patch this
parameters:
- name: gateway.image.tag
Expand All @@ -31,4 +31,4 @@ spec:
syncOptions:
- CreateNamespace=true
- ServerSideApply=true
revisionHistoryLimit: 3
revisionHistoryLimit: 3
8 changes: 4 additions & 4 deletions argocd/environments/prod.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,15 @@ metadata:
finalizers:
- resources-finalizer.argocd.argoproj.io
spec:
project: default
project: grainguard
source:
repoURL: https://github.com/your-org/grainguard
repoURL: https://github.com/pahuldeepp/GrainGuard-.git
targetRevision: HEAD
path: helm/grainguard
path: k8s/helm/grainguard
helm:
valueFiles:
- values.yaml
- values.prod.yaml
- values-prod.yaml
parameters:
- name: gateway.image.tag
value: "latest"
Expand Down
4 changes: 2 additions & 2 deletions argocd/project.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ metadata:
spec:
description: GrainGuard platform project
sourceRepos:
- https://github.com/your-org/grainguard
- https://github.com/pahuldeepp/GrainGuard-.git
destinations:
- namespace: grainguard-dev
server: https://kubernetes.default.svc
Expand All @@ -30,4 +30,4 @@ spec:
description: Can sync prod (humans only, not CI)
policies:
- p, proj:grainguard:prod-deployer, applications, sync, grainguard/grainguard-prod, allow
- p, proj:grainguard:prod-deployer, applications, get, grainguard/grainguard-prod, allow
- p, proj:grainguard:prod-deployer, applications, get, grainguard/grainguard-prod, allow
114 changes: 114 additions & 0 deletions docs/runbooks/postgres-backup-restore.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
# Runbook: Postgres Backup and Restore

**Purpose:** Capture and restore both the write-model and read-model Postgres databases for local drills and operator validation.
**Service affected:** telemetry-service, saga-orchestrator, bff, read-model-builder, asset-registry

---

## Scope

This runbook matches the local Docker stack:

- write DB container: `grainguard-postgres`
- read DB container: `grainguard-postgres-read`
- scripts:
- [`backup-postgres.sh`](infra/scripts/backup-postgres.sh)
- [`restore-postgres.sh`](infra/scripts/restore-postgres.sh)

These scripts create custom-format dumps for:

- `grainguard`
- `grainguard_read`

---

## Backup

```bash
./infra/scripts/backup-postgres.sh
Comment thread
coderabbitai[bot] marked this conversation as resolved.
```

Optional custom target:

```bash
BACKUP_ROOT=/tmp/grainguard-backups ./infra/scripts/backup-postgres.sh
```

Expected output:

- `infra/backups/postgres/<timestamp>/grainguard.dump`
- `infra/backups/postgres/<timestamp>/grainguard_read.dump`
- `infra/backups/postgres/<timestamp>/metadata.env`

---

## Verify backup

```bash
ls -lh infra/backups/postgres/<timestamp>
```

Optional quick integrity check:

```bash
docker exec -i grainguard-postgres pg_restore -l < infra/backups/postgres/<timestamp>/grainguard.dump | head
docker exec -i grainguard-postgres-read pg_restore -l < infra/backups/postgres/<timestamp>/grainguard_read.dump | head
```

---

## Restore

Warning: this is destructive. The target database is dropped and recreated before restore.

Restore both databases:

```bash
./infra/scripts/restore-postgres.sh infra/backups/postgres/<timestamp>
```

Restore only the write DB:

```bash
./infra/scripts/restore-postgres.sh infra/backups/postgres/<timestamp> write
```

Restore only the read DB:

```bash
./infra/scripts/restore-postgres.sh infra/backups/postgres/<timestamp> read
```

---

## Verify recovery

```bash
docker exec grainguard-postgres psql -U postgres -d grainguard -c '\dt'
docker exec grainguard-postgres-read psql -U postgres -d grainguard_read -c '\dt'
curl -fsS http://localhost:8086/health
curl -fsS http://localhost:4000/graphql -H 'content-type: application/json' -d '{"query":"{ __typename }"}'
```

Check application logs if a service still has stale connections:

```bash
docker logs --tail 100 grainguard-gateway
docker logs --tail 100 grainguard-bff
docker logs --tail 100 grainguard-telemetry
```

If needed, restart readers and API services:

```bash
docker compose -f infra/docker/docker-compose.yml restart gateway bff telemetry-service read-model-builder saga-orchestrator
```

---

## Escalate if

- `pg_restore` reports schema corruption
- backup files cannot be listed by `pg_restore -l`
- write DB restores successfully but read projections remain empty after service restart
- WAL/replication behavior is required rather than simple logical dump restore
93 changes: 93 additions & 0 deletions docs/runbooks/redis-backup-restore.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
# Runbook: Redis Backup and Restore

**Purpose:** Capture and restore the standalone Redis instance used by the local Docker stack for cache and lock validation drills.
**Service affected:** bff, saga-orchestrator, jobs-worker, workflow-alerts

---

## Scope

This runbook targets the standalone Redis container in local Docker:

- redis container: `grainguard-redis`
- scripts:
- [`backup-redis.sh`](infra/scripts/backup-redis.sh)
- [`restore-redis.sh`](infra/scripts/restore-redis.sh)
Comment on lines +13 to +15

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Markdown links won't resolve correctly.

Same issue as the Postgres runbook—since this file is at docs/runbooks/redis-backup-restore.md, these links need to traverse up to the repo root.

📝 Proposed fix
 - scripts:
-  - [`backup-redis.sh`](infra/scripts/backup-redis.sh)
-  - [`restore-redis.sh`](infra/scripts/restore-redis.sh)
+  - [`backup-redis.sh`](../../infra/scripts/backup-redis.sh)
+  - [`restore-redis.sh`](../../infra/scripts/restore-redis.sh)
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
- scripts:
- [`backup-redis.sh`](infra/scripts/backup-redis.sh)
- [`restore-redis.sh`](infra/scripts/restore-redis.sh)
- scripts:
- [`backup-redis.sh`](../../infra/scripts/backup-redis.sh)
- [`restore-redis.sh`](../../infra/scripts/restore-redis.sh)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/runbooks/redis-backup-restore.md` around lines 13 - 15, Update the
markdown links for the script references so they resolve from docs/runbooks to
the repository root: replace the current relative links for `backup-redis.sh`
and `restore-redis.sh` with links that traverse up two levels (e.g.,
`../../infra/scripts/backup-redis.sh` and
`../../infra/scripts/restore-redis.sh`) so the `backup-redis.sh` and
`restore-redis.sh` links point to the correct files.


It does **not** back up the six-node Redis cluster used for cluster-mode experiments.

---

## Backup

```bash
./infra/scripts/backup-redis.sh
```

Optional custom target:

```bash
BACKUP_ROOT=/tmp/grainguard-backups ./infra/scripts/backup-redis.sh
```

Expected output:

- `infra/backups/redis/<timestamp>/dump.rdb`
- `infra/backups/redis/<timestamp>/metadata.env`

---

## Verify backup

```bash
ls -lh infra/backups/redis/<timestamp>
```

Sanity check Redis before restore work:

```bash
docker exec grainguard-redis redis-cli PING
docker exec grainguard-redis redis-cli DBSIZE
```

---

## Restore

Warning: this restarts the Redis container and can evict hot cache state and distributed locks.

```bash
./infra/scripts/restore-redis.sh infra/backups/redis/<timestamp>
```

---

## Verify recovery

```bash
docker exec grainguard-redis redis-cli PING
docker exec grainguard-redis redis-cli DBSIZE
docker logs --tail 100 grainguard-bff
docker logs --tail 100 grainguard-saga-orchestrator
```

Optional application check:

```bash
curl -fsS http://localhost:8086/health
```

If application logs still show stale lock/cache issues, restart the consumers:

```bash
docker compose -f infra/docker/docker-compose.yml restart bff saga-orchestrator jobs-worker workflow-alerts
```

---

## Escalate if

- Redis fails to start after replacing `dump.rdb`
- `PING` fails after restore
- cache recovers but saga lock keys remain permanently stale
- you need Redis Cluster restore, not standalone Redis restore
12 changes: 6 additions & 6 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ require (
github.com/testcontainers/testcontainers-go v0.41.0
github.com/testcontainers/testcontainers-go/modules/postgres v0.41.0
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.65.0
go.opentelemetry.io/otel v1.41.0
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.41.0
go.opentelemetry.io/otel/sdk v1.41.0
go.opentelemetry.io/otel v1.42.0
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.42.0
go.opentelemetry.io/otel/sdk v1.42.0
google.golang.org/grpc v1.79.3
google.golang.org/protobuf v1.36.11
)
Expand Down Expand Up @@ -85,9 +85,9 @@ require (
github.com/yusufpapurcu/wmi v1.2.4 // indirect
go.opentelemetry.io/auto/sdk v1.2.1 // indirect
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.41.0 // indirect
go.opentelemetry.io/otel/metric v1.41.0 // indirect
go.opentelemetry.io/otel/trace v1.41.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.42.0 // indirect
go.opentelemetry.io/otel/metric v1.42.0 // indirect
go.opentelemetry.io/otel/trace v1.42.0 // indirect
go.opentelemetry.io/proto/otlp v1.9.0 // indirect
golang.org/x/crypto v0.49.0 // indirect
golang.org/x/net v0.52.0 // indirect
Expand Down
28 changes: 14 additions & 14 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -199,22 +199,22 @@ go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.6
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.65.0/go.mod h1:KDgtbWKTQs4bM+VPUr6WlL9m/WXcmkCcBlIzqxPGzmI=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 h1:F7Jx+6hwnZ41NSFTO5q4LYDtJRXBf2PD0rNBkeB/lus=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0/go.mod h1:UHB22Z8QsdRDrnAtX4PntOl36ajSxcdUMt1sF7Y6E7Q=
go.opentelemetry.io/otel v1.41.0 h1:YlEwVsGAlCvczDILpUXpIpPSL/VPugt7zHThEMLce1c=
go.opentelemetry.io/otel v1.41.0/go.mod h1:Yt4UwgEKeT05QbLwbyHXEwhnjxNO6D8L5PQP51/46dE=
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.41.0 h1:ao6Oe+wSebTlQ1OEht7jlYTzQKE+pnx/iNywFvTbuuI=
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.41.0/go.mod h1:u3T6vz0gh/NVzgDgiwkgLxpsSF6PaPmo2il0apGJbls=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.41.0 h1:mq/Qcf28TWz719lE3/hMB4KkyDuLJIvgJnFGcd0kEUI=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.41.0/go.mod h1:yk5LXEYhsL2htyDNJbEq7fWzNEigeEdV5xBF/Y+kAv0=
go.opentelemetry.io/otel v1.42.0 h1:lSQGzTgVR3+sgJDAU/7/ZMjN9Z+vUip7leaqBKy4sho=
go.opentelemetry.io/otel v1.42.0/go.mod h1:lJNsdRMxCUIWuMlVJWzecSMuNjE7dOYyWlqOXWkdqCc=
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.42.0 h1:THuZiwpQZuHPul65w4WcwEnkX2QIuMT+UFoOrygtoJw=
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.42.0/go.mod h1:J2pvYM5NGHofZ2/Ru6zw/TNWnEQp5crgyDeSrYpXkAw=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.42.0 h1:zWWrB1U6nqhS/k6zYB74CjRpuiitRtLLi68VcgmOEto=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.42.0/go.mod h1:2qXPNBX1OVRC0IwOnfo1ljoid+RD0QK3443EaqVlsOU=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.41.0 h1:inYW9ZhgqiDqh6BioM7DVHHzEGVq76Db5897WLGZ5Go=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.41.0/go.mod h1:Izur+Wt8gClgMJqO/cZ8wdeeMryJ/xxiOVgFSSfpDTY=
go.opentelemetry.io/otel/metric v1.41.0 h1:rFnDcs4gRzBcsO9tS8LCpgR0dxg4aaxWlJxCno7JlTQ=
go.opentelemetry.io/otel/metric v1.41.0/go.mod h1:xPvCwd9pU0VN8tPZYzDZV/BMj9CM9vs00GuBjeKhJps=
go.opentelemetry.io/otel/sdk v1.41.0 h1:YPIEXKmiAwkGl3Gu1huk1aYWwtpRLeskpV+wPisxBp8=
go.opentelemetry.io/otel/sdk v1.41.0/go.mod h1:ahFdU0G5y8IxglBf0QBJXgSe7agzjE4GiTJ6HT9ud90=
go.opentelemetry.io/otel/sdk/metric v1.41.0 h1:siZQIYBAUd1rlIWQT2uCxWJxcCO7q3TriaMlf08rXw8=
go.opentelemetry.io/otel/sdk/metric v1.41.0/go.mod h1:HNBuSvT7ROaGtGI50ArdRLUnvRTRGniSUZbxiWxSO8Y=
go.opentelemetry.io/otel/trace v1.41.0 h1:Vbk2co6bhj8L59ZJ6/xFTskY+tGAbOnCtQGVVa9TIN0=
go.opentelemetry.io/otel/trace v1.41.0/go.mod h1:U1NU4ULCoxeDKc09yCWdWe+3QoyweJcISEVa1RBzOis=
go.opentelemetry.io/otel/metric v1.42.0 h1:2jXG+3oZLNXEPfNmnpxKDeZsFI5o4J+nz6xUlaFdF/4=
go.opentelemetry.io/otel/metric v1.42.0/go.mod h1:RlUN/7vTU7Ao/diDkEpQpnz3/92J9ko05BIwxYa2SSI=
go.opentelemetry.io/otel/sdk v1.42.0 h1:LyC8+jqk6UJwdrI/8VydAq/hvkFKNHZVIWuslJXYsDo=
go.opentelemetry.io/otel/sdk v1.42.0/go.mod h1:rGHCAxd9DAph0joO4W6OPwxjNTYWghRWmkHuGbayMts=
go.opentelemetry.io/otel/sdk/metric v1.42.0 h1:D/1QR46Clz6ajyZ3G8SgNlTJKBdGp84q9RKCAZ3YGuA=
go.opentelemetry.io/otel/sdk/metric v1.42.0/go.mod h1:Ua6AAlDKdZ7tdvaQKfSmnFTdHx37+J4ba8MwVCYM5hc=
go.opentelemetry.io/otel/trace v1.42.0 h1:OUCgIPt+mzOnaUTpOQcBiM/PLQ/Op7oq6g4LenLmOYY=
go.opentelemetry.io/otel/trace v1.42.0/go.mod h1:f3K9S+IFqnumBkKhRJMeaZeNk9epyhnCmQh/EysQCdc=
go.opentelemetry.io/proto/otlp v1.9.0 h1:l706jCMITVouPOqEnii2fIAuO3IVGBRPV5ICjceRb/A=
go.opentelemetry.io/proto/otlp v1.9.0/go.mod h1:xE+Cx5E/eEHw+ISFkwPLwCZefwVjY+pqKg1qcK03+/4=
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
Expand Down
1 change: 1 addition & 0 deletions infra/docker/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -657,6 +657,7 @@ services:
ports:
- "4317:4317"
- "4318:4318"
- "127.0.0.1:13133:13133"
depends_on:
- tempo
networks:
Expand Down
Loading
Loading