Skip to content

Commit

Permalink
app/override: Factor out function to sort override args
Browse files Browse the repository at this point in the history
It was getting cramped in there. Let's split it out so it's easier to
follow.

Mostly a mechanical change.
  • Loading branch information
jlebon committed Jun 17, 2022
1 parent 4f18ee3 commit 2abbb85
Showing 1 changed file with 64 additions and 46 deletions.
110 changes: 64 additions & 46 deletions src/app/rpmostree-override-builtins.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include "config.h"

#include "rpmostree-container.h"
#include "rpmostree-core.h"
#include "rpmostree-libbuiltin.h"
#include "rpmostree-override-builtins.h"

Expand Down Expand Up @@ -70,6 +71,60 @@ static GOptionEntry remove_option_entries[] = { { "replace", 0, 0, G_OPTION_ARG_
&opt_replace_pkgs, "Replace a package", "RPM" },
{ NULL } };

static gboolean
sort_replacements (RPMOSTreeOSExperimental *osexperimental_proxy,
const char *const *replacement_args, char ***out_local,
GUnixFDList **out_fd_list, GCancellable *cancellable, GError **error)
{
g_autoptr (GPtrArray) local = g_ptr_array_new_with_free_func (g_free);
g_autoptr (GPtrArray) freeze = g_ptr_array_new_with_free_func (g_free);
for (const char *const *it = replacement_args; it && *it; it++)
{
auto arg = *it;
if (rpmostreecxx::is_http_arg (arg) || rpmostreecxx::is_rpm_arg (arg))
{
g_ptr_array_add (local, (gpointer)g_strdup (arg));
}
// if the pkg is a valid nevra, then treat it as frozen
else if (opt_freeze || rpmostree_is_valid_nevra (arg))
{
g_ptr_array_add (freeze, (gpointer)g_strdup (arg));
}
else
{
glnx_throw (error, "Remote overrides are not supported yet on the CLI");
}
}

g_autoptr (GUnixFDList) fd_list = NULL;
if (freeze->len > 0)
{
g_ptr_array_add (freeze, NULL);

/* this is really just a D-Bus wrapper around `rpmostree_find_and_download_packages` */
if (!rpmostree_osexperimental_call_download_packages_sync (
osexperimental_proxy, (const char *const *)freeze->pdata, opt_from, NULL, &fd_list,
cancellable, error))
return FALSE;

int nfds;
const int *fds = g_unix_fd_list_peek_fds (fd_list, &nfds);
for (guint i = 0; i < nfds; i++)
g_ptr_array_add (local, g_strdup_printf ("file:///proc/self/fd/%d", fds[i]));
}

if (local->len > 0)
{
g_ptr_array_add (local, NULL);
*out_local = (char **)g_ptr_array_free (util::move_nullify (local), FALSE);
}
else
*out_local = NULL;

*out_fd_list = util::move_nullify (fd_list);
return TRUE;
}

static gboolean
handle_override (RPMOSTreeSysroot *sysroot_proxy, RpmOstreeCommandInvocation *invocation,
const char *const *override_remove, const char *const *override_replace,
Expand All @@ -81,58 +136,21 @@ handle_override (RPMOSTreeSysroot *sysroot_proxy, RpmOstreeCommandInvocation *in
&osexperimental_proxy, error))
return FALSE;

g_autoptr (GUnixFDList) fetched_rpms_fds = NULL;
g_autoptr (GPtrArray) override_replace_final = NULL;

if (!opt_experimental && (opt_freeze || opt_from))
return glnx_throw (error, "Must specify --experimental to use --freeze or --from");

g_autoptr (GUnixFDList) fd_list = NULL; /* this is just used to own the fds */

/* By default, we assume all the args are local overrides. If --from is used, we have to sort them
* first to handle --freeze and (eventually) remote overrides. */
g_auto (GStrv) override_replace_local = NULL;
if (override_replace && opt_from)
{
override_replace_final = g_ptr_array_new_with_free_func (free);
g_autoptr (GPtrArray) queries = g_ptr_array_new ();

for (const char *const *it = override_replace; it && *it; it++)
{
auto pkg = *it;

if (rpmostreecxx::is_http_arg (pkg) || rpmostreecxx::is_rpm_arg (pkg))
{
g_ptr_array_add (override_replace_final, (gpointer)g_strdup (pkg));
}
// if the pkg is a valid nevra, then treat it as frozen
else if (opt_freeze || rpmostree_is_valid_nevra (pkg))
{
g_ptr_array_add (queries, (gpointer)pkg);
}
else
{
return glnx_throw (error, "CLI remote overrides not supported yet");
}
}
if (queries->len > 0)
{
g_ptr_array_add (queries, NULL);
if (!sort_replacements (osexperimental_proxy, override_replace, &override_replace_local,
&fd_list, cancellable, error))
return FALSE;

if (!rpmostree_osexperimental_call_download_packages_sync (
osexperimental_proxy, (const char *const *)queries->pdata, opt_from, NULL,
&fetched_rpms_fds, cancellable, error))
return FALSE;

const int nfds = fetched_rpms_fds ? g_unix_fd_list_get_length (fetched_rpms_fds) : 0;
g_assert_cmpuint (nfds, >, 0);

for (guint i = 0; i < nfds; i++)
{
gint fd = g_unix_fd_list_get (fetched_rpms_fds, i, error);
if (fd < 0)
return FALSE;
g_ptr_array_add (override_replace_final,
g_strdup_printf ("file:///proc/self/fd/%d", fd));
}
g_ptr_array_add (override_replace_final, NULL);
override_replace = (const char *const *)override_replace_final->pdata;
}
override_replace = override_replace_local;
}

/* Perform uninstalls offline; users don't expect the "auto-update" behaviour here. But
Expand Down

0 comments on commit 2abbb85

Please sign in to comment.