Browse Source

new: [rsync-backup] add charm

Signed-off-by: Valentin Lab <valentin.lab@kalysto.org>
0k/dev/master
Valentin Lab 4 years ago
parent
commit
d7723be158
  1. 4
      rsync-backup-target/build/src/etc/ssh/sshd_config
  2. 27
      rsync-backup/build/Dockerfile
  3. 71
      rsync-backup/build/entrypoint.sh
  4. 35
      rsync-backup/hooks/backup-relation-joined
  5. 22
      rsync-backup/hooks/init
  6. 48
      rsync-backup/hooks/schedule_command-relation-joined
  7. 5
      rsync-backup/lib/common
  8. 17
      rsync-backup/metadata.yml

4
rsync-backup-target/build/src/etc/ssh/sshd_config

@ -29,7 +29,7 @@
# Authentication:
#LoginGraceTime 2m
#PermitRootLogin prohibit-password
PermitRootLogin no
#StrictModes yes
#MaxAuthTries 6
#MaxSessions 10
@ -96,7 +96,7 @@ X11Forwarding no
#Compression delayed
#ClientAliveInterval 0
#ClientAliveCountMax 3
#UseDNS no
UseDNS no
#PidFile /run/sshd.pid
#MaxStartups 10:30:100
PermitTunnel no

27
rsync-backup/build/Dockerfile

@ -0,0 +1,27 @@
FROM alpine:3.9
MAINTAINER Valentin Lab <valentin.lab@kalysto.org>
RUN apk add bash rsync sudo openssh-client
# RUN apt-get update && \
# DEBIAN_FRONTEND=noninteractive apt-get install --force-yes -y --no-install-recommends rsync sudo openssh-client && \
# apt-get clean && \
# rm -rf /var/lib/apt/lists/*
## New user/group rsync/rsync with home dir in /var/lib/rsync
RUN mkdir -p /var/lib/rsync && \
addgroup -S rsync && \
adduser -S rsync -h /var/lib/rsync -G rsync && \
chown rsync:rsync /var/lib/rsync
## New user/group rsync/rsync with home dir in /var/lib/rsync
# RUN mkdir -p /var/lib/rsync && \
# groupadd -r rsync && \
# useradd -r rsync -d /var/lib/rsync -g rsync && \
# chown rsync:rsync /var/lib/rsync
COPY ./entrypoint.sh /entrypoint.sh
ENTRYPOINT [ "/entrypoint.sh" ]

71
rsync-backup/build/entrypoint.sh

@ -0,0 +1,71 @@
#!/bin/bash
[ "$UID" != "0" ] && echo "You must be root." 2>&1 && exit 1
##
## code
##
user=rsync
src="$1"
if [ -z "$src" ]; then
echo "You must provide a source directory as first argument." >&2
exit 1
fi
if ! [ -d "$src" ]; then
echo "Folder '$src' not found, please provide a valid directory as first argument." >&2
exit 1
fi
dest="$2"
if [ -z "$dest" ]; then
echo "You must provide a host as target." >&2
exit 1
fi
rsync_options=(${RSYNC_OPTIONS:-})
ssh_options=(${SSH_OPTIONS:--o StrictHostKeyChecking=no})
if echo "$dest" | grep "/" >/dev/null 2>&1; then
rsync_options=("--bwlimit" "$(echo "$dest" | cut -f 2 -d "/")" "${rsync_options[@]}")
dest="$(echo "$dest" | cut -f 1 -d "/")"
fi
if echo "$dest" | grep ":" >/dev/null 2>&1; then
ssh_options=("-p" "$(echo "$dest" | cut -f 2 -d ":")" "${ssh_options[@]}")
dest="$(echo "$dest" | cut -f 1 -d ":")"
fi
hostname=$(hostname)
hostname=${LABEL_HOSTNAME:-$hostname}
dest_path="/var/mirror/$hostname"
touch /etc/rsync/exclude-patterns
touch /etc/rsync/include-patterns
if ! [ -s "/etc/rsync/include-patterns" ]; then
echo "Nothing to do as /etc/rsync/include-patterns is empty."
exit 0
fi
cmd=(/usr/bin/rsync "${rsync_options[@]}" -azvA
-e "sudo -u $user ssh ${ssh_options[*]}"
--include-from /etc/rsync/include-patterns
--exclude-from /etc/rsync/exclude-patterns
--delete --partial --partial-dir .rsync-partial
--numeric-ids "$src/" "$user@$dest":"$dest_path")
rsync_uid_gid=$(stat -c "%u:%g" "/var/lib/rsync")
chown "$rsync_uid_gid" "/var/lib/rsync/.ssh" -R
echo "${cmd[@]}"
exec "${cmd[@]}"

35
rsync-backup/hooks/backup-relation-joined

@ -0,0 +1,35 @@
#!/bin/bash
## When writing relation script, remember:
## - they should be idempotents
## - they can be launched while the dockers is already up
## - they are launched from the host
## - the target of the link is launched first, and get a chance to ``relation-set``
## - both side of the scripts get to use ``relation-get``.
. lib/common
set -e
exclude_patterns=$(relation-get "exclude-patterns") || true
include_patterns=$(relation-get "include-patterns") || true
include_patterns=${include_patterns:-"- /"}
while read-0 pattern; do
if [[ "$pattern" != /* ]]; then
err "Invalid pattern '$pattern' provided as ${WHITE}exclude-pattern${NORMAL}, " \
"in relation's options."
exit 1
fi
echo "/$BASE_SERVICE_NAME$pattern"
done < <(e "$exclude_patterns" | shyaml get-values-0) >> "$RSYNC_EXCLUDE_PATTERNS"
while read-0 pattern; do
if [[ "$pattern" != /* ]]; then
err "Invalid pattern '$pattern' provided as ${WHITE}exclude-pattern${NORMAL}, " \
"in relation's options."
exit 1
fi
echo "/$BASE_SERVICE_NAME$pattern"
done < <(e "$include_patterns" | shyaml get-values-0) >> "$RSYNC_INCLUDE_PATTERNS"

22
rsync-backup/hooks/init

@ -0,0 +1,22 @@
#!/bin/bash
## Init is run on host
## For now it is run every time the script is launched, but
## it should be launched only once after build.
## Accessible variables are:
## - SERVICE_NAME Name of current service
## - DOCKER_BASE_IMAGE Base image from which this service might be built if any
## - SERVICE_DATASTORE Location on host of the DATASTORE of this service
## - SERVICE_CONFIGSTORE Location on host of the CONFIGSTORE of this service
. lib/common
set -e
RSYNC_EXCLUDE_PATTERNS="$SERVICE_CONFIGSTORE/etc/rsync/exclude-patterns"
mkdir -p "${RSYNC_EXCLUDE_PATTERNS%/*}"
echo "/*/" > "$RSYNC_EXCLUDE_PATTERNS" ## start a new
echo > "$RSYNC_INCLUDE_PATTERNS" ## start a new

48
rsync-backup/hooks/schedule_command-relation-joined

@ -0,0 +1,48 @@
#!/bin/bash
## When writing relation script, remember:
## - they should be idempotents
## - they can be launched while the dockers is already up
## - they are launched from the host
## - the target of the link is launched first, and get a chance to ``relation-set``
## - both side of the scripts get to use ``relation-get``.
. lib/common
set -e
schedule=$(relation-get schedule)
if ! echo "$schedule" | egrep '^\s*(([0-9/,*-]+\s+){4,4}[0-9/,*-]+|@[a-z]+)\s*$' >/dev/null 2>&1; then
err "Unrecognized schedule '$schedule'."
exit 1
fi
private_key=$(options-get private-key) || exit 1
target=$(options-get target) || exit 1
ident=$(options-get ident) || exit 1
home=/var/lib/rsync
local_path_key=$home/.ssh
host_path_key="$SERVICE_CONFIGSTORE${local_path_key}"
echo "$private_key" | file_put "$host_path_key/id_rsa"
chmod 600 "$host_path_key/id_rsa"
label="${SERVICE_NAME}"
DST=$CONFIGSTORE/$TARGET_CHARM_NAME/etc/cron/$label
## Warning: using '\' in heredoc will be removed in the final cron file, which
## is totally wanted: cron does not support multilines.
file_put "$DST" <<EOF
$schedule root lock $label -v -D -p 10 -k -c "\
docker run --rm \
-e LABEL_HOSTNAME=\"$ident\" \
-v \"$RSYNC_CONFIG_DIR:/etc/rsync\" \
-v \"$host_path_key:$local_path_key\" \
-v \"$HOST_DATASTORE:/mnt/source\" \
--network ${PROJECT_NAME}_default \
\"$DOCKER_BASE_IMAGE\" \
/mnt/source \"$target\"" 2>&1 | ts '\%F \%T' >> /var/log/cron/${label}_script.log
EOF
chmod +x "$DST"

5
rsync-backup/lib/common

@ -0,0 +1,5 @@
RSYNC_CONFIG_DIR="$SERVICE_CONFIGSTORE/etc/rsync"
RSYNC_INCLUDE_PATTERNS="$RSYNC_CONFIG_DIR/include-patterns"
RSYNC_EXCLUDE_PATTERNS="$RSYNC_CONFIG_DIR/exclude-patterns"

17
rsync-backup/metadata.yml

@ -0,0 +1,17 @@
description: Rsync Backup Service
type: run-once
provides:
backup:
uses:
schedule-command:
constraint: required
auto: summon
solves:
missing-feature: "scheduling of backups"
default-options:
## backup every day on random time
schedule: !bash-stdout |
printf "%d %d * * *" "$((RANDOM % 60))" "$((RANDOM % 6))"
Loading…
Cancel
Save