core: Checksum package checksums, not just NEVRA for change detection

GPG signing an RPM doesn't change its NEVRA, and we need to support
detecting the case when RPMs change from unsigned to signed (or vice
versa).

It's also quite common for local developers to rev RPMs without
bumping the release or whatever, so this will fix that too.

Closes: #291

Closes: #296
Approved by: jlebon
This commit is contained in:
Colin Walters 2016-06-01 15:16:16 -04:00 committed by Atomic Bot
parent 6472b75a69
commit 3a93fc162f

View File

@ -1050,9 +1050,13 @@ ptrarray_sort_compare_strings (gconstpointer ap,
return strcmp (*asp, *bsp);
}
/* Generate a checksum from a goal in a repeatable fashion (ordered
* hash of component NEVRAs). This can be used to see if the goal has
* changed from a previous one efficiently.
/* 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.
*
* This can be used to efficiently see if the goal has changed from a
* previous one.
*/
void
rpmostree_hif_add_checksum_goal (GChecksum *checksum,
@ -1060,22 +1064,27 @@ rpmostree_hif_add_checksum_goal (GChecksum *checksum,
{
g_autoptr(GPtrArray) pkglist = NULL;
guint i;
g_autoptr(GPtrArray) nevras = g_ptr_array_new_with_free_func (g_free);
g_autoptr(GPtrArray) pkg_checksums = g_ptr_array_new_with_free_func (g_free);
pkglist = hy_goal_list_installs (goal, NULL);
g_assert (pkglist);
for (i = 0; i < pkglist->len; i++)
{
HifPackage *pkg = pkglist->pdata[i];
g_ptr_array_add (nevras, hif_package_get_nevra (pkg));
int pkg_checksum_type;
const unsigned char *pkg_checksum_bytes = hif_package_get_chksum (pkg, &pkg_checksum_type);
g_autofree char *pkg_checksum = hy_chksum_str (pkg_checksum_bytes, pkg_checksum_type);
char *pkg_checksum_with_type = g_strconcat (hy_chksum_name (pkg_checksum_type), ":", pkg_checksum, NULL);
g_ptr_array_add (pkg_checksums, pkg_checksum_with_type);
}
g_ptr_array_sort (nevras, ptrarray_sort_compare_strings);
g_ptr_array_sort (pkg_checksums, ptrarray_sort_compare_strings);
for (i = 0; i < nevras->len; i++)
for (i = 0; i < pkg_checksums->len; i++)
{
const char *nevra = nevras->pdata[i];
g_checksum_update (checksum, (guint8*)nevra, strlen (nevra));
const char *pkg_checksum = pkg_checksums->pdata[i];
g_checksum_update (checksum, (guint8*)pkg_checksum, strlen (pkg_checksum));
}
}