deploy: Improve error message for nonexistent stateroot
authorColin Walters <walters@verbum.org>
Thu, 12 Oct 2023 17:22:00 +0000 (13:22 -0400)
committerColin Walters <walters@verbum.org>
Thu, 12 Oct 2023 17:22:35 +0000 (13:22 -0400)
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
tests/admin-test.sh

index 059b55504aaa5fbde49feff7786729c061859865..e7b91b697a6d2a6cda93c676f61c6b991b230bc0 100644 (file)
@@ -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))
index e362162c5b6407232122272bb7a89a319f90578e..520a875c7a22070e24d67b557420e91c66ac9731 100644 (file)
@@ -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