From 71e1e9d18eb3d3c3fa526725b6c9f3e6b92e40c3 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Thu, 22 Aug 2019 18:06:53 +0000 Subject: [PATCH 01/16] Post-release version bump Closes: #1902 Approved by: rfairley --- configure.ac | 4 ++-- src/libostree/libostree-devel.sym | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index 15c60bb4..069bab01 100644 --- a/configure.ac +++ b/configure.ac @@ -4,10 +4,10 @@ dnl update libostree-released.sym from libostree-devel.sym, and update the check dnl in test-symbols.sh, and also set is_release_build=yes below. Then make dnl another post-release commit to bump the version, and set is_release_build=no. m4_define([year_version], [2019]) -m4_define([release_version], [3]) +m4_define([release_version], [4]) m4_define([package_version], [year_version.release_version]) AC_INIT([libostree], [package_version], [walters@verbum.org]) -is_release_build=yes +is_release_build=no AC_CONFIG_HEADER([config.h]) AC_CONFIG_MACRO_DIR([buildutil]) AC_CONFIG_AUX_DIR([build-aux]) diff --git a/src/libostree/libostree-devel.sym b/src/libostree/libostree-devel.sym index 9339c0fd..f552bcea 100644 --- a/src/libostree/libostree-devel.sym +++ b/src/libostree/libostree-devel.sym @@ -18,6 +18,8 @@ ***/ /* Add new symbols here. Release commits should copy this section into -released.sym. */ +LIBOSTREE_2019.4 { +} LIBOSTREE_2019.3; /* Stub section for the stable release *after* this development one; don't * edit this other than to update the year. This is just a copy/paste From 93999d337e521a4be3aa4ae7820835802986d394 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Mon, 26 Aug 2019 17:43:26 +0000 Subject: [PATCH 02/16] sysroot: Add a clearer error if /boot/loader isn't found I've seen people confused by this error in the case where `/boot` isn't mounted or the BLS fragments were deleted, etc. If you understand ostree deeply it's clear but, let's do better here and a direct error message for the case where we can't find `/boot/loader` which is the majority of these. The other case could happen if e.g. just the BLS fragment for the booted deployment was deleted; let's reword that one a bit too. Closes: #1905 Approved by: rfairley --- src/libostree/ostree-sysroot.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/libostree/ostree-sysroot.c b/src/libostree/ostree-sysroot.c index b3ad2498..2c0c0546 100644 --- a/src/libostree/ostree-sysroot.c +++ b/src/libostree/ostree-sysroot.c @@ -959,7 +959,18 @@ ostree_sysroot_load_if_changed (OstreeSysroot *self, } if (self->root_is_ostree_booted && !self->booted_deployment) - return glnx_throw (error, "Unexpected state: /run/ostree-booted found and in / sysroot but not in a booted deployment"); + { + if (!glnx_fstatat_allow_noent (self->sysroot_fd, "boot/loader", NULL, AT_SYMLINK_NOFOLLOW, error)) + return FALSE; + if (errno == ENOENT) + { + return glnx_throw (error, "Unexpected state: /run/ostree-booted found, but no /boot/loader directory"); + } + else + { + return glnx_throw (error, "Unexpected state: /run/ostree-booted found and in / sysroot, but bootloader entry not found"); + } + } if (!_ostree_sysroot_reload_staged (self, error)) return FALSE; From d85366d52a3c837fc11d93043f023d37b6b228aa Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Wed, 28 Aug 2019 18:59:10 +0000 Subject: [PATCH 03/16] ci: Add prow/ subdirectory with Dockerfile I'd like to add OpenShift's prow to this repository. Let's start by adding a Dockerfile - it doesn't really do anything besides build. However...I've lately been thinking about e.g. shipping the ostree tests as an image, and then e.g. we could test FCOS by running that container (which would orchestrate the *host's* ostree). Anyways, not doing that right now but this is a start. Also this cherry picks the fix from rpm-ostree CI for the sad Fedora release package brokenness. Closes: #1906 Approved by: cgwalters --- ci/libpaprci/libbuild.sh | 8 +++++++- ci/prow/Dockerfile | 4 ++++ 2 files changed, 11 insertions(+), 1 deletion(-) create mode 100644 ci/prow/Dockerfile diff --git a/ci/libpaprci/libbuild.sh b/ci/libpaprci/libbuild.sh index a7c774e7..a8ade0d7 100644 --- a/ci/libpaprci/libbuild.sh +++ b/ci/libpaprci/libbuild.sh @@ -35,7 +35,13 @@ pkg_install_if_os() { pkg_install_buildroot() { case "${OS_ID}" in - fedora) pkg_install dnf-plugins-core @buildsys-build;; + fedora) + # https://github.com/projectatomic/rpm-ostree/pull/1889/commits/9ff611758bea22b0ad4892cc16182dd1f7f47e89 + # https://fedoraproject.org/wiki/Common_F30_bugs#Conflicts_between_fedora-release_packages_when_installing_package_groups + if rpm -q fedora-release-container; then + yum -y swap fedora-release{-container,} + fi + pkg_install dnf-plugins-core @buildsys-build;; centos) pkg_install yum-utils # Base buildroot, copied from the mock config sadly pkg_install bash bzip2 coreutils cpio diffutils system-release findutils gawk gcc gcc-c++ \ diff --git a/ci/prow/Dockerfile b/ci/prow/Dockerfile new file mode 100644 index 00000000..b1f83c01 --- /dev/null +++ b/ci/prow/Dockerfile @@ -0,0 +1,4 @@ +FROM registry.fedoraproject.org/fedora:30 +WORKDIR /src +COPY . . +RUN ./ci/build.sh From f82f825fed8253b24eeb9c2d5447089348993862 Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Tue, 27 Aug 2019 02:12:19 +0200 Subject: [PATCH 04/16] lib/bootconfig-parser: Remove support to preserve comments in BLS files OSTree has some logic to preserve comment lines in the BLS fragments, but the BLS fragments are always created on new deployments so the comments are never carried. Also, OSTree never writes BLS fragments with comments so these will only be present in BLS files that were modified outside of OSTree. Something that should be avoided in general. Finally, there is a bug in the logic that causes BLS files to have lines with only a newline character. The ostree_bootconfig_parser_parse_at() function reads the bootconfig file using glnx_fd_readall_utf8() but this function NUL terminates the returned string with the file contents. So when the string is later split using '\n' as delimiter, the last token is set to '\0' and a wrong GVariant will be added to the lines GPtrArray in the OstreeBootconfigParser struct. This will lead to bootconfig files that contains lines with only a newline character, since the key in the GVariant would be set to NUL and won't be present in the options GHashTable of the OstreeBootconfigParser struct. So let's just remove that logic since is never used and makes BLS files to have wrong empty lines. Before this patch: $ tail -n 4 /boot/loader/entries/ostree-1-testos.conf | hexdump -C 00000000 74 69 74 6c 65 20 54 65 73 74 4f 53 20 34 32 20 |title TestOS 42 | 00000010 32 30 31 39 30 38 32 34 2e 30 20 28 6f 73 74 72 |20190824.0 (ostr| 00000020 65 65 29 0a 0a 0a 0a |ee)....| 00000027 After this patch: $ tail -n 4 /boot/loader/entries/ostree-1-testos.conf | hexdump -C 00000000 76 65 72 73 69 6f 6e 20 31 0a 6f 70 74 69 6f 6e |version 1.option| 00000010 73 20 72 6f 6f 74 3d 4c 41 42 45 4c 3d 4d 4f 4f |s root=LABEL=MOO| 00000020 20 71 75 69 65 74 20 6f 73 74 72 65 65 3d 2f 6f | quiet ostree=/o| 00000030 73 74 72 65 65 2f 62 6f 6f 74 2e 31 2f 74 65 73 |stree/boot.1/tes| 00000040 74 6f 73 2f 61 65 34 36 34 39 36 38 30 64 33 65 |tos/ae4649680d3e| 00000050 38 33 62 32 34 65 34 37 66 38 64 66 31 30 38 31 |83b24e47f8df1081| 00000060 38 62 66 36 39 38 39 64 36 34 37 61 62 32 38 38 |8bf6989d647ab288| 00000070 64 31 63 30 39 38 30 36 65 34 61 33 36 61 34 65 |d1c09806e4a36a4e| 00000080 62 62 66 36 2f 30 0a 6c 69 6e 75 78 20 2f 6f 73 |bbf6/0.linux /os| 00000090 74 72 65 65 2f 74 65 73 74 6f 73 2d 61 65 34 36 |tree/testos-ae46| 000000a0 34 39 36 38 30 64 33 65 38 33 62 32 34 65 34 37 |49680d3e83b24e47| 000000b0 66 38 64 66 31 30 38 31 38 62 66 36 39 38 39 64 |f8df10818bf6989d| 000000c0 36 34 37 61 62 32 38 38 64 31 63 30 39 38 30 36 |647ab288d1c09806| 000000d0 65 34 61 33 36 61 34 65 62 62 66 36 2f 76 6d 6c |e4a36a4ebbf6/vml| 000000e0 69 6e 75 7a 2d 33 2e 36 2e 30 0a 74 69 74 6c 65 |inuz-3.6.0.title| 000000f0 20 54 65 73 74 4f 53 20 34 32 20 32 30 31 39 30 | TestOS 42 20190| 00000100 38 32 34 2e 30 20 28 6f 73 74 72 65 65 29 0a |824.0 (ostree).| 0000010f Closes: #1904 Approved by: cgwalters --- src/libostree/ostree-bootconfig-parser.c | 38 +----------------------- 1 file changed, 1 insertion(+), 37 deletions(-) diff --git a/src/libostree/ostree-bootconfig-parser.c b/src/libostree/ostree-bootconfig-parser.c index 25da6657..3d4944cc 100644 --- a/src/libostree/ostree-bootconfig-parser.c +++ b/src/libostree/ostree-bootconfig-parser.c @@ -30,7 +30,6 @@ struct _OstreeBootconfigParser const char *separators; GHashTable *options; - GPtrArray *lines; }; typedef GObjectClass OstreeBootconfigParserClass; @@ -48,9 +47,6 @@ ostree_bootconfig_parser_clone (OstreeBootconfigParser *self) { OstreeBootconfigParser *parser = ostree_bootconfig_parser_new (); - for (guint i = 0; i < self->lines->len; i++) - g_ptr_array_add (parser->lines, g_variant_ref (self->lines->pdata[i])); - GLNX_HASH_TABLE_FOREACH_KV (self->options, const char*, k, const char*, v) g_hash_table_replace (parser->options, g_strdup (k), g_strdup (v)); @@ -84,7 +80,6 @@ ostree_bootconfig_parser_parse_at (OstreeBootconfigParser *self, for (char **iter = lines; *iter; iter++) { const char *line = *iter; - char *keyname = ""; if (g_ascii_isalpha (*line)) { @@ -92,7 +87,6 @@ ostree_bootconfig_parser_parse_at (OstreeBootconfigParser *self, items = g_strsplit_set (line, self->separators, 2); if (g_strv_length (items) == 2 && items[0][0] != '\0') { - keyname = items[0]; g_hash_table_insert (self->options, items[0], items[1]); g_free (items); /* Transfer ownership */ } @@ -101,7 +95,6 @@ ostree_bootconfig_parser_parse_at (OstreeBootconfigParser *self, g_strfreev (items); } } - g_ptr_array_add (self->lines, g_variant_new ("(ss)", keyname, line)); } self->parsed = TRUE; @@ -154,36 +147,9 @@ ostree_bootconfig_parser_write_at (OstreeBootconfigParser *self, GError **error) { g_autoptr(GString) buf = g_string_new (""); - g_autoptr(GHashTable) written_overrides = g_hash_table_new (g_str_hash, g_str_equal); - - for (guint i = 0; i < self->lines->len; i++) - { - GVariant *linedata = self->lines->pdata[i]; - const char *key; - const char *value; - const char *line; - - g_variant_get (linedata, "(&s&s)", &key, &line); - - value = g_hash_table_lookup (self->options, key); - if (value == NULL) - { - g_string_append (buf, line); - g_string_append_c (buf, '\n'); - } - else - { - write_key (self, buf, key, value); - g_hash_table_add (written_overrides, (gpointer)key); - } - } GLNX_HASH_TABLE_FOREACH_KV (self->options, const char*, k, const char*, v) - { - if (g_hash_table_lookup (written_overrides, k)) - continue; - write_key (self, buf, k, v); - } + write_key (self, buf, k, v); if (!glnx_file_replace_contents_at (dfd, path, (guint8*)buf->str, buf->len, GLNX_FILE_REPLACE_NODATASYNC, @@ -210,7 +176,6 @@ ostree_bootconfig_parser_finalize (GObject *object) OstreeBootconfigParser *self = OSTREE_BOOTCONFIG_PARSER (object); g_hash_table_unref (self->options); - g_ptr_array_unref (self->lines); G_OBJECT_CLASS (ostree_bootconfig_parser_parent_class)->finalize (object); } @@ -219,7 +184,6 @@ static void ostree_bootconfig_parser_init (OstreeBootconfigParser *self) { self->options = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); - self->lines = g_ptr_array_new_with_free_func ((GDestroyNotify)g_variant_unref); } void From 2ca2b88f51c3131c3aa2322fe26bae2cee7e76fa Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Tue, 27 Aug 2019 02:12:29 +0200 Subject: [PATCH 05/16] lib/bootconfig-parser: Write BLS fragment fields in a deterministic order Currently the BLS fragments fields write is non-determinisitc. The order of the fields will depend on how the iterator of the options GHashTable iterates over the key/value pairs. But some bootloaders expect the fields to be written in a certain order. For example the zipl bootloader (used in the s390x architecture) fails to parse BLS files if the first field is not the 'title' field, since that's used to name the zipl boot sections that are created from the BLS files. Write the fields in a deterministic order, following what is used in the example file of the BootLoaderspec document: https://systemd.io/BOOT_LOADER_SPECIFICATION Related: https://github.com/ostreedev/ostree/issues/1888 Closes: #1904 Approved by: cgwalters --- src/libostree/ostree-bootconfig-parser.c | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/src/libostree/ostree-bootconfig-parser.c b/src/libostree/ostree-bootconfig-parser.c index 3d4944cc..67f9fb58 100644 --- a/src/libostree/ostree-bootconfig-parser.c +++ b/src/libostree/ostree-bootconfig-parser.c @@ -146,10 +146,32 @@ ostree_bootconfig_parser_write_at (OstreeBootconfigParser *self, GCancellable *cancellable, GError **error) { + /* Write the fields in a deterministic order, following what is used + * in the bootconfig example of the BootLoaderspec document: + * https://systemd.io/BOOT_LOADER_SPECIFICATION + */ + const char *fields[] = { "title", "version", "options", "devicetree", "linux", "initrd" }; + g_autoptr(GHashTable) keys_written = g_hash_table_new (g_str_hash, g_str_equal); g_autoptr(GString) buf = g_string_new (""); + for (guint i = 0; i < G_N_ELEMENTS (fields); i++) + { + const char *key = fields[i]; + const char *value = g_hash_table_lookup (self->options, key); + if (value != NULL) + { + write_key (self, buf, key, value); + g_hash_table_add (keys_written, (gpointer)key); + } + } + + /* Write unknown fields */ GLNX_HASH_TABLE_FOREACH_KV (self->options, const char*, k, const char*, v) - write_key (self, buf, k, v); + { + if (g_hash_table_lookup (keys_written, k)) + continue; + write_key (self, buf, k, v); + } if (!glnx_file_replace_contents_at (dfd, path, (guint8*)buf->str, buf->len, GLNX_FILE_REPLACE_NODATASYNC, From d42f970ed30c1f2f293ee864f32de44b3608b9ac Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Mon, 2 Sep 2019 11:36:12 +0200 Subject: [PATCH 06/16] lib/bootconfig-parser: Always include deployment index in BLS title If there are different deployments for the same commit version, the BLS snippets will have the same title fields (but different version fields): $ grep title * ostree-1-testos.conf:title TestOS 42 20190902.0 (ostree) ostree-2-testos.conf:title TestOS 42 20190902.0 (ostree) ostree-3-testos.conf:title TestOS 42 20190902.0 (ostree) But bootloaders could expect the title field to be unique for BLS files. For example, the zipl bootloader used in the s390x architecture uses the field to name the boot sections that are created from the BLS snippets. So two BLS snippets having the same title would lead to zipl failing to create the IPL boot sections because they would have duplicated names: $ zipl Using config file '/etc/zipl.conf' Using BLS config file '/boot/loader/entries/ostree-3-testos.conf' Using BLS config file '/boot/loader/entries/ostree-2-testos.conf' Using BLS config file '/boot/loader/entries/ostree-1-testos.conf' Error: Config file '/etc/zipl.conf': Line 0: section name 'TestOS 42 20190902.0 (ostree)' already specified Avoid this by always including the deployment index along with the commit version in the title field, so this will be unique even if there are BLS files for deployments that use the same commit version: $ grep title * ostree-1-testos.conf:title TestOS 42 20190902.0 (ostree:2) ostree-2-testos.conf:title TestOS 42 20190902.0 (ostree:1) ostree-3-testos.conf:title TestOS 42 20190902.0 (ostree:0) $ zipl Using config file '/etc/zipl.conf' Using BLS config file '/boot/loader/entries/ostree-3-testos.conf' Using BLS config file '/boot/loader/entries/ostree-2-testos.conf' Using BLS config file '/boot/loader/entries/ostree-1-testos.conf' Building bootmap in '/boot' Building menu 'zipl-automatic-menu' Adding #1: IPL section 'TestOS 42 20190902.0 (ostree:0)' (default) Adding #2: IPL section 'TestOS 42 20190902.0 (ostree:1)' Adding #3: IPL section 'TestOS 42 20190902.0 (ostree:2)' Preparing boot device: dasda (0120). Done. Closes: #1911 Approved by: cgwalters --- src/libostree/ostree-sysroot-deploy.c | 7 +++---- tests/admin-test.sh | 4 ++-- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/libostree/ostree-sysroot-deploy.c b/src/libostree/ostree-sysroot-deploy.c index 9de5464a..c342d7e0 100644 --- a/src/libostree/ostree-sysroot-deploy.c +++ b/src/libostree/ostree-sysroot-deploy.c @@ -1746,10 +1746,9 @@ install_deployment_kernel (OstreeSysroot *sysroot, g_string_append_c (title_key, ':'); g_string_append (title_key, osname); } - if (!(deployment_version && *deployment_version)) - { - g_string_append_printf (title_key, ":%d", ostree_deployment_get_index (deployment)); - } + + g_string_append_printf (title_key, ":%d", ostree_deployment_get_index (deployment)); + g_string_append_c (title_key, ')'); ostree_bootconfig_parser_set (bootconfig, "title", title_key->str); diff --git a/tests/admin-test.sh b/tests/admin-test.sh index 0defebc0..11b9ea14 100644 --- a/tests/admin-test.sh +++ b/tests/admin-test.sh @@ -290,10 +290,10 @@ echo "ok upgrade with multiple kernel args" os_repository_new_commit ${CMD_PREFIX} ostree admin upgrade --os=testos -assert_file_has_content sysroot/boot/loader/entries/ostree-4-testos.conf "^title TestOS 42 ${version} (ostree:testos)$" +assert_file_has_content sysroot/boot/loader/entries/ostree-4-testos.conf "^title TestOS 42 ${version} (ostree:testos:0)$" os_repository_new_commit 0 0 testos/buildmaster/x86_64-runtime 42 ${CMD_PREFIX} ostree admin upgrade --os=testos -assert_file_has_content sysroot/boot/loader/entries/ostree-4-testos.conf "^title TestOS 42 (ostree:testos)$" +assert_file_has_content sysroot/boot/loader/entries/ostree-4-testos.conf "^title TestOS 42 (ostree:testos:0)$" echo "ok no duplicate version strings in title" From 522d31b2d4604026f1c0a442887ca9d4b319e9cc Mon Sep 17 00:00:00 2001 From: Dan Nicholson Date: Thu, 15 Aug 2019 22:24:54 -0600 Subject: [PATCH 07/16] lib/gpg: Only show gpg-connect-agent stderr on failures When listing GPG keys, the temporary GPG homedir will be constructed by simply copying the remote's trusted keys to the pubring.gpg file. In that case, no GPG operations spawning gpg-agent will be run. When gpg-connect-agent is run to cleanup the homedir, it will helpfully print on stderr that it's starting gpg-agent like so: gpg-connect-agent: no running gpg-agent - starting '/usr/bin/gpg-agent' gpg-connect-agent: waiting for the agent to come up ... (5s) gpg-connect-agent: connection to agent established Send gpg-connect-agent's stderr to a pipe and only send it to the application's stderr if an error was encountered. Fixes: #1907 Closes: #1908 Approved by: cgwalters --- src/libotutil/ot-gpg-utils.c | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/src/libotutil/ot-gpg-utils.c b/src/libotutil/ot-gpg-utils.c index cf5ce3ea..35e854b3 100644 --- a/src/libotutil/ot-gpg-utils.c +++ b/src/libotutil/ot-gpg-utils.c @@ -25,6 +25,7 @@ #include +#include #include "libglnx.h" /* Like glnx_throw_errno_prefix, but takes @gpg_error */ @@ -445,19 +446,27 @@ ot_gpgme_kill_agent (const char *homedir) /* Run gpg-connect-agent killagent /bye */ g_autoptr(GError) local_error = NULL; - g_autoptr(GSubprocess) proc = g_subprocess_new(G_SUBPROCESS_FLAGS_STDOUT_SILENCE, - &local_error, - "gpg-connect-agent", - "--homedir", - homedir, - "killagent", - "/bye", - NULL); + GSubprocessFlags flags = G_SUBPROCESS_FLAGS_STDOUT_SILENCE | G_SUBPROCESS_FLAGS_STDERR_PIPE; + g_autoptr(GSubprocess) proc = g_subprocess_new (flags, + &local_error, + "gpg-connect-agent", + "--homedir", + homedir, + "killagent", + "/bye", + NULL); if (proc == NULL) { g_debug ("Spawning gpg-connect-agent failed: %s", local_error->message); return; } if (!g_subprocess_wait_check (proc, NULL, &local_error)) { + /* Dump out stderr on failures */ + GInputStream *stderr_in = g_subprocess_get_stderr_pipe (proc); + g_autoptr(GOutputStream) stderr_out = + G_OUTPUT_STREAM (g_unix_output_stream_new (STDERR_FILENO, FALSE)); + g_output_stream_splice (stderr_out, stderr_in, G_OUTPUT_STREAM_SPLICE_NONE, + NULL, NULL); + g_debug ("Killing GPG agent with gpg-connect-agent failed: %s", local_error->message); return; From d14472a7f04d02d392d2754cfb3cec881aadc704 Mon Sep 17 00:00:00 2001 From: Dan Nicholson Date: Thu, 5 Sep 2019 12:20:04 -0600 Subject: [PATCH 08/16] lib/gpg: Don't kill gpg-agent on newer gnupg GnuPG 2.1.17 contains a bug fix so that `gpg-agent` is killed when the entire GPG home directory is deleted[1]. If the host's GnuPG is new enough, then we don't need to bother calling `gpg-connect-agent` to kill the agent since it will be cleaned up on its own. Get the GnuPG version from the GPGME OpenPGP engine info and parse it to see if it matches this criteria. 1. https://dev.gnupg.org/T2756 Closes: #1915 Approved by: cgwalters --- src/libotutil/ot-gpg-utils.c | 65 ++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/src/libotutil/ot-gpg-utils.c b/src/libotutil/ot-gpg-utils.c index 35e854b3..97a1c756 100644 --- a/src/libotutil/ot-gpg-utils.c +++ b/src/libotutil/ot-gpg-utils.c @@ -439,14 +439,79 @@ ot_gpgme_new_ctx (const char *homedir, return g_steal_pointer (&context); } +static gboolean +get_gnupg_version (guint *major, + guint *minor, + guint *patch) +{ + g_return_val_if_fail (major != NULL, FALSE); + g_return_val_if_fail (minor != NULL, FALSE); + g_return_val_if_fail (patch != NULL, FALSE); + + gpgme_engine_info_t info; + gpgme_error_t err = gpgme_get_engine_info (&info); + if (err != GPG_ERR_NO_ERROR) + { + g_debug ("Failed to get GPGME engine info: %s: %s", + gpgme_strsource (err), gpgme_strerror (err)); + return FALSE; + } + + const char *gnupg_version = NULL; + for (; info != NULL; info = info->next) + { + if (info->protocol == GPGME_PROTOCOL_OpenPGP) + { + gnupg_version = info->version; + break; + } + } + + if (gnupg_version == NULL) + { + g_debug ("Could not determine GnuPG version"); + return FALSE; + } + + g_auto(GStrv) parts = g_strsplit (gnupg_version, ".", 4); + if (g_strv_length (parts) < 3) + { + g_debug ("Less than 3 components in GnuPG version \"%s\"", gnupg_version); + return FALSE; + } + + *major = g_ascii_strtoull (parts[0], NULL, 10); + *minor = g_ascii_strtoull (parts[1], NULL, 10); + *patch = g_ascii_strtoull (parts[2], NULL, 10); + + return TRUE; +} + void ot_gpgme_kill_agent (const char *homedir) { g_return_if_fail (homedir != NULL); + /* If gnupg is at least 2.1.17, gpg-agent will exit when the homedir + * is deleted. + */ + guint gnupg_major = 0, gnupg_minor = 0, gnupg_patch = 0; + if (get_gnupg_version (&gnupg_major, &gnupg_minor, &gnupg_patch)) + { + if ((gnupg_major > 2) || + (gnupg_major == 2 && gnupg_minor > 1) || + (gnupg_major == 2 && gnupg_minor == 1 && gnupg_patch >= 17)) + { + /* Note early return */ + g_debug ("GnuPG >= 2.1.17, skipping gpg-agent cleanup in %s", homedir); + return; + } + } + /* Run gpg-connect-agent killagent /bye */ g_autoptr(GError) local_error = NULL; GSubprocessFlags flags = G_SUBPROCESS_FLAGS_STDOUT_SILENCE | G_SUBPROCESS_FLAGS_STDERR_PIPE; + g_debug ("Killing gpg-agent in %s", homedir); g_autoptr(GSubprocess) proc = g_subprocess_new (flags, &local_error, "gpg-connect-agent", From e49060c207fd201f71316bf174e1b467827abc7a Mon Sep 17 00:00:00 2001 From: Dan Nicholson Date: Fri, 6 Sep 2019 16:52:15 -0600 Subject: [PATCH 09/16] lib/gpg: Use g_spawn_sync to kill gpg-agent For reasons I don't understand, GSubprocess doesn't play nice with KDE's plasmashell. I assume this has something to do with the GSubprocess using the glib worker thread while plasmashell uses the glib main loop. Instead, just use g_spawn_sync to fork and wait in the current thread. Fixes: #1913 Closes: #1917 Approved by: cgwalters --- src/libotutil/ot-gpg-utils.c | 53 ++++++++++++++++++------------------ 1 file changed, 27 insertions(+), 26 deletions(-) diff --git a/src/libotutil/ot-gpg-utils.c b/src/libotutil/ot-gpg-utils.c index 97a1c756..743d941e 100644 --- a/src/libotutil/ot-gpg-utils.c +++ b/src/libotutil/ot-gpg-utils.c @@ -509,31 +509,32 @@ ot_gpgme_kill_agent (const char *homedir) } /* Run gpg-connect-agent killagent /bye */ - g_autoptr(GError) local_error = NULL; - GSubprocessFlags flags = G_SUBPROCESS_FLAGS_STDOUT_SILENCE | G_SUBPROCESS_FLAGS_STDERR_PIPE; - g_debug ("Killing gpg-agent in %s", homedir); - g_autoptr(GSubprocess) proc = g_subprocess_new (flags, - &local_error, - "gpg-connect-agent", - "--homedir", - homedir, - "killagent", - "/bye", - NULL); - if (proc == NULL) { - g_debug ("Spawning gpg-connect-agent failed: %s", local_error->message); - return; - } - if (!g_subprocess_wait_check (proc, NULL, &local_error)) { - /* Dump out stderr on failures */ - GInputStream *stderr_in = g_subprocess_get_stderr_pipe (proc); - g_autoptr(GOutputStream) stderr_out = - G_OUTPUT_STREAM (g_unix_output_stream_new (STDERR_FILENO, FALSE)); - g_output_stream_splice (stderr_out, stderr_in, G_OUTPUT_STREAM_SPLICE_NONE, - NULL, NULL); + g_autoptr(GPtrArray) argv = g_ptr_array_new (); + g_ptr_array_add (argv, "gpg-connect-agent"); + g_ptr_array_add (argv, "--homedir"); + g_ptr_array_add (argv, (gpointer)homedir); + g_ptr_array_add (argv, "killagent"); + g_ptr_array_add (argv, "/bye"); + g_ptr_array_add (argv, NULL); - g_debug ("Killing GPG agent with gpg-connect-agent failed: %s", - local_error->message); - return; - } + g_autoptr(GError) local_error = NULL; + GSpawnFlags flags = G_SPAWN_SEARCH_PATH | G_SPAWN_STDOUT_TO_DEV_NULL; + gint proc_status = 0; + g_autofree gchar *proc_stderr = NULL; + g_debug ("Killing gpg-agent in %s", homedir); + if (!g_spawn_sync (NULL, (char **)argv->pdata, NULL, flags, NULL, NULL, + NULL, &proc_stderr, &proc_status, &local_error)) + { + g_debug ("Spawning gpg-connect-agent failed: %s", local_error->message); + return; + } + if (!g_spawn_check_exit_status (proc_status, &local_error)) + { + /* Dump out stderr on failures */ + g_printerr ("%s", proc_stderr); + + g_debug ("Killing GPG agent with gpg-connect-agent failed: %s", + local_error->message); + return; + } } From b709c3c67bcaf3651ff2dd1d5a5f8680cf20d50c Mon Sep 17 00:00:00 2001 From: Jason Wessel Date: Wed, 10 Jul 2019 14:47:27 -0400 Subject: [PATCH 10/16] fsck: Implement a partial commit reason bitmask After the corruption has been fixed with "ostree fsck -a --delete", a second run of the "ostree fsck" command will print X partial commits not verified and exit with a zero. The zero exit code makes it hard to detect if a repair operation needs to be run. When ever fsck creates a partial commit it should add a reason for the partial commit to the state file found in state/.commitpartial. This will allow a future execution of the fsck to still return an error indicating that the repository is still in the damaged state, awaiting repair. Additional reason codes could be added in the future for why a partial commit exists. Text from: https://github.com/ostreedev/ostree/pull/1880 ==== cgwalters commented: To restate, the core issue is that it's valid to have partial commits for reasons other than fsck pruned bad objects, and libostree doesn't have a way to distinguish. Another option perhaps is to write e.g. fsck-partial into the statefile state/.commitpartial which would mean "partial, and expected to exist but was pruned by fsck" and fsck would continue to error out until the commit was re-pulled. Right now the partial stamp file is empty, so it'd be fully compatible to write a rationale into it. ==== Signed-off-by: Jason Wessel Closes: #1910 Approved by: cgwalters --- apidoc/ostree-sections.txt | 1 + src/libostree/libostree-devel.sym | 1 + src/libostree/ostree-repo-commit.c | 79 ++++++++++++++++++++++-------- src/libostree/ostree-repo.c | 15 ++++-- src/libostree/ostree-repo.h | 44 ++++++++++------- src/ostree/ot-builtin-fsck.c | 12 ++++- 6 files changed, 109 insertions(+), 43 deletions(-) diff --git a/apidoc/ostree-sections.txt b/apidoc/ostree-sections.txt index e8faeb10..252a563a 100644 --- a/apidoc/ostree-sections.txt +++ b/apidoc/ostree-sections.txt @@ -333,6 +333,7 @@ ostree_repo_set_cache_dir ostree_repo_sign_delta ostree_repo_has_object ostree_repo_mark_commit_partial +ostree_repo_mark_commit_partial_reason ostree_repo_write_metadata ostree_repo_write_metadata_async ostree_repo_write_metadata_finish diff --git a/src/libostree/libostree-devel.sym b/src/libostree/libostree-devel.sym index f552bcea..58d35f55 100644 --- a/src/libostree/libostree-devel.sym +++ b/src/libostree/libostree-devel.sym @@ -19,6 +19,7 @@ /* Add new symbols here. Release commits should copy this section into -released.sym. */ LIBOSTREE_2019.4 { + ostree_repo_mark_commit_partial_reason; } LIBOSTREE_2019.3; /* Stub section for the stable release *after* this development one; don't diff --git a/src/libostree/ostree-repo-commit.c b/src/libostree/ostree-repo-commit.c index e7bc9820..0aaebbdb 100644 --- a/src/libostree/ostree-repo-commit.c +++ b/src/libostree/ostree-repo-commit.c @@ -1873,6 +1873,57 @@ ensure_txn_refs (OstreeRepo *self) g_free); } +/** + * ostree_repo_mark_commit_partial_reason: + * @self: Repo + * @checksum: Commit SHA-256 + * @is_partial: Whether or not this commit is partial + * @in_state: Reason bitmask for partial commit + * @error: Error + * + * Allows the setting of a reason code for a partial commit. Presently + * it only supports setting reason bitmask to + * OSTREE_REPO_COMMIT_STATE_FSCK_PARTIAL, or + * OSTREE_REPO_COMMIT_STATE_NORMAL. This will allow successive ostree + * fsck operations to exit properly with an error code if the + * repository has been truncated as a result of fsck trying to repair + * it. + * + * Since: 2019.4 + */ +gboolean +ostree_repo_mark_commit_partial_reason (OstreeRepo *self, + const char *checksum, + gboolean is_partial, + OstreeRepoCommitState in_state, + GError **error) +{ + g_autofree char *commitpartial_path = _ostree_get_commitpartial_path (checksum); + if (is_partial) + { + glnx_autofd int fd = openat (self->repo_dir_fd, commitpartial_path, + O_EXCL | O_CREAT | O_WRONLY | O_CLOEXEC | O_NOCTTY, 0644); + if (fd == -1) + { + if (errno != EEXIST) + return glnx_throw_errno_prefix (error, "open(%s)", commitpartial_path); + } + else + { + if (in_state & OSTREE_REPO_COMMIT_STATE_FSCK_PARTIAL) + if (glnx_loop_write (fd, "f", 1) < 0) + return glnx_throw_errno_prefix (error, "write(%s)", commitpartial_path); + } + } + else + { + if (!ot_ensure_unlinked_at (self->repo_dir_fd, commitpartial_path, 0)) + return FALSE; + } + + return TRUE; +} + /** * ostree_repo_mark_commit_partial: * @self: Repo @@ -1880,9 +1931,10 @@ ensure_txn_refs (OstreeRepo *self) * @is_partial: Whether or not this commit is partial * @error: Error * - * Commits in "partial" state do not have all their child objects written. This - * occurs in various situations, such as during a pull, but also if a "subpath" - * pull is used, as well as "commit only" pulls. + * Commits in the "partial" state do not have all their child objects + * written. This occurs in various situations, such as during a pull, + * but also if a "subpath" pull is used, as well as "commit only" + * pulls. * * This function is used by ostree_repo_pull_with_options(); you * should use this if you are implementing a different type of transport. @@ -1895,24 +1947,9 @@ ostree_repo_mark_commit_partial (OstreeRepo *self, gboolean is_partial, GError **error) { - g_autofree char *commitpartial_path = _ostree_get_commitpartial_path (checksum); - if (is_partial) - { - glnx_autofd int fd = openat (self->repo_dir_fd, commitpartial_path, - O_EXCL | O_CREAT | O_WRONLY | O_CLOEXEC | O_NOCTTY, 0644); - if (fd == -1) - { - if (errno != EEXIST) - return glnx_throw_errno_prefix (error, "open(%s)", commitpartial_path); - } - } - else - { - if (!ot_ensure_unlinked_at (self->repo_dir_fd, commitpartial_path, 0)) - return FALSE; - } - - return TRUE; + return ostree_repo_mark_commit_partial_reason (self, checksum, is_partial, + OSTREE_REPO_COMMIT_STATE_NORMAL, + error); } /** diff --git a/src/libostree/ostree-repo.c b/src/libostree/ostree-repo.c index eb652bef..b654aff2 100644 --- a/src/libostree/ostree-repo.c +++ b/src/libostree/ostree-repo.c @@ -3768,10 +3768,19 @@ load_metadata_internal (OstreeRepo *self, g_autofree char *commitpartial_path = _ostree_get_commitpartial_path (sha256); *out_state = 0; - if (!glnx_fstatat_allow_noent (self->repo_dir_fd, commitpartial_path, NULL, 0, error)) + glnx_autofd int fd = -1; + if (!ot_openat_ignore_enoent (self->repo_dir_fd, commitpartial_path, &fd, error)) return FALSE; - if (errno == 0) - *out_state |= OSTREE_REPO_COMMIT_STATE_PARTIAL; + if (fd != -1) + { + *out_state |= OSTREE_REPO_COMMIT_STATE_PARTIAL; + char reason; + if (read (fd, &reason, 1) == 1) + { + if (reason == 'f') + *out_state |= OSTREE_REPO_COMMIT_STATE_FSCK_PARTIAL; + } + } } } else if (self->parent_repo) diff --git a/src/libostree/ostree-repo.h b/src/libostree/ostree-repo.h index 038bbd41..aaaaa622 100644 --- a/src/libostree/ostree-repo.h +++ b/src/libostree/ostree-repo.h @@ -248,6 +248,26 @@ gboolean ostree_repo_write_config (OstreeRepo *self, GKeyFile *new_config, GError **error); +/** + * OstreeRepoCommitState: + * @OSTREE_REPO_COMMIT_STATE_NORMAL: Commit is complete. This is the default. + * (Since: 2017.14.) + * @OSTREE_REPO_COMMIT_STATE_PARTIAL: One or more objects are missing from the + * local copy of the commit, but metadata is present. (Since: 2015.7.) + * @OSTREE_REPO_COMMIT_STATE_FSCK_PARTIAL: One or more objects are missing from the + * local copy of the commit, due to an fsck --delete. (Since: 2019.3.) + * + * Flags representing the state of a commit in the local repository, as returned + * by ostree_repo_load_commit(). + * + * Since: 2015.7 + */ +typedef enum { + OSTREE_REPO_COMMIT_STATE_NORMAL = 0, + OSTREE_REPO_COMMIT_STATE_PARTIAL = (1 << 0), + OSTREE_REPO_COMMIT_STATE_FSCK_PARTIAL = (1 << 1), +} OstreeRepoCommitState; + /** * OstreeRepoTransactionStats: * @metadata_objects_total: The total number of metadata objects @@ -315,6 +335,13 @@ gboolean ostree_repo_mark_commit_partial (OstreeRepo *self, gboolean is_partial, GError **error); +_OSTREE_PUBLIC +gboolean ostree_repo_mark_commit_partial_reason (OstreeRepo *self, + const char *checksum, + gboolean is_partial, + OstreeRepoCommitState in_state, + GError **error); + _OSTREE_PUBLIC void ostree_repo_transaction_set_refspec (OstreeRepo *self, const char *refspec, @@ -526,23 +553,6 @@ gboolean ostree_repo_load_variant_if_exists (OstreeRepo *self, GVariant **out_variant, GError **error); -/** - * OstreeRepoCommitState: - * @OSTREE_REPO_COMMIT_STATE_NORMAL: Commit is complete. This is the default. - * (Since: 2017.14.) - * @OSTREE_REPO_COMMIT_STATE_PARTIAL: One or more objects are missing from the - * local copy of the commit, but metadata is present. (Since: 2015.7.) - * - * Flags representing the state of a commit in the local repository, as returned - * by ostree_repo_load_commit(). - * - * Since: 2015.7 - */ -typedef enum { - OSTREE_REPO_COMMIT_STATE_NORMAL = 0, - OSTREE_REPO_COMMIT_STATE_PARTIAL = (1 << 0), -} OstreeRepoCommitState; - _OSTREE_PUBLIC gboolean ostree_repo_load_commit (OstreeRepo *self, const char *checksum, diff --git a/src/ostree/ot-builtin-fsck.c b/src/ostree/ot-builtin-fsck.c index a7ecd3d0..44e98a76 100644 --- a/src/ostree/ot-builtin-fsck.c +++ b/src/ostree/ot-builtin-fsck.c @@ -127,7 +127,7 @@ fsck_one_object (OstreeRepo *repo, if ((state & OSTREE_REPO_COMMIT_STATE_PARTIAL) == 0) { g_printerr ("Marking commit as partial: %s\n", parent_commit); - if (!ostree_repo_mark_commit_partial (repo, parent_commit, TRUE, error)) + if (!ostree_repo_mark_commit_partial_reason (repo, parent_commit, TRUE, OSTREE_REPO_COMMIT_STATE_FSCK_PARTIAL, error)) return FALSE; } } @@ -302,6 +302,7 @@ ostree_builtin_fsck (int argc, char **argv, OstreeCommandInvocation *invocation, opt_verify_bindings = TRUE; guint n_partial = 0; + guint n_fsck_partial = 0; g_hash_table_iter_init (&hash_iter, objects); while (g_hash_table_iter_next (&hash_iter, &key, &value)) { @@ -410,7 +411,11 @@ ostree_builtin_fsck (int argc, char **argv, OstreeCommandInvocation *invocation, } if (commitstate & OSTREE_REPO_COMMIT_STATE_PARTIAL) - n_partial++; + { + n_partial++; + if (commitstate & OSTREE_REPO_COMMIT_STATE_FSCK_PARTIAL) + n_fsck_partial++; + } else g_hash_table_add (commits, g_variant_ref (serialized_key)); } @@ -450,5 +455,8 @@ ostree_builtin_fsck (int argc, char **argv, OstreeCommandInvocation *invocation, if (found_corruption) return glnx_throw (error, "Repository corruption encountered"); + if (n_fsck_partial > 0) + return glnx_throw (error, "%u fsck deleted partial commits not verified", n_partial); + return TRUE; } From bdbce9d042585d32d45e6e9f81d0871ef8f6ec53 Mon Sep 17 00:00:00 2001 From: Jason Wessel Date: Wed, 10 Jul 2019 14:42:27 -0400 Subject: [PATCH 11/16] fsck: Add test for --delete corruption, fix repair, and partial commit checks The ostree fsck test is aimed to check that it will still fail an fsck if the repository has been repaired by fsck. It also checks that a pull operation corrects the error and ostree fsck will exit with zero. The test was modeled after the following script: rm -rf ./f1 mkdir -p ./f1 ./ostree --repo=./f1 init --mode=archive-z2 mkdir -p ./trial echo test > ./trial/test ./ostree --repo=./f1 commit --tree=dir=./trial --skip-if-unchanged --branch=exp1 --subject="test Commit" rm -rf ./f2 mkdir -p ./f2 ./ostree --repo=./f2 init ./ostree --repo=./f2 pull-local ./f1 echo whoops > `find ./f2 |grep objects |grep \\.file ` ./ostree fsck --repo=./f2 ; echo Exit: $? ./ostree fsck --delete --repo=./f2 ; echo Exit: $? ./ostree fsck --repo=./f2 ; echo Exit: $? ./ostree --repo=./f2 pull-local ./f1 ./ostree fsck --repo=./f2 ; echo Exit: $? Signed-off-by: Jason Wessel fsck: Update test so that it will pass on fs without xattrs The fsck test does not require xattrs to prove that it works. It is simple enough to change it to use an archvie instead of a bare type repository. Signed-off-by: Jason Wessel Closes: #1910 Approved by: cgwalters --- Makefile-tests.am | 1 + tests/test-fsck-delete.sh | 83 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 84 insertions(+) create mode 100755 tests/test-fsck-delete.sh diff --git a/Makefile-tests.am b/Makefile-tests.am index 5498fd43..f5a65278 100644 --- a/Makefile-tests.am +++ b/Makefile-tests.am @@ -126,6 +126,7 @@ _installed_or_uninstalled_test_scripts = \ tests/test-create-usb.sh \ tests/test-find-remotes.sh \ tests/test-fsck-collections.sh \ + tests/test-fsck-delete.sh \ tests/test-init-collections.sh \ tests/test-prune-collections.sh \ tests/test-refs-collections.sh \ diff --git a/tests/test-fsck-delete.sh b/tests/test-fsck-delete.sh new file mode 100755 index 00000000..3e7347bb --- /dev/null +++ b/tests/test-fsck-delete.sh @@ -0,0 +1,83 @@ +#!/bin/bash +# +# Copyright © 2019 Wind River Systems, Inc. +# +# SPDX-License-Identifier: LGPL-2.0+ +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the +# Free Software Foundation, Inc., 59 Temple Place - Suite 330, +# Boston, MA 02111-1307, USA. + +set -euo pipefail + +. $(dirname $0)/libtest.sh + +echo '1..6' + +cd ${test_tmpdir} + +rm -rf ./f1 +mkdir -p ./f1 +${CMD_PREFIX} ostree --repo=./f1 init --mode=archive-z2 +rm -rf ./trial +mkdir -p ./trial +echo test > ./trial/test +${CMD_PREFIX} ostree --repo=./f1 commit --tree=dir=./trial --skip-if-unchanged --branch=exp1 --subject="test Commit" + +rm -rf ./f2 +mkdir -p ./f2 +${CMD_PREFIX} ostree --repo=./f2 init --mode=archive-z2 +${CMD_PREFIX} ostree --repo=./f2 pull-local ./f1 +echo "ok 1 fsck-pre-commit" + +file=`find ./f2 |grep objects |grep \\.file |tail -1 ` +rm $file +echo whoops > $file + +# First check for corruption +if ${CMD_PREFIX} ostree fsck --repo=./f2 > fsck 2> fsck-error; then + assert_not_reached "fsck did not fail" +fi +assert_file_has_content fsck "^Validating refs\.\.\.$" +assert_file_has_content fsck-error "^error: In commits" + +echo "ok 2 fsck-fail-check" + +# Fix the corruption +if ${CMD_PREFIX} ostree fsck --delete --repo=./f2 > fsck 2> fsck-error; then + assert_not_reached "fsck did not fail" +fi +assert_file_has_content fsck "^Validating refs\.\.\.$" +assert_file_has_content fsck-error "^In commits" + +echo "ok 3 fsck-delete-check" + +# Check that fsck still exits with non-zero after corruption fix +if ${CMD_PREFIX} ostree fsck --repo=./f2 > fsck 2> fsck-error; then + assert_not_reached "fsck did not fail" +fi +assert_file_has_content fsck "^Validating refs\.\.\.$" +assert_file_has_content fsck-error "^error: 1" + +echo "ok 4 fsck-post-delete-check" + +${CMD_PREFIX} ostree --repo=./f2 pull-local ./f1 > /dev/null +echo "ok 5 fsck-repair" + +if ! ${CMD_PREFIX} ostree fsck --repo=./f2 > fsck 2> fsck-error; then + assert_not_reached "fsck failed when it should have passed" +fi +assert_file_has_content fsck "^Validating refs\.\.\.$" +assert_file_empty fsck-error +echo "ok 6 fsck-good" From ca701f69c2610d51a2b4f6b62af9c127fb1336f0 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Mon, 9 Sep 2019 14:23:20 +0000 Subject: [PATCH 12/16] fsck: Fix version in docs, tweak error text I think this error message is clearer. Closes: #1918 Approved by: jlebon --- src/libostree/ostree-repo.h | 2 +- src/ostree/ot-builtin-fsck.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libostree/ostree-repo.h b/src/libostree/ostree-repo.h index aaaaa622..40d3f773 100644 --- a/src/libostree/ostree-repo.h +++ b/src/libostree/ostree-repo.h @@ -255,7 +255,7 @@ gboolean ostree_repo_write_config (OstreeRepo *self, * @OSTREE_REPO_COMMIT_STATE_PARTIAL: One or more objects are missing from the * local copy of the commit, but metadata is present. (Since: 2015.7.) * @OSTREE_REPO_COMMIT_STATE_FSCK_PARTIAL: One or more objects are missing from the - * local copy of the commit, due to an fsck --delete. (Since: 2019.3.) + * local copy of the commit, due to an fsck --delete. (Since: 2019.4.) * * Flags representing the state of a commit in the local repository, as returned * by ostree_repo_load_commit(). diff --git a/src/ostree/ot-builtin-fsck.c b/src/ostree/ot-builtin-fsck.c index 44e98a76..5ad3bf38 100644 --- a/src/ostree/ot-builtin-fsck.c +++ b/src/ostree/ot-builtin-fsck.c @@ -456,7 +456,7 @@ ostree_builtin_fsck (int argc, char **argv, OstreeCommandInvocation *invocation, return glnx_throw (error, "Repository corruption encountered"); if (n_fsck_partial > 0) - return glnx_throw (error, "%u fsck deleted partial commits not verified", n_partial); + return glnx_throw (error, "%u partial commits from fsck-detected corruption", n_partial); return TRUE; } From 653fc6a125e789692d8f8cd47ca4b1a124766a61 Mon Sep 17 00:00:00 2001 From: Benjamin Gilbert Date: Fri, 13 Sep 2019 02:37:01 -0400 Subject: [PATCH 13/16] prepare-root: remember to remove /sysroot.tmp Without this, rerunning ostree-prepare-root will fail in mkdir() because /sysroot.tmp already exists, which complicates debugging from the dracut emergency shell. Closes: #1919 Approved by: cgwalters --- src/switchroot/ostree-prepare-root.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/switchroot/ostree-prepare-root.c b/src/switchroot/ostree-prepare-root.c index 3d6e7833..33c46ff4 100644 --- a/src/switchroot/ostree-prepare-root.c +++ b/src/switchroot/ostree-prepare-root.c @@ -273,6 +273,9 @@ main(int argc, char *argv[]) if (mount (".", root_mountpoint, NULL, MS_MOVE, NULL) < 0) err (EXIT_FAILURE, "failed to MS_MOVE %s to %s", deploy_path, root_mountpoint); + + if (rmdir ("/sysroot.tmp") < 0) + err (EXIT_FAILURE, "couldn't remove temporary sysroot /sysroot.tmp"); } /* The /sysroot mount needs to be private to avoid having a mount for e.g. /var/cache From 94fcba96e08511f782642dad156150f0df063250 Mon Sep 17 00:00:00 2001 From: Philip Withnall Date: Mon, 21 May 2018 16:01:13 +0100 Subject: [PATCH 14/16] lib/repo-pull: Add more debugging on pull failure Signed-off-by: Philip Withnall Closes: #1925 Approved by: cgwalters --- src/libostree/ostree-repo-pull.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/libostree/ostree-repo-pull.c b/src/libostree/ostree-repo-pull.c index 3adaa477..ba6e7289 100644 --- a/src/libostree/ostree-repo-pull.c +++ b/src/libostree/ostree-repo-pull.c @@ -385,6 +385,8 @@ check_outstanding_requests_handle_error (OtPullData *pull_data, GError *error = *errorp; if (error) { + g_debug ("Request caught error: %s", error->message); + if (!pull_data->caught_error) { pull_data->caught_error = TRUE; From 88182635ab7dbaf20e72e7a7bf3d4bdf68fae763 Mon Sep 17 00:00:00 2001 From: Jonathan Lebon Date: Tue, 24 Sep 2019 17:08:54 -0400 Subject: [PATCH 15/16] boot/finalize-staged: Run after systemd-journal-flush.service In Fedora 31, `systemd-journal-flush.service` uses a new `--smart-relinquish-var` switch which fixes the `umount: /var: target is busy` bug by telling journald to stop logging to `/var` and back to `/run` again during shutdown. This interacted with `ostree-finalize-staged.service` in a tricky way: since we weren't strongly ordered against it, when we happened to finalize after `/var` is relinquished, we never persisted the output from that service to disk. This then threw off `rpm-ostree status` when trying to find the completion message to know that finalization went well. Just fix this by adding an explicit `After=` on that unit. That way we shut down *before* `systemd-journal-flush.service` (the `/var` relinquish bit happens in its `ExecStop=`). For more info, see: https://github.com/systemd/systemd/commit/3ff7a50d66e3f851d3d9f132b740a7fb2055aa1d https://github.com/systemd/systemd/commit/1e187d2dd52cbb4f0bb30e4d96acf7f72a145b91 https://bugzilla.redhat.com/show_bug.cgi?id=1751272 Closes: #1926 Approved by: cgwalters --- src/boot/ostree-finalize-staged.service | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/boot/ostree-finalize-staged.service b/src/boot/ostree-finalize-staged.service index e112bc0c..9c4706e8 100644 --- a/src/boot/ostree-finalize-staged.service +++ b/src/boot/ostree-finalize-staged.service @@ -26,6 +26,9 @@ DefaultDependencies=no RequiresMountsFor=/sysroot After=local-fs.target Before=basic.target final.target +# We want to make sure the transaction logs are persisted to disk: +# https://bugzilla.redhat.com/show_bug.cgi?id=1751272 +After=systemd-journal-flush.service Conflicts=final.target [Service] From 9d39e7d91e8497987cad69a3fbed5c5fc91eebdc Mon Sep 17 00:00:00 2001 From: Jonathan Lebon Date: Wed, 25 Sep 2019 09:37:48 -0400 Subject: [PATCH 16/16] Release 2019.4 Tiny release. Just want to get out the important bugfixes instead of backporting patches (notably the gpg-agent stuff and `ostree-finalize-staged.service` ordering). Closes: #1927 Approved by: cgwalters --- configure.ac | 2 +- src/libostree/libostree-devel.sym | 3 --- src/libostree/libostree-released.sym | 4 ++++ tests/test-symbols.sh | 2 +- 4 files changed, 6 insertions(+), 5 deletions(-) diff --git a/configure.ac b/configure.ac index 069bab01..cd3cfd10 100644 --- a/configure.ac +++ b/configure.ac @@ -7,7 +7,7 @@ m4_define([year_version], [2019]) m4_define([release_version], [4]) m4_define([package_version], [year_version.release_version]) AC_INIT([libostree], [package_version], [walters@verbum.org]) -is_release_build=no +is_release_build=yes AC_CONFIG_HEADER([config.h]) AC_CONFIG_MACRO_DIR([buildutil]) AC_CONFIG_AUX_DIR([build-aux]) diff --git a/src/libostree/libostree-devel.sym b/src/libostree/libostree-devel.sym index 58d35f55..9339c0fd 100644 --- a/src/libostree/libostree-devel.sym +++ b/src/libostree/libostree-devel.sym @@ -18,9 +18,6 @@ ***/ /* Add new symbols here. Release commits should copy this section into -released.sym. */ -LIBOSTREE_2019.4 { - ostree_repo_mark_commit_partial_reason; -} LIBOSTREE_2019.3; /* Stub section for the stable release *after* this development one; don't * edit this other than to update the year. This is just a copy/paste diff --git a/src/libostree/libostree-released.sym b/src/libostree/libostree-released.sym index fbcb2d56..ec9eec66 100644 --- a/src/libostree/libostree-released.sym +++ b/src/libostree/libostree-released.sym @@ -571,6 +571,10 @@ global: ostree_kernel_args_to_string; } LIBOSTREE_2018.9; +LIBOSTREE_2019.4 { + ostree_repo_mark_commit_partial_reason; +} LIBOSTREE_2019.3; + /* NOTE: Only add more content here in release commits! See the * comments at the top of this file. */ diff --git a/tests/test-symbols.sh b/tests/test-symbols.sh index 5ec06d72..32285bdc 100755 --- a/tests/test-symbols.sh +++ b/tests/test-symbols.sh @@ -54,7 +54,7 @@ echo 'ok documented symbols' # ONLY update this checksum in release commits! cat > released-sha256.txt <