From b76c9a55c2f602a4240b44d05ec5c5f19aaf80bf Mon Sep 17 00:00:00 2001 From: Gardouille Date: Wed, 21 Aug 2024 19:37:11 +0200 Subject: [PATCH] =?UTF-8?q?Re-add=20docker=20scripts=E2=80=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docker/check.rocketchat.update | 75 +++++++++++++++++++++ docker/check.sharelatex.update | 65 ++++++++++++++++++ docker/container.backup | 118 +++++++++++++++++++++++++++++++++ docker/container.backup.all | 90 +++++++++++++++++++++++++ docker/imagetags | 30 +++++++++ 5 files changed, 378 insertions(+) create mode 100755 docker/check.rocketchat.update create mode 100755 docker/check.sharelatex.update create mode 100755 docker/container.backup create mode 100755 docker/container.backup.all create mode 100755 docker/imagetags diff --git a/docker/check.rocketchat.update b/docker/check.rocketchat.update new file mode 100755 index 0000000..c490162 --- /dev/null +++ b/docker/check.rocketchat.update @@ -0,0 +1,75 @@ +#!/bin/sh +# Purpose {{{ +## Create a temp file (to monitor) if an upgrade is available for rocket.chat +## image on the Docker Hub. +## Download the new version of the image. +## How-to use {{{ +### 1. Needs imagetags script, in the same directory +### cf. https://git.ipr.univ-rennes1.fr/cellinfo/scripts/src/master/docker/imagetags +# wget https://git.ipr.univ-rennes1.fr/cellinfo/scripts/raw/master/docker/imagetags +### 2. Ensure to run with a user member of the docker group. +### 3. Create a cron job, eg. +#00 20 * * * root /opt/repos/ipr.scripts/docker/check.rocketchat.update +### 4. Monitor the temp file. +# Or enable MAILTO in cronjob and print a message in the script. +# Or send a mail. +# … +## }}} +# }}} + +# Vars {{{ +DEBUG=1 + +script_wd=$(dirname "${0}") + +rkt_repo_name="rocketchat" +rkt_image_name="rocket.chat" + +rkt_current_version=$(docker container ls | grep -- "${rkt_repo_name}/${rkt_image_name}" | sed -- "s/.*${rkt_repo_name}\/${rkt_image_name}:\([^ ]*\) .*/\1/") +rkt_current_imageid=$(docker image inspect "${rkt_repo_name}/${rkt_image_name}:${rkt_current_version}" | grep -m 1 -- "Image.*sha256" | sed "s/.*Image.*sha256:\(.*\)\",/\1/") + +rkt_grep_pattern="[[:digit:]]\\.\\+[[:digit:]]*\\.\\?[[:digit:]]*$" +rkt_new_version=$("${script_wd}"/imagetags "${rkt_repo_name}/${rkt_image_name}" "${rkt_grep_pattern}" | tail -n1) +rkt_new_imageid=$(docker image inspect "${rkt_repo_name}/${rkt_image_name}:${rkt_new_version}" | grep -m 1 -- "Image.*sha256" | sed "s/.*Image.*sha256:\(.*\)\",/\1/") + +rkt_new_version_file="/tmp/.docker.rocket.chat.upgrade" +# }}} + +# Check if a container already runs with the wanted image {{{ +if [ ! $(docker container ls | grep -q -- "${rkt_repo_name}${rkt_image_name}") ]; then + [ "${DEBUG}" -eq "0" ] && printf '\e[1;35m%-6s\e[m\n' "DEBUG : Test ${rkt_image_name} — Current version is ${rkt_current_version}." +else + [ "${DEBUG}" -eq "0" ] && printf '\e[1;35m%-6s\e[m\n' "DEBUG : Test ${rkt_image_name} — No container runs with ${rkt_image_name} image on this host." + rm -f -- "${rkt_new_version_file}" + exit 1 +fi +# }}} + +# Check if the current version is the last one {{{ +if [ "${rkt_current_version}" != "${rkt_new_version}" ]; then + [ "${DEBUG}" -eq "0" ] && printf '\e[1;35m%-6s\e[m\n' "DEBUG : Test version — Current version (${rkt_current_version}) and new one (${rkt_new_version}) of ${rkt_image_name} seems to be different." + # Ensure to download this new version of the image + [ "${DEBUG}" -eq "0" ] && printf '\e[1;35m%-6s\e[m\n' "DEBUG : Test version — Download ${rkt_repo_name}/${rkt_image_name}:${rkt_new_version} image to compare ImageID." + docker pull "${rkt_repo_name}/${rkt_image_name}:${rkt_new_version}" > /dev/null + + ## Compare the ImageID of current and new version {{{ + [ "${DEBUG}" -eq "0" ] && printf '\e[1;35m%-6s\e[m\n' "DEBUG : ImageID — ID of the current version is ${rkt_current_imageid}." + [ "${DEBUG}" -eq "0" ] && printf '\e[1;35m%-6s\e[m\n' "DEBUG : ImageID — ID of the new version is ${rkt_new_imageid}." + if [ "${rkt_current_imageid}" != "${rkt_new_imageid}" ]; then + [ "${DEBUG}" -eq "0" ] && printf '\e[1;35m%-6s\e[m\n' "DEBUG : ImageID — An upgrade is available for ${rkt_image_name}: ${rkt_new_version}." + ## Create a temp file to monitor + touch -- "${rkt_new_version_file}" + printf '\e[1;35m%-6s\e[m\n' "An upgrade is available for ${rkt_image_name}: ${rkt_new_version}." >> "${rkt_new_version_file}" + else + [ "${DEBUG}" -eq "0" ] && printf '\e[1;35m%-6s\e[m\n' "DEBUG : ImageID — The current version is up-to-date." + rm -f -- "${rkt_new_version_file}" + fi + ## }}} + +else + [ "${DEBUG}" -eq "0" ] && printf '\e[1;35m%-6s\e[m\n' "DEBUG : Test version — The current version is up-to-date." + rm -f -- "${rkt_new_version_file}" +fi +# }}} + +exit 0 diff --git a/docker/check.sharelatex.update b/docker/check.sharelatex.update new file mode 100755 index 0000000..96b2700 --- /dev/null +++ b/docker/check.sharelatex.update @@ -0,0 +1,65 @@ +#!/bin/sh +# Purpose {{{ +## Create a temp file (to monitor) if an upgrade is available for Sharelatex +## image on the Docker Hub. +## How-to use {{{ +### 1. Needs imagetags script, in the same directory +### cf. https://git.ipr.univ-rennes1.fr/cellinfo/scripts/src/master/docker/imagetags +# wget https://git.ipr.univ-rennes1.fr/cellinfo/scripts/raw/master/docker/imagetags +### 2. Ensure to run with a user member of the docker group. +### 3. Create a cron job, eg. +#00 20 * * * root /opt/repos/ipr.scripts/docker/check.sharelatex.update +### 4. Monitor the temp file. +# Or enable MAILTO in cronjob and print a message in the script. +# Or send a mail. +# … +## }}} +# }}} + +# Vars {{{ +DEBUG=1 + +script_wd=$(dirname "${0}") + +sharelatex_repo_name="sharelatex" +sharelatex_image_name="sharelatex" + +#sharelatex_current_version=$(docker container ls | grep -- "${sharelatex_repo_name}/${sharelatex_image_name}" | sed -- "s/.*${sharelatex_repo_name}\/${sharelatex_image_name}:\([^ ]*\) .*/\1/") +sharelatex_current_version="v1.2.1" + +sharelatex_grep_pattern="v[[:digit:]]\\.\\+[[:digit:]]*\\.\\?[[:digit:]]*$" +sharelatex_new_version=$("${script_wd}"/imagetags "${sharelatex_repo_name}/${sharelatex_image_name}" "${sharelatex_grep_pattern}" | tail -n1) + +sharelatex_new_version_file="/tmp/.docker.sharelatex.upgrade" +# }}} + +# Check if a container already runs with the wanted image {{{ +#if [ ! $(docker container ls | grep -q -- "${sharelatex_repo_name}${sharelatex_image_name}") ]; then + #[ "${DEBUG}" -eq "0" ] && printf '\e[1;35m%-6s\e[m\n' "DEBUG : Test ${sharelatex_image_name} — Current version is ${sharelatex_current_version}." +#else + #[ "${DEBUG}" -eq "0" ] && printf '\e[1;35m%-6s\e[m\n' "DEBUG : Test ${sharelatex_image_name} — No container runs with ${sharelatex_image_name} image on this host." + #rm -f -- "${sharelatex_new_version_file}" + #exit 1 +#fi + +## I am currently using a homemade version of Sharelatex in order to : +## * use the last version of LaTeX/tlmgr env (2018) +## * add severals packages used for Physics papers +## For more informations, see : +## https://github.com/ipr-cnrs/sharelatex-docker-image + +# }}} + +# Check if the current version is the last one {{{ +if [ "${sharelatex_current_version}" != "${sharelatex_new_version}" ]; then + [ "${DEBUG}" -eq "0" ] && printf '\e[1;35m%-6s\e[m\n' "DEBUG : Test version — An upgrade is available for ${sharelatex_image_name}: ${sharelatex_new_version}." + # Create a temp file to monitor + touch -- "${sharelatex_new_version_file}" + printf '\e[1;35m%-6s\e[m\n' "An upgrade is available for ${sharelatex_image_name}: ${sharelatex_new_version}." >> "${sharelatex_new_version_file}" +else + [ "${DEBUG}" -eq "0" ] && printf '\e[1;35m%-6s\e[m\n' "DEBUG : Test version — The current version is up-to-date." + rm -f -- "${sharelatex_new_version_file}" +fi +# }}} + +exit 0 diff --git a/docker/container.backup b/docker/container.backup new file mode 100755 index 0000000..0f4efa2 --- /dev/null +++ b/docker/container.backup @@ -0,0 +1,118 @@ +#!/bin/sh + +# Purpose {{{ +## Backup data of a Docker container. +## To do that, the script will : +## Try to stop the corresponding systemd unit (or docker if no related service is found) +## Make a archive of the container's data to a backup path +## Restart the container service (or docker.service) +## Clean old backup +# }}} +# How-to use {{{ +## First argument should be the absolut path to the container's data. +## The data directory and the container should have the same name. +# }}} + +# Vars {{{ +DEBUG=1 + +## Nomber of backup to keep +keep_backup="3" + +## Manage arguments {{{ +## Expect at least 1 argument and 2 maximum +case $# in + 1 ) + ## Absolut path to the container data + ct_data_path="${1}" + ## Absolut path to store the archives. + ## A sub-directory will be created for the container + docker_backup_path="/mnt/backup/docker" + ;; + 2 ) + ct_data_path="${1}" + docker_backup_path="${2}" + ;; + * ) + cat << HELP + +container.backup -- +Backup data of a given Docker container. + +EXAMPLE : + - Backup data of FIRST_CT container require the absolut path to data + container.backup /srv/docker/FIRST_CT + - Select the directory to store the backup of hello_world container + container.backup /srv/docker/hello_world /media/usb/docker.backup + +HELP + + exit 1 + ;; +esac + +ct_name=$(basename -- "${ct_data_path}") +docker_data_path=$(dirname -- "${ct_data_path}") +ct_backup_path="${docker_backup_path}/${ct_name}" +## }}} +# }}} + +# Tests {{{ + +## Ensure container data directory exists {{{ +if [ ! -d "${ct_data_path}" ]; then + printf '\e[0;31m%-6s\e[m\n' "Docker data directory doesn't seems available : ${ct_data_path} ." + exit 1 +else + [ "${DEBUG}" -eq "0" ] && printf '\e[1;35m%-6s\e[m\n' "DEBUG : Test arg — Path to Docker data : ${ct_data_path} ." + [ "${DEBUG}" -eq "0" ] && printf '\e[1;35m%-6s\e[m\n' "DEBUG : Test arg — Container name to backup : ${ct_name} ." +fi +## }}} +## Ensure backup directory exists {{{ +if [ ! -d "${docker_backup_path}" ]; then + printf '\e[0;31m%-6s\e[m\n' "Backup directory doesn't seems available : ${docker_backup_path} ." + exit 1 +else + [ "${DEBUG}" -eq "0" ] && printf '\e[1;35m%-6s\e[m\n' "DEBUG : Test arg — Path to store the backup : ${docker_backup_path} ." +fi +## }}} +# }}} + +# Get container service name {{{ +ct_service_name=$(find /etc/systemd -type f -iname "*${ct_name}*.service" -printf "%f\n") + +## If no specific systemd service exists, the docker.service will be used +if [ "${ct_service_name}" = "" ]; then + ct_service_name="docker.service" + [ "${DEBUG}" -eq "0" ] && printf '\e[1;35m%-6s\e[m\n' "DEBUG : Service name — No specific service found for ${ct_name} container, the ${ct_service_name} will be stopped." +else + [ "${DEBUG}" -eq "0" ] && printf '\e[1;35m%-6s\e[m\n' "DEBUG : Service name — Service name of ${ct_name} container to stop : ${ct_service_name} ." +fi +# }}} +# Stop the container service {{{ +systemctl stop "${ct_service_name}" +[ "${DEBUG}" -eq "0" ] && printf '\e[1;35m%-6s\e[m\n' "DEBUG : Service management — Service ${ct_service_name} was stopped." +# }}} +# Backup container data {{{ +## Create the directory to store archive if doesn't already exist +if [ ! -d "${ct_backup_path}" ]; then + mkdir -p -- "${ct_backup_path}" + [ "${DEBUG}" -eq "0" ] && printf '\e[1;35m%-6s\e[m\n' "DEBUG : Backup data — ${ct_backup_path} was created." +fi + +## Backup container data +tar czf "${ct_backup_path}/${ct_name}-backup.$(date '+%Y%m%d-%H%M').tar.gz" --directory "${docker_data_path}" "${ct_name}" +[ "${DEBUG}" -eq "0" ] && printf '\e[1;35m%-6s\e[m\n' "DEBUG : Backup data — Data of ${ct_name} container were successfully backuped ${ct_backup_path}/${ct_name}-backup.$(date '+%Y%m%d-%H%M').tar.gz" +# }}} +# Restart the container service {{{ +systemctl start "${ct_service_name}" +[ "${DEBUG}" -eq "0" ] && printf '\e[1;35m%-6s\e[m\n' "DEBUG : Service management — Service ${ct_service_name} was started." +# }}} +# Remove old backups {{{ +cd -- "${ct_backup_path}" || exit 1 +[ "${DEBUG}" -eq "0" ] && printf '\e[1;35m%-6s\e[m\n' "DEBUG : Cleaning — Keep only the ${keep_backup} newest backups." +find . -type f | sort | head -n -"${keep_backup}" | xargs -d '\n' rm -f -- +cd -- - > /dev/null || exit 1 +# }}} + +exit 0 diff --git a/docker/container.backup.all b/docker/container.backup.all new file mode 100755 index 0000000..175aa49 --- /dev/null +++ b/docker/container.backup.all @@ -0,0 +1,90 @@ +#!/bin/sh + +# Purpose {{{ +## Ask to backup data of all Docker containers with a second script. +# }}} +# How-to use {{{ +## 1. Needs container.backup script, in the same directory +## cf. https://git.ipr.univ-rennes1.fr/cellinfo/scripts/src/master/docker/container.backup +# wget https://git.ipr.univ-rennes1.fr/cellinfo/scripts/src/master/docker/container.backup +## First argument should be the path to store the backup. +## Second argument can be the absolut path to the Docker directory for containers. +# }}} + +# Vars {{{ +DEBUG=1 + +script_wd=$(dirname "${0}") + +## Manage arguments {{{ +## Expect at least 1 argument and 2 maximum +case $# in + 1 ) + ## Absolut path to store the archives. + ## A sub-directory will be created for each container + docker_backup_path="${1}" + ## Absolut path to Docker containers + docker_ct_path="/srv/dock" + ;; + 2 ) + docker_backup_path="${1}" + docker_ct_path="${2}" + ;; + * ) + cat << HELP + +container.backup.all -- +Backup all data of all Docker's containers. + +EXAMPLE : + - Backup all data of default Docker path (/srv/dock) to /media/usb/docker.backup + container.backup.all /media/usb/docker.backup + - Choose a specific path where containers are stored + container.backup.all /media/usb/docker.backup /my/path/to/docker + +HELP + + exit 1 + ;; +esac +## }}} + +temp_ct_list_file="/tmp/container.list" + +# }}} + +# Tests {{{ + +## Ensure backup directory exists {{{ +if [ ! -d "${docker_backup_path}" ]; then + printf '\e[0;31m%-6s\e[m\n' "Backup directory doesn't seems available : ${docker_backup_path} ." + exit 1 +else + [ "${DEBUG}" -eq "0" ] && printf '\e[1;35m%-6s\e[m\n' "DEBUG : Test arg — Path to store the backup : ${docker_backup_path} ." +fi +## }}} +## Ensure Docker directory exists {{{ +if [ ! -d "${docker_ct_path}" ]; then + printf '\e[0;31m%-6s\e[m\n' "Docker data directory doesn't seems available : ${docker_ct_path} ." + exit 1 +else + [ "${DEBUG}" -eq "0" ] && printf '\e[1;35m%-6s\e[m\n' "DEBUG : Test arg — Path to Docker data : ${docker_ct_path} ." +fi +## }}} +# }}} + +# Get the list of containers name to backup +find "${docker_ct_path}" -mindepth 1 -maxdepth 1 -type d > "${temp_ct_list_file}" + +# For each container in the list +while IFS= read -r ct_path +do + [ "${DEBUG}" -eq "0" ] && printf '\e[1;35m%-6s\e[m\n' "DEBUG : While loop — The data of ${ct_path} container will be backup." + "${script_wd}/container.backup" "${ct_path}" "${docker_backup_path}" +done < "${temp_ct_list_file}" + +# Clean temp file +rm -f -- "${temp_ct_list_file}" +# }}} + +exit 0 diff --git a/docker/imagetags b/docker/imagetags new file mode 100755 index 0000000..1a82719 --- /dev/null +++ b/docker/imagetags @@ -0,0 +1,30 @@ +#!/bin/sh + +if [ $# -lt 1 ] +then +cat << HELP + +imagetags -- list all tags for a Docker image on a remote registry. + +EXAMPLE: + - list all tags for ubuntu: + imagetags ubuntu + + - list all php tags containing apache: + imagetags php apache + + - list all tags of RocketChat : + imagetags "rocketchat/rocket.chat" + +HELP +fi + +image="$1" +tags=$(wget -q https://registry.hub.docker.com/v1/repositories/"${image}"/tags -O - | sed -e 's/[][]//g' -e 's/"//g' -e 's/ //g' | tr '}' '\n' | awk -F: '{print $3}' | sort --version-sort) + +if [ -n "$2" ] +then + tags=$(echo "${tags}" | grep "${2}") +fi + +echo "${tags}"