set -eux

: $GFDOCKER_PRJ_NAME
: $TZ
: $LANG
: $GFDOCKER_USERNAME_PREFIX
: $GFDOCKER_PRIMARY_USER
: $GFDOCKER_NUM_GFMDS
: $GFDOCKER_NUM_GFSDS
: $GFDOCKER_NUM_CLIENTS
: $GFDOCKER_NUM_USERS
: $GFDOCKER_HOSTNAME_PREFIX_GFMD
: $GFDOCKER_HOSTNAME_PREFIX_GFSD
: $GFDOCKER_HOSTNAME_PREFIX_CLIENT
: $GFDOCKER_HOSTNAME_SUFFIX

SUDO_USER2="sudo sudo -i -u user2"

gfmds=
gfsds=
clients=
allhosts=
users=

for i in $(seq 1 $GFDOCKER_NUM_GFMDS); do
  name="${GFDOCKER_HOSTNAME_PREFIX_GFMD}${i}"
  gfmds="${gfmds} ${name}"
  allhosts="${allhosts} ${name}"
done
for i in $(seq 1 $GFDOCKER_NUM_GFSDS); do
  name="${GFDOCKER_HOSTNAME_PREFIX_GFSD}${i}"
  gfsds="${gfsds} ${name}"
  allhosts="${allhosts} ${name}"
done
for i in $(seq 1 $GFDOCKER_NUM_CLIENTS); do
  name="${GFDOCKER_HOSTNAME_PREFIX_CLIENT}${i}"
  clients="${clients} ${name}"
  allhosts="${allhosts} ${name}"
done
for i in $(seq 1 $GFDOCKER_NUM_USERS); do
  users="${users} ${GFDOCKER_USERNAME_PREFIX}${i}"
done

# keep and distribute shared keys

## create directories to keep keys
for user in $users; do
  sudo mkdir -p /mnt/${user}
  sudo chown ${user} /mnt/${user}
done

GFDOCKER_COPY_SHARED_KEY=/usr/local/bin/gfdocker_copy_shared_key
## generate script #################################################
cat << EOS | sudo dd of="${GFDOCKER_COPY_SHARED_KEY}"
#!/bin/sh

set -eux
# backup or restore gfarm_shared_key

ALLHOSTS="${allhosts}"

BACKUP_KEY_DIR=/mnt/\$(whoami)
BACKUP_KEY=\${BACKUP_KEY_DIR}/gfarm_shared_key
KEY=~/.gfarm_shared_key
PERIOD=315360000

if [ -f \${BACKUP_KEY} ]; then
  cp \${BACKUP_KEY} \${KEY}
fi
if ! gfkey -e; then
  gfkey -f -p \${PERIOD}
fi
cp \${KEY} \${BACKUP_KEY}
chmod 600 \${BACKUP_KEY}

for h in \${ALLHOSTS}; do
   [ \${h} = "${GFDOCKER_HOSTNAME_PREFIX_CLIENT}1" ] && continue
   scp \${KEY} \${h}: &
done
wait
EOS
###################################################
sudo chmod +x ${GFDOCKER_COPY_SHARED_KEY}

# keep ssh host keys only for client1 host

MNT=/mnt
MNT_SSH_HOST_KEY_DIR=${MNT}/ssh_host_keys
MNT_SSH_AUTHORIZED_KEYS_FILE=${MNT}/ssh_authorized_keys
SSH_HOST_KEY_DIR=/etc/ssh

if [ ! -d $MNT_SSH_HOST_KEY_DIR ]; then
  sudo mkdir $MNT_SSH_HOST_KEY_DIR
fi
for f in $(echo $MNT_SSH_HOST_KEY_DIR/ssh_host_*_key); do
  if [ -f "$f" ]; then
    sudo cp -pf "$f" $SSH_HOST_KEY_DIR/
    sudo chmod 400 $SSH_HOST_KEY_DIR/$(basename "$f")
  fi
done
sudo systemctl restart sshd

SAVE_KEYS_SCRIPT=/home/${GFDOCKER_PRIMARY_USER}/SAVE_SSH_HOST_KEYS.sh
cat << EOF > $SAVE_KEYS_SCRIPT
cp -a ${SSH_HOST_KEY_DIR}/ssh_host_*_key $MNT_SSH_HOST_KEY_DIR
chmod 400 ${MNT_SSH_HOST_KEY_DIR}/ssh_host_*_key
EOF
chmod +x $SAVE_KEYS_SCRIPT

# copy ssh authorized keys only for users
SSH_AUTHORIZED_KEYS=.ssh/authorized_keys

if [ -f $MNT_SSH_AUTHORIZED_KEYS_FILE ]; then
  for user in $users; do
    cat $MNT_SSH_AUTHORIZED_KEYS_FILE \
    | sudo tee -a /home/${user}/$SSH_AUTHORIZED_KEYS > /dev/null
  done
fi

ssh_retry() {
  host="$1"
  retry_sec=30
  for i in $(seq 1 $retry_sec); do
     if ssh "$host" hostname; then
         break
     fi
     echo "retry: ssh $host"
     sleep 1
  done
}

# wait for the startup of sshd
for host in $gfmds $gfsds $clients; do
  ssh_retry "$host"
  ssh_retry "${host}${GFDOCKER_HOSTNAME_SUFFIX}"
done

for host in $gfmds; do
  cat <<EOF | ssh "$host" sudo sh
set -eux
ln '/etc/grid-security/${host}cert.pem' /etc/grid-security/hostcert.pem
ln '/etc/grid-security/${host}key.pem' /etc/grid-security/hostkey.pem
EOF
done

## before systemd 235: "rsyslog.service: Failed to kill control group"
for host in $gfmds $gfsds $clients; do
  gfservice -d grid-proxy-init "$host" &
  ssh "$host" sudo systemctl stop postgresql &
  ssh "$host" sudo systemctl disable postgresql &
  (ssh "$host" sudo localectl set-locale "${LANG}"  \
  && ssh "$host" sudo timedatectl set-timezone "${TZ}" \
  && ssh "$host" sudo systemctl restart rsyslog
  ) &
done
wait

gfservice -k -d config-all


for host in $gfmds; do
  (gfservice set-gfmd-conf "$host" digest md5 \
  && gfservice set-gfmd-conf "$host" metadb_server_heartbeat_interval 10 \
  && gfservice set-gfmd-conf "$host" 'auth enable gsi' '*' \
  && gfservice set-gfmd-conf "$host" write_verify enable \
  && gfservice set-gfmd-conf "$host" write_verify_interval 600 \
  && gfservice restart-gfmd "$host" \
  ) &
done
#wait

for host in $gfsds; do
  (gfservice set-gfarm-conf "$host" client_digest_check enable \
  && gfservice set-gfarm-conf "$host" spool_digest_error_check disable \
  && gfservice set-gfarm-conf "$host" 'auth enable gsi' '*' \
  && gfservice restart-gfsd "$host" \
  && ssh "$host" sudo systemctl enable "gfsd-${host}${GFDOCKER_HOSTNAME_SUFFIX}" \
  ) &
done
#wait

for host in $clients; do
  (gfservice set-gfarm-conf "$host" client_digest_check enable \
  && gfservice set-gfarm-conf "$host" schedule_busy_load_thresh 20 \
  ) &
done
wait

# copy current configuration files for external containers
COPY_DIR=/mnt/COPY_DIR
COPY_HOMES="${COPY_DIR}/HOMES"

sudo mkdir -p "${COPY_HOMES}"

# for external gfarm-s3-minio-web container
S3_USERMAP="${COPY_DIR}/gfarm-s3-usermap.conf"
S3_ACCESS_KEY_PREFIX="gfarm_s3_"

echo "### <Gfarm Username>:<Local Username>:<S3 Accesskey ID>" | \
sudo dd of="${S3_USERMAP}" > /dev/null 2>&1

for i in $(seq 1 $GFDOCKER_NUM_USERS); do
  name="${GFDOCKER_USERNAME_PREFIX}${i}"
  from_dir="/home/${name}"
  to_dir="${COPY_HOMES}/${name}"
  subject="/O=Grid/OU=GlobusTest/OU=GlobusSimpleCA/CN=${name}"

  # add gfarm user (skip Gfarm admin user)
  if [ "${name}" != "${GFDOCKER_USERNAME_PREFIX}1" ]; then
    gfuser -c "${name}" "${name}" / "${subject}"
  fi

  # backup or restore gfarm_shared_key
  sudo sudo -i -u "$name" ${GFDOCKER_COPY_SHARED_KEY}

  # copy home directory
  sudo rsync -av --exclude=gfarm --exclude gfarm2fs --exclude tmp \
  "${from_dir}/" "${to_dir}/"

  # add to S3_USERMAP
  echo "${name}:${name}:${S3_ACCESS_KEY_PREFIX}${name}" | \
  sudo dd conv=notrunc oflag=append of="${S3_USERMAP}" > /dev/null 2>&1
done

CERTIFICATES_DIR=/etc/grid-security/certificates
COPY_CERTIFICATES_DIR="${COPY_DIR}/CERTS"
sudo rsync -av --delete "${CERTIFICATES_DIR}/" "${COPY_CERTIFICATES_DIR}/"

GFARM2CONF_REGEXP="^system config file: "
GFARM2CONF=$(gfstatus | grep "$GFARM2CONF_REGEXP" | sed "s/$GFARM2CONF_REGEXP//")
COPY_GFARM2CONF=${COPY_DIR}/gfarm2.conf
sudo cp ${GFARM2CONF} ${COPY_GFARM2CONF}


### master gfmd
GFMD1=${GFDOCKER_HOSTNAME_PREFIX_GFMD}1${GFDOCKER_HOSTNAME_SUFFIX}
gfmdhost -m -C cluster1 ${GFMD1}

### sync slave gfmd
if [ $GFDOCKER_NUM_GFMDS -ge 2 ]; then
  ### XXX If "stop-gfmd" is not executed, master gfmd may freeze.
  GFMD_NAME=${GFDOCKER_HOSTNAME_PREFIX_GFMD}2
  GFMD_HOSTNAME=${GFMD_NAME}${GFDOCKER_HOSTNAME_SUFFIX}
  gfservice stop-gfmd ${GFMD_NAME}
  gfmdhost -m -C cluster1 ${GFMD_HOSTNAME}
  gfservice start-gfmd ${GFMD_NAME}
fi

### async slave gfmd
### (required by docker/dev/common/test-fo.sh)
if [ $GFDOCKER_NUM_GFMDS -ge 3 ]; then
  ### XXX If "stop-gfmd" is not executed, master gfmd may freeze.
  GFMD_NAME=${GFDOCKER_HOSTNAME_PREFIX_GFMD}3
  GFMD_HOSTNAME=${GFMD_NAME}${GFDOCKER_HOSTNAME_SUFFIX}
  gfservice stop-gfmd ${GFMD_NAME}
  gfmdhost -m -C cluster2 ${GFMD_HOSTNAME}
  gfservice start-gfmd ${GFMD_NAME}
fi

set +x

test_auth() {
  echo "***** $authtype *****"
  gfmdhost -l
  gfhost -lv
  num_gfmdhost=$(gfmdhost | wc -l)
  num_gfsched=$(gfsched | wc -l)
  [ $num_gfmdhost -eq $GFDOCKER_NUM_GFMDS ] || exit 1
  [ $num_gfsched -eq $GFDOCKER_NUM_GFSDS ] || exit 1
}

tmp_gfarmconf=$(mktemp)
for authtype in sharedsecret gsi_auth gsi; do
  if [ $authtype = sharedsecret ]; then
    cat <<EOF  > $tmp_gfarmconf
auth enable sharedsecret *
auth disable gsi_auth *
auth disable gsi *
EOF
  elif [ $authtype = gsi_auth ]; then
    cat <<EOF  > $tmp_gfarmconf
auth disable sharedsecret *
auth enable gsi_auth *
auth disable gsi *
EOF
  elif [ $authtype = gsi ]; then
    cat <<EOF  > $tmp_gfarmconf
auth disable sharedsecret *
auth disable gsi_auth *
auth enable gsi *
EOF
  fi
  GFARM_CONFIG_FILE=$tmp_gfarmconf test_auth $authtype
done
rm -f $tmp_gfarmconf

LOG=/var/log/messages
SYSLOG=/var/log/syslog
if [ -f $SYSLOG ]; then
   LOG=$SYSLOG
fi
sudo tail -1 $LOG

date
echo "GFDOCKER_PRJ_NAME=$GFDOCKER_PRJ_NAME: setup is now complete."
