def emergelog(xterm_titles, mystr, short_msg=None):
if xterm_titles:
- if short_msg:
- xtermTitle(short_msg)
- else:
- xtermTitle(mystr)
+ if short_msg == None:
+ short_msg = mystr
+ if "HOSTNAME" in os.environ.keys():
+ short_msg = os.environ["HOSTNAME"]+": "+short_msg
+ xtermTitle(short_msg)
try:
file_path = EPREFIX+"/var/log/emerge.log"
mylogfile = open(file_path, "a")
mreasons = portage.getmaskingstatus(p,
settings=pkgsettings, portdb=portdb)
print "- "+p+" (masked by: "+", ".join(mreasons)+")"
- comment = portage.getmaskingreason(p,
- settings=pkgsettings, portdb=portdb)
+ comment, filename = portage.getmaskingreason(p,
+ settings=pkgsettings, portdb=portdb, return_location=True)
if comment and comment != oldcomment:
+ print filename+":"
print comment
oldcomment = comment
print
def altlist(self, reversed=False):
if reversed in self._altlist_cache:
return self._altlist_cache[reversed][:]
+ if reversed:
+ retlist = self.altlist()
+ retlist.reverse()
+ self._altlist_cache[reversed] = retlist[:]
+ return retlist
mygraph=self.digraph.copy()
myblockers = self.blocker_digraph.copy()
retlist=[]
ignore_priority_range = [None]
ignore_priority_range.extend(
xrange(DepPriority.MIN, DepPriority.MEDIUM + 1))
+ tree_mode = "--tree" in self.myopts
while not mygraph.empty():
ignore_priority = None
nodes = None
selected_nodes = None
if nodes:
if ignore_priority <= DepPriority.SOFT:
- if ignore_priority is None and not reversed:
+ if ignore_priority is None and not tree_mode:
# Greedily pop all of these nodes since no relationship
# has been ignored. This optimization destroys --tree
# output, so it's disabled in reversed mode.
else:
return mykey
-def getmaskingreason(mycpv, settings=None, portdb=None):
+def getmaskingreason(mycpv, settings=None, portdb=None, return_location=False):
from portage.util import grablines
if settings is None:
settings = globals()["settings"]
locations.append(os.path.join(settings["PORTAGE_CONFIGROOT"],
USER_CONFIG_PATH.lstrip(os.path.sep)))
locations.reverse()
- pmasklists = [grablines(os.path.join(x, "package.mask"), recursive=1) for x in locations]
- pmasklines = []
- while pmasklists: # stack_lists doesn't preserve order so it can't be used
- pmasklines.extend(pmasklists.pop(0))
- del pmasklists
+ pmasklists = [(x, grablines(os.path.join(x, "package.mask"), recursive=1)) for x in locations]
if settings.pmaskdict.has_key(mycp):
for x in settings.pmaskdict[mycp]:
comment = ""
l = "\n"
comment_valid = -1
- for i in xrange(len(pmasklines)):
- l = pmasklines[i].strip()
- if l == "":
- comment = ""
- comment_valid = -1
- elif l[0] == "#":
- comment += (l+"\n")
- comment_valid = i + 1
- elif l == x:
- if comment_valid != i:
+ for pmask in pmasklists:
+ pmask_filename = os.path.join(pmask[0], "package.mask")
+ for i in xrange(len(pmask[1])):
+ l = pmask[1][i].strip()
+ if l == "":
comment = ""
- return comment
- elif comment_valid != -1:
- # Apparently this comment applies to muliple masks, so
- # it remains valid until a blank line is encountered.
- comment_valid += 1
+ comment_valid = -1
+ elif l[0] == "#":
+ comment += (l+"\n")
+ comment_valid = i + 1
+ elif l == x:
+ if comment_valid != i:
+ comment = ""
+ if return_location:
+ return (comment, pmask_filename)
+ else:
+ return comment
+ elif comment_valid != -1:
+ # Apparently this comment applies to muliple masks, so
+ # it remains valid until a blank line is encountered.
+ comment_valid += 1
return None
def getmaskingstatus(mycpv, settings=None, portdb=None):
write_atomic(cpath, str(counter))
return counter
+ def get_library_map(self):
+ """ Read the global library->consumer map for this vdb instance """
+ mapfilename = self.getpath(".NEEDED")
+ if not os.path.exists(mapfilename):
+ self.update_library_map()
+ rValue = {}
+ for l in open(mapfilename, "r").read().split("\n"):
+ mysplit = l.split()
+ if len(mysplit) > 1:
+ rValue[mysplit[0]] = mysplit[1].split(",")
+ return rValue
+
+ def update_library_map(self):
+ """ Update the global library->consumer map for this vdb instance. """
+ mapfilename = self.getpath(".NEEDED")
+ obj_dict = {}
+ for cpv in self.cpv_all():
+ needed_list = self.aux_get(cpv, ["NEEDED"])[0]
+ for l in needed_list.split("\n"):
+ mysplit = l.split()
+ if len(mysplit) < 2:
+ continue
+ libs = mysplit[1].split(",")
+ for lib in libs:
+ if not obj_dict.has_key(lib):
+ obj_dict[lib] = [mysplit[0]]
+ else:
+ obj_dict[lib].append(mysplit[0])
+ mapfile = open(mapfilename, "w")
+ for lib in obj_dict.keys():
+ mapfile.write(lib+" "+",".join(obj_dict[lib])+"\n")
+ mapfile.close()
+
class vartree(object):
"this tree will scan a var/db/pkg database located at root (passed to init)"
def __init__(self, root="/", virtual=None, clone=None, categories=None,
doebuild(myebuildpath, "cleanrm", self.myroot, self.settings,
tree="vartree", mydbapi=self.vartree.dbapi,
vartree=self.vartree)
+
+ # regenerate reverse NEEDED map
+ self.vartree.dbapi.update_library_map()
finally:
if builddir_lock:
This function does the following:
+ Preserve old libraries that are still used.
Collision Protection.
calls doebuild(mydo=pkg_preinst)
Merges the package to the livefs
if not os.path.exists(self.dbcatdir):
os.makedirs(self.dbcatdir)
+ myfilelist = listdir(srcroot, recursive=1, filesonly=1, followSymlinks=True)
+ mysymlinks = filter(os.path.islink, listdir(srcroot, recursive=1, filesonly=0, followSymlinks=False))
+ myfilelist.extend(mysymlinks)
+
otherversions = []
for v in self.vartree.dbapi.cp_list(self.mysplit[0]):
otherversions.append(v.split("/")[1])
catsplit(slot_matches[0])[1], destroot, self.settings,
vartree=self.vartree)
+ # Preserve old libs if they are still in use
+ if slot_matches and "preserve-libs" in self.settings.features:
+ # read global reverse NEEDED map
+ libmap = self.vartree.dbapi.get_library_map()
+
+ # get list of libraries from old package instance
+ old_contents = self._installed_instance.getcontents().keys()
+ old_libs = set([os.path.basename(x) for x in old_contents]).intersection(libmap.keys())
+
+ # get list of libraries from new package instance
+ mylibs = set([os.path.basename(x) for x in myfilelist]).intersection(libmap.keys())
+
+ # check which libs are present in the old, but not the new package instance
+ preserve_libs = old_libs.difference(mylibs)
+
+ # ignore any libs that are only internally used by the package
+ for lib in preserve_libs.copy():
+ old_contents_without_libs = [x for x in old_contents if os.path.basename(x) not in preserve_libs]
+ if len(set(libmap[lib]).intersection(old_contents_without_libs)) == len(libmap[lib]):
+ preserve_libs.remove(lib)
+
+ # get the real paths for the libs
+ preserve_paths = [x for x in old_contents if os.path.basename(x) in preserve_libs]
+
+ # inject files that should be preserved into our image dir
+ import shutil
+ for x in preserve_paths:
+ print "injecting %s into %s" % (x, srcroot)
+ mydir = os.path.join(srcroot, os.path.dirname(x))
+ if not os.path.exists(mydir):
+ os.makedirs(mydir)
+
+ # resolve symlinks and extend preserve list
+ # NOTE: we're extending the list in the loop to emulate recursion to
+ # also get indirect symlinks
+ if os.path.islink(x):
+ linktarget = os.readlink(x)
+ os.symlink(linktarget, os.path.join(srcroot, x.lstrip(os.sep)))
+ if linktarget[0] != os.sep:
+ linktarget = os.path.join(os.path.dirname(x), linktarget)
+ preserve_paths.append(linktarget)
+ else:
+ shutil.copy2(x, os.path.join(srcroot, x.lstrip(os.sep)))
+
+
# check for package collisions
if "collision-protect" in self.settings.features:
collision_ignore = set([normalize_path(myignore) for myignore in \
self.settings.get("COLLISION_IGNORE", "").split()])
- myfilelist = listdir(srcroot, recursive=1, filesonly=1, followSymlinks=False)
# the linkcheck only works if we are in srcroot
mycwd = os.getcwd()
os.chdir(srcroot)
- mysymlinks = filter(os.path.islink, listdir(srcroot, recursive=1, filesonly=0, followSymlinks=False))
- myfilelist.extend(mysymlinks)
mysymlinked_directories = [s + os.path.sep for s in mysymlinks]
del mysymlinks
writedict(cfgfiledict, conf_mem_file)
del conf_mem_file
+ # regenerate reverse NEEDED map
+ self.vartree.dbapi.update_library_map()
+
#do postinst script
a = doebuild(myebuild, "postinst", destroot, self.settings, use_cache=0,
tree=self.treetype, mydbapi=mydbapi, vartree=self.vartree)