Commit Graph
59 Commits
Author SHA1 Message Date
rock 36557148c1 test: trigger CI again
build / build-push (push) Failing after 17s
ci / test (push) Failing after 1m43s
2026-08-29 22:47:17 -07:00
rock 59db74dd59 fix: use GITHUB_TOKEN (Forgejo auto-injected secret)
ci / test (push) Canceled after 0s
build / build-push (push) Failing after 18s
2026-08-29 22:47:16 -07:00
rock 7aaf30843e test: trigger CI with FORGEJO_TOKEN
build / build-push (push) Failing after 17s
ci / test (push) Failing after 1m31s
2026-08-29 22:44:49 -07:00
rock 62c3f8a1f7 fix: use FORGEJO_TOKEN instead of REGISTRY_PAT for git auth
ci / test (push) Canceled after 0s
build / build-push (push) Failing after 19s
Forgejo auto-injects GITHUB_TOKEN secret. Use FORGEJO_TOKEN env var
for clarity since we're retiring GitHub.
2026-08-29 22:44:45 -07:00
rock 41bf810de9 test: trigger CI with proper git auth secret
build / build-push (push) Failing after 14s
ci / test (push) Failing after 1m3s
2026-08-28 16:45:35 -07:00
rock 329002fa9b fix: use consistent secret name for git auth in CI workflows
ci / test (push) Canceled after 0s
build / build-push (push) Failing after 17s
2026-08-28 16:45:26 -07:00
rock 454f72ebfe test: trigger CI with Go 1.26 runner
build / build-push (push) Failing after 3m40s
ci / test (push) Failing after 3m6s
2026-08-28 16:35:39 -07:00
rock eabf8d7459 fix: use golang runner label instead of deprecated docker label
build / build-push (push) Failing after 3m57s
ci / test (push) Failing after 15m57s
2026-08-28 15:36:24 -07:00
rock 6193d9a065 fix: sync ArgoCD apps to main branch for auto-rollout
ci / test (push) Canceled after 0s
build / build-push (push) Canceled after 0s
- Update kmsvc-root (root.yaml) targetRevision: prod → main
- Update management-service app targetRevision: prod → main
- Build workflow already pushes images on main commits
- Homelab ArgoCD app (60-kmsvc-manage.yaml) watches main with auto-sync enabled
- image.pullPolicy: Always + tag: latest ensures fresh images on rollouts
2026-08-28 14:54:01 -07:00
rock f3a7e5aa9a fix: update Go version in CI from 1.25 to 1.26
ci / test (push) Canceled after 0s
build / build-push (push) Canceled after 0s
2026-08-28 14:51:51 -07:00
Story Crater Bot e9e925b04a test(ci): verify main-branch CI trigger
build / build-push (push) Canceled after 0s
ci / test (push) Canceled after 0s
2026-08-21 21:07:42 -07:00
Story Crater Bot c0803f6243 test(ci): trigger build on main
ci / test (push) Canceled after 0s
build / build-push (push) Canceled after 0s
2026-08-21 21:05:11 -07:00
Story Crater Bot fe2d4de8bf ci(main): trigger image builds on main branch commits
ci / test (push) Canceled after 0s
build / build-push (push) Canceled after 0s
2026-08-21 20:55:32 -07:00
Story Crater Bot e95256daf5 test(ci): verify REGISTRY_PAT secret works
build-prod / build-push (push) Canceled after 0s
2026-08-21 20:52:44 -07:00
Story Crater Bot 7f595b51f2 fix(ci): use universal REGISTRY_PAT secret for Forgejo registry auth
build-prod / build-push (push) Canceled after 0s
2026-08-21 20:52:37 -07:00
Story Crater Bot 8e7abf411d test(ci): trigger prod build and ArgoCD sync
build-prod / build-push (push) Canceled after 0s
2026-08-21 20:48:27 -07:00
Story Crater Bot 58efc45bf4 ci(prod): update image build workflow to push to Forgejo registry with commit SHA
build-prod / build-push (push) Canceled after 0s
2026-08-21 20:44:16 -07:00
Story Crater Bot 8f0e97dacf ci(prod): add image build workflow for prod deployments
build-prod / build-push (push) Canceled after 0s
2026-08-21 20:36:17 -07:00
Story Crater Bot 7dca7da51d fix(argocd): update apps and root to track prod branch, fix domain and namespaces 2026-08-21 20:36:06 -07:00
Story Crater Bot 3d52eab41d fix(ci,deps): migrate to .gitea/workflows, update domain to forgejo.riotpiao.com/rock, fix k8s argocd config
ci / test (push) Canceled after 0s
2026-08-21 20:14:58 -07:00
Story Crater Bot 370b5a894f (chore) add worker queue
build-push / build-push (push) Canceled after 0s
2026-08-17 12:17:39 -07:00
Story Crater BotandClaude Sonnet 5 3e81b4454d fix: grant queue-operator create/delete RBAC on TemporalWorker and Deployment
Deployed ClusterRole only had get/list/watch/update/patch on temporalworkers,
missing create/delete needed by reconcileTemporalWorker's cross-namespace
(sqs -> temporal) CreateOrUpdate call, and never granted apps/deployments at
all -- both required for the auto-provisioned TemporalWorker + backing
Deployment to reconcile successfully.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-08-17 09:33:16 -07:00
Story Crater Bot f599d2d897 fix: drop dead Authentik env-var validation now that auth interceptors are unwired 2026-07-13 16:45:53 -07:00
Story Crater Bot 52b86ab8e8 feat: queue-operator auto-registers Temporal namespace before creating TemporalWorker
A Queue's temporal.io/namespace label was trusted as-is -- if the referenced
Temporal namespace was never registered (or typo'd), the failure only
surfaced as a worker pod silently polling a namespace that doesn't exist.
Now reconcileTemporalWorker calls RegisterNamespace (idempotent, ignores
AlreadyExists) via a direct WorkflowService gRPC client before creating the
TemporalWorker, so namespace and worker always come into existence together.

Also grant queue-operator's ClusterRole create/delete on temporalworkers
(previously missing, causing forbidden errors on the create-then-delete path).
2026-07-13 13:02:40 -07:00
Story Crater Bot a584fb4462 fix: don't set cross-namespace owner ref on TemporalWorker
Queue lives in the sqs namespace while its TemporalWorker is created
in the Temporal namespace (KMSVC_TEMPORAL_NAMESPACE), so
SetControllerReference always failed with "cross-namespace owner
references are disallowed". Drop the owner ref (lifecycle already
handled explicitly in reconcileDelete) and move Spec population into
the CreateOrUpdate mutate closure so updates to an existing
TemporalWorker actually stick.

Also commit the generated TemporalWorker CRD and RBAC rules
(temporalworkers, deployments) that were previously untracked.
2026-07-13 11:32:04 -07:00
Story Crater Bot a8060444c1 feat: disable OIDC/JWT auth interceptors on gRPC+REST server
Server was crash-looping on TLS trust failures fetching Authentik's OIDC
discovery document (private-CA cert not trusted by the container image).
Drop the auth wiring for now to unblock the deployment; internal/auth and
internal/api/interceptors packages are left intact for when auth comes back.
2026-07-13 10:57:28 -07:00
Story Crater Bot b4cb3a7255 feat: build queue-operator binary alongside kmsvc-server in same image 2026-07-13 10:24:58 -07:00
Story Crater Bot 2f99f8d3d6 fix: cross-compile natively via BUILDPLATFORM/TARGETARCH instead of QEMU-emulating go build 2026-07-13 10:20:14 -07:00
Story Crater Bot 9c01076092 feat: switch to public GitHub kmsvc-proto dependency and GHCR image builds
Forgejo registry unreachable from cluster nodes (WireGuard overlay vs LAN
network isolation, plus host-to-ClusterIP routing gaps). Move to public
GitHub dependency and GHCR image hosting to remove the private-network
dependency entirely.
2026-07-13 10:09:41 -07:00
Story Crater Bot c354876178 test: add comprehensive TemporalWorker tests
Queue reconciliation:
- TemporalWorker creation when label present
- Namespace label validation
- Kubernetes name validation
- Cleanup on Queue deletion

Validation helpers:
- isValidTemporalNamespace (8 cases)
- validateKubernetesName (9 cases)

TemporalWorker controller:
- Deployment creation and updates
- Env var injection including TEMPORAL_TASK_QUEUE
- Status tracking
- Delete handling
2026-07-11 07:30:33 -07:00
Story Crater Bot 68672c72e9 fix: wrap TemporalWorker reconciler errors with context 2026-07-11 07:30:18 -07:00
Story Crater Bot 317396e785 feat: add TemporalWorker auto-provisioning from Queue labels
- Validate temporal namespace and Kubernetes names
- Configurable via env vars: KMSVC_TEMPORAL_NAMESPACE, KMSVC_TEMPORAL_WORKER_IMAGE
- Set ownerReference for cascade deletion and lifecycle management
- Use CreateOrUpdate for spec propagation (idempotent)
- Clean up TemporalWorker on Queue deletion
2026-07-11 07:30:13 -07:00
Story Crater BotandClaude Haiku 4.5 6577efc100 feat: add TemporalWorker CRD and controller
Add TemporalWorker CRD definition with full status tracking and
TemporalWorkerReconciler that manages Deployment lifecycle:
- Auto-generate DeepCopy methods via kubebuilder markers
- Controller creates/updates Deployments matching worker spec
- Injects TEMPORAL_FRONTEND_ADDRESS and TEMPORAL_NAMESPACE env vars
- Tracks replica count and ready status
- Handles graceful deletion via finalizer

Design document (TEMPORAL_INTEGRATION.md) describes three-phase roadmap:
- Phase 1 (MVP): Manual TemporalWorker CRD creation
- Phase 2: Auto-provisioning from Queue labels
- Phase 3: Autoscaling based on queue depth

Co-Authored-By: Claude Haiku 4.5 <[email protected]>
2026-07-11 07:29:34 -07:00
riotpiaole 674fbb6bfe fix: consolidate all modules under homelab org for cross-repo resolution 2026-07-04 08:28:00 -07:00
riotpiaole 43ab2092df ci: add comprehensive CI workflow for server and operator 2026-07-04 07:44:55 -07:00
riotpiaole c7eeed2617 feat: stamp Queue shard status with availability zones
Resolves each shard topic's replica broker IDs (internal/kafka.Admin.
ReplicaBrokerIDs) to the topology.kubernetes.io/zone labels of the nodes
hosting those brokers (ZoneLocator), and writes the result into
ShardStatus.AvailabilityZones each reconcile. Uses mgr.GetAPIReader()
rather than the cached client for the Pod/Node lookups, since the cached
client would otherwise require cluster-wide list/watch RBAC on Pods just
to serve occasional point Gets.
2026-06-22 17:30:26 -07:00
riotpiaole 1ff1ecd563 fix: update kafaka server to kmsvc.riotpiao.homelab.com 2026-06-22 13:05:32 -07:00
riotpiaole c7961d2599 test: add end-to-end queue send/receive/delete smoke test script
Creates a Queue CRD, port-forwards to management-service, fetches an
Authentik client_credentials token, then exercises send/receive/delete
through kmsvc-cli before tearing the queue down.
2026-06-22 12:23:39 -07:00
riotpiaole 9fa5420b22 fix: queue-operator dropped reconcile namespace and overflowed hash-range status
main.go called Reconcile(ctx, req.Name) without req.Namespace, so the
Get against the namespaced Queue CRD always 404'd and was silently
swallowed as success -- no shard topics or Redis state were ever created.

Separately, ShardStatus.HashRangeStart/End were uint32, but controller-gen
maps that to OpenAPI format:int32, whose max (2147483647) is smaller than
FullHashRangeEnd (0xFFFFFFFF), so the apiserver rejected every status
update with the (misleadingly empty-looking) "must be of type integer with
format int32" error. Widened to int64, regenerated the CRD, and synced the
chart's bundled copy.
2026-06-22 12:23:23 -07:00
riotpiaole 173a4935ab fix: pin Kafka broker storage to a 2-replica class sized for current cluster
The default "longhorn" StorageClass requests 3 replicas, but the homelab
cluster currently has only 2 schedulable nodes, so the 3rd replica could
never be scheduled and volumes stayed permanently degraded. Adds
longhorn-kafka (numberOfReplicas: 2) and reduces broker PVC size so 3 broker
volumes' replicas fit within each node's remaining Longhorn scheduling
headroom. Revert to "longhorn" once a 3rd node joins.
2026-06-22 12:23:12 -07:00
riotpiaole 3dda969784 fix: align GOMEMLIMIT with pod memory limits and force fresh image pulls
Go's GC doesn't respect cgroup memory limits on its own, risking OOMKill
under load; set GOMEMLIMIT to ~90% of each deployment's resources.limits.memory.
Also switch imagePullPolicy to Always so :latest tags aren't served stale
from node-local cache after a new push.
2026-06-22 12:22:55 -07:00
riotpiaole 00d06c12bc feat: add ArgoCD app-of-apps manifests for homelab GitOps deployment
Root application + project plus per-component Application CRs (Strimzi
operator, Kafka cluster, Redis, queue CRD/operator, management-service).
2026-06-22 12:22:38 -07:00
riotpiaole f2566e6f89 build: pin docker builds to linux/amd64 and trust homelab CA at runtime
Building on arm64 Mac without GOOS/GOARCH produced amd64 node "exec format
error". The homelab CA was only trusted in the build stage, so the final
distroless runtime couldn't verify Authentik's TLS cert during OIDC discovery.
2026-06-22 12:21:38 -07:00
riotpiaole 8904203266 fix: consolidate helmfile into one file; expose gRPC externally for kmsvc-cli
Cross-file `needs:` across separate nested helmfiles didn't resolve in
Helmfile v1 (releases defined in sibling files weren't visible to each
other's dependency graph) -- confirmed live against the homelab cluster:
kafka-cluster failed with "depend(s) on an undefined release" even though
strimzi-operator had just been installed successfully by a sibling file.
Collapsed releases.d/*.gotmpl into a single helmfile.yaml.gotmpl so the
whole release graph is resolved together.

Also add a second Ingress (management-service-grpc, backend-protocol: GRPC)
scoped to the QueueService gRPC path prefix on the same host/port as the
REST ingress. kmsvc-cli dials --server directly via gRPC (default
kmsvc.homelab.internal:443 per its README), so raw gRPC needs an external
path too, not just REST -- the original "gRPC stays internal" default
didn't account for the CLI's own connection model.

Add Dockerfile.queue-operator (existed for cmd/server only before).
2026-06-22 07:11:58 -07:00
riotpiaole 2519e726b2 fix: use sqs namespace in queue-operator ClusterRoleBinding
Aligns the standalone config/rbac manifest with the sqs namespace used
throughout the new k8s/ Helm charts.
2026-06-22 06:32:09 -07:00
riotpiaole 918ba9393f feat: add Helmfile-managed k8s charts for tasks 10-13
Local charts: kafka-cluster (Strimzi Kafka+KafkaNodePool CRs, 3-replica KRaft
topology, 5Gi memory cap, Longhorn storage, pod anti-affinity), queue-crd
(Queue CRD + queue-operator Deployment/RBAC), management-service
(Deployment/Service/ConfigMap/HPA/Ingress, REST exposed externally via
cert-manager-issued TLS, raw gRPC kept cluster-internal per design.md §7a).

helmfile.yaml.gotmpl + releases.d/*.gotmpl wire strimzi-operator ->
kafka-cluster -> redis -> {queue-crd, management-service} via `needs:`.
Directory is releases.d, not helmfile.d as originally sketched in design.md
section 7b: Helmfile v1 treats a literal "helmfile.d" directory as a special
auto-discovery mode that conflicts with an explicit top-level helmfile.yaml.
Files use .gotmpl (required by Helmfile v1 for {{ }}-templated files) and
each declares its own environments: block, since nested helmfiles don't
inherit the parent's resolved values in this version.

Namespace is sqs throughout. environments/homelab.yaml carries no secrets.
Validated locally via helm lint/helm template (all 3 charts) and
`helmfile -e homelab build` (dependency ordering + value substitution) — no
cluster contact made. Live apply is a separate, explicitly-confirmed step.
2026-06-22 06:31:41 -07:00
riotpiaole fd69e33a98 build: add Dockerfile for the message-plane server
Multi-stage build (golang:1.26 -> distroless/static-nonroot), CGO disabled,
GOPRIVATE set for the kmsvc-proto module fetch.
2026-06-22 06:30:31 -07:00
riotpiaole 26b6922ad4 feat: implement gRPC server + grpc-gateway wiring (task 9)
Assembles tasks 1/6/7/8 into a runnable cmd/server binary: QueueServiceServer
handlers translating kafkamgmt.v1 proto to internal/core/queue's plain Go
types, a lazy per-queue Kafka consumer registry for ReceiveMessage, and a
Redis-scan-based queue discovery loop that starts a reaper goroutine per
queue (queue lifecycle isn't exposed over gRPC, so this is the server's only
signal). Promotes kmsvc-proto to a direct go.mod dependency.

Handler-level integration tests run against kfake+miniredis (same documented
tradeoff as tasks 5-7's envtest/testcontainers substitution), exercising
send->receive->delete through the real QueueServiceServer implementation.
2026-06-22 06:30:25 -07:00
riotpiaole b3be1f929a refactor: consume kmsvc-proto as a Go module instead of local generation
Remove local proto/, buf.yaml, buf.gen.yaml, and generated
internal/api/v1/*.pb.go. The message-plane contract now lives in the
sibling repo kmsvc-proto (forgejo.riotpiao.homelab.com/rock/kmsvc-proto),
fetched via go get — no local buf/protoc plugin install needed.

Nothing in this repo imported internal/api/v1 yet, so this is a clean
swap with no call-site changes.
2026-06-21 19:47:43 -07:00
riotpiaole ef7b54710d feat(auth): add Authentik JWT validation shared by gRPC and REST
JWKS caching via lestrrat-go/jwx, signature/iss/aud/exp validation, and
a single gRPC interceptor that grpc-gateway's forwarded headers make
work identically for REST callers.
2026-06-21 18:55:23 -07:00