Skip to content

Commit

Permalink
core: Run %post before %posttrans
Browse files Browse the repository at this point in the history
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
  • Loading branch information
cgwalters authored and rh-atomic-bot committed Aug 30, 2017
1 parent 4cbdcf9 commit 3047513
Show file tree
Hide file tree
Showing 4 changed files with 97 additions and 100 deletions.
67 changes: 33 additions & 34 deletions src/libpriv/rpmostree-core.c
Expand Up @@ -2435,43 +2435,26 @@ 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)
{
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_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)
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);

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;
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -3002,26 +2985,42 @@ 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);
if (rpmteType (te) != TR_ADDED)
continue;

DnfPackage *pkg = (void*)rpmteKey (te);

g_assert (pkg);

if (!apply_rpmfi_overrides (self, tmprootfs_dfd, pkg, passwdents, groupents,
cancellable, error))
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;
Expand Down
87 changes: 35 additions & 52 deletions src/libpriv/rpmostree-scripts.c
Expand Up @@ -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,
Expand Down Expand Up @@ -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;
case RPMOSTREE_SCRIPT_PREIN:
scriptkind = &pre_script;
break;
case RPMOSTREE_SCRIPT_POSTIN:
scriptkind = &post_script;
break;
case RPMOSTREE_SCRIPT_POSTTRANS:
scriptkind = &posttrans_script;
break;
}

if (!run_script (&posttrans_scripts[i], pkg, hdr, rootfs_fd,
&did_run, cancellable, error))
return FALSE;
gboolean did_run = FALSE;
if (!run_script (scriptkind, pkg, hdr, rootfs_fd,
&did_run, cancellable, error))
return FALSE;

if (did_run)
(*out_n_run)++;
}
if (did_run)
(*out_n_run)++;
return TRUE;
}

Expand Down Expand Up @@ -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
*
Expand Down
27 changes: 13 additions & 14 deletions src/libpriv/rpmostree-scripts.h
Expand Up @@ -45,19 +45,26 @@ 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,
GCancellable *cancellable,
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,
Expand All @@ -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,
Expand Down
16 changes: 16 additions & 0 deletions tests/vmcheck/test-layering-scripts.sh
Expand Up @@ -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'
Expand Down

0 comments on commit 3047513

Please sign in to comment.