From e0f3f5c87c188e2efadda4b1bb041db08c92d896 Mon Sep 17 00:00:00 2001 From: L3D Date: Mon, 2 Aug 2021 01:09:02 +0200 Subject: [PATCH 1/2] improve scheduling of backups via cron or timers improves the handling and differentiation of cronjobs and systemd timers. Rename the ``restic_create_cron`` variable to``restic_create_schedule``. Now new: ``restic_schedule_type: "systemd"``. RESOLVE #22 --- README.md | 28 +++++++++++++--------------- defaults/main.yml | 7 ++++++- handlers/main.yml | 2 +- molecule/default/playbook.yml | 2 +- tasks/main.yml | 4 ++-- tasks/{timer.yml => schedule.yml} | 27 ++++++++++++++++++--------- vars/main.yml | 2 +- 7 files changed, 42 insertions(+), 30 deletions(-) rename tasks/{timer.yml => schedule.yml} (84%) diff --git a/README.md b/README.md index ee4e5e1..6dd055e 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,5 @@ -# Ansible Role: restic + Ansible Role: restic +======================= > **Beta:** This role is in beta status. @@ -6,7 +7,8 @@ [![license](https://raw.githubusercontent.com/roles-ansible/ansible_role_restic/main/.github/license.svg)](https://github.com/roles-ansible/ansible_role_restic/blob/main/LICENSE) [![Ansible Galaxy](https://raw.githubusercontent.com/roles-ansible/ansible_role_restic/main/.github/galaxy.svg)](https://galaxy.ansible.com/do1jlr/restic) -## Description + Description +------------- [Restic](https://github.com/restic/restic) is a versatile Go based backup solution which supports multiple backends, deduplication and incremental backups. @@ -17,15 +19,15 @@ Aditionally, it will setup executable scripts to run a Backup manually. > This Project borrowed heavily from the > [donat-b/ansible-restic](https://github.com/donat-b/ansible-restic) and -> tje [https://github.com/arillso/ansible.restic](https://github.com/arillso/ansible.restic) -> ansible role. We try to make this role more modern by using systemd timer, +> the [https://github.com/arillso/ansible.restic](https://github.com/arillso/ansible.restic) +> ansible role. We try to make this role more easy to anderstand and modern by using systemd timer, > /etc/crontab to define backup paths, more absolute paths and less options. (no S3 Storage, No Windows...) ### Backup Scripts This role will create a backup script and a file with credentials usable with the `source` command on linux for each backup in the `restic_script_dir`. These executable scripts can be used to manually trigger a backup action, but -are also used for automated backups if you have set `restic_create_cron` to true. -make sure to not change the files manually, as this can interfere with your +are also used for automated backups if you have set `restic_create_schedule` variable to true. +Make sure to not change the files manually, as this can interfere with your backups quite a bit. on Linux, if you want to take a manual snapshot, you can run the backup like this: @@ -69,9 +71,10 @@ ansible-galaxy install arillso.restic | `restic_install_path` | `'/usr/local/bin'` | Install location for the restic binary | | `restic_script_dir` | `'/opt/restic'` | Location of the generated backup scripts | | `restic_log_dir` | `'{{ restic_script_dir }}/log'` | Location of the logs of the backup scripts | -| `restic_repos` | `{}` | A dictionary of repositories where snapshots are stored | -| `restic_backups` | `{}` (or `[]`) | A list of dictionaries specifying the files and directories to be backed up | -| `restic_create_cron` | `false` | Should a cronjob be created for each backup | +| `restic_repos` | `{}` | A dictionary of repositories where snapshots are stored. *(More Info: [Repos](#Repos))* | +| `restic_backups` | `{}` (or `[]`) | A list of dictionaries specifying the files and directories to be backed up *(More Infos: [Backups](#Backups))* | +|`restic_create_schedule`| `false` | Should we schedule each backup. Either via cronjob or via systemd timer.| +| `restic_schedule_type` | `systemd` | Here you can define if we create a ``cronjob`` or a ``systemd`` timer. If it fails to create a systemd timer, a cronjob will be created. | | `restic_dir_owner` | `'{{ansible_user}}'` | The owner of all created dirs | | `restic_dir_group` | `'{{ansible_user}}'` | The group of all created dirs | @@ -93,11 +96,6 @@ Available variables: | `location` | yes | The location of the Backend. Currently, [Local](https://restic.readthedocs.io/en/stable/030_preparing_a_new_repo.html#local), [SFTP](https://restic.readthedocs.io/en/stable/030_preparing_a_new_repo.html#sftp), [S3](https://restic.readthedocs.io/en/stable/030_preparing_a_new_repo.html#amazon-s3) and [B2](https://restic.readthedocs.io/en/stable/030_preparing_a_new_repo.html#backblaze-b2) are supported | | `password` | yes | The password used to secure this repository | | `init` | no | Describes if the repository should be initialized or not. Use `false` if you are backuping to an already existing repo. | -| `aws_access_key` | no | The access key for the S3 backend | -| `aws_secret_access_key` | no | The secret access key for the S3 backend | -| `aws_default_region` | no | The desired region for the S3 backend | -| `b2_account_id` | no | The account ID for Backblaze B2 backend | -| `b2_account_key` | no | The account key for Backblaze B2 backend | Example: ```yaml @@ -136,7 +134,7 @@ Available variables: | `keep_within` | no | If set, only keeps snapshots in this time period. | | `keep_tag` | no | If set, keep snapshots with this tags. Make sure to specify a list. | | `prune` | no (`false`) | If `true`, the `restic forget` command in the script has the [`--prune` option](https://restic.readthedocs.io/en/stable/060_forget.html#removing-backup-snapshots) appended. | -| `scheduled` | no (`false`) | If `restic_create_cron` is set to `true`, this backup is scheduled and tries to create a systemd timer unit. If it fails, it is creating a cronjob. | +| `scheduled` | no (`false`) | If `restic_create_schedule` is set to `true`, this backup is scheduled and tries to create a systemd timer unit. If it fails, it is creating a cronjob. | | `schedule_oncalendar` | ``'*-*-* 02:00:00'`` | The time for the systemd timer. Please notice the randomDelaySec option. By Default the backup is done every night at 2 am (+0-4h). But only if scheduled is true. | | `schedule_minute` | no (`*`) | Minute when the job is run. ( 0-59, *, */2, etc ) | | `schedule_hour` | no (`2`) | Hour when the job is run. ( 0-23, *, */2, etc ) | diff --git a/defaults/main.yml b/defaults/main.yml index 01d4385..dd6e5a0 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -8,7 +8,9 @@ restic_script_dir: '/opt/restic' restic_log_dir: '{{ restic_script_dir }}/log' restic_repos: {} restic_backups: [] -restic_create_cron: false +restic_create_schedule: "{{ restic_create_cron }}" +restic_schedule_type: "systemd" +# restic_schedule_type: "cronjob" restic_dir_owner: '{{ ansible_user | default(ansible_user_id) }}' restic_dir_group: '{{ ansible_user | default(ansible_user_id) }}' @@ -19,3 +21,6 @@ restic_systemd_timer_default_OnCalendar: '*-*-* 02:00:00' # perform simple version check for this role? (true is recomended) submodules_versioncheck: false + +# outdated variables because of irritating names, but kept for compatibility +restic_create_cron: false diff --git a/handlers/main.yml b/handlers/main.yml index 4c1bc2c..874c2b6 100644 --- a/handlers/main.yml +++ b/handlers/main.yml @@ -7,7 +7,7 @@ daemon_reload: true with_items: '{{ restic_backups }}' when: - - restic_create_cron + - restic_create_schedule - item.name is defined - item.scheduled | default(false) - ansible_service_mgr == 'systemd' diff --git a/molecule/default/playbook.yml b/molecule/default/playbook.yml index 0b45fa6..9d261ab 100644 --- a/molecule/default/playbook.yml +++ b/molecule/default/playbook.yml @@ -2,7 +2,7 @@ - name: Converge hosts: all roles: - - role: ansible_role_restic + - {role: ansible_role_restic} pre_tasks: - name: install bzip2 package: diff --git a/tasks/main.yml b/tasks/main.yml index 726b549..09466bb 100644 --- a/tasks/main.yml +++ b/tasks/main.yml @@ -25,8 +25,8 @@ distribution_version: '{{ ansible_distribution_version }}' distribution_major_version: '{{ ansible_distribution_major_version }}' -- name: create restic systemd timer - ansible.builtin.include_tasks: 'timer.yml' +- name: schedule restic backup + ansible.builtin.include_tasks: 'schedule.yml' loop_control: loop_var: loop_distribution vars: diff --git a/tasks/timer.yml b/tasks/schedule.yml similarity index 84% rename from tasks/timer.yml rename to tasks/schedule.yml index dfc6453..9b47da4 100644 --- a/tasks/timer.yml +++ b/tasks/schedule.yml @@ -13,7 +13,6 @@ with_items: '{{ restic_backups }}' notify: systemctl restart restic.timer when: - - restic_create_cron - item.name is defined - item.scheduled | default(false) @@ -28,7 +27,6 @@ no_log: true with_items: '{{ restic_backups }}' when: - - restic_create_cron - item.name is defined - item.scheduled | default(false) @@ -43,7 +41,6 @@ no_log: true with_items: '{{ restic_backups }}' when: - - restic_create_cron - item.name is defined - item.scheduled | default(false) @@ -56,7 +53,6 @@ with_items: '{{ restic_backups }}' notify: systemctl restart restic.timer when: - - restic_create_cron - item.name is defined - item.scheduled | default(false) @@ -70,7 +66,6 @@ with_items: '{{ restic_backups }}' notify: systemctl restart restic.timer when: - - restic_create_cron - item.name is defined - item.scheduled | default(false) @@ -89,16 +84,17 @@ no_log: true with_items: '{{ restic_backups }}' when: - - restic_create_cron - item.name is defined - item.scheduled | default(false) - when: ansible_service_mgr == 'systemd' + when: + - ansible_service_mgr == 'systemd' + - restic_schedule_type == "systemd" + - restic_create_schedule | bool rescue: - name: set cronjob intead of systemd set_fact: restic_force_cron: true - - name: install cronjob instead of systemd ansible.builtin.cron: name: "do1jlr.restic backup {{ item.name }}" @@ -114,7 +110,20 @@ no_log: true with_items: '{{ restic_backups }}' when: - - restic_create_cron + - restic_create_schedule - item.name is defined - item.scheduled | default(false) - ansible_service_mgr != 'systemd' or restic_force_cron | default(false) + - restic_schedule_type == "cronjob" or restic_force_cron | default(false) + +- name: make sure no unwanted systemd timer is available + ansible.builtin.systemd: + name: "restic-{{ item.name | replace(' ', '') | string }}.timer" + state: stopped + enabled: false + when: + - restic_create_schedule + - item.name is defined + - item.scheduled | default(false) + - ansible_service_mgr != 'systemd' or restic_force_cron | default(false) + - restic_schedule_type == "cronjob" or restic_force_cron | default(false) diff --git a/vars/main.yml b/vars/main.yml index ca5e061..000e1b6 100644 --- a/vars/main.yml +++ b/vars/main.yml @@ -10,5 +10,5 @@ restic_os_variables: paths: - 'vars' -playbook_version_number: 12 # should be int +playbook_version_number: 13 # should be int playbook_version_path: 'do1jlr.restic.version' From d238ef67d2ae47d12b2a43c7938ac598b2af01d1 Mon Sep 17 00:00:00 2001 From: L3D Date: Mon, 2 Aug 2021 14:13:30 +0200 Subject: [PATCH 2/2] Review changes and fix some issues --- handlers/main.yml | 1 + tasks/schedule.yml | 29 ++++++++++++++++++++++------- vars/main.yml | 2 +- 3 files changed, 24 insertions(+), 8 deletions(-) diff --git a/handlers/main.yml b/handlers/main.yml index 874c2b6..46817b5 100644 --- a/handlers/main.yml +++ b/handlers/main.yml @@ -5,6 +5,7 @@ name: "restic-{{ item.name | replace(' ', '') | string }}.timer" state: 'restarted' daemon_reload: true + masked: false with_items: '{{ restic_backups }}' when: - restic_create_schedule diff --git a/tasks/schedule.yml b/tasks/schedule.yml index 9b47da4..551ca3c 100644 --- a/tasks/schedule.yml +++ b/tasks/schedule.yml @@ -50,6 +50,7 @@ name: "restic-{{ item.name | replace(' ', '') | string }}.service" enabled: true daemon_reload: true + masked: false with_items: '{{ restic_backups }}' notify: systemctl restart restic.timer when: @@ -63,6 +64,7 @@ enabled: true state: started daemon_reload: true + masked: false with_items: '{{ restic_backups }}' notify: systemctl restart restic.timer when: @@ -110,20 +112,33 @@ no_log: true with_items: '{{ restic_backups }}' when: - - restic_create_schedule + - restic_create_schedule | bool - item.name is defined - item.scheduled | default(false) - - ansible_service_mgr != 'systemd' or restic_force_cron | default(false) - - restic_schedule_type == "cronjob" or restic_force_cron | default(false) + - ansible_service_mgr != 'systemd' or restic_force_cron | default(false) or restic_schedule_type == "cronjob" - name: make sure no unwanted systemd timer is available ansible.builtin.systemd: name: "restic-{{ item.name | replace(' ', '') | string }}.timer" - state: stopped + state: 'stopped' enabled: false + masked: true + with_items: '{{ restic_backups }}' when: - - restic_create_schedule + - restic_create_schedule | bool - item.name is defined - item.scheduled | default(false) - - ansible_service_mgr != 'systemd' or restic_force_cron | default(false) - - restic_schedule_type == "cronjob" or restic_force_cron | default(false) + - ansible_service_mgr != 'systemd' or restic_force_cron | default(false) or restic_schedule_type == "cronjob" + +- name: mask systemd service + ansible.builtin.systemd: + name: "restic-{{ item.name | replace(' ', '') | string }}.service" + state: 'stopped' + enabled: false + masked: true + with_items: '{{ restic_backups }}' + when: + - restic_create_schedule | bool + - item.name is defined + - item.scheduled | default(false) + - ansible_service_mgr != 'systemd' or restic_force_cron | default(false) or restic_schedule_type == "cronjob" diff --git a/vars/main.yml b/vars/main.yml index 000e1b6..45e177f 100644 --- a/vars/main.yml +++ b/vars/main.yml @@ -10,5 +10,5 @@ restic_os_variables: paths: - 'vars' -playbook_version_number: 13 # should be int +playbook_version_number: 14 # should be int playbook_version_path: 'do1jlr.restic.version'