sysupdate: fix root cleanup and default feature selection (#43154)
This commit is contained in:
@@ -112,6 +112,27 @@ static int installdb_make_names(const char *path, const char *pattern, char **re
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const char* context_root_relative_path(const Context *c, const char *path) {
|
||||
const char *p;
|
||||
|
||||
assert(c);
|
||||
assert(path);
|
||||
|
||||
if (!c->root)
|
||||
return path;
|
||||
|
||||
p = path_startswith_full(path, c->root, PATH_STARTSWITH_RETURN_LEADING_SLASH);
|
||||
if (p)
|
||||
return p;
|
||||
|
||||
/* path_startswith_full(..., PATH_STARTSWITH_RETURN_LEADING_SLASH) cannot return a pointer
|
||||
* to a leading slash before the start of the original string when both paths are identical. */
|
||||
if (path_equal(path, c->root))
|
||||
return "/";
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int context_installdb_record(
|
||||
Context *c,
|
||||
const char *path,
|
||||
@@ -129,7 +150,11 @@ int context_installdb_record(
|
||||
return 0;
|
||||
|
||||
/* The provided path comes with c->root prefixed. Strip it here again */
|
||||
const char *p = c->root ? ASSERT_PTR(path_startswith(path, c->root)) : path;
|
||||
const char *p = context_root_relative_path(c, path);
|
||||
if (!p)
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
|
||||
"Resolved resource path '%s' is not below root '%s'.",
|
||||
path, c->root);
|
||||
|
||||
r = context_installdb_acquire_fd(c, /* make= */ true);
|
||||
if (r < 0)
|
||||
@@ -170,7 +195,13 @@ static int context_is_path_currently_owned(
|
||||
if (!RESOURCE_IS_FILESYSTEM(t->target.type))
|
||||
continue;
|
||||
|
||||
if (!path_equal(t->target.path, path))
|
||||
const char *target_path = context_root_relative_path(c, t->target.path);
|
||||
if (!target_path)
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
|
||||
"Resolved target path '%s' is not below root '%s'.",
|
||||
t->target.path, c->root);
|
||||
|
||||
if (!path_equal(target_path, path))
|
||||
continue;
|
||||
|
||||
/* OK, so we found a transfer that covers this directory. Now let's see if any of its patterns match */
|
||||
|
||||
@@ -2949,15 +2949,13 @@ static int context_list_components(Context *context, char ***ret_component_names
|
||||
if (ret_component_names)
|
||||
*ret_component_names = TAKE_PTR(z);
|
||||
|
||||
/* Does the system have at least one transfer file in /etc/sysupdate.d, which can be considered a
|
||||
* TARGET_HOST? See target_get_argument() in sysupdated.c */
|
||||
/* Does the system have at least one transfer file in sysupdate.d, which can be considered the
|
||||
* default component-less installation? */
|
||||
if (ret_has_default_component)
|
||||
*ret_has_default_component =
|
||||
!context->definitions &&
|
||||
!context->component &&
|
||||
!context->root &&
|
||||
!context->image &&
|
||||
context->n_transfers > 0;
|
||||
context->n_transfers + context->n_disabled_transfers > 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -907,6 +907,40 @@ test ! -f "$CLEANUP/target/alpha-v2.bin"
|
||||
|
||||
rm -rf "$CONFIGDIR" "$INSTALLDB" "$CLEANUP"
|
||||
|
||||
# Under --root=, cleanup must compare current transfer target paths in the same
|
||||
# root-relative form stored in the install database, and keep still-owned files.
|
||||
ROOT_CLEANUP="$WORKDIR/root-cleanup"
|
||||
ROOT_CLEANUP_ROOT="$ROOT_CLEANUP/root"
|
||||
ROOT_CLEANUP_DB_VALUE="/target/./alpha-@v.bin"
|
||||
ROOT_CLEANUP_DB_KEY="$(printf '%s' "$ROOT_CLEANUP_DB_VALUE" | sha256sum | cut -d' ' -f1)"
|
||||
rm -rf "$ROOT_CLEANUP"
|
||||
mkdir -p "$ROOT_CLEANUP_ROOT/etc/sysupdate.d" \
|
||||
"$ROOT_CLEANUP_ROOT/target" \
|
||||
"$ROOT_CLEANUP_ROOT/var/lib/systemd/sysupdate/installdb"
|
||||
|
||||
cat >"$ROOT_CLEANUP_ROOT/etc/sysupdate.d/01-alpha.transfer" <<EOF
|
||||
[Source]
|
||||
Type=regular-file
|
||||
Path=/source
|
||||
MatchPattern=alpha-@v.bin
|
||||
|
||||
[Target]
|
||||
Type=regular-file
|
||||
Path=/target
|
||||
MatchPattern=alpha-@v.bin
|
||||
InstancesMax=2
|
||||
EOF
|
||||
|
||||
echo "$RANDOM" >"$ROOT_CLEANUP_ROOT/target/alpha-v1.bin"
|
||||
ln -s "$ROOT_CLEANUP_DB_VALUE" \
|
||||
"$ROOT_CLEANUP_ROOT/var/lib/systemd/sysupdate/installdb/$ROOT_CLEANUP_DB_KEY"
|
||||
|
||||
"$SYSUPDATE" --root="$ROOT_CLEANUP_ROOT" --verify=no cleanup
|
||||
test -f "$ROOT_CLEANUP_ROOT/target/alpha-v1.bin"
|
||||
test -L "$ROOT_CLEANUP_ROOT/var/lib/systemd/sysupdate/installdb/$ROOT_CLEANUP_DB_KEY"
|
||||
|
||||
rm -rf "$ROOT_CLEANUP"
|
||||
|
||||
# Briefly check the "--component-all" switch of the "cleanup" verb. Each component
|
||||
# keeps its own install database (installdb.<component>), and "cleanup
|
||||
# --component-all" must clean up orphaned resources across *all* of them in one
|
||||
@@ -1799,6 +1833,50 @@ assert_dropin "$(feat_enable_dropin_default featc)" yes
|
||||
test ! -e "$(feat_enable_dropin_default featb)"
|
||||
set_machine_tags ""
|
||||
|
||||
# --component-all must still include the default component when all of its
|
||||
# transfers are currently disabled by features.
|
||||
compfeat_reset
|
||||
compfeat_source v1
|
||||
mkdir -p /run/sysupdate.d
|
||||
compfeat_transfer /run/sysupdate.d/50-feata.transfer feata "$CF/target-default" feata
|
||||
cat >/run/sysupdate.d/feata.feature <<EOF
|
||||
[Feature]
|
||||
Description=Feature A
|
||||
EOF
|
||||
"$SYSUPDATE" --component-all enable-feature --feature-all
|
||||
assert_dropin "$(feat_enable_dropin_default feata)" yes
|
||||
|
||||
# --component-all must include the default component under --root= too.
|
||||
ROOT_FEATURE="$WORKDIR/root-feature"
|
||||
ROOT_FEATURE_ROOT="$ROOT_FEATURE/root"
|
||||
rm -rf "$ROOT_FEATURE"
|
||||
mkdir -p "$ROOT_FEATURE_ROOT/etc/sysupdate.d" \
|
||||
"$ROOT_FEATURE_ROOT/source" \
|
||||
"$ROOT_FEATURE_ROOT/target"
|
||||
cat >"$ROOT_FEATURE_ROOT/etc/sysupdate.d/50-feata.transfer" <<EOF
|
||||
[Transfer]
|
||||
Features=feata
|
||||
|
||||
[Source]
|
||||
Type=regular-file
|
||||
Path=/source
|
||||
MatchPattern=feata-@v.bin
|
||||
|
||||
[Target]
|
||||
Type=regular-file
|
||||
Path=/target
|
||||
MatchPattern=feata-@v.bin
|
||||
InstancesMax=2
|
||||
EOF
|
||||
cat >"$ROOT_FEATURE_ROOT/etc/sysupdate.d/feata.feature" <<EOF
|
||||
[Feature]
|
||||
Description=Feature A
|
||||
EOF
|
||||
"$SYSUPDATE" --root="$ROOT_FEATURE_ROOT" --component-all enable-feature --feature-all
|
||||
assert_dropin "$ROOT_FEATURE_ROOT$(feat_enable_dropin_default feata)" yes
|
||||
|
||||
rm -rf "$ROOT_FEATURE"
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Features scoped to a named component, and across all components at once
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user