[pacman-dev] [PATCH 0/5] RFC: epoch implementation
Hey guys, This is a quick set of patches to implement the use of epoch in our packages, and remove the 'force' option. It adds a lot more flexibility and should prevent weird upgrade/downgrade interaction between different repositories, and also removes the need to munge versions as often. The pacman stuff is pretty well tested via the current suite of pactests, although we will want to add some new tests specifically playing with the epoch value in the test packages. Anyway, thoughts/comments/suggestions welcome. The changes are not too invasive and the only real complexity comes from trying to remain backward and forward compatible. This addresses bugs such as FS#14887, FS#19153, FS#19639 along with many a conversation we've had in the past on this list. -Dan Dan McGee (5): Add epoch support to pacman/libalpm Update documentation to reflect new epoch package variable Make repo-add and makepkg epoch-aware Add epoch support to pactest Update contrib/ for epoch contrib/PKGBUILD.vim | 10 ++++++++-- contrib/bacman | 3 +++ doc/PKGBUILD.5.txt | 22 ++++++++++++---------- doc/pacman.8.txt | 3 +++ lib/libalpm/alpm.h | 2 +- lib/libalpm/be_files.c | 16 +++++++++++++--- lib/libalpm/be_package.c | 2 ++ lib/libalpm/package.c | 24 ++++++++++++++---------- lib/libalpm/package.h | 2 +- scripts/makepkg.sh.in | 6 ++---- scripts/repo-add.sh.in | 7 ++++++- test/pacman/pmdb.py | 18 +++++++----------- test/pacman/pmpkg.py | 5 +++-- test/pacman/util.py | 4 ++++ 14 files changed, 79 insertions(+), 45 deletions(-) -- 1.7.3.1
This will allow for better control of what was previously the 'force' option
in a PKGBUILD and transferred into the built package.
Signed-off-by: Dan McGee
On 09/10/10 01:02, Dan McGee wrote: <snip>
-/* Is spkg an upgrade for locapkg? */ +/* Is spkg an upgrade for localpkg? */ int _alpm_pkg_compare_versions(pmpkg_t *spkg, pmpkg_t *localpkg) { - int cmp = 0; + int spkg_epoch, localpkg_epoch;
ALPM_LOG_FUNC;
- cmp = alpm_pkg_vercmp(alpm_pkg_get_version(spkg), - alpm_pkg_get_version(localpkg)); + spkg_epoch = alpm_pkg_get_epoch(spkg); + localpkg_epoch = alpm_pkg_get_epoch(localpkg);
- if(cmp< 0&& alpm_pkg_has_force(spkg)) { - cmp = 1; + if(spkg_epoch> localpkg_epoch) { + return(1); + } else if(spkg_epoch< localpkg_epoch) { + return(-1); }
- return(cmp); + /* equal epoch values, move on to version comparison */ + return alpm_pkg_vercmp(alpm_pkg_get_version(spkg), + alpm_pkg_get_version(localpkg)); }
How about: /* Is spkg an upgrade for localpkg? */ int _alpm_pkg_compare_versions(pmpkg_t *spkg, pmpkg_t *localpkg) { int cmp, spkg_epoch, localpkg_epoch; ALPM_LOG_FUNC; cmp = alpm_pkg_vercmp(alpm_pkg_get_version(spkg), alpm_pkg_get_version(localpkg)); spkg_epoch = alpm_pkg_get_epoch(spkg); localpkg_epoch = alpm_pkg_get_epoch(localpkg); if(spkg_epoch > localpkg_epoch && cmp != 0) { return(1); } else if(spkg_epoch < localpkg_epoch) { return(-1); } return(cmp); } So, when 'force' option is in effect, spkg_epoch = INT_MAX, localpkg_epoch = 0, but the versions are the same so we ignore it. Allan
On Fri, Oct 8, 2010 at 10:31 PM, Allan McRae
On 09/10/10 01:02, Dan McGee wrote: <snip>
-/* Is spkg an upgrade for locapkg? */ +/* Is spkg an upgrade for localpkg? */ int _alpm_pkg_compare_versions(pmpkg_t *spkg, pmpkg_t *localpkg) { - int cmp = 0; + int spkg_epoch, localpkg_epoch;
ALPM_LOG_FUNC;
- cmp = alpm_pkg_vercmp(alpm_pkg_get_version(spkg), - alpm_pkg_get_version(localpkg)); + spkg_epoch = alpm_pkg_get_epoch(spkg); + localpkg_epoch = alpm_pkg_get_epoch(localpkg);
- if(cmp< 0&& alpm_pkg_has_force(spkg)) { - cmp = 1; + if(spkg_epoch> localpkg_epoch) { + return(1); + } else if(spkg_epoch< localpkg_epoch) { + return(-1); }
- return(cmp); + /* equal epoch values, move on to version comparison */ + return alpm_pkg_vercmp(alpm_pkg_get_version(spkg), + alpm_pkg_get_version(localpkg)); }
How about:
/* Is spkg an upgrade for localpkg? */ int _alpm_pkg_compare_versions(pmpkg_t *spkg, pmpkg_t *localpkg) { int cmp, spkg_epoch, localpkg_epoch;
ALPM_LOG_FUNC;
cmp = alpm_pkg_vercmp(alpm_pkg_get_version(spkg), alpm_pkg_get_version(localpkg));
spkg_epoch = alpm_pkg_get_epoch(spkg); localpkg_epoch = alpm_pkg_get_epoch(localpkg);
if(spkg_epoch > localpkg_epoch && cmp != 0) { return(1); } else if(spkg_epoch < localpkg_epoch) { return(-1); }
return(cmp); }
So, when 'force' option is in effect, spkg_epoch = INT_MAX, localpkg_epoch = 0, but the versions are the same so we ignore it.
Works great now, but what if there is a legit reason to deem this as an upgrade? Throw out the 'force' and look at it as epochs 1 and 2 or something, so you don't get caught up just thinking this is an old problem. Epoch *always* has to win or it doesn't work correctly. Do we not record the force option in the local database right now? That is quite unfortunate. I think we need to make an exception for the force case, and in the future, we will always have epoch recorded in both sync and local DBs. Counterexample to your code above: Project releases version 1.0, 1.1, and 2.0. Project decides it wasn't ready for 2.0, so abandons that branch and goes back to 1.3. We need to use epoch here because we were quick to package it. Later, because someone wasn't thinking clearly, they release 2.0 again. Contrived, sure, but it would break your code (if the person still had 2.0 installed they would never see the new 2.0). -Dan
Signed-off-by: Dan McGee
Allow it to be a variable in the PKGBUILD as well as propagating it through
to the built package and the package database. We leave some backward
compatibility in place by placing the '%FORCE%' option in the database if
the package contains an epoch; this will be used by older versions of pacman
and more or less ignored by versions that use epoch.
Signed-off-by: Dan McGee
This adds epoch support to pactest, while still producing packages and
database entries the same way makepkg and repo-add currently do in a
backward compatible fashion (still including the 'force' option).
Signed-off-by: Dan McGee
Signed-off-by: Dan McGee
On Fri, Oct 8, 2010 at 5:02 PM, Dan McGee
Hey guys,
This is a quick set of patches to implement the use of epoch in our packages, and remove the 'force' option. It adds a lot more flexibility and should prevent weird upgrade/downgrade interaction between different repositories, and also removes the need to munge versions as often.
The pacman stuff is pretty well tested via the current suite of pactests, although we will want to add some new tests specifically playing with the epoch value in the test packages.
Anyway, thoughts/comments/suggestions welcome. The changes are not too invasive and the only real complexity comes from trying to remain backward and forward compatible.
This addresses bugs such as FS#14887, FS#19153, FS#19639 along with many a conversation we've had in the past on this list.
I don't remember seeing any of these bugs, but I do remember complaining several times about force and advocating use of epoch, so that's very nice :)
Dan McGee (5): Add epoch support to pacman/libalpm Update documentation to reflect new epoch package variable Make repo-add and makepkg epoch-aware Add epoch support to pactest Update contrib/ for epoch
contrib/PKGBUILD.vim | 10 ++++++++-- contrib/bacman | 3 +++ doc/PKGBUILD.5.txt | 22 ++++++++++++---------- doc/pacman.8.txt | 3 +++ lib/libalpm/alpm.h | 2 +- lib/libalpm/be_files.c | 16 +++++++++++++--- lib/libalpm/be_package.c | 2 ++ lib/libalpm/package.c | 24 ++++++++++++++---------- lib/libalpm/package.h | 2 +- scripts/makepkg.sh.in | 6 ++---- scripts/repo-add.sh.in | 7 ++++++- test/pacman/pmdb.py | 18 +++++++----------- test/pacman/pmpkg.py | 5 +++-- test/pacman/util.py | 4 ++++ 14 files changed, 79 insertions(+), 45 deletions(-)
After a quick read through the patches, it looks good to me.
I just took these for a spin.... allan@mugen /home/arch/code/pacman (epoch)
sudo ./src/pacman/pacman -Syu <snip>
Targets (24): blas-3.2.2-2 crafty-23.3-1 db-4.8.26-2 foomatic-db-4.0.5_20100816-1 foomatic-filters-4.0.5_20100816-1 foomatic-db-engine-4.0.5_20100816-1 ghostscript-9.00-1 gsfonts-1.0.7pre44-2 imagemagick-6.6.4.3-1 libffi-3.0.9-1 libimobiledevice-1.0.3-1 libraw1394-2.0.5-1 libshout-2.2.2-3 libvdpau-0.4-1 sqlite3-3.7.3-1 qt-4.7.0-3 rasqal-0.9.20-1 redland-1.0.11-1 soundconverter-1.5.3-4 tdb-1.2.1-2 ttf-liberation-1.06.0.20100721-1 vim-runtime-7.3.3-2 vim-7.3.3-2 vte-0.26.0-4 Total Download Size: 37.54 MB Total Installed Size: 264.40 MB ... allan@mugen /home/arch/code/pacman (epoch)
pacman -Syu <snip>
Targets (8): ghostscript-9.00-1 libimobiledevice-1.0.3-1 sqlite3-3.7.3-1 qt-4.7.0-3 rasqal-0.9.20-1 redland-1.0.11-1 soundconverter-1.5.3-4 vte-0.26.0-4 Total Download Size: 36.76 MB Total Installed Size: 159.49 MB Proceed with installation? [Y/n] A quick look at the extra packages using the epoch patches shows they all appear to have options=('force') and are the same version as already on my system. Allan
On Sat, Oct 9, 2010 at 3:47 AM, Allan McRae
I just took these for a spin....
allan@mugen /home/arch/code/pacman (epoch)
sudo ./src/pacman/pacman -Syu <snip>
Targets (24): blas-3.2.2-2 crafty-23.3-1 db-4.8.26-2 foomatic-db-4.0.5_20100816-1 foomatic-filters-4.0.5_20100816-1 foomatic-db-engine-4.0.5_20100816-1 ghostscript-9.00-1 gsfonts-1.0.7pre44-2 imagemagick-6.6.4.3-1 libffi-3.0.9-1 libimobiledevice-1.0.3-1 libraw1394-2.0.5-1 libshout-2.2.2-3 libvdpau-0.4-1 sqlite3-3.7.3-1 qt-4.7.0-3 rasqal-0.9.20-1 redland-1.0.11-1 soundconverter-1.5.3-4 tdb-1.2.1-2 ttf-liberation-1.06.0.20100721-1 vim-runtime-7.3.3-2 vim-7.3.3-2 vte-0.26.0-4
Total Download Size: 37.54 MB Total Installed Size: 264.40 MB ...
So these are all the packages on your system with force flag ? Maybe now would be a good time to review which of those really need force flag, drop it if it has been unnecessary for a while. Then if upstream mess up version again or for next need of downgrade, start using epoch. Btw this problem happens just once , right ? After this first reinstall of force package, epoch gets written to local database and then it's fine ?
On 09/10/10 20:30, Xavier Chantry wrote:
On Sat, Oct 9, 2010 at 3:47 AM, Allan McRae
wrote: I just took these for a spin....
allan@mugen /home/arch/code/pacman (epoch)
sudo ./src/pacman/pacman -Syu <snip>
Targets (24): blas-3.2.2-2 crafty-23.3-1 db-4.8.26-2 foomatic-db-4.0.5_20100816-1 foomatic-filters-4.0.5_20100816-1 foomatic-db-engine-4.0.5_20100816-1 ghostscript-9.00-1 gsfonts-1.0.7pre44-2 imagemagick-6.6.4.3-1 libffi-3.0.9-1 libimobiledevice-1.0.3-1 libraw1394-2.0.5-1 libshout-2.2.2-3 libvdpau-0.4-1 sqlite3-3.7.3-1 qt-4.7.0-3 rasqal-0.9.20-1 redland-1.0.11-1 soundconverter-1.5.3-4 tdb-1.2.1-2 ttf-liberation-1.06.0.20100721-1 vim-runtime-7.3.3-2 vim-7.3.3-2 vte-0.26.0-4
Total Download Size: 37.54 MB Total Installed Size: 264.40 MB ...
So these are all the packages on your system with force flag ? Maybe now would be a good time to review which of those really need force flag, drop it if it has been unnecessary for a while. Then if upstream mess up version again or for next need of downgrade, start using epoch.
Btw this problem happens just once , right ? After this first reinstall of force package, epoch gets written to local database and then it's fine ?
Dan and I had a talk about this. Note that at the moment "force" and "epoch" are not actually being written to the local database. That is actually good thing given when force is set we set epoch to MAX_INT so writing that to the local db would prevent any further upgrade... So there are things to be fixed around this. Allan
We weren't reading this in from our packages, thus causing us not to write
it out to our local database. Adding this now will help ease the upgrade
path for epoch later and not require reinstallation of all force packages.
Signed-off-by: Dan McGee
On Tue, Oct 12, 2010 at 12:51 AM, Dan McGee
We weren't reading this in from our packages, thus causing us not to write it out to our local database. Adding this now will help ease the upgrade path for epoch later and not require reinstallation of all force packages.
Signed-off-by: Dan McGee
--- For maint, helps to address the problem Allan pointed out regarding upgrading existing packages that used the force flag.
-Dan
lib/libalpm/be_package.c | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/lib/libalpm/be_package.c b/lib/libalpm/be_package.c index 38cf357..ff266ae 100644 --- a/lib/libalpm/be_package.c +++ b/lib/libalpm/be_package.c @@ -75,6 +75,8 @@ static int parse_descfile(struct archive *a, pmpkg_t *newpkg) STRDUP(newpkg->version, ptr, RET_ERR(PM_ERR_MEMORY, -1)); } else if(!strcmp(key, "pkgdesc")) { STRDUP(newpkg->desc, ptr, RET_ERR(PM_ERR_MEMORY, -1)); + } else if(!strcmp(key, "force")) { + newpkg->force = 1; } else if(!strcmp(key, "group")) { newpkg->groups = alpm_list_add(newpkg->groups, strdup(ptr)); } else if(!strcmp(key, "url")) { -- 1.7.3.1
I did not see a problem with that patch, and still don't see any, but I have some new insight after trying out git master. I think we need a similar patch in master, we still need to support old package with just force. We should do that just like sync db does (force -> epoch=1). This will ensure that epoch is always written in local db for package with force. diff --git a/lib/libalpm/be_package.c b/lib/libalpm/be_package.c index ddcad59..254f830 100644 --- a/lib/libalpm/be_package.c +++ b/lib/libalpm/be_package.c @@ -184,6 +184,11 @@ static int parse_descfile(struct archive *a, pmpkg_t *newpkg) STRDUP(newpkg->version, ptr, RET_ERR(PM_ERR_MEMORY, -1)); } else if(strcmp(key, "pkgdesc") == 0) { STRDUP(newpkg->desc, ptr, RET_ERR(PM_ERR_MEMORY, -1)); + } else if(strcmp(key, "force") == 0) { + /* For backward compatibility, like in sync_db_read */ + if(!newpkg->epoch) { + newpkg->epoch = 1; + } } else if(strcmp(key, "epoch") == 0) { newpkg->epoch = atoi(ptr); } else if(strcmp(key, "group") == 0) { As for the maint patch, it seems weird that we will start to write FORCE entries to local database now we decided to kill FORCE. Wouldn't it be better to start writing EPOCH so that we don't start to clutter the local db now with something which is dead ? :) On my system I just have 17 packages to reinstall, 19MB download (but 0MB download actually, thats what a download cache is for). This is done automatically on the first pacman -Su, and with above patch, the transition should be made. So I don't think we need to start writing anything to the local database now, do we ? If we still want to do that just to reduce a bit the (already small) number of packages to reinstall, what about starting to write EPOCH in maint ? I believe we just need two small changes : 1) in maint : never write FORCE in local db but write EPOCH=1 instead 2) in master : we can drop reading FORCE from local db since it never ever got written. (and EPOCH is already read) But anyway this is really a minor point, and my last proposal would actually need the 2-lines fix that got pushed to maint.
On Thu, Oct 14, 2010 at 8:48 PM, Xavier Chantry
On Tue, Oct 12, 2010 at 12:51 AM, Dan McGee
wrote: We weren't reading this in from our packages, thus causing us not to write it out to our local database. Adding this now will help ease the upgrade path for epoch later and not require reinstallation of all force packages.
Signed-off-by: Dan McGee
--- For maint, helps to address the problem Allan pointed out regarding upgrading existing packages that used the force flag.
-Dan
lib/libalpm/be_package.c | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/lib/libalpm/be_package.c b/lib/libalpm/be_package.c index 38cf357..ff266ae 100644 --- a/lib/libalpm/be_package.c +++ b/lib/libalpm/be_package.c @@ -75,6 +75,8 @@ static int parse_descfile(struct archive *a, pmpkg_t *newpkg) STRDUP(newpkg->version, ptr, RET_ERR(PM_ERR_MEMORY, -1)); } else if(!strcmp(key, "pkgdesc")) { STRDUP(newpkg->desc, ptr, RET_ERR(PM_ERR_MEMORY, -1)); + } else if(!strcmp(key, "force")) { + newpkg->force = 1; } else if(!strcmp(key, "group")) { newpkg->groups = alpm_list_add(newpkg->groups, strdup(ptr)); } else if(!strcmp(key, "url")) { -- 1.7.3.1
I did not see a problem with that patch, and still don't see any, but I have some new insight after trying out git master.
I think we need a similar patch in master, we still need to support old package with just force. We should do that just like sync db does (force -> epoch=1). This will ensure that epoch is always written in local db for package with force.
diff --git a/lib/libalpm/be_package.c b/lib/libalpm/be_package.c index ddcad59..254f830 100644 --- a/lib/libalpm/be_package.c +++ b/lib/libalpm/be_package.c @@ -184,6 +184,11 @@ static int parse_descfile(struct archive *a, pmpkg_t *newpkg) STRDUP(newpkg->version, ptr, RET_ERR(PM_ERR_MEMORY, -1)); } else if(strcmp(key, "pkgdesc") == 0) { STRDUP(newpkg->desc, ptr, RET_ERR(PM_ERR_MEMORY, -1)); + } else if(strcmp(key, "force") == 0) { + /* For backward compatibility, like in sync_db_read */ + if(!newpkg->epoch) { + newpkg->epoch = 1; + } } else if(strcmp(key, "epoch") == 0) { newpkg->epoch = atoi(ptr); } else if(strcmp(key, "group") == 0) {
As for the maint patch, it seems weird that we will start to write FORCE entries to local database now we decided to kill FORCE. Wouldn't it be better to start writing EPOCH so that we don't start to clutter the local db now with something which is dead ? :)
On my system I just have 17 packages to reinstall, 19MB download (but 0MB download actually, thats what a download cache is for). This is done automatically on the first pacman -Su, and with above patch, the transition should be made. So I don't think we need to start writing anything to the local database now, do we ?
If we still want to do that just to reduce a bit the (already small) number of packages to reinstall, what about starting to write EPOCH in maint ? I believe we just need two small changes : 1) in maint : never write FORCE in local db but write EPOCH=1 instead 2) in master : we can drop reading FORCE from local db since it never ever got written. (and EPOCH is already read)
But anyway this is really a minor point, and my last proposal would actually need the 2-lines fix that got pushed to maint.
I just pushed this work, 3 small patches. http://code.toofishes.net/cgit/xavier/pacman.git/log/?h=epoch-maint * be_files: write EPOCH instead of FORCE http://code.toofishes.net/cgit/xavier/pacman.git/log/?h=epoch-master * be_package: read force entry and convert to epoch * be_local: drop FORCE in db_read
On Thu, Oct 14, 2010 at 3:39 PM, Xavier Chantry
On Thu, Oct 14, 2010 at 8:48 PM, Xavier Chantry
wrote: On Tue, Oct 12, 2010 at 12:51 AM, Dan McGee
wrote: We weren't reading this in from our packages, thus causing us not to write it out to our local database. Adding this now will help ease the upgrade path for epoch later and not require reinstallation of all force packages.
I did not see a problem with that patch, and still don't see any, but I have some new insight after trying out git master.
I think we need a similar patch in master, we still need to support old package with just force. We should do that just like sync db does (force -> epoch=1). This will ensure that epoch is always written in local db for package with force.
You are correct, we do need this.
diff --git a/lib/libalpm/be_package.c b/lib/libalpm/be_package.c index ddcad59..254f830 100644 --- a/lib/libalpm/be_package.c +++ b/lib/libalpm/be_package.c @@ -184,6 +184,11 @@ static int parse_descfile(struct archive *a, pmpkg_t *newpkg) STRDUP(newpkg->version, ptr, RET_ERR(PM_ERR_MEMORY, -1)); } else if(strcmp(key, "pkgdesc") == 0) { STRDUP(newpkg->desc, ptr, RET_ERR(PM_ERR_MEMORY, -1)); + } else if(strcmp(key, "force") == 0) { + /* For backward compatibility, like in sync_db_read */ + if(!newpkg->epoch) { + newpkg->epoch = 1; + } } else if(strcmp(key, "epoch") == 0) { newpkg->epoch = atoi(ptr); } else if(strcmp(key, "group") == 0) {
As for the maint patch, it seems weird that we will start to write FORCE entries to local database now we decided to kill FORCE. Wouldn't it be better to start writing EPOCH so that we don't start to clutter the local db now with something which is dead ? :)
No, because we are then half-introducing a feature to a maint branch where I want as little breakage as possible, and also a database that doesn't require a lot of extra parsing code.
On my system I just have 17 packages to reinstall, 19MB download (but 0MB download actually, thats what a download cache is for). This is done automatically on the first pacman -Su, and with above patch, the transition should be made. So I don't think we need to start writing anything to the local database now, do we ?
If we still want to do that just to reduce a bit the (already small) number of packages to reinstall, what about starting to write EPOCH in maint ? I believe we just need two small changes : 1) in maint : never write FORCE in local db but write EPOCH=1 instead 2) in master : we can drop reading FORCE from local db since it never ever got written. (and EPOCH is already read)
But anyway this is really a minor point, and my last proposal would actually need the 2-lines fix that got pushed to maint.
I just pushed this work, 3 small patches.
http://code.toofishes.net/cgit/xavier/pacman.git/log/?h=epoch-maint * be_files: write EPOCH instead of FORCE http://code.toofishes.net/cgit/xavier/pacman.git/log/?h=epoch-master * be_package: read force entry and convert to epoch * be_local: drop FORCE in db_read
So yes, I'm a bit torn here, but I always fall on the "let's not touch maint more than necessary" side of the fence, and this starts to push that line. I'm fine with the "read force from package" patch, but the rest I'm just not so keen on. -Dan
On Fri, Oct 15, 2010 at 3:15 AM, Dan McGee
So yes, I'm a bit torn here, but I always fall on the "let's not touch maint more than necessary" side of the fence, and this starts to push that line. I'm fine with the "read force from package" patch, but the rest I'm just not so keen on.
As I said, if we want to be strict on the "let's not touch maint more than necessary", we can drop your patch too. It's not necessary, is it ? It will save 10 seconds on one and only one -Su operation. If not, my additional patch is not a half-feature, it's an one-line change in a completely dead and unused codepath (before your patch). Its consequences are also simpler to appreciate : we just write EPOCH instead of FORCE, and db_read simply ignores unknown lines. Your first patch is less obvious : we now set pkg->force when loading a package from its file, does it really have no impact anywhere in the codebase besides db_write ? (Looks fine.) The only purpose of these two proposals (dropping your patch or adding mine) is to provide an answer to the question 'When can we drop reading FORCE from local db over which we have no real control?' and the answer is 'right now'. Ok this is a very minor benefit, but you should give me at least an equally minor drawback for each of the proposal before rejecting them.
participants (4)
-
Allan McRae
-
Dan McGee
-
Dan McGee
-
Xavier Chantry