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() system_service = api.system_service() # Test if data center is valid # Retrieve the data center service: if system_service.data_centers_service().list( search='name=%s' % config.get_datacenter_name())[0] is None: logger.error("!!! Check the datacenter_name in the config") api.close() sys.exit(1) # Test if config export_domain is valid if system_service.storage_domains_service().list( search='name=%s' % config.get_export_domain())[0] is None: logger.error("!!! Check the export_domain in the config " + config.get_export_domain()) api.close() sys.exit(1) # Test if config cluster_name is valid if system_service.clusters_service().list( search='name=%s' % config.get_cluster_name())[0] is None: logger.error("!!! Check the cluster_name in the config") api.close() sys.exit(1) # Test if config storage_domain is valid if system_service.storage_domains_service().list( search='name=%s' % config.get_storage_domain())[0] is None: logger.error("!!! Check the storage_domain in the config") api.close() sys.exit(1) vms_service = system_service.vms_service() # Add all VM's to the config file if opts.all_vms: vms = vms_service.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 = vms_service.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 all VM names are valid for vm_from_list in config.get_vm_names(): if vms_service.list(search='name=%s' % vm_from_list) is None: logger.error( "!!! There are no VM with the following name in your cluster: %s", vm_from_list) api.close() 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.close() sys.exit(1) vms_with_failures = list(config.get_vm_names()) dcs_service = system_service.data_centers_service() dc = dcs_service.list(search='name=%s' % config.get_datacenter_name())[0] dc_service = dcs_service.data_center_service(dc.id) sds_service = dc_service.storage_domains_service() sd_service = sds_service.list(search='name=%s' % config.get_export_domain())[0] 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.close() 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 = vms_service.list(search='name=%s' % vm_from_list) if len(vm) == 0: logger.warn( "The VM (%s) doesn't exist anymore, skipping backup ...", vm_from_list) continue vm = vm[0] # Delete old backup snapshots VMTools.delete_snapshots(api, 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 ...") snapshots_service = vms_service.vm_service( vm.id).snapshots_service() if not config.get_dry_run(): # Add the new snapshot: snapshots_service.add( types.Snapshot( description=config.get_snapshot_description(), persist_memorystate=config.get_persist_memorystate( ), ), ) VMTools.wait_for_snapshot_operation( api, 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(config.get_timeout()) # Clone the snapshot into a VM snapshots = snapshots_service.list() snap = None for i in snapshots: if i.description == config.get_snapshot_description(): snap = i if not snap: logger.error("!!! No snapshot found !!!") has_errors = True continue logger.info("Clone into VM (%s) started ..." % vm_clone_name) if not config.get_dry_run(): cloned_vm = vms_service.add( vm=types.Vm(name=vm_clone_name, memory=vm.memory, snapshots=[types.Snapshot(id=snap.id)], cluster=types.Cluster( name=config.get_cluster_name()))) # Find the service that manages the cloned virtual machine: cloned_vm_service = vms_service.vm_service(cloned_vm.id) # Wait till the virtual machine is down, as that means that the creation # of the disks of the virtual machine has been completed: while True: time.sleep(config.get_timeout()) logger.debug("Cloning into VM (%s) in progress ..." % vm_clone_name) cloned_vm = cloned_vm_service.get() if cloned_vm.status == types.VmStatus.DOWN: break logger.info("Cloning finished") # Delete backup snapshots VMTools.delete_snapshots(api, 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.system_service().vms_service().list( search='name=%s' % vm_clone_name)[0] logger.info("Export of VM (%s) started ..." % vm_clone_name) if not config.get_dry_run(): cloned_vm_service = vms_service.vm_service(vm_clone.id) cloned_vm_service.export( exclusive=True, discard_snapshots=True, storage_domain=types.StorageDomain( name=config.get_export_domain())) while True: time.sleep(config.get_timeout()) cloned_vm = cloned_vm_service.get() if cloned_vm.status == types.VmStatus.DOWN: break 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 CLONED 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 Exception as e: logger.error("!!! Got unexpected exception: %s", e) api.close() 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.close() sys.exit(1) # Disconnect from the server api.close()
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()