first commit
This commit is contained in:
99
restic/files/backup.sh.jinja
Normal file
99
restic/files/backup.sh.jinja
Normal file
@@ -0,0 +1,99 @@
|
||||
#!/bin/bash
|
||||
|
||||
{%- if pillar['pods']['mariadb'] is defined %}
|
||||
umask 0077
|
||||
BACKUP_DIR={{ pillar.pods.mariadb.containers.main.backup_dir }}
|
||||
databases=$(podman exec -it mariadb-main mysql -B -u root -p{{ pillar.pods.mariadb.containers.main.env.MYSQL_ROOT_PASSWORD }} -e "SHOW DATABASES;" | tr -d "| " | grep -v Database)
|
||||
|
||||
for db in ${databases[@]}; do
|
||||
db=${db::-1}
|
||||
if [[ "$db" != "information_schema" ]] && [[ "$db" != "performance_schema" ]] && [[ "$db" != "mysql" ]] && [[ "$db" != _* ]] && [[ "$db" != "sys" ]]; then
|
||||
echo "Dumping database: $db"
|
||||
podman exec -it mariadb-main mysqldump -u root -p{{ pillar.pods.mariadb.containers.main.env.MYSQL_ROOT_PASSWORD }} --databases $db | gzip > ${BACKUP_DIR}/$(date +"%Y-%m-%d_%H-%M-%S")_$db-sql.gz
|
||||
fi
|
||||
done
|
||||
# Delete the files older than 3 days
|
||||
echo "removing old mysql dumps"
|
||||
find $BACKUP_DIR/* -type f -name *-sql.gz -mtime +3 -exec rm {} \;
|
||||
umask 0022
|
||||
{%- endif %}
|
||||
|
||||
{%- if pillar['containers']['freeipa'] is defined %}
|
||||
echo "Stopping FreeIPA"
|
||||
systemctl stop freeipa.service
|
||||
{%- endif %}
|
||||
|
||||
podman run --rm \
|
||||
--name=restic \
|
||||
--hostname="$HOSTNAME" \
|
||||
-v /root/.restic.password:/restic-password:ro \
|
||||
-v /root:/root \
|
||||
{%- if pillar.restic.repository is defined %}
|
||||
-v {{ pillar.restic.mount }}{{ pillar.restic.suffix }}:/repo \
|
||||
{%- endif %}
|
||||
{%- for target in pillar.restic.targets %}
|
||||
-v {{ target }}:{{ target }} \
|
||||
{%- endfor %}
|
||||
-v /root/.restic.password:/root/.restic.password \
|
||||
{{ pillar.restic.image.url }}:{{ pillar.restic.image.tag }} \
|
||||
restic \
|
||||
backup \
|
||||
--password-file=/restic-password \
|
||||
{%- if pillar.restic.repository is defined %}
|
||||
--repo=/repo \
|
||||
{%- else %}
|
||||
-r sftp:{{ pillar.restic.user }}@{{ pillar.restic.host }}:{{ pillar.restic.mount }}{{ pillar.restic.suffix }} \
|
||||
{%- endif %}
|
||||
--exclude="*.tmp" \
|
||||
--exclude="lost+found" \
|
||||
--exclude="Cache" \
|
||||
--exclude="cache" \
|
||||
--exclude=".cache" \
|
||||
--exclude="tmp" \
|
||||
--exclude="temp" \
|
||||
--exclude="Temp" \
|
||||
--exclude="/home/*/go" \
|
||||
--exclude="/home/*/.local/share/virtualenv" \
|
||||
--exclude="/home/*/.local/share/virtualenvs" \
|
||||
--exclude="/home/*/VirtualBox VMs" \
|
||||
--exclude="/home/*/.mozillla/firefox/*/minidumps" \
|
||||
--exclude="/home/*/.mozillla/firefox/*/storage" \
|
||||
--exclude="/home/*/.mozillla/firefox/*/extensions.sqlite" \
|
||||
--exclude="/home/*/.mozillla/firefox/*/urlclassifier3.sqlite" \
|
||||
--exclude="/home/*/.config/google-chrome/*/Local Storage" \
|
||||
--exclude="/home/*/.config/google-chrome/*/Session Storage" \
|
||||
--exclude="/home/*/.config/google-chrome/*/Application Cache" \
|
||||
--exclude="/home/*/.config/google-chrome/*/History" \
|
||||
--exclude="/home/*/.config/google-chrome/*/History-journal" \
|
||||
--exclude="/home/*/.config/google-chrome/*/History Provider Cache" \
|
||||
--exclude="/home/*/.local/share/flatpak" \
|
||||
--exclude="/home/*/.var/app/com.slack.Slack" \
|
||||
--exclude="/home/*/.local/share/Trash" \
|
||||
--exclude="/home/*/.config/Microsoft/Microsoft Teams" \
|
||||
--exclude="/home/*/.wine" \
|
||||
--exclude="/home/*/.vim/bundle" \
|
||||
--exclude="/home/*/snap" \
|
||||
--exclude="/home/*/Downloads" \
|
||||
--exclude="/home/*/Nextcloud" \
|
||||
--exclude="/home/*/git" \
|
||||
--exclude="/srv/backup" \
|
||||
--verbose \
|
||||
{%- for target in pillar.restic.targets %}
|
||||
{{ target }} \
|
||||
{%- endfor %}
|
||||
|
||||
return_code=$?
|
||||
|
||||
{%- if pillar['containers']['freeipa'] is defined %}
|
||||
echo "Starting FreeIPA"
|
||||
systemctl start freeipa.service
|
||||
{%- endif %}
|
||||
|
||||
if [[ $return_code -eq 0 ]]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
|
||||
MESSAGE="$(journalctl -u restic-backup.service -p 5 --since today)"
|
||||
curl "$GOTIFY_URL/message?token=$GOTIFY_TOKEN" -F "title=$GOTIFY_TITLE" -F "priority=$GOTIFY_PRIO" -F "message=$MESSAGE"
|
||||
|
16
restic/files/mysql-backup.sh
Normal file
16
restic/files/mysql-backup.sh
Normal file
@@ -0,0 +1,16 @@
|
||||
#!/bin/bash
|
||||
umask 0077
|
||||
BACKUP_DIR={{ pillar.containers.mariadb.backup_dir }}
|
||||
databases=$(podman exec -it mariadb mysql -B -u root -p{{ pillar.containers.mariadb.env.MYSQL_ROOT_PASSWORD }} -e "SHOW DATABASES;" | tr -d "| " | grep -v Database)
|
||||
|
||||
for db in ${databases[@]}; do
|
||||
db=${db::-1}
|
||||
if [[ "$db" != "information_schema" ]] && [[ "$db" != "performance_schema" ]] && [[ "$db" != "mysql" ]] && [[ "$db" != _* ]] && [[ "$db" != "sys" ]]; then
|
||||
echo "Dumping database: $db"
|
||||
podman exec -it mariadb mysqldump -u root -p{{ pillar.containers.mariadb.env.MYSQL_ROOT_PASSWORD }} --databases $db | gzip > ${BACKUP_DIR}/$(date +"%Y-%m-%d_%H-%M-%S")_$db-sql.gz
|
||||
fi
|
||||
done
|
||||
# Delete the files older than 3 days
|
||||
echo "removing old mysql dumps"
|
||||
find $BACKUP_DIR/* -type f -name *-sql.gz -mtime +3 -exec rm {} \;
|
||||
umask 0022
|
11
restic/files/restic-backup.service.jinja
Normal file
11
restic/files/restic-backup.service.jinja
Normal file
@@ -0,0 +1,11 @@
|
||||
[Unit]
|
||||
Description=Run restic backup
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
User={{ pillar.restic.user }}
|
||||
ExecStart={{ salt['user.info'](pillar.restic.user).home }}/bin/backup.sh
|
||||
|
||||
[Install]
|
||||
WantedBy=default.target
|
||||
|
11
restic/files/restic-backup.timer.jinja
Normal file
11
restic/files/restic-backup.timer.jinja
Normal file
@@ -0,0 +1,11 @@
|
||||
[Unit]
|
||||
Description=Restic backup timer
|
||||
|
||||
[Timer]
|
||||
OnCalendar={{ pillar.restic.OnCalendar }}
|
||||
RandomizedDelaySec=300
|
||||
Unit=restic-backup.service
|
||||
|
||||
[Install]
|
||||
WantedBy=timers.target
|
||||
|
8
restic/files/restic.automount.jinja
Normal file
8
restic/files/restic.automount.jinja
Normal file
@@ -0,0 +1,8 @@
|
||||
[Unit]
|
||||
Description=Automount for restic repository
|
||||
|
||||
[Automount]
|
||||
Where={{ pillar['restic']['mount'] }}
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
23
restic/files/restic.jinja
Normal file
23
restic/files/restic.jinja
Normal file
@@ -0,0 +1,23 @@
|
||||
#!/bin/bash
|
||||
if [[ "$EUID" -ne 0 ]]; then
|
||||
echo "Needs to be run as root"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
podman run --rm \
|
||||
--name=restic \
|
||||
--hostname="$HOSTNAME" \
|
||||
-v /root/.restic.password:/restic-password:ro \
|
||||
{%- if pillar.restic.repository is defined %}
|
||||
-v {{ pillar.restic.mount }}{{ pillar.restic.suffix }}:/repo \
|
||||
{%- endif %}
|
||||
-v /root:/root \
|
||||
{{ pillar.restic.image.url }}:{{ pillar.restic.image.tag }} \
|
||||
restic \
|
||||
--password-file=/restic-password \
|
||||
{%- if pillar.restic.repository is defined %}
|
||||
--repo=/repo \
|
||||
{%- else %}
|
||||
-r sftp:{{ pillar.restic.user }}@{{ pillar.restic.host }}:{{ pillar.restic.mount }}{{ pillar.restic.suffix }} \
|
||||
{%- endif %}
|
||||
"$@"
|
11
restic/files/restic.mount.jinja
Normal file
11
restic/files/restic.mount.jinja
Normal file
@@ -0,0 +1,11 @@
|
||||
[Unit]
|
||||
Description=Mount the USB disk used as restic repository
|
||||
|
||||
[Mount]
|
||||
What=/dev/disk/by-uuid/{{ pillar['restic']['repository']['disk_uuid'] }}
|
||||
Where={{ pillar['restic']['mount'] }}
|
||||
Type=auto
|
||||
Options=defaults
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
77
restic/init.sls
Normal file
77
restic/init.sls
Normal file
@@ -0,0 +1,77 @@
|
||||
{%- if pillar['containers']['mariadb'] is defined %}
|
||||
Create mariadb dump script:
|
||||
file.managed:
|
||||
- name: /root/bin/mysql-backup.sh
|
||||
- source: salt://restic/files/mysql-backup.sh
|
||||
- template: jinja
|
||||
- user: root
|
||||
- group: root
|
||||
- mode: "0700"
|
||||
|
||||
Create backup destination for mariadn:
|
||||
file.directory:
|
||||
- name: {{ pillar.containers.mariadb.backup_dir }}
|
||||
- user: root
|
||||
- group: root
|
||||
- mode: "0700"
|
||||
|
||||
{%- endif %}
|
||||
|
||||
Create restiv password-file:
|
||||
file.managed:
|
||||
- name: /root/.restic.password
|
||||
- contents:
|
||||
- {{ pillar.restic.password }}
|
||||
- user: root
|
||||
- group: root
|
||||
- mode: "0600"
|
||||
|
||||
Create restic script:
|
||||
file.managed:
|
||||
- name: /usr/local/bin/restic
|
||||
- source: salt://restic/files/restic.jinja
|
||||
- template: jinja
|
||||
- user: root
|
||||
- group: root
|
||||
- mode: "0755"
|
||||
|
||||
Create backup script:
|
||||
file.managed:
|
||||
- name: /root/bin/backup.sh
|
||||
- source: salt://restic/files/backup.sh.jinja
|
||||
- template: jinja
|
||||
- user: root
|
||||
- group: root
|
||||
- mode: "0700"
|
||||
Create the restic backup service unit:
|
||||
file.managed:
|
||||
- name: /etc/systemd/system/restic-backup.service
|
||||
- source: salt://restic/files/restic-backup.service.jinja
|
||||
- template: jinja
|
||||
- user: root
|
||||
- group: root
|
||||
- mode: "0644"
|
||||
|
||||
Create the restic backup timer:
|
||||
file.managed:
|
||||
- name: /etc/systemd/system/restic-backup.timer
|
||||
- source: salt://restic/files/restic-backup.timer.jinja
|
||||
- template: jinja
|
||||
- user: root
|
||||
- group: root
|
||||
- mode: "0644"
|
||||
|
||||
Run systemctl daemon reload for restic:
|
||||
cmd.run:
|
||||
- name: systemctl daemon-reload
|
||||
- onchanges:
|
||||
- file: Create the restic backup service unit
|
||||
- file: Create the restic backup timer
|
||||
|
||||
Start the restic backup timer:
|
||||
service.running:
|
||||
- name: restic-backup.timer
|
||||
- enable: True
|
||||
- onchanges:
|
||||
- cmd: Run systemctl daemon reload for restic
|
||||
|
39
restic/repository.sls
Normal file
39
restic/repository.sls
Normal file
@@ -0,0 +1,39 @@
|
||||
{% set escape_command = [ "systemd-escape -p", pillar['restic']['mount']]|join(" ") %}
|
||||
{% set unit_name = salt['cmd.shell'](escape_command) %}
|
||||
|
||||
Create restic repository mount unit:
|
||||
file.managed:
|
||||
- name: /etc/systemd/system/{{ unit_name }}.mount
|
||||
- source: salt://restic/files/restic.mount.jinja
|
||||
- template: jinja
|
||||
- user: root
|
||||
- group: root
|
||||
- mode: "0644"
|
||||
|
||||
Create restic repository automount unit:
|
||||
file.managed:
|
||||
- name: /etc/systemd/system/{{ unit_name }}.automount
|
||||
- source: salt://restic/files/restic.automount.jinja
|
||||
- template: jinja
|
||||
- user: root
|
||||
- group: root
|
||||
- mode: "0644"
|
||||
|
||||
Run systemd daemon reload for repository:
|
||||
cmd.run:
|
||||
- name: systemctl daemon-reload
|
||||
- onchanges:
|
||||
- file: Create restic repository mount unit
|
||||
- file: Create restic repository automount unit
|
||||
|
||||
Start restic repository automount unit:
|
||||
service.running:
|
||||
- name: {{ unit_name }}.automount
|
||||
- enable: True
|
||||
|
||||
Add autherized keys for root-restic:
|
||||
ssh_auth.present:
|
||||
- user: root
|
||||
- enc: ssh-ed25519
|
||||
- comment: restic-backup
|
||||
- names: {{ pillar.restic.repository.auth_keys }}
|
Reference in New Issue
Block a user