upgrade: perform upgrade of apk-tools first if available
Also re-exec's apk-tools to perform rest of the upgrade using the new apk-tools. This allows handling of new apk-tools features properly. Fixes #140.cute-signatures
parent
0cc41ba4dc
commit
59d222d58c
|
@ -30,6 +30,8 @@
|
|||
#include "apk_blob.h"
|
||||
#include "apk_print.h"
|
||||
|
||||
char **apk_argv;
|
||||
|
||||
static struct apk_option generic_options[] = {
|
||||
{ 'h', "help", "Show generic help or applet specific help" },
|
||||
{ 'p', "root", "Install packages to DIR",
|
||||
|
@ -245,6 +247,10 @@ int main(int argc, char **argv)
|
|||
struct apk_database db;
|
||||
struct apk_db_options dbopts;
|
||||
|
||||
apk_argv = malloc(sizeof(char*[argc+1]));
|
||||
memcpy(apk_argv, argv, sizeof(char*[argc]));
|
||||
apk_argv[argc] = NULL;
|
||||
|
||||
memset(&dbopts, 0, sizeof(dbopts));
|
||||
list_init(&dbopts.repository_list);
|
||||
apk_atom_init();
|
||||
|
|
|
@ -50,6 +50,7 @@
|
|||
extern int apk_verbosity;
|
||||
extern unsigned int apk_flags;
|
||||
extern const char *apk_arch;
|
||||
extern char **apk_argv;
|
||||
|
||||
#define APK_FORCE 0x0001
|
||||
#define APK_SIMULATE 0x0002
|
||||
|
|
|
@ -23,7 +23,8 @@ struct apk_change {
|
|||
};
|
||||
|
||||
struct apk_state {
|
||||
unsigned int refs, num_names;
|
||||
unsigned int refs, num_names, num_changes;
|
||||
int print_ok;
|
||||
struct apk_database *db;
|
||||
struct list_head change_list_head;
|
||||
struct apk_package_array *conflicts;
|
||||
|
|
10
src/state.c
10
src/state.c
|
@ -199,6 +199,7 @@ struct apk_state *apk_state_new(struct apk_database *db)
|
|||
state->refs = 1;
|
||||
state->num_names = db->name_id;
|
||||
state->db = db;
|
||||
state->print_ok = 1;
|
||||
list_init(&state->change_list_head);
|
||||
|
||||
apk_name_array_init(&state->missing);
|
||||
|
@ -235,6 +236,7 @@ static int apk_state_add_change(struct apk_state *state,
|
|||
|
||||
list_init(&change->change_list);
|
||||
list_add_tail(&change->change_list, &state->change_list_head);
|
||||
state->num_changes++;
|
||||
change->oldpkg = oldpkg;
|
||||
change->newpkg = newpkg;
|
||||
|
||||
|
@ -873,13 +875,11 @@ int apk_state_commit(struct apk_state *state,
|
|||
{
|
||||
struct progress prog;
|
||||
struct apk_change *change;
|
||||
int r = 0, size_diff = 0, toplevel = FALSE, deleteonly = TRUE;
|
||||
int n = 0, numpkg = 0;
|
||||
int n = 0, r = 0, size_diff = 0, toplevel = FALSE, deleteonly = TRUE;
|
||||
|
||||
/* Count what needs to be done */
|
||||
memset(&prog, 0, sizeof(prog));
|
||||
list_for_each_entry(change, &state->change_list_head, change_list) {
|
||||
numpkg++;
|
||||
if (change->newpkg == NULL) {
|
||||
if (change->oldpkg->name->flags & APK_NAME_TOPLEVEL)
|
||||
toplevel = TRUE;
|
||||
|
@ -935,7 +935,7 @@ int apk_state_commit(struct apk_state *state,
|
|||
n = 0;
|
||||
list_for_each_entry(change, &state->change_list_head, change_list) {
|
||||
n++;
|
||||
apk_print_change(db, change->oldpkg, change->newpkg, n, numpkg);
|
||||
apk_print_change(db, change->oldpkg, change->newpkg, n, state->num_changes);
|
||||
prog.pkg = change->newpkg;
|
||||
|
||||
if (!(apk_flags & APK_SIMULATE)) {
|
||||
|
@ -963,7 +963,7 @@ update_state:
|
|||
apk_db_run_triggers(db);
|
||||
apk_db_write_config(db);
|
||||
|
||||
if (r == 0)
|
||||
if (r == 0 && state->print_ok)
|
||||
apk_message("OK: %d packages, %d dirs, %d files",
|
||||
db->installed.stats.packages,
|
||||
db->installed.stats.dirs,
|
||||
|
|
|
@ -30,6 +30,46 @@ static int upgrade_parse(void *ctx, struct apk_db_options *dbopts,
|
|||
return 0;
|
||||
}
|
||||
|
||||
int apk_do_self_upgrade(struct apk_database *db, struct apk_state *state)
|
||||
{
|
||||
struct apk_dependency dep;
|
||||
int r, i;
|
||||
|
||||
apk_dep_from_blob(&dep, db, APK_BLOB_STR("apk-tools"));
|
||||
|
||||
if (apk_flags & APK_PREFER_AVAILABLE) {
|
||||
for (i = 0; i < db->world->num; i++) {
|
||||
struct apk_dependency *dep0 = &db->world->item[i];
|
||||
if (dep0->name != dep.name)
|
||||
continue;
|
||||
dep0->version = apk_blob_atomize(APK_BLOB_NULL);
|
||||
dep0->result_mask = APK_VERSION_EQUAL | APK_VERSION_LESS | APK_VERSION_GREATER;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
r = apk_state_lock_dependency(state, &dep);
|
||||
if (r != 0 || state->num_changes == 0)
|
||||
return r;
|
||||
|
||||
if (apk_flags & APK_SIMULATE) {
|
||||
apk_warning("This simulation is not reliable as apk-tools upgrade is available.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
apk_message("Uprading first to new apk-tools:");
|
||||
state->print_ok = 0;
|
||||
r = apk_state_commit(state, db);
|
||||
apk_state_unref(state);
|
||||
apk_db_close(db);
|
||||
|
||||
apk_message("Performing rest of the operation:");
|
||||
execvp(apk_argv[0], apk_argv);
|
||||
|
||||
apk_error("PANIC! Failed to re-execute new apk-tools!");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
static int upgrade_main(void *ctx, struct apk_database *db, int argc, char **argv)
|
||||
{
|
||||
struct apk_state *state = NULL;
|
||||
|
@ -38,12 +78,18 @@ static int upgrade_main(void *ctx, struct apk_database *db, int argc, char **arg
|
|||
int i, r = 0;
|
||||
|
||||
apk_flags |= APK_UPGRADE;
|
||||
|
||||
apk_name_array_init(&missing);
|
||||
|
||||
state = apk_state_new(db);
|
||||
if (state == NULL)
|
||||
goto err;
|
||||
|
||||
r = apk_do_self_upgrade(db, state);
|
||||
if (r != 0) {
|
||||
apk_state_print_errors(state);
|
||||
goto err;
|
||||
}
|
||||
|
||||
for (i = 0; i < db->world->num; i++) {
|
||||
struct apk_dependency *dep = &db->world->item[i];
|
||||
if (dep->version != null_atom &&
|
||||
|
|
Loading…
Reference in New Issue