mirror of
https://git.launchpad.net/~ubuntu-release/britney/+git/britney2-ubuntu
synced 2025-04-09 18:21:10 +00:00
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.
This commit is contained in:
parent
3825241619
commit
76b3a8cf3c
116
britney.py
116
britney.py
@ -187,7 +187,7 @@ import operator
|
||||
import apt_pkg
|
||||
|
||||
from excuse import Excuse
|
||||
from britney import buildSystem, addBinary, removeBinary
|
||||
from britney import buildSystem
|
||||
|
||||
__author__ = 'Fabio Tranchitella'
|
||||
__version__ = '2.0.alpha1'
|
||||
@ -1556,17 +1556,6 @@ class Britney:
|
||||
binaries = self.binaries['testing']
|
||||
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 arch in self.options.architectures:
|
||||
if requested_arch and arch != requested_arch: continue
|
||||
@ -1581,7 +1570,7 @@ class Britney:
|
||||
for pkg_name in binaries[arch][0]:
|
||||
r = systems[arch].is_installable(pkg_name)
|
||||
if not r:
|
||||
add_nuninst(pkg_name, arch)
|
||||
nuninst[arch].append(pkg_name)
|
||||
|
||||
# if they are not required, removed architecture-indipendent packages
|
||||
nuninst[arch + "+all"] = nuninst[arch][:]
|
||||
@ -1963,6 +1952,8 @@ class Britney:
|
||||
for p in source[BINARIES]:
|
||||
binary, parch = p.split("/")
|
||||
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 not self.options.compatible and suite == 'unstable' and \
|
||||
binary not in self.binaries[suite][parch][0] and \
|
||||
@ -1985,7 +1976,7 @@ class Britney:
|
||||
del binaries[parch][1][j]
|
||||
# finally, remove the binary package
|
||||
del binaries[parch][0][binary]
|
||||
removeBinary(self.systems[parch], binary)
|
||||
self.systems[parch].remove_binary(binary)
|
||||
# remove the source package
|
||||
if not arch:
|
||||
undo['sources'][pkg_name] = source
|
||||
@ -2001,7 +1992,7 @@ class Britney:
|
||||
key = (j, arch)
|
||||
if key not in affected: affected.append(key)
|
||||
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)
|
||||
if pkg[0] != "-":
|
||||
@ -2027,10 +2018,10 @@ class Britney:
|
||||
for p in self.get_full_tree(j, parch, 'testing'):
|
||||
key = (p, parch)
|
||||
if key not in affected: affected.append(key)
|
||||
removeBinary(self.systems[parch], binary)
|
||||
self.systems[parch].remove_binary(binary)
|
||||
# add/update the binary package
|
||||
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])
|
||||
# register new provided packages
|
||||
for j in binaries[parch][0][binary][PROVIDES]:
|
||||
@ -2161,57 +2152,40 @@ class Britney:
|
||||
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]]
|
||||
broken = nuninst[arch + "+all"]
|
||||
to_check = [x[0] for x in affected if x[1] == arch]
|
||||
to_check = []
|
||||
|
||||
# broken packages (first round)
|
||||
repaired = []
|
||||
broken_changed = True
|
||||
last_broken = None
|
||||
while broken_changed:
|
||||
broken_changed = False
|
||||
for p in to_check:
|
||||
if p == last_broken: break
|
||||
if p not in binaries[arch][0]: continue
|
||||
r = systems[arch].is_installable(p)
|
||||
if not r and p not in broken:
|
||||
last_broken = p
|
||||
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 broken:
|
||||
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)
|
||||
for p in [x[0] for x in affected if x[1] == arch]:
|
||||
if p not in binaries[arch][0]: continue
|
||||
r = systems[arch].is_installable(p)
|
||||
if not r and p not in broken:
|
||||
to_check.append(p)
|
||||
broken.append(p)
|
||||
if not (skip_archall and binaries[arch][0][p][ARCHITECTURE] == 'all'):
|
||||
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)
|
||||
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
|
||||
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)
|
||||
if not r and p not in broken:
|
||||
broken.append(p)
|
||||
to_check.append(p)
|
||||
if not (skip_archall and binaries[arch][0][p][ARCHITECTURE] == 'all'):
|
||||
nuninst[arch].append(p)
|
||||
elif r and p in nuninst[arch + "+all"]:
|
||||
broken.remove(p)
|
||||
to_check.append(p)
|
||||
if not (skip_archall and binaries[arch][0][p][ARCHITECTURE] == 'all'):
|
||||
nuninst[arch].remove(p)
|
||||
|
||||
# if we are processing hints, go ahead
|
||||
if hint:
|
||||
@ -2265,18 +2239,18 @@ class Britney:
|
||||
binary, arch = p.split("/")
|
||||
if "/" in pkg and arch != pkg[pkg.find("/")+1:]: continue
|
||||
del binaries[arch][0][binary]
|
||||
removeBinary(self.systems[arch], binary)
|
||||
self.systems[arch].remove_binary(binary)
|
||||
|
||||
# undo the changes (binaries)
|
||||
for p in undo['binaries'].keys():
|
||||
binary, arch = p.split("/")
|
||||
if binary[0] == "-":
|
||||
del binaries[arch][0][binary[1:]]
|
||||
removeBinary(self.systems[arch], binary[1:])
|
||||
self.systems[arch].remove_binary(binary[1:])
|
||||
else:
|
||||
binaries[arch][0][binary] = undo['binaries'][p]
|
||||
removeBinary(self.systems[arch], binary)
|
||||
addBinary(self.systems[arch], binary, binaries[arch][0][binary][:PROVIDES] + \
|
||||
self.systems[arch].remove_binary(binary)
|
||||
self.systems[arch].add_binary(binary, binaries[arch][0][binary][:PROVIDES] + \
|
||||
[", ".join(binaries[arch][0][binary][PROVIDES]) or None])
|
||||
|
||||
# undo the changes (virtual packages)
|
||||
@ -2390,14 +2364,14 @@ class Britney:
|
||||
binary, arch = p.split("/")
|
||||
if "/" in pkg and arch != pkg[pkg.find("/")+1:]: continue
|
||||
del self.binaries['testing'][arch][0][binary]
|
||||
removeBinary(self.systems[arch], binary)
|
||||
self.systems[arch].remove_binary(binary)
|
||||
|
||||
# undo the changes (binaries)
|
||||
for p in undo['binaries'].keys():
|
||||
binary, arch = p.split("/")
|
||||
if binary[0] == "-":
|
||||
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]
|
||||
|
||||
# undo the changes (virtual packages)
|
||||
|
192
lib/britney-py.c
192
lib/britney-py.c
@ -246,6 +246,106 @@ static PyObject *dpkgpackages_unsatdeps(dpkgpackages *self, PyObject *args) {
|
||||
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 struct PyMethodDef dpkgsources_methods[] = {
|
||||
{ "is_present", (binaryfunc) dpkgpackages_ispresent,
|
||||
@ -268,6 +368,14 @@ static PyObject *dpkgpackages_getattr(dpkgpackages *self, char *name) {
|
||||
METH_VARARGS, NULL },
|
||||
{ "unsatisfiable_deps", (binaryfunc) dpkgpackages_unsatdeps,
|
||||
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 }
|
||||
};
|
||||
|
||||
@ -889,7 +997,7 @@ static PyObject *build_system(PyObject *self, PyObject *args) {
|
||||
/* initialize the new package */
|
||||
dpkg_package *pkg;
|
||||
pkg = block_malloc(sizeof(dpkg_package));
|
||||
pkg->package = PyString_AsString(key);
|
||||
pkg->package = strdup(PyString_AsString(key));
|
||||
pkg->priority = 0;
|
||||
pkg->details = NULL;
|
||||
pkg->depends[2] = NULL;
|
||||
@ -949,86 +1057,6 @@ static PyObject *build_system(PyObject *self, PyObject *args) {
|
||||
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
|
||||
@ -1041,8 +1069,6 @@ static PyMethodDef britneymethods[] = {
|
||||
{ "versioncmp", apt_versioncmp, 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 }
|
||||
};
|
||||
|
@ -21,7 +21,7 @@ packages = {'phpldapadmin': ['1.0', 'web', 'phpldapadmin', '1.0', 'all', '', 'ap
|
||||
|
||||
system = britney.buildSystem('i386', packages)
|
||||
print system.is_installable('phpldapadmin'), system.packages
|
||||
britney.removeBinary(system, 'apache2')
|
||||
system.remove_binary('apache2')
|
||||
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
|
||||
|
Loading…
x
Reference in New Issue
Block a user