From 265b7f9ecc3a9d245fc6d32922437bf8922df579 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Thu, 12 Oct 2023 13:22:00 -0400 Subject: [PATCH] deploy: Improve error message for nonexistent stateroot Came up on an internal chat; previously we were only erroring out when trying to do the SELinux labeling for `/var` which was really misleading. Add some other error prefixing while we have the patient open. --- src/libostree/ostree-sysroot-deploy.c | 17 +++++++++++++++++ tests/admin-test.sh | 9 ++++++++- 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/src/libostree/ostree-sysroot-deploy.c b/src/libostree/ostree-sysroot-deploy.c index 059b55504a..e7b91b697a 100644 --- a/src/libostree/ostree-sysroot-deploy.c +++ b/src/libostree/ostree-sysroot-deploy.c @@ -820,6 +820,7 @@ static gboolean selinux_relabel_var_if_needed (OstreeSysroot *sysroot, OstreeSePolicy *sepolicy, int os_deploy_dfd, GCancellable *cancellable, GError **error) { + GLNX_AUTO_PREFIX_ERROR ("Relabeling /var", error); /* This is a bit of a hack; we should change the code at some * point in the distant future to only create (and label) /var * when doing a deployment. @@ -3044,6 +3045,17 @@ lint_deployment_fs (OstreeSysroot *self, OstreeDeployment *deployment, int deplo return TRUE; } +static gboolean +require_stateroot (OstreeSysroot *self, const char *stateroot, GError **error) +{ + const char *osdeploypath = glnx_strjoina ("ostree/deploy/", stateroot); + if (!glnx_fstatat_allow_noent (self->sysroot_fd, osdeploypath, NULL, 0, error)) + return FALSE; + if (errno == ENOENT) + return glnx_throw (error, "No such stateroot: %s", stateroot); + return TRUE; +} + /* The first part of writing a deployment. This primarily means doing the * hardlink farm checkout, but we also compute some initial state. */ @@ -3060,6 +3072,9 @@ sysroot_initialize_deployment (OstreeSysroot *self, const char *osname, const ch if (osname == NULL) osname = ostree_deployment_get_osname (self->booted_deployment); + if (!require_stateroot (self, osname, error)) + return FALSE; + OstreeRepo *repo = ostree_sysroot_repo (self); gint new_deployserial; @@ -3234,6 +3249,7 @@ run_in_deployment (int deployment_dfd, const gchar *const *child_argv, gsize chi static gboolean sysroot_finalize_selinux_policy (int deployment_dfd, GError **error) { + GLNX_AUTO_PREFIX_ERROR ("Finalizing SELinux policy", error); struct stat stbuf; gint exit_status; g_autofree gchar *stdout = NULL; @@ -3280,6 +3296,7 @@ sysroot_finalize_deployment (OstreeSysroot *self, OstreeDeployment *deployment, OstreeDeployment *merge_deployment, GCancellable *cancellable, GError **error) { + GLNX_AUTO_PREFIX_ERROR ("Finalizing deployment", error); g_autofree char *deployment_path = ostree_sysroot_get_deployment_dirpath (self, deployment); glnx_autofd int deployment_dfd = -1; if (!glnx_opendirat (self->sysroot_fd, deployment_path, TRUE, &deployment_dfd, error)) diff --git a/tests/admin-test.sh b/tests/admin-test.sh index e362162c5b..520a875c7a 100644 --- a/tests/admin-test.sh +++ b/tests/admin-test.sh @@ -19,7 +19,7 @@ set -euo pipefail -echo "1..$((29 + ${extra_admin_tests:-0}))" +echo "1..$((30 + ${extra_admin_tests:-0}))" mkdir sysrootmin ${CMD_PREFIX} ostree admin init-fs --modern sysrootmin @@ -76,6 +76,13 @@ assert_file_has_content curdir ^`pwd`/sysroot/ostree/deploy/testos/deploy/${rev} echo "ok --print-current-dir" +if ${CMD_PREFIX} ostree admin deploy --stateroot=nosuchroot testos:testos/buildmain/x86_64-runtime 2>err.txt; then + fatal "deployed to nonexistent root" +fi +assert_file_has_content err.txt "error:.*No such stateroot: nosuchroot" + +echo "ok nice error for deploy with no stateroot" + # Test layout of bootloader config and refs assert_not_has_dir sysroot/boot/loader.0 assert_has_dir sysroot/boot/loader.1