Fixed a pointer problem which caused segfaults when dealing with virtual packages; fixed a bug in source removal; moved add_binary and remove_binary from the britney module to the Packages object.

bzr-import-20160707
Fabio Tranchitella 19 years ago
parent 3825241619
commit 76b3a8cf3c

@ -187,7 +187,7 @@ import operator
import apt_pkg import apt_pkg
from excuse import Excuse from excuse import Excuse
from britney import buildSystem, addBinary, removeBinary from britney import buildSystem
__author__ = 'Fabio Tranchitella' __author__ = 'Fabio Tranchitella'
__version__ = '2.0.alpha1' __version__ = '2.0.alpha1'
@ -1556,17 +1556,6 @@ class Britney:
binaries = self.binaries['testing'] binaries = self.binaries['testing']
systems = self.systems systems = self.systems
# when a new uninstallable package is discovered, check again all the
# reverse dependencies and if they are uninstallable, too, call itself
# recursively
def add_nuninst(pkg, arch):
if pkg not in nuninst[arch]:
nuninst[arch].append(pkg)
for p in binaries[arch][0][pkg][RDEPENDS]:
r = systems[arch].is_installable(p)
if not r:
add_nuninst(p, arch)
# for all the architectures # for all the architectures
for arch in self.options.architectures: for arch in self.options.architectures:
if requested_arch and arch != requested_arch: continue if requested_arch and arch != requested_arch: continue
@ -1581,7 +1570,7 @@ class Britney:
for pkg_name in binaries[arch][0]: for pkg_name in binaries[arch][0]:
r = systems[arch].is_installable(pkg_name) r = systems[arch].is_installable(pkg_name)
if not r: if not r:
add_nuninst(pkg_name, arch) nuninst[arch].append(pkg_name)
# if they are not required, removed architecture-indipendent packages # if they are not required, removed architecture-indipendent packages
nuninst[arch + "+all"] = nuninst[arch][:] nuninst[arch + "+all"] = nuninst[arch][:]
@ -1963,6 +1952,8 @@ class Britney:
for p in source[BINARIES]: for p in source[BINARIES]:
binary, parch = p.split("/") binary, parch = p.split("/")
if arch and parch != arch: continue if arch and parch != arch: continue
# do not remove binaries which have been hijacked by other sources
if binaries[parch][0][binary][SOURCE] != pkg_name: continue
# if a smooth update is possible for the package, skip it # if a smooth update is possible for the package, skip it
if not self.options.compatible and suite == 'unstable' and \ if not self.options.compatible and suite == 'unstable' and \
binary not in self.binaries[suite][parch][0] and \ binary not in self.binaries[suite][parch][0] and \
@ -1985,7 +1976,7 @@ class Britney:
del binaries[parch][1][j] del binaries[parch][1][j]
# finally, remove the binary package # finally, remove the binary package
del binaries[parch][0][binary] del binaries[parch][0][binary]
removeBinary(self.systems[parch], binary) self.systems[parch].remove_binary(binary)
# remove the source package # remove the source package
if not arch: if not arch:
undo['sources'][pkg_name] = source undo['sources'][pkg_name] = source
@ -2001,7 +1992,7 @@ class Britney:
key = (j, arch) key = (j, arch)
if key not in affected: affected.append(key) if key not in affected: affected.append(key)
del binaries[arch][0][pkg_name] del binaries[arch][0][pkg_name]
removeBinary(self.systems[arch], pkg_name) self.systems[arch].remove_binary(pkg_name)
# add the new binary packages (if we are not removing) # add the new binary packages (if we are not removing)
if pkg[0] != "-": if pkg[0] != "-":
@ -2027,10 +2018,10 @@ class Britney:
for p in self.get_full_tree(j, parch, 'testing'): for p in self.get_full_tree(j, parch, 'testing'):
key = (p, parch) key = (p, parch)
if key not in affected: affected.append(key) if key not in affected: affected.append(key)
removeBinary(self.systems[parch], binary) self.systems[parch].remove_binary(binary)
# add/update the binary package # add/update the binary package
binaries[parch][0][binary] = self.binaries[suite][parch][0][binary] binaries[parch][0][binary] = self.binaries[suite][parch][0][binary]
addBinary(self.systems[parch], binary, binaries[parch][0][binary][:PROVIDES] + \ self.systems[parch].add_binary(binary, binaries[parch][0][binary][:PROVIDES] + \
[", ".join(binaries[parch][0][binary][PROVIDES]) or None]) [", ".join(binaries[parch][0][binary][PROVIDES]) or None])
# register new provided packages # register new provided packages
for j in binaries[parch][0][binary][PROVIDES]: for j in binaries[parch][0][binary][PROVIDES]:
@ -2161,58 +2152,41 @@ class Britney:
nuninst[arch] = [x for x in nuninst_comp[arch] if x in binaries[arch][0]] nuninst[arch] = [x for x in nuninst_comp[arch] if x in binaries[arch][0]]
nuninst[arch + "+all"] = [x for x in nuninst_comp[arch + "+all"] if x in binaries[arch][0]] nuninst[arch + "+all"] = [x for x in nuninst_comp[arch + "+all"] if x in binaries[arch][0]]
broken = nuninst[arch + "+all"] broken = nuninst[arch + "+all"]
to_check = [x[0] for x in affected if x[1] == arch] to_check = []
# broken packages (first round) # broken packages (first round)
repaired = [] for p in [x[0] for x in affected if x[1] == arch]:
broken_changed = True if p not in binaries[arch][0]: continue
last_broken = None r = systems[arch].is_installable(p)
while broken_changed: if not r and p not in broken:
broken_changed = False to_check.append(p)
for p in to_check: broken.append(p)
if p == last_broken: break if not (skip_archall and binaries[arch][0][p][ARCHITECTURE] == 'all'):
if p not in binaries[arch][0]: continue nuninst[arch].append(p)
elif r and p in broken:
to_check.append(p)
broken.remove(p)
if not (skip_archall and binaries[arch][0][p][ARCHITECTURE] == 'all'):
nuninst[arch].remove(p)
# broken packages (second round, reverse dependencies of the first round)
while to_check:
j = to_check.pop(0)
if j not in binaries[arch][0]: continue
for p in binaries[arch][0][j][RDEPENDS]:
if p in broken or p not in binaries[arch][0]: continue
r = systems[arch].is_installable(p) r = systems[arch].is_installable(p)
if not r and p not in broken: if not r and p not in broken:
last_broken = p
broken.append(p) broken.append(p)
broken_changed = True to_check.append(p)
if not (skip_archall and binaries[arch][0][p][ARCHITECTURE] == 'all'): if not (skip_archall and binaries[arch][0][p][ARCHITECTURE] == 'all'):
nuninst[arch].append(p) nuninst[arch].append(p)
elif r and p in broken: elif r and p in nuninst[arch + "+all"]:
last_broken = p
repaired.append(p)
broken.remove(p) broken.remove(p)
broken_changed = True to_check.append(p)
if not (skip_archall and binaries[arch][0][p][ARCHITECTURE] == 'all'): if not (skip_archall and binaries[arch][0][p][ARCHITECTURE] == 'all'):
nuninst[arch].remove(p) nuninst[arch].remove(p)
# broken packages (second round, reverse dependencies of the first round)
l = 0
broken_changed = True
last_broken = None
while broken_changed:
broken_changed = False
for j in broken + repaired:
if j not in binaries[arch][0]: continue
for p in binaries[arch][0][j][RDEPENDS]:
if p in broken or p not in binaries[arch][0]: continue
r = systems[arch].is_installable(p)
if not r and p not in broken:
l = -1
last_broken = j
broken.append(p)
broken_changed = True
if not (skip_archall and binaries[arch][0][p][ARCHITECTURE] == 'all'):
nuninst[arch].append(p)
elif r and p in nuninst[arch + "+all"]:
last_broken = p
repaired.append(p)
broken.remove(p)
broken_changed = True
if not (skip_archall and binaries[arch][0][p][ARCHITECTURE] == 'all'):
nuninst[arch].remove(p)
if l != -1 and last_broken == j: break
# if we are processing hints, go ahead # if we are processing hints, go ahead
if hint: if hint:
nuninst_comp[arch] = nuninst[arch] nuninst_comp[arch] = nuninst[arch]
@ -2265,18 +2239,18 @@ class Britney:
binary, arch = p.split("/") binary, arch = p.split("/")
if "/" in pkg and arch != pkg[pkg.find("/")+1:]: continue if "/" in pkg and arch != pkg[pkg.find("/")+1:]: continue
del binaries[arch][0][binary] del binaries[arch][0][binary]
removeBinary(self.systems[arch], binary) self.systems[arch].remove_binary(binary)
# undo the changes (binaries) # undo the changes (binaries)
for p in undo['binaries'].keys(): for p in undo['binaries'].keys():
binary, arch = p.split("/") binary, arch = p.split("/")
if binary[0] == "-": if binary[0] == "-":
del binaries[arch][0][binary[1:]] del binaries[arch][0][binary[1:]]
removeBinary(self.systems[arch], binary[1:]) self.systems[arch].remove_binary(binary[1:])
else: else:
binaries[arch][0][binary] = undo['binaries'][p] binaries[arch][0][binary] = undo['binaries'][p]
removeBinary(self.systems[arch], binary) self.systems[arch].remove_binary(binary)
addBinary(self.systems[arch], binary, binaries[arch][0][binary][:PROVIDES] + \ self.systems[arch].add_binary(binary, binaries[arch][0][binary][:PROVIDES] + \
[", ".join(binaries[arch][0][binary][PROVIDES]) or None]) [", ".join(binaries[arch][0][binary][PROVIDES]) or None])
# undo the changes (virtual packages) # undo the changes (virtual packages)
@ -2390,14 +2364,14 @@ class Britney:
binary, arch = p.split("/") binary, arch = p.split("/")
if "/" in pkg and arch != pkg[pkg.find("/")+1:]: continue if "/" in pkg and arch != pkg[pkg.find("/")+1:]: continue
del self.binaries['testing'][arch][0][binary] del self.binaries['testing'][arch][0][binary]
removeBinary(self.systems[arch], binary) self.systems[arch].remove_binary(binary)
# undo the changes (binaries) # undo the changes (binaries)
for p in undo['binaries'].keys(): for p in undo['binaries'].keys():
binary, arch = p.split("/") binary, arch = p.split("/")
if binary[0] == "-": if binary[0] == "-":
del self.binaries['testing'][arch][0][binary[1:]] del self.binaries['testing'][arch][0][binary[1:]]
removeBinary(self.systems[arch], binary[1:]) self.systems[arch].remove_binary(binary[1:])
else: self.binaries['testing'][arch][0][binary] = undo['binaries'][p] else: self.binaries['testing'][arch][0][binary] = undo['binaries'][p]
# undo the changes (virtual packages) # undo the changes (virtual packages)

@ -246,6 +246,106 @@ static PyObject *dpkgpackages_unsatdeps(dpkgpackages *self, PyObject *args) {
return res; return res;
} }
static PyObject *dpkgpackages_remove_binary(dpkgpackages *self, PyObject *args) {
char *pkg_name;
(void)self; /* unused */
if (!PyArg_ParseTuple(args, "s", &pkg_name))
return NULL;
dpkg_collected_package *cpkg = lookup_packagetbl(self->pkgs->packages, pkg_name);
if (cpkg == NULL) return Py_BuildValue("i", 0);
remove_package(self->pkgs, cpkg);
return Py_BuildValue("i", 1);
}
static PyObject *dpkgpackages_add_binary(dpkgpackages *self, PyObject *args) {
char *pkg_name;
PyObject *value, *pyString;
(void)self; /* unused */
if (!PyArg_ParseTuple(args, "sO", &pkg_name, &value) ||
!PyList_Check(value)) return NULL;
/* initialize the new package */
dpkg_package *pkg;
pkg = block_malloc(sizeof(dpkg_package));
pkg->package = strdup(pkg_name);
pkg->priority = 0;
pkg->details = NULL;
pkg->depends[2] = NULL;
pkg->depends[3] = NULL;
pyString = PyList_GetItem(value, 0);
if (pyString == NULL) return NULL;
pkg->version = PyString_AsString(pyString);
pyString = PyList_GetItem(value, 2);
if (pyString == NULL) return NULL;
pkg->source = PyString_AsString(pyString);
pyString = PyList_GetItem(value, 3);
if (pyString == NULL) return NULL;
pkg->source_ver = PyString_AsString(pyString);
pyString = PyList_GetItem(value, 4);
if (pyString == NULL) return NULL;
pkg->arch_all = (!strcmp(PyString_AsString(pyString), "all") ? 1 : 0);
pyString = PyList_GetItem(value, 5);
if (pyString == NULL) return NULL;
if (pyString != Py_None) {
pkg->depends[0] = read_dep_andor(PyString_AsString(pyString));
} else pkg->depends[0] = NULL;
pyString = PyList_GetItem(value, 6);
if (pyString == NULL) return NULL;
if (pyString != Py_None) {
pkg->depends[1] = read_dep_andor(PyString_AsString(pyString));
} else pkg->depends[1] = NULL;
pyString = PyList_GetItem(value, 7);
if (pyString == NULL) return NULL;
if (pyString != Py_None) {
pkg->conflicts = read_dep_and(PyString_AsString(pyString));
} else pkg->conflicts = NULL;
pyString = PyList_GetItem(value, 8);
if (pyString == NULL) return NULL;
if (pyString != Py_None) {
pkg->provides = read_packagenames(PyString_AsString(pyString));
} else pkg->provides = NULL;
add_package(self->pkgs, pkg);
return Py_BuildValue("i", 1);
}
static PyObject *dpkgpackages_print_providers(dpkgpackages *self, PyObject *args) {
char *pkg_name;
(void)self; /* unused */
if (!PyArg_ParseTuple(args, "s", &pkg_name)) return NULL;
virtualpkg *list;
virtualpkg **where;
list = lookup_virtualpkgtbl(self->pkgs->virtualpkgs, pkg_name);
where = &list;
printf("Virtual package: %s\n", pkg_name);
while (*where != NULL) {
printf(" + provided by: %s\n", (*where)->value.pkg->pkg->package);
where = &(*where)->next;
}
printf("\n");
return Py_BuildValue("i", 1);
}
static PyObject *dpkgpackages_getattr(dpkgpackages *self, char *name) { static PyObject *dpkgpackages_getattr(dpkgpackages *self, char *name) {
static struct PyMethodDef dpkgsources_methods[] = { static struct PyMethodDef dpkgsources_methods[] = {
{ "is_present", (binaryfunc) dpkgpackages_ispresent, { "is_present", (binaryfunc) dpkgpackages_ispresent,
@ -268,6 +368,14 @@ static PyObject *dpkgpackages_getattr(dpkgpackages *self, char *name) {
METH_VARARGS, NULL }, METH_VARARGS, NULL },
{ "unsatisfiable_deps", (binaryfunc) dpkgpackages_unsatdeps, { "unsatisfiable_deps", (binaryfunc) dpkgpackages_unsatdeps,
METH_VARARGS, NULL }, METH_VARARGS, NULL },
{ "remove_binary", (binaryfunc) dpkgpackages_remove_binary,
METH_VARARGS, NULL },
{ "add_binary", (binaryfunc) dpkgpackages_add_binary,
METH_VARARGS, NULL },
{ "print_providers", (binaryfunc) dpkgpackages_print_providers,
METH_VARARGS, NULL },
{ NULL, NULL, 0, NULL } { NULL, NULL, 0, NULL }
}; };
@ -889,7 +997,7 @@ static PyObject *build_system(PyObject *self, PyObject *args) {
/* initialize the new package */ /* initialize the new package */
dpkg_package *pkg; dpkg_package *pkg;
pkg = block_malloc(sizeof(dpkg_package)); pkg = block_malloc(sizeof(dpkg_package));
pkg->package = PyString_AsString(key); pkg->package = strdup(PyString_AsString(key));
pkg->priority = 0; pkg->priority = 0;
pkg->details = NULL; pkg->details = NULL;
pkg->depends[2] = NULL; pkg->depends[2] = NULL;
@ -949,86 +1057,6 @@ static PyObject *build_system(PyObject *self, PyObject *args) {
return (PyObject *)res; return (PyObject *)res;
} }
static PyObject *remove_binary(PyObject *self, PyObject *args) {
char *pkg_name;
dpkgpackages *pkgs;
(void)self; /* unused */
if (!PyArg_ParseTuple(args, "Os", &pkgs, &pkg_name))
return NULL;
dpkg_collected_package *cpkg = lookup_packagetbl(pkgs->pkgs->packages, pkg_name);
if (cpkg == NULL) return Py_BuildValue("i", 0);
remove_package(pkgs->pkgs, cpkg);
return Py_BuildValue("i", 1);
}
static PyObject *add_binary(PyObject *self, PyObject *args) {
char *pkg_name;
dpkgpackages *pkgs;
PyObject *value, *pyString;
(void)self; /* unused */
if (!PyArg_ParseTuple(args, "OsO", &pkgs, &pkg_name, &value) ||
!PyList_Check(value)) return NULL;
/* initialize the new package */
dpkg_package *pkg;
pkg = block_malloc(sizeof(dpkg_package));
pkg->package = pkg_name;
pkg->priority = 0;
pkg->details = NULL;
pkg->depends[2] = NULL;
pkg->depends[3] = NULL;
pyString = PyList_GetItem(value, 0);
if (pyString == NULL) return NULL;
pkg->version = PyString_AsString(pyString);
pyString = PyList_GetItem(value, 2);
if (pyString == NULL) return NULL;
pkg->source = PyString_AsString(pyString);
pyString = PyList_GetItem(value, 3);
if (pyString == NULL) return NULL;
pkg->source_ver = PyString_AsString(pyString);
pyString = PyList_GetItem(value, 4);
if (pyString == NULL) return NULL;
pkg->arch_all = (!strcmp(PyString_AsString(pyString), "all") ? 1 : 0);
pyString = PyList_GetItem(value, 5);
if (pyString == NULL) return NULL;
if (pyString != Py_None) {
pkg->depends[0] = read_dep_andor(PyString_AsString(pyString));
} else pkg->depends[0] = NULL;
pyString = PyList_GetItem(value, 6);
if (pyString == NULL) return NULL;
if (pyString != Py_None) {
pkg->depends[1] = read_dep_andor(PyString_AsString(pyString));
} else pkg->depends[1] = NULL;
pyString = PyList_GetItem(value, 7);
if (pyString == NULL) return NULL;
if (pyString != Py_None) {
pkg->conflicts = read_dep_and(PyString_AsString(pyString));
} else pkg->conflicts = NULL;
pyString = PyList_GetItem(value, 8);
if (pyString == NULL) return NULL;
if (pyString != Py_None) {
pkg->provides = read_packagenames(PyString_AsString(pyString));
} else pkg->provides = NULL;
add_package(pkgs->pkgs, pkg);
return Py_BuildValue("i", 1);
}
/************************************************************************** /**************************************************************************
* module initialisation * module initialisation
@ -1041,8 +1069,6 @@ static PyMethodDef britneymethods[] = {
{ "versioncmp", apt_versioncmp, METH_VARARGS, NULL }, { "versioncmp", apt_versioncmp, METH_VARARGS, NULL },
{ "buildSystem", build_system, METH_VARARGS, NULL }, { "buildSystem", build_system, METH_VARARGS, NULL },
{ "removeBinary", remove_binary, METH_VARARGS, NULL },
{ "addBinary", add_binary, METH_VARARGS, NULL },
{ NULL, NULL, 0, NULL } { NULL, NULL, 0, NULL }
}; };

@ -21,7 +21,7 @@ packages = {'phpldapadmin': ['1.0', 'web', 'phpldapadmin', '1.0', 'all', '', 'ap
system = britney.buildSystem('i386', packages) system = britney.buildSystem('i386', packages)
print system.is_installable('phpldapadmin'), system.packages print system.is_installable('phpldapadmin'), system.packages
britney.removeBinary(system, 'apache2') system.remove_binary('apache2')
print system.is_installable('phpldapadmin'), system.packages print system.is_installable('phpldapadmin'), system.packages
britney.addBinary(system, 'apache2', ['2.0', 'web', 'apache2', '2.0', 'i386', '', '', 'phpldapadmin (<= 1.0~)', '', [], []]) system.add_binary('apache2', ['2.0', 'web', 'apache2', '2.0', 'i386', '', '', 'phpldapadmin (<= 1.0~)', '', [], []])
print system.is_installable('phpldapadmin'), system.packages print system.is_installable('phpldapadmin'), system.packages

Loading…
Cancel
Save