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:
parent
f05b980094
commit
defa1dc38a
@ -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 "$@"
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user