mirror of
https://github.com/borgbase/ansible-role-borgbackup.git
synced 2025-07-24 13:48:08 +02:00
Merge 99909dc87c
into 0e5e876626
This commit is contained in:
commit
68df6333ec
@ -1,3 +1,4 @@
|
||||
---
|
||||
skip_list:
|
||||
- fqcn-builtins
|
||||
- var-naming[no-role-prefix]
|
2
.github/workflows/main.yml
vendored
2
.github/workflows/main.yml
vendored
@ -19,3 +19,5 @@ jobs:
|
||||
# uses: mxschmitt/action-tmate@v3.5
|
||||
- name: Test using Molecule
|
||||
run: molecule test
|
||||
- name: Test Docker scenario using Molecule
|
||||
run: molecule test -s docker
|
26
README.md
26
README.md
@ -59,7 +59,23 @@ Works great with [BorgBase.com](https://www.borgbase.com) - Simple and Secure Ho
|
||||
keep_monthly: 6
|
||||
```
|
||||
|
||||
## Example playbook using Docker
|
||||
|
||||
```
|
||||
- hosts: all
|
||||
roles:
|
||||
- role: borgbase.ansible_role_borgbackup
|
||||
borg_install_method: docker
|
||||
borgmatic_timer: cron
|
||||
borg_repository: ssh://xxxxxx@xxxxxx.repo.borgbase.com/./repo
|
||||
borg_encryption_passphrase: CHANGEME
|
||||
borg_source_directories:
|
||||
- /var/www
|
||||
borg_ssh_private_key: !vault |
|
||||
$ANSIBLE_VAULT;1.1;AES256
|
||||
65373636303732303236313234666230386333636233313631663135323734626265616532633064
|
||||
316334...truncated
|
||||
```
|
||||
|
||||
## Installation
|
||||
|
||||
@ -87,7 +103,7 @@ $ git clone https://github.com/borgbase/ansible-role-borgbackup.git roles/ansibl
|
||||
- `borg_encryption_passphrase`: Password to use for repokey or keyfile. Empty if repo is unencrypted.
|
||||
- `borg_exclude_from`: Read exclude patterns from one or more separate named files, one pattern per line.
|
||||
- `borg_exclude_patterns`: Paths or patterns to exclude from backup. See [official documentation](https://borgbackup.readthedocs.io/en/stable/usage/help.html#borg-help-patterns) for more.
|
||||
- `borg_install_method`: By default `pip` is used to install borgmatic. To install via your distributions package manager set this to `package` and (if needed) overwrite the `borg_distro_packages` variable to contain your distributions package names required to install borgmatic. Note that many distributions ship outdated versions of borgbackup and borgmatic; use at your own risk.
|
||||
- `borg_install_method`: By default `pip` is used to install borgmatic. To install via your distributions package manager set this to `package` and (if needed) overwrite the `borg_distro_packages` variable to contain your distributions package names required to install borgmatic. Note that many distributions ship outdated versions of borgbackup and borgmatic; use at your own risk. To install via a Docker container, set this to "docker". Docker must be installed on target host.
|
||||
- `borg_require_epel`: When using `borg_install_method: package` on RHEL-based distributions, the EPEL repo is required. To disable the check (e.g. when using a custom mirror instead of the `epel-release` package), set this to `false`. Defaults to `{{ ansible_os_family == 'RedHat' and ansible_distribution != 'Fedora' }}` (i.e. `true` on Enterprise Linux-based distros).
|
||||
- `borg_lock_wait_time`: Config maximum seconds to wait for acquiring a repository/cache lock. Defaults to 5 seconds.
|
||||
- `borg_one_file_system`: Don't cross file-system boundaries. Defaults to `true`
|
||||
@ -99,6 +115,7 @@ $ git clone https://github.com/borgbase/ansible-role-borgbackup.git roles/ansibl
|
||||
- `borg_ssh_key_name`: Name of the SSH public and pivate key. Default `id_ed25519`
|
||||
- `borg_ssh_key_file_path`: SSH-key to be used. Default `~/.ssh/{{ borg_ssh_key_name }}`
|
||||
- `borg_ssh_key_type`: The algorithm used to generate the SSH private key. Choose: `rsa`, `dsa`, `rsa1`, `ecdsa`, `ed25519`. Default: `ed25519`
|
||||
- `borg_ssh_private_key`: Content of the ssh private key, may you want to provide it. Only keys without passphrase is supported. Most useful for Docker deployments. IMPORTANT! Be sure to provide the content of this variable via an Ansible Vault.
|
||||
- `borg_ssh_command`: Command to use instead of just "ssh". This can be used to specify SSH options.
|
||||
- `borg_version`: Force a specific borg version to be installed
|
||||
- `borg_venv_path`: Path to store the venv for `borg(backup)` and `borgmatic`
|
||||
@ -115,9 +132,12 @@ $ git clone https://github.com/borgbase/ansible-role-borgbackup.git roles/ansibl
|
||||
- `borgmatic_store_ctime`: Store ctime into archive. Defaults to `true`
|
||||
- `borgmatic_version`: Force a specific borgmatic version to be installed
|
||||
|
||||
- `borg_user`: Name of the User to create Backups (service account)
|
||||
- `borg_group`: Name of the Group to create Backups (service account)
|
||||
- `borg_user`: Name of the User to create Backups (service account). When using Docker, must be root.
|
||||
- `borg_group`: Name of the Group to create Backups (service account). When using Docker, must be root.
|
||||
|
||||
- `borgmatic_docker_image_name`: When using borg_install_method=docker, name docker image to build. Defaults to `ansible_borgmatic`
|
||||
- `borgmatic_docker_container_name`: When using borg_install_method=docker, name of the docker container. Defaults to `ansible_borgmatic`
|
||||
- `borgmatic_docker_timezone`: Timezone to use when using borg_install_method=docker. Defaults to `UTC`
|
||||
|
||||
## Contributing
|
||||
|
||||
|
@ -46,4 +46,8 @@ borgmatic_version: ">=1.7.11"
|
||||
borg_venv_path: "/opt/borgmatic"
|
||||
borg_user: "root"
|
||||
borg_group: "root"
|
||||
|
||||
borgmatic_docker_image_name: "ansible_borgmatic"
|
||||
borgmatic_docker_container_name: "ansible_borgmatic"
|
||||
borgmatic_docker_timezone: "UTC"
|
||||
...
|
||||
|
@ -30,12 +30,14 @@ argument_specs:
|
||||
type: str
|
||||
required: false
|
||||
default: pip
|
||||
choices: [pip, package, docker]
|
||||
description: |
|
||||
By default pip is used to install borgmatic.
|
||||
To install via your distributions package manager set this to package and (if needed)
|
||||
overwrite the borg_distro_packages variable to contain your distributions package names
|
||||
required to install borgmatic.
|
||||
Note that many distributions ship outdated versions of borgbackup and borgmatic; use at your own risk.
|
||||
To install via a Docker container, set this to "docker". Docker must be installed on target host
|
||||
borgmatic_config_name:
|
||||
type: str
|
||||
required: false
|
||||
@ -44,11 +46,11 @@ argument_specs:
|
||||
borg_user:
|
||||
type: str
|
||||
default: root
|
||||
description: Name of the User to create Backups (Service Account)
|
||||
description: Name of the User to create Backups (Service Account). When using Docker, must be root.
|
||||
borg_group:
|
||||
type: str
|
||||
default: root
|
||||
description: Name of the Group to create Backups (Service Account)
|
||||
description: Name of the Group to create Backups (Service Account). When using Docker, must be root.
|
||||
borg_source_directories:
|
||||
type: List
|
||||
default: "/etc/hostname"
|
||||
@ -105,6 +107,10 @@ argument_specs:
|
||||
type: str
|
||||
required: false
|
||||
description: Path to ssh-key
|
||||
borg_ssh_private_key:
|
||||
type: str
|
||||
required: false
|
||||
description: Content of the ssh private key, may you want to provide it. Only keys without passphrase is supported. Most useful for Docker deployments. IMPORTANT! Be sure to provide the content of this variable via an Ansible Vault.
|
||||
borg_ssh_command:
|
||||
type: str
|
||||
description: Command to use instead of just ssh. This can be used to specify ssh options.
|
||||
@ -180,3 +186,18 @@ argument_specs:
|
||||
type: str
|
||||
required: false
|
||||
description: Name of the SSH public and private key
|
||||
borgmatic_docker_image_name:
|
||||
type: str
|
||||
required: false
|
||||
default: ansible_borgmatic
|
||||
description: When using borg_install_method=docker, name docker image to build
|
||||
borgmatic_docker_container_name:
|
||||
type: str
|
||||
required: false
|
||||
default: ansible_borgmatic
|
||||
description: When using borg_install_method=docker, name of the docker container
|
||||
borgmatic_docker_timezone:
|
||||
type: str
|
||||
required: false
|
||||
default: UTC
|
||||
description: Timezone to use when using borg_install_method=docker
|
||||
|
@ -21,6 +21,7 @@ galaxy_info:
|
||||
- name: ArchLinux
|
||||
versions:
|
||||
- all
|
||||
- name: Docker
|
||||
galaxy_tags:
|
||||
- backup
|
||||
- cloud
|
||||
|
@ -18,6 +18,6 @@ RUN if [ $(command -v apt-get) ]; then apt-get update && apt-get install -y pyth
|
||||
elif [ $(command -v dnf) ]; then dnf makecache && dnf --assumeyes install /usr/bin/python3 /usr/bin/python3-config /usr/bin/dnf-3 sudo bash iproute && dnf clean all; \
|
||||
elif [ $(command -v yum) ]; then yum makecache fast && yum install -y /usr/bin/python /usr/bin/python2-config sudo yum-plugin-ovl bash iproute && sed -i 's/plugins=0/plugins=1/g' /etc/yum.conf && yum clean all; \
|
||||
elif [ $(command -v zypper) ]; then zypper refresh && zypper install -y python sudo bash python-xml iproute2 && zypper clean -a; \
|
||||
elif [ $(command -v apk) ]; then apk update && apk add --no-cache python sudo bash ca-certificates; \
|
||||
elif [ $(command -v apk) ]; then apk update && apk add --no-cache python3 sudo bash ca-certificates; \
|
||||
elif [ $(command -v pacman) ]; then pacman --noconfirm -Suy python python-pip sudo openssh; \
|
||||
elif [ $(command -v xbps-install) ]; then xbps-install -Syu && xbps-install -y python sudo bash ca-certificates iproute2 && xbps-remove -O; fi
|
||||
|
@ -5,11 +5,13 @@
|
||||
- name: Set ssh server package name for non-Archlinux ansible_os_family
|
||||
set_fact:
|
||||
openssh_package: "openssh-server"
|
||||
pip3_extra_args: ""
|
||||
when: ansible_os_family != "Archlinux"
|
||||
|
||||
- name: Set ssh server package name for Archlinux ansible_os_family
|
||||
- name: Set ssh server package name and pip3 argument for Archlinux ansible_os_family
|
||||
set_fact:
|
||||
openssh_package: "openssh"
|
||||
pip3_extra_args: "--break-system-packages"
|
||||
when: ansible_os_family == "Archlinux"
|
||||
|
||||
- name: Install openssh
|
||||
@ -46,3 +48,5 @@
|
||||
pip:
|
||||
name: yamllint
|
||||
executable: pip3
|
||||
extra_args: "{{ pip3_extra_args }}"
|
||||
|
||||
|
@ -4,10 +4,13 @@
|
||||
tasks:
|
||||
- name: Ensure Borgmatic is installed correctly
|
||||
command: borgmatic --version
|
||||
changed_when: false
|
||||
|
||||
- name: Ensure Borg is installed correctly
|
||||
command: borgmatic borg --version
|
||||
changed_when: false
|
||||
|
||||
- name: Ensure produced YAML is valid
|
||||
command: |
|
||||
yamllint -d "{extends: relaxed, rules: {line-length: {max: 120}}}" /etc/borgmatic/config.yaml
|
||||
changed_when: false
|
||||
|
23
molecule/docker/Dockerfile.j2
Normal file
23
molecule/docker/Dockerfile.j2
Normal file
@ -0,0 +1,23 @@
|
||||
# Molecule managed
|
||||
|
||||
{% if item.registry is defined %}
|
||||
FROM {{ item.registry.url }}/{{ item.image }}
|
||||
{% else %}
|
||||
FROM {{ item.image }}
|
||||
{% endif %}
|
||||
|
||||
{% if item.env is defined %}
|
||||
{% for var, value in item.env.items() %}
|
||||
{% if value %}
|
||||
ENV {{ var }} {{ value }}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
RUN if [ $(command -v apt-get) ]; then apt-get update && apt-get install -y python3 python3-pip sudo bash ca-certificates iproute2 python3-apt aptitude && apt-get clean; \
|
||||
elif [ $(command -v dnf) ]; then dnf makecache && dnf --assumeyes install /usr/bin/python3 /usr/bin/python3-config /usr/bin/dnf-3 sudo bash iproute && dnf clean all; \
|
||||
elif [ $(command -v yum) ]; then yum makecache fast && yum install -y /usr/bin/python /usr/bin/python2-config sudo yum-plugin-ovl bash iproute && sed -i 's/plugins=0/plugins=1/g' /etc/yum.conf && yum clean all; \
|
||||
elif [ $(command -v zypper) ]; then zypper refresh && zypper install -y python sudo bash python-xml iproute2 && zypper clean -a; \
|
||||
elif [ $(command -v apk) ]; then apk update && apk add --no-cache python3 sudo bash ca-certificates; \
|
||||
elif [ $(command -v pacman) ]; then pacman --noconfirm -Suy python python-pip sudo openssh; \
|
||||
elif [ $(command -v xbps-install) ]; then xbps-install -Syu && xbps-install -y python sudo bash ca-certificates iproute2 && xbps-remove -O; fi
|
22
molecule/docker/INSTALL.rst
Normal file
22
molecule/docker/INSTALL.rst
Normal file
@ -0,0 +1,22 @@
|
||||
*******
|
||||
Docker driver installation guide
|
||||
*******
|
||||
|
||||
Requirements
|
||||
============
|
||||
|
||||
* Docker Engine
|
||||
|
||||
Install
|
||||
=======
|
||||
|
||||
Please refer to the `Virtual environment`_ documentation for installation best
|
||||
practices. If not using a virtual environment, please consider passing the
|
||||
widely recommended `'--user' flag`_ when invoking ``pip``.
|
||||
|
||||
.. _Virtual environment: https://virtualenv.pypa.io/en/latest/
|
||||
.. _'--user' flag: https://packaging.python.org/tutorials/installing-packages/#installing-to-the-user-site
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ pip install 'molecule[docker]'
|
96
molecule/docker/converge.yml
Normal file
96
molecule/docker/converge.yml
Normal file
@ -0,0 +1,96 @@
|
||||
---
|
||||
- name: Converge
|
||||
hosts: all
|
||||
pre_tasks:
|
||||
- name: Set ssh server package name for non-Archlinux ansible_os_family
|
||||
set_fact:
|
||||
openssh_package: "openssh-server"
|
||||
pip3_extra_args: ""
|
||||
when: ansible_os_family != "Archlinux"
|
||||
|
||||
- name: Set ssh server package name and pip3 argument for Archlinux ansible_os_family
|
||||
set_fact:
|
||||
openssh_package: "openssh"
|
||||
pip3_extra_args: "--break-system-packages"
|
||||
when: ansible_os_family == "Archlinux"
|
||||
|
||||
- name: Install openssh
|
||||
package:
|
||||
name: "{{ openssh_package }}"
|
||||
state: present
|
||||
|
||||
- name: Define borg_source_directories
|
||||
ansible.builtin.set_fact:
|
||||
borg_source_directories_tmp:
|
||||
- /srv/www
|
||||
- /var/lib/automysqlbackup
|
||||
|
||||
- name: Create backup source folders on the docker host
|
||||
ansible.builtin.file:
|
||||
path: "{{ item }}"
|
||||
mode: "0777"
|
||||
state: directory
|
||||
with_items: "{{ borg_source_directories_tmp }}"
|
||||
|
||||
- name: Define borg_repository
|
||||
ansible.builtin.set_fact:
|
||||
borg_repository_tmp:
|
||||
- m5vz9gp4@m5vz9gp4.repo.borgbase.com:repo
|
||||
- /local_borg_repo
|
||||
|
||||
- name: Create local repository folders on the docker host
|
||||
ansible.builtin.file:
|
||||
path: "{{ item }}"
|
||||
mode: "0777"
|
||||
state: directory
|
||||
with_items: "{{ borg_repository_tmp }}"
|
||||
when: item[0] == "/"
|
||||
|
||||
roles:
|
||||
- role: borgbase.ansible_role_borgbackup
|
||||
borg_install_method: docker
|
||||
borgmatic_timer: cron
|
||||
borg_repository: "{{ borg_repository_tmp }}"
|
||||
borg_encryption_passphrase: CHANGEME
|
||||
borg_source_directories: "{{ borg_source_directories_tmp }}"
|
||||
borg_exclude_patterns:
|
||||
- /srv/www/old-sites
|
||||
borg_retention_policy:
|
||||
keep_hourly: 3
|
||||
keep_daily: 7
|
||||
keep_weekly: 4
|
||||
keep_monthly: 6
|
||||
borgmatic_hooks:
|
||||
before_backup:
|
||||
- echo "`date` - Starting backup."
|
||||
postgresql_databases:
|
||||
- name: users
|
||||
hostname: database1.example.org
|
||||
port: 5433
|
||||
borg_ssh_private_key: !vault |
|
||||
$ANSIBLE_VAULT;1.1;AES256
|
||||
65373636303732303236313234666230386333636233313631663135323734626265616532633064
|
||||
3163346333616539663732636366626535326238623761320a336130633135643735613433636538
|
||||
33333336656238306163303431393562303863633137646337633861346265353131396434393531
|
||||
6564386438356330380a373138353364316535653338396164383861396538333336666436663832
|
||||
32613439616136313331333336636232323231623363633661656632316237653633363466313734
|
||||
35316262653366373137393761393835643166666436333635383334643636616436623030376234
|
||||
33343565363863613161373561616237313138633765376263656536303565363838376163313963
|
||||
37656431316335663030336236633663313937353362653639303836366436383334373132666334
|
||||
39313562316330613131383738613136616631336461626362313764313637356233373437613962
|
||||
31363564643266353737656261613232366336386230333963393935353763343236333564376462
|
||||
36653538363131616133653463613633343036363931316334613136653265636262313235366434
|
||||
31306562363034336431373535393364346435323130386265346431343836613135353430366534
|
||||
61323861653464313763303261656430393930623664396630666133383038313939303030396362
|
||||
34363435316434656462366339346637396134623337633133386638646463633063363133656164
|
||||
35396237366363383637333662366437633361356466616137623362623439323433656562636238
|
||||
66633964323831386435306163343566666533663363343262346332373764366635643961333130
|
||||
63346431326432313234653132383664396165313538346161316264653235616161353833633234
|
||||
31343663346434633863393934653631376334346666346437366639613032343632356635613932
|
||||
62306361343336386435653939386339343066366531356632643730643330353931663239326130
|
||||
39346364363263363332363637616133323761636437313138633630363237383363393432386362
|
||||
33633330323536346430636234373032346663336630623334363363393661376531376337313066
|
||||
64626434356535346461326339376435643738353463343035306433343630653335643635613939
|
||||
37323564323130356338643237383966313539663132656533656434626166373839653435343835
|
||||
62373131393235333934356133643963613665626532643164343063666632626561666330373930
|
||||
6132
|
21
molecule/docker/molecule.yml
Normal file
21
molecule/docker/molecule.yml
Normal file
@ -0,0 +1,21 @@
|
||||
---
|
||||
dependency:
|
||||
name: galaxy
|
||||
driver:
|
||||
name: docker
|
||||
platforms:
|
||||
- name: docker-dind # Based on Alpine
|
||||
image: docker:dind
|
||||
privileged: True # required to have access to the dind
|
||||
command: /usr/local/bin/dockerd-entrypoint.sh # Starts docker daemon
|
||||
provisioner:
|
||||
name: ansible
|
||||
config_options:
|
||||
defaults:
|
||||
vault_password_file: "${MOLECULE_SCENARIO_DIRECTORY}/vault.pw"
|
||||
verifier:
|
||||
name: ansible
|
||||
lint: |
|
||||
set -e
|
||||
yamllint .
|
||||
ansible-lint .
|
1
molecule/docker/vault.pw
Normal file
1
molecule/docker/vault.pw
Normal file
@ -0,0 +1 @@
|
||||
password
|
33
molecule/docker/verify.yml
Normal file
33
molecule/docker/verify.yml
Normal file
@ -0,0 +1,33 @@
|
||||
---
|
||||
- name: Verify
|
||||
hosts: all
|
||||
tasks:
|
||||
- name: Set docker_cmd
|
||||
ansible.builtin.set_fact:
|
||||
docker_cmd: docker exec -i ansible_borgmatic
|
||||
|
||||
- name: Ensure Borgmatic is installed correctly
|
||||
command: "{{ docker_cmd }} borgmatic --version"
|
||||
changed_when: false
|
||||
|
||||
- name: Ensure Borg is installed correctly
|
||||
command: "{{ docker_cmd }} borgmatic borg --version"
|
||||
changed_when: false
|
||||
|
||||
- name: Ensure produced YAML is valid
|
||||
ansible.builtin.shell: |
|
||||
{{ docker_cmd }} pip3 install yamllint && \
|
||||
{{ docker_cmd }} yamllint --list-files -d "{extends: relaxed, rules: {line-length: {max: 120}}}" /etc/borgmatic/config.yaml
|
||||
changed_when: false
|
||||
|
||||
- name: Ensure modified source path name is present in the config instead of the original
|
||||
command: "{{ docker_cmd }} grep /sources/var/lib/automysqlbackup /etc/borgmatic/config.yaml"
|
||||
changed_when: false
|
||||
|
||||
- name: Ensure modified local repo path name is present in the config instead of the original
|
||||
command: "{{ docker_cmd }} grep /repositories/local_borg_repo /etc/borgmatic/config.yaml"
|
||||
changed_when: false
|
||||
|
||||
- name: Ensure supercronic is running
|
||||
command: "{{ docker_cmd }} pgrep supercronic"
|
||||
changed_when: false
|
@ -19,6 +19,7 @@
|
||||
- "{{ ansible_lsb.id }}.yml"
|
||||
|
||||
- name: Install general dependencies (openssh)
|
||||
when: borg_install_method != "docker"
|
||||
ansible.builtin.package:
|
||||
name: "{{ borg_dep_packages }}"
|
||||
state: present
|
||||
|
@ -1,25 +1,29 @@
|
||||
---
|
||||
# So in different positions in that role we need the user home
|
||||
# Since we cannot be sure that this FSH is compatible we will determine it.
|
||||
- name: Get home dir
|
||||
- name: User management
|
||||
when:
|
||||
- borg_user == "root"
|
||||
- borg_install_method != "docker"
|
||||
block:
|
||||
- name: Get home if borg_user == "root"
|
||||
ansible.builtin.user:
|
||||
name: "{{ borg_user }}"
|
||||
state: present
|
||||
register: user_info
|
||||
changed_when: false
|
||||
check_mode: true # Important, otherwise user will be created
|
||||
- name: Get home dir
|
||||
when:
|
||||
- borg_user == "root"
|
||||
block:
|
||||
- name: Get home if borg_user == "root"
|
||||
ansible.builtin.user:
|
||||
name: "{{ borg_user }}"
|
||||
state: present
|
||||
register: user_info
|
||||
changed_when: false
|
||||
check_mode: true # Important, otherwise user will be created
|
||||
|
||||
- name: Save the user_info, we need them for the home_dir
|
||||
ansible.builtin.set_fact:
|
||||
backup_user_info: "{{ user_info }}"
|
||||
- name: Save the user_info, we need them for the home_dir
|
||||
ansible.builtin.set_fact:
|
||||
backup_user_info: "{{ user_info }}"
|
||||
|
||||
- name: Create user if borg_user != "root"
|
||||
when:
|
||||
- borg_user != "root"
|
||||
ansible.builtin.include_tasks:
|
||||
file: noauto_create_backup_user_and_group.yml
|
||||
- name: Create user if borg_user != "root"
|
||||
when:
|
||||
- borg_user != "root"
|
||||
ansible.builtin.include_tasks:
|
||||
file: noauto_create_backup_user_and_group.yml
|
||||
...
|
||||
|
@ -1,28 +1,58 @@
|
||||
---
|
||||
- name: Create SSH key (if neeeded) for {{ borg_user }}
|
||||
- name: Create ssh key
|
||||
when:
|
||||
- borg_install_method != "docker"
|
||||
block:
|
||||
- name: Ensure directory exist
|
||||
ansible.builtin.file:
|
||||
path: "{{ backup_user_info.home }}/.ssh/"
|
||||
state: directory
|
||||
mode: "0700"
|
||||
owner: "{{ borg_user }}"
|
||||
group: "{{ borg_group }}"
|
||||
- name: Create SSH key (if needed) for {{ borg_user }}
|
||||
block:
|
||||
- name: Ensure directory exist
|
||||
ansible.builtin.file:
|
||||
path: "{{ backup_user_info.home }}/.ssh/"
|
||||
state: directory
|
||||
mode: "0700"
|
||||
owner: "{{ borg_user }}"
|
||||
group: "{{ borg_group }}"
|
||||
|
||||
- name: Generate an OpenSSH keypair
|
||||
community.crypto.openssh_keypair:
|
||||
path: "{{ borg_ssh_key_file_path }}"
|
||||
mode: "0600"
|
||||
type: "{{ borg_ssh_key_type }}"
|
||||
owner: "{{ borg_user }}"
|
||||
group: "{{ borg_group }}"
|
||||
- name: Generate an OpenSSH keypair
|
||||
when: borg_ssh_private_key is undefined
|
||||
community.crypto.openssh_keypair:
|
||||
path: "{{ borg_ssh_key_file_path }}"
|
||||
mode: "0600"
|
||||
type: "{{ borg_ssh_key_type }}"
|
||||
owner: "{{ borg_user }}"
|
||||
group: "{{ borg_group }}"
|
||||
|
||||
- name: Read SSH key
|
||||
ansible.builtin.slurp:
|
||||
src: "{{ borg_ssh_key_file_path }}.pub"
|
||||
register: backup_local_ssh_key
|
||||
- name: Copy provided OpenSSH private key
|
||||
when: borg_ssh_private_key is defined
|
||||
ansible.builtin.copy:
|
||||
content: "{{ borg_ssh_private_key }}"
|
||||
dest: "{{ borg_ssh_key_file_path }}"
|
||||
mode: "0600"
|
||||
owner: "{{ borg_user }}"
|
||||
group: "{{ borg_group }}"
|
||||
|
||||
- name: Print key
|
||||
ansible.builtin.debug:
|
||||
msg: "The generated key is: {{ backup_local_ssh_key['content'] | b64decode }}"
|
||||
- name: Generate public key from private key
|
||||
when: borg_ssh_private_key is defined
|
||||
changed_when: false
|
||||
failed_when: not public_key.stdout.startswith("ssh")
|
||||
register: public_key
|
||||
ansible.builtin.command: "ssh-keygen -yf {{ borg_ssh_key_file_path }}"
|
||||
|
||||
- name: Copy provided OpenSSH public key
|
||||
when: borg_ssh_private_key is defined
|
||||
ansible.builtin.copy:
|
||||
content: "{{ public_key.stdout }}"
|
||||
dest: "{{ borg_ssh_key_file_path }}.pub"
|
||||
mode: "0666"
|
||||
owner: "{{ borg_user }}"
|
||||
group: "{{ borg_group }}"
|
||||
|
||||
- name: Read SSH key
|
||||
ansible.builtin.slurp:
|
||||
src: "{{ borg_ssh_key_file_path }}.pub"
|
||||
register: backup_local_ssh_key
|
||||
|
||||
- name: Print key
|
||||
ansible.builtin.debug:
|
||||
msg: "The generated key is: {{ backup_local_ssh_key['content'] | b64decode }}"
|
||||
...
|
||||
|
@ -1,5 +1,7 @@
|
||||
---
|
||||
- name: Add Borgmatic config file
|
||||
when:
|
||||
- borg_install_method != "docker"
|
||||
block:
|
||||
- name: Ensure /etc/borgmatic exists
|
||||
ansible.builtin.file:
|
||||
|
@ -2,6 +2,7 @@
|
||||
- name: Install timer to run Borgmatic
|
||||
when:
|
||||
- borgmatic_timer is defined and borgmatic_timer | length > 0
|
||||
- borg_install_method != "docker"
|
||||
block:
|
||||
- name: Start timer install script
|
||||
ansible.builtin.include_tasks:
|
||||
|
161
tasks/noauto_install_docker.yml
Normal file
161
tasks/noauto_install_docker.yml
Normal file
@ -0,0 +1,161 @@
|
||||
---
|
||||
- name: Install borgbackup with Docker
|
||||
block:
|
||||
|
||||
- name: Create temp directory for Docker build
|
||||
ansible.builtin.tempfile:
|
||||
state: directory
|
||||
register: build_dir
|
||||
changed_when: false
|
||||
|
||||
- name: Install build dependencies
|
||||
ansible.builtin.package:
|
||||
name: "{{ borg_docker_packages }}"
|
||||
state: present
|
||||
|
||||
- name: Define Docker image tag based on borgmatic --version
|
||||
ansible.builtin.set_fact:
|
||||
borgmatic_docker_tag: "{{ borgmatic_version | regex_search('\\d+\\.\\d+(\\.\\d+){0,1}') }}"
|
||||
|
||||
- name: Assert source path exists
|
||||
ansible.builtin.stat:
|
||||
path: "{{ item }}"
|
||||
register: source_path
|
||||
failed_when: not source_path.stat.exists or (source_path.stat.exists and not source_path.stat.isdir)
|
||||
with_items: "{{ borg_source_directories }}"
|
||||
|
||||
- name: Assert local repository path exists
|
||||
ansible.builtin.stat:
|
||||
path: "{{ item }}"
|
||||
register: source_path
|
||||
failed_when: not source_path.stat.exists or (source_path.stat.exists and not source_path.stat.isdir)
|
||||
when: item[0] == "/"
|
||||
with_items: "{{ borg_repository }}"
|
||||
|
||||
- name: Assert user and group are repositories
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- borg_user == "root"
|
||||
- borg_group == "root"
|
||||
fail_msg: For docker deployment, only "root" is supported for borg_user and borg_group
|
||||
|
||||
- name: Build volume list from borg_source_directories and borg_repository
|
||||
ansible.builtin.set_fact:
|
||||
volumes: >-
|
||||
{%- set volumes = [] -%}
|
||||
{%- for dir in borg_source_directories -%}
|
||||
{%- set _ = volumes.append(dir + ":/sources" + dir + ":ro") -%}
|
||||
{%- endfor -%}
|
||||
{%- for dir in borg_repository -%}
|
||||
{%- if dir[0] == "/" -%}
|
||||
{%- set _ = volumes.append(dir + ":/repositories" + dir) -%}
|
||||
{%- endif -%}
|
||||
{%- endfor -%}
|
||||
{{ volumes }}
|
||||
|
||||
- name: Modify borg_source_directories to reflect path in container
|
||||
ansible.builtin.set_fact:
|
||||
borg_source_directories_tmp: >-
|
||||
{%- set sources = [] -%}
|
||||
{%- for source in borg_source_directories -%}
|
||||
{%- set _ = sources.append("/sources" + source) -%}
|
||||
{%- endfor -%}
|
||||
{{ sources }}
|
||||
|
||||
- name: Overwrite borg_source_directories fact
|
||||
ansible.builtin.set_fact:
|
||||
borg_source_directories: "{{ borg_source_directories_tmp }}"
|
||||
|
||||
- name: Modify borg_repository to reflect path in container
|
||||
ansible.builtin.set_fact:
|
||||
borg_repository_tmp: >-
|
||||
{%- set repositories = [] -%}
|
||||
{%- for repo in borg_repository -%}
|
||||
{%- if repo[0] == "/" -%}
|
||||
{%- set _ = repositories.append("/repositories" + repo) -%}
|
||||
{%- else -%}
|
||||
{%- set _ = repositories.append(repo) -%}
|
||||
{%- endif -%}
|
||||
{%- endfor -%}
|
||||
{{ repositories }}
|
||||
borg_repository_flat: "{{ borg_repository | join('|') }}"
|
||||
|
||||
- name: Overwrite borg_repository fact
|
||||
ansible.builtin.set_fact:
|
||||
borg_repository: "{{ borg_repository_tmp }}"
|
||||
|
||||
- name: Check if ssh repo in the list
|
||||
when:
|
||||
- not borg_ssh_private_key
|
||||
- borg_repository_flat is match('|[^/]')
|
||||
ansible.builtin.set_fact:
|
||||
has_ssh_repo: true
|
||||
|
||||
- name: Test if private key was provided
|
||||
when:
|
||||
- not borg_ssh_private_key
|
||||
- has_ssh_repo
|
||||
ansible.builtin.fail:
|
||||
msg: "Private key content must be provided when using docker"
|
||||
|
||||
- name: Copy private key
|
||||
when: borg_ssh_private_key
|
||||
changed_when: false
|
||||
ansible.builtin.copy:
|
||||
dest: "{{ build_dir.path }}/{{ borg_ssh_key_name }}"
|
||||
mode: 0600
|
||||
content: "{{ borg_ssh_private_key }}"
|
||||
validate: ssh-keygen -yf %s # Also ensure priv key content is sound
|
||||
|
||||
- name: Generate public key from private key
|
||||
when: borg_ssh_private_key
|
||||
changed_when: false
|
||||
failed_when: not public_key.stdout.startswith("ssh")
|
||||
register: public_key
|
||||
ansible.builtin.command: "ssh-keygen -yf {{ build_dir.path }}/{{ borg_ssh_key_name }}"
|
||||
|
||||
- name: Copy other files to build folder for docker build
|
||||
changed_when: false
|
||||
ansible.builtin.template:
|
||||
dest: "{{ build_dir.path }}/{{ item | basename | regex_replace('\\.j2$', '') }}"
|
||||
src: "{{ item }}"
|
||||
mode: 0600
|
||||
with_items:
|
||||
- Dockerfile.j2
|
||||
- config.yaml.j2
|
||||
- ansible_entry.sh.j2
|
||||
|
||||
- name: Build docker image
|
||||
changed_when: false # will make the idempotency test fail otherwise
|
||||
community.docker.docker_image:
|
||||
name: "{{ borgmatic_docker_image_name }}:{{ borgmatic_docker_tag }}"
|
||||
source: build
|
||||
state: present
|
||||
force_source: true
|
||||
build:
|
||||
path: "{{ build_dir.path }}"
|
||||
pull: true
|
||||
rm: false
|
||||
args:
|
||||
PUBLIC_KEY: "{{ public_key }}"
|
||||
PRIVATE_KEY: "{{ borg_ssh_private_key }}"
|
||||
|
||||
- name: Start container
|
||||
changed_when: false # will make the idempotency test fail otherwise
|
||||
community.docker.docker_container:
|
||||
name: "{{ borgmatic_docker_container_name }}"
|
||||
image: "{{ borgmatic_docker_image_name }}:{{ borgmatic_docker_tag }}"
|
||||
volumes: "{{ volumes }}"
|
||||
restart_policy: unless-stopped
|
||||
labels:
|
||||
ansible_borgmatic_managed: "1"
|
||||
env:
|
||||
BACKUP_CRON: "{{ borgmatic_timer_minute }} {{ borgmatic_timer_hour }} * * * borgmatic -c /etc/borgmatic/{{ borgmatic_config_name }}"
|
||||
TZ: "{{ borgmatic_docker_timezone }}"
|
||||
|
||||
always:
|
||||
- name: Delete build folder
|
||||
ansible.builtin.file:
|
||||
path: "{{ build_dir.path }}"
|
||||
state: absent
|
||||
changed_when: false
|
15
templates/Dockerfile.j2
Normal file
15
templates/Dockerfile.j2
Normal file
@ -0,0 +1,15 @@
|
||||
FROM ghcr.io/borgmatic-collective/borgmatic:{{ borgmatic_docker_tag }}
|
||||
|
||||
LABEL "ansible_borgmatic_managed"="1"
|
||||
|
||||
COPY config.yaml /etc/borgmatic/{{ borgmatic_config_name }}
|
||||
|
||||
# Those keys will be copied at /root/.ssh at runtime. This is required because of the anom volumes defined in the upstream image
|
||||
ARG PUBLIC_KEY=""
|
||||
ARG PRIVATE_KEY=""
|
||||
RUN if [ ! -z "$PUBLIC_KEY" ]; then echo "$PUBLIC_KEY" > /{{ borg_ssh_key_name}}.pub; fi
|
||||
RUN if [ ! -z "$PRIVATE_KEY" ]; then echo "$PRIVATE_KEY" > /{{ borg_ssh_key_name}}; fi
|
||||
COPY ansible_entry.sh /
|
||||
RUN chmod 700 /ansible_entry.sh
|
||||
|
||||
ENTRYPOINT [ "/ansible_entry.sh" ]
|
9
templates/ansible_entry.sh.j2
Normal file
9
templates/ansible_entry.sh.j2
Normal file
@ -0,0 +1,9 @@
|
||||
#!/bin/sh
|
||||
|
||||
# We need to copy ssh keys at runtime because of the built-in volumes in the upstream Docker image definition
|
||||
if [ -f "/{{ borg_ssh_key_name }}.pub" ]; then mv /{{ borg_ssh_key_name }}.pub /root/.ssh; fi
|
||||
if [ -f "/{{ borg_ssh_key_name }}" ]; then mv /{{ borg_ssh_key_name }} /root/.ssh; fi
|
||||
|
||||
echo "$BACKUP_CRON" > /etc/borgmatic.d/crontab.txt
|
||||
|
||||
exec env SUPERCRONIC_EXTRA_FLAGS=-debug /entry.sh "$@"
|
6
vars/Alpine.yml
Normal file
6
vars/Alpine.yml
Normal file
@ -0,0 +1,6 @@
|
||||
---
|
||||
borg_docker_packages:
|
||||
- py3-docker-py
|
||||
|
||||
python_bin: python3
|
||||
pip_bin: pip3
|
@ -10,6 +10,9 @@ borg_pip_packages:
|
||||
- python-pip
|
||||
- python-setuptools
|
||||
|
||||
borg_docker_packages:
|
||||
- python-docker
|
||||
|
||||
borg_distro_packages:
|
||||
- borg
|
||||
- borgmatic
|
||||
|
@ -19,6 +19,9 @@ borg_pip_packages:
|
||||
- python3-msgpack
|
||||
- python3-venv
|
||||
|
||||
borg_docker_packages:
|
||||
- python3-docker
|
||||
|
||||
borg_distro_packages:
|
||||
- borgbackup
|
||||
- borgmatic
|
||||
|
@ -16,6 +16,9 @@ borg_pip_packages:
|
||||
- python3-setuptools
|
||||
- python3-Cython
|
||||
|
||||
borg_docker_packages:
|
||||
- python3-docker
|
||||
|
||||
borg_distro_packages:
|
||||
- borgbackup
|
||||
- borgmatic
|
||||
|
@ -16,6 +16,9 @@ borg_pip_packages: # untested
|
||||
- python3-msgpack
|
||||
- python3-venv
|
||||
|
||||
borg_docker_packages:
|
||||
- python3-docker
|
||||
|
||||
borg_distro_packages:
|
||||
- borg
|
||||
- borgmatic
|
||||
|
@ -16,6 +16,9 @@ borg_pip_packages:
|
||||
- python3-setuptools
|
||||
- python3-virtualenv
|
||||
|
||||
borg_docker_packages:
|
||||
- python3-docker
|
||||
|
||||
borg_distro_packages:
|
||||
- borgbackup
|
||||
- borgmatic
|
||||
|
@ -16,6 +16,9 @@ borg_pip_packages:
|
||||
- python3-setuptools
|
||||
# - python3-virtualenv
|
||||
|
||||
borg_docker_packages:
|
||||
- python3-docker
|
||||
|
||||
borg_distro_packages:
|
||||
- borgbackup
|
||||
- borgmatic
|
||||
|
@ -15,6 +15,9 @@ borg_pip_packages:
|
||||
- python36-devel
|
||||
- python-setuptools
|
||||
|
||||
borg_docker_packages:
|
||||
- python36-docker
|
||||
|
||||
borg_distro_packages:
|
||||
- borgbackup
|
||||
- borgmatic
|
||||
|
Loading…
Reference in New Issue
Block a user