public inbox for gentoo-portage-dev@lists.gentoo.org
 help / color / mirror / Atom feed
* [gentoo-portage-dev] [PATCH] quickpkg: support FEATURES=xattr (bug 550006)
@ 2015-05-23  6:59 Zac Medico
  2015-05-23  7:35 ` [gentoo-portage-dev] [PATCH v2] " Zac Medico
  0 siblings, 1 reply; 2+ messages in thread
From: Zac Medico @ 2015-05-23  6:59 UTC (permalink / raw
  To: gentoo-portage-dev; +Cc: Zac Medico

The xattrs are preserved in pax headers, in the same way that GNU tar
preserves them.

X-Gentoo-Bug: 550006
X-Gentoo-Bug-url: https://bugs.gentoo.org/show_bug.cgi?id=550006
---
 bin/quickpkg                 | 16 ++++++++++++++--
 pym/portage/dbapi/vartree.py | 18 +++++++++++++++---
 pym/portage/util/xattr.py    | 18 ++++++++++++++++++
 3 files changed, 47 insertions(+), 5 deletions(-)
 create mode 100644 pym/portage/util/xattr.py

diff --git a/bin/quickpkg b/bin/quickpkg
index 8b71c3e..726abff 100755
--- a/bin/quickpkg
+++ b/bin/quickpkg
@@ -22,6 +22,7 @@ from portage.dep import Atom, use_reduce
 from portage.exception import (AmbiguousPackageName, InvalidAtom, InvalidData,
 	InvalidDependString, PackageSetNotFound, PermissionDenied)
 from portage.util import ConfigProtect, ensure_dirs, shlex_split
+import portage.util.xattr as _xattr
 from portage.dbapi.vartree import dblink, tar_contents
 from portage.checksum import perform_md5
 from portage._sets import load_default_config, SETPREFIX
@@ -35,6 +36,7 @@ def quickpkg_atom(options, infos, arg, eout):
 	vartree = trees["vartree"]
 	vardb = vartree.dbapi
 	bintree = trees["bintree"]
+	xattr = 'xattr' in settings.features
 
 	include_config = options.include_config == "y"
 	include_unmodified_config = options.include_unmodified_config == "y"
@@ -132,8 +134,11 @@ def quickpkg_atom(options, infos, arg, eout):
 			binpkg_tmpfile = os.path.join(bintree.pkgdir,
 				cpv + ".tbz2." + str(os.getpid()))
 			ensure_dirs(os.path.dirname(binpkg_tmpfile))
-			tar = tarfile.open(binpkg_tmpfile, "w:bz2")
-			tar_contents(contents, root, tar, protect=protect)
+			# The tarfile module will write pax headers holding the
+			# xattrs only if PAX_FORMAT is specified here.
+			tar = tarfile.open(binpkg_tmpfile, "w:bz2",
+				format=tarfile.PAX_FORMAT if xattr else tarfile.DEFAULT_FORMAT)
+			tar_contents(contents, root, tar, protect=protect, xattr=xattr)
 			tar.close()
 			xpak.tbz2(binpkg_tmpfile).recompose_mem(xpdata)
 		finally:
@@ -233,6 +238,13 @@ def quickpkg_main(options, args, eout):
 		eout.eerror("No write access to '%s'" % bintree.pkgdir)
 		return errno.EACCES
 
+	if 'xattr' in portage.settings.features and not hasattr(_xattr, 'getxattr'):
+		eout.eerror("No xattr support library was found, "
+			"so xattrs will not be preserved!")
+		portage.settings.unlock()
+		portage.settings.features.remove('xattr')
+		portage.settings.lock()
+
 	infos = {}
 	infos["successes"] = []
 	infos["missing"] = []
diff --git a/pym/portage/dbapi/vartree.py b/pym/portage/dbapi/vartree.py
index a2fb325..62d880e 100644
--- a/pym/portage/dbapi/vartree.py
+++ b/pym/portage/dbapi/vartree.py
@@ -35,6 +35,7 @@ portage.proxy.lazyimport.lazyimport(globals(),
 	'portage.util.movefile:movefile',
 	'portage.util.path:first_existing,iter_parents',
 	'portage.util.writeable_check:get_ro_checker',
+	'portage.util:xattr@_xattr',
 	'portage.util._dyn_libs.PreservedLibsRegistry:PreservedLibsRegistry',
 	'portage.util._dyn_libs.LinkageMapELF:LinkageMapELF@LinkageMap',
 	'portage.util._async.SchedulerInterface:SchedulerInterface',
@@ -5266,7 +5267,8 @@ def write_contents(contents, root, f):
 			line = "%s %s\n" % (entry_type, relative_filename)
 		f.write(line)
 
-def tar_contents(contents, root, tar, protect=None, onProgress=None):
+def tar_contents(contents, root, tar, protect=None, onProgress=None,
+	xattr=False):
 	os = _os_merge
 	encoding = _encodings['merge']
 
@@ -5384,9 +5386,19 @@ def tar_contents(contents, root, tar, protect=None, onProgress=None):
 				tar.addfile(tarinfo, f)
 				f.close()
 			else:
-				with open(_unicode_encode(path,
+				path_bytes = _unicode_encode(path,
 					encoding=encoding,
-					errors='strict'), 'rb') as f:
+					errors='strict')
+
+				if xattr:
+					# Compatible with GNU tar, which saves the xattrs
+					# under the SCHILY.xattr namespace.
+					for k in _xattr.listxattr(path_bytes):
+						tarinfo.pax_headers['SCHILY.xattr.' +
+							_unicode_decode(k)] = _unicode_decode(
+							_xattr.getxattr(path_bytes, _unicode_encode(k)))
+
+				with open(path_bytes, 'rb') as f:
 					tar.addfile(tarinfo, f)
 
 		else:
diff --git a/pym/portage/util/xattr.py b/pym/portage/util/xattr.py
new file mode 100644
index 0000000..0f7ab6f
--- /dev/null
+++ b/pym/portage/util/xattr.py
@@ -0,0 +1,18 @@
+# Copyright 2015 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+import os as _os
+
+if hasattr(_os, "getxattr"):
+	getxattr = _os.getxattr
+	listxattr = _os.listxattr
+	setxattr = _os.setxattr
+else:
+	try:
+		import xattr as _xattr
+	except ImportError:
+		pass
+	else:
+		getxattr = _xattr.get
+		listxattr = _xattr.list
+		setxattr = _xattr.set
-- 
2.3.5



^ permalink raw reply related	[flat|nested] 2+ messages in thread

* [gentoo-portage-dev] [PATCH v2] quickpkg: support FEATURES=xattr (bug 550006)
  2015-05-23  6:59 [gentoo-portage-dev] [PATCH] quickpkg: support FEATURES=xattr (bug 550006) Zac Medico
@ 2015-05-23  7:35 ` Zac Medico
  0 siblings, 0 replies; 2+ messages in thread
From: Zac Medico @ 2015-05-23  7:35 UTC (permalink / raw
  To: gentoo-portage-dev; +Cc: Zac Medico

The xattrs are preserved in pax headers, in the same way that GNU tar
preserves them.

X-Gentoo-Bug: 550006
X-Gentoo-Bug-url: https://bugs.gentoo.org/show_bug.cgi?id=550006
---
[PATCH v2] adds absolute_import in portage.util.xattr (py 2.x compat)

 bin/quickpkg                 | 16 ++++++++++++++--
 pym/portage/dbapi/vartree.py | 18 +++++++++++++++---
 pym/portage/util/xattr.py    | 20 ++++++++++++++++++++
 3 files changed, 49 insertions(+), 5 deletions(-)
 create mode 100644 pym/portage/util/xattr.py

diff --git a/bin/quickpkg b/bin/quickpkg
index 8b71c3e..726abff 100755
--- a/bin/quickpkg
+++ b/bin/quickpkg
@@ -22,6 +22,7 @@ from portage.dep import Atom, use_reduce
 from portage.exception import (AmbiguousPackageName, InvalidAtom, InvalidData,
 	InvalidDependString, PackageSetNotFound, PermissionDenied)
 from portage.util import ConfigProtect, ensure_dirs, shlex_split
+import portage.util.xattr as _xattr
 from portage.dbapi.vartree import dblink, tar_contents
 from portage.checksum import perform_md5
 from portage._sets import load_default_config, SETPREFIX
@@ -35,6 +36,7 @@ def quickpkg_atom(options, infos, arg, eout):
 	vartree = trees["vartree"]
 	vardb = vartree.dbapi
 	bintree = trees["bintree"]
+	xattr = 'xattr' in settings.features
 
 	include_config = options.include_config == "y"
 	include_unmodified_config = options.include_unmodified_config == "y"
@@ -132,8 +134,11 @@ def quickpkg_atom(options, infos, arg, eout):
 			binpkg_tmpfile = os.path.join(bintree.pkgdir,
 				cpv + ".tbz2." + str(os.getpid()))
 			ensure_dirs(os.path.dirname(binpkg_tmpfile))
-			tar = tarfile.open(binpkg_tmpfile, "w:bz2")
-			tar_contents(contents, root, tar, protect=protect)
+			# The tarfile module will write pax headers holding the
+			# xattrs only if PAX_FORMAT is specified here.
+			tar = tarfile.open(binpkg_tmpfile, "w:bz2",
+				format=tarfile.PAX_FORMAT if xattr else tarfile.DEFAULT_FORMAT)
+			tar_contents(contents, root, tar, protect=protect, xattr=xattr)
 			tar.close()
 			xpak.tbz2(binpkg_tmpfile).recompose_mem(xpdata)
 		finally:
@@ -233,6 +238,13 @@ def quickpkg_main(options, args, eout):
 		eout.eerror("No write access to '%s'" % bintree.pkgdir)
 		return errno.EACCES
 
+	if 'xattr' in portage.settings.features and not hasattr(_xattr, 'getxattr'):
+		eout.eerror("No xattr support library was found, "
+			"so xattrs will not be preserved!")
+		portage.settings.unlock()
+		portage.settings.features.remove('xattr')
+		portage.settings.lock()
+
 	infos = {}
 	infos["successes"] = []
 	infos["missing"] = []
diff --git a/pym/portage/dbapi/vartree.py b/pym/portage/dbapi/vartree.py
index a2fb325..62d880e 100644
--- a/pym/portage/dbapi/vartree.py
+++ b/pym/portage/dbapi/vartree.py
@@ -35,6 +35,7 @@ portage.proxy.lazyimport.lazyimport(globals(),
 	'portage.util.movefile:movefile',
 	'portage.util.path:first_existing,iter_parents',
 	'portage.util.writeable_check:get_ro_checker',
+	'portage.util:xattr@_xattr',
 	'portage.util._dyn_libs.PreservedLibsRegistry:PreservedLibsRegistry',
 	'portage.util._dyn_libs.LinkageMapELF:LinkageMapELF@LinkageMap',
 	'portage.util._async.SchedulerInterface:SchedulerInterface',
@@ -5266,7 +5267,8 @@ def write_contents(contents, root, f):
 			line = "%s %s\n" % (entry_type, relative_filename)
 		f.write(line)
 
-def tar_contents(contents, root, tar, protect=None, onProgress=None):
+def tar_contents(contents, root, tar, protect=None, onProgress=None,
+	xattr=False):
 	os = _os_merge
 	encoding = _encodings['merge']
 
@@ -5384,9 +5386,19 @@ def tar_contents(contents, root, tar, protect=None, onProgress=None):
 				tar.addfile(tarinfo, f)
 				f.close()
 			else:
-				with open(_unicode_encode(path,
+				path_bytes = _unicode_encode(path,
 					encoding=encoding,
-					errors='strict'), 'rb') as f:
+					errors='strict')
+
+				if xattr:
+					# Compatible with GNU tar, which saves the xattrs
+					# under the SCHILY.xattr namespace.
+					for k in _xattr.listxattr(path_bytes):
+						tarinfo.pax_headers['SCHILY.xattr.' +
+							_unicode_decode(k)] = _unicode_decode(
+							_xattr.getxattr(path_bytes, _unicode_encode(k)))
+
+				with open(path_bytes, 'rb') as f:
 					tar.addfile(tarinfo, f)
 
 		else:
diff --git a/pym/portage/util/xattr.py b/pym/portage/util/xattr.py
new file mode 100644
index 0000000..b8c4620
--- /dev/null
+++ b/pym/portage/util/xattr.py
@@ -0,0 +1,20 @@
+# Copyright 2015 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+from __future__ import absolute_import
+
+import os as _os
+
+if hasattr(_os, "getxattr"):
+	getxattr = _os.getxattr
+	listxattr = _os.listxattr
+	setxattr = _os.setxattr
+else:
+	try:
+		import xattr as _xattr
+	except ImportError:
+		pass
+	else:
+		getxattr = _xattr.get
+		listxattr = _xattr.list
+		setxattr = _xattr.set
-- 
2.3.5



^ permalink raw reply related	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2015-05-23  7:35 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-05-23  6:59 [gentoo-portage-dev] [PATCH] quickpkg: support FEATURES=xattr (bug 550006) Zac Medico
2015-05-23  7:35 ` [gentoo-portage-dev] [PATCH v2] " Zac Medico

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox