Skip to content
This repository was archived by the owner on Aug 7, 2025. It is now read-only.

Commit d4e6569

Browse files
author
William Douglas
committed
Enable bundle delete during non-format bump updates
Signed-off-by: William Douglas <william.douglas@intel.com>
1 parent 243d708 commit d4e6569

File tree

10 files changed

+99
-50
lines changed

10 files changed

+99
-50
lines changed

src/cmds/bundle_list.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,12 @@ static enum swupd_code show_included_bundles(char *bundle_name, int version)
270270
goto out;
271271
}
272272

273+
if (!mom_search_bundle(mom, bundle_name)) {
274+
ret_code = SWUPD_INVALID_BUNDLE;
275+
warn("Bundle \"%s\" is invalid, skipping it...", bundle_name);
276+
goto out;
277+
}
278+
273279
// add_subscriptions takes a list, so construct one with only bundle_name
274280
bundles = list_prepend_data(bundles, bundle_name);
275281
ret = add_subscriptions(bundles, &subs, mom, true, 0);

src/cmds/update.c

Lines changed: 49 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ int add_included_manifests(struct manifest *mom, struct list **subs)
137137
* hit the Manifest delta path. */
138138
ret = add_subscriptions(subbed, subs, mom, true, 0);
139139
list_free_list(subbed);
140-
if (ret & (add_sub_ERR | add_sub_BADNAME)) {
140+
if (ret & add_sub_ERR) {
141141
return ret;
142142
}
143143

@@ -258,6 +258,47 @@ static struct list *create_update_list(struct manifest *server)
258258
return output;
259259
}
260260

261+
static void handle_deleted_bundles(struct manifest *current_manifest, struct manifest *server_manifest)
262+
{
263+
struct list *deletes = NULL;
264+
struct list *list1, *list2;
265+
struct file *file1, *file2;
266+
267+
list1 = list_head(current_manifest->files);
268+
list2 = list_head(server_manifest->files);
269+
270+
while (list1 && list2) { /* m1/file1 matches m2/file2 */
271+
int ret;
272+
file1 = list1->data;
273+
file2 = list2->data;
274+
275+
ret = str_cmp(file1->filename, file2->filename);
276+
if (ret == 0) {
277+
list1 = list1->next;
278+
list2 = list2->next;
279+
continue;
280+
}
281+
if (ret < 0) { /* m1/file1 is before m2/file2 */
282+
file1->is_deleted = true;
283+
deletes = list_prepend_data(deletes, file1);
284+
list1 = list1->next;
285+
continue;
286+
} /* else ret > 0 m1/file1 is after m2/file2 */
287+
list2 = list2->next;
288+
}
289+
290+
while (list1) {
291+
file1 = list1->data;
292+
file1->is_deleted = true;
293+
deletes = list_prepend_data(deletes, file1);
294+
list1 = list1->next;
295+
}
296+
297+
deletes = list_sort(deletes, cmp_file_filename_is_deleted);
298+
heuristics_apply(deletes);
299+
(void)rename_all_files_to_final(deletes);
300+
}
301+
261302
enum swupd_code execute_update_extra(extra_proc_fn_t post_update_fn, extra_proc_fn_t file_validation_fn)
262303
{
263304
int current_version = -1, server_version = -1;
@@ -366,14 +407,8 @@ enum swupd_code execute_update_extra(extra_proc_fn_t post_update_fn, extra_proc_
366407
timelist_timer_start(globals.global_times, "Add included bundle manifests");
367408
ret = add_included_manifests(server_manifest, &latest_subs);
368409
if (ret) {
369-
if (ret & add_sub_BADNAME) {
370-
/* this means a bundle(s) was removed in a future version */
371-
warn("One or more installed bundles are no longer available at version %d\n",
372-
server_version);
373-
} else {
374-
ret = SWUPD_RECURSE_MANIFEST;
375-
goto clean_exit;
376-
}
410+
ret = SWUPD_RECURSE_MANIFEST;
411+
goto clean_exit;
377412
}
378413
timelist_timer_stop(globals.global_times); // closing: Add included bundle manifests
379414

@@ -430,6 +465,11 @@ enum swupd_code execute_update_extra(extra_proc_fn_t post_update_fn, extra_proc_
430465
heuristics_apply(updates);
431466
timelist_timer_stop(globals.global_times); // closing: Applying heuristics
432467
ret = update_loop(updates, server_manifest, file_validation_fn);
468+
if (!download_only) {
469+
timelist_timer_start(globals.global_times, "Bundle deletes");
470+
handle_deleted_bundles(current_manifest, server_manifest);
471+
timelist_timer_stop(globals.global_times); // closing Bundle deletes
472+
}
433473
if (ret == 0 && !download_only) {
434474
/* Failure to write the version file in the state directory
435475
* should not affect exit status. */

src/cmds/verify.c

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1029,6 +1029,16 @@ enum swupd_code execute_verify_extra(extra_proc_fn_t post_verify_fn)
10291029
/* get the list of subscribed (installed) bundles */
10301030
read_subscriptions(&all_subs);
10311031
selected_subs = all_subs;
1032+
if (!cmdline_option_force) {
1033+
char *bundle_name = NULL;
1034+
for (iter = list_head(all_subs); iter; iter = iter->next) {
1035+
bundle_name = ((struct sub *)(iter->data))->component;
1036+
if (!mom_search_bundle(official_manifest, bundle_name)) {
1037+
invalid_bundle = true;
1038+
warn("Bundle \"%s\" is invalid, skipping it...\n", bundle_name);
1039+
}
1040+
}
1041+
}
10321042
if (cmdline_option_bundles) {
10331043
info("\n");
10341044
for (iter = list_head(cmdline_option_bundles); iter; iter = iter->next) {
@@ -1084,18 +1094,7 @@ enum swupd_code execute_verify_extra(extra_proc_fn_t post_verify_fn)
10841094
* continue only if --force was used since the bundles could be removed */
10851095
if (ret || invalid_bundle) {
10861096
if ((ret & add_sub_BADNAME) || invalid_bundle) {
1087-
if (cmdline_option_force) {
1088-
if (cmdline_option_picky && cmdline_option_fix) {
1089-
warn("\nOne or more installed bundles that are not "
1090-
"available at version %d will be removed\n",
1091-
version);
1092-
} else if (cmdline_option_picky && !cmdline_option_fix) {
1093-
warn("\nOne or more installed bundles are not "
1094-
"available at version %d\n",
1095-
version);
1096-
}
1097-
ret = SWUPD_OK;
1098-
} else {
1097+
if (!cmdline_option_force) {
10991098
if (cmdline_option_install || cmdline_option_bundles) {
11001099
error("\nOne or more of the provided bundles are not available at version %d\n", version);
11011100
info("Please make sure the name of the provided bundles are correct, or use --force to override\n")

src/swupd_lib/manifest.c

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -469,19 +469,20 @@ void link_manifests(struct manifest *m1, struct manifest *m2)
469469
continue;
470470
}
471471
if (ret < 0) { /* m1/file1 is before m2/file2 */
472-
/* File is absent in m2, indicating that a format bump
473-
* happened, removing deleted file entries from the
474-
* previous format(s). Do not account the deleted file
475-
* in this case, since an update will not delete the
476-
* file.
477-
*/
472+
account_deleted_file();
478473
list1 = list1->next;
479474
continue;
480475
} /* else ret > 0 m1/file1 is after m2/file2 */
481476
list2 = list2->next;
482477
account_new_file();
483478
}
484479

480+
// Capture deleted files if they are at the tail end of the file list
481+
while (list1) {
482+
list1 = list1->next;
483+
account_deleted_bundle();
484+
}
485+
485486
// Capture new files if they are at the tail end of the file list
486487
while (list2) {
487488
list2 = list2->next;
@@ -534,9 +535,10 @@ void link_submanifests(struct manifest *m1, struct manifest *m2, struct list *su
534535
}
535536
if (ret < 0) { /* m1/file1 is before m2/file2 */
536537
/* A bundle manifest going missing from the MoM in the
537-
* latest version is a breaking change, only possible
538-
* during a format bump, so don't account for this
539-
* possibility in the stats. */
538+
* latest version is no longer a breaking change. */
539+
if (!server && subbed1) {
540+
account_deleted_bundle();
541+
}
540542
list1 = list1->next;
541543
continue;
542544
} /* else ret > 0 m1/file1 is after m2/file2 */
@@ -546,8 +548,14 @@ void link_submanifests(struct manifest *m1, struct manifest *m2, struct list *su
546548
}
547549
}
548550

551+
// Capture deleted bundles if they are at the tail end of the list
552+
while (!server && list1) {
553+
list1 = list1->next;
554+
account_deleted_bundle();
555+
}
556+
549557
// Capture new bundles if they are at the tail end of the list
550-
while (list2) {
558+
while (server && list2) {
551559
file2 = list2->data;
552560
list2 = list2->next;
553561
bool subbed2 = component_subscribed(subs2, file2->filename);

src/swupd_lib/subscriptions.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -202,8 +202,7 @@ static int recurse_subscriptions(struct list *bundles, struct list **subs, struc
202202

203203
file = mom_search_bundle(mom, bundle);
204204
if (!file) {
205-
warn("Bundle \"%s\" is invalid, skipping it...\n", bundle);
206-
ret |= add_sub_BADNAME; /* Use this to get non-zero exit code */
205+
// No longer add_sub_BADNAME with bundle deletes allowed
207206
continue;
208207
}
209208

src/swupd_lib/target_root.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -640,7 +640,7 @@ int rename_staged_file_to_final(struct file *file)
640640
return ret;
641641
}
642642

643-
static int rename_all_files_to_final(struct list *updates)
643+
int rename_all_files_to_final(struct list *updates)
644644
{
645645
int ret, update_errs = 0;
646646
struct list *dirs_to_remove = NULL;

src/swupd_lib/target_root.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,13 @@
1313
extern "C" {
1414
#endif
1515

16+
/**
17+
* @brief Final stage of filesystem modification.
18+
*
19+
* @param updates The list of files to be modified.
20+
*/
21+
int rename_all_files_to_final(struct list *updates);
22+
1623
/**
1724
* @brief Install files from 'files' into the system.
1825
*

test/functional/diagnose/diagnose-picky-downgrade.bats

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,6 @@ test_setup() {
2020
expected_output=$(cat <<-EOM
2121
Diagnosing version 10
2222
Downloading missing manifests...
23-
Warning: Bundle "test-bundle2" is invalid, skipping it...
24-
Warning: One or more installed bundles are not available at version 10
2523
Checking for missing files
2624
Checking for corrupt files
2725
-> Hash mismatch for file: $ABS_TARGET_DIR/usr/lib/os-release

test/functional/repair/repair-picky-downgrade.bats

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@ test_setup() {
2323
expected_output=$(cat <<-EOM
2424
Diagnosing version 10
2525
Warning: The --picky option is specified; ignoring version mismatch for repair
26-
Downloading missing manifests...
2726
Warning: Bundle "test-bundle2" is invalid, skipping it...
27+
Downloading missing manifests...
2828
Error: Unable to verify. One or more currently installed bundles are not available at version 10. Use --force to override
2929
Repair did not fully succeed
3030
EOM
@@ -47,8 +47,6 @@ test_setup() {
4747
Diagnosing version 10
4848
Warning: The --force option is specified; ignoring version mismatch for repair
4949
Downloading missing manifests...
50-
Warning: Bundle "test-bundle2" is invalid, skipping it...
51-
Warning: One or more installed bundles that are not available at version 10 will be removed
5250
Checking for corrupt files
5351
Validate downloaded files
5452
Starting download of remaining update content. This may take a while...
@@ -93,8 +91,6 @@ test_setup() {
9391
Diagnosing version 10
9492
Warning: The --force option is specified; ignoring version mismatch for repair
9593
Downloading missing manifests...
96-
Warning: Bundle "test-bundle2" is invalid, skipping it...
97-
Warning: One or more installed bundles that are not available at version 10 will be removed
9894
Checking for corrupt files
9995
Validate downloaded files
10096
Starting download of remaining update content. This may take a while...

test/functional/update/update-bundle-removed.bats

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,28 +17,24 @@ test_setup() {
1717
@test "UPD008: Updating a system where a bundle was removed in the newer version" {
1818

1919
# If a bundle happens to be removed from the content server (or mix) it means the
20-
# bundle won't be in the MoM anymore, so the bundle in the system will look like an
21-
# invalid bundle. If this happens, the user should be informed, and the update should
22-
# continue.
20+
# bundle won't be in the MoM anymore, this now indicates a bundle delete.
2321

2422
run sudo sh -c "$SWUPD update $SWUPD_OPTS"
2523

2624
assert_status_is 0
2725
expected_output=$(cat <<-EOM
2826
Update started
2927
Preparing to update from 10 to 20
30-
Warning: Bundle "test-bundle1" is invalid, skipping it...
31-
Warning: One or more installed bundles are no longer available at version 20
3228
Downloading packs for:
3329
- os-core
3430
Finishing packs extraction...
3531
Statistics for going from version 10 to version 20:
3632
changed bundles : 1
3733
new bundles : 0
38-
deleted bundles : 0
34+
deleted bundles : 1
3935
changed files : 2
4036
new files : 0
41-
deleted files : 0
37+
deleted files : 2
4238
Validate downloaded files
4339
No extra files need to be downloaded
4440
Installing files...
@@ -49,8 +45,8 @@ test_setup() {
4945
)
5046
assert_is_output "$expected_output"
5147
# bundle should not be removed
52-
assert_file_exists "$TARGET_DIR"/file_1
53-
assert_file_exists "$TARGET_DIR"/usr/share/clear/bundles/test-bundle1
48+
assert_file_not_exists "$TARGET_DIR"/file_1
49+
assert_file_not_exists "$TARGET_DIR"/usr/share/clear/bundles/test-bundle1
5450

5551
}
5652
#WEIGHT=5

0 commit comments

Comments
 (0)