Split fedora and manjaro playbooks

Split playbooks to better accomodate development of both.
This commit is contained in:
ducoterra
2022-04-03 16:48:30 -04:00
parent 2ca110134a
commit 494e91f293
191 changed files with 1195 additions and 1314 deletions

View File

@@ -0,0 +1,29 @@
---
language: python
python: "2.7"
# Use the new container infrastructure
sudo: false
# Install ansible
addons:
apt:
packages:
- python-pip
install:
# Install ansible
- pip install ansible
# Check ansible version
- ansible --version
# Create ansible.cfg with correct roles_path
- printf '[defaults]\nroles_path=../' >ansible.cfg
script:
# Basic role syntax check
- ansible-playbook tests/test.yml -i tests/inventory --syntax-check
notifications:
webhooks: https://galaxy.ansible.com/api/v1/notifications/

View File

@@ -0,0 +1,57 @@
Role Name
=========
Configures automatic BTRFS backups for "/" and "/home"
Requirements
------------
Any pre-requisites that may not be covered by Ansible itself or the role should be mentioned here. For instance, if the role uses the EC2 module, it may be a good idea to mention in this section that the boto package is required.
Role Variables
--------------
```yaml
snapshots:
path: /.snapshots
disk:
name: backup0
# uuid: 1d7ce570-e695-47a0-9dda-5f14b5b20e21
uuid: 7c482f9b-2e1a-494c-9a93-ddecd483f2b2
# password: /home/ducoterra/.lukskeys/backup0
password: /home/ducoterra/.lukskeys/manjaro-laptop-iscsi
backups:
- /
- /home
notifications:
user:
name: ducoterra
uid: 1000
```
Dependencies
------------
A list of other roles hosted on Galaxy should go here, plus any details in regards to parameters that may need to be set for other roles, or variables that are used from other roles.
Example Playbook
----------------
Including an example of how to use your role (for instance, with variables passed in as parameters) is always nice for users too:
- hosts: servers
roles:
- { role: username.rolename, x: 42 }
License
-------
BSD
Author Information
------------------
An optional section for the role authors to include contact information, or a website (HTML is not allowed).

View File

@@ -0,0 +1,2 @@
---
# defaults file for arch_backup

View File

@@ -0,0 +1,5 @@
[Unit]
Description=Runs btrbk with config file at /etc/btrbk/btrbk.conf
[Service]
ExecStart=btrbk -c /etc/btrbk/btrbk.conf -v run

View File

@@ -0,0 +1,11 @@
[Unit]
Description=Run btrbk every hour
[Timer]
OnCalendar=hourly
AccuracySec=10min
Persistent=true
Unit=btrbk.service
[Install]
WantedBy=timers.target

View File

@@ -0,0 +1,2 @@
---
# handlers file for arch_backup

View File

@@ -0,0 +1,52 @@
galaxy_info:
author: your name
description: your role description
company: your company (optional)
# If the issue tracker for your role is not on github, uncomment the
# next line and provide a value
# issue_tracker_url: http://example.com/issue/tracker
# Choose a valid license ID from https://spdx.org - some suggested licenses:
# - BSD-3-Clause (default)
# - MIT
# - GPL-2.0-or-later
# - GPL-3.0-only
# - Apache-2.0
# - CC-BY-4.0
license: license (GPL-2.0-or-later, MIT, etc)
min_ansible_version: 2.1
# If this a Container Enabled role, provide the minimum Ansible Container version.
# min_ansible_container_version:
#
# Provide a list of supported platforms, and for each platform a list of versions.
# If you don't wish to enumerate all versions for a particular platform, use 'all'.
# To view available platforms and versions (or releases), visit:
# https://galaxy.ansible.com/api/v1/platforms/
#
# platforms:
# - name: Fedora
# versions:
# - all
# - 25
# - name: SomePlatform
# versions:
# - all
# - 1.0
# - 7
# - 99.99
galaxy_tags: []
# List tags for your role here, one per line. A tag is a keyword that describes
# and categorizes the role. Users find roles by searching for tags. Be sure to
# remove the '[]' above, if you add tags to this list.
#
# NOTE: A tag is limited to a single word comprised of alphanumeric characters.
# Maximum 20 tags per role.
dependencies: []
# List your role dependencies here, one per line. Be sure to remove the '[]' above,
# if you add dependencies to this list.

View File

@@ -0,0 +1,86 @@
---
# Backup
- name: Ensure snapshot directory
file:
state: directory
path: "{{ snapshots.path }}"
become: yes
- name: Ensure /usr/local/scripts exists
file:
state: directory
path: '/usr/local/scripts'
become: yes
- name: Template btrfs_backup.sh
ansible.builtin.template:
src: btrfs_backup.sh.j2
dest: /usr/local/scripts/btrfs_backup.sh
owner: root
group: root
mode: '0744'
become: yes
# backup home
- name: Create btrfs_backup_home.service
become: yes
copy:
dest: "/etc/systemd/system/btrfs_backup_home.service"
content: |
[Unit]
Description=Takes snapshots and backs up btrfs home volume on a schedule
[Service]
ExecStart=/usr/local/scripts/btrfs_backup.sh /home
- name: Create btrfs_backup_home.service
become: yes
copy:
dest: "/etc/systemd/system/btrfs_backup_home.timer"
content: |
[Unit]
Description=btrfs home backup timer
[Timer]
OnCalendar=hourly
AccuracySec=10min
Persistent=true
Unit=btrfs_backup_home.service
[Install]
WantedBy=multi-user.target
- name: Enable service btrfs_backup_home and ensure it's started
become: yes
ansible.builtin.systemd:
name: btrfs_backup_home.timer
state: started
daemon_reload: yes
# backup root
- name: Create btrfs_backup_root.service
become: yes
copy:
dest: "/etc/systemd/system/btrfs_backup_root.service"
content: |
[Unit]
Description=Takes snapshots and backs up btrfs root volume on a schedule
[Service]
ExecStart=/usr/local/scripts/btrfs_backup.sh /
- name: Create btrfs_backup_root.service
become: yes
copy:
dest: "/etc/systemd/system/btrfs_backup_root.timer"
content: |
[Unit]
Description=btrfs root backup timer
[Timer]
OnCalendar=hourly
AccuracySec=10min
Persistent=true
Unit=btrfs_backup_root.service
[Install]
WantedBy=multi-user.target
- name: Enable service btrfs_backup_root and ensure it's started
become: yes
ansible.builtin.systemd:
name: btrfs_backup_root.timer
state: started
daemon_reload: yes

View File

@@ -0,0 +1,210 @@
#!/bin/bash
# Backup Dir
export SOURCE_DIR=$1
# Fix basename / showing up as "/" -> change to "root"
if [ $(basename $SOURCE_DIR) = / ]; then
export SNAPSHOT_PREFIX=${SNAPSHOT_PREFIX:=root}
else
export SNAPSHOT_PREFIX=${SNAPSHOT_PREFIX:=$(basename $SOURCE_DIR)}
fi
# Set snapshot prefix based on basename
export SNAPSHOT_TIME=$(date +"%y_%m_%d-%H.%M")
export SNAPSHOT_NAME=$SNAPSHOT_PREFIX-$SNAPSHOT_TIME
export SNAPSHOT_DIR=${SNAPSHOT_DIR:=/.snapshots}
export LATEST=$SNAPSHOT_PREFIX-latest
# For notifications
export DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/{{ notifications.user.uid }}/bus
export USER={{ notifications.user.name }}
function exit_success {
# Exit
exit 0
}
function exit_fail {
# Exit
exit 1
}
function get_latest {
DIR=$1
if [ -f $DIR/$LATEST ]; then
echo $(cat $DIR/$LATEST)
else
echo ""
fi
}
function update_latest {
DIR=$1
NAME=$2
echo $2 > $DIR/$LATEST
}
function log {
LEVEL=$1
MESSAGE=$2
log_msg="$(date) $LEVEL: $MESSAGE"
echo $log_msg
}
function notify {
LEVEL=$1
MESSAGE=$2
log "$LEVEL" "$MESSAGE"
sudo -E -u $USER notify-send "$LEVEL" "$MESSAGE" --expire-time 10
}
function get_mount {
findmnt -o target /dev/disk/by-uuid/$1 --noheadings
}
# Show snapshot settings
log "INFO" "SOURCE_DIR $SOURCE_DIR"
log "INFO" "SNAPSHOT_PREFIX $SNAPSHOT_PREFIX"
log "INFO" "SNAPSHOT_TIME $SNAPSHOT_TIME"
log "INFO" "SNAPSHOT_NAME $SNAPSHOT_NAME"
log "INFO" "SNAPSHOT_DIR $SNAPSHOT_DIR"
log "INFO" "LATEST $LATEST"
# Create readonly snapshot
log "INFO" "Creating snapshot from $SOURCE_DIR as $SNAPSHOT_DIR/$SNAPSHOT_NAME"
if [ -d $SNAPSHOT_DIR/$SNAPSHOT_NAME ]; then
log "WARN" "Snapshot $SNAPSHOT_DIR/$SNAPSHOT_NAME already created. Skipping"
else
btrfs subvolume snapshot -r $SOURCE_DIR $SNAPSHOT_DIR/$SNAPSHOT_NAME
fi
# Update latest in snapshot dir
log "INFO" "Updating latest in $SNAPSHOT_DIR to $SNAPSHOT_NAME."
update_latest $SNAPSHOT_DIR $SNAPSHOT_NAME
export BACKUP_DRIVE_UUID={{ disk.uuid }}
get_mount $BACKUP_DRIVE_UUID
if [ $? != 0 ]; then
notify "WARN" "Snapshot complete but backup drive $BACKUP_DRIVE_UUID not mounted. Backup not sent."
exit 1
fi
export BACKUP_DRIVE_MNT=$(findmnt -o target /dev/disk/by-uuid/$BACKUP_DRIVE_UUID --noheadings)
export BACKUP_DIR=$BACKUP_DRIVE_MNT/$(hostname)
mkdir -p $BACKUP_DIR
log "INFO" "BACKUP_DRIVE_MNT $BACKUP_DRIVE_MNT"
log "INFO" "BACKUP_DIR $BACKUP_DIR"
log "INFO" "Drive $BACKUP_DRIVE_UUID mounted at $BACKUP_DRIVE_MNT"
# First check if the snapshot dir has a "latest" snapshot
# This will be needed to send an incremental snapshot
LATEST_SNAPSHOT="$(get_latest $SNAPSHOT_DIR)"
log "INFO" "Latest snapshot is $LATEST_SNAPSHOT"
# Next, check if the backup drive has a "latest" snapshot
LATEST_BACKUP="$(get_latest $BACKUP_DIR)"
log "INFO" "Latest backup is $LATEST_BACKUP"
# Now check if the "latest" snapshots match
# btrfs requires both the sending drive and receiving drive have
# matching parent snapshots.
#
# There are a few scenarios to cover
# 1. Neither the backup drive nor the local snapshot dir have a "latest"
# This can happen if the backup occurs before any snapshots are
# taken. Don't send anything.
# 2. The backup drive has a "latest" but the snapshot dir doesn't
# This can happen when the local drive is restored from backup
# but the snapshot dir didn't copy over. nothing to send.
# 3. The backup drive and snapshot dir have a "latest" and they are the
# same.
# Send backup with parent as normal.
# 4. The snapshot dir has a "latest" but the backup drive doesn't
# This can happen when backing up for the first time. Send the
# snapshot without a parent
# 5. Both the snapshot dir and backup drive have a latest, but they are
# out of sync.
# This can happen when snapshots are taken with the backup drive
# disconnected. There's a few sub-scenarios here:
# a. The snapshot dir has the "latest" snapshot from the backup dir,
# it's just older than the "latest" snapshot in the snapshot dir
# Re-sync the "latest" snapshot dir with the one in the
# backup dir. Send as normal with parents.
# b. The snapshot dir does not have the "latest" snapshot from the
# backup dir.
# Here be dragons. Something went wrong and will likely need
# to be manually reconfigured. Raise a critical alert.
# Scenario 1 and 2
if [ "$LATEST_SNAPSHOT" = "" ]; then
notify "WARN" "Neither the snapshot dir nor the backup drive has a 'latest' snapshot."
exit_success
fi
# Scenario 3
if [ "$LATEST_SNAPSHOT" = "$LATEST_BACKUP" ]; then
log "INFO" "Proceeding with backups as normal."
# Send incremental snapshot
btrfs send -p $SNAPSHOT_DIR/$LATEST_SNAPSHOT $SNAPSHOT_DIR/$SNAPSHOT_NAME | btrfs receive $BACKUP_DIR
if [ $? != 0 ]; then
notify "ERROR" "btrfs send -p $SNAPSHOT_DIR/$LATEST_SNAPSHOT $SNAPSHOT_DIR/$SNAPSHOT_NAME failed."
exit_fail
fi
# Update latest in backup dir
update_latest $BACKUP_DIR $SNAPSHOT_NAME
# Update latest in snapshot dir
update_latest $SNAPSHOT_DIR $SNAPSHOT_NAME
# Exit
notify "INFO" "Backup completed" "Backup $SNAPSHOT_NAME completed successfully."
exit_success
fi
# Scenario 4
if [ "$LATEST_BACKUP" = "" ]; then
log "INFO" "No prior backups detected. Sending full backup."
# Send incremental snapshot
btrfs send $SNAPSHOT_DIR/$SNAPSHOT_NAME | btrfs receive $BACKUP_DIR
if [ $? != 0 ]; then
notify "ERROR" "btrfs send $SNAPSHOT_DIR/$SNAPSHOT_NAME failed."
exit_fail
fi
# Update latest in backup dir
update_latest $BACKUP_DIR $SNAPSHOT_NAME
# Update latest in snapshot dir
update_latest $SNAPSHOT_DIR $SNAPSHOT_NAME
# Exit
notify "INFO" "Backup $SNAPSHOT_NAME completed successfully."
exit_success
fi
# Scenario 5a
log "INFO" "Detected drift. Attempting to synchronize latest snapshot with backup. Set to $LATEST_BACKUP."
if [ -d $SNAPSHOT_DIR/$LATEST_BACKUP ]; then
log "INFO" "$LATEST_BACKUP found in snapshot dir. Synchronizing and proceeding."
btrfs send -p $SNAPSHOT_DIR/$LATEST_BACKUP $SNAPSHOT_DIR/$SNAPSHOT_NAME | btrfs receive $BACKUP_DIR
if [ $? != 0 ]; then
notify "ERROR" "btrfs send -p $SNAPSHOT_DIR/$LATEST_BACKUP $SNAPSHOT_DIR/$SNAPSHOT_NAME failed."
exit_fail
fi
# Update latest in backup dir
update_latest $BACKUP_DIR $SNAPSHOT_NAME
# Update latest in snapshot dir
update_latest $SNAPSHOT_DIR $SNAPSHOT_NAME
# Exit
notify "INFO" "Backup $SNAPSHOT_NAME completed successfully."
exit_success
# Scenario 5b
else
log "ERROR" "Something went wrong. $LATEST_BACKUP not found in $SNAPSHOT_DIR."
notify "ERROR" "$LATEST_BACKUP not found in $SNAPSHOT_DIR."
exit_fail
fi

View File

@@ -0,0 +1,2 @@
localhost

View File

@@ -0,0 +1,5 @@
---
- hosts: localhost
remote_user: root
roles:
- arch_backup

View File

@@ -0,0 +1 @@
---