Skip to content

Commit

Permalink
daemon: use new finalization APIs
Browse files Browse the repository at this point in the history
Now that we've stabilized and made public deployment finalization APIs,
let's use them.

This also fixes an issue where when creating a locked deployment using
the legacy API (i.e. touching the `/run/ostree/staged/deployment-locked`
file before calling the staging API), if a staged deployment already
exists, libostree would just nuke the lockfile (this behaviour was
introduced in ostreedev/ostree#3077).

In theory the legacy API (via the lockfile) should keep working, but
the core issue is that there's no way for libostree to know if the
lockfile is carried-over state, or was freshly created for the current
invocation.

So let's not try to salvage the legacy API and just move over to the
new one.

We already have finalization tests; they will now test that the new API
functions correctly. But stop looking for the legacy lockfile. We could
instead inspect the staged deployment GVariant, but these checks were
redundant anyway since the tests verify the finalization by actually
rebooting and/or not use `finalize-deployment --allow-unlocked`.

Fixes: coreos/fedora-coreos-tracker#1691
  • Loading branch information
jlebon committed Apr 26, 2024
1 parent e0cf3f7 commit 6a3a5eb
Show file tree
Hide file tree
Showing 5 changed files with 9 additions and 27 deletions.
2 changes: 2 additions & 0 deletions rust/src/daemon.rs
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,8 @@ pub(crate) fn deployment_populate_variant(
/* Staging status */
dict.insert("staged", &deployment.is_staged());
if deployment.is_staged()
// XXX: this should check deployment.is_finalization_locked() too now
// but the libostree Rust bindings need to be updated
&& std::path::Path::new("/run/ostree/staged-deployment-locked").exists()
{
dict.insert("finalization-locked", &true);
Expand Down
4 changes: 0 additions & 4 deletions src/daemon/rpmostree-sysroot-core.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,6 @@ G_BEGIN_DECLS
/* The legacy dir, which we will just delete if we find it */
#define RPMOSTREE_OLD_TMP_ROOTFS_DIR "extensions/rpmostree/commit"

/* Really, this is an OSTree API, but let's consider it hidden for now like the
* /run/ostree/staged-deployment path and company. */
#define _OSTREE_SYSROOT_RUNSTATE_STAGED_LOCKED "/run/ostree/staged-deployment-locked"

gboolean rpmostree_syscore_cleanup (OstreeSysroot *sysroot, OstreeRepo *repo,
GCancellable *cancellable, GError **error);

Expand Down
16 changes: 1 addition & 15 deletions src/daemon/rpmostree-sysroot-upgrader.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -1396,27 +1396,13 @@ rpmostree_sysroot_upgrader_deploy (RpmOstreeSysrootUpgrader *self,
}

OstreeSysrootDeployTreeOpts opts = {
.locked = (self->flags & RPMOSTREE_SYSROOT_UPGRADER_FLAGS_LOCK_FINALIZATION),
.override_kernel_argv = self->kargs_strv,
.overlay_initrds = (char **)overlay_v,
};

if (use_staging)
{
/* touch file *before* we stage to avoid races */
if (self->flags & RPMOSTREE_SYSROOT_UPGRADER_FLAGS_LOCK_FINALIZATION)
{
if (!glnx_shutil_mkdir_p_at (AT_FDCWD,
dirname (strdupa (_OSTREE_SYSROOT_RUNSTATE_STAGED_LOCKED)),
0755, cancellable, error))
return FALSE;

glnx_autofd int fd = open (_OSTREE_SYSROOT_RUNSTATE_STAGED_LOCKED,
O_CREAT | O_WRONLY | O_NOCTTY | O_CLOEXEC, 0640);
if (fd == -1)
return glnx_throw_errno_prefix (error, "touch(%s)",
_OSTREE_SYSROOT_RUNSTATE_STAGED_LOCKED);
}

auto task = rpmostreecxx::progress_begin_task ("Staging deployment");
if (!ostree_sysroot_stage_tree_with_options (self->sysroot, self->osname, target_revision,
origin, self->cfg_merge_deployment, &opts,
Expand Down
10 changes: 6 additions & 4 deletions src/daemon/rpmostreed-transaction-types.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -2524,14 +2524,16 @@ finalize_deployment_transaction_execute (RpmostreedTransaction *transaction,
if (!check_sd_inhibitor_locks (cancellable, error))
return FALSE;

if (unlink (_OSTREE_SYSROOT_RUNSTATE_STAGED_LOCKED) < 0)
if (!ostree_deployment_is_finalization_locked (default_deployment))
{
if (errno != ENOENT)
return glnx_throw_errno_prefix (error, "unlink(%s)",
_OSTREE_SYSROOT_RUNSTATE_STAGED_LOCKED);
if (!vardict_lookup_bool (self->options, "allow-unlocked", FALSE))
return glnx_throw (error, "Staged deployment already unlocked");
}
else
{
if (!ostree_sysroot_change_finalization (sysroot, default_deployment, error))
return glnx_prefix_error (error, "Failed to unlock finalization of staged deployment");
}

/* And bump sysroot mtime so we reload... a bit awkward, though this is similar to
* libostree itself doing this for `ostree admin unlock` (and possibly an `ostree admin`
Expand Down
4 changes: 0 additions & 4 deletions tests/vmcheck/test-misc-2.sh
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,12 @@ assert_file_has_content status.txt 'Commit:'
booted_csum=$(vm_get_booted_csum)
commit=$(vm_cmd ostree commit -b vmcheck --tree=ref=vmcheck --bootable)
vm_rpmostree deploy revision="${commit}" --lock-finalization
vm_cmd test -f /run/ostree/staged-deployment-locked
cursor=$(vm_get_journal_cursor)
vm_reboot
assert_streq "$(vm_get_booted_csum)" "${booted_csum}"
vm_assert_journal_has_content $cursor 'Not finalizing; deployment is locked for finalization'
echo "ok locked deploy staging"
vm_rpmostree rebase :"${commit}" --lock-finalization --skip-purge
vm_cmd test -f /run/ostree/staged-deployment-locked
cursor=$(vm_get_journal_cursor)
vm_reboot
assert_streq "$(vm_get_booted_csum)" "${booted_csum}"
Expand All @@ -56,7 +54,6 @@ cursor=$(vm_get_journal_cursor)
vm_cmd env RPMOSTREE_CLIENT_ID=testing-agent-id \
rpm-ostree deploy revision="${commit}" \
--lock-finalization
vm_cmd test -f /run/ostree/staged-deployment-locked
if vm_rpmostree finalize-deployment; then
assert_not_reached "finalized without expected checksum"
elif vm_rpmostree finalize-deployment WRONG_CHECKSUM; then
Expand All @@ -71,7 +68,6 @@ if vm_rpmostree finalize-deployment "${commit}" 2>err.txt; then
assert_not_reached "finalized with inhibitor lock in block mode present"
fi
assert_file_has_content err.txt 'Reboot blocked'
vm_cmd test -f /run/ostree/staged-deployment-locked # Make sure that staged deployment is still locked.
vm_cmd touch /run/wakeup
sleep 1 # Wait one second for the process holding the lock to exit.
vm_reboot_cmd rpm-ostree finalize-deployment "${commit}"
Expand Down

0 comments on commit 6a3a5eb

Please sign in to comment.