| OLD | NEW |
| 1 # Copyright 1998-2010 Gentoo Foundation | 1 # Copyright 1998-2010 Gentoo Foundation |
| 2 # Distributed under the terms of the GNU General Public License v2 | 2 # Distributed under the terms of the GNU General Public License v2 |
| 3 | 3 |
| 4 import errno | 4 import errno |
| 5 import logging | 5 import logging |
| 6 | 6 |
| 7 try: | 7 try: |
| 8 import cPickle as pickle | 8 import cPickle as pickle |
| 9 except ImportError: | 9 except ImportError: |
| 10 import pickle | 10 import pickle |
| 11 | 11 |
| 12 from portage import os | 12 from portage import os |
| 13 from portage import _encodings | 13 from portage import _encodings |
| 14 from portage import _os_merge | 14 from portage import _os_merge |
| 15 from portage import _unicode_encode | 15 from portage import _unicode_encode |
| 16 from portage.exception import PermissionDenied | 16 from portage.exception import PermissionDenied |
| 17 from portage.localization import _ | 17 from portage.localization import _ |
| 18 from portage.util import atomic_ofstream | 18 from portage.util import atomic_ofstream |
| 19 from portage.util import writemsg_level | 19 from portage.util import writemsg_level |
| 20 from portage.versions import cpv_getkey | 20 from portage.versions import cpv_getkey |
| 21 from portage.locks import lockfile, unlockfile |
| 21 | 22 |
| 22 class PreservedLibsRegistry(object): | 23 class PreservedLibsRegistry(object): |
| 23 """ This class handles the tracking of preserved library objects """ | 24 """ This class handles the tracking of preserved library objects """ |
| 24 » def __init__(self, root, filename, autocommit=True): | 25 » def __init__(self, root, filename): |
| 25 """ | 26 """ |
| 26 @param root: root used to check existence of paths in pr
uneNonExisting | 27 @param root: root used to check existence of paths in pr
uneNonExisting |
| 27 @type root: String | 28 @type root: String |
| 28 @param filename: absolute path for saving the preserved
libs records | 29 @param filename: absolute path for saving the preserved
libs records |
| 29 @type filename: String | 30 @type filename: String |
| 30 @param autocommit: determines if the file is written aft
er every update | |
| 31 @type autocommit: Boolean | |
| 32 """ | 31 """ |
| 33 self._root = root | 32 self._root = root |
| 34 self._filename = filename | 33 self._filename = filename |
| 35 » » self._autocommit = autocommit | 34 » » self._data = None |
| 36 » » self.load() | 35 » » self._lock = None |
| 37 » » self.pruneNonExisting() | 36 |
| 37 » def lock(self): |
| 38 » » """Grab an exclusive lock on the preserved libs registry.""" |
| 39 » » self._lock = lockfile(self._filename) |
| 40 |
| 41 » def unlock(self): |
| 42 » » """Release our exclusive lock on the preserved libs registry.""" |
| 43 » » unlockfile(self._lock) |
| 38 | 44 |
| 39 def load(self): | 45 def load(self): |
| 40 """ Reload the registry data from file """ | 46 """ Reload the registry data from file """ |
| 41 self._data = None | 47 self._data = None |
| 42 try: | 48 try: |
| 43 self._data = pickle.load( | 49 self._data = pickle.load( |
| 44 open(_unicode_encode(self._filename, | 50 open(_unicode_encode(self._filename, |
| 45 encoding=_encodings['fs'], errors='stric
t'), 'rb')) | 51 encoding=_encodings['fs'], errors='stric
t'), 'rb')) |
| 46 except (ValueError, pickle.UnpicklingError) as e: | 52 except (ValueError, pickle.UnpicklingError) as e: |
| 47 writemsg_level(_("!!! Error loading '%s': %s\n") % \ | 53 writemsg_level(_("!!! Error loading '%s': %s\n") % \ |
| 48 (self._filename, e), level=logging.ERROR, noisel
evel=-1) | 54 (self._filename, e), level=logging.ERROR, noisel
evel=-1) |
| 49 except (EOFError, IOError) as e: | 55 except (EOFError, IOError) as e: |
| 50 if isinstance(e, EOFError) or e.errno == errno.ENOENT: | 56 if isinstance(e, EOFError) or e.errno == errno.ENOENT: |
| 51 pass | 57 pass |
| 52 elif e.errno == PermissionDenied.errno: | 58 elif e.errno == PermissionDenied.errno: |
| 53 » » » » raise PermissionDenied(self._filename) | 59 » » » » pass |
| 54 else: | 60 else: |
| 55 raise | 61 raise |
| 56 if self._data is None: | 62 if self._data is None: |
| 57 self._data = {} | 63 self._data = {} |
| 58 self._data_orig = self._data.copy() | 64 self._data_orig = self._data.copy() |
| 65 self.pruneNonExisting() |
| 66 |
| 59 def store(self): | 67 def store(self): |
| 60 » » """ Store the registry data to file. No need to call this if aut
ocommit | 68 » » """ Store the registry data to file """ |
| 61 » » was enabled. | |
| 62 » » """ | |
| 63 if os.environ.get("SANDBOX_ON") == "1" or \ | 69 if os.environ.get("SANDBOX_ON") == "1" or \ |
| 64 self._data == self._data_orig: | 70 self._data == self._data_orig: |
| 65 return | 71 return |
| 66 try: | 72 try: |
| 67 f = atomic_ofstream(self._filename, 'wb') | 73 f = atomic_ofstream(self._filename, 'wb') |
| 68 pickle.dump(self._data, f, protocol=2) | 74 pickle.dump(self._data, f, protocol=2) |
| 69 f.close() | 75 f.close() |
| 70 except EnvironmentError as e: | 76 except EnvironmentError as e: |
| 71 if e.errno != PermissionDenied.errno: | 77 if e.errno != PermissionDenied.errno: |
| 72 writemsg_level("!!! %s %s\n" % (e, self._filenam
e), | 78 writemsg_level("!!! %s %s\n" % (e, self._filenam
e), |
| (...skipping 14 matching lines...) Expand all Loading... |
| 87 @param paths: absolute paths of objects that got preserv
ed during an update | 93 @param paths: absolute paths of objects that got preserv
ed during an update |
| 88 @type paths: List | 94 @type paths: List |
| 89 """ | 95 """ |
| 90 cp = cpv_getkey(cpv) | 96 cp = cpv_getkey(cpv) |
| 91 cps = cp+":"+slot | 97 cps = cp+":"+slot |
| 92 if len(paths) == 0 and cps in self._data \ | 98 if len(paths) == 0 and cps in self._data \ |
| 93 and self._data[cps][0] == cpv and int(self._data
[cps][1]) == int(counter): | 99 and self._data[cps][0] == cpv and int(self._data
[cps][1]) == int(counter): |
| 94 del self._data[cps] | 100 del self._data[cps] |
| 95 elif len(paths) > 0: | 101 elif len(paths) > 0: |
| 96 self._data[cps] = (cpv, counter, paths) | 102 self._data[cps] = (cpv, counter, paths) |
| 97 if self._autocommit: | |
| 98 self.store() | |
| 99 | 103 |
| 100 def unregister(self, cpv, slot, counter): | 104 def unregister(self, cpv, slot, counter): |
| 101 """ Remove a previous registration of preserved objects for the
given package. | 105 """ Remove a previous registration of preserved objects for the
given package. |
| 102 @param cpv: package instance whose records should be rem
oved | 106 @param cpv: package instance whose records should be rem
oved |
| 103 @type cpv: CPV (as String) | 107 @type cpv: CPV (as String) |
| 104 @param slot: the value of SLOT of the given package inst
ance | 108 @param slot: the value of SLOT of the given package inst
ance |
| 105 @type slot: String | 109 @type slot: String |
| 106 """ | 110 """ |
| 107 self.register(cpv, slot, counter, []) | 111 self.register(cpv, slot, counter, []) |
| 108 | 112 |
| 109 def pruneNonExisting(self): | 113 def pruneNonExisting(self): |
| 110 """ Remove all records for objects that no longer exist on the f
ilesystem. """ | 114 """ Remove all records for objects that no longer exist on the f
ilesystem. """ |
| 111 | 115 |
| 112 os = _os_merge | 116 os = _os_merge |
| 113 | 117 |
| 114 for cps in list(self._data): | 118 for cps in list(self._data): |
| 115 cpv, counter, paths = self._data[cps] | 119 cpv, counter, paths = self._data[cps] |
| 116 paths = [f for f in paths \ | 120 paths = [f for f in paths \ |
| 117 if os.path.exists(os.path.join(self._root, f.lst
rip(os.sep)))] | 121 if os.path.exists(os.path.join(self._root, f.lst
rip(os.sep)))] |
| 118 if len(paths) > 0: | 122 if len(paths) > 0: |
| 119 self._data[cps] = (cpv, counter, paths) | 123 self._data[cps] = (cpv, counter, paths) |
| 120 else: | 124 else: |
| 121 del self._data[cps] | 125 del self._data[cps] |
| 122 if self._autocommit: | |
| 123 self.store() | |
| 124 | 126 |
| 125 def hasEntries(self): | 127 def hasEntries(self): |
| 126 """ Check if this registry contains any records. """ | 128 """ Check if this registry contains any records. """ |
| 129 if self._data is None: |
| 130 self.load() |
| 127 return len(self._data) > 0 | 131 return len(self._data) > 0 |
| 128 | 132 |
| 129 def getPreservedLibs(self): | 133 def getPreservedLibs(self): |
| 130 """ Return a mapping of packages->preserved objects. | 134 """ Return a mapping of packages->preserved objects. |
| 131 @returns mapping of package instances to preserved objec
ts | 135 @returns mapping of package instances to preserved objec
ts |
| 132 @rtype Dict cpv->list-of-paths | 136 @rtype Dict cpv->list-of-paths |
| 133 """ | 137 """ |
| 138 if self._data is None: |
| 139 self.load() |
| 134 rValue = {} | 140 rValue = {} |
| 135 for cps in self._data: | 141 for cps in self._data: |
| 136 rValue[self._data[cps][0]] = self._data[cps][2] | 142 rValue[self._data[cps][0]] = self._data[cps][2] |
| 137 return rValue | 143 return rValue |
| OLD | NEW |