Rename reinstall-mode prompt; make security-dashboard's "Full reinstall" a real teardown
Two-part change discussed and scoped in this session before touching
anything:
1. Rename "Reinstall in place" (r) -> "Update" (u) and "Full install" (f)
-> "Full reinstall" everywhere the prompt appears: lib/common.sh's
shared prompt_reinstall_mode(), plus the three services that carry
their own duplicated standalone-stub copy of it for standalone
execution (asterisk.sh, coturn.sh, wordpress.sh — per this repo's
documented standalone-bootstrap pattern). Internal state values
(update/fresh/cancel) are unchanged, so no other service's case
statement needed touching. docs/anveo-direct-setup-guide.md's `r`
reference updated to `u` to match. attic/asterisk-digital-ocean.sh
deliberately left alone — this repo's own policy is to not backport
fixes into attic/.
2. security-dashboard.sh's "Full reinstall" now does a real teardown
before reinstalling — stops and removes the systemd unit, sudoers
grant, Caddy site block, and secdash system user, then proceeds
through the normal fresh-install flow — instead of just overwriting
files in place while leaving the old service running underneath.
Prototype for a pattern discussed for other services later: split the
destructive question out explicitly ("also delete
dashboard-admins.conf — per-admin extension scoping?", default n) so
full reinstall doesn't silently discard state a plain "start over"
request wouldn't expect to lose. Verified the backup/restore mechanics
(mktemp, copy out before teardown, copy back after) against a mock
under `set -u` for both the preserve and wipe paths before shipping.
Update mode was already the strongest existing example of surfacing
newer optional prompts (its "Reconfigure Caddy protection?" /
"Reconfigure per-admin scoping?" sub-prompts already cover every setting
fresh-install offers) — no changes needed there for this service.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01H4k6J1qXXyYxhGEgnJaMvn
This commit is contained in:
@@ -143,7 +143,7 @@ account default in step 6 and skip even that:
|
|||||||
sudo ./setup.sh pstn-trunk
|
sudo ./setup.sh pstn-trunk
|
||||||
```
|
```
|
||||||
|
|
||||||
- Existing install → choose **update** (`r`) if you're just changing the
|
- Existing install → choose **update** (`u`) if you're just changing the
|
||||||
DID/server, or the CLI will walk fresh prompts if none exists yet.
|
DID/server, or the CLI will walk fresh prompts if none exists yet.
|
||||||
- Provider quick-pick: **1) Anveo Direct** — pre-fills `sbc.anveo.com` and
|
- Provider quick-pick: **1) Anveo Direct** — pre-fills `sbc.anveo.com` and
|
||||||
Anveo's 4 published signaling IPs (only one of which the hostname
|
Anveo's 4 published signaling IPs (only one of which the hostname
|
||||||
|
|||||||
+4
-4
@@ -718,12 +718,12 @@ prompt_reinstall_mode() {
|
|||||||
return
|
return
|
||||||
fi
|
fi
|
||||||
echo " Existing install detected. Choose:"
|
echo " Existing install detected. Choose:"
|
||||||
echo " r) Reinstall in place — refresh vendor files/config, keep existing settings"
|
echo " u) Update — refresh vendor files/config, keep existing settings"
|
||||||
echo " f) Full install — re-run every prompt from scratch"
|
echo " f) Full reinstall — re-run every prompt from scratch"
|
||||||
echo " c) Cancel — leave everything as-is [default]"
|
echo " c) Cancel — leave everything as-is [default]"
|
||||||
read -p " Choice [r/f/c, Enter=cancel]: " response
|
read -p " Choice [u/f/c, Enter=cancel]: " response
|
||||||
case "${response,,}" in
|
case "${response,,}" in
|
||||||
r) eval "$varname='update'" ;;
|
u) eval "$varname='update'" ;;
|
||||||
f) eval "$varname='fresh'" ;;
|
f) eval "$varname='fresh'" ;;
|
||||||
*) eval "$varname='cancel'" ;;
|
*) eval "$varname='cancel'" ;;
|
||||||
esac
|
esac
|
||||||
|
|||||||
@@ -82,12 +82,12 @@ if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
|
|||||||
return
|
return
|
||||||
fi
|
fi
|
||||||
echo " Existing install detected. Choose:"
|
echo " Existing install detected. Choose:"
|
||||||
echo " r) Reinstall in place — refresh vendor files/config, keep existing settings"
|
echo " u) Update — refresh vendor files/config, keep existing settings"
|
||||||
echo " f) Full install — re-run every prompt from scratch"
|
echo " f) Full reinstall — re-run every prompt from scratch"
|
||||||
echo " c) Cancel — leave everything as-is [default]"
|
echo " c) Cancel — leave everything as-is [default]"
|
||||||
read -r -p " Choice [r/f/c, Enter=cancel]: " _r
|
read -r -p " Choice [u/f/c, Enter=cancel]: " _r
|
||||||
case "${_r,,}" in
|
case "${_r,,}" in
|
||||||
r) eval "$_var='update'" ;;
|
u) eval "$_var='update'" ;;
|
||||||
f) eval "$_var='fresh'" ;;
|
f) eval "$_var='fresh'" ;;
|
||||||
*) eval "$_var='cancel'" ;;
|
*) eval "$_var='cancel'" ;;
|
||||||
esac
|
esac
|
||||||
|
|||||||
+4
-4
@@ -87,12 +87,12 @@ if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
|
|||||||
local _var="$1" _r
|
local _var="$1" _r
|
||||||
if [[ "${UNATTENDED:-false}" == "true" ]]; then eval "$_var='cancel'"; return; fi
|
if [[ "${UNATTENDED:-false}" == "true" ]]; then eval "$_var='cancel'"; return; fi
|
||||||
echo " Existing install detected. Choose:"
|
echo " Existing install detected. Choose:"
|
||||||
echo " r) Reinstall in place — refresh vendor files, keep existing settings"
|
echo " u) Update — refresh vendor files, keep existing settings"
|
||||||
echo " f) Full install — re-run every prompt from scratch"
|
echo " f) Full reinstall — re-run every prompt from scratch"
|
||||||
echo " c) Cancel — leave everything as-is [default]"
|
echo " c) Cancel — leave everything as-is [default]"
|
||||||
read -r -p " Choice [r/f/c, Enter=cancel]: " _r
|
read -r -p " Choice [u/f/c, Enter=cancel]: " _r
|
||||||
case "${_r,,}" in
|
case "${_r,,}" in
|
||||||
r) eval "$_var='update'" ;;
|
u) eval "$_var='update'" ;;
|
||||||
f) eval "$_var='fresh'" ;;
|
f) eval "$_var='fresh'" ;;
|
||||||
*) eval "$_var='cancel'" ;;
|
*) eval "$_var='cancel'" ;;
|
||||||
esac
|
esac
|
||||||
|
|||||||
@@ -184,7 +184,24 @@ install_security-dashboard() {
|
|||||||
log_info "Leaving the existing install as-is."
|
log_info "Leaving the existing install as-is."
|
||||||
return 0
|
return 0
|
||||||
;;
|
;;
|
||||||
fresh) ;;
|
fresh)
|
||||||
|
echo ""
|
||||||
|
log_warning "Full reinstall stops the dashboard and removes its systemd unit,"
|
||||||
|
log_warning "sudoers grant, Caddy block, service user, and app files, then sets"
|
||||||
|
log_warning "it up again from scratch — every prompt below runs as if this were"
|
||||||
|
log_warning "a brand new install."
|
||||||
|
local _WIPE_ADMINS=""
|
||||||
|
prompt_yn " Also delete dashboard-admins.conf (per-admin Calls/Texts/Voicemail scoping)? (y/n):" "n" _WIPE_ADMINS
|
||||||
|
|
||||||
|
local _ADMINS_BACKUP=""
|
||||||
|
if [[ ! "$_WIPE_ADMINS" =~ ^[Yy]$ ]] && [ -f "$APP_DIR/dashboard-admins.conf" ]; then
|
||||||
|
_ADMINS_BACKUP="$(mktemp)"
|
||||||
|
cp "$APP_DIR/dashboard-admins.conf" "$_ADMINS_BACKUP"
|
||||||
|
log_info "Preserving dashboard-admins.conf across the reinstall."
|
||||||
|
fi
|
||||||
|
|
||||||
|
_secdash_teardown "$APP_DIR" "$SVC_USER" "$DASHBOARD_PORT"
|
||||||
|
;;
|
||||||
esac
|
esac
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -197,6 +214,11 @@ install_security-dashboard() {
|
|||||||
_secdash_grant_asterisk_access "$SVC_USER" "$ASTERISK_LOG_DIR" "$ASTERISK_CONFIG_DIR" "$ASTERISK_EA_CONFIG_DIR" "$ASTERISK_SPOOL_DIR"
|
_secdash_grant_asterisk_access "$SVC_USER" "$ASTERISK_LOG_DIR" "$ASTERISK_CONFIG_DIR" "$ASTERISK_EA_CONFIG_DIR" "$ASTERISK_SPOOL_DIR"
|
||||||
|
|
||||||
mkdir -p "$APP_DIR"
|
mkdir -p "$APP_DIR"
|
||||||
|
if [ -n "${_ADMINS_BACKUP:-}" ]; then
|
||||||
|
cp "$_ADMINS_BACKUP" "$APP_DIR/dashboard-admins.conf"
|
||||||
|
rm -f "$_ADMINS_BACKUP"
|
||||||
|
log_success "Restored dashboard-admins.conf"
|
||||||
|
fi
|
||||||
_secdash_write_app "$APP_DIR"
|
_secdash_write_app "$APP_DIR"
|
||||||
chown -R "$SVC_USER:$SVC_USER" "$APP_DIR"
|
chown -R "$SVC_USER:$SVC_USER" "$APP_DIR"
|
||||||
_secdash_write_asn_helper "$APP_DIR"
|
_secdash_write_asn_helper "$APP_DIR"
|
||||||
@@ -974,6 +996,35 @@ _secdash_remove_caddy_block() {
|
|||||||
log_info "Removed the existing dashboard Caddy block (regenerating it fresh)."
|
log_info "Removed the existing dashboard Caddy block (regenerating it fresh)."
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Full teardown for "Full reinstall" — stops the service and removes
|
||||||
|
# everything a fresh install recreates: systemd unit, sudoers grant, Caddy
|
||||||
|
# site block, the secdash system user, and the app directory. Non-Docker
|
||||||
|
# service (systemd + /opt, not a container), so lib/common.sh's
|
||||||
|
# remove_service() (Docker-only, $DOCKER_DIR/<name>) doesn't apply here —
|
||||||
|
# this is the equivalent for this one service. Callers are responsible for
|
||||||
|
# backing up/restoring anything under $_app_dir they want to survive (see
|
||||||
|
# the dashboard-admins.conf handling around the "fresh" case in
|
||||||
|
# install_security-dashboard() — this function does not know which files,
|
||||||
|
# if any, the caller wants to keep).
|
||||||
|
_secdash_teardown() {
|
||||||
|
local _app_dir="$1" _svc_user="$2" _port="$3"
|
||||||
|
|
||||||
|
systemctl stop security-dashboard 2>/dev/null || true
|
||||||
|
systemctl disable security-dashboard 2>/dev/null || true
|
||||||
|
rm -f /etc/systemd/system/security-dashboard.service
|
||||||
|
systemctl daemon-reload
|
||||||
|
|
||||||
|
rm -f /etc/sudoers.d/security-dashboard
|
||||||
|
|
||||||
|
_secdash_remove_caddy_block "$_port"
|
||||||
|
|
||||||
|
id "$_svc_user" &>/dev/null && userdel "$_svc_user" 2>/dev/null
|
||||||
|
|
||||||
|
rm -rf "$_app_dir"
|
||||||
|
|
||||||
|
log_success "Removed security-dashboard's systemd unit, sudoers grant, Caddy block, user, and app files."
|
||||||
|
}
|
||||||
|
|
||||||
# Root-owned helper for editing CrowdSec's Asterisk-scenario YAMLs — the
|
# Root-owned helper for editing CrowdSec's Asterisk-scenario YAMLs — the
|
||||||
# secdash service user (--shell /usr/sbin/nologin, no special file grants)
|
# secdash service user (--shell /usr/sbin/nologin, no special file grants)
|
||||||
# cannot write /etc/crowdsec/scenarios/*.yaml directly (root:root, mode
|
# cannot write /etc/crowdsec/scenarios/*.yaml directly (root:root, mode
|
||||||
|
|||||||
@@ -95,12 +95,12 @@ if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
|
|||||||
local _var="$1" _r
|
local _var="$1" _r
|
||||||
if [[ "${UNATTENDED:-false}" == "true" ]]; then eval "$_var='cancel'"; return; fi
|
if [[ "${UNATTENDED:-false}" == "true" ]]; then eval "$_var='cancel'"; return; fi
|
||||||
echo " Existing install detected. Choose:"
|
echo " Existing install detected. Choose:"
|
||||||
echo " r) Reinstall in place — refresh image/compose, keep database and settings"
|
echo " u) Update — refresh image/compose, keep database and settings"
|
||||||
echo " f) Full install — re-run every prompt from scratch"
|
echo " f) Full reinstall — re-run every prompt from scratch"
|
||||||
echo " c) Cancel — leave everything as-is [default]"
|
echo " c) Cancel — leave everything as-is [default]"
|
||||||
read -r -p " Choice [r/f/c, Enter=cancel]: " _r
|
read -r -p " Choice [u/f/c, Enter=cancel]: " _r
|
||||||
case "${_r,,}" in
|
case "${_r,,}" in
|
||||||
r) eval "$_var='update'" ;;
|
u) eval "$_var='update'" ;;
|
||||||
f) eval "$_var='fresh'" ;;
|
f) eval "$_var='fresh'" ;;
|
||||||
*) eval "$_var='cancel'" ;;
|
*) eval "$_var='cancel'" ;;
|
||||||
esac
|
esac
|
||||||
|
|||||||
Reference in New Issue
Block a user