[sabayon] Merry Christmas, Sysadmins everywhere: Sabayon now supports symlinks
- From: Scott Balneaves <sbalneav src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [sabayon] Merry Christmas, Sysadmins everywhere: Sabayon now supports symlinks
- Date: Fri, 25 Dec 2009 03:01:41 +0000 (UTC)
commit 51ab3829063416a7762c923125ac901481964380
Author: Scott Balneaves <sbalneav ltsp org>
Date: Thu Dec 24 20:54:06 2009 -0600
Merry Christmas, Sysadmins everywhere: Sabayon now supports symlinks
lib/storage.py | 77 ++++++++++++++++++++++++++++++++++++++++++++++++--------
1 files changed, 66 insertions(+), 11 deletions(-)
---
diff --git a/lib/storage.py b/lib/storage.py
index 91f6c52..05b614c 100755
--- a/lib/storage.py
+++ b/lib/storage.py
@@ -151,6 +151,7 @@ class ProfileStorage:
metadata = libxml2.newDoc ("1.0")
root = metadata.newChild (None, "metadata", None)
root.newChild (None, "directories", None)
+ root.newChild (None, "links", None)
root.newChild (None, "files", None)
return metadata
@@ -257,6 +258,24 @@ class ProfileStorage:
self.__update_file_or_dir_node (directory_node, source, attributes, metadata)
+ def __update_link_node (self, path, source, attributes, metadata = None):
+ if metadata is None:
+ metadata = self.metadata
+ assert metadata
+
+ files_node = metadata.xpathEval ("/metadata/links")[0]
+
+ # Ensure the directory node exists
+ nodes = files_node.xpathEval ("link[ path='%s']" % path)
+ if len (nodes):
+ link_node = nodes[0]
+ else:
+ link_node = files_node.newChild (None, "link", None)
+ link_node.setProp ("path", path)
+ link_node.setProp ("dest", os.readlink(path))
+
+ self.__update_file_or_dir_node (link_node, source, attributes, metadata)
+
def __unpack (self):
self.__read_metadata ()
@@ -359,7 +378,10 @@ class ProfileStorage:
dst_path = os.path.join (self.temp_path, path)
if not os.path.exists (src_path):
- raise ProfileStorageException (_("Cannot add non-existent file '%s'") % src_path)
+ # change the raise to a dprint, since some files seem to disappear.
+ # raise ProfileStorageException (_("Cannot add non-existent file '%s'") % src_path)
+ dprint (_("Cannot add non-existent file '%s'"), src_path)
+ return
# Remove old version
node = self.__get_node (path)
@@ -371,7 +393,9 @@ class ProfileStorage:
if os.path.isdir (src_path):
self.__update_directory_node (path, source, attributes)
copy_tree (self.temp_path, src_dir, path)
- else:
+ elif os.path.islink (src_path):
+ self.__update_link_node (path, source, attributes)
+ elif os.path.isfile (src_path) and not os.path.islink (src_path):
self.__update_file_node (path, source, attributes)
dirname = os.path.dirname (dst_path)
if not os.path.exists (dirname):
@@ -389,6 +413,15 @@ class ProfileStorage:
return dir_nodes[0]
return None
+ def __get_link_node (self, path, metadata = None):
+ if metadata is None:
+ metadata = self.metadata
+ assert metadata
+ link_nodes = metadata.xpathEval ("/metadata/links/link[ path='%s']" % path)
+ if len (link_nodes) > 0:
+ return link_nodes[0]
+ return None
+
def __get_file_node (self, path, metadata = None):
if metadata is None:
metadata = self.metadata
@@ -404,6 +437,9 @@ class ProfileStorage:
node = self.__get_dir_node (path, metadata)
if node:
return node
+ node = self.__get_link_node (path, metadata)
+ if node:
+ return node
node = self.__get_file_node (path, metadata)
if node:
return node
@@ -436,6 +472,9 @@ class ProfileStorage:
node = self.__get_dir_node (path)
if node:
return "directory"
+ node = self.__get_link_node (path)
+ if node:
+ return "link"
node = self.__get_file_node (path)
if node:
return "file"
@@ -472,6 +511,7 @@ class ProfileStorage:
# preserve the mode of those files, then delete them,
# write new versions, and restore the mode.
+ dprint ("copy_preserving_permissions('%s', '%s')", src, dest)
got_stat = False
try:
buf = os.stat (dest)
@@ -481,10 +521,16 @@ class ProfileStorage:
raise err
if got_stat:
- try:
- os.unlink (dest)
- except OSError, err:
- raise ProfileStorageException (_("Couldn't unlink file '%s'") % dest)
+ if os.path.isdir (dest):
+ try:
+ os.rmdir (dest)
+ except OSError, err:
+ raise ProfileStorageException (_("Couldn't rmdir '%s'") % dest)
+ else:
+ try:
+ os.unlink (dest)
+ except OSError, err:
+ raise ProfileStorageException (_("Couldn't unlink file '%s'") % dest)
# FIXME: we lose the "original" permissions, mtime, etc. with ZIP files.
shutil.copy2 (src, dest)
@@ -498,8 +544,14 @@ class ProfileStorage:
item_type = self.__get_item_type (path)
+ dprint ("Item Type %s", item_type)
+
if item_type == "directory":
copy_tree (dst_dir, self.temp_path, path, None, overwrite)
+ elif item_type == "link":
+ link_node = self.__get_link_node (path)
+ dest = link_node.prop("dest")
+ os.symlink(dest, path)
else:
dst_path = os.path.join (dst_dir, path)
if overwrite or not os.path.exists (dst_path):
@@ -556,10 +608,13 @@ class ProfileStorage:
"""
self.__read_metadata ()
- for node in self.metadata.xpathEval ("/metadata/files/file"):
+ for node in self.metadata.xpathEval ("/metadata/directories/directory"):
self.__foreach_node (node, callback, user_data, source)
- for node in self.metadata.xpathEval ("/metadata/directories/directory"):
+ for node in self.metadata.xpathEval ("/metadata/links/link"):
+ self.__foreach_node (node, callback, user_data, source)
+
+ for node in self.metadata.xpathEval ("/metadata/files/file"):
self.__foreach_node (node, callback, user_data, source)
def save (self):
@@ -602,7 +657,7 @@ class ProfileStorage:
if os.path.isdir (path):
# We need to stop if we are recursing inside a ignored
# directory.
- if util.should_ignore_dir (homedir,
+ if util.should_ignore_dir (homedir,
DIRECTORIES_TO_IGNORE_PROFILE,
os.path.join (homedir, name, f)):
dprint ("Not going inside %s as it is an ignored directory.", path)
@@ -610,12 +665,12 @@ class ProfileStorage:
zip_directory (save_zip,
path,
os.path.join (name, f))
- elif os.path.isfile (path):
+ elif os.path.isfile (path) and not os.path.islink (path):
# Avoid putting in a duplicate file entry
# See bug #476761
if os.path.join (name, f) in zip_filelist:
dprint ("Not adding %s to zipfile since it is already in the file", os.path.join (name, f))
- elif util.should_ignore_file (homedir,
+ elif util.should_ignore_file (homedir,
DIRECTORIES_TO_IGNORE_PROFILE,
FILES_TO_IGNORE,
os.path.join (homedir, name, f)):
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]