diff --git a/.github/workflows/restore_from_backup.yml b/.github/workflows/restore_from_backup.yml new file mode 100644 index 0000000..3b35fa2 --- /dev/null +++ b/.github/workflows/restore_from_backup.yml @@ -0,0 +1,87 @@ +name: Update Staging Database + +on: + workflow_dispatch: + +# on: +# schedule: +# - cron: '0 0 * * *' # Runs at 00:00 UTC daily. + +jobs: + backup_upload: + runs-on: ubuntu-latest + environment: staging + steps: + - name: Setup SSH + run: | + mkdir -p ~/.ssh + echo "${{ secrets.SSH_PRIVATE_KEY }}" > ~/.ssh/private_key.pem + chmod 600 ~/.ssh/private_key.pem + ssh-keyscan -H ${{ secrets.SERVER_HOST }} >> ~/.ssh/known_hosts + + - name: Update from backup + run: | + echo "Authenticating with GCP." + echo '${{ secrets.GCP_SA_KEY }}' > /tmp/gcp-sa-key.json + gcloud auth activate-service-account --key-file=/tmp/gcp-sa-key.json + rm /tmp/gcp-sa-key.json $BACKUP_NAME + + BACKUP=$(gsutil ls -l gs://ocho-osai/track/pg_data/ | grep -v "TOTAL:" | sort -k2,2 -r | awk '{ $1=$2=""; print $0 }' | sed 's/^[ \t]*//' | head -n 1 | tr -d '\n') + BACKUP_NAME=$(basename $BACKUP) + BACKUP_FILE="backups/$BACKUP_NAME" + mkdir -p ./track/backups/ + gsutil cp $BACKUP $BACKUP_FILE + echo "Most recent backup found: $BACKUP_NAME" + + # Check if the backup file exists and is a gzip file + if [ -f "$BACKUP_FILE" ] && [[ $BACKUP_FILE == *.gz ]]; then + echo "Decompressing backup file $BACKUP_FILE" + gunzip -k "$BACKUP_FILE" + BACKUP_FILE="${BACKUP_FILE%.gz}" + echo "Backup decompressed to $BACKUP_FILE" + else + echo "Backup file does not exist or is not a gzip file." + exit 1 + fi + + ssh -i ~/.ssh/private_key.pem ${{ secrets.SERVER_USER }}@${{ secrets.SERVER_HOST }} << ENDSSH + echo "Removing old backups." + rm -r /home/${{ secrets.SERVER_USER }}/track/backups/ || true + mkdir -p /home/${{ secrets.SERVER_USER }}/track/backups/ + ENDSSH + + scp -i ~/.ssh/private_key.pem $BACKUP_FILE ${{ secrets.SERVER_USER }}@${{ secrets.SERVER_HOST }}:/home/${{ secrets.SERVER_USER }}/track/$BACKUP_FILE + ssh -i ~/.ssh/private_key.pem ${{ secrets.SERVER_USER }}@${{ secrets.SERVER_HOST }} << ENDSSH + echo "Restoring from backup: ./track/$BACKUP_FILE" + ls ./track/backups/ + + export APP_ENV=${{ vars.APP_ENV }} + export HOST_PORT=${{ vars.HOST_PORT }} + export POSTGRES_PASSWORD=${{ secrets.POSTGRES_PASSWORD }} + + # Restore from backup. The postgres docker service is called "db" + echo "Bringing down services." + docker compose -f track/base.yml -f track/prod.yml down + + echo "Starting db service in isolation." + docker compose -f track/base.yml -f track/prod.yml up -d db + + echo "Preparing for restore." + docker compose -f track/base.yml -f track/prod.yml exec db psql -U postgres -c "SELECT pg_terminate_backend(pg_stat_activity.pid) FROM pg_stat_activity WHERE pg_stat_activity.datname = 'postgres' AND pid <> pg_backend_pid();" + docker compose -f track/base.yml -f track/prod.yml exec db psql -U postgres -c "DROP DATABASE IF EXISTS postgres;" + docker compose -f track/base.yml -f track/prod.yml exec db psql -U postgres -c "CREATE DATABASE postgres;" + + echo "Restoring from backup." + docker compose -f track/base.yml -f track/prod.yml cp ./track/$BACKUP_FILE db:/backup + docker compose -f track/base.yml -f track/prod.yml exec db psql -U postgres -d postgres -f /backup + + echo "Bringing down db." + docker compose -f track/base.yml -f track/prod.yml down + + echo "Bringing up all services." + docker compose -f track/base.yml -f track/prod.yml up -d + + echo "Status:" + docker compose -f track/base.yml -f track/prod.yml ps + + ENDSSH diff --git a/ops/curl_weight_api.sh b/ops/curl_weight_api.sh new file mode 100755 index 0000000..f38f7aa --- /dev/null +++ b/ops/curl_weight_api.sh @@ -0,0 +1,17 @@ +#!/usr/bin/env sh + +HOST=$1 + +if [ -z "$HOST" ]; then + echo "Please provide the HOST ip address or hostname as an argument." + exit 1 +fi + +echo "Listing weights:" +curl -X GET $HOST/api/weights + +echo "Creating weight:" +curl -X POST $HOST/api/weights -H "Content-Type: application/json" -d '{"weight_kg": 65.1, "measured_at": "2022-11-01T12:34:56" }' + +echo "Listing weights:" +curl -X GET $HOST/api/weights