Skip to content

Commit

Permalink
Add initial BUILD_DATE upgrade support.
Browse files Browse the repository at this point in the history
This marks packages that have changed their BUILD_DATE (that is, they
have been rebuilt by the remote repository since being installed) for
upgrading.  This fixes various issues where recursive PKGREVISION bumps
have not been applied correctly, and installed packages have outdated
assumptions about their dependencies that have been upgraded.

Examples of this behaviour are in TritonDataCenter/pkgsrc#22 and TritonDataCenter/pkgsrc#80

In this initial implementation, packages with BUILD_DATE changes are
handled as upgrades.  Changes to add full refresh support with associated
output updates and counters will follow.
  • Loading branch information
Jonathan Perkin committed Apr 25, 2018
1 parent 811e54b commit 606fb50
Show file tree
Hide file tree
Showing 9 changed files with 73 additions and 21 deletions.
48 changes: 40 additions & 8 deletions actions.c
Original file line number Diff line number Diff line change
Expand Up @@ -380,16 +380,19 @@ action_list(char *flatlist, char *str)
int
pkgin_install(char **opkgargs, int do_inst)
{
FILE *fp;
int installnum = 0, upgradenum = 0, removenum = 0;
int rc = EXIT_SUCCESS;
int privsreqd = PRIVS_PKGINDB;
uint64_t free_space;
int64_t file_size = 0, size_pkg = 0;
size_t len;
ssize_t llen;
Pkglist *premove, *pinstall;
Pkglist *pimpact;
Plisthead *impacthead; /* impact head */
Plisthead *removehead = NULL, *installhead = NULL;
char **pkgargs;
char **pkgargs, *p;
char *toinstall = NULL, *toupgrade = NULL, *toremove = NULL;
char *unmet_reqs = NULL;
char pkgpath[BUFSIZ], pkgrepo[BUFSIZ], query[BUFSIZ];
Expand Down Expand Up @@ -457,6 +460,28 @@ pkgin_install(char **opkgargs, int do_inst)
pimpact->full, PKG_EXT);
if (stat(pkgpath, &st) < 0 || st.st_size != pimpact->file_size)
pimpact->download = 1;
else {
/*
* If the cached package has the correct size, we must
* verify that the BUILD_DATE has not changed, in case
* the sizes happen to be identical.
*/
p = xasprintf("%s -Q BUILD_DATE %s", pkg_info, pkgpath);

if ((fp = popen(p, "r")) == NULL)
err(EXIT_FAILURE, "Cannot execute '%s'", p);
(void) free(p);

for (p = NULL, len = 0;
(llen = getline(&p, &len, fp)) > 0;
(void) free(p), p = NULL, len = 0) {
if (p[llen - 1] == '\n')
p[llen - 1] = '\0';
if (!pkgstr_identical(p, pimpact->build_date))
pimpact->download = 1;
}
(void) pclose(fp);
}

/*
* Don't account for download size if using a file:// repo.
Expand Down Expand Up @@ -742,16 +767,15 @@ pkgin_remove(char **pkgargs)
return rc;
}

/*
* find closest match for packages to be upgraded
* if we have mysql-5.1.10 installed prefer mysql-5.1.20 over
* mysql-5.5.20 when upgrading
/*
* Find best match for a package to be upgraded.
*/
static char *
narrow_match(Pkglist *opkg)
{
Pkglist *pkglist;
char *best_match;
int refresh = 0;

/* for now, best match is old package itself */
best_match = xstrdup(opkg->full);
Expand All @@ -775,9 +799,17 @@ narrow_match(Pkglist *opkg)
if (!pkgstr_identical(opkg->pkgpath, pkglist->pkgpath))
continue;

/* same package version, next */
if (pkgstr_identical(opkg->full, pkglist->full))
/*
* If the package version is identical, check if the BUILD_DATE
* has changed. If it has, we need to refresh the package as
* it has been rebuilt, possibly against newer dependencies.
*/
if (pkgstr_identical(opkg->full, pkglist->full)) {
if (!pkgstr_identical(opkg->build_date,
pkglist->build_date))
refresh = 1;
continue;
}

/* second package is greater */
if (version_check(best_match, pkglist->full) == 2) {
Expand All @@ -787,7 +819,7 @@ narrow_match(Pkglist *opkg)
} /* SLIST_FOREACH remoteplisthead */

/* there was no upgrade candidate */
if (strcmp(best_match, opkg->full) == 0)
if (strcmp(best_match, opkg->full) == 0 && !refresh)
XFREE(best_match);

return best_match;
Expand Down
16 changes: 11 additions & 5 deletions impact.c
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ break_depends(Plisthead *impacthead)
static int
deps_impact(Plisthead *impacthead, Pkglist *pdp)
{
int toupgrade;
int toupgrade = DONOTHING;
Pkglist *pimpact, *plist, *mapplist;
char remotepkg[BUFSIZ];

Expand All @@ -207,6 +207,7 @@ deps_impact(Plisthead *impacthead, Pkglist *pdp)
pimpact->old = NULL;
pimpact->full = NULL;
pimpact->name = xstrdup(mapplist->name);
pimpact->build_date = xstrdup(mapplist->build_date);

SLIST_INSERT_HEAD(impacthead, pimpact, next);

Expand All @@ -218,16 +219,21 @@ deps_impact(Plisthead *impacthead, Pkglist *pdp)

TRACE(" > found %s\n", pdp->name);

/* default action when local package match */
toupgrade = TOUPGRADE;
/*
* Figure out if this is an upgrade or a refresh.
*/
if (pkg_match(pdp->depend, plist->full) == 0)
toupgrade = TOUPGRADE;
else if (!pkgstr_identical(plist->build_date,
mapplist->build_date))
toupgrade = TOUPGRADE;

/*
* installed version does not match dep requirement
* OR force reinstall, pkgkeep being use to inform -F
* was given
*/
if (!pkg_match(pdp->depend, plist->full) ||
pdp->keep < 0) {
if (toupgrade != DONOTHING || pdp->keep < 0) {

TRACE(" ! didn't match (or force reinstall)\n");
/*
Expand Down
2 changes: 2 additions & 0 deletions order.c
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,7 @@ order_upgrade_remove(Plisthead *impacthead)

pdp->depend = xstrdup(pimpact->old);
pdp->name = NULL; /* safety */
pdp->build_date = xstrdup(pimpact->build_date);
/* XXX: use the "computed" value to record
* action type. Ugly.
*/
Expand Down Expand Up @@ -253,6 +254,7 @@ order_install(Plisthead *impacthead)
pdp->computed = pimpact->action; /* XXX: ugly*/
pdp->depend = xstrdup(pimpact->full);
pdp->name = NULL;
pdp->build_date = xstrdup(pimpact->build_date);
pdp->level = pimpact->level;
/* record package size for download check */
pdp->download = pimpact->download;
Expand Down
1 change: 1 addition & 0 deletions pkgin.h
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,7 @@ typedef struct Pkglist {
char *name; /*!< package name, foo */
char *old; /*!< old package if any */
char *version; /*<! package version, 1.0 */
char *build_date; /*<! BUILD_DATE timestamp */
char *depend; /*!< dewey or glob form for forward (direct)
* dependencies:
* foo>=1.0
Expand Down
2 changes: 2 additions & 0 deletions pkgin.sql
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ CREATE TABLE [REMOTE_PKG] (
"FULLPKGNAME" TEXT UNIQUE,
"PKGNAME" TEXT,
"PKGVERS" TEXT,
"BUILD_DATE" TEXT,
"COMMENT" TEXT,
"LICENSE" TEXT NULL,
"PKGTOOLS_VERSION" TEXT,
Expand All @@ -33,6 +34,7 @@ CREATE TABLE [LOCAL_PKG] (
"FULLPKGNAME" TEXT UNIQUE,
"PKGNAME" TEXT,
"PKGVERS" TEXT,
"BUILD_DATE" TEXT,
"COMMENT" TEXT,
"LICENSE" TEXT NULL,
"PKGTOOLS_VERSION" TEXT,
Expand Down
8 changes: 7 additions & 1 deletion pkgindb.c
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,13 @@ pkgindb_open(void)
errx(EXIT_FAILURE, "cannot create database: %s",
sqlite3_errmsg(pdb));
} else {
if (pkgindb_doquery("SELECT PKGDB_NTIME FROM PKGDB;",
/*
* This query checks the compatibility of the current database,
* and should be one that either completes or fails due to an
* SQL error based on the most recent schema change. Returned
* rows are ignored, so choose a query that runs quickly.
*/
if (pkgindb_doquery("SELECT BUILD_DATE FROM LOCAL_PKG LIMIT 1;",
NULL, NULL) != PDB_OK) {
if (unlink(pkgin_sqldb) < 0)
err(EXIT_FAILURE, "cannot recreate database");
Expand Down
14 changes: 7 additions & 7 deletions pkgindb_queries.c
Original file line number Diff line number Diff line change
Expand Up @@ -119,36 +119,36 @@ const char UNKEEP_PKG[] =
"UPDATE LOCAL_PKG SET PKG_KEEP = NULL WHERE PKGNAME = \'%s\';";

const char INSERT_REMOTE_PKG[] =
"INSERT INTO REMOTE_PKG (PKG_ID,FULLPKGNAME,PKGNAME,PKGVERS,COMMENT,"
"LICENSE,PKGTOOLS_VERSION,HOMEPAGE,OS_VERSION,PKGPATH,"
"INSERT INTO REMOTE_PKG (PKG_ID,FULLPKGNAME,PKGNAME,PKGVERS,BUILD_DATE,"
"COMMENT,LICENSE,PKGTOOLS_VERSION,HOMEPAGE,OS_VERSION,PKGPATH,"
"PKG_OPTIONS,CATEGORIES,SIZE_PKG,FILE_SIZE,OPSYS,REPOSITORY) "
"VALUES (%d,'%s','%s','%s','%s','%s','%s','%s',"
"VALUES (%d,'%s','%s','%s','%s','%s','%s','%s','%s'"
"'%s','%s','%s','%s','%s','%s','%s','%s');";

/* for upgrades, prefer higher versions to be at the top of SLIST */
const char LOCAL_PKGS_QUERY_ASC[] =
"SELECT FULLPKGNAME,PKGNAME,PKGVERS,"
"SELECT FULLPKGNAME,PKGNAME,PKGVERS,BUILD_DATE,"
"COMMENT,FILE_SIZE,SIZE_PKG,CATEGORIES,PKGPATH "
"FROM LOCAL_PKG "
"ORDER BY FULLPKGNAME ASC;";

/* present packages by repository appearance to avoid conflicts between repos */
const char REMOTE_PKGS_QUERY_ASC[] =
"SELECT FULLPKGNAME,PKGNAME,PKGVERS,"
"SELECT FULLPKGNAME,PKGNAME,PKGVERS,BUILD_DATE,"
"COMMENT,FILE_SIZE,SIZE_PKG,CATEGORIES,PKGPATH "
"FROM REMOTE_PKG "
"INNER JOIN REPOS WHERE REMOTE_PKG.REPOSITORY = REPOS.REPO_URL "
"ORDER BY REPOS.ROWID, FULLPKGNAME ASC;";

/* for displays, prefer lower versions to be at the top of SLIST*/
const char LOCAL_PKGS_QUERY_DESC[] =
"SELECT FULLPKGNAME,PKGNAME,PKGVERS,"
"SELECT FULLPKGNAME,PKGNAME,PKGVERS,BUILD_DATE,"
"COMMENT,FILE_SIZE,SIZE_PKG,CATEGORIES,PKGPATH "
"FROM LOCAL_PKG "
"ORDER BY FULLPKGNAME DESC;";

const char REMOTE_PKGS_QUERY_DESC[] =
"SELECT FULLPKGNAME,PKGNAME,PKGVERS,"
"SELECT FULLPKGNAME,PKGNAME,PKGVERS,BUILD_DATE,"
"COMMENT,FILE_SIZE,SIZE_PKG,CATEGORIES,PKGPATH "
"FROM REMOTE_PKG "
"ORDER BY FULLPKGNAME DESC;";
Expand Down
1 change: 1 addition & 0 deletions pkglist.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ malloc_pkglist(uint8_t type)
pkglist->full = NULL;
pkglist->name = NULL;
pkglist->version = NULL;
pkglist->build_date = NULL;
pkglist->depend = NULL;
pkglist->size_pkg = 0;
pkglist->old_size_pkg = -1;
Expand Down
2 changes: 2 additions & 0 deletions sqlite_callbacks.c
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ pdb_rec_list(void *param, int argc, char **argv, char **colname)
plist->name = xstrdup(argv[i]);
if (strcmp(colname[i], "PKGVERS") == 0)
plist->version = xstrdup(argv[i]);
if (strcmp(colname[i], "BUILD_DATE") == 0)
plist->build_date = xstrdup(argv[i]);
if (strcmp(colname[i], "COMMENT") == 0)
plist->comment = xstrdup(argv[i]);
if (strcmp(colname[i], "PKGPATH") == 0)
Expand Down

0 comments on commit 606fb50

Please sign in to comment.