From bb12cae95443004cb508b82ebcf9bbeee04fe41b Mon Sep 17 00:00:00 2001 From: Prophet731 Date: Sun, 26 Apr 2026 02:42:08 -0400 Subject: [PATCH] feat: add install.sh helper for ownership-preserving install/upgrade MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Single-file POSIX bash script with three subcommands: install First-time install. Refuses to overwrite an existing one. upgrade Refresh existing install. Refuses if nothing's installed yet. check Report installed version vs latest. No changes. Exit 0/1/2 for current/outdated/not-installed (handy for cron-driven update monitoring). Solves the long-standing "module installed but invisible in WHMCS" trap: when admins ran the documented `git clone | rsync` recipe as root, the new files landed as root:root and the WHMCS web user couldn't read them. The script reads the parent dir's owner via `stat -c '%U:%G'` and applies it via rsync `--chown`, so a `sudo bash` install ends up with correct ownership automatically. Other niceties: - --version v1.4.1 pin a specific tag (default: latest published) - --with-addon also sync modules/addons/VirtFusionDns - Backs up + restores config/ConfigOptionMapping.php across the rsync --delete (the old docs warned about this; the script just handles it). - Writes .installed-version marker so `check` can report current state. - Pipeable via curl OR wget — both forms documented in the script header for ad-hoc piped invocations. --- install.sh | 190 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 190 insertions(+) create mode 100755 install.sh diff --git a/install.sh b/install.sh new file mode 100755 index 0000000..2bfd0fb --- /dev/null +++ b/install.sh @@ -0,0 +1,190 @@ +#!/usr/bin/env bash +# +# install.sh — Manage the VirtFusion Direct WHMCS module. +# +# Subcommands: +# install First-time install. Refuses if already present (use upgrade). +# upgrade Refresh an existing install. Refuses if nothing is installed. +# check Report installed version vs latest available. No changes. +# +# Flags (install/upgrade only): +# --with-addon, -a Also sync the PowerDNS rDNS addon. +# --version, -v vX.Y.Z Pin a specific release tag (default: latest). +# +# Exit codes for `check`: +# 0 installed and up-to-date +# 1 installed but outdated (or installed-version unknown) +# 2 not installed +# +# Pipeable: +# curl -fsSL https://raw.githubusercontent.com/EZSCALE/virtfusion-whmcs-module/main/install.sh \ +# | sudo bash -s -- install /path/to/whmcs +# +# wget -qO- https://raw.githubusercontent.com/EZSCALE/virtfusion-whmcs-module/main/install.sh \ +# | sudo bash -s -- upgrade --with-addon /path/to/whmcs +# +# curl -fsSL https://raw.githubusercontent.com/EZSCALE/virtfusion-whmcs-module/main/install.sh \ +# | bash -s -- check /path/to/whmcs +# +# Why a script? rsync into a directory owned by the WHMCS web user (e.g. +# www-data, apache) lands files as root:root by default, which the web server +# can't read — the classic "module installed but invisible in WHMCS" symptom. +# This script reads the parent directory's owner and applies it via --chown, so +# a `sudo bash` install ends up with correct ownership. It also preserves any +# custom config/ConfigOptionMapping.php across --delete. + +set -euo pipefail + +REPO="EZSCALE/virtfusion-whmcs-module" +MARKER=".installed-version" + +err() { printf '\033[1;31merror:\033[0m %s\n' "$*" >&2; } +warn() { printf '\033[1;33mwarn:\033[0m %s\n' "$*" >&2; } +info() { printf '\033[1;32m==>\033[0m %s\n' "$*"; } + +usage() { + cat </dev/null || true) + [ -n "$OWNER" ] || { err "Could not detect parent directory owner via stat"; exit 1; } + info "Owner (from $WHMCS/modules/servers): $OWNER" + + local TMP + TMP=$(mktemp -d) + trap 'rm -rf "$TMP"' EXIT + + info "Downloading $VERSION..." + curl -fsSL "https://github.com/$REPO/archive/refs/tags/$VERSION.tar.gz" -o "$TMP/src.tar.gz" + mkdir -p "$TMP/src" + tar -xzf "$TMP/src.tar.gz" -C "$TMP/src" --strip-components=1 + + local SRC="$TMP/src/modules/servers/VirtFusionDirect" + [ -d "$SRC" ] || { err "Tarball did not contain modules/servers/VirtFusionDirect"; exit 1; } + + # Preserve user's custom configurable-option mapping across --delete. + local MAP_FILE="$target/config/ConfigOptionMapping.php" + local MAP_BACKUP="" + if [ -f "$MAP_FILE" ]; then + MAP_BACKUP="$TMP/ConfigOptionMapping.php.bak" + cp -p "$MAP_FILE" "$MAP_BACKUP" + info "Backed up custom ConfigOptionMapping.php" + fi + + info "Syncing server module → $target/" + rsync -ahP --delete --chown="$OWNER" "$SRC/" "$target/" + + if [ -n "$MAP_BACKUP" ]; then + cp -p "$MAP_BACKUP" "$MAP_FILE" + chown "$OWNER" "$MAP_FILE" + info "Restored custom ConfigOptionMapping.php" + fi + + printf '%s\n' "$VERSION" > "$target/$MARKER" + chown "$OWNER" "$target/$MARKER" + + if [ "$WITH_ADDON" = 1 ]; then + local addon_src="$TMP/src/modules/addons/VirtFusionDns" + local addon_target="$WHMCS/modules/addons/VirtFusionDns" + [ -d "$addon_src" ] || { err "Tarball did not contain modules/addons/VirtFusionDns"; exit 1; } + info "Syncing PowerDNS addon → $addon_target/" + rsync -ahP --delete --chown="$OWNER" "$addon_src/" "$addon_target/" + printf '%s\n' "$VERSION" > "$addon_target/$MARKER" + chown "$OWNER" "$addon_target/$MARKER" + fi + + info "$mode complete: $VERSION (owner $OWNER)" +} + +case "${1:-}" in + install) shift; cmd_sync install "$@" ;; + upgrade) shift; cmd_sync upgrade "$@" ;; + check) shift; [ $# -eq 1 ] || usage; cmd_check "$1" ;; + -h|--help|"") usage ;; + *) err "Unknown command: $1"; usage ;; +esac