diff --git a/config b/config index 0aaf6439..af41b167 100644 --- a/config +++ b/config @@ -153,6 +153,9 @@ # Update the index used by search-file to speed up searches (boolean value) #update_search_file_index= +# Also update content from 3rd-party repositories (boolean value) +3rd_party= + [bundle-add] diff --git a/docs/swupd.1.rst b/docs/swupd.1.rst index 46ed5d02..6e8a614f 100644 --- a/docs/swupd.1.rst +++ b/docs/swupd.1.rst @@ -198,6 +198,10 @@ update --update-search-file-index Update the index used by search-file to speed up searches. Don't enable this if you have download or space restrictions. +--3rd-party If update is successfull, also update content from 3rd-party + repositories. + + bundle-add -------------------- diff --git a/src/3rd_party_check_update.c b/src/3rd_party_check_update.c index 6dca1a19..456beb49 100644 --- a/src/3rd_party_check_update.c +++ b/src/3rd_party_check_update.c @@ -80,10 +80,16 @@ static enum swupd_code check_update_repo(UNUSED_PARAM char *unused) return check_update(); } +enum swupd_code third_party_execute_check_update(void) +{ + const int steps_in_checkupdate = 0; + + return third_party_run_operation_multirepo(cmdline_option_repo, check_update_repo, SWUPD_NO, "check-update", steps_in_checkupdate); +} + enum swupd_code third_party_check_update_main(int argc, char **argv) { enum swupd_code ret_code = SWUPD_OK; - const int steps_in_checkupdate = 0; if (!parse_options(argc, argv)) { print("\n"); @@ -97,7 +103,7 @@ enum swupd_code third_party_check_update_main(int argc, char **argv) } /* run check-update */ - ret_code = third_party_run_operation_multirepo(cmdline_option_repo, check_update_repo, SWUPD_NO, "check-update", steps_in_checkupdate); + ret_code = third_party_execute_check_update(); swupd_deinit(); diff --git a/src/3rd_party_update.c b/src/3rd_party_update.c index b3ff501f..726da9c4 100644 --- a/src/3rd_party_update.c +++ b/src/3rd_party_update.c @@ -249,31 +249,23 @@ static enum swupd_code update_repos(UNUSED_PARAM char *unused) } } -enum swupd_code third_party_update_main(int argc, char **argv) +enum swupd_code third_party_execute_update(void) { enum swupd_code ret_code = SWUPD_OK; char *template_file = NULL; char *template = NULL; + size_t template_len; int steps_in_update; int ret; - size_t template_len; - if (!parse_options(argc, argv)) { - print("\n"); - print_help(); - return SWUPD_INVALID_OPTION; - } + /* 3rd-party updates can be executed also from the update command + * using the --3rd-party option, make sure a flag was not set in that + * command before calculating steps */ + cmdline_option_download_only |= update_get_option_download_only(); - ret_code = swupd_init(SWUPD_ALL); - if (ret_code != SWUPD_OK) { - error("Failed swupd initialization, exiting now\n"); - return ret_code; - } - - /* set the command options */ - update_set_option_version(cmdline_option_version); - update_set_option_download_only(cmdline_option_download_only); - update_set_option_keepcache(cmdline_option_keepcache); + /* the --update-search-file-index is not supported for 3rd-party + * so set it to false in case it was set up to true by update */ + update_set_option_update_search_file_index(false); /* * Steps for update: @@ -325,6 +317,33 @@ enum swupd_code third_party_update_main(int argc, char **argv) exit: free_and_clear_pointer(&template_file); sys_mmap_free(template, template_len); + + return ret_code; +} + +enum swupd_code third_party_update_main(int argc, char **argv) +{ + enum swupd_code ret_code = SWUPD_OK; + + if (!parse_options(argc, argv)) { + print("\n"); + print_help(); + return SWUPD_INVALID_OPTION; + } + + ret_code = swupd_init(SWUPD_ALL); + if (ret_code != SWUPD_OK) { + error("Failed swupd initialization, exiting now\n"); + return ret_code; + } + + /* set the command options */ + update_set_option_version(cmdline_option_version); + update_set_option_download_only(cmdline_option_download_only); + update_set_option_keepcache(cmdline_option_keepcache); + + ret_code = third_party_execute_update(); + swupd_deinit(); return ret_code; diff --git a/src/swupd.h b/src/swupd.h index 694627c7..389a5649 100644 --- a/src/swupd.h +++ b/src/swupd.h @@ -337,7 +337,9 @@ extern enum swupd_code execute_update(void); extern enum swupd_code execute_update_extra(extra_proc_fn_t post_update_fn, extra_proc_fn_t file_validation_fn); extern void update_set_option_version(int opt); extern void update_set_option_download_only(bool opt); +extern bool update_get_option_download_only(void); extern void update_set_option_keepcache(bool opt); +extern void update_set_option_update_search_file_index(bool opt); /* verify.c */ extern enum swupd_code execute_verify(void); @@ -370,6 +372,12 @@ extern void bundle_list_set_option_status(bool opt); /* clean.c */ extern int clean_get_stats(void); +/* 3rd_party_check_update.c */ +enum swupd_code third_party_execute_check_update(void); + +/* 3rd_party_update.c */ +enum swupd_code third_party_execute_update(void); + extern struct file **manifest_files_to_array(struct manifest *manifest); extern int enforce_compliant_manifest(struct file **a, struct file **b, int searchsize, int size); extern void manifest_free_array(struct file **array); diff --git a/src/update.c b/src/update.c index 95e6faf6..f8256e49 100644 --- a/src/update.c +++ b/src/update.c @@ -37,12 +37,14 @@ #define FLAG_DOWNLOAD_ONLY 2000 #define FLAG_UPDATE_SEARCH_FILE_INDEX 2001 +#define FLAG_UPDATE_3RD_PARTY 2002 static int requested_version = -1; static bool download_only = false; static bool update_search_file_index = false; static bool keepcache = false; static char swupd_binary[LINE_MAX] = { 0 }; +static bool cmdline_option_3rd_party = false; int nonpack; @@ -61,6 +63,16 @@ void update_set_option_keepcache(bool opt) keepcache = opt; } +void update_set_option_update_search_file_index(bool opt) +{ + update_search_file_index = opt; +} + +bool update_get_option_download_only(void) +{ + return download_only; +} + static void save_swupd_binary_path() { /* we need to resolve the whole path to swupd first, proc/self/exe @@ -544,6 +556,7 @@ static const struct option prog_opts[] = { { "manifest", required_argument, 0, 'm' }, { "status", no_argument, 0, 's' }, { "keepcache", no_argument, 0, 'k' }, + { "3rd-party", no_argument, 0, FLAG_UPDATE_3RD_PARTY }, }; static void print_help(void) @@ -552,8 +565,6 @@ static void print_help(void) print("Usage:\n"); print(" swupd update [OPTION...]\n\n"); - //TODO: Add documentation explaining this command - global_print_help(); print("Options:\n"); @@ -562,6 +573,7 @@ static void print_help(void) print(" -k, --keepcache Do not delete the swupd state directory content after updating the system\n"); print(" --download Download all content, but do not actually install the update\n"); print(" --update-search-file-index Update the index used by search-file to speed up searches (Don't enable this if you have download or space restrictions)\n"); + print(" --3rd-party Also update content from 3rd-party repositories\n"); print("\n"); } @@ -595,6 +607,9 @@ static bool parse_opt(int opt, char *optarg) case FLAG_UPDATE_SEARCH_FILE_INDEX: update_search_file_index = optarg_to_bool(optarg); return true; + case FLAG_UPDATE_3RD_PARTY: + cmdline_option_3rd_party = optarg_to_bool(optarg); + return true; default: return false; } @@ -673,8 +688,24 @@ enum swupd_code update_main(int argc, char **argv) if (cmd_line_status) { ret = check_update(); + + if (cmdline_option_3rd_party) { + progress_finish_steps(ret); + info("\nChecking update status of content from 3rd-party repositories\n\n"); + ret = third_party_execute_check_update(); + } } else { ret = execute_update(); + + if (cmdline_option_3rd_party) { + if (ret == SWUPD_OK) { + progress_finish_steps(ret); + info("\nUpdating content from 3rd-party repositories\n\n"); + ret = third_party_execute_update(); + } else { + warn("The update process was not successful, 3rd-party repositories won't be updated\n"); + } + } } swupd_deinit(); diff --git a/swupd.bash b/swupd.bash index 787e9ccb..beb86eea 100644 --- a/swupd.bash +++ b/swupd.bash @@ -42,7 +42,7 @@ _swupd() opts="$global " break;; ("update") - opts="$global --download --status --force --keepcache --update-search-file-index " + opts="$global --download --status --force --keepcache --update-search-file-index --3rd-party " break;; ("bundle-add") opts="$global --skip-diskspace-check --skip-optional " diff --git a/swupd.zsh b/swupd.zsh index ccbde9dc..3db60f04 100644 --- a/swupd.zsh +++ b/swupd.zsh @@ -252,6 +252,7 @@ if [[ -n "$state" ]]; then '(help status)'{-V,--version=}'[Update to version V, also accepts "latest" (default)]:version:()' + '(status)' '(help options)'{-s,--status}'[Show current OS version and latest version available on server. Equivalent to "swupd check-update"]' + '(help)--3rd-party[Also update content from 3rd-party repositories]' ) _arguments $updates && ret=0 ;; diff --git a/test/functional/update/update-3rd-party.bats b/test/functional/update/update-3rd-party.bats new file mode 100755 index 00000000..65505809 --- /dev/null +++ b/test/functional/update/update-3rd-party.bats @@ -0,0 +1,201 @@ +#!/usr/bin/env bats + +# Author: Castulo Martinez +# Email: castulo.martinez@intel.com + +load "../testlib" + +test_setup() { + + create_test_environment "$TEST_NAME" + + create_bundle -L -t -n upstream-bundle -f /upstream_file "$TEST_NAME" + create_version -p "$TEST_NAME" 20 10 staging + update_bundle "$TEST_NAME" upstream-bundle --update /upstream_file + + create_third_party_repo -a "$TEST_NAME" 10 staging repo1 + create_bundle -L -t -n test-bundle1 -f /foo/file_1 -u repo1 "$TEST_NAME" + create_version -p "$TEST_NAME" 20 10 staging repo1 + update_bundle "$TEST_NAME" test-bundle1 --update /foo/file_1 repo1 + update_bundle "$TEST_NAME" test-bundle1 --add /new_file repo1 + +} + +@test "UPD073: Updating a system along with all the 3rd-party content" { + + # If the --3rd-party flag is used, if the update completes successfully + # the 3rd-party content is also updated + + run sudo sh -c "$SWUPD update $SWUPD_OPTS --3rd-party" + + assert_status_is "$SWUPD_OK" + expected_output=$(cat <<-EOM + Update started + Preparing to update from 10 to 20 + Downloading packs for: + - upstream-bundle + Finishing packs extraction... + Statistics for going from version 10 to version 20: + changed bundles : 1 + new bundles : 0 + deleted bundles : 0 + changed files : 1 + new files : 0 + deleted files : 0 + Validate downloaded files + No extra files need to be downloaded + Installing files... + Update was applied + Calling post-update helper scripts + Update successful - System updated from version 10 to version 20 + Updating content from 3rd-party repositories + _______________________ + 3rd-Party Repo: repo1 + _______________________ + Updates from a 3rd-party repository are forced to run with the --no-scripts flag for security reasons + Update started + Preparing to update from 10 to 20 + Downloading packs for: + - test-bundle1 + Finishing packs extraction... + Statistics for going from version 10 to version 20: + changed bundles : 2 + new bundles : 0 + deleted bundles : 0 + changed files : 2 + new files : 1 + deleted files : 0 + Validate downloaded files + No extra files need to be downloaded + Validating 3rd-party bundle file permissions... + Installing files... + Update was applied + Updating 3rd-party bundle binaries... + Warning: post-update helper scripts skipped due to --no-scripts argument + Update successful - System updated from version 10 to version 20 + EOM + ) + assert_is_output "$expected_output" + +} + +@test "UPD074: Updating a system along with all the 3rd-party content using --json-output" { + + # If the --3rd-party flag is used, if the update completes successfully + # the 3rd-party content is also updated + + run sudo sh -c "$SWUPD update $SWUPD_OPTS --3rd-party --json-output" + + assert_status_is "$SWUPD_OK" + expected_output=$(cat <<-EOM + [ + { "type" : "start", "section" : "update" }, + { "type" : "info", "msg" : "Update started" }, + EOM + ) + assert_in_output "$expected_output" + expected_output=$(cat <<-EOM + { "type" : "info", "msg" : "Update successful - System updated from version 10 to version 20" }, + { "type" : "end", "section" : "update", "status" : 0 } + ] + [ + { "type" : "start", "section" : "3rd-party-update" }, + EOM + ) + assert_in_output "$expected_output" + expected_output=$(cat <<-EOM + { "type" : "info", "msg" : " 3rd-Party Repo: repo1" }, + EOM + ) + assert_in_output "$expected_output" + expected_output=$(cat <<-EOM + { "type" : "info", "msg" : "Update successful - System updated from version 10 to version 20" }, + { "type" : "end", "section" : "3rd-party-update", "status" : 0 } + ] + EOM + ) + assert_in_output "$expected_output" + +} + +@test "UPD075: Checking update status along with all the 3rd-party content" { + + run sudo sh -c "$SWUPD update $SWUPD_OPTS --3rd-party --status" + + assert_status_is "$SWUPD_OK" + expected_output=$(cat <<-EOM + Current OS version: 10 + Latest server version: 20 + There is a new OS version available: 20 + Checking update status of content from 3rd-party repositories + _______________________ + 3rd-Party Repo: repo1 + _______________________ + Current OS version: 10 + Latest server version: 20 + There is a new OS version available: 20 + EOM + ) + assert_is_output "$expected_output" + +} + +@test "UPD076: There are no undesired behaviors when using --3rd-party along with options not supported in 3rd-party" { + + # the --update-search-file-index flag is not supported with + # "3rd-party update", so there should be no side effects when + # using "update --3rd-party --update-search-file-index" + + run sudo sh -c "$SWUPD update $SWUPD_OPTS --3rd-party --update-search-file-index" + + assert_status_is "$SWUPD_OK" + expected_output=$(cat <<-EOM + Update started + Preparing to update from 10 to 20 + Downloading packs for: + - upstream-bundle + Finishing packs extraction... + Statistics for going from version 10 to version 20: + changed bundles : 1 + new bundles : 0 + deleted bundles : 0 + changed files : 1 + new files : 0 + deleted files : 0 + Validate downloaded files + No extra files need to be downloaded + Installing files... + Update was applied + Calling post-update helper scripts + Downloading all Clear Linux manifests... + Update successful - System updated from version 10 to version 20 + Updating content from 3rd-party repositories + _______________________ + 3rd-Party Repo: repo1 + _______________________ + Updates from a 3rd-party repository are forced to run with the --no-scripts flag for security reasons + Update started + Preparing to update from 10 to 20 + Downloading packs for: + - test-bundle1 + Finishing packs extraction... + Statistics for going from version 10 to version 20: + changed bundles : 2 + new bundles : 0 + deleted bundles : 0 + changed files : 2 + new files : 1 + deleted files : 0 + Validate downloaded files + No extra files need to be downloaded + Validating 3rd-party bundle file permissions... + Installing files... + Update was applied + Updating 3rd-party bundle binaries... + Warning: post-update helper scripts skipped due to --no-scripts argument + Update successful - System updated from version 10 to version 20 + EOM + ) + assert_is_output "$expected_output" + +}