commit: 1032cbf4c218741df1c57767fead2d00cc6321d9 Author: Zac Medico <zmedico <AT> gentoo <DOT> org> AuthorDate: Sat May 23 05:53:26 2015 +0000 Commit: Zac Medico <zmedico <AT> gentoo <DOT> org> CommitDate: Tue May 26 19:07:20 2015 +0000 URL: https://gitweb.gentoo.org/proj/portage.git/commit/?id=1032cbf4
quickpkg: support FEATURES=xattr (bug 550006) 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 Acked-by: Brian Dolbec <dolsen <AT> gentoo.org> bin/quickpkg | 16 ++++++++++++++-- pym/portage/dbapi/vartree.py | 18 +++++++++++++++--- pym/portage/util/xattr.py | 20 ++++++++++++++++++++ 3 files changed, 49 insertions(+), 5 deletions(-) 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
