core/scripts: Support /var/lib/rpm-state

I was trying a `--ex-unified-core` compose of FAW, and things fell over
on `urw-base35-fonts` which does a dance of setting a stamp file in
`%post` and checking it in `%posttrans`.

This whole pattern should be considered deprecated by file triggers. But let's
support it for now.

Note there's a lot of parameter passing as we need a single directory which is
held across multiple script invocations.

Closes: #1319
Approved by: jlebon
This commit is contained in:
Colin Walters 2018-03-27 17:14:56 -04:00 committed by Atomic Bot
parent f05b980094
commit defa1dc38a
5 changed files with 52 additions and 10 deletions

View File

@ -21,6 +21,7 @@ for src in lib{,32,64} bin sbin; do
BWRAP_ARGV="$BWRAP_ARGV --symlink usr/$src $src"
fi
done
BWRAP_ARGV="$BWRAP_ARGV --ro-bind usr /usr --ro-bind ./var /var --bind ./usr/etc /etc --tmpfs /var/tmp"
BWRAP_ARGV="$BWRAP_ARGV --ro-bind usr /usr --ro-bind ./var /var --bind ./usr/etc /etc \
--tmpfs /var/tmp --tmpfs /var/lib/rpm-state"
echo exec bwrap $BWRAP_ARGV "$@"
exec env PS1='bwrap$ ' bwrap $BWRAP_ARGV "$@"

View File

@ -3232,6 +3232,7 @@ rpmts_add_erase (RpmOstreeContext *self,
static gboolean
run_script_sync (RpmOstreeContext *self,
int rootfs_dfd,
GLnxTmpDir *var_lib_rpm_statedir,
DnfPackage *pkg,
RpmOstreeScriptKind kind,
guint *out_n_run,
@ -3244,7 +3245,7 @@ run_script_sync (RpmOstreeContext *self,
if (!get_package_metainfo (self, path, &hdr, NULL, error))
return FALSE;
if (!rpmostree_script_run_sync (pkg, hdr, kind, rootfs_dfd,
if (!rpmostree_script_run_sync (pkg, hdr, kind, rootfs_dfd, var_lib_rpm_statedir,
out_n_run, cancellable, error))
return FALSE;
@ -3834,6 +3835,11 @@ rpmostree_context_assemble (RpmOstreeContext *self,
if (!rpmostree_rootfs_fixup_selinux_store_root (tmprootfs_dfd, cancellable, error))
return FALSE;
g_auto(GLnxTmpDir) var_lib_rpm_statedir = { 0, };
if (!glnx_mkdtempat (AT_FDCWD, "/tmp/rpmostree-state.XXXXXX", 0700,
&var_lib_rpm_statedir, error))
return FALSE;
/* We're technically deviating from RPM here by running all the %pre's
* beforehand, rather than each package's %pre & %post in order. Though I
* highly doubt this should cause any issues. The advantage of doing it
@ -3851,7 +3857,8 @@ rpmostree_context_assemble (RpmOstreeContext *self,
DnfPackage *pkg = (void*)rpmteKey (te);
g_assert (pkg);
if (!run_script_sync (self, tmprootfs_dfd, pkg, RPMOSTREE_SCRIPT_PREIN,
if (!run_script_sync (self, tmprootfs_dfd, &var_lib_rpm_statedir,
pkg, RPMOSTREE_SCRIPT_PREIN,
&n_pre_scripts_run, cancellable, error))
return FALSE;
}
@ -3907,7 +3914,8 @@ rpmostree_context_assemble (RpmOstreeContext *self,
return glnx_prefix_error (error, "While applying overrides for pkg %s",
dnf_package_get_name (pkg));
if (!run_script_sync (self, tmprootfs_dfd, pkg, RPMOSTREE_SCRIPT_POSTIN,
if (!run_script_sync (self, tmprootfs_dfd, &var_lib_rpm_statedir,
pkg, RPMOSTREE_SCRIPT_POSTIN,
&n_post_scripts_run, cancellable, error))
return FALSE;
}
@ -3922,7 +3930,8 @@ rpmostree_context_assemble (RpmOstreeContext *self,
DnfPackage *pkg = (void*)rpmteKey (te);
g_assert (pkg);
if (!run_script_sync (self, tmprootfs_dfd, pkg, RPMOSTREE_SCRIPT_POSTTRANS,
if (!run_script_sync (self, tmprootfs_dfd, &var_lib_rpm_statedir,
pkg, RPMOSTREE_SCRIPT_POSTTRANS,
&n_post_scripts_run, cancellable, error))
return FALSE;
}

View File

@ -274,6 +274,7 @@ dump_buffered_output_noerr (const char *prefix,
*/
static gboolean
run_script_in_bwrap_container (int rootfs_fd,
GLnxTmpDir *var_lib_rpm_statedir,
const char *name,
const char *scriptdesc,
const char *interp,
@ -290,6 +291,7 @@ run_script_in_bwrap_container (int rootfs_fd,
const char *postscript_path_host = postscript_path_container + 1;
g_autoptr(RpmOstreeBwrap) bwrap = NULL;
gboolean created_var_tmp = FALSE;
gboolean created_var_lib_rpmstate = FALSE;
glnx_autofd int stdout_fd = -1;
glnx_autofd int stderr_fd = -1;
@ -328,11 +330,29 @@ run_script_in_bwrap_container (int rootfs_fd,
else
created_var_tmp = TRUE;
/* And similarly for /var/lib/rpm-state */
if (var_lib_rpm_statedir)
{
if (mkdirat (rootfs_fd, "var/lib/rpm-state", 0755) < 0)
{
if (errno == EEXIST)
;
else
{
glnx_set_error_from_errno (error);
goto out;
}
}
else
created_var_lib_rpmstate = TRUE;
}
/* ⚠⚠⚠ If you change this, also update scripts/bwrap-script-shell.sh ⚠⚠⚠ */
/* We just did a ro bind mount over /var above. However we want a writable
* var/tmp, so we need to tmpfs mount on top of it. See also
* https://github.com/projectatomic/bubblewrap/issues/182
* Similarly for /var/lib/rpm-state.
*
* See above for why we special case glibc.
*/
@ -347,6 +367,9 @@ run_script_in_bwrap_container (int rootfs_fd,
if (!bwrap)
goto out;
if (var_lib_rpm_statedir)
rpmostree_bwrap_append_bwrap_argv (bwrap, "--bind", var_lib_rpm_statedir->path, "/var/lib/rpm-state", NULL);
const gboolean debugging_script = g_strcmp0 (g_getenv ("RPMOSTREE_SCRIPT_DEBUG"), pkg_script) == 0;
/* https://github.com/systemd/systemd/pull/7631 AKA
@ -431,6 +454,8 @@ run_script_in_bwrap_container (int rootfs_fd,
(void) unlinkat (rootfs_fd, postscript_path_host, 0);
if (created_var_tmp)
(void) unlinkat (rootfs_fd, "var/tmp", AT_REMOVEDIR);
if (created_var_lib_rpmstate)
(void) unlinkat (rootfs_fd, "var/lib/rpm-state", AT_REMOVEDIR);
return ret;
}
@ -443,6 +468,7 @@ impl_run_rpm_script (const KnownRpmScriptKind *rpmscript,
DnfPackage *pkg,
Header hdr,
int rootfs_fd,
GLnxTmpDir *var_lib_rpm_statedir,
GCancellable *cancellable,
GError **error)
{
@ -511,7 +537,7 @@ impl_run_rpm_script (const KnownRpmScriptKind *rpmscript,
}
guint64 start_time_ms = g_get_monotonic_time () / 1000;
if (!run_script_in_bwrap_container (rootfs_fd, dnf_package_get_name (pkg),
if (!run_script_in_bwrap_container (rootfs_fd, var_lib_rpm_statedir, dnf_package_get_name (pkg),
rpmscript->desc, interp, script, script_arg,
-1, cancellable, error))
return glnx_prefix_error (error, "Running %s for %s", rpmscript->desc, dnf_package_get_name (pkg));
@ -536,6 +562,7 @@ run_script (const KnownRpmScriptKind *rpmscript,
DnfPackage *pkg,
Header hdr,
int rootfs_fd,
GLnxTmpDir *var_lib_rpm_statedir,
gboolean *out_did_run,
GCancellable *cancellable,
GError **error)
@ -563,7 +590,7 @@ run_script (const KnownRpmScriptKind *rpmscript,
}
*out_did_run = TRUE;
return impl_run_rpm_script (rpmscript, pkg, hdr, rootfs_fd,
return impl_run_rpm_script (rpmscript, pkg, hdr, rootfs_fd, var_lib_rpm_statedir,
cancellable, error);
}
@ -683,6 +710,7 @@ rpmostree_script_run_sync (DnfPackage *pkg,
Header hdr,
RpmOstreeScriptKind kind,
int rootfs_fd,
GLnxTmpDir *var_lib_rpm_statedir,
guint *out_n_run,
GCancellable *cancellable,
GError **error)
@ -705,6 +733,7 @@ rpmostree_script_run_sync (DnfPackage *pkg,
gboolean did_run = FALSE;
if (!run_script (scriptkind, pkg, hdr, rootfs_fd,
var_lib_rpm_statedir,
&did_run, cancellable, error))
return FALSE;
@ -873,7 +902,7 @@ rpmostree_transfiletriggers_run_sync (Header hdr,
/* Run it, and log the result */
guint64 start_time_ms = g_get_monotonic_time () / 1000;
if (!run_script_in_bwrap_container (rootfs_fd, pkg_name,
if (!run_script_in_bwrap_container (rootfs_fd, NULL, pkg_name,
"%transfiletriggerin", interp, script, NULL,
fileno (tmpf_file), cancellable, error))
return FALSE;

View File

@ -62,6 +62,7 @@ rpmostree_script_run_sync (DnfPackage *pkg,
Header hdr,
RpmOstreeScriptKind kind,
int rootfs_fd,
GLnxTmpDir *var_lib_rpm_statedir,
guint *out_n_run,
GCancellable *cancellable,
GError **error);

View File

@ -36,7 +36,8 @@ vm_build_rpm scriptpkg1 \
echo pretrans should've been ignored && exit 1" \
verifyscript "echo verifyscript should've been ignored && exit 1" \
post_args "-p /usr/bin/python" \
post 'open("/usr/lib/rpmostreetestinterp", "w")' \
post 'open("/usr/lib/rpmostreetestinterp", "w").close();
open("/var/lib/rpm-state/scriptpkg1-stamp", "w").close()' \
posttrans "# Firewalld; https://github.com/projectatomic/rpm-ostree/issues/638
. /etc/os-release || :
# See https://github.com/projectatomic/rpm-ostree/pull/647
@ -45,7 +46,8 @@ vm_build_rpm scriptpkg1 \
echo found file from host /tmp
exit 1
fi
done"
done;
test -f /var/lib/rpm-state/scriptpkg1-stamp"
# check that host /tmp doesn't get mounted
vm_cmd touch /tmp/file-in-host-tmp-not-for-scripts