From edf7477ee9e2c1d238aae35b1a0414e478870837 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Wed, 9 Jun 2021 09:44:09 -0400 Subject: [PATCH] deploy: Warn if we find content in the deployment's /var This will be ignored, so let's make it very clear people are doing something wrong. Motivated by a bug in a build pipeline that injected `/var/lib/rpm` into an ostree commit which ended up crashing rpm-ostree because it was an empty db which it wasn't expecting. It *also* turns out rpm-ostree is incorrectly dumping content in the deployment `/var` today, which is another bug. --- src/libostree/ostree-sysroot-deploy.c | 36 ++++++++++++++++++++++ tests/kolainst/destructive/deployment-lint | 13 ++++++++ 2 files changed, 49 insertions(+) create mode 100755 tests/kolainst/destructive/deployment-lint diff --git a/src/libostree/ostree-sysroot-deploy.c b/src/libostree/ostree-sysroot-deploy.c index 32748a62..840775d4 100644 --- a/src/libostree/ostree-sysroot-deploy.c +++ b/src/libostree/ostree-sysroot-deploy.c @@ -2632,6 +2632,39 @@ _ostree_deployment_set_bootconfig_from_kargs (OstreeDeployment *deployment, } } +// Perform some basic static analysis and emit warnings for things +// that are likely to fail later. This function only returns +// a hard error if something unexpected (e.g. I/O error) occurs. +static gboolean +lint_deployment_fs (OstreeSysroot *self, + OstreeDeployment *deployment, + int deployment_dfd, + GCancellable *cancellable, + GError **error) +{ + g_auto(GLnxDirFdIterator) dfd_iter = { 0, }; + glnx_autofd int dest_dfd = -1; + gboolean exists; + + if (!ot_dfd_iter_init_allow_noent (deployment_dfd, "var", &dfd_iter, &exists, error)) + return FALSE; + while (exists) + { + struct dirent *dent; + + if (!glnx_dirfd_iterator_next_dent (&dfd_iter, &dent, cancellable, error)) + return FALSE; + if (dent == NULL) + break; + + fprintf (stderr, "note: Deploying commit %s which contains content in /var/%s that will be ignored.\n", + ostree_deployment_get_csum (deployment), + dent->d_name); + } + + return TRUE; +} + /* The first part of writing a deployment. This primarily means doing the * hardlink farm checkout, but we also compute some initial state. */ @@ -2680,6 +2713,9 @@ sysroot_initialize_deployment (OstreeSysroot *self, cancellable, error)) return FALSE; + if (!lint_deployment_fs (self, new_deployment, deployment_dfd, cancellable, error)) + return FALSE; + ot_transfer_out_value (out_new_deployment, &new_deployment); return TRUE; } diff --git a/tests/kolainst/destructive/deployment-lint b/tests/kolainst/destructive/deployment-lint new file mode 100755 index 00000000..6981ebbc --- /dev/null +++ b/tests/kolainst/destructive/deployment-lint @@ -0,0 +1,13 @@ +#!/bin/bash +set -xeuo pipefail + +. ${KOLA_EXT_DATA}/libinsttest.sh + +require_writable_sysroot +prepare_tmpdir + +mkdir -p rootfs/var/shouldntdothis/subdir +ostree commit -b testlint --no-bindings --selinux-policy-from-base --tree=ref="${host_refspec}" --consume --tree=dir=rootfs +ostree admin deploy testlint 2>err.txt +assert_file_has_content err.txt 'Deploying commit.*which contains content in /var/shouldntdothis' +echo "ok content in /var"