def rman(self, finalscript): self._setenv() debug("RMAN execution starts") BackupLogger.close() starttime = datetime.now() with TemporaryFile() as f: p = Popen([os.path.join(self.oraclehome, 'bin', 'rman'), "log", BackupLogger.logfile, "append"], stdout=f, stderr=f, stdin=PIPE) # Send the script to RMAN p.communicate(input=finalscript) endtime = datetime.now() BackupLogger.init() debug("RMAN execution time %s" % (endtime-starttime)) # If RMAN exists with any code except 0, then there was some error if p.returncode != 0: error("RMAN execution failed with code %d" % p.returncode) raise Exception('rman', "RMAN exited with code %d" % p.returncode) else: debug("RMAN execution successful")
def sqlplus(self, finalscript, silent=False): self._setenv() with TemporaryFile() as f: args = [os.path.join(self.oraclehome, 'bin', 'sqlplus')] if silent: args.append('-S') args.append('/nolog') debug("SQL*Plus execution starts") BackupLogger.close() p = Popen(args, stdout=f, stderr=f, stdin=PIPE) p.communicate(input=finalscript) BackupLogger.init() if p.returncode != 0: error("SQL*Plus exited with code %d" % p.returncode) raise Exception('sqlplus', "sqlplus exited with code %d" % p.returncode) else: debug("SQL*Plus execution successful") if silent: f.seek(0,0) return f.read()
def runrestore(database): global exitstatus # Configuration.defaultsection = database # restoredest = Configuration.get('autorestoredestination', 'autorestore') mountdest = Configuration.get('autorestoremountpoint', 'autorestore') logdir = Configuration.get('autorestorelogdir', 'autorestore') Configuration.substitutions.update({ 'logdir': logdir, 'autorestorecatalog': Configuration.get('autorestorecatalog', 'autorestore') }) if restoredest is None or not os.path.exists( restoredest) or not os.path.isdir(restoredest): print "Restore directory %s not found or is not a proper directory" % restoredest sys.exit(2) if mountdest is None or not os.path.exists(mountdest) or not os.path.isdir( mountdest): print "Clone mount directory %s not found or is not a proper directory" % mountdest sys.exit(2) # validatechance = int( Configuration.get('autorestorevalidatechance', 'autorestore')) validatemodulus = int( Configuration.get('autorestoremodulus', 'autorestore')) # Reinitialize logging BackupLogger.init( os.path.join( logdir, "%s-%s.log" % (datetime.now().strftime('%Y%m%dT%H%M%S'), database)), database) BackupLogger.clean() # restore = RestoreDB(database) restore.set_mount_path(mountdest) restore.set_restore_path(restoredest) # info("Logfile: %s" % BackupLogger.logfile) Configuration.substitutions.update({'logfile': BackupLogger.logfile}) cleantarget(restoredest) # success = False # if validatemodulus > 0: # Validation based on modulus validationinfo = validationdate(database) validatecorruption = validationinfo[0] if not validatecorruption: debug("Next database validation in %d days: %s" % (validationinfo[1], validationinfo[2])) else: # Validation based on random validatecorruption = (validatechance > 0) and (randint( 1, validatechance) == validatechance) if validatecorruption: debug("Database will be validated during this restore session") # Start restore try: restore.run() restore.verify() if validatecorruption: restore.blockcheck() success = True except: exitstatus = 1 exception( "Error happened, but we can continue with the next database.") finally: restore.cleanup() # Log result to catalog Configuration.substitutions.update({ 'log_dbname': database, 'log_start': restore.starttime.strftime('%Y-%m-%d %H-%M-%S'), 'log_stop': restore.endtime.strftime('%Y-%m-%d %H-%M-%S'), 'log_success': '1' if success else '0', 'log_diff': restore.verifyseconds, 'log_snapid': restore.sourcesnapid, 'log_validated': '1' if validatecorruption else '0' }) debug('Logging the result to catalog.') try: oexec.sqlldr(Configuration.get('autorestorecatalog', 'autorestore'), restoretemplate.get('sqlldrlog')) except: debug("Sending the logfile to catalog failed.") try: oexec.sqlplus(restoretemplate.get('insertlog'), silent=False) except: debug("Logging the result to catalog failed.") # Finish up info("Restore %s, elapsed time: %s" % ('successful' if success else 'failed', restore.endtime - restore.starttime)) # Run ADRCI to clean up diag adrage = int(Configuration.get('logretention', 'generic')) * 1440 f1 = mkstemp(suffix=".adi") ftmp = os.fdopen(f1[0], "w") ftmp.write("set base %s\n" % logdir) ftmp.write("show homes\n") ftmp.close() f2 = mkstemp(suffix=".adi") ftmp2 = os.fdopen(f2[0], "w") ftmp2.write("set base %s\n" % logdir) with TemporaryFile() as f: try: oexec.adrci(f1[1], f) f.seek(0, 0) output = f.read() startreading = False for line in output.splitlines(): if line.startswith('ADR Homes:'): startreading = True elif startreading: ftmp2.write("set home %s\n" % line.strip()) ftmp2.write("purge -age %d\n" % adrage) ftmp2.close() oexec.adrci(f2[1], f) except: print "Executing ADRCI failed." finally: os.unlink(f1[1]) os.unlink(f2[1]) # BackupLogger.close(True)
def runrestore(database): global exitstatus # Configuration.defaultsection = database # Reinitialize logging BackupLogger.init( os.path.join( logdir, "%s-%s.log" % (datetime.now().strftime('%Y%m%dT%H%M%S'), database)), database) BackupLogger.clean() # restore = RestoreDB(database) restore.set_mount_path(mountdest) restore.set_restore_path(restoredest) # info("Logfile: %s" % BackupLogger.logfile) Configuration.substitutions.update({'logfile': BackupLogger.logfile}) cleantarget() # success = False # if validatemodulus > 0: # Validation based on modulus validationinfo = validationdate(database) validatecorruption = validationinfo[0] if not validatecorruption: debug("Next database validation in %d days: %s" % (validationinfo[1], validationinfo[2])) else: # Validation based on random validatecorruption = (validatechance > 0) and (randint( 1, validatechance) == validatechance) if validatecorruption: debug("Database will be validated during this restore session") # Start restore try: restore.run() restore.verify() if validatecorruption: restore.blockcheck() success = True except: exitstatus = 1 exception( "Error happened, but we can continue with the next database.") finally: restore.cleanup() # Log result to catalog Configuration.substitutions.update({ 'log_dbname': database, 'log_start': restore.starttime.strftime('%Y-%m-%d %H-%M-%S'), 'log_stop': restore.endtime.strftime('%Y-%m-%d %H-%M-%S'), 'log_success': '1' if success else '0', 'log_diff': restore.verifyseconds, 'log_snapid': restore.sourcesnapid, 'log_validated': '1' if validatecorruption else '0' }) debug('Logging the result to catalog.') try: oexec.sqlldr(Configuration.get('autorestorecatalog', 'autorestore'), restoretemplate.get('sqlldrlog')) except: debug("Sending the logfile to catalog failed.") try: oexec.sqlplus(restoretemplate.get('insertlog'), silent=False) except: debug("Logging the result to catalog failed.") # Finish up info("Restore %s, elapsed time: %s" % ('successful' if success else 'failed', restore.endtime - restore.starttime)) BackupLogger.close(True)
info("Configuration file: %s" % Configuration.configfilename) lock = BackupLock(lockdir=backupdest, maxlockwait=int(Configuration.get('maxlockwait', 'generic'))) try: # User interface action execution if scriptaction == 'config': configure() elif scriptaction == 'generaterestore': generate_restore() elif scriptaction == 'imagecopywithsnap': imagecopywithsnap() elif scriptaction == 'setschedule': setschedule() elif scriptaction == 'missingarchlog': backup_missing_archlog() else: exec_template(scriptaction) finally: lock.release() if (os.getenv('BACKUP_LOG_TO_SCREEN')) and ( os.environ['BACKUP_LOG_TO_SCREEN'] == 'TRUE'): BackupLogger.close(True) print "\n\n======================\nBACKUP LOG FILE OUTPUT\n======================\n\n" if os.path.isfile(logfile): with open(logfile, 'r') as tmplogf: print tmplogf.read() else: print "Log file not found"