当前位置: > 虚拟化 Virtualization > oVirt >

oVirt 虚拟机备份脚本程序VirtBKP的backup_vm_v1.6.py修改版

时间:2019-11-29 19:11来源:linux.it.net.cn 作者:IT
#!/bin/python

import printf
import ovirtsdk4 as sdk
import ovirtsdk4.types as types
import time
import sys
import subprocess
import requests
import requests
import ConfigParser
from requests.packages.urllib3.exceptions import InsecureRequestWarning
requests.packages.urllib3.disable_warnings()
import xml.etree.ElementTree as ET
import thread
import virtbkp_utils

class backup_vm():
#def __init__():
def __init__(self,conf_file,vmname):
  cfg = ConfigParser.ConfigParser()
  cfg.readfp(open(conf_file))
  self.vmname=vmname
  self.vmid=''
  self.url=cfg.get('bkp', 'url')
  self.user=cfg.get('bkp', 'user')
  self.password=cfg.get('bkp', 'password')
  self.ca_file=cfg.get('bkp', 'ca_file')
  self.bckdir=cfg.get('bkp', 'bckdir')
  self.bkpvm=cfg.get('bkp', 'bkpvm')
  self.date=str((time.strftime("%Y%m%d%H%M%S")))
  self.vmid=''
  self.snapname = "BACKUP" + "_" + self.date +"h"
  self.connection = None

# Get  default values
def start(self):
  try:
    # Create a connection to the server:
    self.connection = sdk.Connection(
   url=self.url,
     username=self.user,
   password=self.password,
  ca_file=self.ca_file)
    printf.OK("Connection to oVIrt API success %s" % self.url)
  except Exception as ex:
    print ex
    printf.ERROR("Connection to oVirt API has failed")
 
# Funcion para obtener el id de la vm buscandola por el nombre
# Function to get VM_ID from VM name
def get_id_vm(self,vmname):
  vm_service = self.connection.service("vms")
  vms = vm_service.list()
  for vm in vms:
   if vm.name == vmname:
     return vm.id

# This example fetches the specified VM configuration data and
# saves it into an OVF file.
def download_vm_ovf(self,vmname):
  # Get the reference to the "vms" service:
  vm_service = self.connection.service("vms")
  # Locate VM service
  vm = vm_service.list(search="name=%s" % vmname, all_content=True)[0]
  bckfiledir = self.bckdir + "/" + self.vmname + "/" + self.date
  mkdir = "mkdir -p " + bckfiledir
  subprocess.call(mkdir, shell=True)
  ovf_filename = bckfiledir + "/" + self.vmname + ".ovf"
  with open(ovf_filename, "wb") as ovf_file:
   ovf_file.write(vm.initialization.configuration.data)
  printf.OK("VM configuration downloaded")


# Funcion para obtener el ID del snapshot creado
# Function to get ID of created snapshot
def get_snap_id(self,vmid):
  headers = {'Content-Type': 'application/xml', 'Accept': 'application/xml'}
  vmsnap_service = self.connection.service("vms/"+vmid+"/snapshots")
  snaps = vmsnap_service.list()
  for snap in snaps:
   if snap.description == self.snapname:
    return snap.id

# Funcion para obtener el estado del snapshot
# Function to get snapshot status
def get_snap_status(self,vmid,snapid):
  vmsnap_service = self.connection.service("vms/"+vmid+"/snapshots")
  snaps = vmsnap_service.list()
  for snap in snaps:
   if snap.id == snapid:
    return snap.snapshot_status

# Funcion para crear el snapshot
# Function to create snapshot
def create_snap(self,vmid,snapname):
  vm_service = self.connection.service("vms")
  snapshots_service = vm_service.vm_service(vmid).snapshots_service()
  snapshots_service.add(types.Snapshot(description=snapname, persist_memorystate=False))
  snapid = self.get_snap_id(vmid)
  status = self.get_snap_status(vmid,snapid)
  printf.INFO("Trying to create snapshot of VM: " + vmid)
  while str(status) == "locked":
    time.sleep(10)
    printf.INFO("Waiting until snapshot creation ends")
    status = self.get_snap_status(vmid,snapid)
  printf.OK("Snapshot created")

# Funcion para eliminar el snapshot
# Function to delte snapshot
def delete_snap(self,vmid,snapid):
  snap_service = self.connection.service("vms/"+vmid+"/snapshots/"+snapid)
  snap_service.remove()
  status = self.get_snap_status(vmid,snapid)
  while str(status) != "None":
    time.sleep(30)
    printf.INFO("Waiting until snapshot deletion ends")
    status = self.get_snap_status(vmid,snapid)
  printf.OK("Snapshot deleted")

# Funcion para obtener el ID del disco de snapshot
# Function to get snapshost disk ID
def snap_disk_id(self,vmid,snapid):
  svc_path = "vms/"+vmid+"/snapshots/"+snapid+"/disks/"
  disksnap_service = self.connection.service(svc_path)
  disks = disksnap_service.list()
  vm_disks = ()
  for disk in disks:
    vm_disks = vm_disks + (disk.id,)
  return vm_disks

# Funcion para atachar disco a VM
# Function to attach disk to VM
def attach_disk(self,bkpid,diskid,snapid):
  xmlattach =  "<disk id=\""+diskid+"\"><snapshot id=\""+snapid+"\"/> <active>true</active></disk>"
  urlattach = self.url+"/v3/vms/"+bkpid+"/disks/"
  headers = {'Content-Type': 'application/xml', 'Accept': 'application/xml'}
  requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
  resp_attach = requests.post(urlattach, data=xmlattach, headers=headers, verify=False, auth=(self.user,self.password))

# Funcion para desactivar disco virtual
# Function to deactivate virtual disk
def deactivate_disk(self,bkpid,diskid):
  xmldeactivate =  "<action/>"
  urldeactivate = self.url+"/v3/vms/"+bkpid+"/disks/"+diskid+"/deactivate"
  headers = {'Content-Type': 'application/xml', 'Accept': 'application/xml'}
  resp_attach = requests.post(urldeactivate, data=xmldeactivate, headers=headers, verify=False, auth=(self.user,self.password))

# Funcion para desataschar disco de VM
# Function to dettach disk
def detach_disk(self,bkpid,diskid):
  urldelete = self.url+"/vms/"+bkpid+"/diskattachments/"+diskid
  requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
  requests.delete(urldelete, verify=False, auth=(self.user,self.password))

# Funcion para obtener el nombre de dispositivo de disco virtual
# Function to get device name of a virtual disk
def get_logical_disk(self,bkpid,diskid):
  dev="None"
  b=True
  urlget = "vms/"+bkpid+"/diskattachments/"
  serial=diskid[0:20]
  cmd="grep -Rlw '"+serial+"' /sys/block/*/serial|awk -F '/' '{print $4}'" 
  while b:
   # Trying to  identify VIRTIO devices
   try:
    path = subprocess.check_output(cmd, shell=True).replace("\n","")
    if path.startswith("vd") or path.startswith("sd") :
      dev = "/dev/" + path
      time.sleep(1)
   except:
    continue
   if str(dev) != "None":
    printf.INFO("Disk found using serial number")
    b=False
   else:
  # Trying to identify devices through API
    disk_service = self.connection.service(urlget)
    for disk in disk_service.list():
     dev = str(disk.logical_name)
     if disk.id == diskid and str(dev) != "None":
       printf.INFO("Disk found using API")
       b=False
     else:
       dev="None"
       time.sleep(1)
  return dev

def run_qemu_convert(self,cmd):
  out = subprocess.call(cmd, shell=True)
  if int(out) == 0:
   #print "Se creo correctamente la imagen"
   print
   printf.OK("qcow2 file creation success")
  else:
   print
   printf.ERROR("qcow2 file creation failed")

# Funcion para crear imagen qcow2 del disco
# Function  to create qcow file of disk
def create_image_bkp(self,dev,diskname):
   bckfiledir = self.bckdir + "/" + self.vmname + "/" + self.date
   mkdir = "mkdir -p " + bckfiledir
   subprocess.call(mkdir, shell=True)
   bckfile = bckfiledir + "/" + diskname
   printf.INFO("Creating qcow2 file: " + bckfile)
   cmd = "qemu-img convert -U -O qcow2 " + dev + " " +bckfile
   utils=virtbkp_utils.virtbkp_utils()
   thread.start_new_thread(self.run_qemu_convert,(cmd,))
   utils.progress_bar_qcow(bckfile)

# Funcion para obtener el nombre del disco virtual
# Function to get virtual disk name
def get_disk_name(self,vmid,snapid,diskid):
   svc_path = "vms/"+vmid+"/snapshots/"+snapid+"/disks/"
   disksnap_service = self.connection.service(svc_path)
   disks = disksnap_service.list()
   for disk in disks:
     if diskid == str(disk.id):
       return disk.alias

def backup(self,vmid,snapid,disk_id,bkpvm):
   # Se agrega el disco a la VM que tomara el backup
   printf.INFO("Attach snap disk to bkpvm")
   self.attach_disk(bkpvm,disk_id,snapid)
   # Se obtiene el nombre del dispositivo
   printf.INFO("Identifying disk device, this might take a while")
   dev = self.get_logical_disk(bkpvm,disk_id)
   # Se obtiene el nombre del disco
   diskname = self.get_disk_name(vmid,snapid,disk_id)
   # Se crea la image qcow que seria el  backup como tal
   self.create_image_bkp(dev,diskname)
   # Se desactiva el disco del cual se hizo el backup
   self.deactivate_disk(bkpvm,disk_id)
   time.sleep(10)
   # Se detacha el disco de la BKPVM
   printf.INFO("Dettach snap disk of bkpvm")
   self.detach_disk(bkpvm,disk_id)
   time.sleep(10)

def main(self):
  self.start()
  ## Parte Principal
  # Se consigue el ID de la VM a la cual se hara backup y la VM donde se montaran sus discos
  self.vmid = self.get_id_vm(self.vmname)
  self.bkpvm = self.get_id_vm(self.bkpvm)
  self.download_vm_ovf(self.vmname)
  # Se crea el snap y se espera un rato para que termine sin problemas y pueda detectar el nombre del disco en VM de backup
  self.create_snap(self.vmid,self.snapname)
  #time.sleep(60)
  # Se obtiene el id del snap
  self.snapid = self.get_snap_id(self.vmid)
  # Se obtiene el ID del disco
  vm_disks = self.snap_disk_id(self.vmid,self.snapid)
  for disk_id in vm_disks:
    printf.INFO("Trying to create a qcow2 file of disk " + disk_id)
    # Backup
    self.backup(self.vmid,self.snapid,disk_id,self.bkpvm)
  printf.INFO("Trying to delete snapshot of " + self.vmname)
  self.delete_snap(self.vmid,self.snapid)
  
#b = backup_vm(sys.argv[1],sys.argv[2])
#b.main()

————————————————
版权声明:本文为CSDN博主「allway2」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/allway2/article/details/102993046 (责任编辑:IT)
------分隔线----------------------------