From a01a0bdb23b4e2a3cb4ca4c5a772344433f6cdf3 Mon Sep 17 00:00:00 2001 From: Fredrik Ahlgren Date: Tue, 29 Sep 2026 09:50:25 +0200 Subject: [PATCH 1/3] docs: unify FTW install and update paths Signed-off-by: Fredrik Ahlgren --- .changeset/clear-update-paths.md | 5 + AGENTS.md | 84 +++------- README.md | 89 +++++------ SUPPORT.md | 5 + VISION.md | 6 + deploy/docker/compose.yaml | 4 +- docs/adr/0007-self-updating-binary.md | 39 +++-- docs/backup-and-restore.md | 5 + docs/ha-integration.md | 6 + docs/linux-packages.md | 7 +- docs/native-beta.md | 211 ++++++++++++++++++-------- docs/operations.md | 24 +-- docs/roadmap.md | 2 +- docs/rpi-image.md | 10 ++ docs/self-update.md | 64 ++++---- docs/setup-guide/README.md | 4 + docs/setup-guide/de.md | 12 +- docs/setup-guide/en.md | 11 +- docs/setup-guide/es.md | 11 +- docs/setup-guide/fr.md | 11 +- docs/setup-guide/sv.md | 11 +- docs/setup-guide/update-sv.md | 191 +++++++++++++++++++++++ docs/upgrade-from-legacy.md | 32 ++-- docs/upgrade-paired-release.md | 22 +-- scripts/install-macos.sh | 7 +- scripts/migrate-legacy-compose.sh | 7 +- scripts/upgrade-paired-release.sh | 7 +- 27 files changed, 558 insertions(+), 329 deletions(-) create mode 100644 .changeset/clear-update-paths.md create mode 100644 docs/rpi-image.md create mode 100644 docs/setup-guide/update-sv.md diff --git a/.changeset/clear-update-paths.md b/.changeset/clear-update-paths.md new file mode 100644 index 000000000..72997bc2d --- /dev/null +++ b/.changeset/clear-update-paths.md @@ -0,0 +1,5 @@ +--- +"ftw": patch +--- + +Retired installer messages now direct users to the new 0.x setup paths and explain that 2.x and 3.x receive no more updates. The scripts still exit without changing the site. Docker's missing-version message asks for an exact published new 0.x tag instead of suggesting an old example. diff --git a/AGENTS.md b/AGENTS.md index 06f850cbe..b006970e8 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -194,12 +194,16 @@ Native 0.x path: refuses because `main` has moved past `drivers-beta`, publish beta first (`-f channel=beta`), then promote. -Do not publish routine Docker releases. Existing 1.x, 2.x and 3.x installs -remain on their current version until their owner uses the guided installer -to move straight to native 0.x. Their in-app update is not the migration path. -Old beta clients may still show an already published 3.x candidate; code on -those boxes cannot be changed retroactively. The native installer must prove -backup, restore and rollback before it is offered to them. +The old lines are retired: no further 2.x or 3.x releases, including safety +hotfixes or betas. All new Core releases use the new 0.x path. Do not recommend +3.x beta as an install or intermediate upgrade. Old clients and aliases may +still offer old releases; that is not a recommendation. + +For people and agents, [Install and update FTW](docs/native-beta.md) is the +single entry point. An owner can switch now with a second SD card/host or a +separate Docker project and new data. Guided migration of settings and history +has not shipped. Keep the old data, verify backup and recovery, and confirm +that only one Core controls the equipment, including after reboot. ### Who releases, and when @@ -221,66 +225,14 @@ The native workflow is dispatched by the owner. The weekly beta cadence in first native pilot; a merge does not publish a beta. Stable follows the week-long site check above. -### Exceptional repair on the old Docker line - -Only a critical safety fix that cannot wait for guided migration may use the -old 2.x workflows. This is a separate owner decision, not part of the native -release path. Start from the affected stable 2.x tag: - -1. `git checkout -b hotfix/vX.Y vX.Y.Z` from the affected stable tag. -2. Land the fix on the branch — cherry-pick from master when it is - already fixed there, otherwise fix it here AND on master. A hotfix - that misses master regresses at the next release. -3. Add the changeset and run `npx changeset version` on the branch, - then commit. The Version Packages bot only serves master; on a - hotfix branch changesets runs by hand, which still counts as - "changesets edits the version, not you". -4. If the old branch needs workflow fixes, use the checked workflow code from - master while keeping binaries tied to the immutable hotfix tag. -5. `gh workflow run beta.yml --ref hotfix/vX.Y -f version=vX.Y.-beta.1` -6. Validate on an affected site, pinned explicitly via - `POST /api/version/update`. -7. `gh workflow run release.yml --ref vX.Y.-beta.1 -f source_beta=vX.Y.-beta.1` - -The old public latest and Docker aliases stay on 2.x. Do not use this path -for 1.x, 3.x or native 0.x. The new native release workflow never moves those -old discovery targets. - -Do not create a new beta, tag, draft or candidate to recover a failed -stable publish. Resume the existing draft by its numeric GitHub Release -id, with workflow code from `master` and binaries from the immutable -tag. GitHub 5xx is an external retry condition, not a reason to rebuild -the candidate. - -See [docs/self-update.md](docs/self-update.md). - -A release is one workflow dispatch, not a manual list of registry commands. -The following registry and Home Assistant dispatch steps apply only to an -exceptional old Docker release. The `srcfl/*` images use the job-scoped -`GITHUB_TOKEN`; each package must grant -the `srcfl/ftw` repository GitHub Actions write access. The compatibility -`frahlg/*` mirror uses the dedicated `LEGACY_GHCR_TOKEN`, with only -`write:packages`. Never use a developer's local `gh` token, create a new token -for each release, or fall back to `GITHUB_TOKEN` for the personal namespace. - -Registry credentials and package access are repository setup, not release -steps. Before creating a beta tag or starting stable publication, the release -workflows request a scoped `pull,push` bearer and start an empty GHCR blob -upload in all four target packages. HTTP 202 proves write access without -creating a blob, manifest, package version or tag. The workflow then tries to -cancel the empty session. GHCR currently returns HTTP 405 for that optional -cleanup, which is accepted; any other unexpected cleanup result fails the -check. If the write check fails, stop, repair package access or rotate the one -dedicated secret, then rerun the same immutable version. Do not mint another -beta tag to work around an access failure. -The Home Assistant app repository, `srcfl/home-assistant-addons`, follows -every release on its own. `beta.yml` and `release-assets.yml` end by sending -it a `repository_dispatch` of type `ftw-release`, authenticated with the -secret `HA_ADDON_DISPATCH_TOKEN`: a fine-grained token with *Contents: read -and write* on that repository only. Without the secret the step logs a notice -and the app repository picks the release up on its hourly sync. The dispatch -never blocks a release, and the app repository verifies the release against -its digest receipt and the registry rather than trusting the payload. +### Retired release tooling + +The old Docker workflows, tags and receipts describe past releases and remain +for recovery and audit. Their presence is not authority to cut another 2.x or +3.x release. Do not dispatch them or the old Home Assistant publication path. +Do not move old `latest` aliases to 0.x: installed old clients cannot migrate +through them. Use [docs/self-update.md](docs/self-update.md) for current release +and operator rules. `CLAUDE.md` imports this file, so these rules apply to Claude and Codex alike. diff --git a/README.md b/README.md index fc29b007c..0e912fb22 100644 --- a/README.md +++ b/README.md @@ -92,64 +92,44 @@ driver actually changed. ## Install on Linux -You install FTW yourself and choose how it runs: natively with systemd, or in -Docker. Both use the same checksummed release package. 0.x is in beta; -[docs/native-beta.md](docs/native-beta.md) has both paths, the everyday -commands and recovery. On a fresh 64-bit Raspberry Pi OS, Debian or Ubuntu -host, the native install is: - -```bash -tag=v0.137.1-beta.1 # the newest beta on the Releases page -curl -fsSLO "https://raw.githubusercontent.com/srcfl/ftw/${tag}/scripts/install.sh" -bash install.sh --fresh-host --tag "${tag}" -``` - -`--fresh-host` confirms there is no -existing FTW site, even a stopped Docker site in a custom directory. The -installer checks the package and checksum, creates native release slots under -`/opt/ftw`, and starts the local -Core service. It does not install Docker. Open `http://:8080/setup` on -the LAN, then check storage health and live device readings. If the first -install is interrupted, use `--resume --tag` with the same tag after checking -the service log; it keeps any data the first attempt created. - -Give the FTW machine a DHCP reservation (a fixed IP) in your router. Devices -that dial in to FTW — OCPP chargers store their backend URL at commissioning, -and some hardware whitelists which addresses may talk to it — silently lose -the connection if DHCP later hands the host a different address. - -Existing 1.x, 2.x, 3.x and earlier native sites stay on their current version -until the guided 0.x migration is ready. The fresh installer refuses them; do -not use Update or old Docker migration scripts to cross release lines. - -The on-box dashboard remains local. The optional +**2.x and 3.x will receive no further updates. New releases use the new 0.x +line. Switch now to follow the latest fixes and features; do not install +3.x beta or use it as an intermediate upgrade.** + +Start with [Install and update FTW](docs/native-beta.md) +([Svenska](docs/setup-guide/update-sv.md)). It covers old Docker images, +Raspberry Pi SD-card images, 1.x/2.x/3.x, older native sites, new native and +Docker installs, Home Assistant, backup, and recovery. + +The new line starts at `v0.131.0-beta.1`; old 0.x releases up to 0.130.x are +also retired. A lower version number or a saved `beta` channel does not tell +you which install path you have. Identify it before running commands. + +Use a fresh 64-bit Raspberry Pi OS, Debian or Ubuntu host for native systemd, +or run the same release package in Docker on Linux. Existing sites can switch +using a second SD card/host or a separate Docker project with new data. The +guided migration of settings and history is not ready; preserve the old data +and get help if those data must move before you switch. Only one Core may +control the equipment, including after reboot. + +Give the FTW host a DHCP reservation in the router so device connections keep +working. Open `http://:8080/setup` after installation. The optional [FTW webapp](https://github.com/srcfl/ftw-webapp) connects through an encrypted -session and blind relay; relay loss does not stop local control. Cloud MCP -access is a product goal, not an endpoint provided by this installation guide. +session and blind relay; relay loss does not stop local control. ## Install on Home Assistant -The official Home Assistant app repository is -[`srcfl/home-assistant-addons`](https://github.com/srcfl/home-assistant-addons). -It publishes beta builds of the older 3.x line; the 0.x line is not in the -app yet. There is no stable app — Home Assistant OS and Supervisor -qualification has to finish first — so treat it as a beta rather than a -production install. - -Open **Settings → Apps → App store → Repositories** in Home Assistant and -add: - -```text -https://github.com/srcfl/home-assistant-addons -``` +The existing [Home Assistant app](https://github.com/srcfl/home-assistant-addons) +is on the retired 3.x line. It does not follow new 0.x releases. Do not install +that beta to get current FTW. Run new FTW on a separate Linux host and use the +[MQTT integration](docs/ha-integration.md) with Home Assistant. -Check the add-on repository's -[compatibility record](https://github.com/srcfl/home-assistant-addons/blob/main/COMPATIBILITY.md) -before each install or update. Report Home Assistant install, update, backup, -restore, or container faults in its -[issue tracker](https://github.com/srcfl/home-assistant-addons/issues). -Report Core, API, UI, control, or state faults in this repository. Report driver -faults to [`srcfl/device-drivers`](https://github.com/srcfl/device-drivers/issues). +Follow [the switch guide](docs/native-beta.md#coming-from-an-older-ftw), including +backup and stopping the old app's Core, Start on boot and Watchdog. Supervisor +still owns recovery of the old app; its update controls do not migrate to 0.x. +Report old app or Supervisor faults in its +[issue tracker](https://github.com/srcfl/home-assistant-addons/issues), and Core +faults in this repository. ## Local development @@ -230,8 +210,7 @@ Changesets produce versions and changelog entries; the native release workflow builds the checksummed Linux packages that the installer, `ftw update` and the Docker files use. The repository owner cuts every release. Details for operators are in [docs/self-update.md](docs/self-update.md); the -full maintainer rules, including the exceptional repair path for the old -Docker line, are in the Releases section of [AGENTS.md](AGENTS.md). +maintainer rules are in the Releases section of [AGENTS.md](AGENTS.md). ## Documentation diff --git a/SUPPORT.md b/SUPPORT.md index cac72403e..5c0e85dda 100644 --- a/SUPPORT.md +++ b/SUPPORT.md @@ -5,6 +5,11 @@ Sourceful Energy (Sourceful Labs AB). Fredrik owns the product direction. ## Community support +For installation or update help, start with [Install and update FTW](docs/native-beta.md) +([Svenska](docs/setup-guide/update-sv.md)). Include the running version and +install type when asking for help. 2.x and 3.x receive no further updates; +the guide explains how to switch to new 0.x and keep a recovery path. + The Community edition is provided as-is, without official support, guaranteed response times, service-level commitments, or warranties. The AGPL in LICENSE and the separate Energyplan binary license contain diff --git a/VISION.md b/VISION.md index d3aedd9f0..ba20a5940 100644 --- a/VISION.md +++ b/VISION.md @@ -212,6 +212,12 @@ continues the earlier 0.x counter at 0.131 so tags that were already published stay unique. [ADR 0007](docs/adr/0007-self-updating-binary.md) records that choice. +2.x and 3.x receive no more updates. All new releases use the new 0.x line. +People who want current fixes and features should switch now using the +[install and update guide](docs/native-beta.md). A new setup is available; +guided migration of old data remains work to prove. Do not recommend 3.x beta +as a new install or a step towards the new line. + ## Running it, updating it, and a later hosted service A person who runs FTW on their own machine is using an early project that diff --git a/deploy/docker/compose.yaml b/deploy/docker/compose.yaml index 611b09e04..af38a2d07 100644 --- a/deploy/docker/compose.yaml +++ b/deploy/docker/compose.yaml @@ -2,7 +2,7 @@ # with FTW_VERSION in one directory, then see docs/native-beta.md: # # mkdir -p data && sudo chown 100:101 data -# echo FTW_VERSION=v0.135.1-beta.1 > .env +# echo FTW_VERSION=v0.X.Y-beta.N > .env # replace with an exact published tag # docker compose up -d --build # # Update: change FTW_VERSION in .env and run `docker compose up -d --build`. @@ -17,7 +17,7 @@ services: build: context: . args: - FTW_VERSION: ${FTW_VERSION:?Set FTW_VERSION in .env, for example FTW_VERSION=v0.135.1-beta.1} + FTW_VERSION: ${FTW_VERSION:?Set FTW_VERSION in .env to an exact published new 0.x tag} image: ftw-local:${FTW_VERSION} restart: unless-stopped # Core saves its state on a clean stop. diff --git a/docs/adr/0007-self-updating-binary.md b/docs/adr/0007-self-updating-binary.md index 5d2009822..10b5754de 100644 --- a/docs/adr/0007-self-updating-binary.md +++ b/docs/adr/0007-self-updating-binary.md @@ -13,6 +13,14 @@ and the Compose and `.env` pinning of the older Docker lines. [self-update.md](../self-update.md) describes what ships. +## Current release policy (29 September 2026) + +2.x and 3.x receive no further updates, including hotfixes and betas. All new +Core releases use the new 0.x line. Do not recommend 3.x beta. Owners can +switch now using a separate new setup; guided migration of old data remains +unshipped. [Install and update FTW](../native-beta.md) is the current operator +guide. The context below describes the earlier system, not current advice. + ## Context The update path is the largest piece of non-control code in Core, and it is @@ -134,16 +142,16 @@ to it. No native update needs a Docker socket or Docker engine.** [`deploy/ftw-native.service`](../../deploy/ftw-native.service), or runs FTW in Docker. The monthly image, its Imager listing and the `rpi-installer` release are removed. Cards flashed from the image keep - Docker 2.x until the guided migration. + old Docker until their owners switch; use a second card for a new setup now. 7. **New Docker packaging builds from the release package.** [`deploy/docker`](../../deploy/docker) holds a Compose file with one Core service and a Dockerfile that installs the same checksummed package as the native installer. There is no sidecar, `update-ipc` volume, broker or published image. The owner updates by setting `FTW_VERSION` and running - `docker compose up -d --build`. Existing 1.x, 2.x and 3.x Docker installs - remain in place until their owners use the guided migration. The Home - Assistant add-on stays on Supervisor. + `docker compose up -d --build`. Existing sites can switch with separate + data now. Guided migration of old data remains a goal to prove. The old + Home Assistant app stays on Supervisor and does not follow new 0.x. 8. **Betas aim for a weekly cadence.** The owner dispatches `native-release.yml` after a Version Packages merge. Once the first @@ -152,14 +160,14 @@ to it. No native update needs a Docker socket or Docker engine.** on the home box and at least one other site. 9. **Transition code is deleted only after the affected boxes have migrated - or left support.** A 3.5 version check is not enough: 1.x and 2.x boxes - stay on their line until the new installer is proven. Remove each old path - after checking the box inventory and its recovery need. Keep the legacy + or no longer need it.** A version check is not enough: older boxes may + still need their recovery path while owners move to new setups. Remove each + old path after checking the box inventory and its recovery need. Keep the legacy state-schema marker while any supported reader still needs it. Code on `master` that only an installed 1.x, 2.x or 3.x box would run is not part - of their migration: those boxes run their installed binaries, and a 2.x - repair builds from its own branch. `master` keeps what the migration and - its way back need. + of their migration: those boxes still run their installed binaries. + No further 2.x or 3.x releases will change them. `master` keeps what the + migration and its way back need. 10. **The owner operates the host.** FTW's own work is the EMS and the Energy Planner. The service manager, when to update, copies of backups @@ -220,8 +228,8 @@ anything may change, and that is the true state of FTW. 1. **The first binary release is `v0.131.0`.** It continues the counter that stopped at `v0.130.4`; those tags exist and cannot be reused. The old - Docker lines stop receiving routine releases. A critical safety fix may - still need an old-line release before a site can migrate. + Docker lines receive no further releases, including critical fixes. + Owners who want current fixes use the new 0.x line. 2. **The reset happens at the native cutover, and nowhere else.** No Docker box uses Update Center to move between the 1.x/2.x, 3.x and native 0.x @@ -252,8 +260,9 @@ anything may change, and that is the true state of FTW. ## What is lost -- **In-app update on Docker installs.** Old installations stay where they are. - An owner who wants a new version uses the guided move to native 0.x. +- **In-app update on old Docker installs.** The old button cannot move a site + to new 0.x. Owners can switch now with a separate setup; preserving old data + through guided migration remains a goal. The old code cannot have its update button removed retroactively. - **In-app update on Windows and macOS.** Manual replacement stays until a launcher exists for those platforms. @@ -308,7 +317,7 @@ anything may change, and that is the true state of FTW. above. - **Release publication must preserve the old stable slot.** #1313 remains a user-visible gap. Native 0.x publication must not move GitHub latest or old - Docker latest away from the 2.x maintenance line. + Docker latest away from the retired 2.x line. - **Risk: the launcher is new and small, and it must be right.** It gets a shell test suite that runs every branch of its decision, and the home box runs an induced crash during a trial before this is accepted. diff --git a/docs/backup-and-restore.md b/docs/backup-and-restore.md index 6e1bc67ac..6d936d762 100644 --- a/docs/backup-and-restore.md +++ b/docs/backup-and-restore.md @@ -1,5 +1,10 @@ # Full backup and safe restore +For a move from an older FTW, start with [Install and update FTW](native-beta.md). +2.x and 3.x receive no more updates. A backup is recovery material, not an +automatic migration to new 0.x. Use the tools and archive format supported by +the installed version; not every older release has the Full backups UI below. + A full backup (`.ftwbak`) recovers a site after a failed disk, a reinstall or a release that changed the stored data, once a copy is on another disk or computer. Local rollback does not replace it. diff --git a/docs/ha-integration.md b/docs/ha-integration.md index 8503fb7da..f49e1f1bc 100644 --- a/docs/ha-integration.md +++ b/docs/ha-integration.md @@ -1,5 +1,11 @@ # Home Assistant +This MQTT integration works with new FTW running on a separate Linux host. +The old Home Assistant app is on retired 3.x and does not follow new 0.x +releases. Do not install its beta to get current FTW. Follow +[Install and update FTW](native-beta.md), including stopping the old app's +Core and automatic start before the new host controls the equipment. + FTW publishes MQTT autodiscovery and state, and accepts a small command set. The bridge is optional and does not participate in the local safety loop. diff --git a/docs/linux-packages.md b/docs/linux-packages.md index dcd4c59a7..e6a3f3179 100644 --- a/docs/linux-packages.md +++ b/docs/linux-packages.md @@ -16,9 +16,10 @@ The web UI only shows the version. `install.sh --refresh` replaces the launcher, the command and the unit when a release asks for it. Do not copy a package into `/opt/ftw` by hand: the launcher expects the slot layout. -The installer is not the guided migration for an existing Docker, Home -Assistant or earlier native box. Those boxes stay on their current version -until the guided 0.x migration has been tested and published. +The installer does not migrate an existing Docker, Home Assistant or older +native site. Use [Install and update FTW](native-beta.md) to switch with +separate data now. Guided transfer of old settings and history is not ready. +2.x and 3.x receive no more updates; do not install 3.x beta. [`deploy/docker`](../deploy/docker) builds a local image from the same package. diff --git a/docs/native-beta.md b/docs/native-beta.md index 6cb9a08cf..88a921d0e 100644 --- a/docs/native-beta.md +++ b/docs/native-beta.md @@ -1,17 +1,57 @@ -# Try the 0.x beta +# Install and update FTW -This guide is for people who test the 0.x beta on their own machine. You -run the host; FTW gives you a few commands for it -([ADR 0007](adr/0007-self-updating-binary.md), decisions 10–14). Install it -natively with systemd, or run it in Docker. Both run the same release -package. Report what you find in an issue that names the beta, for example -`v0.138.0-beta.1`. +**FTW 2.x and 3.x will receive no further updates. All new development and +releases use the new 0.x line. Move to it now to follow the latest fixes and +features. Do not install 3.x beta or use it as an intermediate upgrade.** + +The new line starts at `v0.131.0-beta.1`. Older 0.x releases, up to 0.130.x, +belong to the retired line too. The lower version number is deliberate. +Choosing `beta` in an old installation does not move it to the new line. + +You can switch now with a new setup and separate data. The guided migration +that preserves old settings, history, identity and goals is not ready yet. +If you need those data moved before switching, get help for your exact +installation; do not copy old databases into a new install. + +Use this guide for both people and agents. [Svenska](setup-guide/update-sv.md). +The owner runs the host; FTW supplies the commands. Native systemd and Docker +on 64-bit Linux use the same release package. + +## Choose your path + +| What runs now | How to switch or update | +|---|---| +| Old Docker: 0.x up to 0.130.x, 1.x or 2.x, including Forty Two Watts images | [Switch from an older FTW](#coming-from-an-older-ftw). Use a new SD card/host, or separate Docker project and data. | +| Docker 3.x, including beta | The same switch. No intermediate release and no further 3.x updates. | +| The old ready-made FTW Raspberry Pi image | It runs old Docker. Use a second card with Raspberry Pi OS Lite 64-bit; keep the old card. | +| New 0.x native with launcher/release slots | [Update the native box](#update-a-native-box). Do not reinstall. | +| New 0.x Docker built from the release package | [Change `FTW_VERSION` and rebuild](#docker). `ftw update` does not apply. | +| Older direct native service without release slots | Identify its unit and data paths first. Use a separate host/card, or a checked migration for that site. The [native migration pilot](self-update.md#pilot-an-older-native-systemd-site) is not a general installer. | +| Home Assistant app on the old line | Run new FTW on another Linux host. Stop the old app and its automatic start/watchdog before new Core controls the equipment. The app does not provide new 0.x yet. | +| Custom build, manual binary, macOS or Windows | Identify the process and data first. The release install paths here require 64-bit Linux. | + +### Find out what is running + +Run these read-only checks on the FTW host, through SSH if needed: + +```bash +sudo docker ps -a --format 'table {{.ID}}\t{{.Names}}\t{{.Image}}\t{{.Status}}' +sudo docker compose ls -a +systemctl list-units --type=service --all --no-pager | grep -Ei 'ftw|forty|docker' +systemctl list-unit-files --type=service --no-pager | grep -Ei 'ftw|forty' +``` + +Record the version and dashboard address too. A missing command or permission +error does not prove that no other install exists. Check other hosts, custom +start scripts and Home Assistant if used. A stored Docker image is not a +running Core; inspect containers and their restart rules. A service called +`ftw`, or `ftw status` answering from port 8080, does not identify its layout. ## Before you start - A 64-bit Linux host: a Raspberry Pi 4 or 5 with Raspberry Pi OS Lite 64-bit (Bookworm or Trixie), Debian 12 or 13, or an x86_64 machine. -- Running FTW 1.x, 2.x or 3.x already, perhaps from the Raspberry Pi image? +- Running any older FTW already, perhaps from the Raspberry Pi image? Read [Coming from an older FTW](#coming-from-an-older-ftw) first. - Port 8080 free, `curl`, and `sudo`. - FTW needs no MQTT broker of its own. Ferroamp and CTEK equipment runs @@ -23,10 +63,15 @@ package. Report what you find in an issue that names the beta, for example ## Install -Use the installer from the same tag you install: +Choose an exact published new 0.x beta from [Releases](https://github.com/srcfl/ftw/releases). +Check that it includes the Linux package for your architecture and its SHA-256 +file. Do not use `releases/latest`: it still points to the retired 2.x line. +Replace `v0.X.Y-beta.N` below with that tag and use its own installer. +`--fresh-host` confirms that this host has no existing FTW site, including +stopped containers or data in a custom directory: ```bash -tag=v0.138.0-beta.1 +tag=v0.X.Y-beta.N curl -fsSLO "https://raw.githubusercontent.com/srcfl/ftw/${tag}/scripts/install.sh" bash install.sh --fresh-host --tag "${tag}" ``` @@ -40,51 +85,77 @@ To run it in Docker instead, see [Docker](#docker). ## Coming from an older FTW -Most sites run FTW 1.x, 2.x or 3.x in Docker, many from the Raspberry Pi -image. The beta does not move their settings or history yet; that comes with -the guided migration. Try it beside the old installation instead. The old one -and its data stay as they are, and switching back takes a minute. - -Never run both at once: they would control the same equipment. The beta will -not start while the old one holds port 8080, but an old 1.x-3.x Core started -while the beta runs keeps controlling in the background, without its web -page. So stop the old one before the beta, and the beta before the old one. - -**On a Raspberry Pi, use a second SD card.** This is the safest way. - -1. Write Raspberry Pi OS Lite (64-bit) to a new card with Raspberry Pi - Imager, as in the [setup guide](setup-guide/README.md). Choose a username - other than `ftw`: the installer creates its own `ftw` account, and cards - made from the FTW image used that name for the login. -2. Shut the Pi down, swap the cards, start it and follow [Install](#install). - Set the site up again at `http://:8080/setup`. -3. To go back, shut down and put the old card back. - -**On the same machine, run the beta in Docker.** Stop the old stack, then -follow [Docker](#docker); the beta lives in its own folder, `~/ftw-local`. - -```bash -cd /opt/ftw && sudo docker compose down # the Raspberry Pi image -cd ~/ftw && docker compose down # the Docker installer (1.x: ~/forty-two-watts) -``` - -To go back, stop the beta first, then start the old stack. Its data was never -touched; what the beta recorded stays in `~/ftw-local/data` for next time. - -```bash -cd ~/ftw-local && docker compose down -cd /opt/ftw && sudo docker compose up -d # or ~/ftw, ~/forty-two-watts -``` - -- The old stack's Mosquitto stops with it. Pixii and Heishamon then need - [a broker](#an-mqtt-broker). -- The native installer refuses a machine that still has an older FTW: it - finds `/opt/ftw`, `~/ftw` or an `ftw` account. Installing natively over an - old site is the guided migration. -- On Home Assistant, keep the add-on and try the beta on another machine. +Move directly to the new line using one of the paths below. Keep the old +installation and its data for recovery; the new setup does not import them. +Before switching, save device addresses, goals and schedules, and make a +verified full backup using the tools your installed version supports. Keep +that backup off the host. Not every old version has the same backup UI. +Calendar support is gone: use loadpoint targets and ready-by schedules. + +**Only one Core may control the equipment.** An old Core can keep controlling +when it fails to bind port 8080 and has no working web page. A single visible +dashboard is not proof that only one Core runs. Stop old Core before starting +new Core, and stop new Core before returning to the old install. + +### Raspberry Pi: use a second SD card + +1. Keep the old card intact. Write Raspberry Pi OS Lite **64-bit** to a **new** + card, as in the [setup guide](setup-guide/README.md). Choose a login name + other than `ftw`; the installer creates that service account. +2. Shut the Pi down, swap cards, start it and follow [Install](#install). + Set up the site again at `http://:8080/setup`. +3. If the old card supplied MQTT, provide a broker for the new setup before + connecting the devices. The old card's broker does not move with FTW. +4. Follow [Verify the switch](#verify-the-switch). + +To return, shut down and put the old card back. Also stop any new FTW you ran +on another machine. Data collected by the new setup stays on the new card. + +### Same Linux host: use a separate Docker project + +1. Identify the old project's directory, Compose files, overrides, name and + data mounts. Common paths are `/opt/ftw` on the old Pi image, `~/ftw` and + `~/forty-two-watts`; use the path found on this host. Save its Compose files + and `.env` with the backup so recovery uses the same old version. +2. Check whether that project also supplies Mosquitto or another needed + service. Arrange continued MQTT before stopping the whole project. +3. Stop the old project with its actual files and project name. For a standard + project, run `docker compose down` from its directory (with `sudo` if + required). Do not add `-v`, delete data, or stop Docker as a whole. +4. Check systemd, timers and custom scripts that could recreate or start old + Core or its updater at boot. Disable only the confirmed old start path. + Docker's container restart policy is only one possible start path. +5. Follow [Docker](#docker) in a new directory with separate empty data, + normally `~/ftw-local`. If that directory already exists, inspect it first; + do not overwrite an earlier test or attach the old data directory. +6. Set up the site and follow [Verify the switch](#verify-the-switch). + +To return, stop the new project first, then start the saved old project with +its original files and version pin. Restore only the start rules you disabled. +Each installation keeps its own data. + +The native installer refuses an existing site. Do not remove its checks or +old files to make `--fresh-host` pass. Home Assistant users need another Linux +host for the new line; the old app is not an intermediate upgrade. Stop its +Core, Start on boot and Watchdog before the new site takes control. Keep a +Home Assistant backup and the old app's data for recovery. The MQTT integration +with a separate FTW host still works; see [Home Assistant](ha-integration.md). + +## Verify the switch + +Check the expected running version, healthy devices, advancing measurements, +current plan and history without write failures. Confirm that old Core and +its updater are stopped and cannot start again automatically. Check all hosts +that could control the equipment; port 8080 alone is not a check for this. + +Plan a reboot when the site can tolerate the interruption, then repeat these +checks. If you have not checked after reboot, say so. Service health does not +prove physical charging or battery response; verify those on the equipment. ## Everyday commands +These commands are for the new **native** installation with release slots. + ```bash ftw status # version, releases, last update, disk, health ftw update # install the next release on the saved channel @@ -191,10 +262,10 @@ suits a trusted home network; otherwise add a `password_file`. `ftw update` replaces Core, not the launcher, the `ftw` command or the service definition. When a release notes changes to them, refresh them with -the installer from that release: +the installer from that release. Replace the placeholder with its exact tag: ```bash -tag=v0.138.0-beta.1 +tag=v0.X.Y-beta.N curl -fsSLO "https://raw.githubusercontent.com/srcfl/ftw/${tag}/scripts/install.sh" bash install.sh --refresh --tag "${tag}" ``` @@ -204,14 +275,18 @@ bash install.sh --refresh --tag "${tag}" Docker runs FTW as well as the native install does. Compose builds a small local image from the same checksummed release package; nothing is compiled. You need Docker Engine with Compose on Linux. Docker Desktop on macOS or -Windows keeps the network inside its VM and cannot reach the equipment. +Windows has a different network setup; this Linux host-network recipe does +not establish LAN device access there. Choose an exact published new 0.x tag +as described under [Install](#install). Replace the placeholder below. These +steps create a new site; use an empty directory, not an existing install. ```bash +tag=v0.X.Y-beta.N mkdir -p ~/ftw-local && cd ~/ftw-local -base=https://raw.githubusercontent.com/srcfl/ftw/master/deploy/docker +base="https://raw.githubusercontent.com/srcfl/ftw/${tag}/deploy/docker" curl -fsSLO "${base}/compose.yaml" -O "${base}/Dockerfile" mkdir -p data && sudo chown 100:101 data -echo "FTW_VERSION=v0.138.0-beta.1" > .env +printf 'FTW_VERSION=%s\n' "$tag" > .env docker compose up -d --build ``` @@ -228,12 +303,14 @@ docker compose restart # restart ``` To update, set the new version and rebuild. To go back, set the previous -version; its image is still on the host, so nothing is fetched. Going back +version. If its image is still on the host, Compose can reuse it. Going back works while both releases read the same data, as on a native install. ```bash -sed -i 's/^FTW_VERSION=.*/FTW_VERSION=v0.138.0-beta.1/' .env +# Edit only FTW_VERSION in .env to the chosen exact release; keep other entries. docker compose up -d --build +docker compose ps +docker compose exec ftw ftw status ``` Docker has no automatic fallback. A release that does not start keeps @@ -265,6 +342,17 @@ Give this section to an agent that operates FTW for you. FTW controls real equipment, so the agent uses the same commands a person would and leaves decisions about the site to you. +- Identify the host, running version, process/service or Compose project, + data paths, restart rules and target release before changing anything. Use + [Choose your path](#choose-your-path), including for older 0.x versions. +- Distinguish an update within the new line, a new setup with separate data, + and a migration preserving data. Do not recommend or publish 2.x or 3.x, + even if an old UI or a `latest` alias offers one. +- A diagnosis is read-only. Once the owner has authorized a specific update, + carry it through without asking again for the same action. +- For a switch, confirm an off-host backup, preserve MQTT and stop the old + control/start paths. Report the checks in [Verify the switch](#verify-the-switch), + including anything not tested, before calling the switch complete. - Read the state with `ftw status`. Exit 0 means Core answers and is healthy; exit 1 means it is not, and stderr says why. Exit 2 is a usage error. The commands never prompt. @@ -272,8 +360,9 @@ decisions about the site to you. it. Exit 0 means the box is current or updated. Exit 1 means a step failed; report `ftw status` and `journalctl -u ftw -n 200`, and do not repeat the update. -- Ask the owner before `ftw update --retry`, `ftw rollback`, a restore or - the offline rollback in [When something goes wrong](#when-something-goes-wrong). +- Use `ftw update --retry`, rollback or restore only within the owner's + authorized recovery plan. If that authority is missing, ask before changing + the site. Do not retry a failed update blindly. - Before an update the owner cares about, run `ftw backup --output-dir `. - Change settings in the web UI or the API. Do not edit files in diff --git a/docs/operations.md b/docs/operations.md index 444c7f02b..53bc96187 100644 --- a/docs/operations.md +++ b/docs/operations.md @@ -1,16 +1,17 @@ # Operations -New sites run native 0.x under systemd, or the same release package in -Docker. Older Docker installs (1.x–3.x) stay on their current version until -the guided migration ships. The control loop is local; Energyplan ships with -Core and Core falls back safely when it is unavailable. +New sites run new 0.x under systemd, or the same release package in Docker. +2.x and 3.x receive no further updates. Switch using +[Install and update FTW](native-beta.md); it covers every old and new layout. +A new setup is available now; guided migration of old data is not ready. +The control loop is local; Energyplan ships with Core and Core falls back +safely when it is unavailable. ## Install -[Try the 0.x beta](native-beta.md) is the full guide and names the current -beta. Use the installer from the same tag you install, on a fresh 64-bit -Raspberry Pi OS, Debian or Ubuntu host. During beta, use it only on an agreed -test site: +[Install and update FTW](native-beta.md) is the full guide and explains how +to choose a published new 0.x beta. Use the installer from the same tag you +install, on a fresh 64-bit Raspberry Pi OS, Debian or Ubuntu host: ```bash tag=v0.X.Y-beta.N # the exact release chosen for this site @@ -29,9 +30,10 @@ rerun with `--resume --tag` and the same tag. It keeps any data already saved. Docker runs the same release package; see [Docker](native-beta.md#docker). -Existing Docker, Home Assistant and earlier native installations stay on -their current version until the guided 0.x migration is tested. No native -0.x package for macOS has shipped; the old macOS Docker installer is retired. +Existing Docker, Home Assistant and older native sites can switch with a +separate new setup; preserve old data and follow the one-Core checks in the +guide. No native 0.x package for macOS has shipped; the old macOS Docker +installer is retired. ## Everyday commands diff --git a/docs/roadmap.md b/docs/roadmap.md index 247f11ccf..c74d2e959 100644 --- a/docs/roadmap.md +++ b/docs/roadmap.md @@ -75,7 +75,7 @@ or reopen closed issues. | Useful analysis and fair savings | Keep enough provenance to explain plans and outcomes. Main savings target compares with ordinary self-consumption on the same installation. | Actual cost reconciles with measured import/export and prices. Specify EV behaviour, initial and final stored-energy accounting, efficiency and coverage. Show missing and negative results. Label the current no-PV/no-battery comparison as total site value until replacement is verified. | | External automation and agent access | Give authorized clients structured analysis data, schedule/goal changes and proposed-plan submission. Temporary external control expires; durable goals persist. Support local access and secure cloud MCP access. | Paired Core/client contract tests cover permissions, expiry, replay, rejection, revocation and reconnect. An agent can trace a request through to measured outcome. Prove local fallback when the caller disappears. Reuse the session/relay where suitable and verify that relay and escrow remain blind. Cloud MCP is a target, not a claim of a shipped endpoint. | | Less configuration, reliable operation | Every normal setting serves a user need. Keep expert controls discoverable. Installation, updates, backup and recovery remain part of the finished experience. | Audit settings and feature use before removal. Test migration of stored choices so hidden settings cannot keep directing behaviour. Verify restart, upgrade and restore on a target box and review affected UI flows. | -| Updates the owner runs | The owner operates the host; FTW supplies the steps. `ftw update` runs unattended, falls back on its own when a new release does not stay up, and makes a verified full backup before a change to stored data. The same steps are API calls, so owners and their agents can wrap them. On native, the web UI shows the version and the release notice only. The installer and the Docker migration produce one native layout. | The evidence list in [ADR 0007](adr/0007-self-updating-binary.md#evidence-required-before-rollout), on the home box and one other site: update and rollback timings, a crash during and just after the trial, a slow first start, a state-schema change and its way back, an unattended run, disk use after ten updates, a freshly flashed Pi image, and a Docker 2.x or 3.x box moved to native with a tested return to its old installation. | +| Updates the owner runs | The owner operates the host; FTW supplies the steps. `ftw update` runs unattended, falls back on its own when a new release does not stay up, and makes a verified full backup before a change to stored data. The same steps are API calls, so owners and their agents can wrap them. On native, the web UI shows the version and the release notice only. The installer and the Docker migration produce one native layout. | The evidence list in [ADR 0007](adr/0007-self-updating-binary.md#evidence-required-before-rollout), on the home box and one other site: update and rollback timings, a crash during and just after the trial, a slow first start, a state-schema change and its way back, an unattended run, disk use after ten updates, a fresh Raspberry Pi OS card, and a Docker 2.x or 3.x box moved to native with a tested return to its old installation. The new setup paths ship now; guided transfer of old data remains unshipped. 2.x and 3.x receive no further updates. | Safety is part of each row. Core remains the only dispatch authority, every plan is untrusted input, stale required site-meter data stops dispatch, and diff --git a/docs/rpi-image.md b/docs/rpi-image.md new file mode 100644 index 000000000..915cb7d8c --- /dev/null +++ b/docs/rpi-image.md @@ -0,0 +1,10 @@ +# The old FTW Raspberry Pi image is retired + +Do not flash the old FTW image for a new installation. It runs the retired +Docker line. 2.x and 3.x receive no further updates; do not install 3.x beta. + +Use Raspberry Pi OS Lite **64-bit** and follow +[Install and update FTW](native-beta.md) ([Svenska](setup-guide/update-sv.md)). +If your Pi already runs FTW, use a **second SD card** and keep the old one. +The guide covers backup, a fresh setup, stopping old control, checks after +reboot and going back. Guided migration of settings and history is not ready. diff --git a/docs/self-update.md b/docs/self-update.md index 37354a624..d9baba436 100644 --- a/docs/self-update.md +++ b/docs/self-update.md @@ -18,34 +18,27 @@ is still needed to recover older data or a failed disk. ## Existing 1.x, 2.x and 3.x boxes -Keep an existing Docker or earlier native site on its current version. On an -older Docker install, the web UI's Update and Restart buttons signal the -`ftw-updater` sidecar, which pulls a pinned image and recreates Core. That -path is frozen with its line: the sidecar and its Core counterpart run from -the installed images, and their source stays on the old release tags, not on -`master`. Do not use its Update button, an old Docker migration script, a moving -image alias, or a manual Core/updater swap to cross release lines. The old -code may still show a previously published update; it cannot be changed on a -box that has not installed new code. The scripts on `master` for -Docker-to-Docker migration and 2.x-to-3.x upgrades now exit before changing a -site. - -The planned guided installer will move 1.x, 2.x and 3.x sites directly to -native 0.x. It must first make and verify a full backup held off the box, -then stop the old Core, preserve config, history, identity and goals, install -the native service, check data and connected devices, and retain a tested way -back. It is not ready for users. The [fresh Linux installer](../scripts/install.sh) -is only for an empty 64-bit host and refuses a known existing site. Until -then, [Try the 0.x beta](native-beta.md#coming-from-an-older-ftw) shows how -to test 0.x beside an old site. - -GitHub `releases/latest` and the old Docker `:latest` aliases remain on the -2.x line for installed boxes. Native beta and stable releases use exact tags -without moving that global latest slot. An urgent safety repair may still -need an owner-approved 2.x release; it does not restart routine Docker -releases or provide a hop to 3.x. The old `beta.yml` and `release.yml` -workflows are guarded to that line. A release from either line does not deploy -itself to a box. +**2.x and 3.x will receive no further updates. All new releases use the new +0.x line. Switch now to follow current development. Do not install 3.x beta +or use it as an intermediate upgrade.** Old 0.x up to 0.130.x and 1.x are also +retired. Start with [Install and update FTW](native-beta.md), which identifies +the install type before giving commands. + +A second SD card/host or separate Docker project lets an owner switch now with +new settings and data. Guided migration preserving config, history, identity +and goals has not shipped. Do not copy old databases into new Core or bypass +the fresh installer's checks. If those data must move first, get help for that +site and retain a verified backup off the host and a tested way back. + +Old Docker's Update Center and updater still run their installed code. They +may offer old releases; choosing beta does not migrate to new 0.x. Do not use +those controls, moving image aliases, manual Core/updater swaps or retired +migration scripts to cross lines. The scripts on master refuse the old paths. + +GitHub `releases/latest` and old Docker `:latest` aliases remain on old 2.x to +avoid sending incompatible packages to old clients. They are not current +release recommendations and will not receive new 2.x updates. New releases use +exact 0.x tags. Publication never installs a release on a site by itself. ### Pilot: an older native systemd site @@ -81,10 +74,10 @@ path if automatic recovery fails. The CLI prints the active phase, elapsed time known; it says when a total is unknown. If LAN auth is on, set `FTW_API_TOKEN` in the CLI process environment. Never paste that token into a command line. -The pilot refuses Docker and Home Assistant installations; they remain on -their current line while their own layout and recovery path are tested. A -successful empty-data smoke test does not prove migration of a live -household. +The pilot refuses Docker and Home Assistant installations. Use the separate +setup paths in [the switch guide](native-beta.md#coming-from-an-older-ftw) for +those sites. A successful empty-data smoke test does not prove migration of +a live household. ## Native 0.x releases @@ -168,9 +161,10 @@ the native install. FTW's Core update does not update the host operating system, kernel or Docker engine. The operator handles host updates. -The old Docker workflows and their release receipts remain for an exceptional -2.x repair. The native release workflow cannot publish Docker images or move -old aliases. New Core code refuses cross-line update requests, but that guard +The old Docker workflows and receipts remain as historical and recovery +material, not a path for new releases. The native workflow cannot publish old +Docker images or move old aliases. New Core code refuses cross-line update +requests, but that guard cannot change an older installed binary. Do not use an old tag or script to bypass the guided migration. diff --git a/docs/setup-guide/README.md b/docs/setup-guide/README.md index ad055bf73..7c5ae90bc 100644 --- a/docs/setup-guide/README.md +++ b/docs/setup-guide/README.md @@ -1,5 +1,9 @@ # Setup Guide — FTW +**Already running FTW?** Start with [Install and update FTW](../native-beta.md) +or [Byt till nya FTW](update-sv.md). 2.x and 3.x receive no further updates. +Use a new card for an existing Pi; keep the old card and its data. + Så förbereder du en Raspberry Pi med Raspberry Pi OS för FTW, på flera språk. How to prepare a Raspberry Pi with Raspberry Pi OS for FTW, in several diff --git a/docs/setup-guide/de.md b/docs/setup-guide/de.md index eefdf20ea..c8109e248 100644 --- a/docs/setup-guide/de.md +++ b/docs/setup-guide/de.md @@ -2,7 +2,7 @@ Diese Anleitung ist für dich, wenn du noch nie einen Raspberry Pi eingerichtet hast. Keine Sorge — es ist leichter, als es klingt. Folge den Schritten einfach einer nach dem anderen. -> **Native 0.x-Beta:** Das alte FTW-Image und der Docker-Installer sind für neue Geräte eingestellt. Diese Anleitung zeigt die Pi-Einrichtung. Betatester mit einem neuen 64-Bit-Rechner nutzen den [nativen Linux-Installer](../native-beta.md#install). Läuft FTW schon: siehe [Coming from an older FTW](../native-beta.md#coming-from-an-older-ftw). +> **2.x und 3.x erhalten keine weiteren Updates.** Wechsle zu neuen 0.x-Versionen, um die aktuellen Änderungen zu erhalten. Installiere keine 3.x-Beta. Läuft FTW bereits, beginne mit [Install and update FTW](../native-beta.md). Nutze eine **neue SD-Karte** und behalte die alte Karte mit ihren Daten. > **Kein Raspberry Pi?** Ein neuer 64-Bit-Rechner mit Debian oder Ubuntu kann denselben nativen Beta-Installer nutzen. Überspringe die Pi-Hardware-Schritte und lies **Schritt 11 — FTW installieren**. @@ -52,7 +52,7 @@ Das ist das Grundprogramm, damit der Raspberry Pi funktioniert — ähnlich wie ## Schritt 5 — Die Speicherkarte in deinen Computer stecken -1. Nimm die Speicherkarte aus dem Raspberry Pi (falls sie drin ist). Sei vorsichtig. +1. Wähle eine neue Speicherkarte. Behalte die Karte mit dem alten FTW und seinen Daten. 2. Stecke sie in den Kartenleser an deinem normalen Computer. 3. Klicke im Programm auf das untere Feld ("Storage") und wähle deine Karte aus. @@ -118,13 +118,7 @@ Gut gemacht — du bist jetzt "im" Raspberry Pi. ## Schritt 11 — FTW installieren -Der alte Docker-Installer mit einem Befehl wird nicht mehr verwendet. Native -0.x wird noch getestet; diese Anleitung bietet derzeit keine allgemeine -Installation. Wenn du am Beta-Test teilnimmst und einen neuen 64-Bit-Pi hast, -folge der Anleitung mit festem Tag in den -[Installationsschritten](../native-beta.md#install). Läuft FTW schon auf dem -Pi, lass diese Karte unverändert und lies -[Coming from an older FTW](../native-beta.md#coming-from-an-older-ftw). +Folge [Install and update FTW](../native-beta.md#install) und wähle eine veröffentlichte neue 0.x-Beta mit genauem Tag. Auf einem frischen 64-Bit-Pi kannst du jetzt installieren. Läuft FTW schon, folge zuerst [der Anleitung zum Wechsel](../native-beta.md#coming-from-an-older-ftw): nutze eine neue Karte und richte die Anlage neu ein. Die geführte Übernahme alter Einstellungen und Verlaufsdaten ist noch nicht fertig. ## Nach der Installation diff --git a/docs/setup-guide/en.md b/docs/setup-guide/en.md index dee2b1ee1..28131d875 100644 --- a/docs/setup-guide/en.md +++ b/docs/setup-guide/en.md @@ -2,7 +2,7 @@ This guide is for you if you've never set up a Raspberry Pi before. Relax — it's easier than it sounds. Just follow the steps, one at a time. -> **Native 0.x beta:** the old FTW image and Docker installer are retired for new sites. This guide covers Pi setup; beta testers with a fresh 64-bit host use the [native Linux installer](../native-beta.md#install). Sites that already run FTW: see [Coming from an older FTW](../native-beta.md#coming-from-an-older-ftw). +> **2.x and 3.x receive no further updates.** Switch to new 0.x to follow the latest releases. Do not install 3.x beta. Already running FTW? Start with [Install and update FTW](../native-beta.md). Use a **new SD card** and keep the old card and its data. > **Don't have a Raspberry Pi?** A fresh 64-bit Debian or Ubuntu host can use the same native beta installer. Skip the Pi hardware steps and read **Step 11 — Install FTW**. @@ -52,7 +52,7 @@ This is the base program that makes the Raspberry Pi work — a bit like Windows ## Step 5 — Put the memory card in your computer -1. Take the memory card out of the Raspberry Pi (if it's in there). Handle it gently. +1. Choose a new memory card. Keep the card containing old FTW and its data. 2. Slide it into the card reader on your regular computer. 3. Click the bottom box ("Storage") in the program and select your card. @@ -118,12 +118,7 @@ Well done — you're now "inside" the Raspberry Pi. ## Step 11 — Install FTW -The old one-line Docker installer has been retired. Native 0.x is being tested; -this beginner guide does not yet offer a general install. If you are part of -the beta and this is a fresh 64-bit Pi, follow the exact-tag steps in the -[Linux install guide](../native-beta.md#install). If FTW already runs on this -Pi, keep that card as it is and see -[Coming from an older FTW](../native-beta.md#coming-from-an-older-ftw). +Follow [Install and update FTW](../native-beta.md#install) and choose an exact published new 0.x beta. You can install now on a fresh 64-bit Pi. If FTW already runs on your Pi, follow [the switch guide](../native-beta.md#coming-from-an-older-ftw) first: use a new card and set up the site again. Guided migration of old settings and history is not ready. ## After installation diff --git a/docs/setup-guide/es.md b/docs/setup-guide/es.md index bf3bfdf3c..3bcc9c16d 100644 --- a/docs/setup-guide/es.md +++ b/docs/setup-guide/es.md @@ -2,7 +2,7 @@ Esta guía es para ti que nunca has configurado una Raspberry Pi antes. Tranquila — es más fácil de lo que parece. Basta con seguir los pasos, uno a uno. -> **Beta nativa 0.x:** la antigua imagen FTW y el instalador Docker ya no se usan en equipos nuevos. Esta guía cubre la preparación de la Pi. Quienes prueben la beta en un equipo nuevo de 64 bits deben seguir la [instalación nativa para Linux](../native-beta.md#install). ¿Ya usas FTW? Consulta [Coming from an older FTW](../native-beta.md#coming-from-an-older-ftw). +> **2.x y 3.x no recibirán más actualizaciones.** Cambia a la nueva serie 0.x para seguir las últimas versiones. No instales la beta 3.x. Si ya usas FTW, empieza por [Install and update FTW](../native-beta.md). Usa una **tarjeta SD nueva** y conserva la antigua con sus datos. > **¿No tienes Raspberry Pi?** Un equipo nuevo de 64 bits con Debian o Ubuntu puede usar el mismo instalador de la beta nativa. Salta los pasos de la Pi y lee el **Paso 11 — Instalar FTW**. @@ -52,7 +52,7 @@ Es el programa base que hace funcionar a la Raspberry Pi — un poco como Window ## Paso 5 — Pon la tarjeta de memoria en tu ordenador -1. Saca la tarjeta de memoria de la Raspberry Pi (si está dentro). Manéjala con cuidado. +1. Elige una tarjeta de memoria nueva. Conserva la tarjeta con el FTW antiguo y sus datos. 2. Deslízala en el lector de tarjetas de tu ordenador normal. 3. Haz clic en el cuadro de abajo ("Storage") en el programa y elige tu tarjeta. @@ -118,12 +118,7 @@ Bien hecho — ya estás "dentro" de la Raspberry Pi. ## Paso 11 — Instalar FTW -El instalador antiguo de Docker de una sola línea ya no se usa. Native 0.x -sigue en pruebas; esta guía aún no ofrece una instalación general. Si participas -en la beta y tienes una Pi nueva de 64 bits, sigue los pasos con una versión -exacta en la [guía de instalación](../native-beta.md#install). Si FTW ya se -ejecuta en tu Pi, conserva esa tarjeta tal cual y lee -[Coming from an older FTW](../native-beta.md#coming-from-an-older-ftw). +Sigue [Install and update FTW](../native-beta.md#install) y elige la etiqueta exacta de una nueva beta 0.x publicada. Puedes instalarla ahora en una Pi de 64 bits nueva. Si ya usas FTW, sigue primero [la guía de cambio](../native-beta.md#coming-from-an-older-ftw): usa otra tarjeta y configura el sitio de nuevo. La migración guiada de los ajustes y del historial antiguos aún no está lista. ## Después de la instalación diff --git a/docs/setup-guide/fr.md b/docs/setup-guide/fr.md index 6f38f80e0..48dd8f066 100644 --- a/docs/setup-guide/fr.md +++ b/docs/setup-guide/fr.md @@ -2,7 +2,7 @@ Ce guide est fait pour vous qui n'avez jamais configuré un Raspberry Pi. Pas de panique — c'est plus simple qu'il n'y paraît. Il suffit de suivre les étapes, une par une. -> **Bêta native 0.x :** l'ancienne image FTW et l'installateur Docker ne servent plus aux nouveaux appareils. Ce guide couvre la préparation du Pi. Les testeurs ayant un nouvel hôte 64 bits suivent [l'installation Linux native](../native-beta.md#install). FTW tourne déjà ? Voir [Coming from an older FTW](../native-beta.md#coming-from-an-older-ftw). +> **Les versions 2.x et 3.x ne recevront plus de mises à jour.** Passez à la nouvelle série 0.x pour suivre les dernières versions. N’installez pas la bêta 3.x. Si FTW fonctionne déjà, commencez par [Install and update FTW](../native-beta.md). Utilisez une **nouvelle carte SD** et conservez l’ancienne avec ses données. > **Pas de Raspberry Pi ?** Un nouvel hôte 64 bits sous Debian ou Ubuntu peut utiliser le même installateur natif bêta. Ignorez les étapes propres au Pi et lisez l'**Étape 11 — Installer FTW**. @@ -52,7 +52,7 @@ C'est le programme de base qui fait fonctionner le Raspberry Pi — un peu comme ## Étape 5 — Mettre la carte mémoire dans votre ordinateur -1. Sortez la carte mémoire du Raspberry Pi (si elle est dedans). Manipulez-la doucement. +1. Choisissez une nouvelle carte mémoire. Conservez la carte contenant l’ancien FTW et ses données. 2. Glissez-la dans le lecteur de carte de votre ordinateur habituel. 3. Cliquez sur la case du bas ("Storage") dans le programme et choisissez votre carte. @@ -118,12 +118,7 @@ Bravo — vous êtes maintenant "à l'intérieur" du Raspberry Pi. ## Étape 11 — Installer FTW -L'ancien installateur Docker en une ligne n'est plus utilisé. Native 0.x est -encore en test ; ce guide ne propose pas encore d'installation générale. Si -vous participez à la bêta avec un nouveau Pi 64 bits, suivez les étapes avec -un tag précis dans le [guide d'installation](../native-beta.md#install). Si FTW -tourne déjà sur votre Pi, gardez cette carte telle quelle et lisez -[Coming from an older FTW](../native-beta.md#coming-from-an-older-ftw). +Suivez [Install and update FTW](../native-beta.md#install) et choisissez le tag exact d’une nouvelle bêta 0.x publiée. Vous pouvez l’installer maintenant sur un Pi 64 bits vierge. Si FTW fonctionne déjà, suivez d’abord [le guide de changement](../native-beta.md#coming-from-an-older-ftw) : utilisez une nouvelle carte et configurez à nouveau le site. La migration guidée des anciens réglages et de l’historique n’est pas encore prête. ## Après l'installation diff --git a/docs/setup-guide/sv.md b/docs/setup-guide/sv.md index 211728a9a..d69979d11 100644 --- a/docs/setup-guide/sv.md +++ b/docs/setup-guide/sv.md @@ -2,7 +2,7 @@ Den här guiden är skriven för dig som aldrig har pillat med en Raspberry Pi förut. Lugn — det är lättare än det låter. Följ stegen ett i taget, så går det fint. -> **Native 0.x-beta:** den gamla FTW-imagen och Docker-installationen används inte för nya boxar. Den här guiden visar Pi-stegen. Betatestare med en ny 64-bitars värd följer [installationen för Linux](../native-beta.md#install). Kör du redan FTW: läs [Coming from an older FTW](../native-beta.md#coming-from-an-older-ftw). +> **2.x och 3.x får inga fler uppdateringar.** Byt till nya 0.x för att följa det senaste. Installera inte 3.x-beta. Kör du redan FTW, börja med [Byt till nya FTW](update-sv.md). Använd ett **nytt SD-kort** och behåll det gamla med dess data. > **Ingen Raspberry Pi?** En ny 64-bitars värd med Debian eller Ubuntu kan använda samma native beta. Hoppa över Pi-stegen och läs **Steg 11 — Installera FTW**. @@ -52,7 +52,7 @@ Det här är grundprogrammet som får Raspberry Pin att fungera — ungefär som ## Steg 5 — Stoppa in minneskortet i din dator -1. Ta ur minneskortet ur Raspberry Pin (om det sitter i). Var försiktig. +1. Välj ett nytt minneskort. Behåll kortet med gamla FTW och dess data. 2. Stoppa det i kortläsaren på din vanliga dator. 3. Klicka på den nedersta rutan ("Storage") i programmet och välj ditt kort. @@ -118,12 +118,7 @@ Grattis — du är nu "inne" i Raspberry Pin. ## Steg 11 — Installera FTW -Den gamla Docker-installationen med ett kommando är avslutad. Native 0.x -testas ännu och den här guiden ger därför ingen allmän installation just nu. -Om du deltar i betan och har en ny 64-bitars Pi, följ stegen med exakt tagg i -[installationsguiden](../native-beta.md#install). Kör FTW redan på din Pi, -behåll det kortet som det är och läs -[Coming from an older FTW](../native-beta.md#coming-from-an-older-ftw). +Följ [installationsguiden för nya 0.x](../native-beta.md#install) och välj en exakt publicerad beta. På en ny 64-bitars Pi kan du installera nu. Kör FTW redan på din Pi, följ [bytesguiden](update-sv.md) först: använd ett nytt kort och ställ in anläggningen på nytt. Den guidade flytten av gamla inställningar och historik är ännu inte klar. ## Efter installationen diff --git a/docs/setup-guide/update-sv.md b/docs/setup-guide/update-sv.md new file mode 100644 index 000000000..da47fe3e8 --- /dev/null +++ b/docs/setup-guide/update-sv.md @@ -0,0 +1,191 @@ +# Byt till nya FTW och håll det uppdaterat + +[English and release commands](../native-beta.md). + +**FTW 2.x och 3.x får inga fler uppdateringar. All fortsatt utveckling går +till den nya 0.x-serien. Vill du ha de senaste funktionerna och rättningarna +är det dags att byta nu. Installera inte 3.x-beta, och uppdatera inte en äldre +installation till 3.x som ett steg på vägen.** + +Den nya serien börjar med `v0.131.0-beta.1`. Det lägre versionsnumret är +avsiktligt. Äldre 0.x-versioner, till och med 0.130.x, hör till den gamla +serien. `beta` är kanalen inom en serie; ett kanalbyte flyttar inte en gammal +installation till den nya serien. + +Du kan börja använda nya FTW nu, med nya inställningar och egen datalagring. +Den guidade flytten som tar med gamla inställningar och historik är ännu inte +klar. Behöver du föra över dessa data innan du byter, ta hjälp med just din +installation. Kopiera inte gamla databaser till den nya installationen på egen +hand. + +## Välj väg efter hur FTW körs + +| Det du har nu | Vägen till nya FTW | Nästa uppdatering | +|---|---|---| +| Äldre Docker: gammal 0.x, 1.x eller 2.x, även äldre Forty Two Watts-images | Nytt SD-kort/annan Linux-värd, eller separat Docker-installation på samma Linux-värd. Stoppa gamla Core innan nya Core får styra. | Följ metoden för den nya installationen nedan. | +| Docker 3.x, inklusive 3.x-beta | Samma väg som från äldre Docker. Ingen mellanversion behövs. | Följ metoden för den nya installationen. | +| SD-kort med den gamla färdiga FTW-imagen | Använd ett nytt kort med Raspberry Pi OS Lite 64-bit. Behåll det gamla kortet. Den gamla imagen innehåller Docker; den är ingen egen uppdateringskanal. | `ftw update` på den nya native-installationen. | +| Nya 0.x med native launcher och systemd | Uppdatera den befintliga installationen. Kör inte en nyinstallation. | `ftw update`, eller `ftw update --channel beta` för att välja beta. | +| Nya 0.x i Docker, byggd från releasepaketet | Behåll Compose-projektet och dess datakatalog. | Ändra `FTW_VERSION` i `.env`, kör `docker compose up -d --build`. | +| Äldre native-installation utan release slots | Identifiera tjänsten och datavägarna. Ny installation på separat värd/kort, eller en särskilt kontrollerad flytt. | Det befintliga `migrate-native`-verktyget är en pilot, inte en allmän migrationsguide. | +| Home Assistant-app på gamla serien | Installera nya FTW på en separat Linux-värd och stoppa gamla appens Core, Start on boot och Watchdog innan du tar över. Installera inte 3.x-beta för att få det senaste. | Supervisor hanterar den gamla appen. Den ger ännu ingen väg till nya 0.x. | +| Egen build, manuellt startad binär, macOS eller Windows | Identifiera körsättet först. Den dokumenterade nya installationen kräver 64-bitars Linux. | Använd inte Linux-kommandon som om de gällde varje installation. | + +`ftw.service` eller en fungerande `ftw status` räcker inte för att skilja +körsätten åt. Samma tjänstenamn har använts tidigare, och status visar den Core +som svarar på adressen. + +## Börja här om du inte vet vad som körs + +Öppna en terminal på FTW-maskinen, eller anslut med SSH. Följande kommandon +läser bara tillståndet: + +```bash +sudo docker ps -a --format 'table {{.ID}}\t{{.Names}}\t{{.Image}}\t{{.Status}}' +sudo docker compose ls -a +systemctl list-units --type=service --all --no-pager | grep -Ei 'ftw|forty|docker' +systemctl list-unit-files --type=service --no-pager | grep -Ei 'ftw|forty' +``` + +Spara också versionsnumret och adressen till webbsidan du öppnar. Om ett +kommando saknas eller ger ett fel, spara felet. Det bevisar inte att en gammal +installation saknas. Har du egna startskript eller kör FTW på flera maskiner +behöver även de kontrolleras. + +En Docker-image på disken är inte en körande FTW. En stoppad container är inte +heller aktiv. Kontrollera vilken Core som faktiskt körs och vad som kan starta +den igen vid omboot. + +## Byt på Raspberry Pi med ett nytt SD-kort + +1. Spara uppgifter om enheter, adresser, mål och scheman. Ta en full backup + enligt instruktionerna för den installerade versionen och spara den utanför + Pi:n. Behåll även det gamla kortet. +2. Skriv Raspberry Pi OS Lite **64-bit** till ett **nytt** kort. Välj ett + användarnamn som inte är `ftw`, och slå på SSH. Skriv inte över det gamla + kortet. +3. Stäng av Pi:n, byt kort och starta. Om gamla FTW körs på en annan maskin, + stoppa den innan nya FTW får styra samma utrustning. +4. Välj en publicerad 0.x-beta från + [Releases](https://github.com/srcfl/ftw/releases). Den ska ha paketet för + din arkitektur och dess SHA-256-fil. Använd inte `releases/latest`: den + länken pekar fortfarande på den gamla serien. +5. Följ [installationsstegen](https://github.com/srcfl/ftw/blob/master/docs/native-beta.md#install) + med den valda taggen. Installationsskriptet och paketet ska komma från samma + tagg. `--fresh-host` gäller bara en värd utan en befintlig FTW-installation. +6. Öppna `http://:8080/setup` och ställ in anläggningen på nytt. + Historik, inlärning och gamla inställningar ligger kvar på det gamla kortet; + de följer inte automatiskt med. Ersätt gamla kalenderhändelser med mål och + ready-by-scheman. Kontrollera även MQTT: en broker på det gamla kortet + följer inte med till det nya. +7. Kontrollera rätt version, friska enheter, färska mätvärden och aktuell plan. + Starta sedan om Pi:n när anläggningen kan tåla avbrottet och kontrollera + samma saker igen. + +För att gå tillbaka: stäng av Pi:n och sätt tillbaka det gamla kortet. Stoppa +också eventuell ny FTW på en annan maskin innan gamla FTW får styra igen. Data +som den nya installationen har samlat ligger kvar på det nya kortet. + +## Byt på samma Linux-maskin med Docker + +Den nya Docker-installationen använder en egen katalog och egen data. Det är +en ny installation, inte en flytt av gamla data. + +1. Identifiera det gamla Compose-projektet, dess Core, updater, datakataloger + och startregler. Vanliga kataloger är `/opt/ftw`, `~/ftw` och + `~/forty-two-watts`, men använd den väg som finns på maskinen. +2. Ta en full backup och spara den utanför maskinen. Behåll också Compose-filer, + overrides och `.env`, så att du kan återställa rätt gamla version. +3. Kontrollera om projektet även kör Mosquitto eller andra tjänster som + utrustningen behöver. Ordna fortsatt MQTT innan du stoppar hela projektet. +4. Stoppa den gamla installationen med dess riktiga Compose-filer och + projektnamn. Ett vanligt projekt kan stoppas med `docker compose down` + från rätt katalog. Använd inte `-v` och radera inga datakataloger. + Kontrollera även systemd, timers och egna skript som kan skapa eller starta + den igen. Stäng inte av Docker som helhet. +5. Följ [Docker-guiden för nya FTW](https://github.com/srcfl/ftw/blob/master/docs/native-beta.md#docker). + Använd en ny katalog, normalt `~/ftw-local`, och en tom datakatalog. + Återanvänd inte den gamla datakatalogen eller en redan befintlig testkatalog + utan att först kontrollera vad den innehåller. +6. Ställ in anläggningen och kontrollera version, enheter, mätvärden och plan. + Kontrollera att bara en Core körs och styr utrustningen. Upprepa kontrollen + efter en planerad omboot. + +För att gå tillbaka: stoppa nya FTW först. Starta sedan det bevarade gamla +projektet med dess sparade filer och versionsval. Återaktivera bara de +startregler du själv stängde av. Den gamla och nya installationen behåller var +sin data. + +**Port 8080 är ingen spärr mot dubbel styrning.** Äldre Core kan fortsätta +styra även om den inte kan starta sin webbsida. En enda synlig webbsida är +därför inget bevis på att bara en FTW körs. + +## Uppdatera när du redan kör nya FTW + +### Native med launcher + +Kör på FTW-maskinen: + +```bash +ftw status +ftw update --channel beta +ftw status +journalctl -u ftw --since "10 minutes ago" --no-pager +``` + +`--channel beta` väljer beta och försöker uppdatera. När rätt kanal redan är +sparad räcker `ftw update` nästa gång. Den nya native-webbsidan visar version +och uppdateringsbesked; själva uppdateringen sker via kommandot. + +Kontrollera vilken version som faktiskt körs efteråt. En publicerad release +eller ett lyckat kommando som säger att installationen redan är aktuell är +inte bevis på att just den version du avsåg installerades. + +`ftw rollback` återgår till föregående kompatibla release med nuvarande data. +Det ersätter ingen full backup. En ändrad dataversion kan kräva en annan +återställningsväg. En native-installation kan också falla tillbaka automatiskt +om en ny release inte startar eller fortsätter krascha; spara `ftw status` och +loggar innan du försöker igen. + +Kör inte om nyinstallationen för en vanlig uppdatering. `--refresh` gäller +launcher, CLI och tjänstefil och används när releasen kräver det. En äldre +pilotinstallation med annan katalogstruktur behöver sina egna kontroller. + +### Docker från det nya releasepaketet + +Öppna `.env` i det verifierade nya Compose-projektet och ändra `FTW_VERSION` +till den exakta publicerade release du vill installera. Behåll övriga rader. +Kör sedan i samma projekt: + +```bash +docker compose up -d --build +docker compose ps +docker compose exec ftw ftw status +``` + +Kontrollera även mätvärden och plan. `ftw update` och `ftw rollback` gäller +inte den här Docker-installationen. Återgång sker genom att välja föregående +kompatibla `FTW_VERSION` och köra Compose igen. Docker har ingen automatisk +återgång till föregående version. + +## För agenter som hjälper till + +- Följ samma vägval som människan. Fastställ värd, version, körsätt, + tjänst/projekt, datavägar, startregler och målversion innan du ändrar något. +- Skilj på uppdatering inom nya serien, nyinstallation med nya data och + migrering med bevarade data. Säg vilken åtgärd du avser. +- Välj ingen 2.x- eller 3.x-release. Tolka inte ett gammalt erbjudande i + Update Center eller `releases/latest` som en rekommendation. +- Kör ingen installation, uppdatering eller omstart när uppdraget bara är + felsökning. En begäran att uppdatera ger rätt att utföra den valda vägen; + fråga inte igen om samma sak. +- För en befintlig anläggning: verifiera backup och kopian utanför maskinen + innan ett byte som berör installation eller data. Anta inte att alla gamla + versioner har samma backupknapp eller datalayout. +- Starta inte nya Core mot samma utrustning medan gamla Core fortfarande körs. + Kontrollera även andra värdar och Home Assistant. Bevara beroenden som MQTT. +- En misslyckad hälsokontroll ger ingen rätt att radera data, kringgå + installationsspärrar, köra `down -v` eller prova en annan gammal migration. +- Rapportera målversion och verklig version, Core-processer, startregler, + hälsa, färska mätvärden, plan, backup och möjlig återgång var för sig. + Redovisa om kontroll efter omboot eller fysisk styrning återstår. diff --git a/docs/upgrade-from-legacy.md b/docs/upgrade-from-legacy.md index 886fb8982..606a7b954 100644 --- a/docs/upgrade-from-legacy.md +++ b/docs/upgrade-from-legacy.md @@ -1,21 +1,15 @@ # Older Docker installations -The Docker-to-Docker migration from Forty Two Watts to Sourceful FTW is -retired. `scripts/migrate-legacy-compose.sh` now exits before reading or -changing a site. Do not run an older copy of that script to move an existing -box to another Docker release line. - -Keep a 1.x, 2.x or 3.x site on its current version. The planned guided -migration will take any of these sites directly to native 0.x after it has -been tested. The fresh native installer is for an empty host; it refuses an -existing site and does not preserve its data. To try 0.x beside an older -site now, see [Coming from an older FTW](native-beta.md#coming-from-an-older-ftw). - -Calendar support is gone from 0.x. Move future calendar charging events to -loadpoint targets and ready-by schedules first. A `caldav` section in an old -config is ignored with a warning, and the old calendar tables stay unused in -`state.db`. - -Before any manual recovery, make and verify a full backup, then copy it off -the box. See [backup and restore](backup-and-restore.md) and the current -[update policy](self-update.md). +**2.x and 3.x receive no further updates. Switch directly to the new 0.x line. +Do not install 3.x beta or use it as an intermediate upgrade.** + +Start with [Install and update FTW](native-beta.md) +([Svenska](setup-guide/update-sv.md)). It covers the old Docker installer, +Forty Two Watts images, the Raspberry Pi SD image, 1.x/2.x/3.x, Home Assistant +and older native services. New native and Docker setups are available now; +guided migration of old settings and history is not ready. + +The old Docker-to-Docker and paired Core/updater migration scripts are retired +and exit without changing the site. Do not run an old copy to bypass them. +Keep old data and a verified backup off the host. Stop old Core and its start +rules before new Core controls the equipment, and check again after reboot. diff --git a/docs/upgrade-paired-release.md b/docs/upgrade-paired-release.md index 79e1c3838..209173d3c 100644 --- a/docs/upgrade-paired-release.md +++ b/docs/upgrade-paired-release.md @@ -1,15 +1,15 @@ # Older paired Docker upgrades -The operator-led 2.x-to-3.x Core and updater procedure is retired. -`scripts/upgrade-paired-release.sh` now exits before reading or changing a -site. Do not use an older copy of the script or the orange Update button to -move a 1.x or 2.x box to 3.x. +**2.x and 3.x receive no further updates. Switch directly to the new 0.x line. +Do not install 3.x beta or use it as an intermediate upgrade.** -Keep an existing site on its current version. The planned guided migration -will take 1.x, 2.x and 3.x sites directly to native 0.x after it has been -tested. The fresh native installer is for an empty host and cannot migrate -an existing box. +Start with [Install and update FTW](native-beta.md) +([Svenska](setup-guide/update-sv.md)). It covers the old Docker installer, +Forty Two Watts images, the Raspberry Pi SD image, 1.x/2.x/3.x, Home Assistant +and older native services. New native and Docker setups are available now; +guided migration of old settings and history is not ready. -Before any manual recovery, make and verify a full backup, then copy it off -the box. See [backup and restore](backup-and-restore.md) and the current -[update policy](self-update.md). +The old Docker-to-Docker and paired Core/updater migration scripts are retired +and exit without changing the site. Do not run an old copy to bypass them. +Keep old data and a verified backup off the host. Stop old Core and its start +rules before new Core controls the equipment, and check again after reboot. diff --git a/scripts/install-macos.sh b/scripts/install-macos.sh index 9ba81b0e0..9d06f0da8 100755 --- a/scripts/install-macos.sh +++ b/scripts/install-macos.sh @@ -3,8 +3,9 @@ set -euo pipefail cat >&2 <<'MESSAGE' The macOS Docker installer is retired. This script makes no changes. -No native 0.x package for macOS has been published. Existing macOS FTW sites -stay on their current version until a tested migration path is available. -See https://github.com/srcfl/ftw/blob/master/docs/self-update.md +No native 0.x package for macOS has been published. 2.x and 3.x receive no +further updates. Use a new setup on 64-bit Linux to follow current releases. +Keep old data; guided migration is not ready. +See https://github.com/srcfl/ftw/blob/master/docs/native-beta.md MESSAGE exit 2 diff --git a/scripts/migrate-legacy-compose.sh b/scripts/migrate-legacy-compose.sh index 68969ad68..d72bb3713 100755 --- a/scripts/migrate-legacy-compose.sh +++ b/scripts/migrate-legacy-compose.sh @@ -3,8 +3,9 @@ set -euo pipefail cat >&2 <<'MESSAGE' The Docker-to-Docker migration is retired. This script makes no changes. -Leave an existing FTW site on its current version. The guided native 0.x -migration will handle 1.x, 2.x and 3.x after it has been tested. -See https://github.com/srcfl/ftw/blob/master/docs/self-update.md +2.x and 3.x receive no further updates. Switch to new 0.x with a separate +setup and data; guided migration of old settings and history is not ready. +Do not install 3.x beta or bypass this check with an old script. +See https://github.com/srcfl/ftw/blob/master/docs/native-beta.md MESSAGE exit 2 diff --git a/scripts/upgrade-paired-release.sh b/scripts/upgrade-paired-release.sh index 47e991f36..075f6f3f0 100755 --- a/scripts/upgrade-paired-release.sh +++ b/scripts/upgrade-paired-release.sh @@ -3,8 +3,9 @@ set -euo pipefail cat >&2 <<'MESSAGE' The 2.x-to-3.x Docker upgrade is retired. This script makes no changes. -Leave an existing FTW site on its current version. The guided native 0.x -migration will handle 1.x, 2.x and 3.x after it has been tested. -See https://github.com/srcfl/ftw/blob/master/docs/self-update.md +2.x and 3.x receive no further updates. Switch to new 0.x with a separate +setup and data; guided migration of old settings and history is not ready. +Do not install 3.x beta or bypass this check with an old script. +See https://github.com/srcfl/ftw/blob/master/docs/native-beta.md MESSAGE exit 2 From eb469ab3bbc2777c8757ed68b95bd5a4da6e1a52 Mon Sep 17 00:00:00 2001 From: Fredrik Ahlgren Date: Tue, 29 Sep 2026 09:54:56 +0200 Subject: [PATCH 2/3] docs: align deployment skills with current update paths Signed-off-by: Fredrik Ahlgren --- .../skills/switching-ftw-deploy-mode/SKILL.md | 171 +++++------------- .../skills/switching-ftw-deploy-mode/SKILL.md | 171 +++++------------- docs/native-beta.md | 2 +- docs/upgrade-paired-release.md | 3 +- 4 files changed, 101 insertions(+), 246 deletions(-) diff --git a/.agents/skills/switching-ftw-deploy-mode/SKILL.md b/.agents/skills/switching-ftw-deploy-mode/SKILL.md index 9b5a7fbab..30fa31087 100644 --- a/.agents/skills/switching-ftw-deploy-mode/SKILL.md +++ b/.agents/skills/switching-ftw-deploy-mode/SKILL.md @@ -1,126 +1,53 @@ --- name: switching-ftw-deploy-mode -description: Use when the user wants to flip an FTW host between the official container image and a host-built development binary, in either direction. Detect and preserve legacy service, directory, and binary aliases rather than assuming them. +description: Use when the user wants to switch an FTW host between a release and a development build, or asks how to update an existing host. Identify native release slots, new Docker packaging and retired Docker before choosing a path. Never use old Docker latest as a route to current FTW. --- -# Switching FTW deploy mode (official image ↔ development binary) - -## Safety contract - -Both modes use the existing Compose project and the same persistent `/app/data` -bind. Never create a second install directory, rename the Compose project, or -copy the data directory as part of this switch. Back up an override before -changing it, and use `docker compose up -d ` rather than -`down`. - -The canonical layout is: - -| Surface | Canonical | Supported legacy | -|---|---|---| -| Install directory | `~/ftw` | `~/forty-two-watts` | -| Compose service | `ftw` | `forty-two-watts` | -| Container binary | `/app/ftw` | `/app/forty-two-watts` | -| Official image | `ghcr.io/srcfl/ftw:latest` | mirrored `ghcr.io/frahlg/forty-two-watts:latest` | -| Dev binary | `~/ftw-dev/bin/ftw` | `~/ftw-dev/bin/forty-two-watts` | - -## Required input - -The SSH target (`user@host`) must come from the user. Do not guess or reuse a -host from unrelated context. The default development directory is -`~/ftw-dev`; confirm any different path before writing an override. - -## Detect the installed layout first - -Run a read-only probe: - -```sh -ssh "$HOST" 'set -eu - if [ -d "$HOME/ftw" ]; then dir="$HOME/ftw" - elif [ -d "$HOME/forty-two-watts" ]; then dir="$HOME/forty-two-watts" - else echo "no FTW Compose directory found" >&2; exit 1 - fi - cd "$dir" - services="$(docker compose config --services)" - count="$(printf "%s\n" "$services" | grep -Ec "^(ftw|forty-two-watts)$" || true)" - [ "$count" -eq 1 ] || { echo "expected exactly one FTW main service" >&2; exit 1; } - service="$(printf "%s\n" "$services" | grep -E "^(ftw|forty-two-watts)$")" - docker compose config "$service" | grep -q "/app/data" || - { echo "main service does not map persistent /app/data" >&2; exit 1; } - cid="$(docker compose ps -q "$service")" - printf "dir=%s service=%s container=%s\n" "$dir" "$service" "$cid" - docker inspect "$cid" --format "image={{.Config.Image}}" - ls -1 docker-compose.override.yml* 2>/dev/null || true' -``` - -Stop if both main service names own `/app/data`, neither does, or the data bind -is absent. Those layouts are ambiguous and must not be recreated automatically. - -## Switch to the official image - -Disable the development override by renaming it, then pull and recreate only the -detected main service: - -```sh -ssh "$HOST" 'set -eu - if [ -d "$HOME/ftw" ]; then cd "$HOME/ftw"; else cd "$HOME/forty-two-watts"; fi - service="$(docker compose config --services | grep -E "^(ftw|forty-two-watts)$")" - if [ -f docker-compose.override.yml ]; then - mv docker-compose.override.yml "docker-compose.override.yml.dev-$(date +%Y%m%d-%H%M%S).bak" - fi - docker compose pull "$service" - docker compose up -d "$service" - cid="$(docker compose ps -q "$service")" - docker inspect "$cid" --format "image={{.Config.Image}} version={{index .Config.Labels \"org.opencontainers.image.version\"}}"' -``` - -The effective image after removing the override must be the canonical Sourceful -image or its published compatibility mirror. If it is still a local, -hard-coded developer tag, stop: the base Compose file itself was customized and -needs an explicit reviewed migration. Do not silently replace the whole file. - -## Switch to a development binary - -First locate a canonical or legacy host binary and verify its architecture: - -```sh -ssh "$HOST" 'set -eu - for bin in "$HOME/ftw-dev/bin/ftw" "$HOME/ftw-dev/bin/forty-two-watts"; do - if [ -x "$bin" ]; then file "$bin"; exit 0; fi - done - echo "no executable FTW dev binary found" >&2 - exit 1' -``` - -Prefer restoring the newest saved development override. It preserves the -user's actual service name and paths: - -```sh -ssh "$HOST" 'set -eu - if [ -d "$HOME/ftw" ]; then cd "$HOME/ftw"; else cd "$HOME/forty-two-watts"; fi - service="$(docker compose config --services | grep -E "^(ftw|forty-two-watts)$")" - saved="$(ls -1t docker-compose.override.yml.dev-*.bak 2>/dev/null | head -n1 || true)" - [ -n "$saved" ] || { - echo "no saved dev override; review service and host paths before creating one" >&2 - exit 1 - } - cp "$saved" docker-compose.override.yml - docker compose up -d "$service"' -``` - -Only create a new override after the user confirms the detected service, host -binary path, and container target (`/app/ftw` for canonical images, -`/app/forty-two-watts` for a legacy image). A wrong target can leave the -container running the bundled official binary and make the switch look -successful when it was not. - -## Verification - -Verify all three independently: - -1. `docker compose ps ` reports one healthy/running container. -2. `docker inspect ` shows the intended image and bind mount. -3. The dashboard version/about field or startup log matches the intended - official tag or development revision. - -Do not treat a successful `docker compose up` alone as proof that the mounted -binary is running. +# Choose the FTW deployment and update path + +Read [Install and update FTW](../../../docs/native-beta.md) before changing a +host. It is the common guide for people and agents. 2.x and 3.x receive no +more updates. All new releases use the new 0.x line, starting with +`v0.131.0-beta.1`; old 0.x through 0.130.x belongs to the retired line too. +Do not install 3.x beta as an intermediate step. + +## Identify the host and layout + +Use the host authorized for this task. Record its running version, native unit +or Compose project and files, data paths, image or binary, overrides and start +rules. `ftw.service`, a working dashboard and `ftw status` do not identify the +layout by themselves. A diagnosis stays read-only. An authorized update needs +no repeat approval for the same action. + +| Installed layout | Action | +|---|---| +| New native with launcher and release slots | Follow the native update section: `ftw status`, `ftw update --channel beta`, then verify. Refresh launcher/CLI/unit only when the release requires it. | +| New Docker from a release package | Keep the project and data, set the exact `FTW_VERSION` in its existing `.env`, then `docker compose up -d --build`. Native update/rollback commands do not apply. | +| Old Docker, Pi image or Home Assistant app | Follow the switch guide. Use a separate new setup and data; guided transfer of old data is not ready. | +| Older direct native or custom development build | Inspect the actual binary and override first. Use the guide's older-native path or a checked recovery plan for that site. Do not infer a safe binary swap from the service name. | + +## Returning from a development build + +Preserve the current config, data and override before changing the running +process. Check that the chosen release can read those data. Use the update or +recovery steps for the identified layout, within the owner's authorized scope. +If the development build changed the data format, establish its recovery path +before replacing it. + +The old container distribution, `ghcr.io/srcfl/ftw` and its compatibility +mirror, is retired. Do not pull `:latest` or restore a saved Compose override +to obtain new 0.x. The +[previous skill](https://github.com/srcfl/ftw/blob/5d811a937b6085df7d5494022c615d1f611198fb/.agents/skills/switching-ftw-deploy-mode/SKILL.md) +is historical context, not a current host recipe. + +For local development with separate test data, use +[the development guide](../../../docs/development.md). + +## Verify the result + +Follow the common guide's checks: expected running release or revision, +healthy devices, advancing measurements, plan, history writes and recovery. +Confirm that only one Core controls the equipment and that old Core/updater +start rules cannot bring another instance back. Preserve required MQTT. +Repeat after a planned reboot; report any checks not done. A successful +Compose command or one visible dashboard does not prove a complete switch. diff --git a/.claude/skills/switching-ftw-deploy-mode/SKILL.md b/.claude/skills/switching-ftw-deploy-mode/SKILL.md index 9b5a7fbab..30fa31087 100644 --- a/.claude/skills/switching-ftw-deploy-mode/SKILL.md +++ b/.claude/skills/switching-ftw-deploy-mode/SKILL.md @@ -1,126 +1,53 @@ --- name: switching-ftw-deploy-mode -description: Use when the user wants to flip an FTW host between the official container image and a host-built development binary, in either direction. Detect and preserve legacy service, directory, and binary aliases rather than assuming them. +description: Use when the user wants to switch an FTW host between a release and a development build, or asks how to update an existing host. Identify native release slots, new Docker packaging and retired Docker before choosing a path. Never use old Docker latest as a route to current FTW. --- -# Switching FTW deploy mode (official image ↔ development binary) - -## Safety contract - -Both modes use the existing Compose project and the same persistent `/app/data` -bind. Never create a second install directory, rename the Compose project, or -copy the data directory as part of this switch. Back up an override before -changing it, and use `docker compose up -d ` rather than -`down`. - -The canonical layout is: - -| Surface | Canonical | Supported legacy | -|---|---|---| -| Install directory | `~/ftw` | `~/forty-two-watts` | -| Compose service | `ftw` | `forty-two-watts` | -| Container binary | `/app/ftw` | `/app/forty-two-watts` | -| Official image | `ghcr.io/srcfl/ftw:latest` | mirrored `ghcr.io/frahlg/forty-two-watts:latest` | -| Dev binary | `~/ftw-dev/bin/ftw` | `~/ftw-dev/bin/forty-two-watts` | - -## Required input - -The SSH target (`user@host`) must come from the user. Do not guess or reuse a -host from unrelated context. The default development directory is -`~/ftw-dev`; confirm any different path before writing an override. - -## Detect the installed layout first - -Run a read-only probe: - -```sh -ssh "$HOST" 'set -eu - if [ -d "$HOME/ftw" ]; then dir="$HOME/ftw" - elif [ -d "$HOME/forty-two-watts" ]; then dir="$HOME/forty-two-watts" - else echo "no FTW Compose directory found" >&2; exit 1 - fi - cd "$dir" - services="$(docker compose config --services)" - count="$(printf "%s\n" "$services" | grep -Ec "^(ftw|forty-two-watts)$" || true)" - [ "$count" -eq 1 ] || { echo "expected exactly one FTW main service" >&2; exit 1; } - service="$(printf "%s\n" "$services" | grep -E "^(ftw|forty-two-watts)$")" - docker compose config "$service" | grep -q "/app/data" || - { echo "main service does not map persistent /app/data" >&2; exit 1; } - cid="$(docker compose ps -q "$service")" - printf "dir=%s service=%s container=%s\n" "$dir" "$service" "$cid" - docker inspect "$cid" --format "image={{.Config.Image}}" - ls -1 docker-compose.override.yml* 2>/dev/null || true' -``` - -Stop if both main service names own `/app/data`, neither does, or the data bind -is absent. Those layouts are ambiguous and must not be recreated automatically. - -## Switch to the official image - -Disable the development override by renaming it, then pull and recreate only the -detected main service: - -```sh -ssh "$HOST" 'set -eu - if [ -d "$HOME/ftw" ]; then cd "$HOME/ftw"; else cd "$HOME/forty-two-watts"; fi - service="$(docker compose config --services | grep -E "^(ftw|forty-two-watts)$")" - if [ -f docker-compose.override.yml ]; then - mv docker-compose.override.yml "docker-compose.override.yml.dev-$(date +%Y%m%d-%H%M%S).bak" - fi - docker compose pull "$service" - docker compose up -d "$service" - cid="$(docker compose ps -q "$service")" - docker inspect "$cid" --format "image={{.Config.Image}} version={{index .Config.Labels \"org.opencontainers.image.version\"}}"' -``` - -The effective image after removing the override must be the canonical Sourceful -image or its published compatibility mirror. If it is still a local, -hard-coded developer tag, stop: the base Compose file itself was customized and -needs an explicit reviewed migration. Do not silently replace the whole file. - -## Switch to a development binary - -First locate a canonical or legacy host binary and verify its architecture: - -```sh -ssh "$HOST" 'set -eu - for bin in "$HOME/ftw-dev/bin/ftw" "$HOME/ftw-dev/bin/forty-two-watts"; do - if [ -x "$bin" ]; then file "$bin"; exit 0; fi - done - echo "no executable FTW dev binary found" >&2 - exit 1' -``` - -Prefer restoring the newest saved development override. It preserves the -user's actual service name and paths: - -```sh -ssh "$HOST" 'set -eu - if [ -d "$HOME/ftw" ]; then cd "$HOME/ftw"; else cd "$HOME/forty-two-watts"; fi - service="$(docker compose config --services | grep -E "^(ftw|forty-two-watts)$")" - saved="$(ls -1t docker-compose.override.yml.dev-*.bak 2>/dev/null | head -n1 || true)" - [ -n "$saved" ] || { - echo "no saved dev override; review service and host paths before creating one" >&2 - exit 1 - } - cp "$saved" docker-compose.override.yml - docker compose up -d "$service"' -``` - -Only create a new override after the user confirms the detected service, host -binary path, and container target (`/app/ftw` for canonical images, -`/app/forty-two-watts` for a legacy image). A wrong target can leave the -container running the bundled official binary and make the switch look -successful when it was not. - -## Verification - -Verify all three independently: - -1. `docker compose ps ` reports one healthy/running container. -2. `docker inspect ` shows the intended image and bind mount. -3. The dashboard version/about field or startup log matches the intended - official tag or development revision. - -Do not treat a successful `docker compose up` alone as proof that the mounted -binary is running. +# Choose the FTW deployment and update path + +Read [Install and update FTW](../../../docs/native-beta.md) before changing a +host. It is the common guide for people and agents. 2.x and 3.x receive no +more updates. All new releases use the new 0.x line, starting with +`v0.131.0-beta.1`; old 0.x through 0.130.x belongs to the retired line too. +Do not install 3.x beta as an intermediate step. + +## Identify the host and layout + +Use the host authorized for this task. Record its running version, native unit +or Compose project and files, data paths, image or binary, overrides and start +rules. `ftw.service`, a working dashboard and `ftw status` do not identify the +layout by themselves. A diagnosis stays read-only. An authorized update needs +no repeat approval for the same action. + +| Installed layout | Action | +|---|---| +| New native with launcher and release slots | Follow the native update section: `ftw status`, `ftw update --channel beta`, then verify. Refresh launcher/CLI/unit only when the release requires it. | +| New Docker from a release package | Keep the project and data, set the exact `FTW_VERSION` in its existing `.env`, then `docker compose up -d --build`. Native update/rollback commands do not apply. | +| Old Docker, Pi image or Home Assistant app | Follow the switch guide. Use a separate new setup and data; guided transfer of old data is not ready. | +| Older direct native or custom development build | Inspect the actual binary and override first. Use the guide's older-native path or a checked recovery plan for that site. Do not infer a safe binary swap from the service name. | + +## Returning from a development build + +Preserve the current config, data and override before changing the running +process. Check that the chosen release can read those data. Use the update or +recovery steps for the identified layout, within the owner's authorized scope. +If the development build changed the data format, establish its recovery path +before replacing it. + +The old container distribution, `ghcr.io/srcfl/ftw` and its compatibility +mirror, is retired. Do not pull `:latest` or restore a saved Compose override +to obtain new 0.x. The +[previous skill](https://github.com/srcfl/ftw/blob/5d811a937b6085df7d5494022c615d1f611198fb/.agents/skills/switching-ftw-deploy-mode/SKILL.md) +is historical context, not a current host recipe. + +For local development with separate test data, use +[the development guide](../../../docs/development.md). + +## Verify the result + +Follow the common guide's checks: expected running release or revision, +healthy devices, advancing measurements, plan, history writes and recovery. +Confirm that only one Core controls the equipment and that old Core/updater +start rules cannot bring another instance back. Preserve required MQTT. +Repeat after a planned reboot; report any checks not done. A successful +Compose command or one visible dashboard does not prove a complete switch. diff --git a/docs/native-beta.md b/docs/native-beta.md index 88a921d0e..e35297fb6 100644 --- a/docs/native-beta.md +++ b/docs/native-beta.md @@ -21,7 +21,7 @@ on 64-bit Linux use the same release package. | What runs now | How to switch or update | |---|---| -| Old Docker: 0.x up to 0.130.x, 1.x or 2.x, including Forty Two Watts images | [Switch from an older FTW](#coming-from-an-older-ftw). Use a new SD card/host, or separate Docker project and data. | +| Old Docker: 0.x up to 0.130.x, 1.x or 2.x, including `ghcr.io/frahlg/forty-two-watts` images | [Switch from an older FTW](#coming-from-an-older-ftw). Use a new SD card/host, or separate Docker project and data. | | Docker 3.x, including beta | The same switch. No intermediate release and no further 3.x updates. | | The old ready-made FTW Raspberry Pi image | It runs old Docker. Use a second card with Raspberry Pi OS Lite 64-bit; keep the old card. | | New 0.x native with launcher/release slots | [Update the native box](#update-a-native-box). Do not reinstall. | diff --git a/docs/upgrade-paired-release.md b/docs/upgrade-paired-release.md index 209173d3c..3fa895028 100644 --- a/docs/upgrade-paired-release.md +++ b/docs/upgrade-paired-release.md @@ -5,7 +5,8 @@ Do not install 3.x beta or use it as an intermediate upgrade.** Start with [Install and update FTW](native-beta.md) ([Svenska](setup-guide/update-sv.md)). It covers the old Docker installer, -Forty Two Watts images, the Raspberry Pi SD image, 1.x/2.x/3.x, Home Assistant +`ghcr.io/frahlg/forty-two-watts` images, the Raspberry Pi SD image, +1.x/2.x/3.x, Home Assistant and older native services. New native and Docker setups are available now; guided migration of old settings and history is not ready. From fd8e84485ada507398acad23a365117ced4167b6 Mon Sep 17 00:00:00 2001 From: Fredrik Ahlgren Date: Tue, 29 Sep 2026 11:27:42 +0200 Subject: [PATCH 3/3] fix: block retired release dispatches and align installer guidance Signed-off-by: Fredrik Ahlgren --- .changeset/clear-update-paths.md | 4 +- .github/workflows/beta.yml | 11 +++++- .github/workflows/release-assets.yml | 28 ++++---------- .github/workflows/release.yml | 55 +++++++++------------------ AGENTS.md | 3 +- docs/self-update.md | 10 +++-- scripts/check-legacy-release-line.sh | 4 +- scripts/install.sh | 14 ++++--- scripts/test-exact-image-promotion.sh | 34 ++++++++++++++++- 9 files changed, 87 insertions(+), 76 deletions(-) diff --git a/.changeset/clear-update-paths.md b/.changeset/clear-update-paths.md index 72997bc2d..8eaee7598 100644 --- a/.changeset/clear-update-paths.md +++ b/.changeset/clear-update-paths.md @@ -2,4 +2,6 @@ "ftw": patch --- -Retired installer messages now direct users to the new 0.x setup paths and explain that 2.x and 3.x receive no more updates. The scripts still exit without changing the site. Docker's missing-version message asks for an exact published new 0.x tag instead of suggesting an old example. +Installer messages now direct users to the new 0.x setup paths and explain that 2.x and 3.x receive no more updates. The scripts still exit without changing the site. Docker's missing-version message asks for an exact published new 0.x tag instead of suggesting an old example. + +Block retired Docker release workflow dispatches before checkout or registry writes, while keeping native Changesets version PRs running. diff --git a/.github/workflows/beta.yml b/.github/workflows/beta.yml index 5b36e1a43..dd13647ac 100644 --- a/.github/workflows/beta.yml +++ b/.github/workflows/beta.yml @@ -1,10 +1,12 @@ -name: beta release +name: retired Docker beta release + +# Publication is blocked before checkout or credentials. Use native-release.yml. on: workflow_dispatch: inputs: version: - description: "Immutable prerelease tag, for example v0.128.0-beta.1" + description: "Retired input; publication is blocked. Use native-release.yml." required: true type: string @@ -23,6 +25,11 @@ jobs: name: verify package write access runs-on: ubuntu-latest steps: + - name: Refuse retired Docker publication + run: | + echo "::error::2.x and 3.x releases are retired. Use native-release.yml for new 0.x." + exit 1 + - name: Checkout release checks uses: actions/checkout@v7 with: diff --git a/.github/workflows/release-assets.yml b/.github/workflows/release-assets.yml index 377bb228a..ad6696f93 100644 --- a/.github/workflows/release-assets.yml +++ b/.github/workflows/release-assets.yml @@ -1,25 +1,8 @@ name: release-assets -# Publish the artefacts that accompany a tagged release: -# - Linux packages (amd64/arm64) -# - validated beta manifests promoted unchanged for Core + updater -# - Discord release announcement -# -# Triggered by `release.yml` via `gh workflow run release-assets.yml -# --ref vX.Y.Z` immediately after the tag + draft GitHub Release are created. -# Stable publication is explicit: a hand-pushed tag does not select a beta or -# publish assets. Run release.yml so the chosen validated beta is bound first. -# -# Splitting these jobs out of release.yml means: -# - regular changeset-PR merges to master don't queue + skip a half -# dozen asset jobs every time. -# - asset builds run on the tag ref directly — no need for the meta -# job to thread `outputs.version` from a different workflow run. -# - failures here don't block the next release. To use a workflow fix that -# landed after the tag, rerun the first promotion with -# `--ref master -f tag=vX.Y.Z -f source_beta=vX.Y.Z-beta.N -f release_id=123`. -# After the receipt exists, rerun with -# `--ref master -f tag=vX.Y.Z -f release_id=123`. +# Retired Docker publication. The first job refuses all runs before checkout +# or credentials; all new releases use native-release.yml. The old steps +# remain only as recovery/audit records. on: workflow_dispatch: @@ -53,6 +36,11 @@ jobs: name: verify package write access runs-on: ubuntu-latest steps: + - name: Refuse retired Docker publication + run: | + echo "::error::2.x and 3.x releases are retired. Use native-release.yml for new 0.x." + exit 1 + - name: Checkout release checks uses: actions/checkout@v7 with: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 724fe9984..190351f4b 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,36 +1,9 @@ name: release -# Changesets version PRs for native 0.x; manual stable publication is reserved -# for an exceptional 2.x Docker safety repair. Native 0.x beta and stable -# releases use native-release.yml and never use this workflow's dispatch. -# -# On push, this workflow handles the Changesets Version Packages PR only. -# On an explicit 2.x dispatch, it handles a tag + draft GitHub Release. -# The cross-platform binaries, docker images, and -# Discord announcement live in `release-assets.yml` and are triggered -# explicitly via `gh workflow run release-assets.yml --ref vX.Y.Z` at -# the end of the draft step. release-assets.yml publishes the release only -# after it verifies every required output. Keeping the heavy build matrix out of -# this workflow means regular changeset-PR merges to master don't -# queue + skip ~half a dozen asset jobs on every single push. -# -# Flow: -# 1. PRs land on master, each carrying a `.changeset/*.md` file (or -# touching only allowlisted paths — see changeset-check.yml). -# 2. This workflow fires on push to master. -# - `changesets/action` opens / updates a "Version Packages" PR -# whenever unconsumed changesets exist. We deliberately do NOT -# pass `publish:` — past experience on admin-next showed -# `changeset publish` / `changeset tag` silently no-op'd in -# CI, and the action's built-in `createGithubReleases` defaults -# to true and 422-collides with our own `gh release create`. -# - After the Version PR merges, dispatch native-release.yml from that -# exact commit for a native 0.x beta. This workflow does not publish it. -# - Only for an exceptional 2.x repair, dispatch beta.yml and then this -# workflow with the exact tested 2.x beta tag. -# -# Old Docker stable publication is workflow_dispatch-only. A merge creates a -# native version candidate; it does not publish a Docker release. +# Pushes keep the Changesets Version Packages PR for new 0.x current. +# Manual publication of the retired 2.x/3.x Docker line is blocked before +# checkout or credentials. All new releases use native-release.yml. +# The old publication steps remain only as recovery/audit records. on: push: @@ -48,7 +21,7 @@ on: workflow_dispatch: inputs: source_beta: - description: "Exact beta tag validated on real sites" + description: "Retired input; manual publication is blocked. Use native-release.yml." required: true type: string @@ -69,13 +42,19 @@ concurrency: jobs: release: - name: changesets (version PR / publish) + name: changesets version PR (old publication blocked) runs-on: ubuntu-latest outputs: published: ${{ steps.publish.outputs.published }} version: ${{ steps.publish.outputs.version }} beta_tag: ${{ steps.publish.outputs.beta_tag }} steps: + - name: Refuse retired Docker publication + if: github.event_name == 'workflow_dispatch' + run: | + echo "::error::2.x and 3.x releases are retired. Use native-release.yml for new 0.x." + exit 1 + - name: Checkout uses: actions/checkout@v7 with: @@ -95,7 +74,7 @@ jobs: cache: npm cache-dependency-path: package-lock.json - - name: Reserve manual Docker publication for 2.x + - name: Historical 2.x input check (publication blocked) if: github.event_name == 'workflow_dispatch' run: | set -euo pipefail @@ -145,15 +124,15 @@ jobs: # `version-packages` runs `changeset version` to bump package.json # and rewrite CHANGELOG.md, then synchronizes package-lock.json's # root package metadata with the generated version. - # We deliberately do NOT pass `publish-script:` — see the header - # comment for the rationale. The publish step below does - # the tag + GitHub Release manually, idempotently. + # No publish-script: this action only maintains the version PR. + # New releases use native-release.yml. Manual Docker publication + # stops at the retirement gate above. version-script: npm run version-packages pr-title: "chore(release): version packages" commit-message: "chore(release): version packages" - name: Restore default release credential - if: always() + if: always() && github.event_name == 'push' env: GITHUB_TOKEN: ${{ github.token }} run: | diff --git a/AGENTS.md b/AGENTS.md index b006970e8..7f30fc2cf 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -229,7 +229,8 @@ week-long site check above. The old Docker workflows, tags and receipts describe past releases and remain for recovery and audit. Their presence is not authority to cut another 2.x or -3.x release. Do not dispatch them or the old Home Assistant publication path. +3.x release. Current workflow definitions refuse old publication before +checkout or registry writes. Do not dispatch old workflow revisions or the old Home Assistant path. Do not move old `latest` aliases to 0.x: installed old clients cannot migrate through them. Use [docs/self-update.md](docs/self-update.md) for current release and operator rules. diff --git a/docs/self-update.md b/docs/self-update.md index d9baba436..fd8a9e965 100644 --- a/docs/self-update.md +++ b/docs/self-update.md @@ -162,10 +162,12 @@ FTW's Core update does not update the host operating system, kernel or Docker engine. The operator handles host updates. The old Docker workflows and receipts remain as historical and recovery -material, not a path for new releases. The native workflow cannot publish old -Docker images or move old aliases. New Core code refuses cross-line update -requests, but that guard -cannot change an older installed binary. Do not use an old tag or script to +material, not a path for new releases. Their current definitions refuse +publication before checkout or registry writes; the Changesets version-PR job +still runs on pushes for new 0.x. Do not dispatch historical workflow revisions. +The native workflow cannot publish old Docker images or move old aliases. +New Core code refuses cross-line update requests, but that guard cannot change +an older installed binary. Do not use an old tag or script to bypass the guided migration. Release notes keep the old state-schema markers for the remaining Docker diff --git a/scripts/check-legacy-release-line.sh b/scripts/check-legacy-release-line.sh index f9de7d4a2..3f7e390c6 100644 --- a/scripts/check-legacy-release-line.sh +++ b/scripts/check-legacy-release-line.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash # The old Docker discovery endpoints are shared by already installed boxes. -# Only 2.x maintenance may publish through these workflows until a separate -# native 0.x release path keeps those endpoints on the old line. +# This checks historical tag compatibility for old recovery tools; it does not +# authorize publication. Current workflows block the retired release path. set -euo pipefail tag="${1:?release tag is required}" diff --git a/scripts/install.sh b/scripts/install.sh index 53953cfb3..70592aa23 100755 --- a/scripts/install.sh +++ b/scripts/install.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash # Install one published native 0.x release on a fresh Linux host. -# Existing FTW installations need the separate guided migration. +# Existing sites switch through separate setups; this installer does not migrate data. set -euo pipefail usage() { @@ -17,8 +17,10 @@ an interrupted native install with the same tag and package checksum. of an install this script made with those from the given release. Updates never replace these files; Core itself moves with ftw update. There is no default tag: GitHub releases/latest still serves old Docker boxes. -An existing FTW installation must wait for the guided 0.x migration. This -script will not replace it or update a Docker container. +2.x and 3.x receive no more updates. Existing sites can switch now with a new +SD card/host or separate Docker project and data. Guided transfer of old data +is not ready. See https://github.com/srcfl/ftw/blob/master/docs/native-beta.md. +This script will not replace an existing site or update a Docker container. EOF } @@ -82,7 +84,7 @@ else fi for path in "${existing_paths[@]}"; do if [[ -e "$path" || -L "$path" ]]; then - echo "Existing FTW installation found at $path. Keep it; \"Coming from an older FTW\" in docs/native-beta.md shows how to try 0.x beside it." >&2 + echo "Existing FTW installation found at $path. Keep its data. Use a new card/host or separate Docker setup as described in https://github.com/srcfl/ftw/blob/master/docs/native-beta.md; only one Core may control the equipment." >&2 exit 2 fi done @@ -97,7 +99,7 @@ if [[ "$mode" != --refresh ]] && { fi # Cards made from the old FTW image logged in as ftw, so people pick it again. if [[ "$mode" == --fresh-host ]] && id ftw >/dev/null 2>&1; then - echo "A user named ftw already exists. FTW runs as its own ftw account, so install from a login with another name; on a Raspberry Pi, write the card again and choose a different username." >&2 + echo "A user named ftw already exists. FTW runs as its own ftw account, so install from a login with another name; on a fresh Raspberry Pi card, choose a different username. Keep any card containing an existing FTW site and follow docs/native-beta.md." >&2 exit 2 fi if [[ "$mode" != --refresh ]] && command -v ss >/dev/null 2>&1 && @@ -189,7 +191,7 @@ if [[ "$mode" == --refresh ]]; then fi for path in "${existing_paths[@]}"; do if as_root test -e "$path" || as_root test -L "$path"; then - echo "Existing FTW installation found at $path. Keep it; \"Coming from an older FTW\" in docs/native-beta.md shows how to try 0.x beside it." >&2 + echo "Existing FTW installation found at $path. Keep its data. Use a new card/host or separate Docker setup as described in https://github.com/srcfl/ftw/blob/master/docs/native-beta.md; only one Core may control the equipment." >&2 exit 2 fi done diff --git a/scripts/test-exact-image-promotion.sh b/scripts/test-exact-image-promotion.sh index e602231d3..4d6833593 100755 --- a/scripts/test-exact-image-promotion.sh +++ b/scripts/test-exact-image-promotion.sh @@ -11,6 +11,38 @@ dockerfile="${root}/Dockerfile" core_build="${root}/scripts/build-core.sh" release_guard="${root}/scripts/check-stable-release.py" +# The retained promotion code must be unreachable before checkout or credentials. +python3 - "${beta}" "${release}" "${assets}" <<'PY_GATE' +import pathlib +import re +import subprocess +import sys + +for filename in sys.argv[1:]: + text = pathlib.Path(filename).read_text() + jobs = dict(re.findall(r"^ ([a-z][a-z0-9_-]*):\n(.*?)(?=^ [a-z][a-z0-9_-]*:|\Z)", text.split("\njobs:\n", 1)[1], re.M | re.S)) + root = "release" if filename.endswith("/release.yml") else "registry" + assert root in jobs, filename + for name, body in jobs.items(): + if name != root: + assert re.search(r"^ needs:", body, re.M), (filename, name) + if "always()" in body: + assert "needs.tag.result == 'success'" in body, (filename, name) + first = jobs[root].split(" steps:\n", 1)[1].split("\n - ", 1)[0] + assert "name: Refuse retired Docker publication" in first, filename + assert "continue-on-error" not in first and "continue-on-error" not in jobs[root], filename + if root == "release": + assert "if: github.event_name == 'workflow_dispatch'" in first, filename + assert "\n push:\n" in text, "native version PRs must still run on push" + for condition in re.findall(r"^ if: (.*always\(\).*)$", jobs[root], re.M): + assert condition == "always() && github.event_name == 'push'", condition + else: + assert " if:" not in first, filename + run = first.split(" run: |\n", 1)[1] + result = subprocess.run(["/bin/bash", "-c", run], env={"PATH": "/nonexistent"}, capture_output=True, text=True) + assert result.returncode == 1 and "releases are retired" in result.stdout, filename +PY_GATE + for workflow in "${beta}" "${release}" "${assets}"; do if grep -Eq 'SOURCEFUL_GHCR_(USER|TOKEN)' "${workflow}"; then echo "canonical GHCR writes must use the workflow GITHUB_TOKEN: ${workflow}" >&2 @@ -191,8 +223,6 @@ grep -Fq 'name: Validate both exact candidate manifests' "${assets}" grep -Fq 'name: Preflight all exact stable aliases' "${assets}" grep -Fq 'name: Publish and verify exact stable aliases updater before Core' "${assets}" grep -Fq '.release-workflow/scripts/promote-paired-latest.sh' "${assets}" -grep -Fq -- '--ref master -f tag=vX.Y.Z -f source_beta=vX.Y.Z-beta.N -f release_id=123' "${assets}" -grep -Fq -- '--ref master -f tag=vX.Y.Z -f release_id=123' "${assets}" grep -Fq 'name: verify complete draft assets' "${assets}" grep -Fq 'python3 scripts/check-stable-release.py order "${TAG}"' "${assets}" grep -Fq 'python3 .release-workflow/scripts/check-stable-release.py assets "${TAG}"' "${assets}"