From 252b2b5d5a7c3e54a305e5d0102e6a51482cd931 Mon Sep 17 00:00:00 2001 From: Nikos Skalkotos Date: Fri, 18 Jan 2013 20:45:32 +0200 Subject: [PATCH] Completely exclude mpoints when running rsync We used to exclude mount point from rsync with options like this: --exclude mount/point/* This will copy the directory and leave out all files under it. In some cases, this causes problems because rsync will fail if it cannot stat the directory and some mount point will only return stat info to their owner and not root. Even if this wasn't the case, we cannot determine the real directory attributes. The stat syscall will return the attributes associated with the mount options. It's better to completely exclude those mpoints in rsync and create them explicitly after the command runs. We make them inherit the mode and the ownership of their parent directory. --- image_creator/bundle_volume.py | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/image_creator/bundle_volume.py b/image_creator/bundle_volume.py index c099daa..4b15acd 100644 --- a/image_creator/bundle_volume.py +++ b/image_creator/bundle_volume.py @@ -312,7 +312,7 @@ class BundleVolume(object): if not found_ancestor: excluded.append(mpoint) - return map(lambda d: d + "/*", excluded) + return excluded def _replace_uuids(self, target, new_uuid): @@ -380,17 +380,28 @@ class BundleVolume(object): absmpoints = self._mount(target, [(mapped[i], filesystem[i].mpoint) for i in mapped.keys()]) - exclude = self._to_exclude() + [image] + excluded = self._to_exclude() rsync = Rsync(self.out) # Excluded paths need to be relative to the source - for excl in map(lambda p: os.path.relpath(p, '/'), exclude): + for excl in map(lambda p: os.path.relpath(p, '/'), + excluded + [image]): rsync.exclude(excl) rsync.archive().hard_links().xattrs().sparse().acls() rsync.run('/', target, 'host', 'temporary image') + # Create missing mountpoints. Since they are mountpoints, we + # cannot determine the ownership and the mode of the real + # directory. Make them inherit those properties from their + # parent dir + for excl in excluded: + dirname = os.path.dirname(excl) + stat = os.stat(dirname) + os.mkdir(target + excl, stat.st_mode) + os.chown(target + excl, stat.st_uid, stat.st_gid) + # We need to replace the old UUID referencies with the new # ones in grub configuration files and /etc/fstab for file # systems that have been recreated. -- 1.7.10.4