maintainerr: add LXC helper script and installer - #1541
Conversation
📝 WalkthroughWalkthroughAdds three new artifacts to provision, build, update, and run Maintainerr: a container runtime script ( Changes
Sequence Diagram(s)sequenceDiagram
participant Operator
participant Installer as "install/maintainerr-install.sh"
participant GitHub
participant Builder as "Node / Yarn / Turbo"
participant Systemd as "systemd"
participant App as "/opt/maintainerr (server)"
Operator->>Installer: run installer
Installer->>GitHub: fetch release tarball
GitHub-->>Installer: tarball
Installer->>Installer: extract to /opt/maintainerr, setup Node & Corepack
Installer->>Builder: yarn install / turbo build / ui build
Builder-->>Installer: build artifacts
Installer->>App: copy UI dist -> /opt/maintainerr/apps/server/dist/ui
Installer->>Systemd: write unit & config, enable & start service
Systemd->>App: launch via /opt/maintainerr/start.sh
App-->>Operator: serve UI on configured port
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 4
🧹 Nitpick comments (2)
install/maintainerr-install.sh (1)
111-113: Add trailing newline at end of file.The file should end with a newline character for POSIX compliance.
Proposed fix
motd_ssh customize cleanup_lxc +🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@install/maintainerr-install.sh` around lines 111 - 113, Add a POSIX trailing newline by ensuring the script ends with a newline character after the final statement; open the file containing the final calls motd_ssh, customize, cleanup_lxc and add a single newline (blank line) at EOF so the last line is newline-terminated.ct/maintainerr.sh (1)
22-52: Consider extracting shared build logic.The
build_maintainerrfunction duplicates nearly all build steps frominstall/maintainerr-install.sh(lines 24-53). If this duplication is not intentional for the project structure, consider extracting the shared logic into a sourced helper to prevent drift between the two files.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@ct/maintainerr.sh` around lines 22 - 52, The build_maintainerr function duplicates the build sequence used elsewhere; extract the common steps (node setup, corepack/yarn handling, env write, NODE_OPTIONS export, yarn install/build/focus, copying UI dist, symlink) into a shared helper function (e.g., prepare_and_build_maintainerr or build_shared_runtime) placed in a sourced helper script and then replace the duplicated block inside build_maintainerr with a call to that helper (ensure you preserve unique steps like the VITE_BASE_PATH heredoc and the final ln -sfnT). Update both this file and the other script to source the helper and invoke the shared function to avoid drift.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@ct/maintainerr.sh`:
- Around line 59-62: The script currently calls exit with no code inside the
installation check (the block using APP and msg_error) which returns status 0;
change the exit to a non-zero code (e.g., exit 1) so callers detect failure.
Update the conditional that checks for /opt/maintainerr (the if [[ ! -d
/opt/maintainerr ]]; then ... fi block) to call msg_error "No ${APP}
Installation Found!" and then exit with a non-zero status.
- Line 40: The script currently runs the command 'cd /opt/maintainerr' without
checking its result; add error handling so the script does not continue if the
directory change fails (e.g., the directory is missing or inaccessible). Replace
the bare cd with a guarded check that tests the exit status of 'cd
/opt/maintainerr' and on failure prints a clear error message and exits non‑zero
(for example, use a conditional or '||' to log and exit), ensuring subsequent
commands only run when the cd succeeds.
In `@install/maintainerr-install.sh`:
- Around line 56-74: The start.sh currently performs an in-place sed replacement
of the placeholder '/__PATH_PREFIX__' with BASE_PATH_REPLACE every startup which
permanently bakes the first value; change start.sh to detect and handle
BASE_PATH changes by tracking the last-applied value (e.g., a marker file like
an "applied base path" record) or by detecting whether the placeholder still
exists before rewriting (use UI_DIST_DIR and BASE_PATH_REPLACE as referenced),
and if the tracked value differs from the current BASE_PATH_REPLACE either
rebuild the UI dist or emit a clear warning and refuse to start; ensure the
logic around the sed replacement only runs when the placeholder is present or
when the recorded applied base path differs from BASE_PATH_REPLACE so you don't
silently leave stale paths in built files.
- Line 43: The script currently runs the command "cd /opt/maintainerr" without
checking for failure; update maintainerr-install.sh to check the exit status of
that cd and abort if it fails (emit an explanatory error message and exit with a
non-zero status) so subsequent commands don't run in the wrong directory; apply
this check immediately after the "cd /opt/maintainerr" invocation (or enable
strict error handling at the top of the script) and ensure any error message
clearly mentions the target directory.
---
Nitpick comments:
In `@ct/maintainerr.sh`:
- Around line 22-52: The build_maintainerr function duplicates the build
sequence used elsewhere; extract the common steps (node setup, corepack/yarn
handling, env write, NODE_OPTIONS export, yarn install/build/focus, copying UI
dist, symlink) into a shared helper function (e.g.,
prepare_and_build_maintainerr or build_shared_runtime) placed in a sourced
helper script and then replace the duplicated block inside build_maintainerr
with a call to that helper (ensure you preserve unique steps like the
VITE_BASE_PATH heredoc and the final ln -sfnT). Update both this file and the
other script to source the helper and invoke the shared function to avoid drift.
In `@install/maintainerr-install.sh`:
- Around line 111-113: Add a POSIX trailing newline by ensuring the script ends
with a newline character after the final statement; open the file containing the
final calls motd_ssh, customize, cleanup_lxc and add a single newline (blank
line) at EOF so the last line is newline-terminated.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: d046454f-0b46-4552-a68d-ec251d313d7a
📒 Files selected for processing (3)
ct/maintainerr.shfrontend/public/json/maintainerr.jsoninstall/maintainerr-install.sh
There was a problem hiding this comment.
♻️ Duplicate comments (1)
install/maintainerr-install.sh (1)
83-86:⚠️ Potential issue | 🟠 MajorLegacy compatibility branch can still mask stale BASE_PATH assets.
When no placeholder and no marker exist, the script blindly writes a new marker and continues. For pre-marker installs with previously rewritten UI, this can silently keep an old baked base path.
Suggested patch
else - # Compatibility path for installs created before marker tracking existed. - printf '%s' "$BASE_PATH_REPLACE" >"$BASE_PATH_MARKER" + # Legacy install with unknown applied BASE_PATH; fail safe. + echo "Cannot verify existing UI BASE_PATH for legacy install. Rebuild Maintainerr to initialize BASE_PATH tracking." >&2 + exit 1 fi🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@install/maintainerr-install.sh` around lines 83 - 86, The legacy branch that writes BASE_PATH_MARKER when no placeholder/marker exists can leave previously rewritten UI assets with a stale baked base path; update the else branch that currently does printf '%s' "$BASE_PATH_REPLACE" >"$BASE_PATH_MARKER" to first check UI asset files for occurrences of the old base path (e.g. grep/search for the original hardcoded base path or absence of the dynamic placeholder) and if any are found either rewrite those assets to the new BASE_PATH_REPLACE or abort with a clear warning and instructions, otherwise write the marker; reference the existing variables BASE_PATH_REPLACE and BASE_PATH_MARKER and the logic branch that handles the pre-marker compatibility path when implementing this validation/repair step.
🧹 Nitpick comments (1)
ct/maintainerr.sh (1)
69-75: Make rebuild failure handling explicit before service restart.
build_maintainerrcan fail, but restart steps follow immediately. Please gate restart on a successful rebuild to avoid starting with a partially updated tree.Suggested patch
- CLEAN_INSTALL=1 fetch_and_deploy_gh_release "maintainerr" "Maintainerr/Maintainerr" "tarball" "latest" "/opt/maintainerr" - build_maintainerr + CLEAN_INSTALL=1 fetch_and_deploy_gh_release "maintainerr" "Maintainerr/Maintainerr" "tarball" "latest" "/opt/maintainerr" + if ! build_maintainerr; then + msg_error "Build failed; refusing to restart service." + exit 1 + fi🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@ct/maintainerr.sh` around lines 69 - 75, The script currently runs build_maintainerr and then always proceeds to systemctl start maintainerr; change this so the service restart is gated on a successful rebuild: run build_maintainerr and check its exit status (e.g., if build_maintainerr; then ... else ... fi), only perform systemctl daemon-reload and systemctl start maintainerr on success, and on failure call msg_error (or msg_info) and exit non-zero to avoid starting with a partial update; reference the build_maintainerr invocation and the systemctl start/daemon-reload lines when making the change.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Duplicate comments:
In `@install/maintainerr-install.sh`:
- Around line 83-86: The legacy branch that writes BASE_PATH_MARKER when no
placeholder/marker exists can leave previously rewritten UI assets with a stale
baked base path; update the else branch that currently does printf '%s'
"$BASE_PATH_REPLACE" >"$BASE_PATH_MARKER" to first check UI asset files for
occurrences of the old base path (e.g. grep/search for the original hardcoded
base path or absence of the dynamic placeholder) and if any are found either
rewrite those assets to the new BASE_PATH_REPLACE or abort with a clear warning
and instructions, otherwise write the marker; reference the existing variables
BASE_PATH_REPLACE and BASE_PATH_MARKER and the logic branch that handles the
pre-marker compatibility path when implementing this validation/repair step.
---
Nitpick comments:
In `@ct/maintainerr.sh`:
- Around line 69-75: The script currently runs build_maintainerr and then always
proceeds to systemctl start maintainerr; change this so the service restart is
gated on a successful rebuild: run build_maintainerr and check its exit status
(e.g., if build_maintainerr; then ... else ... fi), only perform systemctl
daemon-reload and systemctl start maintainerr on success, and on failure call
msg_error (or msg_info) and exit non-zero to avoid starting with a partial
update; reference the build_maintainerr invocation and the systemctl
start/daemon-reload lines when making the change.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 10fd2cc5-3397-4ac0-9519-84f07797c3f0
📒 Files selected for processing (2)
ct/maintainerr.shinstall/maintainerr-install.sh
| function build_maintainerr() { | ||
| NODE_VERSION="24" setup_nodejs | ||
| msg_info "Preparing Build Runtime" | ||
| export COREPACK_ENABLE_DOWNLOAD_PROMPT=0 | ||
| $STD corepack enable | ||
| if [[ -f /opt/maintainerr/package.json ]]; then | ||
| if command -v jq >/dev/null 2>&1; then | ||
| yarn_spec=$(jq -r '.packageManager // empty' /opt/maintainerr/package.json 2>/dev/null || true) | ||
| if [[ -n "$yarn_spec" && "$yarn_spec" == yarn@* ]]; then | ||
| yarn_ver="${yarn_spec#yarn@}" | ||
| yarn_ver="${yarn_ver%%+*}" | ||
| $STD corepack prepare "yarn@${yarn_ver}" --activate || true | ||
| fi | ||
| fi | ||
| fi | ||
| msg_ok "Prepared Build Runtime" |
There was a problem hiding this comment.
This PR is far from out standards, please take a look at the docs folder on ProxmoxVE and also when using ai, use the AI.md in docs folder of ProxmoxVED folder.
|
Also you need to properly fill out the PR template, if the markdown checkboxes are filled in correctly, they will render as actual checkboxes. |
| function build_maintainerr() { | ||
| NODE_VERSION="24" setup_nodejs | ||
| msg_info "Preparing Build Runtime" | ||
| export COREPACK_ENABLE_DOWNLOAD_PROMPT=0 | ||
| $STD corepack enable | ||
| if [[ -f /opt/maintainerr/package.json ]]; then | ||
| if command -v jq >/dev/null 2>&1; then | ||
| yarn_spec=$(jq -r '.packageManager // empty' /opt/maintainerr/package.json 2>/dev/null || true) | ||
| if [[ -n "$yarn_spec" && "$yarn_spec" == yarn@* ]]; then | ||
| yarn_ver="${yarn_spec#yarn@}" | ||
| yarn_ver="${yarn_ver%%+*}" | ||
| $STD corepack prepare "yarn@${yarn_ver}" --activate || true | ||
| fi | ||
| fi | ||
| fi | ||
| msg_ok "Prepared Build Runtime" | ||
|
|
||
| msg_info "Building Maintainerr (Patience)" | ||
| cd /opt/maintainerr || { msg_error "Failed to change to /opt/maintainerr"; return 1; } | ||
| cat <<'EOF' >/opt/maintainerr/apps/ui/.env | ||
| VITE_BASE_PATH=/__PATH_PREFIX__ | ||
| EOF | ||
| export NODE_OPTIONS="--max-old-space-size=4096" | ||
| $STD yarn install --immutable --network-timeout 99999999 | ||
| $STD yarn turbo build | ||
| $STD yarn workspaces focus --all --production | ||
| mkdir -p /opt/maintainerr/apps/server/dist/ui | ||
| cp -a /opt/maintainerr/apps/ui/dist/. /opt/maintainerr/apps/server/dist/ui/ | ||
| ln -sfnT /opt/maintainerr /opt/app | ||
| msg_ok "Built Maintainerr" | ||
| } |
There was a problem hiding this comment.
This doesn't need to be a function, move it down to the update_script block
| systemctl stop maintainerr | ||
| msg_ok "Stopped Service" | ||
|
|
||
| CLEAN_INSTALL=1 fetch_and_deploy_gh_release "maintainerr" "Maintainerr/Maintainerr" "tarball" "latest" "/opt/maintainerr" |
There was a problem hiding this comment.
| CLEAN_INSTALL=1 fetch_and_deploy_gh_release "maintainerr" "Maintainerr/Maintainerr" "tarball" "latest" "/opt/maintainerr" | |
| CLEAN_INSTALL=1 fetch_and_deploy_gh_release "maintainerr" "Maintainerr/Maintainerr" "tarball" |
| msg_ok "Stopped Service" | ||
|
|
||
| CLEAN_INSTALL=1 fetch_and_deploy_gh_release "maintainerr" "Maintainerr/Maintainerr" "tarball" "latest" "/opt/maintainerr" | ||
| build_maintainerr |
There was a problem hiding this comment.
| build_maintainerr |
| [Install] | ||
| WantedBy=multi-user.target | ||
| EOF | ||
| systemctl daemon-reload |
There was a problem hiding this comment.
| systemctl daemon-reload |
| build_maintainerr | ||
|
|
||
| msg_info "Starting Service" | ||
| systemctl daemon-reload |
There was a problem hiding this comment.
| systemctl daemon-reload |
| printf '%s' "$BASE_PATH_REPLACE" >"$BASE_PATH_MARKER" | ||
| fi | ||
|
|
||
| exec npm run --prefix /opt/maintainerr/apps/server start |
| msg_ok "Created Start Script" | ||
|
|
||
| msg_info "Configuring Maintainerr" | ||
| cat <<'EOF' >/etc/maintainerr/maintainerr.conf |
There was a problem hiding this comment.
| cat <<'EOF' >/etc/maintainerr/maintainerr.conf | |
| cat <<EOF >/etc/maintainerr/maintainerr.conf |
| msg_ok "Configured Maintainerr" | ||
|
|
||
| msg_info "Creating Service" | ||
| cat <<'EOF' >/etc/systemd/system/maintainerr.service |
There was a problem hiding this comment.
| cat <<'EOF' >/etc/systemd/system/maintainerr.service | |
| cat <<EOF >/etc/systemd/system/maintainerr.service |
|
|
||
| msg_info "Building Maintainerr (Patience)" | ||
| cd /opt/maintainerr || { msg_error "Failed to change to /opt/maintainerr"; exit 1; } | ||
| cat <<'EOF' >/opt/maintainerr/apps/ui/.env |
There was a problem hiding this comment.
| cat <<'EOF' >/opt/maintainerr/apps/ui/.env | |
| cat <<EOF >/opt/maintainerr/apps/ui/.env |
| msg_ok "Prepared Build Runtime" | ||
|
|
||
| msg_info "Building Maintainerr (Patience)" | ||
| cd /opt/maintainerr || { msg_error "Failed to change to /opt/maintainerr"; exit 1; } |
There was a problem hiding this comment.
| cd /opt/maintainerr || { msg_error "Failed to change to /opt/maintainerr"; exit 1; } | |
| cd /opt/maintainerr |
There was a problem hiding this comment.
♻️ Duplicate comments (1)
install/maintainerr-install.sh (1)
42-53:⚠️ Potential issue | 🟡 MinorAdd error handling for
cdcommand.Line 43 lacks error handling for the directory change. If
/opt/maintainerrdoesn't exist (e.g., fetch failed silently), subsequent commands will execute in the wrong directory.Proposed fix
msg_info "Building Maintainerr (Patience)" -cd /opt/maintainerr +cd /opt/maintainerr || exit 1 cat <<EOF >/opt/maintainerr/apps/ui/.env🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@install/maintainerr-install.sh` around lines 42 - 53, The script runs a plain cd before build steps (the cd invocation before yarn commands) without checking success; add error handling so if cd fails it logs an error (use existing msg_* helper, e.g., call msg_error "Failed to change directory to <dir>" or similar) and exits non‑zero (or aborts the script) instead of continuing; implement this by replacing the bare cd with a guarded form (cd <dir> || { msg_error "..." ; exit 1; }) so subsequent commands like yarn install, yarn turbo build, and the cp step never run in the wrong location.
🧹 Nitpick comments (1)
ct/maintainerr.sh (1)
54-75: Use explicit exit code at function end.Line 74 uses bare
exitwhich defaults to the last command's exit status. For clarity and predictable behavior, use explicitexit 0to indicate successful completion.Proposed fix
msg_ok "Updated successfully!" fi - exit + exit 0 }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@ct/maintainerr.sh` around lines 54 - 75, Replace the bare "exit" at the end of the script with an explicit success status to ensure predictable behavior: change the final "exit" (the one after the closing brace and after the last msg_ok) to "exit 0". This targets the explicit exit for the function/termination sequence that currently uses the bare exit symbol and ensures the script returns a clear success code.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Duplicate comments:
In `@install/maintainerr-install.sh`:
- Around line 42-53: The script runs a plain cd before build steps (the cd
invocation before yarn commands) without checking success; add error handling so
if cd fails it logs an error (use existing msg_* helper, e.g., call msg_error
"Failed to change directory to <dir>" or similar) and exits non‑zero (or aborts
the script) instead of continuing; implement this by replacing the bare cd with
a guarded form (cd <dir> || { msg_error "..." ; exit 1; }) so subsequent
commands like yarn install, yarn turbo build, and the cp step never run in the
wrong location.
---
Nitpick comments:
In `@ct/maintainerr.sh`:
- Around line 54-75: Replace the bare "exit" at the end of the script with an
explicit success status to ensure predictable behavior: change the final "exit"
(the one after the closing brace and after the last msg_ok) to "exit 0". This
targets the explicit exit for the function/termination sequence that currently
uses the bare exit symbol and ensures the script returns a clear success code.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: d0b82136-8d19-4a78-8707-4f497f826697
📒 Files selected for processing (2)
ct/maintainerr.shinstall/maintainerr-install.sh
|
@tumeden This PR has been marked as stale. It will be closed if no new commits are added in 7 days. |
|
Maybe someone else can take it over. I had it working, but my understanding of the script is minimal. My intent was to just get it working for the community. Would be nice to have an LXC installer for maintainerr. |
|
if any other @community-scripts/contributor want to have a look? |
✍️ Description
Proxmox LXC installer for maintainerr
https://github.com/Maintainerr/Maintainerr
🔗 Related PR / Issue
Link: community-scripts/ProxmoxVE#97 (reply in thread)
✅ Prerequisites (X in brackets)
🛠️ Type of Change (X in brackets)
README,AppName.md,CONTRIBUTING.md, or other docs.🔍 Code & Security Review (X in brackets)
Code_Audit.md&CONTRIBUTING.mdguidelinesAppName.sh,AppName-install.sh,AppName.json)📦 Application Requirements (for new scripts)
Summary by CodeRabbit