Commit Graph
47 Commits
Author SHA1 Message Date
claude-bot 6543fd77d8 fix(nexus-db): address codex review — early encoding guard, robust helpers
CI / Shell-Lint (bash -n, source-check, Validierungs-Tests) (pull_request) Successful in 2s
- assert encoding BEFORE role/password mutation on re-run, so an old
  SQL_ASCII DB aborts with no side effects (codex finding 1)
- ensure_utf8_locale_active honours its locale argument consistently in
  match, locale.gen line and export (codex finding 2)
- assert_db_encoding_utf8 uses argv-clean runuser psql with :'db' literal
  binding instead of nested su -c shell; docs keep su - postgres -c
  (codex finding 3)
2026-06-13 14:34:35 +02:00
claude-bot bd4293f53e fix(nexus-db): enforce UTF8 encoding at install time (issue #8)
CI / Shell-Lint (bash -n, source-check, Validierungs-Tests) (pull_request) Successful in 1s
A PostgreSQL cluster/database freezes its encoding at initdb / CREATE
DATABASE time; a C (non-UTF-8) locale yields a SQL_ASCII cluster, which
makes psycopg3 return bytes and crashes SQLAlchemy. Harden the installer
and add a reusable pattern for future DB installers:

- ensure_utf8_locale_active: generate AND activate en_US.UTF-8 for the
  install process before the server package runs initdb; abort if the
  locale is not actually available
- create the database explicitly with TEMPLATE template0 ENCODING 'UTF8'
  LC_COLLATE/LC_CTYPE 'en_US.UTF-8' instead of inheriting the cluster
  default
- assert_db_encoding_utf8: post-install guard, abort with an actionable
  message if pg_encoding_to_char is not UTF8 (catches old SQL_ASCII DBs
  on re-run too)
- credentials/README docs use su - postgres -c (minimal LXCs have no sudo)
2026-06-13 14:30:40 +02:00
l.kirchner 553b923445 Merge pull request 'docs: README-Dedup — Contributing konsolidiert, Stand aktualisiert' (#7) from chore/readme-dedup into main
CI / Shell-Lint (bash -n, source-check, Validierungs-Tests) (push) Successful in 2s
docs: README-Dedup nach K-114-Merge (PR #7) — ein Contributing-Abschnitt, Status/CI aktuell
2026-06-12 19:42:48 +02:00
l.kirchner 09ac4d2507 docs: consolidate duplicate contributing sections, refresh README
CI / Shell-Lint (bash -n, source-check, Validierungs-Tests) (pull_request) Successful in 1s
- merge the two contributing sections into one (PR + cross-review rule,
  both real incidents, CI enforcement in present tense - the suite is
  live on the homelab runner since K-114/PR #5)
- script catalog: runner is in production (PR #6 merged)
- usage: document input validation behavior (re-prompt on junk bytes,
  env values abort when malformed)
- pattern: SSH root login prompt (sshd drop-in) and the locale fix in
  setup_base_apt
- repo layout: tests/ added
2026-06-12 16:46:57 +02:00
l.kirchner a397ade6e1 Merge pull request 'K-114: Input-Validierung in build.func + Mini-CI' (#5) from k114/input-validierung-mini-ci into main
CI / Shell-Lint (bash -n, source-check, Validierungs-Tests) (push) Successful in 1s
K-114: Input-Validierung in build.func + Mini-CI (PR #5) — SSH-Root-Login-Prompt, locale-Fix, runs-on homelab
2026-06-12 16:40:37 +02:00
l.kirchner e5cbf3f60e Merge pull request 'feat: allgemeiner instanzweiter Actions-Runner-LXC (Label homelab, ohne Deploy-Rechte)' (#6) from feature/runner-lxc into main
feat: allgemeiner instanzweiter Actions-Runner-LXC (PR #6) — Label homelab, ohne Deploy-Rechte; Review-Findings 90/88/82/80/85 adressiert
2026-06-12 16:28:07 +02:00
l.kirchner 43c19f2cce fix(runner): Re-Review-Nits — irreführenden Validator-Kommentar korrigiert, EOF-Abbruch in Prompt-Loop 2026-06-12 15:27:45 +02:00
l.kirchner 63a735e697 fix(runner): Re-Review-Finding 85 — run_user wechselt via env -C ins RUNNER_DIR (.runner landet sonst in /) 2026-06-12 15:26:53 +02:00
l.kirchner ebdd3f5eac fix(runner): Review-Finding 80 — validierte Prompts mit Re-Prompt, env-Werte geprüft; Quoting-Falle (76) durch Charset-Validierung entschärft 2026-06-12 15:05:57 +02:00
l.kirchner f06e873118 fix(runner): Review-Findings 90/88/82/80 (+70) — Re-Run ohne deploy.env, Sicherheitsmodell dokumentiert, Requires=docker, strikte Input-Validierung, argv statt Shell-Interpolation, Unit-Härtung 2026-06-12 15:04:57 +02:00
l.kirchner 360db12cc9 docs: README neu strukturiert — vollständiger Katalog, Pattern, Security-Konventionen, PR-Pflicht 2026-06-12 14:58:49 +02:00
l.kirchner 7f64b12a77 K-114: set up locales in setup_base_apt (C.UTF-8 during install, en_US.UTF-8 default)
CI / Shell-Lint (bash -n, source-check, Validierungs-Tests) (pull_request) Successful in 9s
LXC templates ship without a configured locale, so every apt/perl run
warned 'Setting locale failed'. setup_base_apt now exports C.UTF-8 for
the install run itself, installs the locales package, generates
en_US.UTF-8 and sets it as the system default via update-locale.
2026-06-12 14:42:03 +02:00
l.kirchner aa3ad2f716 K-114: SSH root login prompt with sshd drop-in in the install path
prompt_lxc_config asks 'SSH-Root-Login erlauben? [Y/n]' (env-presettable
via SSH_ROOT_LOGIN, validated, normalized to yes|no). The bootstrap passes
the value into the container; configure_ssh_root_login writes
/etc/ssh/sshd_config.d/zz-root-login.conf (yes -> PermitRootLogin yes,
no -> prohibit-password) and reloads sshd.
2026-06-12 14:41:31 +02:00
l.kirchner 5f532fe10a K-114: run mini CI on the instance-wide homelab runner 2026-06-12 14:40:42 +02:00
l.kirchner ad04edec5b feat(runner): Installer — act_runner instanzweit als unprivilegierter User, Docker, ohne sudoers 2026-06-12 13:25:42 +02:00
l.kirchner 2941afa53f feat(runner): allgemeiner instanzweiter Actions-Runner-LXC (Label homelab, ohne Deploy-Rechte) 2026-06-12 13:25:10 +02:00
l.kirchner 490fda2ed1 K-114: address cross-review findings
CI / Shell-Lint (bash -n, source-check, Validierungs-Tests) (pull_request) Has been cancelled
- CTID prompt re-prompts on invalid interactive input (was: abort)
- env-provided NAMESERVER is validated when non-empty ('' stays inherit)
- prompt_validated handles EOF (no infinite loop, clean abort under -e)
- 10# base forcing in vlan/cidr/ipv4 arithmetic (leading zeros are not
  octal errors); is_clean_ascii rejects embedded newline/tab explicitly
  (command substitution strips trailing newlines); is_ipv4_list checks
  the whole string before word splitting
- nameref guard against reserved variable names in prompt_validated/
  require_valid; source-check pattern documented as the repo contract
- 8 new test cases (41 total)
2026-06-12 03:20:11 +02:00
l.kirchner 80e2ec04ff K-114: input validation in build.func + mini CI (nexus-hub card)
- validation helpers: sanitize_input trims CR/edge whitespace only;
  embedded control/non-ASCII bytes FAIL validation and re-prompt with a
  hint (2026-06-11 incident: invisible byte in a pasted VLAN tag broke
  pct create mid-run) - never silently stripped
- prompt_lxc_config: every prompt validated (uint for CTID/disk/cores/
  RAM, VLAN 1-4094, hostname/token formats, IP/CIDR/gateway, DNS list);
  env-provided values are sanitized + validated too (abort, no re-prompt
  loop in non-interactive use); helpers reusable for app prompts
- tests/test_validation.sh: 34 cases incl. the 2<0x80>0 repro, re-prompt
  simulation, BASH_REMATCH clobbering regression (is_cidr), env dry-run
  of prompt_lxc_config without PVE/TTY
- tests/check_ct_source.sh: every ct/*.sh must source build.func (bug
  shipped twice); negative proof via prepared fixture in the test suite
- .gitea/workflows/ci.yml: bash -n over all scripts, source-check,
  validation tests, shellcheck if present (documented skip otherwise)
- README: contributions via PR with cross-review (binding)
2026-06-12 03:14:32 +02:00
l.kirchner cad741a97c fix(authentik): fehlendes source von build.func ergänzt (gleicher Bug wie Codex-Finding 96 in nexus-db) 2026-06-11 17:06:41 +02:00
l.kirchner 828e3d1aad feat(authentik): Installer — Docker, offizielles Compose, headless Bootstrap-Credentials + API-Token, Blueprints-Mount 2026-06-11 17:02:47 +02:00
l.kirchner ab0354bc22 feat(authentik): LXC-Vorlage — Nesting, Agent-SSH-Key, automatisierungsfreundlich (nexus ADR-0003/K-102) 2026-06-11 17:02:10 +02:00
l.kirchner e8bace387d Merge pull request 'feat(nexus-db): PostgreSQL 16 + pgvector LXC template (nexus-hub K-102)' (#4) from k102/nexus-db into main
Reviewed-on: #4
2026-06-11 16:36:30 +02:00
l.kirchner 559ad8dc2d fix(nexus-db): cross-review findings
- source build.func (script was unrunnable without it)
- validate DB_NAME/DB_USER/DB_PORT/NEXUS_APP_IP before SQL/pg_hba use
- rotate password when role exists but credentials file is missing
2026-06-11 15:56:05 +02:00
l.kirchner 0ee7ceae55 feat(nexus-db): PostgreSQL 16 + pgvector LXC template (nexus-hub K-102)
webapp-pattern ct/install pair: PGDG repo, database nexus with
least-privilege owner role, pg_hba allowlist restricted to the nexus
app LXC (explicit reject for everything else), pgvector created by the
installer, credentials/DSN summary in /root/nexus-db.credentials.
Idempotent re-runs keep role/db and do not rotate the password.
2026-06-11 15:51:04 +02:00
l.kirchner abc62f5704 Merge pull request 'feat(nexus): runtime provisioning for the decided stack (nexus-hub K-101)' (#3) from k101/nexus-runtime into main 2026-06-11 15:18:14 +02:00
l.kirchner ad36417b30 Merge branch 'fix/nexus-service-condition' 2026-06-11 14:54:47 +02:00
l.kirchner afd0a4ea35 fix(nexus): guard nexus.service with ConditionPathExists
A reboot before the first deploy would leave the enabled unit in failed
state; the condition keeps it inert until start.sh exists (same guard as
nexus-worker.service).
2026-06-11 14:54:47 +02:00
l.kirchner 2152683397 Merge branch 'feat/nexus-runtime-k101' 2026-06-11 14:48:53 +02:00
l.kirchner 1dd89e25bc feat(nexus): runtime provisioning for the decided stack (nexus-hub K-101)
- new install/nexus-runtime.sh (idempotent, re-runnable on an existing
  LXC): uv for the nexus user (manages Python 3.12), tesseract deu+eng,
  nexus-worker.service unit (ConditionPathExists guards the skeleton
  phase), sudoers extended to cover the worker service
- nexus-install.sh: RUNTIME section now invokes nexus-runtime.sh at the
  end of the install (after base sudoers/units, which it extends)
2026-06-11 14:48:53 +02:00
l.kirchner 34ac5a05f6 feat: nexus installer — Host-Mode-Runner, App-User, Service-Skeleton, enge sudoers 2026-06-10 23:42:38 +02:00
l.kirchner 5379586545 feat: nexus LXC template — Host-Mode-Runner + Deploy-as-Code (Skeleton bis Stack-Entscheidung) 2026-06-10 23:41:57 +02:00
l.kirchner 3012245c93 Merge pull request 'Set container DNS from the VLAN tag via a network profile (incl. DHCP)' (#2) from network-profiles into main
Reviewed-on: #2
2026-06-07 21:25:27 +02:00
l.kirchner 953ef3001e build.func: set DNS from VLAN tag via network profile (incl. DHCP)
Adds apply_network_profile(), which looks up DNS servers for the entered
VLAN tag in lib/networks.conf and sets --nameserver accordingly — even
when IP is DHCP. Precedence: explicit env NAMESERVER > profile > static
prompt > inherit. Comma-separated DNS is normalised to spaces for pct.
2026-06-07 21:22:19 +02:00
l.kirchner 3a805b8bda Add network profiles file (VLAN tag → DNS servers)
Data file mapping a VLAN tag to its DNS servers and subnet, so build.func
can set the right resolvers from the tag entered at install time — even
with DHCP. New networks are a one-line addition here.
2026-06-07 21:21:05 +02:00
l.kirchner 1d6a15c962 Merge pull request 'Add webapp: Next.js LXC with deploy-as-code via Gitea Actions runner' (#1) from add-webapp into main
Reviewed-on: #1
2026-06-05 02:33:37 +02:00
l.kirchner ab839b0e85 README: add webapp to the available scripts table 2026-06-05 02:29:35 +02:00
l.kirchner 601abeef4c Add webapp in-container installer (Node + act_runner host mode)
Installs Node.js and act_runner in host mode, registers the runner as
the unprivileged webapp user, and wires up systemd units for the runner
and the next-start service. A narrow sudoers rule lets the runner restart
only webapp.service; the build/deploy itself is driven by the repo workflow.
2026-06-05 02:29:15 +02:00
l.kirchner ddd22b175e Add webapp installer: Next.js site via self-hosted Gitea Actions runner
Host-side script that creates an unprivileged Debian 12 LXC, installs
Node.js + act_runner in host mode, and registers it against the Gitea
instance. Deploy logic lives in the repo's .gitea/workflows/deploy.yml
(deploy-as-code); the runner polls outbound, so no inbound port.
2026-06-05 02:28:20 +02:00
l.kirchner 42aad8a117 fix(build): add DNS server prompt for static IPs + better network diagnostics
For DHCP setups DNS is delivered with the lease, but with a static IP the
container inherits /etc/resolv.conf from the PVE host - which is often
unreachable from the container's VLAN.

Changes:
- New NAMESERVER prompt (only shown for static IPs, defaults to gateway)
- pct create now passes --nameserver when set
- Network wait loop tests L3 and DNS separately so failures point at the
  actual cause (no route to gateway vs. bad DNS server)
- Refactored pct create args into an array for cleaner conditional flags
2026-05-22 00:11:49 +02:00
l.kirchner b93ec8b553 fix(build): rename HOSTNAME -> CT_HOSTNAME (shadowed bash builtin), add VLAN_TAG prompt, fail fast on network timeout
HOSTNAME is a bash built-in always containing the host's name, so the
"-z HOSTNAME" check never fired and the prompt was silently skipped —
containers ended up named after the Proxmox host.

Also added an optional VLAN tag prompt (empty = no tag), and the network
wait loop now exits with an error if the network never comes up instead
of silently proceeding to a guaranteed-broken apt-get update.
2026-05-21 23:32:12 +02:00
l.kirchner 7343501b25 Add docs/adding-a-script.md 2026-05-21 23:05:38 +02:00
l.kirchner 3614475402 Add install/devpi-install.sh: in-container installer for devpi 2026-05-21 23:05:15 +02:00
l.kirchner 87d68d9aba Add ct/devpi.sh: host-side installer for devpi 2026-05-21 23:03:38 +02:00
l.kirchner bf5afc7d26 Add lib/install.func: shared in-container helpers 2026-05-21 23:03:26 +02:00
l.kirchner 9a57d30433 Add lib/build.func: shared host-side helpers 2026-05-21 23:02:02 +02:00
l.kirchner d5b9f56535 Add MIT license 2026-05-21 23:01:20 +02:00
l.kirchner 2b4f08c5eb Initial commit: README 2026-05-21 23:00:07 +02:00