mirror of
https://github.com/lephisto/crossover.git
synced 2025-12-06 04:09:20 +01:00
Changed logic of locking, changed help accordingly
This commit is contained in:
66
crossover
66
crossover
@@ -29,7 +29,8 @@ declare -i opt_debug=0
|
|||||||
declare -i opt_dry_run=0
|
declare -i opt_dry_run=0
|
||||||
declare -i opt_syslog=0
|
declare -i opt_syslog=0
|
||||||
declare -i opt_lock=1
|
declare -i opt_lock=1
|
||||||
declare -i opt_keeplock=0
|
declare -i opt_keepslock=0
|
||||||
|
declare -i opt_keepdlock=0
|
||||||
declare -i opt_overwrite=0
|
declare -i opt_overwrite=0
|
||||||
declare -i opt_online=0
|
declare -i opt_online=0
|
||||||
declare -i opt_keep_local=0
|
declare -i opt_keep_local=0
|
||||||
@@ -37,8 +38,6 @@ declare -i opt_keep_remote=0
|
|||||||
|
|
||||||
declare -r redstconf='^\/etc\/pve\/nodes\/(.*)\/qemu-server\/([0-9]+).conf$'
|
declare -r redstconf='^\/etc\/pve\/nodes\/(.*)\/qemu-server\/([0-9]+).conf$'
|
||||||
declare -r recephimg='([a-zA-Z0-9]+)\:(.*)'
|
declare -r recephimg='([a-zA-Z0-9]+)\:(.*)'
|
||||||
declare -r resnapname=".*@$opt_snapshot_prefix(.*)"
|
|
||||||
declare -r resplitvmid='^([0-9]+):([0-9]+)$'
|
|
||||||
|
|
||||||
function usage(){
|
function usage(){
|
||||||
shift
|
shift
|
||||||
@@ -68,17 +67,15 @@ Commands:
|
|||||||
mirror Replicate a stopped VM to another Cluster (full clone)
|
mirror Replicate a stopped VM to another Cluster (full clone)
|
||||||
|
|
||||||
Options:
|
Options:
|
||||||
--vmid The ID of the VM/CT, comma separated (es. 100,101,102),
|
--vmid The source+target ID of the VM/CT, comma separated (eg. --vmid=100:100,101:101),
|
||||||
'all-???' for all known guest systems in specific host (es. all-pve1, all-\$(hostname)),
|
|
||||||
'all' for all known guest systems in cluster,
|
|
||||||
'storage-???' storage Proxmox VE (pool Ceph)
|
|
||||||
--destination 'Target PVE Host in target pool. e.g. --destination=pve04
|
--destination 'Target PVE Host in target pool. e.g. --destination=pve04
|
||||||
--pool 'Ceph pool name in target pool. e.g. --pool=data
|
--pool 'Ceph pool name in target pool. e.g. --pool=data
|
||||||
--keeplocal 'How many additional Snapshots to keep locally. e.g. --keeplocal=2
|
--keeplocal 'How many additional Snapshots to keep locally. e.g. --keeplocal=2
|
||||||
--keepremote 'How many additional Snapshots to keep remote. e.g. --keepremote=2
|
--keepremote 'How many additional Snapshots to keep remote. e.g. --keepremote=2
|
||||||
--online 'Allow online Copy
|
--online 'Allow online Copy
|
||||||
--nolock 'Don't lock source VM on Transfer
|
--nolock 'Don't lock source VM on Transfer (mainly for test purposes)
|
||||||
--keeplock 'Keep source VM locked on Transfer
|
--keep-slock 'Keep source VM locked on Transfer
|
||||||
|
--keep-dlock 'Keep VM locked after transfer on Destination
|
||||||
--overwrite 'Overwrite Destination
|
--overwrite 'Overwrite Destination
|
||||||
--debug 'Show Debug Output
|
--debug 'Show Debug Output
|
||||||
|
|
||||||
@@ -95,7 +92,7 @@ function parse_opts(){
|
|||||||
local args
|
local args
|
||||||
args=$(getopt \
|
args=$(getopt \
|
||||||
--options '' \
|
--options '' \
|
||||||
--longoptions=vmid:,destination:,pool:,keeplocal:,keepremote:,online,nolock,keeplock,overwrite,dry-run,debug \
|
--longoptions=vmid:,destination:,pool:,keeplocal:,keepremote:,online,nolock,keep-slock,keep-dlock,overwrite,dry-run,debug \
|
||||||
--name "$PROGNAME" \
|
--name "$PROGNAME" \
|
||||||
-- "$@") \
|
-- "$@") \
|
||||||
|| end_process 128
|
|| end_process 128
|
||||||
@@ -113,7 +110,8 @@ function parse_opts(){
|
|||||||
--dry-run) opt_dry_run=1; shift;;
|
--dry-run) opt_dry_run=1; shift;;
|
||||||
--debug) opt_debug=1; shift;;
|
--debug) opt_debug=1; shift;;
|
||||||
--nolock) opt_lock=0; shift;;
|
--nolock) opt_lock=0; shift;;
|
||||||
--keeplock) opt_keeplock=1; shift;;
|
--keep-slock) opt_keepslock=1; shift;;
|
||||||
|
--keep-dlock) opt_keepdlock=1; shift;;
|
||||||
--overwrite) opt_overwrite=1; shift;;
|
--overwrite) opt_overwrite=1; shift;;
|
||||||
--) shift; break;;
|
--) shift; break;;
|
||||||
*) break;;
|
*) break;;
|
||||||
@@ -297,38 +295,45 @@ function mirror() {
|
|||||||
local disk=''
|
local disk=''
|
||||||
dvmid=${dvmids[$vm_id]}
|
dvmid=${dvmids[$vm_id]}
|
||||||
|
|
||||||
dststatus=$(ssh root@${dstpvnode[$dvmid]} qm status $dvmid|cut -d' ' -f 2)
|
|
||||||
if [ $dststatus == "running" ]; then
|
|
||||||
log error "Destination VM is running. bailing out"
|
|
||||||
end_process 255
|
|
||||||
fi
|
|
||||||
|
|
||||||
srcvmgenid=$(cat $PVE_NODES/"${pvnode[$vm_id]}"/$QEMU/"$vm_id".conf|grep vmgenid|sed -r -e 's/^vmgenid:\s(.*)/\1/')
|
srcvmgenid=$(cat $PVE_NODES/"${pvnode[$vm_id]}"/$QEMU/"$vm_id".conf|grep vmgenid|sed -r -e 's/^vmgenid:\s(.*)/\1/')
|
||||||
dstvmgenid=$(ssh $opt_destination cat $PVE_NODES/"${dstpvnode[$dvmid]}"/$QEMU/"$dvmid".conf|grep vmgenid|sed -r -e 's/^vmgenid:\s(.*)/\1/')
|
dstvmgenid=$(ssh $opt_destination cat $PVE_NODES/"${dstpvnode[$dvmid]}"/$QEMU/"$dvmid".conf 2>/dev/null|grep vmgenid|sed -r -e 's/^vmgenid:\s(.*)/\1/')
|
||||||
log debug "Checking for VM $dvmid on Destination Host $opt_destination $QEMU_CONF_CLUSTER"
|
log debug "Checking for VM $dvmid on Destination Host $opt_destination $QEMU_CONF_CLUSTER"
|
||||||
log debug "DVMID: $dvmid"
|
log debug "DVMID: $dvmid"
|
||||||
conf_on_destination=$(ssh $opt_destination "ls -d $QEMU_CONF_CLUSTER/$dvmid$EXT_CONF 2>/dev/null")
|
conf_on_destination=$(ssh $opt_destination "ls -d $QEMU_CONF_CLUSTER/$dvmid$EXT_CONF 2>/dev/null")
|
||||||
[[ "$conf_on_destination" =~ $redstconf ]]
|
[[ "$conf_on_destination" =~ $redstconf ]]
|
||||||
host_on_destination=${BASH_REMATCH[1]}
|
host_on_destination=${BASH_REMATCH[1]}
|
||||||
|
|
||||||
|
if [ $host_on_destination ]; then
|
||||||
|
dststatus=$(ssh root@${dstpvnode[$dvmid]} qm status $dvmid|cut -d' ' -f 2)
|
||||||
|
if [ $dststatus == "running" ]; then
|
||||||
|
log error "Destination VM is running. bailing out"
|
||||||
|
end_process 255
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
#Check if source VM is running
|
||||||
srcstatus=$(ssh root@${pvnode[$vm_id]} qm status $vm_id|cut -d' ' -f 2)
|
srcstatus=$(ssh root@${pvnode[$vm_id]} qm status $vm_id|cut -d' ' -f 2)
|
||||||
if [ $srcstatus == "running" ] && [ $opt_online -eq 0 ]; then
|
if [ $srcstatus == "running" ] && [ $opt_online -eq 0 ]; then
|
||||||
log error "Source VM is running .. exiting"
|
log error "Source VM is running .. exiting"
|
||||||
end_process 1
|
end_process 1
|
||||||
fi
|
fi
|
||||||
if [ -z "$host_on_destination" ] || [ $opt_overwrite -eq 1 ]; then
|
|
||||||
if [ $srcvmgenid != $dstvmgenid ]; then
|
if [ ! "$host_on_destination" ] || [ $opt_overwrite -eq 1 ]; then
|
||||||
log error "Source VM genid ($srcvmgenid) doesn't match destination VM genid ($dstvmgenid). This should not happen. Bailing out"
|
if [ "$host_on_destination" ] && [ $srcvmgenid != $dstvmgenid ]; then
|
||||||
|
log error "Source VM genid ($srcvmgenid) doesn't match destination VM genid ($dstvmgenid). This should not happen. Bailing out.."
|
||||||
end_process 255
|
end_process 255
|
||||||
fi
|
fi
|
||||||
log info "Transmitting Config for VM $vm_id to desination $dvmid"
|
log info "Transmitting Config for VM $vm_id to desination $dvmid"
|
||||||
rewriteconfig $PVE_NODES/"${pvnode[$vm_id]}"/$QEMU/"$vm_id".conf $opt_destination "$opt_pool" $PVE_NODES/"$opt_destination"/$QEMU/"$dvmid".conf "$dvmid"
|
rewriteconfig $PVE_NODES/"${pvnode[$vm_id]}"/$QEMU/"$vm_id".conf $opt_destination "$opt_pool" $PVE_NODES/"$opt_destination"/$QEMU/"$dvmid".conf "$dvmid"
|
||||||
fi
|
fi
|
||||||
exit
|
|
||||||
#Lock on source
|
#Lock on source + destination
|
||||||
if [ $opt_lock -eq 1 ]; then
|
if [ $opt_lock -eq 1 ]; then
|
||||||
ssh root@"${pvnode[$vm_id]}" qm set "$vm_id" --lock backup
|
ssh root@"${pvnode[$vm_id]}" qm set "$vm_id" --lock backup
|
||||||
|
ssh root@"${dstpvnode[$dvmid]}" qm set "$dvmid" --lock backup
|
||||||
fi
|
fi
|
||||||
#Take Rbd Snapshot
|
|
||||||
|
#Freeze, take Rbd Snapshot then unfreeze
|
||||||
vm_freeze "$vm_id" "${pvnode[$vm_id]}"
|
vm_freeze "$vm_id" "${pvnode[$vm_id]}"
|
||||||
for disk in $(get_disks_from_config "$file_config"); do
|
for disk in $(get_disks_from_config "$file_config"); do
|
||||||
src_image_spec=$(get_image_spec "$disk")
|
src_image_spec=$(get_image_spec "$disk")
|
||||||
@@ -342,13 +347,11 @@ function mirror() {
|
|||||||
[ -z "$src_image_spec" ] && continue
|
[ -z "$src_image_spec" ] && continue
|
||||||
dst_image_spec=$(echo $src_image_spec | sed -r -e "s/([a-zA-Z0-9]+\/[a-zA-Z0-9]+\-)([0-9]+)(\-[a-zA-Z0-9]+\-[0-9]+)/\1$dvmid\3/")
|
dst_image_spec=$(echo $src_image_spec | sed -r -e "s/([a-zA-Z0-9]+\/[a-zA-Z0-9]+\-)([0-9]+)(\-[a-zA-Z0-9]+\-[0-9]+)/\1$dvmid\3/")
|
||||||
[ -z "$dst_image_spec" ] && continue
|
[ -z "$dst_image_spec" ] && continue
|
||||||
echo "src_image_spec: $src_image_spec dst_image_spec: $dst_image_spec"
|
|
||||||
[[ $disk =~ $recephimg ]]
|
[[ $disk =~ $recephimg ]]
|
||||||
src_image_pool=${BASH_REMATCH[1]}
|
src_image_pool=${BASH_REMATCH[1]}
|
||||||
src_image_name=${BASH_REMATCH[2]}
|
src_image_name=${BASH_REMATCH[2]}
|
||||||
[[ $dst_image_spec =~ ^[a-zA-Z0-9]+\/(.*)$ ]]
|
[[ $dst_image_spec =~ ^[a-zA-Z0-9]+\/(.*)$ ]]
|
||||||
dst_image_name=${BASH_REMATCH[1]}
|
dst_image_name=${BASH_REMATCH[1]}
|
||||||
echo "dst:image_name: $dst_image_name"
|
|
||||||
snapshot_name="@$opt_snapshot_prefix$timestamp"
|
snapshot_name="@$opt_snapshot_prefix$timestamp"
|
||||||
localsnapcount=$(rbd ls -l $src_image_pool | grep $src_image_name@$opt_snapshot_prefix | cut -d ' ' -f 1|wc -l)
|
localsnapcount=$(rbd ls -l $src_image_pool | grep $src_image_name@$opt_snapshot_prefix | cut -d ' ' -f 1|wc -l)
|
||||||
if [ $localsnapcount -ge 2 ]; then
|
if [ $localsnapcount -ge 2 ]; then
|
||||||
@@ -357,6 +360,7 @@ function mirror() {
|
|||||||
localts=$(rbd ls -l $src_image_pool | grep $src_image_name@$opt_snapshot_prefix | cut -d ' ' -f 1 | sed -r -e 's/.*@mirror-(.*)/\1/')
|
localts=$(rbd ls -l $src_image_pool | grep $src_image_name@$opt_snapshot_prefix | cut -d ' ' -f 1 | sed -r -e 's/.*@mirror-(.*)/\1/')
|
||||||
fi
|
fi
|
||||||
latestremote=$(ssh $opt_destination rbd ls -l $opt_pool | grep $dst_image_name@$opt_snapshot_prefix | cut -d ' ' -f 1|tail -n 1)
|
latestremote=$(ssh $opt_destination rbd ls -l $opt_pool | grep $dst_image_name@$opt_snapshot_prefix | cut -d ' ' -f 1|tail -n 1)
|
||||||
|
if [ $latestremote ]; then
|
||||||
[[ $latestremote =~ ^.*@$opt_snapshot_prefix([0-9]+)$ ]]
|
[[ $latestremote =~ ^.*@$opt_snapshot_prefix([0-9]+)$ ]]
|
||||||
latestremotets=${BASH_REMATCH[1]}
|
latestremotets=${BASH_REMATCH[1]}
|
||||||
for ts in $localts; do
|
for ts in $localts; do
|
||||||
@@ -364,6 +368,7 @@ function mirror() {
|
|||||||
basets=$ts
|
basets=$ts
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
fi
|
||||||
if [ -z $basets ]; then
|
if [ -z $basets ]; then
|
||||||
log debug "No matching Snapshot found on destination - Full Copy $src_image_pool/$src_image_name$snapshot_name to $opt_pool/$dst_image_name"
|
log debug "No matching Snapshot found on destination - Full Copy $src_image_pool/$src_image_name$snapshot_name to $opt_pool/$dst_image_name"
|
||||||
xmitjob="rbd export --rbd-concurrent-management-ops 8 $src_image_pool/$src_image_name$snapshot_name --no-progress -|pv -r|ssh $opt_destination rbd import --image-format 2 - $opt_pool/$dst_image_name"
|
xmitjob="rbd export --rbd-concurrent-management-ops 8 $src_image_pool/$src_image_name$snapshot_name --no-progress -|pv -r|ssh $opt_destination rbd import --image-format 2 - $opt_pool/$dst_image_name"
|
||||||
@@ -376,7 +381,6 @@ function mirror() {
|
|||||||
do_run $cmd
|
do_run $cmd
|
||||||
else
|
else
|
||||||
log debug "Basecopy + snapshot on destination - let's just transfer the diff"
|
log debug "Basecopy + snapshot on destination - let's just transfer the diff"
|
||||||
# [[ $previouslocal =~ $resnapname ]]
|
|
||||||
xmitjob="rbd export-diff --from-snap $opt_snapshot_prefix$basets $src_image_pool/$currentlocal - | ssh $opt_destination rbd import-diff - $opt_pool/$dst_image_name"
|
xmitjob="rbd export-diff --from-snap $opt_snapshot_prefix$basets $src_image_pool/$currentlocal - | ssh $opt_destination rbd import-diff - $opt_pool/$dst_image_name"
|
||||||
if ! do_run $xmitjob; then
|
if ! do_run $xmitjob; then
|
||||||
log error "Transmitting Image failed"
|
log error "Transmitting Image failed"
|
||||||
@@ -386,9 +390,13 @@ function mirror() {
|
|||||||
do_housekeeping "$opt_destination" "$opt_pool" "$dst_image_name" $opt_keep_remote
|
do_housekeeping "$opt_destination" "$opt_pool" "$dst_image_name" $opt_keep_remote
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
if [ ! $opt_keeplock -eq 1 ] && [ ! $opt_lock -eq 1 ]; then
|
if [ ! $opt_keepslock -eq 1 ]; then
|
||||||
ssh root@${pvnode[$vm_id]} qm unlock $vm_id
|
ssh root@${pvnode[$vm_id]} qm unlock $vm_id
|
||||||
log info "Unlocking VM $vm_id"
|
log info "Unlocking source VM $vm_id"
|
||||||
|
fi
|
||||||
|
if [ $opt_keepdlock -eq 0 ]; then
|
||||||
|
ssh root@${dstpvnode[$dvmid]} qm unlock $dvmid
|
||||||
|
log info "Unlocking destination VM $dvmid"
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
}
|
}
|
||||||
@@ -427,7 +435,6 @@ function vm_freeze() {
|
|||||||
fi
|
fi
|
||||||
local cmd="ssh root@$fhost /usr/sbin/qm guest cmd $fvm fsfreeze-freeze"
|
local cmd="ssh root@$fhost /usr/sbin/qm guest cmd $fvm fsfreeze-freeze"
|
||||||
log info "VM $fvm - Issuing fsfreeze-freeze to $fvm on $fhost"
|
log info "VM $fvm - Issuing fsfreeze-freeze to $fvm on $fhost"
|
||||||
log debug "$cmd"
|
|
||||||
do_run "$cmd"
|
do_run "$cmd"
|
||||||
rc=$?
|
rc=$?
|
||||||
log debug "vm_freeze() return $rc"
|
log debug "vm_freeze() return $rc"
|
||||||
@@ -443,7 +450,6 @@ function vm_unfreeze() {
|
|||||||
fi
|
fi
|
||||||
local cmd="ssh root@$fhost /usr/sbin/qm guest cmd $fvm fsfreeze-thaw"
|
local cmd="ssh root@$fhost /usr/sbin/qm guest cmd $fvm fsfreeze-thaw"
|
||||||
log info "VM $fvm - Issuing fsfreeze-thaw to $fvm on $fhost"
|
log info "VM $fvm - Issuing fsfreeze-thaw to $fvm on $fhost"
|
||||||
log debug "$cmd"
|
|
||||||
do_run "$cmd"
|
do_run "$cmd"
|
||||||
rc=$?
|
rc=$?
|
||||||
log debug "vm_unfreeze() return $rc"
|
log debug "vm_unfreeze() return $rc"
|
||||||
|
|||||||
Reference in New Issue
Block a user