5 Commits

Author SHA1 Message Date
Bastian
587392e06d Add TPM Disk to migration 2024-10-15 12:53:00 +02:00
Bastian Mäuser
2f985df07d Added option, do specify VMs to process using Proxmox UI Tags 2024-02-26 15:32:23 +01:00
Bastian Mäuser
b7c86b0206 fix incremental ecpool 2024-02-23 12:08:50 +01:00
Bastian Mäuser
3d0babd12c Adjust Documentation 2024-02-23 11:43:00 +01:00
Bastian Mäuser
a885c9fbf9 Added Option to select ssh cipher and set decent default for it 2024-02-23 11:38:11 +01:00
2 changed files with 29 additions and 11 deletions

View File

@@ -2,7 +2,7 @@
[![License](https://img.shields.io/github/license/EnterpriseVE/eve4pve-barc.svg)](https://www.gnu.org/licenses/gpl-3.0.en.html) [![License](https://img.shields.io/github/license/EnterpriseVE/eve4pve-barc.svg)](https://www.gnu.org/licenses/gpl-3.0.en.html)
Cross-Pool (live) Replication and near-live migration for Proxmox VE Cross-Pool asynchronous online-replication and near-live migration for Proxmox VE
```text ```text
@@ -11,7 +11,7 @@ ______
| --| _| . |_ -|_ -| . | | | -_| _| | --| _| . |_ -|_ -| . | | | -_| _|
|_____|_| |___|___|___|___|\_/|___|_| |_____|_| |___|___|___|___|\_/|___|_|
Cross Pool (live) replication and near-live migration for Proxmox VE Cross Pool asynchronous online-replication and near-live migration for Proxmox VE
Usage: Usage:
crossover <COMMAND> [ARGS] [OPTIONS] crossover <COMMAND> [ARGS] [OPTIONS]
@@ -25,6 +25,7 @@ Commands:
mirror Replicate a stopped VM to another Cluster (full clone) mirror Replicate a stopped VM to another Cluster (full clone)
Options: Options:
--sshcipher SSH Cipher to use for transfer (default: aes128-gcm@openssh.com,aes128-cbc)
--vmid The source+target ID of the VM, comma separated (eg. --vmid=100:100,101:101) --vmid The source+target ID of the VM, comma separated (eg. --vmid=100:100,101:101)
(The possibility to specify a different Target VMID is to not interfere with VMIDs on the (The possibility to specify a different Target VMID is to not interfere with VMIDs on the
target cluster, or mark mirrored VMs on the destination) target cluster, or mark mirrored VMs on the destination)

View File

@@ -19,7 +19,7 @@ declare opt_influx_summary_metrics='crossover_jobs'
name=$(basename "$0") name=$(basename "$0")
# readonly variables # readonly variables
declare -r NAME=$name declare -r NAME=$name
declare -r VERSION=0.8 declare -r VERSION=0.9
declare -r PROGNAME=${NAME%.*} declare -r PROGNAME=${NAME%.*}
declare -r PVE_DIR="/etc/pve" declare -r PVE_DIR="/etc/pve"
declare -r PVE_NODES="$PVE_DIR/nodes" declare -r PVE_NODES="$PVE_DIR/nodes"
@@ -68,6 +68,8 @@ declare opt_vm_ids=''
declare opt_snapshot_prefix='mirror-' declare opt_snapshot_prefix='mirror-'
declare opt_rewrite='' declare opt_rewrite=''
declare opt_pool='rbd' declare opt_pool='rbd'
declare opt_sshcipher='aes128-gcm@openssh.com,aes128-cbc'
declare opt_tag=''
declare -i opt_prefix_id declare -i opt_prefix_id
declare opt_exclude_vmids='' declare opt_exclude_vmids=''
declare -i opt_debug=0 declare -i opt_debug=0
@@ -118,6 +120,8 @@ Commands:
mirror Replicate a stopped VM to another Cluster (full clone) mirror Replicate a stopped VM to another Cluster (full clone)
Options: Options:
--sshcipher SSH Cipher to use for transfer (default: aes128-gcm@openssh.com,aes128-cbc)
--tag Include all VMs with a specific tag set in the Proxmox UI (if set, implies vmid=all)
--vmid The source+target ID of the VM/CT, comma separated (eg. --vmid=100:100,101:101), or all for all --vmid The source+target ID of the VM/CT, comma separated (eg. --vmid=100:100,101:101), or all for all
--prefixid Prefix for VMID's on target System [optional] --prefixid Prefix for VMID's on target System [optional]
--excludevmids Exclusde VM IDs when using --vmid==all --excludevmids Exclusde VM IDs when using --vmid==all
@@ -154,7 +158,7 @@ function parse_opts(){
local args local args
args=$(getopt \ args=$(getopt \
--options '' \ --options '' \
--longoptions=vmid:,prefixid:,excludevmids:,destination:,pool:,keeplocal:,keepremote:,rewrite:,influxurl:,influxorg:,influxtoken:,influxbucket:,jobname:,mail:,online,migrate,nolock,keep-slock,keep-dlock,overwrite,dry-run,noconfirm,debug,syslog \ --longoptions=sshcipher:,tag:,vmid:,prefixid:,excludevmids:,destination:,pool:,keeplocal:,keepremote:,rewrite:,influxurl:,influxorg:,influxtoken:,influxbucket:,jobname:,mail:,online,migrate,nolock,keep-slock,keep-dlock,overwrite,dry-run,noconfirm,debug,syslog \
--name "$PROGNAME" \ --name "$PROGNAME" \
-- "$@") \ -- "$@") \
|| end_process 128 || end_process 128
@@ -163,6 +167,8 @@ function parse_opts(){
while true; do while true; do
case "$1" in case "$1" in
--sshcipher) opt_sshcipher=$2; shift 2;;
--tag) opt_tag=$2; shift 2;;
--vmid) opt_vm_ids=$2; shift 2;; --vmid) opt_vm_ids=$2; shift 2;;
--prefixid) opt_prefix_id=$2; shift 2;; --prefixid) opt_prefix_id=$2; shift 2;;
--excludevmids) opt_exclude_vmids=$2; shift 2;; --excludevmids) opt_exclude_vmids=$2; shift 2;;
@@ -204,7 +210,6 @@ function parse_opts(){
log info "============================================" log info "============================================"
fi fi
[ -z "$opt_vm_ids" ] && { log info "VM id is not set."; end_process 1; }
[ -z "$opt_influx_jobname" ] && { log info "Jobname is not set."; end_process 1; } [ -z "$opt_influx_jobname" ] && { log info "Jobname is not set."; end_process 1; }
@@ -227,6 +232,15 @@ function parse_opts(){
end_process 255 end_process 255
fi fi
if [ -n "$opt_tag" ] && [ -n "$opt_vm_ids" ] && [ "$opt_vm_ids" != "all" ]; then
log error "You can't use --tag and --vmid at the same time"
end_process 255
fi
[ -n "$opt_tag" ] && [ -z $opt_vm_ids ] && opt_vm_ids="all"
[ -z "$opt_vm_ids" ] && { log info "VM id is not set."; end_process 1; }
if [ "$opt_vm_ids" = "all" ]; then if [ "$opt_vm_ids" = "all" ]; then
local all='' local all=''
local data='' local data=''
@@ -234,6 +248,7 @@ function parse_opts(){
local ids='' local ids=''
all=$(get_vm_ids "$QEMU_CONF_CLUSTER/*$EXT_CONF" "$LXC_CONF_CLUSTER/*$EXT_CONF") all=$(get_vm_ids "$QEMU_CONF_CLUSTER/*$EXT_CONF" "$LXC_CONF_CLUSTER/*$EXT_CONF")
log debug "all: $all"
all=$(echo "$all" | tr ',' "\n") all=$(echo "$all" | tr ',' "\n")
opt_exclude_vmids=$(echo "$opt_exclude_vmids" | tr ',' "\n") opt_exclude_vmids=$(echo "$opt_exclude_vmids" | tr ',' "\n")
for id in $all; do for id in $all; do
@@ -254,7 +269,7 @@ function parse_opts(){
vm_ids=$(echo "$opt_vm_ids" | tr ',' "\n") vm_ids=$(echo "$opt_vm_ids" | tr ',' "\n")
fi fi
fi fi
log debug "vm_ids: $vm_ids"
} }
human_readable() { human_readable() {
@@ -316,7 +331,9 @@ function get_vm_ids(){
while [ $# -gt 0 ]; do while [ $# -gt 0 ]; do
for conf in $1; do for conf in $1; do
[ ! -e "$conf" ] && break [ ! -e "$conf" ] && break
if [ -n "$opt_tag" ] && ! grep -qE "^tags:\s.*$opt_tag(;|$)" $conf; then
continue
fi
conf=$(basename "$conf") conf=$(basename "$conf")
[ "$data" != '' ] && data="$data," [ "$data" != '' ] && data="$data,"
data="$data${conf%.*}" data="$data${conf%.*}"
@@ -338,7 +355,7 @@ function get_disks_from_config(){
[[ "$line" == "" ]] && break [[ "$line" == "" ]] && break
echo "$line" echo "$line"
done < "$file_config" | \ done < "$file_config" | \
grep -P '^(?:((?:efidisk|virtio|ide|scsi|sata|mp)\d+)|rootfs): ' | \ grep -P '^(?:((?:efidisk|virtio|ide|scsi|sata|mp|tpmstate)\d+)|rootfs): ' | \
grep -v -P 'cdrom|none' | \ grep -v -P 'cdrom|none' | \
grep -v -P 'backup=0' | \ grep -v -P 'backup=0' | \
awk '{ split($0,a,","); split(a[1],b," "); print b[2]}') awk '{ split($0,a,","); split(a[1],b," "); print b[2]}')
@@ -616,7 +633,7 @@ function mirror() {
#snapts=$(echo $currentlocal | sed -r -e 's/.*@mirror-(.*)/\1/') #snapts=$(echo $currentlocal | sed -r -e 's/.*@mirror-(.*)/\1/')
snapshotsize=$(rbd du --pretty-format --format json $src_image_pool/$src_image_name|jq '.images[] | select (.snapshot_id == null) | {provisioned_size}.provisioned_size'|tail -1) snapshotsize=$(rbd du --pretty-format --format json $src_image_pool/$src_image_name|jq '.images[] | select (.snapshot_id == null) | {provisioned_size}.provisioned_size'|tail -1)
log debug "snapsize: $snapshotsize " log debug "snapsize: $snapshotsize "
xmitjob="rbd export --rbd-concurrent-management-ops 8 $src_image_pool/$src_image_name$snapshot_name --no-progress - | tee >({ wc -c; } >/tmp/$PROGNAME.$pid.$dst_image_pool-$dst_image_name.size) | pv -s $snapshotsize -F \"VM $vm_id - F $src_image_pool/$src_image_name$snapshot_name: $PVFORMAT_FULL\" | ssh $opt_destination rbd import --image-format 2 - $dst_image_pool/$dst_image_name $dst_data_opt 2>/dev/null" xmitjob="rbd export --rbd-concurrent-management-ops 8 $src_image_pool/$src_image_name$snapshot_name --no-progress - | tee >({ wc -c; } >/tmp/$PROGNAME.$pid.$dst_image_pool-$dst_image_name.size) | pv -s $snapshotsize -F \"VM $vm_id - F $src_image_pool/$src_image_name$snapshot_name: $PVFORMAT_FULL\" | ssh -c $opt_sshcipher $opt_destination rbd import --image-format 2 - $dst_image_pool/$dst_image_name $dst_data_opt 2>/dev/null"
# create initial snapshot on destination # create initial snapshot on destination
log debug "xmitjob: $xmitjob" log debug "xmitjob: $xmitjob"
startdisk=$(date +%s) startdisk=$(date +%s)
@@ -644,7 +661,7 @@ function mirror() {
#disk was not attached, or really nothing has changed.. #disk was not attached, or really nothing has changed..
snapshotsize=0 snapshotsize=0
fi fi
xmitjob="rbd export-diff --no-progress --from-snap $opt_snapshot_prefix$basets $src_image_pool/$currentlocal - | tee >({ wc -c; } >/tmp/$PROGNAME.$pid.$dst_image_pool-$dst_image_name.size) | pv -F \"VM $vm_id - I $src_image_pool/$src_image_name$snapshot_name: $PVFORMAT_SNAP\" | ssh $opt_destination rbd import-diff --no-progress - $dst_image_pool/$dst_image_name $dst_data_opt" xmitjob="rbd export-diff --no-progress --from-snap $opt_snapshot_prefix$basets $src_image_pool/$currentlocal - | tee >({ wc -c; } >/tmp/$PROGNAME.$pid.$dst_image_pool-$dst_image_name.size) | pv -F \"VM $vm_id - I $src_image_pool/$src_image_name$snapshot_name: $PVFORMAT_SNAP\" | ssh -c $opt_sshcipher $opt_destination rbd import-diff --no-progress - $dst_image_pool/$dst_image_name"
log debug "xmitjob: $xmitjob" log debug "xmitjob: $xmitjob"
startdisk=$(date +%s) startdisk=$(date +%s)
do_run "$xmitjob" do_run "$xmitjob"
@@ -815,7 +832,7 @@ function rewriteconfig(){
else else
sedcmd='sed -e /^$/,$d' sedcmd='sed -e /^$/,$d'
fi fi
cat "$oldconfig" | sed -r -e "s/^(efidisk|virtio|ide|scsi|sata|mp)([0-9]+):\s([a-zA-Z0-9]+):(.*)-([0-9]+)-disk-([0-9]+).*,(.*)$/\1\2: $newpool:\4-$newvmid-disk-\6-\3,\7/g" | $sedcmd | sed -e '/^$/,$d' | sed -e '/ide[0-9]:.*-cloudinit,media=cdrom.*/d' | grep -v "^parent:\s.*$" | ssh "$dst" "cat - >$newconfig" cat "$oldconfig" | sed -r -e "s/^(efidisk|virtio|ide|scsi|sata|mp|tpmstate)([0-9]+):\s([a-zA-Z0-9]+):(.*)-([0-9]+)-disk-([0-9]+).*,(.*)$/\1\2: $newpool:\4-$newvmid-disk-\6-\3,\7/g" | $sedcmd | sed -e '/^$/,$d' | sed -e '/ide[0-9]:.*-cloudinit,media=cdrom.*/d' | grep -v "^parent:\s.*$" | ssh "$dst" "cat - >$newconfig"
} }
function checkvmid(){ function checkvmid(){