def freeze_snapshot(timeout): try: global hutil, backup_logger, run_result, run_status, error_msg, freezer, freeze_result, para_parser, snapshot_info_array, g_fsfreeze_on, workload_patch canTakeCrashConsistentSnapshot = can_take_crash_consistent_snapshot( para_parser) freeze_snap_shotter = FreezeSnapshotter( backup_logger, hutil, freezer, g_fsfreeze_on, para_parser, canTakeCrashConsistentSnapshot) backup_logger.log("Calling do snapshot method", True, 'Info') run_result, run_status, snapshot_info_array = freeze_snap_shotter.doFreezeSnapshot( ) if (canTakeCrashConsistentSnapshot == True and run_result != CommonVariables.success and run_result != CommonVariables.success_appconsistent): if (snapshot_info_array is not None and snapshot_info_array != [] and check_snapshot_array_fail() == False and len(snapshot_info_array) == 1): run_status = CommonVariables.status_success run_result = CommonVariables.success hutil.SetSnapshotConsistencyType( Status.SnapshotConsistencyType.crashConsistent) except Exception as e: errMsg = 'Failed to do the snapshot with error: %s, stack trace: %s' % ( str(e), traceback.format_exc()) backup_logger.log(errMsg, True, 'Error') run_result = CommonVariables.error run_status = 'error' error_msg = 'Enable failed with exception in safe freeze or snapshot ' hutil.SetExtErrorCode( ExtensionErrorCodeHelper.ExtensionErrorCodeEnum.error)
def freeze_snapshot(timeout): try: global hutil,backup_logger,run_result,run_status,error_msg,freezer,freeze_result,para_parser,snapshot_info_array,g_fsfreeze_on if(hutil.get_value_from_configfile('doseq') == '2'): hutil.set_value_to_configfile('doseq', '1') if(hutil.get_value_from_configfile('doseq') != '1'): hutil.set_value_to_configfile('doseq', '2') freeze_snap_shotter = FreezeSnapshotter(backup_logger, hutil, freezer, g_fsfreeze_on, para_parser) backup_logger.log("Calling do snapshot method", True, 'Info') run_result, run_status, snapshot_info_array = freeze_snap_shotter.doFreezeSnapshot() except Exception as e: if(hutil.get_value_from_configfile('doseq') == '2'): hutil.set_value_to_configfile('doseq', '0') errMsg = 'Failed to do the snapshot with error: %s, stack trace: %s' % (str(e), traceback.format_exc()) backup_logger.log(errMsg, True, 'Error') run_result = CommonVariables.error run_status = 'error' error_msg = 'Enable failed with exception in safe freeze or snapshot ' hutil.SetExtErrorCode(ExtensionErrorCodeHelper.ExtensionErrorCodeEnum.error)
def daemon(): global MyPatching, backup_logger, hutil, run_result, run_status, error_msg, freezer, para_parser, snapshot_done, snapshot_info_array, g_fsfreeze_on, total_used_size, patch_class_name, orig_distro, workload_patch, configSeqNo #this is using the most recent file timestamp. hutil.do_parse_context('Executing', configSeqNo) try: backup_logger.log('starting daemon', True) backup_logger.log( "patch_class_name: " + str(patch_class_name) + " and orig_distro: " + str(orig_distro), True) # handle the restoring scenario. mi = MachineIdentity() stored_identity = mi.stored_identity() if (stored_identity is None): mi.save_identity() else: current_identity = mi.current_identity() if (current_identity != stored_identity): current_seq_no = -1 backup_logger.log( "machine identity not same, set current_seq_no to " + str(current_seq_no) + " " + str(stored_identity) + " " + str(current_identity), True) hutil.set_last_seq(current_seq_no) mi.save_identity() except Exception as e: errMsg = 'Failed to validate sequence number with error: %s, stack trace: %s' % ( str(e), traceback.format_exc()) backup_logger.log(errMsg, True, 'Error') freezer = FsFreezer(patching=MyPatching, logger=backup_logger, hutil=hutil) global_error_result = None # precheck freeze_called = False configfile = '/etc/azure/vmbackup.conf' thread_timeout = str(60) OnAppFailureDoFsFreeze = True OnAppSuccessDoFsFreeze = True #Adding python version to the telemetry try: python_version_info = sys.version_info python_version = str(sys.version_info[0]) + '.' + str( sys.version_info[1]) + '.' + str(sys.version_info[2]) HandlerUtil.HandlerUtility.add_to_telemetery_data( "pythonVersion", python_version) except Exception as e: errMsg = 'Failed to do retrieve python version with error: %s, stack trace: %s' % ( str(e), traceback.format_exc()) backup_logger.log(errMsg, True, 'Error') #fetching platform architecture try: architecture = platform.architecture()[0] HandlerUtil.HandlerUtility.add_to_telemetery_data( "platformArchitecture", architecture) except Exception as e: errMsg = 'Failed to do retrieve "platform architecture" with error: %s, stack trace: %s' % ( str(e), traceback.format_exc()) backup_logger.log(errMsg, True, 'Error') try: if (freezer.mounts is not None): hutil.partitioncount = len(freezer.mounts.mounts) backup_logger.log(" configfile " + str(configfile), True) config = ConfigParsers.ConfigParser() config.read(configfile) if config.has_option('SnapshotThread', 'timeout'): thread_timeout = config.get('SnapshotThread', 'timeout') if config.has_option('SnapshotThread', 'OnAppFailureDoFsFreeze'): OnAppFailureDoFsFreeze = config.get('SnapshotThread', 'OnAppFailureDoFsFreeze') if config.has_option('SnapshotThread', 'OnAppSuccessDoFsFreeze'): OnAppSuccessDoFsFreeze = config.get('SnapshotThread', 'OnAppSuccessDoFsFreeze') except Exception as e: errMsg = 'cannot read config file or file not present' backup_logger.log(errMsg, True, 'Warning') backup_logger.log("final thread timeout" + thread_timeout, True) snapshot_info_array = None try: # we need to freeze the file system first backup_logger.log('starting daemon', True) """ protectedSettings is the privateConfig passed from Powershell. WATCHOUT that, the _context_config are using the most freshest timestamp. if the time sync is alive, this should be right. """ protected_settings = hutil._context._config['runtimeSettings'][0][ 'handlerSettings'].get('protectedSettings', {}) public_settings = hutil._context._config['runtimeSettings'][0][ 'handlerSettings'].get('publicSettings') para_parser = ParameterParser(protected_settings, public_settings, backup_logger) hutil.update_settings_file() if (bool(public_settings) == False and not protected_settings): error_msg = "unable to load certificate" hutil.SetExtErrorCode( ExtensionErrorCodeHelper.ExtensionErrorCodeEnum. FailedHandlerGuestAgentCertificateNotFound) temp_result = CommonVariables.FailedHandlerGuestAgentCertificateNotFound temp_status = 'error' exit_with_commit_log(temp_status, temp_result, error_msg, para_parser) if (para_parser.commandStartTimeUTCTicks is not None and para_parser.commandStartTimeUTCTicks != ""): canTakeCrashConsistentSnapshot = can_take_crash_consistent_snapshot( para_parser) temp_g_fsfreeze_on = True freeze_snap_shotter = FreezeSnapshotter( backup_logger, hutil, freezer, temp_g_fsfreeze_on, para_parser, canTakeCrashConsistentSnapshot) if freeze_snap_shotter.is_command_timedout(para_parser): error_msg = "CRP timeout limit has reached, will not take snapshot." errMsg = error_msg hutil.SetExtErrorCode( ExtensionErrorCodeHelper.ExtensionErrorCodeEnum. FailedGuestAgentInvokedCommandTooLate) temp_result = CommonVariables.FailedGuestAgentInvokedCommandTooLate temp_status = 'error' exit_with_commit_log(temp_status, temp_result, error_msg, para_parser) hutil.save_seq() commandToExecute = para_parser.commandToExecute #validate all the required parameter here backup_logger.log(commandToExecute, True) if (CommonVariables.iaas_install_command in commandToExecute.lower()): backup_logger.log('install succeed.', True) run_status = 'success' error_msg = 'Install Succeeded' run_result = CommonVariables.success backup_logger.log(error_msg) elif (CommonVariables.iaas_vmbackup_command in commandToExecute.lower()): if (para_parser.backup_metadata is None or para_parser.public_config_obj is None): run_result = CommonVariables.error_parameter hutil.SetExtErrorCode(ExtensionErrorCodeHelper. ExtensionErrorCodeEnum.error_parameter) run_status = 'error' error_msg = 'required field empty or not correct' backup_logger.log(error_msg, True, 'Error') else: backup_logger.log('commandToExecute is ' + commandToExecute, True) """ make sure the log is not doing when the file system is freezed. """ temp_status = 'success' temp_result = CommonVariables.ExtensionTempTerminalState temp_msg = 'Transitioning state in extension' blob_report_msg, file_report_msg = get_status_to_report( temp_status, temp_result, temp_msg, None) status_report_to_file(file_report_msg) status_report_to_blob(blob_report_msg) #partial logging before freeze if (para_parser is not None and para_parser.logsBlobUri is not None and para_parser.logsBlobUri != ""): backup_logger.commit_to_blob(para_parser.logsBlobUri) else: backup_logger.log( "the logs blob uri is not there, so do not upload log." ) backup_logger.log('commandToExecute is ' + commandToExecute, True) workload_patch = WorkloadPatch.WorkloadPatch(backup_logger) #new flow only if workload name is present in workload.conf if workload_patch.name != None and workload_patch.name != "": backup_logger.log( "workload backup enabled for workload: " + workload_patch.name, True) hutil.set_pre_post_enabled() pre_skipped = False if len(workload_patch.error_details) > 0: backup_logger.log("skip pre and post") pre_skipped = True else: workload_patch.pre() if len(workload_patch.error_details) > 0: backup_logger.log("file system consistent backup only") #todo error handling if len( workload_patch.error_details ) > 0 and OnAppFailureDoFsFreeze == True: #App&FS consistency g_fsfreeze_on = True elif len( workload_patch.error_details ) > 0 and OnAppFailureDoFsFreeze == False: # Do Fs freeze only if App success hutil.SetExtErrorCode(ExtensionErrorCodeHelper. ExtensionErrorCodeEnum.error) error_msg = 'Failing backup as OnAppFailureDoFsFreeze is set to false' temp_result = CommonVariables.error temp_status = 'error' exit_with_commit_log(temp_status, temp_result, error_msg, para_parser) elif len( workload_patch.error_details ) == 0 and OnAppSuccessDoFsFreeze == False: # App only g_fsfreeze_on = False elif len( workload_patch.error_details ) == 0 and OnAppSuccessDoFsFreeze == True: #App&FS consistency g_fsfreeze_on = True else: g_fsfreeze_on = True freeze_snapshot(thread_timeout) if pre_skipped == False: workload_patch.post() workload_error = workload_patch.populateErrors() if workload_error != None and g_fsfreeze_on == False: run_status = 'error' run_result = workload_error.errorCode hutil.SetExtErrorCode(workload_error.errorCode) error_msg = 'Workload Patch failed with error message: ' + workload_error.errorMsg error_msg = error_msg + ExtensionErrorCodeHelper.ExtensionErrorCodeHelper.StatusCodeStringBuilder( hutil.ExtErrorCode) backup_logger.log(error_msg, True) elif workload_error != None and g_fsfreeze_on == True: hutil.SetExtErrorCode(workload_error.errorCode) error_msg = 'Workload Patch failed with warning message: ' + workload_error.errorMsg error_msg = error_msg + ExtensionErrorCodeHelper.ExtensionErrorCodeHelper.StatusCodeStringBuilder( hutil.ExtErrorCode) backup_logger.log(error_msg, True) else: if (run_status == CommonVariables.status_success): run_status = 'success' run_result = CommonVariables.success_appconsistent hutil.SetExtErrorCode( ExtensionErrorCodeHelper. ExtensionErrorCodeEnum.success_appconsistent) error_msg = 'Enable Succeeded with App Consistent Snapshot' backup_logger.log(error_msg, True) else: error_msg = 'Enable failed in fsfreeze snapshot flow' backup_logger.log(error_msg, True) else: PluginHostObj = PluginHost(logger=backup_logger) PluginHostErrorCode, dobackup, g_fsfreeze_on = PluginHostObj.pre_check( ) doFsConsistentbackup = False appconsistentBackup = False if not (PluginHostErrorCode == CommonVariables. FailedPrepostPluginhostConfigParsing or PluginHostErrorCode == CommonVariables.FailedPrepostPluginConfigParsing or PluginHostErrorCode == CommonVariables. FailedPrepostPluginhostConfigNotFound or PluginHostErrorCode == CommonVariables. FailedPrepostPluginhostConfigPermissionError or PluginHostErrorCode == CommonVariables.FailedPrepostPluginConfigNotFound): backup_logger.log( 'App Consistent Consistent Backup Enabled', True) HandlerUtil.HandlerUtility.add_to_telemetery_data( "isPrePostEnabled", "true") appconsistentBackup = True if (PluginHostErrorCode != CommonVariables.PrePost_PluginStatus_Success): backup_logger.log( 'Triggering File System Consistent Backup because of error code' + ExtensionErrorCodeHelper.ExtensionErrorCodeHelper. StatusCodeStringBuilder(PluginHostErrorCode), True) doFsConsistentbackup = True preResult = PluginHostResult() postResult = PluginHostResult() if not doFsConsistentbackup: preResult = PluginHostObj.pre_script() dobackup = preResult.continueBackup if (g_fsfreeze_on == False and preResult.anyScriptFailed): dobackup = False if dobackup: freeze_snapshot(thread_timeout) if not doFsConsistentbackup: postResult = PluginHostObj.post_script() if not postResult.continueBackup: dobackup = False if (g_fsfreeze_on == False and postResult.anyScriptFailed): dobackup = False if not dobackup: if run_result == CommonVariables.success and PluginHostErrorCode != CommonVariables.PrePost_PluginStatus_Success: run_status = 'error' run_result = PluginHostErrorCode hutil.SetExtErrorCode(PluginHostErrorCode) error_msg = 'Plugin Host Precheck Failed' error_msg = error_msg + ExtensionErrorCodeHelper.ExtensionErrorCodeHelper.StatusCodeStringBuilder( hutil.ExtErrorCode) backup_logger.log(error_msg, True) if run_result == CommonVariables.success: pre_plugin_errors = preResult.errors for error in pre_plugin_errors: if error.errorCode != CommonVariables.PrePost_PluginStatus_Success: run_status = 'error' run_result = error.errorCode hutil.SetExtErrorCode(error.errorCode) error_msg = 'PreScript failed for the plugin ' + error.pluginName error_msg = error_msg + ExtensionErrorCodeHelper.ExtensionErrorCodeHelper.StatusCodeStringBuilder( hutil.ExtErrorCode) backup_logger.log(error_msg, True) break if run_result == CommonVariables.success: post_plugin_errors = postResult.errors for error in post_plugin_errors: if error.errorCode != CommonVariables.PrePost_PluginStatus_Success: run_status = 'error' run_result = error.errorCode hutil.SetExtErrorCode(error.errorCode) error_msg = 'PostScript failed for the plugin ' + error.pluginName error_msg = error_msg + ExtensionErrorCodeHelper.ExtensionErrorCodeHelper.StatusCodeStringBuilder( hutil.ExtErrorCode) backup_logger.log(error_msg, True) break if appconsistentBackup: if (PluginHostErrorCode != CommonVariables.PrePost_PluginStatus_Success): hutil.SetExtErrorCode(PluginHostErrorCode) pre_plugin_errors = preResult.errors for error in pre_plugin_errors: if error.errorCode != CommonVariables.PrePost_PluginStatus_Success: hutil.SetExtErrorCode(error.errorCode) post_plugin_errors = postResult.errors for error in post_plugin_errors: if error.errorCode != CommonVariables.PrePost_PluginStatus_Success: hutil.SetExtErrorCode(error.errorCode) if run_result == CommonVariables.success and not doFsConsistentbackup and not ( preResult.anyScriptFailed or postResult.anyScriptFailed): run_status = 'success' run_result = CommonVariables.success_appconsistent hutil.SetExtErrorCode( ExtensionErrorCodeHelper.ExtensionErrorCodeEnum. success_appconsistent) error_msg = 'Enable Succeeded with App Consistent Snapshot' backup_logger.log(error_msg, True) else: run_status = 'error' run_result = CommonVariables.error_parameter hutil.SetExtErrorCode(ExtensionErrorCodeHelper. ExtensionErrorCodeEnum.error_parameter) error_msg = 'command is not correct' backup_logger.log(error_msg, True, 'Error') except Exception as e: hutil.update_settings_file() errMsg = 'Failed to enable the extension with error: %s, stack trace: %s' % ( str(e), traceback.format_exc()) backup_logger.log(errMsg, True, 'Error') global_error_result = e """ we do the final report here to get rid of the complex logic to handle the logging when file system be freezed issue. """ try: if (global_error_result is not None): if (hasattr(global_error_result, 'errno') and global_error_result.errno == 2): run_result = CommonVariables.error_12 hutil.SetExtErrorCode( ExtensionErrorCodeHelper.ExtensionErrorCodeEnum.error_12) elif (para_parser is None): run_result = CommonVariables.error_parameter hutil.SetExtErrorCode(ExtensionErrorCodeHelper. ExtensionErrorCodeEnum.error_parameter) else: run_result = CommonVariables.error hutil.SetExtErrorCode( ExtensionErrorCodeHelper.ExtensionErrorCodeEnum.error) run_status = 'error' error_msg += ('Enable failed.' + str(global_error_result)) status_report_msg = None hutil.SetExtErrorCode( run_result ) #setting extension errorcode at the end if missed somewhere HandlerUtil.HandlerUtility.add_to_telemetery_data( "extErrorCode", str(ExtensionErrorCodeHelper.ExtensionErrorCodeHelper. ExtensionErrorCodeNameDict[hutil.ExtErrorCode])) total_used_size = -1 blob_report_msg, file_report_msg = get_status_to_report( run_status, run_result, error_msg, snapshot_info_array) if (hutil.is_status_file_exists()): status_report_to_file(file_report_msg) status_report_to_blob(blob_report_msg) except Exception as e: errMsg = 'Failed to log status in extension' backup_logger.log(errMsg, True, 'Error') if (para_parser is not None and para_parser.logsBlobUri is not None and para_parser.logsBlobUri != ""): backup_logger.commit(para_parser.logsBlobUri) else: backup_logger.log( "the logs blob uri is not there, so do not upload log.") backup_logger.commit_to_local() sys.exit(0)