libpriv/rpm-util: encode epoch as a string

This is essentially a revert of #1190. I initially changed from storing
the epoch, version, and release separately to together to avoid endian
issues with epoch. This works around that instead by just encoding it as
a string.

As is done in our custom NEVRA printer (which before #1190 we used
here), we make sure that epochs of "0" are not printed as part of the
`nevra` or `evr` members.

Closes: #1198
Approved by: cgwalters
This commit is contained in:
Jonathan Lebon 2018-01-11 20:39:44 +00:00 committed by Atomic Bot
parent bc5237ebf8
commit 699cc89198
3 changed files with 30 additions and 8 deletions

View File

@ -53,6 +53,7 @@ struct RpmOstreePackage
char *nevra; char *nevra;
const char *name; const char *name;
const char *evr; const char *evr;
char *evr_owned;
const char *arch; const char *arch;
}; };
@ -67,6 +68,7 @@ rpm_ostree_package_finalize (GObject *object)
g_clear_pointer (&pkg->gv_nevra, g_variant_unref); g_clear_pointer (&pkg->gv_nevra, g_variant_unref);
g_clear_pointer (&pkg->nevra, g_free); g_clear_pointer (&pkg->nevra, g_free);
g_clear_pointer (&pkg->evr_owned, g_free);
G_OBJECT_CLASS (rpm_ostree_package_parent_class)->finalize (object); G_OBJECT_CLASS (rpm_ostree_package_parent_class)->finalize (object);
} }
@ -193,8 +195,18 @@ _rpm_ostree_package_new_from_variant (GVariant *gv_nevra)
p->gv_nevra = g_variant_ref (gv_nevra); p->gv_nevra = g_variant_ref (gv_nevra);
/* we deconstruct now to make accessors simpler */ /* we deconstruct now to make accessors simpler */
const char *epoch;
const char *version;
const char *release;
g_variant_get (p->gv_nevra, "(&s&s&s)", &p->name, &p->evr, &p->arch); g_variant_get (p->gv_nevra, "(&s&s&s&s&s)", &p->name, &epoch, &version, &release, &p->arch);
/* we follow the libdnf convention here of explicit 0 --> skip over */
g_assert (epoch);
if (g_str_equal (epoch, "0"))
p->evr_owned = g_strdup_printf ("%s-%s", version, release);
else
p->evr_owned = g_strdup_printf ("%s:%s-%s", epoch, version, release);
p->evr = p->evr_owned;
p->nevra = g_strdup_printf ("%s-%s.%s", p->name, p->evr, p->arch); p->nevra = g_strdup_printf ("%s-%s.%s", p->name, p->evr, p->arch);
return p; return p;
} }
@ -205,7 +217,7 @@ get_commit_rpmdb_pkglist (GVariant *commit)
g_autoptr(GVariant) meta = g_variant_get_child_value (commit, 0); g_autoptr(GVariant) meta = g_variant_get_child_value (commit, 0);
g_autoptr(GVariantDict) meta_dict = g_variant_dict_new (meta); g_autoptr(GVariantDict) meta_dict = g_variant_dict_new (meta);
return g_variant_dict_lookup_value (meta_dict, "rpmostree.rpmdb.pkglist", return g_variant_dict_lookup_value (meta_dict, "rpmostree.rpmdb.pkglist",
G_VARIANT_TYPE ("a(sss)")); G_VARIANT_TYPE ("a(sssss)"));
} }
static GPtrArray * static GPtrArray *

View File

@ -1143,15 +1143,20 @@ rpmostree_create_rpmdb_pkglist_variant (int rootfs_dfd,
g_autoptr(GPtrArray) pkglist = rpmostree_sack_get_sorted_packages (refsack->sack); g_autoptr(GPtrArray) pkglist = rpmostree_sack_get_sorted_packages (refsack->sack);
GVariantBuilder pkglist_v_builder; GVariantBuilder pkglist_v_builder;
g_variant_builder_init (&pkglist_v_builder, (GVariantType*)"a(sss)"); g_variant_builder_init (&pkglist_v_builder, (GVariantType*)"a(sssss)");
const guint n = pkglist->len; const guint n = pkglist->len;
for (guint i = 0; i < n; i++) for (guint i = 0; i < n; i++)
{ {
DnfPackage *pkg = pkglist->pdata[i]; DnfPackage *pkg = pkglist->pdata[i];
g_variant_builder_add (&pkglist_v_builder, "(sss)",
dnf_package_get_name (pkg), /* put epoch as a string so we're indifferent to endianness -- also note that unlike
dnf_package_get_evr (pkg), * librpm, libdnf doesn't care about unset vs 0 epoch and neither do we */
g_autofree char *epoch = g_strdup_printf ("%" PRIu64, dnf_package_get_epoch (pkg));
g_variant_builder_add (&pkglist_v_builder, "(sssss)",
dnf_package_get_name (pkg), epoch,
dnf_package_get_version (pkg),
dnf_package_get_release (pkg),
dnf_package_get_arch (pkg)); dnf_package_get_arch (pkg));
} }

View File

@ -75,8 +75,13 @@ rm -f refs.txt refdata.txt
vm_cmd ostree fsck vm_cmd ostree fsck
vm_cmd ostree show --print-metadata-key rpmostree.rpmdb.pkglist \ vm_cmd ostree show --print-metadata-key rpmostree.rpmdb.pkglist \
$(vm_get_deployment_info 0 checksum) > variant-pkglist.txt $(vm_get_deployment_info 0 checksum) > variant-pkglist.txt
# No 0: in EVR # 0 shows up in variant dump
assert_file_has_content_literal 'variant-pkglist.txt' "('foo', '1.0-1', 'x86_64')" assert_file_has_content_literal 'variant-pkglist.txt' "('foo', '0', '1.0', '1', 'x86_64')"
# But no 0: in e.g. db diff output, which uses pkglist metadata
vm_rpmostree db diff --format=diff \
$(vm_get_deployment_info 0 base-checksum) \
$(vm_get_deployment_info 0 checksum) > db-diff.txt
assert_file_has_content_literal 'db-diff.txt' "+foo-1.0-1.x86_64"
echo "ok pkg-add foo" echo "ok pkg-add foo"
vm_reboot vm_reboot