Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Docker support #140

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .ansible-lint
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
---
skip_list:
- fqcn-builtins
- var-naming[no-role-prefix]
2 changes: 2 additions & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,5 @@ jobs:
# uses: mxschmitt/[email protected]
- name: Test using Molecule
run: molecule test
- name: Test Docker scenario using Molecule
run: molecule test -s docker
26 changes: 23 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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://[email protected]/./repo
borg_encryption_passphrase: CHANGEME
borg_source_directories:
- /var/www
borg_ssh_private_key: !vault |
$ANSIBLE_VAULT;1.1;AES256
65373636303732303236313234666230386333636233313631663135323734626265616532633064
316334...truncated
```

## Installation

Expand Down Expand Up @@ -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`
Expand All @@ -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`
Expand All @@ -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

Expand Down
4 changes: 4 additions & 0 deletions defaults/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
...
25 changes: 23 additions & 2 deletions meta/arguments_specs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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"
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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
1 change: 1 addition & 0 deletions meta/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ galaxy_info:
- name: ArchLinux
versions:
- all
- name: Docker
galaxy_tags:
- backup
- cloud
Expand Down
2 changes: 1 addition & 1 deletion molecule/default/Dockerfile.j2
Original file line number Diff line number Diff line change
Expand Up @@ -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
6 changes: 5 additions & 1 deletion molecule/default/converge.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -46,3 +48,5 @@
pip:
name: yamllint
executable: pip3
extra_args: "{{ pip3_extra_args }}"

3 changes: 3 additions & 0 deletions molecule/default/verify.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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 changes: 23 additions & 0 deletions molecule/docker/Dockerfile.j2
Original file line number Diff line number Diff line change
@@ -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 changes: 22 additions & 0 deletions molecule/docker/INSTALL.rst
Original file line number Diff line number Diff line change
@@ -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 changes: 96 additions & 0 deletions molecule/docker/converge.yml
Original file line number Diff line number Diff line change
@@ -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:
- [email protected]: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 changes: 21 additions & 0 deletions molecule/docker/molecule.yml
Original file line number Diff line number Diff line change
@@ -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 change: 1 addition & 0 deletions molecule/docker/vault.pw
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
password
33 changes: 33 additions & 0 deletions molecule/docker/verify.yml
Original file line number Diff line number Diff line change
@@ -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
1 change: 1 addition & 0 deletions tasks/01_install.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Loading