#!/usr/bin/env bash## Setup, configure, backup my personal linux systems## Aims to have a single folder to contain all backup-able items##functionlinux_setup(){
# - prompt for system/user home dir# - prompt for system files directory (source of truth)# - prompt for Documents parent directory# - Contains 'Documents', 'Pictures', and so on. We will make symlinks# - prompt for home_symlinks directory where each immediate child is directly symlinked into home dir# - prompt for scripts directory of scripts to execute after built-in system setup# - copy my firefox profile# - copy spacevim's init.toml file# - prompt if old home dirs ('documents', etc) should be deleted or moved# - backup home dir (for symlinking)# - target home directory (on the system we're setting up)# - Execution# - execute pre-setup scripts# - create symlinks to each file in `home_symlinks` dir# - remove existing `Documents` & other dirs if empty. Move otherwise# - symlink to own documents & pictures directories# - execute post-setup scripts
homeDir=""
rootDir=""if [[ -f ~/.tlfsetup ]];thensource ~/.tlfsetup
fiwhile [[ ! -d "$homeDir" ]]; do
prompt "Absolute path to your home directory:" homeDir
donewhile [[ ! -d "$rootDir" ]]; do
prompt "Absolute path to all your files:" rootDir
doneecho"# Enter paths relative to '$rootDir'"echo""## Where 'Documents' and 'Pictures' & the like go
filesDir="$rootDir/Files/"while [[ ! -d "$filesDir" ]]; do
prompt "Relative path to Files dir (contains Documents/, Pictures/, etc):" filesDir
filesDir="$rootDir/$filesDir"done## System Dir, where setup files are located
systemDir="$rootDir/Linux"while [[ ! -d "$systemDir" ]]; do
prompt "Relative path to system dir" systemDir
systemDir="$rootDir/$systemDir"doneecho"Root Paths Found"echo""echo"----"echo"# Enter paths relative to '$systemDir'"echo""## Home Symlinks. link ~/FILE to $homelinkDir/* (including directories)
homeLinkDir="$systemDir/homelink"while [[ ! -d "$homeLinkDir" ]]; do
prompt "Relative path to homelinks dir:" homeLinkDir
homeLinkDir="$systemDir/$homeLinkDir"done## Home Symlinks. link ~/FILE to $homelinkDir/* (including directories)
systemFilesDir="$systemDir/files"while [[ ! -d "$systemFilesDir" ]]; do
prompt "Relative path to system files dir (requires special setup by scripts):" homeLinkDir
systemFilesDir="$systemDir/$systemFilesDir"done## Where to put files that we (re)move during setup
trashDir="$systemDir/setup_trash/"while [[ ! -d "$trashDir" ]]; do
prompt "Relative path to setup trash dir:" trashDir
trashDir="$systemDir/$trashDir"done
trashDir="$trashDir/$(date +%d-%m-%Y-%H:%M)/"
mkdir "$trashDir"## Setup Dir, to load scripts & packages to install & such
setupDir="$systemDir/setup/"while [[ ! -d "$setupDir" ]]; do
prompt "Relative path to setup dir, to load scripts & info from: " setupDir
postSetupScriptsDir="$systemDir/$setupDir"done## Source directory for scripts & things
sourceDir="$systemDir/src/"while [[ ! -d "$sourceDir" ]]; do
prompt "Relative path to source dir, where your scripts will load from:" soureDir
sourceDir="$ystemDir/$sourceDir"doneecho"System Paths Found"echo""########### done getting paths##### start doing actual setup######
preSetupScript="$setupDir/pre-setup.bash"if [[ -f "$preSetupScript" ]];then
step "Run pre Setup Script?"source"$setupDir/pre-setup.bash"fi
step "Write symlinks to files. " write_home_symlinks_to "$homeLinkDir""$homeDir""$trashDir"
step "Write symlinks to Documents, Pictures, etc" write_home_symlinks_to "$filesDir""$homeDir""$trashDir"if [[ -f "$setupDir/dnf-remove" ]];then
dnfRemoveList="$(cat "$setupDir/dnf-remove")"
prompt=$(echo -e "\nRemove ${dnfRemoveList[@]}")
step "$prompt" sudo dnf remove ${dnfRemoveList[@]}fiif [[ -f "$setupDir/dnf-install" ]];then
dnfInstallList="$(cat "$setupDir/dnf-install")"
prompt=$(echo -e "\nInstall ${dnfInstallList[@]}")
step "$prompt" sudo dnf install ${dnfInstallList[@]}fi
postSetupScript="$setupDir/post-setup.bash"if [[ -f "$postSetupScript" ]];then
step "Run Post Setup Script?"source"$setupDir/post-setup.bash"fi
step_run
}
functionlinux_restore(){
echo"Being run from '$(pwd)'"echo"Use absolute paths"# Executing it for backup would# - prompt for backup path# - prompt for target restore path# - Ask if we should do a dry run# - ask if we should --delete on restore# - The backup# - Delete files that don't exist in source of truth# - overrwrite existing files unless they're the same (how do I do that with rsync?)# - execute 'pre-restore' scripts# - rsync everything# - execute 'post-backup' scripts# - decompress git folders# - Write a .last_backup file that shows when the backup was performed
backupDir=""
restoreDir=""# backupDir="/path/to/test/backup/dir/"# restoreDir="/path/to/test/source/dir"# backupDir="/mnt/BackupDrive/a/"# restoreDir="/home/reed/.disk"while [[ ! -d "$backupDir" ]]; do
prompt "The directory to restore your files from" backupDir
done
backupDir="$backupDir/"# Location to restore towhile [[ ! -d "$restoreDir" ]]; do
prompt "Enter path to restore files into" restoreDir
done
restoreDir="${restoreDir%/}"
prompt_yes_or_no "Delete files in target directory, if they're not found in the backup?" doDelete
prompt_yes_or_no "Overwrite files in target directory?" doOverwrite
prompt_yes_or_no "Do dry run?" doDryRun
echo"Restoring from '$backupDir' into '$restoreDir'"## --archive equals -rlptgoD or:# --recursive # recurse into directories# --links # copy symlinks as symlinks# --perms # preserve permissions# --times # preserve modification times# --group # preserve group# --owner # preserve owner# -D is --devices --specials # "preserve device files" & "preserve special files" respectively## Others:# --hard-links preserve hard links (probably not needed)# --executability preserve executability# --acls preserve ACLs (implies --perms) (see `info ACL`. I think this is needed for sticky bits to work? idk)
rsync_args=(--verbose --archive --hard-links --executability --acls --progress)
if [[ $doDelete -eq 1 ]];then
rsync_args+=(--delete)
echo"Delete files not in backup!"fiif [[ $doOverwrite -eq 0 ]];then
rsync_args+=(--ignore-existing)
echo"Overwrite files!"fiif [[ $doDryRun -eq 1 ]]; then
rsync_args+=(--dry-run)
echo"Do dry run!"fiecho"Restore into dir: $restoreDir"echo"Backup Dir: $backupDir"read -p "[enter] continue "
rsync "${rsync_args[@]}""$backupDir""$restoreDir"
run_decompress_git "$restoreDir"
postRestoreScript="$restoreDir/post-restore.bash"if [[ -f "$postRestoreScript" ]];thensource"$postRestoreScript"fiecho -e "\nShould be all done!!\n"
}
functionlinux_backup(){
echo"Being run from '$(pwd)'"echo"Use absolute paths"# Executing it for backup would# - prompt for target backup path# - prompt for source of truth# - ask if git folders should be backed up# - Ask if we should do a dry run# - The backup# - Delete files that don't exist in source of truth# - overrwrite existing files unless they're the same (how do I do that with rsync?)# - execute 'pre-backup' scripts# - compress git folders# - rsync compressed git folders# - rsync everything else except ignored directories (ignore git folders)# - execute 'post-backup' scripts# - decompress git folders# - Write a .last_backup file that shows when the backup was performed
sourceDir=""
backupDir=""# sourceDir="/path/to/test/source/dir/"# backupDir="/path/to/test/backup/dir"while [[ ! -d "$sourceDir" ]]; do
prompt "The directory to backup" sourceDir
sourceDir="$sourceDir/"done
excludesListFile=""
useExcludesFile=truewhile [[ ! -f "$excludesListFile" ]]; do
prompt "Enter relative path to your rsync excludes file (within '$sourceDir') or 's' to skip" excludesListRelFile
if [[ "$excludesListRelFile" == "s" ]];then
useExcludesFile=falsebreak;
fi
excludesListFile="$sourceDir/$excludesListRelFile"done# Location to backup sourcedir towhile [[ ! -d "$backupDir" ]]; do
prompt "Enter path to backup dir" backupDir
backupDir="${backupDir%/}"done
prompt_yes_or_no "Backup .git folders?" doBackupGit
prompt_yes_or_no "Do dry run?" doDryRun
echo"Backing up from '$sourceDir' into '$backupDir'"
preBackupScript="$sourceDir/pre-backup.bash"if [[ -f "$preBackupScript" ]];then
step "Run pre backup Script?"source"$preBackupScript"fiif [[ $doBackupGit -eq 1 ]];then
run_compress_git "$sourceDir"echo -e "\n\n-------- .git folders compressed: \n"
find "$sourceDir" | grep ".git.tar.gz"echo -e "\n----------------\n"read -p "(enter) to continue"fi## --archive equals -rlptgoD or:# --recursive # recurse into directories# --links # copy symlinks as symlinks# --perms # preserve permissions# --times # preserve modification times# --group # preserve group# --owner # preserve owner# -D is --devices --specials # "preserve device files" & "preserve special files" respectively## Others:# --hard-links preserve hard links (probably not needed)# --executability preserve executability# --acls preserve ACLs (implies --perms) (see `info ACL`. I think this is needed for sticky bits to work? idk)
rsync_args=(--verbose --archive --hard-links --executability --acls --progress)
if [[ $doDryRun -eq 1 ]]; then
rsync_args+=(--dry-run)
echo"Do dry run!"fi
rsync_end_args=()
if$useExcludesFile;then
rsync_end_args+=("--exclude-from=$excludesListFile")
fiecho"Source Dir: $sourceDir"echo"Backup Dir: $backupDir"
rsync "${rsync_args[@]}" --delete --delete-excluded --exclude=".git/" --exclude="vendor/""${rsync_end_args[@]}""$sourceDir""$backupDir"if [[ $doBackupGit -eq 1 ]];then
run_decompress_git "$sourceDir"fiecho -e "\nShould be all done!!\n"
}