Skip to content

Instantly share code, notes, and snippets.

@clexanis
Last active March 30, 2023 19:30
Show Gist options
  • Save clexanis/2b44f7581f847daa182190860872fdef to your computer and use it in GitHub Desktop.
Save clexanis/2b44f7581f847daa182190860872fdef to your computer and use it in GitHub Desktop.
omv-tmp
#!/bin/bash
#
# shellcheck disable=SC1091,SC2086,SC2181
#
# Copyright (c) 2013-2023 OpenMediaVault Plugin Developers
#
# This file is licensed under the terms of the GNU General Public
# License version 3. This program is licensed "as is" without any
# warranty of any kind, whether express or implied.
#
# version: 1.1.2
#
method=ddfull
root="/dev/sda"
backupDir=/srv/tmpfs
declare -i esp=0
OMV_BACKUP_DIR_NAME=${OMV_BACKUP_DIR_NAME:-"omvbackup"}
OMV_BACKUP_FILE_PREFIX=${OMV_BACKUP_FILE_PREFIX:-"backup-omv"}
OMV_BACKUP_MAX_DEPTH=${OMV_BACKUP_MAX_DEPTH:-"1"}
# TODO: Use Salt instead
OMV_BACKUP_FSA_COMP_LEVEL=${OMV_BACKUP_FSA_COMP_LEVEL:-"2"}
threads=$(nproc --all)
purgeOld()
{
# get number of days to keep
keep=$(omv_config_get "/config/system/backup/keep")
echo "keep days :: ${keep}"
if [[ ${keep} -gt 0 ]]; then
echo "Purging old files..."
find "${backupDir}" -maxdepth ${OMV_BACKUP_MAX_DEPTH} -type f -mtime +${keep} -name "${OMV_BACKUP_FILE_PREFIX}*" -delete
if [ $? -eq 0 ]; then
echo "Purging done."
else
echo "Purge failed!"
fi
else
echo "Purging disabled."
fi
}
echo "Starting backup..."
# date
date=$(date +"%Y-%m-%d_%H-%M-%S")
# clean apt-get cache to save space
apt-get clean
# set backup directory and create it if it doesn't exist
_log "Create ${backupDir}"
mkdir -p "${backupDir}"
# Get the method of backup
echo "Method: ${method}"
# get device file for /
devicefile=$(awk '$5 == "/" { print $10 }' /proc/self/mountinfo)
echo "Device file: ${devicefile}"
# try alternate method to get root device if /dev/root is returned
if [ "${devicefile}" = "/dev/root" ]; then
devicefile=$(findmnt -n / | awk '{ print $2 }')
fi
if [ "${devicefile}" = "/dev/root" ] || [ -z "${devicefile}" ]; then
echo "Could not determine root device file. Please specify in the root device textbox. Exiting..."
exit 12
fi
# if root is empty, try to determine root device
if [ -z "${root}" ]; then
root="/dev/$(lsblk -no pkname ${devicefile})"
fi
echo "Root drive: ${root}"
if [ -z "${root}" ]; then
echo "Could not determine root device. Exiting..."
exit 13
fi
# save helpful information
echo "Save fdisk output for ${root}"
fdisk -l ${root} > "${backupDir}/${OMV_BACKUP_FILE_PREFIX}-${date}.fdisk"
if [ $? -eq 0 ]; then
echo "Successfully saved fdisk output for ${root}"
else
echo "Save of fdisk output for ${root} failed!"
fi
echo "Save blkid output"
blkid > "${backupDir}/${OMV_BACKUP_FILE_PREFIX}-${date}.blkid"
if [ $? -eq 0 ]; then
echo "Successfully saved blkid output"
else
echo "Save of blkid output failed!"
fi
echo "Save package list"
dpkg -l | grep openmediavault > "${backupDir}/${OMV_BACKUP_FILE_PREFIX}-${date}.packages"
if [ $? -eq 0 ]; then
echo "Successfully saved package list"
else
echo "Save of package list failed!"
fi
# TODO: Use Salt instead
# zstd options
if [ -z "${OMV_BACKUP_ZSTD_OPTIONS}" ]; then
if [ ${threads} -eq 1 ]; then # Toaster mode!
OMV_BACKUP_ZSTD_OPTIONS="--fast=5"
else
OMV_BACKUP_ZSTD_OPTIONS="-T0 --adapt"
fi
fi
# calculate partition table size to accommodate GPT and MBR.
part_type=$(blkid -p ${root} | cut -d \" -f4)
echo "Partition type :: ${part_type}"
if [ "${part_type}" = "gpt" ]; then
num_parts=$(parted -m ${root} print | tail -n1 | cut -b1)
grubparts_bs_calc=$(((128 * num_parts) + 1024))
esp=$(parted -m ${root} print | awk -F ":" '$7 ~ /esp/ { print $1 }')
if [ ${esp} -lt 1 ]; then
echo "ESP partition not found."
else
partletter=""
if [[ ${root} =~ nvme ]]; then
partletter="p"
fi
esppart="${root}${partletter}${esp}"
echo "ESP partition :: ${esppart}"
if [ -e "${esppart}" ]; then
echo "Backup ESP partition"
dd if=${esppart} bs=1M conv=sync,noerror status=progress | zstd ${OMV_BACKUP_ZSTD_OPTIONS} <${esppart} >"${backupDir}/${OMV_BACKUP_FILE_PREFIX}-${date}.espdd.zst"
if [ $? -eq 0 ]; then
echo "Successfully backuped ESP partition"
else
echo "Backup of ESP partition failed!"
fi
else
echo "ESP partition '${esppart}' not found."
fi
fi
else
grubparts_bs_calc=512
fi
# save partition table and mbr
echo "Save mbr"
dd if=${root} of="${backupDir}/${OMV_BACKUP_FILE_PREFIX}-${date}.grub" bs=446 count=1
if [ $? -eq 0 ]; then
echo "Successfully saved MBR"
else
echo "Save of MBR failed!"
fi
echo "Save mbr and partition table"
dd if=${root} of="${backupDir}/${OMV_BACKUP_FILE_PREFIX}-${date}.grubparts" bs=${grubparts_bs_calc} count=1
if [ $? -eq 0 ]; then
echo "Successfully saved MBR and partition table"
else
echo "Save of MBR and partition table failed!"
fi
# Save partition table using sfdisk
echo "Save partitions using sfdisk"
sfdisk -d ${root} > "${backupDir}/${OMV_BACKUP_FILE_PREFIX}-${date}.sfdisk"
if [ $? -eq 0 ]; then
echo "Successfully saved partition table using sfdisk"
else
echo "Save of sfdisk partition table failed"
fi
# check for /boot partition
bootpart=$(awk '$2 == "/boot" { print $1 }' /proc/mounts)
if [ ! -b "${bootpart}" ]; then
bootpart=""
else
echo "Boot drive: ${bootpart}"
fi
# backup u-boot if platform_install.sh exists
if [ -f "/usr/lib/u-boot/platform_install.sh" ]; then
. /usr/lib/u-boot/platform_install.sh
if [ -d "${DIR}" ]; then
echo "Backup u-boot"
tar cjf "${backupDir}/${OMV_BACKUP_FILE_PREFIX}-${date}_u-boot.tar.bz" ${DIR}/*
if [ $? -eq 0 ]; then
echo "Successfully backuped u-boot"
else
echo "Backup of u-boot failed!"
fi
fi
fi
# perform backup based on method selected
case ${method} in
dd)
echo "Starting dd backup..."
zstd -v ${OMV_BACKUP_ZSTD_OPTIONS} <"${devicefile}" >"${backupDir}/${OMV_BACKUP_FILE_PREFIX}-${date}.dd.zst"
status=( "${PIPESTATUS[@]}" )
echo "dd exit code = ${status[0]}"
echo "zstd ${OMV_BACKUP_ZSTD_OPTIONS}exit code = ${status[1]}"
if [[ ${status[0]} -gt 0 ]] || [[ ${status[1]} -gt 0 ]]; then
echo "dd backup failed!"
exit 14
else
echo "dd backup complete."
fi
sync
if [ -n "${bootpart}" ]; then
echo "Starting dd backup of boot partition..."
zstd ${OMV_BACKUP_ZSTD_OPTIONS} <"${bootpart}" >"${backupDir}/${OMV_BACKUP_FILE_PREFIX}-${date}_boot.dd.zst"
if [ $? -eq 0 ]; then
echo "dd backup of boot partition complete."
else
echo "dd backup of boot partition failed!"
exit 15
fi
fi
sync
touch "${backupDir}/${OMV_BACKUP_FILE_PREFIX}"-${date}*.dd.zst
purgeOld
;;
ddfull)
echo "Starting dd full disk..."
zstd -v ${OMV_BACKUP_ZSTD_OPTIONS} <"${root}" > "${backupDir}/${OMV_BACKUP_FILE_PREFIX}-${date}.ddfull.zst"
status=( "${PIPESTATUS[@]}" )
echo "dd exit code = ${status[0]}"
echo "zstd ${OMV_BACKUP_ZSTD_OPTIONS}exit code = ${status[1]}"
if [[ ${status[0]} -gt 0 ]] || [[ ${status[1]} -gt 0 ]]; then
echo "dd full disk backup failed!"
exit 16
else
echo "dd full disk backup complete."
fi
sync
sync
touch "${backupDir}/${OMV_BACKUP_FILE_PREFIX}"*-${date}.ddfull.zst
purgeOld
;;
esac
echo "Backup complete."
exit 0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment