219 lines
6.5 KiB
Bash
Executable File
219 lines
6.5 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
set -Eeuo pipefail
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
INSTALL_DIR="$(cd "${SCRIPT_DIR}/.." && pwd)"
|
|
REPO_ROOT="$(cd "${INSTALL_DIR}/.." && pwd)"
|
|
|
|
# shellcheck source=install/lib/common.sh
|
|
source "${INSTALL_DIR}/lib/common.sh"
|
|
# shellcheck source=install/lib/logging.sh
|
|
source "${INSTALL_DIR}/lib/logging.sh"
|
|
# shellcheck source=install/lib/files.sh
|
|
source "${INSTALL_DIR}/lib/files.sh"
|
|
|
|
atlas_set_script_name "50-plotdirector-dev.sh"
|
|
atlas_install_error_trap
|
|
|
|
APP_REPO="/srv/repos/PlotDirector"
|
|
APP_BRANCH="onboarding"
|
|
APP_PROJECT="${APP_REPO}/PlotLine/PlotLine.csproj"
|
|
PUBLISH_DIR="/srv/apps/plotdirector-dev/current"
|
|
UPLOADS_DIR="/srv/apps/plotdirector-dev/uploads"
|
|
ENV_FILE="/etc/plotdirector/plotdirector.env"
|
|
SERVICE_USER="plotdirector"
|
|
SERVICE_NAME="plotdirector-dev"
|
|
SYSTEMD_SOURCE="${REPO_ROOT}/config/systemd/plotdirector-dev.service"
|
|
SYSTEMD_DEST="/etc/systemd/system/plotdirector-dev.service"
|
|
NGINX_SOURCE="${REPO_ROOT}/config/nginx/plotdirector-dev.conf"
|
|
NGINX_DEST="/etc/nginx/sites-available/plotdirector-dev.conf"
|
|
NGINX_LINK="/etc/nginx/sites-enabled/plotdirector-dev.conf"
|
|
NGINX_BACKUP_DIR="/etc/nginx/atlas-backups"
|
|
ALLOW_DIRTY=0
|
|
|
|
usage() {
|
|
cat <<'USAGE'
|
|
Usage: install/phases/50-plotdirector-dev.sh [options]
|
|
|
|
Publish and run the PlotDirector onboarding branch as the Atlas development
|
|
instance behind nginx. This script does not modify PlotDirector source,
|
|
create Git commits, or store secrets.
|
|
|
|
Prerequisites:
|
|
- /srv/repos/PlotDirector exists on branch onboarding.
|
|
- /etc/plotdirector/plotdirector.env exists and contains runtime settings.
|
|
- The PlotDirector development database has already been initialised.
|
|
|
|
Options:
|
|
--help Show this help text.
|
|
--version Show script/framework version.
|
|
--dry-run Show intended actions without making changes.
|
|
--verbose Print additional diagnostic output.
|
|
--allow-dirty Permit deployment from a dirty PlotDirector working tree.
|
|
|
|
USAGE
|
|
}
|
|
|
|
while [[ "$#" -gt 0 ]]; do
|
|
case "$1" in
|
|
--help)
|
|
usage
|
|
exit "${ATLAS_EXIT_OK}"
|
|
;;
|
|
--version)
|
|
atlas_print_version
|
|
exit "${ATLAS_EXIT_OK}"
|
|
;;
|
|
--dry-run)
|
|
atlas_enable_dry_run
|
|
;;
|
|
--verbose)
|
|
atlas_enable_verbose
|
|
;;
|
|
--allow-dirty)
|
|
ALLOW_DIRTY=1
|
|
;;
|
|
*)
|
|
atlas_usage_error "Unknown option: $1"
|
|
exit "${ATLAS_EXIT_USAGE}"
|
|
;;
|
|
esac
|
|
shift
|
|
done
|
|
|
|
require_prerequisites() {
|
|
atlas_require_command git
|
|
atlas_require_command dotnet
|
|
atlas_require_command curl
|
|
atlas_require_sudo_noninteractive || {
|
|
atlas_log_error "Passwordless non-interactive sudo is required"
|
|
exit "${ATLAS_EXIT_PREREQ}"
|
|
}
|
|
|
|
if [[ ! -d "${APP_REPO}/.git" ]]; then
|
|
atlas_log_error "PlotDirector repository not found at ${APP_REPO}"
|
|
exit "${ATLAS_EXIT_PREREQ}"
|
|
fi
|
|
|
|
local current_branch
|
|
current_branch="$(git -C "$APP_REPO" branch --show-current)"
|
|
if [[ "$current_branch" != "$APP_BRANCH" ]]; then
|
|
atlas_log_error "Expected ${APP_REPO} to be on ${APP_BRANCH}; found ${current_branch}"
|
|
exit "${ATLAS_EXIT_UNSAFE}"
|
|
fi
|
|
|
|
if [[ "$ALLOW_DIRTY" != "1" ]] && [[ -n "$(git -C "$APP_REPO" status --porcelain)" ]]; then
|
|
atlas_log_error "PlotDirector working tree is dirty. Use --allow-dirty only for deliberate local deployments."
|
|
exit "${ATLAS_EXIT_UNSAFE}"
|
|
fi
|
|
|
|
if ! sudo -n test -f "$ENV_FILE"; then
|
|
atlas_log_error "Runtime environment file is missing: ${ENV_FILE}"
|
|
exit "${ATLAS_EXIT_PREREQ}"
|
|
fi
|
|
}
|
|
|
|
ensure_runtime_user_and_dirs() {
|
|
if atlas_is_dry_run; then
|
|
atlas_log_info "Dry-run mode: would ensure ${SERVICE_USER} user and deployment directories"
|
|
return 0
|
|
fi
|
|
|
|
if ! id "$SERVICE_USER" >/dev/null 2>&1; then
|
|
sudo -n useradd --system --home-dir /srv/apps/plotdirector-dev --shell /usr/sbin/nologin --create-home "$SERVICE_USER"
|
|
fi
|
|
|
|
sudo -n install -d -m 0750 -o "$SERVICE_USER" -g "$SERVICE_USER" /srv/apps/plotdirector-dev "$PUBLISH_DIR" "$UPLOADS_DIR"
|
|
local srv_mode
|
|
srv_mode="$(stat -c '%a' /srv)"
|
|
if (( (8#$srv_mode & 0001) == 0 )); then
|
|
sudo -n chmod o+x /srv
|
|
fi
|
|
sudo -n chown root:"$SERVICE_USER" /etc/plotdirector
|
|
sudo -n chmod 0750 /etc/plotdirector
|
|
sudo -n chown root:"$SERVICE_USER" "$ENV_FILE"
|
|
sudo -n chmod 0640 "$ENV_FILE"
|
|
}
|
|
|
|
publish_application() {
|
|
if atlas_is_dry_run; then
|
|
atlas_log_info "Dry-run mode: would restore and publish ${APP_PROJECT} to ${PUBLISH_DIR}"
|
|
return 0
|
|
fi
|
|
|
|
local publish_tmp
|
|
publish_tmp="$(mktemp -d)"
|
|
dotnet restore "$APP_PROJECT"
|
|
dotnet publish "$APP_PROJECT" --configuration Release --output "$publish_tmp"
|
|
sudo -n rsync -a --delete "${publish_tmp}/" "${PUBLISH_DIR}/"
|
|
sudo -n chown -R "${SERVICE_USER}:${SERVICE_USER}" "$PUBLISH_DIR" "$UPLOADS_DIR"
|
|
sudo -n find "$PUBLISH_DIR" -type d -exec chmod 0750 {} +
|
|
sudo -n find "$PUBLISH_DIR" -type f -exec chmod 0640 {} +
|
|
rm -rf "$publish_tmp"
|
|
}
|
|
|
|
deploy_systemd_unit() {
|
|
if atlas_is_dry_run; then
|
|
atlas_log_info "Dry-run mode: would deploy ${SYSTEMD_DEST}"
|
|
atlas_log_info "Dry-run mode: would enable ${SERVICE_NAME}"
|
|
return 0
|
|
fi
|
|
|
|
if [[ -f "$SYSTEMD_DEST" ]] && cmp -s "$SYSTEMD_SOURCE" "$SYSTEMD_DEST"; then
|
|
atlas_log_ok "No change required for ${SYSTEMD_DEST}"
|
|
else
|
|
sudo -n install -m 0644 -o root -g root "$SYSTEMD_SOURCE" "$SYSTEMD_DEST"
|
|
atlas_log_ok "Updated ${SYSTEMD_DEST}"
|
|
fi
|
|
sudo -n systemctl daemon-reload
|
|
sudo -n systemctl enable "$SERVICE_NAME"
|
|
}
|
|
|
|
deploy_nginx_site() {
|
|
if atlas_is_dry_run; then
|
|
atlas_log_info "Dry-run mode: would deploy nginx site ${NGINX_DEST}"
|
|
return 0
|
|
fi
|
|
|
|
sudo -n install -d -m 0755 /etc/nginx/sites-available /etc/nginx/sites-enabled
|
|
sudo -n install -d -m 0750 "$NGINX_BACKUP_DIR"
|
|
sudo -n nginx -t
|
|
sudo -n install -m 0644 "$NGINX_SOURCE" "$NGINX_DEST"
|
|
sudo -n ln -sfn "$NGINX_DEST" "$NGINX_LINK"
|
|
sudo -n nginx -t
|
|
}
|
|
|
|
restart_and_verify() {
|
|
if atlas_is_dry_run; then
|
|
atlas_log_info "Dry-run mode: would restart ${SERVICE_NAME}, reload nginx, and verify HTTP responses"
|
|
return 0
|
|
fi
|
|
|
|
sudo -n systemctl restart "$SERVICE_NAME"
|
|
|
|
local attempt
|
|
for attempt in {1..30}; do
|
|
if curl -fsS http://127.0.0.1:5050/ >/dev/null 2>&1; then
|
|
break
|
|
fi
|
|
sleep 2
|
|
done
|
|
|
|
curl -fsS http://127.0.0.1:5050/ >/dev/null
|
|
sudo -n nginx -t
|
|
sudo -n systemctl reload nginx
|
|
curl -fsS -H "Host: dev.plotdirector.com" http://127.0.0.1/health >/dev/null
|
|
atlas_log_ok "PlotDirector development deployment verified"
|
|
}
|
|
|
|
main() {
|
|
require_prerequisites
|
|
ensure_runtime_user_and_dirs
|
|
publish_application
|
|
deploy_systemd_unit
|
|
deploy_nginx_site
|
|
restart_and_verify
|
|
}
|
|
|
|
main
|