aboutsummaryrefslogtreecommitdiff
path: root/borger
blob: 240de3691b8970607d76cd52414c3e534bcd7597 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
#!/bin/bash
#
# Borg script for home folder backups.
# Adapted from https://borgbackup.readthedocs.io/en/stable/quickstart.html#automating-backups
#
# Example config to be put at ~/.config/borger/destination-name:
#
#   # Backup destination
#   export SSH_SERVER="user@host"
#   export SSH_PORT="2202"
#
#   # Repository path
#   export BORG_REPO_DIR="/var/backups/users/$USER/borg"
#   export BORG_REPO="ssh://$SSH_SERVER:$SSH_PORT/$BORG_REPO_DIR"
#
#   # Setting this, so you won't be asked for your repository passphrase:
#   #export BORG_PASSPHRASE='HACKME'
#   #export BORG_PASSCOMMAND='pass show backup'
#   #export BORG_PASSCOMMAND='keyringer default decrypt pessoal/backups/borg 2> /dev/null'
#
#   # Backup config
#   keepdaily="7"
#   keepweekly="4"
#   keepmonth="3"
#   encryption="keyfile"

# Parameters
BASENAME="`basename $0`"
DESTINATION="$1"
BASE_CONFIG="$HOME/.config/borger"
CONFIG="$BASE_CONFIG/$DESTINATION"
HOSTNAME=`cat /etc/hostname`

# Some helpers and error handling:
info() { printf "\n%s %s\n\n" "$( date )" "$*" >&2; }
fatal() { info $*; exit 1; }

# Ensure we have our base config folder
mkdir -p $BASE_CONFIG

# List available targets
if [ -z "$DESTINATION" ]; then
  echo "usage: $BASENAME <destination> [--check]"
  echo -n "available destinations from $BASE_CONFIG: "
  ls $BASE_CONFIG
  exit 1
fi

# Ensure we have an username
if [ -z "$USER" ]; then
  USER="`whoami`"
fi

# In case your home folder is a symlink
if [ ! -z "`readlink $HOME`" ]; then
  ORIG="`readlink $HOME`"
else
  ORIG="$HOME"
fi

# Default backup config
keepdaily="7"
keepweekly="4"
keepmonth="3"
encryption="keyfile"

# Config
if [ -e "$CONFIG" ] ; then
  source $CONFIG
else
  fatal "No such config $CONFIG"
fi

# Setting this, so the repo does not need to be given on the commandline:
if [ -z "$BORG_REPO" ]; then
  export BORG_REPO_DIR="/var/backups/users/$USER/borg"
  export BORG_REPO="ssh://$SSH_SERVER:$SSH_PORT/$BORG_REPO_DIR"
fi

# Check
if [ "$2" == "--check" ]; then
  borg list
  exit $?
fi

# Our trap
trap 'info $( date ) Backup interrupted >&2; exit 2' INT TERM

# Initialize
if ! ssh $SSH_SERVER -p $SSH_PORT test -f $BORG_REPO_DIR/config; then
  info "Initializing borg repository at $BORG_REPO..."
  borg init --encryption=$encryption $BORG_REPO

  init_exit=$?

  if [ "$init_exit" != "0" ]; then
    fatal "Error initializing repository"
  fi
fi

# Backup the most important directories into an archive named after
# the machine this script is currently running on:

info "Starting backup..."

borg create                          \
  --verbose                          \
  --filter AME                       \
  --list                             \
  --stats                            \
  --show-rc                          \
  --compression lz4                  \
  --exclude-caches                   \
  ::'{now}'                          \
  $ORIG

  backup_exit=$?

if [ "$backup_exit" != "0" ]; then
  fatal "Error creating snapshot"
fi

info "Pruning repository..."

# Use the `prune` subcommand to maintain 7 daily, 4 weekly and 6 monthly
# archives of THIS machine. The '{hostname}-' prefix is very important to
# limit prune's operation to this machine's archives and not apply to
# other machines' archives also:

borg prune                      \
  --list                        \
  --show-rc                     \
  --keep-daily    $keepdaily    \
  --keep-weekly   $keepweekly   \
  --keep-monthly  $keepmonthly  \

  prune_exit=$?

if [ "$prune_exit" != "0" ]; then
  fatal "Error pruning repository"
fi

# use highest exit code as global exit code
#global_exit=$(( backup_exit > prune_exit ? backup_exit : prune_exit ))
#
#if [ ${global_exit} -eq 1 ];
#then
#  info "Backup and/or Prune finished with a warning"
#fi
#
#if [ ${global_exit} -gt 1 ];
#then
#  info "Backup and/or Prune finished with an error"
#fi
#
#exit ${global_exit}