[CalendarServer-changes] [732] CalendarServer/branches/backup

source_changes at macosforge.org source_changes at macosforge.org
Wed Dec 6 13:43:22 PST 2006


Revision: 732
          http://trac.macosforge.org/projects/calendarserver/changeset/732
Author:   dreid at apple.com
Date:     2006-12-06 13:43:22 -0800 (Wed, 06 Dec 2006)

Log Message:
-----------
backup stuff

Modified Paths:
--------------
    CalendarServer/branches/backup/setup.py

Added Paths:
-----------
    CalendarServer/branches/backup/bin/calendar_restore
    CalendarServer/branches/backup/conf/85-calendar.plist
    CalendarServer/branches/backup/twistedcaldav/backup.py

Added: CalendarServer/branches/backup/bin/calendar_restore
===================================================================
--- CalendarServer/branches/backup/bin/calendar_restore	                        (rev 0)
+++ CalendarServer/branches/backup/bin/calendar_restore	2006-12-06 21:43:22 UTC (rev 732)
@@ -0,0 +1,173 @@
+#!/usr/bin/env python
+##
+# Copyright (c) 2005-2006 Apple Computer, Inc. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# DRI: David Reid, dreid at apple.com
+##
+
+import os
+import sys
+import shutil
+import fnmatch
+import plistlib
+import tempfile
+import commands
+
+from twistedcaldav.backup import *
+
+SERVICE = "calendar"
+
+ServiceConf = "85-calendar.plist"
+
+etcPath = "/private/etc/caldavd"
+configFile = "caldavd.plist"
+
+removePatterns = ['.db.sqlite']
+
+ at logFuncCall
+def restore_data(src, tmp, dst):
+    debug('restoring data')
+
+    docRoot = readConfig('/'.join((src,
+                                   etcPath,
+                                   configFile)))['DocumentRoot']
+
+    srcDoc = '/'.join((src, docRoot))
+    tmpDoc = '/'.join((tmp, docRoot))
+    dstDoc = '/'.join((dst, docRoot))
+
+    mkroot(tmpDoc)
+
+    copy(srcDoc, tmpDoc)
+
+    purge(tmpDoc, removePatterns)
+
+    wasRunning = isRunning(SERVICE)
+
+    if wasRunning:
+        serveradmin('stop', SERVICE)
+
+    bakDoc = dstDoc.rstrip('/') + '.bak'
+
+    move(dstDoc, bakDoc)
+
+    try:
+        move(tmpDoc, dstDoc)
+
+    except OSError:
+        move(bakDoc, dstDoc)
+
+    else:
+        remove(bakDoc)
+
+    if wasRunning:
+        serveradmin('start', SERVICE)
+
+    debug('restoring data done')
+
+
+ at logFuncCall
+def restore_configuration(src, tmp, dst):
+    debug('restoring configuration')
+
+    srcEtc = '/'.join((src, etcPath))
+    tmpEtc = '/'.join((tmp, etcPath))
+    dstEtc = '/'.join((dst, etcPath))
+
+    mkroot(tmpEtc)
+
+    copy(srcEtc, tmpEtc)
+
+    debug('restoring configuration done')
+
+
+ at logFuncCall
+def cmd_restore(options):
+    imgPath = options['imgPath']
+    target = options['target']
+    log = options['log']
+    opt = options['opt']
+
+    if opt not in ['all', 'data', 'configuration']:
+        print "Unknown -opt value %s" % (opt,)
+        sys.exit(1)
+
+    sourceRoot = '/'.join(imgPath.split('/')[:-2])
+    tmpRoot = tempfile.mktemp(prefix='calendar_restore-')
+    dstRoot = target
+
+    if opt in ['all', 'configuration']:
+        restore_configuration(sourceRoot, tmpRoot, dstRoot)
+
+    if opt in ['all', 'data']:
+        restore_data(sourceRoot, tmpRoot, dstRoot)
+
+
+ at logFuncCall
+def cmd_browse(options):
+    pass
+
+
+ at logFuncCall
+def cmd_actions(options):
+    pl = plistlib.readPlist(os.path.join(SBSCONF, ServiceConf))
+    for k,v in pl['RestoreActions'].iteritems():
+        print "%s: %s" % (k,v)
+
+
+ at logFuncCall
+def cmd_help(options):
+    print "Usage:"
+    print " -cmd actions :"
+    print "    Print out the supported actions from the config file"
+    print " -cmd browse -imgPath path :"
+    print "    Show browse information for the given path"
+    print " -cmd restore -imgPath path -opt option -target target"
+    print ("    Restore the files specified by option from the given path to "
+           "the target")
+    print " -cmd help : Display usage"
+    print " -cmd version : Display version"
+
+
+ at logFuncCall
+def cmd_version(options):
+    pl = plistlib.readConfig(os.path.join(SBSCONF, ServiceConf))
+    print pl['Version']
+
+
+if __name__ == '__main__':
+    debug("calendar_restore was called")
+
+    options = Options({'cmd': None,
+                       'target': None,
+                       'imgPath': None,
+                       'log': None,
+                       'opt': 'all'})
+
+    options.parseOpts(sys.argv[1:])
+
+    debug("parsing options: %s" % (options,))
+    
+    cmd = globals().get('cmd_%s' % (options['cmd'],), None)
+
+    debug("found command: %s" % (cmd,))
+
+    if not cmd:
+        print "Unknown Command: %s" % (options['cmd'],)
+        sys.exit(1)
+
+    cmd(options)
+
+    debug("calendar_restore done")


Property changes on: CalendarServer/branches/backup/bin/calendar_restore
___________________________________________________________________
Name: svn:executable
   + *

Added: CalendarServer/branches/backup/conf/85-calendar.plist
===================================================================
--- CalendarServer/branches/backup/conf/85-calendar.plist	                        (rev 0)
+++ CalendarServer/branches/backup/conf/85-calendar.plist	2006-12-06 21:43:22 UTC (rev 732)
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+    <key>ServiceName</key>
+    <string>calendar</string>
+    
+    <key>RestoreBinaryPath</key>
+	<string>/usr/libexec/sbs_backup/calendar_restore</string>
+	<key>RestoreLog</key>
+	<string>/private/var/log/sbs_backup/calendar_restore.log</string>
+	<key>RestoreActions</key>
+	<dict>
+		<key>Configuration</key>
+		<string>configuration</string>
+		<key>Data</key>
+		<string>data</string>
+		<key>Default</key>
+		<string>all</string>
+		<key>Browse</key>
+		<string>browse</string>
+	</dict>
+
+	<key>VerifyBinaryPath</key>
+	<string>/usr/libexec/sbs_backup/sharePoints_verify</string>
+	<key>VerifyLog</key>
+	<string>/private/var/log/sbs_backup/sharePoints_verify.log</string>
+	<key>VerifyActions</key>
+	<dict>
+		<key>Configuration</key>
+		<string>configuration</string>
+		<key>Data</key>
+		<string>data</string>
+		<key>Default</key>
+		<string>all</string>
+	</dict>
+
+    <key>Version</key>
+    <string>10.5</string>
+</dict>
+</plist>

Modified: CalendarServer/branches/backup/setup.py
===================================================================
--- CalendarServer/branches/backup/setup.py	2006-12-06 21:41:12 UTC (rev 731)
+++ CalendarServer/branches/backup/setup.py	2006-12-06 21:43:22 UTC (rev 732)
@@ -73,6 +73,14 @@
 
 from distutils.core import setup
 
+data_files = ["caldavd", ["conf/repository.xml", "conf/caldavd.plist"]]
+
+if sys.platform == 'darwin':
+    data_files.append(['/etc/sbs_backup/', ['conf/85-calendar.plist']])
+    data_files.append(['/usr/libexec/sbs_backup', ['bin/calendar_restore']])
+
+print data_files
+
 setup(
     name             = "twistedcaldav",
     version          = version,
@@ -86,5 +94,5 @@
     platforms        = [ "all" ],
     packages         = [ "twistedcaldav", "twistedcaldav.directory", "twistedcaldav.method", "twistedcaldav.query" ],
     scripts          = [ "bin/caldavd" ],
-    data_files       = [("caldavd", ["conf/repository.xml", "conf/caldavd.plist"]),],
+    data_files       = [data_files]
 )

Added: CalendarServer/branches/backup/twistedcaldav/backup.py
===================================================================
--- CalendarServer/branches/backup/twistedcaldav/backup.py	                        (rev 0)
+++ CalendarServer/branches/backup/twistedcaldav/backup.py	2006-12-06 21:43:22 UTC (rev 732)
@@ -0,0 +1,180 @@
+##
+# Copyright (c) 2005-2006 Apple Computer, Inc. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# DRI: David Reid, dreid at apple.com
+##
+
+"""
+Utility code for backup and restore
+"""
+
+import os
+import shutil
+import fnmatch
+import plistlib
+import tempfile
+import commands
+
+VERBOSE = os.environ.get('VERBOSE', False)
+FUNCLOG = os.environ.get('FUNCLOG', False)
+
+SERVERADMIN = "/usr/sbin/serveradmin"
+
+SBSCONF = "/private/etc/sbs_backup"
+
+class Options(dict):
+    def parseOpts(self, argv):
+        for x in xrange(0, len(argv)):
+            opt = argv[x]
+            if opt.startswith('-'):
+                self[opt.strip('-')] = argv[x+1]
+
+
+def debug(string):
+    if VERBOSE:
+        print "DEBUG:", string
+
+
+def funclog(string):
+    if FUNCLOG:
+        print "FUNCLOG:", string
+
+
+def logFuncCall(func):
+    def printArgs(args):
+        a = []
+        for arg in args:
+            a.append(repr(arg))
+            a.append(', ')
+
+        return ''.join(a).strip(', ')
+
+    def printKwargs(kwargs):
+        a = []
+        for kwarg, value in kwargs:
+            a.append('%s=%r, ' % (kwarg, value))
+
+        return ''.join(a).strip(', ')
+
+    def _(*args, **kwargs):
+        funclog("%s(%s)" % (func.func_name, 
+                            ', '.join((printArgs(args),
+                                       printKwargs(kwargs))).strip(', ')))
+
+        retval = func(*args, **kwargs)
+
+        funclog("%s - > %s" % (func.func_name, retval))
+
+        return retval
+    
+    return _
+
+
+ at logFuncCall
+def readConfig(configFile):
+    config = plistlib.readPlist(configFile + '.default')
+
+    if os.path.exists(configFile):
+        config.update(plistlib.readPlist(configFile))
+
+    return config
+        
+
+ at logFuncCall
+def mkroot(path):
+    root = '/'.join(path.rstrip('/').split('/')[:-1])
+    os.makedirs(root)
+
+
+ at logFuncCall
+def serveradmin(action, service):
+    cmd = ' '.join((
+            SERVERADMIN,
+            action,
+            service))
+
+    status, output = commands.getstatusoutput(cmd)
+
+    for line in output.split('\n'):
+        debug("C: %s" % (line,))
+
+    return status
+
+
+ at logFuncCall
+def isRunning(service):
+    cmd = ' '.join((
+            SERVERADMIN,
+            'status',
+            service))
+
+    debug(cmd)
+
+    output = commands.getoutput(cmd)
+
+    for line in output.split('\n'):
+        debug("C: %s" % (line,))
+
+    status = output.split('=')[-1].strip(' "\n')
+
+    if status == "RUNNING":
+        return True
+    else:
+        return False
+
+
+ at logFuncCall
+def copy(src, dst):
+    shutil.copytree(src, dst)
+
+
+ at logFuncCall
+def move(src, dst):
+    os.rename(src, dst)
+
+
+ at logFuncCall
+def remove(dst):
+    shutil.rmtree(dst)
+
+
+ at logFuncCall
+def purge(root, patterns):
+    removed = []
+
+    for root, dirs, files in os.walk(root):
+        debug("purging in %s" % (root,))
+
+        for file in files:
+            for pat in patterns:
+                if fnmatch.fnmatch(file, pat):
+                    full = os.path.join(root, file)
+                    debug("removing %s because of %s" % (full, pat))
+
+                    os.remove(full)
+
+                    removed.append(full)
+
+        for dir in dirs:
+            for pat in patterns:
+                if fnmatch.fnmatch(dir, pat):
+                    full = os.path.join(root, dir)
+                    debug("removing %s because of %s" % (full, pat))
+
+                    os.remove(full)
+
+                    removed.append(full)
+                    
+    return removed

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20061206/55ddd6b3/attachment.html


More information about the calendarserver-changes mailing list