Viewing file: Backup.py (8.37 KB) -rw-r--r-- Select action/file-type: (+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
######################################################################## # $Header: /var/local/cvsroot/4Suite/Ft/Server/Server/Commands/Backup.py,v 1.3 2004/10/07 16:18:44 uogbuji Exp $ """ 4Suite repository backup command (4ss_manager backup)
Copyright 2004 Fourthought, Inc. (USA). Detailed license and copyright information: http://4suite.org/COPYRIGHT Project home, documentation, distributions: http://4suite.org/ """
__doc__ = """\ Create a low level system backup of the entire repository """
import os, sys from Ft.Server.Server.Commands.CommandUtil import GetRepository from Ft.Server.Common import Schema, ResourceTypes from Ft.Lib import Time, Uri from Ft.Server import __version__,FTSERVER_NAMESPACE import Ft.Rdf.Util from distutils import archive_util, dir_util
def Run(options, args):
username, password, properties, repo = \ GetRepository(options, '4ss_manager.backup')
basePaths = args.get('base-path') if not basePaths: basePaths = ['/']
excludes = options.get('exclude',[]) if type(excludes) != type([]): excludes = [excludes]
baseDirectory = options.get('directory','.')
lmd = options.get('modified-since') if lmd: lmd = str(Time.FromISO8601(lmd))
quiet = options.get('quiet',0)
if not os.path.exists(baseDirectory): raise Exception("Directory %s must exit" % baseDirectory)
baseDirectory = os.path.join(baseDirectory,"ftss-backup") if not os.path.exists(baseDirectory): os.mkdir(baseDirectory)
contentDirBase = os.path.join(baseDirectory,'content') if not os.path.exists(contentDirBase): os.mkdir(contentDirBase) else: sys.stderr.write("Directory: %s already exists, could be conflicts\n" % contentDirBase)
metadataDirBase = os.path.join(baseDirectory,'metadata') if not os.path.exists(metadataDirBase): os.mkdir(metadataDirBase) else: sys.stderr.write("Directory: %s already exists, could be conflicts\n" % metadataDirBase)
cacheDirBase = os.path.join(baseDirectory,'cache') if not os.path.exists(cacheDirBase): os.mkdir(cacheDirBase) else: sys.stderr.write("Directory: %s already exists, could be conflicts\n" % cacheDirBase)
backupDate = Time.FromPythonTime() logFile = open(os.path.join(baseDirectory,"backup.log"),"w") print "Backup log created at: %s" % os.path.join(baseDirectory,"backup.log") logFile.write("<ftss:Backup xmlns:ftss='%s' date='%s' version='%s'>\n" % (FTSERVER_NAMESPACE, str(backupDate), __version__)) stored = {} madeit = 0 try: for stmt in repo.getModel().complete(None,Schema.TYPE,None): if stored.has_key(stmt.subject): #Already stored continue for basePath in basePaths: if stmt.subject[:len(basePath)] != basePath: if not quiet: print "Skipping %s, not in basePath %s" % (stmt.subject,basePath) continue
excluded = 0 for exclude in excludes: if stmt.subject[:len(exclude)] == exclude: if not quiet: print "Skipping %s, excluded by %s" % (stmt.subject,exclude) excluded = 1 break if excluded: continue #Get the resource at this point, we will check LMD on the actual resource if not repo.hasResource(stmt.subject): print "Corrupt RDF entry for: " + stmt.subject continue resource = repo.fetchResource(stmt.subject) if lmd and resource.getLastModifiedDate() < lmd: if not quiet: print "Skipping %s, LMD of %s is before %s" % (stmt.subject,resource.getLastModifiedDate(),lmd) continue
#This looks like one to backup stored[stmt.subject] = 1 print stmt.subject refID = Uri.BASIC_RESOLVER.generate()[9:] logFile.write(" <ftss:Entry path='%s' ref-id='%s' " % (stmt.subject,refID)) for (_type,base) in [(ResourceTypes.RESOURCE_CONTENT,contentDirBase), (ResourceTypes.RESOURCE_METADATA,metadataDirBase), (ResourceTypes.RESOURCE_CACHE,cacheDirBase), ]: driver = repo._driver._driver if driver.hasFile(stmt.subject,_type): data = driver.fetchFile(stmt.subject,_type) f = open(os.path.join(base,refID),'wb') f.write(data) f.close() logFile.write(" data%d='yes'" % _type) else: logFile.write(" data%d='no'" % _type) logFile.write("/>\n")
#Now dump the system model print "Serializing System RDF Model" stmts = [] serialized = stored.keys() for stmt in repo._driver._driver.getSystemModel().complete(None,None,None): if stmt.subject in serialized or stmt.scope in serialized: stmts.append(stmt)
f = open(os.path.join(baseDirectory,"system.rdf"),"wb") f.write(Ft.Rdf.Util.SerializeStatementList(stmts)) f.close() logFile.write(" <ftss:SystemModel path='system.rdf'/>\n")
if options.get('user-model'): print "Serializing User RDF Model" f = open(os.path.join(baseDirectory,"user.rdf"),"wb") f.write(Ft.Rdf.Util.SerializeModel(repo._driver._driver.getUserModel())) f.close() logFile.write(" <ftss:UserModel path='user.rdf'/>\n") madeit = 1 finally: logFile.write("</ftss:Backup>\n") logFile.close() repo.txRollback() if madeit and options.get('archive'): #Archive it!! base_name = 'ftss-backup-%s' % backupDate.asISO8601Date()
print "Creating %s archive..." % options['archive'] fName = archive_util.make_archive (base_name, options['archive'], root_dir=options.get('directory','.'), base_dir=baseDirectory, verbose=0, dry_run=0)
print "Created: %s" % fName dir_util.remove_tree(baseDirectory)
def Register(): from Ft.Lib.CommandLine import Command, Options, Arguments options = [Options.Option('e', 'exclude=', 'Exclude a path (and all children) from backup (multiple allowed)'), Options.Option('d', 'directory=', 'Directory to backup too.'), Options.Option('m', 'modified-since=', 'Only backup files modified since specified ISO datetime'), Options.Option('q', 'quiet', 'No extra output'), Options.Option(None, 'user-model', 'Also dump the user model'), Options.TypedOption(None, 'archive=', "Create an archive (not all options will work on all platforms!!)", map(lambda x: (x[0],x[1][-1]),archive_util.ARCHIVE_FORMATS.items()), ), ]
cmd = Command.Command('backup', "Create a low level backup of the entire system.", '', __doc__, function=Run, fileName=__file__, options=Options.Options(options), arguments = [Arguments.ZeroOrMoreArgument('base-path', 'Initial resources to start the backup at.', str), ],
) return cmd
|