Merge pull request #51 from roles-ansible/ansible-5

restructure schedule.yml to prevent failing on Ansible 5
This commit is contained in:
L3D 2022-01-10 14:43:50 +01:00 committed by GitHub
commit 94bb2aba89
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
17 changed files with 281 additions and 156 deletions

View file

@ -78,6 +78,7 @@ ansible-galaxy install arillso.restic
| `restic_dir_owner` | `'{{ansible_user}}'` | The owner of all created dirs |
| `restic_dir_group` | `'{{ansible_user}}'` | The group of all created dirs |
| `restic_no_log` | `true` | set to false to see hidden ansible logs |
| `restic_do_not_cleanup_cron ` | `false` | we changed the cron location and clean up the old one. You can skip the cleanup here |
### Repos
Restic stores data in repositories. You have to specify at least one repository

View file

@ -22,6 +22,7 @@ restic_systemd_timer_default_OnCalendar: '*-*-* 02:00:00'
# perform simple version check for this role? (true is recomended)
submodules_versioncheck: false
restic_do_not_cleanup_cron: false
# outdated variables because of irritating names, but kept for compatibility
restic_create_cron: false

View file

@ -8,6 +8,7 @@
masked: false
with_items: '{{ restic_backups }}'
ignore_errors: true
tags: skip_ansible_lint
when:
- restic_create_schedule
- item.name is defined

View file

@ -1,11 +1,11 @@
---
- name: reformat dict if necessary
- name: (BACKUP) reformat dict if necessary
set_fact:
restic_backups: "{{ restic_backups|dict2items|json_query('[*].value') }}"
when:
- restic_backups | type_debug == "dict"
- name: Create backup credentials
- name: (BACKUP) Create backup credentials
template:
src: restic_access_Linux.j2
dest: "{{ restic_script_dir }}/access-{{ item.name | replace(' ', '') }}.sh"
@ -20,7 +20,7 @@
- item.src is defined or item.stdin and item.stdin_cmd is defined
- item.repo in restic_repos
- name: Create backup script
- name: (BACKUP) Create backup script
template:
src: restic_script_Linux.j2
dest: "{{ restic_script_dir }}/backup-{{ item.name | replace(' ', '') }}.sh"

View file

@ -1,5 +1,5 @@
---
- name: Initialize repository
- name: (CONF)Initialize repository
command: '{{ restic_install_path }}/restic init'
environment:
RESTIC_REPOSITORY: '{{ item.value.location }}'

View file

@ -0,0 +1,49 @@
---
- name: "(SCHEDULE) (OLD) check if ansible version is under 2.12.0"
ansible.builtin.assert:
that:
- "ansible_version.full is version_compare('2.12.0', '<')"
fail_msg: "[ERROR] Youre ansible version is above 2.12.0"
success_msg: "Congratulations. You are using ansible version {{ ansible_version.full }}"
delegate_to: localhost
- name: (SCHEDULE) (OLD) try to remove entries from /etc/crontab
ansible.builtin.cron:
name: "do1jlr.restic backup {{ item.name }}"
job: "CRON=true {{ restic_script_dir }}/backup-{{ item.name | replace(' ', '') }}.sh"
minute: '{{ item.schedule_minute | default("*") }}'
hour: '{{ item.schedule_hour | default("2") }}'
weekday: '{{ item.schedule_weekday | default("*") }}'
month: '{{ item.schedule_month | default("*") }}'
state: absent
cron_file: '/etc/crontab'
user: 'root'
become: true
no_log: "{{ restic_no_log }}"
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"
ignore_error: true
tags: skip_ansible_lint
register: cron_delete
- name: "(SCHEDULE) (OLD) make sure 'do1jlr.restic backup {{ item.name }}' is not in /etc/crontab"
become: true
ansible.builtin.lineinfile:
path: '/etc/crontab'
state: absent
search_string: "do1jlr.restic backup {{ item.name }}"
when: cron_delete.failed
with_items: '{{ restic_backups }}'
- name: "(SCHEDULE) (OLD) make sure '{{ restic_script_dir }}/backup-{{ item.name | replace(' ', '') }}.sh' is not in /etc/crontab"
become: true
ansible.builtin.lineinfile:
path: '/etc/crontab'
state: absent
search_string: "{{ restic_script_dir }}/backup-{{ item.name | replace(' ', '') }}.sh"
when: cron_delete.failed
with_items: '{{ restic_backups }}'

View file

@ -2,5 +2,5 @@
# tasks file for skeleton
- name: Message
debug:
ansible.builtin.fail:
msg: 'Your {{ ansible_system }} is not yet supported'

View file

@ -1,8 +1,8 @@
---
- name: install and verify restic binary
- name: (INSTALL) install and verify restic binary
become: true
block:
- name: Download client binary
- name: (INSTALL) Download client binary
ansible.builtin.get_url:
url: '{{ restic_url }}'
dest: '{{ restic_download_path }}/restic.bz2'
@ -10,43 +10,43 @@
register: get_url_restic
# TODO: This needs to become independent of the shell module to actually work
- name: Decompress the binary
- name: (INSTALL) Decompress the binary
ansible.builtin.shell: "bzip2 -dc {{ get_url_restic.dest }} > {{ restic_bin_bath }}"
args:
creates: '{{ restic_download_path }}/bin/restic-{{ restic_version }}'
- name: Ensure permissions are correct
- name: (INSTALL) Ensure permissions are correct
ansible.builtin.file:
path: '{{ restic_download_path }}/bin/restic-{{ restic_version }}'
mode: '0755'
owner: '{{ restic_dir_owner }}'
group: '{{ restic_dir_group }}'
- name: Test the binary
- name: (INSTALL) Test the binary
ansible.builtin.command: "{{ restic_bin_bath }} version"
ignore_errors: true
register: restic_test_result
- name: Remove faulty binary
- name: (INSTALL) Remove faulty binary
ansible.builtin.file:
path: '{{ restic_bin_bath }}'
state: absent
when: "'FAILED' in restic_test_result.stderr"
- name: Fail if restic could not be installed
- name: (INSTALL) Fail if restic could not be installed
ansible.builtin.fail:
msg: >-
Restic binary has been faulty and has been removed.
Try to re-run the role and make sure you have bzip2 installed!
when: "'FAILED' in restic_test_result.stderr"
- name: Create symbolic link to the correct version
- name: (INSTALL) Create symbolic link to the correct version
ansible.builtin.file:
src: '{{ restic_download_path }}/bin/restic-{{ restic_version }}'
path: '{{ restic_install_path }}/restic'
state: link
force: true
rescue:
- name: try restic self-update
- name: (INSTALL) try restic self-update
become: true
ansible.builtin.command: "{{ restic_install_path }}/restic self-update"

View file

@ -2,18 +2,18 @@
- name: add OS specific variables
ansible.builtin.include_vars: "{{ lookup('first_found', restic_os_variables) }}"
- name: perform versionscheck
- name: perform optional versionscheck
ansible.builtin.include_tasks: 'versioncheck.yml'
when: submodules_versioncheck|bool
when: submodules_versioncheck | bool
- name: make sure restic is available
ansible.builtin.include_tasks: 'preperation.yml'
- name: Install restic
- name: make sure restic is installed
ansible.builtin.include_tasks: 'install.yml'
when: not restic_executable.stat.exists or not restic_installed.stat.exists
- name: Configure restic
- name: initialize restic repo(s)
ansible.builtin.include_tasks: 'configure.yml'
- name: create backup script

View file

@ -1,5 +1,6 @@
---
- name: Ensure restic directories exist
- name: (PREPARE) Ensure restic directories exist
become: true
ansible.builtin.file:
state: 'directory'
path: '{{ item }}'
@ -8,12 +9,12 @@
group: '{{ restic_dir_group }}'
with_items: '{{ restic_create_paths }}'
- name: Check if downloaded binary is present
- name: (PREPARE) Check if downloaded binary is present
ansible.builtin.stat:
path: '{{ restic_download_path }}/bin/restic-{{ restic_version }}'
register: restic_executable
- name: Check if installed binary is present
- name: (PREPARE) Check if installed binary is present
ansible.builtin.stat:
path: '{{ restic_install_path }}/restic'
register: restic_installed

View file

@ -0,0 +1,18 @@
---
- name: (SCHEDULE) (CRON) install restic backup cronjob
ansible.builtin.cron:
name: "do1jlr.restic backup {{ item.name }}"
job: "CRON=true {{ restic_script_dir }}/backup-{{ item.name | replace(' ', '') }}.sh"
minute: '{{ item.schedule_minute | default("*") }}'
hour: '{{ item.schedule_hour | default("2") }}'
weekday: '{{ item.schedule_weekday | default("*") }}'
month: '{{ item.schedule_month | default("*") }}'
state: present
user: 'root'
cron_file: restic_backup
become: true
no_log: "{{ restic_no_log }}"
with_items: '{{ restic_backups }}'
when:
- item.name is defined
- item.scheduled | default(false)

View file

@ -0,0 +1,66 @@
---
- name: (SCHEDULE) (SYSTEMD) create systemd timer
block:
- name: (SCHEDULE) (SYSTEMD) copy systemd timer
become: true
ansible.builtin.template:
src: templates/restic.timer.j2
dest: "/lib/systemd/system/restic-{{ item.name | replace(' ', '') }}.timer"
owner: 'root'
group: 'root'
mode: '0644'
no_log: "{{ restic_no_log }}"
with_items: '{{ restic_backups }}'
notify: systemctl restart restic.timer
when:
- item.name is defined
- item.scheduled | default(false)
- name: (SCHEDULE) (SYSTEMD) copy systemd service
become: true
ansible.builtin.template:
src: templates/restic.service.j2
dest: "/lib/systemd/system/restic-{{ item.name | replace(' ', '') }}.service"
owner: 'root'
group: 'root'
mode: '0644'
no_log: "{{ restic_no_log }}"
with_items: '{{ restic_backups }}'
when:
- item.name is defined
- item.scheduled | default(false)
- name: (SCHEDULE) (SYSTEMD) Enable restic service
become: true
ansible.builtin.systemd:
name: "restic-{{ item.name | replace(' ', '') | string }}.service"
enabled: true
daemon_reload: true
masked: false
with_items: '{{ restic_backups }}'
notify: systemctl restart restic.timer
when:
- item.name is defined
- item.scheduled | default(false)
- name: (SCHEDULE) (SYSTEMD) Enable and start restic timer
become: true
ansible.builtin.systemd:
name: "restic-{{ item.name | replace(' ', '') | string }}.timer"
enabled: true
state: started
daemon_reload: true
masked: false
with_items: '{{ restic_backups }}'
notify: systemctl restart restic.timer
when:
- item.name is defined
- item.scheduled | default(false)
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

View file

@ -0,0 +1,18 @@
---
- name: (SCHEDULE) (CRON) remove restic backup cronjob
ansible.builtin.cron:
name: "do1jlr.restic backup {{ item.name }}"
job: "CRON=true {{ restic_script_dir }}/backup-{{ item.name | replace(' ', '') }}.sh"
minute: '{{ item.schedule_minute | default("*") }}'
hour: '{{ item.schedule_hour | default("2") }}'
weekday: '{{ item.schedule_weekday | default("*") }}'
month: '{{ item.schedule_month | default("*") }}'
state: present
user: 'root'
cron_file: restic_backup
become: true
no_log: "{{ restic_no_log }}"
with_items: '{{ restic_backups }}'
when:
- item.name is defined
- item.scheduled | default(false)

View file

@ -0,0 +1,60 @@
---
- name: (SCHEDULE) (SYSTEMD) remove systemd timer
block:
- name: (SCHEDULE) (SYSTEMD) mask restic timer
become: true
ansible.builtin.systemd:
name: "restic-{{ item.name | replace(' ', '') | string }}.timer"
enabled: false
state: stopped
daemon_reload: true
masked: false
with_items: '{{ restic_backups }}'
ignore_errors: true
tags: skip_ansible_lint
failed_when: false
changed_when: false
when:
- item.name is defined
- item.scheduled | default(false)
- restic_schedule_type == "cronjob" or restic_force_cron | default(false)
- name: (SCHEDULE) (SYSTEMD) mask restic service
become: true
ansible.builtin.systemd:
name: "restic-{{ item.name | replace(' ', '') | string }}.service"
enabled: false
state: stopped
daemon_reload: true
masked: true
with_items: '{{ restic_backups }}'
when:
- item.name is defined
- item.scheduled | default(false)
- restic_schedule_type == "cronjob" or restic_force_cron | default(false)
ignore_errors: true
failed_when: false
tags: skip_ansible_lint
changed_when: false
- name: (SCHEDULE) (SYSTEMD) delete systemd .timer file
become: true
ansible.builtin.file:
path: "/lib/systemd/system/restic-{{ item.name | replace(' ', '') }}.timer"
state: absent
with_items: '{{ restic_backups }}'
when:
- item.name is defined
- item.scheduled | default(false)
- restic_schedule_type == "cronjob" or restic_force_cron | default(false)
- name: (SCHEDULE) (SYSTEMD) delete systemd .service file
become: true
ansible.builtin.file:
path: "/lib/systemd/system/restic-{{ item.name | replace(' ', '') }}.service"
state: absent
with_items: '{{ restic_backups }}'
when:
- item.name is defined
- item.scheduled | default(false)
- restic_schedule_type == "cronjob" or restic_force_cron | default(false)

View file

@ -1,146 +1,32 @@
---
- name: create systemd timer
block:
- name: copy systemd timer
become: true
ansible.builtin.template:
src: templates/restic.timer.j2
dest: "/lib/systemd/system/restic-{{ item.name | replace(' ', '') }}.timer"
owner: 'root'
group: 'root'
mode: '0644'
no_log: "{{ restic_no_log }}"
with_items: '{{ restic_backups }}'
notify: systemctl restart restic.timer
when:
- item.name is defined
- item.scheduled | default(false)
- name: copy systemd service
become: true
ansible.builtin.template:
src: templates/restic.service.j2
dest: "/lib/systemd/system/restic-{{ item.name | replace(' ', '') }}.service"
owner: 'root'
group: 'root'
mode: '0644'
no_log: "{{ restic_no_log }}"
with_items: '{{ restic_backups }}'
when:
- item.name is defined
- item.scheduled | default(false)
- name: copy systemd service
become: true
ansible.builtin.template:
src: templates/restic.service.j2
dest: "/lib/systemd/system/restic-{{ item.name | replace(' ', '') }}.service"
owner: 'root'
group: 'root'
mode: '0644'
no_log: "{{ restic_no_log }}"
with_items: '{{ restic_backups }}'
when:
- item.name is defined
- item.scheduled | default(false)
- name: Enable restic service
become: true
ansible.builtin.systemd:
name: "restic-{{ item.name | replace(' ', '') | string }}.service"
enabled: true
daemon_reload: true
masked: false
with_items: '{{ restic_backups }}'
notify: systemctl restart restic.timer
when:
- item.name is defined
- item.scheduled | default(false)
- name: Enable and start restic timer
become: true
ansible.builtin.systemd:
name: "restic-{{ item.name | replace(' ', '') | string }}.timer"
enabled: true
state: started
daemon_reload: true
masked: false
with_items: '{{ restic_backups }}'
notify: systemctl restart restic.timer
when:
- item.name is defined
- item.scheduled | default(false)
- name: delete old cronjob entry if available
ansible.builtin.cron:
name: "do1jlr.restic backup {{ item.name }}"
job: "CRON=true {{ restic_script_dir }}/backup-{{ item.name | replace(' ', '') }}.sh"
minute: '{{ item.schedule_minute | default("*") }}'
hour: '{{ item.schedule_hour | default("2") }}'
weekday: '{{ item.schedule_weekday | default("*") }}'
month: '{{ item.schedule_month | default("*") }}'
state: absent
cron_file: '/etc/crontab'
user: 'root'
become: true
no_log: "{{ restic_no_log }}"
with_items: '{{ restic_backups }}'
when:
- item.name is defined
- item.scheduled | default(false)
- name: (SCHEDULE) create restic systemd timer
ansible.builtin.include_tasks: restic_create_systemd.yml
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 }}"
job: "CRON=true {{ restic_script_dir }}/backup-{{ item.name | replace(' ', '') }}.sh"
minute: '{{ item.schedule_minute | default("*") }}'
hour: '{{ item.schedule_hour | default("2") }}'
weekday: '{{ item.schedule_weekday | default("*") }}'
month: '{{ item.schedule_month | default("*") }}'
state: present
cron_file: '/etc/crontab'
user: 'root'
become: true
no_log: "{{ restic_no_log }}"
with_items: '{{ restic_backups }}'
- name: (SCHEDULE) delete systemd timers if available
ansible.builtin.include_tasks: restic_delete_systemd.yml
when:
- ansible_service_mgr == 'systemd'
- restic_schedule_type == "cronjob" or restic_force_cron | default(false)
- restic_create_schedule | bool
- name: (SCHEDULE) delete old cron entry from previous versions of this role
ansible.builtin.include_tasks: delete_legacy_cron_entry.yml
when: restic_do_not_cleanup_cron | bool
- name: (SCHEDULE) install restic via cronjob
ansible.builtin.include_tasks: restic_create_cron.yml
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"
- name: make sure no unwanted systemd timer is available
ansible.builtin.systemd:
name: "restic-{{ item.name | replace(' ', '') | string }}.timer"
state: 'stopped'
enabled: false
masked: true
with_items: '{{ restic_backups }}'
ignore_errors: true
- name: (SCHEDULE) remove restic cronjobs
ansible.builtin.include_tasks: restic_delete_cron.yml
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"
- name: mask systemd service
ansible.builtin.systemd:
name: "restic-{{ item.name | replace(' ', '') | string }}.service"
state: 'stopped'
enabled: false
masked: true
with_items: '{{ restic_backups }}'
ignore_errors: true
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"
- ansible_service_mgr == 'systemd'
- not restic_force_cron | default(false)
- restic_schedule_type != "cronjob"

View file

@ -3,6 +3,28 @@
# Backup script for {{ item.src|default('stdin') }}
# Use this file to create a Backup and prune existing data with one execution.
pid="/var/run/restic_backup_{{ item.name | regex_replace('\'', '\'\\\'\'') }}.pid"
trap "rm -f $pid" SIGSEGV
trap "rm -f $pid" SIGINT
if [ -e $pid ]; then
echo "A nother version of this restic backup script is already running!"
{% if item.mail_on_error is defined and item.mail_on_error == true %}
mail -s "starting restic backup failed on {{ ansible_hostname }}" {{ item.mail_address }} <<< "Another restic backup process is already running. We canceled starting a new restic backup script running at {{ ansible_hostname }} at $(date -u '+%Y-%m-%d %H:%M:%S').
{%- if item.src is defined -%}
{{ ' ' }}We tried to backup '{{ item.src }}'.
{%- endif -%}
{{ ' ' }}Please repair the restic-{{ item.name | replace(' ', '') }} job."
{% endif %}
exit # pid file exists, another instance is running, so now we politely exit
else
echo $$ > $pid # pid file doesn't exit, create one and go on
fi
# your normal workflow here...
{% if item.disable_logging is defined and item.disable_logging %}
{% set backup_result_log, backup_output_log = "/dev/null", "/dev/null" %}
{% set forget_result_log, forget_output_log = "/dev/null", "/dev/null" %}
@ -164,3 +186,5 @@ else
{{ ' ' }}Please repair the restic-{{ item.name | replace(' ', '') }} job."
{% endif %}
fi
rm -f $pid # remove pid file just before exiting
exit

View file

@ -10,5 +10,5 @@ restic_os_variables:
paths:
- 'vars'
playbook_version_number: 20 # should be int
playbook_version_number: 22 # should be int
playbook_version_path: 'do1jlr.restic.version'