Skip to content

Commit

Permalink
app: add 'makecache' command
Browse files Browse the repository at this point in the history
This is essentially the `dnf`/`yum` equivalent for rpm-ostree. To
complete the picture, we're missing the `-C` equivalent as well for all
the commands that make use of this metadata. Though `makecache` on its
own should be particularly helpful in test environment provisioning
where one may have cached metadata available to inject and just wants
rpm-ostree to sanity check it.
  • Loading branch information
jlebon committed Oct 4, 2017
1 parent cafe89c commit b1d4ec3
Show file tree
Hide file tree
Showing 14 changed files with 325 additions and 32 deletions.
1 change: 1 addition & 0 deletions Makefile-rpm-ostree.am
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ rpm_ostree_SOURCES = src/app/main.c \
src/app/rpmostree-builtin-initramfs.c \
src/app/rpmostree-builtin-livefs.c \
src/app/rpmostree-builtin-override.c \
src/app/rpmostree-builtin-makecache.c \
src/app/rpmostree-pkg-builtins.c \
src/app/rpmostree-builtin-status.c \
src/app/rpmostree-builtin-ex.c \
Expand Down
11 changes: 11 additions & 0 deletions man/rpm-ostree.xml
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,17 @@ Boston, MA 02111-1307, USA.
</listitem>
</varlistentry>

<varlistentry>
<term><command>makecache</command></term>

<listitem>
<para>
Download the latest rpm repo metadata if necessary and generate the
cache.
</para>
</listitem>
</varlistentry>

<varlistentry>
<term><command>cleanup</command></term>

Expand Down
3 changes: 3 additions & 0 deletions src/app/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,9 @@ static RpmOstreeCommand commands[] = {
{ "uninstall", 0,
"Remove one or more overlay packages",
rpmostree_builtin_uninstall },
{ "makecache", 0,
"Generate rpm repo metadata",
rpmostree_builtin_makecache },
/* Legacy aliases */
{ "pkg-add", RPM_OSTREE_BUILTIN_FLAG_HIDDEN,
NULL, rpmostree_builtin_install },
Expand Down
94 changes: 94 additions & 0 deletions src/app/rpmostree-builtin-makecache.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
/* Copyright (C) 2017 Jonathan Lebon <[email protected]>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation; either version 2 of the licence or (at
* your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General
* Public License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place, Suite 330,
* Boston, MA 02111-1307, USA.
*/

#include "config.h"

#include <string.h>
#include <glib-unix.h>

#include "rpmostree-builtins.h"
#include "rpmostree-util.h"
#include "rpmostree-libbuiltin.h"
#include "rpmostree-dbus-helpers.h"

#include <libglnx.h>

static char *opt_osname;

static GOptionEntry option_entries[] = {
{ "os", 0, 0, G_OPTION_ARG_STRING, &opt_osname, "Operate on provided OSNAME", "OSNAME" },
{ NULL }
};

static GVariant *
get_args_variant (void)
{
GVariantDict dict;
g_variant_dict_init (&dict, NULL);
return g_variant_dict_end (&dict);
}

int
rpmostree_builtin_makecache (int argc,
char **argv,
RpmOstreeCommandInvocation *invocation,
GCancellable *cancellable,
GError **error)
{
g_autoptr(GOptionContext) context = g_option_context_new ("");
glnx_unref_object RPMOSTreeOS *os_proxy = NULL;
glnx_unref_object RPMOSTreeSysroot *sysroot_proxy = NULL;
g_autofree char *transaction_address = NULL;
_cleanup_peer_ GPid peer_pid = 0;

if (!rpmostree_option_context_parse (context,
option_entries,
&argc, &argv,
invocation,
cancellable,
NULL, NULL,
&sysroot_proxy,
&peer_pid,
error))
return EXIT_FAILURE;

if (argc < 1 || argc > 2)
{
rpmostree_usage_error (context, "Too few or too many arguments", error);
return EXIT_FAILURE;
}

if (!rpmostree_load_os_proxy (sysroot_proxy, opt_osname,
cancellable, &os_proxy, error))
return EXIT_FAILURE;

if (!rpmostree_os_call_make_cache_sync (os_proxy,
get_args_variant (),
&transaction_address,
cancellable,
error))
return EXIT_FAILURE;

if (!rpmostree_transaction_get_response_sync (sysroot_proxy,
transaction_address,
cancellable,
error))
return EXIT_FAILURE;

return EXIT_SUCCESS;
}
1 change: 1 addition & 0 deletions src/app/rpmostree-builtins.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ BUILTINPROTO(cleanup);
BUILTINPROTO(rollback);
BUILTINPROTO(initramfs);
BUILTINPROTO(status);
BUILTINPROTO(makecache);
BUILTINPROTO(db);
BUILTINPROTO(internals);
BUILTINPROTO(container);
Expand Down
11 changes: 11 additions & 0 deletions src/daemon/org.projectatomic.rpmostree1.policy
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,17 @@
</defaults>
</action>

<action id="org.projectatomic.rpmostree1.makecache">
<description>Generate rpm repo metadata cache</description>
<message>Authentication is required to generate cache</message>
<icon_name>package-x-generic</icon_name>
<defaults>
<allow_any>auth_admin</allow_any>
<allow_inactive>auth_admin</allow_inactive>
<allow_active>auth_admin_keep</allow_active>
</defaults>
</action>

<action id="org.projectatomic.rpmostree1.override">
<description>Override packages</description>
<message>Authentication is required to override base OS software</message>
Expand Down
5 changes: 5 additions & 0 deletions src/daemon/org.projectatomic.rpmostree1.xml
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,11 @@
<arg type="s" name="transaction_address" direction="out"/>
</method>

<method name="MakeCache">
<arg type="a{sv}" name="options" direction="in"/>
<arg type="s" name="transaction_address" direction="out"/>
</method>

<!-- Available modifiers:
"set-refspec" (type 's')
"set-revision" (type 's')
Expand Down
24 changes: 3 additions & 21 deletions src/daemon/rpmostree-sysroot-upgrader.c
Original file line number Diff line number Diff line change
Expand Up @@ -774,27 +774,9 @@ prepare_context_for_assembly (RpmOstreeSysrootUpgrader *self,
GCancellable *cancellable,
GError **error)
{
DnfContext *hifctx = rpmostree_context_get_hif (self->ctx);

const char *sysroot_path =
gs_file_get_path_cached (ostree_sysroot_get_path (self->sysroot));
g_autofree char *merge_deployment_dirpath =
ostree_sysroot_get_deployment_dirpath (self->sysroot,
self->cfg_merge_deployment);
g_autofree char *merge_deployment_root =
g_build_filename (sysroot_path, merge_deployment_dirpath, NULL);

g_autofree char *reposdir = g_build_filename (merge_deployment_root,
"etc/yum.repos.d", NULL);
g_autofree char *passwddir = g_build_filename (merge_deployment_root,
"etc", NULL);

/* point libhif to the yum.repos.d and os-release of the merge deployment */
dnf_context_set_repo_dir (hifctx, reposdir);
dnf_context_set_source_root (hifctx, tmprootfs);

/* point the core to the passwd & group of the merge deployment */
rpmostree_context_set_passwd_dir (self->ctx, passwddir);
/* make sure yum repos and passwd used are from our cfg merge */
rpmostree_context_configure_from_deployment (self->ctx, self->sysroot,
self->cfg_merge_deployment);

/* load the sepolicy to use during import */
glnx_unref_object OstreeSePolicy *sepolicy = NULL;
Expand Down
2 changes: 1 addition & 1 deletion src/daemon/rpmostreed-daemon.c
Original file line number Diff line number Diff line change
Expand Up @@ -451,7 +451,7 @@ update_status (RpmostreedDaemon *self)
guint64 readytime = g_source_get_ready_time (self->idle_exit_source);
guint64 curtime = g_source_get_time (self->idle_exit_source);
guint64 timeout_micros = readytime - curtime;
if (timeout_micros < 0)
if (readytime < curtime)
timeout_micros = 0;

g_assert (currently_idle && self->idle_exit_source);
Expand Down
54 changes: 54 additions & 0 deletions src/daemon/rpmostreed-os.c
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,10 @@ os_authorize_method (GDBusInterfaceSkeleton *interface,
{
g_ptr_array_add (actions, "org.projectatomic.rpmostree1.install-uninstall-packages");
}
else if (g_strcmp0 (method_name, "MakeCache") == 0)
{
g_ptr_array_add (actions, "org.projectatomic.rpmostree1.makecache");
}
else if (g_strcmp0 (method_name, "UpdateDeployment") == 0)
{
g_autoptr(GVariant) modifiers = g_variant_get_child_value (parameters, 0);
Expand Down Expand Up @@ -958,6 +962,55 @@ os_handle_rollback (RPMOSTreeOS *interface,
return TRUE;
}

static gboolean
os_handle_make_cache (RPMOSTreeOS *interface,
GDBusMethodInvocation *invocation,
GVariant *arg_options)
{
RpmostreedOS *self = RPMOSTREED_OS (interface);
glnx_unref_object RpmostreedTransaction *transaction = NULL;
glnx_unref_object OstreeSysroot *ot_sysroot = NULL;
g_autoptr(GCancellable) cancellable = g_cancellable_new ();
const char *osname;
GError *local_error = NULL;

transaction = merge_compatible_txn (self, invocation);
if (transaction)
goto out;

if (!rpmostreed_sysroot_load_state (rpmostreed_sysroot_get (),
cancellable,
&ot_sysroot,
NULL,
&local_error))
goto out;

osname = rpmostree_os_get_name (interface);

transaction = rpmostreed_transaction_new_makecache (invocation,
ot_sysroot,
osname,
cancellable,
&local_error);
if (transaction == NULL)
goto out;

rpmostreed_transaction_monitor_add (self->transaction_monitor, transaction);

out:
if (local_error != NULL)
{
g_dbus_method_invocation_take_error (invocation, local_error);
}
else
{
const char *client_address = rpmostreed_transaction_get_client_address (transaction);
rpmostree_os_complete_make_cache (interface, invocation, client_address);
}

return TRUE;
}

/* This is an older variant of Cleanup, kept for backcompat */
static gboolean
os_handle_clear_rollback_target (RPMOSTreeOS *interface,
Expand Down Expand Up @@ -1527,6 +1580,7 @@ rpmostreed_os_iface_init (RPMOSTreeOSIface *iface)
iface->handle_rollback = os_handle_rollback;
iface->handle_clear_rollback_target = os_handle_clear_rollback_target;
iface->handle_rebase = os_handle_rebase;
iface->handle_make_cache = os_handle_make_cache;
iface->handle_pkg_change = os_handle_pkg_change;
iface->handle_set_initramfs_state = os_handle_set_initramfs_state;
iface->handle_cleanup = os_handle_cleanup;
Expand Down
106 changes: 106 additions & 0 deletions src/daemon/rpmostreed-transaction-types.c
Original file line number Diff line number Diff line change
Expand Up @@ -1272,3 +1272,109 @@ rpmostreed_transaction_new_cleanup (GDBusMethodInvocation *invocation,
return (RpmostreedTransaction *) self;

}

/* ================================ MakeCache ================================ */

typedef struct {
RpmostreedTransaction parent;
char *osname;
} MakeCacheTransaction;

typedef RpmostreedTransactionClass MakeCacheTransactionClass;

GType makecache_transaction_get_type (void);

G_DEFINE_TYPE (MakeCacheTransaction,
makecache_transaction,
RPMOSTREED_TYPE_TRANSACTION)

static void
makecache_transaction_finalize (GObject *object)
{
MakeCacheTransaction *self;

self = (MakeCacheTransaction *) object;
g_free (self->osname);

G_OBJECT_CLASS (makecache_transaction_parent_class)->finalize (object);
}

static gboolean
makecache_transaction_execute (RpmostreedTransaction *transaction,
GCancellable *cancellable,
GError **error)
{
MakeCacheTransaction *self = (MakeCacheTransaction *) transaction;
OstreeSysroot *sysroot = rpmostreed_transaction_get_sysroot (transaction);
g_autoptr(OstreeRepo) repo = NULL;
if (!ostree_sysroot_get_repo (sysroot, &repo, cancellable, error))
return FALSE;

g_autoptr(OstreeDeployment) cfg_merge_deployment =
ostree_sysroot_get_merge_deployment (sysroot, self->osname);
g_autoptr(OstreeDeployment) origin_merge_deployment =
rpmostree_syscore_get_origin_merge_deployment (sysroot, self->osname);

g_autoptr(RpmOstreeContext) ctx = rpmostree_context_new_system (cancellable, error);

/* but set the source root to be the origin merge deployment's so we pick up releasever */
const char *sysroot_path = gs_file_get_path_cached (ostree_sysroot_get_path (sysroot));
g_autofree char *origin_deployment_dirpath =
ostree_sysroot_get_deployment_dirpath (sysroot, origin_merge_deployment);
g_autofree char *origin_deployment_root =
g_build_filename (sysroot_path, origin_deployment_dirpath, NULL);

/* XXX: clean up this hack */
g_autoptr(GKeyFile) kf = g_key_file_new ();
g_autoptr(RpmOstreeTreespec) treespec = rpmostree_treespec_new_from_keyfile (kf, NULL);
if (!rpmostree_context_setup (ctx, NULL, origin_deployment_root, treespec, cancellable, error))
return FALSE;

/* point libdnf to our repos dir */
rpmostree_context_configure_from_deployment (ctx, sysroot, cfg_merge_deployment);

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

return TRUE;
}

static void
makecache_transaction_class_init (CleanupTransactionClass *class)
{
GObjectClass *object_class;

object_class = G_OBJECT_CLASS (class);
object_class->finalize = makecache_transaction_finalize;

class->execute = makecache_transaction_execute;
}

static void
makecache_transaction_init (MakeCacheTransaction *self)
{
}

RpmostreedTransaction *
rpmostreed_transaction_new_makecache (GDBusMethodInvocation *invocation,
OstreeSysroot *sysroot,
const char *osname,
GCancellable *cancellable,
GError **error)
{
g_return_val_if_fail (G_IS_DBUS_METHOD_INVOCATION (invocation), NULL);
g_return_val_if_fail (OSTREE_IS_SYSROOT (sysroot), NULL);

MakeCacheTransaction *self =
g_initable_new (makecache_transaction_get_type (),
cancellable, error,
"invocation", invocation,
"sysroot-path", gs_file_get_path_cached (ostree_sysroot_get_path (sysroot)),
NULL);

if (self != NULL)
self->osname = g_strdup (osname);

return (RpmostreedTransaction *) self;

}
Loading

0 comments on commit b1d4ec3

Please sign in to comment.