add btrbk_named drop latest_clone

add btrfs_clone and mp_subvol
fix but s: to s  in copy options
add several path string helper function
master
David Kebler 2024-03-05 13:50:09 -08:00
parent 195c34e80a
commit c42c9777a9
4 changed files with 118 additions and 12 deletions

View File

@ -11,6 +11,7 @@
btrbk_scripts_dir="$(dirname $(realpath "${BASH_SOURCE:-$0}"))" btrbk_scripts_dir="$(dirname $(realpath "${BASH_SOURCE:-$0}"))"
module_load helpers
# will try to find a conf file with out without .conf extension in a few places # will try to find a conf file with out without .conf extension in a few places
btrbk_conf () { btrbk_conf () {
@ -128,12 +129,22 @@ btrbk_latest_links $([[ $dry_run ]] || printf "%s" -e) $file
(return 0 2>/dev/null) || btrbk_run $@ (return 0 2>/dev/null) || btrbk_run $@
latest_clone () { btrbk_named () {
# btrfs subvolume list -o . -r --sort path,gen
# todo
# rw vs ro -r
# -f folder with extensions removed vs appended extension
# figure out latest instead of depending on .latest
# find unique names, then list and grep on those and use
# btrfs subvolume list -o . -r --sort path+gen
module_load confirm
local name; local names
local snapname=".latest"
[[ $1 == "-s" ]] && snapname="$2" && shift 2
local src=$(realpath $1) local src=$(realpath $1)
local dest=$(realpath $2) local dest=$(realpath $2)
shift 2
module_load confirm
if [[ ! -d $dest ]]; then if [[ ! -d $dest ]]; then
if confirm "destination directory $dest does not exist, create it"; then if confirm "destination directory $dest does not exist, create it"; then
sudo mkdir -p $dest sudo mkdir -p $dest
@ -141,9 +152,23 @@ latest_clone () {
return 1 return 1
fi fi
fi fi
local snaps=$(ls $src | grep latest | sed 's/.\{1\}$//' | xargs -I % realpath $src/%) echo looking for snapshots in $src with extension matching $snapname
[[ ! $snaps ]] && echo no latest snapshots in $src && ls -la $src && return 1 local snaps=$(ls $src | grep "\..*$snapname" | sed 's/.\{1\}$//' | xargs -I % realpath $src/%)
if confirm create snapshots for $snaps in $dest; then
# while read test; do
# echo $test
# done <<< "$( btrfs subvolume list -o . -r --sort path+gen | get just path | get only fname)"
[[ ! $snaps ]] && echo no snapshots with extension $snapname in $src && ls -la $src && return 1
echo creating snapshots for
for snap in $snaps; do
name=$(get_only_fname $snap)
[[ $names == *"$name"* ]] && echo whoops! snapshots found for $(rm_ext $snap) using filter $snapname not unique, aborting && ls -la | grep $ && return 3
names+=" $name"
echo $snap
done
if confirm in $dest; then
local destsnap local destsnap
for snap in $snaps; do for snap in $snaps; do
destsnap="$dest/$(basename $snap | cut -f 1 -d '.' )" destsnap="$dest/$(basename $snap | cut -f 1 -d '.' )"
@ -156,6 +181,7 @@ latest_clone () {
fi fi
sudo btrfs subvolume snapshot $@ $snap $destsnap sudo btrfs subvolume snapshot $@ $snap $destsnap
done done
echo $dest echo $dest
ls -la $dest ls -la $dest
fi fi

View File

@ -13,6 +13,7 @@ make_subvol() {
[[ $EUID -ne 0 ]] && usesudo=sudo [[ $EUID -ne 0 ]] && usesudo=sudo
uid=${2:-$USER} uid=${2:-$USER}
gid=${3:-$uid} gid=${3:-$uid}
mkdir -p $(dirname $1) &> /dev/null
echo $usesudo $BTRFS_BIN subvolume create $1 echo $usesudo $BTRFS_BIN subvolume create $1
$usesudo $BTRFS_BIN subvolume create $1 $usesudo $BTRFS_BIN subvolume create $1
echo $usesudo chown $uid:$gid $1 echo $usesudo chown $uid:$gid $1
@ -112,12 +113,12 @@ folder_snapshot() {
} }
mount_subvolume () { mount_subvolume () {
echo sudo mount $1 -o subvol=$2 $3 # echo sudo mount $1 -o subvol=$2 $3
if mountpoint $3; then if mountpoint $3 &> /dev/null; then
echo $3 already a mountpoint, aborting subvolume mount echo $3 already a mountpoint, aborting subvolume mount
else else
mkdir -p $3 mkdir -p $3 &> /dev/null
sudo mount $1 -o subvol=$2 $3 if ! sudo mount $1 -o subvol=$2 $3 > /dev/null ; then echo "failed to mount $2"; return 1; fi
fi fi
} }
@ -146,6 +147,64 @@ fi
} }
# finds device and subvolume of a mountpoint (or a mountpoint above the given path)
mp_subvol () {
module_load filesystem
local mp; local subvol
mp=$(find_mountpoint $1)
path=${1//"$mp"/}
dev=$(mount | grep "$mp " | cut -f 1 -d ' ')
IFS=, read -r -a input <<< $(findmnt -nt btrfs | grep "$mp ")
for x in "${input[@]}"; do
eval $(echo $x | grep subvol=)
[[ $subvol ]] && echo $dev $subvol$path
done
}
btrfs_clone () {
# btrfs_clone <subvol> <source> <dest>
# if [[ $# == "3" ]]; then
module_load filesystem
local src; local dest; local dr; local usesudo
[[ $EUID -ne 0 ]] && usesudo=sudo
dr="--dry-run"
[[ $1 == "-r" ]] && dr="" && shift
subvol=$1
src=$2
dest=$3
$usesudo umount /tmp/source &> /dev/null
sudo mount $src /tmp/source
# $usesudo umount /tmp/dest &> /dev/null
# if mount_subvolume $src $subvol /tmp/source; then
if ! make_subvol $dest/$(basename $subvol) &> /dev/null; then echo unable to make subvolume $1 at $dest; return 2; fi
# $usesudo btrfs subvolume show $dest/$(basename $subvol)
# if mount_subvolume $(mp_subvol $dest/$(basename $subvol)) /tmp/dest; then
# echo cloning now
# # echo $usesudo btrfs-clone --toplevel $dr -v /tmp/source /tmp/dest
cmd="$usesudo btrbk $dr archive /tmp/source/$1 $dest/$1"
echo "command: $cmd"
if eval "$cmd"; then
echo "######### $dest/$1 #########"
ls -la /tmp/dest
echo "#################################"
else
echo clone failed
echo $cmd
fi
# else
# echo unable to mount a destination subvolume $1 at $3
# fi
# else
# echo unable to mount source subvolume $1 from $2
# return 1
# fi
# confirm press any key to unmount temporary mountpoints /tmp/source, /tmp/dest
echo unmounting source
$usesudo umount /tmp/source &> /dev/null
# $usesudo umount /tmp/dest &> /dev/null
}
# alias # alias
alias btvl="sudo $BTRFS_BIN subvolume list" alias btvl="sudo $BTRFS_BIN subvolume list"
alias btrfs="sudo $BTRFS_BIN" alias btrfs="sudo $BTRFS_BIN"

View File

@ -140,6 +140,27 @@ mkrfilename () {
echo ${2:-/tmp/}${1:-file}.$RANDOM echo ${2:-/tmp/}${1:-file}.$RANDOM
} }
rm_ext () {
# sed -re 's/(^.*[^/])\.[^./]*$/\1/' <<< "$1"
echo "${1%.*}"
}
get_ext () {
echo "${1##*.}"
}
get_fname () {
# basename $1
echo "${1##*/}"
}
get_only_fname () {
rm_ext "$(get_fname "$1")"
}
get_dir () {
echo "${1%/*}"
}
#rows between matched rows #rows between matched rows
# sed '1,/firstmatch/d;/secondmatch/,$d' # sed '1,/firstmatch/d;/secondmatch/,$d'

View File

@ -52,7 +52,7 @@ EOF
local OPTION local OPTION
local OPTARG local OPTARG
local OPTIND local OPTIND
while getopts 'avMqpf:le:rcCmd:s:hnF' OPTION; do while getopts 'avMqpf:le:rcCmd:shnF' OPTION; do
# echo OPTION $OPTION ARG $OPTARG INDX $OPTIND # echo OPTION $OPTION ARG $OPTARG INDX $OPTIND
case "$OPTION" in case "$OPTION" in
s) s)