Gentoo Archives: gentoo-commits

From: "Fabian Groffen (grobian)" <grobian@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] portage r15481 - in main/branches/prefix: bin pym/_emerge pym/portage pym/portage/dbapi pym/portage/package/ebuild pym/portage/util
Date: Sat, 27 Feb 2010 19:21:15
Message-Id: E1NlSDu-0000bs-HH@stork.gentoo.org
1 Author: grobian
2 Date: 2010-02-27 19:21:09 +0000 (Sat, 27 Feb 2010)
3 New Revision: 15481
4
5 Added:
6 main/branches/prefix/pym/portage/util/ExtractKernelVersion.py
7 main/branches/prefix/pym/portage/util/digestgen.py
8 main/branches/prefix/pym/portage/util/env_update.py
9 Modified:
10 main/branches/prefix/bin/repoman
11 main/branches/prefix/pym/_emerge/Scheduler.py
12 main/branches/prefix/pym/portage/__init__.py
13 main/branches/prefix/pym/portage/dbapi/vartree.py
14 main/branches/prefix/pym/portage/package/ebuild/doebuild.py
15 Log:
16 Merged from trunk -r15451:15455
17
18 | 15452 | Move env_update to portage.util.env_update.envupdate. |
19 | zmedico | |
20
21 | 15453 | Move ExtractKernelVersion |
22 | zmedico | portage.util.ExtractKernelVersion. |
23
24 | 15454 | Move digestgen to portage.util.digestgen. |
25 | zmedico | |
26
27 | 15455 | Define 'long' for Python 3. |
28 | arfrever | |
29
30
31 Modified: main/branches/prefix/bin/repoman
32 ===================================================================
33 --- main/branches/prefix/bin/repoman 2010-02-27 19:01:26 UTC (rev 15480)
34 +++ main/branches/prefix/bin/repoman 2010-02-27 19:21:09 UTC (rev 15481)
35 @@ -75,6 +75,7 @@
36 green, nocolor, red, turquoise, yellow
37 from portage.output import ConsoleStyleFile, StyleWriter
38 from portage.util import cmp_sort_key, writemsg_level
39 +from portage.util.digestgen import digestgen
40
41 if sys.hexversion >= 0x3000000:
42 basestring = str
43 @@ -1011,7 +1012,7 @@
44 portage._doebuild_manifest_exempt_depend -= 1
45
46 repoman_settings["O"] = checkdir
47 - if not portage.digestgen(mysettings=repoman_settings, myportdb=portdb):
48 + if not digestgen(mysettings=repoman_settings, myportdb=portdb):
49 print("Unable to generate manifest.")
50 dofail = 1
51 if options.mode == "manifest":
52 @@ -2339,7 +2340,7 @@
53 mydone=[]
54 if repolevel==3: # In a package dir
55 repoman_settings["O"] = startdir
56 - portage.digestgen(mysettings=repoman_settings, myportdb=portdb)
57 + digestgen(mysettings=repoman_settings, myportdb=portdb)
58 elif repolevel==2: # In a category dir
59 for x in myfiles:
60 xs=x.split("/")
61 @@ -2353,7 +2354,7 @@
62 repoman_settings["O"] = os.path.join(startdir, xs[0])
63 if not os.path.isdir(repoman_settings["O"]):
64 continue
65 - portage.digestgen(mysettings=repoman_settings, myportdb=portdb)
66 + digestgen(mysettings=repoman_settings, myportdb=portdb)
67 elif repolevel==1: # repo-cvsroot
68 print(green("RepoMan sez:"), "\"You're rather crazy... doing the entire repository.\"\n")
69 for x in myfiles:
70 @@ -2368,7 +2369,7 @@
71 repoman_settings["O"] = os.path.join(startdir, xs[0], xs[1])
72 if not os.path.isdir(repoman_settings["O"]):
73 continue
74 - portage.digestgen(mysettings=repoman_settings, myportdb=portdb)
75 + digestgen(mysettings=repoman_settings, myportdb=portdb)
76 else:
77 print(red("I'm confused... I don't know where I am!"))
78 sys.exit(1)
79
80 Modified: main/branches/prefix/pym/_emerge/Scheduler.py
81 ===================================================================
82 --- main/branches/prefix/pym/_emerge/Scheduler.py 2010-02-27 19:01:26 UTC (rev 15480)
83 +++ main/branches/prefix/pym/_emerge/Scheduler.py 2010-02-27 19:21:09 UTC (rev 15481)
84 @@ -24,6 +24,7 @@
85 from portage.sets import SETPREFIX
86 from portage.sets.base import InternalPackageSet
87 from portage.util import writemsg, writemsg_level
88 +from portage.util.digestgen import digestgen
89
90 from _emerge.BinpkgPrefetcher import BinpkgPrefetcher
91 from _emerge.Blocker import Blocker
92 @@ -591,7 +592,7 @@
93 if ebuild_path is None:
94 raise AssertionError("ebuild not found for '%s'" % x.cpv)
95 pkgsettings['O'] = os.path.dirname(ebuild_path)
96 - if not portage.digestgen(mysettings=pkgsettings, myportdb=portdb):
97 + if not digestgen(mysettings=pkgsettings, myportdb=portdb):
98 writemsg_level(
99 "!!! Unable to generate manifest for '%s'.\n" \
100 % x.cpv, level=logging.ERROR, noiselevel=-1)
101
102 Modified: main/branches/prefix/pym/portage/__init__.py
103 ===================================================================
104 --- main/branches/prefix/pym/portage/__init__.py 2010-02-27 19:01:26 UTC (rev 15480)
105 +++ main/branches/prefix/pym/portage/__init__.py 2010-02-27 19:21:09 UTC (rev 15481)
106 @@ -42,8 +42,6 @@
107 # which is unavailable.
108 from StringIO import StringIO
109
110 - from time import sleep
111 - from itertools import chain
112 import platform
113 import warnings
114
115 @@ -121,7 +119,10 @@
116 'pickle_read,pickle_write,stack_dictlist,stack_dicts,' + \
117 'stack_lists,unique_array,varexpand,writedict,writemsg,' + \
118 'writemsg_stdout,write_atomic',
119 + 'portage.util.digestgen:digestgen',
120 'portage.util.digraph:digraph',
121 + 'portage.util.env_update:env_update',
122 + 'portage.util.ExtractKernelVersion:ExtractKernelVersion',
123 'portage.util.listdir:cacheddir,listdir',
124 'portage.versions',
125 'portage.versions:best,catpkgsplit,catsplit,cpv_getkey,' + \
126 @@ -535,529 +536,6 @@
127 mylink=mydir+"/"+mylink
128 return os.path.normpath(mylink)
129
130 -#parse /etc/env.d and generate /etc/profile.env
131 -
132 -def env_update(makelinks=1, target_root=None, prev_mtimes=None, contents=None,
133 - env=None, writemsg_level=None):
134 - if writemsg_level is None:
135 - writemsg_level = portage.util.writemsg_level
136 - if target_root is None:
137 - global settings
138 - target_root = settings["ROOT"]
139 - if prev_mtimes is None:
140 - global mtimedb
141 - prev_mtimes = mtimedb["ldpath"]
142 - if env is None:
143 - env = os.environ
144 - envd_dir = os.path.join(target_root, EPREFIX_LSTRIP, "etc", "env.d")
145 - portage.util.ensure_dirs(envd_dir, mode=0o755)
146 - fns = listdir(envd_dir, EmptyOnError=1)
147 - fns.sort()
148 - templist = []
149 - for x in fns:
150 - if len(x) < 3:
151 - continue
152 - if not x[0].isdigit() or not x[1].isdigit():
153 - continue
154 - if x.startswith(".") or x.endswith("~") or x.endswith(".bak"):
155 - continue
156 - templist.append(x)
157 - fns = templist
158 - del templist
159 -
160 - space_separated = set(["CONFIG_PROTECT", "CONFIG_PROTECT_MASK"])
161 - colon_separated = set(["ADA_INCLUDE_PATH", "ADA_OBJECTS_PATH",
162 - "CLASSPATH", "INFODIR", "INFOPATH", "KDEDIRS", "LDPATH", "MANPATH",
163 - "PATH", "PKG_CONFIG_PATH", "PRELINK_PATH", "PRELINK_PATH_MASK",
164 - "PYTHONPATH", "ROOTPATH"])
165 -
166 - config_list = []
167 -
168 - for x in fns:
169 - file_path = os.path.join(envd_dir, x)
170 - try:
171 - myconfig = getconfig(file_path, expand=False)
172 - except portage.exception.ParseError as e:
173 - writemsg("!!! '%s'\n" % str(e), noiselevel=-1)
174 - del e
175 - continue
176 - if myconfig is None:
177 - # broken symlink or file removed by a concurrent process
178 - writemsg("!!! File Not Found: '%s'\n" % file_path, noiselevel=-1)
179 - continue
180 -
181 - config_list.append(myconfig)
182 - if "SPACE_SEPARATED" in myconfig:
183 - space_separated.update(myconfig["SPACE_SEPARATED"].split())
184 - del myconfig["SPACE_SEPARATED"]
185 - if "COLON_SEPARATED" in myconfig:
186 - colon_separated.update(myconfig["COLON_SEPARATED"].split())
187 - del myconfig["COLON_SEPARATED"]
188 -
189 - env = {}
190 - specials = {}
191 - for var in space_separated:
192 - mylist = []
193 - for myconfig in config_list:
194 - if var in myconfig:
195 - for item in myconfig[var].split():
196 - if item and not item in mylist:
197 - mylist.append(item)
198 - del myconfig[var] # prepare for env.update(myconfig)
199 - if mylist:
200 - env[var] = " ".join(mylist)
201 - specials[var] = mylist
202 -
203 - for var in colon_separated:
204 - mylist = []
205 - for myconfig in config_list:
206 - if var in myconfig:
207 - for item in myconfig[var].split(":"):
208 - if item and not item in mylist:
209 - mylist.append(item)
210 - del myconfig[var] # prepare for env.update(myconfig)
211 - if mylist:
212 - env[var] = ":".join(mylist)
213 - specials[var] = mylist
214 -
215 - for myconfig in config_list:
216 - """Cumulative variables have already been deleted from myconfig so that
217 - they won't be overwritten by this dict.update call."""
218 - env.update(myconfig)
219 -
220 - if EPREFIX == '':
221 - sleep_for_mtime_granularity = dolinkingstuff(
222 - target_root, specials, prelink_capable,
223 - makelinks, contents, prev_mtimes, env)
224 - else:
225 - sleep_for_mtime_granularity = False
226 - writeshellprofile(target_root, env, sleep_for_mtime_granularity)
227 -
228 -def dolinkingstuff(target_root, specials, prelink_capable, makelinks,
229 - contents, prev_mtimes, env):
230 - # updating this stuff will never work in an offset, other than ROOT
231 - # (e.g. not in Prefix), hence the EPREFIX is not taken into account
232 - # here since this code should never be triggered on an offset install
233 - ldsoconf_path = os.path.join(target_root, "etc", "ld.so.conf")
234 - try:
235 - myld = codecs.open(_unicode_encode(ldsoconf_path,
236 - encoding=_encodings['fs'], errors='strict'),
237 - mode='r', encoding=_encodings['content'], errors='replace')
238 - myldlines=myld.readlines()
239 - myld.close()
240 - oldld=[]
241 - for x in myldlines:
242 - #each line has at least one char (a newline)
243 - if x[0]=="#":
244 - continue
245 - oldld.append(x[:-1])
246 - except (IOError, OSError) as e:
247 - if e.errno != errno.ENOENT:
248 - raise
249 - oldld = None
250 -
251 - ld_cache_update=False
252 -
253 - newld = specials["LDPATH"]
254 - if (oldld!=newld):
255 - #ld.so.conf needs updating and ldconfig needs to be run
256 - myfd = atomic_ofstream(ldsoconf_path)
257 - myfd.write("# ld.so.conf autogenerated by env-update; make all changes to\n")
258 - myfd.write("# contents of /etc/env.d directory\n")
259 - for x in specials["LDPATH"]:
260 - myfd.write(x+"\n")
261 - myfd.close()
262 - ld_cache_update=True
263 -
264 - # Update prelink.conf if we are prelink-enabled
265 - if prelink_capable:
266 - newprelink = atomic_ofstream(
267 - os.path.join(target_root, "etc", "prelink.conf"))
268 - newprelink.write("# prelink.conf autogenerated by env-update; make all changes to\n")
269 - newprelink.write("# contents of /etc/env.d directory\n")
270 -
271 - for x in ["/bin","/sbin","/usr/bin","/usr/sbin","/lib","/usr/lib"]:
272 - newprelink.write("-l "+x+"\n");
273 - for x in specials["LDPATH"]+specials["PATH"]+specials["PRELINK_PATH"]:
274 - if not x:
275 - continue
276 - if x[-1]!='/':
277 - x=x+"/"
278 - plmasked=0
279 - for y in specials["PRELINK_PATH_MASK"]:
280 - if not y:
281 - continue
282 - if y[-1]!='/':
283 - y=y+"/"
284 - if y==x[0:len(y)]:
285 - plmasked=1
286 - break
287 - if not plmasked:
288 - newprelink.write("-h "+x+"\n")
289 - for x in specials["PRELINK_PATH_MASK"]:
290 - newprelink.write("-b "+x+"\n")
291 - newprelink.close()
292 -
293 - # Portage stores mtimes with 1 second granularity but in >=python-2.5 finer
294 - # granularity is possible. In order to avoid the potential ambiguity of
295 - # mtimes that differ by less than 1 second, sleep here if any of the
296 - # directories have been modified during the current second.
297 - sleep_for_mtime_granularity = False
298 - current_time = long(time.time())
299 - mtime_changed = False
300 - lib_dirs = set()
301 - for lib_dir in portage.util.unique_array(specials["LDPATH"]+['usr/lib','usr/lib64','usr/lib32','lib','lib64','lib32']):
302 - x = os.path.join(target_root, lib_dir.lstrip(os.sep))
303 - try:
304 - newldpathtime = os.stat(x)[stat.ST_MTIME]
305 - lib_dirs.add(normalize_path(x))
306 - except OSError as oe:
307 - if oe.errno == errno.ENOENT:
308 - try:
309 - del prev_mtimes[x]
310 - except KeyError:
311 - pass
312 - # ignore this path because it doesn't exist
313 - continue
314 - raise
315 - if newldpathtime == current_time:
316 - sleep_for_mtime_granularity = True
317 - if x in prev_mtimes:
318 - if prev_mtimes[x] == newldpathtime:
319 - pass
320 - else:
321 - prev_mtimes[x] = newldpathtime
322 - mtime_changed = True
323 - else:
324 - prev_mtimes[x] = newldpathtime
325 - mtime_changed = True
326 -
327 - if mtime_changed:
328 - ld_cache_update = True
329 -
330 - if makelinks and \
331 - not ld_cache_update and \
332 - contents is not None:
333 - libdir_contents_changed = False
334 - for mypath, mydata in contents.items():
335 - if mydata[0] not in ("obj","sym"):
336 - continue
337 - head, tail = os.path.split(mypath)
338 - if head in lib_dirs:
339 - libdir_contents_changed = True
340 - break
341 - if not libdir_contents_changed:
342 - makelinks = False
343 -
344 - ldconfig = "/sbin/ldconfig"
345 - if "CHOST" in env and "CBUILD" in env and \
346 - env["CHOST"] != env["CBUILD"]:
347 - from portage.process import find_binary
348 - ldconfig = find_binary("%s-ldconfig" % env["CHOST"])
349 -
350 - # Only run ldconfig as needed
351 - if (ld_cache_update or makelinks) and ldconfig:
352 - # ldconfig has very different behaviour between FreeBSD and Linux
353 - if ostype=="Linux" or ostype.lower().endswith("gnu"):
354 - # We can't update links if we haven't cleaned other versions first, as
355 - # an older package installed ON TOP of a newer version will cause ldconfig
356 - # to overwrite the symlinks we just made. -X means no links. After 'clean'
357 - # we can safely create links.
358 - writemsg_level(_(">>> Regenerating %setc/ld.so.cache...\n") % \
359 - (target_root,))
360 - if makelinks:
361 - os.system("cd / ; %s -r '%s'" % (ldconfig, target_root))
362 - else:
363 - os.system("cd / ; %s -X -r '%s'" % (ldconfig, target_root))
364 - elif ostype in ("FreeBSD","DragonFly"):
365 - writemsg_level(_(">>> Regenerating %svar/run/ld-elf.so.hints...\n") % \
366 - target_root)
367 - os.system(("cd / ; %s -elf -i " + \
368 - "-f '%svar/run/ld-elf.so.hints' '%setc/ld.so.conf'") % \
369 - (ldconfig, target_root, target_root))
370 -
371 - del specials["LDPATH"]
372 -
373 - return sleep_for_mtime_granularity
374 -
375 -def writeshellprofile(target_root, env, sleep_for_mtime_granularity):
376 - penvnotice = "# THIS FILE IS AUTOMATICALLY GENERATED BY env-update.\n"
377 - penvnotice += "# DO NOT EDIT THIS FILE. CHANGES TO STARTUP PROFILES\n"
378 - cenvnotice = penvnotice[:]
379 - penvnotice += "# GO INTO "+EPREFIX+"/etc/profile NOT "+EPREFIX+"/etc/profile.env\n\n"
380 - cenvnotice += "# GO INTO "+EPREFIX+"/etc/csh.cshrc NOT "+EPREFIX+"/etc/csh.env\n\n"
381 -
382 - #create /etc/profile.env for bash support
383 - outfile = atomic_ofstream(os.path.join(target_root, EPREFIX_LSTRIP, "etc", "profile.env"))
384 - outfile.write(penvnotice)
385 -
386 - env_keys = [ x for x in env if x != "LDPATH" ]
387 - env_keys.sort()
388 - for k in env_keys:
389 - v = env[k]
390 - if v.startswith('$') and not v.startswith('${'):
391 - outfile.write("export %s=$'%s'\n" % (k, v[1:]))
392 - else:
393 - outfile.write("export %s='%s'\n" % (k, v))
394 - outfile.close()
395 -
396 - #create /etc/csh.env for (t)csh support
397 - outfile = atomic_ofstream(os.path.join(target_root, EPREFIX_LSTRIP, "etc", "csh.env"))
398 - outfile.write(cenvnotice)
399 - for x in env_keys:
400 - outfile.write("setenv %s '%s'\n" % (x, env[x]))
401 - outfile.close()
402 -
403 - if sleep_for_mtime_granularity:
404 - while current_time == long(time.time()):
405 - sleep(1)
406 -
407 -def ExtractKernelVersion(base_dir):
408 - """
409 - Try to figure out what kernel version we are running
410 - @param base_dir: Path to sources (usually /usr/src/linux)
411 - @type base_dir: string
412 - @rtype: tuple( version[string], error[string])
413 - @returns:
414 - 1. tuple( version[string], error[string])
415 - Either version or error is populated (but never both)
416 -
417 - """
418 - lines = []
419 - pathname = os.path.join(base_dir, 'Makefile')
420 - try:
421 - f = codecs.open(_unicode_encode(pathname,
422 - encoding=_encodings['fs'], errors='strict'), mode='r',
423 - encoding=_encodings['content'], errors='replace')
424 - except OSError as details:
425 - return (None, str(details))
426 - except IOError as details:
427 - return (None, str(details))
428 -
429 - try:
430 - for i in range(4):
431 - lines.append(f.readline())
432 - except OSError as details:
433 - return (None, str(details))
434 - except IOError as details:
435 - return (None, str(details))
436 -
437 - lines = [l.strip() for l in lines]
438 -
439 - version = ''
440 -
441 - #XXX: The following code relies on the ordering of vars within the Makefile
442 - for line in lines:
443 - # split on the '=' then remove annoying whitespace
444 - items = line.split("=")
445 - items = [i.strip() for i in items]
446 - if items[0] == 'VERSION' or \
447 - items[0] == 'PATCHLEVEL':
448 - version += items[1]
449 - version += "."
450 - elif items[0] == 'SUBLEVEL':
451 - version += items[1]
452 - elif items[0] == 'EXTRAVERSION' and \
453 - items[-1] != items[0]:
454 - version += items[1]
455 -
456 - # Grab a list of files named localversion* and sort them
457 - localversions = os.listdir(base_dir)
458 - for x in range(len(localversions)-1,-1,-1):
459 - if localversions[x][:12] != "localversion":
460 - del localversions[x]
461 - localversions.sort()
462 -
463 - # Append the contents of each to the version string, stripping ALL whitespace
464 - for lv in localversions:
465 - version += "".join( " ".join( grabfile( base_dir+ "/" + lv ) ).split() )
466 -
467 - # Check the .config for a CONFIG_LOCALVERSION and append that too, also stripping whitespace
468 - kernelconfig = getconfig(base_dir+"/.config")
469 - if kernelconfig and "CONFIG_LOCALVERSION" in kernelconfig:
470 - version += "".join(kernelconfig["CONFIG_LOCALVERSION"].split())
471 -
472 - return (version,None)
473 -
474 -def digestgen(myarchives=None, mysettings=None,
475 - overwrite=None, manifestonly=None, myportdb=None):
476 - """
477 - Generates a digest file if missing. Fetches files if necessary.
478 - NOTE: myarchives and mysettings used to be positional arguments,
479 - so their order must be preserved for backward compatibility.
480 - @param mysettings: the ebuild config (mysettings["O"] must correspond
481 - to the ebuild's parent directory)
482 - @type mysettings: config
483 - @param myportdb: a portdbapi instance
484 - @type myportdb: portdbapi
485 - @rtype: int
486 - @returns: 1 on success and 0 on failure
487 - """
488 - if mysettings is None:
489 - raise TypeError("portage.digestgen(): missing" + \
490 - " required 'mysettings' parameter")
491 - if myportdb is None:
492 - warnings.warn("portage.digestgen() called without 'myportdb' parameter",
493 - DeprecationWarning, stacklevel=2)
494 - global portdb
495 - myportdb = portdb
496 - if overwrite is not None:
497 - warnings.warn("portage.digestgen() called with " + \
498 - "deprecated 'overwrite' parameter",
499 - DeprecationWarning, stacklevel=2)
500 - if manifestonly is not None:
501 - warnings.warn("portage.digestgen() called with " + \
502 - "deprecated 'manifestonly' parameter",
503 - DeprecationWarning, stacklevel=2)
504 - global _doebuild_manifest_exempt_depend
505 - try:
506 - _doebuild_manifest_exempt_depend += 1
507 - distfiles_map = {}
508 - fetchlist_dict = FetchlistDict(mysettings["O"], mysettings, myportdb)
509 - for cpv in fetchlist_dict:
510 - try:
511 - for myfile in fetchlist_dict[cpv]:
512 - distfiles_map.setdefault(myfile, []).append(cpv)
513 - except portage.exception.InvalidDependString as e:
514 - writemsg("!!! %s\n" % str(e), noiselevel=-1)
515 - del e
516 - return 0
517 - mytree = os.path.dirname(os.path.dirname(mysettings["O"]))
518 - manifest1_compat = False
519 - mf = Manifest(mysettings["O"], mysettings["DISTDIR"],
520 - fetchlist_dict=fetchlist_dict, manifest1_compat=manifest1_compat)
521 - # Don't require all hashes since that can trigger excessive
522 - # fetches when sufficient digests already exist. To ease transition
523 - # while Manifest 1 is being removed, only require hashes that will
524 - # exist before and after the transition.
525 - required_hash_types = set()
526 - required_hash_types.add("size")
527 - required_hash_types.add(portage.const.MANIFEST2_REQUIRED_HASH)
528 - dist_hashes = mf.fhashdict.get("DIST", {})
529 -
530 - # To avoid accidental regeneration of digests with the incorrect
531 - # files (such as partially downloaded files), trigger the fetch
532 - # code if the file exists and it's size doesn't match the current
533 - # manifest entry. If there really is a legitimate reason for the
534 - # digest to change, `ebuild --force digest` can be used to avoid
535 - # triggering this code (or else the old digests can be manually
536 - # removed from the Manifest).
537 - missing_files = []
538 - for myfile in distfiles_map:
539 - myhashes = dist_hashes.get(myfile)
540 - if not myhashes:
541 - try:
542 - st = os.stat(os.path.join(mysettings["DISTDIR"], myfile))
543 - except OSError:
544 - st = None
545 - if st is None or st.st_size == 0:
546 - missing_files.append(myfile)
547 - continue
548 - size = myhashes.get("size")
549 -
550 - try:
551 - st = os.stat(os.path.join(mysettings["DISTDIR"], myfile))
552 - except OSError as e:
553 - if e.errno != errno.ENOENT:
554 - raise
555 - del e
556 - if size == 0:
557 - missing_files.append(myfile)
558 - continue
559 - if required_hash_types.difference(myhashes):
560 - missing_files.append(myfile)
561 - continue
562 - else:
563 - if st.st_size == 0 or size is not None and size != st.st_size:
564 - missing_files.append(myfile)
565 - continue
566 -
567 - if missing_files:
568 - mytree = os.path.realpath(os.path.dirname(
569 - os.path.dirname(mysettings["O"])))
570 - fetch_settings = config(clone=mysettings)
571 - debug = mysettings.get("PORTAGE_DEBUG") == "1"
572 - for myfile in missing_files:
573 - uris = set()
574 - for cpv in distfiles_map[myfile]:
575 - myebuild = os.path.join(mysettings["O"],
576 - catsplit(cpv)[1] + ".ebuild")
577 - # for RESTRICT=fetch, mirror, etc...
578 - doebuild_environment(myebuild, "fetch",
579 - mysettings["ROOT"], fetch_settings,
580 - debug, 1, myportdb)
581 - uris.update(myportdb.getFetchMap(
582 - cpv, mytree=mytree)[myfile])
583 -
584 - fetch_settings["A"] = myfile # for use by pkg_nofetch()
585 -
586 - try:
587 - st = os.stat(os.path.join(
588 - mysettings["DISTDIR"],myfile))
589 - except OSError:
590 - st = None
591 -
592 - if not fetch({myfile : uris}, fetch_settings):
593 - writemsg(_("!!! Fetch failed for %s, can't update "
594 - "Manifest\n") % myfile, noiselevel=-1)
595 - if myfile in dist_hashes and \
596 - st is not None and st.st_size > 0:
597 - # stat result is obtained before calling fetch(),
598 - # since fetch may rename the existing file if the
599 - # digest does not match.
600 - writemsg(_("!!! If you would like to "
601 - "forcefully replace the existing "
602 - "Manifest entry\n!!! for %s, use "
603 - "the following command:\n") % myfile + \
604 - "!!! " + colorize("INFORM",
605 - "ebuild --force %s manifest" % \
606 - os.path.basename(myebuild)) + "\n",
607 - noiselevel=-1)
608 - return 0
609 - writemsg_stdout(_(">>> Creating Manifest for %s\n") % mysettings["O"])
610 - try:
611 - mf.create(assumeDistHashesSometimes=True,
612 - assumeDistHashesAlways=(
613 - "assume-digests" in mysettings.features))
614 - except portage.exception.FileNotFound as e:
615 - writemsg(_("!!! File %s doesn't exist, can't update "
616 - "Manifest\n") % e, noiselevel=-1)
617 - return 0
618 - except portage.exception.PortagePackageException as e:
619 - writemsg(("!!! %s\n") % (e,), noiselevel=-1)
620 - return 0
621 - try:
622 - mf.write(sign=False)
623 - except portage.exception.PermissionDenied as e:
624 - writemsg(_("!!! Permission Denied: %s\n") % (e,), noiselevel=-1)
625 - return 0
626 - if "assume-digests" not in mysettings.features:
627 - distlist = list(mf.fhashdict.get("DIST", {}))
628 - distlist.sort()
629 - auto_assumed = []
630 - for filename in distlist:
631 - if not os.path.exists(
632 - os.path.join(mysettings["DISTDIR"], filename)):
633 - auto_assumed.append(filename)
634 - if auto_assumed:
635 - mytree = os.path.realpath(
636 - os.path.dirname(os.path.dirname(mysettings["O"])))
637 - cp = os.path.sep.join(mysettings["O"].split(os.path.sep)[-2:])
638 - pkgs = myportdb.cp_list(cp, mytree=mytree)
639 - pkgs.sort()
640 - writemsg_stdout(" digest.assumed" + portage.output.colorize("WARN",
641 - str(len(auto_assumed)).rjust(18)) + "\n")
642 - for pkg_key in pkgs:
643 - fetchlist = myportdb.getFetchMap(pkg_key, mytree=mytree)
644 - pv = pkg_key.split("/")[1]
645 - for filename in auto_assumed:
646 - if filename in fetchlist:
647 - writemsg_stdout(
648 - " %s::%s\n" % (pv, filename))
649 - return 1
650 - finally:
651 - _doebuild_manifest_exempt_depend -= 1
652 -
653 def digestParseFile(myfilename, mysettings=None):
654 """(filename) -- Parses a given file for entries matching:
655 <checksumkey> <checksum_hex_string> <filename> <filesize>
656
657 Modified: main/branches/prefix/pym/portage/dbapi/vartree.py
658 ===================================================================
659 --- main/branches/prefix/pym/portage/dbapi/vartree.py 2010-02-27 19:01:26 UTC (rev 15480)
660 +++ main/branches/prefix/pym/portage/dbapi/vartree.py 2010-02-27 19:21:09 UTC (rev 15481)
661 @@ -25,6 +25,7 @@
662 'writemsg,writemsg_level,write_atomic,atomic_ofstream,writedict,' + \
663 'grabfile,grabdict,normalize_path,new_protect_filename,getlibpaths',
664 'portage.util.digraph:digraph',
665 + 'portage.util.env_update:env_update',
666 'portage.util.listdir:dircache,listdir',
667 'portage.versions:best,catpkgsplit,catsplit,cpv_getkey,pkgcmp,' + \
668 '_pkgsplit@pkgsplit',
669 @@ -39,7 +40,7 @@
670 FileNotFound, PermissionDenied, UnsupportedAPIException
671 from portage.localization import _
672
673 -from portage import dep_expand, env_update, \
674 +from portage import dep_expand, \
675 abssymlink, movefile, _movefile, bsd_chflags
676
677 # This is a special version of the os module, wrapped for unicode support.
678
679 Modified: main/branches/prefix/pym/portage/package/ebuild/doebuild.py
680 ===================================================================
681 --- main/branches/prefix/pym/portage/package/ebuild/doebuild.py 2010-02-27 19:01:26 UTC (rev 15480)
682 +++ main/branches/prefix/pym/portage/package/ebuild/doebuild.py 2010-02-27 19:21:09 UTC (rev 15481)
683 @@ -21,23 +21,35 @@
684 import portage
685 portage.proxy.lazyimport.lazyimport(globals(),
686 'portage.package.ebuild.config:check_config_instance',
687 + 'portage.util.digestgen:digestgen',
688 + 'portage.util.ExtractKernelVersion:ExtractKernelVersion'
689 )
690
691 -from portage import auxdbkeys, bsd_chflags, dep_check, digestcheck, digestgen, eapi_is_supported, ExtractKernelVersion, merge, os, selinux, StringIO, unmerge, _encodings, _parse_eapi_ebuild_head, _os_merge, _shell_quote, _split_ebuild_name_glep55, _unicode_decode, _unicode_encode
692 -from portage.const import EBUILD_SH_ENV_FILE, EBUILD_SH_BINARY, INVALID_ENV_FILE, MISC_SH_BINARY
693 -from portage.data import portage_gid, portage_uid, secpass, uid, userpriv_groups
694 +from portage import auxdbkeys, bsd_chflags, dep_check, digestcheck, \
695 + eapi_is_supported, merge, os, selinux, StringIO, \
696 + unmerge, _encodings, _parse_eapi_ebuild_head, _os_merge, \
697 + _shell_quote, _split_ebuild_name_glep55, _unicode_decode, _unicode_encode
698 +from portage.const import EBUILD_SH_ENV_FILE, EBUILD_SH_BINARY, \
699 + INVALID_ENV_FILE, MISC_SH_BINARY
700 +from portage.data import portage_gid, portage_uid, secpass, \
701 + uid, userpriv_groups
702 from portage.dbapi.virtual import fakedbapi
703 -from portage.dep import Atom, paren_enclose, paren_normalize, paren_reduce, use_reduce
704 +from portage.dep import Atom, paren_enclose, paren_normalize, \
705 + paren_reduce, use_reduce
706 from portage.elog import elog_process
707 from portage.elog.messages import eerror, eqawarn
708 -from portage.exception import DigestException, FileNotFound, IncorrectParameter, InvalidAtom, InvalidDependString, PermissionDenied, UnsupportedAPIException
709 +from portage.exception import DigestException, FileNotFound, \
710 + IncorrectParameter, InvalidAtom, InvalidDependString, PermissionDenied, \
711 + UnsupportedAPIException
712 from portage.localization import _
713 from portage.manifest import Manifest
714 from portage.output import style_to_ansi_code
715 from portage.package.ebuild.fetch import fetch
716 from portage.package.ebuild.prepare_build_dirs import prepare_build_dirs
717 from portage.package.ebuild._pty import _create_pty_or_pipe
718 -from portage.util import apply_recursive_permissions, apply_secpass_permissions, noiselimit, normalize_path, writemsg, writemsg_stdout, write_atomic
719 +from portage.util import apply_recursive_permissions, \
720 + apply_secpass_permissions, noiselimit, normalize_path, \
721 + writemsg, writemsg_stdout, write_atomic
722 from portage.versions import _pkgsplit
723
724 def doebuild_environment(myebuild, mydo, myroot, mysettings,
725
726 Copied: main/branches/prefix/pym/portage/util/ExtractKernelVersion.py (from rev 15455, main/trunk/pym/portage/util/ExtractKernelVersion.py)
727 ===================================================================
728 --- main/branches/prefix/pym/portage/util/ExtractKernelVersion.py (rev 0)
729 +++ main/branches/prefix/pym/portage/util/ExtractKernelVersion.py 2010-02-27 19:21:09 UTC (rev 15481)
730 @@ -0,0 +1,77 @@
731 +# Copyright 2010 Gentoo Foundation
732 +# Distributed under the terms of the GNU General Public License v2
733 +# $Id$
734 +
735 +__all__ = ['ExtractKernelVersion']
736 +
737 +import codecs
738 +
739 +from portage import os, _encodings, _unicode_encode
740 +from portage.util import getconfig, grabfile
741 +
742 +def ExtractKernelVersion(base_dir):
743 + """
744 + Try to figure out what kernel version we are running
745 + @param base_dir: Path to sources (usually /usr/src/linux)
746 + @type base_dir: string
747 + @rtype: tuple( version[string], error[string])
748 + @returns:
749 + 1. tuple( version[string], error[string])
750 + Either version or error is populated (but never both)
751 +
752 + """
753 + lines = []
754 + pathname = os.path.join(base_dir, 'Makefile')
755 + try:
756 + f = codecs.open(_unicode_encode(pathname,
757 + encoding=_encodings['fs'], errors='strict'), mode='r',
758 + encoding=_encodings['content'], errors='replace')
759 + except OSError as details:
760 + return (None, str(details))
761 + except IOError as details:
762 + return (None, str(details))
763 +
764 + try:
765 + for i in range(4):
766 + lines.append(f.readline())
767 + except OSError as details:
768 + return (None, str(details))
769 + except IOError as details:
770 + return (None, str(details))
771 +
772 + lines = [l.strip() for l in lines]
773 +
774 + version = ''
775 +
776 + #XXX: The following code relies on the ordering of vars within the Makefile
777 + for line in lines:
778 + # split on the '=' then remove annoying whitespace
779 + items = line.split("=")
780 + items = [i.strip() for i in items]
781 + if items[0] == 'VERSION' or \
782 + items[0] == 'PATCHLEVEL':
783 + version += items[1]
784 + version += "."
785 + elif items[0] == 'SUBLEVEL':
786 + version += items[1]
787 + elif items[0] == 'EXTRAVERSION' and \
788 + items[-1] != items[0]:
789 + version += items[1]
790 +
791 + # Grab a list of files named localversion* and sort them
792 + localversions = os.listdir(base_dir)
793 + for x in range(len(localversions)-1,-1,-1):
794 + if localversions[x][:12] != "localversion":
795 + del localversions[x]
796 + localversions.sort()
797 +
798 + # Append the contents of each to the version string, stripping ALL whitespace
799 + for lv in localversions:
800 + version += "".join( " ".join( grabfile( base_dir+ "/" + lv ) ).split() )
801 +
802 + # Check the .config for a CONFIG_LOCALVERSION and append that too, also stripping whitespace
803 + kernelconfig = getconfig(base_dir+"/.config")
804 + if kernelconfig and "CONFIG_LOCALVERSION" in kernelconfig:
805 + version += "".join(kernelconfig["CONFIG_LOCALVERSION"].split())
806 +
807 + return (version,None)
808
809 Copied: main/branches/prefix/pym/portage/util/digestgen.py (from rev 15455, main/trunk/pym/portage/util/digestgen.py)
810 ===================================================================
811 --- main/branches/prefix/pym/portage/util/digestgen.py (rev 0)
812 +++ main/branches/prefix/pym/portage/util/digestgen.py 2010-02-27 19:21:09 UTC (rev 15481)
813 @@ -0,0 +1,204 @@
814 +# Copyright 2010 Gentoo Foundation
815 +# Distributed under the terms of the GNU General Public License v2
816 +# $Id$
817 +
818 +__all__ = ['digestgen']
819 +
820 +import errno
821 +import warnings
822 +
823 +import portage
824 +portage.proxy.lazyimport.lazyimport(globals(),
825 + 'portage.package.ebuild.doebuild:doebuild_environment',
826 +)
827 +
828 +from portage import os
829 +from portage.const import MANIFEST2_REQUIRED_HASH
830 +from portage.dbapi.porttree import FetchlistDict
831 +from portage.exception import InvalidDependString, FileNotFound, \
832 + PermissionDenied, PortagePackageException
833 +from portage.localization import _
834 +from portage.manifest import Manifest
835 +from portage.output import colorize
836 +from portage.package.ebuild.config import config
837 +from portage.package.ebuild.fetch import fetch
838 +from portage.util import writemsg, writemsg_stdout
839 +from portage.versions import catsplit
840 +
841 +def digestgen(myarchives=None, mysettings=None,
842 + overwrite=None, manifestonly=None, myportdb=None):
843 + """
844 + Generates a digest file if missing. Fetches files if necessary.
845 + NOTE: myarchives and mysettings used to be positional arguments,
846 + so their order must be preserved for backward compatibility.
847 + @param mysettings: the ebuild config (mysettings["O"] must correspond
848 + to the ebuild's parent directory)
849 + @type mysettings: config
850 + @param myportdb: a portdbapi instance
851 + @type myportdb: portdbapi
852 + @rtype: int
853 + @returns: 1 on success and 0 on failure
854 + """
855 + if mysettings is None:
856 + raise TypeError("portage.digestgen(): missing" + \
857 + " required 'mysettings' parameter")
858 + if myportdb is None:
859 + warnings.warn("portage.digestgen() called without 'myportdb' parameter",
860 + DeprecationWarning, stacklevel=2)
861 + myportdb = portage.portdb
862 + if overwrite is not None:
863 + warnings.warn("portage.digestgen() called with " + \
864 + "deprecated 'overwrite' parameter",
865 + DeprecationWarning, stacklevel=2)
866 + if manifestonly is not None:
867 + warnings.warn("portage.digestgen() called with " + \
868 + "deprecated 'manifestonly' parameter",
869 + DeprecationWarning, stacklevel=2)
870 +
871 + try:
872 + portage._doebuild_manifest_exempt_depend += 1
873 + distfiles_map = {}
874 + fetchlist_dict = FetchlistDict(mysettings["O"], mysettings, myportdb)
875 + for cpv in fetchlist_dict:
876 + try:
877 + for myfile in fetchlist_dict[cpv]:
878 + distfiles_map.setdefault(myfile, []).append(cpv)
879 + except InvalidDependString as e:
880 + writemsg("!!! %s\n" % str(e), noiselevel=-1)
881 + del e
882 + return 0
883 + mytree = os.path.dirname(os.path.dirname(mysettings["O"]))
884 + manifest1_compat = False
885 + mf = Manifest(mysettings["O"], mysettings["DISTDIR"],
886 + fetchlist_dict=fetchlist_dict, manifest1_compat=manifest1_compat)
887 + # Don't require all hashes since that can trigger excessive
888 + # fetches when sufficient digests already exist. To ease transition
889 + # while Manifest 1 is being removed, only require hashes that will
890 + # exist before and after the transition.
891 + required_hash_types = set()
892 + required_hash_types.add("size")
893 + required_hash_types.add(MANIFEST2_REQUIRED_HASH)
894 + dist_hashes = mf.fhashdict.get("DIST", {})
895 +
896 + # To avoid accidental regeneration of digests with the incorrect
897 + # files (such as partially downloaded files), trigger the fetch
898 + # code if the file exists and it's size doesn't match the current
899 + # manifest entry. If there really is a legitimate reason for the
900 + # digest to change, `ebuild --force digest` can be used to avoid
901 + # triggering this code (or else the old digests can be manually
902 + # removed from the Manifest).
903 + missing_files = []
904 + for myfile in distfiles_map:
905 + myhashes = dist_hashes.get(myfile)
906 + if not myhashes:
907 + try:
908 + st = os.stat(os.path.join(mysettings["DISTDIR"], myfile))
909 + except OSError:
910 + st = None
911 + if st is None or st.st_size == 0:
912 + missing_files.append(myfile)
913 + continue
914 + size = myhashes.get("size")
915 +
916 + try:
917 + st = os.stat(os.path.join(mysettings["DISTDIR"], myfile))
918 + except OSError as e:
919 + if e.errno != errno.ENOENT:
920 + raise
921 + del e
922 + if size == 0:
923 + missing_files.append(myfile)
924 + continue
925 + if required_hash_types.difference(myhashes):
926 + missing_files.append(myfile)
927 + continue
928 + else:
929 + if st.st_size == 0 or size is not None and size != st.st_size:
930 + missing_files.append(myfile)
931 + continue
932 +
933 + if missing_files:
934 + mytree = os.path.realpath(os.path.dirname(
935 + os.path.dirname(mysettings["O"])))
936 + fetch_settings = config(clone=mysettings)
937 + debug = mysettings.get("PORTAGE_DEBUG") == "1"
938 + for myfile in missing_files:
939 + uris = set()
940 + for cpv in distfiles_map[myfile]:
941 + myebuild = os.path.join(mysettings["O"],
942 + catsplit(cpv)[1] + ".ebuild")
943 + # for RESTRICT=fetch, mirror, etc...
944 + doebuild_environment(myebuild, "fetch",
945 + mysettings["ROOT"], fetch_settings,
946 + debug, 1, myportdb)
947 + uris.update(myportdb.getFetchMap(
948 + cpv, mytree=mytree)[myfile])
949 +
950 + fetch_settings["A"] = myfile # for use by pkg_nofetch()
951 +
952 + try:
953 + st = os.stat(os.path.join(
954 + mysettings["DISTDIR"],myfile))
955 + except OSError:
956 + st = None
957 +
958 + if not fetch({myfile : uris}, fetch_settings):
959 + writemsg(_("!!! Fetch failed for %s, can't update "
960 + "Manifest\n") % myfile, noiselevel=-1)
961 + if myfile in dist_hashes and \
962 + st is not None and st.st_size > 0:
963 + # stat result is obtained before calling fetch(),
964 + # since fetch may rename the existing file if the
965 + # digest does not match.
966 + writemsg(_("!!! If you would like to "
967 + "forcefully replace the existing "
968 + "Manifest entry\n!!! for %s, use "
969 + "the following command:\n") % myfile + \
970 + "!!! " + colorize("INFORM",
971 + "ebuild --force %s manifest" % \
972 + os.path.basename(myebuild)) + "\n",
973 + noiselevel=-1)
974 + return 0
975 + writemsg_stdout(_(">>> Creating Manifest for %s\n") % mysettings["O"])
976 + try:
977 + mf.create(assumeDistHashesSometimes=True,
978 + assumeDistHashesAlways=(
979 + "assume-digests" in mysettings.features))
980 + except FileNotFound as e:
981 + writemsg(_("!!! File %s doesn't exist, can't update "
982 + "Manifest\n") % e, noiselevel=-1)
983 + return 0
984 + except PortagePackageException as e:
985 + writemsg(("!!! %s\n") % (e,), noiselevel=-1)
986 + return 0
987 + try:
988 + mf.write(sign=False)
989 + except PermissionDenied as e:
990 + writemsg(_("!!! Permission Denied: %s\n") % (e,), noiselevel=-1)
991 + return 0
992 + if "assume-digests" not in mysettings.features:
993 + distlist = list(mf.fhashdict.get("DIST", {}))
994 + distlist.sort()
995 + auto_assumed = []
996 + for filename in distlist:
997 + if not os.path.exists(
998 + os.path.join(mysettings["DISTDIR"], filename)):
999 + auto_assumed.append(filename)
1000 + if auto_assumed:
1001 + mytree = os.path.realpath(
1002 + os.path.dirname(os.path.dirname(mysettings["O"])))
1003 + cp = os.path.sep.join(mysettings["O"].split(os.path.sep)[-2:])
1004 + pkgs = myportdb.cp_list(cp, mytree=mytree)
1005 + pkgs.sort()
1006 + writemsg_stdout(" digest.assumed" + colorize("WARN",
1007 + str(len(auto_assumed)).rjust(18)) + "\n")
1008 + for pkg_key in pkgs:
1009 + fetchlist = myportdb.getFetchMap(pkg_key, mytree=mytree)
1010 + pv = pkg_key.split("/")[1]
1011 + for filename in auto_assumed:
1012 + if filename in fetchlist:
1013 + writemsg_stdout(
1014 + " %s::%s\n" % (pv, filename))
1015 + return 1
1016 + finally:
1017 + portage._doebuild_manifest_exempt_depend -= 1
1018
1019 Copied: main/branches/prefix/pym/portage/util/env_update.py (from rev 15455, main/trunk/pym/portage/util/env_update.py)
1020 ===================================================================
1021 --- main/branches/prefix/pym/portage/util/env_update.py (rev 0)
1022 +++ main/branches/prefix/pym/portage/util/env_update.py 2010-02-27 19:21:09 UTC (rev 15481)
1023 @@ -0,0 +1,307 @@
1024 +# Copyright 2010 Gentoo Foundation
1025 +# Distributed under the terms of the GNU General Public License v2
1026 +# $Id$
1027 +
1028 +__all__ = ['env_update']
1029 +
1030 +import codecs
1031 +import errno
1032 +import stat
1033 +import sys
1034 +import time
1035 +
1036 +import portage
1037 +from portage import os, _encodings, _unicode_encode
1038 +from portage.checksum import prelink_capable
1039 +from portage.data import ostype
1040 +from portage.exception import ParseError
1041 +from portage.localization import _
1042 +from portage.process import find_binary
1043 +from portage.util import atomic_ofstream, ensure_dirs, getconfig, \
1044 + normalize_path, writemsg
1045 +from portage.util.listdir import listdir
1046 +
1047 +if sys.hexversion >= 0x3000000:
1048 + long = int
1049 +
1050 +def env_update(makelinks=1, target_root=None, prev_mtimes=None, contents=None,
1051 + env=None, writemsg_level=None):
1052 + """
1053 + Parse /etc/env.d and use it to generate /etc/profile.env, csh.env,
1054 + ld.so.conf, and prelink.conf. Finally, run ldconfig.
1055 + """
1056 + if writemsg_level is None:
1057 + writemsg_level = portage.util.writemsg_level
1058 + if target_root is None:
1059 + target_root = portage.settings["ROOT"]
1060 + if prev_mtimes is None:
1061 + prev_mtimes = portage.mtimedb["ldpath"]
1062 + if env is None:
1063 + env = os.environ
1064 + envd_dir = os.path.join(target_root, EPREFIX_LSTRIP, "etc", "env.d")
1065 + ensure_dirs(envd_dir, mode=0o755)
1066 + fns = listdir(envd_dir, EmptyOnError=1)
1067 + fns.sort()
1068 + templist = []
1069 + for x in fns:
1070 + if len(x) < 3:
1071 + continue
1072 + if not x[0].isdigit() or not x[1].isdigit():
1073 + continue
1074 + if x.startswith(".") or x.endswith("~") or x.endswith(".bak"):
1075 + continue
1076 + templist.append(x)
1077 + fns = templist
1078 + del templist
1079 +
1080 + space_separated = set(["CONFIG_PROTECT", "CONFIG_PROTECT_MASK"])
1081 + colon_separated = set(["ADA_INCLUDE_PATH", "ADA_OBJECTS_PATH",
1082 + "CLASSPATH", "INFODIR", "INFOPATH", "KDEDIRS", "LDPATH", "MANPATH",
1083 + "PATH", "PKG_CONFIG_PATH", "PRELINK_PATH", "PRELINK_PATH_MASK",
1084 + "PYTHONPATH", "ROOTPATH"])
1085 +
1086 + config_list = []
1087 +
1088 + for x in fns:
1089 + file_path = os.path.join(envd_dir, x)
1090 + try:
1091 + myconfig = getconfig(file_path, expand=False)
1092 + except ParseError as e:
1093 + writemsg("!!! '%s'\n" % str(e), noiselevel=-1)
1094 + del e
1095 + continue
1096 + if myconfig is None:
1097 + # broken symlink or file removed by a concurrent process
1098 + writemsg("!!! File Not Found: '%s'\n" % file_path, noiselevel=-1)
1099 + continue
1100 +
1101 + config_list.append(myconfig)
1102 + if "SPACE_SEPARATED" in myconfig:
1103 + space_separated.update(myconfig["SPACE_SEPARATED"].split())
1104 + del myconfig["SPACE_SEPARATED"]
1105 + if "COLON_SEPARATED" in myconfig:
1106 + colon_separated.update(myconfig["COLON_SEPARATED"].split())
1107 + del myconfig["COLON_SEPARATED"]
1108 +
1109 + env = {}
1110 + specials = {}
1111 + for var in space_separated:
1112 + mylist = []
1113 + for myconfig in config_list:
1114 + if var in myconfig:
1115 + for item in myconfig[var].split():
1116 + if item and not item in mylist:
1117 + mylist.append(item)
1118 + del myconfig[var] # prepare for env.update(myconfig)
1119 + if mylist:
1120 + env[var] = " ".join(mylist)
1121 + specials[var] = mylist
1122 +
1123 + for var in colon_separated:
1124 + mylist = []
1125 + for myconfig in config_list:
1126 + if var in myconfig:
1127 + for item in myconfig[var].split(":"):
1128 + if item and not item in mylist:
1129 + mylist.append(item)
1130 + del myconfig[var] # prepare for env.update(myconfig)
1131 + if mylist:
1132 + env[var] = ":".join(mylist)
1133 + specials[var] = mylist
1134 +
1135 + for myconfig in config_list:
1136 + """Cumulative variables have already been deleted from myconfig so that
1137 + they won't be overwritten by this dict.update call."""
1138 + env.update(myconfig)
1139 +
1140 + if EPREFIX == '':
1141 + sleep_for_mtime_granularity = dolinkingstuff(
1142 + target_root, specials, prelink_capable,
1143 + makelinks, contents, prev_mtimes, env)
1144 + else:
1145 + sleep_for_mtime_granularity = False
1146 + writeshellprofile(target_root, env, sleep_for_mtime_granularity)
1147 +
1148 +def dolinkingstuff(target_root, specials, prelink_capable, makelinks,
1149 + contents, prev_mtimes, env):
1150 + # updating this stuff will never work in an offset, other than ROOT
1151 + # (e.g. not in Prefix), hence the EPREFIX is not taken into account
1152 + # here since this code should never be triggered on an offset install
1153 + ldsoconf_path = os.path.join(target_root, "etc", "ld.so.conf")
1154 + try:
1155 + myld = codecs.open(_unicode_encode(ldsoconf_path,
1156 + encoding=_encodings['fs'], errors='strict'),
1157 + mode='r', encoding=_encodings['content'], errors='replace')
1158 + myldlines=myld.readlines()
1159 + myld.close()
1160 + oldld=[]
1161 + for x in myldlines:
1162 + #each line has at least one char (a newline)
1163 + if x[:1] == "#":
1164 + continue
1165 + oldld.append(x[:-1])
1166 + except (IOError, OSError) as e:
1167 + if e.errno != errno.ENOENT:
1168 + raise
1169 + oldld = None
1170 +
1171 + ld_cache_update=False
1172 +
1173 + newld = specials["LDPATH"]
1174 + if (oldld != newld):
1175 + #ld.so.conf needs updating and ldconfig needs to be run
1176 + myfd = atomic_ofstream(ldsoconf_path)
1177 + myfd.write("# ld.so.conf autogenerated by env-update; make all changes to\n")
1178 + myfd.write("# contents of /etc/env.d directory\n")
1179 + for x in specials["LDPATH"]:
1180 + myfd.write(x + "\n")
1181 + myfd.close()
1182 + ld_cache_update=True
1183 +
1184 + # Update prelink.conf if we are prelink-enabled
1185 + if prelink_capable:
1186 + newprelink = atomic_ofstream(
1187 + os.path.join(target_root, "etc", "prelink.conf"))
1188 + newprelink.write("# prelink.conf autogenerated by env-update; make all changes to\n")
1189 + newprelink.write("# contents of /etc/env.d directory\n")
1190 +
1191 + for x in ["/bin","/sbin","/usr/bin","/usr/sbin","/lib","/usr/lib"]:
1192 + newprelink.write("-l %s\n" % (x,));
1193 + prelink_paths = []
1194 + prelink_paths += specials.get("LDPATH", [])
1195 + prelink_paths += specials.get("PATH", [])
1196 + prelink_paths += specials.get("PRELINK_PATH", [])
1197 + prelink_path_mask = specials.get("PRELINK_PATH_MASK", [])
1198 + for x in prelink_paths:
1199 + if not x:
1200 + continue
1201 + if x[-1:] != '/':
1202 + x += "/"
1203 + plmasked = 0
1204 + for y in prelink_path_mask:
1205 + if not y:
1206 + continue
1207 + if y[-1] != '/':
1208 + y += "/"
1209 + if y == x[0:len(y)]:
1210 + plmasked = 1
1211 + break
1212 + if not plmasked:
1213 + newprelink.write("-h %s\n" % (x,))
1214 + for x in prelink_path_mask:
1215 + newprelink.write("-b %s\n" % (x,))
1216 + newprelink.close()
1217 +
1218 + # Portage stores mtimes with 1 second granularity but in >=python-2.5 finer
1219 + # granularity is possible. In order to avoid the potential ambiguity of
1220 + # mtimes that differ by less than 1 second, sleep here if any of the
1221 + # directories have been modified during the current second.
1222 + sleep_for_mtime_granularity = False
1223 + current_time = long(time.time())
1224 + mtime_changed = False
1225 + lib_dirs = set()
1226 + for lib_dir in set(specials["LDPATH"] + \
1227 + ['usr/lib','usr/lib64','usr/lib32','lib','lib64','lib32']):
1228 + x = os.path.join(target_root, lib_dir.lstrip(os.sep))
1229 + try:
1230 + newldpathtime = os.stat(x)[stat.ST_MTIME]
1231 + lib_dirs.add(normalize_path(x))
1232 + except OSError as oe:
1233 + if oe.errno == errno.ENOENT:
1234 + try:
1235 + del prev_mtimes[x]
1236 + except KeyError:
1237 + pass
1238 + # ignore this path because it doesn't exist
1239 + continue
1240 + raise
1241 + if newldpathtime == current_time:
1242 + sleep_for_mtime_granularity = True
1243 + if x in prev_mtimes:
1244 + if prev_mtimes[x] == newldpathtime:
1245 + pass
1246 + else:
1247 + prev_mtimes[x] = newldpathtime
1248 + mtime_changed = True
1249 + else:
1250 + prev_mtimes[x] = newldpathtime
1251 + mtime_changed = True
1252 +
1253 + if mtime_changed:
1254 + ld_cache_update = True
1255 +
1256 + if makelinks and \
1257 + not ld_cache_update and \
1258 + contents is not None:
1259 + libdir_contents_changed = False
1260 + for mypath, mydata in contents.items():
1261 + if mydata[0] not in ("obj", "sym"):
1262 + continue
1263 + head, tail = os.path.split(mypath)
1264 + if head in lib_dirs:
1265 + libdir_contents_changed = True
1266 + break
1267 + if not libdir_contents_changed:
1268 + makelinks = False
1269 +
1270 + ldconfig = "/sbin/ldconfig"
1271 + if "CHOST" in env and "CBUILD" in env and \
1272 + env["CHOST"] != env["CBUILD"]:
1273 + ldconfig = find_binary("%s-ldconfig" % env["CHOST"])
1274 +
1275 + # Only run ldconfig as needed
1276 + if (ld_cache_update or makelinks) and ldconfig:
1277 + # ldconfig has very different behaviour between FreeBSD and Linux
1278 + if ostype == "Linux" or ostype.lower().endswith("gnu"):
1279 + # We can't update links if we haven't cleaned other versions first, as
1280 + # an older package installed ON TOP of a newer version will cause ldconfig
1281 + # to overwrite the symlinks we just made. -X means no links. After 'clean'
1282 + # we can safely create links.
1283 + writemsg_level(_(">>> Regenerating %setc/ld.so.cache...\n") % \
1284 + (target_root,))
1285 + if makelinks:
1286 + os.system("cd / ; %s -r '%s'" % (ldconfig, target_root))
1287 + else:
1288 + os.system("cd / ; %s -X -r '%s'" % (ldconfig, target_root))
1289 + elif ostype in ("FreeBSD","DragonFly"):
1290 + writemsg_level(_(">>> Regenerating %svar/run/ld-elf.so.hints...\n") % \
1291 + target_root)
1292 + os.system(("cd / ; %s -elf -i " + \
1293 + "-f '%svar/run/ld-elf.so.hints' '%setc/ld.so.conf'") % \
1294 + (ldconfig, target_root, target_root))
1295 +
1296 + del specials["LDPATH"]
1297 +
1298 + return sleep_for_mtime_granularity
1299 +
1300 +def writeshellprofile(target_root, env, sleep_for_mtime_granularity):
1301 + penvnotice = "# THIS FILE IS AUTOMATICALLY GENERATED BY env-update.\n"
1302 + penvnotice += "# DO NOT EDIT THIS FILE. CHANGES TO STARTUP PROFILES\n"
1303 + cenvnotice = penvnotice[:]
1304 + penvnotice += "# GO INTO " + EPREFIX + "/etc/profile NOT /etc/profile.env\n\n"
1305 + cenvnotice += "# GO INTO " + EPREFIX + "/etc/csh.cshrc NOT /etc/csh.env\n\n"
1306 +
1307 + #create /etc/profile.env for bash support
1308 + outfile = atomic_ofstream(os.path.join(target_root, EPREFIX_LSTRIP, "etc", "profile.env"))
1309 + outfile.write(penvnotice)
1310 +
1311 + env_keys = [ x for x in env if x != "LDPATH" ]
1312 + env_keys.sort()
1313 + for k in env_keys:
1314 + v = env[k]
1315 + if v.startswith('$') and not v.startswith('${'):
1316 + outfile.write("export %s=$'%s'\n" % (k, v[1:]))
1317 + else:
1318 + outfile.write("export %s='%s'\n" % (k, v))
1319 + outfile.close()
1320 +
1321 + #create /etc/csh.env for (t)csh support
1322 + outfile = atomic_ofstream(os.path.join(target_root, EPREFIX_LSTRIP, "etc", "csh.env"))
1323 + outfile.write(cenvnotice)
1324 + for x in env_keys:
1325 + outfile.write("setenv %s '%s'\n" % (x, env[x]))
1326 + outfile.close()
1327 +
1328 + if sleep_for_mtime_granularity:
1329 + while current_time == long(time.time()):
1330 + time.sleep(1)