First version of app upgrade.
This commit is contained in:
112
ADDING-APPS.md
112
ADDING-APPS.md
@@ -85,6 +85,118 @@ Wild Cloud uses a two-part version scheme inspired by Debian packaging: `<upstre
|
||||
|
||||
The web UI uses version comparison to detect available updates. If the deployed version differs from the wild-directory version, operators see an update indicator and can apply it from the app detail panel.
|
||||
|
||||
### Upgrade Metadata
|
||||
|
||||
Most apps can upgrade from any version to any other version directly — no special metadata is needed. The `upgrade` field is **optional** and only required when an app has breaking changes that need controlled upgrade paths.
|
||||
|
||||
**When you don't need `upgrade:`** Simple apps (Ghost, Redis, most stateless apps) where any version can safely replace any other version. This is the 90% case — just bump the version and the system handles it as a single-step update.
|
||||
|
||||
**When you need `upgrade:`** Apps with breaking database schema changes, incompatible config formats, or upstream requirements for sequential version upgrades (e.g., Discourse requires stepping through major versions).
|
||||
|
||||
#### The `upgrade` block
|
||||
|
||||
```yaml
|
||||
upgrade:
|
||||
from:
|
||||
- version: ">=3.5.0" # Can upgrade directly from 3.5.x
|
||||
- version: ">=3.4.0"
|
||||
via: "3.5.3-1" # Must pass through 3.5.x first
|
||||
- version: "<3.4.0"
|
||||
blocked: true
|
||||
notes: "Requires sequential major upgrades. See upstream docs."
|
||||
preUpgrade:
|
||||
backup: required # "none", "recommended", or "required"
|
||||
migrations:
|
||||
pre:
|
||||
- migrations/pre-deploy.yaml # K8s Job YAML paths relative to app dir
|
||||
post:
|
||||
- migrations/post-deploy.yaml
|
||||
configMigrations:
|
||||
oldKeyName: newKeyName # Renames config keys automatically
|
||||
```
|
||||
|
||||
**Fields:**
|
||||
|
||||
| Field | Description |
|
||||
|-------|-------------|
|
||||
| `from` | List of version constraint rules, evaluated in order (first match wins) |
|
||||
| `from[].version` | Version constraint: `>=`, `>`, `<=`, `<`, `=`, or `>0` (matches any) |
|
||||
| `from[].via` | Waypoint version in `.versions/` — upgrade must pass through this version first |
|
||||
| `from[].blocked` | If true, upgrade is blocked with an error message |
|
||||
| `from[].notes` | Human-readable message shown when blocked or as context |
|
||||
| `preUpgrade.backup` | Backup requirement: `"required"` blocks upgrade until backup is done, `"recommended"` shows a warning |
|
||||
| `migrations.pre` | K8s Job YAMLs to run before deploying each version step |
|
||||
| `migrations.post` | K8s Job YAMLs to run after deploying each version step |
|
||||
| `configMigrations` | Map of old config key → new config key for automatic renaming |
|
||||
|
||||
#### Waypoint versions (`.versions/` directory)
|
||||
|
||||
When an upgrade requires passing through an intermediate version, store that version's files in a `.versions/` subdirectory:
|
||||
|
||||
```
|
||||
myapp/
|
||||
├── manifest.yaml # Latest version (e.g., 3.6.0)
|
||||
├── kustomization.yaml
|
||||
├── *.yaml
|
||||
└── .versions/
|
||||
└── 3.5.3-1/ # Waypoint version
|
||||
├── manifest.yaml # version: 3.5.3-1 (with its own upgrade rules)
|
||||
├── kustomization.yaml
|
||||
└── *.yaml
|
||||
```
|
||||
|
||||
Each waypoint is a complete app package. The system computes a chain automatically — for example, upgrading from 3.4.0 to 3.6.0 might produce: `3.4.0 → 3.5.3-1 → 3.6.0`.
|
||||
|
||||
**Creating a waypoint:**
|
||||
|
||||
```bash
|
||||
mkdir -p wild-directory/myapp/.versions
|
||||
rsync -a --exclude='.versions' wild-directory/myapp/ wild-directory/myapp/.versions/3.5.3-1/
|
||||
# Now update wild-directory/myapp/manifest.yaml to the new version + upgrade rules
|
||||
```
|
||||
|
||||
#### Migration jobs
|
||||
|
||||
Migration jobs are K8s Job manifests that run database migrations or other one-time tasks during an upgrade step. They must be **idempotent** (safe to re-run) since a failed upgrade might be retried.
|
||||
|
||||
Place migration job files in the waypoint or app directory and reference them from the `migrations` field:
|
||||
|
||||
```yaml
|
||||
# migrations/db-migrate.yaml
|
||||
apiVersion: batch/v1
|
||||
kind: Job
|
||||
metadata:
|
||||
name: myapp-db-migrate
|
||||
spec:
|
||||
template:
|
||||
spec:
|
||||
restartPolicy: OnFailure
|
||||
containers:
|
||||
- name: migrate
|
||||
image: myapp:3.6.0
|
||||
command: ["bundle", "exec", "rake", "db:migrate"]
|
||||
```
|
||||
|
||||
Each migration step belongs to the version that introduces the breaking change. If version 3.6.0 requires a schema migration, the migration lives in the 3.6.0 manifest (or its waypoint), not on 3.5.x.
|
||||
|
||||
#### Example: simple app with waypoint
|
||||
|
||||
```yaml
|
||||
# myapp/manifest.yaml (version 2.0.0)
|
||||
version: 2.0.0
|
||||
upgrade:
|
||||
from:
|
||||
- version: ">=1.0.0"
|
||||
via: "1.0.0-1"
|
||||
- version: "<1.0.0"
|
||||
blocked: true
|
||||
notes: "Versions before 1.0.0 are not supported"
|
||||
preUpgrade:
|
||||
backup: recommended
|
||||
```
|
||||
|
||||
This creates a 2-step upgrade path: `1.x → 1.0.0-1 → 2.0.0`. The waypoint at `.versions/1.0.0-1/` has no `upgrade` block, so it accepts any version directly.
|
||||
|
||||
### Dependency Configuration
|
||||
|
||||
- Each dependency in `requires` can have:
|
||||
|
||||
Reference in New Issue
Block a user