daemon: Unify PkgAdd/PkgDelete into PkgChange

We need the ability to both add and remove packages as one
transaction in the general case (`Conflicts:`), plus it'd
be quite nice to allow users to do multiple package things
before rebooting.

And finally, this deletes a lot of duplicate code.

Where I'm really thinking this should go is we only have one
transaction type internally for at least upgrade/pkg as a group.

Closes: #326
Approved by: jlebon
This commit is contained in:
Colin Walters 2016-06-15 16:37:54 -04:00 committed by Atomic Bot
parent 90cae512a8
commit 5936b53812
8 changed files with 93 additions and 295 deletions

View File

@ -41,8 +41,7 @@ librpmostreed_la_SOURCES = \
src/daemon/rpmostreed-transaction-monitor.c \
src/daemon/rpmostreed-transaction-types.h \
src/daemon/rpmostreed-transaction-types.c \
src/daemon/rpmostreed-transaction-pkg-add.c \
src/daemon/rpmostreed-transaction-pkg-delete.c \
src/daemon/rpmostreed-transaction-pkg-change.c \
src/daemon/rpmostree-package-variants.h \
src/daemon/rpmostree-package-variants.c \
src/daemon/rpmostreed-os.h \

View File

@ -65,6 +65,7 @@ rpmostree_builtin_pkg_add (int argc,
g_autoptr(GVariant) default_deployment = NULL;
g_autofree char *transaction_address = NULL;
int i;
g_autoptr(GPtrArray) argv_empty = g_ptr_array_new ();
g_autoptr(GPtrArray) argv_and_null = g_ptr_array_new ();
context = g_option_context_new ("PACKAGE [PACKAGE...] - Download and install layered RPM packages");
@ -88,16 +89,19 @@ rpmostree_builtin_pkg_add (int argc,
g_ptr_array_add (argv_and_null, argv[i]);
g_ptr_array_add (argv_and_null, NULL);
g_ptr_array_add (argv_empty, NULL);
if (!rpmostree_load_os_proxy (sysroot_proxy, opt_osname,
cancellable, &os_proxy, error))
goto out;
if (!rpmostree_os_call_pkg_add_sync (os_proxy,
get_args_variant (),
(const char * const*)argv_and_null->pdata,
&transaction_address,
cancellable,
error))
if (!rpmostree_os_call_pkg_change_sync (os_proxy,
get_args_variant (),
(const char * const*)argv_and_null->pdata,
(const char * const*)argv_empty->pdata,
&transaction_address,
cancellable,
error))
goto out;
if (!rpmostree_transaction_get_response_sync (sysroot_proxy,

View File

@ -65,6 +65,7 @@ rpmostree_builtin_pkg_delete (int argc,
g_autoptr(GVariant) default_deployment = NULL;
g_autofree char *transaction_address = NULL;
int i;
g_autoptr(GPtrArray) argv_empty = g_ptr_array_new ();
g_autoptr(GPtrArray) argv_and_null = g_ptr_array_new ();
context = g_option_context_new ("PACKAGE [PACKAGE...] - Remove previously layered RPM packages");
@ -88,12 +89,15 @@ rpmostree_builtin_pkg_delete (int argc,
g_ptr_array_add (argv_and_null, argv[i]);
g_ptr_array_add (argv_and_null, NULL);
g_ptr_array_add (argv_empty, NULL);
if (!rpmostree_load_os_proxy (sysroot_proxy, opt_osname,
cancellable, &os_proxy, error))
goto out;
if (!rpmostree_os_call_pkg_delete_sync (os_proxy,
if (!rpmostree_os_call_pkg_change_sync (os_proxy,
get_args_variant (),
(const char * const*)argv_empty->pdata,
(const char * const*)argv_and_null->pdata,
&transaction_address,
cancellable,

View File

@ -172,15 +172,10 @@
<arg type="s" name="transaction_address" direction="out"/>
</method>
<method name="PkgAdd">
<method name="PkgChange">
<arg type="a{sv}" name="options" direction="in"/>
<arg type="as" name="packages"/>
<arg type="s" name="transaction_address" direction="out"/>
</method>
<method name="PkgDelete">
<arg type="a{sv}" name="options" direction="in"/>
<arg type="as" name="packages"/>
<arg type="as" name="packages_added"/>
<arg type="as" name="packages_removed"/>
<arg type="s" name="transaction_address" direction="out"/>
</method>

View File

@ -746,10 +746,11 @@ pkg_opts_to_flags (GVariant *options)
}
static gboolean
os_handle_pkg_add (RPMOSTreeOS *interface,
GDBusMethodInvocation *invocation,
GVariant *arg_options,
const char * const *arg_packages)
os_handle_pkg_change (RPMOSTreeOS *interface,
GDBusMethodInvocation *invocation,
GVariant *arg_options,
const char * const *arg_packages_added,
const char * const *arg_packages_removed)
{
RpmostreedOS *self = RPMOSTREED_OS (interface);
glnx_unref_object RpmostreedTransaction *transaction = NULL;
@ -779,75 +780,14 @@ os_handle_pkg_add (RPMOSTreeOS *interface,
osname = rpmostree_os_get_name (interface);
transaction = rpmostreed_transaction_new_pkg_add (invocation,
ot_sysroot,
osname,
arg_packages,
pkg_opts_to_flags (arg_options),
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;
client_address = rpmostreed_transaction_get_client_address (transaction);
rpmostree_os_complete_pkg_add (interface, invocation, client_address);
}
return TRUE;
}
static gboolean
os_handle_pkg_delete (RPMOSTreeOS *interface,
GDBusMethodInvocation *invocation,
GVariant *arg_options,
const char * const *arg_packages)
{
RpmostreedOS *self = RPMOSTREED_OS (interface);
glnx_unref_object RpmostreedTransaction *transaction = NULL;
glnx_unref_object OstreeSysroot *ot_sysroot = NULL;
glnx_unref_object GCancellable *cancellable = NULL;
const char *osname;
GError *local_error = NULL;
/* If a compatible transaction is in progress, share its bus address. */
transaction = rpmostreed_transaction_monitor_ref_active_transaction (self->transaction_monitor);
if (transaction != NULL)
{
if (rpmostreed_transaction_is_compatible (transaction, invocation))
goto out;
g_clear_object (&transaction);
}
cancellable = g_cancellable_new ();
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_pkg_delete (invocation,
ot_sysroot,
osname,
arg_packages,
transaction = rpmostreed_transaction_new_pkg_change (invocation,
ot_sysroot,
osname,
arg_packages_added,
arg_packages_removed,
pkg_opts_to_flags (arg_options),
cancellable,
&local_error);
cancellable,
&local_error);
if (transaction == NULL)
goto out;
@ -863,7 +803,7 @@ out:
{
const char *client_address;
client_address = rpmostreed_transaction_get_client_address (transaction);
rpmostree_os_complete_pkg_delete (interface, invocation, client_address);
rpmostree_os_complete_pkg_change (interface, invocation, client_address);
}
return TRUE;
@ -1254,8 +1194,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_pkg_add = os_handle_pkg_add;
iface->handle_pkg_delete = os_handle_pkg_delete;
iface->handle_pkg_change = os_handle_pkg_change;
iface->handle_get_cached_rebase_rpm_diff = os_handle_get_cached_rebase_rpm_diff;
iface->handle_download_rebase_rpm_diff = os_handle_download_rebase_rpm_diff;
iface->handle_get_cached_deploy_rpm_diff = os_handle_get_cached_deploy_rpm_diff;

View File

@ -1,157 +0,0 @@
/*
* Copyright (C) 2015 Red Hat, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "config.h"
#include "ostree.h"
#include <libglnx.h>
#include <rpm/rpmlib.h>
#include <rpm/rpmlog.h>
#include <rpm/rpmdb.h>
#include <libhif/libhif.h>
#include <libgsystem.h>
#include "rpmostreed-transaction-types.h"
#include "rpmostreed-transaction-types.h"
#include "rpmostreed-transaction.h"
#include "rpmostreed-deployment-utils.h"
#include "rpmostreed-sysroot.h"
#include "rpmostree-sysroot-upgrader.h"
#include "rpmostreed-utils.h"
#include "rpmostree-postprocess.h"
#include "rpmostree-rpm-util.h"
#include "rpmostree-core.h"
typedef struct {
RpmostreedTransaction parent;
char *osname;
char **packages;
RpmOstreeTransactionPkgFlags flags;
} PkgAddTransaction;
typedef RpmostreedTransactionClass PkgAddTransactionClass;
GType pkg_add_transaction_get_type (void);
G_DEFINE_TYPE (PkgAddTransaction,
pkg_add_transaction,
RPMOSTREED_TYPE_TRANSACTION)
static void
pkg_add_transaction_finalize (GObject *object)
{
PkgAddTransaction *self;
self = (PkgAddTransaction *) object;
g_free (self->osname);
g_strfreev (self->packages);
G_OBJECT_CLASS (pkg_add_transaction_parent_class)->finalize (object);
}
static gboolean
pkg_add_transaction_execute (RpmostreedTransaction *transaction,
GCancellable *cancellable,
GError **error)
{
gboolean ret = FALSE;
PkgAddTransaction *self = NULL;
OstreeSysroot *sysroot = NULL;
glnx_unref_object RpmOstreeSysrootUpgrader *upgrader = NULL;
int flags = RPMOSTREE_SYSROOT_UPGRADER_FLAGS_REDEPLOY;
self = (PkgAddTransaction *) transaction;
sysroot = rpmostreed_transaction_get_sysroot (transaction);
if (self->flags & RPMOSTREE_TRANSACTION_PKG_FLAG_DRY_RUN)
flags |= RPMOSTREE_SYSROOT_UPGRADER_FLAGS_PKGOVERLAY_DRY_RUN;
if (self->flags & RPMOSTREE_TRANSACTION_PKG_FLAG_NOSCRIPTS)
flags |= RPMOSTREE_SYSROOT_UPGRADER_FLAGS_PKGOVERLAY_NOSCRIPTS;
upgrader = rpmostree_sysroot_upgrader_new (sysroot, self->osname, flags,
cancellable, error);
if (upgrader == NULL)
{
if (error && *error == NULL)
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
"Could not create sysroot upgrader");
goto out;
}
if (!rpmostree_sysroot_upgrader_add_packages (upgrader, self->packages,
cancellable, error))
goto out;
if (!rpmostree_sysroot_upgrader_deploy (upgrader, cancellable, error))
goto out;
if (self->flags & RPMOSTREE_TRANSACTION_PKG_FLAG_REBOOT)
rpmostreed_reboot (cancellable, error);
ret = TRUE;
out:
return ret;
}
static void
pkg_add_transaction_class_init (PkgAddTransactionClass *class)
{
GObjectClass *object_class;
object_class = G_OBJECT_CLASS (class);
object_class->finalize = pkg_add_transaction_finalize;
class->execute = pkg_add_transaction_execute;
}
static void
pkg_add_transaction_init (PkgAddTransaction *self)
{
}
RpmostreedTransaction *
rpmostreed_transaction_new_pkg_add (GDBusMethodInvocation *invocation,
OstreeSysroot *sysroot,
const char *osname,
const char * const *packages,
RpmOstreeTransactionPkgFlags flags,
GCancellable *cancellable,
GError **error)
{
PkgAddTransaction *self;
g_return_val_if_fail (G_IS_DBUS_METHOD_INVOCATION (invocation), NULL);
g_return_val_if_fail (OSTREE_IS_SYSROOT (sysroot), NULL);
g_return_val_if_fail (osname != NULL, NULL);
g_return_val_if_fail (packages != NULL, NULL);
self = g_initable_new (pkg_add_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);
self->packages = g_strdupv ((char**)packages);
self->flags = flags;
}
return (RpmostreedTransaction *) self;
}

View File

@ -40,42 +40,44 @@
typedef struct {
RpmostreedTransaction parent;
char *osname;
char **packages;
char **packages_added;
char **packages_removed;
RpmOstreeTransactionPkgFlags flags;
} PkgDeleteTransaction;
} PkgChangeTransaction;
typedef RpmostreedTransactionClass PkgDeleteTransactionClass;
typedef RpmostreedTransactionClass PkgChangeTransactionClass;
GType pkg_delete_transaction_get_type (void);
GType pkg_change_transaction_get_type (void);
G_DEFINE_TYPE (PkgDeleteTransaction,
pkg_delete_transaction,
G_DEFINE_TYPE (PkgChangeTransaction,
pkg_change_transaction,
RPMOSTREED_TYPE_TRANSACTION)
static void
pkg_delete_transaction_finalize (GObject *object)
pkg_change_transaction_finalize (GObject *object)
{
PkgDeleteTransaction *self;
PkgChangeTransaction *self;
self = (PkgDeleteTransaction *) object;
self = (PkgChangeTransaction *) object;
g_free (self->osname);
g_strfreev (self->packages);
g_strfreev (self->packages_added);
g_strfreev (self->packages_removed);
G_OBJECT_CLASS (pkg_delete_transaction_parent_class)->finalize (object);
G_OBJECT_CLASS (pkg_change_transaction_parent_class)->finalize (object);
}
static gboolean
pkg_delete_transaction_execute (RpmostreedTransaction *transaction,
GCancellable *cancellable,
GError **error)
pkg_change_transaction_execute (RpmostreedTransaction *transaction,
GCancellable *cancellable,
GError **error)
{
gboolean ret = FALSE;
PkgDeleteTransaction *self = NULL;
PkgChangeTransaction *self = NULL;
OstreeSysroot *sysroot = NULL;
glnx_unref_object RpmOstreeSysrootUpgrader *upgrader = NULL;
int flags = RPMOSTREE_SYSROOT_UPGRADER_FLAGS_REDEPLOY;
self = (PkgDeleteTransaction *) transaction;
self = (PkgChangeTransaction *) transaction;
sysroot = rpmostreed_transaction_get_sysroot (transaction);
if (self->flags & RPMOSTREE_TRANSACTION_PKG_FLAG_DRY_RUN)
@ -93,9 +95,19 @@ pkg_delete_transaction_execute (RpmostreedTransaction *transaction,
goto out;
}
if (!rpmostree_sysroot_upgrader_delete_packages (upgrader, self->packages,
cancellable, error))
goto out;
if (self->packages_removed)
{
if (!rpmostree_sysroot_upgrader_delete_packages (upgrader, self->packages_removed,
cancellable, error))
goto out;
}
if (self->packages_added)
{
if (!rpmostree_sysroot_upgrader_add_packages (upgrader, self->packages_added,
cancellable, error))
goto out;
}
if (!rpmostree_sysroot_upgrader_deploy (upgrader, cancellable, error))
goto out;
@ -109,38 +121,47 @@ out:
}
static void
pkg_delete_transaction_class_init (PkgDeleteTransactionClass *class)
pkg_change_transaction_class_init (PkgChangeTransactionClass *class)
{
GObjectClass *object_class;
object_class = G_OBJECT_CLASS (class);
object_class->finalize = pkg_delete_transaction_finalize;
object_class->finalize = pkg_change_transaction_finalize;
class->execute = pkg_delete_transaction_execute;
class->execute = pkg_change_transaction_execute;
}
static void
pkg_delete_transaction_init (PkgDeleteTransaction *self)
pkg_change_transaction_init (PkgChangeTransaction *self)
{
}
RpmostreedTransaction *
rpmostreed_transaction_new_pkg_delete (GDBusMethodInvocation *invocation,
OstreeSysroot *sysroot,
const char *osname,
const char * const *packages,
RpmOstreeTransactionPkgFlags flags,
GCancellable *cancellable,
GError **error)
static char **
strdupv_canonicalize (const char *const *strv)
{
PkgDeleteTransaction *self;
if (strv && *strv)
return g_strdupv ((char**)strv);
return NULL;
}
RpmostreedTransaction *
rpmostreed_transaction_new_pkg_change (GDBusMethodInvocation *invocation,
OstreeSysroot *sysroot,
const char *osname,
const char * const *packages_added,
const char * const *packages_removed,
RpmOstreeTransactionPkgFlags flags,
GCancellable *cancellable,
GError **error)
{
PkgChangeTransaction *self;
g_return_val_if_fail (G_IS_DBUS_METHOD_INVOCATION (invocation), NULL);
g_return_val_if_fail (OSTREE_IS_SYSROOT (sysroot), NULL);
g_return_val_if_fail (osname != NULL, NULL);
g_return_val_if_fail (packages != NULL, NULL);
g_return_val_if_fail (packages_added != NULL || packages_removed != NULL, NULL);
self = g_initable_new (pkg_delete_transaction_get_type (),
self = g_initable_new (pkg_change_transaction_get_type (),
cancellable, error,
"invocation", invocation,
"sysroot-path", gs_file_get_path_cached (ostree_sysroot_get_path (sysroot)),
@ -149,7 +170,8 @@ rpmostreed_transaction_new_pkg_delete (GDBusMethodInvocation *invocation,
if (self != NULL)
{
self->osname = g_strdup (osname);
self->packages = g_strdupv ((char**)packages);
self->packages_added = strdupv_canonicalize (packages_added);
self->packages_removed = strdupv_canonicalize (packages_removed);
self->flags = flags;
}

View File

@ -80,19 +80,11 @@ typedef enum {
} RpmOstreeTransactionPkgFlags;
RpmostreedTransaction *
rpmostreed_transaction_new_pkg_add (GDBusMethodInvocation *invocation,
rpmostreed_transaction_new_pkg_change (GDBusMethodInvocation *invocation,
OstreeSysroot *sysroot,
const char *osname,
const char *const *packages,
RpmOstreeTransactionPkgFlags flags,
GCancellable *cancellable,
GError **error);
RpmostreedTransaction *
rpmostreed_transaction_new_pkg_delete (GDBusMethodInvocation *invocation,
OstreeSysroot *sysroot,
const char *osname,
const char *const *packages,
const char *const *packages_added,
const char *const *packages_removed,
RpmOstreeTransactionPkgFlags flags,
GCancellable *cancellable,
GError **error);