Files
instance-template-v3/values.yaml
OdooSky v3 4a8dc61a92 feat(chart): rip out pg dual-mode shim — ESO-only (0.1.8)
A-Chunk 3 finalisation. All live instances are migrated to ESO,
and Tower 0.77.2 makes the migrate + template-deploy paths also
emit ESO-shape overlays (wizard always has). The
`{{- if not .Values.postgres.passwordVaultPath }}` shim in
postgres-secret.yaml has zero remaining production callers.

Changes:
  - DELETE templates/postgres-secret.yaml (dual-mode legacy path)
  - DELETE _helpers.tpl `instance.pgPassword` (only consumed by
    postgres-secret.yaml; no other callers)
  - UNWRAP templates/postgres-password-externalsecret.yaml — the
    outer `{{- if .Values.postgres.passwordVaultPath }}` conditional
    is removed; the template now renders unconditionally and the
    chart's `required` directive on tenant.id is the new boundary
    (chart render fails loud if Tower forgot to populate it)
  - SIMPLIFY values.yaml — drop the legacy `postgres.password` field
    and the dual-mode documentation. `passwordVaultPath` stays as an
    operator-visible advisory string but the chart hardcodes the
    path shape from tenant.id + instance.code

Chart 0.1.7 → 0.1.8. helm template + helm lint verified locally;
helm template with tenant.id missing fails loud with a clear
error pointing the operator at the chart line + the source of the
missing value.

The live instances (erp/erp18v3/v19) carry tenant.id + passwordVaultPath
in their overlays already; this chart version produces the same
manifests for them on next ArgoCD reconcile — no observable change.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-12 13:56:40 +03:00

231 lines
9.7 KiB
YAML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# OdooSky v3 instance-template-v3 — default values.
#
# Per-tenant overlay repos override only the keys that differ from these
# defaults. Keep this file as the single source of truth for what an
# Odoo instance looks like by default; do not duplicate defaults in the
# overlay schema or in Tower-Go.
instance:
# Short slug used in K8s object names + as the Helm release name.
# Must be DNS-safe (lowercase, no underscores, <= 40 chars).
code: demo
# The full HTTPS hostname this instance answers on.
# Tenants live under *.tenants.odoosky.org (covered by wildcard DNS A).
domain: demo.tenants.odoosky.org
# Named size — looked up against the `sizes` table below to derive
# CPU / memory limits + Odoo workers. Per-tenant overlays only need
# `instance.size: medium` (etc); they don't have to know the numbers.
size: small
# tenant — owning tenant identity. Required: the chart's ExternalSecret
# constructs `tenants/<tenant.id>/instances/<instance.code>/pg` from
# this value. Tower writes it into every overlay (wizard create,
# bundle-migrate, template-deploy). The `required` directive in
# templates/postgres-password-externalsecret.yaml fails loud at chart
# render time if it's missing.
tenant:
id: ""
# The named-size table. Single source of truth for what each instance
# tier actually gets. Adjust here, ALL future instances pick up the
# new defaults on next reconcile. Existing instances keep their
# previously-rendered manifests until ArgoCD re-syncs.
#
# Numbers are TOTAL across Odoo + Postgres containers. Odoo/PG split
# is roughly 70/30 (matches v2 production tuning). Workers follow
# the standard `(cpus*2 - 1)` heuristic capped by RAM headroom.
#
# tier total RAM total CPU PVC (fs/db) workers use case
# tiny 1.5 GB 1.0 5/5 GB 0 sandbox/dev only — NOT recommended for production
# small 3 GB 2.0 10/10 GB 1 515 users — RECOMMENDED MINIMUM
# medium 6 GB 4.0 20/20 GB 2 1550 users
# large 12 GB 8.0 50/50 GB 4 50150 users
# custom operator operator operator operator HA / enterprise — wizard collects all fields
sizes:
tiny:
odoo:
requests: { memory: 384Mi, cpu: 200m }
limits: { memory: 1Gi, cpu: 700m }
postgres:
requests: { memory: 128Mi, cpu: 100m }
limits: { memory: 512Mi, cpu: 300m }
storage:
filestore: 5Gi
database: 5Gi
small:
odoo:
requests: { memory: 1Gi, cpu: 500m }
limits: { memory: 2Gi, cpu: "1" }
postgres:
requests: { memory: 512Mi, cpu: 250m }
limits: { memory: 1Gi, cpu: "1" }
storage:
filestore: 10Gi
database: 10Gi
medium:
odoo:
requests: { memory: 2Gi, cpu: "1" }
limits: { memory: 4Gi, cpu: "2" }
postgres:
requests: { memory: 1Gi, cpu: 500m }
limits: { memory: 2Gi, cpu: "2" }
storage:
filestore: 25Gi
database: 25Gi
large:
odoo:
requests: { memory: 4Gi, cpu: "2" }
limits: { memory: 8Gi, cpu: "5" }
postgres:
requests: { memory: 2Gi, cpu: "1" }
limits: { memory: 4Gi, cpu: "3" }
storage:
filestore: 50Gi
database: 100Gi
# imageMirror — REQUIRED for production. Customer instances must pull
# their Odoo + Postgres images from the OdooSky-controlled registry,
# never from Docker Hub directly. Three reasons:
#
# 1. Determinism. Docker Hub's `odoo:18.0` is a rolling tag — every
# pod restart picks up whatever the latest nightly is. The 2026-05-04
# build shipped a SQL regression (now() - INTERVAL '15 minutes'
# string-quoted) that broke every login on every new pod. We pin
# to a specific date-stamped tag we tested.
# 2. Air-gap. Customers running disconnected clusters can't reach
# Docker Hub; they can reach our registry.
# 3. Rate-limit immunity. Docker Hub anonymous pulls cap at ~100/6h
# per IP. A cluster with 50 instances bouncing pods can hit that.
#
# Pinned tags are tracked in the `odoo-tower/odoosky-odoo` Gitea repo
# (versions.yaml). Bumping that repo + this file is the GitOps path
# for Odoo image updates. See the bump policy in odoosky-odoo/README.md.
imageMirror:
registry: "registry.odoosky.cloud/odoosky/docker-mirror"
# pullSecret — name of a Secret in the instance namespace carrying
# registry credentials. Provisioned per-cluster by cluster-platform-v3.
pullSecret: "docker-mirror-pull"
odoo:
image: odoo
# `tag` may be either a MAJOR reference ("18.0") or a literal pinned
# tag ("18.0-20260421"). When it's a major, the chart resolves it via
# `pinnedTags` below — that's the GitOps-clean path. Per-instance
# overlays should carry the major; the chart owns the exact nightly.
# Literal tags here are an escape hatch for staging tests.
tag: "18.0"
# pinnedTags — major → exact upstream nightly we have tested.
# MUST stay in sync with odoo-tower/odoosky-odoo/versions.yaml; that
# repo is the source of truth + bump policy. To bump:
# 1. Test the candidate nightly (see odoosky-odoo README).
# 2. Mirror it: nerdctl pull → tag → push to docker-mirror.
# 3. Update BOTH versions.yaml AND this map in the same PR.
# 4. ArgoCD reconciles; every instance of that major picks up the
# new image on next pod restart, no overlay edits.
#
# Adding a new major: add an entry here. Tower's renderer writes the
# major as `odoo.tag` — adding "17.0" / "19.0" here lights up that
# major across every instance that asks for it.
pinnedTags:
"19.0": "19.0-20260421"
"18.0": "18.0-20260421"
"17.0": "17.0-20260421"
"16.0": "16.0-20250909" # 16.0 reached EOL upstream Sep 2025; this is the final nightly
# Filestore PVC size (Odoo's /var/lib/odoo).
filestoreSize: 10Gi
# Addons selected for this instance. Each entry is a tagged image in
# the cluster-local registry (deployed by cluster-platform-v3 chart).
# The chart renders one initContainer per entry that copies the
# addon's content into a shared volume; the Odoo container reads from
# /mnt/extra-addons/<code>.
#
# Tower owns this list — it commits new entries to the tenant overlay
# AFTER ensuring the corresponding image exists in the destination
# cluster's registry (spawning a build Job from Gitea source if not).
#
# Schema:
# addons:
# - code: odoosky_demo
# version: "18.0.1.0.0"
# source: platform # platform | tenant
# image: registry.odoosky-system.svc.cluster.local:5000/addons/odoosky_demo
#
# Empty list = no extra addons; only Odoo's built-in modules.
addons: []
# Path inside the Odoo container where addons are materialized.
# Odoo's addons_path includes this dir; one folder per addon code.
# Override only if you need a non-standard layout.
addonsMountPath: /mnt/extra-addons
postgres:
image: postgres
tag: "16-alpine"
user: odoo
database: postgres
# passwordVaultPath — operator-visible advisory string carrying the
# OpenBao path Tower wrote the password to. Tower sets this on every
# overlay (it's how the operator runs `bao kv get` if they need to
# rotate the password manually). The chart's
# postgres-password-externalsecret.yaml template hardcodes the same
# path shape — this field is informational, not load-bearing for
# ExternalSecret resolution.
passwordVaultPath: ""
# externalSecretsStoreRef — ClusterSecretStore name the
# ExternalSecret references. Provisioned by cluster-platform-v3
# under `openbao-platform` by default. Override only on clusters
# that name the store differently.
externalSecretsStoreRef: openbao-platform
storage: 10Gi
backups:
enabled: true
# Cron schedule for the automatic backup job. Default 03:00 UTC
# daily — quiet hour for most timezones, non-business in EU/US/AS.
schedule: "0 3 * * *"
# How many dumps to retain in S3. The backup job prunes older
# objects matching the instance's prefix on every successful run.
retain: 7
# S3-compatible destination. The endpoint + region + bucket are
# NON-secret and live in this committed values.yaml; the AWS
# credentials live in a K8s Secret named by `credentialsSecret`,
# provisioned out-of-band by Tower's bootstrap script (which reads
# from OpenBao). The chart never sees access/secret keys directly.
s3:
endpoint: https://s3.eu-central-1.s4.mega.io
region: eu-central-1
bucket: odoosky-v3-backups
# Per-instance S3 key prefix. Each instance writes under its own
# code/ subdirectory inside the shared bucket.
prefix: "{{ .Values.instance.code }}"
# Name of the K8s Secret holding AWS_ACCESS_KEY_ID +
# AWS_SECRET_ACCESS_KEY. Mounted via envFrom on the backup Job.
credentialsSecret: s3-backup-creds
ingress:
# Traefik entrypoint name (set on the Traefik install in the
# `traefik` namespace).
entryPoint: websecure
# The pre-provisioned wildcard cert for *.tenants.odoosky.org —
# one Certificate resource issued ONCE in the chart's release
# namespace, then every instance's IngressRoute references the
# resulting Secret. Avoids Let's Encrypt's per-week certificate
# issuance ceiling (50/week/registered-domain) as we scale to
# many tenants.
#
# See infrastructure/cluster/wildcard-cert.yaml for the
# provisioning manifest.
tlsSecret: tenants-wildcard-tls
# useTenantsDefaults — when true, the IngressRoute references the
# cluster-level `tenants-default-retry` Middleware (rendered by the
# cluster-platform-v3 chart in the same `tenants` namespace).
# Default true matches the standard platform shape; flip to false
# only when running on a cluster whose Traefik install isn't
# paired with the platform's defaults Middleware set (e.g. an
# externally-managed Traefik, or cluster-platform-v3's
# `traefik.enabled` is false). Audit B.11.
useTenantsDefaults: true