daemon: Fold pkgchange txn into deploy

The next step will be to design a DBus + commandline API for this. In the
meantime, there are some small subtle new features like honoring the dry-run
option for upgrade. I'm not testing that explicitly yet, but I think that's OK.

Closes: #593
Approved by: jlebon
This commit is contained in:
Colin Walters 2017-01-26 10:41:10 -05:00 committed by Atomic Bot
parent c7d44e67d1
commit 7c7806f831
5 changed files with 77 additions and 248 deletions

View File

@ -41,7 +41,6 @@ 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-change.c \
src/daemon/rpmostree-package-variants.h \
src/daemon/rpmostree-package-variants.c \
src/daemon/rpmostreed-os.h \

View File

@ -359,6 +359,8 @@ deploy_flags_from_options (GVariant *options,
gboolean opt_reboot = FALSE;
gboolean opt_skip_purge = FALSE;
gboolean opt_allow_downgrade = FALSE;
gboolean opt_dry_run = FALSE;
gboolean opt_noscripts = FALSE;
g_variant_dict_init (&options_dict, options);
@ -378,6 +380,16 @@ deploy_flags_from_options (GVariant *options,
if (opt_skip_purge)
ret |= RPMOSTREE_TRANSACTION_DEPLOY_FLAG_SKIP_PURGE;
g_variant_dict_lookup (&options_dict, "dry-run", "b",
&opt_dry_run);
if (opt_dry_run)
ret |= RPMOSTREE_TRANSACTION_DEPLOY_FLAG_DRY_RUN;
g_variant_dict_lookup (&options_dict, "noscripts", "b",
&opt_noscripts);
if (opt_noscripts)
ret |= RPMOSTREE_TRANSACTION_DEPLOY_FLAG_NOSCRIPTS;
g_variant_dict_clear (&options_dict);
return ret;
@ -413,7 +425,7 @@ os_handle_deploy (RPMOSTreeOS *interface,
ot_sysroot,
deploy_flags_from_options (arg_options,
RPMOSTREE_TRANSACTION_DEPLOY_FLAG_ALLOW_DOWNGRADE),
osname, NULL, arg_revision,
osname, NULL, arg_revision, NULL, NULL,
cancellable,
&local_error);
@ -464,7 +476,7 @@ os_handle_upgrade (RPMOSTreeOS *interface,
transaction = rpmostreed_transaction_new_deploy (invocation, ot_sysroot,
deploy_flags_from_options (arg_options, 0),
osname, NULL, NULL,
osname, NULL, NULL, NULL, NULL,
cancellable, &local_error);
if (transaction == NULL)
@ -651,9 +663,8 @@ os_handle_rebase (RPMOSTreeOS *interface,
ot_sysroot,
deploy_flags_from_options (arg_options,
RPMOSTREE_TRANSACTION_DEPLOY_FLAG_ALLOW_DOWNGRADE),
osname,
arg_refspec,
opt_revision,
osname, arg_refspec, opt_revision,
NULL, NULL,
cancellable,
&local_error);
@ -690,10 +701,6 @@ os_handle_pkg_change (RPMOSTreeOS *interface,
g_autoptr(GCancellable) cancellable = g_cancellable_new ();
const char *osname;
GError *local_error = NULL;
gboolean v;
GVariantDict dict;
RpmOstreeTransactionPkgFlags flags = 0;
const char *const *ignore_scripts;
transaction = merge_compatible_txn (self, invocation);
if (transaction)
@ -708,38 +715,17 @@ os_handle_pkg_change (RPMOSTreeOS *interface,
osname = rpmostree_os_get_name (interface);
g_variant_dict_init (&dict, arg_options);
v = FALSE;
/* XXX Fail if option type is wrong? */
g_variant_dict_lookup (&dict, "reboot", "b", &v);
if (v)
flags |= RPMOSTREE_TRANSACTION_PKG_FLAG_REBOOT;
v = FALSE;
g_variant_dict_lookup (&dict, "dry-run", "b", &v);
if (v)
flags |= RPMOSTREE_TRANSACTION_PKG_FLAG_DRY_RUN;
v = FALSE;
g_variant_dict_lookup (&dict, "noscripts", "b", &v);
if (v)
flags |= RPMOSTREE_TRANSACTION_PKG_FLAG_NOSCRIPTS;
ignore_scripts = NULL;
g_variant_dict_lookup (&dict, "ignore-scripts", "^a&s", (char***)&ignore_scripts);
transaction = rpmostreed_transaction_new_pkg_change (invocation,
ot_sysroot,
osname,
arg_packages_added,
arg_packages_removed,
ignore_scripts,
flags,
cancellable,
&local_error);
g_variant_dict_clear (&dict);
/* By default, pkgchange does not pull the base; we will likley
* add an option in the future.
*/
transaction = rpmostreed_transaction_new_deploy (invocation,
ot_sysroot,
deploy_flags_from_options (arg_options,
RPMOSTREE_TRANSACTION_DEPLOY_FLAG_NO_PULL_BASE),
osname, NULL, NULL,
arg_packages_added,
arg_packages_removed,
cancellable, &local_error);
if (transaction == NULL)
goto out;

View File

@ -1,187 +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 <libdnf/libdnf.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-scripts.h"
#include "rpmostree-core.h"
typedef struct {
RpmostreedTransaction parent;
char *osname;
char **packages_added;
char **packages_removed;
GHashTable *ignore_scripts;
RpmOstreeTransactionPkgFlags flags;
} PkgChangeTransaction;
typedef RpmostreedTransactionClass PkgChangeTransactionClass;
GType pkg_change_transaction_get_type (void);
G_DEFINE_TYPE (PkgChangeTransaction,
pkg_change_transaction,
RPMOSTREED_TYPE_TRANSACTION)
static void
pkg_change_transaction_finalize (GObject *object)
{
PkgChangeTransaction *self;
self = (PkgChangeTransaction *) object;
g_free (self->osname);
g_strfreev (self->packages_added);
g_strfreev (self->packages_removed);
g_clear_pointer (&self->ignore_scripts, g_hash_table_unref);
G_OBJECT_CLASS (pkg_change_transaction_parent_class)->finalize (object);
}
static gboolean
pkg_change_transaction_execute (RpmostreedTransaction *transaction,
GCancellable *cancellable,
GError **error)
{
gboolean ret = FALSE;
PkgChangeTransaction *self = NULL;
OstreeSysroot *sysroot = NULL;
glnx_unref_object RpmOstreeSysrootUpgrader *upgrader = NULL;
int flags = 0;
self = (PkgChangeTransaction *) 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 (self->ignore_scripts)
rpmostree_sysroot_upgrader_set_ignore_scripts (upgrader, self->ignore_scripts);
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;
if (self->flags & RPMOSTREE_TRANSACTION_PKG_FLAG_REBOOT)
rpmostreed_reboot (cancellable, error);
ret = TRUE;
out:
return ret;
}
static void
pkg_change_transaction_class_init (PkgChangeTransactionClass *class)
{
GObjectClass *object_class;
object_class = G_OBJECT_CLASS (class);
object_class->finalize = pkg_change_transaction_finalize;
class->execute = pkg_change_transaction_execute;
}
static void
pkg_change_transaction_init (PkgChangeTransaction *self)
{
}
static char **
strdupv_canonicalize (const char *const *strv)
{
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,
const char * const *ignore_scripts,
RpmOstreeTransactionPkgFlags flags,
GCancellable *cancellable,
GError **error)
{
glnx_unref_object PkgChangeTransaction *self = NULL;
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_added != NULL || packages_removed != NULL, NULL);
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)),
NULL);
if (self != NULL)
{
self->osname = g_strdup (osname);
self->packages_added = strdupv_canonicalize (packages_added);
self->packages_removed = strdupv_canonicalize (packages_removed);
if (!rpmostree_script_ignore_hash_from_strv (ignore_scripts, &self->ignore_scripts, error))
return NULL;
self->flags = flags;
}
return (RpmostreedTransaction *) g_steal_pointer (&self);
}

View File

@ -603,6 +603,8 @@ typedef struct {
char *osname;
char *refspec; /* NULL for non-rebases */
char *revision; /* NULL for upgrade */
char **packages_added;
char **packages_removed;
} DeployTransaction;
typedef RpmostreedTransactionClass DeployTransactionClass;
@ -622,6 +624,8 @@ deploy_transaction_finalize (GObject *object)
g_free (self->osname);
g_free (self->refspec);
g_free (self->revision);
g_strfreev (self->packages_added);
g_strfreev (self->packages_removed);
G_OBJECT_CLASS (deploy_transaction_parent_class)->finalize (object);
}
@ -648,6 +652,10 @@ deploy_transaction_execute (RpmostreedTransaction *transaction,
if (self->flags & RPMOSTREE_TRANSACTION_DEPLOY_FLAG_ALLOW_DOWNGRADE)
upgrader_flags |= RPMOSTREE_SYSROOT_UPGRADER_FLAGS_ALLOW_OLDER;
if (self->flags & RPMOSTREE_TRANSACTION_DEPLOY_FLAG_DRY_RUN)
upgrader_flags |= RPMOSTREE_SYSROOT_UPGRADER_FLAGS_PKGOVERLAY_DRY_RUN;
if (self->flags & RPMOSTREE_TRANSACTION_DEPLOY_FLAG_NOSCRIPTS)
upgrader_flags |= RPMOSTREE_SYSROOT_UPGRADER_FLAGS_PKGOVERLAY_NOSCRIPTS;
if (self->refspec)
{
@ -684,12 +692,34 @@ deploy_transaction_execute (RpmostreedTransaction *transaction,
goto out;
}
if (!rpmostree_sysroot_upgrader_pull (upgrader, NULL, 0,
progress, &changed, cancellable, error))
goto out;
/* Mainly for the `install` command */
if (!(self->flags & RPMOSTREE_TRANSACTION_DEPLOY_FLAG_NO_PULL_BASE))
{
if (!rpmostree_sysroot_upgrader_pull (upgrader, NULL, 0,
progress, &changed, cancellable, error))
goto out;
}
rpmostree_transaction_emit_progress_end (RPMOSTREE_TRANSACTION (transaction));
if (self->packages_removed)
{
if (!rpmostree_sysroot_upgrader_delete_packages (upgrader, self->packages_removed,
cancellable, error))
goto out;
changed = TRUE;
}
if (self->packages_added)
{
if (!rpmostree_sysroot_upgrader_add_packages (upgrader, self->packages_added,
cancellable, error))
goto out;
changed = TRUE;
}
/* TODO - better logic for "changed" based on deployments */
if (changed || self->refspec)
{
@ -745,6 +775,14 @@ deploy_transaction_init (DeployTransaction *self)
{
}
static char **
strdupv_canonicalize (const char *const *strv)
{
if (strv && *strv)
return g_strdupv ((char**)strv);
return NULL;
}
RpmostreedTransaction *
rpmostreed_transaction_new_deploy (GDBusMethodInvocation *invocation,
OstreeSysroot *sysroot,
@ -752,6 +790,8 @@ rpmostreed_transaction_new_deploy (GDBusMethodInvocation *invocation,
const char *osname,
const char *refspec,
const char *revision,
const char *const *packages_added,
const char *const *packages_removed,
GCancellable *cancellable,
GError **error)
{
@ -773,6 +813,8 @@ rpmostreed_transaction_new_deploy (GDBusMethodInvocation *invocation,
self->flags = flags;
self->refspec = g_strdup (refspec);
self->revision = g_strdup (revision);
self->packages_added = strdupv_canonicalize (packages_added);
self->packages_removed = strdupv_canonicalize (packages_removed);
}
return (RpmostreedTransaction *) self;

View File

@ -49,6 +49,9 @@ typedef enum {
RPMOSTREE_TRANSACTION_DEPLOY_FLAG_REBOOT = (1 << 0),
RPMOSTREE_TRANSACTION_DEPLOY_FLAG_SKIP_PURGE = (1 << 1),
RPMOSTREE_TRANSACTION_DEPLOY_FLAG_ALLOW_DOWNGRADE = (1 << 2),
RPMOSTREE_TRANSACTION_DEPLOY_FLAG_NO_PULL_BASE = (1 << 4),
RPMOSTREE_TRANSACTION_DEPLOY_FLAG_DRY_RUN = (1 << 5),
RPMOSTREE_TRANSACTION_DEPLOY_FLAG_NOSCRIPTS = (1 << 6)
} RpmOstreeTransactionDeployFlags;
@ -59,25 +62,11 @@ RpmostreedTransaction *
const char *osname,
const char *refspec,
const char *revision,
const char *const *packages_added,
const char *const *packages_removed,
GCancellable *cancellable,
GError **error);
typedef enum {
RPMOSTREE_TRANSACTION_PKG_FLAG_REBOOT = (1 << 0),
RPMOSTREE_TRANSACTION_PKG_FLAG_DRY_RUN = (1 << 1),
RPMOSTREE_TRANSACTION_PKG_FLAG_NOSCRIPTS = (1 << 2)
} RpmOstreeTransactionPkgFlags;
RpmostreedTransaction *
rpmostreed_transaction_new_pkg_change (GDBusMethodInvocation *invocation,
OstreeSysroot *sysroot,
const char *osname,
const char *const *packages_added,
const char *const *packages_removed,
const char *const *ignore_scripts,
RpmOstreeTransactionPkgFlags flags,
GCancellable *cancellable,
GError **error);
RpmostreedTransaction *
rpmostreed_transaction_new_initramfs_state (GDBusMethodInvocation *invocation,
OstreeSysroot *sysroot,