Commit Graph

75 Commits

Author SHA1 Message Date
root
49b68cf820 Lower backup/restore RAM safety threshold 1536MB -> 1024MB
Investigated a resource-safety abort during Odoo restore testing:
available RAM was hovering ~1.3-1.5GB even under normal conditions on
this host (k3s + Jenkins + Docker monitoring/wazuh stack + dev tooling
baseline), not a leak from any single process. 1536MB was tripping on
ordinary single-app backups; 1024MB still leaves real headroom above
what a pg_dump/mysqldump/tar step actually needs.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017avLHFqkiti3g62Anq9sVA
2026-08-21 01:43:37 +02:00
root
4dd4b8ef9b Checkout: hostPath-mount the VPS's own CloudOps checkout instead of cloning
18 straight clone failures today (early EOF / invalid index-pack) even with
http.postBuffer/http.version tuning applied — Gitea's HTTP endpoint itself is
degraded right now, not something fixable client-side. Sidesteps it entirely:
the docker-agent pod template now hostPath-mounts /root/CloudOps (read-only,
see k3s-cloud-init.groovy) and Checkout just `cp -r`s from it, no network
fetch at all. Build/SonarQube paths revert to ./platform/ (no more repo/
subdirectory, since we're not cloning into one).

Real tradeoff, accepted deliberately: builds now reflect whatever's on the
VPS's disk at build time, not necessarily what's pushed to Gitea. Depends on
/root/CloudOps being kept current via the normal git pull workflow.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-20 11:55:41 +02:00
root
3c90fe9ce8 Replace Jenkins Git plugin checkout with a plain shell clone + retry loop
The Git plugin's checkout([...]) step doesn't expose http.postBuffer/
http.version tuning, which is what's reliably fixed every stuck
push/clone today (VPS and both laptops) — meanwhile checkout was failing
~10 times in a row, consistently dying at 84-95% during the shallow clone
(early EOF / invalid index-pack). Bypasses the plugin entirely: a plain
`git clone` with those settings applied, wrapped in its own 8-attempt
bash retry loop, using the existing dd13f593-06b1-4a5a-9477-2df0d186b490
credential (confirmed via credentials.xml to be a UsernamePasswordCredentialsImpl,
compatible with the usernamePassword binding as-is).

Code now lands in a repo/ subdirectory instead of the workspace root, so
every stage referencing a repo-relative path was updated to match:
- Build Docker Image: ./platform/ -> ./repo/platform/
- SonarQube Analysis: -Dsonar.sources=platform -> -Dsonar.sources=repo/platform
Deploy to Kubernetes needed no changes — it only references the already-built
image tag and hardcoded kubectl args, no filesystem paths into the checkout.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-20 11:46:39 +02:00
root
a6fb9e5e18 Wire management-platform's backup/restore routes to the k8s scripts
api_backup_run and restore_start were still hardcoded to the Docker-era
backup-myapps.sh/restore-myapps.sh, which target Docker volumes that no
longer exist for the 5 apps now running in k3s (n8n, odoo, mautic,
nextcloud, frappe/erpnext) — every backup/restore triggered from the UI
has been silently hollow for these apps since the migration.

- api_backup_run: /root/backup-myapps.sh -> /root/CloudOps/backup/backup-k8s-apps.sh
- restore_start: switched from the old image-relative path (which resolved
  to /app/restore-myapps.sh, baked into the Docker image from platform/)
  to an absolute /root/CloudOps/backup/restore-k8s-apps.sh path — the new
  backup/ folder is a sibling of platform/, not part of the Docker build
  context, so it's only reachable via the pod's existing /root hostPath
  mount, the same way api_backup_run already reaches its script.

--apps flag shape and the job-log streaming contract are unchanged, so no
frontend/template changes needed for the core flow. modules/backups.py's
three hardcoded myapps-backup-* references (get_local_backups, get_vm_backups
x2, delete_backup's filename regex) now also recognize the new
myapps-k8s-backup-* prefix, so both backup lineages stay visible/manageable
in the UI.

Depends on the previous commit (scoped ServiceAccount + k3s kubectl access
for the pod) to actually function when triggered from the UI.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-20 11:30:14 +02:00
root
f3f08c3ef6 Give management-platform a scoped ServiceAccount for k8s backup/restore
The pod running app.py had no kubectl binary and only a read-only SA
(management-platform-viewer-sa) — backup-k8s-apps.sh/restore-k8s-apps.sh
could never actually run from inside it. Adds:

- management-platform-backup-role (ClusterRole, bound via RoleBinding only
  in n8n/odoo/mautic/nextcloud/erpnext — not cluster-wide): get/list/watch
  on pods/deployments/configmaps/ingresses/PVCs, pods/exec create, pods
  create+delete (needed for restore's populate-before-scale-up loader pod),
  secrets get/list/update/patch, deployments/scale update/patch only (no
  write on full Deployment/Service/ConfigMap/Ingress specs).
- management-platform-sa, replacing management-platform-viewer-sa as the
  pod's identity — inherits the old viewer-role's read-only bindings too
  (retargeted in management-platform-viewer-rbac.yaml) so the existing
  cluster-view page keeps working under one SA.
- k3s binary hostPath-mounted read-only into the pod (same pattern as the
  Jenkins agent's docker-cli container), so `k3s kubectl` is available
  where no separate kubectl binary exists.

Both scripts updated to fall back to k3s kubectl when no kubectl is on
PATH, and to use /proc/meminfo instead of `free` for the resource-safety
check (not present in the pod's minimal image). Also fixes a real issue
found while live-testing this from inside the pod: the pod's pre-existing
/root hostPath mount also exposes the host's own admin ~/.kube/config,
which k3s kubectl was silently preferring over the scoped SA token —
forcing --kubeconfig=/dev/null in both scripts closes that.

Verified end-to-end from inside the actual management-platform pod:
manifests/secret/DB-dump/PVC-data backup for n8n succeeds under the new
SA's scoped permissions, and a kube-system access attempt is correctly
rejected (Forbidden) once the kubeconfig leak is closed.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-20 11:30:03 +02:00
root
8255527254 Add k8s-native backup/restore scripts for the 5 live apps
backup-myapps.sh/restore-myapps.sh only ever knew about Docker volumes,
which no longer exist for n8n/odoo/mautic/nextcloud/frappe now that
they're all running in k3s — nightly backups have been silently hollow
for these apps since the migration. These new scripts capture/restore
each app's k8s manifests, Secret, DB (pg_dump/mysqldump via kubectl exec),
and app-data PVC contents (kubectl exec tar, never raw filesystem access),
reusing the existing local+VM+R2 3-2-1 storage/retention logic unchanged.

Tested standalone: full backup of all 5 apps produces verified non-empty
manifests/secrets/DB dumps/PVC data; restore-in-place tested end-to-end
against n8n (DB row counts and PVC data matched exactly pre/post, app
verified healthy over HTTPS).

Not wired into management-platform yet (app.py stays untouched) — restore
script also doesn't yet handle a fresh/DR cluster where the PVCs and their
manifests don't already exist (same-cluster restore only for now).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-20 11:03:14 +02:00
b4308b7d15 fix jenkinsfile structure, add retry(5) to checkout 2026-08-14 12:52:00 +01:00
8f6add243f add retry(5) to checkout stage - gitea git-upload-pack drops connections intermittently 2026-08-14 12:49:06 +01:00
root
9791d541de fix jenkins checkout: skip default full checkout, use shallow clone 2026-08-14 13:37:52 +02:00
a284269574 test push after jenkins checkout fix 2026-08-14 12:33:28 +01:00
84f80b7779 Add read-only Kubernetes cluster view alongside Docker container view
New modules/kubernetes.py lists pods and deployments across the 8 app
namespaces via the in-cluster management-platform-viewer-sa (read-only,
no secrets/exec/log), with metrics-server usage as a best-effort extra
that degrades silently when unreachable. New /cluster page and
/api/cluster endpoint, nav entry, and templates render pods/deployments
grouped by namespace using the existing card/badge design system.
Additive only — no existing Docker routes or views touched.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-14 11:40:03 +01:00
root
c58f19ccda Add read-only RBAC for management-platform cluster-view SA
ServiceAccount management-platform-viewer-sa (in management-platform ns),
ClusterRole management-platform-viewer-role (get/list/watch on pods,
services, deployments.apps only - no secrets, no write verbs), and a
RoleBinding per app namespace (n8n, odoo, mautic, erpnext, nextcloud,
jenkins-agents, jenkins, management-platform). Already applied to the
live cluster and verified via kubectl auth can-i; committing here for
source-of-truth tracking.
2026-08-14 12:20:58 +02:00
root
3782241a88 Add management-platform Deployment manifest with viewer SA wired in
Source-of-truth manifest for the management-platform Deployment, with
serviceAccountName: management-platform-viewer-sa added so the pod can
authenticate for the read-only k8s cluster-view feature. Not yet applied
to the cluster.
2026-08-14 12:20:58 +02:00
root
47a2c43fdb Sync from main server - 2026-06-04 18:24:37 2026-08-14 12:20:58 +02:00
5c9d5372a2 fix deploy stage: use k3s kubectl, mask token from logs 2026-08-06 01:31:40 +01:00
6af8e5f791 sonar sidecar container, unique image tags, real k8s deploy stage 2026-08-06 01:06:24 +01:00
78d114f41d switch to k8s agent, remove docker deploy placeholder 2026-08-06 00:02:16 +01:00
04bbbb192b Change : sonarqubefix , backup.py 2026-06-21 19:31:24 +01:00
32feb9d4eb Change : UI/UX design 2026-06-21 19:16:07 +01:00
ae267a6d9b Change : UI/UX design 2026-06-21 18:56:18 +01:00
b43c87de73 Change : display 2026-06-21 18:15:36 +01:00
9b2bc907aa Change : display 2026-06-21 18:05:52 +01:00
6ee29a462e Change : Backup pick 2026-06-21 01:17:51 +01:00
bf9c4a01b2 Change : Backup pick 2026-06-21 00:20:37 +01:00
c3e3a3b28c Change : dashboard , containers 2026-06-12 21:49:47 +01:00
df99603d9e ADD SonarQube 2026-06-10 17:16:30 +01:00
c9db50638e ADD SonarQube 2026-06-10 17:10:43 +01:00
ec53903726 ADD SonarQube 2026-06-10 17:06:03 +01:00
4e39130210 fix jenkins build 2026-06-08 13:30:25 +01:00
dd384aebe4 fix jenkins build 2026-06-08 13:26:55 +01:00
e2fd7e7c91 ADD: remove architecture , fix sites 2026-06-07 18:35:25 +01:00
515fc94754 ADD: remove architecture , fix sites 2026-06-07 18:31:10 +01:00
d4d15da0df ADD: sites and architecture module fix 2026-06-07 18:16:20 +01:00
c3fbb0b9da ADD: sites and architecture module fix 2026-06-07 18:11:02 +01:00
f51d5755c2 ADD: sites and architecture module fix 2026-06-07 18:06:09 +01:00
6df165d8d7 ADD: sites and architecture module 2026-06-07 17:52:26 +01:00
dbc83830ef fix: hostname 2026-06-06 15:45:36 +01:00
a7c3e3e7fe fix: restore script 2026-06-06 15:10:39 +01:00
715993af46 fix: restore script 2026-06-05 17:37:45 +01:00
0d7468dd7f fix: remove BuildKit due to missing buildx component 2026-06-04 15:55:49 +01:00
c37f83433c fix: remove BuildKit due to missing buildx component 2026-06-04 15:42:04 +01:00
eacf533e9f fix: remove BuildKit due to missing buildx component 2026-06-04 15:40:55 +01:00
3ee079b18e fix: use psutil for reliable CPU and memory metrics 2026-06-04 15:36:39 +01:00
b3d3c0d457 fix: use psutil for reliable CPU and memory metrics 2026-06-04 15:24:02 +01:00
47600ccd42 fix: remove /proc/sys/kernel/hostname mount in docker run 2026-06-04 15:12:35 +01:00
7255c510b3 fix: cpu/memory , test webhook 2026-06-04 14:53:34 +01:00
92908695ae fix: cpu/memory , test webhook 2026-06-04 14:42:36 +01:00
7a3f3113f3 fix: cpu/memory , test webhook 2026-06-04 14:37:55 +01:00
a89fe1ecfd fix: cpu/memory , test webhook 2026-06-04 14:29:22 +01:00
a5bd4b75cf fix: cpu/memory , test webhook 2026-06-04 14:16:45 +01:00