Gentoo Archives: gentoo-commits

From: "Zac Medico (zmedico)" <zmedico@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] portage r15464 - in main/trunk/pym/portage: . dbapi util
Date: Thu, 25 Feb 2010 21:52:46
Message-Id: E1NkldO-0006oT-Qd@stork.gentoo.org
1 Author: zmedico
2 Date: 2010-02-25 21:52:38 +0000 (Thu, 25 Feb 2010)
3 New Revision: 15464
4
5 Added:
6 main/trunk/pym/portage/util/movefile.py
7 Modified:
8 main/trunk/pym/portage/__init__.py
9 main/trunk/pym/portage/dbapi/vartree.py
10 Log:
11 Move portage.movefile to portage.util.movefile.
12
13
14 Modified: main/trunk/pym/portage/__init__.py
15 ===================================================================
16 --- main/trunk/pym/portage/__init__.py 2010-02-25 21:38:30 UTC (rev 15463)
17 +++ main/trunk/pym/portage/__init__.py 2010-02-25 21:52:38 UTC (rev 15464)
18 @@ -130,6 +130,7 @@
19 'portage.util.env_update:env_update',
20 'portage.util.ExtractKernelVersion:ExtractKernelVersion',
21 'portage.util.listdir:cacheddir,listdir',
22 + 'portage.util.movefile:movefile',
23 'portage.versions',
24 'portage.versions:best,catpkgsplit,catsplit,cpv_getkey,' + \
25 'cpv_getkey@getCPFromCPV,endversion_keys,' + \
26 @@ -638,223 +639,6 @@
27 raise portage.exception.PortageException(
28 "mv '%s' '%s'" % (src, dest))
29
30 -def movefile(src, dest, newmtime=None, sstat=None, mysettings=None,
31 - hardlink_candidates=None, encoding=_encodings['fs']):
32 - """moves a file from src to dest, preserving all permissions and attributes; mtime will
33 - be preserved even when moving across filesystems. Returns true on success and false on
34 - failure. Move is atomic."""
35 - #print "movefile("+str(src)+","+str(dest)+","+str(newmtime)+","+str(sstat)+")"
36 -
37 - if mysettings is None:
38 - global settings
39 - mysettings = settings
40 -
41 - selinux_enabled = mysettings.selinux_enabled()
42 - if selinux_enabled:
43 - selinux = _unicode_module_wrapper(_selinux, encoding=encoding)
44 -
45 - lchown = _unicode_func_wrapper(data.lchown, encoding=encoding)
46 - os = _unicode_module_wrapper(_os,
47 - encoding=encoding, overrides=_os_overrides)
48 - shutil = _unicode_module_wrapper(_shutil, encoding=encoding)
49 -
50 - try:
51 - if not sstat:
52 - sstat=os.lstat(src)
53 -
54 - except SystemExit as e:
55 - raise
56 - except Exception as e:
57 - print(_("!!! Stating source file failed... movefile()"))
58 - print("!!!",e)
59 - return None
60 -
61 - destexists=1
62 - try:
63 - dstat=os.lstat(dest)
64 - except (OSError, IOError):
65 - dstat=os.lstat(os.path.dirname(dest))
66 - destexists=0
67 -
68 - if bsd_chflags:
69 - if destexists and dstat.st_flags != 0:
70 - bsd_chflags.lchflags(dest, 0)
71 - # Use normal stat/chflags for the parent since we want to
72 - # follow any symlinks to the real parent directory.
73 - pflags = os.stat(os.path.dirname(dest)).st_flags
74 - if pflags != 0:
75 - bsd_chflags.chflags(os.path.dirname(dest), 0)
76 -
77 - if destexists:
78 - if stat.S_ISLNK(dstat[stat.ST_MODE]):
79 - try:
80 - os.unlink(dest)
81 - destexists=0
82 - except SystemExit as e:
83 - raise
84 - except Exception as e:
85 - pass
86 -
87 - if stat.S_ISLNK(sstat[stat.ST_MODE]):
88 - try:
89 - target=os.readlink(src)
90 - if mysettings and mysettings["D"]:
91 - if target.find(mysettings["D"])==0:
92 - target=target[len(mysettings["D"]):]
93 - if destexists and not stat.S_ISDIR(dstat[stat.ST_MODE]):
94 - os.unlink(dest)
95 - if selinux_enabled:
96 - selinux.symlink(target, dest, src)
97 - else:
98 - os.symlink(target,dest)
99 - lchown(dest,sstat[stat.ST_UID],sstat[stat.ST_GID])
100 - # utime() only works on the target of a symlink, so it's not
101 - # possible to perserve mtime on symlinks.
102 - return os.lstat(dest)[stat.ST_MTIME]
103 - except SystemExit as e:
104 - raise
105 - except Exception as e:
106 - print(_("!!! failed to properly create symlink:"))
107 - print("!!!",dest,"->",target)
108 - print("!!!",e)
109 - return None
110 -
111 - hardlinked = False
112 - # Since identical files might be merged to multiple filesystems,
113 - # so os.link() calls might fail for some paths, so try them all.
114 - # For atomic replacement, first create the link as a temp file
115 - # and them use os.rename() to replace the destination.
116 - if hardlink_candidates:
117 - head, tail = os.path.split(dest)
118 - hardlink_tmp = os.path.join(head, ".%s._portage_merge_.%s" % \
119 - (tail, os.getpid()))
120 - try:
121 - os.unlink(hardlink_tmp)
122 - except OSError as e:
123 - if e.errno != errno.ENOENT:
124 - writemsg(_("!!! Failed to remove hardlink temp file: %s\n") % \
125 - (hardlink_tmp,), noiselevel=-1)
126 - writemsg("!!! %s\n" % (e,), noiselevel=-1)
127 - return None
128 - del e
129 - for hardlink_src in hardlink_candidates:
130 - try:
131 - os.link(hardlink_src, hardlink_tmp)
132 - except OSError:
133 - continue
134 - else:
135 - try:
136 - os.rename(hardlink_tmp, dest)
137 - except OSError as e:
138 - writemsg(_("!!! Failed to rename %s to %s\n") % \
139 - (hardlink_tmp, dest), noiselevel=-1)
140 - writemsg("!!! %s\n" % (e,), noiselevel=-1)
141 - return None
142 - hardlinked = True
143 - break
144 -
145 - renamefailed=1
146 - if hardlinked:
147 - renamefailed = False
148 - if not hardlinked and (selinux_enabled or sstat.st_dev == dstat.st_dev):
149 - try:
150 - if selinux_enabled:
151 - ret = selinux.rename(src, dest)
152 - else:
153 - ret=os.rename(src,dest)
154 - renamefailed=0
155 - except OSError as e:
156 - if e.errno != errno.EXDEV:
157 - # Some random error.
158 - print(_("!!! Failed to move %(src)s to %(dest)s") % {"src": src, "dest": dest})
159 - print("!!!",e)
160 - return None
161 - # Invalid cross-device-link 'bind' mounted or actually Cross-Device
162 - if renamefailed:
163 - didcopy=0
164 - if stat.S_ISREG(sstat[stat.ST_MODE]):
165 - try: # For safety copy then move it over.
166 - if selinux_enabled:
167 - selinux.copyfile(src, dest + "#new")
168 - selinux.rename(dest + "#new", dest)
169 - else:
170 - shutil.copyfile(src,dest+"#new")
171 - os.rename(dest+"#new",dest)
172 - didcopy=1
173 - except SystemExit as e:
174 - raise
175 - except Exception as e:
176 - print(_('!!! copy %(src)s -> %(dest)s failed.') % {"src": src, "dest": dest})
177 - print("!!!",e)
178 - return None
179 - else:
180 - #we don't yet handle special, so we need to fall back to /bin/mv
181 - a = process.spawn([MOVE_BINARY, '-f', src, dest], env=os.environ)
182 - if a != os.EX_OK:
183 - writemsg(_("!!! Failed to move special file:\n"), noiselevel=-1)
184 - writemsg(_("!!! '%(src)s' to '%(dest)s'\n") % \
185 - {"src": _unicode_decode(src, encoding=encoding),
186 - "dest": _unicode_decode(dest, encoding=encoding)}, noiselevel=-1)
187 - writemsg("!!! %s\n" % a, noiselevel=-1)
188 - return None # failure
189 - try:
190 - if didcopy:
191 - if stat.S_ISLNK(sstat[stat.ST_MODE]):
192 - lchown(dest,sstat[stat.ST_UID],sstat[stat.ST_GID])
193 - else:
194 - os.chown(dest,sstat[stat.ST_UID],sstat[stat.ST_GID])
195 - os.chmod(dest, stat.S_IMODE(sstat[stat.ST_MODE])) # Sticky is reset on chown
196 - os.unlink(src)
197 - except SystemExit as e:
198 - raise
199 - except Exception as e:
200 - print(_("!!! Failed to chown/chmod/unlink in movefile()"))
201 - print("!!!",dest)
202 - print("!!!",e)
203 - return None
204 -
205 - # Always use stat_obj[stat.ST_MTIME] for the integral timestamp which
206 - # is returned, since the stat_obj.st_mtime float attribute rounds *up*
207 - # if the nanosecond part of the timestamp is 999999881 ns or greater.
208 - try:
209 - if hardlinked:
210 - newmtime = os.stat(dest)[stat.ST_MTIME]
211 - else:
212 - # Note: It is not possible to preserve nanosecond precision
213 - # (supported in POSIX.1-2008 via utimensat) with the IEEE 754
214 - # double precision float which only has a 53 bit significand.
215 - if newmtime is not None:
216 - os.utime(dest, (newmtime, newmtime))
217 - else:
218 - newmtime = sstat[stat.ST_MTIME]
219 - if renamefailed:
220 - # If rename succeeded then timestamps are automatically
221 - # preserved with complete precision because the source
222 - # and destination inode are the same. Otherwise, round
223 - # down to the nearest whole second since python's float
224 - # st_mtime cannot be used to preserve the st_mtim.tv_nsec
225 - # field with complete precision. Note that we have to use
226 - # stat_obj[stat.ST_MTIME] here because the float
227 - # stat_obj.st_mtime rounds *up* sometimes.
228 - os.utime(dest, (newmtime, newmtime))
229 - except OSError:
230 - # The utime can fail here with EPERM even though the move succeeded.
231 - # Instead of failing, use stat to return the mtime if possible.
232 - try:
233 - newmtime = os.stat(dest)[stat.ST_MTIME]
234 - except OSError as e:
235 - writemsg(_("!!! Failed to stat in movefile()\n"), noiselevel=-1)
236 - writemsg("!!! %s\n" % dest, noiselevel=-1)
237 - writemsg("!!! %s\n" % str(e), noiselevel=-1)
238 - return None
239 -
240 - if bsd_chflags:
241 - # Restore the flags we saved before moving
242 - if pflags:
243 - bsd_chflags.chflags(os.path.dirname(dest), pflags)
244 -
245 - return newmtime
246 -
247 def merge(mycat, mypkg, pkgloc, infloc, myroot, mysettings, myebuild=None,
248 mytree=None, mydbapi=None, vartree=None, prev_mtimes=None, blockers=None,
249 scheduler=None):
250
251 Modified: main/trunk/pym/portage/dbapi/vartree.py
252 ===================================================================
253 --- main/trunk/pym/portage/dbapi/vartree.py 2010-02-25 21:38:30 UTC (rev 15463)
254 +++ main/trunk/pym/portage/dbapi/vartree.py 2010-02-25 21:52:38 UTC (rev 15464)
255 @@ -39,8 +39,9 @@
256 InvalidData, InvalidPackageName, \
257 FileNotFound, PermissionDenied, UnsupportedAPIException
258 from portage.localization import _
259 +from portage.util.movefile import movefile
260
261 -from portage import abssymlink, movefile, _movefile, bsd_chflags
262 +from portage import abssymlink, _movefile, bsd_chflags
263
264 # This is a special version of the os module, wrapped for unicode support.
265 from portage import os
266
267 Added: main/trunk/pym/portage/util/movefile.py
268 ===================================================================
269 --- main/trunk/pym/portage/util/movefile.py (rev 0)
270 +++ main/trunk/pym/portage/util/movefile.py 2010-02-25 21:52:38 UTC (rev 15464)
271 @@ -0,0 +1,234 @@
272 +# Copyright 2010 Gentoo Foundation
273 +# Distributed under the terms of the GNU General Public License v2
274 +# $Id$
275 +
276 +__all__ = ['movefile']
277 +
278 +import errno
279 +import os as _os
280 +import shutil as _shutil
281 +import stat
282 +
283 +import portage
284 +from portage import bsd_chflags, _encodings, _os_overrides, _selinux, \
285 + _unicode_decode, _unicode_func_wrapper, _unicode_module_wrapper
286 +from portage.const import MOVE_BINARY
287 +from portage.localization import _
288 +from portage.process import spawn
289 +from portage.util import writemsg
290 +
291 +def movefile(src, dest, newmtime=None, sstat=None, mysettings=None,
292 + hardlink_candidates=None, encoding=_encodings['fs']):
293 + """moves a file from src to dest, preserving all permissions and attributes; mtime will
294 + be preserved even when moving across filesystems. Returns true on success and false on
295 + failure. Move is atomic."""
296 + #print "movefile("+str(src)+","+str(dest)+","+str(newmtime)+","+str(sstat)+")"
297 +
298 + if mysettings is None:
299 + mysettings = portage.settings
300 +
301 + selinux_enabled = mysettings.selinux_enabled()
302 + if selinux_enabled:
303 + selinux = _unicode_module_wrapper(_selinux, encoding=encoding)
304 +
305 + lchown = _unicode_func_wrapper(portage.data.lchown, encoding=encoding)
306 + os = _unicode_module_wrapper(_os,
307 + encoding=encoding, overrides=_os_overrides)
308 + shutil = _unicode_module_wrapper(_shutil, encoding=encoding)
309 +
310 + try:
311 + if not sstat:
312 + sstat=os.lstat(src)
313 +
314 + except SystemExit as e:
315 + raise
316 + except Exception as e:
317 + print(_("!!! Stating source file failed... movefile()"))
318 + print("!!!",e)
319 + return None
320 +
321 + destexists=1
322 + try:
323 + dstat=os.lstat(dest)
324 + except (OSError, IOError):
325 + dstat=os.lstat(os.path.dirname(dest))
326 + destexists=0
327 +
328 + if bsd_chflags:
329 + if destexists and dstat.st_flags != 0:
330 + bsd_chflags.lchflags(dest, 0)
331 + # Use normal stat/chflags for the parent since we want to
332 + # follow any symlinks to the real parent directory.
333 + pflags = os.stat(os.path.dirname(dest)).st_flags
334 + if pflags != 0:
335 + bsd_chflags.chflags(os.path.dirname(dest), 0)
336 +
337 + if destexists:
338 + if stat.S_ISLNK(dstat[stat.ST_MODE]):
339 + try:
340 + os.unlink(dest)
341 + destexists=0
342 + except SystemExit as e:
343 + raise
344 + except Exception as e:
345 + pass
346 +
347 + if stat.S_ISLNK(sstat[stat.ST_MODE]):
348 + try:
349 + target=os.readlink(src)
350 + if mysettings and mysettings["D"]:
351 + if target.find(mysettings["D"])==0:
352 + target=target[len(mysettings["D"]):]
353 + if destexists and not stat.S_ISDIR(dstat[stat.ST_MODE]):
354 + os.unlink(dest)
355 + if selinux_enabled:
356 + selinux.symlink(target, dest, src)
357 + else:
358 + os.symlink(target,dest)
359 + lchown(dest,sstat[stat.ST_UID],sstat[stat.ST_GID])
360 + # utime() only works on the target of a symlink, so it's not
361 + # possible to perserve mtime on symlinks.
362 + return os.lstat(dest)[stat.ST_MTIME]
363 + except SystemExit as e:
364 + raise
365 + except Exception as e:
366 + print(_("!!! failed to properly create symlink:"))
367 + print("!!!",dest,"->",target)
368 + print("!!!",e)
369 + return None
370 +
371 + hardlinked = False
372 + # Since identical files might be merged to multiple filesystems,
373 + # so os.link() calls might fail for some paths, so try them all.
374 + # For atomic replacement, first create the link as a temp file
375 + # and them use os.rename() to replace the destination.
376 + if hardlink_candidates:
377 + head, tail = os.path.split(dest)
378 + hardlink_tmp = os.path.join(head, ".%s._portage_merge_.%s" % \
379 + (tail, os.getpid()))
380 + try:
381 + os.unlink(hardlink_tmp)
382 + except OSError as e:
383 + if e.errno != errno.ENOENT:
384 + writemsg(_("!!! Failed to remove hardlink temp file: %s\n") % \
385 + (hardlink_tmp,), noiselevel=-1)
386 + writemsg("!!! %s\n" % (e,), noiselevel=-1)
387 + return None
388 + del e
389 + for hardlink_src in hardlink_candidates:
390 + try:
391 + os.link(hardlink_src, hardlink_tmp)
392 + except OSError:
393 + continue
394 + else:
395 + try:
396 + os.rename(hardlink_tmp, dest)
397 + except OSError as e:
398 + writemsg(_("!!! Failed to rename %s to %s\n") % \
399 + (hardlink_tmp, dest), noiselevel=-1)
400 + writemsg("!!! %s\n" % (e,), noiselevel=-1)
401 + return None
402 + hardlinked = True
403 + break
404 +
405 + renamefailed=1
406 + if hardlinked:
407 + renamefailed = False
408 + if not hardlinked and (selinux_enabled or sstat.st_dev == dstat.st_dev):
409 + try:
410 + if selinux_enabled:
411 + selinux.rename(src, dest)
412 + else:
413 + os.rename(src,dest)
414 + renamefailed=0
415 + except OSError as e:
416 + if e.errno != errno.EXDEV:
417 + # Some random error.
418 + print(_("!!! Failed to move %(src)s to %(dest)s") % {"src": src, "dest": dest})
419 + print("!!!",e)
420 + return None
421 + # Invalid cross-device-link 'bind' mounted or actually Cross-Device
422 + if renamefailed:
423 + didcopy=0
424 + if stat.S_ISREG(sstat[stat.ST_MODE]):
425 + try: # For safety copy then move it over.
426 + if selinux_enabled:
427 + selinux.copyfile(src, dest + "#new")
428 + selinux.rename(dest + "#new", dest)
429 + else:
430 + shutil.copyfile(src,dest+"#new")
431 + os.rename(dest+"#new",dest)
432 + didcopy=1
433 + except SystemExit as e:
434 + raise
435 + except Exception as e:
436 + print(_('!!! copy %(src)s -> %(dest)s failed.') % {"src": src, "dest": dest})
437 + print("!!!",e)
438 + return None
439 + else:
440 + #we don't yet handle special, so we need to fall back to /bin/mv
441 + a = spawn([MOVE_BINARY, '-f', src, dest], env=os.environ)
442 + if a != os.EX_OK:
443 + writemsg(_("!!! Failed to move special file:\n"), noiselevel=-1)
444 + writemsg(_("!!! '%(src)s' to '%(dest)s'\n") % \
445 + {"src": _unicode_decode(src, encoding=encoding),
446 + "dest": _unicode_decode(dest, encoding=encoding)}, noiselevel=-1)
447 + writemsg("!!! %s\n" % a, noiselevel=-1)
448 + return None # failure
449 + try:
450 + if didcopy:
451 + if stat.S_ISLNK(sstat[stat.ST_MODE]):
452 + lchown(dest,sstat[stat.ST_UID],sstat[stat.ST_GID])
453 + else:
454 + os.chown(dest,sstat[stat.ST_UID],sstat[stat.ST_GID])
455 + os.chmod(dest, stat.S_IMODE(sstat[stat.ST_MODE])) # Sticky is reset on chown
456 + os.unlink(src)
457 + except SystemExit as e:
458 + raise
459 + except Exception as e:
460 + print(_("!!! Failed to chown/chmod/unlink in movefile()"))
461 + print("!!!",dest)
462 + print("!!!",e)
463 + return None
464 +
465 + # Always use stat_obj[stat.ST_MTIME] for the integral timestamp which
466 + # is returned, since the stat_obj.st_mtime float attribute rounds *up*
467 + # if the nanosecond part of the timestamp is 999999881 ns or greater.
468 + try:
469 + if hardlinked:
470 + newmtime = os.stat(dest)[stat.ST_MTIME]
471 + else:
472 + # Note: It is not possible to preserve nanosecond precision
473 + # (supported in POSIX.1-2008 via utimensat) with the IEEE 754
474 + # double precision float which only has a 53 bit significand.
475 + if newmtime is not None:
476 + os.utime(dest, (newmtime, newmtime))
477 + else:
478 + newmtime = sstat[stat.ST_MTIME]
479 + if renamefailed:
480 + # If rename succeeded then timestamps are automatically
481 + # preserved with complete precision because the source
482 + # and destination inode are the same. Otherwise, round
483 + # down to the nearest whole second since python's float
484 + # st_mtime cannot be used to preserve the st_mtim.tv_nsec
485 + # field with complete precision. Note that we have to use
486 + # stat_obj[stat.ST_MTIME] here because the float
487 + # stat_obj.st_mtime rounds *up* sometimes.
488 + os.utime(dest, (newmtime, newmtime))
489 + except OSError:
490 + # The utime can fail here with EPERM even though the move succeeded.
491 + # Instead of failing, use stat to return the mtime if possible.
492 + try:
493 + newmtime = os.stat(dest)[stat.ST_MTIME]
494 + except OSError as e:
495 + writemsg(_("!!! Failed to stat in movefile()\n"), noiselevel=-1)
496 + writemsg("!!! %s\n" % dest, noiselevel=-1)
497 + writemsg("!!! %s\n" % str(e), noiselevel=-1)
498 + return None
499 +
500 + if bsd_chflags:
501 + # Restore the flags we saved before moving
502 + if pflags:
503 + bsd_chflags.chflags(os.path.dirname(dest), pflags)
504 +
505 + return newmtime
506
507
508 Property changes on: main/trunk/pym/portage/util/movefile.py
509 ___________________________________________________________________
510 Added: svn:keywords
511 + Id