Cool. So, I tested this by installing: - https://alioth.debian.org/anonscm/git/mirrorer/mirrorer.git (git repo)
- branched off the (default) debian branch [2] - patched with Add-multiple-version-management.patch https://bugs.debian.org/cgi-bin/bugreport.cgi?msg=70;filename=Add-multiple-version-management.patch;att=15;bug=570623 - fixed 3 conflicts in main.c, not sure what was conflicting, probably leftover whitespace or something. - autoreconf -vi (see INSTALL for dependencies) - ./configure --prefix=/usr/local; make; make install - renamed the resultant binaries with "-mver" suffix so they don't conflict with the rest of my setup Initial observations: - I started a new multi-version repository and loaded up several versions of a package: it works. - Downgrading/upgrading a single package from that repository works. - Warnings when including a new package:
debian-mver# reprepro-mver -C acos include wheezy /srv/junk/asterisk*13.3.*changes Error while parsing 'asterisk-config|1:13.3.0-acos1+o0' as version: epoch in version is not number Parse errors processing versions. Error while parsing 'asterisk-dbg|1:13.3.0-acos1+o0' as version: epoch in version is not number Parse errors processing versions.
... It complained about the epoch in version not being a number. I assume someone takes "asterisk-config|1" to be an epoch, instead of just "1". (See below/attachment for a fix.) - When including two packages with the same minor/micro version, things were less okay:
debian-mver# reprepro-mver -C acos include wheezy /srv/junk/old/asterisk_13.2.0*acos2*changes Error while parsing 'asterisk-config|1:13.2.0-acos2+o0+2up' as version: epoch in version is not number Parse errors processing versions.
...
Internal error of the underlying BerkeleyDB database: Within references.db subtable references at put: DB_KEYEXIST: Key/data pair already exists Warning: database 'wheezy|acos|amd64' was modified but no index file was exported. Changes will only be visible after the next 'export'! There have been errors!
But a dump [1] of the references file revealed no immediate problem:
debian-mver# diff -pu <(cat -A references.db.2) <(cat -A references.db.3) --- /dev/fd/63 2015-04-07 11:45:35.900044000 +0200 +++ /dev/fd/62 2015-04-07 11:45:35.900044000 +0200 @@ -8,38 +8,72 @@ db_pagesize=4096$ HEADER=END$ >>> pool/acos/a/asterisk/asterisk-config_13.2.0-acos1+o0+2up_all.deb^@$ >>> wheezy|acos|amd64^@$ +>>> pool/acos/a/asterisk/asterisk-config_13.2.0-acos2+o0+2up_all.deb^@$ +>>> wheezy|acos|amd64^@$
... I added a few debug prints, and I got this: ...
Skipping inclusion of 'asterisk-modules' '1:13.2.0-acos2+o0+2up' in 'wheezy|acos|amd64', as this version already exists. Skipping inclusion of 'asterisk' '1:13.2.0-acos2+o0+2up' in 'wheezy|acos|amd64', as this version already exists.
db: 'pool/acos/a/asterisk/asterisk_13.2.0-acos2+o0+2up.dsc' adding to references.db(references). Internal error of the underlying BerkeleyDB database: Within references.db subtable references at put: DB_KEYEXIST: Key/data pair already exists db: 'pool/acos/a/asterisk/asterisk_13.2.0.orig.tar.gz' adding to references.db(references). Internal error of the underlying BerkeleyDB database: Within references.db subtable references at put: DB_KEYEXIST: Key/data pair already exists db: 'pool/acos/a/asterisk/asterisk_13.2.0-acos2+o0+2up.debian.tar.gz' adding to references.db(references). Internal error of the underlying BerkeleyDB database: Within references.db subtable references at put: DB_KEYEXIST: Key/data pair already exists There have been errors!
Those errors only popped up when uploading the 2nd (acos2) version. For the first (acos1), I just get the "Skipping" notices like expected (when calling it a second/third time). - Removing a package worked, unless we have multiple versions:
debian-mver# reprepro-mver -C acos remove wheezy libpjproject-dev=2.3.0.0.ast20150218-acos1
OK - Removing a package did not work when we have multiple versions:
debian-mver# reprepro-mver -C acos list wheezy | head -n2 wheezy|acos|amd64: asterisk 1:13.3.0-acos1+o0 wheezy|acos|amd64: asterisk 1:13.2.0-acos2+o0+2up
...
debian-mver# reprepro-mver -C acos remove wheezy asterisk=1:13.2.0-acos2+o0+2up removing 'asterisk=1:13.2.0-acos2+o0+2up' from 'wheezy|acos|amd64'... Error while parsing 'asterisk|1:13.2.0-acos2+o0+2up' as version: epoch in version is not number Parse errors processing versions. Error while parsing 'asterisk|1:13.2.0-acos2+o0+2up' as version: epoch in version is not number Parse errors processing versions. /srv/reprepro/debian-mver/db/packages.db/wheezy|acos|amd64: DB_SECONDARY_BAD: Secondary index inconsistent with primary Internal error of the underlying BerkeleyDB database: Within packages.db subtable wheezy|acos|amd64 at del: DB_SECONDARY_BAD: Secondary index inconsistent with primary There have been errors!
- However, when adding bug570623_version_compare.patch (attached), removal started to work as expected. In summary: - patching the version compare helps, but - multiple closely related versions still cause grief Thanks for the patches! Cheers, Walter Doekes OSSO B.V. [1] references.db was dumped like this: $ db5.1_dump db/references.db | perl -pe '/^ /&&s/^/>>> /&&s/[0-9a-f]{2}/chr hex$&/ige' [2] changing from the `debian` branch to the `master` branch didn't seem to change anything
diff --git a/database.c b/database.c index d0f2c63..3303239 100644 --- a/database.c +++ b/database.c @@ -1903,6 +1903,22 @@ retvalue database_openreferences(void) { return RET_OK; } +static retvalue fullversions_cmp(const char *first, const char *second, int *result) { + const char *a = strchr(first, '|'); /* name|version */ + const char *b = strchr(second, '|'); + + if (a == NULL && b == NULL) { + return dpkgversions_cmp(first, second, result); + } else if (a && b) { + if ((a - first) == (b - second) && memcmp(first, second, (a - first)) == 0) { + return dpkgversions_cmp(a + 1, b + 1, result); + } + } + + fprintf(stderr, "We have trouble comparing '%s' with '%s'\n", first, second); + return RET_ERROR; +} + static int debianversioncompare(UNUSED(DB *db), const DBT *a, const DBT *b) { const char *a_version; const char *b_version; @@ -1912,7 +1928,7 @@ static int debianversioncompare(UNUSED(DB *db), const DBT *a, const DBT *b) { // TODO: Check lenght of a->data and b->data a_version = packagedata_getversion(a->data); b_version = packagedata_getversion(b->data); - r = dpkgversions_cmp(a_version, b_version, &versioncmp); + r = fullversions_cmp(a_version, b_version, &versioncmp); if (RET_WAS_ERROR(r)) { fprintf(stderr, "Parse errors processing versions.\n"); return r;