| #!/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. |
| |
| version=0.9.1 |
| OPTIND=1 |
| OPTIND=1 |
| verb=0 |
| logDir="/nsr/logs/cloudstack/" |
| clusterClient="" |
| networkerServer="" |
| hvVersion="" |
| libvVersion="" |
| apiVersion="" |
| logFile="" |
| destination="" |
| volume="" |
| ssid="" |
| newvolumeUuid="" |
| POOLPATH="" |
| |
| log () { |
| [[ "$verb" -eq 1 ]] && builtin echo "$@" |
| if [[ "$1" == "-ne" || "$1" == "-e" || "$1" == "-n" ]]; then |
| builtin echo -e "$(date '+%Y-%m-%d %H-%M-%S>')" "${@: 2}" >> "$logFile" |
| else |
| builtin echo "$(date '+%Y-%m-%d %H-%M-%S>')" "$@" >> "$logFile" |
| fi |
| } |
| |
| vercomp() { |
| local a b IFS=. -; set -f |
| printf -v a %08d $1; printf -v b %08d $3 |
| test $a "$2" $b |
| } |
| |
| usage() { |
| echo " |
| |
| Usage:[-v] [-h] [-l log_dir] [-s networker_server] [-c networker_cluster_client] [-S ssid] [-d networker_destination_client ] [ -a volume ] [ -p pool_local_path ] |
| |
| Options: |
| -h Help and usage |
| -v Enable log mode |
| -l log_dir. Specify log directory. Default is /nsr/logs/cloudstack |
| -s networker_server Specify the EMC Networker server we are going to use |
| -c networker_cluster_client Specify the EMC Networker client CLUSTER to use |
| -d networker_destination_client Specify the EMC Networker client that is going to be used for the restore |
| -a volume Specify volume to restore |
| -p pool_local_path Local Path to Pool |
| -S ssid Specify SSID |
| Supplements Apache Cloudstack B&R Framework EMC Networker plugin and performs the backup of the Virtual Machines |
| " |
| |
| } |
| |
| sanity_checks() { |
| log "Performing environment sanity checks..." |
| |
| log -ne "\t[1] Checking if Networker is installed\t" |
| if [[ $(systemctl list-unit-files | grep networker) = *networker* ]]; then |
| log "Success" |
| else |
| log "Failure" |
| log -e "\n\tNetworker Service NOT FOUND. Make sure that Networker client is properly installed" |
| exit 1 |
| fi |
| |
| log -ne "\t[2] Checking if Networker is running\t" |
| if [[ $(systemctl is-active networker) = *active* ]]; then |
| log "Success" |
| else |
| log "Failure" |
| log -e "\n\tNetworker Service is not running. Investigate Networker logs, startup server and try again" |
| exit 2 |
| fi |
| log -ne "\t[3] Checking Networker DNS Resolution\t" |
| if [[ $(getent hosts "$networkerServer") = *$networkerServer* ]]; then |
| log "Success" |
| else |
| log "Failure" |
| log -e "\n\tNetworker Server cannot be resolved. Backups will most probably fail. Consider adding the ip/hostname to /etc/host or fix DNS resolution" |
| exit 3 |
| fi |
| |
| log -ne "\t[4] Checking QEMU / Libvirt Versions \t" |
| hvVersion=$(virsh version | grep hypervisor | awk '{print $(NF)}') |
| libvVersion=$(virsh version | grep libvirt | awk '{print $(NF)}' | tail -n 1) |
| apiVersion=$(virsh version | grep API | awk '{print $(NF)}') |
| if vercomp "$hvVersion" \> 2.1.2; then |
| log -n "Success" |
| log -ne "\t\t [ Libvirt: $libvVersion apiVersion: $apiVersion ]" |
| echo |
| else |
| log "Failure" |
| log -e "\n\tYour QEMU version $hvVersion is unsupported. Consider upgrading at least to latest QEMU at branch 2" |
| exit 4 |
| fi |
| log "Environment Sanity Checks successfully passed" |
| } |
| echo " |
| Cloudstack B&R Framework - EMC Networker backup script |
| Version $version |
| " |
| restore_all_volumes() { |
| log "Preparing restore for SAVESET $ssid" |
| cmd="$(sudo recover -s "$networkerServer" -S "$ssid" -iY)" |
| retVal=$? |
| log "$cmd" |
| if [ "$retVal" -ne 0 ]; then |
| log "Unable to restore SAVESET $ssid" |
| exit 4 |
| else |
| log "Restore of SAVESET $ssid has been completed" |
| fi |
| } |
| |
| restore_volume() { |
| log "Preparning restore for volume $volume at destination as $POOLPATH/$newvolumeUuid" |
| cmd="$(recover -R "$destination" -c "$clusterClient" -s "$networkerServer" -a "$POOLPATH/$volume" -iR)" |
| retVal=$? |
| log "$cmd" |
| if [ "$retVal" -ne 0 ]; then |
| log "Unable to restore SAVESET $ssid" |
| exit 5 |
| else |
| log "Restore of SAVESET $ssid has been completed" |
| fi |
| |
| if [ -f "$POOLPATH/$volume.R" ]; then |
| mv "$POOLPATH/$volume.R" "$POOLPATH/$newvolumeUuid" |
| else |
| mv "$POOLPATH/$volume" "$POOLPATH/$newvolumeUuid" |
| fi |
| |
| if [ -f "$POOLPATH/$newvolumeUuid" ]; then |
| log "Volume restored under path/name: $POOLPATH/$newvolumeUuid" |
| |
| else |
| log "Unable to verify final restored volume: $POOLPATH/$newvolumeUuid" |
| exit 6 |
| fi |
| |
| } |
| |
| while getopts "h?vs:l:c:d:a:S:n:p:" opt; do |
| case "$opt" in |
| h|\?) |
| usage |
| exit 254 |
| ;; |
| c) clusterClient="$OPTARG" |
| ;; |
| s) networkerServer="$OPTARG" |
| ;; |
| l) logDir="$OPTARG" |
| ;; |
| d) destination="$OPTARG" |
| ;; |
| a) volume="$OPTARG" |
| ;; |
| S) ssid="$OPTARG" |
| ;; |
| n) newvolumeUuid="$OPTARG" |
| ;; |
| p) POOLPATH="$OPTARG" |
| ;; |
| v) verb=1 |
| ;; |
| esac |
| done |
| shift $((OPTIND-1)) |
| |
| [ "${1:-}" = "--" ] && shift |
| |
| if [[ -n "$newvolumeUuid" ]]; then |
| if [[ -z "$networkerServer" || -z "$destination" || -z "$clusterClient" || -z "$newvolumeUuid" || -z "$POOLPATH" ]]; then |
| usage |
| exit 255 |
| fi |
| elif [[ -n "$ssid" ]]; then |
| if [[ -z "$networkerServer" ]]; then |
| usage |
| exit 255 |
| fi |
| elif [[ -n "$ssid" && -n "$volumeUuid" ]]; then |
| echo "You can either restore a whole saveset or part of it but not both." |
| exit 250 |
| else |
| exit 255 |
| fi |
| |
| if [ ! -d "$logDir" ]; then |
| mkdir -p "$logDir" |
| fi |
| |
| |
| if [[ -z "$ssid" && -n "$newvolumeUuid" ]]; then |
| logFile="$logDir/RESTORE-$newvolumeUuid-$(date +'%Y_%m_%d_%I_%M_%p').log" |
| # Perform Initial sanity checks |
| sanity_checks |
| restore_volume |
| elif [[ -n "$ssid" && -z "$newvolumeUuid" ]]; then |
| logFile="$logDir/RESTORE-$ssid-$(date +'%Y_%m_%d_%I_%M_%p').log" |
| # Perform Initial sanity checks |
| sanity_checks |
| restore_all_volumes |
| fi |
| exit 0 |