diff options
-rw-r--r-- | src/apk_database.h | 1 | ||||
-rw-r--r-- | src/solver.c | 14 | ||||
-rw-r--r-- | src/upgrade.c | 44 |
3 files changed, 42 insertions, 17 deletions
diff --git a/src/apk_database.h b/src/apk_database.h index d0f94f2..e8acda5 100644 --- a/src/apk_database.h +++ b/src/apk_database.h @@ -123,6 +123,7 @@ struct apk_database { char *cache_remount_dir; apk_blob_t *arch; unsigned int local_repos; + int performing_self_update : 1; int permanent : 1; int compat_newfeatures : 1; int compat_notinstallable : 1; diff --git a/src/solver.c b/src/solver.c index aa73481..48ba846 100644 --- a/src/solver.c +++ b/src/solver.c @@ -745,6 +745,17 @@ static int free_state(apk_hash_item item, void *ctx) return 0; } +static int free_package(apk_hash_item item, void *ctx) +{ + struct apk_package *pkg = (struct apk_package *) item; + + if (pkg->state_ptr != NULL) { + free(pkg->state_ptr); + pkg->state_ptr = NULL; + } + return 0; +} + void apk_solver_set_name_flags(struct apk_name *name, unsigned short solver_flags) { @@ -816,6 +827,7 @@ int apk_solver_solve(struct apk_database *db, apk_package_array_free(&ss->best_solution); apk_hash_foreach(&db->available.names, free_state, NULL); + apk_hash_foreach(&db->available.packages, free_package, NULL); free(ss); return r; @@ -1066,7 +1078,7 @@ all_done: apk_dependency_array_copy(&db->world, world); apk_db_write_config(db); - if (r == 0) { + if (r == 0 && !db->performing_self_update) { apk_message("OK: %d packages, %d dirs, %d files", db->installed.stats.packages, db->installed.stats.dirs, diff --git a/src/upgrade.c b/src/upgrade.c index f33da17..38c5496 100644 --- a/src/upgrade.c +++ b/src/upgrade.c @@ -36,28 +36,36 @@ static int upgrade_parse(void *ctx, struct apk_db_options *dbopts, return 0; } -int apk_do_self_upgrade(struct apk_database *db) +int apk_do_self_upgrade(struct apk_database *db, unsigned short solver_flags) { -#if 0 - /* FIXME: Reimplement self-upgrade. */ - struct apk_dependency dep; + struct apk_name *name; + struct apk_changeset changeset = {}; + struct apk_package_array *solution = NULL; int r; - apk_dep_from_blob(&dep, db, APK_BLOB_STR("apk-tools")); + name = apk_db_get_name(db, APK_BLOB_STR("apk-tools")); + apk_solver_set_name_flags(name, solver_flags); + db->performing_self_update = 1; + + r = apk_solver_solve(db, 0, db->world, &solution, &changeset); + if (r != 0) { + if (apk_flags & APK_FORCE) + r = 0; + else + apk_solver_print_errors(db, solution, db->world, r); + goto ret; + } - r = apk_state_lock_dependency(state, &dep); - if (r != 0 || state->num_changes == 0) - return r; + if (changeset.changes->num == 0) + goto ret; if (apk_flags & APK_SIMULATE) { apk_warning("This simulation is not reliable as apk-tools upgrade is available."); - return 0; + goto ret; } apk_message("Upgrading critical system libraries and apk-tools:"); - state->print_ok = 0; - r = apk_state_commit(state); - apk_state_unref(state); + apk_solver_commit_changeset(db, &changeset, db->world); apk_db_close(db); apk_message("Continuing the upgrade transaction with new apk-tools:"); @@ -65,9 +73,13 @@ int apk_do_self_upgrade(struct apk_database *db) apk_error("PANIC! Failed to re-execute new apk-tools!"); exit(1); -#else - return 0; -#endif + +ret: + apk_package_array_free(&solution); + apk_change_array_free(&changeset.changes); + db->performing_self_update = 0; + + return r; } static int upgrade_main(void *ctx, struct apk_database *db, int argc, char **argv) @@ -78,7 +90,7 @@ static int upgrade_main(void *ctx, struct apk_database *db, int argc, char **arg solver_flags = APK_SOLVERF_UPGRADE | uctx->solver_flags; - r = apk_do_self_upgrade(db); + r = apk_do_self_upgrade(db, solver_flags); if (r != 0) return r; |