Files

283 lines
9.5 KiB
Bash
Executable File

#!/usr/bin/env bash
set -euo pipefail
script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
repo_root="$(cd "${script_dir}/.." && pwd)"
env_file="${repo_root}/.env.devprod"
mode="nossl"
compose_file=""
skip_finish="0"
skip_auth_repair="0"
switch_service_user="0"
legacy_service_user="sovereign_oidc_service"
nuqloud_service_user="nuqloud_oidc_service"
usage() {
cat <<USAGE
Usage: ./scripts/migrate-nuqloud-branding.sh [options]
One-time helper to migrate existing dev/prod-cloud env files from legacy
Sovereign/SC naming to NuQloud naming with minimal risk.
Actions:
1) Backs up the selected env file.
2) Seeds missing NUQLOUD_* env aliases from legacy SOVEREIGN_*/SC_* keys.
3) Keeps NEXTCLOUD_SERVICE_USER unchanged by default (legacy/new both supported).
4) Optionally switches NEXTCLOUD_SERVICE_USER to nuqloud_oidc_service.
5) Optionally runs finish/auth repair scripts to apply runtime changes.
Options:
--env-file <path> Env file to migrate (default: .env.devprod)
--mode ssl|nossl Compose mode for runtime actions (default: nossl)
--compose-file <path> Explicit compose file for runtime actions
--switch-service-user Set NEXTCLOUD_SERVICE_USER to nuqloud_oidc_service
--legacy-service-user <id> Legacy service username (default: sovereign_oidc_service)
--nuqloud-service-user <id> New NuQloud service username (default: nuqloud_oidc_service)
--skip-finish Skip scripts/finish-initial-setup.sh runtime sync
--skip-auth-repair Skip scripts/ensure-nextcloud-service-auth.sh --repair
-h, --help Show this help
USAGE
}
log() {
echo "[nuqloud-migrate] $*"
}
trim() {
local value="${1:-}"
value="$(echo "${value}" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')"
echo "${value}"
}
read_kv() {
local key="$1"
local line
line="$(grep -m1 -E "^${key}=" "${env_file}" || true)"
if [[ -z "${line}" ]]; then
return 1
fi
echo "${line#*=}"
}
set_kv() {
local key="$1"
local value="$2"
local esc
esc="${value//\\/\\\\}"
esc="${esc//&/\\&}"
esc="${esc//|/\\|}"
if grep -q -E "^${key}=" "${env_file}"; then
sed -i -E "s|^${key}=.*|${key}=${esc}|" "${env_file}"
else
echo "${key}=${value}" >> "${env_file}"
fi
}
seed_alias_if_missing() {
local dest_key="$1"
shift
local current
current="$(trim "$(read_kv "${dest_key}" || true)")"
if [[ -n "${current}" ]]; then
return 0
fi
local source_key source_value
for source_key in "$@"; do
source_value="$(trim "$(read_kv "${source_key}" || true)")"
if [[ -n "${source_value}" ]]; then
set_kv "${dest_key}" "${source_value}"
log "Seeded ${dest_key} from ${source_key}."
return 0
fi
done
}
while [[ $# -gt 0 ]]; do
case "$1" in
--env-file)
env_file="${2:-}"
shift 2
;;
--env-file=*)
env_file="${1#*=}"
shift
;;
--mode)
mode="${2:-}"
shift 2
;;
--mode=*)
mode="${1#*=}"
shift
;;
--compose-file)
compose_file="${2:-}"
shift 2
;;
--compose-file=*)
compose_file="${1#*=}"
shift
;;
--switch-service-user)
switch_service_user="1"
shift
;;
--legacy-service-user)
legacy_service_user="${2:-}"
shift 2
;;
--legacy-service-user=*)
legacy_service_user="${1#*=}"
shift
;;
--nuqloud-service-user)
nuqloud_service_user="${2:-}"
shift 2
;;
--nuqloud-service-user=*)
nuqloud_service_user="${1#*=}"
shift
;;
--skip-finish)
skip_finish="1"
shift
;;
--skip-auth-repair)
skip_auth_repair="1"
shift
;;
-h|--help)
usage
exit 0
;;
*)
echo "Unknown option: $1"
usage
exit 1
;;
esac
done
if [[ "${env_file}" != /* ]]; then
env_file="${repo_root}/${env_file}"
fi
if [[ ! -f "${env_file}" ]]; then
echo "Missing env file: ${env_file}"
exit 1
fi
if [[ "${mode}" != "ssl" && "${mode}" != "nossl" ]]; then
echo "Invalid mode: ${mode} (expected ssl or nossl)"
exit 1
fi
if [[ -z "${compose_file}" ]]; then
if [[ "${mode}" == "ssl" ]]; then
compose_file="${repo_root}/docker-compose.devprod.yml"
else
compose_file="${repo_root}/docker-compose.devprod.nossl.yml"
fi
elif [[ "${compose_file}" != /* ]]; then
compose_file="${repo_root}/${compose_file}"
fi
run_runtime_actions="1"
if [[ "${skip_finish}" == "1" && "${skip_auth_repair}" == "1" ]]; then
run_runtime_actions="0"
fi
if [[ "${run_runtime_actions}" == "1" && ! -f "${compose_file}" ]]; then
echo "Missing compose file: ${compose_file}"
exit 1
fi
if [[ "${legacy_service_user}" == "${nuqloud_service_user}" ]]; then
echo "legacy/new service usernames must differ."
exit 1
fi
backup_file="${env_file}.nuqloud-migrate.$(date +%Y%m%d-%H%M%S).bak"
cp "${env_file}" "${backup_file}"
log "Backed up env file to ${backup_file}"
seed_alias_if_missing "NUQLOUD_MODE" "SOVEREIGN_MODE" "SC_MODE"
seed_alias_if_missing "NUQLOUD_BILLING_ENABLED" "SOVEREIGN_BILLING_ENABLED" "SC_BILLING_ENABLED"
seed_alias_if_missing "NUQLOUD_BILLING_MANAGED_BY_CHD" "SOVEREIGN_BILLING_MANAGED_BY_CHD" "SC_BILLING_MANAGED_BY_CHD"
seed_alias_if_missing "NUQLOUD_BILLING_PROVIDER" "SOVEREIGN_BILLING_PROVIDER" "SC_BILLING_PROVIDER"
seed_alias_if_missing "NUQLOUD_BILLING_SYNC_MODE" "SOVEREIGN_BILLING_SYNC_MODE" "SC_BILLING_SYNC_MODE"
seed_alias_if_missing "NUQLOUD_CHD_BASE_URL" "SOVEREIGN_CHD_BASE_URL" "SC_CHD_BASE_URL"
seed_alias_if_missing "NUQLOUD_CHD_SYNC_PATH" "SOVEREIGN_CHD_SYNC_PATH" "SC_CHD_SYNC_PATH"
seed_alias_if_missing "NUQLOUD_CHD_REGISTER_PATH" "SOVEREIGN_CHD_REGISTER_PATH" "SC_CHD_REGISTER_PATH"
seed_alias_if_missing "NUQLOUD_CHD_CHECKOUT_PATH" "SOVEREIGN_CHD_CHECKOUT_PATH" "SC_CHD_CHECKOUT_PATH"
seed_alias_if_missing "NUQLOUD_CHD_CATALOG_PATH" "SOVEREIGN_CHD_CATALOG_PATH" "SC_CHD_CATALOG_PATH"
seed_alias_if_missing "NUQLOUD_CHD_CATALOG_CATEGORY_ID" "SOVEREIGN_CHD_CATALOG_CATEGORY_ID" "SC_CHD_CATALOG_CATEGORY_ID"
seed_alias_if_missing "NUQLOUD_CHD_REGISTRATION_TOKEN" "SOVEREIGN_CHD_REGISTRATION_TOKEN" "SC_CHD_REGISTRATION_TOKEN"
seed_alias_if_missing "NUQLOUD_CHD_INSTANCE_ID" "SOVEREIGN_CHD_INSTANCE_ID" "SC_CHD_INSTANCE_ID"
seed_alias_if_missing "NUQLOUD_CHD_INSTANCE_TOKEN" "SOVEREIGN_CHD_INSTANCE_TOKEN" "SC_CHD_INSTANCE_TOKEN"
seed_alias_if_missing "NUQLOUD_CHD_INSTANCE_SECRET" "SOVEREIGN_CHD_INSTANCE_SECRET" "SC_CHD_INSTANCE_SECRET"
seed_alias_if_missing "NUQLOUD_BILLING_CONTACT_NAME" "SOVEREIGN_BILLING_CONTACT_NAME" "SC_BILLING_CONTACT_NAME"
seed_alias_if_missing "NUQLOUD_BILLING_CONTACT_EMAIL" "SOVEREIGN_BILLING_CONTACT_EMAIL" "SC_BILLING_CONTACT_EMAIL"
seed_alias_if_missing "NUQLOUD_BILLING_COMPANY_NAME" "SOVEREIGN_BILLING_COMPANY_NAME" "SC_BILLING_COMPANY_NAME"
seed_alias_if_missing "NUQLOUD_BILLING_PHONE" "SOVEREIGN_BILLING_PHONE" "SC_BILLING_PHONE"
seed_alias_if_missing "NUQLOUD_BILLING_ADDRESS1" "SOVEREIGN_BILLING_ADDRESS1" "SC_BILLING_ADDRESS1"
seed_alias_if_missing "NUQLOUD_BILLING_ADDRESS2" "SOVEREIGN_BILLING_ADDRESS2" "SC_BILLING_ADDRESS2"
seed_alias_if_missing "NUQLOUD_BILLING_CITY" "SOVEREIGN_BILLING_CITY" "SC_BILLING_CITY"
seed_alias_if_missing "NUQLOUD_BILLING_STATE" "SOVEREIGN_BILLING_STATE" "SC_BILLING_STATE"
seed_alias_if_missing "NUQLOUD_BILLING_POSTAL_CODE" "SOVEREIGN_BILLING_POSTAL_CODE" "SC_BILLING_POSTAL_CODE"
seed_alias_if_missing "NUQLOUD_BILLING_COUNTRY" "SOVEREIGN_BILLING_COUNTRY" "SC_BILLING_COUNTRY"
seed_alias_if_missing "NUQLOUD_MSP_MODE_ENABLED" "MSP_MODE_ENABLED" "SC_MSP_MODE_ENABLED"
seed_alias_if_missing "NUQLOUD_MSP_ADMIN_GROUP" "MSP_ADMIN_GROUP" "SC_MSP_ADMIN_GROUP"
service_user_before="$(trim "$(read_kv "NEXTCLOUD_SERVICE_USER" || true)")"
if [[ -z "${service_user_before}" ]]; then
service_user_before="${legacy_service_user}"
set_kv "NEXTCLOUD_SERVICE_USER" "${service_user_before}"
log "NEXTCLOUD_SERVICE_USER was empty; set to legacy-compatible default '${service_user_before}'."
fi
if [[ "${switch_service_user}" == "1" ]]; then
if [[ "${service_user_before}" != "${nuqloud_service_user}" ]]; then
set_kv "NEXTCLOUD_SERVICE_USER" "${nuqloud_service_user}"
log "Switched NEXTCLOUD_SERVICE_USER from '${service_user_before}' to '${nuqloud_service_user}'."
else
log "NEXTCLOUD_SERVICE_USER is already '${nuqloud_service_user}'."
fi
else
log "Keeping NEXTCLOUD_SERVICE_USER='${service_user_before}'."
fi
if [[ "${skip_finish}" != "1" ]]; then
if [[ ! -x "${repo_root}/scripts/finish-initial-setup.sh" ]]; then
echo "Missing executable: scripts/finish-initial-setup.sh"
exit 1
fi
log "Running finish-initial-setup for runtime branding sync..."
"${repo_root}/scripts/finish-initial-setup.sh" \
--mode "${mode}" \
--env-file "${env_file}" \
--skip-register \
--skip-api-key
fi
if [[ "${switch_service_user}" == "1" && "${skip_finish}" == "1" && "${skip_auth_repair}" != "1" ]]; then
log "Recreating broker service so runtime env picks up NEXTCLOUD_SERVICE_USER change..."
docker compose -f "${compose_file}" --env-file "${env_file}" up -d --force-recreate broker
fi
if [[ "${skip_auth_repair}" != "1" ]]; then
if [[ ! -x "${repo_root}/scripts/ensure-nextcloud-service-auth.sh" ]]; then
echo "Missing executable: scripts/ensure-nextcloud-service-auth.sh"
exit 1
fi
log "Validating and repairing broker service auth (supports legacy or NuQloud username)..."
"${repo_root}/scripts/ensure-nextcloud-service-auth.sh" \
--compose-file "${compose_file}" \
--env-file "${env_file}" \
--repair
fi
log "Migration complete."
log "Env file: ${env_file}"
log "Compose file used for runtime actions: ${compose_file}"