diff --git a/Makefile.am b/Makefile.am index 1fd386e8..e17290da 100644 --- a/Makefile.am +++ b/Makefile.am @@ -167,6 +167,7 @@ BATS = \ test/functional/update/update-client-certificate.bats \ test/functional/update/update-delta-without-rename-flag.bats \ test/functional/update/update-download.bats \ + test/functional/update/update-fail-to-get-mom.bats \ test/functional/update/update-include.bats \ test/functional/update/update-include-old-bundle.bats \ test/functional/update/update-include-old-bundle-with-tracked-file.bats \ diff --git a/src/bundle.c b/src/bundle.c index 687e48a4..0e39fac9 100644 --- a/src/bundle.c +++ b/src/bundle.c @@ -56,9 +56,9 @@ int list_installable_bundles() } mix_exists = (check_mix_exists() & system_on_mix()); - MoM = load_mom(current_version, false, mix_exists); + MoM = load_mom(current_version, false, mix_exists, NULL); if (!MoM) { - return EMOM_NOTFOUND; + return EMOM_LOAD; } list = MoM->manifests = list_sort(MoM->manifests, file_sort_filename); @@ -87,9 +87,9 @@ static int load_bundle_manifest(const char *bundle_name, struct list *subs, int *submanifest = NULL; - mom = load_mom(version, false, false); + mom = load_mom(version, false, false, NULL); if (!mom) { - return EMOM_NOTFOUND; + return EMOM_LOAD; } sub_list = recurse_manifest(mom, subs, bundle_name, false); @@ -203,10 +203,10 @@ int show_included_bundles(char *bundle_name) goto out; } - mom = load_mom(current_version, false, false); + mom = load_mom(current_version, false, false, NULL); if (!mom) { fprintf(stderr, "Cannot load official manifest MoM for version %i\n", current_version); - ret = EMOM_NOTFOUND; + ret = EMOM_LOAD; goto out; } @@ -301,10 +301,10 @@ int show_bundle_reqd_by(const char *bundle_name, bool server) goto out; } - current_manifest = load_mom(version, server, false); + current_manifest = load_mom(version, server, false, NULL); if (!current_manifest) { fprintf(stderr, "Unable to download/verify %d Manifest.MoM\n", version); - ret = EMOM_NOTFOUND; + ret = EMOM_LOAD; goto out; } @@ -540,10 +540,10 @@ int remove_bundles(char **bundles) fprintf(stderr, "Removing bundle: %s\n", bundle); } - current_mom = load_mom(current_version, false, mix_exists); + current_mom = load_mom(current_version, false, mix_exists, NULL); if (!current_mom) { fprintf(stderr, "Unable to download/verify %d Manifest.MoM\n", current_version); - ret = EMOM_NOTFOUND; + ret = EMOM_LOAD; bad++; goto out_free_curl; } @@ -1052,10 +1052,10 @@ int install_bundles_frontend(char **bundles) mix_exists = (check_mix_exists() & system_on_mix()); - mom = load_mom(current_version, false, mix_exists); + mom = load_mom(current_version, false, mix_exists, NULL); if (!mom) { fprintf(stderr, "Cannot load official manifest MoM for version %i\n", current_version); - ret = EMOM_NOTFOUND; + ret = EMOM_LOAD; goto clean_and_exit; } diff --git a/src/curl.c b/src/curl.c index 61c2aa79..fb435b60 100644 --- a/src/curl.c +++ b/src/curl.c @@ -435,7 +435,7 @@ exit: err = -ENONET; break; case CURLE_FILE_COULDNT_READ_FILE: - err = -1; + err = -ENOENT; break; case CURLE_PARTIAL_FILE: fprintf(stderr, "Curl: File incompletely downloaded from '%s' to '%s'\n", diff --git a/src/manifest.c b/src/manifest.c index c95b55d4..22c605ac 100644 --- a/src/manifest.c +++ b/src/manifest.c @@ -487,11 +487,6 @@ static void remove_manifest_files(char *filename, int version, char *hash) } } -struct manifest *load_mom(int version, bool latest, bool mix_exists) -{ - return load_mom_err(version, latest, mix_exists, NULL); -} - /* Loads the MoM (Manifest of Manifests) for VERSION. * * Implementation note: MoMs are not huge so deltas do not give much benefit, @@ -504,7 +499,7 @@ struct manifest *load_mom(int version, bool latest, bool mix_exists) * loaded into memory, this function will return NULL. If err is passed, it is set * with the error code. */ -struct manifest *load_mom_err(int version, bool latest, bool mix_exists, int *err) +struct manifest *load_mom(int version, bool latest, bool mix_exists, int *err) { struct manifest *manifest = NULL; int ret = 0; diff --git a/src/search.c b/src/search.c index 224b6825..77f81141 100644 --- a/src/search.c +++ b/src/search.c @@ -805,10 +805,10 @@ static int download_manifests(struct manifest **MoM, struct list **subs) return ECURRENT_VERSION; } - *MoM = load_mom(current_version, false, false); + *MoM = load_mom(current_version, false, false, NULL); if (!(*MoM)) { fprintf(stderr, "Cannot load official manifest MoM for version %i\n", current_version); - return EMOM_NOTFOUND; + return EMOM_LOAD; } list = (*MoM)->manifests; diff --git a/src/swupd-error.h b/src/swupd-error.h index b606d3dc..4860c0f6 100644 --- a/src/swupd-error.h +++ b/src/swupd-error.h @@ -5,7 +5,7 @@ #define EBUNDLE_MISMATCH 2 /* at least one local bundle mismatches from MoM */ #define EBUNDLE_REMOVE 3 /* cannot delete local bundle filename */ -#define EMOM_NOTFOUND 4 /* MoM cannot be loaded into memory (this could imply network issue) */ +#define EMOM_LOAD 4 /* MoM cannot be loaded into memory (this could imply network issue) */ #define ETYPE_CHANGED_FILE_RM 5 /* do_staging() couldn't delete a file which must be deleted */ #define EDIR_OVERWRITE 6 /* do_staging() couldn't overwrite a directory */ #define EDOTFILE_WRITE 7 /* do_staging() couldn't create a dotfile */ diff --git a/src/swupd.h b/src/swupd.h index d75f5040..1f5478a6 100644 --- a/src/swupd.h +++ b/src/swupd.h @@ -218,8 +218,7 @@ extern void apply_heuristics(struct file *file); extern int file_sort_filename(const void *a, const void *b); extern int file_sort_filename_reverse(const void *a, const void *b); -extern struct manifest *load_mom_err(int version, bool latest, bool mix_exists, int *err); -extern struct manifest *load_mom(int version, bool latest, bool mix_exists); +extern struct manifest *load_mom(int version, bool latest, bool mix_exists, int *err); extern struct manifest *load_manifest(int version, struct file *file, struct manifest *mom, bool header_only); extern struct manifest *load_manifest_full(int version, bool mix); extern struct list *create_update_list(struct manifest *server); diff --git a/src/update.c b/src/update.c index b8c369d7..0fba0874 100644 --- a/src/update.c +++ b/src/update.c @@ -315,25 +315,27 @@ version_check: grabtime_stop(×); grabtime_stop(×); // Close step 1 grabtime_start(×, "Load Manifests:"); + int manifest_err; load_current_mom: /* Step 3: setup manifests */ /* get the from/to MoM manifests */ if (system_on_mix()) { - current_manifest = load_mom(current_version, false, mix_exists); + current_manifest = load_mom(current_version, false, mix_exists, &manifest_err); } else { - current_manifest = load_mom(current_version, false, false); + current_manifest = load_mom(current_version, false, false, &manifest_err); } if (!current_manifest) { /* TODO: possibly remove this as not getting a "from" manifest is not fatal * - we just don't apply deltas */ - if (retries < MAX_TRIES) { + if (manifest_err == -ENET404 || manifest_err == -ENOENT) { + fprintf(stderr, "The current MoM manifest was not found\n"); + } else if (retries < MAX_TRIES) { increment_retries(&retries, &timeout); - fprintf(stderr, "Retry #%d downloading from/to MoM Manifests\n", retries); + fprintf(stderr, "Retry #%d downloading current MoM manifest\n", retries); goto load_current_mom; } - fprintf(stderr, "Failure retrieving manifest from server\n"); - ret = EMOM_NOTFOUND; + ret = EMOM_LOAD; goto clean_exit; } @@ -344,21 +346,17 @@ load_current_mom: load_server_mom: grabtime_stop(×); // Close step 2 grabtime_start(×, "Recurse and Consolidate Manifests"); - int server_manifest_err; - server_manifest = load_mom_err(server_version, true, mix_exists, &server_manifest_err); + server_manifest = load_mom(server_version, true, mix_exists, &manifest_err); if (!server_manifest) { - if (retries < MAX_TRIES && server_manifest_err != -ENET404) { + if (manifest_err == -ENET404 || manifest_err == -ENOENT) { + fprintf(stderr, "The server MoM manifest was not found\n"); + fprintf(stderr, "Version %d not available\n", server_version); + } else if (retries < MAX_TRIES) { increment_retries(&retries, &timeout); - fprintf(stderr, "Retry #%d downloading server Manifests\n", retries); + fprintf(stderr, "Retry #%d downloading server MoM manifest\n", retries); goto load_server_mom; } - fprintf(stderr, "Failure retrieving manifest from server\n"); - if (server_manifest_err == -ENET404) { - fprintf(stderr, "Version %d not available\n", server_version); - } else { - fprintf(stderr, "Unable to load manifest after retrying (config or network problem?)\n"); - } - ret = EMOM_NOTFOUND; + ret = EMOM_LOAD; goto clean_exit; } diff --git a/src/verify.c b/src/verify.c index fab4b1e9..1cbd33ab 100644 --- a/src/verify.c +++ b/src/verify.c @@ -765,9 +765,9 @@ int verify_main(int argc, char **argv) * disable checks for mixer state so the user can easily switch back to their * normal update stream */ if (version != sys_version) { - official_manifest = load_mom(version, false, false); + official_manifest = load_mom(version, false, false, NULL); } else { - official_manifest = load_mom(version, false, system_on_mix()); + official_manifest = load_mom(version, false, system_on_mix(), NULL); } if (!official_manifest) { @@ -776,7 +776,7 @@ int verify_main(int argc, char **argv) * not provided. */ fprintf(stderr, "Unable to download/verify %d Manifest.MoM\n", version); - ret = EMOM_NOTFOUND; + ret = EMOM_LOAD; /* No repair is possible without a manifest, nor is accurate reporting * of the state of the system. Therefore cleanup, report failure and exit diff --git a/test/functional/testlib.bash b/test/functional/testlib.bash index 9509c4d5..9ce15d57 100644 --- a/test/functional/testlib.bash +++ b/test/functional/testlib.bash @@ -14,7 +14,7 @@ export SWUPD="$SWUPD_DIR/swupd" # Error codes export EBUNDLE_MISMATCH=2 # at least one local bundle mismatches from MoM export EBUNDLE_REMOVE=3 # cannot delete local bundle filename -export EMOM_NOTFOUND=4 # MoM cannot be loaded into memory (this could imply network issue) +export EMOM_LOAD=4 # MoM cannot be loaded into memory (this could imply network issue) export ETYPE_CHANGED_FILE_RM=5 # do_staging() couldn't delete a file which must be deleted export EDIR_OVERWRITE=6 # do_staging() couldn't overwrite a directory export EDOTFILE_WRITE=7 # do_staging() couldn't create a dotfile diff --git a/test/functional/update/update-fail-to-get-mom.bats b/test/functional/update/update-fail-to-get-mom.bats new file mode 100755 index 00000000..66d70e6b --- /dev/null +++ b/test/functional/update/update-fail-to-get-mom.bats @@ -0,0 +1,49 @@ +#!/usr/bin/env bats + +load "../testlib" + +test_setup() { + + create_test_environment "$TEST_NAME" + create_version -p "$TEST_NAME" 20 10 + +} + +@test "update do not re-attempt download 'from' MoM if it was not found" { + + # remove the "from" mom + sudo rm -rf "$WEBDIR"/10/Manifest.MoM.tar + + run sudo sh -c "$SWUPD update $SWUPD_OPTS" + + assert_status_is "$EMOM_LOAD" + expected_output=$(cat <<-EOM + Update started. + Preparing to update from 10 to 20 + Failed to retrieve 10 MoM manifest + The current MoM manifest was not found + EOM + ) + assert_regex_is_output "$expected_output" + +} + +@test "update do not re-attempt download 'to' MoM if it was not found" { + + # remove the "to" mom + sudo rm -rf "$WEBDIR"/20/Manifest.MoM.tar + + run sudo sh -c "$SWUPD update $SWUPD_OPTS" + + assert_status_is "$EMOM_LOAD" + expected_output=$(cat <<-EOM + Update started. + Preparing to update from 10 to 20 + Failed to retrieve 20 MoM manifest + The server MoM manifest was not found + Version 20 not available + EOM + ) + assert_regex_is_output "$expected_output" + +} \ No newline at end of file