Files
William Douglas 02d276564d Rework content deletion handling
Currently sys_rm_recursive was used in any instance of deleting swupd
content from the system (update, repair and bundle-remove). This can
cause user data loss when unkown files are in directories that swupd
is deleting.

To prevent this, this patch changes how deleting content in swupd
operates. Swupd content removal is now done with sys_rm and the return
value is checked in case the removal failed due to a directory that
still had files in it. When this specific failure occurs, the
directory is added to a new list for reprocessing removals as it is
expected once the rest of the deletes on the system occur the failures
will go away as the directories will be empty (these deletes are
processed in alphabetical reverse order so leaf directories are
processed first). If the removal fails again it is presumed the
contents of the directory are not files swupd knows about and as such
should be kept somewhere else.

For handling the retention of user data, directories (with only the
content unknown to swupd) are renamed (currently using a
.deleted.$timestamp. prefix of the old name) and stored at the same
directory level they were previously found with one exception. The
exception is for nested deleted content best illustrated with an
example:

/swupd-dir1/user-file1
/swupd-dir1/swupd-dir2/user-file2

When swupd tries to remove the /swupd-dir1 content, it will store the
user files as follows:

/.deleted.$timestamp1.swupd-dir1/user-file1
/.deleted.$timestamp1.swupd-dir1/.deleted.$timestamp1.swupd-dir2/user-file2

To demarcate what was part of swupd content vs user content.

Signed-off-by: William Douglas <william.douglas@intel.com>
2024-04-05 10:28:41 -07:00

209 lines
6.2 KiB
Bash
Executable File

#!/usr/bin/env bats
load "../testlib"
setup_file() {
create_test_environment "$TEST_NAME"
create_bundle -L -t -n test-bundle1 -d /foo -f /test-file1,/bar/test-file2,/bat/test-file3,/bat/common "$TEST_NAME"
create_bundle -L -t -n test-bundle2 -f /bat/test-file4,/bat/common "$TEST_NAME"
create_bundle -n test-bundle3 -f /baz/test-file5 "$TEST_NAME"
}
teardown_file() {
destroy_test_environment --force "$TEST_NAME"
}
test_teardown() {
# reinstall test-bundle1 and test-bundle2
install_bundle "$WEB_DIR"/10/Manifest.test-bundle1
install_bundle "$WEB_DIR"/10/Manifest.test-bundle2
}
# ------------------------------------------
# Good Cases (all good bundles)
# ------------------------------------------
@test "REM001: Removing one bundle" {
sudo mkdir "$TARGET_DIR"/bar/keep1
run sudo sh -c "$SWUPD bundle-remove $SWUPD_OPTS test-bundle1"
assert_status_is 0
# bundle1 was removed
assert_file_not_exists "$TARGET_DIR"/usr/share/clear/bundles/test-bundle1
assert_file_not_exists "$TARGET_DIR"/test-file1
assert_file_not_exists "$TARGET_DIR"/bar/test-file2
assert_file_not_exists "$TARGET_DIR"/bat/test-file3
assert_dir_not_exists "$TARGET_DIR"/foo
assert_dir_not_exists "$TARGET_DIR"/bar
assert_file_not_exists "$STATE_DIR"/bundles/test-bundle1
# keep file isn't removed
assert_file_exists "$TARGET_DIR"/.deleted.*.bar/keep1
# bundle2 was not removed
assert_file_exists "$TARGET_DIR"/usr/share/clear/bundles/test-bundle2
assert_file_exists "$TARGET_DIR"/bat/test-file4
assert_file_exists "$TARGET_DIR"/bat/common
assert_file_exists "$STATE_DIR"/bundles/test-bundle2
expected_output=$(cat <<-EOM
The following bundles are being removed:
- test-bundle1
Deleting bundle files...
Total deleted files: 6
Successfully removed 1 bundle
EOM
)
}
@test "REM002: Removing multiple bundles" {
run sudo sh -c "$SWUPD bundle-remove $SWUPD_OPTS test-bundle1 test-bundle2"
assert_status_is 0
# bundle1 and 2 were removed
assert_file_not_exists "$TARGET_DIR"/usr/share/clear/bundles/test-bundle1
assert_file_not_exists "$TARGET_DIR"/usr/share/clear/bundles/test-bundle2
assert_file_not_exists "$TARGET_DIR"/test-file1
assert_file_not_exists "$TARGET_DIR"/bar/test-file2
assert_file_not_exists "$TARGET_DIR"/bat/test-file3
assert_file_not_exists "$TARGET_DIR"/bat/test-file4
assert_file_not_exists "$TARGET_DIR"/bat/common
assert_dir_not_exists "$TARGET_DIR"/foo
assert_dir_not_exists "$TARGET_DIR"/bar
assert_dir_not_exists "$TARGET_DIR"/bat
assert_file_not_exists "$STATE_DIR"/bundles/test-bundle1
assert_file_not_exists "$STATE_DIR"/bundles/test-bundle2
expected_output=$(cat <<-EOM
The following bundles are being removed:
- test-bundle2
- test-bundle1
Deleting bundle files...
Total deleted files: 9
Successfully removed 2 bundles
EOM
)
assert_is_output "$expected_output"
}
# ------------------------------------------
# Bad Cases (all bad bundles)
# ------------------------------------------
@test "REM003: Try removing a bundle that is not installed" {
run sudo sh -c "$SWUPD bundle-remove $SWUPD_OPTS test-bundle3"
assert_status_is "$SWUPD_BUNDLE_NOT_TRACKED"
expected_output=$(cat <<-EOM
Warning: Bundle "test-bundle3" is not installed, skipping it...
Failed to remove 1 of 1 bundles
EOM
)
assert_is_output --identical "$expected_output"
}
@test "REM004: Try removing a bundle that does not exist" {
run sudo sh -c "$SWUPD bundle-remove $SWUPD_OPTS fake-bundle"
assert_status_is "$SWUPD_INVALID_BUNDLE"
expected_output=$(cat <<-EOM
Warning: Bundle "fake-bundle" is invalid, skipping it...
Failed to remove 1 of 1 bundles
EOM
)
assert_is_output --identical "$expected_output"
}
@test "REM005: Try removing multiple bundles, all invalid, one non existent, one already removed" {
run sudo sh -c "$SWUPD bundle-remove $SWUPD_OPTS fake-bundle test-bundle3"
assert_status_is "$SWUPD_BUNDLE_NOT_TRACKED"
expected_output=$(cat <<-EOM
Warning: Bundle "fake-bundle" is invalid, skipping it...
Warning: Bundle "test-bundle3" is not installed, skipping it...
Failed to remove 2 of 2 bundles
EOM
)
assert_is_output --identical "$expected_output"
}
# ------------------------------------------
# Partial Cases (at least one good bundle)
# ------------------------------------------
@test "REM006: Try removing multiple bundles, one valid, one not installed" {
run sudo sh -c "$SWUPD bundle-remove $SWUPD_OPTS test-bundle3 test-bundle1"
assert_status_is "$SWUPD_BUNDLE_NOT_TRACKED"
assert_file_not_exists "$TARGET_DIR"/usr/share/clear/bundles/test-bundle1
assert_file_not_exists "$TARGET_DIR"/test-file1
assert_file_not_exists "$TARGET_DIR"/bar/test-file2
assert_file_not_exists "$TARGET_DIR"/bat/test-file3
assert_dir_not_exists "$TARGET_DIR"/foo
assert_dir_not_exists "$TARGET_DIR"/bar
# bundle2 was not removed
assert_file_exists "$TARGET_DIR"/usr/share/clear/bundles/test-bundle2
assert_file_exists "$TARGET_DIR"/bat/test-file4
assert_file_exists "$TARGET_DIR"/bat/common
expected_output=$(cat <<-EOM
Warning: Bundle "test-bundle3" is not installed, skipping it...
The following bundles are being removed:
- test-bundle1
Deleting bundle files...
Total deleted files: 6
Failed to remove 1 of 2 bundles
EOM
)
assert_is_output "$expected_output"
}
@test "REM007: Try removing multiple bundles, one valid, one non existent" {
run sudo sh -c "$SWUPD bundle-remove $SWUPD_OPTS fake-bundle test-bundle1"
assert_status_is "$SWUPD_INVALID_BUNDLE"
assert_file_not_exists "$TARGET_DIR"/usr/share/clear/bundles/test-bundle1
assert_file_not_exists "$TARGET_DIR"/test-file1
assert_file_not_exists "$TARGET_DIR"/bar/test-file2
assert_file_not_exists "$TARGET_DIR"/bat/test-file3
assert_dir_not_exists "$TARGET_DIR"/foo
assert_dir_not_exists "$TARGET_DIR"/bar
# bundle2 was not removed
assert_file_exists "$TARGET_DIR"/usr/share/clear/bundles/test-bundle2
assert_file_exists "$TARGET_DIR"/bat/test-file4
assert_file_exists "$TARGET_DIR"/bat/common
expected_output=$(cat <<-EOM
Warning: Bundle "fake-bundle" is invalid, skipping it...
The following bundles are being removed:
- test-bundle1
Deleting bundle files...
Total deleted files: 6
Failed to remove 1 of 2 bundles
EOM
)
assert_is_output "$expected_output"
}
#WEIGHT=6