Commit efb76dbd authored by OskarStenberg's avatar OskarStenberg
Browse files

Added an incremental backup script

parent 797b04d2
#!/bin/bash
snipeitDirectory="/var/www/html/snipeit"
backupDirectory="$snipeitDirectory/storage/app/backups"
dbDumpFile="$snipeitDirectory/vendor/spatie/db-dumper/src/Databases/MySql.php"
destinationDir="/export/home/snipeit/backups"
#/ Usage: backup.sh [-dbmof]
#/
#/ Create an incremental backup of a snipeit-instance
#/
#/ OPTIONS:
#/ -d | --snipeit-directory Set the directory of the instance to be backed up
#/ -b | --backup-directory Set the directory where SnipeIT places the internal backups
#/ -m | --mysql-dump-settings Set the location of the database dump settings file
#/ -o | --output-directory Set the output directory for where to place the backups
#/ -f | --full-backup Make a new, full, backup instead of an incremental one
#/ -h | --help Show this message.
print_usage () {
grep '^#/' <"$0" | cut -c 4-
exit 1
}
#Parse arguments
while [[ $# > 0 ]]; do
case "$1" in
-d|--snipeit-directory)
shift
if test $# -gt 0; then
snipeitDirectory=$(echo "$1" | sed "s,/$,,")
else
echo "No SnipeIT directory specified"
exit 1
fi
shift
;;
-b|--backup-directory)
shift
if test $# -gt 0; then
backupDirectory=$(echo "$1" | sed "s,/$,,")
else
echo "No backup directory specified"
exit 1
fi
shift
;;
-m|--mysql-dump-settings)
if test $# -gt 0; then
dbDumpFile=$1
else
echo "No database dump settings specified"
exit 1
fi
shift
;;
-o|--output-directory)
if test $# -gt 0; then
destinationDir=$(echo "$1" | sed "s,/$,,")
else
echo "No output directory specified"
exit 1
fi
shift
;;
-f|--full-backup)
echo "Creating full backup"
mkdir "$destinationDir/$(date +%s)"
shift
;;
-h|--help)
print_usage
exit 1
;;
-*)
echo "Error: invalid argument: '$1'" 1>&2
print_usage
exit 1
;;
esac
done
if ! [ -d "$destinationDir/" ]; then
echo "Output directory not found: $destinationDir"
exit 0
fi
if ! [ -d "$snipeitDirectory/" ]; then
echo "SnipeIT directory not found: $snipeitDirectory"
exit 0
fi
if ! [ -d "$backupDirectory/" ]; then
echo "Backup directory not found: $backupDirectory"
exit 0
fi
if ! [ -f "$dbDumpFile" ]; then
echo "Database dump settings file not found: $dbDumpFile"
exit 0
fi
#Update value in config file to get correct format
sed -i 's/protected $useExtendedInserts = true;/protected $useExtendedInserts = false;/' $dbDumpFile
#Generate the internal backup
cd $snipeitDirectory
php artisan backup:run
backupFile=$(ls -lt $backupDirectory | head -3 | tail -1 | awk '{print $9}')
extractDir=$(echo $backupFile | cut -f 1 -d '.')
echo "Current backup: $extractDir"
#Create the workdir and copy all the important files to it
workdir=$(mktemp -d)
cd $workdir
echo "Tmp dir: $workdir"
mkdir new
unzip -qq "$backupDirectory/$backupFile" -d "./$extractDir" > /dev/null 2>&1
cd $extractDir
echo "Copied:"
find . -path ".$snipeitDirectory/public/uploads/barcodes" -prune -o -print| egrep '(*\.png|*\.jpg|*\.webp|*\.gif|*\.svg|\.env)$' | cpio -pdmu ../new/
cd ../
cp -r $extractDir/db-dumps new/
now=$(date +%s)
#If there are no previous full backups, then create one
if [ -z "$(ls -A "$destinationDir/")" ]; then
mkdir "$destinationDir/$now"
fi
lastBackup=$(ls -lt $destinationDir | head -2 | tail -1 | awk '{print $9}')
#If there are no patches, create a folder for them
if ! [ -d "$destinationDir/$lastBackup/patches" ]; then
mkdir "$destinationDir/$lastBackup/patches"
fi
#Check and copy all files (images, .env) that are either new or changed.
cd new
files=$(find ".$snipeitDirectory" -type f)
echo "Files to check:"
echo "$files"
echo "Trying to copy:"
while IFS= read -r file; do
if ! [ -f "$destinationDir/$lastBackup/$(echo $file | cut -c 3-)" ] || [ "$destinationDir/$lastBackup/$(echo $file | cut -c 3-)" -ot "$file" ]; then
cp -u --parents "$file" "$destinationDir/$lastBackup/"
echo "Copied $file $destinationDir/$lastBackup/$(echo $file | cut -c 3-)"
else
echo "File already exists: $destinationDir/$lastBackup/$(echo $file | cut -c 3-)"
fi
done <<< "$files"
#Try to make a patch of the database dump
file="db-dumps/mysql-snipeit.sql"
if [ -z "$(ls -A "$destinationDir/$lastBackup/patches")" ]; then
diff -urN null $file > patch.patch
cp "patch.patch" "$destinationDir/$lastBackup/patches/$now.patch"
echo "Copied patch to $destinationDir/$lastBackup/patches/$now.patch"
else
for p in "$destinationDir/$lastBackup/patches/*.patch"; do
(patch --quiet -p1) < $p
done
result=$(diff "mysql-snipeit.sql" "$file" > "$now.patch" && echo $? || echo $?)
#Only save non-empty patches
if [ $result != 0 -a $result != 1 ]; then
echo "Nothing to patch"
exit 1
fi
if [ -s "$now.patch" ]; then
cp "$now.patch" "$destinationDir/$lastBackup/patches/"
echo "Copied patch to $destinationDir/$lastBackup/patches/$now.patch"
else
echo "Nothing to patch"
fi
fi
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment