mirror of
https://github.com/apache/cloudstack.git
synced 2025-12-19 20:14:06 +01:00
168 lines
3.9 KiB
Bash
Executable File
168 lines
3.9 KiB
Bash
Executable File
#!/usr/bin/bash
|
|
## Licensed to the Apache Software Foundation (ASF) under one
|
|
## or more contributor license agreements. See the NOTICE file
|
|
## distributed with this work for additional information
|
|
## regarding copyright ownership. The ASF licenses this file
|
|
## to you under the Apache License, Version 2.0 (the
|
|
## "License"); you may not use this file except in compliance
|
|
## with the License. You may obtain a copy of the License at
|
|
##
|
|
## http://www.apache.org/licenses/LICENSE-2.0
|
|
##
|
|
## Unless required by applicable law or agreed to in writing,
|
|
## software distributed under the License is distributed on an
|
|
## "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
## KIND, either express or implied. See the License for the
|
|
## specific language governing permissions and limitations
|
|
## under the License.
|
|
|
|
set -e
|
|
|
|
# CloudStack B&R NAS Backup and Recovery Tool for KVM
|
|
|
|
# TODO: do libvirt/logging etc checks
|
|
|
|
### Declare variables ###
|
|
|
|
OP=""
|
|
VM=""
|
|
NAS_TYPE=""
|
|
NAS_ADDRESS=""
|
|
MOUNT_OPTS=""
|
|
BACKUP_DIR=""
|
|
DISK_PATHS=""
|
|
|
|
### Operation methods ###
|
|
|
|
backup_running_vm() {
|
|
mount_operation
|
|
mkdir -p $dest
|
|
|
|
deviceId=0
|
|
name="root"
|
|
echo "<domainbackup mode='push'><disks>" > $dest/backup.xml
|
|
for disk in $(virsh -c qemu:///system domblklist $VM --details 2>/dev/null | awk '/disk/{print$3}'); do
|
|
volpath=$(virsh -c qemu:///system domblklist $VM --details | awk "/$disk/{print $4}" | sed 's/.*\///')
|
|
echo "<disk name='$disk' backup='yes' type='file' backupmode='full'><driver type='qcow2'/><target file='$dest/$deviceId.$name.$volpath.qcow2' /></disk>" >> $dest/backup.xml
|
|
deviceId=$((devideId+1))
|
|
name="datadisk"
|
|
done
|
|
echo "</disks></domainbackup>" >> $dest/backup.xml
|
|
|
|
# Start push backup
|
|
virsh -c qemu:///system backup-begin --domain $VM --backupxml $dest/backup.xml > /dev/null 2>/dev/null
|
|
|
|
# Backup domain information
|
|
virsh -c qemu:///system dumpxml $VM > $dest/domain-config.xml 2>/dev/null
|
|
virsh -c qemu:///system dominfo $VM > $dest/dominfo.xml 2>/dev/null
|
|
virsh -c qemu:///system domiflist $VM > $dest/domiflist.xml 2>/dev/null
|
|
virsh -c qemu:///system domblklist $VM > $dest/domblklist.xml 2>/dev/null
|
|
|
|
until virsh -c qemu:///system domjobinfo $VM --completed --keep-completed 2>/dev/null | grep "Completed" > /dev/null; do
|
|
sleep 5
|
|
done
|
|
rm -f $dest/backup.xml
|
|
sync
|
|
|
|
# Print statistics
|
|
virsh -c qemu:///system domjobinfo $VM --completed
|
|
du -sb $dest | cut -f1
|
|
|
|
umount $mount_point
|
|
rmdir $mount_point
|
|
}
|
|
|
|
backup_stopped_vm() {
|
|
mount_operation
|
|
mkdir -p $dest
|
|
|
|
IFS=","
|
|
|
|
for disk in $DISK_PATHS; do
|
|
rsync -az $disk $dest
|
|
done
|
|
}
|
|
|
|
delete_backup() {
|
|
mount_operation
|
|
|
|
rm -frv $dest
|
|
sync
|
|
|
|
umount $mount_point
|
|
rmdir $mount_point
|
|
}
|
|
|
|
mount_operation() {
|
|
mount_point=$(mktemp -d -t csbackup.XXXXX)
|
|
dest="$mount_point/${BACKUP_DIR}"
|
|
|
|
mount -t ${NAS_TYPE} ${NAS_ADDRESS} ${mount_point} $([[ ! -z "${MOUNT_OPTS}" ]] && echo -o ${MOUNT_OPTS})
|
|
}
|
|
|
|
function usage {
|
|
echo ""
|
|
echo "Usage: $0 -b <domain> -s <NAS storage mount path> -p <backup dest path>"
|
|
echo ""
|
|
exit 1
|
|
}
|
|
|
|
while [[ $# -gt 0 ]]; do
|
|
case $1 in
|
|
-o|--operation)
|
|
OP="$2"
|
|
shift
|
|
shift
|
|
;;
|
|
-v|--vm)
|
|
VM="$2"
|
|
shift
|
|
shift
|
|
;;
|
|
-t|--type)
|
|
NAS_TYPE="$2"
|
|
shift
|
|
shift
|
|
;;
|
|
-s|--storage)
|
|
NAS_ADDRESS="$2"
|
|
shift
|
|
shift
|
|
;;
|
|
-m|--mount)
|
|
MOUNT_OPTS="$2"
|
|
shift
|
|
shift
|
|
;;
|
|
-p|--path)
|
|
BACKUP_DIR="$2"
|
|
shift
|
|
shift
|
|
;;
|
|
-d|--diskpaths)
|
|
DISK_PATHS="$2"
|
|
shift
|
|
shift
|
|
;;
|
|
-h|--help)
|
|
usage
|
|
shift
|
|
;;
|
|
*)
|
|
echo "Invalid option: $1"
|
|
usage
|
|
;;
|
|
esac
|
|
done
|
|
|
|
if [ "$OP" = "backup" ]; then
|
|
STATE=$(virsh -c qemu:///system list | grep $VM | awk '{print $3}')
|
|
if [ "$STATE" = "running" ]; then
|
|
backup_running_vm
|
|
else
|
|
backup_stopped_vm
|
|
fi
|
|
elif [ "$OP" = "delete" ]; then
|
|
delete_backup
|
|
fi
|