birdnet-go: don't abort init when default-config download fails

Removing /config/config.yaml after a failed first-boot curl left the
next yq read (.realtime.audio.export.path) trying to open a missing
file; under set -e that aborts the entire cont-init script, so the
addon would never get to seed its defaults or start BirdNET-Go.

Seed an empty YAML document ({}) instead. The existing "//=" defaults
block then populates output.sqlite.path, logging.file_output.*, and
the migration block writes realtime.audio.export.path. Result: an
offline first boot now produces a valid minimal config.yaml and the
container starts cleanly.

Also harden the yq read with "// """ so a freshly seeded "{}" doc
returns an empty string (caught by the existing :-DEFAULT fallback)
rather than the literal string "null".
This commit is contained in:
Claude
2026-05-28 17:24:11 +00:00
parent 854f90cbe8
commit a4f6ab3b2f
2 changed files with 12 additions and 7 deletions

View File

@@ -5,7 +5,7 @@
- **Breaking (UI only)**: The nginx ingress reverse-proxy no longer rewrites HTML `href`/`src`/`action` attributes; upstream BirdNET-Go handles those itself via `X-Ingress-Path`. JavaScript string-literal rewrites are unchanged. Please file an issue if you see broken images, links, or forms in the ingress UI after upgrade.
- Fix database-migration restore: the timestamped backup created during a `BIRDSONGS_FOLDER` change was being written to the script's working directory and looked up under a fresh timestamp on restore, so a SQL failure left the user unable to recover. Backup path is now absolute and reused for restore.
- Harden the `BIRDSONGS_FOLDER` SQL/YAML path substitution: paths containing characters outside `[A-Za-z0-9._/-]` are now rejected up front instead of being interpolated raw into the SQL UPDATE statement.
- Tolerate a missing internet connection on first boot: if the default `config.yaml` cannot be downloaded from GitHub, BirdNET-Go now falls back to its embedded defaults instead of starting with an empty config.
- Tolerate a missing internet connection on first boot: if the default `config.yaml` cannot be downloaded from GitHub, the init script now seeds an empty YAML document so the addon-defaults block populates a usable config (rather than aborting the script on the next `yq` call under `set -e`).
- Warn (without failing the build) if the upstream `entrypoint.sh` patch target drifts in a new nightly.
- Remove a dead nginx upstream definition that pointed at an unused port.

View File

@@ -27,13 +27,16 @@ validate_safe_path() {
if [ ! -f "$CONFIG_LOCATION" ]; then
bashio::log.warning "There is no config.yaml yet in the config folder, downloading a default one. Please customize"
# Network may be unreachable on first boot; tolerate failure and let
# birdnet-go fall back to its embedded default on first run.
# Network may be unreachable on first boot. If the download fails, seed
# an empty YAML document so the yq reads/writes below succeed and the
# default-value seeding logic later in this script populates a usable
# config. (We can't remove the file and continue — subsequent yq calls
# under set -e would abort the init script.)
if ! curl -fL -s -S \
https://raw.githubusercontent.com/tphakala/birdnet-go/refs/heads/main/internal/conf/config.yaml \
-o "$CONFIG_LOCATION"; then
bashio::log.warning "Could not download default config.yaml; birdnet-go will create one from its embedded defaults"
rm -f "$CONFIG_LOCATION"
bashio::log.warning "Could not download default config.yaml; seeding an empty document so addon defaults can populate it"
echo '{}' > "$CONFIG_LOCATION"
fi
fi
@@ -48,8 +51,10 @@ fi
######################
# Birdsongs Location
######################
# Read the current folder from config.yaml; fall back to the legacy default.
CURRENT_BIRDSONGS_FOLDER="$(yq '.realtime.audio.export.path' "$CONFIG_LOCATION" | tr -d '\"')"
# Read the current folder from config.yaml; "// """ collapses both missing
# keys and explicit nulls (e.g. in a freshly seeded "{}" doc) to an empty
# string so the ${VAR:-DEFAULT} fallback below kicks in.
CURRENT_BIRDSONGS_FOLDER="$(yq -r '.realtime.audio.export.path // ""' "$CONFIG_LOCATION")"
CURRENT_BIRDSONGS_FOLDER="${CURRENT_BIRDSONGS_FOLDER:-$DEFAULT_BIRDSONGS_FOLDER}"
# Treat the upstream-shipped relative "clips/" as the legacy default.
if [[ "$CURRENT_BIRDSONGS_FOLDER" == "clips" || "$CURRENT_BIRDSONGS_FOLDER" == "clips/" ]]; then