From a29ec5b0936809459a9b92bff3e40f93e9a58b67 Mon Sep 17 00:00:00 2001 From: Frank Dornheim <524257+conloos@users.noreply.github.com> Date: Mon, 13 Mar 2023 22:08:06 +0100 Subject: [PATCH] Add Check frequency, therefore, we no longer need to distinguish between normal and large repos --- README.md | 10 +- defaults/main.yml | 14 +-- meta/arguments_specs.yml | 12 +- tasks/noauto_create_backup_user_and_group.yml | 2 - tasks/noauto_create_cronjobs.yml | 37 +----- tasks/noauto_create_timer.yml | 112 ++++++------------ templates/backup.service.j2 | 60 ++++++++++ templates/backup.timer.j2 | 13 ++ 8 files changed, 120 insertions(+), 140 deletions(-) create mode 100644 templates/backup.service.j2 create mode 100644 templates/backup.timer.j2 diff --git a/README.md b/README.md index 8a5f6df..c14dabd 100644 --- a/README.md +++ b/README.md @@ -49,7 +49,7 @@ Main features: borg_repository: m5vz9gp4@m5vz9gp4.repo.borgbase.com:repo borgmatic_timer: systemd borg_ssh_key_file: "{{ backup_user_info.home }}/.ssh/backup" - borg_ssh_command: "ssh -i {{ backup_ssh_key_file }} -o StrictHostKeyChecking=no" + borg_ssh_command: "ssh -i {{ borg_ssh_key_file }} -o StrictHostKeyChecking=no" borgmatic_timer: systemd borgbackup_user: "srv_backup" borgbackup_group: "srv_backup" @@ -116,14 +116,10 @@ $ git clone https://github.com/borgbase/ansible-role-borgbackup.git roles/ansibl - `borgmatic_check_last`: Number of archives to check. Defaults to `3` - `borgmatic_checks`: List of consistency checks. Defaults to `['repository']` - `borgmatic_config_name`: Name to use for the borgmatic config file. Defaults to `config.yaml` -- `borgmatic_cron_checks_day`: Day when cron job for infrequent checks will run. Defaults to `{{ 28 | random }}` -- `borgmatic_cron_checks_hour`: Hour when cron job for infrequent checks will run. Defaults to `{{ range(7, 24) | random }}` -- `borgmatic_cron_checks_minute`: Minute when cron job for infrequent checks will run. Defaults to `{{ 59 | random }}` -- `borgmatic_cron_hour`: Hour when regular create and prune cron job will run. Defaults to `{{ 6 | random }}` -- `borgmatic_cron_minute`: Minute when regular create and prune cron job will run. Defaults to `{{ 59 | random }}` +- `borgmatic_timer_hour`: Hour when regular create and prune cron/systemd-timer job will run. Defaults to `{{ 6 | random }}` +- `borgmatic_timer_minute`: Minute when regular create and prune cron/systemd-timer job will run. Defaults to `{{ 59 | random }}` - `borgmatic_hooks`: Hooks to monitor your backups e.g. with [Healthchecks](https://healthchecks.io/). See [official documentation](https://torsion.org/borgmatic/docs/how-to/monitor-your-backups/) for more. - `borgmatic_initialization_repo`: Auto initialization of the repo on the backup server. Defaults to `false` -- `borgmatic_large_repo`: Less frequent, monthly repo checking. Defaults to `true` - `borgmatic_timer`: If the variable is set, a timer is installed. A choice must be made between `cron` and `systemd`. - `borgmatic_relocated_repo_access_is_ok`: Bypass Borg error about a repository that has been moved. Defaults to `false` - `borgmatic_store_atime`: Store atime into archive. Defaults to `true` diff --git a/defaults/main.yml b/defaults/main.yml index b50a9f2..c8d51d0 100755 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -6,8 +6,8 @@ borg_exclude_from: [] borg_encryption_passcommand: false borg_lock_wait_time: 5 borg_ssh_key_file: "{{ backup_user_info.home }}/.ssh/backup" -borg_ssh_command: "ssh -i {{ backup_ssh_key_file }}" -# borg_ssh_command: "ssh -i {{ backup_ssh_key_file }} -o StrictHostKeyChecking=no" +borg_ssh_command: "ssh -i {{ borg_ssh_key_file }}" +# borg_ssh_command: "ssh -i {{ borg_ssh_key_file }} -o StrictHostKeyChecking=no" borg_ssh_key_type: "rsa" borg_remote_path: false borg_remote_rate_limit: 0 @@ -21,14 +21,9 @@ borgmatic_timer_cron_name: "borgmatic" borgmatic_timer: systemd borgmatic_timer_hour: "{{ range(0, 5) | random(seed=inventory_hostname) }}" borgmatic_timer_minute: "{{ range(0, 59) | random(seed=inventory_hostname) }}" -borgmatic_timer_day_of_the_week: "{{ ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'] | random }}" # or "" -borgmatic_timer_checks_day: "*" # "{{ range(1, 28) | random(seed=inventory_hostname) }}" -borgmatic_timer_checks_hour: "{{ range(9, 24) | random(seed=inventory_hostname) }}" -borgmatic_timer_checks_minute: "{{ 59 | random(seed=inventory_hostname) }}" borg_install_method: pip borgmatic_config_name: config.yaml -borgmatic_large_repo: true borgmatic_hooks: on_error: - echo "`date` - Error while creating a backup." @@ -37,7 +32,10 @@ borgmatic_hooks: after_backup: - echo "`date` - Finished backup." borgmatic_checks: - - repository + - name: repository + frequency: "2 Weeks" + - name: archives + frequency: "1 month" borgmatic_check_last: 3 borgmatic_store_atime: true borgmatic_store_ctime: true diff --git a/meta/arguments_specs.yml b/meta/arguments_specs.yml index a1a3321..d10b9b4 100644 --- a/meta/arguments_specs.yml +++ b/meta/arguments_specs.yml @@ -49,14 +49,6 @@ argument_specs: type: str default: root description: Name of the Group to create Backups (Service Account) - backup_id_rsa: - type: path - required: false - description: Path to the ssh-cert for the backup user - backup_id_rsa_pub: - type: path - required: false - description: Path to the ssh-key for the backup user borg_source_directories: type: List default: "/etc/hostname" @@ -109,6 +101,10 @@ argument_specs: type: int required: false description: Remote network upload rate limit in kiBytes/second. + borg_ssh_key_file: + type: str + required: false + description: Path to ssh-key borg_ssh_command: type: str description: Command to use instead of just ssh. This can be used to specify ssh options. diff --git a/tasks/noauto_create_backup_user_and_group.yml b/tasks/noauto_create_backup_user_and_group.yml index fc3a339..33de866 100644 --- a/tasks/noauto_create_backup_user_and_group.yml +++ b/tasks/noauto_create_backup_user_and_group.yml @@ -32,7 +32,5 @@ nopassword: true commands: - "/opt/borgmatic/bin/borg" - - "/usr/local/bin/borgmatic -C -p -c /etc/borgmatic/{{ borgmatic_config_name }}" - - "/usr/local/bin/borgmatic -k -c /etc/borgmatic/{{ borgmatic_config_name }}" - "/usr/local/bin/borgmatic -c /etc/borgmatic/{{ borgmatic_config_name }}" ... diff --git a/tasks/noauto_create_cronjobs.yml b/tasks/noauto_create_cronjobs.yml index ca1a298..b160800 100644 --- a/tasks/noauto_create_cronjobs.yml +++ b/tasks/noauto_create_cronjobs.yml @@ -1,42 +1,7 @@ --- -- name: Add cron-job for borgmatic (large repo, create and check separate) +- name: Add cron-job for borgmatic when: - borgmatic_timer is defined and borgmatic_timer == "cron" - - borgmatic_large_repo - tags: - - install_backup - block: - # I don't like to re-do the installation of packages here, but cron - # should not be one of the automatically installed packages since there - # is systemd-timer as an alternative. - - name: Install general dependencies (cron) - ansible.builtin.package: - name: "{{ borg_cron_package }}" - state: present - - - name: Add cron job for regular create and prune - cron: - name: "{{ borgmatic_timer_cron_name }}" - hour: "{{ borgmatic_timer_hour }}" - minute: "{{ borgmatic_timer_minute }}" - user: "{{ borgbackup_user }}" - cron_file: "{{ borgmatic_timer_cron_name }}" - job: "/usr/local/bin/borgmatic -C -p -c /etc/borgmatic/{{ borgmatic_config_name }}" - - - name: Add cron job for infrequent checks - cron: - name: "{{ borgmatic_timer_cron_name }}-check" - day: "{{ borgmatic_timer_checks_day }}" - hour: "{{ borgmatic_timer_checks_hour }}" - minute: "{{ borgmatic_timer_checks_minute }}" - user: "{{ borgbackup_user }}" - cron_file: "{{ borgmatic_timer_cron_name }}" - job: "/usr/local/bin/borgmatic -k -c /etc/borgmatic/{{ borgmatic_config_name }}" - -- name: Add cron-job for borgmatic (normal-sized repo) - when: - - borgmatic_timer is defined and borgmatic_timer == "cron" - - not borgmatic_large_repo tags: - install_backup block: diff --git a/tasks/noauto_create_timer.yml b/tasks/noauto_create_timer.yml index 233be15..b109bbc 100644 --- a/tasks/noauto_create_timer.yml +++ b/tasks/noauto_create_timer.yml @@ -5,85 +5,39 @@ tags: - install_backup block: - - name: Add systemd.timer for borgmatic (large repo, create and check separate) - when: borgmatic_large_repo - block: - - name: Copy systemd files - ansible.builtin.template: - src: "{{ item.src }}" - dest: "{{ item.dest }}" - owner: root - group: root - backup: true - mode: "{{ item.mode }}" - with_items: - - { src: "backup_large_repo_check.timer.j2", dest: "/usr/lib/systemd/system/backup_large_repo_check.timer", mode: "0644" } - - { src: "backup_large_repo_check.service.j2", dest: "/usr/lib/systemd/system/backup_large_repo_check.service", mode: "0644" } - - { src: "backup_large_repo.timer.j2", dest: "/usr/lib/systemd/system/backup_large_repo.timer", mode: "0644" } - - { src: "backup_large_repo.service.j2", dest: "/usr/lib/systemd/system/backup_large_repo.service", mode: "0644" } + - name: Copy systemd files + ansible.builtin.template: + src: "{{ item.src }}" + dest: "{{ item.dest }}" + owner: root + group: root + backup: true + mode: "{{ item.mode }}" + with_items: + - { src: "backup.timer.j2", dest: "/usr/lib/systemd/system/backup.timer", mode: "0644" } + - { src: "backup.service.j2", dest: "/usr/lib/systemd/system/backup.service", mode: "0644" } - - name: Populate service facts (large repo, create and check separate) - ansible.builtin.service_facts: + - name: Populate service facts + ansible.builtin.service_facts: - - name: Restart borgmatic services (large repo, create and check separate) - ansible.builtin.systemd: - name: "{{ item }}" - state: restarted - enabled: true - masked: false - daemon_reload: true - when: "item in services" - with_items: - - "backup_large_repo_check.service" - - "backup_large_repo.service" - - # bug: Need own section without masked else the timer are skipped - - name: Restart borgmatic timers (large repo, create and check separate) - ansible.builtin.systemd: - name: "{{ item }}" - state: started - enabled: true - daemon_reload: true - with_items: - - "backup_large_repo_check.timer" - - "backup_large_repo.timer" - - - name: Add systemd.timer for borgmatic (normal-sized repo) - when: not borgmatic_large_repo - block: - - name: Copy systemd files (normal-sized repo) - ansible.builtin.template: - src: "{{ item.src }}" - dest: "{{ item.dest }}" - owner: root - group: root - backup: true - mode: "{{ item.mode }}" - with_items: - - { src: "backup_normal_repo.timer.j2", dest: "/usr/lib/systemd/system/backup_normal_repo.timer", mode: "0644" } - - { src: "backup_normal_repo.service.j2", dest: "/usr/lib/systemd/system/backup_normal_repo.service", mode: "0644" } - - - name: Populate service facts - ansible.builtin.service_facts: - - - name: Restart borgmatic services (normal-sized repo) - ansible.builtin.systemd: - name: "{{ item }}" - state: started - enabled: true - masked: false - daemon_reload: true - when: "item in services" - with_items: - - backup_normal_repo.service - - # bug: Need own section without masked else the timer ar skipped - - name: Restart borgmatic timers (normal-sized repo) - ansible.builtin.systemd: - name: "{{ item }}" - state: started - enabled: true - daemon_reload: true - with_items: - - "backup_normal_repo.timer" + - name: Restart borgmatic services + ansible.builtin.systemd: + name: "{{ item }}" + state: started + enabled: true + masked: false + daemon_reload: true + when: "item in services" + with_items: + - backup.service + + # bug: Need own section without masked else the timer are skipped + - name: Restart borgmatic timers + ansible.builtin.systemd: + name: "{{ item }}" + state: started + enabled: true + daemon_reload: true + with_items: + - "backup.timer" ... diff --git a/templates/backup.service.j2 b/templates/backup.service.j2 new file mode 100644 index 0000000..ebd9186 --- /dev/null +++ b/templates/backup.service.j2 @@ -0,0 +1,60 @@ +# Managed by Ansible, please don't edit manually + +[Unit] +Description=borgmatic backup +Wants=backup_normal_repo.timer +Wants=network-online.target +After=network-online.target +# Prevent borgmatic from running unless the machine is plugged into power. Remove this line if you +# want to allow borgmatic to run anytime. +ConditionACPower=true + +[Service] +Type=oneshot +User={{ borgbackup_user }} +ExecStart=/usr/local/bin/borgmatic -c /etc/borgmatic/{{ borgmatic_config_name }} + +# Source: https://projects.torsion.org/borgmatic-collective/borgmatic/raw/branch/master/sample/systemd/borgmatic.service +# Security settings for systemd running as root, optional but recommended to improve security. You +# can disable individual settings if they cause problems for your use case. For more details, see +# the systemd manual: https://www.freedesktop.org/software/systemd/man/systemd.exec.html +LockPersonality=true +# Certain borgmatic features like Healthchecks integration need MemoryDenyWriteExecute to be off. +# But you can try setting it to "yes" for improved security if you don't use those features. +MemoryDenyWriteExecute=no +NoNewPrivileges=yes +PrivateDevices=yes +PrivateTmp=yes +ProtectClock=yes +ProtectControlGroups=yes +ProtectHostname=yes +ProtectKernelLogs=yes +ProtectKernelModules=yes +ProtectKernelTunables=yes +RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6 AF_NETLINK +RestrictNamespaces=yes +RestrictRealtime=yes +RestrictSUIDSGID=yes +SystemCallArchitectures=native +SystemCallFilter=@system-service +SystemCallErrorNumber=EPERM +# To restrict write access further, change "ProtectSystem" to "strict" and uncomment +# "ReadWritePaths", "ReadOnlyPaths", "ProtectHome", and "BindPaths". Then add any local repository +# paths to the list of "ReadWritePaths" and local backup source paths to "ReadOnlyPaths". This +# leaves most of the filesystem read-only to borgmatic. +ProtectSystem=full +# ReadWritePaths=-/mnt/my_backup_drive +# ReadOnlyPaths=-/var/lib/my_backup_source +# This will mount a tmpfs on top of /root and pass through needed paths +# ProtectHome=tmpfs +# BindPaths=-/root/.cache/borg -/root/.config/borg -/root/.borgmatic + +# May interfere with running external programs within borgmatic hooks. +# CapabilityBoundingSet=CAP_DAC_READ_SEARCH CAP_NET_RAW + +# Lower CPU and I/O priority. +Nice=19 +CPUSchedulingPolicy=batch +IOSchedulingClass=best-effort +IOSchedulingPriority=7 +IOWeight=100 diff --git a/templates/backup.timer.j2 b/templates/backup.timer.j2 new file mode 100644 index 0000000..2ff402c --- /dev/null +++ b/templates/backup.timer.j2 @@ -0,0 +1,13 @@ +# Managed by Ansible, please don't edit manually + +[Unit] +Description=Start creating of Backups - see: https://www.freedesktop.org/software/systemd/man/systemd.time.html# + +[Timer] +# Day-of-the-Week Year-Month-Day Hour:Minutes:Seconds +# Persistent -> resume backup after shutdown +OnCalendar= *-*-* {{ borgmatic_timer_hour }}:{{ borgmatic_timer_minute }}:00 +Persistent=true + +[Install] +WantedBy=timers.target \ No newline at end of file