Skip to content

Commit

Permalink
[transaction] Add DNF_TRANSACTION_FLAG_DISABLE_SWDB
Browse files Browse the repository at this point in the history
Not all users of libdnf really need the functionality added by the SWDB
database. This is especially true for rpm-ostree-based variants of
Fedora and RHEL, which only use libdnf for composing on the server and
package layering on the client.

Some major differences that render the SWDB not useful for rpm-ostree:
- rpm-ostree already keeps track of requested packages in a separate
  database (really, text file).
- rpm-ostree always applies package installs from scratch on top of the
  base OSTree, so the concept of history is simply different (see e.g.
  coreos/rpm-ostree#1489).
- rpm-ostree updates are performed offline, i.e. not on the live system.
  As such, we don't need to track the state of the RPM transaction as it
  happens in a separate database. If librpm throws an error, we just
  throw out the whole offline rootfs.
- OSTree commits themselves already contain the list of packages that
  were installed in them, so that we can consult the commit metadata (or
  even the rpmdb directly) if we need to render the RPM diff on a system
  or OSTree branch.
  • Loading branch information
jlebon committed Dec 20, 2018
1 parent 4aa0dfc commit 4df94e5
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 23 deletions.
65 changes: 42 additions & 23 deletions libdnf/dnf-transaction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -502,7 +502,7 @@ dnf_find_pkg_from_name(GPtrArray *array, const gchar *pkgname)
static void
_swdb_transaction_item_progress(libdnf::Swdb *swdb, DnfPackage *pkg)
{
if (pkg == NULL) {
if (swdb == NULL || pkg == NULL) {
return;
}
const char *nevra = dnf_package_get_nevra(pkg);
Expand Down Expand Up @@ -844,6 +844,8 @@ _get_current_time()
static void
_history_write_item(DnfPackage *pkg, libdnf::Swdb *swdb, libdnf::TransactionItemAction action)
{
// this should be checked before calling
g_assert (swdb != NULL);
auto rpm = swdb->createRPMItem();
rpm->setName(dnf_package_get_name(pkg));
rpm->setEpoch(dnf_package_get_epoch(pkg));
Expand Down Expand Up @@ -1152,7 +1154,8 @@ dnf_transaction_commit(DnfTransaction *transaction, HyGoal goal, DnfState *state
goto out;

// initialize SWDB transaction
swdb->initTransaction();
if (swdb != NULL)
swdb->initTransaction();

dnf_state_action_start(state, DNF_STATE_ACTION_REQUEST, NULL);

Expand Down Expand Up @@ -1199,17 +1202,19 @@ dnf_transaction_commit(DnfTransaction *transaction, HyGoal goal, DnfState *state
goto out;

// resolve swdb reason
libdnf::TransactionItemAction swdbAction = libdnf::TransactionItemAction::INSTALL;
if (action == DNF_STATE_ACTION_UPDATE) {
swdbAction = libdnf::TransactionItemAction::UPGRADE;
} else if (action == DNF_STATE_ACTION_DOWNGRADE) {
swdbAction = libdnf::TransactionItemAction::DOWNGRADE;
} else if (action == DNF_STATE_ACTION_REINSTALL) {
swdbAction = libdnf::TransactionItemAction::REINSTALL;
}
if (swdb != NULL) {
libdnf::TransactionItemAction swdbAction = libdnf::TransactionItemAction::INSTALL;
if (action == DNF_STATE_ACTION_UPDATE) {
swdbAction = libdnf::TransactionItemAction::UPGRADE;
} else if (action == DNF_STATE_ACTION_DOWNGRADE) {
swdbAction = libdnf::TransactionItemAction::DOWNGRADE;
} else if (action == DNF_STATE_ACTION_REINSTALL) {
swdbAction = libdnf::TransactionItemAction::REINSTALL;
}

// add item to swdb transaction
_history_write_item(pkg, swdb, swdbAction);
// add item to swdb transaction
_history_write_item(pkg, swdb, swdbAction);
}

/* this section done */
ret = dnf_state_done(state_local, error);
Expand Down Expand Up @@ -1237,19 +1242,20 @@ dnf_transaction_commit(DnfTransaction *transaction, HyGoal goal, DnfState *state
g_warning("failed to pre-get pkgid for %s", dnf_package_get_package_id(pkg));
}

libdnf::TransactionItemAction swdbAction = libdnf::TransactionItemAction::REMOVE;

/* are the things being removed actually being upgraded */
pkg_tmp = dnf_find_pkg_from_name(priv->install, dnf_package_get_name(pkg));
if (pkg_tmp != NULL) {
dnf_package_set_action(pkg, DNF_STATE_ACTION_CLEANUP);
if (dnf_package_evr_cmp(pkg, pkg_tmp)) {
swdbAction = libdnf::TransactionItemAction::UPGRADED;
} else {
swdbAction = libdnf::TransactionItemAction::DOWNGRADED;
if (swdb != NULL) {
libdnf::TransactionItemAction swdbAction = libdnf::TransactionItemAction::REMOVE;
if (dnf_package_evr_cmp(pkg, pkg_tmp)) {
swdbAction = libdnf::TransactionItemAction::UPGRADED;
} else {
swdbAction = libdnf::TransactionItemAction::DOWNGRADED;
}
_history_write_item(pkg, swdb, swdbAction);
}
}
_history_write_item(pkg, swdb, swdbAction);
}

/* add anything that gets obsoleted to a helper array which is used to
Expand All @@ -1270,6 +1276,12 @@ dnf_transaction_commit(DnfTransaction *transaction, HyGoal goal, DnfState *state
g_ptr_array_add(priv->remove_helper, g_object_ref(pkg_tmp));
dnf_package_set_action(pkg_tmp, DNF_STATE_ACTION_CLEANUP);

// and now prepare to write this in the db

// swdb disabled -- we're done!
if (swdb == NULL)
continue;

const char *pkg_tmp_name = dnf_package_get_name(pkg_tmp);

if (dnf_find_pkg_from_name(priv->remove, pkg_tmp_name) != NULL) {
Expand Down Expand Up @@ -1415,7 +1427,8 @@ dnf_transaction_commit(DnfTransaction *transaction, HyGoal goal, DnfState *state
rpmdb_begin = dnf_sack_get_rpmdb_version(rpmdb_version_sack);
g_object_unref(rpmdb_version_sack);
}
swdb->beginTransaction(_get_current_time(), rpmdb_begin, "", priv->uid);
if (swdb != NULL)
swdb->beginTransaction(_get_current_time(), rpmdb_begin, "", priv->uid);

/* run the transaction */
priv->state = dnf_state_get_child(state);
Expand Down Expand Up @@ -1460,8 +1473,10 @@ dnf_transaction_commit(DnfTransaction *transaction, HyGoal goal, DnfState *state
rpmdb_end = dnf_sack_get_rpmdb_version(rpmdb_version_sack);
g_object_unref(rpmdb_version_sack);

swdb->endTransaction(_get_current_time(), rpmdb_end.c_str(), libdnf::TransactionState::DONE);
swdb->closeTransaction();
if (swdb != NULL) {
swdb->endTransaction(_get_current_time(), rpmdb_end.c_str(), libdnf::TransactionState::DONE);
swdb->closeTransaction();
}

data.hookId = PLUGIN_HOOK_ID_CONTEXT_TRANSACTION;
if (!dnf_context_plugin_hook(priv->context, PLUGIN_HOOK_ID_CONTEXT_TRANSACTION, &data, nullptr))
Expand Down Expand Up @@ -1534,13 +1549,17 @@ dnf_transaction_new_with_flags(DnfContext *context, guint64 flags)
{
auto transaction = DNF_TRANSACTION(g_object_new(DNF_TYPE_TRANSACTION, NULL));
auto priv = GET_PRIVATE(transaction);
priv->swdb = new libdnf::Swdb(libdnf::Swdb::defaultPath);
priv->context = context;
g_object_add_weak_pointer(G_OBJECT(priv->context), (void **)&priv->context);
priv->ts = rpmtsCreate();
rpmtsSetRootDir(priv->ts, dnf_context_get_install_root(context));
priv->keyring = rpmtsGetKeyring(priv->ts, 1);
priv->flags = flags;

if (!(priv->flags & DNF_TRANSACTION_FLAG_DISABLE_SWDB)) {
priv->swdb = new libdnf::Swdb(libdnf::Swdb::defaultPath);
}

return transaction;
}

Expand Down
2 changes: 2 additions & 0 deletions libdnf/dnf-transaction.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ struct _DnfTransactionClass
* @DNF_TRANSACTION_FLAG_ALLOW_DOWNGRADE: Allow package downrades
* @DNF_TRANSACTION_FLAG_NODOCS: Don't install documentation
* @DNF_TRANSACTION_FLAG_TEST: Only do a transaction test
* @DNF_TRANSACTION_FLAG_DISABLE_SWDB: Don't write to SWDB
*
* The transaction flags.
**/
Expand All @@ -67,6 +68,7 @@ typedef enum {
DNF_TRANSACTION_FLAG_ALLOW_DOWNGRADE = 1 << 2,
DNF_TRANSACTION_FLAG_NODOCS = 1 << 3,
DNF_TRANSACTION_FLAG_TEST = 1 << 4,
DNF_TRANSACTION_FLAG_DISABLE_SWDB = 1 << 5,
/*< private >*/
DNF_TRANSACTION_FLAG_LAST
} DnfTransactionFlag;
Expand Down

0 comments on commit 4df94e5

Please sign in to comment.