From de44133ec1ca5dda0f020678686a3327bf9d7468 Mon Sep 17 00:00:00 2001 From: Julien Acroute Date: Wed, 21 Mar 2018 16:07:38 +0100 Subject: [PATCH 1/3] Switch to debian stretch --- Dockerfile | 2 +- Makefile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 75817fb..0832353 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM debian:jessie +FROM debian:stretch MAINTAINER fvanderbiest "francois.vanderbiest@gmail.com" diff --git a/Makefile b/Makefile index 90187bd..da974c6 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ docker-build: - docker pull debian:jessie + docker pull debian:stretch docker build -t fvanderbiest/volume-git-backup:`date +%Y%m%d%H%M%S` . docker build -t fvanderbiest/volume-git-backup:latest . From bf0da3353af39c393d2cb7d9ecde28db44663438 Mon Sep 17 00:00:00 2001 From: Julien Acroute Date: Wed, 21 Mar 2018 16:11:26 +0100 Subject: [PATCH 2/3] Use ssh key to access remote repo Clone remote repo at startup or update (git pull) existing one Make remote branch configurable: REMOTE_BRANCH Add FORCE_CLONE option to remove existing file in volume --- Dockerfile | 2 ++ README.md | 25 ++++++++++++---- scripts/entrypoint.sh | 69 +++++++++++++++++++++++++++++++++---------- scripts/run.sh | 4 +-- 4 files changed, 78 insertions(+), 22 deletions(-) diff --git a/Dockerfile b/Dockerfile index 0832353..dbe1ce0 100644 --- a/Dockerfile +++ b/Dockerfile @@ -12,5 +12,7 @@ RUN chmod +x /entrypoint.sh VOLUME [ "/var/local/data" ] WORKDIR /var/local/data +ENV REMOTE_BRANCH master + ENTRYPOINT [ "/entrypoint.sh" ] CMD ["bash", "-l", "/run.sh"] diff --git a/README.md b/README.md index ee98afc..7dd80b7 100644 --- a/README.md +++ b/README.md @@ -3,8 +3,8 @@ [![License](https://img.shields.io/dub/l/vibe-d.svg)](LICENSE) [![Pulls](https://img.shields.io/docker/pulls/fvanderbiest/volume-git-backup.svg)](https://hub.docker.com/r/fvanderbiest/volume-git-backup/) -This repository is the source of the [fvanderbiest/volume-git-backup](https://hub.docker.com/r/fvanderbiest/volume-git-backup/) image on Docker Hub. -The image provides an easy way to `git commit` a docker volume every time a file is updated. +This repository is the source of the [fvanderbiest/volume-git-backup](https://hub.docker.com/r/fvanderbiest/volume-git-backup/) image on Docker Hub. +The image provides an easy way to `git commit` a docker volume every time a file is updated. Feel free to use it if it suits your needs. Contributions welcomed. This image expects to find the volume mounted in `rw` mode on `/var/local/data`. @@ -14,6 +14,12 @@ Internally, we're using `inotifywait` to watch the file. When change is detected, the script performs the commit and optionally pushes to a remote repository. +At startup, if a remote repository is configured a clone of this repository is +done in the volume. If volume is not empty, you will need to set FORCE_CLONE var +to 'yes' to force a cleanup of the volume. If the volume is already verionned +(contains a `.git` folder) then git remote is updated and local repository is updated +to the last commit of configured branch. + Example usage: ```yaml sync: @@ -29,14 +35,23 @@ sync: Required environment: * `WATCH_FILE`: file to watch (path relative to volume root) - * `GIT_COMMIT_MESSAGE`: string or expression evaluated in the volume to provide a commit message + * `GIT_COMMIT_MESSAGE`: string or expression evaluated in the volume to provide a commit message * `GIT_USERNAME`: git username for commit * `GIT_EMAIL`: git email for commit To push to a repository, these additional variables are required: * `REMOTE_NAME`: name of the git remote, eg `origin` * `REMOTE_URL`: git repository URL, eg `https://github.com/fvanderbiest/playground.git` - * `TOKEN`: password or OAuth token (eg: [GitHub token](https://github.com/settings/tokens)) + +Optional environment: + * `REMOTE_BRANCH`: Remote branch to use + * `FORCE_CLONE`: Delete volume content before cloning remote repository + +To use SSH authentication to access remote repository, one of following +variables must be set: + * `GIT_RSA_DEPLOY_KEY`: Private RSA key to use (eg: [GitHub deploy keys](https://developer.github.com/guides/managing-deploy-keys/)) + * `GIT_RSA_DEPLOY_KEY_FILE`: Path to a file containning the private RSA key to use + **WARNING**: the `git push` command performs a **forced update** to the `master` branch, which might result in **data loss** ! @@ -46,7 +61,7 @@ Optional: # testing -In the `tests` folder there's a [docker-compose](tests/docker-compose.yml) file to easily create a testing environment. +In the `tests` folder there's a [docker-compose](tests/docker-compose.yml) file to easily create a testing environment. The Dockerfile in the `tests/geoserver_mock` directory creates an image whose purpose is to periodically update the contents of a docker volume. It kind of mimics what [GeoServer](http://geoserver.org/) does to its config directory and is a lightweight alternative. diff --git a/scripts/entrypoint.sh b/scripts/entrypoint.sh index 49889fb..37bbd6c 100644 --- a/scripts/entrypoint.sh +++ b/scripts/entrypoint.sh @@ -1,27 +1,66 @@ #!/bin/bash -# test if "git init" has already been performed -# if not, do it now: -if [ ! -d .git ]; then - git init -fi - # set name and email to use for commits made by this container git config --global user.email "$GIT_EMAIL" git config --global user.name "$GIT_USERNAME" -if [ $REMOTE_NAME ] && [ $REMOTE_URL ] && [ $TOKEN ]; then - git config --global credential.helper store +# configure access to remote git repo if defined +mkdir ~/.ssh +if [ -n "$GIT_RSA_DEPLOY_KEY" ]; then + echo "Installing rsa key from var" + echo "$GIT_RSA_DEPLOY_KEY" > ~/.ssh/id_rsa +fi +if [ -n "$GIT_RSA_DEPLOY_KEY_FILE" ]; then + echo "Installing rsa key from file" + cp $GIT_RSA_DEPLOY_KEY_FILE ~/.ssh/id_rsa +fi +chmod -R go-rx ~/.ssh + +# Init ssh connection to git repo +if [ -n "$REMOTE_NAME" ] && [ -n "$REMOTE_URL" ]; then + git_hostname=`echo $REMOTE_URL | sed -e 's#.*\@\(.*\):.*#\1#'` + ssh-keyscan -H $git_hostname >> ~/.ssh/known_hosts +fi + +# test if local git repo already exists, if not clone or init +if [ ! -d .git ]; then + + # clone remote repo if defined + if [ -n "$REMOTE_NAME" ] && [ -n "$REMOTE_URL" ]; then + + # check if there is something in directory + files_count=`ls -a | wc -l` + if [ $files_count -gt 2 ]; then + if [ -n "$FORCE_CLONE" ] && [ $FORCE_CLONE = "yes" ]; then + rm -fr ./* + rm -fr ./.* + else + echo "Directory not empty and FORCE_CLONE not set so stopping" + exit 1 + fi + fi - # extract machine name from $REMOTE_URL - MACHINE=$(echo $REMOTE_URL | sed -e 's#.*://\([^/]*\)/.*#\1#') + echo "Cloning from $REMOTE_URL" + git clone -b $REMOTE_BRANCH $REMOTE_URL . + + else + echo "No remote configured, just init" + git init + fi + +fi - # tell git which credentials to use for commit - echo "https://$GIT_USERNAME:$TOKEN@$MACHINE" > /root/.git-credentials +# Fetch last commits of remote repo if defined +if [ -n "$REMOTE_NAME" ] && [ -n "$REMOTE_URL" ]; then + # set new url for remote + echo "Setup remote $REMOTE_NAME to $REMOTE_URL" + git remote rm $REMOTE_NAME &> /dev/null + git remote add $REMOTE_NAME $REMOTE_URL - # set new url for remote - git remote rm $REMOTE_NAME &> /dev/null - git remote add $REMOTE_NAME $REMOTE_URL + echo "Fetch remote repo" + git fetch $REMOTE_NAME + echo "Reset to upstream state" + git reset --hard $REMOTE_NAME/$REMOTE_BRANCH fi # execute CMD diff --git a/scripts/run.sh b/scripts/run.sh index eb69260..f4301c6 100644 --- a/scripts/run.sh +++ b/scripts/run.sh @@ -28,8 +28,8 @@ do msg=`eval $GIT_COMMIT_MESSAGE` git commit -m "${msg:-"no commit message"}" - if [ $REMOTE_NAME ] && [ $REMOTE_URL ] && [ $TOKEN ]; then + if [ $REMOTE_NAME ] && [ $REMOTE_URL ]; then # push to repository in the background - git push --force $REMOTE_NAME master & + git push --force $REMOTE_NAME $REMOTE_BRANCH & fi done From 8d572b4d7ee3278734ad41239b96d3700ce5553d Mon Sep 17 00:00:00 2001 From: Julien Acroute Date: Mon, 26 Mar 2018 17:55:50 +0200 Subject: [PATCH 3/3] Fix based on fvanderbiest comments * Add git clean * Remove --force on git push * Fix typo in README --- README.md | 4 ++-- scripts/entrypoint.sh | 1 + scripts/run.sh | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 7dd80b7..0c41ae9 100644 --- a/README.md +++ b/README.md @@ -44,13 +44,13 @@ To push to a repository, these additional variables are required: * `REMOTE_URL`: git repository URL, eg `https://github.com/fvanderbiest/playground.git` Optional environment: - * `REMOTE_BRANCH`: Remote branch to use + * `REMOTE_BRANCH`: Remote branch to use. Defaults to master. * `FORCE_CLONE`: Delete volume content before cloning remote repository To use SSH authentication to access remote repository, one of following variables must be set: * `GIT_RSA_DEPLOY_KEY`: Private RSA key to use (eg: [GitHub deploy keys](https://developer.github.com/guides/managing-deploy-keys/)) - * `GIT_RSA_DEPLOY_KEY_FILE`: Path to a file containning the private RSA key to use + * `GIT_RSA_DEPLOY_KEY_FILE`: Path to a file containing the private RSA key to use **WARNING**: the `git push` command performs a **forced update** to the `master` branch, which might result in **data loss** ! diff --git a/scripts/entrypoint.sh b/scripts/entrypoint.sh index 37bbd6c..d2c49b2 100644 --- a/scripts/entrypoint.sh +++ b/scripts/entrypoint.sh @@ -61,6 +61,7 @@ if [ -n "$REMOTE_NAME" ] && [ -n "$REMOTE_URL" ]; then git fetch $REMOTE_NAME echo "Reset to upstream state" git reset --hard $REMOTE_NAME/$REMOTE_BRANCH + git clean -xdf fi # execute CMD diff --git a/scripts/run.sh b/scripts/run.sh index f4301c6..a664ac6 100644 --- a/scripts/run.sh +++ b/scripts/run.sh @@ -30,6 +30,6 @@ do if [ $REMOTE_NAME ] && [ $REMOTE_URL ]; then # push to repository in the background - git push --force $REMOTE_NAME $REMOTE_BRANCH & + git push $REMOTE_NAME $REMOTE_BRANCH & fi done