#!/usr/bin/env bash
#/ Usage: ghe-backup-pages
#/ Take an online, incremental snapshot of all Pages data
#/
#/ Note: This command typically isn't called directly. It's invoked by
#/ ghe-backup.
set -e

# Bring in the backup configuration
# shellcheck source=share/github-backup-utils/ghe-backup-config
. "$( dirname "${BASH_SOURCE[0]}" )/ghe-backup-config"

bm_start "$(basename $0)"

# Set up remote host and root backup snapshot directory based on config
host="$GHE_HOSTNAME"
backup_dir="$GHE_SNAPSHOT_DIR/pages"

# Verify rsync is available.
if ! rsync --version 1>/dev/null 2>&1; then
  log_error "rsync not found." 1>&2
  exit 1
fi

# Perform a host-check and establish GHE_REMOTE_XXX variables.
ghe_remote_version_required "$host"

# Split host:port into parts
port=$(ssh_port_part "$GHE_HOSTNAME")
host=$(ssh_host_part "$GHE_HOSTNAME")

# Add user / -l option
user="${host%@*}"
[ "$user" = "$host" ] && user="admin"

hostnames=$host
ssh_config_file_opt=
tempdir=$(mktemp -d -t backup-utils-restore-XXXXXX)
opts="$GHE_EXTRA_SSH_OPTS"

# Pages server hostnames under cluster
if [ "$GHE_BACKUP_STRATEGY" = "cluster" ]; then
  ssh_config_file="$tempdir/ssh_config"
  ssh_config_file_opt="-F $ssh_config_file"
  opts="$opts -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -o PasswordAuthentication=no"
  hostnames=$(ghe-cluster-find-nodes "$GHE_HOSTNAME" "pages-server")
  ghe-ssh-config "$GHE_HOSTNAME" "$hostnames" > "$ssh_config_file"
fi

# Make sure root backup dir exists if this is the first run
mkdir -p "$backup_dir"

# Removes the remote sync-in-progress file on exit, re-enabling GC operations
# on the remote instance.
cleanup() {
  rm -rf $tempdir
}
trap 'cleanup' EXIT INT

# If we have a previous increment and it is not empty, avoid transferring existing files via rsync's
# --link-dest support. This also decreases physical space usage considerably.
if [ -d "$GHE_DATA_DIR/current/pages" ] && [ "$(ls -A $GHE_DATA_DIR/current/pages)" ]; then
  link_dest="--link-dest=../../current/pages"
fi

count=0
for hostname in $hostnames; do
  bm_start "$(basename $0) - $hostname"
  echo 1>&3
  ghe_verbose "* Starting backup for host: $hostname"
  # Sync all auxiliary repository data. This includes files and directories like
  # HEAD, audit_log, config, description, info/, etc. No refs or object data
  # should be transferred here.
  echo 1>&3
  ghe_verbose "* Transferring pages files ..."
  log_rsync "BEGIN: pages rsync" 1>&3
  # Transfer all data from the user data directory using rsync.
  ghe-rsync -av \
    -e "ssh -q $opts -p $port $ssh_config_file_opt -l $user" \
    --rsync-path='sudo -u git rsync' \
    $link_dest \
    "$hostname:$GHE_REMOTE_DATA_USER_DIR/pages/" \
    "$GHE_SNAPSHOT_DIR/pages" 1>&3
  log_rsync "END: pages rsync" 1>&3
  bm_end "$(basename $0) - $hostname"
  count=$((count + 1))
done
increment-progress-total-count $count
bm_end "$(basename $0)"
