From 699cc891985084a43c2c0dc435379d07f20cb567 Mon Sep 17 00:00:00 2001 From: Jonathan Lebon Date: Thu, 11 Jan 2018 20:39:44 +0000 Subject: [PATCH] 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 --- src/lib/rpmostree-package.c | 16 ++++++++++++++-- src/libpriv/rpmostree-rpm-util.c | 13 +++++++++---- tests/vmcheck/test-layering-basic.sh | 9 +++++++-- 3 files changed, 30 insertions(+), 8 deletions(-) diff --git a/src/lib/rpmostree-package.c b/src/lib/rpmostree-package.c index 7d6b17c6..ca7b5abe 100644 --- a/src/lib/rpmostree-package.c +++ b/src/lib/rpmostree-package.c @@ -53,6 +53,7 @@ struct RpmOstreePackage char *nevra; const char *name; const char *evr; + char *evr_owned; 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->nevra, g_free); + g_clear_pointer (&pkg->evr_owned, g_free); 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); /* 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); 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(GVariantDict) meta_dict = g_variant_dict_new (meta); return g_variant_dict_lookup_value (meta_dict, "rpmostree.rpmdb.pkglist", - G_VARIANT_TYPE ("a(sss)")); + G_VARIANT_TYPE ("a(sssss)")); } static GPtrArray * diff --git a/src/libpriv/rpmostree-rpm-util.c b/src/libpriv/rpmostree-rpm-util.c index 31bb57d8..e1f068be 100644 --- a/src/libpriv/rpmostree-rpm-util.c +++ b/src/libpriv/rpmostree-rpm-util.c @@ -1143,15 +1143,20 @@ rpmostree_create_rpmdb_pkglist_variant (int rootfs_dfd, g_autoptr(GPtrArray) pkglist = rpmostree_sack_get_sorted_packages (refsack->sack); 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; for (guint i = 0; i < n; i++) { DnfPackage *pkg = pkglist->pdata[i]; - g_variant_builder_add (&pkglist_v_builder, "(sss)", - dnf_package_get_name (pkg), - dnf_package_get_evr (pkg), + + /* put epoch as a string so we're indifferent to endianness -- also note that unlike + * 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)); } diff --git a/tests/vmcheck/test-layering-basic.sh b/tests/vmcheck/test-layering-basic.sh index 95f56fac..27920728 100755 --- a/tests/vmcheck/test-layering-basic.sh +++ b/tests/vmcheck/test-layering-basic.sh @@ -75,8 +75,13 @@ rm -f refs.txt refdata.txt vm_cmd ostree fsck vm_cmd ostree show --print-metadata-key rpmostree.rpmdb.pkglist \ $(vm_get_deployment_info 0 checksum) > variant-pkglist.txt -# No 0: in EVR -assert_file_has_content_literal 'variant-pkglist.txt' "('foo', '1.0-1', 'x86_64')" +# 0 shows up in variant dump +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" vm_reboot