From 9466908c2277193fbf15f91d133af012cbf9d3a4 Mon Sep 17 00:00:00 2001 From: Georgios Kalpakas Date: Wed, 17 May 2017 17:09:53 +0300 Subject: [PATCH] build(aio): add script for updating the preview server --- aio/aio-builds-setup/docs/_TOC.md | 4 ++ .../docs/overview--scripts-and-commands.md | 3 + .../docs/vm-setup--update-docker-container.md | 52 ++++++++++++++ .../scripts/update-preview-server.sh | 69 +++++++++++++++++++ 4 files changed, 128 insertions(+) create mode 100644 aio/aio-builds-setup/docs/vm-setup--update-docker-container.md create mode 100755 aio/aio-builds-setup/scripts/update-preview-server.sh diff --git a/aio/aio-builds-setup/docs/_TOC.md b/aio/aio-builds-setup/docs/_TOC.md index 16aa208e19..97ec20a2b9 100644 --- a/aio/aio-builds-setup/docs/_TOC.md +++ b/aio/aio-builds-setup/docs/_TOC.md @@ -23,6 +23,10 @@ - [Start docker container](vm-setup--start-docker-container.md) +## Updating the docker container +- [Update docker container](vm-setup--update-docker-container.md) + + ## Miscellaneous - [Debug docker container](misc--debug-docker-container.md) - [Integrate with CI](misc--integrate-with-ci.md) diff --git a/aio/aio-builds-setup/docs/overview--scripts-and-commands.md b/aio/aio-builds-setup/docs/overview--scripts-and-commands.md index c29eee85ce..c0ad6b69d9 100644 --- a/aio/aio-builds-setup/docs/overview--scripts-and-commands.md +++ b/aio/aio-builds-setup/docs/overview--scripts-and-commands.md @@ -22,6 +22,9 @@ available: upload build artifacts. This is useful for CI integration. See [here](misc--integrate-with-ci.md) for more info. +- `update-preview-server.sh` + Can be used for updating the docker container (and image) based on the latest changes checked out + from a git repository. See [here](vm-setup--update-docker-container.md) for more info. ## Commands The following commands are available globally from inside the docker container. They are either used diff --git a/aio/aio-builds-setup/docs/vm-setup--update-docker-container.md b/aio/aio-builds-setup/docs/vm-setup--update-docker-container.md new file mode 100644 index 0000000000..47fd61ac6a --- /dev/null +++ b/aio/aio-builds-setup/docs/vm-setup--update-docker-container.md @@ -0,0 +1,52 @@ +# VM setup - Update docker container + + +## Overview +Assuming you have cloned the repository containing the preview server code (as described +[here](vm-setup--create-docker-image.md)), you can use the `update-preview-server.sh` script on the +VM host to update the preview server based on changes in the source code. + +The script will pull the latest changes from the origin's master branch and examine if there have +been any changes in files inside the preview server source code directory (see below). If there are, +it will create a new image and verify that is works as expected. Finally, it will stop and remove +the old docker container and image, create and new container based on the new image and start it. + +The script assumes that the preview server source code is in the repository's +`aio/aio-builds-setup/` directory and expects the following inputs: + +- **$1**: `HOST_REPO_DIR` +- **$2**: `HOST_LOCALCERTS_DIR` +- **$3**: `HOST_SECRETS_DIR` +- **$4**: `HOST_BUILDS_DIR` +- **$5**: `HOST_LOGS_DIR` + +See [here](vm-setup--create-host-dirs-and-files.md) for more info on what each input directory is +used for. + +**Note 1:** The script has to execute docker commands with `sudo`. + +**Note 2:** Make sure the user that executes the script has access to update the repository + + +## Run the script manually +You may choose to manually run the script, when necessary. Example: + +``` +update-preview-server.sh \ + /path/to/repo \ + /path/to/localcerts \ + /path/to/secrets \ + /path/to/builds \ + /path/to/logs +``` + + +## Run the script automatically +You may choose to automatically trigger the script, e.g. using a cronjob. For example, the following +cronjob entry would run the script every hour and update the preview server (assuming the user has +the necessary permissions): + +``` +# Periodically check for changes and update the preview server (if necessary) +*/30 * * * * /path/to/update-preview-server.sh /path/to/repo /path/to/localcerts /path/to/secrets /path/to/builds /path/to/logs +``` diff --git a/aio/aio-builds-setup/scripts/update-preview-server.sh b/aio/aio-builds-setup/scripts/update-preview-server.sh new file mode 100755 index 0000000000..e2fe89cefb --- /dev/null +++ b/aio/aio-builds-setup/scripts/update-preview-server.sh @@ -0,0 +1,69 @@ +#!/usr/bin/env bash + +set -eux -o pipefail +exec 3>&1 + +# Input +readonly HOST_REPO_DIR=$1 +readonly HOST_LOCALCERTS_DIR=$2 +readonly HOST_SECRETS_DIR=$3 +readonly HOST_BUILDS_DIR=$4 +readonly HOST_LOGS_DIR=$5 + +# Constants +readonly PROVISIONAL_IMAGE_NAME=aio-builds:provisional +readonly LATEST_IMAGE_NAME=aio-builds:latest +readonly CONTAINER_NAME=aio + +# Run +( + echo "[`date`] - Updating the preview server..." + + cd "$HOST_REPO_DIR" + + readonly lastDeployedCommit=$(git rev-parse HEAD) + echo "Currently at commit $lastDeployedCommit." + + # Pull latest master from origin. + git pull origin master + + # Do not update the server unless files inside `aio-builds-setup/` have changed. + readonly relevantChangedFilesCount=$(git diff --name-only $lastDeployedCommit...HEAD | grep -P "^aio/aio-builds-setup/" | wc -l) + if [[ $relevantChangedFilesCount -eq 0 ]]; then + echo "Skipping update because no relevant files have been touched." + exit 0 + fi + + # Create and verify a new docker image. + sudo docker rmi "$PROVISIONAL_IMAGE_NAME" || true + aio/aio-builds-setup/scripts/create-image.sh "$PROVISIONAL_IMAGE_NAME" + readonly imageVerified=$(sudo docker run --dns 127.0.0.1 --rm --volume $HOST_SECRETS_DIR:/aio-secrets:ro "$PROVISIONAL_IMAGE_NAME" /bin/bash -c "aio-init && aio-health-check && aio-verify-setup" > /dev/fd/3 && echo "true" || echo "false") + + if [[ "$imageVerified" != "true" ]]; then + echo "Failed to verify new docker image. Aborting update!" + exit 1 + fi + + # Remove the old container and replace the docker image. + sudo docker stop "$CONTAINER_NAME" || true + sudo docker rm "$CONTAINER_NAME" || true + sudo docker rmi "$LATEST_IMAGE_NAME" || true + sudo docker tag "$PROVISIONAL_IMAGE_NAME" "$LATEST_IMAGE_NAME" + sudo docker rmi "$PROVISIONAL_IMAGE_NAME" + + # Create and start a docker container based on the new image. + sudo docker run \ + --detach \ + --dns 127.0.0.1 \ + --name "$CONTAINER_NAME" \ + --publish 80:80 \ + --publish 443:443 \ + --restart unless-stopped \ + --volume $HOST_LOCALCERTS_DIR:/etc/ssl/localcerts:ro \ + --volume $HOST_SECRETS_DIR:/aio-secrets:ro \ + --volume $HOST_BUILDS_DIR:/var/www/aio-builds \ + --volume $HOST_LOGS_DIR:/var/log/aio \ + "$LATEST_IMAGE_NAME" + + echo "The new docker image has been successfully deployed." +)