[CalendarServer-changes] [4475] CalendarServer/trunk/twistedcaldav

source_changes at macosforge.org source_changes at macosforge.org
Fri Jul 24 14:47:40 PDT 2009


Revision: 4475
          http://trac.macosforge.org/projects/calendarserver/changeset/4475
Author:   sagen at apple.com
Date:     2009-07-24 14:47:39 -0700 (Fri, 24 Jul 2009)
Log Message:
-----------
Two fixes:
Files such as .DS_Store lying around should no longer hinder an upgrade (they'll be skipped)
Orphaned calendar homes under calendars/users (or groups, locations, resources) will now get moved into dataroot/archived

Modified Paths:
--------------
    CalendarServer/trunk/twistedcaldav/test/test_upgrade.py
    CalendarServer/trunk/twistedcaldav/upgrade.py

Modified: CalendarServer/trunk/twistedcaldav/test/test_upgrade.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/test/test_upgrade.py	2009-07-24 18:30:54 UTC (rev 4474)
+++ CalendarServer/trunk/twistedcaldav/test/test_upgrade.py	2009-07-24 21:47:39 UTC (rev 4475)
@@ -370,6 +370,294 @@
         upgradeData(config)
         self.assertTrue(self.verifyHierarchy(root, after))
 
+
+
+    def test_calendarsUpgradeWithOrphans(self):
+        """
+        Verify that calendar homes in the /calendars/<type>/<shortname>/ form
+        whose records don't exist are moved into dataroot/archived/
+        """
+
+        self.setUpXMLDirectory()
+        directory = getDirectory()
+
+        before = {
+            "calendars" :
+            {
+                "users" :
+                {
+                    "unknownuser" :
+                    {
+                    },
+                },
+                "groups" :
+                {
+                    "unknowngroup" :
+                    {
+                    },
+                },
+            },
+            "principals" :
+            {
+                CalendarUserProxyDatabase.dbOldFilename :
+                {
+                    "@contents" : "",
+                }
+            }
+        }
+
+        after = {
+            "archived" :
+            {
+                "unknownuser" :
+                {
+                },
+                "unknowngroup" :
+                {
+                },
+            },
+            "tasks" :
+            {
+                "incoming" :
+                {
+                },
+            },
+            ".calendarserver_version" :
+            {
+                "@contents" : "1",
+            },
+            "calendars" :
+            {
+                "__uids__" :
+                {
+                },
+            },
+            CalendarUserProxyDatabase.dbFilename :
+            {
+                "@contents" : None,
+            },
+            MailGatewayTokensDatabase.dbFilename :
+            {
+                "@contents" : None,
+            },
+            ResourceInfoDatabase.dbFilename :
+            {
+                "@contents" : None,
+            }
+        }
+
+        root = self.createHierarchy(before)
+
+        config.DocumentRoot = root
+        config.DataRoot = root
+
+        upgradeData(config)
+        self.assertTrue(self.verifyHierarchy(root, after))
+
+        # Ensure that repeating the process doesn't change anything
+        upgradeData(config)
+        self.assertTrue(self.verifyHierarchy(root, after))
+
+
+    def test_calendarsUpgradeWithDuplicateOrphans(self):
+        """
+        Verify that calendar homes in the /calendars/<type>/<shortname>/ form
+        whose records don't exist are moved into dataroot/archived/
+        """
+
+        self.setUpXMLDirectory()
+        directory = getDirectory()
+
+        before = {
+            "archived" :
+            {
+                "unknownuser" :
+                {
+                },
+                "unknowngroup" :
+                {
+                },
+            },
+            "calendars" :
+            {
+                "users" :
+                {
+                    "unknownuser" :
+                    {
+                    },
+                },
+                "groups" :
+                {
+                    "unknowngroup" :
+                    {
+                    },
+                },
+            },
+            "principals" :
+            {
+                CalendarUserProxyDatabase.dbOldFilename :
+                {
+                    "@contents" : "",
+                }
+            }
+        }
+
+        after = {
+            "archived" :
+            {
+                "unknownuser" :
+                {
+                },
+                "unknowngroup" :
+                {
+                },
+                "unknownuser.1" :
+                {
+                },
+                "unknowngroup.1" :
+                {
+                },
+            },
+            "tasks" :
+            {
+                "incoming" :
+                {
+                },
+            },
+            ".calendarserver_version" :
+            {
+                "@contents" : "1",
+            },
+            "calendars" :
+            {
+                "__uids__" :
+                {
+                },
+            },
+            CalendarUserProxyDatabase.dbFilename :
+            {
+                "@contents" : None,
+            },
+            MailGatewayTokensDatabase.dbFilename :
+            {
+                "@contents" : None,
+            },
+            ResourceInfoDatabase.dbFilename :
+            {
+                "@contents" : None,
+            }
+        }
+
+        root = self.createHierarchy(before)
+
+        config.DocumentRoot = root
+        config.DataRoot = root
+
+        upgradeData(config)
+        self.assertTrue(self.verifyHierarchy(root, after))
+
+        # Ensure that repeating the process doesn't change anything
+        upgradeData(config)
+        self.assertTrue(self.verifyHierarchy(root, after))
+
+
+
+    def test_calendarsUpgradeWithDSStore(self):
+        """
+        Verify that .DS_Store files don't hinder an upgrade
+        """
+
+        self.setUpXMLDirectory()
+        directory = getDirectory()
+
+        before = {
+            ".DS_Store" :
+            {
+                "@contents" : "",
+            },
+            "calendars" :
+            {
+                ".DS_Store" :
+                {
+                    "@contents" : "",
+                },
+                "__uids__" :
+                {
+                    ".DS_Store" :
+                    {
+                        "@contents" : "",
+                    },
+                },
+            },
+            "principals" :
+            {
+                ".DS_Store" :
+                {
+                    "@contents" : "",
+                },
+                CalendarUserProxyDatabase.dbOldFilename :
+                {
+                    "@contents" : "",
+                }
+            }
+        }
+
+        after = {
+            ".DS_Store" :
+            {
+                "@contents" : "",
+            },
+            "tasks" :
+            {
+                "incoming" :
+                {
+                },
+            },
+            ".calendarserver_version" :
+            {
+                "@contents" : "1",
+            },
+            "calendars" :
+            {
+                ".DS_Store" :
+                {
+                    "@contents" : "",
+                },
+                "__uids__" :
+                {
+                    ".DS_Store" :
+                    {
+                        "@contents" : "",
+                    },
+                },
+            },
+            CalendarUserProxyDatabase.dbFilename :
+            {
+                "@contents" : None,
+            },
+            MailGatewayTokensDatabase.dbFilename :
+            {
+                "@contents" : None,
+            },
+            ResourceInfoDatabase.dbFilename :
+            {
+                "@contents" : None,
+            }
+        }
+
+        root = self.createHierarchy(before)
+
+        config.DocumentRoot = root
+        config.DataRoot = root
+
+        upgradeData(config)
+        self.assertTrue(self.verifyHierarchy(root, after))
+
+        # Ensure that repeating the process doesn't change anything
+        upgradeData(config)
+        self.assertTrue(self.verifyHierarchy(root, after))
+
+
     def test_calendarsUpgradeWithUIDs(self):
         """
         Verify that calendar homes in the /calendars/__uids__/<guid>/ form

Modified: CalendarServer/trunk/twistedcaldav/upgrade.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/upgrade.py	2009-07-24 18:30:54 UTC (rev 4474)
+++ CalendarServer/trunk/twistedcaldav/upgrade.py	2009-07-24 21:47:39 UTC (rev 4475)
@@ -343,6 +343,10 @@
                         continue
 
                     oldHome = os.path.join(uidHomes, home)
+                    if not os.path.isdir(oldHome):
+                        # Skip non-directories
+                        continue
+
                     newHome = os.path.join(uidHomes, home[0:2], home[2:4], home)
                     moveCalendarHome(oldHome, newHome, uid=uid, gid=gid)
 
@@ -361,11 +365,16 @@
                     for shortName in os.listdir(dirPath):
                         record = directory.recordWithShortName(recordType,
                             shortName)
+                        oldHome = os.path.join(dirPath, shortName)
                         if record is not None:
-                            oldHome = os.path.join(dirPath, shortName)
                             newHome = os.path.join(uidHomes, record.uid[0:2],
                                 record.uid[2:4], record.uid)
                             moveCalendarHome(oldHome, newHome, uid=uid, gid=gid)
+                        else:
+                            # an orphaned calendar home (principal no longer
+                            # exists in the directory)
+                            archive(config, oldHome, uid, gid)
+
                     os.rmdir(dirPath)
 
 
@@ -549,3 +558,31 @@
             os.mkdir(path)
             os.chown(path, uid, gid)
 
+
+def archive(config, srcPath, uid, gid):
+    """
+    Move srcPath into dataroot/archived, giving the destination a unique
+    (sequentially numbered) name in the case of duplicates.
+    """
+
+    archiveDir = os.path.join(config.DataRoot, "archived")
+
+    if not os.path.exists(archiveDir):
+        os.mkdir(archiveDir)
+    os.chown(archiveDir, uid, gid)
+
+    baseName = os.path.basename(srcPath)
+    newName = baseName
+    count = 0
+    destPath = os.path.join(archiveDir, newName)
+    while os.path.exists(destPath):
+        count += 1
+        newName = "%s.%d" % (baseName, count)
+        destPath = os.path.join(archiveDir, newName)
+
+    try:
+        os.rename(srcPath, destPath)
+    except OSError:
+        # Can't rename, must copy/delete
+        shutil.copy2(srcPath, destPath)
+        os.remove(srcPath)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20090724/34344d9d/attachment-0001.html>


More information about the calendarserver-changes mailing list