Add nebula sync container - #1424
Conversation
- Host script (ct/nebula-sync.sh) and install script for nebula-sync - Prompts for primary/replica Pi-hole URL and API password, sync options, cron - .env with PRIMARY/REPLICAS in url|password format, wrapper and systemd service - Frontend JSON and header; notes on Pi-hole API and app_sudo requirement
Remove || true error suppression and properly check file/service state before operations
- Remove inline comments from wrapper script heredoc - Fix env verification to parse lines instead of unsafe shell-loading - Add standard access URL format to completion block
Greptile OverviewGreptile Summary
Confidence Score: 3/5
Important Files Changed
|
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
| INSTALL_PATH="/opt/nebula-sync" | ||
| ENV_PATH="/opt/nebula-sync/.env" | ||
| SERVICE_PATH="/etc/systemd/system/nebula-sync.service" | ||
|
|
||
| msg_info "Installing Nebula-Sync" | ||
| fetch_and_deploy_gh_release "nebula-sync" "lovelaze/nebula-sync" "prebuild" "latest" "/opt/nebula-sync" "nebula-sync_.*_linux_.*\.tar\.gz" |
There was a problem hiding this comment.
Missing install dir
This script writes "$ENV_PATH" (/opt/nebula-sync/.env) but never creates ${INSTALL_PATH} first. If fetch_and_deploy_gh_release doesn’t create the directory on failure (or if it extracts elsewhere), the redirect > "$ENV_PATH" will fail and abort the install.
| INSTALL_PATH="/opt/nebula-sync" | |
| ENV_PATH="/opt/nebula-sync/.env" | |
| SERVICE_PATH="/etc/systemd/system/nebula-sync.service" | |
| msg_info "Installing Nebula-Sync" | |
| fetch_and_deploy_gh_release "nebula-sync" "lovelaze/nebula-sync" "prebuild" "latest" "/opt/nebula-sync" "nebula-sync_.*_linux_.*\.tar\.gz" | |
| INSTALL_PATH="/opt/nebula-sync" | |
| ENV_PATH="/opt/nebula-sync/.env" | |
| SERVICE_PATH="/etc/systemd/system/nebula-sync.service" | |
| mkdir -p "$INSTALL_PATH" |
| if [[ "$FULL_SYNC" == "false" ]]; then | ||
| cat <<EOF>>"$ENV_PATH" | ||
| SYNC_CONFIG_DNS=${SYNC_CONFIG_DNS} |
There was a problem hiding this comment.
Heredoc redirection style
Repo style rule requires heredoc delimiter to come before the redirection (i.e., cat <<EOF>>file). This currently uses cat <<EOF>>"$ENV_PATH".
| if [[ "$FULL_SYNC" == "false" ]]; then | |
| cat <<EOF>>"$ENV_PATH" | |
| SYNC_CONFIG_DNS=${SYNC_CONFIG_DNS} | |
| cat <<EOF >>"$ENV_PATH" |
Context Used: Rule from dashboard - What: Heredoc syntax must come before the output redirection in cat commands.
Why: Placing the here... (source)
Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
| [[ -z "$line" || "$line" =~ ^[[:space:]]*# ]] && continue | ||
| if [[ "$line" =~ ^[A-Z_][A-Z0-9_]*= ]]; then | ||
| key="${line%%=*}" | ||
| value="${line#*=}" | ||
| export "${key}=${value}" |
There was a problem hiding this comment.
Wrapper ignores # lines
The wrapper skips lines matching ^[[:space:]]*#, but the repo rule forbids comments in install/ct scripts; since .env is generated without comments, this is dead code and adds unnecessary complexity. If you keep it, it can also break if a value legitimately starts with #.
| [[ -z "$line" || "$line" =~ ^[[:space:]]*# ]] && continue | |
| if [[ "$line" =~ ^[A-Z_][A-Z0-9_]*= ]]; then | |
| key="${line%%=*}" | |
| value="${line#*=}" | |
| export "${key}=${value}" | |
| [[ -z "$line" ]] && continue |
Context Used: Rule from dashboard - What: Shell script files in ct/ and /install directories must not contain comments except for file h... (source)
| exec "$BINARY" run | ||
| EOFWRAPPER |
There was a problem hiding this comment.
No binary existence check
The wrapper unconditionally execs /opt/nebula-sync/nebula-sync. If the release deploy fails or changes asset layout, the service will crash-loop with a less actionable error. Add an explicit check so install/update failures surface clearly.
| exec "$BINARY" run | |
| EOFWRAPPER | |
| if [[ ! -x "$BINARY" ]]; then | |
| echo "Nebula-Sync binary not found/executable at $BINARY" >&2 | |
| exit 1 | |
| fi | |
| exec "$BINARY" run |
Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
| chmod +x /usr/local/bin/update_nebula-sync | ||
| msg_ok "Created update script" | ||
|
|
||
| echo "$LATEST_RELEASE" > "/opt/nebula-sync_version.txt" |
There was a problem hiding this comment.
Empty version on API failure
LATEST_RELEASE is written to /opt/nebula-sync_version.txt without validating it’s non-empty. If the GitHub API call fails or rate-limits, this writes an empty version file and the CT update flow will think an update is always needed. Guard the write.
| echo "$LATEST_RELEASE" > "/opt/nebula-sync_version.txt" | |
| if [[ -n "$LATEST_RELEASE" ]]; then | |
| echo "$LATEST_RELEASE" > "/opt/nebula-sync_version.txt" | |
| fi |
| if [[ ! -f /usr/local/bin/update_nebula-sync ]] && [[ ! -f /opt/nebula-sync_version.txt ]]; then | ||
| msg_error "No ${APP} Installation Found!" | ||
| exit | ||
| fi |
There was a problem hiding this comment.
Update check condition
This if requires both the update script and version file to be missing to error. If either one exists but is stale/broken, the script proceeds and then may fail later. If the intent is “must have update script present for update flow”, check that directly.
| if [[ ! -f /usr/local/bin/update_nebula-sync ]] && [[ ! -f /opt/nebula-sync_version.txt ]]; then | |
| msg_error "No ${APP} Installation Found!" | |
| exit | |
| fi | |
| if [[ ! -f /usr/local/bin/update_nebula-sync ]]; then | |
| msg_error "No ${APP} Installation Found!" | |
| exit | |
| fi |
|
@gabriel403 is this ready to review? |
|
@gabriel403 This PR has been marked as stale. It will be closed if no new commits are added in 7 days. |
|
@gabriel403 Closing stale PR due to inactivity (no commits for 7 days after stale label). |
✍️ Description
Adds a new LXC container script for Nebula-Sync (lovelaze/nebula-sync), which synchronizes configuration across multiple Pi-hole v6.x instances (primary → replica).
Included:
ct/nebula-sync.sh): Creates unprivileged Debian 13 LXC (1 CPU, 512 MB RAM, 2 GB disk), tagsdns;sync, supports update flow.install/nebula-sync-install.sh): Downloads latest release binary, prompts for primary and replica Pi-hole URL/IP and API password, sync mode (all or custom selection), and cron interval. Writes/opt/nebula-sync/.envinurl|passwordformat (handles special characters), creates wrapper + systemd service, and installsupdate_nebula-sync.frontend/public/json/nebula-sync.json): App metadata, description, and notes for the script’s web page.ct/headers/nebula-sync): ASCII banner for the app.User-facing notes (in JSON and for docs): Pi-hole must be v6.x with API access; API password is the web interface password;
app_sudo = truemust be set in/etc/pihole/pihole.tomlunder[webserver.api]on all Pi-hole instances for sync to work.🔗 Related Issue
Fixes #
✅ Prerequisites (X in brackets)
🛠️ Type of Change (X in brackets)
README,AppName.md,CONTRIBUTING.md, or other docs.