From 89973a2bb7febc2325f1c4ea8c3e972bd9b044fb Mon Sep 17 00:00:00 2001 From: alexbelgium Date: Thu, 24 Sep 2026 07:48:41 +0200 Subject: [PATCH] feat(free_games_claimer): store application data in /config/data The add-on kept everything the application writes in its private /data volume, so the claim database, the screenshots and the browser profiles could only be reached with a "docker exec" (#3081). /fgc/data now points at /config/data, which Home Assistant exposes as /addon_configs/xxx-free_games_claimer/data. This is the pattern the aurral, maintainerr and nextcloud add-ons already use for the same problem. An existing /data payload is copied over once on first start. The copy is staged in /config/.data-migration and renamed into place, so an interrupted migration is retried on the next start instead of leaving a half-copied database or browser profile behind. Nothing is removed from /data, so a downgrade to 2.1.0 still finds its data. Two clean-ups in the same script, both consequences of the move: the "cp -rnf /fgc/* /data/" line copied the whole upstream source tree into the persistent volume on every start and nothing ever read those copies, and the recursive "chmod 777" on the configuration directory would now have made the migrated browser profile and the credentials in config.env world-writable. Co-Authored-By: Claude Opus 5 --- free_games_claimer/CHANGELOG.md | 30 +++++++++++++++++++ free_games_claimer/Dockerfile | 2 +- free_games_claimer/README.md | 30 +++++++++++++++++-- free_games_claimer/config.yaml | 2 +- .../rootfs/etc/cont-init.d/20-folders.sh | 30 ++++++++++++++++--- .../rootfs/etc/cont-init.d/99-run.sh | 8 ++--- .../usr/local/bin/migrate_vogler_data.py | 4 +-- 7 files changed, 92 insertions(+), 14 deletions(-) diff --git a/free_games_claimer/CHANGELOG.md b/free_games_claimer/CHANGELOG.md index 8314c6f919..69471b3af6 100644 --- a/free_games_claimer/CHANGELOG.md +++ b/free_games_claimer/CHANGELOG.md @@ -1,3 +1,33 @@ +## 2.2.0 (2026-09-24) + +- Moved the application data out of the add-on's private `/data` volume and + into `/config/data`, so it is visible from Home Assistant as + `/addon_configs/xxx-free_games_claimer/data` instead of needing a + `docker exec`. Everything the application writes now lands there: `fgc.db`, + the `screenshots/` captures, the `browser/` profiles, `TurboVNC.log` and + upstream's debug dumps (#3081). +- An existing `/data` payload is copied over once on the first start of this + version: `fgc.db` and its pre-migration backup, `browser/`, `screenshots/`, + `prime-gaming.json`, the legacy `data/` directory and the migration marker. + Logs and last-run debug dumps are not copied, because the application + regenerates them. The copy is staged and renamed into place, so an interrupted + migration is retried rather than leaving a half-copied database or browser + profile. Nothing is deleted from `/data`: the migration needs temporary free + space roughly equal to the existing data, can take a few minutes for a large + browser profile, and leaves the old copy in place so a downgrade still + works. +- **The migrated `browser/` directory holds authenticated store sessions and + `config.env` holds the account credentials. Both are now readable by any + add-on with access to `addon_configs`, such as File Editor or Samba. Treat + that directory as secret and do not share or back it up publicly.** +- Removed the `cp -rnf /fgc/* /data/` line from `20-folders.sh`, which copied + the whole upstream source tree into the persistent volume on every start. + Nothing read those copies. They are left in `/data` and can be deleted by + hand. +- Stopped applying a recursive `chmod 777` to the configuration directory on + every start, which would otherwise have made the migrated browser profile + and credentials world-writable. + ## 2.1.1 (2026-09-12) - Update to latest version from P-Adamiec/Free-Games-Claimer-Remaster (changelog : https://github.com/P-Adamiec/Free-Games-Claimer-Remaster/releases) diff --git a/free_games_claimer/Dockerfile b/free_games_claimer/Dockerfile index f56c24935d..bcfd464924 100644 --- a/free_games_claimer/Dockerfile +++ b/free_games_claimer/Dockerfile @@ -118,7 +118,7 @@ RUN (curl --proto "=https" --tlsv1.2 -fsSL \ && chmod 0755 /usr/local/bin/docker-entrypoint.sh \ && rm -f /tmp/free-games-claimer-remaster.tar.gz \ && rm -rf /fgc/data \ - && ln -s /data /fgc/data + && ln -s /config/data /fgc/data # Add Home Assistant integration files and shared helper modules. COPY rootfs/ / diff --git a/free_games_claimer/README.md b/free_games_claimer/README.md index 0dcb0a2256..ed7911826f 100644 --- a/free_games_claimer/README.md +++ b/free_games_claimer/README.md @@ -67,6 +67,31 @@ the default and preserves the behavior of the former vogler-based add-on. With `RUN_ONCE: false`, the remaster remains running and uses its internal scheduler. Set `SCHEDULER_HOURS` in `config.env` to control the interval. +## Application data + +The add-on stores everything the application writes in `/config/data`, which +Home Assistant exposes as `/addon_configs/xxx-free_games_claimer/data`. It can +be inspected with a file browser add-on without a `docker exec`, and contains: + +| Path | Contents | +|------|----------| +| `fgc.db` | SQLite claim history | +| `screenshots//` | Screenshots taken during a claiming run | +| `browser/` | Chromium profiles, one per store | +| `TurboVNC.log` | Virtual display server log | +| `config.env` | Runtime copy of `CONFIG_LOCATION` | + +**This directory is secret.** `browser/` holds signed-in store sessions and +`config.env` holds the account credentials, so anyone with access to +`addon_configs` — the File Editor and Samba add-ons, for instance — can use +them. Do not share or publish it. + +Versions up to 2.1.1 kept this data in the private `/data` volume. An existing +payload is copied to `/config/data` once, on the first start of version 2.2.0. The copy needs temporary free space roughly equal to the +existing data and can take a few minutes when the browser profile is large. +Nothing is removed from `/data`, so a downgrade keeps working; the old copy can +be deleted by hand once the new location is confirmed to work. + ## Environment configuration The add-on keeps its configuration in `CONFIG_LOCATION`, which defaults to @@ -124,12 +149,13 @@ The add-on performs the following migration automatically on first start: 1. The existing `config.env` remains at the same configured location. 2. Legacy `epic-games.json`, `prime-gaming.json`, and `gog.json` claim history - is imported into the remaster SQLite database at `/data/fgc.db`. + is imported into the remaster SQLite database at `/config/data/fgc.db`. 3. Existing database rows are detected and are not duplicated if migration is retried. 4. A pre-migration database backup is created when an existing `fgc.db` is present. -5. All old files remain under `/data/data` for rollback or manual recovery. +5. All old files remain under `/config/data/data` for rollback or manual + recovery. Browser sessions cannot be converted because the old add-on used a shared Firefox profile while the remaster uses separate Chromium profiles per store. diff --git a/free_games_claimer/config.yaml b/free_games_claimer/config.yaml index bdaf2c7b68..1d7d21322f 100644 --- a/free_games_claimer/config.yaml +++ b/free_games_claimer/config.yaml @@ -96,5 +96,5 @@ schema: slug: free_games_claimer udev: true url: https://github.com/alexbelgium/hassio-addons -version: "2.1.1" +version: "2.2.0" webui: "[PROTO:ssl]://[HOST]:[PORT:6080]" diff --git a/free_games_claimer/rootfs/etc/cont-init.d/20-folders.sh b/free_games_claimer/rootfs/etc/cont-init.d/20-folders.sh index 396a0ebb13..e19f32cbde 100755 --- a/free_games_claimer/rootfs/etc/cont-init.d/20-folders.sh +++ b/free_games_claimer/rootfs/etc/cont-init.d/20-folders.sh @@ -8,8 +8,30 @@ echo "Creating config location ..." HOME="$(bashio::config "CONFIG_LOCATION")" HOME="$(dirname "$HOME")" mkdir -p "$HOME" -chmod -R 777 "$HOME" -# Copy files to data -echo "Copying files if needed..." -cp -rnf /fgc/* /data/ +# Up to version 2.1.1 the application stored its data in the add-on's private +# /data volume, which is only reachable with "docker exec". It now lives in +# /config/data, which Home Assistant exposes as +# /addon_configs/xxx-free_games_claimer/data. Copy an existing payload over +# once. The copy is staged and renamed into place, so an interrupted migration +# is retried on the next start instead of leaving a half-copied database or +# browser profile behind. Nothing is removed from /data, so downgrading still +# finds its data. +if [ ! -d /config/data ]; then + legacy=() + for entry in fgc.db fgc.db.pre-vogler-migration .vogler-remaster-migrated-v1.json \ + browser screenshots data prime-gaming.json; do + if [ -e "/data/$entry" ]; then + legacy+=("/data/$entry") + fi + done + if [ "${#legacy[@]}" -gt 0 ]; then + echo "Copying the application data to /config/data, this can take a few minutes ..." + rm -rf /config/.data-migration + mkdir -p /config/.data-migration + cp -a "${legacy[@]}" /config/.data-migration/ + mv /config/.data-migration /config/data + fi +fi + +mkdir -p /config/data diff --git a/free_games_claimer/rootfs/etc/cont-init.d/99-run.sh b/free_games_claimer/rootfs/etc/cont-init.d/99-run.sh index 7dac64162d..ea832041c7 100755 --- a/free_games_claimer/rootfs/etc/cont-init.d/99-run.sh +++ b/free_games_claimer/rootfs/etc/cont-init.d/99-run.sh @@ -7,9 +7,9 @@ if bashio::config.has_value 'CONFIG_LOCATION'; then CONFIG_FILE="$(bashio::config 'CONFIG_LOCATION')" fi CONFIG_DIR="$(dirname "${CONFIG_FILE}")" -RUNTIME_CONFIG="/data/config.env" +RUNTIME_CONFIG="/config/data/config.env" -mkdir -p "${CONFIG_DIR}" /data +mkdir -p "${CONFIG_DIR}" /config/data # Recover from an old add-on bug that could create config.env as a directory. if [ -d "${CONFIG_FILE}" ]; then @@ -25,8 +25,8 @@ else bashio::log.info "Using configuration from ${CONFIG_FILE}" fi -# The remaster reads /fgc/data/config.env. /fgc/data is linked to Home -# Assistant's persistent /data volume by the Dockerfile. +# The remaster reads /fgc/data/config.env. /fgc/data is linked to /config/data +# by the Dockerfile, so the runtime copy is visible under /addon_configs. install -m 0600 "${CONFIG_FILE}" "${RUNTIME_CONFIG}" sed -i 's/\r$//' "${RUNTIME_CONFIG}" diff --git a/free_games_claimer/rootfs/usr/local/bin/migrate_vogler_data.py b/free_games_claimer/rootfs/usr/local/bin/migrate_vogler_data.py index 1c11bf6e3b..0b683b1cc7 100644 --- a/free_games_claimer/rootfs/usr/local/bin/migrate_vogler_data.py +++ b/free_games_claimer/rootfs/usr/local/bin/migrate_vogler_data.py @@ -12,7 +12,7 @@ from datetime import datetime, timezone from pathlib import Path from typing import Any, Iterator -DATA_DIR = Path(os.environ.get("FGC_DATA_DIR", "/data")) +DATA_DIR = Path(os.environ.get("FGC_DATA_DIR", "/config/data")) LEGACY_DIR = DATA_DIR / "data" DATABASE = DATA_DIR / "fgc.db" MARKER = DATA_DIR / ".vogler-remaster-migrated-v1.json" @@ -220,7 +220,7 @@ def migrate() -> int: if legacy_browser.exists(): log( - "Legacy Firefox browser data remains in /data/data/browser. It is " + "Legacy Firefox browser data remains in /config/data/data/browser. It is " "not compatible with Chromium, so use noVNC for a one-time login if needed." )