From 8d2a3fd616842706aae8abcc7f2bd24ed1b5d14e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Filip=20Str=C3=B6mb=C3=A4ck?= <filip.stromback@liu.se> Date: Wed, 30 Sep 2020 10:17:57 +0200 Subject: [PATCH] Added a script for keeping a Git repo updated. It is not yet tested in contexts where it needs to be executed as another user. --- files/update_repo.sh | 97 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100755 files/update_repo.sh diff --git a/files/update_repo.sh b/files/update_repo.sh new file mode 100755 index 0000000..1742fb7 --- /dev/null +++ b/files/update_repo.sh @@ -0,0 +1,97 @@ +#!/bin/bash + +# Keep a Git repository updated. Optionally execute a command whenever it has been updated in order +# to trigger further processing of some kind (e.g. restarting services). + +# The command is called as follows: +# update_repo.sh <destination path> <source repo> <source branch> + +# If REPO_ON_UPDATE is set, then that command will be executed whenever the repo is created and/or +# updated to a new revision. This can be used to trigger further processing of some sort, such as +# compiling the contained source and/or restarting system services as appropriate. + +# This script is designed to be executed as a privillegied user so that the update command could do +# privillegied operations. Thus, the git commands will be isolated to a user as described by +# REPO_USER and REPO_GROUP, if they are is set. It is, of course, also possible to just run this +# script as a regular user without setting REPO_USER. + + +# Function that keeps the repo updated. Returns 0 if nothing was done, 100 if the repo was updated, +# and something else on some kind of error. This function will be executed as the user indicated in +# the environment variables. +function update_repo() { + if [[ ! -d "$repo_path" ]] + then + # Does not exist. We need to checkout the repository. + git clone --single-branch --branch "$repo_branch" "$repo_source" "$repo_path" || exit 1 + exit 100 + else + # It does exist. Make sure it is updated. + cd "$repo_path" + old_sha=$(git rev-parse HEAD) + git fetch -f "$repo_source" "$repo_branch":remotes/origin/"$repo_branch" || exit 1 + new_sha=$(git rev-parse remotes/origin/"$repo_branch") + if [[ "$old_sha" == "$new_sha" ]] + then + # They are the same, we don't need to do anything. + exit 0 + else + # They differ. Check out the new revision. + git checkout -f "$new_sha" || exit 1 + git branch -f "$repo_branch" "$new_sha" || exit 1 + # This is not strictly necessary, but it makes it look like we have the correct branch + # checked out. Good if someone inspects the repo at a later time. + git checkout -f "$repo_branch" || exit 1 + exit 100 + fi + fi +} + +# Check for enough parameters. +if [[ "$#" < 3 ]] +then + echo "Not enough parameters." + echo "Usage: update_repo.sh <path> <source> <branch>" + exit 2 +fi + +# Setup variables for calling "update_repo"... +repo_path="$1" +repo_source="$2" +repo_branch="$3" + +export repo_path repo_source repo_branch +export -f update_repo + +if [[ -z "$REPO_USER" ]] +then + # Just run it in a subshell + bash -c update_repo +else + # Perhaps group was not supplied. + if [[ -z "$REPO_GROUP" ]] + then + REPO_GROUP="$REPO_USER" + fi + sudo --preserve-env=repo_path,repo_source,repo_branch,update_repo --set-home --user="$REPO_USER" --group="$REPO_GROUP" -- bash -c update_repo +fi +# Note: We cannot put any commands between the if-statement and here. We need the result code from +# invoking bash, which is the last command in both the if- and else- branches. +result="$?" +if [[ $result == 0 ]] +then + # All is well, nothing needed to be done. + exit 0 +elif [[ $result == 100 ]] +then + # All is well, but we need to tell the environment that we updated the repo. + if [[ ! -z "$REPO_ON_UPDATE" ]] + then + # Run it if it is there. + $REPO_ON_UPDATE + fi + exit 0 +else + # Something went awry, forward the exit code. + exit $result +fi -- GitLab