|
|
@@ -1,9 +1,12 @@
|
|
|
#!/bin/bash
|
|
|
|
|
|
-# Make sure the script is run as root user
|
|
|
+# Make sure the script is run as root user, or someone in the 'docker' group
|
|
|
if [[ ${EUID} -ne 0 ]]; then
|
|
|
- echo "This script must be run as root"
|
|
|
- exit 1
|
|
|
+ id | grep -q "docker"
|
|
|
+ if [[ $? -ne 0 ]]; then
|
|
|
+ echo "This script must be run as root, or a user in the 'docker' group"
|
|
|
+ exit 1
|
|
|
+ fi
|
|
|
fi
|
|
|
|
|
|
usage () {
|
|
|
@@ -35,7 +38,11 @@ generate_temporary_credentials () {
|
|
|
ssh-keygen -t rsa -b 4096 -C "temp-psiphond-ad_hoc" -f psiphond-ad_hoc -N ""
|
|
|
PUBLIC_KEY=$(cat psiphond-ad_hoc.pub)
|
|
|
|
|
|
- echo "${PUBLIC_KEY}" | ssh -o PreferredAuthentications=interactive,password -p $PORT $USER@$HOST cat >> $HOME/.ssh/authorized_keys
|
|
|
+ if [ $USER == "root" ]; then
|
|
|
+ echo "${PUBLIC_KEY}" | ssh -o PreferredAuthentications=interactive,password -p $PORT $USER@$HOST "cat >> /$USER/.ssh/authorized_keys"
|
|
|
+ else
|
|
|
+ echo "${PUBLIC_KEY}" | ssh -o PreferredAuthentications=interactive,password -p $PORT $USER@$HOST "cat >> /home/$USER/.ssh/authorized_keys"
|
|
|
+ fi
|
|
|
if [ $? -ne 0 ]; then
|
|
|
echo "...Failed"
|
|
|
return 1
|
|
|
@@ -45,7 +52,12 @@ generate_temporary_credentials () {
|
|
|
destroy_temporary_credentials () {
|
|
|
echo "..Removing the temporary key from the remote host"
|
|
|
PUBLIC_KEY=$(cat psiphond-ad_hoc.pub)
|
|
|
- ssh -i psiphond-ad_hoc -o IdentitiesOnly=yes -p $PORT $USER@$HOST sed -i '/temp-psiphond-ad_hoc/d' $HOME/.ssh/authorized_keys
|
|
|
+
|
|
|
+ if [ $USER == "root" ]; then
|
|
|
+ ssh -i psiphond-ad_hoc -o PreferredAuthentications=publickey -o IdentitiesOnly=yes -p $PORT $USER@$HOST "sed -i '/temp-psiphond-ad_hoc/d' /$USER/.ssh/authorized_keys"
|
|
|
+ else
|
|
|
+ ssh -i psiphond-ad_hoc -o PreferredAuthentications=publickey -o IdentitiesOnly=yes -p $PORT $USER@$HOST "sed -i '/temp-psiphond-ad_hoc/d' /home/$USER/.ssh/authorized_keys"
|
|
|
+ fi
|
|
|
if [ $? -ne 0 ]; then
|
|
|
echo "...Failed"
|
|
|
return 1
|
|
|
@@ -112,15 +124,14 @@ save_image () {
|
|
|
|
|
|
put_and_load_image () {
|
|
|
echo "..Copying '${ARCHIVE}' to '${HOST}:/tmp'"
|
|
|
- scp -i psiphond-ad_hoc -o IdentitiesOnly=yes -P $PORT $ARCHIVE $USER@$HOST:/tmp/
|
|
|
+ scp -i psiphond-ad_hoc -o PreferredAuthentications=publickey -o IdentitiesOnly=yes -P $PORT $ARCHIVE $USER@$HOST:/tmp/
|
|
|
if [ $? -ne 0 ]; then
|
|
|
echo "...Failed"
|
|
|
return 1
|
|
|
fi
|
|
|
|
|
|
echo "..Loading image into remote docker"
|
|
|
- # Variable interpolation into the remote script doesn't always work as expected, use fixed paths here instead
|
|
|
- ssh -i psiphond-ad_hoc -o IdentitiesOnly=yes -p $PORT $USER@$HOST zcat /tmp/psiphond-ad-hoc.tar.gz | docker load && rm /tmp/psiphond-ad-hoc.tar.gz
|
|
|
+ ssh -i psiphond-ad_hoc -o PreferredAuthentications=publickey -o IdentitiesOnly=yes -p $PORT $USER@$HOST "zcat /tmp/$ARCHIVE | docker load && rm /tmp/$ARCHIVE"
|
|
|
if [ $? -ne 0 ]; then
|
|
|
echo "...Failed"
|
|
|
return 1
|
|
|
@@ -129,7 +140,8 @@ put_and_load_image () {
|
|
|
|
|
|
remove_image () {
|
|
|
echo "..Removing image from remote docker"
|
|
|
- ssh -i psiphond-ad_hoc -o IdentitiesOnly=yes -p $PORT $USER@$HOST docker rmi ${CONTAINER_TAG}
|
|
|
+ # Single quotes prevents local substitution of variables
|
|
|
+ ssh -i psiphond-ad_hoc -o PreferredAuthentications=publickey -o IdentitiesOnly=yes -p $PORT $USER@$HOST 'docker rmi $(docker images -q psiphond/ad-hoc)'
|
|
|
if [ $? -ne 0 ]; then
|
|
|
echo "...Failed"
|
|
|
return 1
|
|
|
@@ -137,10 +149,17 @@ remove_image () {
|
|
|
}
|
|
|
|
|
|
put_systemd_dropin () {
|
|
|
+ echo "..Creating ad-hoc environment variables file"
|
|
|
+ ssh -i psiphond-ad_hoc -o PreferredAuthentications=publickey -o IdentitiesOnly=yes -p $PORT $USER@$HOST "sed 's/DOCKER_CONTENT_TRUST=1/DOCKER_CONTENT_TRUST=0/' /opt/psiphon/psiphond/config/psiphond.env | sed '/CONTAINER_TAG=/d' > /opt/psiphon/psiphond/config/psiphond.env.adhoc"
|
|
|
+ if [ $? -ne 0 ]; then
|
|
|
+ echo "...Failed"
|
|
|
+ return 1
|
|
|
+ fi
|
|
|
+
|
|
|
echo "..Creating systemd unit drop-in"
|
|
|
cat <<- EOF > ad-hoc.conf
|
|
|
[Service]
|
|
|
- Environment=DOCKER_CONTENT_TRUST=0
|
|
|
+ EnvironmentFile=/opt/psiphon/psiphond/config/psiphond.env.adhoc
|
|
|
|
|
|
# Clear previous pre-start command before setting new one
|
|
|
# Execute these commands prior to starting the service
|
|
|
@@ -151,17 +170,17 @@ put_systemd_dropin () {
|
|
|
|
|
|
# Clear previous start command before setting new one
|
|
|
ExecStart=
|
|
|
- ExecStart=/usr/bin/docker run --rm $CONTAINER_PORT_STRING $CONTAINER_VOLUME_STRING $CONTAINER_ULIMIT_STRING $CONTAINER_SYSCTL_STRING --name %p-run ${CONTAINER_TAG}
|
|
|
+ ExecStart=/usr/bin/docker run --rm \$CONTAINER_PORT_STRING \$CONTAINER_VOLUME_STRING \$CONTAINER_ULIMIT_STRING \$CONTAINER_SYSCTL_STRING --name %p-run ${CONTAINER_TAG}
|
|
|
EOF
|
|
|
|
|
|
- ssh -i psiphond-ad_hoc -o IdentitiesOnly=yes -p $PORT $USER@$HOST mkdir -p /etc/systemd/system/psiphond.service.d
|
|
|
+ ssh -i psiphond-ad_hoc -o PreferredAuthentications=publickey -o IdentitiesOnly=yes -p $PORT $USER@$HOST "mkdir -p /etc/systemd/system/psiphond.service.d"
|
|
|
echo "..Ensuring drop-in directory is available"
|
|
|
if [ $? -ne 0 ]; then
|
|
|
echo "...Failed"
|
|
|
return 1
|
|
|
fi
|
|
|
|
|
|
- scp -i psiphond-ad_hoc -o IdentitiesOnly=yes -P $PORT ad-hoc.conf $USER@$HOST:/etc/systemd/system/psiphond.service.d/
|
|
|
+ scp -i psiphond-ad_hoc -o PreferredAuthentications=publickey -o IdentitiesOnly=yes -P $PORT ad-hoc.conf $USER@$HOST:/etc/systemd/system/psiphond.service.d/
|
|
|
echo "..Copying drop-in to remote host"
|
|
|
if [ $? -ne 0 ]; then
|
|
|
echo "...Failed"
|
|
|
@@ -173,7 +192,14 @@ put_systemd_dropin () {
|
|
|
|
|
|
remove_systemd_dropin () {
|
|
|
echo "..Removing systemd unit drop-in"
|
|
|
- ssh -i psiphond-ad_hoc -o IdentitiesOnly=yes -p $PORT $USER@$HOST [ ! -f /etc/systemd/system/psiphond.service.d/ad-hoc.conf ] || rm /etc/systemd/system/psiphond.service.d/ad-hoc.conf
|
|
|
+ ssh -i psiphond-ad_hoc -o PreferredAuthentications=publickey -o IdentitiesOnly=yes -p $PORT $USER@$HOST "[ ! -f /etc/systemd/system/psiphond.service.d/ad-hoc.conf ] || rm /etc/systemd/system/psiphond.service.d/ad-hoc.conf"
|
|
|
+ if [ $? -ne 0 ]; then
|
|
|
+ echo "...Failed"
|
|
|
+ return 1
|
|
|
+ fi
|
|
|
+
|
|
|
+ echo "..Removing ad-hoc environment variables file"
|
|
|
+ ssh -i psiphond-ad_hoc -o PreferredAuthentications=publickey -o IdentitiesOnly=yes -p $PORT $USER@$HOST "[ ! -f /opt/psiphon/psiphond/config/psiphond.env.adhoc ] || rm /opt/psiphon/psiphond/config/psiphond.env.adhoc"
|
|
|
if [ $? -ne 0 ]; then
|
|
|
echo "...Failed"
|
|
|
return 1
|
|
|
@@ -182,7 +208,7 @@ remove_systemd_dropin () {
|
|
|
|
|
|
reload_systemd () {
|
|
|
echo "..Reloading systemd unit file cache"
|
|
|
- ssh -i psiphond-ad_hoc -o IdentitiesOnly=yes -p $PORT $USER@$HOST systemctl daemon-reload
|
|
|
+ ssh -i psiphond-ad_hoc -o PreferredAuthentications=publickey -o IdentitiesOnly=yes -p $PORT $USER@$HOST "systemctl daemon-reload"
|
|
|
if [ $? -ne 0 ]; then
|
|
|
echo "...Failed"
|
|
|
return 1
|
|
|
@@ -191,13 +217,79 @@ reload_systemd () {
|
|
|
|
|
|
restart_psiphond () {
|
|
|
echo "..Restarting the 'psiphond' service"
|
|
|
- ssh -i psiphond-ad_hoc -o IdentitiesOnly=yes -p $PORT $USER@$HOST systemctl restart psiphond
|
|
|
+ ssh -i psiphond-ad_hoc -o PreferredAuthentications=publickey -o IdentitiesOnly=yes -p $PORT $USER@$HOST "systemctl restart psiphond"
|
|
|
if [ $? -ne 0 ]; then
|
|
|
echo "...Failed"
|
|
|
return 1
|
|
|
fi
|
|
|
}
|
|
|
|
|
|
+install() {
|
|
|
+ docker_build_builder
|
|
|
+ if [ $? -ne 0 ]; then
|
|
|
+ return 1
|
|
|
+ fi
|
|
|
+
|
|
|
+ docker_build_psiphond_binary
|
|
|
+ if [ $? -ne 0 ]; then
|
|
|
+ return 1
|
|
|
+ fi
|
|
|
+
|
|
|
+ docker_build_psiphond_container
|
|
|
+ if [ $? -ne 0 ]; then
|
|
|
+ return 1
|
|
|
+ fi
|
|
|
+
|
|
|
+ save_image
|
|
|
+ if [ $? -ne 0 ]; then
|
|
|
+ return 1
|
|
|
+ fi
|
|
|
+
|
|
|
+ put_and_load_image
|
|
|
+ if [ $? -ne 0 ]; then
|
|
|
+ return 1
|
|
|
+ fi
|
|
|
+
|
|
|
+ put_systemd_dropin
|
|
|
+ if [ $? -ne 0 ]; then
|
|
|
+ return 1
|
|
|
+ fi
|
|
|
+
|
|
|
+ reload_systemd
|
|
|
+ if [ $? -ne 0 ]; then
|
|
|
+ return 1
|
|
|
+ fi
|
|
|
+
|
|
|
+ restart_psiphond
|
|
|
+ if [ $? -ne 0 ]; then
|
|
|
+ return 1
|
|
|
+ fi
|
|
|
+}
|
|
|
+
|
|
|
+remove () {
|
|
|
+ remove_systemd_dropin
|
|
|
+ if [ $? -ne 0 ]; then
|
|
|
+ echo "...Failed, continuing removal steps. Drop-in file or ad-hoc environment file may still exist"
|
|
|
+ fi
|
|
|
+
|
|
|
+ reload_systemd
|
|
|
+ if [ $? -ne 0 ]; then
|
|
|
+ echo "...Failed, continuing removal steps. 'systemctl daemon-reload' may still be needed to restore previous functionality"
|
|
|
+ fi
|
|
|
+
|
|
|
+ restart_psiphond
|
|
|
+ if [ $? -ne 0 ]; then
|
|
|
+ echo "...Failed, continuing removal steps. The old 'psiphond' may still be running"
|
|
|
+ fi
|
|
|
+
|
|
|
+ remove_image
|
|
|
+ if [ $? -ne 0 ]; then
|
|
|
+ echo "...Final step failed, check for leftover images manually with 'docker images psiphond/ad-hoc', then use 'docker rmi' to remove them"
|
|
|
+ destroy_temporary_credentials
|
|
|
+ return 1
|
|
|
+ fi
|
|
|
+}
|
|
|
+
|
|
|
# Locate and change to the directory containing the script
|
|
|
BASE=$( cd "$(dirname "$0")" ; pwd -P )
|
|
|
cd $BASE
|
|
|
@@ -276,8 +368,10 @@ echo " - Action: ${ACTION}"
|
|
|
echo " - User: ${USER}"
|
|
|
echo " - Host: ${HOST}"
|
|
|
echo " - Port: ${PORT}"
|
|
|
-echo " - Containter Tag: ${CONTAINER_TAG}"
|
|
|
-echo " - Archive Name: ${ARCHIVE}"
|
|
|
+if [ $ACTION == "install" ]; then
|
|
|
+ echo " - Containter Tag: ${CONTAINER_TAG}"
|
|
|
+ echo " - Archive Name: ${ARCHIVE}"
|
|
|
+fi
|
|
|
echo ""
|
|
|
echo "Pausing 5 seconds to allow for ^C prior to starting"
|
|
|
sleep 5
|
|
|
@@ -289,89 +383,19 @@ if [ $? -ne 0 ]; then
|
|
|
fi
|
|
|
|
|
|
if [ "${ACTION}" == "install" ]; then
|
|
|
- docker_build_builder
|
|
|
- if [ $? -ne 0 ]; then
|
|
|
- echo "...Aborting"
|
|
|
- destroy_temporary_credentials
|
|
|
- exit 1
|
|
|
- fi
|
|
|
-
|
|
|
- docker_build_psiphond_binary
|
|
|
- if [ $? -ne 0 ]; then
|
|
|
- echo "...Aborting"
|
|
|
- destroy_temporary_credentials
|
|
|
- exit 1
|
|
|
- fi
|
|
|
-
|
|
|
- docker_build_psiphond_container
|
|
|
- if [ $? -ne 0 ]; then
|
|
|
- echo "...Aborting"
|
|
|
- destroy_temporary_credentials
|
|
|
- exit 1
|
|
|
- fi
|
|
|
-
|
|
|
- save_image
|
|
|
- if [ $? -ne 0 ]; then
|
|
|
- echo "...Aborting"
|
|
|
- destroy_temporary_credentials
|
|
|
- exit 1
|
|
|
- fi
|
|
|
-
|
|
|
- put_and_load_image
|
|
|
- if [ $? -ne 0 ]; then
|
|
|
- echo "...Aborting"
|
|
|
- destroy_temporary_credentials
|
|
|
- exit 1
|
|
|
- fi
|
|
|
-
|
|
|
- put_systemd_dropin
|
|
|
- if [ $? -ne 0 ]; then
|
|
|
- echo "...Aborting"
|
|
|
- destroy_temporary_credentials
|
|
|
- exit 1
|
|
|
- fi
|
|
|
-
|
|
|
- reload_systemd
|
|
|
- if [ $? -ne 0 ]; then
|
|
|
- echo "...Aborting"
|
|
|
- destroy_temporary_credentials
|
|
|
- exit 1
|
|
|
- fi
|
|
|
-
|
|
|
- restart_psiphond
|
|
|
- if [ $? -ne 0 ]; then
|
|
|
- echo "...Aborting"
|
|
|
- destroy_temporary_credentials
|
|
|
- exit 1
|
|
|
- fi
|
|
|
+ install
|
|
|
+ if [ $? -ne 0 ]; then
|
|
|
+ echo "....Error during install, rolling back"
|
|
|
+ remove
|
|
|
+ if [ $? -ne 0 ]; then
|
|
|
+ echo "....Rollback failed"
|
|
|
+ fi
|
|
|
+ fi
|
|
|
elif [ "${ACTION}" == "remove" ]; then
|
|
|
- remove_systemd_dropin
|
|
|
- if [ $? -ne 0 ]; then
|
|
|
- echo "...Aborting"
|
|
|
- destroy_temporary_credentials
|
|
|
- exit 1
|
|
|
- fi
|
|
|
-
|
|
|
- reload_systemd
|
|
|
- if [ $? -ne 0 ]; then
|
|
|
- echo "...Aborting"
|
|
|
- destroy_temporary_credentials
|
|
|
- exit 1
|
|
|
- fi
|
|
|
-
|
|
|
- restart_psiphond
|
|
|
- if [ $? -ne 0 ]; then
|
|
|
- echo "...Aborting"
|
|
|
- destroy_temporary_credentials
|
|
|
- exit 1
|
|
|
- fi
|
|
|
-
|
|
|
- remove_image
|
|
|
- if [ $? -ne 0 ]; then
|
|
|
- echo "...Aborting"
|
|
|
- destroy_temporary_credentials
|
|
|
- exit 1
|
|
|
- fi
|
|
|
+ remove
|
|
|
+ if [ $? -ne 0 ]; then
|
|
|
+ echo "...Rollback failed"
|
|
|
+ fi
|
|
|
else
|
|
|
echo "Parameter validation passed, but action was not 'install' or 'remove', aborting"
|
|
|
exit 1
|