From ffd264e3ec3ff939854a5b5dc833c2868e26adf6 Mon Sep 17 00:00:00 2001 From: mg Date: Wed, 9 Feb 2022 10:06:37 +0100 Subject: [PATCH] =?UTF-8?q?Script=20user=20f=C3=BCr=20restic=20erstellt=20?= =?UTF-8?q?(#260)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Michael Grote Reviewed-on: https://git.mgrote.net/mg/ansible/pulls/260 Co-authored-by: mg Co-committed-by: mg --- .../on-off/remove_old_restic_cronjob.yml | 12 +++++++ roles/mgrote.restic/defaults/main.yml | 3 ++ roles/mgrote.restic/tasks/config.yml | 27 ++++++++------- .../tasks/{folders.yml => dir.yml} | 6 ++-- roles/mgrote.restic/tasks/install.yml | 1 + roles/mgrote.restic/tasks/main.yml | 10 ++++-- roles/mgrote.restic/tasks/user.yml | 33 +++++++++++++++++++ .../mgrote.restic/templates/restic_backup.sh | 33 +++++++++---------- 8 files changed, 90 insertions(+), 35 deletions(-) create mode 100644 playbooks/on-off/remove_old_restic_cronjob.yml rename roles/mgrote.restic/tasks/{folders.yml => dir.yml} (74%) create mode 100644 roles/mgrote.restic/tasks/user.yml diff --git a/playbooks/on-off/remove_old_restic_cronjob.yml b/playbooks/on-off/remove_old_restic_cronjob.yml new file mode 100644 index 00000000..0c687ac3 --- /dev/null +++ b/playbooks/on-off/remove_old_restic_cronjob.yml @@ -0,0 +1,12 @@ +--- +- hosts: all + tasks: + - name: remove restic cronjob + become: yes + ansible.builtin.cron: + name: restic + state: absent + job: "/usr/local/bin/restic_backup.sh" + minute: "{{ 59|random(seed=inventory_hostname) }}" + hour: "{{ restic_cron_hours }}" + # siehe: https://stackoverflow.com/questions/33379378/idempotence-and-random-variables-in-ansible diff --git a/roles/mgrote.restic/defaults/main.yml b/roles/mgrote.restic/defaults/main.yml index b1896557..557955a7 100644 --- a/roles/mgrote.restic/defaults/main.yml +++ b/roles/mgrote.restic/defaults/main.yml @@ -16,3 +16,6 @@ **/**Cache***/** **/**AppData***/** restic_enable_role: true + ### under which user the script is run + restic_user_group: "root" + restic_user: "restic" diff --git a/roles/mgrote.restic/tasks/config.yml b/roles/mgrote.restic/tasks/config.yml index 0d004b82..aac70387 100644 --- a/roles/mgrote.restic/tasks/config.yml +++ b/roles/mgrote.restic/tasks/config.yml @@ -4,16 +4,18 @@ ansible.builtin.template: src: "smb_password.txt" dest: "/etc/restic/smb_password.txt" - owner: root - group: root - mode: 0700 + owner: "{{ restic_user }}" + group: "{{ restic_user_group }}" + mode: 0600 - name: copy restic_backup.sh become: yes ansible.builtin.template: src: "restic_backup.sh" dest: "/usr/local/bin/restic_backup.sh" - mode: a+x + mode: 0744 + owner: "{{ restic_user }}" + group: "{{ restic_user_group }}" - name: create exclude.txt become: yes @@ -28,9 +30,9 @@ ansible.builtin.template: src: "password.txt" dest: "/etc/restic/password.txt" - owner: root - group: root - mode: 0700 + owner: "{{ restic_user }}" + group: "{{ restic_user_group }}" + mode: 0600 - name: create restic cronjob become: yes @@ -41,15 +43,16 @@ minute: "{{ 59|random(seed=inventory_hostname) }}" hour: "{{ restic_cron_hours }}" # siehe: https://stackoverflow.com/questions/33379378/idempotence-and-random-variables-in-ansible + user: "{{ restic_user }}" - name: Create restic log become: true ansible.builtin.file: path: /var/log/restic.log state: touch - owner: root - group: root - mode: 0640 + owner: "{{ restic_user }}" + group: "{{ restic_user_group }}" + mode: 0644 access_time: preserve modification_time: preserve @@ -58,6 +61,6 @@ ansible.builtin.template: src: logrotate_restic dest: /etc/logrotate.d/restic - owner: root - group: root + owner: "{{ restic_user }}" + group: "{{ restic_user_group }}" mode: 0644 diff --git a/roles/mgrote.restic/tasks/folders.yml b/roles/mgrote.restic/tasks/dir.yml similarity index 74% rename from roles/mgrote.restic/tasks/folders.yml rename to roles/mgrote.restic/tasks/dir.yml index 8b6e4ccc..5489163a 100644 --- a/roles/mgrote.restic/tasks/folders.yml +++ b/roles/mgrote.restic/tasks/dir.yml @@ -10,6 +10,6 @@ ansible.builtin.file: path: "{{ restic_mount }}" state: directory - owner: root - group: root - mode: 0777 + owner: "{{ restic_user }}" + group: "{{ restic_user_group }}" + mode: 0755 diff --git a/roles/mgrote.restic/tasks/install.yml b/roles/mgrote.restic/tasks/install.yml index f2bb7f3e..00e2b4e9 100644 --- a/roles/mgrote.restic/tasks/install.yml +++ b/roles/mgrote.restic/tasks/install.yml @@ -6,4 +6,5 @@ - restic - logrotate - cifs-utils + - sudo state: present diff --git a/roles/mgrote.restic/tasks/main.yml b/roles/mgrote.restic/tasks/main.yml index d4882096..a5fcd7ce 100644 --- a/roles/mgrote.restic/tasks/main.yml +++ b/roles/mgrote.restic/tasks/main.yml @@ -1,10 +1,16 @@ --- + - name: include user tasks + include_tasks: user.yml + when: restic_enable_role + - name: include install tasks include_tasks: install.yml when: restic_enable_role - - name: include folder tasks - include_tasks: folders.yml + + - name: include directories tasks + include_tasks: dir.yml when: restic_enable_role + - name: include config tasks include_tasks: config.yml when: restic_enable_role diff --git a/roles/mgrote.restic/tasks/user.yml b/roles/mgrote.restic/tasks/user.yml new file mode 100644 index 00000000..c71a8cde --- /dev/null +++ b/roles/mgrote.restic/tasks/user.yml @@ -0,0 +1,33 @@ +--- + - name: ensure group exists + become: true + ansible.builtin.group: + name: "{{ restic_user_group }}" + state: present + when: + - restic_user_group is defined + + - name: ensure user exists + become: true + ansible.builtin.user: + name: "{{ restic_user }}" + group: "{{ restic_user_group }}" + shell: /usr/sbin/nologin + when: + - restic_user_group is defined + - restic_user is defined + + - name: add user to sudoers + become: true + ansible.builtin.blockinfile: + path: /etc/sudoers + state: present + block: | + {{ restic_user }} ALL=(ALL) NOPASSWD:ALL + validate: '/usr/sbin/visudo -cf %s' + backup: yes + marker_begin: restic-sudoers BEGIN + marker_end: restic-sudoers END + when: + - restic_user_group is defined + - restic_user is defined diff --git a/roles/mgrote.restic/templates/restic_backup.sh b/roles/mgrote.restic/templates/restic_backup.sh index 6fa776fb..5e5fdc2c 100644 --- a/roles/mgrote.restic/templates/restic_backup.sh +++ b/roles/mgrote.restic/templates/restic_backup.sh @@ -1,23 +1,22 @@ #!/bin/bash {{ file_header | default () }} -LOCKDIR=${HOME}/.cache # set lockdir -function exlock() { # define Function for setting lock; stops the script i a lock exists - exec {lock_fd}>${LOCKDIR}/$(basename $0).lock - flock -nx "$lock_fd" - if [[ $? == 1 ]]; then - exit 1 - fi -} -function unlock() { # define function for removing lock - rm "${LOCKDIR}/$(basename $0).lock" - [[ -n $1 ]] && exit $1 - exit -} -exlock # set lock +# source functions +if [[ -f "/usr/local/bin/functions.sh" ]]; then + source /usr/local/bin/functions.sh +else + echo "[ERROR] Could not find: /usr/local/bin/functions.sh" + exit 3 +fi + +# set lock +## call function +## lock gets set and released if the script terminates +set_lock + abbruch_restic=0 # set counter for error -mount -t cifs -o credentials="/etc/restic/smb_password.txt",vers=3.0 {{ restic_repository }} {{ restic_mount }} # mount share +sudo mount -t cifs -o credentials="/etc/restic/smb_password.txt",vers=3.0,uid=$UID {{ restic_repository }} {{ restic_mount }} # mount share mount_return_value=$? # schreib Exit Code in Variable if ( [ "$mount_return_value" -ne 0 ] ); then { @@ -55,11 +54,9 @@ do } >> /var/log/restic.log 2>&1; # leite die komplette Ausgabe in logfile um done -umount {{ restic_mount }} >> /var/log/restic.log 2>&1; # unmount +sudo umount {{ restic_mount }} >> /var/log/restic.log 2>&1; # unmount if ( [[ "$restic_return_value" -ne 0 ]] ); then # sende eMail wenn Restic Fehler ungleich 0, also Fehler; #https://stackoverflow.com/a/45817972 tail --lines=50 "/var/log/restic.log" | mail -s "Backup-Error - restic - $HOSTNAME" {{ empfaenger_mail }} # schreibe die letzten 50 Zeilen aus dem Logfile in den Body der Mail fi - -unlock # entferne lock