core: Run %post before %posttrans

While working on unified core and the Fedora Atomic Host content set, I hit a
dependency between `docker.posttrans` which tries to read `/etc/os-release`, and
`fedora-release-atomichost.post` which creates that symlink.

It seems best practice to me to run `%post`s strictly before
`%posttrans`; we're not likely to do parallelization anytime
soon anyways.

While here I cleaned things up by having an enum for the script kind,
rather than multiple functions, otherwise we would have had another
wrapper in core.c.

Closes: #963
Approved by: jlebon
This commit is contained in:
Colin Walters 2017-08-30 07:16:46 -04:00 committed by Atomic Bot
parent 4cbdcf93c8
commit 3047513509
4 changed files with 98 additions and 101 deletions

View File

@ -2435,13 +2435,17 @@ rpmts_add_erase (RpmOstreeContext *self,
return TRUE;
}
/* Look up the header for a package, and pass it
* to the script core to execute.
*/
static gboolean
run_posttrans_sync (RpmOstreeContext *self,
int rootfs_dfd,
DnfPackage *pkg,
guint *out_n_run,
GCancellable *cancellable,
GError **error)
run_script_sync (RpmOstreeContext *self,
int rootfs_dfd,
DnfPackage *pkg,
RpmOstreeScriptKind kind,
guint *out_n_run,
GCancellable *cancellable,
GError **error)
{
g_auto(Header) hdr = NULL;
g_autofree char *path = get_package_relpath (pkg);
@ -2449,29 +2453,8 @@ run_posttrans_sync (RpmOstreeContext *self,
if (!get_package_metainfo (self, path, &hdr, NULL, error))
return FALSE;
if (!rpmostree_posttrans_run_sync (pkg, hdr, rootfs_dfd,
out_n_run, cancellable, error))
return FALSE;
return TRUE;
}
static gboolean
run_pre_sync (RpmOstreeContext *self,
int rootfs_dfd,
DnfPackage *pkg,
guint *out_n_run,
GCancellable *cancellable,
GError **error)
{
g_auto(Header) hdr = NULL;
g_autofree char *path = get_package_relpath (pkg);
if (!get_package_metainfo (self, path, &hdr, NULL, error))
return FALSE;
if (!rpmostree_pre_run_sync (pkg, hdr, rootfs_dfd,
out_n_run, cancellable, error))
if (!rpmostree_script_run_sync (pkg, hdr, kind, rootfs_dfd,
out_n_run, cancellable, error))
return FALSE;
return TRUE;
@ -2959,8 +2942,8 @@ rpmostree_context_assemble_tmprootfs (RpmOstreeContext *self,
DnfPackage *pkg = (void*)rpmteKey (te);
g_assert (pkg);
if (!run_pre_sync (self, tmprootfs_dfd, pkg,
&n_pre_scripts_run, cancellable, error))
if (!run_script_sync (self, tmprootfs_dfd, pkg, RPMOSTREE_SCRIPT_PREIN,
&n_pre_scripts_run, cancellable, error))
return FALSE;
}
rpmostree_output_task_end ("%u done", n_pre_scripts_run);
@ -3002,6 +2985,7 @@ rpmostree_context_assemble_tmprootfs (RpmOstreeContext *self,
rpmostree_output_task_begin ("Running post scripts");
guint n_post_scripts_run = 0;
/* %post */
for (guint i = 0; i < n_rpmts_elements; i++)
{
rpmte te = rpmtsElement (ordering_ts, i);
@ -3009,7 +2993,6 @@ rpmostree_context_assemble_tmprootfs (RpmOstreeContext *self,
continue;
DnfPackage *pkg = (void*)rpmteKey (te);
g_assert (pkg);
if (!apply_rpmfi_overrides (self, tmprootfs_dfd, pkg, passwdents, groupents,
@ -3017,11 +3000,27 @@ rpmostree_context_assemble_tmprootfs (RpmOstreeContext *self,
return glnx_prefix_error (error, "While applying overrides for pkg %s",
dnf_package_get_name (pkg));
if (!run_posttrans_sync (self, tmprootfs_dfd, pkg,
&n_post_scripts_run, cancellable, error))
if (!run_script_sync (self, tmprootfs_dfd, pkg, RPMOSTREE_SCRIPT_POSTIN,
&n_post_scripts_run, cancellable, error))
return FALSE;
}
/* %posttrans */
for (guint i = 0; i < n_rpmts_elements; i++)
{
rpmte te = rpmtsElement (ordering_ts, i);
if (rpmteType (te) != TR_ADDED)
continue;
DnfPackage *pkg = (void*)rpmteKey (te);
g_assert (pkg);
if (!run_script_sync (self, tmprootfs_dfd, pkg, RPMOSTREE_SCRIPT_POSTTRANS,
&n_post_scripts_run, cancellable, error))
return FALSE;
}
/* file triggers */
if (!run_all_transfiletriggers (self, ordering_ts, tmprootfs_dfd,
&n_post_scripts_run, cancellable, error))
return FALSE;

View File

@ -72,18 +72,13 @@ static const KnownRpmScriptKind ignored_scripts[] = {
};
#endif
static const KnownRpmScriptKind pre_scripts[] = {
{ "%prein", 0,
RPMTAG_PREIN, RPMTAG_PREINPROG, RPMTAG_PREINFLAGS },
};
static const KnownRpmScriptKind posttrans_scripts[] = {
/* For now, we treat %post as equivalent to %posttrans */
{ "%post", 0,
RPMTAG_POSTIN, RPMTAG_POSTINPROG, RPMTAG_POSTINFLAGS },
{ "%posttrans", 0,
RPMTAG_POSTTRANS, RPMTAG_POSTTRANSPROG, RPMTAG_POSTTRANSFLAGS },
};
/* Supported script types */
static const KnownRpmScriptKind pre_script =
{ "%prein", 0, RPMTAG_PREIN, RPMTAG_PREINPROG, RPMTAG_PREINFLAGS };
static const KnownRpmScriptKind post_script =
{ "%post", 0, RPMTAG_POSTIN, RPMTAG_POSTINPROG, RPMTAG_POSTINFLAGS };
static const KnownRpmScriptKind posttrans_script =
{ "%posttrans", 0, RPMTAG_POSTTRANS, RPMTAG_POSTTRANSPROG, RPMTAG_POSTTRANSFLAGS };
static const KnownRpmScriptKind unsupported_scripts[] = {
{ "%triggerprein", RPMSENSE_TRIGGERPREIN,
@ -469,27 +464,39 @@ find_and_write_matching_files (int rootfs_fd, const char *pattern,
}
#endif
/* Execute all post/post-transaction scripts for @pkg */
/* Execute a supported script. Note that @cancellable
* does not currently kill a running script subprocess.
*/
gboolean
rpmostree_posttrans_run_sync (DnfPackage *pkg,
Header hdr,
int rootfs_fd,
guint *out_n_run,
GCancellable *cancellable,
GError **error)
rpmostree_script_run_sync (DnfPackage *pkg,
Header hdr,
RpmOstreeScriptKind kind,
int rootfs_fd,
guint *out_n_run,
GCancellable *cancellable,
GError **error)
{
/* We treat %post and %posttrans equivalently, so do those in one go */
for (guint i = 0; i < G_N_ELEMENTS (posttrans_scripts); i++)
const KnownRpmScriptKind *scriptkind;
switch (kind)
{
gboolean did_run = FALSE;
if (!run_script (&posttrans_scripts[i], pkg, hdr, rootfs_fd,
&did_run, cancellable, error))
return FALSE;
if (did_run)
(*out_n_run)++;
case RPMOSTREE_SCRIPT_PREIN:
scriptkind = &pre_script;
break;
case RPMOSTREE_SCRIPT_POSTIN:
scriptkind = &post_script;
break;
case RPMOSTREE_SCRIPT_POSTTRANS:
scriptkind = &posttrans_script;
break;
}
gboolean did_run = FALSE;
if (!run_script (scriptkind, pkg, hdr, rootfs_fd,
&did_run, cancellable, error))
return FALSE;
if (did_run)
(*out_n_run)++;
return TRUE;
}
@ -675,30 +682,6 @@ rpmostree_transfiletriggers_run_sync (Header hdr,
return TRUE;
}
/* Execute all pre-install scripts for @pkg */
gboolean
rpmostree_pre_run_sync (DnfPackage *pkg,
Header hdr,
int rootfs_fd,
guint *out_n_run,
GCancellable *cancellable,
GError **error)
{
for (guint i = 0; i < G_N_ELEMENTS (pre_scripts); i++)
{
gboolean did_run = FALSE;
if (!run_script (&pre_scripts[i], pkg, hdr, rootfs_fd,
&did_run, cancellable, error))
return FALSE;
if (did_run)
(*out_n_run)++;
}
return TRUE;
}
/* Ensure that we can at least execute /usr/bin/true inside the new root.
* See https://github.com/projectatomic/rpm-ostree/pull/888
*

View File

@ -45,6 +45,12 @@ struct RpmOstreePackageScriptHandler {
const struct RpmOstreePackageScriptHandler* rpmostree_script_gperf_lookup(const char *key, GPERF_LEN_TYPE length);
typedef enum {
RPMOSTREE_SCRIPT_PREIN,
RPMOSTREE_SCRIPT_POSTIN,
RPMOSTREE_SCRIPT_POSTTRANS,
} RpmOstreeScriptKind;
gboolean
rpmostree_script_txn_validate (DnfPackage *package,
Header hdr,
@ -52,12 +58,13 @@ rpmostree_script_txn_validate (DnfPackage *package,
GError **error);
gboolean
rpmostree_posttrans_run_sync (DnfPackage *pkg,
Header hdr,
int rootfs_fd,
guint *out_n_run,
GCancellable *cancellable,
GError **error);
rpmostree_script_run_sync (DnfPackage *pkg,
Header hdr,
RpmOstreeScriptKind kind,
int rootfs_fd,
guint *out_n_run,
GCancellable *cancellable,
GError **error);
gboolean
rpmostree_transfiletriggers_run_sync (Header hdr,
@ -66,14 +73,6 @@ rpmostree_transfiletriggers_run_sync (Header hdr,
GCancellable *cancellable,
GError **error);
gboolean
rpmostree_pre_run_sync (DnfPackage *pkg,
Header hdr,
int rootfs_fd,
guint *out_n_run,
GCancellable *cancellable,
GError **error);
gboolean
rpmostree_deployment_sanitycheck (int rootfs_fd,
GCancellable *cancellable,

View File

@ -63,7 +63,23 @@ echo "ok group scriptpkg1 active"
vm_has_files "/usr/lib/rpmostreetestinterp"
echo "ok interp"
# cleanup
vm_rpmostree uninstall scriptpkg1
vm_reboot
# post ordering
vm_build_rpm postorder1 \
post 'touch /usr/share/postorder1.post' \
posttrans 'test -f /usr/share/postorder1.post && test -f /usr/share/postorder2.post'
vm_build_rpm postorder2 \
requires 'postorder1' \
post 'touch /usr/share/postorder2.post' \
posttrans 'test -f /usr/share/postorder1.post && test -f /usr/share/postorder2.post'
vm_rpmostree install postorder{1,2}
vm_rpmostree cleanup -p
echo "ok post ordering"
# script expansion
vm_build_rpm scriptpkg2 \
post_args "-e" \
post 'echo %%{_prefix} > /usr/lib/prefixtest.txt'