Skip to content

[feature] Allow custom install/upgrade path in auto-install.sh#515

Open
c-gabri wants to merge 7 commits intoopenwisp:masterfrom
c-gabri:custom-install-path
Open

[feature] Allow custom install/upgrade path in auto-install.sh#515
c-gabri wants to merge 7 commits intoopenwisp:masterfrom
c-gabri:custom-install-path

Conversation

@c-gabri
Copy link
Contributor

@c-gabri c-gabri commented Oct 4, 2025

Checklist

  • I have read the OpenWISP Contributing Guidelines.
  • I have manually tested the changes proposed in this pull request.
  • I have written new test cases for new code and/or updated existing tests for changes to existing code.
  • I have updated the documentation.

Reference to Existing Issue

Closes #514.

Description of Changes

Let users specify a custom install/upgrade path when running auto-install.sh by passing it as an argument of --install/--upgrade. Document this feature.

Screenshot

@coderabbitai
Copy link

coderabbitai bot commented Mar 10, 2026

Warning

Rate limit exceeded

@nemesifier has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 13 minutes and 57 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 64eaf2e2-b1b7-4a08-b486-ce08292f0f3c

📥 Commits

Reviewing files that changed from the base of the PR and between bf4963c and 12f00c6.

📒 Files selected for processing (1)
  • docs/user/quickstart.rst
📝 Walkthrough

Walkthrough

The PR makes the auto-install script's installation path configurable by introducing USER_INSTALL_PATH (default /opt/openwisp) and allowing an optional path via -i/--install or -u/--upgrade. INSTALL_PATH, LOG_FILE, ENV_USER, and ENV_BACKUP are derived from USER_INSTALL_PATH after CLI parsing and exported for the remainder of the script. Help text and docs (docs/user/quickstart.rst) were updated to document the configurable path and upgrade usage. images/openwisp_dashboard/openvpn.json only had formatting changes.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant Script as auto-install.sh
    participant Parser as Arg Parser
    participant Env as Env Derivation
    participant Installer as Setup/Upgrade
    User->>Script: run script (with/without -i/--install or -u/--upgrade)
    Script->>Parser: forward CLI args
    Parser-->>Script: parsed flags and optional install-path
    Script->>Env: set USER_INSTALL_PATH (default or resolved realpath)
    Env-->>Script: export INSTALL_PATH, LOG_FILE, ENV_USER, ENV_BACKUP
    Script->>Installer: proceed with setup or upgrade using derived paths
    Installer-->>Script: write logs to LOG_FILE, update ENV_USER/ENV_BACKUP
    Script-->>User: exit status and log/help location
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

🚥 Pre-merge checks | ✅ 3 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Out of Scope Changes check ⚠️ Warning The PR includes a minor JSON formatting change to openvpn.json that appears unrelated to the custom install path feature. Remove the JSON formatting changes from images/openwisp_dashboard/openvpn.json or move them to a separate PR focused on code formatting.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically describes the main feature: allowing custom install/upgrade paths in auto-install.sh.
Description check ✅ Passed The description covers the main changes and closes the linked issue, but lacks new test cases and only partially documents all changes.
Linked Issues check ✅ Passed The PR fully implements the requirements from issue #514: accepting custom paths via --install/--upgrade arguments and documenting the feature.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@deploy/auto-install.sh`:
- Around line 72-73: The problem is that the curl and sh invocations use single
quotes around '${USER_INSTALL_PATH}/get-docker.sh' which prevents shell variable
expansion; update the two commands that reference
${USER_INSTALL_PATH}/get-docker.sh (the curl line and the sh line) to allow
expansion by removing the single quotes or using double quotes so the variable
expands at runtime and the script is saved and executed from the intended path.
- Around line 313-321: The issue is the unconditional inner "shift" inside the
case branch handling "-i | --install | -u | --upgrade" which consumes the next
token even when no path was provided or when that token is another flag; update
the case handling around USER_INSTALL_PATH and the shifts so that you only call
"shift" to consume the optional path when a path was actually set (i.e., when [[
-n "$2" ]] is true), leaving the outer "shift" to consume the option flag
itself; locate the case branch that sets USER_INSTALL_PATH and adjust control
flow to avoid shifting away a next flag or shifting past available args.
- Around line 313-327: The script accepts arbitrary USER_INSTALL_PATH and then
builds INSTALL_PATH, LOG_FILE, ENV_USER, ENV_BACKUP but uses those variables
unquoted; fix by wrapping every expansion of $USER_INSTALL_PATH, $INSTALL_PATH,
$LOG_FILE, $ENV_USER and $ENV_BACKUP in double quotes throughout the script
(e.g., change occurrences used in mv, rm -rf, cd, make -C, and any other
commands to use "$INSTALL_PATH", "$ENV_BACKUP", "$ENV_USER", "$LOG_FILE",
"$USER_INSTALL_PATH") so paths with spaces or glob characters are not split or
expanded.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: bc937f98-1432-43c0-9ba3-057dc920990d

📥 Commits

Reviewing files that changed from the base of the PR and between 101870b and c9d7b2f.

📒 Files selected for processing (2)
  • deploy/auto-install.sh
  • docs/user/quickstart.rst
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: CI Build
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2026-02-17T17:08:12.144Z
Learnt from: atif09
Repo: openwisp/docker-openwisp PR: 555
File: .env:7-9
Timestamp: 2026-02-17T17:08:12.144Z
Learning: In docker-openwisp, OPENWISP_VERSION=edge is intentionally set as the default in .env to maintain consistency with the existing TAG=edge default in the Makefile. Production users are expected to override OPENWISP_VERSION in their .env file to pin to a specific stable release tag.

Applied to files:

  • deploy/auto-install.sh
🪛 Shellcheck (0.11.0)
deploy/auto-install.sh

[info] 72-72: Expressions don't expand in single quotes, use double quotes for that.

(SC2016)


[info] 72-72: Double quote to prevent globbing and word splitting.

(SC2086)


[info] 73-73: Double quote to prevent globbing and word splitting.

(SC2086)


[info] 251-251: Double quote to prevent globbing and word splitting.

(SC2086)


[info] 251-251: Double quote to prevent globbing and word splitting.

(SC2086)


[info] 255-255: Double quote to prevent globbing and word splitting.

(SC2086)


[info] 255-255: Double quote to prevent globbing and word splitting.

(SC2086)


[info] 259-259: Double quote to prevent globbing and word splitting.

(SC2086)

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 8

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@deploy/auto-install.sh`:
- Around line 299-301: The help text prints option labels with a backslash
(e.g., "-i\--install", "-u\--upgrade", "-h\--help") which can render oddly;
update the strings emitted by the echo statements to use a conventional
separator such as "/" or ", " between short and long options (for example
"-i/--install" and "-u/--upgrade") so the usage lines are clear and display
correctly in the help output.
- Line 202: The command substitution for TAG in the make invocation is unquoted;
update the make call (the line invoking make start with TAG=$(cat
"$INSTALL_PATH/VERSION") -C "$INSTALL_PATH/" &>>"$LOG_FILE") to quote the
substitution so the TAG assignment becomes TAG="$(cat "$INSTALL_PATH/VERSION")"
to preserve whitespace and glob characters when reading the VERSION file; keep
the surrounding variables (INSTALL_PATH, LOG_FILE) and redirection as-is.
- Around line 195-198: The current for loop that iterates over command
substitution of grep | cut can break on config names with whitespace; replace it
with a while read loop that reads each config line safely using IFS= and read
-r, feeding the output of grep '=' "$ENV_BACKUP" | cut -f1 -d'=' via process
substitution or a pipe, then call get_env "$config" "$ENV_BACKUP" and set_env
"$config" "$value" inside the loop; target the block using the variables/symbols
ENV_BACKUP, get_env, set_env and the existing loop to implement this change.
- Line 179: The make invocation uses unquoted command substitution for TAG which
can break if the VERSION file contains whitespace; update the make command so
the TAG assignment quotes the substitution (e.g., change TAG=$(cat
"$INSTALL_PATH/VERSION") to TAG="$(cat "$INSTALL_PATH/VERSION")") in the line
invoking make start -C "$INSTALL_PATH/" &>>"$LOG_FILE" to prevent word
splitting.
- Around line 190-192: The upgrade path block should get the same defensive
handling as setup_docker_openwisp: validate INSTALL_PATH is non-empty and
writable, use a safe cd invocation that checks its exit status (so replace the
bare cd "$INSTALL_PATH" with a guarded cd and then call check_status if cd
fails), ensure all expansions use quotes (e.g. "$INSTALL_PATH" and "$LOG_FILE"),
redirect both stdout/stderr to the log consistently, and ensure writing VERSION
uses a safe write (create the directory if missing and handle failures) while
keeping the existing check_status/error handling for openwisp_version; update
the upgrade-path code that touches INSTALL_PATH, LOG_FILE, check_status, and
openwisp_version to mirror the fixes in setup_docker_openwisp.
- Around line 126-128: The script currently runs cd "$INSTALL_PATH"
&>>"$LOG_FILE" but doesn't stop if cd fails and later writes an unquoted
$openwisp_version into VERSION; update the sequence so the cd is checked
immediately (use the cd command's exit status and call check_status on failure
before proceeding) and ensure when writing the version you quote the variable
(write "$openwisp_version" to "$INSTALL_PATH/VERSION"); keep using INSTALL_PATH,
LOG_FILE, check_status and openwisp_version identifiers to locate and change the
lines.

In `@docs/user/quickstart.rst`:
- Around line 75-78: The inline comment-style notation in the example command
"sudo bash auto-install.sh  # [--install install-path]" can cause users to copy
the "#" accidentally; update the docs to present the optional flag separately
and clearly reference the "--install install-path" flag (e.g., show the command
without the "#" and add a following explanatory line or a separate example
demonstrating use of the "--install" flag), ensuring the code block only
contains the exact command to run and the explanatory text describes the
optional flag.
- Line 94: Replace the inline comment in the code block that reads "sudo bash
auto-install.sh --upgrade  # [install-path]" with explicit, separate upgrade
examples: one showing the default upgrade invocation using the auto-install.sh
script with the --upgrade flag, and a second showing how to pass an explicit
install path using the --install-path option (e.g., auto-install.sh --upgrade
--install-path /your/install/path); update the documented line referencing the
script name auto-install.sh and flags --upgrade and --install-path so readers
see concrete example usages instead of an inline comment.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: f7f1f9fd-dfd5-49be-bdef-970221481ec3

📥 Commits

Reviewing files that changed from the base of the PR and between c9d7b2f and a546fe3.

📒 Files selected for processing (3)
  • deploy/auto-install.sh
  • docs/user/quickstart.rst
  • images/openwisp_dashboard/openvpn.json
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: CI Build
🧰 Additional context used
🧠 Learnings (3)
📚 Learning: 2026-02-17T17:08:12.144Z
Learnt from: atif09
Repo: openwisp/docker-openwisp PR: 555
File: .env:7-9
Timestamp: 2026-02-17T17:08:12.144Z
Learning: In docker-openwisp, OPENWISP_VERSION=edge is intentionally set as the default in .env to maintain consistency with the existing TAG=edge default in the Makefile. Production users are expected to override OPENWISP_VERSION in their .env file to pin to a specific stable release tag.

Applied to files:

  • deploy/auto-install.sh
📚 Learning: 2026-02-17T16:59:43.808Z
Learnt from: atif09
Repo: openwisp/docker-openwisp PR: 555
File: Makefile:4-5
Timestamp: 2026-02-17T16:59:43.808Z
Learning: In the docker-openwisp Makefile, `include .env` is intentionally mandatory (not `-include .env`) because the .env file contains critical configurations that must be present for safe operation. Silent failures with empty values would be more dangerous than failing explicitly when the file is missing.

Applied to files:

  • deploy/auto-install.sh
📚 Learning: 2026-03-02T19:44:00.554Z
Learnt from: nemesifier
Repo: openwisp/docker-openwisp PR: 0
File: :0-0
Timestamp: 2026-03-02T19:44:00.554Z
Learning: In the OpenVPN configuration (openvpn.json), "none" is included in the data_ciphers field (e.g., "AES-128-GCM:none") for backward compatibility with older configurations or devices.

Applied to files:

  • images/openwisp_dashboard/openvpn.json
🪛 Shellcheck (0.11.0)
deploy/auto-install.sh

[info] 15-15: Double quote to prevent globbing and word splitting.

(SC2086)


[info] 15-15: Double quote to prevent globbing and word splitting.

(SC2086)


[info] 16-16: Double quote to prevent globbing and word splitting.

(SC2086)


[info] 16-16: Double quote to prevent globbing and word splitting.

(SC2086)


[info] 23-23: Double quote to prevent globbing and word splitting.

(SC2086)


[warning] 24-24: Quote this to prevent word splitting.

(SC2046)


[style] 24-24: Useless echo? Instead of 'cmd $(echo foo)', just use 'cmd foo'.

(SC2116)


[warning] 24-24: The surrounding quotes actually unquote this. Remove or escape them.

(SC2027)


[info] 24-24: Double quote to prevent globbing and word splitting.

(SC2086)


[warning] 126-126: Use 'cd ... || exit' or 'cd ... || return' in case cd fails.

(SC2164)


[info] 128-128: Double quote to prevent globbing and word splitting.

(SC2086)


[warning] 179-179: Quote this to prevent word splitting.

(SC2046)


[warning] 190-190: Use 'cd ... || exit' or 'cd ... || return' in case cd fails.

(SC2164)


[info] 192-192: Double quote to prevent globbing and word splitting.

(SC2086)


[info] 195-195: To read lines rather than words, pipe/redirect to a 'while read' loop.

(SC2013)


[warning] 202-202: Quote this to prevent word splitting.

(SC2046)


[info] 251-251: Double quote to prevent globbing and word splitting.

(SC2086)


[info] 251-251: Double quote to prevent globbing and word splitting.

(SC2086)


[info] 255-255: Double quote to prevent globbing and word splitting.

(SC2086)


[info] 255-255: Double quote to prevent globbing and word splitting.

(SC2086)

🔇 Additional comments (5)
images/openwisp_dashboard/openvpn.json (1)

14-23: LGTM!

Formatting-only changes to the data_ciphers array indentation. No functional impact.

deploy/auto-install.sh (4)

4-4: LGTM!

Default USER_INSTALL_PATH is properly initialized before argument parsing, allowing it to be overridden when -i/-u flags provide a custom path.


72-73: LGTM!

Docker bootstrap paths are now properly quoted, resolving the variable expansion issue from the previous review.


82-84: LGTM!

Path variables are properly quoted, supporting paths with spaces or special characters.


313-328: LGTM!

The argument parsing logic correctly:

  1. Only consumes the path argument when it exists and isn't another flag ("$2" != -*)
  2. Only shifts when a path is actually consumed
  3. Derives dependent exports (INSTALL_PATH, LOG_FILE, etc.) after parsing completes

This resolves the issues raised in previous reviews.

nemesifier and others added 2 commits March 10, 2026 20:54
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
@nemesifier
Copy link
Member

@coderabbitai review but focus on real issues only

@coderabbitai
Copy link

coderabbitai bot commented Mar 11, 2026

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Get the full content of the changed files
cat deploy/auto-install.sh

Length of output: 10173


@nemesifier: Here are the real issues I found in deploy/auto-install.sh:


1. No existence check on ENV_BACKUP during upgrade — silent data loss

In upgrade_docker_openwisp, the restore loop runs unconditionally:

for config in $(grep '=' "$ENV_BACKUP" | cut -f1 -d'='); do
    value=$(get_env "$config" "$ENV_BACKUP")
    set_env "$config" "$value"
done

ENV_BACKUP is only created by download_docker_openwisp if $INSTALL_PATH/.env already exists:

if [[ -f "$INSTALL_PATH/.env" ]]; then
    mv "$INSTALL_PATH/.env" "$ENV_BACKUP" ...
fi

With the new custom-path feature, a user who passes a wrong or fresh path to --upgrade will have no $INSTALL_PATH/.env, so ENV_BACKUP is never created. grep on the non-existent file then silently fails, the restore loop runs zero iterations, and the upgrade finishes with a blank .env — no error, no warning.

A guard should be added:

upgrade_docker_openwisp() {
    ...
    if [[ ! -f "$ENV_BACKUP" ]]; then
        error_msg "No backup config found at $ENV_BACKUP. Is $USER_INSTALL_PATH the correct install path?"
    fi
    ...
}

2. The *) action='help' catch-all silently hijacks the action

The argument-parsing loop has two separate case blocks on $1. The first one contains:

*) action='help' ;;

Any extra/unrecognized token that reaches this block (e.g. a stray argument after the path) silently resets action to 'help', discarding the previously parsed install/upgrade intent with no error message. For example:

sudo bash auto-install.sh --install /opt/custom typo
# action ends up as 'help', not 'install'

The catch-all should emit an error instead:

*)
    echo -e "${RED}Unknown argument: $1${NON}"
    init_help
    exit 1
    ;;

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
deploy/auto-install.sh (1)

79-95: ⚠️ Potential issue | 🟠 Major

Fail fast when git clone fails.

download_docker_openwisp() logs the git clone, but never checks its exit status. Both callers then validate only cd, which can still succeed on a partially created target directory after a failed clone, so the script continues with a broken checkout and reports the wrong step as successful.

🛠️ Proposed fix
 	git clone "$GIT_PATH" "$INSTALL_PATH" --depth 1 --branch "$GIT_BRANCH" &>>"$LOG_FILE"
+	check_status $? "docker-openwisp download failed."
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@deploy/auto-install.sh` around lines 79 - 95, download_docker_openwisp
currently runs git clone but doesn't check its exit status, allowing subsequent
steps to proceed on a failed or partial clone; update download_docker_openwisp
to capture the git clone exit code (or check its success) and immediately log an
error via start_step/processLogger (or existing logging functions) and exit with
non-zero status if clone fails, so callers relying on cd won't continue on a
broken checkout—refer to the function name download_docker_openwisp and ensure
the git clone invocation is followed by an if/conditional that handles failure
and terminates the script.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@deploy/auto-install.sh`:
- Around line 18-25: The set_env function currently uses eval to construct an
awk command which risks shell injection; change it to call awk directly without
eval and pass the key, value and target line number via awk -v (e.g., use awk -i
inplace -v k="$1" -v v="$2" -v ln="$line_number" 'NR==ln {$0 = k"="v}1'
"$INSTALL_PATH/.env"), ensure you still handle the append case when the key is
missing and keep using INSTALL_PATH, set_env, line_number and the .env file
variables.

In `@docs/user/quickstart.rst`:
- Around line 101-102: The doc example uses "--upgrade --install
/path/to/install" which is parsed by deploy/auto-install.sh as the install
action; update the quickstart example to use the actual upgrade flag syntax the
script expects (e.g. replace the example with the correct form such as
"--upgrade --install-path /path/to/install" or whatever flag name is implemented
in deploy/auto-install.sh), and ensure the flag name in docs matches the unique
symbol used in the script (the install/upgrade flag parsing logic in
deploy/auto-install.sh) so the command triggers the upgrade flow rather than
switching back to install mode.

---

Outside diff comments:
In `@deploy/auto-install.sh`:
- Around line 79-95: download_docker_openwisp currently runs git clone but
doesn't check its exit status, allowing subsequent steps to proceed on a failed
or partial clone; update download_docker_openwisp to capture the git clone exit
code (or check its success) and immediately log an error via
start_step/processLogger (or existing logging functions) and exit with non-zero
status if clone fails, so callers relying on cd won't continue on a broken
checkout—refer to the function name download_docker_openwisp and ensure the git
clone invocation is followed by an if/conditional that handles failure and
terminates the script.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 1178fcac-c7ee-4376-8579-c0ebbe27b574

📥 Commits

Reviewing files that changed from the base of the PR and between a546fe3 and bf4963c.

📒 Files selected for processing (2)
  • deploy/auto-install.sh
  • docs/user/quickstart.rst
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: CI Build
🧰 Additional context used
🧠 Learnings (3)
📚 Learning: 2026-02-17T17:08:12.144Z
Learnt from: atif09
Repo: openwisp/docker-openwisp PR: 555
File: .env:7-9
Timestamp: 2026-02-17T17:08:12.144Z
Learning: In docker-openwisp, OPENWISP_VERSION=edge is intentionally set as the default in .env to maintain consistency with the existing TAG=edge default in the Makefile. Production users are expected to override OPENWISP_VERSION in their .env file to pin to a specific stable release tag.

Applied to files:

  • deploy/auto-install.sh
📚 Learning: 2026-02-17T16:59:43.808Z
Learnt from: atif09
Repo: openwisp/docker-openwisp PR: 555
File: Makefile:4-5
Timestamp: 2026-02-17T16:59:43.808Z
Learning: In the docker-openwisp Makefile, `include .env` is intentionally mandatory (not `-include .env`) because the .env file contains critical configurations that must be present for safe operation. Silent failures with empty values would be more dangerous than failing explicitly when the file is missing.

Applied to files:

  • deploy/auto-install.sh
📚 Learning: 2026-01-06T11:28:41.789Z
Learnt from: pandafy
Repo: openwisp/docker-openwisp PR: 549
File: docker-compose.yml:171-171
Timestamp: 2026-01-06T11:28:41.789Z
Learning: In docker-openwisp, the OpenVPN container (images/common/init_command.sh) exits silently with exit code 0 when VPN_DOMAIN environment variable is not set. Combined with restart policy "on-failure" in docker-compose.yml, this prevents the container from restarting when VPN is disabled.

Applied to files:

  • deploy/auto-install.sh
🪛 Shellcheck (0.11.0)
deploy/auto-install.sh

[info] 15-15: Double quote to prevent globbing and word splitting.

(SC2086)


[info] 15-15: Double quote to prevent globbing and word splitting.

(SC2086)


[info] 16-16: Double quote to prevent globbing and word splitting.

(SC2086)


[info] 16-16: Double quote to prevent globbing and word splitting.

(SC2086)


[info] 23-23: Double quote to prevent globbing and word splitting.

(SC2086)


[warning] 24-24: Quote this to prevent word splitting.

(SC2046)


[style] 24-24: Useless echo? Instead of 'cmd $(echo foo)', just use 'cmd foo'.

(SC2116)


[warning] 24-24: The surrounding quotes actually unquote this. Remove or escape them.

(SC2027)


[info] 24-24: Double quote to prevent globbing and word splitting.

(SC2086)


[warning] 178-178: Quote this to prevent word splitting.

(SC2046)


[info] 193-193: To read lines rather than words, pipe/redirect to a 'while read' loop.

(SC2013)


[warning] 200-200: Quote this to prevent word splitting.

(SC2046)


[info] 249-249: Double quote to prevent globbing and word splitting.

(SC2086)


[info] 249-249: Double quote to prevent globbing and word splitting.

(SC2086)


[info] 253-253: Double quote to prevent globbing and word splitting.

(SC2086)


[info] 253-253: Double quote to prevent globbing and word splitting.

(SC2086)

Comment on lines 18 to 25
set_env() {
line=$(grep -n "^$1=" $INSTALL_PATH/.env)
line=$(grep -n "^$1=" "$INSTALL_PATH/.env")
if [ -z "$line" ]; then
echo "$1=$2" >>$INSTALL_PATH/.env
echo "$1=$2" >>"$INSTALL_PATH/.env"
else
line_number=$(echo $line | cut -f1 -d:)
eval $(echo "awk -i inplace 'NR=="${line_number}" {\$0=\"${1}=${2}\"}1' $INSTALL_PATH/.env")
eval $(echo "awk -i inplace 'NR=="${line_number}" {\$0=\"${1}=${2}\"}1' \"$INSTALL_PATH/.env\"")
fi
Copy link

@coderabbitai coderabbitai bot Mar 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Remove eval from set_env before writing config values.

Line 24 builds an awk command through eval with raw values coming from prompts and from backup.env. Any value containing " or shell syntax can break the update or execute shell code as root during install/upgrade. Pass the replacement via awk -v instead of interpolating it into an evaluated command.

🐛 Proposed fix
 set_env() {
 	line=$(grep -n "^$1=" "$INSTALL_PATH/.env")
 	if [ -z "$line" ]; then
 		echo "$1=$2" >>"$INSTALL_PATH/.env"
 	else
-		line_number=$(echo $line | cut -f1 -d:)
-		eval $(echo "awk -i inplace 'NR=="${line_number}" {\$0=\"${1}=${2}\"}1' \"$INSTALL_PATH/.env\"")
+		line_number=$(printf '%s' "$line" | cut -f1 -d:)
+		awk -i inplace -v line_number="$line_number" -v replacement="$1=$2" \
+			'NR == line_number { $0 = replacement } 1' "$INSTALL_PATH/.env"
 	fi
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
set_env() {
line=$(grep -n "^$1=" $INSTALL_PATH/.env)
line=$(grep -n "^$1=" "$INSTALL_PATH/.env")
if [ -z "$line" ]; then
echo "$1=$2" >>$INSTALL_PATH/.env
echo "$1=$2" >>"$INSTALL_PATH/.env"
else
line_number=$(echo $line | cut -f1 -d:)
eval $(echo "awk -i inplace 'NR=="${line_number}" {\$0=\"${1}=${2}\"}1' $INSTALL_PATH/.env")
eval $(echo "awk -i inplace 'NR=="${line_number}" {\$0=\"${1}=${2}\"}1' \"$INSTALL_PATH/.env\"")
fi
set_env() {
line=$(grep -n "^$1=" "$INSTALL_PATH/.env")
if [ -z "$line" ]; then
echo "$1=$2" >>"$INSTALL_PATH/.env"
else
line_number=$(printf '%s' "$line" | cut -f1 -d:)
awk -i inplace -v line_number="$line_number" -v replacement="$1=$2" \
'NR == line_number { $0 = replacement } 1' "$INSTALL_PATH/.env"
fi
}
🧰 Tools
🪛 Shellcheck (0.11.0)

[info] 23-23: Double quote to prevent globbing and word splitting.

(SC2086)


[warning] 24-24: Quote this to prevent word splitting.

(SC2046)


[style] 24-24: Useless echo? Instead of 'cmd $(echo foo)', just use 'cmd foo'.

(SC2116)


[warning] 24-24: The surrounding quotes actually unquote this. Remove or escape them.

(SC2027)


[info] 24-24: Double quote to prevent globbing and word splitting.

(SC2086)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@deploy/auto-install.sh` around lines 18 - 25, The set_env function currently
uses eval to construct an awk command which risks shell injection; change it to
call awk directly without eval and pass the key, value and target line number
via awk -v (e.g., use awk -i inplace -v k="$1" -v v="$2" -v ln="$line_number"
'NR==ln {$0 = k"="v}1' "$INSTALL_PATH/.env"), ensure you still handle the append
case when the key is missing and keep using INSTALL_PATH, set_env, line_number
and the .env file variables.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this could be moved to a separate issue as it's not really specific to this PR

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nemesifier, that's a fair point — the eval concern in set_env pre-dates this PR. Would you like me to open a GitHub issue to track the fix separately?

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Copy link
Member

@nemesifier nemesifier left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@coderabbitai

1. No existence check on ENV_BACKUP during upgrade — silent data loss
I think #568 should be dealing with that, do you have a way to check?

2. The *) action='help' catch-all silently hijacks the action
If not specific to this PR, I'd create a new issue.

Comment on lines 18 to 25
set_env() {
line=$(grep -n "^$1=" $INSTALL_PATH/.env)
line=$(grep -n "^$1=" "$INSTALL_PATH/.env")
if [ -z "$line" ]; then
echo "$1=$2" >>$INSTALL_PATH/.env
echo "$1=$2" >>"$INSTALL_PATH/.env"
else
line_number=$(echo $line | cut -f1 -d:)
eval $(echo "awk -i inplace 'NR=="${line_number}" {\$0=\"${1}=${2}\"}1' $INSTALL_PATH/.env")
eval $(echo "awk -i inplace 'NR=="${line_number}" {\$0=\"${1}=${2}\"}1' \"$INSTALL_PATH/.env\"")
fi
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this could be moved to a separate issue as it's not really specific to this PR

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[feature] Allow custom install/upgrade path in auto-install.sh

2 participants