def snapshot_cold_merge(api): if api.vms.get(VM1_NAME) is None: raise SkipTest('Glance is not available') dead_snap1_params = params.Snapshot( description='dead_snap1', persist_memorystate=False, disks=params.Disks(disk=[ params.Disk(id=api.vms.get(VM1_NAME).disks.get(DISK1_NAME).id, ), ], ), ) api.vms.get(VM1_NAME).snapshots.add(dead_snap1_params) testlib.assert_true_within_long(lambda: api.vms.get(VM1_NAME).snapshots. list()[-1].snapshot_status == 'ok') dead_snap2_params = params.Snapshot( description='dead_snap2', persist_memorystate=False, disks=params.Disks(disk=[ params.Disk(id=api.vms.get(VM1_NAME).disks.get(DISK1_NAME).id, ), ], ), ) api.vms.get(VM1_NAME).snapshots.add(dead_snap2_params) testlib.assert_true_within_long(lambda: api.vms.get(VM1_NAME).snapshots. list()[-1].snapshot_status == 'ok') api.vms.get(VM1_NAME).snapshots.list()[-2].delete() testlib.assert_true_within_long( lambda: (len(api.vms.get(VM1_NAME).snapshots.list()) == 2) and (api.vms.get(VM1_NAME).snapshots.list()[-1].snapshot_status == 'ok'), )
def snapshot_merge(api): dead_snap1_params = params.Snapshot( description='dead_snap1', persist_memorystate=False, disks=params.Disks(disk=[ params.Disk(id=api.vms.get(VM0_NAME).disks.get(DISK0_NAME).id, ), ], ), ) api.vms.get(VM0_NAME).snapshots.add(dead_snap1_params) testlib.assert_true_within_short(lambda: api.vms.get(VM0_NAME).snapshots. list()[-1].snapshot_status == 'ok') dead_snap2_params = params.Snapshot( description='dead_snap2', persist_memorystate=False, disks=params.Disks(disk=[ params.Disk(id=api.vms.get(VM0_NAME).disks.get(DISK0_NAME).id, ), ], ), ) api.vms.get(VM0_NAME).snapshots.add(dead_snap2_params) testlib.assert_true_within_short(lambda: api.vms.get(VM0_NAME).snapshots. list()[-1].snapshot_status == 'ok') api.vms.get(VM0_NAME).snapshots.list()[-2].delete() testlib.assert_true_within_short( lambda: (len(api.vms.get(VM0_NAME).snapshots.list()) == 2) and (api.vms.get(VM0_NAME).snapshots.list()[-1].snapshot_status == 'ok'), )
def snapshot_live_merge(api): disk = api.vms.get(VM1_NAME).disks.list()[0] disk_id = disk.id disk_name = disk.name live_snap1_params = params.Snapshot( description='live_snap1', persist_memorystate=True, disks=params.Disks(disk=[ params.Disk(id=disk_id, ), ], ), ) api.vms.get(VM1_NAME).snapshots.add(live_snap1_params) testlib.assert_true_within( func=(lambda: api.vms.get(VM1_NAME).snapshots.list()[-1]. snapshot_status == 'ok'), timeout=SHORT_TIMEOUT, ) live_snap2_params = params.Snapshot( description='live_snap2', persist_memorystate=True, disks=params.Disks(disk=[ params.Disk(id=disk_id, ), ], ), ) api.vms.get(VM1_NAME).snapshots.add(live_snap2_params) for i, _ in enumerate(api.vms.get(VM1_NAME).snapshots.list()): testlib.assert_true_within( func=(lambda: (api.vms.get(VM1_NAME).snapshots.list()[i]. snapshot_status == 'ok')), timeout=SHORT_TIMEOUT, ) api.vms.get(VM1_NAME).snapshots.list()[-2].delete() testlib.assert_true_within_long( lambda: len(api.vms.get(VM1_NAME).snapshots.list()) == 2, ) for i, _ in enumerate(api.vms.get(VM1_NAME).snapshots.list()): testlib.assert_true_within_long( lambda: (api.vms.get(VM1_NAME).snapshots.list()[i].snapshot_status == 'ok'), ) testlib.assert_true_within_short( lambda: api.vms.get(VM1_NAME).status.state == 'up', ) testlib.assert_true_within_long( lambda: api.vms.get(VM1_NAME).disks.get(disk_name).status.state == 'ok', )
def make_snapshot(self, name): show("Deleting all previous snapshots") show.tab() self.shutdown(name) for snap in self.get_vm(name).snapshots.list(): if snap.get_description() != 'Active VM': show("Deleting snapshot: %s" % snap.get_description()) snap.delete() while len(self.get_vm(name).snapshots.list()) > 1: show("Waiting for the deletion to complete.") sleep(15) show.untab() try: snapshot = params.Snapshot(description=locals.SNAPSHOT_NAME, vm=self.get_vm(name)) self.get_vm(name).snapshots.add(snapshot) show("Creating a Snapshot") show('Waiting for Snapshot creation to finish') while self.get_vm(name).status.state == 'image_locked': sleep(15) except Exception as e: show('Failed to Create a Snapshot:\n%s' % str(e)) if self.get_snapshot(name, locals.SNAPSHOT_NAME): show("Snapshot created: %s" % locals.SNAPSHOT_NAME) show.untab()
def snapshot_live_merge(api): raise SkipTest( "[02/04/17] Test is failing for weeks without real knowladge on the reason, despite debugging from storage team" ) disk = api.vms.get(VM0_NAME).disks.list()[0] disk_id = disk.id disk_name = disk.name live_snap1_params = params.Snapshot( description='live_snap1', persist_memorystate=True, disks=params.Disks(disk=[ params.Disk(id=disk_id, ), ], ), ) nt.assert_true(api.vms.get(VM0_NAME).snapshots.add(live_snap1_params)) testlib.assert_true_within_short(lambda: api.vms.get(VM0_NAME).snapshots. list()[-1].snapshot_status == 'ok') live_snap2_params = params.Snapshot( description='live_snap2', persist_memorystate=True, disks=params.Disks(disk=[ params.Disk(id=disk_id, ), ], ), ) nt.assert_true(api.vms.get(VM0_NAME).snapshots.add(live_snap2_params)) for i, _ in enumerate(api.vms.get(VM0_NAME).snapshots.list()): testlib.assert_true_within_short(lambda: (api.vms.get( VM0_NAME).snapshots.list()[i].snapshot_status == 'ok')) nt.assert_true(api.vms.get(VM0_NAME).snapshots.list()[-2].delete()) testlib.assert_true_within_long( lambda: len(api.vms.get(VM0_NAME).snapshots.list()) == 2, ) for i, _ in enumerate(api.vms.get(VM0_NAME).snapshots.list()): testlib.assert_true_within_long( lambda: (api.vms.get(VM0_NAME).snapshots.list()[i].snapshot_status == 'ok'), ) testlib.assert_true_within_short( lambda: api.vms.get(VM0_NAME).status.state == 'up') testlib.assert_true_within_long(lambda: api.vms.get(VM0_NAME).disks.get( disk_name).status.state == 'ok')
def clone_snapshot(api, config, vm_from_list): """ Clone snapshot into a new vm :param api: ovirtsdk api :param config: Configuration :vm: VM to clone """ vm_clone_name = vm_from_list + config.get_vm_middle() + config.get_vm_suffix() vm = api.vms.get(vm_from_list) snapshots = vm.snapshots.list(description=config.get_snapshot_description()) if not snapshots: logger.error("!!! No snapshot found !!!") has_errors = True snapshot=snapshots[0] # Find the storage domain where the disks should be created: sd = api.storagedomains.get(name=config.get_destination_domain()) # Find the image identifiers of the disks of the snapshot, as # we need them in order to explicitly indicate that we want # them created in a different storage domain: disk_ids = [] for current in snapshot.disks.list(): disk_ids.append(current.get_id()) # Prepare the list of disks for the operation to create the # snapshot,explicitly indicating for each of them the storage # domain where it should be created: disk_list = [] for disk_id in disk_ids: disk = params.Disk( image_id=disk_id, storage_domains=params.StorageDomains( storage_domain=[ params.StorageDomain( id=sd.get_id(), ), ], ), ) disk_list.append(disk) snapshot_param = params.Snapshot(id=snapshot.id) snapshots_param = params.Snapshots(snapshot=[snapshot_param]) logger.info("Clone into VM (%s) started ..." % vm_clone_name) if not config.get_dry_run(): api.vms.add(params.VM( name=vm_clone_name, memory=vm.get_memory(), cluster=api.clusters.get(config.get_cluster_name()), snapshots=snapshots_param, disks=params.Disks( disk=disk_list, ) ) ) VMTools.wait_for_vm_operation(api, config, "Cloning", vm_from_list) logger.info("Cloning finished")
def snapshot_live_merge(api): if api.vms.get(VM0_NAME).disks.get(GLANCE_DISK_NAME) is None: raise SkipTest('Glance is not available') disk_id = api.vms.get(VM0_NAME).disks.get(GLANCE_DISK_NAME).id live_snap1_params = params.Snapshot( description='live_snap1', persist_memorystate=True, disks=params.Disks(disk=[ params.Disk(id=disk_id, ), ], ), ) nt.assert_true(api.vms.get(VM0_NAME).snapshots.add(live_snap1_params)) testlib.assert_true_within_short(lambda: api.vms.get(VM0_NAME).snapshots. list()[-1].snapshot_status == 'ok') live_snap2_params = params.Snapshot( description='live_snap2', persist_memorystate=True, disks=params.Disks(disk=[ params.Disk(id=disk_id, ), ], ), ) nt.assert_true(api.vms.get(VM0_NAME).snapshots.add(live_snap2_params)) for i, _ in enumerate(api.vms.get(VM0_NAME).snapshots.list()): testlib.assert_true_within_short(lambda: (api.vms.get( VM0_NAME).snapshots.list()[i].snapshot_status == 'ok')) nt.assert_true(api.vms.get(VM0_NAME).snapshots.list()[-2].delete()) testlib.assert_true_within_long( lambda: len(api.vms.get(VM0_NAME).snapshots.list()) == 2, ) for i, _ in enumerate(api.vms.get(VM0_NAME).snapshots.list()): testlib.assert_true_within_long( lambda: (api.vms.get(VM0_NAME).snapshots.list()[i].snapshot_status == 'ok'), ) testlib.assert_true_within_short( lambda: api.vms.get(VM0_NAME).status.state == 'up') testlib.assert_true_within_long(lambda: api.vms.get(VM0_NAME).disks.get( GLANCE_DISK_NAME).status.state == 'ok')
def _ssh_create_snap(self, vmName, snapName): """ """ vmObj = self.ssh_get_vmObj(vmName) snapList = self.ssh_get_snapList(vmObj) if snapName in snapList: return ' [e] Error snapshotName alreay existed.' apiID = self.api.id vss = VMSnapshots(vmObj, apiID) if self.enMemery == '1': snapshotParams = params.Snapshot(description=snapName, persist_memorystate=True) else: snapshotParams = params.Snapshot(description=snapName, persist_memorystate=False) #[@param snapshot.persist_memorystate: boolean] vmState = vmObj.status.state # create snapshot. vss.add(snapshot=snapshotParams) if not vmState == 'up': print 'creating snaphot: %s' % snapName return 'Snapshot %s created.' % snapName retry = 6000 while (retry > 0): sleep(1) snapObj = self.ssh_get_snapObj(vmName, snapName) if not snapObj: continue if snapObj.get_snapshot_status() == 'ok': print 'finished...' break retry = retry - 1 if not vmObj.status.state == 'up': vmObj.start() print 'Snapshot %s created.' % snapName return snapObj.get_id()
def create_vm_to_export(self, vm, new_name, desc): try: self.snapshot = self.api.vms.get(vm).snapshots.list( description=desc)[0] self.snapshots = params.Snapshots( snapshot=[params.Snapshot(id=self.snapshot.id)]) self.cluster = self.api.clusters.get( id=self.api.vms.get(vm).cluster.id) self.api.vms.add( params.VM(name=new_name, snapshots=self.snapshots, cluster=self.cluster, template=self.api.templates.get(name="Blank"), delete_protected=False)) self.__wait(new_name, 0) except RequestError as err: print("Error: {} Reason: {}".format(err.status, err.reason)) raise Exception(14)
def snapshot(self, snapshot_name='my_snapshot'): """ Create a snapshot to VM. @snapshot_name: 'my_snapshot' is default snapshot name. """ snap_params = param.Snapshot(description=snapshot_name, vm=self.instance) try: logging.info('Creating a snapshot %s for VM %s' % (snapshot_name, self.name)) self.instance.snapshots.add(snap_params) logging.info('Waiting for snapshot creation to finish ...') while self.state() == 'image_locked': self.instance = self.api.vms.get(self.name) time.sleep(1) logging.info('Snapshot was created successfully') except Exception, e: logging.error('Failed to create a snapshot:\n%s' % str(e))
def create_snapshot(api, config, vm_from_list): """ Create snapshot of given vm :param api: ovirtsdk api :param config: Configuration :vm: VM to snapshot """ vm = api.vms.get(vm_from_list) logger.info("Snapshot creation started ...") if not config.get_dry_run(): vm.snapshots.add( params.Snapshot( description=config.get_snapshot_description(), vm=vm, persist_memorystate=config.get_persist_memorystate(), ) ) VMTools.wait_for_snapshot_operation(vm, config, "creation") logger.info("Snapshot created")
def create_snap(self, desc, vm): """Create a snapshot from a virtual machine with params: @param desc: Description of Snapshot @param vm: Virtual Machine Name """ try: snapshot = self.snapshot = self.api.vms.get(vm).snapshots.list() for snap in snapshot: if snap.description == desc: self.delete_snap(desc=desc, vm=vm) self.api.vms.get(vm).snapshots.add( params.Snapshot(description=desc, vm=self.api.vms.get(vm))) self.snapshot = self.api.vms.get(vm).snapshots.list( description=desc)[0] self.__wait_snap(vm, self.snapshot.id) except RequestError as err: print("CREATE SNAP Error: {} Reason: {}".format( err.status, err.reason)) raise Exception(12)
def snapshot(self, snapshot_name='my_snapshot', timeout=300): """ Create a snapshot to VM. :param snapshot_name: 'my_snapshot' is default snapshot name. :param timeout: Time out """ end_time = time.time() + timeout snap_params = param.Snapshot(description=snapshot_name, vm=self.instance) logging.info('Creating a snapshot %s for VM %s' % (snapshot_name, self.name)) self.instance.snapshots.add(snap_params) logging.info('Waiting for snapshot creation to finish') vm_snapsnop = False while time.time() < end_time: if self.state() != 'image_locked': vm_snapsnop = True break time.sleep(1) if not vm_snapsnop: raise WaitVMStateTimeoutError("SNAPSHOT", self.state()) logging.info('Snapshot was created successfully')
def ssh_create_snap(self, vmName, snapName): """ """ vmObj = self.ssh_get_vmObj(vmName) snapList = self.ssh_list_snap(vmName, snapName) if snapName in snapList: return ' [e] Error snapshotName alreay existed.' apiID = self.api.id vss = VMSnapshots(vmObj, apiID) snapshotParams = params.Snapshot(description=snapName) vmState = vmObj.status.state # create snapshot. vss.add(snapshot=snapshotParams) if not vmState == 'up': print 'creating snaphot: %s' % snapName return 'Snapshot %s created.' % snapName retry = 60 while (retry > 0): print 'creating snaphot: %s' % snapName print '...', sleep(5) snapObj = self.ssh_get_snapObj(vmName, snapName) if not snapObj: continue print snapObj.get_snapshot_status() if snapObj.get_snapshot_status() == 'ok': print 'finished...' break retry = retry - 1 if not vmObj.status.state == 'up': vmObj.start() return 'Snapshot %s created.' % snapName
def main(args): retcode = 0 if (args.config): # Read config file config = ConfigParser.ConfigParser() config.read(args.config) server = config.get('connection', 'server') username = config.get('connection', 'user_name') password = config.get('connection', 'password') if not server or not username or not password: logger.error("Server credentials not provided") sys.exit("Server credentials not provided") time_start = int(time.time()) # Connect to server try: connect(server, username, password) logger.debug("connected to server: " + server) except Exception as e: logger.error("Error:" + str(e)) sys.exit(1) wait_timeout = config.get('snapshot', 'wait_timeout') vms=api.vms.list(max=100) vms_to_commit = [] for vm_ in vms: try: # Get the VM vm = api.vms.get(vm_.name) if vm.status.state == 'up' and vm.name != 'HostedEngine': logger.info("Adding snapshot for: " + vm_.name ) snapshot = vm.snapshots.add(params.Snapshot(description=_SNAPSHOT_NAME)) logger.debug("snapshot: " + snapshot.get_id()) vms_to_commit.append({'vm': vm, 'snapshot': snapshot}) logger.debug("Added snapshot for vm: " + vm_.name) except Exception as e: logger.error("Error:" + str(e)) diskimgs_to_del = [] for vm_to_commit in vms_to_commit: try: # Get the VM vmcached = vm_to_commit['vm'] vm = api.vms.get(vmcached.name) snapshotid = vm_to_commit['snapshot'].get_id() logger.debug("Refreshed vm object for: " + vm.name + ":" + snapshotid) while True: snapshot = vm.snapshots.get(id=snapshotid) if snapshot is not None: if snapshot.get_snapshot_status() == 'ok': logger.info("Snapshot created for VM :" + vm.name) # get the overlay image id to delete at slave overlaydisks = vm.disks.list() for disk in overlaydisks: logger.debug("DISK:" + disk.get_id()) dskImage = disk.get_image_id() logger.debug("DISK IMAGE:" + dskImage) diskimgs_to_del.append(dskImage) break else: logger.debug ("Waiting for snapshot creation.. status: " + snapshot.get_snapshot_status()) time.sleep(10) else: logger.error ("Snapshot not retrieved for vm: " + vm.name) break except Exception as e: logger.error("Error:" + str(e)) # call geo-rep scheduler cmd = _georepScheduleCmd + [args.mastervol, args.slave, args.slavevol, "--interval", str(args.interval), "--timeout", str(args.timeout)] ret, out, err = execCmd(cmd) # Post schedule successful exit - block commit all VMs if ret != 0: logger.error("Error:" + str(out) + ":" + '.'.join(err)) retcode = 1 else: # delete overlay images from slave with glustermount(args.slave, args.slavevol) as mnt: # find overlay image path (returns .lease and .meta files too) for diskImg in diskimgs_to_del: imgPaths = findImgPaths(diskImg, mnt) for imgPath in imgPaths: logger.debug("IMG PATH:" + imgPath) os.remove(imgPath) for vm_to_commit in vms_to_commit: # Block commit VMs try: vm = vm_to_commit['vm'] logger.debug("Deleting snapshot for: " + vm.name) snapshot = vm_to_commit['snapshot'] # live merge snapshot.delete() # wait for snapshot deletion to complete wait_for_snapshot_deletion(vm, snapshot.get_id(), wait_timeout) logger.debug("Deleted snapshot {0} for vm {1}".format(snapshot.get_name(), vm.name)) except Exception as e: logger.error("Error:" + str(e)) time_end = int(time.time()) time_diff = (time_end - time_start) time_minutes = int(time_diff / 60) time_seconds = time_diff % 60 logger.info("Duration of run: " + str(time_minutes) + ":" + str(time_seconds) + " minutes") add_event(retcode, str(time_minutes) + ":" + str(time_seconds)) # Disconnect from the server api.disconnect() sys.exit(retcode)
def main(argv): usage = "backup.py -c <config.cfg>" try: opts, args = getopt(argv, "hc:d") debug = False if not opts: print usage sys.exit(1) for opt, arg in opts: if (opt == "-h") or (opt == "--help"): print usage sys.exit(0) elif opt in ("-c"): config_file = arg elif opt in ("-d"): debug = True except GetoptError: print usage sys.exit(1) global config config = Config(config_file, debug) time_start = int(time.time()) has_errors = False # Connect to server connect() # Test if all VM names are valid for vm_from_list in config.get_vm_names(): if not api.vms.get(vm_from_list): print "!!! There are no VM with the following name in your cluster: " + vm_from_list api.disconnect() sys.exit(1) vms_with_failures = list(config.get_vm_names()) for vm_from_list in config.get_vm_names(): config.clear_vm_suffix() vm_clone_name = vm_from_list + config.get_vm_middle( ) + config.get_vm_suffix() # Check VM name length limitation length = len(vm_clone_name) if length > config.get_vm_name_max_length(): print "!!! VM name with middle and suffix are to long (size: " + str( length) + ", allowed " + str( config.get_vm_name_max_length()) + ") !!!" Logger.log("VM name: " + vm_clone_name) api.disconnect() sys.exit(1) Logger.log("Start backup for: " + vm_from_list) try: # Get the VM vm = api.vms.get(vm_from_list) # Cleanup: Delete the cloned VM VMTools.delete_vm(api, config, vm_from_list) # Delete old backup snapshots VMTools.delete_snapshots(vm, config, vm_from_list) # Determine disks to snapshot vm_disks = [] try: config_disks = config.get_vm_disks()[vm_from_list] except KeyError: config_disks = None for vm_disk in vm.disks.list(): if config_disks is None or vm_disk.get_name() in config_disks: vm_disks.append(vm_disk) # Create a VM snapshot: try: Logger.log("Snapshot creation started ...") if not config.get_dry_run(): vm.snapshots.add( params.Snapshot( description=config.get_snapshot_description(), vm=vm, disks=params.Disks(disk=vm_disks))) VMTools.wait_for_snapshot_operation(vm, config, "creation") Logger.log("Snapshot created") except Exception as e: Logger.log("Can't create snapshot for VM: " + vm_from_list) Logger.log("DEBUG: " + str(e)) has_errors = True continue # Clone the snapshot into a VM snapshots = vm.snapshots.list( description=config.get_snapshot_description()) if not snapshots: Logger.log("!!! No snapshot found") has_errors = True continue snapshot = snapshots[0] snapshot_param = params.Snapshot(id=snapshot.id) snapshots_param = params.Snapshots(snapshot=[snapshot_param], collapse_snapshots=True) if config.get_vm_clone_domain() is not None: clone_sd = api.storagedomains.get( name=config.get_vm_clone_domain()) if not clone_sd: Logger.log( "!!! Unknown storage domain value for vm_clone_domain") has_errors = True continue vm_clone_disks = [] for disk in snapshot.disks.list(): vm_clone_disks.append( params.Disk(image_id=disk.get_id(), storage_domains=params.StorageDomains( storage_domain=[clone_sd]))) else: vm_clone_disks = snapshot.disks.list() Logger.log("Clone into VM started ...") if not config.get_dry_run(): api.vms.add( params.VM(name=vm_clone_name, memory=vm.get_memory(), cluster=api.clusters.get( config.get_cluster_name()), snapshots=snapshots_param, disks=params.Disks(disk=vm_clone_disks))) VMTools.wait_for_vm_operation(api, config, "Cloning", vm_from_list) Logger.log("Cloning finished") # Delete backup snapshots VMTools.delete_snapshots(vm, config, vm_from_list) # Delete old backups VMTools.delete_old_backups(api, config, vm_from_list) # Export the VM try: vm_clone = api.vms.get(vm_clone_name) Logger.log("Export started ...") if not config.get_dry_run(): vm_clone.export( params.Action(storage_domain=api.storagedomains.get( config.get_export_domain()))) VMTools.wait_for_vm_operation(api, config, "Exporting", vm_from_list) Logger.log("Exporting finished") except Exception as e: Logger.log("Can't export cloned VM (" + vm_clone_name + ") to domain: " + config.get_export_domain()) Logger.log("DEBUG: " + str(e)) has_errors = True continue # Delete the VM VMTools.delete_vm(api, config, vm_from_list) time_end = int(time.time()) time_diff = (time_end - time_start) time_minutes = int(time_diff / 60) time_seconds = time_diff % 60 Logger.log("Duration: " + str(time_minutes) + ":" + str(time_seconds) + " minutes") Logger.log("VM exported as " + vm_clone_name) Logger.log("Backup done for: " + vm_from_list) vms_with_failures.remove(vm_from_list) except errors.ConnectionError as e: Logger.log("!!! Can't connect to the server" + str(e)) connect() continue except errors.RequestError as e: Logger.log("!!! Got a RequestError: " + str(e)) has_errors = True continue except Exception as e: Logger.log("!!! Got unexpected exception: " + str(e)) api.disconnect() sys.exit(1) Logger.log("All backups done") if vms_with_failures: Logger.log("Backup failured for:") for i in vms_with_failures: Logger.log(" " + i) if has_errors: Logger.log( "Some errors occured during the backup, please check the log file") api.disconnect() sys.exit(1) # Disconnect from the server api.disconnect()
def main(argv): try: opts, args = getopt(argv, "hac:d") debug = False all_vms = False if not opts: usage() for opt, arg in opts: if (opt == "-h") or (opt == "--help"): usage() elif opt in ("-c"): config_file = arg elif opt in ("-d"): debug = True elif opt in ("-a"): all_vms = True except GetoptError: usage() global config config = Config(config_file, debug) time_start = int(time.time()) has_errors = False # Connect to server connect() # Add all VM's to the config file if all_vms: vms = api.vms.list(max=400) vmlist.get_vm_list(vms, config_file) config = Config(config_file, debug) # Test if config export_domain is valid if api.storagedomains.get(config.get_export_domain()) is None: print "!!! Check the export_domain in the config" api.disconnect() sys.exit(1) # Test if config cluster_name is valid if api.clusters.get(config.get_cluster_name()) is None: print "!!! Check the cluster_name in the config" api.disconnect() sys.exit(1) # Test if config storage_domain is valid if api.storagedomains.get(config.get_storage_domain()) is None: print "!!! Check the storage_domain in the config" api.disconnect() sys.exit(1) # Test if all VM names are valid for vm_from_list in config.get_vm_names(): if not api.vms.get(vm_from_list): print "!!! There are no VM with the following name in your cluster: " + vm_from_list api.disconnect() sys.exit(1) # Test if config vm_middle is valid if not config.get_vm_middle(): print "!!! It's not valid to leave vm_middle empty" api.disconnect() sys.exit(1) vms_with_failures = list(config.get_vm_names()) for vm_from_list in config.get_vm_names(): config.clear_vm_suffix() vm_clone_name = vm_from_list + config.get_vm_middle( ) + config.get_vm_suffix() # Check VM name length limitation length = len(vm_clone_name) if length > config.get_vm_name_max_length(): print "!!! VM name with middle and suffix are to long (size: " + str( length) + ", allowed " + str( config.get_vm_name_max_length()) + ") !!!" Logger.log("VM name: " + vm_clone_name) api.disconnect() sys.exit(1) Logger.log("Start backup for: " + vm_from_list) try: # Get the VM vm = api.vms.get(vm_from_list) # Cleanup: Delete the cloned VM VMTools.delete_vm(api, config, vm_from_list) # Delete old backup snapshots VMTools.delete_snapshots(vm, config, vm_from_list) # Check free space on the storage VMTools.check_free_space(api, config, vm) # Create a VM snapshot: try: Logger.log("Snapshot creation started ...") if not config.get_dry_run(): vm.snapshots.add( params.Snapshot( description=config.get_snapshot_description(), vm=vm)) VMTools.wait_for_snapshot_operation(vm, config, "creation") Logger.log("Snapshot created") except Exception as e: Logger.log("Can't create snapshot for VM: " + vm_from_list) Logger.log("DEBUG: " + str(e)) has_errors = True continue # Workaround for some SDK problems see issue #17 time.sleep(10) # Clone the snapshot into a VM snapshots = vm.snapshots.list( description=config.get_snapshot_description()) if not snapshots: Logger.log("!!! No snapshot found") has_errors = True continue snapshot_param = params.Snapshot(id=snapshots[0].id) snapshots_param = params.Snapshots(snapshot=[snapshot_param]) Logger.log("Clone into VM started ...") if not config.get_dry_run(): api.vms.add( params.VM(name=vm_clone_name, memory=vm.get_memory(), cluster=api.clusters.get( config.get_cluster_name()), snapshots=snapshots_param)) VMTools.wait_for_vm_operation(api, config, "Cloning", vm_from_list) Logger.log("Cloning finished") # Delete backup snapshots VMTools.delete_snapshots(vm, config, vm_from_list) # Delete old backups VMTools.delete_old_backups(api, config, vm_from_list) # Export the VM try: vm_clone = api.vms.get(vm_clone_name) Logger.log("Export started ...") if not config.get_dry_run(): vm_clone.export( params.Action(storage_domain=api.storagedomains.get( config.get_export_domain()))) VMTools.wait_for_vm_operation(api, config, "Exporting", vm_from_list) Logger.log("Exporting finished") except Exception as e: Logger.log("Can't export cloned VM (" + vm_clone_name + ") to domain: " + config.get_export_domain()) Logger.log("DEBUG: " + str(e)) has_errors = True continue # Delete the VM VMTools.delete_vm(api, config, vm_from_list) time_end = int(time.time()) time_diff = (time_end - time_start) time_minutes = int(time_diff / 60) time_seconds = time_diff % 60 Logger.log("Duration: " + str(time_minutes) + ":" + str(time_seconds) + " minutes") Logger.log("VM exported as " + vm_clone_name) Logger.log("Backup done for: " + vm_from_list) vms_with_failures.remove(vm_from_list) except errors.ConnectionError as e: Logger.log("!!! Can't connect to the server" + str(e)) connect() continue except errors.RequestError as e: Logger.log("!!! Got a RequestError: " + str(e)) has_errors = True continue except Exception as e: Logger.log("!!! Got unexpected exception: " + str(e)) api.disconnect() sys.exit(1) Logger.log("All backups done") if vms_with_failures: Logger.log("Backup failured for:") for i in vms_with_failures: Logger.log(" " + i) if has_errors: Logger.log( "Some errors occured during the backup, please check the log file") api.disconnect() sys.exit(1) # Disconnect from the server api.disconnect()
#!/usr/bin/env python import sys from ovirtsdk.api import API from ovirtsdk.xml import params from datetime import date USERNAME = '******' PASSWORD = '******' URL = 'https://localhost/api' SNAPSHOT_NAME = 'backup-{}'.format(date.today().strftime("%Y%m%d")) api = API(URL, username=USERNAME, password=PASSWORD, insecure=True) vms = api.vms.list() for i in vms: if i.tags.list() != [] and i.tags.list()[0].name == sys.argv[1]: i.snapshots.add(params.Snapshot(description=SNAPSHOT_NAME, vm=i))
def main(argv): p = create_argparser() opts = p.parse_args(argv) config_arguments = arguments_to_dict(opts) global config with opts.config_file: config = Config(opts.config_file, opts.debug, config_arguments) initialize_logger( config.get_logger_fmt(), config.get_logger_file_path(), opts.debug, ) time_start = int(time.time()) has_errors = False # Connect to server connect() # Add all VM's to the config file if opts.all_vms: vms = api.vms.list(max=400) config.set_vm_names([vm.name for vm in vms]) # Update config file if opts.config_file.name != "<stdin>": config.write_update(opts.config_file.name) # Add VM's with the tag to the vm list if opts.vm_tag: vms = api.vms.list(max=400, query="tag=" + opts.vm_tag) config.set_vm_names([vm.name for vm in vms]) # Update config file if opts.config_file.name != "<stdin>": config.write_update(opts.config_file.name) # Test if data center is valid if api.datacenters.get(config.get_datacenter_name()) is None: logger.error("!!! Check the datacenter_name in the config") api.disconnect() sys.exit(1) # Test if config export_domain is valid if api.storagedomains.get(config.get_export_domain()) is None: logger.error("!!! Check the export_domain in the config") api.disconnect() sys.exit(1) # Test if config cluster_name is valid if api.clusters.get(config.get_cluster_name()) is None: logger.error("!!! Check the cluster_name in the config") api.disconnect() sys.exit(1) # Test if config storage_domain is valid if api.storagedomains.get(config.get_storage_domain()) is None: logger.error("!!! Check the storage_domain in the config") api.disconnect() sys.exit(1) # Test if all VM names are valid for vm_from_list in config.get_vm_names(): if not api.vms.get(vm_from_list): logger.error( "!!! There are no VM with the following name in your cluster: %s", vm_from_list) api.disconnect() sys.exit(1) # Test if config vm_middle is valid if not config.get_vm_middle(): logger.error("!!! It's not valid to leave vm_middle empty") api.disconnect() sys.exit(1) vms_with_failures = list(config.get_vm_names()) for vm_from_list in config.get_vm_names(): config.clear_vm_suffix() vm_clone_name = vm_from_list + config.get_vm_middle( ) + config.get_vm_suffix() # Check VM name length limitation length = len(vm_clone_name) if length > config.get_vm_name_max_length(): logger.error( "!!! VM name with middle and suffix are to long (size: %s, allowed %s) !!!", length, config.get_vm_name_max_length()) logger.info("VM name: %s", vm_clone_name) api.disconnect() sys.exit(1) logger.info("Start backup for: %s", vm_from_list) try: VMTools.check_storage_domain_status(api, config.get_datacenter_name(), config.get_export_domain()) # Cleanup: Delete the cloned VM VMTools.delete_vm(api, config, vm_from_list) # Get the VM vm = api.vms.get(vm_from_list) if vm is None: logger.warn( "The VM (%s) doesn't exist anymore, skipping backup ...", vm_from_list) continue # Delete old backup snapshots VMTools.delete_snapshots(vm, config, vm_from_list) # Check free space on the storage VMTools.check_free_space(api, config, vm) # Create a VM snapshot: try: logger.info("Snapshot creation started ...") if not config.get_dry_run(): vm.snapshots.add( params.Snapshot( description=config.get_snapshot_description(), vm=vm, persist_memorystate=config.get_persist_memorystate( ), )) VMTools.wait_for_snapshot_operation(vm, config, "creation") logger.info("Snapshot created") except Exception as e: logger.info("Can't create snapshot for VM: %s", vm_from_list) logger.info("DEBUG: %s", e) has_errors = True continue # Workaround for some SDK problems see issue #17 time.sleep(10) # Clone the snapshot into a VM snapshots = vm.snapshots.list( description=config.get_snapshot_description()) if not snapshots: logger.error("!!! No snapshot found !!!") has_errors = True continue snapshot_param = params.Snapshot(id=snapshots[0].id) snapshots_param = params.Snapshots(snapshot=[snapshot_param]) logger.info("Clone into VM (%s) started ..." % vm_clone_name) if not config.get_dry_run(): api.vms.add( params.VM(name=vm_clone_name, memory=vm.get_memory(), cluster=api.clusters.get( config.get_cluster_name()), snapshots=snapshots_param)) VMTools.wait_for_vm_operation(api, config, "Cloning", vm_from_list) logger.info("Cloning finished") # Delete backup snapshots VMTools.delete_snapshots(vm, config, vm_from_list) # Delete old backups if (config.get_backup_keep_count()): VMTools.delete_old_backups(api, config, vm_from_list) if (config.get_backup_keep_count_by_number()): VMTools.delete_old_backups_by_number(api, config, vm_from_list) # Export the VM try: vm_clone = api.vms.get(vm_clone_name) logger.info("Export of VM (%s) started ..." % vm_clone_name) if not config.get_dry_run(): vm_clone.export( params.Action(storage_domain=api.storagedomains.get( config.get_export_domain()))) VMTools.wait_for_vm_operation(api, config, "Exporting", vm_from_list) logger.info("Exporting finished") except Exception as e: logger.info("Can't export cloned VM (%s) to domain: %s", vm_clone_name, config.get_export_domain()) logger.info("DEBUG: %s", e) has_errors = True continue # Delete the VM VMTools.delete_vm(api, config, vm_from_list) time_end = int(time.time()) time_diff = (time_end - time_start) time_minutes = int(time_diff / 60) time_seconds = time_diff % 60 logger.info("Duration: %s:%s minutes", time_minutes, time_seconds) logger.info("VM exported as %s", vm_clone_name) logger.info("Backup done for: %s", vm_from_list) vms_with_failures.remove(vm_from_list) except errors.ConnectionError as e: logger.error("!!! Can't connect to the server %s", e) connect() continue except errors.RequestError as e: logger.error("!!! Got a RequestError: %s", e) has_errors = True continue except Exception as e: logger.error("!!! Got unexpected exception: %s", e) api.disconnect() sys.exit(1) logger.info("All backups done") if vms_with_failures: logger.info("Backup failured for:") for i in vms_with_failures: logger.info(" %s", i) if has_errors: logger.info( "Some errors occured during the backup, please check the log file") api.disconnect() sys.exit(1) # Disconnect from the server api.disconnect()
def snapclone_to_export(api, vm): """Generates a snapshot of a VM, clones it, then exports, and removes the temporary VM""" description = "Preexport-%s" % time.mktime(time.gmtime()) # GET VM cluster = api.clusters.get(id=vm.cluster.id) if not vm: print "VM %s not found" % vm.name sys.exit(1) # Create new snapshot if options.verbosity > 0: print "Creating snapshot..." vm.snapshots.add(params.Snapshot(description=description, vm=vm)) # Wait for snapshot to finish i = 0 while api.vms.get(name=vm.name).status.state == "image_locked": if options.verbosity > 0: print "waiting for snapshot to finish %s..." % i time.sleep(10) i = i + 1 # Get snapshot object snap = api.vms.get(name=vm.name).snapshots.list(description=description)[0] # Build snapshots collection snapshots = params.Snapshots(snapshot=[params.Snapshot(id=snap.id)]) # Create new VM from SNAPSHOT (NOT WORKING AT THE MOMENT) newname = "%s-deleteme" % vm.name if options.verbosity > 0: print "Creating new VM based on snapshot..." api.vms.add( params.VM(name=newname, snapshots=snapshots, cluster=cluster, template=api.templates.get(name="Blank"))) # Wait for create to finish i = 0 while api.vms.get(name=newname).status.state == "image_locked": if options.verbosity > 0: print "Waiting for creation to finish..." i = i + 1 time.sleep(10) # DC dc = api.datacenters.get(id=cluster.data_center.id) # Get Export domain from our DC export = None for sd in dc.storagedomains.list(): if sd.type_ == "export": export = sd if not export: print "Export domain required, and none found, exitting..." sys.exit(1) if options.verbosity > 0: print "Exporting cloned VM to export domain..." # Export cloned VM to export domain for backup api.vms.get(name=newname).export(params.Action(storage_domain=export)) # Wait for create to finish i = 0 while api.vms.get(name=newname).status.state == "image_locked": i = i + 1 if options.verbosity > 0: print "waiting for export to finish..." time.sleep(10) if options.verbosity > 0: print "Deleting temporary VM..." api.vms.get(name=newname).delete() if options.verbosity > 0: print "Deleting temporary snapshot..." print "NOT YET SUPPORTED BY RHEV API" return
def main(): argument_spec = { "state": { "default": "present", "choices": ['present', 'absent', 'restored'], "type": 'str' }, "url": { "default": 'https://127.0.0.1/ovirt-engine/api', "required": False, "type": "str" }, "user": { "default": 'admin@internal', "required": False, "type": "str" }, "password": { "required": True, "type": "str" }, "vm": { "required": True, "type": "str" }, "name": { "required": False, "type": "str" }, "wait": { "default": True, "required": False, "type": "bool" }, "force": { "default": False, "required": False, "type": "bool" }, "start": { "default": True, "required": False, "type": "bool" }, } module = AnsibleModule(argument_spec=argument_spec) url = module.params['url'] user = module.params['user'] password = module.params['password'] vm = module.params['vm'] state = module.params['state'] name = module.params['name'] wait = module.params['wait'] force = module.params['force'] start = module.params['start'] api = API(url=url, username=user, password=password, insecure=True) vmname = vm vm = api.vms.get(name=vm) if not vm: module.fail_json(msg='Vm %s not found' % vmname) if state == 'present': if name is not None: snapshot = next( (s for s in vm.snapshots.list() if s.description == name), None) if snapshot is not None: if not force: module.fail_json(msg='Snapshot %s allready exists' % name) else: wait_ready(api, vmname) snapshot.delete() description = name else: now = datetime.now().strftime('%Y%m%d%H%M%S') description = "%s_%s" % (vmname, now) snapshot = params.Snapshot(description=description) wait_ready(api, vmname) vm.snapshots.add(snapshot) if wait: wait_ready(api, vmname) result = "%s created" % name meta = {'result': result} module.exit_json(changed=True, skipped=False, meta=meta) elif state == 'restored': if name is None: module.fail_json(msg='Snapshot name missing') else: snapshots = [ s for s in vm.snapshots.list() if s.description == name ] if not snapshots: module.fail_json(msg='No Snapshot with name %s found' % name) elif len(snapshots) > 1: module.fail_json(msg='Multiple Snapshots with name %s found' % name) else: if api.vms.get(vmname).status.state != 'down' and not force: module.fail_json( msg='Cant Restore from snapshot while vm %s is up' % vmname) else: api.vms.get(vmname).stop() # api.vms.get(vmname).shutdown() while api.vms.get(vmname).status.state != "down": sleep(5) snapshot = snapshots[0] action = params.Action(snapshot=snapshot) wait_ready(api, vmname) vm.preview_snapshot(action) wait_ready(api, vmname) vm.commit_snapshot(action) wait_ready(api, vmname) if start: api.vms.get(vmname).start() wait_up(api, vmname) snapshot.delete() wait_ready(api, vmname) meta = {'result': '%s Restored' % name} module.exit_json(changed=True, skipped=False, meta=meta) elif state == 'absent': if name is None: module.fail_json(msg='Snapshot name missing') else: snapshotname = name snapshots = [ s for s in vm.snapshots.list() if s.description == snapshotname ] if snapshots: for snapshot in snapshots: wait_ready(api, vmname) snapshot.delete() if wait: wait_ready(api, vmname) meta = {'result': '%s deleted' % snapshotname} module.exit_json(changed=True, skipped=False, meta=meta) else: meta = {'result': '%s not found' % snapshotname} module.exit_json(changed=False, skipped=True, meta=meta)
def _getSnapshotParams(self, snapshotName): return params.Snapshot( description=snapshotName)
USERNAME = YYYYYYYYYYYY PASSWORD = YYYYYYYYYYYY api = ovirtsdk.api.API(url=SERVER, username=USERNAME, password=PASSWORD, insecure=True, debug=False) logging.basicConfig() log = logging.getLogger() ###########################BACKUP################################# vm = api.vms.get(VM_NAME) #Create a VM snapshot: vm.snapshots.add(params.Snapshot(description=SNAPSHOT_DESCRIPTION, vm=vm)) while api.vms.get(VM_NAME).status.state == 'image_locked': sleep(1) # Get the snapshot, you can backup the configuration data to be able to # restore the vm with the same configuration later on snap = api.vms.get(name=vm.name).snapshots.list( all_content=True, description=SNAPSHOT_DESCRIPTION)[0] configuration_data = snap.get_initialization().get_configuration().get_data() print configuration_data # Find the disk snapshot that you want to backup: disks = snap.disks.list() disk = None for current in disks: if current.get_name() == "VM_FOR_BACKUP_Disk1":