diff --git a/.github/workflows/ansible-linting-check.yml b/.github/workflows/ansible-linting-check.yml index cee058f..e442afc 100644 --- a/.github/workflows/ansible-linting-check.yml +++ b/.github/workflows/ansible-linting-check.yml @@ -2,21 +2,21 @@ name: Ansible Lint check # yamllint disable-line rule:truthy -on: - push: - branches: '*' - pull_request: - branches: '*' +on: [push, pull_request] jobs: build: - + name: Ansible Lint runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 - - - name: Lint Ansible Playbook - uses: ansible/ansible-lint-action@v6 + - name: 'checkout git repo' + uses: actions/checkout@v4 with: - targets: "." + submodules: true + fetch-depth: 0 + + - name: Run ansible-lint + uses: ansible-actions/ansible-lint-action@v1.0.1 + with: + target: "./" diff --git a/.github/workflows/galaxy.yml b/.github/workflows/galaxy.yml index 4130155..f8beb99 100644 --- a/.github/workflows/galaxy.yml +++ b/.github/workflows/galaxy.yml @@ -1,20 +1,24 @@ --- -name: Galaxy release +name: Galaxy-NG Roles Import # yamllint disable-line rule:truthy on: - push: - branches: ['main'] release: types: ['created'] jobs: build: + name: Galaxy Role Importer runs-on: ubuntu-latest + steps: - - name: checkout - uses: actions/checkout@v3 - - name: galaxy - uses: robertdebock/galaxy-action@1.2.1 + - name: 'Checkout git repo' + uses: actions/checkout@v4 + with: + submodules: true + fetch-depth: 0 + + - name: 'Release on galaxy' + uses: ansible-actions/ansible-galaxy-action@v1.0.1 with: galaxy_api_key: ${{ secrets.galaxy_api_key }} diff --git a/.github/workflows/yamllint.yaml b/.github/workflows/yamllint.yaml deleted file mode 100644 index 98efa06..0000000 --- a/.github/workflows/yamllint.yaml +++ /dev/null @@ -1,22 +0,0 @@ ---- -name: 'Yamllint GitHub Actions' - -# yamllint disable-line rule:truthy -on: - push: - branches: '*' - pull_request: - branches: '*' - -jobs: - yamllint: - name: 'Yamllint' - runs-on: ubuntu-latest - steps: - - name: 'Checkout' - uses: actions/checkout@v3 - - name: 'Yamllint' - uses: karancode/yamllint-github-action@master - with: - yamllint_file_or_dir: '.' - yamllint_config_filepath: './.yamllint' diff --git a/handlers/main.yml b/handlers/main.yml index 729a92f..f274f7b 100644 --- a/handlers/main.yml +++ b/handlers/main.yml @@ -1,17 +1,17 @@ --- -- name: systemctl daemon-reload +- name: Run systemctl daemon-reload become: true ansible.builtin.systemd: daemon_reload: true -- name: systemctl start restic-archiver.timer +- name: Run systemctl start restic-archiver.timer become: true ansible.builtin.systemd: name: restic-archiver.timer enabled: true state: started -- name: systemctl enable restic-archiver.service +- name: Run systemctl enable restic-archiver.service become: true ansible.builtin.systemd: name: restic-archiver.service diff --git a/meta/main.yml b/meta/main.yml index 0cb5a98..0345f97 100644 --- a/meta/main.yml +++ b/meta/main.yml @@ -1,18 +1,19 @@ --- galaxy_info: role_name: restic_archiver - author: L3D - namespace: do1jlr + author: do1jlr + namespace: l3d description: Role to deploy restic and setup backups. license: MIT - min_ansible_version: 2.11 + min_ansible_version: "2.13" platforms: - name: Debian - versions: all + versions: ['all'] galaxy_tags: - backup - archive - delete - restic + - linux dependencies: [] diff --git a/tasks/cron.yml b/tasks/cron.yml index 4377296..95eaf2d 100644 --- a/tasks/cron.yml +++ b/tasks/cron.yml @@ -1,17 +1,17 @@ --- -- name: install cron +- name: Install cron become: true ansible.builtin.package: name: "{{ restic_archiver__package }}" state: present -- name: migrate cronjob to cron.d directory +- name: Migrate cronjob to cron.d directory become: true ansible.builtin.cron: name: "archive restic backup with ansible_role_restic_archiver" state: absent -- name: setup cronjob for restic with logging +- name: Setup cronjob for restic with logging become: true ansible.builtin.cron: name: "archive restic backup with ansible_role_restic_archiver" @@ -22,7 +22,7 @@ user: "{{ restic_archiver__owner }}" when: restic_archiver__log_output -- name: setup cronjob for restic without logging +- name: Setup cronjob for restic without logging become: true ansible.builtin.cron: name: "archive restic backup with ansible_role_restic_archiver" diff --git a/tasks/distribution/Linux.yml b/tasks/distribution/Linux.yml index 697b2fa..62d6cc2 100644 --- a/tasks/distribution/Linux.yml +++ b/tasks/distribution/Linux.yml @@ -1,9 +1,7 @@ --- -# tasks file for skeleton - -- name: reformat dict if necessary +- name: Reformat dict if necessary ansible.builtin.set_fact: - restic_archiver__backups: "{{ restic_archiver__backups|dict2items|json_query('[*].value') }}" + restic_archiver__backups: "{{ restic_archiver__backups | dict2items | json_query('[*].value') }}" when: - restic_archiver__backups | type_debug == "dict" diff --git a/tasks/logs.yml b/tasks/logs.yml index 78a8495..3c36086 100644 --- a/tasks/logs.yml +++ b/tasks/logs.yml @@ -1,5 +1,5 @@ --- -- name: create /var/log/restic/ +- name: Create /var/log/restic/ become: true ansible.builtin.file: path: /var/log/restic @@ -9,14 +9,14 @@ owner: "{{ restic_archiver__group }}" mode: 0750 -- name: install logrotate +- name: Install logrotate become: true ansible.builtin.package: name: logrotate state: present when: restic_archiver__logrotate | bool -- name: create logrotate config +- name: Create logrotate config become: true ansible.builtin.copy: src: files/logrotate.conf diff --git a/tasks/mail.yml b/tasks/mail.yml index fe86ad5..98815e6 100644 --- a/tasks/mail.yml +++ b/tasks/mail.yml @@ -1,5 +1,5 @@ --- -- name: install requirements +- name: Install requirements become: true ansible.builtin.package: name: diff --git a/tasks/main.yml b/tasks/main.yml index ff59204..096d528 100644 --- a/tasks/main.yml +++ b/tasks/main.yml @@ -1,9 +1,9 @@ --- -- name: run optional versionscheck +- name: Run optional versionscheck ansible.builtin.include_tasks: versioncheck.yml - when: submodules_versioncheck|bool + when: submodules_versioncheck | bool -- name: deploy restic template +- name: Deploy restic template ansible.builtin.template: src: templates/restic_forget_snapshots.j2 dest: /opt/restic-backup.sh @@ -12,18 +12,18 @@ mode: 0700 become: true -- name: setup logrotate +- name: Setup logrotate ansible.builtin.include_tasks: logs.yml when: restic_archiver__log_output | bool -- name: create cronjob +- name: Create cronjob ansible.builtin.include_tasks: cron.yml when: not restic_archiver__use_systemd_timer | bool -- name: create systemd timer +- name: Create systemd timer ansible.builtin.include_tasks: systemd.yml when: restic_archiver__use_systemd_timer | bool -- name: install requirements for mailing +- name: Install requirements for mailing ansible.builtin.include_tasks: mail.yml when: restic_archiver__mailsummary | bool diff --git a/tasks/systemd.yml b/tasks/systemd.yml index 16579c9..3cc2fb8 100644 --- a/tasks/systemd.yml +++ b/tasks/systemd.yml @@ -1,5 +1,5 @@ --- -- name: create restic-archiver.service +- name: Create restic-archiver.service become: true ansible.builtin.template: src: templates/restic-archiver.service.j2 @@ -8,10 +8,10 @@ owner: root group: root notify: - - systemctl daemon-reload - - systemctl enable restic-archiver.service + - Run systemctl daemon-reload + - Run systemctl enable restic-archiver.service -- name: create restic-archiver.timer +- name: Create restic-archiver.timer become: true ansible.builtin.template: src: templates/restic-archiver.timer.j2 @@ -20,5 +20,5 @@ owner: root group: root notify: - - systemctl daemon-reload - - systemctl start restic-archiver.timer + - Run systemctl daemon-reload + - Run systemctl start restic-archiver.timer diff --git a/tasks/versioncheck.yml b/tasks/versioncheck.yml index 5128cc8..dd22a1a 100644 --- a/tasks/versioncheck.yml +++ b/tasks/versioncheck.yml @@ -8,37 +8,38 @@ path: '/etc/.ansible-version' state: directory mode: 0755 - when: submodules_versioncheck|bool + when: submodules_versioncheck | bool -- name: check playbook version +- name: Check playbook version become: true ansible.builtin.slurp: src: "/etc/.ansible-version/{{ playbook_version_path }}" register: playbook_version - when: submodules_versioncheck|bool + when: submodules_versioncheck | bool ignore_errors: true failed_when: false - name: Print remote role version ansible.builtin.debug: msg: "Remote role version: {{ playbook_version.content | default('Y3VycmVudGx5IG5vdCBkZXBsb3llZAo=') | b64decode | string }}" - when: submodules_versioncheck|bool + when: submodules_versioncheck | bool - name: Print locale role version ansible.builtin.debug: - msg: "Local role version: '{{ playbook_version_number|string }}'." - when: submodules_versioncheck|bool + msg: "Local role version: '{{ playbook_version_number | string }}'." + when: submodules_versioncheck | bool - name: Check if your version is outdated ansible.builtin.fail: msg: "Your ansible module has the version '{{ playbook_version_number }}' and is outdated. You need to update it!" when: - - playbook_version.content|default("Mgo=")|b64decode|int - 1 >= playbook_version_number|int and submodules_versioncheck|bool + - playbook_version.content|default("Mgo=")|b64decode|int - 1 >= playbook_version_number|int and submodules_versioncheck | bool -- name: write new version to remote disk +- name: Write new version to remote disk become: true ansible.builtin.copy: content: "{{ playbook_version_number }}" dest: "/etc/.ansible-version/{{ playbook_version_path }}" mode: '0644' - when: submodules_versioncheck|bool + when: submodules_versioncheck | bool + tags: skip_ansible_lint_template-instead-of-copy diff --git a/templates/includes/repo_todos.sh.j2 b/templates/includes/repo_todos.sh.j2 index 7cb6f0d..6dfb1f5 100644 --- a/templates/includes/repo_todos.sh.j2 +++ b/templates/includes/repo_todos.sh.j2 @@ -4,79 +4,83 @@ Variables are defined via defaults! #} -{% macro retention_pattern(repo) -%} - {% if repo.keep_last is defined and repo.keep_last != None -%} - --keep-last {{ repo.keep_last }} - {%- else -%} - --keep-last {{ restic_archiver__keep }} - {%- endif %} \ - {% if repo.keep_hourly is defined and repo.keep_hourly != None -%} - --keep-hourly {{ repo.keep_hourly }} - {%- else -%} - --keep-hourly {{ restic_archiver__keep_hourly }} - {%- endif %} \ - {% if repo.keep_daily is defined and repo.keep_daily != None -%} - --keep-daily {{ repo.keep_daily }} - {%- else -%} - --keep-daily {{ restic_archiver__keep_daily }} - {%- endif %} \ - {% if repo.keep_weekly is defined and repo.keep_weekly != None -%} - --keep-weekly {{ repo.keep_weekly }} - {%- else -%} - --keep-weekly {{ restic_archiver__keep_weekly }} - {%- endif %} \ - {% if repo.keep_monthly is defined and repo.keep_monthly != None -%} - --keep-monthly {{ repo.keep_monthly }} - {%- else -%} - --keep-monthly {{ restic_archiver__keep_monthly }} - {%- endif %} \ - {% if repo.keep_yearly is defined and repo.keep_yearly != None -%} - --keep-yearly {{ repo.keep_yearly }} - {%- else -%} - --keep-yearly {{ restic_archiver__keep_yearly }} - {%- endif -%} - {% if repo.keep_within is defined and repo.keep_within != None %} \ - --keep-within {{ repo.keep_within }} {% endif -%} - {%- if repo.prune|default(restic_archiver__prune) %} \ - --prune {% endif %} -{%- endmacro %} +{% macro retention_pattern(repo) %} +{% if repo.keep_last is defined and repo.keep_last != None %} + --keep-last {{ repo.keep_last }} \ +{% else %} + --keep-last {{ restic_archiver__keep }} \ +{% endif %} +{% if repo.keep_hourly is defined and repo.keep_hourly != None %} + --keep-hourly {{ repo.keep_hourly }} \ +{% else %} + --keep-hourly {{ restic_archiver__keep_hourly }} \ +{% endif %} +{% if repo.keep_daily is defined and repo.keep_daily != None %} + --keep-daily {{ repo.keep_daily }} \ +{% else %} + --keep-daily {{ restic_archiver__keep_daily }} \ +{% endif %} +{% if repo.keep_weekly is defined and repo.keep_weekly != None %} + --keep-weekly {{ repo.keep_weekly }} \ +{% else %} + --keep-weekly {{ restic_archiver__keep_weekly }} \ +{% endif %} +{% if repo.keep_monthly is defined and repo.keep_monthly != None %} + --keep-monthly {{ repo.keep_monthly }} \ +{% else %} + --keep-monthly {{ restic_archiver__keep_monthly }} \ +{% endif %} +{% if repo.keep_yearly is defined and repo.keep_yearly != None %} + --keep-yearly {{ repo.keep_yearly }} \ +{% else %} + --keep-yearly {{ restic_archiver__keep_yearly }} \ +{% endif %} +{% if repo.keep_within is defined and repo.keep_within != None %} + --keep-within {{ repo.keep_within }} \ +{% endif %} +{% if repo.prune | default(restic_archiver__prune) %} + --prune +{% endif %} +{% endmacro %} -{% macro retention_archive_pattern(repo) -%} - {% if repo.keep_last is defined and repo.archive_keep_last != None -%} - --keep-last {{ repo.archive_keep_last }} - {%- else -%} - --keep-last {{ restic_archiver__archive_keep }} - {%- endif %} \ - {% if repo.keep_hourly is defined and repo.archive_keep_hourly != None -%} - --keep-hourly {{ repo.archive_keep_hourly }} - {%- else -%} - --keep-hourly {{ restic_archiver__archive_keep_hourly }} - {%- endif %} \ - {% if repo.keep_daily is defined and repo.archive_keep_daily != None -%} - --keep-daily {{ repo.archive_keep_daily }} - {%- else -%} - --keep-daily {{ restic_archiver__archive_keep_daily }} - {%- endif %} \ - {% if repo.keep_weekly is defined and repo.archive_keep_weekly != None -%} - --keep-weekly {{ repo.archive_keep_weekly }} - {%- else -%} - --keep-weekly {{ restic_archiver__archive_keep_weekly }} - {%- endif %} \ - {% if repo.keep_monthly is defined and repo.archive_keep_monthly != None -%} - --keep-monthly {{ repo.archive_keep_monthly }} - {%- else -%} - --keep-monthly {{ restic_archiver__archive_keep_monthly }} - {%- endif %} \ - {% if repo.keep_yearly is defined and repo.archive_keep_yearly != None -%} - --keep-yearly {{ repo.archive_keep_yearly }} - {%- else -%} - --keep-yearly {{ restic_archiver__archive_keep_yearly }} - {%- endif -%} - {% if repo.keep_within is defined and repo.archive_keep_within != None %} \ - --keep-within {{ repo.archive_keep_within }} {% endif -%} - {%- if repo.prune|default(restic_archiver__prune) %} \ - --prune {% endif %} -{%- endmacro %} +{% macro retention_archive_pattern(repo) %} +{% if repo.keep_last is defined and repo.archive_keep_last != None %} + --keep-last {{ repo.archive_keep_last }} \ +{% else %} + --keep-last {{ restic_archiver__archive_keep }} \ +{% endif %} +{% if repo.keep_hourly is defined and repo.archive_keep_hourly != None %} + --keep-hourly {{ repo.archive_keep_hourly }} \ +{% else %} + --keep-hourly {{ restic_archiver__archive_keep_hourly }} \ +{% endif %} +{% if repo.keep_daily is defined and repo.archive_keep_daily != None %} + --keep-daily {{ repo.archive_keep_daily }} \ +{% else %} + --keep-daily {{ restic_archiver__archive_keep_daily }} \ +{% endif %} +{% if repo.keep_weekly is defined and repo.archive_keep_weekly != None %} + --keep-weekly {{ repo.archive_keep_weekly }} \ +{% else %} + --keep-weekly {{ restic_archiver__archive_keep_weekly }} \ +{% endif %} +{% if repo.keep_monthly is defined and repo.archive_keep_monthly != None %} + --keep-monthly {{ repo.archive_keep_monthly }} \ +{% else %} + --keep-monthly {{ restic_archiver__archive_keep_monthly }} +{% endif %} +{% if repo.keep_yearly is defined and repo.archive_keep_yearly != None %} + --keep-yearly {{ repo.archive_keep_yearly }} +{% else %} + --keep-yearly {{ restic_archiver__archive_keep_yearly }} +{% endif %} +{% if repo.keep_within is defined and repo.archive_keep_within != None %} \ + --keep-within {{ repo.archive_keep_within }} +{% endif %} +{% if repo.prune | default(restic_archiver__prune) %} + --prune +{% endif %} +{% endmacro %} {# @@ -86,7 +90,7 @@ START DOING STUFF INSIDE THE RESTIC REPO FOR LOOP { # try {% if restic_archiver__mount_required %} - {% include 'includes/mounting.sh.j2' %} + {% include 'includes/mounting.sh.j2' %} {% endif %} # Settings for Server {{ repo['name'] | string }} @@ -103,7 +107,7 @@ START DOING STUFF INSIDE THE RESTIC REPO FOR LOOP echo "init $BACKUP_NAME" restic {{ restic_archiver__default_opt }} forget {{ retention_pattern(repo) }} echo "restic forget done" - {% if repo.prune|default(restic_archiver__prune) %} + {% if repo.prune | default(restic_archiver__prune) %} restic {{ restic_archiver__default_opt }} prune echo "restic prune done" {% endif %} @@ -141,16 +145,16 @@ EOT restic {{ restic_archiver__default_opt }} check {% endif %} - {% if repo.archive|default(false) %} + {% if repo.archive | default(false) %} # ARCHIVE Settings for Server "{{ repo['name'] | string }}" export RESTIC_REPOSITORY="{{ repo['archive_location'] }}" export RESTIC_PASSWORD='{{ repo['archive_password'] | regex_replace('\'', '\'\\\'\'') }}' 2>/dev/null BACKUP_NAME="{{ repo.name }}_archive" echo "init $BACKUP_NAME" - {% if restic_archiver__mount_required %} - {% include 'includes/mounting.sh.j2' %} - {% endif %} + {% if restic_archiver__mount_required %} + {% include 'includes/mounting.sh.j2' %} + {% endif %} # init repo if it does not exist if ([ -z "$(restic cat config)" ]) 2>/dev/null; then @@ -161,14 +165,14 @@ EOT export RESTIC_PASSWORD2='{{ repo['archive_password'] | regex_replace('\'', '\'\\\'\'') }}' 2>/dev/null export RESTIC_REPOSITORY="{{ repo['location'] }}" export RESTIC_PASSWORD='{{ repo['password'] | regex_replace('\'', '\'\\\'\'') }}' 2>/dev/null - {% if restic_archiver__mount_required %} - {% include 'includes/mounting.sh.j2' %} - {% endif %} + {% if restic_archiver__mount_required %} + {% include 'includes/mounting.sh.j2' %} + {% endif %} # transfer snapshots to archive restic {{ restic_archiver__default_opt }} copy - {% if repo.archive_cleanup %} + {% if repo.archive_cleanup %} # ARCHIVE CLEANUP Settings for Server "{{ repo['name'] | string }}" export RESTIC_REPOSITORY="{{ repo['archive_location'] }}" @@ -176,15 +180,15 @@ EOT BACKUP_NAME="{{ repo.name }}_archive" restic {{ restic_archiver__default_opt }} forget {{ retention_archive_pattern(repo) }} - {% if repo.prune|default(restic_archiver__prune) %} + {% if repo.prune | default(restic_archiver__prune) %} restic {{ restic_archiver__default_opt }} prune echo "restic ARCHIVE prune done" - {% endif %} + {% endif %} - {% endif %} - {% if restic_archiver__mail_report | default(false) %} + {% endif %} + {% if restic_archiver__mail_report | default(false) %} restic --quiet stats --json | python3 -c "import sys, json; jsondata=json.load(sys.stdin); print('\nexternal_archive\n', str(int(jsondata['total_size'] / 1024 / 1024 / 1024 * 1000 )/1000 ), 'GB\n ', str(jsondata['total_file_count']), ' Files.\n\n')" >> /tmp/mailcontent - {% endif %} + {% endif %} echo -e "\n

" >> /tmp/mailcontent restic {{ restic_archiver__default_opt }} check --quiet >> /tmp/mailcontent {% else %} @@ -192,7 +196,7 @@ EOT {% endif %} -} || { # catch +} | | { # catch echo -e "

ALARM, ALARM

\n

SOMETING IN $RESTIC_REPOSITORY went wrong

" >> /tmp/mailcontent awk 'NR==3{print "

ALARM, ALARM

\n

SOMETING IN $RESTIC_REPOSITORY went wrong

"}1' /tmp/mailcontent >> /tmp/mailcontentx mv /tmp/mailcontentx /tmp/mailcontent diff --git a/templates/restic-archiver.service.j2 b/templates/restic-archiver.service.j2 index 66a3d45..be41d43 100644 --- a/templates/restic-archiver.service.j2 +++ b/templates/restic-archiver.service.j2 @@ -6,6 +6,6 @@ Documentation=https://github.com/roles-ansible/ansible_role_restic_archiver.git Type=oneshot ExecStart=/opt/restic-backup.sh TimeoutStartSec=0 -{% if restic_archiver__log_output -%} +{% if restic_archiver__log_output %} StandardOutput=append:/var/log/restic/restic_archiver.log -{%- endif -%} +{% endif %} diff --git a/templates/restic_forget_snapshots.j2 b/templates/restic_forget_snapshots.j2 index d9df9e1..091b0bc 100644 --- a/templates/restic_forget_snapshots.j2 +++ b/templates/restic_forget_snapshots.j2 @@ -18,25 +18,25 @@ fi {% if restic_archiver__cache_config | bool %} - {% include 'includes/restic_cache.sh.j2' %} +{% include 'includes/restic_cache.sh.j2' %} {% endif %} {% if restic_archiver__mail_on_error | bool %} - {% include 'includes/set_send_mail_on_error_variable.sh.j2' %} +{% include 'includes/set_send_mail_on_error_variable.sh.j2' %} {% endif %} {% if restic_archiver__mail_report | default(false) %} - {% include 'includes/mail_report_header.sh.j2' %} +{% include 'includes/mail_report_header.sh.j2' %} {% endif %} {% for repo in restic_archiver__repos %} - {% include 'includes/repo_todos.sh.j2' %} +{% include 'includes/repo_todos.sh.j2' %} {% endfor %} sync {% if restic_archiver__mail_report | default(false) %} - {% include 'includes/mail_report_trailer.sh.j2' %} +{% include 'includes/mail_report_trailer.sh.j2' %} {% endif %} {% if restic_archiver__mail_on_error | bool %} diff --git a/vars/main.yml b/vars/main.yml index c869c5e..958a761 100644 --- a/vars/main.yml +++ b/vars/main.yml @@ -1,3 +1,3 @@ --- -playbook_version_number: 54 # should be int +playbook_version_number: 55 # should be int playbook_version_path: 'role-restic_archiver_roles-ansible_github.com.version'