3 # Usage: backup-db.sh [--all]
5 # This script makes a rotating backup of the very
6 # important database files $chroot/etc/passwd and
7 # $chroot/etc/group and $chroot/etc/sshkeys.
8 # Backup files are rotated dropping .9.$ext and
9 # renaming the others to the next higher number
10 # and then finally making a copy of the original
11 # to a .1 (not compressed for passwd and group).
13 # If the `--all` option is specified, then project
14 # metadata for each project is also backed up (all
15 # the project's settings -- pretty much everything
16 # except the objects from the repository).
18 # The backup files are stored in $chroot/etc/backups/
19 # which MUST ALREADY EXIST (jailsetup.sh creates it).
21 # Running this regularly from a cron entry is
22 # highly recommended. It may be run manually
23 # from the $basedir/toolbox directory any time
24 # after make install has been run to create an
27 # Backups retain the modification date of the file
28 # they are backing up at the time the backup was
29 # made. If restoration is required this can be
30 # used to determine the time period from which data
31 # would be lost if the backup were to be used.
33 # Backups are moved into place after being fully
34 # created with a ".tmp_" prefix and are therefore
35 # always safe to copy out once they have their
36 # final backup name (i.e. the leading ".tmp_" has
43 # returns specified hash (e.g. "md5", "sha1" etc.)
44 # $1 => variable name to store result in
45 # $2 => hash name ("md5", "sha1" or anything openssl dgst understands)
50 _hash
="$('openssl' dgst -"$2" <"$3" 2>/dev/null)" &&
51 _hash
="${_hash##*[!0-9a-fA-F]}" && [ -n "$_hash" ] &&
55 # rotate_file basename suffix
57 ! [ -f "$1.8.$2" ] ||
mv -f "$1.8.$2" "$1.9.$2"
58 ! [ -f "$1.7.$2" ] ||
mv -f "$1.7.$2" "$1.8.$2"
59 ! [ -f "$1.6.$2" ] ||
mv -f "$1.6.$2" "$1.7.$2"
60 ! [ -f "$1.5.$2" ] ||
mv -f "$1.5.$2" "$1.6.$2"
61 ! [ -f "$1.4.$2" ] ||
mv -f "$1.4.$2" "$1.5.$2"
62 ! [ -f "$1.3.$2" ] ||
mv -f "$1.3.$2" "$1.4.$2"
63 ! [ -f "$1.2.$2" ] ||
mv -f "$1.2.$2" "$1.3.$2"
67 # backup_file dir basename backupdir
69 rotate_file2_9
"$3/$2" gz
70 if [ -f "$3/$2.1" ]; then
71 rm -f "$3/$2.2.gz" "$3/.tmp_$2.2.gz" &&
72 gzip -n9 <"$3/$2.1" >"$3/.tmp_$2.2.gz" &&
73 touch -r "$3/$2.1" "$3/.tmp_$2.2.gz" &&
74 mv -f "$3/.tmp_$2.2.gz" "$3/$2.2.gz" &&
75 chmod a-w
"$3/$2.2.gz"
77 if [ -f "$1/$2" ]; then
78 rm -f "$3/$2.1" "$3/.tmp_$2.1" &&
79 cp -pf "$1/$2" "$3/.tmp_$2.1" &&
80 mv -f "$3/.tmp_$2.1" "$3/$2.1" &&
86 # badkup_dir dir basename backupdir
89 rotate_file2_9
"$3/$2" tar.gz
90 ! [ -f "$3/$2.1.tar.gz" ] ||
mv -f "$3/$2.1.tar.gz" "$3/$2.2.tar.gz"
91 if [ -d "$1/$2" ]; then
93 rm -f "$3/$2.1.tar.gz" "$3/.tmp_$2.1.tar.gz" &&
94 tar -c -f - "$2" |
gzip -n9 >"$3/.tmp_$2.1.tar.gz" &&
95 mv -f "$3/.tmp_$2.1.tar.gz" "$3/$2.1.tar.gz" &&
96 chmod a-w
"$3/$2.1.tar.gz"
103 bombin
="$cfg_basedir/toolbox/create_projects_bom.pl"
104 [ -f "$bombin" ] && [ -x "$bombin" ] ||
{
105 echo 'ERROR: backup-db.sh could not find create_projects_bom.pl' >&2
106 echo 'ERROR: backup-db.sh projects data NOT backed up!' >&2
109 cpiobin
="$cfg_basedir/toolbox/perlcpio.pl"
110 [ -f "$cpiobin" ] && [ -x "$cpiobin" ] ||
{
111 echo 'ERROR: backup-db.sh could not find perlcpio.pl' >&2
112 echo 'ERROR: backup-db.sh projects data NOT backed up!' >&2
116 echo "ERROR: no such directory: $1/$2" >&2
117 echo 'ERROR: backup-db.sh projects data NOT backed up!' >&2
120 rotate_file2_9
"$3/$2" pax.gz
121 rotate_file2_9
"$3/$2" pax.gz.sha1
122 ! [ -f "$3/$2.1.pax.gz" ] ||
mv -f "$3/$2.1.pax.gz" "$3/$2.2.pax.gz"
123 ! [ -f "$3/$2.1.pax.gz.sha1" ] ||
mv -f "$3/$2.1.pax.gz.sha1" "$3/$2.2.pax.gz.sha1"
125 rm -f "$3/$2.1.pax.gz" "$3/.tmp_$2.1.pax.gz" &&
126 "$bombin" |
sed "s,^,./$2/," |
127 "$cpiobin" ${var_cgi_uid:+-u} $var_cgi_uid ${var_group_gid:+-g} $var_group_gid -kcq |
128 gzip -n9 >"$3/.tmp_$2.1.pax.gz" &&
129 mv "$3/.tmp_$2.1.pax.gz" "$3/$2.1.pax.gz" &&
130 chmod a-w
"$3/$2.1.pax.gz" &&
131 if vgethash sha1 sha1
"$3/$2.1.pax.gz"; then
132 rm -f "$3/$2.1.pax.gz.sha1" "$3/.tmp_$2.1.pax.gz.sha1" &&
133 echo "$sha1" >"$3/.tmp_$2.1.pax.gz.sha1" &&
134 touch -r "$3/$2.1.pax.gz" "$3/.tmp_$2.1.pax.gz.sha1" &&
135 mv "$3/.tmp_$2.1.pax.gz.sha1" "$3/$2.1.pax.gz.sha1" &&
136 chmod a-w
"$3/$2.1.pax.gz.sha1"
141 if [ -z "$cfg_chroot" ] ||
[ "$cfg_chroot" = "/" ]; then
142 echo 'Config.pm chroot setting is invalid' >&2
145 if [ ! -d "$cfg_chroot/etc/backups" ]; then
146 echo "No such directory: $cfg_chroot/etc/backups" >&2
149 if [ ! -w "$cfg_chroot/etc/backups" ]; then
150 echo "Not writable directory: $cfg_chroot/etc/backups" >&2
156 backup_file
"$cfg_chroot/etc" "passwd" "$cfg_chroot/etc/backups"
157 backup_file
"$cfg_chroot/etc" "group" "$cfg_chroot/etc/backups"
158 backup_dir
"$cfg_chroot/etc" "sshkeys" "$cfg_chroot/etc/backups"
159 [ "$1" != "--all" ] ||
{
160 ! command -v renice
>/dev
/null
2>&1 || renice
-n +10 -p $$
>/dev
/null
2>&1 ||
:
161 ! command -v ionice
>/dev
/null
2>&1 || ionice
-c 3 -p $$
>/dev
/null
2>&1 ||
:
162 tmploc
="$(mktemp -d /tmp/backup-db-XXXXXX)"
163 ln -s "$cfg_reporoot" "$tmploc/projects"
164 backup_projects
"$tmploc" "projects" "$cfg_chroot/etc/backups"
167 [ -z "$tmploc" ] ||
rm -rf "$tmploc"