diff --git a/deployment/deploy_vm.sh b/deployment/deploy_vm.sh index 591ced5..1e77d7d 100755 --- a/deployment/deploy_vm.sh +++ b/deployment/deploy_vm.sh @@ -3,6 +3,8 @@ set -eu cd "$(dirname "$0")" +. ./base.sh + ## This is a weird if clause since we need to LEFT-ALIGN the statement below. SSH_STRING="Host ${FQDN}" if ! grep -q "$SSH_STRING" "$SSH_HOME/config"; then diff --git a/deployment/down.sh b/deployment/down.sh index a6a4a83..bf21aec 100755 --- a/deployment/down.sh +++ b/deployment/down.sh @@ -26,13 +26,12 @@ for i in "$@"; do esac done -. ../defaults.sh +. ./deployment_defaults.sh . ./remote_env.sh . ./project_env.sh - # let's bring down services on the remote deployment if necessary. export DOMAIN_NAME="$PRIMARY_DOMAIN" export SITE_PATH="$SITES_PATH/$PRIMARY_DOMAIN" @@ -45,16 +44,16 @@ for VIRTUAL_MACHINE in www btcpayserver; do LXD_NAME="$VIRTUAL_MACHINE-${PRIMARY_DOMAIN//./-}" if lxc list | grep -q "$LXD_NAME"; then - bash -c "./deploy.sh --stop --skip-$SKIP" + bash -c "./up.sh --stop --skip-$SKIP" lxc stop "$LXD_NAME" lxc delete "$LXD_NAME" - - # remove the ssh known endpoint else we get warnings. - ssh-keygen -f "$SSH_HOME/known_hosts" -R "$LXD_NAME" fi + # remove the ssh known endpoint else we get warnings. + ssh-keygen -f "$SSH_HOME/known_hosts" -R "$VIRTUAL_MACHINE.$PRIMARY_DOMAIN" | exit + if lxc profile list | grep -q "$LXD_NAME"; then lxc profile delete "$LXD_NAME" fi @@ -86,10 +85,3 @@ done if lxc network list -q | grep -q ss-ovn; then lxc network delete ss-ovn fi - -# delete the base image so it can be created. -if lxc list | grep -q "$BASE_IMAGE_VM_NAME"; then - lxc delete -f "$BASE_IMAGE_VM_NAME" --project default - # remove the ssh known endpoint else we get warnings. - ssh-keygen -f "$SSH_HOME/known_hosts" -R "$BASE_IMAGE_VM_NAME" -fi diff --git a/deployment/show.sh b/deployment/show.sh index 891711d..9540173 100755 --- a/deployment/show.sh +++ b/deployment/show.sh @@ -1,9 +1,9 @@ #!/bin/bash -set -eu +set -e cd "$(dirname "$0")" -. ../defaults.sh +. ./deployment_defaults.sh . ./remote_env.sh diff --git a/deployment/up.sh b/deployment/up.sh new file mode 100755 index 0000000..8e3749f --- /dev/null +++ b/deployment/up.sh @@ -0,0 +1,440 @@ +#!/bin/bash + +set -exu +cd "$(dirname "$0")" + +LATEST_GIT_COMMIT="$(cat ./project/.git/refs/heads/main)" +export LATEST_GIT_COMMIT="$LATEST_GIT_COMMIT" + +# check to ensure dependencies are met. +for cmd in wait-for-it dig rsync sshfs lxc; do + if ! command -v "$cmd" >/dev/null 2>&1; then + echo "This script requires \"${cmd}\" to be installed. Please run 'install.sh'." + exit 1 + fi +done + +# do a spot check; if we are on production warn. +if lxc remote get-default | grep -q "production"; then + echo "WARNING: You are running command against a production system!" + echo "" + + # check if there are any uncommited changes. It's dangerous to + # alter production systems when you have commits to make or changes to stash. + if git update-index --refresh | grep -q "needs update"; then + echo "ERROR: You have uncommited changes! You MUST commit or stash all changes to continue." + exit 1 + fi + + RESPONSE= + read -r -p " Are you sure you want to continue (y) ": RESPONSE + if [ "$RESPONSE" != "y" ]; then + echo "STOPPING." + exit 1 + fi + +fi + + +PRIMARY_DOMAIN= +RUN_CERT_RENEWAL=true +SKIP_BASE_IMAGE_CREATION=false +SKIP_WWW=false +RESTORE_WWW=false +RESTORE_CERTS=false +BACKUP_CERTS=false +BACKUP_BTCPAY=false +BACKUP_CERTS=false +BACKUP_APPS=false +BACKUP_BTCPAY=false +BACKUP_BTCPAY_ARCHIVE_PATH= +RESTORE_BTCPAY=false +SKIP_BTCPAY=false +UPDATE_BTCPAY=false +REMOTE_NAME="$(lxc remote get-default)" +STOP_SERVICES=false +USER_SAYS_YES=false +RESTART_FRONT_END=true + +# grab any modifications from the command line. +for i in "$@"; do + case $i in + --restore-certs) + RESTORE_CERTS=true + shift + ;; + --restore-www) + RESTORE_WWW=true + RESTORE_CERTS=true + + shift + ;; + --restore-btcpay) + RESTORE_BTCPAY=true + shift + ;; + --backup-www) + BACKUP_CERTS=true + BACKUP_APPS=true + shift + ;; + --backup-btcpayserver) + BACKUP_BTCPAY=true + shift + ;; + --stop) + STOP_SERVICES=true + RESTART_FRONT_END=false + shift + ;; + --backup-archive-path=*) + BACKUP_BTCPAY_ARCHIVE_PATH="${i#*=}" + shift + ;; + --update-btcpay) + UPDATE_BTCPAY=true + shift + ;; + --skip-www) + SKIP_WWW=true + shift + ;; + --skip-btcpayserver) + SKIP_BTCPAY=true + shift + ;; + --skip-base-image) + SKIP_BASE_IMAGE_CREATION=true + shift + ;; + --no-cert-renew) + RUN_CERT_RENEWAL=false + shift + ;; + -y) + USER_SAYS_YES=true + shift + ;; + *) + echo "Unexpected option: $1" + exit 1 + ;; + esac +done + +if [ "$RESTORE_BTCPAY" = true ] && [ -z "$BACKUP_BTCPAY_ARCHIVE_PATH" ]; then + echo "ERROR: Use the '--backup-archive-path=/path/to/btcpay/archive.tar.gz' option when restoring btcpay server." + exit 1 +fi + +if [ "$RESTORE_BTCPAY" = true ] && [ ! -f "$BACKUP_BTCPAY_ARCHIVE_PATH" ]; then + echo "ERROR: The backup archive path you specified DOES NOT exist!" + exit 1 +fi + +. ./remote_env.sh + +export REGISTRY_DOCKER_IMAGE="registry:2" +export RESTORE_WWW="$RESTORE_WWW" +export STOP_SERVICES="$STOP_SERVICES" +export BACKUP_CERTS="$BACKUP_CERTS" +export BACKUP_APPS="$BACKUP_APPS" +export RESTORE_BTCPAY="$RESTORE_BTCPAY" +export BACKUP_BTCPAY="$BACKUP_BTCPAY" +export RUN_CERT_RENEWAL="$RUN_CERT_RENEWAL" +export REMOTE_NAME="$REMOTE_NAME" +export REMOTE_PATH="$REMOTES_PATH/$REMOTE_NAME" +export USER_SAYS_YES="$USER_SAYS_YES" +export BACKUP_BTCPAY_ARCHIVE_PATH="$BACKUP_BTCPAY_ARCHIVE_PATH" +export RESTART_FRONT_END="$RESTART_FRONT_END" +export RESTORE_CERTS="$RESTORE_CERTS" + +# todo convert this to Trezor-T +SSH_PUBKEY_PATH="$SSH_HOME/id_rsa.pub" +export SSH_PUBKEY_PATH="$SSH_PUBKEY_PATH" +if [ ! -f "$SSH_PUBKEY_PATH" ]; then + # generate a new SSH key for the base vm image. + ssh-keygen -f "$SSH_HOME/id_rsa" -t ecdsa -b 521 -N "" +fi + +# ensure our remote path is created. +mkdir -p "$REMOTE_PATH" + +REMOTE_DEFINITION="$REMOTE_PATH/remote.conf" +if [ ! -f "$REMOTE_DEFINITION" ]; then + echo "ERROR: The remote definition could not be found. You may need to re-run 'ss-remote'." + exit 1 +fi + +export REMOTE_DEFINITION="$REMOTE_DEFINITION" +source "$REMOTE_DEFINITION" +export LXD_REMOTE_PASSWORD="$LXD_REMOTE_PASSWORD" +export DEPLOYMENT_STRING="$DEPLOYMENT_STRING" + +# this is our password generation mechanism. Relying on GPG for secure password generation +function new_pass { + gpg --gen-random --armor 1 25 +} + + +function stub_site_definition { + mkdir -p "$SITE_PATH" "$PROJECT_PATH/sites" + + # create a symlink from the PROJECT_PATH/sites/DOMAIN_NAME to the ss-sites/domain name + DOMAIN_SYMLINK_PATH="$PROJECT_PATH/sites/$DOMAIN_NAME" + if [ ! -L "$DOMAIN_SYMLINK_PATH" ]; then + ln -r -s "$SITE_PATH" "$DOMAIN_SYMLINK_PATH" + fi + + if [ ! -f "$SITE_PATH/site.conf" ]; then + # check to see if the enf file exists. exist if not. + SITE_DEFINITION_PATH="$SITE_PATH/site.conf" + if [ ! -f "$SITE_DEFINITION_PATH" ]; then + + # stub out a site.conf with new passwords. + cat >"$SITE_DEFINITION_PATH" <"$PROJECT_DEFINITION_PATH" < /home/ubuntu/.ss-githead" +else + echo "INFO: Skipping www VM." +fi + +export DOMAIN_NAME="$PRIMARY_DOMAIN" +export SITE_PATH="$SITES_PATH/$DOMAIN_NAME" +if [ "$SKIP_BTCPAY" = false ]; then + ./project/btcpayserver/go.sh + + ssh ubuntu@"$BTCPAY_FQDN" "echo $LATEST_GIT_COMMIT > /home/ubuntu/.ss-githead" +else + echo "INFO: Skipping the btcpayserver VM." +fi \ No newline at end of file diff --git a/deployment/update.sh b/deployment/update.sh index 2237a89..8ea7247 100755 --- a/deployment/update.sh +++ b/deployment/update.sh @@ -3,7 +3,7 @@ set -exu cd "$(dirname "$0")" -TARGET_PROJECT_GIT_COMMIT=9576b56ae8ac90ac4d68429a63e8f6ab843cd4e4 +TARGET_PROJECT_GIT_COMMIT=2e68e93303196fd57b1b473b149b5a82c9faa4f0 # # As part of the install script, we pull down any other sovereign-stack git repos # PROJECTS_SCRIPTS_REPO_URL="https://git.sovereign-stack.org/ss/project" @@ -77,13 +77,13 @@ git checkout "$GIT_COMMIT_ON_REMOTE_HOST" cd - # run deploy which backups up everything, but doesnt restart any services. -bash -c "./deploy.sh --stop --backup-archive-path=$BTCPAY_RESTORE_ARCHIVE_PATH --backup-www --backup-btcpayserver --skip-base-image" +bash -c "./up.sh --stop --backup-archive-path=$BTCPAY_RESTORE_ARCHIVE_PATH --backup-www --backup-btcpayserver --skip-base-image" # call the down script (be default it is non-destructuve of user data.) ./down.sh -# next we switch back to the current version of Sovereign Stack scripts for bringin up the new version. +next we switch back to the current version of Sovereign Stack scripts for bringin up the new version. cd project/ echo "INFO: switching the 'project' repo back to the most recent commit '$TARGET_PROJECT_GIT_COMMIT'" echo " That way new deployments will be instantiated using the latest codebase." @@ -98,4 +98,4 @@ cd - # need to do any restorations (or backups for that matter, though we still grab one); # we simply mount the existing data. That's the more common case where the user is simply upgrading the system in-place. -./project/deploy.sh +./up.sh diff --git a/deployment/wait_for_lxc_ip.sh b/deployment/wait_for_lxc_ip.sh new file mode 100755 index 0000000..eac89e8 --- /dev/null +++ b/deployment/wait_for_lxc_ip.sh @@ -0,0 +1,49 @@ +#!/bin/bash + +set -e + +LXC_INSTANCE_NAME= + +# grab any modifications from the command line. +for i in "$@"; do + case $i in + --lxd-name=*) + LXC_INSTANCE_NAME="${i#*=}" + shift + ;; + *) + echo "Unexpected option: $1" + exit 1 + ;; + esac +done + +# if the invoker did not set the instance name, throw an error. +if [ -z "$LXC_INSTANCE_NAME" ]; then + echo "ERROR: The lxc instance name was not specified. Use '--lxc-name' when calling wait_for_lxc_ip.sh." + exit 1 +fi + +if ! lxc list --format csv | grep -q "$LXC_INSTANCE_NAME"; then + echo "ERROR: the lxc instance '$LXC_INSTANCE_NAME' does not exist." + exit 1 +fi + +IP_V4_ADDRESS= +while true; do + IP_V4_ADDRESS="$(lxc list "$LXC_INSTANCE_NAME" --format csv --columns=4 | grep enp5s0 | grep -Eo '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}')" || true + export IP_V4_ADDRESS="$IP_V4_ADDRESS" + if [ -n "$IP_V4_ADDRESS" ]; then + # give the machine extra time to spin up. + wait-for-it -t 300 "$IP_V4_ADDRESS:22" + break + else + sleep 1 + printf '.' + fi +done + +# wait for cloud-init to complet before returning. +while lxc exec "$LXC_INSTANCE_NAME" -- [ ! -f /var/lib/cloud/instance/boot-finished ]; do + sleep 1 +done \ No newline at end of file diff --git a/management/bash_aliases b/management/bash_aliases index 702e42c..b7b3803 100755 --- a/management/bash_aliases +++ b/management/bash_aliases @@ -1,6 +1,6 @@ #!/bin/bash -alias ss-deploy='/home/ubuntu/sovereign-stack/deployment/deploy.sh $@' +alias ss-up='/home/ubuntu/sovereign-stack/deployment/up.sh $@' alias ss-remote='/home/ubuntu/sovereign-stack/deployment/remote.sh $@' alias ss-show='/home/ubuntu/sovereign-stack/deployment/show.sh $@' alias ss-reset='/home/ubuntu/sovereign-stack/deployment/reset.sh $@'