commit2jigdo: Synthesize Requires: for jigdo set

Having the "jigdo set" in repodata makes it so we can parallel download the
jigdo RPM with the set. However for now, I kept the jigdo set in the jigdoRPM,
since that way it'll be covered by the signature.

Also, this changes the way we inject metadata to use a magic comment string,
since trying to pass a gigantic macro to `rpmbuild` via its argv didn't work out
so well (it looks like rpmbuild eats newlines). This approach is more robust.

Closes: https://github.com/projectatomic/rpm-ostree/issues/1132

Closes: #1140
Approved by: jlebon
This commit is contained in:
Colin Walters 2017-12-08 14:21:19 -05:00 committed by Atomic Bot
parent 7a03fd1bc1
commit ca2a651619
4 changed files with 79 additions and 16 deletions

View File

@ -585,6 +585,52 @@ build_objid_map_for_package (RpmOstreeCommit2JigdoContext *self,
return TRUE;
}
/* Take input spec file and generate a temporary spec file with our metadata
* inserted.
*/
static char *
generate_spec (RpmOstreeCommit2JigdoContext *self,
const char *spec_path,
GPtrArray *jigdo_packages,
GCancellable *cancellable,
GError **error)
{
g_autofree char *spec_contents =
glnx_file_get_contents_utf8_at (AT_FDCWD, spec_path, NULL,
cancellable, error);
if (!spec_contents)
return NULL;
/* Look for the magic comment */
const char *meta = strstr (spec_contents, "\n" RPMOSTREE_JIGDO_SPEC_META_MAGIC);
if (!meta)
return glnx_null_throw (error, "Missing magic '%s' in %s", RPMOSTREE_JIGDO_SPEC_META_MAGIC, spec_path);
/* Generate a replacement in memory */
g_autoptr(GString) replacement = g_string_new ("");
g_string_append_len (replacement, spec_contents, meta - spec_contents);
g_string_append (replacement, "# Generated by rpm-ostree\n");
g_string_append (replacement, "Provides: " RPMOSTREE_JIGDO_PROVIDE_V1 "\n");
/* Add Requires: on our dependent packages */
for (guint i = 0; i < jigdo_packages->len; i++)
{
DnfPackage *pkg = jigdo_packages->pdata[i];
g_string_append_printf (replacement, "Requires: %s = %s\n",
dnf_package_get_name (pkg),
dnf_package_get_evr (pkg));
}
g_string_append (replacement, meta + strlen (RPMOSTREE_JIGDO_SPEC_META_MAGIC) + 1);
g_string_append (replacement, "# End data generated by rpm-ostree\n");
char *tmppath = g_strdup ("/tmp/rpmostree-jigdo-spec.XXXXXX");
glnx_autofd int fd = g_mkstemp_full (tmppath, O_WRONLY | O_CLOEXEC, 0644);
if (glnx_loop_write (fd, replacement->str, replacement->len) < 0)
return glnx_null_throw_errno_prefix (error, "write");
return g_steal_pointer (&tmppath);
}
static int
compare_pkgs (gconstpointer ap,
gconstpointer bp)
@ -649,13 +695,13 @@ write_commit2jigdo (RpmOstreeCommit2JigdoContext *self,
}
/* write out the variant containing packages */
{ g_autoptr(GPtrArray) jigdo_packages = g_ptr_array_new ();
GLNX_HASH_TABLE_FOREACH (pkgs_with_content, DnfPackage *, pkg)
{
g_ptr_array_add (jigdo_packages, pkg);
}
g_ptr_array_sort (jigdo_packages, compare_pkgs);
g_autoptr(GVariantBuilder) pkgbuilder = g_variant_builder_new (RPMOSTREE_JIGDO_PKGS_VARIANT_FORMAT);
g_autoptr(GPtrArray) jigdo_packages = g_ptr_array_new ();
GLNX_HASH_TABLE_FOREACH (pkgs_with_content, DnfPackage *, pkg)
{
g_ptr_array_add (jigdo_packages, pkg);
}
g_ptr_array_sort (jigdo_packages, compare_pkgs);
{ g_autoptr(GVariantBuilder) pkgbuilder = g_variant_builder_new (RPMOSTREE_JIGDO_PKGS_VARIANT_FORMAT);
for (guint i = 0; i < jigdo_packages->len; i++)
{
DnfPackage *pkg = jigdo_packages->pdata[i];
@ -900,6 +946,11 @@ write_commit2jigdo (RpmOstreeCommit2JigdoContext *self,
if (!opt_only_contentdir)
{
g_autofree char *tmp_spec =
generate_spec (self, oirpm_spec, jigdo_packages, cancellable, error);
if (!tmp_spec)
return FALSE;
const char *commit_version;
if (!g_variant_lookup (commit_inline_meta, OSTREE_COMMIT_META_KEY_VERSION, "&s", &commit_version))
commit_version = NULL;
@ -927,10 +978,7 @@ write_commit2jigdo (RpmOstreeCommit2JigdoContext *self,
g_ptr_array_add (rpmbuild_argv, g_strconcat ("ostree_version ", commit_version, NULL));
}
g_ptr_array_add (rpmbuild_argv, g_strdup ("-D"));
g_ptr_array_add (rpmbuild_argv, g_strconcat ("rpmostree_jigdo_meta ", "Provides: " RPMOSTREE_JIGDO_PROVIDE_V1 "\n", NULL));
g_ptr_array_add (rpmbuild_argv, g_strdup (oirpm_spec));
g_ptr_array_add (rpmbuild_argv, g_strdup (tmp_spec));
g_ptr_array_add (rpmbuild_argv, NULL);
int estatus;
GLNX_AUTO_PREFIX_ERROR ("Running rpmbuild", error);
@ -938,7 +986,12 @@ write_commit2jigdo (RpmOstreeCommit2JigdoContext *self,
NULL, NULL, NULL, NULL, &estatus, error))
return FALSE;
if (!g_spawn_check_exit_status (estatus, error))
return FALSE;
{
g_printerr ("Temporary spec retained: %s", tmp_spec);
return FALSE;
}
(void) unlinkat (AT_FDCWD, tmp_spec, 0);
}
else
{

View File

@ -33,9 +33,11 @@
* so that can be GPG verified first - if that fails, we can then cleanly
* abort.
*
* Next, we have the "jigdo set" - the NEVRAs + repodata checksum of the
* RPM packages we need. So during client side processing, downloads
* can be initiated for those while we continue to process the OIRPM.
* Next, we have the "jigdo set" - the NEVRAs + repodata checksum of the RPM
* packages we need. These requires are also included in the RPM, but we also
* have the repodata checksum here so that it's covered by the RPM GPG
* signature, increasing security. The plan is to ensure that the repodata
* checksums match the ones in this set.
*
* The dirmeta/dirtree objects that are referenced by the commit follow.
*
@ -77,3 +79,6 @@
#define RPMOSTREE_JIGDO_XATTRS_PKG_VARIANT_FORMAT (G_VARIANT_TYPE ("a(su)"))
#define RPMOSTREE_JIGDO_PROVIDE_V1 "rpmostree-jigdo(v1)"
/* This one goes in the spec file to use as our replacement */
#define RPMOSTREE_JIGDO_SPEC_META_MAGIC "#@@@rpmostree_jigdo_meta@@@"

View File

@ -79,6 +79,11 @@ assert_file_has_content test-newpkg-list.txt 'test-newpkg-1.0-1.x86_64'
do_commit2jigdo ${newrev}
find jigdo-output -name '*.rpm' | tee rpms.txt
assert_file_has_content rpms.txt 'fedora-atomic-host-42.1.*x86_64'
path=$(head -1 rpms.txt)
rpm -qp --requires ${path} > requires.txt
assert_file_has_content requires.txt 'glibc = '
assert_file_has_content requires.txt 'systemd = '
assert_file_has_content requires.txt 'test-pkg = 1.0-1'
# And pull it; we should download the newer version by default
do_jigdo2commit

View File

@ -7,7 +7,7 @@ Version: %{ostree_version}
Release: 1%{?dist}
Summary: Image (rpm-ostree jigdo) for Fedora Atomic Host
License: MIT
%{rpmostree_jigdo_meta}
#@@@rpmostree_jigdo_meta@@@
%description
%{summary}