[CalendarServer-changes] [6436] CalendarServer/trunk
source_changes at macosforge.org
source_changes at macosforge.org
Mon Oct 18 09:34:39 PDT 2010
Revision: 6436
http://trac.macosforge.org/projects/calendarserver/changeset/6436
Author: sagen at apple.com
Date: 2010-10-18 09:34:37 -0700 (Mon, 18 Oct 2010)
Log Message:
-----------
To make the migrator module testable, renaming without the 59_ (which will be added back at build time)
Modified Paths:
--------------
CalendarServer/trunk/support/Makefile.Apple
Added Paths:
-----------
CalendarServer/trunk/contrib/__init__.py
CalendarServer/trunk/contrib/migration/__init__.py
CalendarServer/trunk/contrib/migration/calendarmigrator.py
Removed Paths:
-------------
CalendarServer/trunk/contrib/migration/59_calendarmigrator.py
Added: CalendarServer/trunk/contrib/__init__.py
===================================================================
--- CalendarServer/trunk/contrib/__init__.py (rev 0)
+++ CalendarServer/trunk/contrib/__init__.py 2010-10-18 16:34:37 UTC (rev 6436)
@@ -0,0 +1,15 @@
+##
+# Copyright (c) 2010 Apple 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.
+##
Deleted: CalendarServer/trunk/contrib/migration/59_calendarmigrator.py
===================================================================
--- CalendarServer/trunk/contrib/migration/59_calendarmigrator.py 2010-10-18 16:32:53 UTC (rev 6435)
+++ CalendarServer/trunk/contrib/migration/59_calendarmigrator.py 2010-10-18 16:34:37 UTC (rev 6436)
@@ -1,654 +0,0 @@
-#!/usr/bin/env python
-#
-# MigrationExtra script to maintain the enabled/disabled state of the
-# calendar server.
-#
-# This script examines the launchd preferences from the previous system
-# (also taking into account the overrides.plist) and then invokes serveradmin
-# to start/stop calendar server.
-#
-# The only argument this script currently cares about is --sourceRoot, which
-# should point to the root of the previous system.
-#
-# Copyright (c) 2005-2010 Apple Inc. All Rights Reserved.
-#
-# IMPORTANT NOTE: This file is licensed only for use on Apple-labeled
-# computers and is subject to the terms and conditions of the Apple
-# Software License Agreement accompanying the package this file is a
-# part of. You may not port this file to another platform without
-# Apple's written consent.
-
-from __future__ import with_statement
-
-import datetime
-import grp
-import optparse
-import os
-import pwd
-import shutil
-import sys
-
-from plistlib import readPlist, writePlist
-
-LAUNCHD_KEY = "org.calendarserver.calendarserver"
-LOG = "/Library/Logs/Migration/calendarmigrator.log"
-SERVICE_NAME = "calendar"
-LAUNCHD_OVERRIDES = "var/db/launchd.db/com.apple.launchd/overrides.plist"
-LAUNCHD_PREFS_DIR = "System/Library/LaunchDaemons"
-CALDAVD_CONFIG_DIR = "private/etc/caldavd"
-CARDDAVD_CONFIG_DIR = "private/etc/carddavd"
-CALDAVD_PLIST = "caldavd.plist"
-CARDDAVD_PLIST = "carddavd.plist"
-NEW_SERVER_ROOT = "/Library/Server/Calendar and Contacts"
-
-
-verbatimKeys = """
-AccountingCategories
-AccountingPrincipals
-AdminPrincipals
-Aliases
-AnonymousDirectoryAddressBookAccess
-AugmentService
-BindAddresses
-ConfigRoot
-ControlPort
-DatabaseRoot
-DefaultLogLevel
-DirectoryAddressBook
-DirectoryService
-EnableAddMember
-EnableAnonymousReadNav
-EnableCalDAV
-EnableCardDAV
-EnableDropBox
-EnableExtendedAccessLog
-EnableKeepAlive
-EnableMonolithicCalendars
-EnablePrincipalListings
-EnablePrivateEvents
-EnableProxyPrincipals
-EnableSACLs
-EnableSSL
-EnableSearchAddressBook
-EnableSyncReport
-EnableTimezoneService
-EnableWebAdmin
-EnableWellKnown
-ErrorLogEnabled
-ErrorLogMaxRotatedFiles
-ErrorLogRotateMB
-FreeBusyURL
-GlobalAddressBook
-GlobalStatsLoggingFrequency
-GlobalStatsLoggingPeriod
-GlobalStatsSocket
-GroupName
-HTTPPort
-HTTPRetryAfter
-IdleConnectionTimeOut
-Includes
-ListenBacklog
-Localization
-LogLevels
-LogRoot
-MaxAccepts
-MaxAttendeesPerInstance
-MaxInstancesForRRULE
-MaxMultigetWithDataHREFs
-MaxQueryWithDataResults
-MaxRequests
-MaximumAttachmentSize
-Memcached
-MultiProcess
-Notifications
-Partitioning
-Postgres
-ProcessType
-Profiling
-ProxyDBService
-ProxyLoadFromFile
-ReadPrincipals
-RedirectHTTPToHTTPS
-RejectClients
-ResourceService
-ResponseCompression
-RotateAccessLog
-RunRoot
-SSLAuthorityChain
-SSLCertAdmin
-SSLCertificate
-SSLCiphers
-SSLMethod
-SSLPrivateKey
-Scheduling
-ServerHostName
-ServerRoot
-Sharing
-SudoersFile
-Twisted
-UIDReservationTimeOut
-UseDatabase
-UseMetaFD
-UserName
-UserQuota
-WebCalendarRoot
-umask
-""".split()
-
-# These are going to require some processing
-specialKeys = """
-AccessLogFile
-AccountingLogRoot
-Authentication
-BindHTTPPorts
-BindSSLPorts
-DataRoot
-DocumentRoot
-ErrorLogFile
-MaxAddressBookMultigetHrefs
-MaxAddressBookQueryResults
-""".split()
-
-ignoredKkeys = """
-ControlSocket
-EnableAnonymousReadRoot
-EnableFindSharedReport
-EnableNotifications
-PIDFile
-PythonDirector
-ResponseCacheTimeout
-SSLPassPhraseDialog
-SSLPort
-ServerStatsFile
-Verbose
-""".split()
-
-
-def main():
-
- optionParser = optparse.OptionParser()
-
- optionParser.add_option('--purge', choices=('0', '1'),
- metavar='[0|1]',
- help='remove old files after migration (IGNORED)')
-
- optionParser.add_option('--sourceRoot', type='string',
- metavar='DIR',
- help='path to the root of the system to migrate')
-
- optionParser.add_option('--sourceType', type='string',
- metavar='[System|TimeMachine]',
- help='migration source type (IGNORED)')
-
- optionParser.add_option('--sourceVersion', type='string',
- metavar='10.X.X',
- help='version number of previous system (IGNORED)')
-
- optionParser.add_option('--targetRoot', type='string',
- metavar='DIR',
- help='path to the root of the new system',
- default='/')
-
- optionParser.add_option('--language', choices=('en', 'fr', 'de', 'ja'),
- metavar='[en|fr|de|ja]',
- help='language identifier (IGNORED)')
-
- (options, args) = optionParser.parse_args()
- log("Options: %s" % (options,))
-
- if options.sourceRoot:
-
- if os.path.exists(options.sourceRoot):
- newServerRootValue = migrateData(options)
- migrateConfiguration(options, newServerRootValue)
- migrateRunState(options)
-
- else:
- log("ERROR: --sourceRoot must be specified")
- sys.exit(1)
-
-
-def migrateRunState(options):
- """
- Try to determine whether server was running in previous system, then
- modify the launchd settings in the new system.
- """
-
- try:
- disabled = isServiceDisabled(options.sourceRoot, LAUNCHD_KEY)
- log("Service '%s' was previously %s" %
- (LAUNCHD_KEY, "disabled" if disabled else "enabled"))
- except ServiceStateError, e:
- log("Couldn't determine previous state of service '%s': %s" %
- (LAUNCHD_KEY, e))
- return
-
- setServiceStateDisabled(options.targetRoot, LAUNCHD_KEY, disabled)
-
-
-def migrateConfiguration(options, newServerRootValue):
- """
- Copy files/directories/symlinks from previous system's /etc/caldavd
- and /etc/carddavd
-
- Skips anything ending in ".default".
- Regular files overwrite copies in new system.
- Directories and symlinks only copied over if they don't overwrite anything.
- """
-
- newConfigDir = os.path.join(options.targetRoot, CALDAVD_CONFIG_DIR)
- if not os.path.exists(newConfigDir):
- log("New configuration directory does not exist: %s" % (newConfigDir,))
- return
-
-
- for configDir in (CALDAVD_CONFIG_DIR, CARDDAVD_CONFIG_DIR):
-
- oldConfigDir = os.path.join(options.sourceRoot, configDir)
- if not os.path.exists(oldConfigDir):
- log("Old configuration directory does not exist: %s" % (oldConfigDir,))
- continue
-
-
- log("Copying configuration files from %s to %s" % (oldConfigDir, newConfigDir))
-
- for name in os.listdir(oldConfigDir):
-
- if not (name.endswith(".default") or name in (CALDAVD_PLIST, CARDDAVD_PLIST)):
-
- oldPath = os.path.join(oldConfigDir, name)
- newPath = os.path.join(newConfigDir, name)
-
- if os.path.islink(oldPath) and not os.path.exists(newPath):
- # Recreate the symlink if it won't overwrite an existing file
- link = os.readlink(oldPath)
- log("Symlinking %s to %s" % (newPath, link))
- os.symlink(link, newPath)
-
- elif os.path.isfile(oldPath):
- # Copy the file over, overwriting copy in newConfigDir
- log("Copying file %s to %s" % (oldPath, newConfigDir))
- shutil.copy2(oldPath, newConfigDir)
-
- elif os.path.isdir(oldPath) and not os.path.exists(newPath):
- # Copy the dir over, but only if new one doesn't exist
- log("Copying directory %s to %s" % (oldPath, newPath))
- shutil.copytree(oldPath, newPath, symlinks=True)
-
-
- # Migrate certain settings from the old plists to new:
-
- oldCalDAVPlistPath = os.path.join(options.sourceRoot, CALDAVD_CONFIG_DIR,
- CALDAVD_PLIST)
- if os.path.exists(oldCalDAVPlistPath):
- oldCalDAVDPlist = readPlist(oldCalDAVPlistPath)
- else:
- oldCalDAVDPlist = { }
-
- oldCardDAVDPlistPath = os.path.join(options.sourceRoot, CARDDAVD_CONFIG_DIR,
- CARDDAVD_PLIST)
- if os.path.exists(oldCardDAVDPlistPath):
- oldCardDAVDPlist = readPlist(oldCardDAVDPlistPath)
- else:
- oldCardDAVDPlist = { }
-
- newCalDAVDPlistPath = os.path.join(options.targetRoot, CALDAVD_CONFIG_DIR,
- CALDAVD_PLIST)
- if os.path.exists(newCalDAVDPlistPath):
- newCalDAVDPlist = readPlist(newCalDAVDPlistPath)
- else:
- newCalDAVDPlist = { }
-
- log("Processing %s and %s" % (oldCalDAVPlistPath, oldCardDAVDPlistPath))
- mergePlist(oldCalDAVDPlist, oldCardDAVDPlist, newCalDAVDPlist)
-
- newCalDAVDPlist["ServerRoot"] = newServerRootValue
- newCalDAVDPlist["DocumentRoot"] = "Documents"
- newCalDAVDPlist["DataRoot"] = "Data"
-
- log("Writing %s" % (newCalDAVDPlistPath,))
- writePlist(newCalDAVDPlist, newCalDAVDPlistPath)
-
-
-def mergePlist(oldCalDAVDPlist, oldCardDAVDPlist, newCalDAVDPlist):
-
- # These keys are copied verbatim:
- for key in verbatimKeys:
- if key in oldCardDAVDPlist:
- newCalDAVDPlist[key] = oldCardDAVDPlist[key]
- if key in oldCalDAVDPlist:
- newCalDAVDPlist[key] = oldCalDAVDPlist[key]
-
- # "Wiki" is a new authentication in v2.x; copy all "Authentication" sub-keys # over, and "Wiki" will be picked up from the new plist:
- if "Authentication" in oldCalDAVDPlist:
- for key in oldCalDAVDPlist["Authentication"]:
- newCalDAVDPlist["Authentication"][key] = oldCalDAVDPlist["Authentication"][key]
-
- # Strip out any unknown params from the DirectoryService:
- if "DirectoryService" in oldCalDAVDPlist:
- newCalDAVDPlist["DirectoryService"] = oldCalDAVDPlist["DirectoryService"]
- for key in newCalDAVDPlist["DirectoryService"]["params"].keys():
- if key not in ("node", "cacheTimeout", "xmlFile"):
- del newCalDAVDPlist["DirectoryService"]["params"][key]
-
-
-
-def isServiceDisabled(source, service):
- """
- Returns whether or not a service is disabled
-
- @param source: System root to examine
- @param service: launchd key representing service
- @return: True if service is disabled, False if enabled
- """
-
- overridesPath = os.path.join(source, LAUNCHD_OVERRIDES)
- if os.path.isfile(overridesPath):
- overrides = readPlist(overridesPath)
- try:
- return overrides[service]['Disabled']
- except KeyError:
- # Key is not in the overrides.plist, continue on
- pass
-
- prefsPath = os.path.join(source, LAUNCHD_PREFS_DIR, "%s.plist" % service)
- if os.path.isfile(prefsPath):
- prefs = readPlist(prefsPath)
- try:
- return prefs['Disabled']
- except KeyError:
- return False
-
- raise ServiceStateError("Neither %s nor %s exist" %
- (overridesPath, prefsPath))
-
-
-def setServiceStateDisabled(target, service, disabled):
- """
- Modifies launchd settings for a service
-
- @param target: System root
- @param service: launchd key representing service
- @param disabled: boolean
- """
-
- overridesPath = os.path.join(target, LAUNCHD_OVERRIDES)
- if os.path.isfile(overridesPath):
- overrides = readPlist(overridesPath)
- if not overrides.has_key(service):
- overrides[service] = { }
- overrides[service]['Disabled'] = disabled
- writePlist(overrides, overridesPath)
-
-
-class ServiceStateError(Exception):
- """
- Could not determine service state
- """
-
-
-def log(msg):
- try:
- with open(LOG, 'a') as output:
- timestamp = datetime.datetime.now().strftime("%b %d %H:%M:%S")
- output.write("%s %s\n" % (timestamp, msg))
- except IOError:
- # Could not write to log
- pass
-
-def migrateData(options):
- """
- Examines the old caldavd.plist and carddavd.plist to see where data
- lives in the previous system. If there is old data, calls relocateData( )
- """
-
- oldCalDocuments = None
- oldCalData = None
- oldABDocuments = None
- calendarDataInDefaultLocation = True
- addressbookDataInDefaultLocation = True
- uid = -1
- gid = -1
- newServerRoot = None
-
- oldCalConfigDir = os.path.join(options.sourceRoot, CALDAVD_CONFIG_DIR)
- oldCalPlistPath = os.path.join(oldCalConfigDir, CALDAVD_PLIST)
- if os.path.exists(oldCalPlistPath):
- oldCalPlist = readPlist(oldCalPlistPath)
- uid, gid = getServerIDs(oldCalPlist)
- log("ServerIDs: %d, %d" % (uid, gid))
- else:
- log("Can't find previous calendar plist at %s" % (oldCalPlistPath,))
- oldCalPlist = None
- newCalConfigDir = os.path.join(options.targetRoot, CALDAVD_CONFIG_DIR)
- newCalPlistPath = os.path.join(newCalConfigDir, CALDAVD_PLIST)
- if os.path.exists(newCalPlistPath):
- newCalPlist = readPlist(newCalPlistPath)
- uid, gid = getServerIDs(newCalPlist)
- log("ServerIDs: %d, %d" % (uid, gid))
-
-
- oldABConfigDir = os.path.join(options.sourceRoot, CARDDAVD_CONFIG_DIR)
- oldABPlistPath = os.path.join(oldABConfigDir, CARDDAVD_PLIST)
- if os.path.exists(oldABPlistPath):
- oldABPlist = readPlist(oldABPlistPath)
- else:
- log("Can't find previous addressbook plist at %s" % (oldABPlistPath,))
- oldABPlist = None
-
- if oldCalPlist is not None:
- # See if there is actually any calendar data
-
- oldDocumentRoot = oldCalPlist["DocumentRoot"]
- if oldDocumentRoot.rstrip("/") != "/Library/CalendarServer/Documents":
- log("Calendar data in non-standard location: %s" % (oldDocumentRoot,))
- calendarDataInDefaultLocation = False
- else:
- log("Calendar data in standard location: %s" % (oldDocumentRoot,))
-
- oldDataRoot = oldCalPlist["DataRoot"]
-
- oldCalendarsPath = os.path.join(oldDocumentRoot, "calendars")
- if os.path.exists(oldCalendarsPath):
- # There is calendar data
- oldCalDocuments = oldDocumentRoot
- oldCalData = oldDataRoot
- log("Calendar data to migrate from %s and %s" %
- (oldCalDocuments, oldCalData))
-
- if calendarDataInDefaultLocation:
- newServerRoot = absolutePathWithRoot(options.targetRoot,
- NEW_SERVER_ROOT)
- newServerRootValue = NEW_SERVER_ROOT
- else:
- newServerRoot = absolutePathWithRoot(options.targetRoot,
- oldDocumentRoot)
- newServerRootValue = oldDocumentRoot
- else:
- log("No calendar data to migrate")
-
- if oldABPlist is not None:
- # See if there is actually any addressbook data
-
- oldDocumentRoot = oldABPlist["DocumentRoot"]
- if oldDocumentRoot.rstrip("/") != "/Library/AddressBookServer/Documents":
- log("AddressBook data in non-standard location: %s" % (oldDocumentRoot,))
- addressbookDataInDefaultLocation = False
- else:
- log("AddressBook data in standard location: %s" % (oldDocumentRoot,))
-
- oldAddressbooksPath = os.path.join(oldDocumentRoot, "addressbooks")
- if os.path.exists(oldAddressbooksPath):
- # There is addressbook data
- oldABDocuments = oldDocumentRoot
- log("AddressBook data to migrate from %s" % (oldABDocuments,))
-
- if newServerRoot is None:
- # don't override server root computed from calendar
- if addressbookDataInDefaultLocation:
- newServerRoot = absolutePathWithRoot(options.targetRoot,
- NEW_SERVER_ROOT)
- newServerRootValue = NEW_SERVER_ROOT
- else:
- newServerRoot = absolutePathWithRoot(options.targetRoot,
- oldDocumentRoot)
- newServerRootValue = oldDocumentRoot
- else:
- log("No addressbook data to migrate")
-
- if (oldCalDocuments or oldABDocuments) and newServerRoot:
- relocateData(oldCalDocuments, oldCalData, oldABDocuments, uid, gid,
- calendarDataInDefaultLocation, addressbookDataInDefaultLocation,
- newServerRoot)
-
- return newServerRootValue
-
-def relocateData(oldCalDocuments, oldCalData, oldABDocuments, uid, gid,
- calendarDataInDefaultLocation, addressbookDataInDefaultLocation,
- newServerRoot):
- """
- Relocates existing calendar data to the new default location iff the data
- was previously in the old default location; otherwise the old calendar
- DocumentRoot becomes the new ServerRoot directory, the contents of the
- old DocumentRoot are moved into ServerRoot/Documents and the contents of
- old DataRoot are copied/moved into ServerRoot/Data. If there is addressbook
- data, a symlink is created as ServerRoot/Documents/addressbooks pointing
- to the old addressbook directory so that the import-to-PostgreSQL will
- find it.
- """
-
- log("RelocateData: cal documents=%s, cal data=%s, ab documents=%s, new server root=%s"
- % (oldCalDocuments, oldCalData, oldABDocuments, newServerRoot))
-
- if oldCalDocuments and os.path.exists(oldCalDocuments):
-
- if calendarDataInDefaultLocation:
- # We're in the default location, relocate to new location
- newCalDocuments = os.path.join(newServerRoot, "Documents")
- newCalData = os.path.join(newServerRoot, "Data")
- if os.path.exists(oldCalDocuments):
- if os.path.exists(newCalDocuments):
- # Move evertying from oldCalDocuments
- for item in list(os.listdir(oldCalDocuments)):
- source = os.path.join(oldCalDocuments, item)
- dest = os.path.join(newCalDocuments, item)
- log("Relocating %s to %s" % (source, dest))
- os.rename(source, dest)
- else:
- log("Error: %s does not exist" % (newCalDocuments,))
- else:
- log("Warning: %s does not exist; nothing to migrate" % (oldCalDocuments,))
- else:
- # The admin has moved calendar data to a non-standard location so
- # we're going to leave it there, but move things down a level so
- # that the old DocumentRoot becomes new ServerRoot
-
- # Create "Documents" directory with same ownership as oldCalDocuments
- newCalDocuments = os.path.join(newServerRoot, "Documents")
- log("New documents directory: %s" % (newCalDocuments,))
- newCalData = os.path.join(newServerRoot, "Data")
- log("New data directory: %s" % (newCalData,))
- os.mkdir(newCalDocuments)
- os.mkdir(newCalData)
- for item in list(os.listdir(newServerRoot)):
- if item not in ("Documents", "Data"):
- source = os.path.join(newServerRoot, item)
- dest = os.path.join(newCalDocuments, item)
- log("Relocating %s to %s" % (source, dest))
- os.rename(source, dest)
-
- # Relocate calendar DataRoot, copying all files
- if os.path.exists(oldCalData):
- for item in list(os.listdir(oldCalData)):
- source = os.path.join(oldCalData, item)
- if not os.path.isfile(source):
- continue
- dest = os.path.join(newCalData, item)
- log("Relocating %s to %s" % (source, dest))
- try:
- os.rename(source, dest)
- except OSError:
- # Can't rename because it's cross-volume; must copy/delete
- shutil.copy2(source, dest)
- os.remove(source)
-
- # Symlink to AB document root so server will find it an import to
- # PostgreSQL
- if oldABDocuments and os.path.exists(oldABDocuments):
- oldAddressBooks = os.path.join(oldABDocuments, "addressbooks")
- newAddressBooks = os.path.join(newCalDocuments, "addressbooks")
- log("Symlinking AddressBook data: %s to %s" % (newAddressBooks, oldAddressBooks))
- os.symlink(oldAddressBooks, newAddressBooks)
-
-
- elif oldABDocuments and os.path.exists(oldABDocuments):
- # No calendar data, only addressbook data
-
- if addressbookDataInDefaultLocation:
- # We're in the default location, relocate to new location
- newABDocuments = os.path.join(newServerRoot, "Documents")
- if os.path.exists(newABDocuments):
- # Move evertying from oldABDocuments
- for item in list(os.listdir(oldABDocuments)):
- source = os.path.join(oldABDocuments, item)
- dest = os.path.join(newABDocuments, item)
- log("Relocating %s to %s" % (source, dest))
- os.rename(source, dest)
- else:
- log("Error: %s does not exist" % (newABDocuments,))
- else:
- # The admin has moved addressbook data to a non-standard location so
- # we're going to leave it there, but move things down a level so
- # that the old DocumentRoot becomes new ServerRoot
-
- # Create "Documents" directory with same ownership as oldABDocuments
- newABDocuments = os.path.join(newServerRoot, "Documents")
- newABData = os.path.join(newServerRoot, "Data")
- log("New documents directory: %s" % (newABDocuments,))
- os.mkdir(newABDocuments)
- os.mkdir(newABData)
- for item in list(os.listdir(newServerRoot)):
- if item not in ("Documents", "Data"):
- source = os.path.join(newServerRoot, item)
- dest = os.path.join(newABDocuments, item)
- log("Relocating %s to %s" % (source, dest))
- os.rename(source, dest)
-
- if newServerRoot and os.path.exists(newServerRoot):
- """
- Change onwnership of entire ServerRoot
- """
- os.chown(newServerRoot, uid, gid)
- for root, dirs, files in os.walk(newServerRoot, followlinks=True):
- for name in dirs:
- os.chown(os.path.join(root, name), uid, gid)
- for name in files:
- os.chown(os.path.join(root, name), uid, gid)
-
-
-
-def getServerIDs(plist):
- """
- Given a caldavd.plist, return the userid and groupid for the UserName and
- GroupName specified.
- """
- uid = -1
- if plist["UserName"]:
- uid = pwd.getpwnam(plist["UserName"]).pw_uid
- gid = -1
- if plist["GroupName"]:
- gid = grp.getgrnam(plist["GroupName"]).gr_gid
- return uid, gid
-
-def absolutePathWithRoot(root, path):
- """
- Combine root and path as long as path does not start with /Volumes/
- """
- if path.startswith("/Volumes/"):
- return path
- else:
- path = path.strip("/")
- return os.path.join(root, path)
-
-if __name__ == '__main__':
- main()
Added: CalendarServer/trunk/contrib/migration/__init__.py
===================================================================
--- CalendarServer/trunk/contrib/migration/__init__.py (rev 0)
+++ CalendarServer/trunk/contrib/migration/__init__.py 2010-10-18 16:34:37 UTC (rev 6436)
@@ -0,0 +1,15 @@
+##
+# Copyright (c) 2010 Apple 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.
+##
Copied: CalendarServer/trunk/contrib/migration/calendarmigrator.py (from rev 6435, CalendarServer/trunk/contrib/migration/59_calendarmigrator.py)
===================================================================
--- CalendarServer/trunk/contrib/migration/calendarmigrator.py (rev 0)
+++ CalendarServer/trunk/contrib/migration/calendarmigrator.py 2010-10-18 16:34:37 UTC (rev 6436)
@@ -0,0 +1,654 @@
+#!/usr/bin/env python
+#
+# MigrationExtra script to maintain the enabled/disabled state of the
+# calendar server.
+#
+# This script examines the launchd preferences from the previous system
+# (also taking into account the overrides.plist) and then invokes serveradmin
+# to start/stop calendar server.
+#
+# The only argument this script currently cares about is --sourceRoot, which
+# should point to the root of the previous system.
+#
+# Copyright (c) 2005-2010 Apple Inc. All Rights Reserved.
+#
+# IMPORTANT NOTE: This file is licensed only for use on Apple-labeled
+# computers and is subject to the terms and conditions of the Apple
+# Software License Agreement accompanying the package this file is a
+# part of. You may not port this file to another platform without
+# Apple's written consent.
+
+from __future__ import with_statement
+
+import datetime
+import grp
+import optparse
+import os
+import pwd
+import shutil
+import sys
+
+from plistlib import readPlist, writePlist
+
+LAUNCHD_KEY = "org.calendarserver.calendarserver"
+LOG = "/Library/Logs/Migration/calendarmigrator.log"
+SERVICE_NAME = "calendar"
+LAUNCHD_OVERRIDES = "var/db/launchd.db/com.apple.launchd/overrides.plist"
+LAUNCHD_PREFS_DIR = "System/Library/LaunchDaemons"
+CALDAVD_CONFIG_DIR = "private/etc/caldavd"
+CARDDAVD_CONFIG_DIR = "private/etc/carddavd"
+CALDAVD_PLIST = "caldavd.plist"
+CARDDAVD_PLIST = "carddavd.plist"
+NEW_SERVER_ROOT = "/Library/Server/Calendar and Contacts"
+
+
+verbatimKeys = """
+AccountingCategories
+AccountingPrincipals
+AdminPrincipals
+Aliases
+AnonymousDirectoryAddressBookAccess
+AugmentService
+BindAddresses
+ConfigRoot
+ControlPort
+DatabaseRoot
+DefaultLogLevel
+DirectoryAddressBook
+DirectoryService
+EnableAddMember
+EnableAnonymousReadNav
+EnableCalDAV
+EnableCardDAV
+EnableDropBox
+EnableExtendedAccessLog
+EnableKeepAlive
+EnableMonolithicCalendars
+EnablePrincipalListings
+EnablePrivateEvents
+EnableProxyPrincipals
+EnableSACLs
+EnableSSL
+EnableSearchAddressBook
+EnableSyncReport
+EnableTimezoneService
+EnableWebAdmin
+EnableWellKnown
+ErrorLogEnabled
+ErrorLogMaxRotatedFiles
+ErrorLogRotateMB
+FreeBusyURL
+GlobalAddressBook
+GlobalStatsLoggingFrequency
+GlobalStatsLoggingPeriod
+GlobalStatsSocket
+GroupName
+HTTPPort
+HTTPRetryAfter
+IdleConnectionTimeOut
+Includes
+ListenBacklog
+Localization
+LogLevels
+LogRoot
+MaxAccepts
+MaxAttendeesPerInstance
+MaxInstancesForRRULE
+MaxMultigetWithDataHREFs
+MaxQueryWithDataResults
+MaxRequests
+MaximumAttachmentSize
+Memcached
+MultiProcess
+Notifications
+Partitioning
+Postgres
+ProcessType
+Profiling
+ProxyDBService
+ProxyLoadFromFile
+ReadPrincipals
+RedirectHTTPToHTTPS
+RejectClients
+ResourceService
+ResponseCompression
+RotateAccessLog
+RunRoot
+SSLAuthorityChain
+SSLCertAdmin
+SSLCertificate
+SSLCiphers
+SSLMethod
+SSLPrivateKey
+Scheduling
+ServerHostName
+ServerRoot
+Sharing
+SudoersFile
+Twisted
+UIDReservationTimeOut
+UseDatabase
+UseMetaFD
+UserName
+UserQuota
+WebCalendarRoot
+umask
+""".split()
+
+# These are going to require some processing
+specialKeys = """
+AccessLogFile
+AccountingLogRoot
+Authentication
+BindHTTPPorts
+BindSSLPorts
+DataRoot
+DocumentRoot
+ErrorLogFile
+MaxAddressBookMultigetHrefs
+MaxAddressBookQueryResults
+""".split()
+
+ignoredKkeys = """
+ControlSocket
+EnableAnonymousReadRoot
+EnableFindSharedReport
+EnableNotifications
+PIDFile
+PythonDirector
+ResponseCacheTimeout
+SSLPassPhraseDialog
+SSLPort
+ServerStatsFile
+Verbose
+""".split()
+
+
+def main():
+
+ optionParser = optparse.OptionParser()
+
+ optionParser.add_option('--purge', choices=('0', '1'),
+ metavar='[0|1]',
+ help='remove old files after migration (IGNORED)')
+
+ optionParser.add_option('--sourceRoot', type='string',
+ metavar='DIR',
+ help='path to the root of the system to migrate')
+
+ optionParser.add_option('--sourceType', type='string',
+ metavar='[System|TimeMachine]',
+ help='migration source type (IGNORED)')
+
+ optionParser.add_option('--sourceVersion', type='string',
+ metavar='10.X.X',
+ help='version number of previous system (IGNORED)')
+
+ optionParser.add_option('--targetRoot', type='string',
+ metavar='DIR',
+ help='path to the root of the new system',
+ default='/')
+
+ optionParser.add_option('--language', choices=('en', 'fr', 'de', 'ja'),
+ metavar='[en|fr|de|ja]',
+ help='language identifier (IGNORED)')
+
+ (options, args) = optionParser.parse_args()
+ log("Options: %s" % (options,))
+
+ if options.sourceRoot:
+
+ if os.path.exists(options.sourceRoot):
+ newServerRootValue = migrateData(options)
+ migrateConfiguration(options, newServerRootValue)
+ migrateRunState(options)
+
+ else:
+ log("ERROR: --sourceRoot must be specified")
+ sys.exit(1)
+
+
+def migrateRunState(options):
+ """
+ Try to determine whether server was running in previous system, then
+ modify the launchd settings in the new system.
+ """
+
+ try:
+ disabled = isServiceDisabled(options.sourceRoot, LAUNCHD_KEY)
+ log("Service '%s' was previously %s" %
+ (LAUNCHD_KEY, "disabled" if disabled else "enabled"))
+ except ServiceStateError, e:
+ log("Couldn't determine previous state of service '%s': %s" %
+ (LAUNCHD_KEY, e))
+ return
+
+ setServiceStateDisabled(options.targetRoot, LAUNCHD_KEY, disabled)
+
+
+def migrateConfiguration(options, newServerRootValue):
+ """
+ Copy files/directories/symlinks from previous system's /etc/caldavd
+ and /etc/carddavd
+
+ Skips anything ending in ".default".
+ Regular files overwrite copies in new system.
+ Directories and symlinks only copied over if they don't overwrite anything.
+ """
+
+ newConfigDir = os.path.join(options.targetRoot, CALDAVD_CONFIG_DIR)
+ if not os.path.exists(newConfigDir):
+ log("New configuration directory does not exist: %s" % (newConfigDir,))
+ return
+
+
+ for configDir in (CALDAVD_CONFIG_DIR, CARDDAVD_CONFIG_DIR):
+
+ oldConfigDir = os.path.join(options.sourceRoot, configDir)
+ if not os.path.exists(oldConfigDir):
+ log("Old configuration directory does not exist: %s" % (oldConfigDir,))
+ continue
+
+
+ log("Copying configuration files from %s to %s" % (oldConfigDir, newConfigDir))
+
+ for name in os.listdir(oldConfigDir):
+
+ if not (name.endswith(".default") or name in (CALDAVD_PLIST, CARDDAVD_PLIST)):
+
+ oldPath = os.path.join(oldConfigDir, name)
+ newPath = os.path.join(newConfigDir, name)
+
+ if os.path.islink(oldPath) and not os.path.exists(newPath):
+ # Recreate the symlink if it won't overwrite an existing file
+ link = os.readlink(oldPath)
+ log("Symlinking %s to %s" % (newPath, link))
+ os.symlink(link, newPath)
+
+ elif os.path.isfile(oldPath):
+ # Copy the file over, overwriting copy in newConfigDir
+ log("Copying file %s to %s" % (oldPath, newConfigDir))
+ shutil.copy2(oldPath, newConfigDir)
+
+ elif os.path.isdir(oldPath) and not os.path.exists(newPath):
+ # Copy the dir over, but only if new one doesn't exist
+ log("Copying directory %s to %s" % (oldPath, newPath))
+ shutil.copytree(oldPath, newPath, symlinks=True)
+
+
+ # Migrate certain settings from the old plists to new:
+
+ oldCalDAVPlistPath = os.path.join(options.sourceRoot, CALDAVD_CONFIG_DIR,
+ CALDAVD_PLIST)
+ if os.path.exists(oldCalDAVPlistPath):
+ oldCalDAVDPlist = readPlist(oldCalDAVPlistPath)
+ else:
+ oldCalDAVDPlist = { }
+
+ oldCardDAVDPlistPath = os.path.join(options.sourceRoot, CARDDAVD_CONFIG_DIR,
+ CARDDAVD_PLIST)
+ if os.path.exists(oldCardDAVDPlistPath):
+ oldCardDAVDPlist = readPlist(oldCardDAVDPlistPath)
+ else:
+ oldCardDAVDPlist = { }
+
+ newCalDAVDPlistPath = os.path.join(options.targetRoot, CALDAVD_CONFIG_DIR,
+ CALDAVD_PLIST)
+ if os.path.exists(newCalDAVDPlistPath):
+ newCalDAVDPlist = readPlist(newCalDAVDPlistPath)
+ else:
+ newCalDAVDPlist = { }
+
+ log("Processing %s and %s" % (oldCalDAVPlistPath, oldCardDAVDPlistPath))
+ mergePlist(oldCalDAVDPlist, oldCardDAVDPlist, newCalDAVDPlist)
+
+ newCalDAVDPlist["ServerRoot"] = newServerRootValue
+ newCalDAVDPlist["DocumentRoot"] = "Documents"
+ newCalDAVDPlist["DataRoot"] = "Data"
+
+ log("Writing %s" % (newCalDAVDPlistPath,))
+ writePlist(newCalDAVDPlist, newCalDAVDPlistPath)
+
+
+def mergePlist(oldCalDAVDPlist, oldCardDAVDPlist, newCalDAVDPlist):
+
+ # These keys are copied verbatim:
+ for key in verbatimKeys:
+ if key in oldCardDAVDPlist:
+ newCalDAVDPlist[key] = oldCardDAVDPlist[key]
+ if key in oldCalDAVDPlist:
+ newCalDAVDPlist[key] = oldCalDAVDPlist[key]
+
+ # "Wiki" is a new authentication in v2.x; copy all "Authentication" sub-keys # over, and "Wiki" will be picked up from the new plist:
+ if "Authentication" in oldCalDAVDPlist:
+ for key in oldCalDAVDPlist["Authentication"]:
+ newCalDAVDPlist["Authentication"][key] = oldCalDAVDPlist["Authentication"][key]
+
+ # Strip out any unknown params from the DirectoryService:
+ if "DirectoryService" in oldCalDAVDPlist:
+ newCalDAVDPlist["DirectoryService"] = oldCalDAVDPlist["DirectoryService"]
+ for key in newCalDAVDPlist["DirectoryService"]["params"].keys():
+ if key not in ("node", "cacheTimeout", "xmlFile"):
+ del newCalDAVDPlist["DirectoryService"]["params"][key]
+
+
+
+def isServiceDisabled(source, service):
+ """
+ Returns whether or not a service is disabled
+
+ @param source: System root to examine
+ @param service: launchd key representing service
+ @return: True if service is disabled, False if enabled
+ """
+
+ overridesPath = os.path.join(source, LAUNCHD_OVERRIDES)
+ if os.path.isfile(overridesPath):
+ overrides = readPlist(overridesPath)
+ try:
+ return overrides[service]['Disabled']
+ except KeyError:
+ # Key is not in the overrides.plist, continue on
+ pass
+
+ prefsPath = os.path.join(source, LAUNCHD_PREFS_DIR, "%s.plist" % service)
+ if os.path.isfile(prefsPath):
+ prefs = readPlist(prefsPath)
+ try:
+ return prefs['Disabled']
+ except KeyError:
+ return False
+
+ raise ServiceStateError("Neither %s nor %s exist" %
+ (overridesPath, prefsPath))
+
+
+def setServiceStateDisabled(target, service, disabled):
+ """
+ Modifies launchd settings for a service
+
+ @param target: System root
+ @param service: launchd key representing service
+ @param disabled: boolean
+ """
+
+ overridesPath = os.path.join(target, LAUNCHD_OVERRIDES)
+ if os.path.isfile(overridesPath):
+ overrides = readPlist(overridesPath)
+ if not overrides.has_key(service):
+ overrides[service] = { }
+ overrides[service]['Disabled'] = disabled
+ writePlist(overrides, overridesPath)
+
+
+class ServiceStateError(Exception):
+ """
+ Could not determine service state
+ """
+
+
+def log(msg):
+ try:
+ with open(LOG, 'a') as output:
+ timestamp = datetime.datetime.now().strftime("%b %d %H:%M:%S")
+ output.write("%s %s\n" % (timestamp, msg))
+ except IOError:
+ # Could not write to log
+ pass
+
+def migrateData(options):
+ """
+ Examines the old caldavd.plist and carddavd.plist to see where data
+ lives in the previous system. If there is old data, calls relocateData( )
+ """
+
+ oldCalDocuments = None
+ oldCalData = None
+ oldABDocuments = None
+ calendarDataInDefaultLocation = True
+ addressbookDataInDefaultLocation = True
+ uid = -1
+ gid = -1
+ newServerRoot = None
+
+ oldCalConfigDir = os.path.join(options.sourceRoot, CALDAVD_CONFIG_DIR)
+ oldCalPlistPath = os.path.join(oldCalConfigDir, CALDAVD_PLIST)
+ if os.path.exists(oldCalPlistPath):
+ oldCalPlist = readPlist(oldCalPlistPath)
+ uid, gid = getServerIDs(oldCalPlist)
+ log("ServerIDs: %d, %d" % (uid, gid))
+ else:
+ log("Can't find previous calendar plist at %s" % (oldCalPlistPath,))
+ oldCalPlist = None
+ newCalConfigDir = os.path.join(options.targetRoot, CALDAVD_CONFIG_DIR)
+ newCalPlistPath = os.path.join(newCalConfigDir, CALDAVD_PLIST)
+ if os.path.exists(newCalPlistPath):
+ newCalPlist = readPlist(newCalPlistPath)
+ uid, gid = getServerIDs(newCalPlist)
+ log("ServerIDs: %d, %d" % (uid, gid))
+
+
+ oldABConfigDir = os.path.join(options.sourceRoot, CARDDAVD_CONFIG_DIR)
+ oldABPlistPath = os.path.join(oldABConfigDir, CARDDAVD_PLIST)
+ if os.path.exists(oldABPlistPath):
+ oldABPlist = readPlist(oldABPlistPath)
+ else:
+ log("Can't find previous addressbook plist at %s" % (oldABPlistPath,))
+ oldABPlist = None
+
+ if oldCalPlist is not None:
+ # See if there is actually any calendar data
+
+ oldDocumentRoot = oldCalPlist["DocumentRoot"]
+ if oldDocumentRoot.rstrip("/") != "/Library/CalendarServer/Documents":
+ log("Calendar data in non-standard location: %s" % (oldDocumentRoot,))
+ calendarDataInDefaultLocation = False
+ else:
+ log("Calendar data in standard location: %s" % (oldDocumentRoot,))
+
+ oldDataRoot = oldCalPlist["DataRoot"]
+
+ oldCalendarsPath = os.path.join(oldDocumentRoot, "calendars")
+ if os.path.exists(oldCalendarsPath):
+ # There is calendar data
+ oldCalDocuments = oldDocumentRoot
+ oldCalData = oldDataRoot
+ log("Calendar data to migrate from %s and %s" %
+ (oldCalDocuments, oldCalData))
+
+ if calendarDataInDefaultLocation:
+ newServerRoot = absolutePathWithRoot(options.targetRoot,
+ NEW_SERVER_ROOT)
+ newServerRootValue = NEW_SERVER_ROOT
+ else:
+ newServerRoot = absolutePathWithRoot(options.targetRoot,
+ oldDocumentRoot)
+ newServerRootValue = oldDocumentRoot
+ else:
+ log("No calendar data to migrate")
+
+ if oldABPlist is not None:
+ # See if there is actually any addressbook data
+
+ oldDocumentRoot = oldABPlist["DocumentRoot"]
+ if oldDocumentRoot.rstrip("/") != "/Library/AddressBookServer/Documents":
+ log("AddressBook data in non-standard location: %s" % (oldDocumentRoot,))
+ addressbookDataInDefaultLocation = False
+ else:
+ log("AddressBook data in standard location: %s" % (oldDocumentRoot,))
+
+ oldAddressbooksPath = os.path.join(oldDocumentRoot, "addressbooks")
+ if os.path.exists(oldAddressbooksPath):
+ # There is addressbook data
+ oldABDocuments = oldDocumentRoot
+ log("AddressBook data to migrate from %s" % (oldABDocuments,))
+
+ if newServerRoot is None:
+ # don't override server root computed from calendar
+ if addressbookDataInDefaultLocation:
+ newServerRoot = absolutePathWithRoot(options.targetRoot,
+ NEW_SERVER_ROOT)
+ newServerRootValue = NEW_SERVER_ROOT
+ else:
+ newServerRoot = absolutePathWithRoot(options.targetRoot,
+ oldDocumentRoot)
+ newServerRootValue = oldDocumentRoot
+ else:
+ log("No addressbook data to migrate")
+
+ if (oldCalDocuments or oldABDocuments) and newServerRoot:
+ relocateData(oldCalDocuments, oldCalData, oldABDocuments, uid, gid,
+ calendarDataInDefaultLocation, addressbookDataInDefaultLocation,
+ newServerRoot)
+
+ return newServerRootValue
+
+def relocateData(oldCalDocuments, oldCalData, oldABDocuments, uid, gid,
+ calendarDataInDefaultLocation, addressbookDataInDefaultLocation,
+ newServerRoot):
+ """
+ Relocates existing calendar data to the new default location iff the data
+ was previously in the old default location; otherwise the old calendar
+ DocumentRoot becomes the new ServerRoot directory, the contents of the
+ old DocumentRoot are moved into ServerRoot/Documents and the contents of
+ old DataRoot are copied/moved into ServerRoot/Data. If there is addressbook
+ data, a symlink is created as ServerRoot/Documents/addressbooks pointing
+ to the old addressbook directory so that the import-to-PostgreSQL will
+ find it.
+ """
+
+ log("RelocateData: cal documents=%s, cal data=%s, ab documents=%s, new server root=%s"
+ % (oldCalDocuments, oldCalData, oldABDocuments, newServerRoot))
+
+ if oldCalDocuments and os.path.exists(oldCalDocuments):
+
+ if calendarDataInDefaultLocation:
+ # We're in the default location, relocate to new location
+ newCalDocuments = os.path.join(newServerRoot, "Documents")
+ newCalData = os.path.join(newServerRoot, "Data")
+ if os.path.exists(oldCalDocuments):
+ if os.path.exists(newCalDocuments):
+ # Move evertying from oldCalDocuments
+ for item in list(os.listdir(oldCalDocuments)):
+ source = os.path.join(oldCalDocuments, item)
+ dest = os.path.join(newCalDocuments, item)
+ log("Relocating %s to %s" % (source, dest))
+ os.rename(source, dest)
+ else:
+ log("Error: %s does not exist" % (newCalDocuments,))
+ else:
+ log("Warning: %s does not exist; nothing to migrate" % (oldCalDocuments,))
+ else:
+ # The admin has moved calendar data to a non-standard location so
+ # we're going to leave it there, but move things down a level so
+ # that the old DocumentRoot becomes new ServerRoot
+
+ # Create "Documents" directory with same ownership as oldCalDocuments
+ newCalDocuments = os.path.join(newServerRoot, "Documents")
+ log("New documents directory: %s" % (newCalDocuments,))
+ newCalData = os.path.join(newServerRoot, "Data")
+ log("New data directory: %s" % (newCalData,))
+ os.mkdir(newCalDocuments)
+ os.mkdir(newCalData)
+ for item in list(os.listdir(newServerRoot)):
+ if item not in ("Documents", "Data"):
+ source = os.path.join(newServerRoot, item)
+ dest = os.path.join(newCalDocuments, item)
+ log("Relocating %s to %s" % (source, dest))
+ os.rename(source, dest)
+
+ # Relocate calendar DataRoot, copying all files
+ if os.path.exists(oldCalData):
+ for item in list(os.listdir(oldCalData)):
+ source = os.path.join(oldCalData, item)
+ if not os.path.isfile(source):
+ continue
+ dest = os.path.join(newCalData, item)
+ log("Relocating %s to %s" % (source, dest))
+ try:
+ os.rename(source, dest)
+ except OSError:
+ # Can't rename because it's cross-volume; must copy/delete
+ shutil.copy2(source, dest)
+ os.remove(source)
+
+ # Symlink to AB document root so server will find it an import to
+ # PostgreSQL
+ if oldABDocuments and os.path.exists(oldABDocuments):
+ oldAddressBooks = os.path.join(oldABDocuments, "addressbooks")
+ newAddressBooks = os.path.join(newCalDocuments, "addressbooks")
+ log("Symlinking AddressBook data: %s to %s" % (newAddressBooks, oldAddressBooks))
+ os.symlink(oldAddressBooks, newAddressBooks)
+
+
+ elif oldABDocuments and os.path.exists(oldABDocuments):
+ # No calendar data, only addressbook data
+
+ if addressbookDataInDefaultLocation:
+ # We're in the default location, relocate to new location
+ newABDocuments = os.path.join(newServerRoot, "Documents")
+ if os.path.exists(newABDocuments):
+ # Move evertying from oldABDocuments
+ for item in list(os.listdir(oldABDocuments)):
+ source = os.path.join(oldABDocuments, item)
+ dest = os.path.join(newABDocuments, item)
+ log("Relocating %s to %s" % (source, dest))
+ os.rename(source, dest)
+ else:
+ log("Error: %s does not exist" % (newABDocuments,))
+ else:
+ # The admin has moved addressbook data to a non-standard location so
+ # we're going to leave it there, but move things down a level so
+ # that the old DocumentRoot becomes new ServerRoot
+
+ # Create "Documents" directory with same ownership as oldABDocuments
+ newABDocuments = os.path.join(newServerRoot, "Documents")
+ newABData = os.path.join(newServerRoot, "Data")
+ log("New documents directory: %s" % (newABDocuments,))
+ os.mkdir(newABDocuments)
+ os.mkdir(newABData)
+ for item in list(os.listdir(newServerRoot)):
+ if item not in ("Documents", "Data"):
+ source = os.path.join(newServerRoot, item)
+ dest = os.path.join(newABDocuments, item)
+ log("Relocating %s to %s" % (source, dest))
+ os.rename(source, dest)
+
+ if newServerRoot and os.path.exists(newServerRoot):
+ """
+ Change onwnership of entire ServerRoot
+ """
+ os.chown(newServerRoot, uid, gid)
+ for root, dirs, files in os.walk(newServerRoot, followlinks=True):
+ for name in dirs:
+ os.chown(os.path.join(root, name), uid, gid)
+ for name in files:
+ os.chown(os.path.join(root, name), uid, gid)
+
+
+
+def getServerIDs(plist):
+ """
+ Given a caldavd.plist, return the userid and groupid for the UserName and
+ GroupName specified.
+ """
+ uid = -1
+ if plist["UserName"]:
+ uid = pwd.getpwnam(plist["UserName"]).pw_uid
+ gid = -1
+ if plist["GroupName"]:
+ gid = grp.getgrnam(plist["GroupName"]).gr_gid
+ return uid, gid
+
+def absolutePathWithRoot(root, path):
+ """
+ Combine root and path as long as path does not start with /Volumes/
+ """
+ if path.startswith("/Volumes/"):
+ return path
+ else:
+ path = path.strip("/")
+ return os.path.join(root, path)
+
+if __name__ == '__main__':
+ main()
Modified: CalendarServer/trunk/support/Makefile.Apple
===================================================================
--- CalendarServer/trunk/support/Makefile.Apple 2010-10-18 16:32:53 UTC (rev 6435)
+++ CalendarServer/trunk/support/Makefile.Apple 2010-10-18 16:34:37 UTC (rev 6436)
@@ -99,7 +99,7 @@
$(_v) $(INSTALL_FILE) "$(Sources)/contrib/launchd/calendarserver.plist" "$(DSTROOT)$(NSLIBRARYDIR)/LaunchDaemons/org.calendarserver.calendarserver.plist"
@echo "Installing migration config..."
$(_v) $(INSTALL_DIRECTORY) "$(DSTROOT)/System/Library/ServerSetup/MigrationExtras"
- $(_v) $(INSTALL_FILE) "$(Sources)/contrib/migration/59_calendarmigrator.py" "$(DSTROOT)/System/Library/ServerSetup/MigrationExtras/59_calendarmigrator.py"
+ $(_v) $(INSTALL_FILE) "$(Sources)/contrib/migration/calendarmigrator.py" "$(DSTROOT)/System/Library/ServerSetup/MigrationExtras/59_calendarmigrator.py"
$(_v) chmod ugo+x "$(DSTROOT)/System/Library/ServerSetup/MigrationExtras/59_calendarmigrator.py"
@echo "Installing changeip config..."
$(_v) $(INSTALL_DIRECTORY) "$(DSTROOT)/usr/libexec/changeip"
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20101018/dd496ab2/attachment-0001.html>
More information about the calendarserver-changes
mailing list