hasq splitdebug ${FEATURES} || return 0
local x=$1
- local y="${ED}usr/lib/debug/${x:${#ED}}.debug"
+ local y="${ED}usr/lib/debug/${x:${#D}}.debug"
# dont save debug info twice
[[ ${x} == *".debug" ]] && return 0
${STRIP} ${PORTAGE_STRIP_FLAGS} "${x}"
fi
elif [[ ${f} == *"SB relocatable"* ]] ; then
- vecho " ${x:${#D}}"
+ vecho " ${x:${#ED}}"
save_elf_sources "${x}"
if ${strip_this} ; then
[[ ${x} == *.ko ]] && save_elf_debug "${x}"
# variables are expanded:
# ${PACKAGE} - see description of PORTAGE_ELOG_COMMAND
# ${HOST} - FQDN of the host portage is running on
-#PORTAGE_ELOG_MAILSUBJECT="package \${PACKAGE} merged on \${HOST} with notice"
+#PORTAGE_ELOG_MAILSUBJECT="[portage] ebuild log for \${PACKAGE} on \${HOST}"
from portage.data import secpass
from portage.util import normalize_path as normpath
from portage.util import writemsg
+from portage.sets import InternalPackageSet
+from portage.sets.profiles import PackagesSystemSet as SystemSet
+from portage.sets.files import WorldSet
from itertools import chain, izip
from UserDict import DictMixin
def clean_world(vardb, cpv):
"""Remove a package from the world file when unmerged."""
- world_set = WorldSet(vardb.settings)
+ world_set = WorldSet("world", vardb.settings["ROOT"])
world_set.lock()
- world_set.load()
worldlist = list(world_set)
mykey = portage.cpv_getkey(cpv)
newworldlist = []
#this doesn't match the package we're unmerging; keep it.
newworldlist.append(x)
- world_set.clear()
- world_set.update(newworldlist)
- world_set.save()
+ world_set.replace(newworldlist)
world_set.unlock()
-class AtomSet(object):
- def __init__(self, atoms=None):
- self._atoms = {}
- if atoms:
- self.update(atoms)
- def clear(self):
- self._atoms.clear()
- def add(self, atom):
- cp = portage.dep_getkey(atom)
- cp_list = self._atoms.get(cp)
- if cp_list is None:
- cp_list = []
- self._atoms[cp] = cp_list
- if atom not in cp_list:
- cp_list.append(atom)
- def update(self, atoms):
- for atom in atoms:
- self.add(atom)
- def __contains__(self, atom):
- cp = portage.dep_getkey(atom)
- if cp in self._atoms and atom in self._atoms[cp]:
- return True
- return False
- def findAtomForPackage(self, cpv, metadata):
- """Return the best match for a given package from the arguments, or
- None if there are no matches. This matches virtual arguments against
- the PROVIDE metadata. This can raise an InvalidDependString exception
- if an error occurs while parsing PROVIDE."""
- cpv_slot = "%s:%s" % (cpv, metadata["SLOT"])
- cp = portage.dep_getkey(cpv)
- atoms = self._atoms.get(cp)
- if atoms:
- best_match = portage.best_match_to_list(cpv_slot, atoms)
- if best_match:
- return best_match
- if not metadata["PROVIDE"]:
- return None
- provides = portage.flatten(portage.dep.use_reduce(
- portage.dep.paren_reduce(metadata["PROVIDE"]),
- uselist=metadata["USE"].split()))
- for provide in provides:
- provided_cp = portage.dep_getkey(provide)
- atoms = self._atoms.get(provided_cp)
- if atoms:
- transformed_atoms = [atom.replace(provided_cp, cp) for atom in atoms]
- best_match = portage.best_match_to_list(cpv_slot, transformed_atoms)
- if best_match:
- return atoms[transformed_atoms.index(best_match)]
- return None
- def __iter__(self):
- for atoms in self._atoms.itervalues():
- for atom in atoms:
- yield atom
-
-class SystemSet(AtomSet):
- def __init__(self, settings, **kwargs):
- AtomSet.__init__(self, **kwargs)
- self.update(getlist(settings, "system"))
-
-class WorldSet(AtomSet):
- def __init__(self, settings, **kwargs):
- AtomSet.__init__(self, **kwargs)
- self.world_file = os.path.join(settings["ROOT"], portage.WORLD_FILE)
- self._lock = None
- def _ensure_dirs(self):
- portage.util.ensure_dirs(os.path.dirname(self.world_file),
- gid=portage.portage_gid, mode=02750, mask=02)
- def load(self):
- self.clear()
- self.update(portage.util.grabfile_package(self.world_file))
- def save(self):
- self._ensure_dirs()
- portage.write_atomic(self.world_file,
- "\n".join(sorted(self)) + "\n")
- def lock(self):
- self._ensure_dirs()
- self._lock = portage.locks.lockfile(self.world_file, wantnewlockfile=1)
- def unlock(self):
- portage.locks.unlockfile(self._lock)
- self._lock = None
class RootConfig(object):
"""This is used internally by depgraph to track information about a
self.settings = trees["vartree"].settings
self.root = self.settings["ROOT"]
self.sets = {}
- world_set = WorldSet(self.settings)
- world_set.load()
+ world_set = WorldSet("world", self.root)
self.sets["world"] = world_set
- system_set = SystemSet(self.settings)
+ system_set = SystemSet("system", self.settings.profiles)
self.sets["system"] = system_set
def create_world_atom(pkg_key, metadata, args_set, root_config):
# contains all sets added to the graph
self._sets = {}
# contains atoms given as arguments
- self._sets["args"] = AtomSet()
+ self._sets["args"] = InternalPackageSet()
# contains all atoms from all sets added to the graph, including
# atoms given as arguments
- self._set_atoms = AtomSet()
+ self._set_atoms = InternalPackageSet()
# contains all nodes pulled in by self._set_atoms
self._set_nodes = set()
self.blocker_digraph = digraph()
if verbosity is None:
verbosity = ("--quiet" in self.myopts and 1 or \
"--verbose" in self.myopts and 3 or 2)
- favorites_set = AtomSet()
- favorites_set.update(favorites)
+ favorites_set = InternalPackageSet(favorites)
changelogs=[]
p=[]
blockers = []
pkg_system = False
pkg_world = False
try:
- pkg_system = system_set.findAtomForPackage(pkg_key, metadata)
- pkg_world = world_set.findAtomForPackage(pkg_key, metadata)
+ pkg_system = system_set.containsCPV(pkg_key)
+ pkg_world = world_set.containsCPV(pkg_key)
if not pkg_world and myroot == self.target_root and \
- favorites_set.findAtomForPackage(pkg_key, metadata):
+ favorites_set.containsCPV(pkg_key):
# Maybe it will be added to world now.
if create_world_atom(pkg_key, metadata,
favorites_set, root_config):
root_config = self.roots[self.target_root]
world_set = root_config.sets["world"]
world_set.lock()
- world_set.load()
args_set = self._sets["args"]
portdb = self.trees[self.target_root]["porttree"].dbapi
added_favorites = set()
writemsg("!!! see '%s'\n\n" % os.path.join(
root, portage.VDB_PATH, pkg_key, "PROVIDE"), noiselevel=-1)
del e
- if added_favorites:
- world_set.save()
world_set.unlock()
def loadResumeCommand(self, resume_data):
root_config = RootConfig(self.trees[self.target_root])
system_set = root_config.sets["system"]
- args_set = AtomSet(favorites)
+ args_set = InternalPackageSet(favorites)
world_set = root_config.sets["world"]
if "--resume" not in self.myopts:
mymergelist = mylist
#buildsyspkg: Check if we need to _force_ binary package creation
issyspkg = ("buildsyspkg" in myfeat) \
and x[0] != "blocks" \
- and system_set.findAtomForPackage(pkg_key, metadata) \
+ and system_set.containsCPV(pkg_key) \
and "--buildpkg" not in self.myopts
if x[0] in ["ebuild","blocks"]:
if x[0] == "blocks" and "--fetchonly" not in self.myopts:
self.trees[x[1]]["vartree"].inject(x[2])
myfavkey = portage.cpv_getkey(x[2])
if not fetchonly and not pretend and \
- args_set.findAtomForPackage(pkg_key, metadata):
+ args_set.containsCPV(pkg_key):
world_set.lock()
- world_set.load()
myfavkey = create_world_atom(pkg_key, metadata,
args_set, root_config)
if myfavkey:
- world_set.add(myfavkey)
print ">>> Recording",myfavkey,"in \"world\" favorites file..."
emergelog(xterm_titles, " === ("+\
str(mergecount)+" of "+\
str(len(mymergelist))+\
") Updating world file ("+x[pkgindex]+")")
- world_set.save()
+ world_set.add(myfavkey)
world_set.unlock()
if "--pretend" not in self.myopts and \
vardb = dep_check_trees[myroot]["vartree"].dbapi
# Constrain dependency selection to the installed packages.
dep_check_trees[myroot]["porttree"] = dep_check_trees[myroot]["vartree"]
- system_set = SystemSet(settings)
+ system_set = SystemSet("system", settings.profiles)
syslist = list(system_set)
- world_set = WorldSet(settings)
- world_set.load()
+ world_set = WorldSet("world", myroot)
worldlist = list(world_set)
fakedb = portage.fakedbapi(settings=settings)
myvarlist = vardb.cpv_all()
self.features.remove("usersandbox")
self.features.sort()
+ if "gpg" in self.features:
+ writemsg(colorize("WARN", "!!! FEATURES=gpg is unmaintained, incomplete and broken. Disabling it."), noiselevel=-1)
+ self.features.remove("gpg")
self["FEATURES"] = " ".join(self.features)
self.backup_changes("FEATURES")
mysubject = mysubject.replace("${PACKAGE}", key)
mysubject = mysubject.replace("${HOST}", socket.getfqdn())
+ # look at the phases listed in our logentries to figure out what action was performed
+ action = "merged"
+ for phase in logentries.keys():
+ # if we found a *rm phase assume that the package was unmerged
+ if phase in ["postrm", "prerm"]:
+ action = "unmerged"
+ # if we think that the package was unmerged, make sure there was no unexpected
+ # phase recorded to avoid misinformation
+ if action == "unmerged":
+ for phase in logentries.keys():
+ if phase not in ["postrm", "prerm", "other"]:
+ action = "unknown"
+
+ mysubject = mysubject.replace("${ACTION}", action)
+
mymessage = portage.mail.create_message(myfrom, myrecipient, mysubject, fulltext)
portage.mail.send_mail(mysettings, mymessage)
@rtype: Boolean
@returns: True if the GLSA was applied, False if not
"""
- aList = grabfile(os.path.join(os.sep, self.config["ROOT"], CACHE_PATH.lstrip(os.sep)))
+ aList = grabfile(os.path.join(os.sep, self.config["ROOT"], CACHE_PATH.lstrip(os.sep), "glsa"))
return (self.nr in aList)
def inject(self):
@returns: None
"""
if not self.isApplied():
- checkfile = open(os.path.join(os.sep, self.config["ROOT"], CACHE_PATH.lstrip(os.sep)), "a+")
+ checkfile = open(os.path.join(os.sep, self.config["ROOT"], CACHE_PATH.lstrip(os.sep), "glsa"), "a+")
checkfile.write(self.nr+"\n")
checkfile.close()
return None
from portage.const import PRIVATE_PATH, USER_CONFIG_PATH
from portage.exception import InvalidAtom
-from portage.dep import isvalidatom
+from portage.dep import isvalidatom, match_from_list, best_match_to_list, dep_getkey, use_reduce, paren_reduce
+from portage import flatten
-OPERATIONS = ["merge", "unmerge", "edit"]
+OPERATIONS = ["merge", "unmerge"]
DEFAULT_SETS = ["world", "system", "everything", "security"] \
+["package_"+x for x in ["mask", "unmask", "use", "keywords"]]
class PackageSet(object):
+ # Set this to operations that are supported by your subclass. While
+ # technically there is no difference between "merge" and "unmerge" regarding
+ # package sets, the latter doesn't make sense for some sets like "system"
+ # or "security" and therefore isn't supported by them.
_operations = ["merge"]
-
+ _atommap = {}
+ description = "generic package set"
+
def __init__(self, name):
- self._name = name
- self._nodes = []
+ self.name = name
+ self._atoms = set()
+ self._atommap = {}
self._loaded = False
+ self._loading = False
+
+ def __contains__(self, atom):
+ return atom in self.getAtoms()
+
+ def __iter__(self):
+ for x in self.getAtoms():
+ yield x
def supportsOperation(self, op):
if not op in OPERATIONS:
raise ValueError(op)
return op in self._operations
- def getNodes(self):
- if not self._loaded:
+ def getAtoms(self):
+ if not (self._loaded or self._loading):
+ self._loading = True
self.load()
self._loaded = True
- return self._nodes
-
- def _setNodes(self, nodes):
- nodes = map(str.strip, nodes)
- for n in nodes[:]:
- if n == "":
- nodes.remove(n)
- elif not isvalidatom(n):
- raise InvalidAtom(n)
- self._nodes = nodes
-
- def getName(self):
- return self._name
+ self._loading = False
+ return self._atoms
+
+ def _setAtoms(self, atoms):
+ atoms = map(str.strip, atoms)
+ for a in atoms[:]:
+ if a == "":
+ atoms.remove(a)
+ elif not isvalidatom(a):
+ raise InvalidAtom(a)
+ self._atoms = atoms
+ self._updateAtomMap()
+
+ def load(self):
+ # This method must be overwritten by subclasses
+ # Editable sets should use the value of self._mtime to determine if they
+ # need to reload themselves
+ raise NotImplementedError()
+
+ def containsCPV(self, cpv):
+ for a in self.getAtoms():
+ if match_from_list(a, [cpv]):
+ return True
+ return False
- def addNode(self, node):
- if self.supportsOperation("edit"):
- self.load()
- self._nodes.append(node)
- self.write()
+ def getMetadata(self, key):
+ if hasattr(self, key.lower()):
+ return getattr(self, key.lower())
else:
- raise NotImplementedError()
+ return ""
+
+ def _updateAtomMap(self):
+ for a in self._atoms:
+ cp = dep_getkey(a)
+ self._atommap.setdefault(cp, set())
+ self._atommap[cp].add(a)
+
+ # Not sure if this one should really be in PackageSet
+ def findAtomForPackage(self, cpv, metadata):
+ """Return the best match for a given package from the arguments, or
+ None if there are no matches. This matches virtual arguments against
+ the PROVIDE metadata. This can raise an InvalidDependString exception
+ if an error occurs while parsing PROVIDE."""
+ cpv_slot = "%s:%s" % (cpv, metadata["SLOT"])
+ cp = dep_getkey(cpv)
+ atoms = self._atommap.get(cp)
+ if atoms:
+ best_match = best_match_to_list(cpv_slot, atoms)
+ if best_match:
+ return best_match
+ if not metadata["PROVIDE"]:
+ return None
+ provides = flatten(use_reduce(paren_reduce(metadata["PROVIDE"]),
+ uselist=metadata["USE"].split()))
+ for provide in provides:
+ provided_cp = dep_getkey(provide)
+ atoms = self._atommap.get(provided_cp)
+ if atoms:
+ atoms = list(atoms)
+ transformed_atoms = [atom.replace(provided_cp, cp) for atom in atoms]
+ best_match = best_match_to_list(cpv_slot, transformed_atoms)
+ if best_match:
+ return atoms[transformed_atoms.index(best_match)]
+ return None
- def removeNode(self, node):
- if self.supportsOperation("edit"):
- self.load()
- self._nodes.remove(node)
- self.write()
- else:
- raise NotImplementedError()
+class EditablePackageSet(PackageSet):
+ def getAtoms(self):
+ self.load()
+ return self._atoms
+
+ def update(self, atoms):
+ self.load()
+ self._atoms.update(atoms)
+ self._updateAtomMap()
+ self.write()
+
+ def add(self, atom):
+ self.update([atom])
+
+ def replace(self, atoms):
+ self._setAtoms(atoms)
+ self.write()
+
+ def remove(self, atom):
+ self.load()
+ self._atoms.discard(atom)
+ self._updateAtomMap()
+ self.write()
+
+ def removePackageAtoms(self, cp):
+ self.load()
+ for a in self.getAtoms():
+ if dep_getkey(a) == cp:
+ self.remove(a)
+ self.write()
def write(self):
+ # This method must be overwritten in subclasses that should be editable
raise NotImplementedError()
+
+class InternalPackageSet(EditablePackageSet):
+ def __init__(self, initial_atoms=None):
+ super(InternalPackageSet, self).__init__("")
+ if initial_atoms != None:
+ self.update(initial_atoms)
+
+ def clear(self):
+ self._atoms.clear()
+ self._updateAtomMap()
+
def load(self):
- raise NotImplementedError()
+ pass
-class EmptyPackageSet(PackageSet):
- _operations = ["merge", "unmerge"]
+ def write(self):
+ pass
def make_default_sets(configroot, root, profile_paths, settings=None,
vdbapi=None, portdbapi=None):
from portage.sets.files import StaticFileSet, ConfigFileSet
from portage.sets.profiles import PackagesSystemSet
- from portage.sets.security import AffectedSet
+ from portage.sets.security import NewAffectedSet
from portage.sets.dbapi import EverythingSet
rValue = set()
- rValue.add(StaticFileSet("world", os.path.join(root, PRIVATE_PATH, "world")))
+ worldset = StaticFileSet("world", os.path.join(root, PRIVATE_PATH, "world"))
+ worldset.description = "Set of packages that were directly installed"
+ rValue.add(worldset)
for suffix in ["mask", "unmask", "keywords", "use"]:
myname = "package_"+suffix
myset = ConfigFileSet(myname, os.path.join(configroot, USER_CONFIG_PATH.lstrip(os.sep), "package."+suffix))
rValue.add(myset)
rValue.add(PackagesSystemSet("system", profile_paths))
if settings != None and portdbapi != None:
- rValue.add(AffectedSet("security", settings, vdbapi, portdbapi))
+ rValue.add(NewAffectedSet("security", settings, vdbapi, portdbapi))
else:
- rValue.add(EmptyPackageSet("security"))
+ rValue.add(InternalPackageSet("security"))
if vdbapi != None:
rValue.add(EverythingSet("everything", vdbapi))
else:
- rValue.add(EmptyPackageSet("everything"))
+ rValue.add(InternalPackageSet("everything"))
return rValue
rValue.add(StaticFileSet(fname, os.path.join(mydir, myname)))
return rValue
+def make_category_sets(portdbapi, settings, only_visible=True):
+ from portage.sets.dbapi import CategorySet
+ rValue = set()
+ for c in settings.categories:
+ rValue.add(CategorySet("category_%s" % c, c, portdbapi, only_visible=only_visible))
+ return rValue
+
# adhoc test code
if __name__ == "__main__":
- import portage
+ import portage, sys, os
+ from portage.sets.dbapi import CategorySet
+ from portage.sets.files import StaticFileSet
l = make_default_sets("/", "/", portage.settings.profiles, portage.settings, portage.db["/"]["vartree"].dbapi, portage.db["/"]["porttree"].dbapi)
l.update(make_extra_static_sets("/"))
+ if len(sys.argv) > 1:
+ for s in sys.argv[1:]:
+ if s.startswith("category_"):
+ c = s[9:]
+ l.add(CategorySet("category_%s" % c, c, portdbapi, only_visible=only_visible))
+ elif os.path.exists(s):
+ l.add(StaticFileSet(os.path.basename(s), s))
+ elif s != "*":
+ print "ERROR: could not create set '%s'" % s
+ if not "*" in sys.argv:
+ l = [s for s in l if s.name in sys.argv[1:]]
for x in l:
- print x.getName()+":"
- for n in sorted(x.getNodes()):
+ print x.name+":"
+ print "DESCRIPTION = %s" % x.getMetadata("Description")
+ for n in sorted(x.getAtoms()):
print "- "+n
print
class EverythingSet(PackageSet):
_operations = ["merge", "unmerge"]
-
+ description = "Package set containing all installed packages"
+
def __init__(self, name, vdbapi):
super(EverythingSet, self).__init__(name)
self._db = vdbapi
def load(self):
- mynodes = []
+ myatoms = []
for cp in self._db.cp_all():
if len(self._db.cp_list(cp)) > 1:
for cpv in self._db.cp_list(cp):
myslot = self._db.aux_get(cpv, ["SLOT"])[0]
- mynodes.append(cp+":"+myslot)
+ myatoms.append(cp+":"+myslot)
else:
- mynodes.append(cp)
- self._setNodes(mynodes)
+ myatoms.append(cp)
+ self._setAtoms(myatoms)
class CategorySet(PackageSet):
_operations = ["merge", "unmerge"]
self._db = portdbapi
self._category = category
self._check = only_visible
+ if only_visible:
+ s="visible"
+ else:
+ s="all"
+ self.description = "Package set containing %s packages of category %s" % (s, self._category)
def load(self):
- mynodes = []
+ myatoms = []
for cp in self._db.cp_all():
if catsplit(cp)[0] == self._category:
if (not self._check) or len(self._db.match(cp)) > 0:
- mynodes.append(cp)
- self._setNodes(mynodes)
+ myatoms.append(cp)
+ self._setAtoms(myatoms)
# Distributed under the terms of the GNU General Public License v2
# $Id$
-from portage.util import grabfile_package, grabdict_package, write_atomic
+from portage.util import grabfile, grabfile_package, grabdict_package, write_atomic, ensure_dirs
+from portage.const import PRIVATE_PATH
+from portage.locks import lockfile, unlockfile
+from portage import portage_gid
+import os
-from portage.sets import PackageSet
+from portage.sets import PackageSet, EditablePackageSet
-class StaticFileSet(PackageSet):
- _operations = ["merge", "unmerge", "edit"]
+class StaticFileSet(EditablePackageSet):
+ _operations = ["merge", "unmerge"]
def __init__(self, name, filename):
super(StaticFileSet, self).__init__(name)
self._filename = filename
+ self._mtime = None
+ self.description = "Package set loaded from file %s" % self._filename
+ metadata = grabfile(self._filename + ".metadata")
+ key = None
+ for line in metadata:
+ line = line.strip()
+ if len(line) == 0 and key != None:
+ setattr(self, key, " ".join(value))
+ key = None
+ elif line[-1] == ":" and key == None:
+ key = line[:-1].lower()
+ value = []
+ elif key != None:
+ value.append(line)
+ else:
+ pass
+ else:
+ if key != None:
+ setattr(self, key, " ".join(value))
def write(self):
- write_atomic(self._filename, "\n".join(self._nodes)+"\n")
+ write_atomic(self._filename, "\n".join(self._atoms)+"\n")
def load(self):
- self._setNodes(grabfile_package(self._filename, recursive=True))
+ try:
+ mtime = os.stat(self._filename).st_mtime
+ except (OSError, IOError):
+ mtime = None
+ if (not self._loaded or self._mtime != mtime):
+ self._setAtoms(grabfile_package(self._filename, recursive=True))
+ self._mtime = mtime
-class ConfigFileSet(StaticFileSet):
- _operations = ["merge", "unmerge"]
+class ConfigFileSet(PackageSet):
+ def __init__(self, name, filename):
+ super(ConfigFileSet, self).__init__(name)
+ self._filename = filename
+ self.description = "Package set generated from %s" % self._filename
- def write(self):
- raise NotImplementedError()
-
def load(self):
- self._setNodes(grabdict_package(self._filename, recursive=True).keys())
+ self._setAtoms(grabdict_package(self._filename, recursive=True).keys())
+
+class WorldSet(StaticFileSet):
+ description = "Set of packages that were directly installed by the user"
+
+ def __init__(self, name, root):
+ super(WorldSet, self).__init__(name, os.path.join(os.sep, root, PRIVATE_PATH, "world"))
+ self._lock = None
+
+ def _ensure_dirs(self):
+ ensure_dirs(os.path.dirname(self._filename), gid=portage_gid, mode=02750, mask=02)
+
+ def lock(self):
+ self._ensure_dirs()
+ self._lock = lockfile(self._filename, wantnewlockfile=1)
+ def unlock(self):
+ unlockfile(self._lock)
+ self._lock = None
def __init__(self, name, profile_paths):
super(PackagesSystemSet, self).__init__(name)
self._profile_paths = profile_paths
+ self.description = "System packages for profile %s" % self._profile_paths[-1]
def load(self):
mylist = [grabfile_package(os.path.join(x, "packages")) for x in self._profile_paths]
mylist = stack_lists(mylist, incremental=1)
- self._setNodes([x[1:] for x in mylist if x[0] == "*"])
+ self._setAtoms([x[1:] for x in mylist if x[0] == "*"])
# $Id$
import portage.glsa as glsa
+from portage.util import grabfile
+from portage.const import CACHE_PATH
+import os
from portage.sets import PackageSet
class SecuritySet(PackageSet):
_operations = ["merge"]
-
+ _skip_applied = False
+
+ description = "package set that includes all packages possibly affected by a GLSA"
+
def __init__(self, name, settings, vardbapi, portdbapi):
super(SecuritySet, self).__init__(name)
self._settings = settings
self._vardbapi = vardbapi
self._portdbapi = portdbapi
+ self._checkfile = os.path.join(os.sep, self._settings["ROOT"], CACHE_PATH.lstrip(os.sep), "glsa")
+
+ def getGlsaList(self, skip_applied):
+ glsaindexlist = glsa.get_glsa_list(self._settings)
+ if skip_applied:
+ applied_list = grabfile(self._checkfile)
+ glsaindexlist = set(glsaindexlist).difference(applied_list)
+ glsaindexlist = list(glsaindexlist)
+ glsaindexlist.sort()
+ return glsaindexlist
- def loadCheckfile(self):
- self._appliedlist = grabfile(os.path.join(os.sep, self._settings["ROOT"], CACHE_PATH, "glsa"))
-
def load(self):
- glsaindexlist = glsa.get_glsa_list(self._settings)
- nodelist = []
+ glsaindexlist = self.getGlsaList(self._skip_applied)
+ atomlist = []
for glsaid in glsaindexlist:
myglsa = glsa.Glsa(glsaid, self._settings, self._vardbapi, self._portdbapi)
#print glsaid, myglsa.isVulnerable(), myglsa.isApplied(), myglsa.getMergeList()
if self.useGlsa(myglsa):
- nodelist += myglsa.getMergeList(least_change=False)
- self._setNodes(nodelist)
-
- def useGlsaId(self, glsaid):
- return True
+ atomlist += myglsa.getMergeList(least_change=False)
+ self._setAtoms(atomlist)
def useGlsa(self, myglsa):
return True
+
+ def updateAppliedList(self):
+ glsaindexlist = self.getGlsaList(True)
+ applied_list = grabfile(self._checkfile)
+ for glsaid in glsaindexlist:
+ myglsa = glsa.Glsa(glsaid, self._settings, self._vardbapi, self._portdbapi)
+ if not myglsa.isVulnerable():
+ applied_list.append(glsaid)
+ write_atomic(self._checkfile, "\n".join(applied_list))
class NewGlsaSet(SecuritySet):
- def useGlsa(self, myglsa):
- return not myglsa.isApplied()
+ _skip_applied = True
+ description = "Package set that includes all packages possibly affected by an unapplied GLSA"
class AffectedSet(SecuritySet):
+ description = "Package set that includes all packages affected by an unapplied GLSA"
+
def useGlsa(self, myglsa):
return myglsa.isVulnerable()
+
+class NewAffectedSet(AffectedSet):
+ _skip_applied = True
+ description = "Package set that includes all packages affected by an unapplied GLSA"
def __init__(self, name, command):
super(CommandOutputSet, self).__init__(name)
self._command = command
+ self.description = "Package set generated from output of '%s'" % self._command
def load(self):
pipe = subprocess.Popen(self._command, stdout=subprocess.PIPE, shell=True)
if pipe.wait() == os.EX_OK:
text = pipe.stdout.read()
- self._setNodes(text.split("\n"))
+ self._setAtoms(text.split("\n"))