Skip to content

Commit

Permalink
WIP: Add rpm-ostree compose container command
Browse files Browse the repository at this point in the history
This command takes a *derivation* treefile and applies necessary changes
to the live container to make it true.

Currently, only `packages` is supported. But this paves the way for
supporting more derivation fields as well as making currently "base"
fields only become valid derivation fields too (by promoting it from the
`BaseComposeConfigFields` struct to `TreeComposeConfig`).

I think this also helps the move towards coreos#2326 by formalizing "client"
or "derivation" treefiles more and introducing code which consumes them.

What we're doing here is providing a "container" backend for derivation
treefiles, but coreos#2326 will provide a "client" backend which uses the core
more fully. But the input file itself is the exact same, hence providing
symmetry between the two flows. (See also discussions about this in
coreos/fedora-coreos-tracker#1054).

This will also allow us to drop the `microdnf` dependency, though I
haven't yet done that.
  • Loading branch information
jlebon committed Jan 18, 2022
1 parent 4686b5a commit 2524f40
Show file tree
Hide file tree
Showing 3 changed files with 97 additions and 0 deletions.
6 changes: 6 additions & 0 deletions src/app/rpmostree-builtin-compose.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,12 @@ static RpmOstreeCommand compose_subcommands[] = {
{ "extensions", RPM_OSTREE_BUILTIN_FLAG_LOCAL_CMD,
"Download RPM packages guaranteed to depsolve with a base OSTree",
rpmostree_compose_builtin_extensions },
{ "container", (RpmOstreeBuiltinFlags)
(RPM_OSTREE_BUILTIN_FLAG_LOCAL_CMD |
RPM_OSTREE_BUILTIN_FLAG_HIDDEN |
RPM_OSTREE_BUILTIN_FLAG_REQUIRES_ROOT),
"Compose container from derivation treefile",
rpmostree_compose_builtin_container },
{ NULL, (RpmOstreeBuiltinFlags)0, NULL, NULL }
};

Expand Down
90 changes: 90 additions & 0 deletions src/app/rpmostree-compose-builtin-tree.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -1661,3 +1661,93 @@ rpmostree_compose_builtin_extensions (int argc,

return TRUE;
}

static void
state_action_changed_cb (DnfState *state,
DnfStateAction action,
const gchar *action_hint)
{
switch (action)
{
case DNF_STATE_ACTION_INSTALL:
if (action_hint)
{
g_auto(GStrv) split = g_strsplit (action_hint, ";", 0);
if (g_strv_length (split) == 4)
g_print ("Installing: %s-%s.%s (%s)\n", split[0], split[1], split[2], split[3]);
else
g_print ("Installing: %s\n", action_hint);
}
break;
default:
break;
}
}

gboolean
rpmostree_compose_builtin_container (int argc,
char **argv,
RpmOstreeCommandInvocation *invocation,
GCancellable *cancellable,
GError **error)
{
g_printerr ("NOTICE: This command is experimental and subject to change.\n");
g_autoptr(GOptionContext) context = g_option_context_new ("TREEFILE");

if (!rpmostree_option_context_parse (context,
NULL,
&argc, &argv,
invocation,
cancellable,
NULL, NULL, NULL,
error))
return FALSE;

/* In practice, nothing stops us from running in a regular container today.
* But in the future we'll likely have more binding between OSTree container
* peculiarities and this code. And we don't want to support more than we need
* to.*/
auto is_ostree_container = CXX_TRY_VAL(is_ostree_container(), error);
if (!is_ostree_container)
return glnx_throw (error, "This command can only run in an OSTree container.");

if (argc < 2)
{
rpmostree_usage_error (context, "TREEFILE must be specified", error);
return FALSE;
}

const char *treefile_path = argv[1];
auto basearch = rpmostreecxx::get_rpm_basearch();
auto treefile = CXX_TRY_VAL(treefile_new_client (treefile_path, basearch, -1), error);
auto packages = treefile->get_packages();

/* for now, we only support package installs */
if (packages.empty())
return TRUE;

g_autoptr(RpmOstreeContext) ctx = rpmostree_context_new_container ();
rpmostree_context_set_treefile (ctx, *treefile);

if (!rpmostree_context_setup (ctx, "/", "/", cancellable, error))
return FALSE;

if (!rpmostree_context_prepare (ctx, cancellable, error))
return FALSE;

if (!rpmostree_context_download (ctx, cancellable, error))
return FALSE;

DnfContext *dnfctx = rpmostree_context_get_dnf (ctx);
DnfState *state = dnf_context_get_state (dnfctx);
g_signal_connect (state, "action-changed",
G_CALLBACK (state_action_changed_cb),
NULL);

/* can't use cancellable here because it wants to re-set it on the state,
* which will trigger an assertion; XXX: tweak libdnf */
if (!dnf_context_run (dnfctx, NULL, error))
return FALSE;

return TRUE;
}
1 change: 1 addition & 0 deletions src/app/rpmostree-compose-builtins.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ gboolean rpmostree_compose_builtin_install (int argc, char **argv, RpmOstreeComm
gboolean rpmostree_compose_builtin_postprocess (int argc, char **argv, RpmOstreeCommandInvocation *invocation, GCancellable *cancellable, GError **error);
gboolean rpmostree_compose_builtin_commit (int argc, char **argv, RpmOstreeCommandInvocation *invocation, GCancellable *cancellable, GError **error);
gboolean rpmostree_compose_builtin_extensions (int argc, char **argv, RpmOstreeCommandInvocation *invocation, GCancellable *cancellable, GError **error);
gboolean rpmostree_compose_builtin_container (int argc, char **argv, RpmOstreeCommandInvocation *invocation, GCancellable *cancellable, GError **error);

G_END_DECLS

0 comments on commit 2524f40

Please sign in to comment.