* OPNSense: Bump FreeBSD to 15 and OPNSense to 26.7
* fix user feedback
* fix typo
* fix url for image
* Replace fixed OPNsense wait with screen polling
Swap the hardcoded 1000-second sleep for an adaptive loop that watches VM console screendump hashes and proceeds after sustained stability. The new logic enforces a minimum 5-minute wait, checks every 30 seconds, and caps total wait at 40 minutes to handle slower hosts or screendump failures more reliably.
* Harden OPNsense build wait detection
Improves VM install completion detection by encapsulating screendump hashing in a helper, clearing stale dump files, and trying both `qm monitor` and `pvesh` monitor paths. The stability check now tolerates alternating A/B frames from a blinking login cursor instead of requiring one identical frame. It also adds elapsed-time progress output and a safe fallback to a fixed 12-minute wait when screendumps are unavailable, avoiding false completion or endless polling.
* core: add OS mismatch guard for container updates
Introduces `check_container_os_guard()` to compare the container's `/etc/os-release` against the script's recommended `var_os`/`var_version` before running updates. On mismatch, interactive runs now prompt to continue (default no), while silent/headless runs abort to avoid partial breakage on unsupported bases. A bypass flag (`var_ignore_os_mismatch=1|yes|true|on`) was added, and the guard is wired into all update entry paths in `start()`.
* Refine OS mismatch update guidance
Updates the OS version mismatch prompts in `check_container_os_guard()` to recommend upgrading the existing container OS to the target release before rerunning the update, instead of recreating the container. The skip/error path now uses the same guidance while still documenting `var_ignore_os_mismatch=1` as an override.
* Add persistent OS mismatch bypass option
Enhances `check_container_os_guard` to support a persistent opt-out for OS version mismatch checks. The prompt now uses a 3-option whiptail menu (cancel, continue once, continue and remember), and stores ignored targets in `/root/.helper-scripts-ignoreOSupdate` so users are re-prompted when a newer recommended OS appears. Messaging was also tightened to explicitly warn that bypassing may break updates and is unsupported.
* switch to /usr/local
* Re-download snappdf Chromium after Invoice Ninja updates
update_script() redeploys /opt/invoiceninja via CLEAN_INSTALL, which
wipes vendor/beganovich/snappdf/versions. That path isn't covered by
create_backup/restore_backup, so the Chromium binary snappdf needs for
PDF generation was missing after every update, breaking PDFs (#15942).
Re-run the same "vendor/bin/snappdf download" step the install script
already does, right after the backup is restored.
* Back up snappdf's Chromium download to avoid re-fetching on every update
vendor/bin/snappdf download is idempotent: it exits immediately without
downloading if versions/revision.txt already exists, and PDF generation
doesn't check that version against the installed snappdf package - it
just uses whatever's in versions/. So the cached Chromium build survives
just fine across an update via the existing backup/restore mechanism.
Add vendor/beganovich/snappdf/versions to create_backup/restore_backup;
keep the snappdf download call only as a safety net for when the backup
doesn't have it yet (e.g. the first update after this fix ships).
* Remove explanatory comment
Overwriting /etc/mongod.conf with only the replication block wiped
out storage.dbPath from the mongodb-org package default, so mongod
fell back to its compiled-in /data/db path, which was never created.
Append the replication section instead of replacing the file.
* Fix Nametag update failing with missing tailwindcss module
npm ci during update ran with devDependencies omitted, likely because
NODE_ENV=production was already present in the environment by then
(npm's documented default: omit=dev when NODE_ENV=production). Since
@tailwindcss/postcss is a devDependency, the subsequent `npm run build`
failed with "Cannot find module '@tailwindcss/postcss'". Force devDeps
to be installed regardless of NODE_ENV via --include=dev.
* Apply --include=dev to fresh installs too, for parity with update fix
Couldn't confirm within this repo why devDependencies would only be
omitted on update and not on a fresh install - create_backup/
restore_backup are plain file copies and nothing in tools.func sets
NODE_ENV or writes an .npmrc. Since npm ci runs before .env is sourced
in both scripts, apply the same explicit --include=dev to the installer
as defense-in-depth against the same class of failure.
Same bug as build.func's install-recovery menu: this "Remove broken
container?" prompt treated a hard read failure (broken/closed stdin,
I/O error) identically to a real 60s timeout, defaulting to pct
destroy either way. Only auto-remove on an actual timeout (read_rc >
128); on a genuine read failure, keep the container instead of
guessing and destroying it.
read -t returns >128 on a real timeout, but a lower/plain error code
on a genuine read failure (e.g. broken/closed stdin, I/O error) -
these were treated identically as "no response", so a user whose
keystroke failed to be captured (e.g. a transient stdin I/O error)
got their container silently destroyed instead of kept. Only
auto-remove on an actual timeout; on a hard read failure, keep the
container (reversible) and tell the user how to remove it manually.
Updates temp-file and temp-dir cleanup traps in `misc/tools.func` to unset the `RETURN` trap after running cleanup. This prevents stale RETURN traps from leaking into later function returns and avoids repeated or unintended cleanup behavior in nested helper flows.
Overhaul the telemetry system to enforce a single-reporter model where only the HOST sends terminal statuses (success/failed/aborted) to the API. Containers now write local artifact files (.failed flag + .errinfo) that the host picks up after lxc-attach returns, preventing the race condition where a metadata-less container payload would win over the full host payload.
Key changes:
- Add TELEMETRY_CONTEXT=container export in install.func/alpine-install.func to mark container context before error handling starts
- Introduce _is_container_context() heuristic and _container_write_failure() artifact writer in error_handler.func
- Refactor api.func: unified _tm_payload() builder (full metadata on every send), _tm_send() curl wrapper, _tm_enabled() gate, telemetry_collect_sysinfo() cached collector
- Add structured .errinfo capture in silent() (core.func) using byte-offset to extract exactly the failing command's output
- Pull .errinfo from container in build.func after lxc-attach for precise error traces
- Add categorize_error(), telemetry_new_attempt(), detect_arm(), REPO_SLUG tracking
- Signal exits (129/130/143) now report as 'aborted' instead of 'failed'
- Remove post_update_to_api_extended() (superseded by unified _tm_payload)
- Export REPO_SOURCE, REPO_SLUG, TELEMETRY_PLATFORM into container environment
CLEAN_INSTALL now removes dotfiles (e.g. .env) along with other files, using `find -mindepth 1 -delete` instead of `rm -rf *`. Update scripts for affine, nametag, and postiz are updated to explicitly back up and restore .env (via create_backup/restore_backup or cp) BEFORE the build step that sources it, rather than relying on the wipe preserving dotfiles.
* RomM: use backup helpers in update / clear folder
Replace manual .env backup/restore with create_backup and restore_backup helpers, and add CLEAN_INSTALL=1 flag to fetch_and_deploy_gh_release.
* add screenscraper env
* add rom_patcher
* add ruffle and emulatorJS
Define `path.data` and `path.logs` in the Zammad install script's Elasticsearch config so the service uses the expected data and log directories when running in the single-node local setup.
Update both `ct/omada.sh` and `install/omada-install.sh` to parse the Omada version directly from the `_v..._linux` segment of the Debian filename. This removes the old dependency on a timestamp suffix format and ensures `.omada` gets a valid version when TP-Link package naming varies.
The /data/plugins symlink fails in default unprivileged containers with Operation not permitted. Link plugins via /opt/wanderer/source/db/data/plugins instead so PluginDir() can discover them without root-level symlinks.
Fixes#15799
* tools.func: replace rm -rf with find for safer directory cleanup
* tools.func: replace rm -rf with find for safer directory cleanup
* refactor(tools.func): centralize deploy tail + trap-based tmpdir cleanup
Extract the duplicated post-download logic of the fetch_and_deploy_*
helpers into two shared functions and switch per-branch cleanup to a
single RETURN trap.
- _deploy_source_tarball: shared source-tarball tail (6 call sites)
- _deploy_unpacked_archive: shared prebuild-archive tail (3 call sites)
- RETURN trap per function guarantees tmpdir/unpack_tmp cleanup on every
return path, replacing ~40 manual `rm -rf "$tmpdir"` lines
- CLEAN_INSTALL now lives in the helpers instead of 12 copies
Behavior-preserving except: codeberg prebuild gains .txz support and
uses helper return codes; from_url resets shopt on error paths.
* Add _download_source_tarball with retry/validation
Introduce `_download_source_tarball` helper that validates gzip integrity after download and retries up to 3 times. This guards against truncated-but-valid-HTTP responses from GitHub/GitLab/Codeberg on-the-fly archive generation. Replace ad-hoc curl/curl_download calls in fetch_and_deploy_* functions with the new helper. Also remove redundant tmpdir cleanup before early returns (tmpdir is cleaned up at function exit).
* Fix Manyfold Ruby setup home initialization
Create the `manyfold` service user before calling `setup_ruby` so `/home/manyfold` exists when rbenv profile snippets are written. Also harden `setup_ruby` by creating `$HOME` if missing, preventing profile-write failures for installers that pass a home directory before creating the user.
* Update install/manyfold-install.sh
---------
Co-authored-by: Sam Heinz <sam@samheinz.com>