libpriv/core: also checksum package action
When calculating the goal checksum, we only accounted for package installs. But with override support, there are now other package actions we need to pick up on. In practice, the fact that we also checksum the treespec made this hard to actually cause an issue. Although, since the actual final goal is also dependent on the underlying rpmdb, I can imagine e.g. a replacement override be considered a `DNF_PACKAGE_INFO_UPDATE` for one rpmdb appear as a `DNF_PACKAGE_INFO_DOWNGRADE` for another. While we're here, do some light code style porting and streamline the checksumming process to avoid creating a separate `GPtrArray`. Closes: #1053 Approved by: cgwalters
This commit is contained in:
parent
e5e9f1f0b8
commit
2b4a65bca5
@ -1612,42 +1612,65 @@ rpmostree_context_prepare (RpmOstreeContext *self,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Generate a checksum from a goal in a repeatable fashion -
|
||||
* we checksum an ordered array of the checksums of individual
|
||||
* packages. We *used* to just checksum the NEVRAs but that
|
||||
* breaks with RPM gpg signatures.
|
||||
static int
|
||||
compare_pkgs (gconstpointer ap,
|
||||
gconstpointer bp)
|
||||
{
|
||||
DnfPackage **a = (gpointer)ap;
|
||||
DnfPackage **b = (gpointer)bp;
|
||||
return dnf_package_cmp (*a, *b);
|
||||
}
|
||||
|
||||
/* XXX: push this into libdnf */
|
||||
static const char*
|
||||
convert_dnf_action_to_string (DnfStateAction action)
|
||||
{
|
||||
switch (action)
|
||||
{
|
||||
case DNF_STATE_ACTION_INSTALL:
|
||||
return "install";
|
||||
case DNF_STATE_ACTION_UPDATE:
|
||||
return "update";
|
||||
case DNF_STATE_ACTION_DOWNGRADE:
|
||||
return "downgrade";
|
||||
case DNF_STATE_ACTION_REMOVE:
|
||||
return "remove";
|
||||
case DNF_STATE_ACTION_OBSOLETE:
|
||||
return "obsolete";
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
return NULL; /* satisfy static analysis tools */
|
||||
}
|
||||
|
||||
/* Generate a checksum from a goal in a repeatable fashion - we checksum an ordered array of
|
||||
* the checksums of individual packages as well as the associated action. We *used* to just
|
||||
* checksum the NEVRAs but that breaks with RPM gpg signatures.
|
||||
*
|
||||
* This can be used to efficiently see if the goal has changed from a
|
||||
* previous one.
|
||||
*
|
||||
* It can also handle goals in which only dummy header-only pkgs are
|
||||
* available. In such cases, it uses the ostree checksum of the pkg
|
||||
* instead.
|
||||
* This can be used to efficiently see if the goal has changed from a previous one.
|
||||
*/
|
||||
void
|
||||
rpmostree_dnf_add_checksum_goal (GChecksum *checksum,
|
||||
HyGoal goal)
|
||||
{
|
||||
g_autoptr(GPtrArray) pkglist = NULL;
|
||||
guint i;
|
||||
g_autoptr(GPtrArray) pkg_checksums = g_ptr_array_new_with_free_func (g_free);
|
||||
|
||||
pkglist = hy_goal_list_installs (goal, NULL);
|
||||
g_autoptr(GPtrArray) pkglist = dnf_goal_get_packages (goal, DNF_PACKAGE_INFO_INSTALL,
|
||||
DNF_PACKAGE_INFO_UPDATE,
|
||||
DNF_PACKAGE_INFO_DOWNGRADE,
|
||||
DNF_PACKAGE_INFO_REMOVE,
|
||||
DNF_PACKAGE_INFO_OBSOLETE,
|
||||
-1);
|
||||
g_assert (pkglist);
|
||||
for (i = 0; i < pkglist->len; i++)
|
||||
g_ptr_array_sort (pkglist, compare_pkgs);
|
||||
for (guint i = 0; i < pkglist->len; i++)
|
||||
{
|
||||
DnfPackage *pkg = pkglist->pdata[i];
|
||||
DnfStateAction action = dnf_package_get_action (pkg);
|
||||
const char *action_str = convert_dnf_action_to_string (action);
|
||||
g_checksum_update (checksum, (guint8*)action_str, strlen (action_str));
|
||||
|
||||
g_autofree char* chksum_repr = NULL;
|
||||
g_assert (rpmostree_get_repodata_chksum_repr (pkg, &chksum_repr, NULL));
|
||||
g_ptr_array_add (pkg_checksums, g_steal_pointer (&chksum_repr));
|
||||
}
|
||||
|
||||
g_ptr_array_sort (pkg_checksums, rpmostree_ptrarray_sort_compare_strings);
|
||||
|
||||
for (guint i = 0; i < pkg_checksums->len; i++)
|
||||
{
|
||||
const char *pkg_checksum = pkg_checksums->pdata[i];
|
||||
g_checksum_update (checksum, (guint8*)pkg_checksum, strlen (pkg_checksum));
|
||||
g_checksum_update (checksum, (guint8*)chksum_repr, strlen (chksum_repr));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -961,8 +961,8 @@ rpmostree_print_transaction (DnfContext *hifctx)
|
||||
|
||||
{ g_autoptr(GPtrArray) packages = NULL;
|
||||
packages = dnf_goal_get_packages (dnf_context_get_goal (hifctx),
|
||||
DNF_PACKAGE_INFO_REMOVE,
|
||||
DNF_PACKAGE_INFO_OBSOLETE,
|
||||
DNF_PACKAGE_INFO_REMOVE,
|
||||
DNF_PACKAGE_INFO_OBSOLETE,
|
||||
-1);
|
||||
|
||||
if (packages->len > 0)
|
||||
@ -1058,13 +1058,16 @@ rpmostree_get_repodata_chksum_repr (DnfPackage *pkg,
|
||||
g_autofree char *chksum = NULL;
|
||||
const unsigned char *chksum_raw = NULL;
|
||||
|
||||
chksum_raw = dnf_package_get_chksum (pkg, &chksum_type);
|
||||
/* for rpmdb packages, use the hdr checksum */
|
||||
if (dnf_package_installed (pkg))
|
||||
chksum_raw = dnf_package_get_hdr_chksum (pkg, &chksum_type);
|
||||
else
|
||||
chksum_raw = dnf_package_get_chksum (pkg, &chksum_type);
|
||||
if (chksum_raw)
|
||||
chksum = hy_chksum_str (chksum_raw, chksum_type);
|
||||
|
||||
if (chksum == NULL)
|
||||
return glnx_throw (error, "Couldn't get chksum for pkg %s",
|
||||
dnf_package_get_nevra(pkg));
|
||||
return glnx_throw (error, "Couldn't get chksum for pkg %s", dnf_package_get_nevra(pkg));
|
||||
|
||||
*out_chksum_repr =
|
||||
g_strconcat (hy_chksum_name (chksum_type), ":", chksum, NULL);
|
||||
|
Loading…
Reference in New Issue
Block a user