From 79a88ac249054cbb3555e5c800f9628099c7e342 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Wed, 26 Jul 2017 15:13:06 -0400 Subject: [PATCH 01/67] build-sys: Post-release version bump Closes: #1029 Approved by: jlebon --- configure.ac | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index 01e6b534..58689cc0 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], [2017]) -m4_define([release_version], [9]) +m4_define([release_version], [10]) 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]) From d24b259cc588ac8db991d5d60b0ae39000219f9a Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Wed, 19 Jul 2017 15:59:46 -0400 Subject: [PATCH 02/67] grub2: Handle aarch64 (at least on Fedora/RHEL) See: https://github.com/projectatomic/rpm-ostree-toolbox/issues/102#issuecomment-316483554 The logic here should now match what grubby does. I have no idea whether this applies to other distributions though. Closes: #1021 Approved by: jlebon --- src/libostree/ostree-bootloader-grub2.c | 38 +++++++++++++------------ 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/src/libostree/ostree-bootloader-grub2.c b/src/libostree/ostree-bootloader-grub2.c index 86970d36..ff83f151 100644 --- a/src/libostree/ostree-bootloader-grub2.c +++ b/src/libostree/ostree-bootloader-grub2.c @@ -38,9 +38,19 @@ * among others. */ #if defined(__i386__) || defined(__x86_64__) -#define GRUB2_USES_16 1 +#define GRUB2_SUFFIX "16" #else -#define GRUB2_USES_16 0 +#define GRUB2_SUFFIX "" +#endif +/* https://github.com/projectatomic/rpm-ostree-toolbox/issues/102#issuecomment-316483554 + * https://github.com/rhboot/grubby/blob/34b1436ccbd56eab8024314cab48f2fc880eef08/grubby.c#L63 + * + * This is true at least on Fedora/Red Hat Enterprise Linux for aarch64. + */ +#if defined(__aarch64__) +#define GRUB2_EFI_SUFFIX "" +#else +#define GRUB2_EFI_SUFFIX "efi" #endif struct _OstreeBootloaderGrub2 @@ -214,16 +224,12 @@ _ostree_bootloader_grub2_generate_config (OstreeSysroot *sysroot "No \"linux\" key in bootloader config"); goto out; } + g_string_append (output, "linux"); if (is_efi) - g_string_append (output, "linuxefi "); + g_string_append (output, GRUB2_EFI_SUFFIX); else - { -#if GRUB2_USES_16 - g_string_append (output, "linux16 "); -#else - g_string_append (output, "linux "); -#endif - } + g_string_append (output, GRUB2_SUFFIX); + g_string_append_c (output, ' '); g_string_append (output, kernel); options = ostree_bootconfig_parser_get (config, "options"); @@ -237,16 +243,12 @@ _ostree_bootloader_grub2_generate_config (OstreeSysroot *sysroot initrd = ostree_bootconfig_parser_get (config, "initrd"); if (initrd) { + g_string_append (output, "initrd"); if (is_efi) - g_string_append (output, "initrdefi "); + g_string_append (output, GRUB2_EFI_SUFFIX); else - { -#if GRUB2_USES_16 - g_string_append (output, "initrd16 "); -#else - g_string_append (output, "initrd "); -#endif - } + g_string_append (output, GRUB2_SUFFIX); + g_string_append_c (output, ' '); g_string_append (output, initrd); g_string_append_c (output, '\n'); } From d7f953aa3a9fc61d7d22fd2d05ff92583cb7b21d Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Thu, 27 Jul 2017 15:49:05 -0400 Subject: [PATCH 03/67] lib/pull: Journal fetch results This is a continuation of addition of journaling to libostree; see e.g. . I wanted more information at the end of fetches; in particular some details about the delta execution (what opcodes etc.), but this is a first step: we log things like the transferred data as well as whether or not GPG was enabled, etc. One awkward thing about this is how we map the fetcher options like `tls-ca-path` back out into an enum for the code to log. But eh, hard to fix without a bigger refactoring. Closes: #1032 Approved by: jlebon --- src/libostree/ostree-repo-pull.c | 103 +++++++++++++++++++++++++++++-- 1 file changed, 98 insertions(+), 5 deletions(-) diff --git a/src/libostree/ostree-repo-pull.c b/src/libostree/ostree-repo-pull.c index 8ba69580..7ef0ba1c 100644 --- a/src/libostree/ostree-repo-pull.c +++ b/src/libostree/ostree-repo-pull.c @@ -50,10 +50,21 @@ #include #include +#ifdef HAVE_LIBSYSTEMD +#include +#endif + +#define OSTREE_MESSAGE_FETCH_COMPLETE_ID SD_ID128_MAKE(75,ba,3d,eb,0a,f0,41,a9,a4,62,72,ff,85,d9,e7,3e) #define OSTREE_REPO_PULL_CONTENT_PRIORITY (OSTREE_FETCHER_DEFAULT_PRIORITY) #define OSTREE_REPO_PULL_METADATA_PRIORITY (OSTREE_REPO_PULL_CONTENT_PRIORITY - 100) +typedef enum { + OSTREE_FETCHER_SECURITY_STATE_CA_PINNED, + OSTREE_FETCHER_SECURITY_STATE_TLS, + OSTREE_FETCHER_SECURITY_STATE_INSECURE, +} OstreeFetcherSecurityState; + typedef struct { OstreeRepo *repo; int tmpdir_dfd; @@ -61,6 +72,8 @@ typedef struct { char *remote_name; OstreeRepoMode remote_mode; OstreeFetcher *fetcher; + OstreeFetcherSecurityState fetcher_security_state; + GPtrArray *meta_mirrorlist; /* List of base URIs for fetching metadata */ GPtrArray *content_mirrorlist; /* List of base URIs for fetching content */ OstreeRepo *remote_repo_local; @@ -2612,11 +2625,13 @@ static OstreeFetcher * _ostree_repo_remote_new_fetcher (OstreeRepo *self, const char *remote_name, gboolean gzip, + OstreeFetcherSecurityState *out_state, GError **error) { OstreeFetcher *fetcher = NULL; OstreeFetcherConfigFlags fetcher_flags = 0; gboolean tls_permissive = FALSE; + OstreeFetcherSecurityState ret_state = OSTREE_FETCHER_SECURITY_STATE_TLS; gboolean success = FALSE; g_return_val_if_fail (OSTREE_IS_REPO (self), NULL); @@ -2628,7 +2643,10 @@ _ostree_repo_remote_new_fetcher (OstreeRepo *self, goto out; if (tls_permissive) - fetcher_flags |= OSTREE_FETCHER_FLAGS_TLS_PERMISSIVE; + { + fetcher_flags |= OSTREE_FETCHER_FLAGS_TLS_PERMISSIVE; + ret_state = OSTREE_FETCHER_SECURITY_STATE_INSECURE; + } if (gzip) fetcher_flags |= OSTREE_FETCHER_FLAGS_TRANSFER_GZIP; @@ -2673,6 +2691,10 @@ _ostree_repo_remote_new_fetcher (OstreeRepo *self, if (tls_ca_path != NULL) { _ostree_fetcher_set_tls_database (fetcher, tls_ca_path); + + /* Don't change if it's already _INSECURE */ + if (ret_state == OSTREE_FETCHER_SECURITY_STATE_TLS) + ret_state = OSTREE_FETCHER_SECURITY_STATE_CA_PINNED; } } @@ -2706,6 +2728,8 @@ _ostree_repo_remote_new_fetcher (OstreeRepo *self, out: if (!success) g_clear_object (&fetcher); + if (out_state) + *out_state = ret_state; return fetcher; } @@ -2891,7 +2915,7 @@ repo_remote_fetch_summary (OstreeRepo *self, mainctx = g_main_context_new (); g_main_context_push_thread_default (mainctx); - fetcher = _ostree_repo_remote_new_fetcher (self, name, TRUE, error); + fetcher = _ostree_repo_remote_new_fetcher (self, name, TRUE, NULL, error); if (fetcher == NULL) goto out; @@ -3001,10 +3025,13 @@ repo_remote_fetch_summary (OstreeRepo *self, * any options specific to this pull (such as extra headers). */ static gboolean -reinitialize_fetcher (OtPullData *pull_data, const char *remote_name, GError **error) +reinitialize_fetcher (OtPullData *pull_data, const char *remote_name, + GError **error) { g_clear_object (&pull_data->fetcher); - pull_data->fetcher = _ostree_repo_remote_new_fetcher (pull_data->repo, remote_name, FALSE, error); + pull_data->fetcher = _ostree_repo_remote_new_fetcher (pull_data->repo, remote_name, FALSE, + &pull_data->fetcher_security_state, + error); if (pull_data->fetcher == NULL) return FALSE; @@ -3210,6 +3237,10 @@ ostree_repo_pull_with_options (OstreeRepo *self, g_autoptr(GHashTable) updated_requested_refs_to_fetch = NULL; /* (element-type OstreeCollectionRef utf8) */ int i; g_autofree char **opt_localcache_repos = NULL; + /* If refs or collection-refs has exactly one value, this will point to that + * value, otherwise NULL. Used for logging. + */ + const char *the_ref_to_fetch = NULL; if (options) { @@ -3892,6 +3923,15 @@ ostree_repo_pull_with_options (OstreeRepo *self, g_hash_table_unref (requested_refs_to_fetch); requested_refs_to_fetch = g_steal_pointer (&updated_requested_refs_to_fetch); + if (g_hash_table_size (requested_refs_to_fetch) == 1) + { + GLNX_HASH_TABLE_FOREACH (requested_refs_to_fetch, + const OstreeCollectionRef *, ref) + { + the_ref_to_fetch = ref->ref_name; + break; + } + } /* Create the state directory here - it's new with the commitpartial code, * and may not exist in older repositories. @@ -4060,6 +4100,59 @@ ostree_repo_pull_with_options (OstreeRepo *self, ostree_async_progress_set_status (pull_data->progress, buf->str); } +#ifdef HAVE_LIBSYSTEMD + if (bytes_transferred > 0 && pull_data->remote_name) + { + g_autoptr(GString) msg = g_string_new (""); + if (the_ref_to_fetch) + g_string_append_printf (msg, "libostree pull from '%s' for %s complete", + pull_data->remote_name, the_ref_to_fetch); + else + g_string_append_printf (msg, "libostree pull from '%s' for %u refs complete", + pull_data->remote_name, g_hash_table_size (requested_refs_to_fetch)); + + g_string_append_printf (msg, "\nsecurity: GPG: %s ", pull_data->gpg_verify ? "yes" : "no"); + OstreeFetcherURI *first_uri = pull_data->meta_mirrorlist->pdata[0]; + g_autofree char *first_scheme = _ostree_fetcher_uri_get_scheme (first_uri); + if (g_str_has_prefix (first_scheme, "http")) + { + g_string_append (msg, "http: "); + switch (pull_data->fetcher_security_state) + { + case OSTREE_FETCHER_SECURITY_STATE_CA_PINNED: + g_string_append (msg, "CA-pinned"); + break; + case OSTREE_FETCHER_SECURITY_STATE_TLS: + g_string_append (msg, "TLS"); + break; + case OSTREE_FETCHER_SECURITY_STATE_INSECURE: + g_string_append (msg, "insecure"); + break; + } + } + g_string_append (msg, "\n"); + + if (pull_data->n_fetched_deltaparts > 0) + g_string_append_printf (msg, "delta: parts: %u loose: %u", + pull_data->n_fetched_deltaparts, + pull_data->n_fetched_metadata + pull_data->n_fetched_content); + else + g_string_append_printf (msg, "non-delta: meta: %u content: %u", + pull_data->n_fetched_metadata, pull_data->n_fetched_content); + const guint n_seconds = (guint) ((end_time - pull_data->start_time) / G_USEC_PER_SEC); + g_autofree char *formatted_xferred = g_format_size (bytes_transferred); + g_string_append_printf (msg, "\ntransfer: secs: %u size: %s", n_seconds, formatted_xferred); + + sd_journal_send ("MESSAGE=%s", msg->str, + "MESSAGE_ID=" SD_ID128_FORMAT_STR, SD_ID128_FORMAT_VAL(OSTREE_MESSAGE_FETCH_COMPLETE_ID), + "OSTREE_REMOTE=%s", pull_data->remote_name, + "OSTREE_GPG=%s", pull_data->gpg_verify ? "yes" : "no", + "OSTREE_SECONDS=%u", n_seconds, + "OSTREE_XFER_SIZE=%s", formatted_xferred, + NULL); + } +#endif + /* iterate over commits fetched and delete any commitpartial files */ if (pull_data->dirs == NULL && !pull_data->is_commit_only) { @@ -4836,7 +4929,7 @@ find_remotes_cb (GObject *obj, goto error; fetcher = _ostree_repo_remote_new_fetcher (self, result->remote->name, - TRUE, &error); + TRUE, NULL, &error); if (fetcher == NULL) goto error; From 156cf23576df15cfd06d8138f7fc4443bfee5058 Mon Sep 17 00:00:00 2001 From: Robert McQueen Date: Sun, 30 Jul 2017 17:35:46 +0100 Subject: [PATCH 04/67] gpg-verify-result: canonicalise key when looking up signatures Use gpgme_get_key to find the primary key for the key we are looking for, and the primary key for each signature, and compare these when looking up signatures. The primary key is the first in the list of subkeys, which is the normal key ID people use when referring to a GPG key as an identity. If the key has a signing subkey, signature->fpr will not match the provided key_id, so looking up both keys and comparing the primary key fingerprints ensures they are both canonicalised. https://github.com/ostreedev/ostree/issues/608 Closes: #1036 Approved by: cgwalters --- src/libostree/ostree-gpg-verify-result.c | 35 +++++++++++++++++++----- 1 file changed, 28 insertions(+), 7 deletions(-) diff --git a/src/libostree/ostree-gpg-verify-result.c b/src/libostree/ostree-gpg-verify-result.c index 0277ce1e..059b3d56 100644 --- a/src/libostree/ostree-gpg-verify-result.c +++ b/src/libostree/ostree-gpg-verify-result.c @@ -237,7 +237,7 @@ ostree_gpg_verify_result_lookup (OstreeGpgVerifyResult *result, const gchar *key_id, guint *out_signature_index) { - g_autofree char *key_id_upper = NULL; + gpgme_key_t lookup_key = NULL; gpgme_signature_t signature; guint signature_index; gboolean ret = FALSE; @@ -245,25 +245,46 @@ ostree_gpg_verify_result_lookup (OstreeGpgVerifyResult *result, g_return_val_if_fail (OSTREE_IS_GPG_VERIFY_RESULT (result), FALSE); g_return_val_if_fail (key_id != NULL, FALSE); - /* signature->fpr is always upper-case. */ - key_id_upper = g_ascii_strup (key_id, -1); + /* fetch requested key_id from keyring to canonicalise ID */ + (void) gpgme_get_key (result->context, key_id, &lookup_key, 0); + + if (lookup_key == NULL) + { + g_debug ("Could not find key ID %s to lookup signature.", key_id); + return FALSE; + } for (signature = result->details->signatures, signature_index = 0; signature != NULL; signature = signature->next, signature_index++) { - if (signature->fpr == NULL) - continue; + gpgme_key_t signature_key = NULL; - if (g_str_has_suffix (signature->fpr, key_id_upper)) + (void) gpgme_get_key (result->context, signature->fpr, &signature_key, 0); + + if (signature_key == NULL) + { + g_debug ("Could not find key when looking up signature from %s.", signature->fpr); + continue; + } + + /* the first subkey in the list is the primary key */ + if (!g_strcmp0 (lookup_key->subkeys->fpr, + signature_key->subkeys->fpr)) { if (out_signature_index != NULL) *out_signature_index = signature_index; ret = TRUE; - break; } + + gpgme_key_unref (signature_key); + + if (ret) + break; } + gpgme_key_unref (lookup_key); + return ret; } From e8a9172daad5f27ba5805fd4e4abba1b419dffc0 Mon Sep 17 00:00:00 2001 From: Robert McQueen Date: Sun, 30 Jul 2017 17:44:35 +0100 Subject: [PATCH 05/67] gpg-verify-result: try to display the primary key ID from signatures The fingerprint associated with each signature can be different to the primary key ID (the normal one that people use to identify a GPG key) if the signature is from a signing subkey. Try to find the primary key and print this ID in preference to the subkey signature. https://github.com/ostreedev/ostree/issues/608 Closes: #1036 Approved by: cgwalters --- src/libostree/ostree-gpg-verify-result.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/libostree/ostree-gpg-verify-result.c b/src/libostree/ostree-gpg-verify-result.c index 059b3d56..7cee6c28 100644 --- a/src/libostree/ostree-gpg-verify-result.c +++ b/src/libostree/ostree-gpg-verify-result.c @@ -334,7 +334,8 @@ ostree_gpg_verify_result_get (OstreeGpgVerifyResult *result, * (OSTREE_GPG_SIGNATURE_ATTR_KEY_MISSING). */ for (ii = 0; ii < n_attrs; ii++) { - if (attrs[ii] == OSTREE_GPG_SIGNATURE_ATTR_USER_NAME || + if (attrs[ii] == OSTREE_GPG_SIGNATURE_ATTR_FINGERPRINT || + attrs[ii] == OSTREE_GPG_SIGNATURE_ATTR_USER_NAME || attrs[ii] == OSTREE_GPG_SIGNATURE_ATTR_USER_EMAIL) { (void) gpgme_get_key (result->context, signature->fpr, &key, 0); @@ -378,7 +379,11 @@ ostree_gpg_verify_result_get (OstreeGpgVerifyResult *result, break; case OSTREE_GPG_SIGNATURE_ATTR_FINGERPRINT: - child = g_variant_new_string (signature->fpr); + if (key != NULL && key->subkeys != NULL) + v_string = key->subkeys->fpr; + else + v_string = signature->fpr; + child = g_variant_new_string (v_string); break; case OSTREE_GPG_SIGNATURE_ATTR_TIMESTAMP: From fbefe875c77e03b9070f1f6b5e3f0ea085749ba7 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Tue, 1 Aug 2017 09:12:16 -0400 Subject: [PATCH 06/67] docs/pull: Finish incomplete docs for pull@hash syntax Closes: https://github.com/ostreedev/ostree/issues/1043 Closes: #1045 Approved by: guyshapiro --- man/ostree-pull.xml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/man/ostree-pull.xml b/man/ostree-pull.xml index 394a29c2..dd901aa2 100644 --- a/man/ostree-pull.xml +++ b/man/ostree-pull.xml @@ -136,8 +136,11 @@ Boston, MA 02111-1307, USA. - A special syntax in the @ character allows - specifying a specific commit to retrieve from a branch. This + A special syntax in the @ character allows + specifying a specific commit to retrieve from a branch. The + use cases for this are somewhat similar to pulling a specific + git tag; one could e.g. script a system upgrade to a known-good + version, rather than the latest from the content provider. From 36ab8cd0e1cf487fe5f03917a617ab88d7b0a86d Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Mon, 31 Jul 2017 09:27:56 -0400 Subject: [PATCH 07/67] tests: Add some return value checking to pacify Coverity No real problems here, but Coverity likes to see consistent checking of return values, and I agree with it. Coverity CID: 1452213 Coverity CID: 1452211 Closes: #1037 Approved by: jlebon --- src/ostree/ostree-trivial-httpd.c | 2 +- tests/test-bsdiff.c | 2 +- tests/test-mutable-tree.c | 4 +++- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/ostree/ostree-trivial-httpd.c b/src/ostree/ostree-trivial-httpd.c index 176f5ec7..de04e9a4 100644 --- a/src/ostree/ostree-trivial-httpd.c +++ b/src/ostree/ostree-trivial-httpd.c @@ -94,7 +94,7 @@ httpd_log (OtTrivialHttpd *httpd, const gchar *format, ...) g_string_append_vprintf (str, format, args); va_end (args); - g_output_stream_write_all (httpd->log, str->str, str->len, &written, NULL, NULL); + (void)g_output_stream_write_all (httpd->log, str->str, str->len, &written, NULL, NULL); } static int diff --git a/tests/test-bsdiff.c b/tests/test-bsdiff.c index 24772a1e..0bf500da 100644 --- a/tests/test-bsdiff.c +++ b/tests/test-bsdiff.c @@ -86,7 +86,7 @@ test_bsdiff (void) bsdiff_stream.opaque = out; g_assert_cmpint (bsdiff (old, OLD_SIZE, new, NEW_SIZE, &bsdiff_stream), ==, 0); - g_output_stream_close (out, NULL, NULL); + g_assert (g_output_stream_close (out, NULL, NULL)); /* Now generate NEW_GENERATED from OLD and OUT. */ { g_autoptr(GBytes) bytes = g_memory_output_stream_steal_as_bytes (G_MEMORY_OUTPUT_STREAM (out)); diff --git a/tests/test-mutable-tree.c b/tests/test-mutable-tree.c index 9df36ac6..f878f116 100644 --- a/tests/test-mutable-tree.c +++ b/tests/test-mutable-tree.c @@ -72,8 +72,10 @@ test_mutable_tree_walk (void) glnx_unref_object OstreeMutableTree *subdir = NULL; glnx_unref_object OstreeMutableTree *a = NULL; g_autofree char *source_checksum = NULL; - ostree_mutable_tree_lookup (tree, "a", &source_checksum, &a, &error); + g_assert (ostree_mutable_tree_lookup (tree, "a", &source_checksum, &a, &error)); + g_assert_no_error (error); g_assert (ostree_mutable_tree_walk (a, split_path, 1, &subdir, &error)); + g_assert_no_error (error); g_assert (subdir); } } From 78348fa296dc03c366a08f40aaa90565f5743158 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Mon, 31 Jul 2017 09:30:09 -0400 Subject: [PATCH 08/67] bin/refs: Fix error handling logic Spotted by Coverity. Coverity CID: 1452202 Closes: #1037 Approved by: jlebon --- src/ostree/ot-builtin-refs.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/ostree/ot-builtin-refs.c b/src/ostree/ot-builtin-refs.c index 19420842..f2274802 100644 --- a/src/ostree/ot-builtin-refs.c +++ b/src/ostree/ot-builtin-refs.c @@ -264,7 +264,8 @@ ostree_builtin_refs (int argc, char **argv, GCancellable *cancellable, GError ** goto out; } - ret = do_ref (repo, NULL, cancellable, error); + if (!do_ref (repo, NULL, cancellable, error)) + goto out; } ret = TRUE; From 5daae8629e84444879e7c94ccc990b7b906c58a6 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Mon, 31 Jul 2017 09:31:55 -0400 Subject: [PATCH 09/67] tests/lzma: Use GRand over random() It's designed for test suites and non-critical random uses like this. This silences a Coverity warning about weak randomness. Closes: #1037 Approved by: jlebon --- tests/test-lzma.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test-lzma.c b/tests/test-lzma.c index 1f7d2559..b3487ee3 100644 --- a/tests/test-lzma.c +++ b/tests/test-lzma.c @@ -81,9 +81,9 @@ test_lzma_random (void) gssize i; const guint32 buffer_size = 4096 + 1; guint8 buffer[buffer_size]; - srandom (1); + g_autoptr(GRand) r = g_rand_new (); for (i = 0; i < buffer_size; i++) - buffer[i] = random (); + buffer[i] = g_rand_int (r); for (i = 2; i <= buffer_size; i *= 2) { From e70db67c018f34f404ae9ef5a992e7a67d377301 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Mon, 31 Jul 2017 09:34:33 -0400 Subject: [PATCH 10/67] rofiles-fuse: Add missing error handling for fcntl() Spotted by Coverity. Coverity CID: 1452201 Closes: #1037 Approved by: jlebon --- src/rofiles-fuse/main.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/rofiles-fuse/main.c b/src/rofiles-fuse/main.c index 12a9d886..88cdba6c 100644 --- a/src/rofiles-fuse/main.c +++ b/src/rofiles-fuse/main.c @@ -96,6 +96,8 @@ callback_readdir (const char *path, void *buf, fuse_fill_dir_t filler, if (!*path) { dfd = fcntl (basefd, F_DUPFD_CLOEXEC, 3); + if (dfd < 0) + return -errno; lseek (dfd, 0, SEEK_SET); } else From fe8938227e767ab85bc4f1d599032165aa2bf133 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Mon, 31 Jul 2017 10:05:04 -0400 Subject: [PATCH 11/67] tests/lzma: Fix off-by-one in buffer size Coverity spotted that we had an off-by-one here since we were using `i+1`. Fix this by adding a `-1` to the bounds check. Also use `sizeof()` to ensure the data and size are coupled. Coverity CID: 1452207 Closes: #1037 Approved by: jlebon --- tests/test-lzma.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/tests/test-lzma.c b/tests/test-lzma.c index b3487ee3..559e9ad4 100644 --- a/tests/test-lzma.c +++ b/tests/test-lzma.c @@ -79,13 +79,12 @@ static void test_lzma_random (void) { gssize i; - const guint32 buffer_size = 4096 + 1; - guint8 buffer[buffer_size]; + guint8 buffer[4096]; g_autoptr(GRand) r = g_rand_new (); - for (i = 0; i < buffer_size; i++) + for (i = 0; i < sizeof(buffer); i++) buffer[i] = g_rand_int (r); - for (i = 2; i <= buffer_size; i *= 2) + for (i = 2; i < (sizeof(buffer) - 1); i *= 2) { helper_test_compress_decompress (buffer, i - 1); helper_test_compress_decompress (buffer, i); From 2f0707a054139174bef552adc778259f58b12125 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Mon, 31 Jul 2017 12:35:58 -0400 Subject: [PATCH 12/67] lib/commit: Rework a conditional set for clarity and Coverity Coverity complained that the `else if (bytes_read == 0)` was dead code if we happened to find it was already false when testing `else if (G_UNLIKELY (bytes_read == 0 ...`. There was nothing wrong with the logic, but let's rework it to only test the value once; I think it does end up nicer anyways. Coverity CID: 1452186 Closes: #1037 Approved by: jlebon --- src/libostree/ostree-repo-commit.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/libostree/ostree-repo-commit.c b/src/libostree/ostree-repo-commit.c index 1d3d6840..ab348311 100644 --- a/src/libostree/ostree-repo-commit.c +++ b/src/libostree/ostree-repo-commit.c @@ -485,10 +485,13 @@ create_regular_tmpfile_linkable_with_content (OstreeRepo *self, g_input_stream_read (input, buf, MIN (remaining, sizeof (buf)), cancellable, error); if (bytes_read < 0) return FALSE; - else if (G_UNLIKELY (bytes_read == 0 && remaining > 0)) - return glnx_throw (error, "Unexpected EOF with %" G_GUINT64_FORMAT "/%" G_GUINT64_FORMAT " bytes remaining", remaining, length); else if (bytes_read == 0) - break; + { + if (G_UNLIKELY (remaining > 0)) + return glnx_throw (error, "Unexpected EOF with %" G_GUINT64_FORMAT "/%" G_GUINT64_FORMAT " bytes remaining", remaining, length); + else + break; + } if (glnx_loop_write (tmpf.fd, buf, bytes_read) < 0) return glnx_throw_errno_prefix (error, "write"); remaining -= bytes_read; From 6347c0fb8878ac2cf809caa74cdf7fef5a97b786 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Mon, 31 Jul 2017 10:48:57 -0400 Subject: [PATCH 13/67] lib/curl: Only check individual request errors It looks like `curl_multi_socket_action()` will return an error if *one* of the requests has an error, but we already check for that explicitly by iterating over each handle. In libcurl, the "easy" layer doesn't really make use of this return value. I did a bit of looking elsewhere; systemd does check it as a runtime error, not an assertion. librepo doesn't use the multi interface. Closes: https://github.com/ostreedev/ostree/issues/1035 Closes: #1038 Approved by: jlebon --- src/libostree/ostree-fetcher-curl.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/libostree/ostree-fetcher-curl.c b/src/libostree/ostree-fetcher-curl.c index ae8bea73..57118f9c 100644 --- a/src/libostree/ostree-fetcher-curl.c +++ b/src/libostree/ostree-fetcher-curl.c @@ -425,11 +425,9 @@ static gboolean timer_cb (gpointer data) { OstreeFetcher *fetcher = data; - CURLMcode rc; GSource *orig_src = fetcher->timer_event; - rc = curl_multi_socket_action (fetcher->multi, CURL_SOCKET_TIMEOUT, 0, &fetcher->curl_running); - g_assert (rc == CURLM_OK); + (void)curl_multi_socket_action (fetcher->multi, CURL_SOCKET_TIMEOUT, 0, &fetcher->curl_running); check_multi_info (fetcher); if (fetcher->timer_event == orig_src) fetcher->timer_event = NULL; @@ -460,15 +458,12 @@ static gboolean event_cb (int fd, GIOCondition condition, gpointer data) { OstreeFetcher *fetcher = data; - CURLMcode rc; int action = (condition & G_IO_IN ? CURL_CSELECT_IN : 0) | (condition & G_IO_OUT ? CURL_CSELECT_OUT : 0); - rc = curl_multi_socket_action (fetcher->multi, fd, action, &fetcher->curl_running); - g_assert (rc == CURLM_OK); - + (void)curl_multi_socket_action (fetcher->multi, fd, action, &fetcher->curl_running); check_multi_info (fetcher); if (fetcher->curl_running > 0) { From ded6417aee906fad25a80fe5db85ee43b0552426 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Mon, 31 Jul 2017 13:24:25 -0400 Subject: [PATCH 14/67] lib/gpg: Switch to GLib autocleanups for gpgme types Prep for dropping `GLNX_DEFINE_CLEANUP_FUNCTION` from libglnx in favor of using GLib's `G_DEFINE_AUTO_CLEANUP_FREE_FUNC()`. Closes: #1042 Approved by: jlebon --- src/libostree/ostree-gpg-verifier.c | 6 +++--- src/libostree/ostree-repo.c | 6 +++--- src/libotutil/ot-gpg-utils.c | 2 +- src/libotutil/ot-gpg-utils.h | 6 ++---- 4 files changed, 9 insertions(+), 11 deletions(-) diff --git a/src/libostree/ostree-gpg-verifier.c b/src/libostree/ostree-gpg-verifier.c index 77594d9b..680c410b 100644 --- a/src/libostree/ostree-gpg-verifier.c +++ b/src/libostree/ostree-gpg-verifier.c @@ -95,8 +95,8 @@ _ostree_gpg_verifier_check_signature (OstreeGpgVerifier *self, { GLNX_AUTO_PREFIX_ERROR("GPG", error); gpgme_error_t gpg_error = 0; - ot_auto_gpgme_data gpgme_data_t data_buffer = NULL; - ot_auto_gpgme_data gpgme_data_t signature_buffer = NULL; + g_auto(gpgme_data_t) data_buffer = NULL; + g_auto(gpgme_data_t) signature_buffer = NULL; g_autofree char *tmp_dir = NULL; g_autoptr(GOutputStream) target_stream = NULL; OstreeGpgVerifyResult *result = NULL; @@ -165,7 +165,7 @@ _ostree_gpg_verifier_check_signature (OstreeGpgVerifier *self, { const char *path = self->key_ascii_files->pdata[i]; glnx_fd_close int fd = -1; - ot_auto_gpgme_data gpgme_data_t kdata = NULL; + g_auto(gpgme_data_t) kdata = NULL; if (!glnx_openat_rdonly (AT_FDCWD, path, TRUE, &fd, error)) goto out; diff --git a/src/libostree/ostree-repo.c b/src/libostree/ostree-repo.c index 896c57bc..5730b11e 100644 --- a/src/libostree/ostree-repo.c +++ b/src/libostree/ostree-repo.c @@ -1331,9 +1331,9 @@ ostree_repo_remote_gpg_import (OstreeRepo *self, GError **error) { OstreeRemote *remote; - ot_auto_gpgme_ctx gpgme_ctx_t source_context = NULL; - ot_auto_gpgme_ctx gpgme_ctx_t target_context = NULL; - ot_auto_gpgme_data gpgme_data_t data_buffer = NULL; + g_auto(gpgme_ctx_t) source_context = NULL; + g_auto(gpgme_ctx_t) target_context = NULL; + g_auto(gpgme_data_t) data_buffer = NULL; gpgme_import_result_t import_result; gpgme_import_status_t import_status; g_autofree char *source_tmp_dir = NULL; diff --git a/src/libotutil/ot-gpg-utils.c b/src/libotutil/ot-gpg-utils.c index 001daa0a..99f4879e 100644 --- a/src/libotutil/ot-gpg-utils.c +++ b/src/libotutil/ot-gpg-utils.c @@ -413,7 +413,7 @@ ot_gpgme_new_ctx (const char *homedir, GError **error) { gpgme_error_t err; - ot_auto_gpgme_ctx gpgme_ctx_t context = NULL; + g_auto(gpgme_ctx_t) context = NULL; if ((err = gpgme_new (&context)) != GPG_ERR_NO_ERROR) { diff --git a/src/libotutil/ot-gpg-utils.h b/src/libotutil/ot-gpg-utils.h index 184a8d64..9545e14b 100644 --- a/src/libotutil/ot-gpg-utils.h +++ b/src/libotutil/ot-gpg-utils.h @@ -26,10 +26,8 @@ G_BEGIN_DECLS -GLNX_DEFINE_CLEANUP_FUNCTION0(gpgme_data_t, ot_cleanup_gpgme_data, gpgme_data_release) -#define ot_auto_gpgme_data __attribute__((cleanup(ot_cleanup_gpgme_data))) -GLNX_DEFINE_CLEANUP_FUNCTION0(gpgme_ctx_t, ot_cleanup_gpgme_ctx, gpgme_release) -#define ot_auto_gpgme_ctx __attribute__((cleanup(ot_cleanup_gpgme_ctx))) +G_DEFINE_AUTO_CLEANUP_FREE_FUNC(gpgme_data_t, gpgme_data_release, NULL); +G_DEFINE_AUTO_CLEANUP_FREE_FUNC(gpgme_ctx_t, gpgme_release, NULL); void ot_gpgme_error_to_gio_error (gpgme_error_t gpg_error, GError **error); From 40b41d2cc9cd541891f04f959beff59f19129d87 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Mon, 31 Jul 2017 13:28:16 -0400 Subject: [PATCH 15/67] tree-wide: Use GLib autocleanups for libarchive Define typedefs for read/write archives, and use the GLib autocleanups for them. Prep for updating libglnx to drop its custom autocleanup macros. Closes: #1042 Approved by: jlebon --- src/libostree/ostree-libarchive-private.h | 14 ++++++-------- src/libostree/ostree-repo-libarchive.c | 2 +- src/ostree/ot-builtin-export.c | 2 +- tests/test-libarchive-import.c | 18 +++++++++--------- 4 files changed, 17 insertions(+), 19 deletions(-) diff --git a/src/libostree/ostree-libarchive-private.h b/src/libostree/ostree-libarchive-private.h index 865a4b8d..dcf86ea3 100644 --- a/src/libostree/ostree-libarchive-private.h +++ b/src/libostree/ostree-libarchive-private.h @@ -22,6 +22,8 @@ #pragma once +#include "config.h" + #include #include "libglnx.h" #ifdef HAVE_LIBARCHIVE @@ -32,14 +34,10 @@ G_BEGIN_DECLS #ifdef HAVE_LIBARCHIVE -GLNX_DEFINE_CLEANUP_FUNCTION (void *, flatpak_local_free_write_archive, archive_write_free) -#define ot_cleanup_write_archive __attribute__((cleanup (flatpak_local_free_write_archive))) - -GLNX_DEFINE_CLEANUP_FUNCTION (void *, flatpak_local_free_read_archive, archive_read_free) -#define ot_cleanup_read_archive __attribute__((cleanup (flatpak_local_free_read_archive))) -#else -#define ot_cleanup_write_archive -#define ot_cleanup_read_archive +typedef struct archive OtAutoArchiveWrite; +G_DEFINE_AUTOPTR_CLEANUP_FUNC(OtAutoArchiveWrite, archive_write_free) +typedef struct archive OtAutoArchiveRead; +G_DEFINE_AUTOPTR_CLEANUP_FUNC(OtAutoArchiveRead, archive_read_free) #endif G_END_DECLS diff --git a/src/libostree/ostree-repo-libarchive.c b/src/libostree/ostree-repo-libarchive.c index 2e1696b5..02e12d50 100644 --- a/src/libostree/ostree-repo-libarchive.c +++ b/src/libostree/ostree-repo-libarchive.c @@ -900,7 +900,7 @@ ostree_repo_write_archive_to_mtree (OstreeRepo *self, { #ifdef HAVE_LIBARCHIVE gboolean ret = FALSE; - ot_cleanup_read_archive struct archive *a = archive_read_new (); + g_autoptr(OtAutoArchiveRead) a = archive_read_new (); OstreeRepoImportArchiveOptions opts = { 0, }; #ifdef HAVE_ARCHIVE_READ_SUPPORT_FILTER_ALL diff --git a/src/ostree/ot-builtin-export.c b/src/ostree/ot-builtin-export.c index 2d40112a..fea03c3e 100644 --- a/src/ostree/ot-builtin-export.c +++ b/src/ostree/ot-builtin-export.c @@ -68,7 +68,7 @@ ostree_builtin_export (int argc, char **argv, GCancellable *cancellable, GError g_autoptr(GFile) subtree = NULL; g_autofree char *commit = NULL; g_autoptr(GVariant) commit_data = NULL; - ot_cleanup_write_archive struct archive *a = NULL; + g_autoptr(OtAutoArchiveWrite) a = NULL; OstreeRepoExportArchiveOptions opts = { 0, }; context = g_option_context_new ("COMMIT - Stream COMMIT to stdout in tar format"); diff --git a/tests/test-libarchive-import.c b/tests/test-libarchive-import.c index e9be7f66..8f884a66 100644 --- a/tests/test-libarchive-import.c +++ b/tests/test-libarchive-import.c @@ -41,7 +41,7 @@ static void test_data_init (TestData *td) { GError *error = NULL; - ot_cleanup_write_archive struct archive *a = archive_write_new (); + g_autoptr(OtAutoArchiveWrite) a = archive_write_new (); struct archive_entry *ae; uid_t uid = getuid (); gid_t gid = getgid (); @@ -165,7 +165,7 @@ test_libarchive_noautocreate_empty (gconstpointer data) { TestData *td = (void*)data; GError *error = NULL; - ot_cleanup_read_archive struct archive *a = archive_read_new (); + g_autoptr(OtAutoArchiveRead) a = archive_read_new (); OstreeRepoImportArchiveOptions opts = { 0, }; glnx_unref_object OstreeMutableTree *mtree = ostree_mutable_tree_new (); @@ -181,7 +181,7 @@ test_libarchive_autocreate_empty (gconstpointer data) { TestData *td = (void*)data; g_autoptr(GError) error = NULL; - ot_cleanup_read_archive struct archive *a = archive_read_new (); + g_autoptr(OtAutoArchiveRead) a = archive_read_new (); OstreeRepoImportArchiveOptions opts = { 0, }; glnx_unref_object OstreeMutableTree *mtree = ostree_mutable_tree_new (); @@ -199,7 +199,7 @@ test_libarchive_error_device_file (gconstpointer data) { TestData *td = (void*)data; g_autoptr(GError) error = NULL; - ot_cleanup_read_archive struct archive *a = archive_read_new (); + g_autoptr(OtAutoArchiveRead) a = archive_read_new (); OstreeRepoImportArchiveOptions opts = { 0, }; glnx_unref_object OstreeMutableTree *mtree = ostree_mutable_tree_new (); @@ -270,7 +270,7 @@ test_libarchive_ignore_device_file (gconstpointer data) { TestData *td = (void*)data; g_autoptr(GError) error = NULL; - ot_cleanup_read_archive struct archive *a = archive_read_new (); + g_autoptr(OtAutoArchiveRead) a = archive_read_new (); OstreeRepoImportArchiveOptions opts = { 0, }; if (skip_if_no_xattr (td)) @@ -332,7 +332,7 @@ test_libarchive_ostree_convention (gconstpointer data) { TestData *td = (void*)data; GError *error = NULL; - ot_cleanup_read_archive struct archive *a = archive_read_new (); + g_autoptr(OtAutoArchiveRead) a = archive_read_new (); OstreeRepoImportArchiveOptions opts = { 0, }; if (skip_if_no_xattr (td)) @@ -374,7 +374,7 @@ test_libarchive_xattr_callback (gconstpointer data) { TestData *td = (void*)data; GError *error = NULL; - ot_cleanup_read_archive struct archive *a = archive_read_new (); + g_autoptr(OtAutoArchiveRead) a = archive_read_new (); OstreeRepoImportArchiveOptions opts = { 0 }; OstreeRepoCommitModifier *modifier = NULL; char buf[7] = { 0 }; @@ -429,7 +429,7 @@ static void entry_pathname_test_helper (gconstpointer data, gboolean on) { TestData *td = (void*)data; GError *error = NULL; - ot_cleanup_read_archive struct archive *a = archive_read_new (); + g_autoptr(OtAutoArchiveRead) a = archive_read_new (); OstreeRepoImportArchiveOptions opts = { 0, }; OstreeRepoCommitModifier *modifier = NULL; gboolean met_etc_file = FALSE; @@ -491,7 +491,7 @@ test_libarchive_selinux (gconstpointer data) { TestData *td = (void*)data; GError *error = NULL; - ot_cleanup_read_archive struct archive *a = archive_read_new (); + g_autoptr(OtAutoArchiveRead) a = archive_read_new (); OstreeRepoImportArchiveOptions opts = { 0 }; glnx_unref_object OstreeSePolicy *sepol = NULL; OstreeRepoCommitModifier *modifier = NULL; From 4d723df2f2e59764a13df3778743140c0ea2f439 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Tue, 1 Aug 2017 05:43:35 -0400 Subject: [PATCH 16/67] lib/sysroot: Add prefixes to syncfs/fsync error messages And clean up one other bare `glnx_throw_errno()`. Closes: #1044 Approved by: jlebon --- src/libostree/ostree-sysroot-deploy.c | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/src/libostree/ostree-sysroot-deploy.c b/src/libostree/ostree-sysroot-deploy.c index b2b46b36..2e030429 100644 --- a/src/libostree/ostree-sysroot-deploy.c +++ b/src/libostree/ostree-sysroot-deploy.c @@ -977,7 +977,7 @@ syncfs_dir_at (int dfd, if (!glnx_opendirat (dfd, path, TRUE, &child_dfd, error)) return FALSE; if (syncfs (child_dfd) != 0) - return glnx_throw_errno (error); + return glnx_throw_errno_prefix (error, "syncfs(%s)", path); return TRUE; } @@ -992,7 +992,7 @@ full_system_sync (OstreeSysroot *self, GError **error) { if (syncfs (self->sysroot_fd) != 0) - return glnx_throw_errno (error); + return glnx_throw_errno_prefix (error, "syncfs(sysroot)"); if (!syncfs_dir_at (self->sysroot_fd, "boot", cancellable, error)) return FALSE; @@ -1379,7 +1379,7 @@ swap_bootloader (OstreeSysroot *sysroot, * admin by going back to the previous session. */ if (fsync (boot_dfd) != 0) - return glnx_throw_errno (error); + return glnx_throw_errno_prefix (error, "fsync(boot)"); return TRUE; } @@ -1452,10 +1452,9 @@ cleanup_legacy_current_symlinks (OstreeSysroot *self, GCancellable *cancellable, GError **error) { - guint i; g_autoptr(GString) buf = g_string_new (""); - for (i = 0; i < self->deployments->len; i++) + for (guint i = 0; i < self->deployments->len; i++) { OstreeDeployment *deployment = self->deployments->pdata[i]; const char *osname = ostree_deployment_get_osname (deployment); @@ -1463,11 +1462,8 @@ cleanup_legacy_current_symlinks (OstreeSysroot *self, g_string_truncate (buf, 0); g_string_append_printf (buf, "ostree/deploy/%s/current", osname); - if (unlinkat (self->sysroot_fd, buf->str, 0) < 0) - { - if (errno != ENOENT) - return glnx_throw_errno (error); - } + if (!ot_ensure_unlinked_at (self->sysroot_fd, buf->str, error)) + return FALSE; } return TRUE; From d1eb909cd0a45246095d71f077c7e4cd4b5646fe Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Tue, 1 Aug 2017 09:05:21 -0400 Subject: [PATCH 17/67] lib/deploy: Add structured logging info for syncfs() times I plan to at some point change rpm-ostree to read the journal messages from libostree and render things like the time we spent in syncfs(). Closes: #1044 Approved by: jlebon --- src/libostree/ostree-sysroot-deploy.c | 56 ++++++++++++++++++++++----- src/libotutil/ot-log-utils.c | 2 +- src/libotutil/ot-log-utils.h | 2 + 3 files changed, 50 insertions(+), 10 deletions(-) diff --git a/src/libostree/ostree-sysroot-deploy.c b/src/libostree/ostree-sysroot-deploy.c index 2e030429..99559f63 100644 --- a/src/libostree/ostree-sysroot-deploy.c +++ b/src/libostree/ostree-sysroot-deploy.c @@ -28,6 +28,9 @@ #ifdef HAVE_LIBMOUNT #include #endif +#ifdef HAVE_LIBSYSTEMD +#include +#endif #include "ostree-sysroot-private.h" #include "ostree-sepolicy-private.h" @@ -39,7 +42,9 @@ #define OSTREE_VARRELABEL_ID "da679b08acd34504b789d96f818ea781" #define OSTREE_CONFIGMERGE_ID "d3863baec13e4449ab0384684a8af3a7" -#define OSTREE_DEPLOYMENT_COMPLETE_ID "dd440e3e549083b63d0efc7dc15255f1" +#ifdef HAVE_LIBSYSTEMD +#define OSTREE_DEPLOYMENT_COMPLETE_ID SD_ID128_MAKE(dd,44,0e,3e,54,90,83,b6,3d,0e,fc,7d,c1,52,55,f1) +#endif /* * Like symlinkat() but overwrites (atomically) an existing @@ -982,20 +987,34 @@ syncfs_dir_at (int dfd, return TRUE; } +typedef struct { + guint64 root_syncfs_msec; + guint64 boot_syncfs_msec; + guint64 extra_syncfs_msec; +} SyncStats; + /* First, sync the root directory as well as /var and /boot which may * be separate mount points. Then *in addition*, do a global * `sync()`. */ static gboolean full_system_sync (OstreeSysroot *self, + SyncStats *out_stats, GCancellable *cancellable, GError **error) { + guint64 start_msec = g_get_monotonic_time () / 1000; if (syncfs (self->sysroot_fd) != 0) return glnx_throw_errno_prefix (error, "syncfs(sysroot)"); + guint64 end_msec = g_get_monotonic_time () / 1000; + out_stats->root_syncfs_msec = (end_msec - start_msec); + + start_msec = g_get_monotonic_time () / 1000; if (!syncfs_dir_at (self->sysroot_fd, "boot", cancellable, error)) return FALSE; + end_msec = g_get_monotonic_time () / 1000; + out_stats->boot_syncfs_msec = (end_msec - start_msec); /* And now out of an excess of conservativism, we still invoke * sync(). The advantage of still using `syncfs()` above is that we @@ -1003,7 +1022,10 @@ full_system_sync (OstreeSysroot *self, * delineate what we actually want to sync in the future when this * global sync call is removed. */ + start_msec = g_get_monotonic_time () / 1000; sync (); + end_msec = g_get_monotonic_time () / 1000; + out_stats->extra_syncfs_msec = (end_msec - start_msec); return TRUE; } @@ -1564,6 +1586,8 @@ ostree_sysroot_write_deployments_with_options (OstreeSysroot *self, gboolean found_booted_deployment = FALSE; gboolean bootloader_is_atomic = FALSE; gboolean boot_was_ro_mount = FALSE; + SyncStats syncstats = { 0, }; + glnx_unref_object OstreeBootloader *bootloader = NULL; g_assert (self->loaded); @@ -1627,7 +1651,7 @@ ostree_sysroot_write_deployments_with_options (OstreeSysroot *self, goto out; } - if (!full_system_sync (self, cancellable, error)) + if (!full_system_sync (self, &syncstats, cancellable, error)) { g_prefix_error (error, "Full sync: "); goto out; @@ -1646,7 +1670,6 @@ ostree_sysroot_write_deployments_with_options (OstreeSysroot *self, else { int new_bootversion = self->bootversion ? 0 : 1; - glnx_unref_object OstreeBootloader *bootloader = NULL; g_autofree char* new_loader_entries_dir = NULL; glnx_unref_object OstreeRepo *repo = NULL; gboolean show_osname = FALSE; @@ -1747,7 +1770,7 @@ ostree_sysroot_write_deployments_with_options (OstreeSysroot *self, goto out; } - if (!full_system_sync (self, cancellable, error)) + if (!full_system_sync (self, &syncstats, cancellable, error)) { g_prefix_error (error, "Full sync: "); goto out; @@ -1761,11 +1784,26 @@ ostree_sysroot_write_deployments_with_options (OstreeSysroot *self, } } - ot_log_structured_print_id_v (OSTREE_DEPLOYMENT_COMPLETE_ID, - "%s; bootconfig swap: %s deployment count change: %i", - (bootloader_is_atomic ? "Transaction complete" : "Bootloader updated"), - requires_new_bootversion ? "yes" : "no", - new_deployments->len - self->deployments->len); + { g_autofree char *msg = + g_strdup_printf ("%s; bootconfig swap: %s deployment count change: %i", + (bootloader_is_atomic ? "Transaction complete" : "Bootloader updated"), + requires_new_bootversion ? "yes" : "no", + new_deployments->len - self->deployments->len); +#ifdef HAVE_LIBSYSTEMD + sd_journal_send ("MESSAGE_ID=" SD_ID128_FORMAT_STR, SD_ID128_FORMAT_VAL(OSTREE_DEPLOYMENT_COMPLETE_ID), + "MESSAGE=%s", msg, + "OSTREE_BOOTLOADER=%s", bootloader ? _ostree_bootloader_get_name (bootloader) : "none", + "OSTREE_BOOTLOADER_ATOMIC=%s", bootloader_is_atomic ? "yes" : "no", + "OSTREE_DID_BOOTSWAP=%s", requires_new_bootversion ? "yes" : "no", + "OSTREE_N_DEPLOYMENTS=%u", new_deployments->len, + "OSTREE_SYNCFS_ROOT_MSEC=%" G_GUINT64_FORMAT, syncstats.root_syncfs_msec, + "OSTREE_SYNCFS_BOOT_MSEC=%" G_GUINT64_FORMAT, syncstats.boot_syncfs_msec, + "OSTREE_SYNCFS_EXTRA_MSEC=%" G_GUINT64_FORMAT, syncstats.extra_syncfs_msec, + NULL); +#endif + if (!ot_stdout_is_journal ()) + g_print ("%s\n", msg); + } if (!_ostree_sysroot_bump_mtime (self, error)) goto out; diff --git a/src/libotutil/ot-log-utils.c b/src/libotutil/ot-log-utils.c index e1ce1690..c8a3bda7 100644 --- a/src/libotutil/ot-log-utils.c +++ b/src/libotutil/ot-log-utils.c @@ -88,7 +88,7 @@ ot_log_structured (const char *message, * * Returns: %TRUE if stdout is (probably) connnected to the systemd journal */ -static gboolean +gboolean ot_stdout_is_journal (void) { static gsize initialized; diff --git a/src/libotutil/ot-log-utils.h b/src/libotutil/ot-log-utils.h index 8d9786de..4433ee16 100644 --- a/src/libotutil/ot-log-utils.h +++ b/src/libotutil/ot-log-utils.h @@ -24,6 +24,8 @@ G_BEGIN_DECLS +gboolean ot_stdout_is_journal (void); + void ot_log_structured_print_id_v (const char *message_id, const char *format, ...) G_GNUC_PRINTF(2, 3); From d5273b34d0b4359aa668563528644061025e7ab1 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Thu, 27 Jul 2017 21:22:48 -0400 Subject: [PATCH 18/67] lib/repo: Add API to create and list ref aliases There are multiple use cases where we'd like to alias refs. First, having a "stable" alias which gets swapped across major versions: https://pagure.io/atomic-wg/issue/228 Another case is when a ref is obsoleted; This second one could be done with endoflife rebase, but I think this case is better on the server side, as we might later change our minds and do actual releases there. I initially just added some test cases for symlinks in the `refs/heads` dir to ensure this actually works (and it did), but I think it's worth having APIs. Closes: #1033 Approved by: jlebon --- apidoc/ostree-sections.txt | 1 + src/libostree/libostree-devel.sym | 1 + src/libostree/ostree-repo-commit.c | 28 +++++++- src/libostree/ostree-repo-private.h | 1 + src/libostree/ostree-repo-refs.c | 103 +++++++++++++++++++++++----- src/libostree/ostree-repo.h | 10 +++ src/ostree/ot-builtin-refs.c | 60 ++++++++++++---- tests/test-refs.sh | 42 +++++++++++- 8 files changed, 213 insertions(+), 33 deletions(-) diff --git a/apidoc/ostree-sections.txt b/apidoc/ostree-sections.txt index 47f351d2..43e267f6 100644 --- a/apidoc/ostree-sections.txt +++ b/apidoc/ostree-sections.txt @@ -307,6 +307,7 @@ ostree_repo_abort_transaction ostree_repo_transaction_set_refspec ostree_repo_transaction_set_ref ostree_repo_set_ref_immediate +ostree_repo_set_alias_ref_immediate ostree_repo_set_cache_dir ostree_repo_sign_delta ostree_repo_has_object diff --git a/src/libostree/libostree-devel.sym b/src/libostree/libostree-devel.sym index c93e388a..d4ee86bf 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_2017.10 { + ostree_repo_set_alias_ref_immediate; }; /* 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 ab348311..37b14f26 100644 --- a/src/libostree/ostree-repo-commit.c +++ b/src/libostree/ostree-repo-commit.c @@ -1451,7 +1451,31 @@ ostree_repo_set_ref_immediate (OstreeRepo *self, GError **error) { const OstreeCollectionRef _ref = { NULL, (gchar *) ref }; - return _ostree_repo_write_ref (self, remote, &_ref, checksum, + return _ostree_repo_write_ref (self, remote, &_ref, checksum, NULL, + cancellable, error); +} + +/** + * ostree_repo_set_alias_ref_immediate: + * @self: An #OstreeRepo + * @remote: (allow-none): A remote for the ref + * @ref: The ref to write + * @target: (allow-none): The ref target to point it to, or %NULL to unset + * @cancellable: GCancellable + * @error: GError + * + * Like ostree_repo_set_ref_immediate(), but creates an alias. + */ +gboolean +ostree_repo_set_alias_ref_immediate (OstreeRepo *self, + const char *remote, + const char *ref, + const char *target, + GCancellable *cancellable, + GError **error) +{ + const OstreeCollectionRef _ref = { NULL, (gchar *) ref }; + return _ostree_repo_write_ref (self, remote, &_ref, NULL, target, cancellable, error); } @@ -1483,7 +1507,7 @@ ostree_repo_set_collection_ref_immediate (OstreeRepo *self, g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), FALSE); g_return_val_if_fail (error == NULL || *error == NULL, FALSE); - return _ostree_repo_write_ref (self, NULL, ref, checksum, + return _ostree_repo_write_ref (self, NULL, ref, checksum, NULL, cancellable, error); } diff --git a/src/libostree/ostree-repo-private.h b/src/libostree/ostree-repo-private.h index 5dd0dea7..1596c0db 100644 --- a/src/libostree/ostree-repo-private.h +++ b/src/libostree/ostree-repo-private.h @@ -265,6 +265,7 @@ _ostree_repo_write_ref (OstreeRepo *self, const char *remote, const OstreeCollectionRef *ref, const char *rev, + const char *alias, GCancellable *cancellable, GError **error); diff --git a/src/libostree/ostree-repo-refs.c b/src/libostree/ostree-repo-refs.c index 491f22bd..a180e40b 100644 --- a/src/libostree/ostree-repo-refs.c +++ b/src/libostree/ostree-repo-refs.c @@ -472,6 +472,7 @@ ostree_repo_resolve_rev_ext (OstreeRepo *self, static gboolean enumerate_refs_recurse (OstreeRepo *repo, const char *remote, + OstreeRepoListRefsExtFlags flags, const char *collection_id, int base_dfd, GString *base_path, @@ -482,6 +483,7 @@ enumerate_refs_recurse (OstreeRepo *repo, GError **error) { g_auto(GLnxDirFdIterator) dfd_iter = { 0, }; + const gboolean aliases_only = (flags & OSTREE_REPO_LIST_REFS_EXT_ALIASES) > 0; if (!glnx_dirfd_iterator_init_at (child_dfd, path, FALSE, &dfd_iter, error)) return FALSE; @@ -502,16 +504,30 @@ enumerate_refs_recurse (OstreeRepo *repo, { g_string_append_c (base_path, '/'); - if (!enumerate_refs_recurse (repo, remote, collection_id, base_dfd, base_path, + if (!enumerate_refs_recurse (repo, remote, flags, collection_id, base_dfd, base_path, dfd_iter.fd, dent->d_name, refs, cancellable, error)) return FALSE; } - else if (dent->d_type == DT_REG) + else { - if (!add_ref_to_set (remote, collection_id, base_dfd, base_path->str, refs, - cancellable, error)) - return FALSE; + if (aliases_only && dent->d_type == DT_LNK) + { + g_autofree char *target = glnx_readlinkat_malloc (base_dfd, base_path->str, + cancellable, error); + const char *resolved_target = target; + if (!target) + return FALSE; + while (g_str_has_prefix (resolved_target, "../")) + resolved_target += 3; + g_hash_table_insert (refs, g_strdup (base_path->str), g_strdup (resolved_target)); + } + else if ((!aliases_only && dent->d_type == DT_REG) || dent->d_type == DT_LNK) + { + if (!add_ref_to_set (remote, collection_id, base_dfd, base_path->str, refs, + cancellable, error)) + return FALSE; + } } g_string_truncate (base_path, len); @@ -523,6 +539,7 @@ enumerate_refs_recurse (OstreeRepo *repo, static gboolean _ostree_repo_list_refs_internal (OstreeRepo *self, gboolean cut_prefix, + OstreeRepoListRefsExtFlags flags, const char *refspec_prefix, GHashTable **out_all_refs, GCancellable *cancellable, @@ -571,7 +588,7 @@ _ostree_repo_list_refs_internal (OstreeRepo *self, if (!glnx_opendirat (self->repo_dir_fd, cut_prefix ? path : prefix_path, TRUE, &base_fd, error)) return FALSE; - if (!enumerate_refs_recurse (self, remote, NULL, base_fd, base_path, + if (!enumerate_refs_recurse (self, remote, flags, NULL, base_fd, base_path, base_fd, cut_prefix ? "." : ref_prefix, ret_all_refs, cancellable, error)) return FALSE; @@ -598,7 +615,7 @@ _ostree_repo_list_refs_internal (OstreeRepo *self, if (!glnx_opendirat (self->repo_dir_fd, "refs/heads", TRUE, &refs_heads_dfd, error)) return FALSE; - if (!enumerate_refs_recurse (self, NULL, NULL, refs_heads_dfd, base_path, + if (!enumerate_refs_recurse (self, NULL, flags, NULL, refs_heads_dfd, base_path, refs_heads_dfd, ".", ret_all_refs, cancellable, error)) return FALSE; @@ -624,7 +641,7 @@ _ostree_repo_list_refs_internal (OstreeRepo *self, if (!glnx_opendirat (dfd_iter.fd, dent->d_name, TRUE, &remote_dfd, error)) return FALSE; - if (!enumerate_refs_recurse (self, dent->d_name, NULL, remote_dfd, base_path, + if (!enumerate_refs_recurse (self, dent->d_name, flags, NULL, remote_dfd, base_path, remote_dfd, ".", ret_all_refs, cancellable, error)) @@ -655,7 +672,10 @@ ostree_repo_list_refs (OstreeRepo *self, GCancellable *cancellable, GError **error) { - return _ostree_repo_list_refs_internal (self, TRUE, refspec_prefix, out_all_refs, cancellable, error); + return _ostree_repo_list_refs_internal (self, TRUE, + OSTREE_REPO_LIST_REFS_EXT_NONE, + refspec_prefix, out_all_refs, + cancellable, error); } /** @@ -681,7 +701,9 @@ ostree_repo_list_refs_ext (OstreeRepo *self, GCancellable *cancellable, GError **error) { - return _ostree_repo_list_refs_internal (self, FALSE, refspec_prefix, out_all_refs, cancellable, error); + return _ostree_repo_list_refs_internal (self, FALSE, flags, + refspec_prefix, out_all_refs, + cancellable, error); } /** @@ -757,17 +779,43 @@ ostree_repo_remote_list_refs (OstreeRepo *self, return TRUE; } +static char * +relative_symlink_to (const char *relpath, + const char *target) +{ + g_assert (*relpath); + g_assert (*target && *target != '/'); + + g_autoptr(GString) buf = g_string_new (""); + + while (TRUE) + { + const char *slash = strchr (relpath, '/'); + if (!slash) + break; + relpath = slash + 1; + g_string_append (buf, "../"); + } + + g_string_append (buf, target); + + return g_string_free (g_steal_pointer (&buf), FALSE); +} + +/* May specify @rev or @alias */ gboolean _ostree_repo_write_ref (OstreeRepo *self, const char *remote, const OstreeCollectionRef *ref, const char *rev, + const char *alias, GCancellable *cancellable, GError **error) { glnx_fd_close int dfd = -1; g_return_val_if_fail (remote == NULL || ref->collection_id == NULL, FALSE); + g_return_val_if_fail (!(rev != NULL && alias != NULL), FALSE); if (remote != NULL && !ostree_validate_remote_name (remote, error)) return FALSE; @@ -832,7 +880,7 @@ _ostree_repo_write_ref (OstreeRepo *self, return glnx_throw_errno_prefix (error, "Opening remotes/ dir %s", remote); } - if (rev == NULL) + if (rev == NULL && alias == NULL) { if (dfd >= 0) { @@ -843,11 +891,32 @@ _ostree_repo_write_ref (OstreeRepo *self, } } } - else + else if (rev != NULL) { if (!write_checksum_file_at (self, dfd, ref->ref_name, rev, cancellable, error)) return FALSE; } + else if (alias != NULL) + { + const char *lastslash = strrchr (ref->ref_name, '/'); + + if (lastslash) + { + char *parent = strdupa (ref->ref_name); + parent[lastslash - ref->ref_name] = '\0'; + + if (!glnx_shutil_mkdir_p_at (dfd, parent, 0755, cancellable, error)) + return FALSE; + } + + g_autofree char *reltarget = relative_symlink_to (ref->ref_name, alias); + g_autofree char *tmplink = NULL; + if (!_ostree_make_temporary_symlink_at (self->tmp_dir_fd, reltarget, + &tmplink, cancellable, error)) + return FALSE; + if (!glnx_renameat (self->tmp_dir_fd, tmplink, dfd, ref->ref_name, error)) + return FALSE; + } if (!_ostree_repo_update_mtime (self, error)) return FALSE; @@ -876,7 +945,7 @@ _ostree_repo_update_refs (OstreeRepo *self, return FALSE; const OstreeCollectionRef ref = { NULL, ref_name }; - if (!_ostree_repo_write_ref (self, remote, &ref, rev, + if (!_ostree_repo_write_ref (self, remote, &ref, rev, NULL, cancellable, error)) return FALSE; } @@ -899,7 +968,7 @@ _ostree_repo_update_collection_refs (OstreeRepo *self, const OstreeCollectionRef *ref = key; const char *rev = value; - if (!_ostree_repo_write_ref (self, NULL, ref, rev, + if (!_ostree_repo_write_ref (self, NULL, ref, rev, NULL, cancellable, error)) return FALSE; } @@ -961,7 +1030,8 @@ ostree_repo_list_collection_refs (OstreeRepo *self, if (!glnx_opendirat (self->repo_dir_fd, "refs/heads", TRUE, &refs_heads_dfd, error)) return FALSE; - if (!enumerate_refs_recurse (self, NULL, main_collection_id, refs_heads_dfd, base_path, + if (!enumerate_refs_recurse (self, NULL, OSTREE_REPO_LIST_REFS_EXT_NONE, + main_collection_id, refs_heads_dfd, base_path, refs_heads_dfd, ".", ret_all_refs, cancellable, error)) return FALSE; @@ -993,7 +1063,8 @@ ostree_repo_list_collection_refs (OstreeRepo *self, if (!glnx_opendirat (dfd_iter.fd, dent->d_name, TRUE, &collection_dfd, error)) return FALSE; - if (!enumerate_refs_recurse (self, NULL, dent->d_name, collection_dfd, base_path, + if (!enumerate_refs_recurse (self, NULL, OSTREE_REPO_LIST_REFS_EXT_NONE, + dent->d_name, collection_dfd, base_path, collection_dfd, ".", ret_all_refs, cancellable, error)) diff --git a/src/libostree/ostree-repo.h b/src/libostree/ostree-repo.h index f1e964b7..decf9a4e 100644 --- a/src/libostree/ostree-repo.h +++ b/src/libostree/ostree-repo.h @@ -327,6 +327,14 @@ gboolean ostree_repo_set_ref_immediate (OstreeRepo *self, GCancellable *cancellable, GError **error); +_OSTREE_PUBLIC +gboolean ostree_repo_set_alias_ref_immediate (OstreeRepo *self, + const char *remote, + const char *ref, + const char *target, + GCancellable *cancellable, + GError **error); + #ifdef OSTREE_ENABLE_EXPERIMENTAL_API _OSTREE_PUBLIC @@ -452,9 +460,11 @@ gboolean ostree_repo_list_refs (OstreeRepo *self, /** * OstreeRepoListRefsExtFlags: * @OSTREE_REPO_LIST_REFS_EXT_NONE: No flags. + * @OSTREE_REPO_LIST_REFS_EXT_ALIASES: Only list aliases. Since: 2017.10 */ typedef enum { OSTREE_REPO_LIST_REFS_EXT_NONE = 0, + OSTREE_REPO_LIST_REFS_EXT_ALIASES = 1, } OstreeRepoListRefsExtFlags; _OSTREE_PUBLIC diff --git a/src/ostree/ot-builtin-refs.c b/src/ostree/ot-builtin-refs.c index f2274802..0f850069 100644 --- a/src/ostree/ot-builtin-refs.c +++ b/src/ostree/ot-builtin-refs.c @@ -28,6 +28,7 @@ static gboolean opt_delete; static gboolean opt_list; +static gboolean opt_alias; static char *opt_create; #ifdef OSTREE_ENABLE_EXPERIMENTAL_API static gboolean opt_collections; @@ -36,6 +37,7 @@ static gboolean opt_collections; static GOptionEntry options[] = { { "delete", 0, 0, G_OPTION_ARG_NONE, &opt_delete, "Delete refs which match PREFIX, rather than listing them", NULL }, { "list", 0, 0, G_OPTION_ARG_NONE, &opt_list, "Do not remove the prefix from the refs", NULL }, + { "alias", 'A', 0, G_OPTION_ARG_NONE, &opt_alias, "If used with --create, create an alias, otherwise just list aliases", NULL }, { "create", 0, 0, G_OPTION_ARG_STRING, &opt_create, "Create a new ref for an existing commit", "NEWREF" }, #ifdef OSTREE_ENABLE_EXPERIMENTAL_API { "collections", 'c', 0, G_OPTION_ARG_NONE, &opt_collections, "Enable listing collection IDs for refs", NULL }, @@ -132,18 +134,36 @@ do_ref_with_collections (OstreeRepo *repo, static gboolean do_ref (OstreeRepo *repo, const char *refspec_prefix, GCancellable *cancellable, GError **error) { g_autoptr(GHashTable) refs = NULL; + g_autoptr(GHashTable) ref_aliases = NULL; GHashTableIter hashiter; gpointer hashkey, hashvalue; gboolean ret = FALSE; + gboolean is_list; #ifdef OSTREE_ENABLE_EXPERIMENTAL_API if (opt_collections) return do_ref_with_collections (repo, refspec_prefix, cancellable, error); #endif /* OSTREE_ENABLE_EXPERIMENTAL_API */ - if (opt_delete || opt_list) + /* If we're doing aliasing, we need the full list of aliases mostly to allow + * replacing existing aliases. + */ + if (opt_alias) { - if (!ostree_repo_list_refs_ext (repo, refspec_prefix, &refs, OSTREE_REPO_LIST_REFS_EXT_NONE, + if (!ostree_repo_list_refs_ext (repo, NULL, &ref_aliases, + OSTREE_REPO_LIST_REFS_EXT_ALIASES, + cancellable, error)) + goto out; + } + + is_list = !(opt_delete || opt_create); + + if (opt_delete || opt_list || (!opt_create && opt_alias)) + { + OstreeRepoListRefsExtFlags flags = OSTREE_REPO_LIST_REFS_EXT_NONE; + if (opt_alias) + flags |= OSTREE_REPO_LIST_REFS_EXT_ALIASES; + if (!ostree_repo_list_refs_ext (repo, refspec_prefix, &refs, flags, cancellable, error)) goto out; } @@ -156,13 +176,14 @@ static gboolean do_ref (OstreeRepo *repo, const char *refspec_prefix, GCancellab else if (!ostree_repo_list_refs (repo, refspec_prefix, &refs, cancellable, error)) goto out; - if (!opt_delete && !opt_create) + if (is_list) { - g_hash_table_iter_init (&hashiter, refs); - while (g_hash_table_iter_next (&hashiter, &hashkey, &hashvalue)) + GLNX_HASH_TABLE_FOREACH_KV (refs, const char *, ref, const char *, value) { - const char *ref = hashkey; - g_print ("%s\n", ref); + if (opt_alias) + g_print ("%s -> %s\n", ref, value); + else + g_print ("%s\n", ref); } } else if (opt_create) @@ -183,22 +204,33 @@ static gboolean do_ref (OstreeRepo *repo, const char *refspec_prefix, GCancellab else goto out; } - if (checksum_existing != NULL) + /* We want to allow replacing an existing alias */ + gboolean replacing_alias = opt_alias && g_hash_table_contains (ref_aliases, opt_create); + if (!replacing_alias && checksum_existing != NULL) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "--create specified but ref %s already exists", opt_create); goto out; } - if (!ostree_repo_resolve_rev (repo, refspec_prefix, FALSE, &checksum, error)) - goto out; - if (!ostree_parse_refspec (opt_create, &remote, &ref, error)) goto out; - if (!ostree_repo_set_ref_immediate (repo, remote, ref, checksum, - cancellable, error)) - goto out; + if (opt_alias) + { + if (!ostree_repo_set_alias_ref_immediate (repo, remote, ref, refspec_prefix, + cancellable, error)) + goto out; + } + else + { + if (!ostree_repo_resolve_rev (repo, refspec_prefix, FALSE, &checksum, error)) + goto out; + + if (!ostree_repo_set_ref_immediate (repo, remote, ref, checksum, + cancellable, error)) + goto out; + } } else /* delete */ diff --git a/tests/test-refs.sh b/tests/test-refs.sh index d4db0013..e48784aa 100755 --- a/tests/test-refs.sh +++ b/tests/test-refs.sh @@ -23,7 +23,7 @@ set -euo pipefail setup_fake_remote_repo1 "archive-z2" -echo '1..1' +echo '1..2' cd ${test_tmpdir} mkdir repo @@ -117,3 +117,43 @@ ${CMD_PREFIX} ostree --repo=repo refs | wc -l > refscount.create6 assert_file_has_content refscount.create6 "^11$" echo "ok refs" + +# Test symlinking a ref +${CMD_PREFIX} ostree --repo=repo refs ctest --create=exampleos/x86_64/26/server +${CMD_PREFIX} ostree --repo=repo refs -A exampleos/x86_64/26/server --create=exampleos/x86_64/stable/server +${CMD_PREFIX} ostree --repo=repo summary -u +${CMD_PREFIX} ostree --repo=repo refs > refs.txt +for v in 26 stable; do + assert_file_has_content refs.txt exampleos/x86_64/${v}/server +done +${CMD_PREFIX} ostree --repo=repo refs -A > refs.txt +assert_file_has_content_literal refs.txt 'exampleos/x86_64/stable/server -> exampleos/x86_64/26/server' +assert_not_file_has_content refs.txt '^exampleos/x86_64/26/server' +stable=$(${CMD_PREFIX} ostree --repo=repo rev-parse exampleos/x86_64/stable/server) +current=$(${CMD_PREFIX} ostree --repo=repo rev-parse exampleos/x86_64/26/server) +assert_streq "${stable}" "${current}" +${CMD_PREFIX} ostree --repo=repo commit -b exampleos/x86_64/26/server --tree=dir=tree +${CMD_PREFIX} ostree --repo=repo summary -u +newcurrent=$(${CMD_PREFIX} ostree --repo=repo rev-parse exampleos/x86_64/26/server) +assert_not_streq "${newcurrent}" "${current}" +newstable=$(${CMD_PREFIX} ostree --repo=repo rev-parse exampleos/x86_64/stable/server) +assert_streq "${newcurrent}" "${newstable}" + +# Test that we can swap the symlink +${CMD_PREFIX} ostree --repo=repo commit -b exampleos/x86_64/27/server --tree=dir=tree +newcurrent=$(${CMD_PREFIX} ostree --repo=repo rev-parse exampleos/x86_64/27/server) +assert_not_streq "${newcurrent}" "${newstable}" +${CMD_PREFIX} ostree --repo=repo refs -A exampleos/x86_64/27/server --create=exampleos/x86_64/stable/server +newnewstable=$(${CMD_PREFIX} ostree --repo=repo rev-parse exampleos/x86_64/stable/server) +assert_not_streq "${newnewstable}" "${newstable}" +assert_streq "${newnewstable}" "${newcurrent}" +${CMD_PREFIX} ostree --repo=repo refs > refs.txt +for v in 26 27 stable; do + assert_file_has_content refs.txt exampleos/x86_64/${v}/server +done +${CMD_PREFIX} ostree --repo=repo refs -A > refs.txt +assert_file_has_content_literal refs.txt 'exampleos/x86_64/stable/server -> exampleos/x86_64/27/server' + +${CMD_PREFIX} ostree --repo=repo summary -u + +echo "ok ref symlink" From e0f17b41ba609197a316f26b5e56f0762012fcfe Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Wed, 2 Aug 2017 10:40:56 -0400 Subject: [PATCH 19/67] lib/pull: Log state of summary/commit GPG verification Since we have both, we should clearly log the state of both of them. Split this out of a larger patch. Closes: #1046 Approved by: jlebon --- src/libostree/ostree-repo-pull.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/libostree/ostree-repo-pull.c b/src/libostree/ostree-repo-pull.c index 7ef0ba1c..e0c384a2 100644 --- a/src/libostree/ostree-repo-pull.c +++ b/src/libostree/ostree-repo-pull.c @@ -4111,7 +4111,17 @@ ostree_repo_pull_with_options (OstreeRepo *self, g_string_append_printf (msg, "libostree pull from '%s' for %u refs complete", pull_data->remote_name, g_hash_table_size (requested_refs_to_fetch)); - g_string_append_printf (msg, "\nsecurity: GPG: %s ", pull_data->gpg_verify ? "yes" : "no"); + const char *gpg_verify_state; + if (pull_data->gpg_verify_summary) + { + if (pull_data->gpg_verify) + gpg_verify_state = "summary+commit"; + else + gpg_verify_state = "summary-only"; + } + else + gpg_verify_state = (pull_data->gpg_verify ? "commit" : "disabled"); + g_string_append_printf (msg, "\nsecurity: GPG: %s ", gpg_verify_state); OstreeFetcherURI *first_uri = pull_data->meta_mirrorlist->pdata[0]; g_autofree char *first_scheme = _ostree_fetcher_uri_get_scheme (first_uri); if (g_str_has_prefix (first_scheme, "http")) @@ -4146,7 +4156,7 @@ ostree_repo_pull_with_options (OstreeRepo *self, sd_journal_send ("MESSAGE=%s", msg->str, "MESSAGE_ID=" SD_ID128_FORMAT_STR, SD_ID128_FORMAT_VAL(OSTREE_MESSAGE_FETCH_COMPLETE_ID), "OSTREE_REMOTE=%s", pull_data->remote_name, - "OSTREE_GPG=%s", pull_data->gpg_verify ? "yes" : "no", + "OSTREE_GPG=%s", gpg_verify_state, "OSTREE_SECONDS=%u", n_seconds, "OSTREE_XFER_SIZE=%s", formatted_xferred, NULL); From 7f33d94dde16c685169c93a868ae91c8390e4292 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Wed, 2 Aug 2017 13:26:23 -0400 Subject: [PATCH 20/67] tests/libtest-core.sh: Add a comment that this copy is canonical Ref: https://github.com/projectatomic/bubblewrap/pull/203 Closes: #1047 Approved by: jlebon --- tests/libtest-core.sh | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/tests/libtest-core.sh b/tests/libtest-core.sh index de850544..d0b7d372 100644 --- a/tests/libtest-core.sh +++ b/tests/libtest-core.sh @@ -1,6 +1,9 @@ -# Core source library for shell script tests; this -# file is intended to be the canonical source, which at -# is copied at least into: +# Core source library for shell script tests; the +# canonical version lives in: +# +# https://github.com/ostreedev/ostree +# +# Known copies are in the following repos: # # - https://github.com/projectatomic/rpm-ostree # From aa63d0e0c55fc419a0b86e5c02a0ac8b97757a0d Mon Sep 17 00:00:00 2001 From: Guy Shapiro Date: Thu, 3 Aug 2017 12:32:36 +0300 Subject: [PATCH 21/67] Documentation: README: Remove deprecated wiki link The old wiki only contains link back to readthedocs. The link to is useless. Closes: #1050 Approved by: cgwalters --- README.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/README.md b/README.md index c985cd14..743d49df 100644 --- a/README.md +++ b/README.md @@ -98,9 +98,6 @@ More documentation New! See the docs online at [Read The Docs (OSTree)](https://ostree.readthedocs.org/en/latest/ ) -Some more information is available on the old wiki page: - - Contributing ------------ From b929b620aebbc241caa965472f4fe351223b7a35 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Mon, 31 Jul 2017 12:16:59 -0400 Subject: [PATCH 22/67] tree-wide: Use g_autoptr(Ostree*) Part of cleaning up our usage of libglnx; we want to use what's in GLib where we can. Had to change a few .c files to `#include ostree.h` early on to pick up autoptrs for the core types. Closes: #1040 Approved by: jlebon --- src/libostree/ostree-bootloader.h | 1 + src/libostree/ostree-deployment.c | 3 ++- src/libostree/ostree-fetcher-soup.c | 2 +- src/libostree/ostree-metalink.h | 1 + src/libostree/ostree-mutable-tree.c | 9 ++++---- src/libostree/ostree-repo-commit.c | 10 ++++----- src/libostree/ostree-repo-libarchive.c | 15 +++++++------ src/libostree/ostree-repo-pull.c | 14 ++++++------- src/libostree/ostree-repo.c | 6 +++--- src/libostree/ostree-sysroot-deploy.c | 17 ++++++++------- src/libostree/ostree-sysroot.c | 21 ++++++++++--------- src/libostree/ostree-tls-cert-interaction.h | 1 + src/ostree/ot-admin-builtin-cleanup.c | 2 +- src/ostree/ot-admin-builtin-deploy.c | 8 +++---- src/ostree/ot-admin-builtin-diff.c | 4 ++-- src/ostree/ot-admin-builtin-init-fs.c | 4 ++-- src/ostree/ot-admin-builtin-os-init.c | 2 +- src/ostree/ot-admin-builtin-set-origin.c | 6 +++--- src/ostree/ot-admin-builtin-status.c | 6 +++--- src/ostree/ot-admin-builtin-switch.c | 8 +++---- src/ostree/ot-admin-builtin-undeploy.c | 4 ++-- src/ostree/ot-admin-builtin-unlock.c | 2 +- src/ostree/ot-admin-builtin-upgrade.c | 6 +++--- ...ot-admin-instutil-builtin-grub2-generate.c | 2 +- ...-instutil-builtin-selinux-ensure-labeled.c | 4 ++-- .../ot-admin-instutil-builtin-set-kargs.c | 2 +- src/ostree/ot-builtin-checkout.c | 2 +- src/ostree/ot-builtin-commit.c | 4 ++-- src/ostree/ot-builtin-config.c | 2 +- src/ostree/ot-builtin-diff.c | 2 +- src/ostree/ot-builtin-export.c | 2 +- src/ostree/ot-builtin-find-remotes.c | 4 ++-- src/ostree/ot-builtin-fsck.c | 2 +- src/ostree/ot-builtin-gpg-sign.c | 4 ++-- src/ostree/ot-builtin-log.c | 2 +- src/ostree/ot-builtin-ls.c | 2 +- src/ostree/ot-builtin-prune.c | 2 +- src/ostree/ot-builtin-pull-local.c | 6 +++--- src/ostree/ot-builtin-pull.c | 4 ++-- src/ostree/ot-builtin-refs.c | 2 +- src/ostree/ot-builtin-reset.c | 2 +- src/ostree/ot-builtin-rev-parse.c | 2 +- src/ostree/ot-builtin-show.c | 4 ++-- src/ostree/ot-builtin-static-delta.c | 10 ++++----- src/ostree/ot-builtin-summary.c | 2 +- src/ostree/ot-main.c | 2 +- src/ostree/ot-remote-builtin-summary.c | 2 +- 47 files changed, 114 insertions(+), 110 deletions(-) diff --git a/src/libostree/ostree-bootloader.h b/src/libostree/ostree-bootloader.h index eb044300..92cc521b 100644 --- a/src/libostree/ostree-bootloader.h +++ b/src/libostree/ostree-bootloader.h @@ -48,6 +48,7 @@ struct _OstreeBootloaderInterface GError **error); gboolean (* is_atomic) (OstreeBootloader *self); }; +G_DEFINE_AUTOPTR_CLEANUP_FUNC (OstreeBootloader, g_object_unref) GType _ostree_bootloader_get_type (void) G_GNUC_CONST; diff --git a/src/libostree/ostree-deployment.c b/src/libostree/ostree-deployment.c index 8bdc9b57..e3ee0b55 100644 --- a/src/libostree/ostree-deployment.c +++ b/src/libostree/ostree-deployment.c @@ -20,6 +20,7 @@ #include "config.h" +#include "ostree.h" #include "ostree-deployment-private.h" #include "libglnx.h" @@ -138,7 +139,7 @@ _ostree_deployment_set_bootcsum (OstreeDeployment *self, OstreeDeployment * ostree_deployment_clone (OstreeDeployment *self) { - glnx_unref_object OstreeBootconfigParser *new_bootconfig = NULL; + g_autoptr(OstreeBootconfigParser) new_bootconfig = NULL; OstreeDeployment *ret = ostree_deployment_new (self->index, self->osname, self->csum, self->deployserial, self->bootcsum, self->bootserial); diff --git a/src/libostree/ostree-fetcher-soup.c b/src/libostree/ostree-fetcher-soup.c index f73554a2..e8185591 100644 --- a/src/libostree/ostree-fetcher-soup.c +++ b/src/libostree/ostree-fetcher-soup.c @@ -350,7 +350,7 @@ session_thread_set_tls_interaction_cb (ThreadClosure *thread_closure, const char *cert_and_key_path = data; /* str\0str\0 in one malloc buf */ const char *cert_path = cert_and_key_path; const char *key_path = cert_and_key_path + strlen (cert_and_key_path) + 1; - glnx_unref_object OstreeTlsCertInteraction *interaction = NULL; + g_autoptr(OstreeTlsCertInteraction) interaction = NULL; /* The GTlsInteraction instance must be created in the * session thread so it uses the correct GMainContext. */ diff --git a/src/libostree/ostree-metalink.h b/src/libostree/ostree-metalink.h index 55ed92e8..60a24204 100644 --- a/src/libostree/ostree-metalink.h +++ b/src/libostree/ostree-metalink.h @@ -40,6 +40,7 @@ struct OstreeMetalinkClass { GObjectClass parent_class; }; +G_DEFINE_AUTOPTR_CLEANUP_FUNC (OstreeMetalink, g_object_unref) GType _ostree_metalink_get_type (void) G_GNUC_CONST; diff --git a/src/libostree/ostree-mutable-tree.c b/src/libostree/ostree-mutable-tree.c index c263fbe4..c144cff4 100644 --- a/src/libostree/ostree-mutable-tree.c +++ b/src/libostree/ostree-mutable-tree.c @@ -22,9 +22,8 @@ #include "config.h" -#include "ostree-mutable-tree.h" +#include "ostree.h" #include "otutil.h" -#include "ostree-core.h" /** * SECTION:ostree-mutable-tree @@ -183,7 +182,7 @@ ostree_mutable_tree_ensure_dir (OstreeMutableTree *self, GError **error) { gboolean ret = FALSE; - glnx_unref_object OstreeMutableTree *ret_dir = NULL; + g_autoptr(OstreeMutableTree) ret_dir = NULL; g_return_val_if_fail (name != NULL, FALSE); @@ -219,7 +218,7 @@ ostree_mutable_tree_lookup (OstreeMutableTree *self, GError **error) { gboolean ret = FALSE; - glnx_unref_object OstreeMutableTree *ret_subdir = NULL; + g_autoptr(OstreeMutableTree) ret_subdir = NULL; g_autofree char *ret_file_checksum = NULL; ret_subdir = ot_gobject_refz (g_hash_table_lookup (self->subdirs, name)); @@ -261,7 +260,7 @@ ostree_mutable_tree_ensure_parent_dirs (OstreeMutableTree *self, gboolean ret = FALSE; int i; OstreeMutableTree *subdir = self; /* nofree */ - glnx_unref_object OstreeMutableTree *ret_parent = NULL; + g_autoptr(OstreeMutableTree) ret_parent = NULL; g_assert (metadata_checksum != NULL); diff --git a/src/libostree/ostree-repo-commit.c b/src/libostree/ostree-repo-commit.c index 37b14f26..346cbb42 100644 --- a/src/libostree/ostree-repo-commit.c +++ b/src/libostree/ostree-repo-commit.c @@ -27,16 +27,16 @@ #include #include #include -#include "otutil.h" +#include +#include +#include "ostree.h" #include "ostree-core-private.h" #include "ostree-repo-private.h" #include "ostree-repo-file-enumerator.h" #include "ostree-checksum-input-stream.h" -#include "ostree-mutable-tree.h" #include "ostree-varint.h" -#include -#include +#include "otutil.h" gboolean _ostree_repo_ensure_loose_objdir_at (int dfd, @@ -2555,7 +2555,7 @@ write_directory_content_to_mtree_internal (OstreeRepo *self, { g_autoptr(GFile) child = NULL; g_autoptr(GFileInfo) modified_info = NULL; - glnx_unref_object OstreeMutableTree *child_mtree = NULL; + g_autoptr(OstreeMutableTree) child_mtree = NULL; g_autofree char *child_relpath = NULL; const char *name; GFileType file_type; diff --git a/src/libostree/ostree-repo-libarchive.c b/src/libostree/ostree-repo-libarchive.c index 02e12d50..f3f4b29e 100644 --- a/src/libostree/ostree-repo-libarchive.c +++ b/src/libostree/ostree-repo-libarchive.c @@ -22,10 +22,9 @@ #include "config.h" +#include "ostree.h" #include "ostree-core-private.h" #include "ostree-repo-private.h" -#include "ostree-repo-file.h" -#include "ostree-mutable-tree.h" #ifdef HAVE_LIBARCHIVE #include @@ -185,7 +184,7 @@ mtree_ensure_dir_with_meta (OstreeRepo *repo, GCancellable *cancellable, GError **error) { - glnx_unref_object OstreeMutableTree *dir = NULL; + g_autoptr(OstreeMutableTree) dir = NULL; g_autofree guchar *csum_raw = NULL; g_autofree char *csum = NULL; @@ -374,7 +373,7 @@ aic_create_parent_dirs (OstreeRepoArchiveImportContext *ctx, GError **error) { g_autofree char *fullpath = NULL; - glnx_unref_object OstreeMutableTree *dir = NULL; + g_autoptr(OstreeMutableTree) dir = NULL; /* start with the root itself */ if (!aic_ensure_parent_dir (ctx, ctx->root, "/", &dir, cancellable, error)) @@ -643,7 +642,7 @@ aic_import_entry (OstreeRepoArchiveImportContext *ctx, GError **error) { g_autoptr(GFileInfo) fi = NULL; - glnx_unref_object OstreeMutableTree *parent = NULL; + g_autoptr(OstreeMutableTree) parent = NULL; g_autofree char *path = aic_get_final_entry_pathname (ctx, error); if (path == NULL) @@ -669,7 +668,7 @@ aic_import_from_hardlink (OstreeRepoArchiveImportContext *ctx, const char *name = glnx_basename (target); const char *name_dh = glnx_basename (dh->path); g_autoptr(GPtrArray) components = NULL; - glnx_unref_object OstreeMutableTree *parent = NULL; + g_autoptr(OstreeMutableTree) parent = NULL; if (!ostree_mutable_tree_lookup (dh->parent, name_dh, &csum, NULL, error)) return FALSE; @@ -696,8 +695,8 @@ aic_lookup_file_csum (OstreeRepoArchiveImportContext *ctx, { g_autofree char *csum = NULL; const char *name = glnx_basename (target); - glnx_unref_object OstreeMutableTree *parent = NULL; - glnx_unref_object OstreeMutableTree *subdir = NULL; + g_autoptr(OstreeMutableTree) parent = NULL; + g_autoptr(OstreeMutableTree) subdir = NULL; g_autoptr(GPtrArray) components = NULL; if (!ot_util_path_split_validate (target, &components, error)) diff --git a/src/libostree/ostree-repo-pull.c b/src/libostree/ostree-repo-pull.c index e0c384a2..fd4be499 100644 --- a/src/libostree/ostree-repo-pull.c +++ b/src/libostree/ostree-repo-pull.c @@ -1418,7 +1418,7 @@ gpg_verify_unwritten_commit (OtPullData *pull_data, { if (pull_data->gpg_verify) { - glnx_unref_object OstreeGpgVerifyResult *result = NULL; + g_autoptr(OstreeGpgVerifyResult) result = NULL; g_autoptr(GBytes) signed_data = g_variant_get_data_as_bytes (commit); if (!detached_metadata) @@ -1624,7 +1624,7 @@ scan_commit_object (OtPullData *pull_data, if (pull_data->gpg_verify) { - glnx_unref_object OstreeGpgVerifyResult *result = NULL; + g_autoptr(OstreeGpgVerifyResult) result = NULL; result = ostree_repo_verify_commit_for_remote (pull_data->repo, checksum, @@ -2748,7 +2748,7 @@ _ostree_preload_metadata_file (OstreeRepo *self, if (is_metalink) { - glnx_unref_object OstreeMetalink *metalink = NULL; + g_autoptr(OstreeMetalink) metalink = NULL; GError *local_error = NULL; /* the metalink uri is buried in the mirrorlist as the first (and only) @@ -2898,7 +2898,7 @@ repo_remote_fetch_summary (OstreeRepo *self, GCancellable *cancellable, GError **error) { - glnx_unref_object OstreeFetcher *fetcher = NULL; + g_autoptr(OstreeFetcher) fetcher = NULL; g_autoptr(GMainContext) mainctx = NULL; gboolean ret = FALSE; gboolean from_cache = FALSE; @@ -3213,7 +3213,7 @@ ostree_repo_pull_with_options (OstreeRepo *self, g_autoptr(GHashTable) requested_refs_to_fetch = NULL; /* (element-type OstreeCollectionRef utf8) */ g_autoptr(GHashTable) commits_to_fetch = NULL; g_autofree char *remote_mode_str = NULL; - glnx_unref_object OstreeMetalink *metalink = NULL; + g_autoptr(OstreeMetalink) metalink = NULL; OtPullData pull_data_real = { 0, }; OtPullData *pull_data = &pull_data_real; GKeyFile *remote_config = NULL; @@ -4960,7 +4960,7 @@ find_remotes_cb (GObject *obj, &error)) goto error; - glnx_unref_object OstreeGpgVerifyResult *verify_result = NULL; + g_autoptr(OstreeGpgVerifyResult) verify_result = NULL; verify_result = ostree_repo_verify_commit_for_remote (self, commit_metadata->checksum, @@ -5608,7 +5608,7 @@ ostree_repo_remote_fetch_summary_with_options (OstreeRepo *self, /* Verify any summary signatures. */ if (gpg_verify_summary && summary != NULL && signatures != NULL) { - glnx_unref_object OstreeGpgVerifyResult *result = NULL; + g_autoptr(OstreeGpgVerifyResult) result = NULL; result = ostree_repo_verify_summary (self, name, diff --git a/src/libostree/ostree-repo.c b/src/libostree/ostree-repo.c index 5730b11e..5d5d871b 100644 --- a/src/libostree/ostree-repo.c +++ b/src/libostree/ostree-repo.c @@ -4082,7 +4082,7 @@ ostree_repo_sign_commit (OstreeRepo *self, * check if the commit has already been signed with the given key ID. * We want to avoid storing duplicate signatures in the metadata. */ g_autoptr(GError) local_error = NULL; - glnx_unref_object OstreeGpgVerifyResult *result + g_autoptr(OstreeGpgVerifyResult) result =_ostree_repo_gpg_verify_with_metadata (self, commit_data, old_metadata, NULL, NULL, NULL, cancellable, &local_error); @@ -4239,7 +4239,7 @@ _ostree_repo_gpg_verify_data_internal (OstreeRepo *self, GCancellable *cancellable, GError **error) { - glnx_unref_object OstreeGpgVerifier *verifier = NULL; + g_autoptr(OstreeGpgVerifier) verifier = NULL; gboolean add_global_keyring_dir = TRUE; verifier = _ostree_gpg_verifier_new (); @@ -4441,7 +4441,7 @@ ostree_repo_verify_commit (OstreeRepo *self, GCancellable *cancellable, GError **error) { - glnx_unref_object OstreeGpgVerifyResult *result = NULL; + g_autoptr(OstreeGpgVerifyResult) result = NULL; result = ostree_repo_verify_commit_ext (self, commit_checksum, keyringdir, extra_keyring, diff --git a/src/libostree/ostree-sysroot-deploy.c b/src/libostree/ostree-sysroot-deploy.c index 99559f63..d857f0c5 100644 --- a/src/libostree/ostree-sysroot-deploy.c +++ b/src/libostree/ostree-sysroot-deploy.c @@ -32,6 +32,7 @@ #include #endif +#include "ostree.h" #include "ostree-sysroot-private.h" #include "ostree-sepolicy-private.h" #include "ostree-deployment-private.h" @@ -722,7 +723,7 @@ merge_configuration (OstreeSysroot *sysroot, GCancellable *cancellable, GError **error) { - glnx_unref_object OstreeSePolicy *sepolicy = NULL; + g_autoptr(OstreeSePolicy) sepolicy = NULL; if (previous_deployment) { @@ -1587,7 +1588,7 @@ ostree_sysroot_write_deployments_with_options (OstreeSysroot *self, gboolean bootloader_is_atomic = FALSE; gboolean boot_was_ro_mount = FALSE; SyncStats syncstats = { 0, }; - glnx_unref_object OstreeBootloader *bootloader = NULL; + g_autoptr(OstreeBootloader) bootloader = NULL; g_assert (self->loaded); @@ -1671,7 +1672,7 @@ ostree_sysroot_write_deployments_with_options (OstreeSysroot *self, { int new_bootversion = self->bootversion ? 0 : 1; g_autofree char* new_loader_entries_dir = NULL; - glnx_unref_object OstreeRepo *repo = NULL; + g_autoptr(OstreeRepo) repo = NULL; gboolean show_osname = FALSE; if (self->booted_deployment) @@ -1918,7 +1919,7 @@ ostree_sysroot_deploy_tree (OstreeSysroot *self, return FALSE; OstreeRepo *repo = ostree_sysroot_repo (self); - glnx_unref_object OstreeDeployment *merge_deployment = NULL; + g_autoptr(OstreeDeployment) merge_deployment = NULL; if (provided_merge_deployment != NULL) merge_deployment = g_object_ref (provided_merge_deployment); @@ -1928,7 +1929,7 @@ ostree_sysroot_deploy_tree (OstreeSysroot *self, return FALSE; g_autofree char *new_bootcsum = NULL; - glnx_unref_object OstreeDeployment *new_deployment = + g_autoptr(OstreeDeployment) new_deployment = ostree_deployment_new (0, osname, revision, new_deployserial, new_bootcsum, -1); ostree_deployment_set_origin (new_deployment, origin); @@ -1966,10 +1967,10 @@ ostree_sysroot_deploy_tree (OstreeSysroot *self, /* Create an empty boot configuration; we will merge things into * it as we go. */ - glnx_unref_object OstreeBootconfigParser *bootconfig = ostree_bootconfig_parser_new (); + g_autoptr(OstreeBootconfigParser) bootconfig = ostree_bootconfig_parser_new (); ostree_deployment_set_bootconfig (new_deployment, bootconfig); - glnx_unref_object OstreeSePolicy *sepolicy = NULL; + g_autoptr(OstreeSePolicy) sepolicy = NULL; if (!merge_configuration (self, repo, merge_deployment, new_deployment, deployment_dfd, &sepolicy, @@ -2047,7 +2048,7 @@ ostree_sysroot_deployment_set_kargs (OstreeSysroot *self, { guint i; g_autoptr(GPtrArray) new_deployments = g_ptr_array_new_with_free_func (g_object_unref); - glnx_unref_object OstreeDeployment *new_deployment = NULL; + g_autoptr(OstreeDeployment) new_deployment = NULL; __attribute__((cleanup(_ostree_kernel_args_cleanup))) OstreeKernelArgs *kargs = NULL; g_autofree char *new_options = NULL; OstreeBootconfigParser *new_bootconfig; diff --git a/src/libostree/ostree-sysroot.c b/src/libostree/ostree-sysroot.c index d262a903..cb09db7b 100644 --- a/src/libostree/ostree-sysroot.c +++ b/src/libostree/ostree-sysroot.c @@ -25,6 +25,7 @@ #include #include +#include "ostree.h" #include "ostree-core-private.h" #include "ostree-repo-private.h" #include "ostree-sepolicy-private.h" @@ -307,7 +308,7 @@ ostree_sysroot_ensure_initialized (OstreeSysroot *self, else { g_autoptr(GFile) repo_dir = g_file_resolve_relative_path (self->path, "ostree/repo"); - glnx_unref_object OstreeRepo *repo = ostree_repo_new (repo_dir); + g_autoptr(OstreeRepo) repo = ostree_repo_new (repo_dir); if (!ostree_repo_create (repo, OSTREE_REPO_MODE_BARE, cancellable, error)) return FALSE; @@ -454,7 +455,7 @@ _ostree_sysroot_read_boot_loader_configs (OstreeSysroot *self, g_str_has_suffix (dent->d_name, ".conf") && S_ISREG (stbuf.st_mode)) { - glnx_unref_object OstreeBootconfigParser *config = ostree_bootconfig_parser_new (); + g_autoptr(OstreeBootconfigParser) config = ostree_bootconfig_parser_new (); if (!ostree_bootconfig_parser_parse_at (config, dfd_iter.fd, dent->d_name, cancellable, error)) return glnx_prefix_error (error, "Parsing %s", dent->d_name); @@ -624,7 +625,7 @@ parse_deployment (OstreeSysroot *self, cancellable, error)) return FALSE; - glnx_unref_object OstreeDeployment *ret_deployment + g_autoptr(OstreeDeployment) ret_deployment = ostree_deployment_new (-1, osname, treecsum, deployserial, bootcsum, treebootserial); if (origin) @@ -691,7 +692,7 @@ list_deployments_process_one_boot_entry (OstreeSysroot *self, if (ostree_arg == NULL) return glnx_throw (error, "No ostree= kernel argument found"); - glnx_unref_object OstreeDeployment *deployment = NULL; + g_autoptr(OstreeDeployment) deployment = NULL; if (!parse_deployment (self, ostree_arg, &deployment, cancellable, error)) return FALSE; @@ -999,7 +1000,7 @@ _ostree_sysroot_query_bootloader (OstreeSysroot *sysroot, GError **error) { gboolean is_active; - glnx_unref_object OstreeBootloader *ret_loader = + g_autoptr(OstreeBootloader) ret_loader = (OstreeBootloader*)_ostree_bootloader_syslinux_new (sysroot); if (!_ostree_bootloader_query (ret_loader, &is_active, cancellable, error)) @@ -1078,7 +1079,7 @@ find_booted_deployment (OstreeSysroot *self, { struct stat root_stbuf; struct stat self_stbuf; - glnx_unref_object OstreeDeployment *ret_deployment = NULL; + g_autoptr(OstreeDeployment) ret_deployment = NULL; if (stat ("/", &root_stbuf) != 0) return glnx_throw_errno_prefix (error, "stat /"); @@ -1549,7 +1550,7 @@ clone_deployment (OstreeSysroot *sysroot, { gboolean ret = FALSE; __attribute__((cleanup(_ostree_kernel_args_cleanup))) OstreeKernelArgs *kargs = NULL; - glnx_unref_object OstreeDeployment *new_deployment = NULL; + g_autoptr(OstreeDeployment) new_deployment = NULL; /* Ensure we have a clean slate */ if (!ostree_sysroot_prepare_cleanup (sysroot, cancellable, error)) @@ -1617,12 +1618,12 @@ ostree_sysroot_deployment_unlock (OstreeSysroot *self, GError **error) { gboolean ret = FALSE; - glnx_unref_object OstreeSePolicy *sepolicy = NULL; + g_autoptr(OstreeSePolicy) sepolicy = NULL; OstreeDeploymentUnlockedState current_unlocked = ostree_deployment_get_unlocked (deployment); - glnx_unref_object OstreeDeployment *deployment_clone = + g_autoptr(OstreeDeployment) deployment_clone = ostree_deployment_clone (deployment); - glnx_unref_object OstreeDeployment *merge_deployment = NULL; + g_autoptr(OstreeDeployment) merge_deployment = NULL; GKeyFile *origin_clone = ostree_deployment_get_origin (deployment_clone); const char hotfix_ovl_options[] = "lowerdir=usr,upperdir=.usr-ovl-upper,workdir=.usr-ovl-work"; const char *ovl_options = NULL; diff --git a/src/libostree/ostree-tls-cert-interaction.h b/src/libostree/ostree-tls-cert-interaction.h index ae4532f7..e62618c5 100644 --- a/src/libostree/ostree-tls-cert-interaction.h +++ b/src/libostree/ostree-tls-cert-interaction.h @@ -31,6 +31,7 @@ G_BEGIN_DECLS typedef struct _OstreeTlsCertInteraction OstreeTlsCertInteraction; typedef struct _OstreeTlsCertInteractionClass OstreeTlsCertInteractionClass; +G_DEFINE_AUTOPTR_CLEANUP_FUNC(OstreeTlsCertInteraction, g_object_unref) GType _ostree_tls_cert_interaction_get_type (void) G_GNUC_CONST; diff --git a/src/ostree/ot-admin-builtin-cleanup.c b/src/ostree/ot-admin-builtin-cleanup.c index a6f74e38..a67b9675 100644 --- a/src/ostree/ot-admin-builtin-cleanup.c +++ b/src/ostree/ot-admin-builtin-cleanup.c @@ -37,7 +37,7 @@ gboolean ot_admin_builtin_cleanup (int argc, char **argv, GCancellable *cancellable, GError **error) { g_autoptr(GOptionContext) context = NULL; - glnx_unref_object OstreeSysroot *sysroot = NULL; + g_autoptr(OstreeSysroot) sysroot = NULL; gboolean ret = FALSE; context = g_option_context_new ("Delete untagged deployments and repository objects"); diff --git a/src/ostree/ot-admin-builtin-deploy.c b/src/ostree/ot-admin-builtin-deploy.c index 709c635e..085029ac 100644 --- a/src/ostree/ot-admin-builtin-deploy.c +++ b/src/ostree/ot-admin-builtin-deploy.c @@ -55,11 +55,11 @@ ot_admin_builtin_deploy (int argc, char **argv, GCancellable *cancellable, GErro gboolean ret = FALSE; const char *refspec; g_autoptr(GOptionContext) context = NULL; - glnx_unref_object OstreeSysroot *sysroot = NULL; + g_autoptr(OstreeSysroot) sysroot = NULL; g_autoptr(GKeyFile) origin = NULL; - glnx_unref_object OstreeRepo *repo = NULL; - glnx_unref_object OstreeDeployment *new_deployment = NULL; - glnx_unref_object OstreeDeployment *merge_deployment = NULL; + g_autoptr(OstreeRepo) repo = NULL; + g_autoptr(OstreeDeployment) new_deployment = NULL; + g_autoptr(OstreeDeployment) merge_deployment = NULL; g_autofree char *revision = NULL; __attribute__((cleanup(_ostree_kernel_args_cleanup))) OstreeKernelArgs *kargs = NULL; diff --git a/src/ostree/ot-admin-builtin-diff.c b/src/ostree/ot-admin-builtin-diff.c index 2615f24c..865cfca8 100644 --- a/src/ostree/ot-admin-builtin-diff.c +++ b/src/ostree/ot-admin-builtin-diff.c @@ -40,9 +40,9 @@ gboolean ot_admin_builtin_diff (int argc, char **argv, GCancellable *cancellable, GError **error) { g_autoptr(GOptionContext) context = NULL; - glnx_unref_object OstreeSysroot *sysroot = NULL; + g_autoptr(OstreeSysroot) sysroot = NULL; gboolean ret = FALSE; - glnx_unref_object OstreeDeployment *deployment = NULL; + g_autoptr(OstreeDeployment) deployment = NULL; g_autoptr(GFile) deployment_dir = NULL; g_autoptr(GPtrArray) modified = NULL; g_autoptr(GPtrArray) removed = NULL; diff --git a/src/ostree/ot-admin-builtin-init-fs.c b/src/ostree/ot-admin-builtin-init-fs.c index 9c08630d..126bcb31 100644 --- a/src/ostree/ot-admin-builtin-init-fs.c +++ b/src/ostree/ot-admin-builtin-init-fs.c @@ -37,10 +37,10 @@ gboolean ot_admin_builtin_init_fs (int argc, char **argv, GCancellable *cancellable, GError **error) { g_autoptr(GOptionContext) context = NULL; - glnx_unref_object OstreeSysroot *sysroot = NULL; + g_autoptr(OstreeSysroot) sysroot = NULL; gboolean ret = FALSE; glnx_fd_close int root_dfd = -1; - glnx_unref_object OstreeSysroot *target_sysroot = NULL; + g_autoptr(OstreeSysroot) target_sysroot = NULL; guint i; const char *normal_toplevels[] = {"boot", "dev", "home", "proc", "run", "sys"}; diff --git a/src/ostree/ot-admin-builtin-os-init.c b/src/ostree/ot-admin-builtin-os-init.c index cb95bebd..117733f2 100644 --- a/src/ostree/ot-admin-builtin-os-init.c +++ b/src/ostree/ot-admin-builtin-os-init.c @@ -37,7 +37,7 @@ gboolean ot_admin_builtin_os_init (int argc, char **argv, GCancellable *cancellable, GError **error) { g_autoptr(GOptionContext) context = NULL; - glnx_unref_object OstreeSysroot *sysroot = NULL; + g_autoptr(OstreeSysroot) sysroot = NULL; gboolean ret = FALSE; const char *osname = NULL; diff --git a/src/ostree/ot-admin-builtin-set-origin.c b/src/ostree/ot-admin-builtin-set-origin.c index a814d9d5..36f03877 100644 --- a/src/ostree/ot-admin-builtin-set-origin.c +++ b/src/ostree/ot-admin-builtin-set-origin.c @@ -48,9 +48,9 @@ ot_admin_builtin_set_origin (int argc, char **argv, GCancellable *cancellable, G const char *remotename = NULL; const char *url = NULL; const char *branch = NULL; - glnx_unref_object OstreeRepo *repo = NULL; - glnx_unref_object OstreeSysroot *sysroot = NULL; - glnx_unref_object OstreeDeployment *target_deployment = NULL; + g_autoptr(OstreeRepo) repo = NULL; + g_autoptr(OstreeSysroot) sysroot = NULL; + g_autoptr(OstreeDeployment) target_deployment = NULL; context = g_option_context_new ("REMOTENAME URL [BRANCH]"); diff --git a/src/ostree/ot-admin-builtin-status.c b/src/ostree/ot-admin-builtin-status.c index a437e7cf..f7d20337 100644 --- a/src/ostree/ot-admin-builtin-status.c +++ b/src/ostree/ot-admin-builtin-status.c @@ -84,9 +84,9 @@ gboolean ot_admin_builtin_status (int argc, char **argv, GCancellable *cancellable, GError **error) { g_autoptr(GOptionContext) context = NULL; - glnx_unref_object OstreeSysroot *sysroot = NULL; + g_autoptr(OstreeSysroot) sysroot = NULL; gboolean ret = FALSE; - glnx_unref_object OstreeRepo *repo = NULL; + g_autoptr(OstreeRepo) repo = NULL; OstreeDeployment *booted_deployment = NULL; g_autoptr(OstreeDeployment) pending_deployment = NULL; g_autoptr(OstreeDeployment) rollback_deployment = NULL; @@ -129,7 +129,7 @@ ot_admin_builtin_status (int argc, char **argv, GCancellable *cancellable, GErro const char *ref = ostree_deployment_get_csum (deployment); OstreeDeploymentUnlockedState unlocked = ostree_deployment_get_unlocked (deployment); g_autofree char *version = version_of_commit (repo, ref); - glnx_unref_object OstreeGpgVerifyResult *result = NULL; + g_autoptr(OstreeGpgVerifyResult) result = NULL; guint jj, n_signatures; GError *local_error = NULL; diff --git a/src/ostree/ot-admin-builtin-switch.c b/src/ostree/ot-admin-builtin-switch.c index 9df77f05..e54d4db5 100644 --- a/src/ostree/ot-admin-builtin-switch.c +++ b/src/ostree/ot-admin-builtin-switch.c @@ -44,9 +44,9 @@ ot_admin_builtin_switch (int argc, char **argv, GCancellable *cancellable, GErro { gboolean ret = FALSE; g_autoptr(GOptionContext) context = NULL; - glnx_unref_object OstreeSysroot *sysroot = NULL; + g_autoptr(OstreeSysroot) sysroot = NULL; const char *new_provided_refspec = NULL; - glnx_unref_object OstreeRepo *repo = NULL; + g_autoptr(OstreeRepo) repo = NULL; g_autofree char *origin_refspec = NULL; g_autofree char *origin_remote = NULL; g_autofree char *origin_ref = NULL; @@ -54,8 +54,8 @@ ot_admin_builtin_switch (int argc, char **argv, GCancellable *cancellable, GErro g_autofree char *new_ref = NULL; g_autofree char *new_refspec = NULL; const char* remote; - glnx_unref_object OstreeSysrootUpgrader *upgrader = NULL; - glnx_unref_object OstreeAsyncProgress *progress = NULL; + g_autoptr(OstreeSysrootUpgrader) upgrader = NULL; + g_autoptr(OstreeAsyncProgress) progress = NULL; gboolean changed; GKeyFile *old_origin; g_autoptr(GKeyFile) new_origin = NULL; diff --git a/src/ostree/ot-admin-builtin-undeploy.c b/src/ostree/ot-admin-builtin-undeploy.c index 00252c80..be832344 100644 --- a/src/ostree/ot-admin-builtin-undeploy.c +++ b/src/ostree/ot-admin-builtin-undeploy.c @@ -36,11 +36,11 @@ gboolean ot_admin_builtin_undeploy (int argc, char **argv, GCancellable *cancellable, GError **error) { g_autoptr(GOptionContext) context = NULL; - glnx_unref_object OstreeSysroot *sysroot = NULL; + g_autoptr(OstreeSysroot) sysroot = NULL; const char *deploy_index_str; int deploy_index; g_autoptr(GPtrArray) current_deployments = NULL; - glnx_unref_object OstreeDeployment *target_deployment = NULL; + g_autoptr(OstreeDeployment) target_deployment = NULL; context = g_option_context_new ("INDEX - Delete deployment INDEX"); diff --git a/src/ostree/ot-admin-builtin-unlock.c b/src/ostree/ot-admin-builtin-unlock.c index aecba51b..89888b53 100644 --- a/src/ostree/ot-admin-builtin-unlock.c +++ b/src/ostree/ot-admin-builtin-unlock.c @@ -43,7 +43,7 @@ ot_admin_builtin_unlock (int argc, char **argv, GCancellable *cancellable, GErro { gboolean ret = FALSE; g_autoptr(GOptionContext) context = NULL; - glnx_unref_object OstreeSysroot *sysroot = NULL; + g_autoptr(OstreeSysroot) sysroot = NULL; OstreeDeployment *booted_deployment = NULL; OstreeDeploymentUnlockedState target_state; diff --git a/src/ostree/ot-admin-builtin-upgrade.c b/src/ostree/ot-admin-builtin-upgrade.c index 7c710ffc..105d7790 100644 --- a/src/ostree/ot-admin-builtin-upgrade.c +++ b/src/ostree/ot-admin-builtin-upgrade.c @@ -54,10 +54,10 @@ ot_admin_builtin_upgrade (int argc, char **argv, GCancellable *cancellable, GErr { gboolean ret = FALSE; g_autoptr(GOptionContext) context = NULL; - glnx_unref_object OstreeSysroot *sysroot = NULL; - glnx_unref_object OstreeSysrootUpgrader *upgrader = NULL; + g_autoptr(OstreeSysroot) sysroot = NULL; + g_autoptr(OstreeSysrootUpgrader) upgrader = NULL; g_autoptr(GKeyFile) origin = NULL; - glnx_unref_object OstreeAsyncProgress *progress = NULL; + g_autoptr(OstreeAsyncProgress) progress = NULL; gboolean changed; OstreeSysrootUpgraderPullFlags upgraderpullflags = 0; diff --git a/src/ostree/ot-admin-instutil-builtin-grub2-generate.c b/src/ostree/ot-admin-instutil-builtin-grub2-generate.c index 4b8b581b..a634c82d 100644 --- a/src/ostree/ot-admin-instutil-builtin-grub2-generate.c +++ b/src/ostree/ot-admin-instutil-builtin-grub2-generate.c @@ -39,7 +39,7 @@ ot_admin_instutil_builtin_grub2_generate (int argc, char **argv, GCancellable *c gboolean ret = FALSE; guint bootversion; g_autoptr(GOptionContext) context = NULL; - glnx_unref_object OstreeSysroot *sysroot = NULL; + g_autoptr(OstreeSysroot) sysroot = NULL; context = g_option_context_new ("[BOOTVERSION] - generate GRUB2 configuration from given BLS entries"); diff --git a/src/ostree/ot-admin-instutil-builtin-selinux-ensure-labeled.c b/src/ostree/ot-admin-instutil-builtin-selinux-ensure-labeled.c index 424c7645..77666924 100644 --- a/src/ostree/ot-admin-instutil-builtin-selinux-ensure-labeled.c +++ b/src/ostree/ot-admin-instutil-builtin-selinux-ensure-labeled.c @@ -185,11 +185,11 @@ ot_admin_instutil_builtin_selinux_ensure_labeled (int argc, char **argv, GCancel const char *policy_name; g_autoptr(GFile) subpath = NULL; const char *prefix = NULL; - glnx_unref_object OstreeSePolicy *sepolicy = NULL; + g_autoptr(OstreeSePolicy) sepolicy = NULL; g_autoptr(GPtrArray) deployments = NULL; OstreeDeployment *first_deployment; g_autoptr(GOptionContext) context = NULL; - glnx_unref_object OstreeSysroot *sysroot = NULL; + g_autoptr(OstreeSysroot) sysroot = NULL; g_autoptr(GFile) deployment_path = NULL; context = g_option_context_new ("[SUBPATH PREFIX] - relabel all or part of a deployment"); diff --git a/src/ostree/ot-admin-instutil-builtin-set-kargs.c b/src/ostree/ot-admin-instutil-builtin-set-kargs.c index ad792a3a..63441ff2 100644 --- a/src/ostree/ot-admin-instutil-builtin-set-kargs.c +++ b/src/ostree/ot-admin-instutil-builtin-set-kargs.c @@ -51,7 +51,7 @@ ot_admin_instutil_builtin_set_kargs (int argc, char **argv, GCancellable *cancel g_autoptr(GPtrArray) deployments = NULL; OstreeDeployment *first_deployment = NULL; g_autoptr(GOptionContext) context = NULL; - glnx_unref_object OstreeSysroot *sysroot = NULL; + g_autoptr(OstreeSysroot) sysroot = NULL; __attribute__((cleanup(_ostree_kernel_args_cleanup))) OstreeKernelArgs *kargs = NULL; context = g_option_context_new ("ARGS - set new kernel command line arguments"); diff --git a/src/ostree/ot-builtin-checkout.c b/src/ostree/ot-builtin-checkout.c index 937c5b96..eae946e5 100644 --- a/src/ostree/ot-builtin-checkout.c +++ b/src/ostree/ot-builtin-checkout.c @@ -254,7 +254,7 @@ gboolean ostree_builtin_checkout (int argc, char **argv, GCancellable *cancellable, GError **error) { g_autoptr(GOptionContext) context = NULL; - glnx_unref_object OstreeRepo *repo = NULL; + g_autoptr(OstreeRepo) repo = NULL; gboolean ret = FALSE; const char *commit; const char *destination; diff --git a/src/ostree/ot-builtin-commit.c b/src/ostree/ot-builtin-commit.c index 8f359380..08120284 100644 --- a/src/ostree/ot-builtin-commit.c +++ b/src/ostree/ot-builtin-commit.c @@ -375,7 +375,7 @@ gboolean ostree_builtin_commit (int argc, char **argv, GCancellable *cancellable, GError **error) { g_autoptr(GOptionContext) context = NULL; - glnx_unref_object OstreeRepo *repo = NULL; + g_autoptr(OstreeRepo) repo = NULL; gboolean ret = FALSE; gboolean skip_commit = FALSE; g_autoptr(GFile) object_to_commit = NULL; @@ -384,7 +384,7 @@ ostree_builtin_commit (int argc, char **argv, GCancellable *cancellable, GError g_autoptr(GFile) root = NULL; g_autoptr(GVariant) metadata = NULL; g_autoptr(GVariant) detached_metadata = NULL; - glnx_unref_object OstreeMutableTree *mtree = NULL; + g_autoptr(OstreeMutableTree) mtree = NULL; g_autofree char *tree_type = NULL; g_autoptr(GHashTable) mode_adds = NULL; g_autoptr(GHashTable) mode_overrides = NULL; diff --git a/src/ostree/ot-builtin-config.c b/src/ostree/ot-builtin-config.c index a9a5f52a..e73398ee 100644 --- a/src/ostree/ot-builtin-config.c +++ b/src/ostree/ot-builtin-config.c @@ -55,7 +55,7 @@ gboolean ostree_builtin_config (int argc, char **argv, GCancellable *cancellable, GError **error) { g_autoptr(GOptionContext) context = NULL; - glnx_unref_object OstreeRepo *repo = NULL; + g_autoptr(OstreeRepo) repo = NULL; gboolean ret = FALSE; const char *op; const char *section_key; diff --git a/src/ostree/ot-builtin-diff.c b/src/ostree/ot-builtin-diff.c index a7e2aad2..bf8a8335 100644 --- a/src/ostree/ot-builtin-diff.c +++ b/src/ostree/ot-builtin-diff.c @@ -126,7 +126,7 @@ ostree_builtin_diff (int argc, char **argv, GCancellable *cancellable, GError ** { gboolean ret = FALSE; g_autoptr(GOptionContext) context = NULL; - glnx_unref_object OstreeRepo *repo = NULL; + g_autoptr(OstreeRepo) repo = NULL; const char *src; const char *target; g_autofree char *src_prev = NULL; diff --git a/src/ostree/ot-builtin-export.c b/src/ostree/ot-builtin-export.c index fea03c3e..a7c2e302 100644 --- a/src/ostree/ot-builtin-export.c +++ b/src/ostree/ot-builtin-export.c @@ -61,7 +61,7 @@ gboolean ostree_builtin_export (int argc, char **argv, GCancellable *cancellable, GError **error) { g_autoptr(GOptionContext) context = NULL; - glnx_unref_object OstreeRepo *repo = NULL; + g_autoptr(OstreeRepo) repo = NULL; gboolean ret = FALSE; const char *rev; g_autoptr(GFile) root = NULL; diff --git a/src/ostree/ot-builtin-find-remotes.c b/src/ostree/ot-builtin-find-remotes.c index 344febb5..10c310b2 100644 --- a/src/ostree/ot-builtin-find-remotes.c +++ b/src/ostree/ot-builtin-find-remotes.c @@ -125,9 +125,9 @@ ostree_builtin_find_remotes (int argc, GError **error) { g_autoptr(GOptionContext) context = NULL; - glnx_unref_object OstreeRepo *repo = NULL; + g_autoptr(OstreeRepo) repo = NULL; g_autoptr(GPtrArray) refs = NULL; /* (element-type OstreeCollectionRef) */ - glnx_unref_object OstreeAsyncProgress *progress = NULL; + g_autoptr(OstreeAsyncProgress) progress = NULL; gsize i; g_autoptr(GAsyncResult) find_result = NULL, pull_result = NULL; g_auto(OstreeRepoFinderResultv) results = NULL; diff --git a/src/ostree/ot-builtin-fsck.c b/src/ostree/ot-builtin-fsck.c index 66f5536d..01241399 100644 --- a/src/ostree/ot-builtin-fsck.c +++ b/src/ostree/ot-builtin-fsck.c @@ -212,7 +212,7 @@ fsck_reachable_objects_from_commits (OstreeRepo *repo, gboolean ostree_builtin_fsck (int argc, char **argv, GCancellable *cancellable, GError **error) { - glnx_unref_object OstreeRepo *repo = NULL; + g_autoptr(OstreeRepo) repo = NULL; gboolean found_corruption = FALSE; g_autoptr(GOptionContext) context = g_option_context_new ("- Check the repository for consistency"); diff --git a/src/ostree/ot-builtin-gpg-sign.c b/src/ostree/ot-builtin-gpg-sign.c index e14eba68..eace474b 100644 --- a/src/ostree/ot-builtin-gpg-sign.c +++ b/src/ostree/ot-builtin-gpg-sign.c @@ -55,7 +55,7 @@ delete_signatures (OstreeRepo *repo, GError **error) { GVariantDict metadata_dict; - glnx_unref_object OstreeGpgVerifyResult *result = NULL; + g_autoptr(OstreeGpgVerifyResult) result = NULL; g_autoptr(GVariant) old_metadata = NULL; g_autoptr(GVariant) new_metadata = NULL; g_autoptr(GVariant) signature_data = NULL; @@ -199,7 +199,7 @@ gboolean ostree_builtin_gpg_sign (int argc, char **argv, GCancellable *cancellable, GError **error) { g_autoptr(GOptionContext) context = NULL; - glnx_unref_object OstreeRepo *repo = NULL; + g_autoptr(OstreeRepo) repo = NULL; g_autofree char *resolved_commit = NULL; const char *commit; char **key_ids; diff --git a/src/ostree/ot-builtin-log.c b/src/ostree/ot-builtin-log.c index ca1cdc68..c2210351 100644 --- a/src/ostree/ot-builtin-log.c +++ b/src/ostree/ot-builtin-log.c @@ -82,7 +82,7 @@ ostree_builtin_log (int argc, GError **error) { g_autoptr(GOptionContext) context = NULL; - glnx_unref_object OstreeRepo *repo = NULL; + g_autoptr(OstreeRepo) repo = NULL; gboolean ret = FALSE; const char *rev; g_autofree char *checksum = NULL; diff --git a/src/ostree/ot-builtin-ls.c b/src/ostree/ot-builtin-ls.c index 3e0336f6..2a9b0244 100644 --- a/src/ostree/ot-builtin-ls.c +++ b/src/ostree/ot-builtin-ls.c @@ -239,7 +239,7 @@ gboolean ostree_builtin_ls (int argc, char **argv, GCancellable *cancellable, GError **error) { g_autoptr(GOptionContext) context = NULL; - glnx_unref_object OstreeRepo *repo = NULL; + g_autoptr(OstreeRepo) repo = NULL; gboolean ret = FALSE; const char *rev; int i; diff --git a/src/ostree/ot-builtin-prune.c b/src/ostree/ot-builtin-prune.c index 8c595b73..2742c375 100644 --- a/src/ostree/ot-builtin-prune.c +++ b/src/ostree/ot-builtin-prune.c @@ -162,7 +162,7 @@ ostree_builtin_prune (int argc, char **argv, GCancellable *cancellable, GError * { gboolean ret = FALSE; g_autoptr(GOptionContext) context = NULL; - glnx_unref_object OstreeRepo *repo = NULL; + g_autoptr(OstreeRepo) repo = NULL; g_autofree char *formatted_freed_size = NULL; OstreeRepoPruneFlags pruneflags = 0; gint n_objects_total; diff --git a/src/ostree/ot-builtin-pull-local.c b/src/ostree/ot-builtin-pull-local.c index 66e189bc..302ebd85 100644 --- a/src/ostree/ot-builtin-pull-local.c +++ b/src/ostree/ot-builtin-pull-local.c @@ -56,11 +56,11 @@ ostree_builtin_pull_local (int argc, char **argv, GCancellable *cancellable, GEr { gboolean ret = FALSE; g_autoptr(GOptionContext) context = NULL; - glnx_unref_object OstreeRepo *repo = NULL; + g_autoptr(OstreeRepo) repo = NULL; int i; const char *src_repo_arg; g_autofree char *src_repo_uri = NULL; - glnx_unref_object OstreeAsyncProgress *progress = NULL; + g_autoptr(OstreeAsyncProgress) progress = NULL; g_autoptr(GPtrArray) refs_to_fetch = NULL; OstreeRepoPullFlags pullflags = 0; @@ -103,7 +103,7 @@ ostree_builtin_pull_local (int argc, char **argv, GCancellable *cancellable, GEr if (argc == 2) { g_autoptr(GFile) src_repo_path = g_file_new_for_path (src_repo_arg); - glnx_unref_object OstreeRepo *src_repo = ostree_repo_new (src_repo_path); + g_autoptr(OstreeRepo) src_repo = ostree_repo_new (src_repo_path); g_autoptr(GHashTable) refs_to_clone = NULL; refs_to_fetch = g_ptr_array_new_with_free_func (g_free); diff --git a/src/ostree/ot-builtin-pull.c b/src/ostree/ot-builtin-pull.c index 7898e107..36e99b3a 100644 --- a/src/ostree/ot-builtin-pull.c +++ b/src/ostree/ot-builtin-pull.c @@ -138,13 +138,13 @@ gboolean ostree_builtin_pull (int argc, char **argv, GCancellable *cancellable, GError **error) { g_autoptr(GOptionContext) context = NULL; - glnx_unref_object OstreeRepo *repo = NULL; + g_autoptr(OstreeRepo) repo = NULL; gboolean ret = FALSE; g_autofree char *remote = NULL; OstreeRepoPullFlags pullflags = 0; g_autoptr(GPtrArray) refs_to_fetch = NULL; g_autoptr(GPtrArray) override_commit_ids = NULL; - glnx_unref_object OstreeAsyncProgress *progress = NULL; + g_autoptr(OstreeAsyncProgress) progress = NULL; gulong signal_handler_id = 0; context = g_option_context_new ("REMOTE [BRANCH...] - Download data from remote repository"); diff --git a/src/ostree/ot-builtin-refs.c b/src/ostree/ot-builtin-refs.c index 0f850069..9e13a048 100644 --- a/src/ostree/ot-builtin-refs.c +++ b/src/ostree/ot-builtin-refs.c @@ -260,7 +260,7 @@ ostree_builtin_refs (int argc, char **argv, GCancellable *cancellable, GError ** { gboolean ret = FALSE; g_autoptr(GOptionContext) context = NULL; - glnx_unref_object OstreeRepo *repo = NULL; + g_autoptr(OstreeRepo) repo = NULL; int i; context = g_option_context_new ("[PREFIX] - List refs"); diff --git a/src/ostree/ot-builtin-reset.c b/src/ostree/ot-builtin-reset.c index 344d692c..e87f0924 100644 --- a/src/ostree/ot-builtin-reset.c +++ b/src/ostree/ot-builtin-reset.c @@ -38,7 +38,7 @@ ostree_builtin_reset (int argc, GError **error) { g_autoptr(GOptionContext) context = NULL; - glnx_unref_object OstreeRepo *repo = NULL; + g_autoptr(OstreeRepo) repo = NULL; g_autoptr(GHashTable) known_refs = NULL; gboolean ret = FALSE; const char *ref; diff --git a/src/ostree/ot-builtin-rev-parse.c b/src/ostree/ot-builtin-rev-parse.c index bedcc79d..6099931a 100644 --- a/src/ostree/ot-builtin-rev-parse.c +++ b/src/ostree/ot-builtin-rev-parse.c @@ -35,7 +35,7 @@ gboolean ostree_builtin_rev_parse (int argc, char **argv, GCancellable *cancellable, GError **error) { g_autoptr(GOptionContext) context = NULL; - glnx_unref_object OstreeRepo *repo = NULL; + g_autoptr(OstreeRepo) repo = NULL; gboolean ret = FALSE; const char *rev = "master"; int i; diff --git a/src/ostree/ot-builtin-show.c b/src/ostree/ot-builtin-show.c index dcd9090c..0c57637b 100644 --- a/src/ostree/ot-builtin-show.c +++ b/src/ostree/ot-builtin-show.c @@ -147,7 +147,7 @@ print_object (OstreeRepo *repo, if (objtype == OSTREE_OBJECT_TYPE_COMMIT) { - glnx_unref_object OstreeGpgVerifyResult *result = NULL; + g_autoptr(OstreeGpgVerifyResult) result = NULL; g_autoptr(GError) local_error = NULL; g_autoptr(GFile) gpg_homedir = opt_gpg_homedir ? g_file_new_for_path (opt_gpg_homedir) : NULL; @@ -223,7 +223,7 @@ ostree_builtin_show (int argc, char **argv, GCancellable *cancellable, GError ** { g_autoptr(GOptionContext) context = g_option_context_new ("OBJECT - Output a metadata object"); - glnx_unref_object OstreeRepo *repo = NULL; + g_autoptr(OstreeRepo) repo = NULL; if (!ostree_option_context_parse (context, options, &argc, &argv, OSTREE_BUILTIN_FLAG_NONE, &repo, cancellable, error)) return FALSE; diff --git a/src/ostree/ot-builtin-static-delta.c b/src/ostree/ot-builtin-static-delta.c index c98436af..30de612f 100644 --- a/src/ostree/ot-builtin-static-delta.c +++ b/src/ostree/ot-builtin-static-delta.c @@ -113,7 +113,7 @@ ot_static_delta_builtin_list (int argc, char **argv, GCancellable *cancellable, g_autoptr(GPtrArray) delta_names = NULL; guint i; g_autoptr(GOptionContext) context = NULL; - glnx_unref_object OstreeRepo *repo = NULL; + g_autoptr(OstreeRepo) repo = NULL; context = g_option_context_new ("LIST - list static delta files"); @@ -145,7 +145,7 @@ ot_static_delta_builtin_show (int argc, char **argv, GCancellable *cancellable, { gboolean ret = FALSE; g_autoptr(GOptionContext) context = NULL; - glnx_unref_object OstreeRepo *repo = NULL; + g_autoptr(OstreeRepo) repo = NULL; const char *delta_id = NULL; context = g_option_context_new ("SHOW - Dump information on a delta"); @@ -175,7 +175,7 @@ ot_static_delta_builtin_delete (int argc, char **argv, GCancellable *cancellable { gboolean ret = FALSE; g_autoptr(GOptionContext) context = NULL; - glnx_unref_object OstreeRepo *repo = NULL; + g_autoptr(OstreeRepo) repo = NULL; const char *delta_id = NULL; context = g_option_context_new ("DELETE - Remove a delta"); @@ -206,7 +206,7 @@ ot_static_delta_builtin_generate (int argc, char **argv, GCancellable *cancellab { gboolean ret = FALSE; g_autoptr(GOptionContext) context = NULL; - glnx_unref_object OstreeRepo *repo = NULL; + g_autoptr(OstreeRepo) repo = NULL; context = g_option_context_new ("GENERATE [TO] - Generate static delta files"); if (!ostree_option_context_parse (context, generate_options, &argc, &argv, OSTREE_BUILTIN_FLAG_NONE, &repo, cancellable, error)) @@ -357,7 +357,7 @@ ot_static_delta_builtin_apply_offline (int argc, char **argv, GCancellable *canc const char *patharg; g_autoptr(GFile) path = NULL; g_autoptr(GOptionContext) context = NULL; - glnx_unref_object OstreeRepo *repo = NULL; + g_autoptr(OstreeRepo) repo = NULL; context = g_option_context_new ("APPLY-OFFLINE - Apply static delta file"); if (!ostree_option_context_parse (context, apply_offline_options, &argc, &argv, OSTREE_BUILTIN_FLAG_NONE, &repo, cancellable, error)) diff --git a/src/ostree/ot-builtin-summary.c b/src/ostree/ot-builtin-summary.c index f2e687ec..2f7d9729 100644 --- a/src/ostree/ot-builtin-summary.c +++ b/src/ostree/ot-builtin-summary.c @@ -81,7 +81,7 @@ ostree_builtin_summary (int argc, char **argv, GCancellable *cancellable, GError { gboolean ret = FALSE; g_autoptr(GOptionContext) context = NULL; - glnx_unref_object OstreeRepo *repo = NULL; + g_autoptr(OstreeRepo) repo = NULL; OstreeDumpFlags flags = OSTREE_DUMP_NONE; context = g_option_context_new ("Manage summary metadata"); diff --git a/src/ostree/ot-main.c b/src/ostree/ot-main.c index ca4f1592..56d247b4 100644 --- a/src/ostree/ot-main.c +++ b/src/ostree/ot-main.c @@ -372,7 +372,7 @@ ostree_admin_option_context_parse (GOptionContext *context, if (opt_sysroot != NULL) sysroot_path = g_file_new_for_path (opt_sysroot); - glnx_unref_object OstreeSysroot *sysroot = ostree_sysroot_new (sysroot_path); + g_autoptr(OstreeSysroot) sysroot = ostree_sysroot_new (sysroot_path); if (flags & OSTREE_ADMIN_BUILTIN_FLAG_SUPERUSER) { diff --git a/src/ostree/ot-remote-builtin-summary.c b/src/ostree/ot-remote-builtin-summary.c index 5ddcf69b..b7d0f0a9 100644 --- a/src/ostree/ot-remote-builtin-summary.c +++ b/src/ostree/ot-remote-builtin-summary.c @@ -101,7 +101,7 @@ ot_remote_builtin_summary (int argc, char **argv, GCancellable *cancellable, GEr * option for raw signature data like "--raw-signatures". */ if (signature_bytes != NULL && !opt_raw) { - glnx_unref_object OstreeGpgVerifyResult *result = NULL; + g_autoptr(OstreeGpgVerifyResult) result = NULL; /* The actual signed summary verification happens above in * ostree_repo_remote_fetch_summary(). Here we just parse From d3897e52e7afb123de0eff6d83a318969286e4fb Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Mon, 31 Jul 2017 11:31:13 -0400 Subject: [PATCH 23/67] lib: Define and use an autoptr cleanup for gpgme_key_t Followup for previous patch, allows porting a bit to new code style. Closes: #1039 Approved by: jlebon --- src/libostree/ostree-gpg-verify-result.c | 21 ++++++--------------- src/libotutil/ot-gpg-utils.h | 1 + 2 files changed, 7 insertions(+), 15 deletions(-) diff --git a/src/libostree/ostree-gpg-verify-result.c b/src/libostree/ostree-gpg-verify-result.c index 7cee6c28..a8ada775 100644 --- a/src/libostree/ostree-gpg-verify-result.c +++ b/src/libostree/ostree-gpg-verify-result.c @@ -237,10 +237,9 @@ ostree_gpg_verify_result_lookup (OstreeGpgVerifyResult *result, const gchar *key_id, guint *out_signature_index) { - gpgme_key_t lookup_key = NULL; + g_auto(gpgme_key_t) lookup_key = NULL; gpgme_signature_t signature; guint signature_index; - gboolean ret = FALSE; g_return_val_if_fail (OSTREE_IS_GPG_VERIFY_RESULT (result), FALSE); g_return_val_if_fail (key_id != NULL, FALSE); @@ -258,7 +257,7 @@ ostree_gpg_verify_result_lookup (OstreeGpgVerifyResult *result, signature != NULL; signature = signature->next, signature_index++) { - gpgme_key_t signature_key = NULL; + g_auto(gpgme_key_t) signature_key = NULL; (void) gpgme_get_key (result->context, signature->fpr, &signature_key, 0); @@ -274,18 +273,13 @@ ostree_gpg_verify_result_lookup (OstreeGpgVerifyResult *result, { if (out_signature_index != NULL) *out_signature_index = signature_index; - ret = TRUE; + /* Note early return */ + return TRUE; } - gpgme_key_unref (signature_key); - - if (ret) - break; } - gpgme_key_unref (lookup_key); - - return ret; + return FALSE; } /** @@ -312,7 +306,7 @@ ostree_gpg_verify_result_get (OstreeGpgVerifyResult *result, guint n_attrs) { GVariantBuilder builder; - gpgme_key_t key = NULL; + g_auto(gpgme_key_t) key = NULL; gpgme_signature_t signature; guint ii; @@ -433,9 +427,6 @@ ostree_gpg_verify_result_get (OstreeGpgVerifyResult *result, g_variant_builder_add_value (&builder, child); } - if (key != NULL) - gpgme_key_unref (key); - return g_variant_builder_end (&builder); } diff --git a/src/libotutil/ot-gpg-utils.h b/src/libotutil/ot-gpg-utils.h index 9545e14b..036e5c28 100644 --- a/src/libotutil/ot-gpg-utils.h +++ b/src/libotutil/ot-gpg-utils.h @@ -28,6 +28,7 @@ G_BEGIN_DECLS G_DEFINE_AUTO_CLEANUP_FREE_FUNC(gpgme_data_t, gpgme_data_release, NULL); G_DEFINE_AUTO_CLEANUP_FREE_FUNC(gpgme_ctx_t, gpgme_release, NULL); +G_DEFINE_AUTO_CLEANUP_FREE_FUNC(gpgme_key_t, gpgme_key_unref, NULL) void ot_gpgme_error_to_gio_error (gpgme_error_t gpg_error, GError **error); From 4e068f3924f57f7a4a26a91aab38c725520251fe Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Thu, 3 Aug 2017 10:55:51 -0400 Subject: [PATCH 24/67] tree-wide: Fix the build with old glib (Ubuntu Trusty etc.) This regressed with but currently the Travis builds aren't gating. Closes: #1051 Approved by: jlebon --- src/libostree/ostree-bootloader.h | 1 + src/libostree/ostree-deployment.c | 2 +- src/libostree/ostree-libarchive-private.h | 2 +- src/libostree/ostree-mutable-tree.c | 2 +- src/libostree/ostree-repo-commit.c | 2 +- src/libostree/ostree-repo-libarchive.c | 1 + src/libostree/ostree-repo-private.h | 2 +- src/libostree/ostree-sysroot-deploy.c | 2 +- src/libostree/ostree-tls-cert-interaction.h | 1 + src/ostree/ot-builtin-export.c | 6 ++++-- 10 files changed, 13 insertions(+), 8 deletions(-) diff --git a/src/libostree/ostree-bootloader.h b/src/libostree/ostree-bootloader.h index 92cc521b..de46422d 100644 --- a/src/libostree/ostree-bootloader.h +++ b/src/libostree/ostree-bootloader.h @@ -21,6 +21,7 @@ #pragma once #include +#include "otutil.h" G_BEGIN_DECLS diff --git a/src/libostree/ostree-deployment.c b/src/libostree/ostree-deployment.c index e3ee0b55..9fb5b028 100644 --- a/src/libostree/ostree-deployment.c +++ b/src/libostree/ostree-deployment.c @@ -20,9 +20,9 @@ #include "config.h" +#include "otutil.h" #include "ostree.h" #include "ostree-deployment-private.h" -#include "libglnx.h" typedef GObjectClass OstreeDeploymentClass; diff --git a/src/libostree/ostree-libarchive-private.h b/src/libostree/ostree-libarchive-private.h index dcf86ea3..870ddf82 100644 --- a/src/libostree/ostree-libarchive-private.h +++ b/src/libostree/ostree-libarchive-private.h @@ -25,7 +25,7 @@ #include "config.h" #include -#include "libglnx.h" +#include "otutil.h" #ifdef HAVE_LIBARCHIVE #include #include diff --git a/src/libostree/ostree-mutable-tree.c b/src/libostree/ostree-mutable-tree.c index c144cff4..5e933acc 100644 --- a/src/libostree/ostree-mutable-tree.c +++ b/src/libostree/ostree-mutable-tree.c @@ -22,8 +22,8 @@ #include "config.h" -#include "ostree.h" #include "otutil.h" +#include "ostree.h" /** * SECTION:ostree-mutable-tree diff --git a/src/libostree/ostree-repo-commit.c b/src/libostree/ostree-repo-commit.c index 346cbb42..dc52f5e7 100644 --- a/src/libostree/ostree-repo-commit.c +++ b/src/libostree/ostree-repo-commit.c @@ -30,13 +30,13 @@ #include #include +#include "otutil.h" #include "ostree.h" #include "ostree-core-private.h" #include "ostree-repo-private.h" #include "ostree-repo-file-enumerator.h" #include "ostree-checksum-input-stream.h" #include "ostree-varint.h" -#include "otutil.h" gboolean _ostree_repo_ensure_loose_objdir_at (int dfd, diff --git a/src/libostree/ostree-repo-libarchive.c b/src/libostree/ostree-repo-libarchive.c index f3f4b29e..1839a088 100644 --- a/src/libostree/ostree-repo-libarchive.c +++ b/src/libostree/ostree-repo-libarchive.c @@ -22,6 +22,7 @@ #include "config.h" +#include "otutil.h" #include "ostree.h" #include "ostree-core-private.h" #include "ostree-repo-private.h" diff --git a/src/libostree/ostree-repo-private.h b/src/libostree/ostree-repo-private.h index 1596c0db..9c514766 100644 --- a/src/libostree/ostree-repo-private.h +++ b/src/libostree/ostree-repo-private.h @@ -21,10 +21,10 @@ #pragma once #include +#include "otutil.h" #include "ostree-ref.h" #include "ostree-repo.h" #include "ostree-remote-private.h" -#include "otutil.h" G_BEGIN_DECLS diff --git a/src/libostree/ostree-sysroot-deploy.c b/src/libostree/ostree-sysroot-deploy.c index d857f0c5..29fcfeed 100644 --- a/src/libostree/ostree-sysroot-deploy.c +++ b/src/libostree/ostree-sysroot-deploy.c @@ -32,13 +32,13 @@ #include #endif +#include "otutil.h" #include "ostree.h" #include "ostree-sysroot-private.h" #include "ostree-sepolicy-private.h" #include "ostree-deployment-private.h" #include "ostree-core-private.h" #include "ostree-linuxfsutil.h" -#include "otutil.h" #include "libglnx.h" #define OSTREE_VARRELABEL_ID "da679b08acd34504b789d96f818ea781" diff --git a/src/libostree/ostree-tls-cert-interaction.h b/src/libostree/ostree-tls-cert-interaction.h index e62618c5..09a8ad0d 100644 --- a/src/libostree/ostree-tls-cert-interaction.h +++ b/src/libostree/ostree-tls-cert-interaction.h @@ -18,6 +18,7 @@ #pragma once +#include "otutil.h" #include G_BEGIN_DECLS diff --git a/src/ostree/ot-builtin-export.c b/src/ostree/ot-builtin-export.c index a7c2e302..14960b12 100644 --- a/src/ostree/ot-builtin-export.c +++ b/src/ostree/ot-builtin-export.c @@ -20,12 +20,12 @@ #include "config.h" +#include "otutil.h" #include "ot-main.h" #include "ot-builtins.h" +#include "ostree-libarchive-private.h" #include "ostree.h" #include "ostree-repo-file.h" -#include "ostree-libarchive-private.h" -#include "otutil.h" #ifdef HAVE_LIBARCHIVE #include @@ -68,7 +68,9 @@ ostree_builtin_export (int argc, char **argv, GCancellable *cancellable, GError g_autoptr(GFile) subtree = NULL; g_autofree char *commit = NULL; g_autoptr(GVariant) commit_data = NULL; +#ifdef HAVE_LIBARCHIVE g_autoptr(OtAutoArchiveWrite) a = NULL; +#endif OstreeRepoExportArchiveOptions opts = { 0, }; context = g_option_context_new ("COMMIT - Stream COMMIT to stdout in tar format"); From 5682f4cc041d1b53448739f8656ed6fd120e7dbe Mon Sep 17 00:00:00 2001 From: Matthew Leeds Date: Fri, 4 Aug 2017 13:18:40 -0700 Subject: [PATCH 25/67] main: Fix subcommand usage output This commit sets prgname correctly so that the "ostree subcommand --help" output prints the subcommand rather than just "ostree". This was removed in commit f0519e541f29 because it tripped the thread sanitizer, but it's being added back conditionally so most users who don't compile with -fsanitize=adress see proper help output. Closes: #1054 Approved by: cgwalters --- configure.ac | 13 +++++++++++++ src/ostree/ot-main.c | 8 ++++++++ 2 files changed, 21 insertions(+) diff --git a/configure.ac b/configure.ac index 58689cc0..228ee84b 100644 --- a/configure.ac +++ b/configure.ac @@ -58,6 +58,19 @@ else AC_MSG_RESULT([no]) fi AM_CONDITIONAL(BUILDOPT_ASAN, [test x$using_asan = xyes]) +AM_COND_IF([BUILDOPT_ASAN], + [AC_DEFINE([BUILDOPT_ASAN], 1, [Define if we are building with -fsanitize=address])]) + +AC_MSG_CHECKING([for -fsanitize=thread in CFLAGS]) +if echo $CFLAGS | grep -q -e -fsanitize=thread; then + AC_MSG_RESULT([yes]) + using_tsan=yes +else + AC_MSG_RESULT([no]) +fi +AM_CONDITIONAL(BUILDOPT_TSAN, [test x$using_tsan = xyes]) +AM_COND_IF([BUILDOPT_TSAN], + [AC_DEFINE([BUILDOPT_TSAN], 1, [Define if we are building with -fsanitize=thread])]) # Initialize libtool LT_PREREQ([2.2.4]) diff --git a/src/ostree/ot-main.c b/src/ostree/ot-main.c index 56d247b4..5b6e301d 100644 --- a/src/ostree/ot-main.c +++ b/src/ostree/ot-main.c @@ -117,6 +117,9 @@ ostree_run (int argc, OstreeCommand *command; GError *error = NULL; GCancellable *cancellable = NULL; +#ifndef BUILDOPT_TSAN + g_autofree char *prgname = NULL; +#endif const char *command_name = NULL; gboolean success = FALSE; int in, out; @@ -192,6 +195,11 @@ ostree_run (int argc, goto out; } +#ifndef BUILDOPT_TSAN + prgname = g_strdup_printf ("%s %s", g_get_prgname (), command_name); + g_set_prgname (prgname); +#endif + if (!command->fn (argc, argv, cancellable, &error)) goto out; From b08a198f00a61ee764c6e0f84d91473a385d09ed Mon Sep 17 00:00:00 2001 From: Guy Shapiro Date: Sun, 6 Aug 2017 11:26:51 +0300 Subject: [PATCH 26/67] Documentation: static delta default from Document that the default behavior of `ostree static-delta generate` if to generate the delta from the parent. Closes: #1057 Approved by: cgwalters --- man/ostree-static-delta.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/man/ostree-static-delta.xml b/man/ostree-static-delta.xml index ed2e1f48..3b16aaff 100644 --- a/man/ostree-static-delta.xml +++ b/man/ostree-static-delta.xml @@ -90,6 +90,8 @@ Boston, MA 02111-1307, USA. Create delta to revision REV. (This option is required.) + The delta is from the parent of REV, unless specified otherwise by + or . From 8eec337feee95d76f14f6e1b39e0b08673e40c22 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Mon, 31 Jul 2017 12:27:31 -0400 Subject: [PATCH 27/67] lib/deltas: Squash Coverity warning for div-by-zero in delta show If a delta happens to have zero objects, we could end up doing a divide-by-zero when inferring endianness. In practice, a zero-object delta isn't possible to generate I think, but let's make sure the code is defensive all the same. Spotted by Coverity. Coverity CID: 1452208 Closes: #1041 Approved by: pwithnall --- src/libostree/ostree-repo-static-delta-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libostree/ostree-repo-static-delta-core.c b/src/libostree/ostree-repo-static-delta-core.c index c8cefdef..b8a2c590 100644 --- a/src/libostree/ostree-repo-static-delta-core.c +++ b/src/libostree/ostree-repo-static-delta-core.c @@ -649,7 +649,7 @@ _ostree_delta_get_endianness (GVariant *superblock, * deltas, period. Past the gigabyte scale you really want * bittorrent or something. */ - if ((total_size / total_objects) > G_MAXUINT32) + if (total_objects > 0 && (total_size / total_objects) > G_MAXUINT32) { is_byteswapped = TRUE; } From 48f8f329211fd6647b0c9bd0b72d494e8701a0fb Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Mon, 31 Jul 2017 12:22:16 -0400 Subject: [PATCH 28/67] bin/pull: Fix @ override syntax when pulling multiple refs Coverity spotted an infloop here since we were incrementing `i++` instead of `j++`. But adding a test revealed other bugs - we need to keep the arrays in sync. Coverity CID: 1452204 Closes: #1041 Approved by: pwithnall --- src/ostree/ot-builtin-pull.c | 12 ++++++++---- tests/pull-test.sh | 6 +++++- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/src/ostree/ot-builtin-pull.c b/src/ostree/ot-builtin-pull.c index 36e99b3a..b07ce90b 100644 --- a/src/ostree/ot-builtin-pull.c +++ b/src/ostree/ot-builtin-pull.c @@ -209,11 +209,13 @@ ostree_builtin_pull (int argc, char **argv, GCancellable *cancellable, GError ** goto out; if (!override_commit_ids) - override_commit_ids = g_ptr_array_new_with_free_func (g_free); + { + override_commit_ids = g_ptr_array_new_with_free_func (g_free); - /* Backfill */ - for (j = 2; j < i; i++) - g_ptr_array_add (override_commit_ids, g_strdup ("")); + /* Backfill */ + for (j = 2; j < i; j++) + g_ptr_array_add (override_commit_ids, g_strdup ("")); + } g_ptr_array_add (override_commit_ids, g_strdup (override_commit_id)); g_ptr_array_add (refs_to_fetch, g_strndup (argv[i], at - argv[i])); @@ -221,6 +223,8 @@ ostree_builtin_pull (int argc, char **argv, GCancellable *cancellable, GError ** else { g_ptr_array_add (refs_to_fetch, g_strdup (argv[i])); + if (override_commit_ids) + g_ptr_array_add (override_commit_ids, g_strdup ("")); } } diff --git a/tests/pull-test.sh b/tests/pull-test.sh index 9bbe0fa2..f51d4445 100644 --- a/tests/pull-test.sh +++ b/tests/pull-test.sh @@ -35,7 +35,7 @@ function verify_initial_contents() { assert_file_has_content baz/cow '^moo$' } -echo "1..27" +echo "1..28" # Try both syntaxes repo_init --no-gpg-verify @@ -364,6 +364,10 @@ assert_not_has_file baz/saucer echo "ok static delta 2" +cd ${test_tmpdir} +${CMD_PREFIX} ostree --repo=repo pull origin main main@${rev} main@${rev} main main@${rev} main +echo "ok pull specific commit array" + cd ${test_tmpdir} ${CMD_PREFIX} ostree --repo=repo remote add --set=gpg-verify=false --set=unconfigured-state="Access to ExampleOS requires ONE BILLION DOLLARS." origin-subscription file://$(pwd)/ostree-srv/gnomerepo if ${CMD_PREFIX} ostree --repo=repo pull origin-subscription main 2>err.txt; then From 6d861dd92d8dad7a38625daed8d28d72752636b2 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Sat, 5 Aug 2017 15:20:04 -0400 Subject: [PATCH 29/67] tree-wide: Remove trailing semicolon from autoptr declarations It confuses `g-ir-scanner`, and isn't necessary. Closes: #1056 Approved by: pwithnall --- src/libostree/ostree-impl-system-generator.c | 2 +- src/libostree/ostree-repo-checkout.c | 2 +- src/libostree/ostree-repo-private.h | 2 +- src/libotutil/ot-fs-utils.h | 2 +- src/libotutil/ot-gpg-utils.h | 4 ++-- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/libostree/ostree-impl-system-generator.c b/src/libostree/ostree-impl-system-generator.c index d64c8a27..ed2bb97c 100644 --- a/src/libostree/ostree-impl-system-generator.c +++ b/src/libostree/ostree-impl-system-generator.c @@ -36,7 +36,7 @@ #ifdef HAVE_LIBMOUNT typedef FILE OtLibMountFile; -G_DEFINE_AUTOPTR_CLEANUP_FUNC(OtLibMountFile, endmntent); +G_DEFINE_AUTOPTR_CLEANUP_FUNC(OtLibMountFile, endmntent) /* Taken from systemd path-util.c */ static bool diff --git a/src/libostree/ostree-repo-checkout.c b/src/libostree/ostree-repo-checkout.c index 15d0394b..bfc280b6 100644 --- a/src/libostree/ostree-repo-checkout.c +++ b/src/libostree/ostree-repo-checkout.c @@ -46,7 +46,7 @@ checkout_state_clear (CheckoutState *state) if (state->selabel_path_buf) g_string_free (state->selabel_path_buf, TRUE); } -G_DEFINE_AUTO_CLEANUP_CLEAR_FUNC(CheckoutState, checkout_state_clear); +G_DEFINE_AUTO_CLEANUP_CLEAR_FUNC(CheckoutState, checkout_state_clear) static gboolean checkout_object_for_uncompressed_cache (OstreeRepo *self, diff --git a/src/libostree/ostree-repo-private.h b/src/libostree/ostree-repo-private.h index 9c514766..d2c41316 100644 --- a/src/libostree/ostree-repo-private.h +++ b/src/libostree/ostree-repo-private.h @@ -173,7 +173,7 @@ _ostree_repo_memory_cache_ref_init (OstreeRepoMemoryCacheRef *state, void _ostree_repo_memory_cache_ref_destroy (OstreeRepoMemoryCacheRef *state); -G_DEFINE_AUTO_CLEANUP_CLEAR_FUNC(OstreeRepoMemoryCacheRef, _ostree_repo_memory_cache_ref_destroy); +G_DEFINE_AUTO_CLEANUP_CLEAR_FUNC(OstreeRepoMemoryCacheRef, _ostree_repo_memory_cache_ref_destroy) #define OSTREE_REPO_TMPDIR_STAGING "staging-" #define OSTREE_REPO_TMPDIR_FETCHER "fetcher-" diff --git a/src/libotutil/ot-fs-utils.h b/src/libotutil/ot-fs-utils.h index 43bc6942..e25522db 100644 --- a/src/libotutil/ot-fs-utils.h +++ b/src/libotutil/ot-fs-utils.h @@ -49,7 +49,7 @@ ot_cleanup_unlinkat (OtCleanupUnlinkat *cleanup) ot_cleanup_unlinkat_clear (cleanup); } } -G_DEFINE_AUTO_CLEANUP_CLEAR_FUNC(OtCleanupUnlinkat, ot_cleanup_unlinkat); +G_DEFINE_AUTO_CLEANUP_CLEAR_FUNC(OtCleanupUnlinkat, ot_cleanup_unlinkat) GFile * ot_fdrel_to_gfile (int dfd, const char *path); diff --git a/src/libotutil/ot-gpg-utils.h b/src/libotutil/ot-gpg-utils.h index 036e5c28..b639e5ac 100644 --- a/src/libotutil/ot-gpg-utils.h +++ b/src/libotutil/ot-gpg-utils.h @@ -26,8 +26,8 @@ G_BEGIN_DECLS -G_DEFINE_AUTO_CLEANUP_FREE_FUNC(gpgme_data_t, gpgme_data_release, NULL); -G_DEFINE_AUTO_CLEANUP_FREE_FUNC(gpgme_ctx_t, gpgme_release, NULL); +G_DEFINE_AUTO_CLEANUP_FREE_FUNC(gpgme_data_t, gpgme_data_release, NULL) +G_DEFINE_AUTO_CLEANUP_FREE_FUNC(gpgme_ctx_t, gpgme_release, NULL) G_DEFINE_AUTO_CLEANUP_FREE_FUNC(gpgme_key_t, gpgme_key_unref, NULL) void ot_gpgme_error_to_gio_error (gpgme_error_t gpg_error, GError **error); From 773154a51324abc3947a716f62fe6eb3d8496fa5 Mon Sep 17 00:00:00 2001 From: Stef Walter Date: Tue, 8 Aug 2017 08:14:13 +0200 Subject: [PATCH 30/67] autogen.sh: Fix running out of tree The autogen.sh script should be runnable out of tree. It's mostly already the case, just one little tweak to make it work. $ mkdir build $ cd build $ ../autogen.sh --prefix=/usr Closes: #1063 Approved by: cgwalters --- autogen.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/autogen.sh b/autogen.sh index 0f32089a..17f6abf4 100755 --- a/autogen.sh +++ b/autogen.sh @@ -28,7 +28,6 @@ else gtkdocize fi -cd $olddir if ! test -f libglnx/README.md || ! test -f bsdiff/README.md; then git submodule update --init fi @@ -41,4 +40,5 @@ ln -sf ../libglnx/libglnx.m4 buildutil/libglnx.m4 autoreconf --force --install --verbose +cd $olddir test -n "$NOCONFIGURE" || "$srcdir/configure" "$@" From 39b3c8e90a7ba0195cd2d4b8bef2f776a9b45c9b Mon Sep 17 00:00:00 2001 From: Stef Walter Date: Tue, 8 Aug 2017 07:59:17 +0200 Subject: [PATCH 31/67] man: The min-free-space-percent item goes in [core] section The documentation incorrectly indicates that min-free-space-percent goes in the [remote "name"] section. It should go in [core] instead. Closes: #1062 Approved by: cgwalters --- man/ostree.repo-config.xml | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/man/ostree.repo-config.xml b/man/ostree.repo-config.xml index 60458dfa..90d0f3dc 100644 --- a/man/ostree.repo-config.xml +++ b/man/ostree.repo-config.xml @@ -114,6 +114,14 @@ Boston, MA 02111-1307, USA. + + + min-free-space-percent + Integer percentage value (0-99) that specifies a minimum + percentage of total space (in blocks) in the underlying filesystem to + keep free. The default value is 3. + + @@ -191,13 +199,6 @@ Boston, MA 02111-1307, USA. If set, pulls from this remote will fail with the configured text. This is intended for OS vendors which have a subscription process to access content. - - min-free-space-percent - Integer percentage value (0-99) that specifies a minimum - percentage of total space (in blocks) in the underlying filesystem to - keep free. The default value is 3. - - From be4832242da27887399eb0c0bb7be1378d858b14 Mon Sep 17 00:00:00 2001 From: Philip Withnall Date: Mon, 7 Aug 2017 13:37:57 +0100 Subject: [PATCH 32/67] lib/repo-pull: Fix counting of latest commits when finding repos MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The intended behaviour of ostree_repo_find_remotes() is to return results which have the latest version of at least one of the requested refs. Results which have some of the requested refs, but don’t have the latest version of any of them, should be ignored. The logic to do this was broken in the case that a result contained a positive number of the requested refs, but none of them were the latest version. (It previously worked when the result contained none of the requested refs.) Fix the counting to work correctly in both cases. Signed-off-by: Philip Withnall Closes: #1058 Approved by: cgwalters --- src/libostree/ostree-repo-pull.c | 7 +++++-- tests/test-find-remotes.sh | 18 +++++++++++------- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/src/libostree/ostree-repo-pull.c b/src/libostree/ostree-repo-pull.c index fd4be499..ed616a81 100644 --- a/src/libostree/ostree-repo-pull.c +++ b/src/libostree/ostree-repo-pull.c @@ -5077,7 +5077,7 @@ find_remotes_cb (GObject *obj, { OstreeRepoFinderResult *result = g_ptr_array_index (results, i); g_autoptr(GHashTable) validated_ref_to_checksum = NULL; /* (element-type utf8 utf8) */ - gsize j; + gsize j, n_latest_refs; /* Previous error processing this result? */ if (result == NULL) @@ -5089,6 +5089,7 @@ find_remotes_cb (GObject *obj, ostree_collection_ref_equal, (GDestroyNotify) ostree_collection_ref_free, g_free); + n_latest_refs = 0; for (j = 0; refs[j] != NULL; j++) { @@ -5096,11 +5097,13 @@ find_remotes_cb (GObject *obj, if (pointer_table_get (refs_and_remotes_table, j, i) != latest_commit_for_ref) latest_commit_for_ref = NULL; + if (latest_commit_for_ref != NULL) + n_latest_refs++; g_hash_table_insert (validated_ref_to_checksum, ostree_collection_ref_dup (refs[j]), g_strdup (latest_commit_for_ref)); } - if (g_hash_table_size (validated_ref_to_checksum) == 0) + if (n_latest_refs == 0) { g_debug ("%s: Omitting remote ‘%s’ from results as none of its refs are new enough.", G_STRFUNC, result->remote->name); diff --git a/tests/test-find-remotes.sh b/tests/test-find-remotes.sh index 0b887664..0cf0127f 100755 --- a/tests/test-find-remotes.sh +++ b/tests/test-find-remotes.sh @@ -71,11 +71,16 @@ ${CMD_PREFIX} ostree --repo=local-mirror pull --mirror os-remote os/amd64/master ${CMD_PREFIX} ostree --repo=local-mirror refs | wc -l > refscount assert_file_has_content refscount "^0$" +ls -1 local-mirror/refs/remotes | wc -l > remotescount +assert_file_has_content remotescount "^0$" ${CMD_PREFIX} ostree --repo=local-mirror refs --collections > refs assert_file_has_content refs "^(org.example.AppsCollection, app1)$" assert_file_has_content refs "^(org.example.OsCollection, os/amd64/master)$" +assert_file_has_content local-mirror/refs/mirrors/org.example.AppsCollection/app1 "^$(cat app1-checksum)$" +assert_file_has_content local-mirror/refs/mirrors/org.example.OsCollection/os/amd64/master "^$(cat os-checksum)$" + for repo in local local-mirror; do # Try finding an update for an existing branch. ${CMD_PREFIX} ostree --repo=$repo find-remotes org.example.AppsCollection app1 > find @@ -169,14 +174,16 @@ for repo in local-mirror; do assert_file_has_content pull "^Pulled 1/1 refs successfully.$" assert_not_file_has_content pull "Failed to pull some refs from the remotes" assert_ref $repo os/amd64/master $(cat os-checksum-2) + + # We need to manually update the refs afterwards, since the original pull + # into the local-mirror was a --mirror pull — so it wrote refs/mirrors/blah. + # This pull was not, so it wrote refs/remotes/blah. + ${CMD_PREFIX} ostree --repo=$repo refs --collections --create org.example.OsCollection:os/amd64/master os-remote:os/amd64/master done # Add the local mirror to the local repository as a remote, so that the local repo # has two configured remotes for the os-collection. Ensure its summary is up to date first. -#${CMD_PREFIX} ostree --repo=local-mirror summary --update -# FIXME: This `cp` can be changed to `ostree summary --update` once PR #946 lands. -# Prior to that, we need to preserve the signatures. -cp os-collection/summary{,.sig} local-mirror/ +${CMD_PREFIX} ostree --repo=local-mirror summary --update ${CMD_PREFIX} ostree --repo=local remote add os-remote-local-mirror file://$(pwd)/local-mirror --collection-id org.example.OsCollection --gpg-import=${test_tmpdir}/gpghome/key2.asc for repo in local; do @@ -212,9 +219,6 @@ for repo in local; do assert_file_has_content find "^Result [0-9]\+: file://$(pwd)/os-collection$" assert_file_has_content find "^ - Keyring: os-remote.trustedkeys.gpg$" assert_file_has_content find "^ - (org.example.OsCollection, os/amd64/master) = $(cat os-checksum-3)$" - assert_file_has_content find "^Result [0-9]\+: file://$(pwd)/local-mirror$" - assert_file_has_content find "^ - Keyring: os-remote-local-mirror.trustedkeys.gpg$" - assert_file_has_content find "^ - (org.example.OsCollection, os/amd64/master) = $(cat os-checksum-3)$" assert_file_has_content find "^1/1 refs were found.$" assert_not_file_has_content find "^No results.$" From 0d2a9a79090a2d3bbe3f638018c473c4cc2f3b11 Mon Sep 17 00:00:00 2001 From: Philip Withnall Date: Mon, 7 Aug 2017 19:49:17 +0100 Subject: [PATCH 33/67] lib/repo-finder: Avoid a potential unref-of-NULL crash MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As the comment explains, it’s possible for a result to be freed while ref_to_checksum is NULL, even though normally the data structure guarantees it’s non-NULL. This was causing crashes when results were filtered out of a find-remotes call. Guard against that. Signed-off-by: Philip Withnall Closes: #1058 Approved by: cgwalters --- src/libostree/ostree-repo-finder.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/libostree/ostree-repo-finder.c b/src/libostree/ostree-repo-finder.c index 7893978d..1ddb2c62 100644 --- a/src/libostree/ostree-repo-finder.c +++ b/src/libostree/ostree-repo-finder.c @@ -550,7 +550,9 @@ ostree_repo_finder_result_free (OstreeRepoFinderResult *result) { g_return_if_fail (result != NULL); - g_hash_table_unref (result->ref_to_checksum); + /* This may be NULL iff the result is freed half-way through find_remotes_cb() + * in ostree-repo-pull.c, and at no other time. */ + g_clear_pointer (&result->ref_to_checksum, g_hash_table_unref); g_object_unref (result->finder); ostree_remote_unref (result->remote); g_free (result); From 11e165b154bbf35915eaea62bf36e4cd30acb1c1 Mon Sep 17 00:00:00 2001 From: Philip Withnall Date: Mon, 7 Aug 2017 19:50:40 +0100 Subject: [PATCH 34/67] lib/repo-pull: Add a missing precondition This catches a few failure modes in the pull code a little earlier, before the incorrectly-NULL repo makes its way into a closure and a worker thread, where the cause of the problem is harder to track down. Signed-off-by: Philip Withnall Closes: #1058 Approved by: cgwalters --- src/libostree/ostree-repo-pull.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libostree/ostree-repo-pull.c b/src/libostree/ostree-repo-pull.c index ed616a81..8c0c4ff1 100644 --- a/src/libostree/ostree-repo-pull.c +++ b/src/libostree/ostree-repo-pull.c @@ -3270,6 +3270,7 @@ ostree_repo_pull_with_options (OstreeRepo *self, (void) g_variant_lookup (options, "localcache-repos", "^a&s", &opt_localcache_repos); } + g_return_val_if_fail (OSTREE_IS_REPO (self), FALSE); g_return_val_if_fail (pull_data->maxdepth >= -1, FALSE); g_return_val_if_fail (!opt_collection_refs_set || (refs_to_fetch == NULL && override_commit_ids == NULL), FALSE); From f35b409077dc7881e6e1a8d59bb709226e0d93c6 Mon Sep 17 00:00:00 2001 From: Philip Withnall Date: Mon, 7 Aug 2017 19:52:17 +0100 Subject: [PATCH 35/67] lib/repo-refs: Add ostree_repo_remote_list_collection_refs() API MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This parallels ostree_repo_remote_list_refs(), but returns a map of OstreeCollectionRef → checksum, and includes refs from collection IDs other than the remote repository’s main collection ID. Use this in OstreeRepoFinderConfig to ensure that refs are matched against even if they’re stored in the repository summary file’s collection map, rather than its main ref map. This fixes false negatives when searching for refs in some situations. Signed-off-by: Philip Withnall Closes: #1058 Approved by: cgwalters --- apidoc/ostree-experimental-sections.txt | 1 + src/libostree/libostree-experimental.sym | 1 + src/libostree/ostree-repo-finder-config.c | 9 +- src/libostree/ostree-repo-refs.c | 120 ++++++++++++++++++++++ src/libostree/ostree-repo.h | 9 ++ 5 files changed, 136 insertions(+), 4 deletions(-) diff --git a/apidoc/ostree-experimental-sections.txt b/apidoc/ostree-experimental-sections.txt index a2c2c295..23412dda 100644 --- a/apidoc/ostree-experimental-sections.txt +++ b/apidoc/ostree-experimental-sections.txt @@ -82,6 +82,7 @@ ostree_repo_get_collection_id ostree_repo_set_collection_id ostree_validate_collection_id ostree_repo_list_collection_refs +ostree_repo_remote_list_collection_refs ostree_repo_set_collection_ref_immediate ostree_repo_transaction_set_collection_ref diff --git a/src/libostree/libostree-experimental.sym b/src/libostree/libostree-experimental.sym index 32ba0929..f60d4e01 100644 --- a/src/libostree/libostree-experimental.sym +++ b/src/libostree/libostree-experimental.sym @@ -70,6 +70,7 @@ global: ostree_repo_list_collection_refs; ostree_repo_pull_from_remotes_async; ostree_repo_pull_from_remotes_finish; + ostree_repo_remote_list_collection_refs; ostree_repo_resolve_keyring_for_collection; ostree_repo_set_collection_id; ostree_repo_set_collection_ref_immediate; diff --git a/src/libostree/ostree-repo-finder-config.c b/src/libostree/ostree-repo-finder-config.c index 79a63536..2f9841db 100644 --- a/src/libostree/ostree-repo-finder-config.c +++ b/src/libostree/ostree-repo-finder-config.c @@ -111,7 +111,7 @@ ostree_repo_finder_config_resolve_async (OstreeRepoFinder *find for (i = 0; i < n_remotes; i++) { g_autoptr(GError) local_error = NULL; - g_autoptr(GHashTable) remote_refs = NULL; /* (element-type utf8 utf8) */ + g_autoptr(GHashTable) remote_refs = NULL; /* (element-type OstreeCollectionRef utf8) */ const gchar *checksum; g_autofree gchar *remote_collection_id = NULL; @@ -127,8 +127,9 @@ ostree_repo_finder_config_resolve_async (OstreeRepoFinder *find continue; } - if (!ostree_repo_remote_list_refs (parent_repo, remote_name, &remote_refs, - cancellable, &local_error)) + if (!ostree_repo_remote_list_collection_refs (parent_repo, remote_name, + &remote_refs, cancellable, + &local_error)) { g_debug ("Ignoring remote ‘%s’ due to error loading its refs: %s", remote_name, local_error->message); @@ -139,7 +140,7 @@ ostree_repo_finder_config_resolve_async (OstreeRepoFinder *find for (j = 0; refs[j] != NULL; j++) { if (g_strcmp0 (refs[j]->collection_id, remote_collection_id) == 0 && - g_hash_table_lookup_extended (remote_refs, refs[j]->ref_name, NULL, (gpointer *) &checksum)) + g_hash_table_lookup_extended (remote_refs, refs[j], NULL, (gpointer *) &checksum)) { /* The requested ref is listed in the refs for this remote. Add * the remote to the results, and the ref to its diff --git a/src/libostree/ostree-repo-refs.c b/src/libostree/ostree-repo-refs.c index a180e40b..6c113fb6 100644 --- a/src/libostree/ostree-repo-refs.c +++ b/src/libostree/ostree-repo-refs.c @@ -779,6 +779,126 @@ ostree_repo_remote_list_refs (OstreeRepo *self, return TRUE; } +#ifdef OSTREE_ENABLE_EXPERIMENTAL_API +static gboolean +remote_list_collection_refs_process_refs (OstreeRepo *self, + const gchar *remote_name, + const gchar *summary_collection_id, + GVariant *summary_refs, + GHashTable *ret_all_refs, + GError **error) +{ + gsize j, n; + + for (j = 0, n = g_variant_n_children (summary_refs); j < n; j++) + { + const guchar *csum_bytes; + g_autoptr(GVariant) ref_v = NULL, csum_v = NULL; + gchar tmp_checksum[OSTREE_SHA256_STRING_LEN + 1]; + const gchar *ref_name; + + /* Check the ref name. */ + ref_v = g_variant_get_child_value (summary_refs, j); + g_variant_get_child (ref_v, 0, "&s", &ref_name); + + if (!ostree_validate_rev (ref_name, error)) + return FALSE; + + /* Check the commit checksum. */ + g_variant_get_child (ref_v, 1, "(t@ay@a{sv})", NULL, &csum_v, NULL); + + csum_bytes = ostree_checksum_bytes_peek_validate (csum_v, error); + if (csum_bytes == NULL) + return FALSE; + + ostree_checksum_inplace_from_bytes (csum_bytes, tmp_checksum); + + g_hash_table_insert (ret_all_refs, + ostree_collection_ref_new (summary_collection_id, ref_name), + g_strdup (tmp_checksum)); + } + + return TRUE; +} + +/** + * ostree_repo_remote_list_collection_refs: + * @self: Repo + * @remote_name: Name of the remote. + * @out_all_refs: (out) (element-type OstreeCollectionRef utf8): Mapping from collection–ref to checksum + * @cancellable: Cancellable + * @error: Error + * + * List refs advertised by @remote_name, including refs which are part of + * collections. If the repository at @remote_name has a collection ID set, its + * refs will be returned with that collection ID; otherwise, they will be returned + * with a %NULL collection ID in each #OstreeCollectionRef key in @out_all_refs. + * Any refs for other collections stored in the repository will also be returned. + * No filtering is performed. + * + * Since: 2017.10 + */ +gboolean +ostree_repo_remote_list_collection_refs (OstreeRepo *self, + const char *remote_name, + GHashTable **out_all_refs, + GCancellable *cancellable, + GError **error) +{ + g_autoptr(GBytes) summary_bytes = NULL; + g_autoptr(GHashTable) ret_all_refs = NULL; /* (element-type OstreeCollectionRef utf8) */ + g_autoptr(GVariant) summary_v = NULL; + g_autoptr(GVariant) additional_metadata_v = NULL; + g_autoptr(GVariant) summary_refs = NULL; + const char *summary_collection_id; + g_autoptr(GVariantIter) summary_collection_map = NULL; + + if (!ostree_repo_remote_fetch_summary (self, remote_name, + &summary_bytes, NULL, + cancellable, error)) + return FALSE; + + if (summary_bytes == NULL) + return glnx_throw (error, "Remote refs not available; server has no summary file"); + + ret_all_refs = g_hash_table_new_full (ostree_collection_ref_hash, + ostree_collection_ref_equal, + (GDestroyNotify) ostree_collection_ref_free, + g_free); + + summary_v = g_variant_new_from_bytes (OSTREE_SUMMARY_GVARIANT_FORMAT, + summary_bytes, FALSE); + additional_metadata_v = g_variant_get_child_value (summary_v, 1); + + /* List the refs in the main map. */ + if (!g_variant_lookup (additional_metadata_v, OSTREE_SUMMARY_COLLECTION_ID, "&s", &summary_collection_id)) + summary_collection_id = NULL; + + summary_refs = g_variant_get_child_value (summary_v, 0); + + if (!remote_list_collection_refs_process_refs (self, remote_name, + summary_collection_id, summary_refs, + ret_all_refs, error)) + return FALSE; + + /* List the refs in the collection map. */ + if (!g_variant_lookup (additional_metadata_v, OSTREE_SUMMARY_COLLECTION_MAP, "a{sa(s(taya{sv}))}", &summary_collection_map)) + summary_collection_map = NULL; + + while (summary_collection_map != NULL && + g_variant_iter_loop (summary_collection_map, "{s@a(s(taya{sv}))}", &summary_collection_id, &summary_refs)) + { + if (!remote_list_collection_refs_process_refs (self, remote_name, + summary_collection_id, summary_refs, + ret_all_refs, error)) + return FALSE; + } + + ot_transfer_out_value (out_all_refs, &ret_all_refs); + return TRUE; +} +#endif /* OSTREE_ENABLE_EXPERIMENTAL_API */ + static char * relative_symlink_to (const char *relpath, const char *target) diff --git a/src/libostree/ostree-repo.h b/src/libostree/ostree-repo.h index decf9a4e..f01fee2a 100644 --- a/src/libostree/ostree-repo.h +++ b/src/libostree/ostree-repo.h @@ -482,6 +482,15 @@ gboolean ostree_repo_remote_list_refs (OstreeRepo *self, GCancellable *cancellable, GError **error); +#ifdef OSTREE_ENABLE_EXPERIMENTAL_API +_OSTREE_PUBLIC +gboolean ostree_repo_remote_list_collection_refs (OstreeRepo *self, + const char *remote_name, + GHashTable **out_all_refs, + GCancellable *cancellable, + GError **error); +#endif /* OSTREE_ENABLE_EXPERIMENTAL_API */ + _OSTREE_PUBLIC gboolean ostree_repo_load_variant (OstreeRepo *self, OstreeObjectType objtype, From baa9534fdadbc2103036511a31ac7053ee174f62 Mon Sep 17 00:00:00 2001 From: Philip Withnall Date: Mon, 7 Aug 2017 14:06:43 +0100 Subject: [PATCH 36/67] lib/repo-finder-avahi: Drop redundant conditional MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit summary_timestamp is checked for non-NULL-ness above, and the function bails if it’s NULL. Fixes Coverity issue #1452616. Signed-off-by: Philip Withnall Closes: #1059 Approved by: cgwalters --- src/libostree/ostree-repo-finder-avahi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libostree/ostree-repo-finder-avahi.c b/src/libostree/ostree-repo-finder-avahi.c index 433914b4..e9e2471a 100644 --- a/src/libostree/ostree-repo-finder-avahi.c +++ b/src/libostree/ostree-repo-finder-avahi.c @@ -830,7 +830,7 @@ ostree_avahi_service_build_repo_finder_result (OstreeAvahiService g_ptr_array_add (results, ostree_repo_finder_result_new (remote, OSTREE_REPO_FINDER (finder), priority, supported_ref_to_checksum, - (summary_timestamp != NULL) ? GUINT64_FROM_BE (g_variant_get_uint64 (summary_timestamp)) : 0)); + GUINT64_FROM_BE (g_variant_get_uint64 (summary_timestamp)))); } } From 4f187b576dc58d725757070148c824916d3c3aa7 Mon Sep 17 00:00:00 2001 From: Philip Withnall Date: Mon, 7 Aug 2017 14:09:07 +0100 Subject: [PATCH 37/67] lib/repo-commit: Drop unreachable conditional branch MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit (remaining > 0) is asserted by the loop condition, and remaining is not modified between that check and the G_UNLIKELY — so the condition in the G_UNLIKELY will always be true. Spotted by Coverity as issue #1452617. Signed-off-by: Philip Withnall Closes: #1059 Approved by: cgwalters --- src/libostree/ostree-repo-commit.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/libostree/ostree-repo-commit.c b/src/libostree/ostree-repo-commit.c index dc52f5e7..72961dde 100644 --- a/src/libostree/ostree-repo-commit.c +++ b/src/libostree/ostree-repo-commit.c @@ -486,12 +486,7 @@ create_regular_tmpfile_linkable_with_content (OstreeRepo *self, if (bytes_read < 0) return FALSE; else if (bytes_read == 0) - { - if (G_UNLIKELY (remaining > 0)) - return glnx_throw (error, "Unexpected EOF with %" G_GUINT64_FORMAT "/%" G_GUINT64_FORMAT " bytes remaining", remaining, length); - else - break; - } + return glnx_throw (error, "Unexpected EOF with %" G_GUINT64_FORMAT "/%" G_GUINT64_FORMAT " bytes remaining", remaining, length); if (glnx_loop_write (tmpf.fd, buf, bytes_read) < 0) return glnx_throw_errno_prefix (error, "write"); remaining -= bytes_read; From e9b9123bae755c91c9a0cddc4c9cdb8383267f75 Mon Sep 17 00:00:00 2001 From: Philip Withnall Date: Mon, 7 Aug 2017 14:11:31 +0100 Subject: [PATCH 38/67] lib/sepolicy: Drop duplicate assignment Spotted by Coverity as issue #1452619. Signed-off-by: Philip Withnall Closes: #1059 Approved by: cgwalters --- src/libostree/ostree-sepolicy.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libostree/ostree-sepolicy.c b/src/libostree/ostree-sepolicy.c index 7387ea0f..6012d9da 100644 --- a/src/libostree/ostree-sepolicy.c +++ b/src/libostree/ostree-sepolicy.c @@ -328,7 +328,7 @@ initable_init (GInitable *initable, g_autoptr(GFile) policy_root = NULL; if (g_file_query_exists (policy_config_path, NULL)) { - g_autoptr(GFileInputStream) filein = filein = g_file_read (policy_config_path, cancellable, error); + g_autoptr(GFileInputStream) filein = g_file_read (policy_config_path, cancellable, error); if (!filein) return FALSE; From 86dce4b252005949a4f9a4f7b4666982b12a84d4 Mon Sep 17 00:00:00 2001 From: Philip Withnall Date: Mon, 7 Aug 2017 14:13:30 +0100 Subject: [PATCH 39/67] ostree/parse-datetime: Ensure tm structs are initialised Otherwise tm.tm_wday remains uninitialised and gets propagated elsewhere. Spotted by Coverity as issue #209265. Signed-off-by: Philip Withnall Closes: #1059 Approved by: cgwalters --- src/ostree/parse-datetime.y | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ostree/parse-datetime.y b/src/ostree/parse-datetime.y index f5688d30..50917354 100644 --- a/src/ostree/parse-datetime.y +++ b/src/ostree/parse-datetime.y @@ -1280,8 +1280,8 @@ parse_datetime (struct timespec *result, char const *p, time_t Start; long int Start_ns; struct tm const *tmp; - struct tm tm; - struct tm tm0; + struct tm tm = { 0, }; + struct tm tm0 = { 0, }; parser_control pc; struct timespec gettime_buffer; unsigned char c; From 1672e2eee058d0fe41ed102ca310a9634d36572f Mon Sep 17 00:00:00 2001 From: Philip Withnall Date: Tue, 8 Aug 2017 15:39:34 +0100 Subject: [PATCH 40/67] lib/repo: Fix handling of missing summary files when downloading MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The API for downloading a summary file can legitimately return NULL for the summary file contents when it returns TRUE (success). This indicates an error 404 — the summary file was not found. Two call sites were not handling that correctly, which was causing later assertion failures. Signed-off-by: Philip Withnall Closes: #1061 Closes: #1065 Approved by: cgwalters --- src/libostree/ostree-repo-finder-avahi.c | 10 +++++++++- src/libostree/ostree-repo-pull.c | 8 ++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/libostree/ostree-repo-finder-avahi.c b/src/libostree/ostree-repo-finder-avahi.c index e9e2471a..a1500567 100644 --- a/src/libostree/ostree-repo-finder-avahi.c +++ b/src/libostree/ostree-repo-finder-avahi.c @@ -556,7 +556,8 @@ get_refs_and_checksums_from_summary (GBytes *summary_bytes, } /* Download the summary file from @remote, and return the bytes of the file in - * @out_summary_bytes. */ + * @out_summary_bytes. This will return %TRUE and set @out_summary_bytes to %NULL + * if the summary file does not exist. */ static gboolean fetch_summary_from_remote (OstreeRepo *repo, OstreeRemote *remote, @@ -648,6 +649,13 @@ get_checksums (OstreeRepoFinderAvahi *finder, error)) return FALSE; + if (summary_bytes == NULL) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND, + "No summary file found on server"); + return FALSE; + } + return get_refs_and_checksums_from_summary (summary_bytes, supported_ref_to_checksum, error); } diff --git a/src/libostree/ostree-repo-pull.c b/src/libostree/ostree-repo-pull.c index 8c0c4ff1..6298a28e 100644 --- a/src/libostree/ostree-repo-pull.c +++ b/src/libostree/ostree-repo-pull.c @@ -4834,6 +4834,14 @@ find_remotes_cb (GObject *obj, g_clear_error (&error); continue; } + else if (summary_bytes == NULL) + { + g_debug ("%s: Failed to download summary for result ‘%s’. Ignoring. %s", + G_STRFUNC, result->remote->name, + "No summary file exists on server"); + g_clear_pointer (&g_ptr_array_index (results, i), (GDestroyNotify) ostree_repo_finder_result_free); + continue; + } /* Check the metadata in the summary file, especially whether it contains * all the @refs we are interested in. */ From 9f8f351cd45e5dd0219c3177558b497ab10c58e9 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Mon, 24 Jul 2017 16:39:01 -0400 Subject: [PATCH 41/67] lib: Port gpg verification for remotes to fd-relative This was the last use of `repo->repodir` internally, and will help finally add `ostree_repo_open_at()`. Closes: #1034 Approved by: jlebon --- src/libostree/ostree-gpg-verifier.c | 86 +++++++++++++++++++++-------- src/libostree/ostree-gpg-verifier.h | 12 +++- src/libostree/ostree-repo.c | 56 +++++++++++++------ 3 files changed, 112 insertions(+), 42 deletions(-) diff --git a/src/libostree/ostree-gpg-verifier.c b/src/libostree/ostree-gpg-verifier.c index 680c410b..99756e2b 100644 --- a/src/libostree/ostree-gpg-verifier.c +++ b/src/libostree/ostree-gpg-verifier.c @@ -40,6 +40,7 @@ struct OstreeGpgVerifier { GObject parent; GList *keyrings; + GPtrArray *keyring_data; GPtrArray *key_ascii_files; }; @@ -53,6 +54,7 @@ ostree_gpg_verifier_finalize (GObject *object) g_list_free_full (self->keyrings, g_object_unref); if (self->key_ascii_files) g_ptr_array_unref (self->key_ascii_files); + g_clear_pointer (&self->keyring_data, (GDestroyNotify)g_ptr_array_unref); G_OBJECT_CLASS (_ostree_gpg_verifier_parent_class)->finalize (object); } @@ -71,6 +73,7 @@ _ostree_gpg_verifier_class_init (OstreeGpgVerifierClass *klass) static void _ostree_gpg_verifier_init (OstreeGpgVerifier *self) { + self->keyring_data = g_ptr_array_new_with_free_func ((GDestroyNotify)g_bytes_unref); } static void @@ -151,6 +154,17 @@ _ostree_gpg_verifier_check_signature (OstreeGpgVerifier *self, goto out; } + for (guint i = 0; i < self->keyring_data->len; i++) + { + GBytes *keyringd = self->keyring_data->pdata[i]; + gsize len; + gsize bytes_written; + const guint8 *buf = g_bytes_get_data (keyringd, &len); + if (!g_output_stream_write_all (target_stream, buf, len, &bytes_written, + cancellable, error)) + goto out; + } + if (!g_output_stream_close (target_stream, cancellable, error)) goto out; @@ -253,15 +267,28 @@ out: return result; } +/* Given @path which should contain a GPG keyring file, add it + * to the list of trusted keys. + */ void -_ostree_gpg_verifier_add_keyring (OstreeGpgVerifier *self, - GFile *path) +_ostree_gpg_verifier_add_keyring_file (OstreeGpgVerifier *self, + GFile *path) { g_return_if_fail (G_IS_FILE (path)); self->keyrings = g_list_append (self->keyrings, g_object_ref (path)); } +/* Given @keyring which should be the contents of a GPG keyring file, add it to + * the list of trusted keys. + */ +void +_ostree_gpg_verifier_add_keyring_data (OstreeGpgVerifier *self, + GBytes *keyring) +{ + g_ptr_array_add (self->keyring_data, g_bytes_ref (keyring)); +} + void _ostree_gpg_verifier_add_key_ascii_file (OstreeGpgVerifier *self, const char *path) @@ -276,32 +303,39 @@ _ostree_gpg_verifier_add_keyring_dir (OstreeGpgVerifier *self, GFile *path, GCancellable *cancellable, GError **error) + { - gboolean ret = FALSE; - g_autoptr(GFileEnumerator) enumerator = NULL; - - enumerator = g_file_enumerate_children (path, OSTREE_GIO_FAST_QUERYINFO, - G_FILE_QUERY_INFO_NONE, - cancellable, error); - if (!enumerator) - goto out; + return _ostree_gpg_verifier_add_keyring_dir_at (self, AT_FDCWD, + gs_file_get_path_cached (path), + cancellable, error); +} + +gboolean +_ostree_gpg_verifier_add_keyring_dir_at (OstreeGpgVerifier *self, + int dfd, + const char *path, + GCancellable *cancellable, + GError **error) + +{ + g_auto(GLnxDirFdIterator) dfd_iter = { 0, }; + if (!glnx_dirfd_iterator_init_at (dfd, path, FALSE, + &dfd_iter, error)) + return FALSE; while (TRUE) { - GFileInfo *file_info; - GFile *path; - const char *name; + struct dirent *dent; - if (!g_file_enumerator_iterate (enumerator, &file_info, &path, - cancellable, error)) - goto out; - if (file_info == NULL) + if (!glnx_dirfd_iterator_next_dent_ensure_dtype (&dfd_iter, &dent, cancellable, error)) + return FALSE; + if (dent == NULL) break; - if (g_file_info_get_file_type (file_info) != G_FILE_TYPE_REGULAR) + if (dent->d_type != DT_REG) continue; - name = g_file_info_get_name (file_info); + const char *name = dent->d_name; /* Files with a .gpg suffix are typically keyrings except * for trustdb.gpg, which is the GPG trust database. */ @@ -315,12 +349,18 @@ _ostree_gpg_verifier_add_keyring_dir (OstreeGpgVerifier *self, if (g_str_equal (name, "secring.gpg")) continue; - self->keyrings = g_list_append (self->keyrings, g_object_ref (path)); + glnx_fd_close int fd = -1; + if (!glnx_openat_rdonly (dfd_iter.fd, dent->d_name, TRUE, &fd, error)) + return FALSE; + + g_autoptr(GBytes) data = glnx_fd_readall_bytes (fd, cancellable, error); + if (!data) + return FALSE; + + g_ptr_array_add (self->keyring_data, g_steal_pointer (&data)); } - ret = TRUE; - out: - return ret; + return TRUE; } gboolean diff --git a/src/libostree/ostree-gpg-verifier.h b/src/libostree/ostree-gpg-verifier.h index 4156d1bd..7d5a7594 100644 --- a/src/libostree/ostree-gpg-verifier.h +++ b/src/libostree/ostree-gpg-verifier.h @@ -55,12 +55,20 @@ gboolean _ostree_gpg_verifier_add_keyring_dir (OstreeGpgVerifier *self, GCancellable *cancellable, GError **error); +gboolean _ostree_gpg_verifier_add_keyring_dir_at (OstreeGpgVerifier *self, + int dfd, + const char *path, + GCancellable *cancellable, + GError **error); + gboolean _ostree_gpg_verifier_add_global_keyring_dir (OstreeGpgVerifier *self, GCancellable *cancellable, GError **error); -void _ostree_gpg_verifier_add_keyring (OstreeGpgVerifier *self, - GFile *path); +void _ostree_gpg_verifier_add_keyring_data (OstreeGpgVerifier *self, + GBytes *data); +void _ostree_gpg_verifier_add_keyring_file (OstreeGpgVerifier *self, + GFile *path); void _ostree_gpg_verifier_add_key_ascii_file (OstreeGpgVerifier *self, const char *path); diff --git a/src/libostree/ostree-repo.c b/src/libostree/ostree-repo.c index 5d5d871b..7b787760 100644 --- a/src/libostree/ostree-repo.c +++ b/src/libostree/ostree-repo.c @@ -4202,31 +4202,52 @@ ostree_repo_add_gpg_signature_summary (OstreeRepo *self, /* Special remote for _ostree_repo_gpg_verify_with_metadata() */ static const char *OSTREE_ALL_REMOTES = "__OSTREE_ALL_REMOTES__"; -static GFile * +/* Look for a keyring for @remote in the repo itself, or in + * /etc/ostree/remotes.d. + */ +static gboolean find_keyring (OstreeRepo *self, OstreeRemote *remote, - GCancellable *cancellable) + GBytes **ret_bytes, + GCancellable *cancellable, + GError **error) { - g_autoptr(GFile) file = g_file_get_child (self->repodir, remote->keyring); + glnx_fd_close int fd = -1; + if (!ot_openat_ignore_enoent (self->repo_dir_fd, remote->keyring, &fd, error)) + return FALSE; - if (g_file_query_exists (file, cancellable)) + if (fd != -1) { - return g_steal_pointer (&file); + GBytes *ret = glnx_fd_readall_bytes (fd, cancellable, error); + if (!ret) + return FALSE; + *ret_bytes = ret; + return TRUE; } g_autoptr(GFile) remotes_d = get_remotes_d_dir (self, NULL); if (remotes_d) { - g_autoptr(GFile) file2 = g_file_get_child (remotes_d, remote->keyring); + g_autoptr(GFile) child = g_file_get_child (remotes_d, remote->keyring); - if (g_file_query_exists (file2, cancellable)) - return g_steal_pointer (&file2); + if (!ot_openat_ignore_enoent (AT_FDCWD, gs_file_get_path_cached (child), &fd, error)) + return FALSE; + + if (fd != -1) + { + GBytes *ret = glnx_fd_readall_bytes (fd, cancellable, error); + if (!ret) + return FALSE; + *ret_bytes = ret; + return TRUE; + } } if (self->parent_repo) - return find_keyring (self->parent_repo, remote, cancellable); + return find_keyring (self->parent_repo, remote, ret_bytes, cancellable, error); - return NULL; + *ret_bytes = NULL; + return TRUE; } static OstreeGpgVerifyResult * @@ -4248,8 +4269,8 @@ _ostree_repo_gpg_verify_data_internal (OstreeRepo *self, { /* Add all available remote keyring files. */ - if (!_ostree_gpg_verifier_add_keyring_dir (verifier, self->repodir, - cancellable, error)) + if (!_ostree_gpg_verifier_add_keyring_dir_at (verifier, self->repo_dir_fd, ".", + cancellable, error)) return NULL; } else if (remote_name != NULL) @@ -4258,17 +4279,18 @@ _ostree_repo_gpg_verify_data_internal (OstreeRepo *self, /* Add the remote's keyring file if it exists. */ OstreeRemote *remote; - g_autoptr(GFile) file = NULL; remote = _ostree_repo_get_remote_inherited (self, remote_name, error); if (remote == NULL) return NULL; - file = find_keyring (self, remote, cancellable); + g_autoptr(GBytes) keyring_data = NULL; + if (!find_keyring (self, remote, &keyring_data, cancellable, error)) + return NULL; - if (file != NULL) + if (keyring_data != NULL) { - _ostree_gpg_verifier_add_keyring (verifier, file); + _ostree_gpg_verifier_add_keyring_data (verifier, keyring_data); add_global_keyring_dir = FALSE; } @@ -4297,7 +4319,7 @@ _ostree_repo_gpg_verify_data_internal (OstreeRepo *self, } if (extra_keyring != NULL) { - _ostree_gpg_verifier_add_keyring (verifier, extra_keyring); + _ostree_gpg_verifier_add_keyring_file (verifier, extra_keyring); } return _ostree_gpg_verifier_check_signature (verifier, From 8642ef5ab3fec3ac8eb8f193054852f83a8bc4d0 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Wed, 2 Aug 2017 22:07:26 -0400 Subject: [PATCH 42/67] lib/deploy: Use a FIFREEZE/FITHAW cycle for /boot See: http://marc.info/?l=linux-fsdevel&m=149520244919284&w=2 XFS doesn't flush the journal on `syncfs()`. GRUB doesn't know how to follow the XFS journal, so if the filesystem is in a dirty state (possible with xfs `/boot`, extremely likely with `/`, if the journaled data includes content for `/boot`, the system may be unbootable if a system crash occurs. Fix this by doing a `FIFREEZE`+`FITHAW` cycle. Now, most people probably would have replaced the `syncfs()` invocation with those two ioctls. But this would have become (I believe) the *only* place in libostree where we weren't safe against interruption. The failure mode would be ugly; nothing else would be able to write to the filesystem until manual intervention. The real fix here I think is to land an atomic `FIFREEZETHAW` ioctl in the kernel. I might try a patch. In the meantime though, let's jump through some hoops and set up a "watchdog" child process that acts as a fallback unfreezer. Closes: https://github.com/ostreedev/ostree/issues/876 Closes: #1049 Approved by: jlebon --- src/libostree/ostree-sysroot-deploy.c | 137 +++++++++++++++++++++++-- src/libostree/ostree-sysroot-private.h | 3 +- src/libostree/ostree-sysroot.c | 1 + tests/admin-test.sh | 8 ++ tests/test-admin-deploy-grub2.sh | 2 +- tests/test-admin-deploy-syslinux.sh | 2 +- tests/test-admin-deploy-uboot.sh | 2 +- 7 files changed, 141 insertions(+), 14 deletions(-) diff --git a/src/libostree/ostree-sysroot-deploy.c b/src/libostree/ostree-sysroot-deploy.c index 29fcfeed..d87ba1a0 100644 --- a/src/libostree/ostree-sysroot-deploy.c +++ b/src/libostree/ostree-sysroot-deploy.c @@ -22,8 +22,14 @@ #include #include +#include #include #include +#include +#include +#include +#include +#include #ifdef HAVE_LIBMOUNT #include @@ -973,18 +979,126 @@ checksum_from_kernel_src (const char *name, return TRUE; } +/* We used to syncfs(), but that doesn't flush the journal on XFS, + * and since GRUB2 can't read the XFS journal, the system + * could fail to boot. + * + * http://marc.info/?l=linux-fsdevel&m=149520244919284&w=2 + * https://github.com/ostreedev/ostree/pull/1049 + */ static gboolean -syncfs_dir_at (int dfd, - const char *path, - GCancellable *cancellable, - GError **error) +fsfreeze_thaw_cycle (OstreeSysroot *self, + int rootfs_dfd, + GCancellable *cancellable, + GError **error) { - glnx_fd_close int child_dfd = -1; - if (!glnx_opendirat (dfd, path, TRUE, &child_dfd, error)) - return FALSE; - if (syncfs (child_dfd) != 0) - return glnx_throw_errno_prefix (error, "syncfs(%s)", path); + GLNX_AUTO_PREFIX_ERROR ("During fsfreeze-thaw", error); + int sockpair[2]; + if (socketpair (AF_UNIX, SOCK_SEQPACKET | SOCK_CLOEXEC, 0, sockpair) < 0) + return glnx_throw_errno_prefix (error, "socketpair"); + glnx_fd_close int sock_parent = sockpair[0]; + glnx_fd_close int sock_watchdog = sockpair[1]; + + pid_t pid = fork (); + if (pid < 0) + return glnx_throw_errno_prefix (error, "fork"); + + const gboolean debug_fifreeze = (self->debug_flags & OSTREE_SYSROOT_DEBUG_TEST_FIFREEZE)>0; + char c = '!'; + if (pid == 0) /* Child watchdog/unfreezer process. */ + { + (void) close (glnx_steal_fd (&sock_parent)); + /* Daemonize, and mask SIGINT/SIGTERM, so we're likely to survive e.g. + * someone doing a `systemctl restart rpm-ostreed` or a Ctrl-C of + * `ostree admin upgrade`. + */ + if (daemon (0, debug_fifreeze ? 1 : 0) < 0) + err (1, "daemon"); + int sigs[] = { SIGINT, SIGTERM }; + for (guint i = 0; i < G_N_ELEMENTS (sigs); i++) + { + if (signal (sigs[i], SIG_IGN) == SIG_ERR) + err (1, "signal"); + } + /* Tell the parent we're ready */ + if (write (sock_watchdog, &c, sizeof (c)) != 1) + err (1, "write"); + /* Wait for the parent to say it's going to freeze. */ + ssize_t bytes_read = TEMP_FAILURE_RETRY (read (sock_watchdog, &c, sizeof (c))); + if (bytes_read < 0) + err (1, "read"); + if (bytes_read != 1) + errx (1, "failed to read from parent"); + /* Now we wait for the second message from the parent saying the freeze is + * complete. We have a 30 second timeout; if somehow the parent hasn't + * signaled completion, go ahead and unfreeze. But for debugging, just 1 + * second to avoid exessively lengthining the test suite. + */ + const int timeout_ms = debug_fifreeze ? 1000 : 30000; + struct pollfd pfds[1]; + pfds[0].fd = sock_watchdog; + pfds[0].events = POLLIN | POLLHUP; + int r = TEMP_FAILURE_RETRY (poll (pfds, 1, timeout_ms)); + /* Do a thaw if we hit an error, or if the poll timed out */ + if (r <= 0) + { + if (TEMP_FAILURE_RETRY (ioctl (rootfs_dfd, FITHAW, 0)) != 0) + { + if (errno == EPERM) + ; /* Ignore this for the test suite */ + else + err (1, "FITHAW"); + } + /* But if we got an error from poll, let's log it */ + if (r < 0) + err (1, "poll"); + } + if (debug_fifreeze) + g_printerr ("fifreeze watchdog was run\n"); + exit (EXIT_SUCCESS); + } + else /* Parent process. */ + { + (void) close (glnx_steal_fd (&sock_watchdog)); + /* Wait for the watchdog to say it's set up; mainly that it's + * masked SIGTERM successfully. + */ + ssize_t bytes_read = TEMP_FAILURE_RETRY (read (sock_parent, &c, sizeof (c))); + if (bytes_read < 0) + return glnx_throw_errno_prefix (error, "read(watchdog init)"); + if (bytes_read != 1) + return glnx_throw (error, "read(watchdog init)"); + /* And tell the watchdog that we're ready to start */ + if (write (sock_parent, &c, sizeof (c)) != sizeof (c)) + return glnx_throw_errno_prefix (error, "write(watchdog start)"); + /* Testing infrastructure */ + if (debug_fifreeze) + return glnx_throw (error, "aborting due to test-fifreeze"); + /* Do a freeze/thaw cycle; TODO add a FIFREEZETHAW ioctl */ + if (ioctl (rootfs_dfd, FIFREEZE, 0) != 0) + { + /* Not supported, or we're running in the unit tests (as non-root)? + * OK, let's just do a syncfs. + */ + if (G_IN_SET (errno, EOPNOTSUPP, EPERM)) + { + if (TEMP_FAILURE_RETRY (syncfs (rootfs_dfd)) != 0) + return glnx_throw_errno_prefix (error, "syncfs"); + /* Write the completion, and return */ + if (write (sock_parent, &c, sizeof (c)) != sizeof (c)) + return glnx_throw_errno_prefix (error, "write(watchdog syncfs complete)"); + return TRUE; + } + else + return glnx_throw_errno_prefix (error, "ioctl(FIFREEZE)"); + } + /* And finally thaw, then signal our completion to the watchdog */ + if (TEMP_FAILURE_RETRY (ioctl (rootfs_dfd, FITHAW, 0)) != 0) + return glnx_throw_errno_prefix (error, "ioctl(FITHAW)"); + if (write (sock_parent, &c, sizeof (c)) != sizeof (c)) + return glnx_throw_errno_prefix (error, "write(watchdog FITHAW complete)"); + } return TRUE; } @@ -1012,7 +1126,10 @@ full_system_sync (OstreeSysroot *self, out_stats->root_syncfs_msec = (end_msec - start_msec); start_msec = g_get_monotonic_time () / 1000; - if (!syncfs_dir_at (self->sysroot_fd, "boot", cancellable, error)) + glnx_fd_close int boot_dfd = -1; + if (!glnx_opendirat (self->sysroot_fd, "boot", TRUE, &boot_dfd, error)) + return FALSE; + if (!fsfreeze_thaw_cycle (self, boot_dfd, cancellable, error)) return FALSE; end_msec = g_get_monotonic_time () / 1000; out_stats->boot_syncfs_msec = (end_msec - start_msec); diff --git a/src/libostree/ostree-sysroot-private.h b/src/libostree/ostree-sysroot-private.h index 82abc8e7..07c4bf6e 100644 --- a/src/libostree/ostree-sysroot-private.h +++ b/src/libostree/ostree-sysroot-private.h @@ -33,7 +33,8 @@ typedef enum { OSTREE_SYSROOT_DEBUG_MUTABLE_DEPLOYMENTS = 1 << 0, /* See https://github.com/ostreedev/ostree/pull/759 */ OSTREE_SYSROOT_DEBUG_NO_XATTRS = 1 << 1, - + /* https://github.com/ostreedev/ostree/pull/1049 */ + OSTREE_SYSROOT_DEBUG_TEST_FIFREEZE = 1 << 2, } OstreeSysrootDebugFlags; /** diff --git a/src/libostree/ostree-sysroot.c b/src/libostree/ostree-sysroot.c index cb09db7b..20539e4d 100644 --- a/src/libostree/ostree-sysroot.c +++ b/src/libostree/ostree-sysroot.c @@ -166,6 +166,7 @@ ostree_sysroot_init (OstreeSysroot *self) { const GDebugKey keys[] = { { "mutable-deployments", OSTREE_SYSROOT_DEBUG_MUTABLE_DEPLOYMENTS }, + { "test-fifreeze", OSTREE_SYSROOT_DEBUG_TEST_FIFREEZE }, { "no-xattrs", OSTREE_SYSROOT_DEBUG_NO_XATTRS }, }; diff --git a/tests/admin-test.sh b/tests/admin-test.sh index 6001ceea..55de7235 100644 --- a/tests/admin-test.sh +++ b/tests/admin-test.sh @@ -249,3 +249,11 @@ ${CMD_PREFIX} ostree --sysroot=${deployment} remote add --set=gpg-verify=false r assert_not_file_has_content sysroot/ostree/repo/config remote-test-nonphysical assert_file_has_content ${deployment}/etc/ostree/remotes.d/remote-test-nonphysical.conf testos-repo echo "ok remote add nonphysical sysroot" + +if env OSTREE_SYSROOT_DEBUG="${OSTREE_SYSROOT_DEBUG},test-fifreeze" \ + ${CMD_PREFIX} ostree admin deploy --os=testos testos:testos/buildmaster/x86_64-runtime 2>err.txt; then + fatal "fifreeze-test exited successfully?" +fi +assert_file_has_content err.txt "fifreeze watchdog was run" +assert_file_has_content err.txt "During fsfreeze-thaw: aborting due to test-fifreeze" +echo "ok fifreeze test" diff --git a/tests/test-admin-deploy-grub2.sh b/tests/test-admin-deploy-grub2.sh index d7c1c6db..6f785df5 100755 --- a/tests/test-admin-deploy-grub2.sh +++ b/tests/test-admin-deploy-grub2.sh @@ -19,7 +19,7 @@ set -euo pipefail -echo "1..18" +echo "1..19" . $(dirname $0)/libtest.sh diff --git a/tests/test-admin-deploy-syslinux.sh b/tests/test-admin-deploy-syslinux.sh index 797836f0..e03e211b 100755 --- a/tests/test-admin-deploy-syslinux.sh +++ b/tests/test-admin-deploy-syslinux.sh @@ -19,7 +19,7 @@ set -euo pipefail -echo "1..18" +echo "1..19" . $(dirname $0)/libtest.sh diff --git a/tests/test-admin-deploy-uboot.sh b/tests/test-admin-deploy-uboot.sh index d9104f8c..5262b48a 100755 --- a/tests/test-admin-deploy-uboot.sh +++ b/tests/test-admin-deploy-uboot.sh @@ -20,7 +20,7 @@ set -euo pipefail -echo "1..19" +echo "1..20" . $(dirname $0)/libtest.sh From 8c148eb7e1d7d5d7317e144b336b64aa39a57215 Mon Sep 17 00:00:00 2001 From: Philip Withnall Date: Tue, 8 Aug 2017 18:58:52 +0100 Subject: [PATCH 43/67] lib/repo-finder: Emit gpg-verify-summary=false in dynamic remote config When returning results from finding repos, set gpg-verify-summary=false in their configs, since any pulls from such remotes will necessarily involve collection IDs, and hence should be using the unsigned summary support. In the intended deployment mode for P2P transmission of OSTree refs, summaries *cannot* be signed, so setting gpg-verify-summary=true would cause all the pulls to fail. The unsigned summary support is the move of repository metadata from the summary file (not spliceable) to the well-known ostree-metadata ref (spliceable, as it can exist for multiple collection IDs in the same repository). Signed-off-by: Philip Withnall Closes: #1066 Approved by: cgwalters --- src/libostree/ostree-repo-finder-avahi.c | 3 ++- src/libostree/ostree-repo-finder-mount.c | 3 ++- src/libostree/ostree-repo-pull.c | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/libostree/ostree-repo-finder-avahi.c b/src/libostree/ostree-repo-finder-avahi.c index a1500567..5ded9636 100644 --- a/src/libostree/ostree-repo-finder-avahi.c +++ b/src/libostree/ostree-repo-finder-avahi.c @@ -824,9 +824,10 @@ ostree_avahi_service_build_repo_finder_result (OstreeAvahiService g_clear_pointer (&remote->keyring, g_free); remote->keyring = g_strdup (repo->keyring); + /* gpg-verify-summary is false since we use the unsigned summary file support. */ g_key_file_set_string (remote->options, remote->group, "url", repo->uri); g_key_file_set_boolean (remote->options, remote->group, "gpg-verify", TRUE); - g_key_file_set_boolean (remote->options, remote->group, "gpg-verify-summary", TRUE); + g_key_file_set_boolean (remote->options, remote->group, "gpg-verify-summary", FALSE); get_checksums (finder, parent_repo, remote, supported_ref_to_checksum, &error); if (error != NULL) diff --git a/src/libostree/ostree-repo-finder-mount.c b/src/libostree/ostree-repo-finder-mount.c index ffe31e99..1eb3d31d 100644 --- a/src/libostree/ostree-repo-finder-mount.c +++ b/src/libostree/ostree-repo-finder-mount.c @@ -392,9 +392,10 @@ ostree_repo_finder_mount_resolve_async (OstreeRepoFinder *finde g_clear_pointer (&remote->keyring, g_free); remote->keyring = g_strdup (repo->keyring); + /* gpg-verify-summary is false since we use the unsigned summary file support. */ g_key_file_set_string (remote->options, remote->group, "url", repo->uri); g_key_file_set_boolean (remote->options, remote->group, "gpg-verify", TRUE); - g_key_file_set_boolean (remote->options, remote->group, "gpg-verify-summary", TRUE); + g_key_file_set_boolean (remote->options, remote->group, "gpg-verify-summary", FALSE); /* Set the timestamp in the #OstreeRepoFinderResult to 0 because * the code in ostree_repo_pull_from_remotes_async() will be able to diff --git a/src/libostree/ostree-repo-pull.c b/src/libostree/ostree-repo-pull.c index 6298a28e..d637d5fd 100644 --- a/src/libostree/ostree-repo-pull.c +++ b/src/libostree/ostree-repo-pull.c @@ -5344,7 +5344,7 @@ ostree_repo_pull_from_remotes_async (OstreeRepo *self, g_variant_dict_insert (&local_options_dict, "flags", "i", OSTREE_REPO_PULL_FLAGS_UNTRUSTED | flags); g_variant_dict_insert_value (&local_options_dict, "collection-refs", g_variant_builder_end (&refs_to_pull_builder)); g_variant_dict_insert (&local_options_dict, "gpg-verify", "b", TRUE); - g_variant_dict_insert (&local_options_dict, "gpg-verify-summary", "b", TRUE); + g_variant_dict_insert (&local_options_dict, "gpg-verify-summary", "b", FALSE); g_variant_dict_insert (&local_options_dict, "inherit-transaction", "b", TRUE); copy_option (&options_dict, &local_options_dict, "depth", G_VARIANT_TYPE ("i")); copy_option (&options_dict, &local_options_dict, "disable-static-deltas", G_VARIANT_TYPE ("b")); From 596fc2967eba43394d4e336a39553cac701cc1c5 Mon Sep 17 00:00:00 2001 From: "Lisa St. John" Date: Tue, 8 Aug 2017 22:10:07 +0100 Subject: [PATCH 44/67] Update introduction.md Added missing "is" in the first sentence. Closes: #1067 Approved by: cgwalters --- docs/manual/introduction.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/manual/introduction.md b/docs/manual/introduction.md index 6cde8ddd..ec449998 100644 --- a/docs/manual/introduction.md +++ b/docs/manual/introduction.md @@ -2,7 +2,7 @@ ## Introduction -OSTree an upgrade system for Linux-based operating systems that +OSTree is an upgrade system for Linux-based operating systems that performs atomic upgrades of complete filesystem trees. It is not a package system; rather, it is intended to complement them. A primary model is composing packages on a server, and then From 8b60f63f58639dfebbc608fae853c29a11ce4177 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Fri, 4 Aug 2017 14:18:14 -0400 Subject: [PATCH 45/67] lib/sysroot-deploy: Port a kernel finding logic to new style Prep for more work here. Closes: #1053 Approved by: jlebon --- src/libostree/ostree-sysroot-deploy.c | 28 ++++++++++----------------- 1 file changed, 10 insertions(+), 18 deletions(-) diff --git a/src/libostree/ostree-sysroot-deploy.c b/src/libostree/ostree-sysroot-deploy.c index d87ba1a0..32078505 100644 --- a/src/libostree/ostree-sysroot-deploy.c +++ b/src/libostree/ostree-sysroot-deploy.c @@ -876,38 +876,33 @@ get_kernel_from_tree (int deployment_dfd, GCancellable *cancellable, GError **error) { - gboolean ret = FALSE; - glnx_fd_close int ret_boot_dfd = -1; - g_auto(GLnxDirFdIterator) dfditer = { 0, }; g_autofree char *ret_kernel_name = NULL; g_autofree char *ret_initramfs_name = NULL; g_autofree char *kernel_checksum = NULL; g_autofree char *initramfs_checksum = NULL; - ret_boot_dfd = glnx_opendirat_with_errno (deployment_dfd, "usr/lib/ostree-boot", TRUE); + glnx_fd_close int ret_boot_dfd = glnx_opendirat_with_errno (deployment_dfd, "usr/lib/ostree-boot", TRUE); if (ret_boot_dfd == -1) { if (errno != ENOENT) - { - glnx_set_prefix_error_from_errno (error, "%s", "openat"); - goto out; - } + return glnx_throw_errno_prefix (error, "%s", "openat(usr/lib/ostree-boot)"); else { if (!glnx_opendirat (deployment_dfd, "boot", TRUE, &ret_boot_dfd, error)) - goto out; + return FALSE; } } + g_auto(GLnxDirFdIterator) dfditer = { 0, }; if (!glnx_dirfd_iterator_init_at (ret_boot_dfd, ".", FALSE, &dfditer, error)) - goto out; + return FALSE; while (TRUE) { struct dirent *dent; if (!glnx_dirfd_iterator_next_dent (&dfditer, &dent, cancellable, error)) - goto out; + return FALSE; if (dent == NULL) break; @@ -941,7 +936,7 @@ get_kernel_from_tree (int deployment_dfd, { g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND, "Failed to find boot/vmlinuz- in tree"); - goto out; + return FALSE; } if (ret_initramfs_name != NULL) @@ -950,17 +945,14 @@ get_kernel_from_tree (int deployment_dfd, { g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND, "Mismatched kernel checksum vs initrd in tree"); - goto out; + return FALSE; } } - *out_boot_dfd = ret_boot_dfd; - ret_boot_dfd = -1; + *out_boot_dfd = glnx_steal_fd (&ret_boot_dfd); *out_kernel_name = g_steal_pointer (&ret_kernel_name); *out_initramfs_name = g_steal_pointer (&ret_initramfs_name); - ret = TRUE; - out: - return ret; + return TRUE; } static gboolean From f1102763dfda1d1acc0352b66cf9f309d28d6b1a Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Fri, 4 Aug 2017 15:58:41 -0400 Subject: [PATCH 46/67] lib/sysroot-deploy: Refactor kernel layout parsing I'd like to move the new canonical kernel directory to `/usr/lib/modules/$kver`, as Fedora has done. The `get_kernel_from_tree()` function now abstracts over parsing the data (src vs destination filenames, as well as checksum) in preparation for adding the new case. In preparation for this, let's change the current test suite to use the *current* directory of `/usr/lib/ostree-boot`, and also add coverage of `/boot`. Closes: #1053 Approved by: jlebon --- src/libostree/ostree-sysroot-deploy.c | 154 +++++++++++++------------- tests/libtest.sh | 39 ++++--- tests/test-admin-deploy-syslinux.sh | 22 +++- tests/test-admin-deploy-uboot.sh | 3 +- 4 files changed, 125 insertions(+), 93 deletions(-) diff --git a/src/libostree/ostree-sysroot-deploy.c b/src/libostree/ostree-sysroot-deploy.c index 32078505..7e72a3ef 100644 --- a/src/libostree/ostree-sysroot-deploy.c +++ b/src/libostree/ostree-sysroot-deploy.c @@ -113,7 +113,7 @@ hardlink_or_copy_at (int src_dfd, sysroot_flags_to_copy_flags (0, flags), cancellable, error); else - return glnx_throw_errno_prefix (error, "linkat"); + return glnx_throw_errno_prefix (error, "linkat(%s)", dest_subpath); } return TRUE; @@ -868,16 +868,29 @@ ostree_sysroot_write_origin_file (OstreeSysroot *sysroot, cancellable, error); } +/* Originally OSTree defined kernels to be found underneath /boot + * in the tree. But that means when mounting /boot at runtime + * we end up masking the content underneath, triggering a warning. + * + * For that reason, and also consistency with the "/usr defines the OS" model we + * later switched to defining the in-tree kernels to be found under + * /usr/lib/ostree-boot. + */ static gboolean get_kernel_from_tree (int deployment_dfd, int *out_boot_dfd, - char **out_kernel_name, - char **out_initramfs_name, + char **out_kernel_srcpath, + char **out_kernel_namever, + char **out_initramfs_srcpath, + char **out_initramfs_namever, + char **out_bootcsum, GCancellable *cancellable, GError **error) { - g_autofree char *ret_kernel_name = NULL; - g_autofree char *ret_initramfs_name = NULL; + g_autofree char *ret_kernel_srcpath = NULL; + g_autofree char *ret_kernel_namever = NULL; + g_autofree char *ret_initramfs_srcpath = NULL; + g_autofree char *ret_initramfs_namever = NULL; g_autofree char *kernel_checksum = NULL; g_autofree char *initramfs_checksum = NULL; @@ -907,67 +920,57 @@ get_kernel_from_tree (int deployment_dfd, if (dent == NULL) break; - if (ret_kernel_name == NULL && g_str_has_prefix (dent->d_name, "vmlinuz-")) + const char *name = dent->d_name; + if (ret_kernel_srcpath == NULL && g_str_has_prefix (name, "vmlinuz-")) { - const char *dash = strrchr (dent->d_name, '-'); + const char *dash = strrchr (name, '-'); g_assert (dash); if (ostree_validate_structureof_checksum_string (dash + 1, NULL)) { kernel_checksum = g_strdup (dash + 1); - ret_kernel_name = g_strdup (dent->d_name); + ret_kernel_srcpath = g_strdup (name); + ret_kernel_namever = g_strndup (name, dash - name); } } - else if (ret_initramfs_name == NULL && g_str_has_prefix (dent->d_name, "initramfs-")) + else if (ret_initramfs_srcpath == NULL && g_str_has_prefix (name, "initramfs-")) { - const char *dash = strrchr (dent->d_name, '-'); + const char *dash = strrchr (name, '-'); g_assert (dash); if (ostree_validate_structureof_checksum_string (dash + 1, NULL)) { initramfs_checksum = g_strdup (dash + 1); - ret_initramfs_name = g_strdup (dent->d_name); + ret_initramfs_srcpath = g_strdup (name); + ret_initramfs_namever = g_strndup (name, dash - name); } } - if (ret_kernel_name != NULL && ret_initramfs_name != NULL) + if (ret_kernel_srcpath != NULL && ret_initramfs_srcpath != NULL) break; } - if (ret_kernel_name == NULL) + if (ret_kernel_srcpath == NULL) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND, - "Failed to find boot/vmlinuz- in tree"); + "Failed to find kernel in /usr/lib/ostree-boot or /boot"); return FALSE; } - if (ret_initramfs_name != NULL) + if (ret_initramfs_srcpath != NULL) { if (strcmp (kernel_checksum, initramfs_checksum) != 0) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND, - "Mismatched kernel checksum vs initrd in tree"); + "Mismatched kernel checksum vs initrd"); return FALSE; } } *out_boot_dfd = glnx_steal_fd (&ret_boot_dfd); - *out_kernel_name = g_steal_pointer (&ret_kernel_name); - *out_initramfs_name = g_steal_pointer (&ret_initramfs_name); - return TRUE; -} - -static gboolean -checksum_from_kernel_src (const char *name, - char **out_checksum, - GError **error) -{ - const char *last_dash = strrchr (name, '-'); - if (!last_dash) - { - return glnx_throw (error, - "Malformed kernel/initramfs name '%s', missing '-'", - name); - } - *out_checksum = g_strdup (last_dash + 1); + *out_kernel_srcpath = g_steal_pointer (&ret_kernel_srcpath); + *out_kernel_namever = g_steal_pointer (&ret_kernel_namever); + *out_initramfs_srcpath = g_steal_pointer (&ret_initramfs_srcpath); + *out_initramfs_namever = g_steal_pointer (&ret_initramfs_namever); + *out_bootcsum = g_steal_pointer (&kernel_checksum); return TRUE; } @@ -1231,15 +1234,6 @@ swap_bootlinks (OstreeSysroot *self, return TRUE; } -static char * -remove_checksum_from_kernel_name (const char *name, - const char *csum) -{ - const char *p = strrchr (name, '-'); - g_assert_cmpstr (p+1, ==, csum); - return g_strndup (name, p-name); -} - static GHashTable * parse_os_release (const char *contents, const char *split) @@ -1293,11 +1287,19 @@ install_deployment_kernel (OstreeSysroot *sysroot, &deployment_dfd, error)) return FALSE; + /* Find the kernel/initramfs in the tree */ glnx_fd_close int tree_boot_dfd = -1; - g_autofree char *tree_kernel_name = NULL; - g_autofree char *tree_initramfs_name = NULL; + g_autofree char *tree_kernel_srcpath = NULL; + g_autofree char *tree_kernel_namever = NULL; + g_autofree char *tree_initramfs_srcpath = NULL; + g_autofree char *tree_initramfs_namever = NULL; + g_autofree char *tree_bootcsum = NULL; if (!get_kernel_from_tree (deployment_dfd, &tree_boot_dfd, - &tree_kernel_name, &tree_initramfs_name, + &tree_kernel_srcpath, + &tree_kernel_namever, + &tree_initramfs_srcpath, + &tree_initramfs_namever, + &tree_bootcsum, cancellable, error)) return FALSE; @@ -1307,6 +1309,7 @@ install_deployment_kernel (OstreeSysroot *sysroot, const char *osname = ostree_deployment_get_osname (deployment); const char *bootcsum = ostree_deployment_get_bootcsum (deployment); + g_assert_cmpstr (bootcsum, ==, tree_bootcsum); g_autofree char *bootcsumdir = g_strdup_printf ("ostree/%s-%s", osname, bootcsum); g_autofree char *bootconfdir = g_strdup_printf ("loader.%d/entries", new_bootversion); g_autofree char *bootconf_name = g_strdup_printf ("ostree-%s-%d.conf", osname, @@ -1321,30 +1324,33 @@ install_deployment_kernel (OstreeSysroot *sysroot, if (!glnx_shutil_mkdir_p_at (boot_dfd, bootconfdir, 0775, cancellable, error)) return FALSE; - g_autofree char *dest_kernel_name = remove_checksum_from_kernel_name (tree_kernel_name, bootcsum); + /* Install (hardlink/copy) the kernel into /boot/ostree/osname-${bootcsum} if + * it doesn't exist already. + */ struct stat stbuf; - if (fstatat (bootcsum_dfd, dest_kernel_name, &stbuf, 0) != 0) + if (fstatat (bootcsum_dfd, tree_kernel_namever, &stbuf, 0) != 0) { if (errno != ENOENT) - return glnx_throw_errno_prefix (error, "fstat %s", dest_kernel_name); - if (!hardlink_or_copy_at (tree_boot_dfd, tree_kernel_name, - bootcsum_dfd, dest_kernel_name, + return glnx_throw_errno_prefix (error, "fstat %s", tree_kernel_namever); + if (!hardlink_or_copy_at (tree_boot_dfd, tree_kernel_srcpath, + bootcsum_dfd, tree_kernel_namever, sysroot->debug_flags, cancellable, error)) return FALSE; } - g_autofree char *dest_initramfs_name = NULL; - if (tree_initramfs_name) + /* If we have an initramfs, then install it into + * /boot/ostree/osname-${bootcsum} if it doesn't exist already. + */ + if (tree_initramfs_srcpath) { - dest_initramfs_name = remove_checksum_from_kernel_name (tree_initramfs_name, bootcsum); - - if (fstatat (bootcsum_dfd, dest_initramfs_name, &stbuf, 0) != 0) + g_assert (tree_initramfs_namever); + if (fstatat (bootcsum_dfd, tree_initramfs_namever, &stbuf, 0) != 0) { if (errno != ENOENT) - return glnx_throw_errno_prefix (error, "fstat %s", dest_initramfs_name); - if (!hardlink_or_copy_at (tree_boot_dfd, tree_initramfs_name, - bootcsum_dfd, dest_initramfs_name, + return glnx_throw_errno_prefix (error, "fstat %s", tree_initramfs_namever); + if (!hardlink_or_copy_at (tree_boot_dfd, tree_initramfs_srcpath, + bootcsum_dfd, tree_initramfs_namever, sysroot->debug_flags, cancellable, error)) return FALSE; @@ -1425,12 +1431,12 @@ install_deployment_kernel (OstreeSysroot *sysroot, g_autofree char *version_key = g_strdup_printf ("%d", n_deployments - ostree_deployment_get_index (deployment)); ostree_bootconfig_parser_set (bootconfig, OSTREE_COMMIT_META_KEY_VERSION, version_key); - g_autofree char * boot_relpath = g_strconcat ("/", bootcsumdir, "/", dest_kernel_name, NULL); + g_autofree char * boot_relpath = g_strconcat ("/", bootcsumdir, "/", tree_kernel_namever, NULL); ostree_bootconfig_parser_set (bootconfig, "linux", boot_relpath); - if (dest_initramfs_name) + if (tree_initramfs_namever) { - g_autofree char * boot_relpath = g_strconcat ("/", bootcsumdir, "/", dest_initramfs_name, NULL); + g_autofree char * boot_relpath = g_strconcat ("/", bootcsumdir, "/", tree_initramfs_namever, NULL); ostree_bootconfig_parser_set (bootconfig, "initrd", boot_relpath); } @@ -2053,24 +2059,20 @@ ostree_sysroot_deploy_tree (OstreeSysroot *self, } glnx_fd_close int tree_boot_dfd = -1; - g_autofree char *tree_kernel_path = NULL; - g_autofree char *tree_initramfs_path = NULL; + g_autofree char *tree_kernel_srcpath = NULL; + g_autofree char *tree_kernel_namever = NULL; + g_autofree char *tree_initramfs_srcpath = NULL; + g_autofree char *tree_initramfs_namever = NULL; + g_autofree char *tree_bootcsum = NULL; if (!get_kernel_from_tree (deployment_dfd, &tree_boot_dfd, - &tree_kernel_path, &tree_initramfs_path, + &tree_kernel_srcpath, + &tree_kernel_namever, + &tree_initramfs_srcpath, + &tree_initramfs_namever, + &new_bootcsum, cancellable, error)) return FALSE; - if (tree_initramfs_path != NULL) - { - if (!checksum_from_kernel_src (tree_initramfs_path, &new_bootcsum, error)) - return FALSE; - } - else - { - if (!checksum_from_kernel_src (tree_kernel_path, &new_bootcsum, error)) - return FALSE; - } - _ostree_deployment_set_bootcsum (new_deployment, new_bootcsum); /* Create an empty boot configuration; we will merge things into diff --git a/tests/libtest.sh b/tests/libtest.sh index 6f33c5b5..ff096505 100755 --- a/tests/libtest.sh +++ b/tests/libtest.sh @@ -363,8 +363,10 @@ setup_os_boot_grub2() { setup_os_repository () { mode=$1 - bootmode=$2 shift + bootmode=$1 + shift + bootdir=${1:-usr/lib/ostree-boot} oldpwd=`pwd` @@ -379,14 +381,19 @@ setup_os_repository () { cd ${test_tmpdir} mkdir osdata cd osdata - mkdir -p boot usr/bin usr/lib/modules/3.6.0 usr/share usr/etc - echo "a kernel" > boot/vmlinuz-3.6.0 - echo "an initramfs" > boot/initramfs-3.6.0 - bootcsum=$(cat boot/vmlinuz-3.6.0 boot/initramfs-3.6.0 | sha256sum | cut -f 1 -d ' ') + mkdir -p usr/bin usr/lib/modules/3.6.0 usr/share usr/etc + mkdir -p ${bootdir} + echo "a kernel" > ${bootdir}/vmlinuz-3.6.0 + echo "an initramfs" > ${bootdir}/initramfs-3.6.0 + bootcsum=$(cat ${bootdir}/vmlinuz-3.6.0 ${bootdir}/initramfs-3.6.0 | sha256sum | cut -f 1 -d ' ') export bootcsum - mv boot/vmlinuz-3.6.0 boot/vmlinuz-3.6.0-${bootcsum} - mv boot/initramfs-3.6.0 boot/initramfs-3.6.0-${bootcsum} - + # Add the checksum for legacy dirs (/boot, /usr/lib/ostree-boot), but not + # /usr/lib/modules. + if [[ $bootdir != usr/lib/modules ]]; then + mv ${bootdir}/vmlinuz-3.6.0{,-${bootcsum}} + mv ${bootdir}/initramfs-3.6.0{,-${bootcsum}} + fi + echo "an executable" > usr/bin/sh echo "some shared data" > usr/share/langs.txt echo "a library" > usr/lib/libfoo.so.0 @@ -458,13 +465,17 @@ os_repository_new_commit () branch=${3:-testos/buildmaster/x86_64-runtime} echo "BOOT ITERATION: $boot_checksum_iteration" cd ${test_tmpdir}/osdata - rm boot/* - echo "new: a kernel ${boot_checksum_iteration}" > boot/vmlinuz-3.6.0 - echo "new: an initramfs ${boot_checksum_iteration}" > boot/initramfs-3.6.0 - bootcsum=$(cat boot/vmlinuz-3.6.0 boot/initramfs-3.6.0 | sha256sum | cut -f 1 -d ' ') + bootdir=usr/lib/ostree-boot + if ! test -d ${bootdir}; then + bootdir=boot + fi + rm ${bootdir}/* + echo "new: a kernel ${boot_checksum_iteration}" > ${bootdir}/vmlinuz-3.6.0 + echo "new: an initramfs ${boot_checksum_iteration}" > ${bootdir}/initramfs-3.6.0 + bootcsum=$(cat ${bootdir}/vmlinuz-3.6.0 ${bootdir}/initramfs-3.6.0 | sha256sum | cut -f 1 -d ' ') export bootcsum - mv boot/vmlinuz-3.6.0 boot/vmlinuz-3.6.0-${bootcsum} - mv boot/initramfs-3.6.0 boot/initramfs-3.6.0-${bootcsum} + mv ${bootdir}/vmlinuz-3.6.0 ${bootdir}/vmlinuz-3.6.0-${bootcsum} + mv ${bootdir}/initramfs-3.6.0 ${bootdir}/initramfs-3.6.0-${bootcsum} echo "a new default config file" > usr/etc/a-new-default-config-file mkdir -p usr/etc/new-default-dir diff --git a/tests/test-admin-deploy-syslinux.sh b/tests/test-admin-deploy-syslinux.sh index e03e211b..b19a74f0 100755 --- a/tests/test-admin-deploy-syslinux.sh +++ b/tests/test-admin-deploy-syslinux.sh @@ -19,7 +19,7 @@ set -euo pipefail -echo "1..19" +echo "1..20" . $(dirname $0)/libtest.sh @@ -27,3 +27,23 @@ echo "1..19" setup_os_repository "archive-z2" "syslinux" . $(dirname $0)/admin-test.sh + +cd ${test_tmpdir} +rm httpd osdata testos-repo sysroot -rf +setup_os_repository "archive-z2" "syslinux" "boot" + +${CMD_PREFIX} ostree --repo=sysroot/ostree/repo pull-local --remote=testos testos-repo testos/buildmaster/x86_64-runtime +rev=$(${CMD_PREFIX} ostree --repo=sysroot/ostree/repo rev-parse testos/buildmaster/x86_64-runtime) +${CMD_PREFIX} ostree admin deploy --karg=root=LABEL=MOO --karg=quiet --os=testos testos:testos/buildmaster/x86_64-runtime +assert_file_has_content sysroot/boot/loader/entries/ostree-testos-0.conf 'options.* root=LABEL=MOO' +assert_file_has_content sysroot/boot/loader/entries/ostree-testos-0.conf 'options.* quiet' +assert_file_has_content sysroot/boot/ostree/testos-${bootcsum}/vmlinuz-3.6.0 'a kernel' +assert_file_has_content sysroot/boot/ostree/testos-${bootcsum}/initramfs-3.6.0 'an initramfs' +# kernel/initrams should also be in the tree's /boot with the checksum +assert_file_has_content sysroot/ostree/deploy/testos/deploy/${rev}.0/boot/vmlinuz-3.6.0-${bootcsum} 'a kernel' +assert_file_has_content sysroot/ostree/deploy/testos/deploy/${rev}.0/boot/initramfs-3.6.0-${bootcsum} 'an initramfs' +assert_file_has_content sysroot/ostree/deploy/testos/deploy/${rev}.0/etc/os-release 'NAME=TestOS' +assert_file_has_content sysroot/ostree/boot.1/testos/${bootcsum}/0/etc/os-release 'NAME=TestOS' +${CMD_PREFIX} ostree admin status +validate_bootloader +echo "ok kernel in tree's /boot" diff --git a/tests/test-admin-deploy-uboot.sh b/tests/test-admin-deploy-uboot.sh index 5262b48a..3685e31e 100755 --- a/tests/test-admin-deploy-uboot.sh +++ b/tests/test-admin-deploy-uboot.sh @@ -30,8 +30,7 @@ setup_os_repository "archive-z2" "uboot" . $(dirname $0)/admin-test.sh cd ${test_tmpdir} -ln -s ../../boot/ osdata/usr/lib/ostree-boot -cat << 'EOF' > osdata/boot/uEnv.txt +cat << 'EOF' > osdata/usr/lib/ostree-boot/uEnv.txt loaduimage=load mmc ${bootpart} ${loadaddr} ${kernel_image} loadfdt=load mmc ${bootpart} ${fdtaddr} ${bootdir}${fdtfile} loadramdisk=load mmc ${bootpart} ${rdaddr} ${ramdisk_image} From 75bce24cb9417f9b8111ed689d3d9c2f4bec154f Mon Sep 17 00:00:00 2001 From: Philip Withnall Date: Wed, 9 Aug 2017 14:35:53 +0100 Subject: [PATCH 47/67] lib/gpg-verify: Add an OstreeGpgError error domain Add a new error domain for GPG signing/verification errors, and use it throughout libostree for describing verification errors. This replaces various uses of G_IO_ERROR_FAILED, and one instance of G_IO_ERROR_NOT_FOUND (for which some code in ot-builtin-show.c had to be changed to ensure it was still handled correctly). The use of a separate error domain allows failures in GPG operations to be handled separately from network failures (where the summary file could not be found to be downloaded, for example) or timeouts. Signed-off-by: Philip Withnall Closes: #1064 Closes: #1071 Approved by: mbarnes --- apidoc/ostree-sections.txt | 3 +++ src/libostree/libostree-devel.sym | 1 + src/libostree/ostree-gpg-verify-result.c | 7 +++++-- src/libostree/ostree-gpg-verify-result.h | 21 +++++++++++++++++++++ src/libostree/ostree-repo-pull.c | 12 ++++++------ src/libostree/ostree-repo.c | 4 ++-- src/ostree/ot-builtin-show.c | 2 +- 7 files changed, 39 insertions(+), 11 deletions(-) diff --git a/apidoc/ostree-sections.txt b/apidoc/ostree-sections.txt index 43e267f6..df9767d4 100644 --- a/apidoc/ostree-sections.txt +++ b/apidoc/ostree-sections.txt @@ -194,6 +194,7 @@ ostree_diff_item_get_type
ostree-gpg-verify-result +OstreeGpgError OstreeGpgVerifyResult OstreeGpgSignatureAttr ostree_gpg_verify_result_count_all @@ -210,6 +211,8 @@ OSTREE_GPG_VERIFY_RESULT OSTREE_IS_GPG_VERIFY_RESULT OSTREE_TYPE_GPG_VERIFY_RESULT ostree_gpg_verify_result_get_type +OSTREE_GPG_ERROR +ostree_gpg_error_quark
ostree-lzma-compressor diff --git a/src/libostree/libostree-devel.sym b/src/libostree/libostree-devel.sym index d4ee86bf..49111b4a 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_2017.10 { + ostree_gpg_error_quark; ostree_repo_set_alias_ref_immediate; }; diff --git a/src/libostree/ostree-gpg-verify-result.c b/src/libostree/ostree-gpg-verify-result.c index a8ada775..f6689e63 100644 --- a/src/libostree/ostree-gpg-verify-result.c +++ b/src/libostree/ostree-gpg-verify-result.c @@ -682,9 +682,12 @@ ostree_gpg_verify_result_require_valid_signature (OstreeGpgVerifyResult *result, if (ostree_gpg_verify_result_count_valid (result) == 0) { - return glnx_throw (error, "%s", - "GPG signatures found, but none are in trusted keyring"); + g_set_error (error, OSTREE_GPG_ERROR, OSTREE_GPG_ERROR_MISSING_KEY, + "GPG signatures found, but none are in trusted keyring"); + return FALSE; } return TRUE; } + +G_DEFINE_QUARK (OstreeGpgError, ostree_gpg_error) diff --git a/src/libostree/ostree-gpg-verify-result.h b/src/libostree/ostree-gpg-verify-result.h index f9512538..f5fadd59 100644 --- a/src/libostree/ostree-gpg-verify-result.h +++ b/src/libostree/ostree-gpg-verify-result.h @@ -137,4 +137,25 @@ _OSTREE_PUBLIC gboolean ostree_gpg_verify_result_require_valid_signature (OstreeGpgVerifyResult *result, GError **error); +/** + * OstreeGpgError: + * @OSTREE_GPG_ERROR_NO_SIGNATURE: A signature was expected, but not found. + * @OSTREE_GPG_ERROR_INVALID_SIGNATURE: A signature was malformed. + * @OSTREE_GPG_ERROR_MISSING_KEY: A signature was found, but was created with a key not in the configured keyrings. + * + * Errors returned by signature creation and verification operations in OSTree. + * These may be returned by any API which creates or verifies signatures. + * + * Since: 2017.10 + */ +typedef enum { + OSTREE_GPG_ERROR_NO_SIGNATURE = 0, + OSTREE_GPG_ERROR_INVALID_SIGNATURE, + OSTREE_GPG_ERROR_MISSING_KEY, +} OstreeGpgError; + +_OSTREE_PUBLIC +GQuark ostree_gpg_error_quark (void); +#define OSTREE_GPG_ERROR (ostree_gpg_error_quark ()) + G_END_DECLS diff --git a/src/libostree/ostree-repo-pull.c b/src/libostree/ostree-repo-pull.c index d637d5fd..b53e0729 100644 --- a/src/libostree/ostree-repo-pull.c +++ b/src/libostree/ostree-repo-pull.c @@ -1423,7 +1423,7 @@ gpg_verify_unwritten_commit (OtPullData *pull_data, if (!detached_metadata) { - g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + g_set_error (error, OSTREE_GPG_ERROR, OSTREE_GPG_ERROR_NO_SIGNATURE, "Commit %s: no detached metadata found for GPG verification", checksum); return FALSE; @@ -2463,7 +2463,7 @@ on_superblock_fetched (GObject *src, */ if (pull_data->gpg_verify_summary && !summary_csum) { - g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + g_set_error (error, OSTREE_GPG_ERROR, OSTREE_GPG_ERROR_NO_SIGNATURE, "GPG verification enabled, but no summary signatures found (use gpg-verify-summary=false in remote config to disable)"); goto out; } @@ -3653,21 +3653,21 @@ ostree_repo_pull_with_options (OstreeRepo *self, if (!bytes_summary && pull_data->gpg_verify_summary) { - g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND, "GPG verification enabled, but no summary found (use gpg-verify-summary=false in remote config to disable)"); goto out; } if (!bytes_summary && pull_data->require_static_deltas) { - g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND, "Fetch configured to require static deltas, but no summary found"); goto out; } if (!bytes_sig && pull_data->gpg_verify_summary) { - g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + g_set_error (error, OSTREE_GPG_ERROR, OSTREE_GPG_ERROR_NO_SIGNATURE, "GPG verification enabled, but no summary.sig found (use gpg-verify-summary=false in remote config to disable)"); goto out; } @@ -5612,7 +5612,7 @@ ostree_repo_remote_fetch_summary_with_options (OstreeRepo *self, if (gpg_verify_summary && signatures == NULL) { - g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + g_set_error (error, OSTREE_GPG_ERROR, OSTREE_GPG_ERROR_NO_SIGNATURE, "GPG verification enabled, but no summary signatures found (use gpg-verify-summary=false in remote config to disable)"); goto out; } diff --git a/src/libostree/ostree-repo.c b/src/libostree/ostree-repo.c index 7b787760..df019dd6 100644 --- a/src/libostree/ostree-repo.c +++ b/src/libostree/ostree-repo.c @@ -4089,7 +4089,7 @@ ostree_repo_sign_commit (OstreeRepo *self, if (!result) { /* "Not found" just means the commit is not yet signed. That's okay. */ - if (g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND)) + if (g_error_matches (local_error, OSTREE_GPG_ERROR, OSTREE_GPG_ERROR_NO_SIGNATURE)) { g_clear_error (&local_error); } @@ -4351,7 +4351,7 @@ _ostree_repo_gpg_verify_with_metadata (OstreeRepo *self, _OSTREE_METADATA_GPGSIGS_TYPE); if (!signaturedata) { - g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND, + g_set_error_literal (error, OSTREE_GPG_ERROR, OSTREE_GPG_ERROR_NO_SIGNATURE, "GPG verification enabled, but no signatures found (use gpg-verify=false in remote config to disable)"); return NULL; } diff --git a/src/ostree/ot-builtin-show.c b/src/ostree/ot-builtin-show.c index 0c57637b..4a510a99 100644 --- a/src/ostree/ot-builtin-show.c +++ b/src/ostree/ot-builtin-show.c @@ -163,7 +163,7 @@ print_object (OstreeRepo *repo, &local_error); } - if (g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND)) + if (g_error_matches (local_error, OSTREE_GPG_ERROR, OSTREE_GPG_ERROR_NO_SIGNATURE)) { /* Ignore */ } From de153dea30ba8bb28a5dfafe9d0995224766df60 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Thu, 3 Aug 2017 21:45:50 -0400 Subject: [PATCH 48/67] lib/sysroot: Add journal-msg signal This will allow us to drop the awful hack in rpm-ostree where we watch our own stdout. In general, libraries shouldn't write to stdout. Also we can kill the systemd journal wrapper code. There's some duplication at each call site now...but it's easier than trying to write a `sd_journal_send()` wrapper. I was originally going to have this emit all of the structured data too as a `GVariant` but decided it wasn't worth it right now. Closes: #1052 Approved by: jlebon --- Makefile-otutil.am | 2 - src/libostree/ostree-sysroot-deploy.c | 37 ++++-- src/libostree/ostree-sysroot-private.h | 4 + src/libostree/ostree-sysroot.c | 38 ++++++ src/libotutil/ot-log-utils.c | 163 ------------------------- src/libotutil/ot-log-utils.h | 33 ----- src/libotutil/otutil.h | 1 - src/ostree/ot-main.c | 8 ++ 8 files changed, 75 insertions(+), 211 deletions(-) delete mode 100644 src/libotutil/ot-log-utils.c delete mode 100644 src/libotutil/ot-log-utils.h diff --git a/Makefile-otutil.am b/Makefile-otutil.am index db632705..ff7533e9 100644 --- a/Makefile-otutil.am +++ b/Makefile-otutil.am @@ -36,8 +36,6 @@ libotutil_la_SOURCES = \ src/libotutil/ot-variant-utils.h \ src/libotutil/ot-gio-utils.c \ src/libotutil/ot-gio-utils.h \ - src/libotutil/ot-log-utils.c \ - src/libotutil/ot-log-utils.h \ src/libotutil/ot-gpg-utils.c \ src/libotutil/ot-gpg-utils.h \ src/libotutil/otutil.c \ diff --git a/src/libostree/ostree-sysroot-deploy.c b/src/libostree/ostree-sysroot-deploy.c index 7e72a3ef..622f9975 100644 --- a/src/libostree/ostree-sysroot-deploy.c +++ b/src/libostree/ostree-sysroot-deploy.c @@ -47,9 +47,9 @@ #include "ostree-linuxfsutil.h" #include "libglnx.h" -#define OSTREE_VARRELABEL_ID "da679b08acd34504b789d96f818ea781" -#define OSTREE_CONFIGMERGE_ID "d3863baec13e4449ab0384684a8af3a7" #ifdef HAVE_LIBSYSTEMD +#define OSTREE_VARRELABEL_ID SD_ID128_MAKE(da,67,9b,08,ac,d3,45,04,b7,89,d9,6f,81,8e,a7,81) +#define OSTREE_CONFIGMERGE_ID SD_ID128_MAKE(d3,86,3b,ae,c1,3e,44,49,ab,03,84,68,4a,8a,f3,a7) #define OSTREE_DEPLOYMENT_COMPLETE_ID SD_ID128_MAKE(dd,44,0e,3e,54,90,83,b6,3d,0e,fc,7d,c1,52,55,f1) #endif @@ -429,11 +429,19 @@ merge_configuration_from (OstreeSysroot *sysroot, cancellable, error)) return glnx_prefix_error (error, "While computing configuration diff"); - ot_log_structured_print_id_v (OSTREE_CONFIGMERGE_ID, - "Copying /etc changes: %u modified, %u removed, %u added", - modified->len, - removed->len, - added->len); + { g_autofree char *msg = + g_strdup_printf ("Copying /etc changes: %u modified, %u removed, %u added", + modified->len, removed->len, added->len); +#ifdef HAVE_LIBSYSTEMD + sd_journal_send ("MESSAGE_ID=" SD_ID128_FORMAT_STR, SD_ID128_FORMAT_VAL(OSTREE_CONFIGMERGE_ID), + "MESSAGE=%s", msg, + "ETC_N_MODIFIED=%u", modified->len, + "ETC_N_REMOVED=%u", removed->len, + "ETC_N_ADDED=%u", added->len, + NULL); +#endif + _ostree_sysroot_emit_journal_msg (sysroot, msg); + } glnx_fd_close int orig_etc_fd = -1; if (!glnx_opendirat (merge_deployment_dfd, "usr/etc", TRUE, &orig_etc_fd, error)) @@ -688,9 +696,15 @@ selinux_relabel_var_if_needed (OstreeSysroot *sysroot, if (!deployment_var_labeled) { - ot_log_structured_print_id_v (OSTREE_VARRELABEL_ID, - "Relabeling /var (no stamp file '%s' found)", - selabeled); + { g_autofree char *msg = + g_strdup_printf ("Relabeling /var (no stamp file '%s' found)", selabeled); +#ifdef HAVE_LIBSYSTEMD + sd_journal_send ("MESSAGE_ID=" SD_ID128_FORMAT_STR, SD_ID128_FORMAT_VAL(OSTREE_VARRELABEL_ID), + "MESSAGE=%s", msg, + NULL); +#endif + _ostree_sysroot_emit_journal_msg (sysroot, msg); + } g_autoptr(GFile) deployment_var_path = ot_fdrel_to_gfile (os_deploy_dfd, "var"); if (!selinux_relabel_dir (sysroot, sepolicy, @@ -1917,8 +1931,7 @@ ostree_sysroot_write_deployments_with_options (OstreeSysroot *self, "OSTREE_SYNCFS_EXTRA_MSEC=%" G_GUINT64_FORMAT, syncstats.extra_syncfs_msec, NULL); #endif - if (!ot_stdout_is_journal ()) - g_print ("%s\n", msg); + _ostree_sysroot_emit_journal_msg (self, msg); } if (!_ostree_sysroot_bump_mtime (self, error)) diff --git a/src/libostree/ostree-sysroot-private.h b/src/libostree/ostree-sysroot-private.h index 07c4bf6e..4c6cb328 100644 --- a/src/libostree/ostree-sysroot-private.h +++ b/src/libostree/ostree-sysroot-private.h @@ -69,6 +69,10 @@ struct OstreeSysroot { #define _OSTREE_SYSROOT_DEPLOYMENT_RUNSTATE_DIR "/run/ostree/deployment-state/" #define _OSTREE_SYSROOT_DEPLOYMENT_RUNSTATE_FLAG_DEVELOPMENT "unlocked-development" +void +_ostree_sysroot_emit_journal_msg (OstreeSysroot *self, + const char *msg); + gboolean _ostree_sysroot_read_boot_loader_configs (OstreeSysroot *self, int bootversion, diff --git a/src/libostree/ostree-sysroot.c b/src/libostree/ostree-sysroot.c index 20539e4d..5bdfe116 100644 --- a/src/libostree/ostree-sysroot.c +++ b/src/libostree/ostree-sysroot.c @@ -58,8 +58,18 @@ find_booted_deployment (OstreeSysroot *self, */ typedef struct { GObjectClass parent_class; + + /* Signals */ + void (*journal_msg) (OstreeSysroot *sysroot, + const char *msg); } OstreeSysrootClass; +enum { + JOURNAL_MSG_SIGNAL, + LAST_SIGNAL, +}; +static guint signals[LAST_SIGNAL] = { 0 }; + enum { PROP_0, @@ -159,6 +169,27 @@ ostree_sysroot_class_init (OstreeSysrootClass *klass) "", G_TYPE_FILE, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + + /** + * OstreeSysroot::journal-msg: + * @self: Self + * @msg: Human-readable string (should not contain newlines) + * + * libostree will log to the journal various events, such as the /etc merge + * status, and transaction completion. Connect to this signal to also + * synchronously receive the text for those messages. This is intended to be + * used by command line tools which link to libostree as a library. + * + * Currently, the structured data is only available via the systemd journal. + * + * Since: 2017.10 + */ + signals[JOURNAL_MSG_SIGNAL] = + g_signal_new ("journal-msg", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (OstreeSysrootClass, journal_msg), + NULL, NULL, NULL, G_TYPE_NONE, 1, G_TYPE_STRING); } static void @@ -319,6 +350,13 @@ ostree_sysroot_ensure_initialized (OstreeSysroot *self, return TRUE; } +void +_ostree_sysroot_emit_journal_msg (OstreeSysroot *self, + const char *msg) +{ + g_signal_emit (self, signals[JOURNAL_MSG_SIGNAL], 0, msg); +} + gboolean _ostree_sysroot_parse_deploy_path_name (const char *name, char **out_csum, diff --git a/src/libotutil/ot-log-utils.c b/src/libotutil/ot-log-utils.c deleted file mode 100644 index c8a3bda7..00000000 --- a/src/libotutil/ot-log-utils.c +++ /dev/null @@ -1,163 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- - * - * Copyright (C) 2016 Colin Walters - * - * 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. - * - * Author: Colin Walters - */ - -#include "config.h" - -#include - -#include - -#include "otutil.h" -#include "libglnx.h" - -#ifdef HAVE_LIBSYSTEMD -#define SD_JOURNAL_SUPPRESS_LOCATION -#include -#endif -#include - -/** - * ot_log_structured: - * @message: Text message to send - * @keys: (allow-none) (array zero-terminated=1) (element-type utf8): Optional structured data - * - * Log structured data in an operating-system specific fashion. The - * parameter @opts should be an array of UTF-8 KEY=VALUE strings. - * This function does not support binary data. See - * http://www.freedesktop.org/software/systemd/man/systemd.journal-fields.html - * for more information about fields that can be used on a systemd - * system. - */ -static void -ot_log_structured (const char *message, - const char *const *keys) -{ -#ifdef HAVE_LIBSYSTEMD - const char *const*iter; - g_autofree char *msgkey = NULL; - guint i, n_opts; - struct iovec *iovs; - - for (n_opts = 0, iter = keys; *iter; iter++, n_opts++) - ; - - n_opts++; /* Add one for MESSAGE= */ - iovs = g_alloca (sizeof (struct iovec) * n_opts); - - for (i = 0, iter = keys; *iter; iter++, i++) { - iovs[i].iov_base = (char*)keys[i]; - iovs[i].iov_len = strlen (keys[i]); - } - g_assert(i == n_opts-1); - msgkey = g_strconcat ("MESSAGE=", message, NULL); - iovs[i].iov_base = msgkey; - iovs[i].iov_len = strlen (msgkey); - - // The code location isn't useful since we're wrapping - sd_journal_sendv (iovs, n_opts); -#else - g_print ("%s\n", message); -#endif -} - -/** - * ot_stdout_is_journal: - * - * Use this function when you want your code to behave differently - * depeneding on whether your program was started as a systemd unit, - * or e.g. interactively at a terminal. - * - * Returns: %TRUE if stdout is (probably) connnected to the systemd journal - */ -gboolean -ot_stdout_is_journal (void) -{ - static gsize initialized; - static gboolean stdout_is_socket; - - if (g_once_init_enter (&initialized)) - { - guint64 pid = (guint64) getpid (); - g_autofree char *fdpath = g_strdup_printf ("/proc/%" G_GUINT64_FORMAT "/fd/1", pid); - char buf[1024]; - ssize_t bytes_read; - - if ((bytes_read = readlink (fdpath, buf, sizeof(buf) - 1)) != -1) - { - buf[bytes_read] = '\0'; - stdout_is_socket = g_str_has_prefix (buf, "socket:"); - } - else - stdout_is_socket = FALSE; - - g_once_init_leave (&initialized, TRUE); - } - - return stdout_is_socket; -} - -/** - * gs_log_structured_print: - * @message: A message to log - * @keys: (allow-none) (array zero-terminated=1) (element-type utf8): Optional structured data - * - * Like gs_log_structured(), but also print to standard output (if it - * is not already connected to the system log). - */ -static void -ot_log_structured_print (const char *message, - const char *const *keys) -{ - ot_log_structured (message, keys); - -#ifdef HAVE_LIBSYSTEMD - if (!ot_stdout_is_journal ()) - g_print ("%s\n", message); -#endif -} - -/** - * ot_log_structured_print_id_v: - * @message_id: A unique MESSAGE_ID - * @format: A format string - * - * The provided @message_id is a unique MESSAGE_ID (see for more information). - * - * This function otherwise acts as ot_log_structured_print(), taking - * @format as a format string. - */ -void -ot_log_structured_print_id_v (const char *message_id, - const char *format, - ...) -{ - const char *key0 = glnx_strjoina ("MESSAGE_ID=", message_id); - const char *keys[] = { key0, NULL }; - g_autofree char *msg = NULL; - va_list args; - - va_start (args, format); - msg = g_strdup_vprintf (format, args); - va_end (args); - - ot_log_structured_print (msg, (const char *const *)keys); -} diff --git a/src/libotutil/ot-log-utils.h b/src/libotutil/ot-log-utils.h deleted file mode 100644 index 4433ee16..00000000 --- a/src/libotutil/ot-log-utils.h +++ /dev/null @@ -1,33 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- - * - * Copyright (C) 2016 Colin Walters . - * - * 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. - */ - -#pragma once - -#include "ot-unix-utils.h" - -G_BEGIN_DECLS - -gboolean ot_stdout_is_journal (void); - -void ot_log_structured_print_id_v (const char *message_id, - const char *format, - ...) G_GNUC_PRINTF(2, 3); - -G_END_DECLS diff --git a/src/libotutil/otutil.h b/src/libotutil/otutil.h index dfe951d0..0647515c 100644 --- a/src/libotutil/otutil.h +++ b/src/libotutil/otutil.h @@ -51,7 +51,6 @@ #include #include #include -#include #include void ot_ptrarray_add_many (GPtrArray *a, ...) G_GNUC_NULL_TERMINATED; diff --git a/src/ostree/ot-main.c b/src/ostree/ot-main.c index 5b6e301d..81d10b98 100644 --- a/src/ostree/ot-main.c +++ b/src/ostree/ot-main.c @@ -358,6 +358,13 @@ ostree_option_context_parse (GOptionContext *context, return TRUE; } +static void +on_sysroot_journal_msg (OstreeSysroot *sysroot, + const char *msg) +{ + g_print ("%s\n", msg); +} + gboolean ostree_admin_option_context_parse (GOptionContext *context, const GOptionEntry *main_entries, @@ -381,6 +388,7 @@ ostree_admin_option_context_parse (GOptionContext *context, sysroot_path = g_file_new_for_path (opt_sysroot); g_autoptr(OstreeSysroot) sysroot = ostree_sysroot_new (sysroot_path); + g_signal_connect (sysroot, "journal-msg", G_CALLBACK (on_sysroot_journal_msg), NULL); if (flags & OSTREE_ADMIN_BUILTIN_FLAG_SUPERUSER) { From 6c7a6519dd7bb15a5d37fe99940e06e6e8eb710d Mon Sep 17 00:00:00 2001 From: Matthew Leeds Date: Tue, 8 Aug 2017 14:55:23 -0700 Subject: [PATCH 49/67] man: Update ostree-refs manpage Update the ostree-refs manpage to document recently added options, and fix some minor mistakes. Closes: #1068 Approved by: cgwalters --- man/ostree-refs.xml | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/man/ostree-refs.xml b/man/ostree-refs.xml index 726a94ac..26a3203d 100644 --- a/man/ostree-refs.xml +++ b/man/ostree-refs.xml @@ -51,13 +51,17 @@ Boston, MA 02111-1307, USA. ostree refs OPTIONS PREFIX + + ostree refs EXISTING --create=NEWREF + Description - Lists all refs available on the host. If specified, PREFIX assigns the refspec prefix; default prefix is null, which lists all refs. + Lists all refs available on the host. If specified, PREFIX assigns the refspec prefix; default + prefix is null, which lists all refs. This command can also be used to create or delete refs. @@ -75,6 +79,16 @@ Boston, MA 02111-1307, USA. printed in full, rather than truncated. + + + =NEWREF + + + Create a ref pointing to the commit EXISTING. NEWREF must not already exist, and EXISTING + must be an existing commit. More than one ref can point to the same commit. + + + @@ -85,7 +99,15 @@ Boston, MA 02111-1307, USA. - + , + + + If used with , create an alias. Otherwise just list aliases. + + + + + , Enable interactions with refs using the combination of their @@ -99,8 +121,7 @@ Boston, MA 02111-1307, USA. is created. (This is an abuse of the refspec syntax.) When deleting refs, all refs whose collection ID equals - the value of the argument are - deleted. + PREFIX are deleted. From 95c832b4e22dab7a26d815ee8e94e04f733bd66d Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Wed, 9 Aug 2017 09:07:11 -0400 Subject: [PATCH 50/67] lib/deploy: Close test suite race condition Saw this in a PR result; we need to wait for the child to have written its result to stderr before we exit, otherwise the test suite may not read it in time. Closes: #1070 Approved by: jlebon --- src/libostree/ostree-sysroot-deploy.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/libostree/ostree-sysroot-deploy.c b/src/libostree/ostree-sysroot-deploy.c index 622f9975..18624640 100644 --- a/src/libostree/ostree-sysroot-deploy.c +++ b/src/libostree/ostree-sysroot-deploy.c @@ -1083,7 +1083,12 @@ fsfreeze_thaw_cycle (OstreeSysroot *self, return glnx_throw_errno_prefix (error, "write(watchdog start)"); /* Testing infrastructure */ if (debug_fifreeze) - return glnx_throw (error, "aborting due to test-fifreeze"); + { + int wstatus; + /* Ensure the child has written its data */ + (void) TEMP_FAILURE_RETRY (waitpid (pid, &wstatus, 0)); + return glnx_throw (error, "aborting due to test-fifreeze"); + } /* Do a freeze/thaw cycle; TODO add a FIFREEZETHAW ioctl */ if (ioctl (rootfs_dfd, FIFREEZE, 0) != 0) { From d3a5d26176c88903f47a21f31b4154abd7631694 Mon Sep 17 00:00:00 2001 From: Jonathan Lebon Date: Thu, 10 Aug 2017 09:05:15 -0400 Subject: [PATCH 51/67] man: document configured branches Closes: #1072 Closes: #1073 Approved by: guyshapiro --- man/ostree-pull.xml | 2 +- man/ostree-remote.xml | 7 +++++++ man/ostree.repo-config.xml | 7 +++++++ 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/man/ostree-pull.xml b/man/ostree-pull.xml index dd901aa2..d7831850 100644 --- a/man/ostree-pull.xml +++ b/man/ostree-pull.xml @@ -132,7 +132,7 @@ Boston, MA 02111-1307, USA. This command can retrieve just a specific commit, or go all the way to performing a full mirror of the remote repository. If no BRANCH is specified, - all branches are retrieved. + all configured branches are retrieved. diff --git a/man/ostree-remote.xml b/man/ostree-remote.xml index 2bb8aa71..bf41a10c 100644 --- a/man/ostree-remote.xml +++ b/man/ostree-remote.xml @@ -96,6 +96,13 @@ Boston, MA 02111-1307, USA. Changes remote repository configurations. The NAME refers to the name of the remote. + + The BRANCH arguments to the + add subcommand specifies the configured branches + for the remote. See the branches section in + ostree.repo-config5 + for more information. + The gpg-import subcommand can associate GPG keys to a specific remote repository for use when pulling signed commits from that repository (if GPG verification is enabled). diff --git a/man/ostree.repo-config.xml b/man/ostree.repo-config.xml index 90d0f3dc..cf0bf7c0 100644 --- a/man/ostree.repo-config.xml +++ b/man/ostree.repo-config.xml @@ -147,6 +147,13 @@ Boston, MA 02111-1307, USA. metadata: summary, static delta "superblocks". + + branches + A list of strings. Represents the default configured + branches to fetch from the remote when no specific branches are + requested during a pull operation. + + proxy A string value, if given should be a URL for a From 2522db016456fbb0c83a9b26e8e73c11d7471aec Mon Sep 17 00:00:00 2001 From: Philip Withnall Date: Fri, 11 Aug 2017 10:14:58 +0100 Subject: [PATCH 52/67] lib/repo-finder-config: Add some more debug output This makes diagnosing false negatives a little easier. Signed-off-by: Philip Withnall Closes: #1075 Approved by: jlebon --- src/libostree/ostree-repo-finder-config.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/libostree/ostree-repo-finder-config.c b/src/libostree/ostree-repo-finder-config.c index 2f9841db..ada8479e 100644 --- a/src/libostree/ostree-repo-finder-config.c +++ b/src/libostree/ostree-repo-finder-config.c @@ -114,6 +114,7 @@ ostree_repo_finder_config_resolve_async (OstreeRepoFinder *find g_autoptr(GHashTable) remote_refs = NULL; /* (element-type OstreeCollectionRef utf8) */ const gchar *checksum; g_autofree gchar *remote_collection_id = NULL; + gboolean resolved_a_ref = FALSE; remote_name = remotes[i]; @@ -147,6 +148,7 @@ ostree_repo_finder_config_resolve_async (OstreeRepoFinder *find * @supported_ref_to_checksum. */ g_debug ("Resolved ref (%s, %s) to remote ‘%s’.", refs[j]->collection_id, refs[j]->ref_name, remote_name); + resolved_a_ref = TRUE; supported_ref_to_checksum = g_hash_table_lookup (repo_name_to_refs, remote_name); @@ -162,6 +164,9 @@ ostree_repo_finder_config_resolve_async (OstreeRepoFinder *find (gpointer) refs[j], g_strdup (checksum)); } } + + if (!resolved_a_ref) + g_debug ("Ignoring remote ‘%s’ due to it not advertising any of the requested refs.", remote_name); } /* Aggregate the results. */ From 64b7c420255e71dacc0549e0f9f20cfda2b2d524 Mon Sep 17 00:00:00 2001 From: Jonathan Lebon Date: Fri, 11 Aug 2017 10:16:17 -0400 Subject: [PATCH 53/67] pull: mark commits from local cache as partial If one of the localcache repos has the exact same commit we resolved from the remote, then we need to make sure to mark it as partial so that we download the full tree. Closes: #1074 Closes: #1076 Approved by: cgwalters --- man/ostree-pull.xml | 2 +- src/libostree/ostree-repo-pull.c | 7 +++++++ tests/test-pull-localcache.sh | 36 +++++++++++++++++++++++++------- 3 files changed, 36 insertions(+), 9 deletions(-) diff --git a/man/ostree-pull.xml b/man/ostree-pull.xml index d7831850..59a6dbc8 100644 --- a/man/ostree-pull.xml +++ b/man/ostree-pull.xml @@ -78,7 +78,7 @@ Boston, MA 02111-1307, USA. Like git's clone --reference. Reuse the provided - OSTree repo as a local object cache of objects when doing HTTP fetches. + OSTree repo as a local object cache when doing HTTP fetches. May be specified multiple times. diff --git a/src/libostree/ostree-repo-pull.c b/src/libostree/ostree-repo-pull.c index b53e0729..337190ce 100644 --- a/src/libostree/ostree-repo-pull.c +++ b/src/libostree/ostree-repo-pull.c @@ -1790,6 +1790,7 @@ scan_one_metadata_object_c (OtPullData *pull_data, { if (objtype == OSTREE_OBJECT_TYPE_COMMIT) { + /* mark as partial to ensure we scan the commit below */ if (!write_commitpartial_for (pull_data, tmp_checksum, error)) return FALSE; } @@ -1819,6 +1820,12 @@ scan_one_metadata_object_c (OtPullData *pull_data, return FALSE; if (!localcache_repo_has_obj) continue; + if (objtype == OSTREE_OBJECT_TYPE_COMMIT) + { + /* mark as partial to ensure we scan the commit below */ + if (!write_commitpartial_for (pull_data, tmp_checksum, error)) + return FALSE; + } if (!ostree_repo_import_object_from_with_trust (pull_data->repo, refd_repo, objtype, tmp_checksum, !pull_data->is_untrusted, diff --git a/tests/test-pull-localcache.sh b/tests/test-pull-localcache.sh index 5f810acb..44403f92 100755 --- a/tests/test-pull-localcache.sh +++ b/tests/test-pull-localcache.sh @@ -23,23 +23,43 @@ set -euo pipefail setup_fake_remote_repo1 "archive" -echo '1..1' +echo '1..2' cd ${test_tmpdir} gnomerepo_url="$(cat httpd-address)/ostree/gnomerepo" -ostree_repo_init repo --mode "archive" + +# Set up our local cache ostree_repo_init repo-local --mode "archive" -for repo in repo{,-local}; do - ${CMD_PREFIX} ostree --repo=${repo} remote add --set=gpg-verify=false origin ${gnomerepo_url} -done +${CMD_PREFIX} ostree --repo=repo-local remote add --set=gpg-verify=false origin ${gnomerepo_url} + +init_repo() { + ostree_repo_init repo --mode "archive" + ${CMD_PREFIX} ostree --repo=repo remote add --set=gpg-verify=false origin ${gnomerepo_url} +} # Pull the contents to our local cache ${CMD_PREFIX} ostree --repo=repo-local pull origin main rm files -rf ${CMD_PREFIX} ostree --repo=ostree-srv/gnomerepo checkout main files echo anewfile > files/anewfile -${CMD_PREFIX} ostree --repo=ostree-srv/gnomerepo commit -b main --tree=dir=files +commit=$(${CMD_PREFIX} ostree --repo=ostree-srv/gnomerepo commit -b main --tree=dir=files) -${CMD_PREFIX} ostree --repo=repo pull -L repo-local origin main >out.txt +# Check that pulling a new commit of the same tree hits our cache +rm -rf repo +init_repo +${CMD_PREFIX} ostree --repo=repo pull --localcache-repo repo-local origin main >out.txt assert_file_has_content out.txt '3 metadata, 1 content objects fetched (4 meta, 5 content local)' -echo "ok pull --reference" +echo "ok pull --localcache-repo" + +# Check that pulling the same commit works as well +rm -rf repo +init_repo +${CMD_PREFIX} ostree --repo=repo-local pull origin $commit +${CMD_PREFIX} ostree --repo=repo pull -L repo-local origin main +commit2=$(${CMD_PREFIX} ostree --repo=repo rev-parse main) +[[ $commit == $commit2 ]] +# and check that it's not partial +rm -rf files +${CMD_PREFIX} ostree --repo=repo checkout main files +test -f files/anewfile +echo "ok pull --localcache-repo same commit" From fd98bda3c741527bf326164de5832eabcaee8a94 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Fri, 28 Apr 2017 15:51:32 -0400 Subject: [PATCH 54/67] repo: Introduce ostree_repo_open_at() and ostree_repo_create_at() This essentially completes our fd-relative conversion. While here, I cleaned up the semantics of `ostree_repo_create()` and `ostree_repo_create_at()` to be more atomic - basically various scripts were testing for the `objects` subdirectory, so let's formalize that. Closes: #820 Approved by: jlebon --- apidoc/ostree-sections.txt | 2 + src/libostree/libostree-devel.sym | 2 + src/libostree/ostree-repo-finder-mount.c | 37 ++- src/libostree/ostree-repo-private.h | 15 +- src/libostree/ostree-repo.c | 317 ++++++++++++++++------- src/libostree/ostree-repo.h | 14 + src/libostree/ostree-sysroot-private.h | 3 +- src/libostree/ostree-sysroot.c | 51 ++-- tests/test-repo-finder-config.c | 6 +- tests/test-repo-finder-mount.c | 6 +- 10 files changed, 297 insertions(+), 156 deletions(-) diff --git a/apidoc/ostree-sections.txt b/apidoc/ostree-sections.txt index df9767d4..90bec167 100644 --- a/apidoc/ostree-sections.txt +++ b/apidoc/ostree-sections.txt @@ -271,6 +271,7 @@ ostree_mutable_tree_get_type OstreeRepo OstreeRepoMode ostree_repo_mode_from_string +ostree_repo_open_at ostree_repo_new ostree_repo_new_for_sysroot_path ostree_repo_new_default @@ -279,6 +280,7 @@ ostree_repo_set_disable_fsync ostree_repo_get_disable_fsync ostree_repo_is_system ostree_repo_is_writable +ostree_repo_create_at ostree_repo_create ostree_repo_get_path ostree_repo_get_mode diff --git a/src/libostree/libostree-devel.sym b/src/libostree/libostree-devel.sym index 49111b4a..82b18667 100644 --- a/src/libostree/libostree-devel.sym +++ b/src/libostree/libostree-devel.sym @@ -21,6 +21,8 @@ LIBOSTREE_2017.10 { ostree_gpg_error_quark; ostree_repo_set_alias_ref_immediate; + ostree_repo_open_at; + ostree_repo_create_at; }; /* Stub section for the stable release *after* this development one; don't diff --git a/src/libostree/ostree-repo-finder-mount.c b/src/libostree/ostree-repo-finder-mount.c index 1eb3d31d..7f257f68 100644 --- a/src/libostree/ostree-repo-finder-mount.c +++ b/src/libostree/ostree-repo-finder-mount.c @@ -31,6 +31,7 @@ #include "ostree-autocleanups.h" #include "ostree-remote-private.h" +#include "ostree-repo-private.h" #include "ostree-repo-finder.h" #include "ostree-repo-finder-mount.h" @@ -257,19 +258,16 @@ ostree_repo_finder_mount_resolve_async (OstreeRepoFinder *finde { struct stat stbuf; g_autofree gchar *collection_and_ref = NULL; - g_autofree gchar *repo_dir_path = NULL; g_autofree gchar *resolved_repo_uri = NULL; g_autofree gchar *keyring = NULL; g_autoptr(UriAndKeyring) resolved_repo = NULL; collection_and_ref = g_build_filename (refs[i]->collection_id, refs[i]->ref_name, NULL); - repo_dir_path = g_build_filename (mount_root_path, ".ostree", "repos", - collection_and_ref, NULL); if (!glnx_fstatat (repos_dfd, collection_and_ref, &stbuf, AT_NO_AUTOMOUNT, &local_error)) { g_debug ("Ignoring ref (%s, %s) on mount ‘%s’ as querying info of ‘%s’ failed: %s", - refs[i]->collection_id, refs[i]->ref_name, mount_name, repo_dir_path, local_error->message); + refs[i]->collection_id, refs[i]->ref_name, mount_name, collection_and_ref, local_error->message); g_clear_error (&local_error); continue; } @@ -277,7 +275,7 @@ ostree_repo_finder_mount_resolve_async (OstreeRepoFinder *finde if ((stbuf.st_mode & S_IFMT) != S_IFDIR) { g_debug ("Ignoring ref (%s, %s) on mount ‘%s’ as ‘%s’ is of type %u, not a directory.", - refs[i]->collection_id, refs[i]->ref_name, mount_name, repo_dir_path, (stbuf.st_mode & S_IFMT)); + refs[i]->collection_id, refs[i]->ref_name, mount_name, collection_and_ref, (stbuf.st_mode & S_IFMT)); g_clear_error (&local_error); continue; } @@ -294,27 +292,19 @@ ostree_repo_finder_mount_resolve_async (OstreeRepoFinder *finde } /* Exclude repositories which resolve to @parent_repo. */ - g_autofree char *canonical_repo_dir_path = realpath (repo_dir_path, NULL); - g_autofree gchar *parent_repo_path = g_file_get_path (ostree_repo_get_path (parent_repo)); - g_autofree char *canonical_parent_repo_path = realpath (parent_repo_path, NULL); - - if (g_strcmp0 (canonical_repo_dir_path, canonical_parent_repo_path) == 0) + if (stbuf.st_dev == parent_repo->device && + stbuf.st_ino == parent_repo->inode) { - g_debug ("Ignoring ref (%s, %s) on mount ‘%s’ as its repository was the one we are resolving for: %s", - refs[i]->collection_id, refs[i]->ref_name, mount_name, canonical_parent_repo_path); + g_debug ("Ignoring ref (%s, %s) on mount ‘%s’ as it is the same as the one we are resolving", + refs[i]->collection_id, refs[i]->ref_name, mount_name); g_clear_error (&local_error); continue; } - /* Grab the given ref and a checksum for it from the repo. - * FIXME: Ideally, there would be some ostree_repo_open_at() which we - * could use to keep the openat() chain going. See - * https://github.com/ostreedev/ostree/pull/820. */ - g_autoptr(OstreeRepo) repo = NULL; - g_autoptr(GFile) repo_dir_file = g_file_new_for_path (repo_dir_path); - repo = ostree_repo_new (repo_dir_file); - - if (!ostree_repo_open (repo, cancellable, &local_error)) + /* Grab the given ref and a checksum for it from the repo, if it appears to be a valid repo */ + g_autoptr(OstreeRepo) repo = ostree_repo_open_at (repos_dfd, collection_and_ref, + cancellable, &local_error); + if (!repo) { g_debug ("Ignoring ref (%s, %s) on mount ‘%s’ as its repository could not be opened: %s", refs[i]->collection_id, refs[i]->ref_name, mount_name, local_error->message); @@ -358,6 +348,11 @@ ostree_repo_finder_mount_resolve_async (OstreeRepoFinder *finde * $mount_root/.ostree/repos/$refs[i]->collection_id/$refs[i]->ref_name. * Add it to the results, keyed by the canonicalised repository URI * to deduplicate the results. */ + + g_autofree char *repo_abspath = g_build_filename (mount_root_path, ".ostree/repos", + collection_and_ref, NULL); + /* FIXME - why are we using realpath here? */ + g_autofree char *canonical_repo_dir_path = realpath (repo_abspath, NULL); resolved_repo_uri = g_strconcat ("file://", canonical_repo_dir_path, NULL); g_debug ("Resolved ref (%s, %s) on mount ‘%s’ to repo URI ‘%s’ with keyring ‘%s’.", refs[i]->collection_id, refs[i]->ref_name, mount_name, resolved_repo_uri, keyring); diff --git a/src/libostree/ostree-repo-private.h b/src/libostree/ostree-repo-private.h index d2c41316..e38e48bc 100644 --- a/src/libostree/ostree-repo-private.h +++ b/src/libostree/ostree-repo-private.h @@ -96,7 +96,11 @@ struct OstreeRepo { char *commit_stagedir_name; GLnxLockFile commit_stagedir_lock; - GFile *repodir; + /* A cached fd-relative version, distinct from the case where we may have a + * user-provided absolute path. + */ + GFile *repodir_fdrel; + GFile *repodir; /* May be %NULL if we were opened via ostree_repo_open_at() */ int repo_dir_fd; int tmp_dir_fd; int cache_dir_fd; @@ -132,10 +136,13 @@ struct OstreeRepo { GHashTable *updated_uncompressed_dirs; GHashTable *object_sizes; - uid_t owner_uid; - uid_t target_owner_uid; + /* Cache the repo's device/inode to use for comparisons elsewhere */ + dev_t device; + ino_t inode; + uid_t owner_uid; /* Cache of repo's owner uid */ + uid_t target_owner_uid; /* Ensure files are chowned to this uid/gid */ gid_t target_owner_gid; - guint min_free_space_percent; + guint min_free_space_percent; /* See the min-free-space-percent config option */ guint test_error_flags; /* OstreeRepoTestErrorFlags */ diff --git a/src/libostree/ostree-repo.c b/src/libostree/ostree-repo.c index df019dd6..795016ce 100644 --- a/src/libostree/ostree-repo.c +++ b/src/libostree/ostree-repo.c @@ -456,6 +456,7 @@ ostree_repo_finalize (GObject *object) g_clear_object (&self->parent_repo); g_free (self->stagedir_prefix); + g_clear_object (&self->repodir_fdrel); g_clear_object (&self->repodir); if (self->repo_dir_fd != -1) (void) close (self->repo_dir_fd); @@ -546,22 +547,11 @@ ostree_repo_get_property(GObject *object, } } -static void -ostree_repo_constructed (GObject *object) -{ - OstreeRepo *self = OSTREE_REPO (object); - - g_assert (self->repodir != NULL); - - G_OBJECT_CLASS (ostree_repo_parent_class)->constructed (object); -} - static void ostree_repo_class_init (OstreeRepoClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); - object_class->constructed = ostree_repo_constructed; object_class->get_property = ostree_repo_get_property; object_class->set_property = ostree_repo_set_property; object_class->finalize = ostree_repo_finalize; @@ -581,6 +571,7 @@ ostree_repo_class_init (OstreeRepoClass *klass) "", G_TYPE_FILE, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + g_object_class_install_property (object_class, PROP_REMOTES_CONFIG_DIR, g_param_spec_string ("remotes-config-dir", @@ -662,6 +653,43 @@ ostree_repo_new (GFile *path) return g_object_new (OSTREE_TYPE_REPO, "path", path, NULL); } +static OstreeRepo * +repo_open_at_take_fd (int *dfd, + GCancellable *cancellable, + GError **error) +{ + g_autoptr(OstreeRepo) repo = g_object_new (OSTREE_TYPE_REPO, NULL); + repo->repo_dir_fd = glnx_steal_fd (dfd); + + if (!ostree_repo_open (repo, cancellable, error)) + return NULL; + return g_steal_pointer (&repo); +} + +/** + * ostree_repo_open_at: + * @dfd: Directory fd + * @path: Path + * + * This combines ostree_repo_new() (but using fd-relative access) with + * ostree_repo_open(). Use this when you know you should be operating on an + * already extant repository. If you want to create one, use ostree_repo_create_at(). + * + * Returns: (transfer full): An accessor object for an OSTree repository located at @dfd + @path + */ +OstreeRepo* +ostree_repo_open_at (int dfd, + const char *path, + GCancellable *cancellable, + GError **error) +{ + glnx_fd_close int repo_dfd = -1; + if (!glnx_opendirat (dfd, path, TRUE, &repo_dfd, error)) + return NULL; + + return repo_open_at_take_fd (&repo_dfd, cancellable, error); +} + static GFile * get_default_repo_path (GFile *sysroot_path) { @@ -744,8 +772,16 @@ ostree_repo_is_system (OstreeRepo *repo) if (!repo->sysroot_dir) return FALSE; - g_autoptr(GFile) default_repo_path = get_default_repo_path (repo->sysroot_dir); - return g_file_equal (repo->repodir, default_repo_path); + /* If we created via ostree_repo_new(), we'll have a repo path. Compare + * it to the sysroot path in that case. + */ + if (repo->repodir) + { + g_autoptr(GFile) default_repo_path = get_default_repo_path (repo->sysroot_dir); + return g_file_equal (repo->repodir, default_repo_path); + } + /* Otherwise, not a system repo */ + return FALSE; } /** @@ -1670,6 +1706,104 @@ ostree_repo_mode_from_string (const char *mode, #define DEFAULT_CONFIG_CONTENTS ("[core]\n" \ "repo_version=1\n") +/* Just write the dirs to disk, return a dfd */ +static gboolean +repo_create_at_internal (int dfd, + const char *path, + OstreeRepoMode mode, + GVariant *options, + int *out_dfd, + GCancellable *cancellable, + GError **error) +{ + struct stat stbuf; + /* We do objects/ last - if it exists we do nothing and exit successfully */ + const char *state_dirs[] = { "tmp", "extensions", "state", + "refs", "refs/heads", "refs/mirrors", + "refs/remotes", "objects" }; + + /* Early return if we have an existing repo */ + { g_autofree char *objects_path = g_build_filename (path, "objects", NULL); + + if (fstatat (dfd, objects_path, &stbuf, 0) == 0) + { + glnx_fd_close int repo_dfd = -1; + if (!glnx_opendirat (dfd, path, TRUE, &repo_dfd, error)) + return FALSE; + + /* Note early return */ + *out_dfd = glnx_steal_fd (&repo_dfd); + return TRUE; + } + else if (errno != ENOENT) + return glnx_throw_errno_prefix (error, "fstatat"); + } + + if (mkdirat (dfd, path, 0755) != 0) + { + if (G_UNLIKELY (errno != EEXIST)) + return glnx_throw_errno_prefix (error, "mkdirat"); + } + + glnx_fd_close int repo_dfd = -1; + if (!glnx_opendirat (dfd, path, TRUE, &repo_dfd, error)) + return FALSE; + + if (fstatat (repo_dfd, "config", &stbuf, 0) < 0) + { + if (errno == ENOENT) + { + const char *mode_str = NULL; + g_autoptr(GString) config_data = g_string_new (DEFAULT_CONFIG_CONTENTS); + + if (!ostree_repo_mode_to_string (mode, &mode_str, error)) + return FALSE; + g_assert (mode_str); + + g_string_append_printf (config_data, "mode=%s\n", mode_str); + + const char *collection_id = NULL; + if (options) + g_variant_lookup (options, "collection-id", "&s", &collection_id); + if (collection_id != NULL) + g_string_append_printf (config_data, "collection-id=%s\n", collection_id); + + if (!glnx_file_replace_contents_at (repo_dfd, "config", + (guint8*)config_data->str, config_data->len, + 0, cancellable, error)) + return FALSE; + } + else + return glnx_throw_errno_prefix (error, "fstatat"); + } + + for (guint i = 0; i < G_N_ELEMENTS (state_dirs); i++) + { + const char *elt = state_dirs[i]; + if (mkdirat (repo_dfd, elt, 0755) == -1) + { + if (G_UNLIKELY (errno != EEXIST)) + return glnx_throw_errno_prefix (error, "mkdirat"); + } + } + + /* Test that the fs supports user xattrs now, so we get an error early rather + * than during an object write later. + */ + if (mode == OSTREE_REPO_MODE_BARE_USER) + { + g_auto(GLnxTmpfile) tmpf = { 0, }; + + if (!glnx_open_tmpfile_linkable_at (repo_dfd, ".", O_RDWR|O_CLOEXEC, &tmpf, error)) + return FALSE; + if (!_ostree_write_bareuser_metadata (tmpf.fd, 0, 0, 644, NULL, error)) + return FALSE; + } + + *out_dfd = glnx_steal_fd (&repo_dfd); + return TRUE; +} + /** * ostree_repo_create: * @self: An #OstreeRepo @@ -1686,6 +1820,11 @@ ostree_repo_mode_from_string (const char *mode, * of an existing repository, and will silently ignore an attempt to * do so. * + * Since 2017.9, "existing repository" is defined by the existence of an + * `objects` subdirectory. + * + * This function predates ostree_repo_create_at(). It is an error to call + * this function on a repository initialized via ostree_repo_open_at(). */ gboolean ostree_repo_create (OstreeRepo *self, @@ -1693,76 +1832,64 @@ ostree_repo_create (OstreeRepo *self, GCancellable *cancellable, GError **error) { + g_return_val_if_fail (self->repodir, FALSE); const char *repopath = gs_file_get_path_cached (self->repodir); - glnx_fd_close int dfd = -1; - struct stat stbuf; - const char *state_dirs[] = { "objects", "tmp", "extensions", "state", - "refs", "refs/heads", "refs/mirrors", - "refs/remotes" }; + g_autoptr(GVariantBuilder) builder = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}")); + if (self->collection_id) + g_variant_builder_add (builder, "{s@v}", "collection-id", + g_variant_new_variant (g_variant_new_string (self->collection_id))); - if (mkdir (repopath, 0755) != 0) - { - if (G_UNLIKELY (errno != EEXIST)) - return glnx_throw_errno (error); - } - - if (!glnx_opendirat (AT_FDCWD, repopath, TRUE, &dfd, error)) + glnx_fd_close int repo_dir_fd = -1; + if (!repo_create_at_internal (AT_FDCWD, repopath, mode, + g_variant_builder_end (builder), + &repo_dir_fd, + cancellable, error)) return FALSE; - - if (fstatat (dfd, "config", &stbuf, 0) < 0) - { - if (errno == ENOENT) - { - const char *mode_str = NULL; - g_autoptr(GString) config_data = g_string_new (DEFAULT_CONFIG_CONTENTS); - - if (!ostree_repo_mode_to_string (mode, &mode_str, error)) - return FALSE; - g_assert (mode_str); - - g_string_append_printf (config_data, "mode=%s\n", mode_str); - - if (self->collection_id != NULL) - g_string_append_printf (config_data, "collection-id=%s\n", self->collection_id); - - if (!glnx_file_replace_contents_at (dfd, "config", - (guint8*)config_data->str, config_data->len, - 0, cancellable, error)) - return FALSE; - } - else - return glnx_throw_errno (error); - } - - for (guint i = 0; i < G_N_ELEMENTS (state_dirs); i++) - { - const char *elt = state_dirs[i]; - if (mkdirat (dfd, elt, 0755) == -1) - { - if (G_UNLIKELY (errno != EEXIST)) - return glnx_throw_errno (error); - } - } - - /* Test that the fs supports user xattrs now, so we get an error early rather - * than during an object write later. - */ - if (mode == OSTREE_REPO_MODE_BARE_USER) - { - g_auto(GLnxTmpfile) tmpf = { 0, }; - - if (!glnx_open_tmpfile_linkable_at (dfd, ".", O_RDWR|O_CLOEXEC, &tmpf, error)) - return FALSE; - if (!_ostree_write_bareuser_metadata (tmpf.fd, 0, 0, 644, NULL, error)) - return FALSE; - } - + self->repo_dir_fd = glnx_steal_fd (&repo_dir_fd); if (!ostree_repo_open (self, cancellable, error)) return FALSE; - return TRUE; } +/** + * ostree_repo_create_at: + * @dfd: Directory fd + * @path: Path + * @mode: The mode to store the repository in + * @options: a{sv}: See below for accepted keys + * @cancellable: Cancellable + * @error: Error + * + * This is a file-descriptor relative version of ostree_repo_create(). + * Create the underlying structure on disk for the repository, and call + * ostree_repo_open_at() on the result, preparing it for use. + * + * If a repository already exists at @dfd + @path (defined by an `objects/` + * subdirectory existing), then this function will simply call + * ostree_repo_open_at(). In other words, this function cannot be used to change + * the mode or configuration (`repo/config`) of an existing repo. + * + * The @options dict may contain: + * + * - collection-id: s: Set as collection ID in repo/config (Since 2017.9) + * + * Returns: (transfer full): A new OSTree repository reference + */ +OstreeRepo * +ostree_repo_create_at (int dfd, + const char *path, + OstreeRepoMode mode, + GVariant *options, + GCancellable *cancellable, + GError **error) +{ + glnx_fd_close int repo_dfd = -1; + if (!repo_create_at_internal (dfd, path, mode, options, &repo_dfd, + cancellable, error)) + return NULL; + return repo_open_at_take_fd (&repo_dfd, cancellable, error); +} + static gboolean enumerate_directory_allow_noent (GFile *dirpath, const char *queryargs, @@ -2132,7 +2259,6 @@ ostree_repo_open (OstreeRepo *self, GCancellable *cancellable, GError **error) { - struct stat self_stbuf; struct stat stbuf; g_return_val_if_fail (error == NULL || *error == NULL, FALSE); @@ -2162,22 +2288,25 @@ ostree_repo_open (OstreeRepo *self, self->stagedir_prefix = g_strconcat (OSTREE_REPO_TMPDIR_STAGING, boot_id, "-", NULL); } - if (!glnx_opendirat (AT_FDCWD, gs_file_get_path_cached (self->repodir), TRUE, - &self->repo_dir_fd, error)) + if (self->repo_dir_fd == -1) { - g_prefix_error (error, "%s: ", gs_file_get_path_cached (self->repodir)); - return FALSE; + g_assert (self->repodir); + if (!glnx_opendirat (AT_FDCWD, gs_file_get_path_cached (self->repodir), TRUE, + &self->repo_dir_fd, error)) + { + g_prefix_error (error, "%s: ", gs_file_get_path_cached (self->repodir)); + return FALSE; + } } - if (!glnx_fstat (self->repo_dir_fd, &self_stbuf, error)) + if (!glnx_fstat (self->repo_dir_fd, &stbuf, error)) return FALSE; + self->device = stbuf.st_dev; + self->inode = stbuf.st_ino; if (!glnx_opendirat (self->repo_dir_fd, "objects", TRUE, &self->objects_dir_fd, error)) - { - g_prefix_error (error, "Opening objects/ directory: "); - return FALSE; - } + return FALSE; self->writable = faccessat (self->objects_dir_fd, ".", W_OK, 0) == 0; if (!self->writable) @@ -2238,8 +2367,8 @@ ostree_repo_open (OstreeRepo *self, if (fstatat (AT_FDCWD, "/ostree/repo", &system_stbuf, 0) == 0) { /* Are we the same as /ostree/repo? */ - if (self_stbuf.st_dev == system_stbuf.st_dev && - self_stbuf.st_ino == system_stbuf.st_ino) + if (self->device == system_stbuf.st_dev && + self->inode == system_stbuf.st_ino) self->sysroot_kind = OSTREE_REPO_SYSROOT_KIND_IS_SYSROOT_OSTREE; else self->sysroot_kind = OSTREE_REPO_SYSROOT_KIND_NO; @@ -2349,14 +2478,24 @@ _ostree_repo_file_replace_contents (OstreeRepo *self, /** * ostree_repo_get_path: - * @self: + * @self: Repo + * + * Note that since the introduction of ostree_repo_open_at(), this function may + * return a process-specific path in `/proc` if the repository was created using + * that API. In general, you should avoid use of this API. * * Returns: (transfer none): Path to repo */ GFile * ostree_repo_get_path (OstreeRepo *self) { - return self->repodir; + /* Did we have an abspath? Return it */ + if (self->repodir) + return self->repodir; + /* Lazily create a fd-relative path */ + if (!self->repodir_fdrel) + self->repodir_fdrel = ot_fdrel_to_gfile (self->repo_dir_fd, "."); + return self->repodir_fdrel; } /** diff --git a/src/libostree/ostree-repo.h b/src/libostree/ostree-repo.h index f01fee2a..8766e6df 100644 --- a/src/libostree/ostree-repo.h +++ b/src/libostree/ostree-repo.h @@ -63,6 +63,13 @@ gboolean ostree_repo_open (OstreeRepo *self, GCancellable *cancellable, GError **error); +_OSTREE_PUBLIC +OstreeRepo* +ostree_repo_open_at (int dfd, + const char *path, + GCancellable *cancellable, + GError **error); + _OSTREE_PUBLIC void ostree_repo_set_disable_fsync (OstreeRepo *self, gboolean disable_fsync); @@ -89,6 +96,13 @@ gboolean ostree_repo_create (OstreeRepo *self, OstreeRepoMode mode, GCancellable *cancellable, GError **error); +_OSTREE_PUBLIC +OstreeRepo * ostree_repo_create_at (int dfd, + const char *path, + OstreeRepoMode mode, + GVariant *options, + GCancellable *cancellable, + GError **error); #ifdef OSTREE_ENABLE_EXPERIMENTAL_API diff --git a/src/libostree/ostree-sysroot-private.h b/src/libostree/ostree-sysroot-private.h index 4c6cb328..8c4de9e0 100644 --- a/src/libostree/ostree-sysroot-private.h +++ b/src/libostree/ostree-sysroot-private.h @@ -57,9 +57,8 @@ struct OstreeSysroot { OstreeDeployment *booted_deployment; struct timespec loaded_ts; - /* Only access through ostree_sysroot_get_repo() */ + /* Only access through ostree_sysroot_[_get]repo() */ OstreeRepo *repo; - gboolean repo_opened; OstreeSysrootDebugFlags debug_flags; }; diff --git a/src/libostree/ostree-sysroot.c b/src/libostree/ostree-sysroot.c index 5bdfe116..8d91cde6 100644 --- a/src/libostree/ostree-sysroot.c +++ b/src/libostree/ostree-sysroot.c @@ -137,18 +137,11 @@ static void ostree_sysroot_constructed (GObject *object) { OstreeSysroot *self = OSTREE_SYSROOT (object); - g_autoptr(GFile) repo_path = NULL; /* Ensure the system root path is set. */ if (self->path == NULL) self->path = g_object_ref (_ostree_get_default_sysroot_path ()); - repo_path = g_file_resolve_relative_path (self->path, "ostree/repo"); - self->repo = ostree_repo_new_for_sysroot_path (repo_path, self->path); - self->repo->sysroot_kind = OSTREE_REPO_SYSROOT_KIND_VIA_SYSROOT; - /* Hold a weak ref for the remote-add handling */ - g_weak_ref_init (&self->repo->sysroot, object); - G_OBJECT_CLASS (ostree_sysroot_parent_class)->constructed (object); } @@ -332,21 +325,12 @@ ostree_sysroot_ensure_initialized (OstreeSysroot *self, cancellable, error)) return FALSE; - struct stat stbuf; - if (fstatat (self->sysroot_fd, "ostree/repo/objects", &stbuf, 0) != 0) - { - if (errno != ENOENT) - return glnx_throw_errno_prefix (error, "stat(ostree/repo/objects)"); - else - { - g_autoptr(GFile) repo_dir = g_file_resolve_relative_path (self->path, "ostree/repo"); - g_autoptr(OstreeRepo) repo = ostree_repo_new (repo_dir); - if (!ostree_repo_create (repo, OSTREE_REPO_MODE_BARE, - cancellable, error)) - return FALSE; - } - } - + g_autoptr(OstreeRepo) repo = + ostree_repo_create_at (self->sysroot_fd, "ostree/repo", + OSTREE_REPO_MODE_BARE, NULL, + cancellable, error); + if (!repo) + return FALSE; return TRUE; } @@ -772,14 +756,22 @@ ostree_sysroot_load (OstreeSysroot *self, } static gboolean -ensure_repo_opened (OstreeSysroot *self, - GError **error) +ensure_repo (OstreeSysroot *self, + GError **error) { - if (self->repo_opened) + if (self->repo != NULL) return TRUE; - if (!ostree_repo_open (self->repo, NULL, error)) + if (!ensure_sysroot_fd (self, error)) return FALSE; - self->repo_opened = TRUE; + self->repo = ostree_repo_open_at (self->sysroot_fd, "ostree/repo", NULL, error); + if (!self->repo) + return FALSE; + + /* Flag it as having been created via ostree_sysroot_get_repo(), and hold a + * weak ref for the remote-add handling. + */ + g_weak_ref_init (&self->repo->sysroot, self); + self->repo->sysroot_kind = OSTREE_REPO_SYSROOT_KIND_VIA_SYSROOT; return TRUE; } @@ -796,7 +788,7 @@ ostree_sysroot_load_if_changed (OstreeSysroot *self, * previous to v2017.6, but we do now to support the error-free * ostree_sysroot_repo() API. */ - if (!ensure_repo_opened (self, error)) + if (!ensure_repo (self, error)) return FALSE; int bootversion = 0; @@ -999,9 +991,8 @@ ostree_sysroot_get_repo (OstreeSysroot *self, GCancellable *cancellable, GError **error) { - if (!ensure_repo_opened (self, error)) + if (!ensure_repo (self, error)) return FALSE; - if (out_repo != NULL) *out_repo = g_object_ref (self->repo); return TRUE; diff --git a/tests/test-repo-finder-config.c b/tests/test-repo-finder-config.c index dc083754..ba7191ec 100644 --- a/tests/test-repo-finder-config.c +++ b/tests/test-repo-finder-config.c @@ -70,7 +70,6 @@ static void teardown (Fixture *fixture, gconstpointer test_data) { - glnx_fd_close int parent_repo_dfd = -1; g_autoptr(GError) error = NULL; /* Recursively remove the temporary directory. */ @@ -81,10 +80,7 @@ teardown (Fixture *fixture, /* The repo also needs its source files to be removed. This is the inverse * of setup_test_repository() in libtest.sh. */ - g_autofree gchar *parent_repo_path = g_file_get_path (ostree_repo_get_path (fixture->parent_repo)); - glnx_opendirat (-1, parent_repo_path, TRUE, &parent_repo_dfd, &error); - g_assert_no_error (error); - + int parent_repo_dfd = ostree_repo_get_dfd (fixture->parent_repo); glnx_shutil_rm_rf_at (parent_repo_dfd, "../files", NULL, NULL); glnx_shutil_rm_rf_at (parent_repo_dfd, "../repo", NULL, NULL); diff --git a/tests/test-repo-finder-mount.c b/tests/test-repo-finder-mount.c index c84feb52..f51fb3bb 100644 --- a/tests/test-repo-finder-mount.c +++ b/tests/test-repo-finder-mount.c @@ -73,7 +73,6 @@ static void teardown (Fixture *fixture, gconstpointer test_data) { - glnx_fd_close int parent_repo_dfd = -1; g_autoptr(GError) error = NULL; /* Recursively remove the temporary directory. */ @@ -84,10 +83,7 @@ teardown (Fixture *fixture, /* The repo also needs its source files to be removed. This is the inverse * of setup_test_repository() in libtest.sh. */ - g_autofree gchar *parent_repo_path = g_file_get_path (ostree_repo_get_path (fixture->parent_repo)); - glnx_opendirat (-1, parent_repo_path, TRUE, &parent_repo_dfd, &error); - g_assert_no_error (error); - + int parent_repo_dfd = ostree_repo_get_dfd (fixture->parent_repo); glnx_shutil_rm_rf_at (parent_repo_dfd, "../files", NULL, NULL); glnx_shutil_rm_rf_at (parent_repo_dfd, "../repo", NULL, NULL); From a11d696b4c4374a280d09cf40e68e1c849b4e539 Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Sat, 12 Aug 2017 01:17:23 +0000 Subject: [PATCH 55/67] bash: Add bash completion Completes commands, options, commit checksums, ref names, remotes, and file paths. Closes: #1077 Approved by: jlebon --- Makefile-bash.am | 21 + Makefile.am | 1 + bash/ostree | 2148 ++++++++++++++++++++++++++++++++++++++++++++++ configure.ac | 11 + 4 files changed, 2181 insertions(+) create mode 100644 Makefile-bash.am create mode 100644 bash/ostree diff --git a/Makefile-bash.am b/Makefile-bash.am new file mode 100644 index 00000000..e61829a2 --- /dev/null +++ b/Makefile-bash.am @@ -0,0 +1,21 @@ +# Makefile for bash/ +# +# Copyright (C) 2017 Red Hat Inc. +# +# 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. + +completionsdir = @BASH_COMPLETIONSDIR@ +dist_completions_DATA = bash/ostree diff --git a/Makefile.am b/Makefile.am index 0939d4b7..b542d3c1 100644 --- a/Makefile.am +++ b/Makefile.am @@ -111,6 +111,7 @@ endif include Makefile-tests.am include Makefile-boot.am include Makefile-man.am +include Makefile-bash.am release-tag: cd $(srcdir) && git $(srcdir) tag -m "Release $(VERSION)" v$(VERSION) diff --git a/bash/ostree b/bash/ostree new file mode 100644 index 00000000..f4305f69 --- /dev/null +++ b/bash/ostree @@ -0,0 +1,2148 @@ +#!/bin/bash +# +# bash completion file for ostree commands +# +# This script provides completion of: +# - commands and their options +# - ostree commit checksums +# - ostree ref names +# +# To enable the completions either: +# - place this file in /etc/bash_completion.d +# or +# - copy this file to e.g. ~/.ostree-completion.sh and add the line +# below to your .bashrc after bash completion features are loaded +# . ~/.ostree-completion.sh +# +# Note for developers: +# Please arrange options sorted alphabetically by long name with the short +# options immediately following their corresponding long form. +# This order should be applied to lists, alternatives and code blocks. + +# TODO +# +# - Long form options with an equal sign (--foo=BAR) are not parsed. +# +# - Structured option arguments (e.g. --foo KEY=VALUE) are not parsed. +# +# - Static deltas could likely be completed. (e.g. ostree static-delta delete [TAB]) +# +# - The "--repo PATH" option needs to come after the subcommand or it +# won't be picked up for completion of subsequent options. +# i.e. ostree commit --repo PATH ... <-- works +# ostree --repo PATH commit ... <-- does not work +# (Possibly an easy fix.) + + +# Finds the position of the first non-flag word. +__ostree_pos_first_nonflag() { + local argument_flags=$1 + + local counter=$cpos + while [ $counter -le $cword ]; do + if [ -n "$argument_flags" ] && eval "case '${words[$counter]}' in $argument_flags) true ;; *) false ;; esac"; then + (( counter++ )) + else + case "${words[$counter]}" in + -*) + ;; + *) + break + ;; + esac + fi + (( counter++ )) + done + + echo $counter +} + +# Transforms a multiline list of strings into a single line string +# with the words separated by "|". +# This is used to prepare arguments to __ostree_pos_first_nonflag(). +__ostree_to_alternatives() { + local parts=( $1 ) + local IFS='|' + echo "${parts[*]}" +} + +# Transforms a multiline list of options into an extglob pattern +# suitable for use in case statements. +__ostree_to_extglob() { + local extglob=$( __ostree_to_alternatives "$1" ) + echo "@($extglob)" +} + +# Transform object path to a 64-char checksum. +__ostree_object_to_checksum() { + local str=( $1 ) + # Trim off extension (e.g. .commit) + str=${str%.*} + # Isolate checksum portion (nn/nnn...) + str=${str: -65} + # Drop the slash + echo "${str/\//}" +} + +__ostree_compreply_all_options() { + COMPREPLY+=( $( compgen -W "$all_options" -- "$cur" ) ) +} + +__ostree_compreply_all_files() { + COMPREPLY+=( $( compgen -f "$cur" ) ) +} + +__ostree_compreply_dirs_only() { + COMPREPLY+=( $( compgen -d "$cur" ) ) +} + +# Find commit objects under $repo_path. +__ostree_compreply_commits() { + local objectsdir="$repo_path/objects" + if test -d "$objectsdir"; then + local commits=() + for path in `find "$objectsdir" -name "*.commit"`; do + commits+=( $( __ostree_object_to_checksum "$path" ) ) + done + COMPREPLY+=( $( compgen -W "$commits" -- "$cur" ) ) + fi +} + +# Find oses under $sysroot_path +__ostree_compreply_oses() { + local deploydir="$sysroot_path/ostree/deploy" + if test -d "$deploydir"; then + local oses=() + for path in `find "$deploydir" -mindepth 1 -maxdepth 1 -type d`; do + oses+=( $( basename "$path" ) ) + done + COMPREPLY+=( $( compgen -W "$oses" -- "$cur" ) ) + fi +} + +# Find refs under $repo_path. +__ostree_compreply_refs() { + refs=$( ostree refs --repo $repo_path 2>/dev/null ) + COMPREPLY+=( $( compgen -W "$refs" -- "$cur" ) ) +} + +# Find remotes under $repo_path. +__ostree_compreply_remotes() { + remotes=$( ostree remote list --repo $repo_path 2> /dev/null ) + COMPREPLY+=( $( compgen -W "$remotes" -- "$cur" ) ) +} + +# Find commit objects and refs under $repo_path. +__ostree_compreply_revisions() { + __ostree_compreply_commits + __ostree_compreply_refs +} + +# Subcommand processing. +# Locates the first occurrence of any of the subcommands contained in the +# first argument. In case of a match, calls the corresponding completion +# function and returns 0. +# If no match is found, 1 is returned. The calling function can then +# continue processing its completion. +# +# TODO If the preceding command has options that accept arguments and an +# argument is equal to one of the subcommands, this is falsely detected +# as a match. +__ostree_subcommands() { + local subcommands="$1" + + local counter=$cpos + while [ $counter -lt $cword ]; do + case "${words[$counter]}" in + $( __ostree_to_extglob "$subcommands" ) ) + local subcommand=${words[$counter]} + cpos=$counter + (( cpos++ )) + local completions_func=_ostree_${command//-/_}_${subcommand//-/_} + declare -F $completions_func >/dev/null && $completions_func + return 0 + ;; + esac + (( counter++ )) + done + return 1 +} + +# This handles "ostree [TAB]" (without a subcommand). +_ostree_ostree() { + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "$main_boolean_options" -- "$cur" ) ) + ;; + *) + COMPREPLY=( $( compgen -W "$commands" -- "$cur" ) ) + ;; + esac + + return 0 +} + +_ostree_admin_cleanup() { + local boolean_options=" + $main_boolean_options + " + + local options_with_args=" + --sysroot + " + + local options_with_args_glob=$( __ostree_to_extglob "$options_with_args" ) + + case "$prev" in + --sysroot) + __ostree_compreply_dirs_only + return 0 + ;; + $options_with_args_glob ) + return 0 + ;; + esac + + case "$cur" in + -*) + local all_options="$boolean_options $options_with_args" + __ostree_compreply_all_options + ;; + esac + + return 0 +} + +_ostree_admin_config_diff() { + local boolean_options=" + $main_boolean_options + " + + local options_with_args=" + --os + --sysroot + " + + local options_with_args_glob=$( __ostree_to_extglob "$options_with_args" ) + + case "$prev" in + --os) + __ostree_compreply_oses + return 0 + ;; + --sysroot) + __ostree_compreply_dirs_only + return 0 + ;; + $options_with_args_glob ) + return 0 + ;; + esac + + case "$cur" in + -*) + local all_options="$boolean_options $options_with_args" + __ostree_compreply_all_options + ;; + esac + + return 0 +} + +_ostree_admin_deploy() { + local boolean_options=" + $main_boolean_options + --retain + --karg-proc-cmdline + " + + local options_with_args=" + --karg + --karg-append + --origin-file + --os + --sysroot + " + + local options_with_args_glob=$( __ostree_to_extglob "$options_with_args" ) + + case "$prev" in + --origin-file) + __ostree_compreply_all_files + return 0 + ;; + --os) + __ostree_compreply_oses + return 0 + ;; + --sysroot) + __ostree_compreply_dirs_only + return 0 + ;; + $options_with_args_glob ) + return 0 + ;; + esac + + case "$cur" in + -*) + local all_options="$boolean_options $options_with_args" + __ostree_compreply_all_options + ;; + esac + + return 0 +} + +_ostree_admin_init_fs() { + local boolean_options=" + $main_boolean_options + " + + local options_with_args=" + --sysroot + " + + local options_with_args_glob=$( __ostree_to_extglob "$options_with_args" ) + + case "$prev" in + --sysroot) + __ostree_compreply_dirs_only + return 0 + ;; + $options_with_args_glob ) + return 0 + ;; + esac + + case "$cur" in + -*) + local all_options="$boolean_options $options_with_args" + __ostree_compreply_all_options + ;; + esac + + return 0 +} + +_ostree_admin_instutil() { + local boolean_options=" + $main_boolean_options + " + + local options_with_args=" + --sysroot + " + + local options_with_args_glob=$( __ostree_to_extglob "$options_with_args" ) + + case "$prev" in + --sysroot) + __ostree_compreply_dirs_only + return 0 + ;; + $options_with_args_glob ) + return 0 + ;; + esac + + case "$cur" in + -*) + local all_options="$boolean_options $options_with_args" + __ostree_compreply_all_options + ;; + *) + local argpos=$( __ostree_pos_first_nonflag $( __ostree_to_alternatives "$options_with_args" ) ) + if [ $cword -eq $argpos ]; then + local instutil_commands=" + grub2-generate + selinux-ensure-labeled + set-kargs + " + COMPREPLY=( $( compgen -W "$instutil_commands" -- "$cur" ) ) + fi + ;; + esac + + return 0 +} + +_ostree_admin_os_init() { + local boolean_options=" + $main_boolean_options + " + + local options_with_args=" + --sysroot + " + + local options_with_args_glob=$( __ostree_to_extglob "$options_with_args" ) + + case "$prev" in + --sysroot) + __ostree_compreply_dirs_only + return 0 + ;; + $options_with_args_glob ) + return 0 + ;; + esac + + case "$cur" in + -*) + local all_options="$boolean_options $options_with_args" + __ostree_compreply_all_options + ;; + esac + + return 0 +} + +_ostree_admin_set_origin() { + local boolean_options=" + $main_boolean_options + " + + local options_with_args=" + --index + --set -s + --sysroot + " + + local options_with_args_glob=$( __ostree_to_extglob "$options_with_args" ) + + case "$prev" in + --sysroot) + __ostree_compreply_dirs_only + return 0 + ;; + $options_with_args_glob ) + return 0 + ;; + esac + + case "$cur" in + -*) + local all_options="$boolean_options $options_with_args" + __ostree_compreply_all_options + ;; + *) + local argpos=$( __ostree_pos_first_nonflag $( __ostree_to_alternatives "$options_with_args" ) ) + if [ $cword -eq $argpos ]; then + __ostree_compreply_remotes + fi + ;; + esac + + return 0 +} + +_ostree_admin_status() { + local boolean_options=" + $main_boolean_options + " + + local options_with_args=" + --sysroot + " + + local options_with_args_glob=$( __ostree_to_extglob "$options_with_args" ) + + case "$prev" in + --sysroot) + __ostree_compreply_dirs_only + return 0 + ;; + $options_with_args_glob ) + return 0 + ;; + esac + + case "$cur" in + -*) + local all_options="$boolean_options $options_with_args" + __ostree_compreply_all_options + ;; + esac + + return 0 +} + +_ostree_admin_switch() { + local boolean_options=" + $main_boolean_options + " + + local options_with_args=" + --os + --reboot -r + --sysroot + " + + local options_with_args_glob=$( __ostree_to_extglob "$options_with_args" ) + + case "$prev" in + --os) + __ostree_compreply_oses + return 0 + ;; + --sysroot) + __ostree_compreply_dirs_only + return 0 + ;; + $options_with_args_glob ) + return 0 + ;; + esac + + case "$cur" in + -*) + local all_options="$boolean_options $options_with_args" + __ostree_compreply_all_options + ;; + *) + local argpos=$( __ostree_pos_first_nonflag $( __ostree_to_alternatives "$options_with_args" ) ) + + if [ $cword -eq $argpos ]; then + __ostree_compreply_refs + fi + esac + + return 0 +} + +_ostree_admin_undeploy() { + local boolean_options=" + $main_boolean_options + " + + local options_with_args=" + --sysroot + " + + local options_with_args_glob=$( __ostree_to_extglob "$options_with_args" ) + + case "$prev" in + --sysroot) + __ostree_compreply_dirs_only + return 0 + ;; + $options_with_args_glob ) + return 0 + ;; + esac + + case "$cur" in + -*) + local all_options="$boolean_options $options_with_args" + __ostree_compreply_all_options + ;; + esac + + return 0 +} + +_ostree_admin_unlock() { + local boolean_options=" + $main_boolean_options + --hotfix + " + + local options_with_args=" + --sysroot + " + + local options_with_args_glob=$( __ostree_to_extglob "$options_with_args" ) + + case "$prev" in + --sysroot) + __ostree_compreply_dirs_only + return 0 + ;; + $options_with_args_glob ) + return 0 + ;; + esac + + case "$cur" in + -*) + local all_options="$boolean_options $options_with_args" + __ostree_compreply_all_options + ;; + esac + + return 0 +} + +_ostree_admin_upgrade() { + local boolean_options=" + $main_boolean_options + --allow-downgrade + --deploy-only + --pull-only + --reboot -r + " + + local options_with_args=" + --os + --override-commit + --sysroot + " + + local options_with_args_glob=$( __ostree_to_extglob "$options_with_args" ) + + case "$prev" in + --override-commit) + __ostree_compreply_commits + return 0 + ;; + --sysroot) + __ostree_compreply_dirs_only + return 0 + ;; + $options_with_args_glob ) + return 0 + ;; + esac + + case "$cur" in + -*) + local all_options="$boolean_options $options_with_args" + __ostree_compreply_all_options + ;; + esac + + return 0 +} + +_ostree_admin() { + local subcommands=" + cleanup + config-diff + deploy + init-fs + instutil + os-init + set-origin + status + switch + undeploy + unlock + upgrade + " + + __ostree_subcommands "$subcommands" && return 0 + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "$main_boolean_options" -- "$cur" ) ) + ;; + *) + COMPREPLY=( $( compgen -W "$subcommands" -- "$cur" ) ) + ;; + esac + + return 0 +} + +_ostree_cat() { + local boolean_options=" + $main_boolean_options + " + + local options_with_args=" + --repo + " + + local options_with_args_glob=$( __ostree_to_extglob "$options_with_args" ) + + case "$prev" in + --repo) + __ostree_compreply_dirs_only + return 0 + ;; + $options_with_args_glob ) + return 0 + ;; + esac + + case "$cur" in + -*) + local all_options="$boolean_options $options_with_args" + __ostree_compreply_all_options + ;; + *) + local argpos=$( __ostree_pos_first_nonflag $( __ostree_to_alternatives "$options_with_args" ) ) + if [ $cword -eq $argpos ]; then + __ostree_compreply_commits + elif [ $cword -eq $(($argpos + 1)) ]; then + __ostree_compreply_dirs_only + fi + ;; + esac + + return 0 +} + +_ostree_checkout() { + local boolean_options=" + $main_boolean_options + --allow-noent + --bareuseronly-dirs -M + --disable-cache + --force-copy -C + --from-stdin + --require-hardlinks -H + --union + --union-add + --user-mode -U + --whiteouts + " + + local options_with_args=" + --from-file + --fsync + --repo + --subpath + " + + local options_with_args_glob=$( __ostree_to_extglob "$options_with_args" ) + + case "$prev" in + --from-file) + __ostree_compreply_all_files + return 0 + ;; + --repo|--subpath) + __ostree_compreply_dirs_only + return 0 + ;; + $options_with_args_glob ) + return 0 + ;; + esac + + case "$cur" in + -*) + local all_options="$boolean_options $options_with_args" + __ostree_compreply_all_options + ;; + *) + local argpos=$( __ostree_pos_first_nonflag $( __ostree_to_alternatives "$options_with_args" ) ) + + if [ $cword -eq $argpos ]; then + __ostree_compreply_commits + elif [ $cword -eq $(($argpos + 1)) ]; then + __ostree_compreply_dirs_only + fi + esac + + return 0 +} + +_ostree_checksum() { + local boolean_options=" + $main_boolean_options + " + + case "$cur" in + -*) + local all_options="$boolean_options" + __ostree_compreply_all_options + ;; + *) + local argpos=$( __ostree_pos_first_nonflag $( __ostree_to_alternatives "") ) + + if [ $cword -eq $argpos ]; then + __ostree_compreply_all_files + fi + ;; + esac + + return 0 +} + +_ostree_commit() { + local boolean_options=" + $main_boolean_options + --canonical-permissions + --editor -e + --generate-sizes + --link-checkout-speedup + --no-xattrs + --orphan + --skip-if-unchanged + --table-output + --tar-autocreate-parents + " + + local options_with_args=" + --add-detached-metadata-string + --add-metadata-string + --bind-ref + --body -m + --body-file -F + --branch -b + --fsync + --gpg-homedir + --gpg-sign + --owner-gid + --owner-uid + --parent + --repo + --skip-list + --statoverride + --subject -s + --timestamp + --tree + " + + local options_with_args_glob=$( __ostree_to_extglob "$options_with_args" ) + + case "$prev" in + --body-file|--skip-list|--statoverride) + __ostree_compreply_all_files + return 0 + ;; + --gpg-homedir|--repo) + __ostree_compreply_dirs_only + return 0 + ;; + --bind-ref) + __ostree_compreply_refs + return 0 + ;; + --parent) + __ostree_compreply_commits + return 0 + ;; + $options_with_args_glob ) + return 0 + ;; + esac + + case "$cur" in + -*) + local all_options="$boolean_options $options_with_args" + __ostree_compreply_all_options + ;; + *) + local argpos=$( __ostree_pos_first_nonflag $( __ostree_to_alternatives "$options_with_args" ) ) + + if [ $cword -eq $argpos ]; then + __ostree_compreply_all_files + fi + esac + + return 0 +} + +_ostree_config() { + local boolean_options=" + $main_boolean_options + " + + local options_with_args=" + --repo + " + + local options_with_args_glob=$( __ostree_to_extglob "$options_with_args" ) + + case "$prev" in + --repo) + __ostree_compreply_dirs_only + return 0 + ;; + $options_with_args_glob ) + return 0 + ;; + esac + + case "$cur" in + -*) + local all_options="$boolean_options $options_with_args" + __ostree_compreply_all_options + ;; + esac + + return 0 +} + +_ostree_diff() { + local boolean_options=" + $main_boolean_options + --fs-diff + --no-xattrs + --stats + " + + local options_with_args=" + --owner-gid + --owner-uid + --repo + " + + local options_with_args_glob=$( __ostree_to_extglob "$options_with_args" ) + + case "$prev" in + --repo) + __ostree_compreply_dirs_only + return 0 + ;; + $options_with_args_glob ) + return 0 + ;; + esac + + case "$cur" in + -*) + local all_options="$boolean_options $options_with_args" + __ostree_compreply_all_options + ;; + *) + local argpos=$( __ostree_pos_first_nonflag $( __ostree_to_alternatives "$options_with_args" ) ) + + if [ $cword -eq $argpos ]; then + __ostree_compreply_revisions + elif [ $cword -eq $(($argpos + 1)) ]; then + __ostree_compreply_dirs_only + fi + esac + + return 0 +} + +_ostree_export() { + local boolean_options=" + $main_boolean_options + --no-xattrs + " + + local options_with_args=" + --output -o + --prefix + --repo + --subpath + " + + local options_with_args_glob=$( __ostree_to_extglob "$options_with_args" ) + + case "$prev" in + --prefix|--repo|--subpath) + __ostree_compreply_dirs_only + return 0 + ;; + $options_with_args_glob ) + return 0 + ;; + esac + + case "$cur" in + -*) + local all_options="$boolean_options $options_with_args" + __ostree_compreply_all_options + ;; + *) + local argpos=$( __ostree_pos_first_nonflag $( __ostree_to_alternatives "$options_with_args" ) ) + + if [ $cword -eq $argpos ]; then + __ostree_compreply_commits + fi + esac + + return 0 +} + +_ostree_fsck() { + local boolean_options=" + $main_boolean_options + --add-tombstones + --delete + --quiet -q + " + + local options_with_args=" + --repo + " + + local options_with_args_glob=$( __ostree_to_extglob "$options_with_args" ) + + case "$prev" in + --repo) + __ostree_compreply_dirs_only + return 0 + ;; + $options_with_args_glob ) + return 0 + ;; + esac + + case "$cur" in + -*) + local all_options="$boolean_options $options_with_args" + __ostree_compreply_all_options + ;; + esac + + return 0 +} + +_ostree_gpg_sign() { + local boolean_options=" + $main_boolean_options + --delete -d + " + + local options_with_args=" + --gpg-homedir + --repo + " + + local options_with_args_glob=$( __ostree_to_extglob "$options_with_args" ) + + case "$prev" in + --gpg-homedir|--repo) + __ostree_compreply_dirs_only + return 0 + ;; + $options_with_args_glob ) + return 0 + ;; + esac + + case "$cur" in + -*) + local all_options="$boolean_options $options_with_args" + __ostree_compreply_all_options + ;; + *) + local argpos=$( __ostree_pos_first_nonflag $( __ostree_to_alternatives "$options_with_args" ) ) + + if [ $cword -eq $argpos ]; then + __ostree_compreply_commits + fi + esac + + return 0 +} + +_ostree_init() { + local boolean_options=" + $main_boolean_options + " + + local options_with_args=" + --mode + --repo + " + + local options_with_args_glob=$( __ostree_to_extglob "$options_with_args" ) + + case "$prev" in + --mode) + COMPREPLY=( $( compgen -W "bare archive-z2" -- "$cur" ) ) + return 0 + ;; + --repo) + __ostree_compreply_dirs_only + return 0 + ;; + $options_with_args_glob ) + return 0 + ;; + esac + + case "$cur" in + -*) + local all_options="$boolean_options $options_with_args" + __ostree_compreply_all_options + ;; + esac + + return 0 +} + +_ostree_log() { + local boolean_options=" + $main_boolean_options + --raw + " + + local options_with_args=" + --repo + " + + local options_with_args_glob=$( __ostree_to_extglob "$options_with_args" ) + + case "$prev" in + --repo) + __ostree_compreply_dirs_only + return 0 + ;; + $options_with_args_glob ) + return 0 + ;; + esac + + case "$cur" in + -*) + local all_options="$boolean_options $options_with_args" + __ostree_compreply_all_options + ;; + *) + local argpos=$( __ostree_pos_first_nonflag $( __ostree_to_alternatives "$options_with_args" ) ) + + if [ $cword -eq $argpos ]; then + __ostree_compreply_revisions + fi + esac + + return 0 +} + +_ostree_ls() { + local boolean_options=" + $main_boolean_options + --checksum -C + --dironly -d + --nul-filenames-only + --recursive -R + --xattrs -X + " + + local options_with_args=" + --repo + " + + local options_with_args_glob=$( __ostree_to_extglob "$options_with_args" ) + + case "$prev" in + --repo) + __ostree_compreply_dirs_only + return 0 + ;; + $options_with_args_glob ) + return 0 + ;; + esac + + case "$cur" in + -*) + local all_options="$boolean_options $options_with_args" + __ostree_compreply_all_options + ;; + *) + local argpos=$( __ostree_pos_first_nonflag $( __ostree_to_alternatives "$options_with_args" ) ) + + if [ $cword -eq $argpos ]; then + __ostree_compreply_revisions + return 0 + fi + + __ostree_compreply_all_files + esac + + return 0 +} + +_ostree_prune() { + local boolean_options=" + $main_boolean_options + --no-prune + --refs-only + --static-deltas-only + " + + local options_with_args=" + --delete-commit + --depth + --keep-younger-than + --repo + --retain-branch-depth + " + + local options_with_args_glob=$( __ostree_to_extglob "$options_with_args" ) + + case "$prev" in + --delete-commit) + __ostree_compreply_commits + return 0 + ;; + --repo) + __ostree_compreply_dirs_only + return 0 + ;; + $options_with_args_glob ) + return 0 + ;; + esac + + case "$cur" in + -*) + local all_options="$boolean_options $options_with_args" + __ostree_compreply_all_options + ;; + esac + + return 0 +} + +_ostree_pull_local() { + local boolean_options=" + $main_boolean_options + --bareuseronly-files + --disable-fsync + --gpg-verify + --gpg-verify-summary + --require-static-deltas + --untrusted + " + + local options_with_args=" + --depth + --remote + --repo + " + + local options_with_args_glob=$( __ostree_to_extglob "$options_with_args" ) + + case "$prev" in + --remote) + __ostree_compreply_remotes + return 0 + ;; + --repo) + __ostree_compreply_dirs_only + return 0 + ;; + $options_with_args_glob ) + return 0 + ;; + esac + + case "$cur" in + -*) + local all_options="$boolean_options $options_with_args" + __ostree_compreply_all_options + ;; + *) + local argpos=$( __ostree_pos_first_nonflag $( __ostree_to_alternatives "$options_with_args" ) ) + + if [ $cword -eq $argpos ]; then + __ostree_compreply_dirs_only + return 0 + fi + + __ostree_revisions + esac + + return 0 +} + +_ostree_pull() { + local boolean_options=" + $main_boolean_options + --commit-metadata-only + --cache-dir + --disable-fsync + --disable-static-deltas + --require-static-deltas + --mirror + --untrusted + --bareuseronly-files + --dry-run + " + + local options_with_args=" + --depth + --http-header + --localcache-repo -L + --repo + --subpath + --update-frequency + --url + " + + local options_with_args_glob=$( __ostree_to_extglob "$options_with_args" ) + + case "$prev" in + --localcache-repo|-L|--repo|--subpath) + __ostree_compreply_dirs_only + return 0 + ;; + $options_with_args_glob ) + return 0 + ;; + esac + + case "$cur" in + -*) + local all_options="$boolean_options $options_with_args" + __ostree_compreply_all_options + ;; + *) + local argpos=$( __ostree_pos_first_nonflag $( __ostree_to_alternatives "$options_with_args" ) ) + + if [ $cword -eq $argpos ]; then + __ostree_compreply_remotes + fi + esac + + return 0 +} + +_ostree_refs() { + local boolean_options=" + $main_boolean_options + --alias -A + --delete + --list + " + + local options_with_args=" + --create + --repo + " + + local options_with_args_glob=$( __ostree_to_extglob "$options_with_args" ) + + case "$prev" in + --repo) + __ostree_compreply_dirs_only + return 0 + ;; + $options_with_args_glob ) + return 0 + ;; + esac + + case "$cur" in + -*) + local all_options="$boolean_options $options_with_args" + __ostree_compreply_all_options + ;; + esac + + return 0 +} + +_ostree_remote_add() { + local boolean_options=" + $main_boolean_options + --if-not-exists + --no-gpg-verify + " + + local options_with_args=" + --contenturl + --gpg-import + --repo + --set + --sysroot + " + + local options_with_args_glob=$( __ostree_to_extglob "$options_with_args" ) + + case "$prev" in + --repo|--sysroot) + __ostree_compreply_dirs_only + return 0 + ;; + --gpg-import) + __ostree_compreply_all_files + return 0 + ;; + $options_with_args_glob ) + return 0 + ;; + esac + + case "$cur" in + -*) + local all_options="$boolean_options $options_with_args" + __ostree_compreply_all_options + ;; + esac + + return 0 +} + +_ostree_remote_add_cookie() { + local boolean_options=" + $main_boolean_options + " + + local options_with_args=" + --repo + " + + local options_with_args_glob=$( __ostree_to_extglob "$options_with_args" ) + + case "$prev" in + --repo) + __ostree_compreply_dirs_only + return 0 + ;; + esac + + case "$cur" in + -*) + local all_options="$boolean_options $options_with_args" + __ostree_compreply_all_options + ;; + *) + local argpos=$( __ostree_pos_first_nonflag $( __ostree_to_alternatives "$options_with_args" ) ) + + if [ $cword -eq $argpos ]; then + __ostree_compreply_remotes + fi + esac + + return 0 +} + +_ostree_remote_delete() { + local boolean_options=" + $main_boolean_options + --if-exists + " + + local options_with_args=" + --repo + --sysroot + " + + local options_with_args_glob=$( __ostree_to_extglob "$options_with_args" ) + + case "$prev" in + --repo|--sysroot) + __ostree_compreply_dirs_only + return 0 + ;; + esac + + case "$cur" in + -*) + local all_options="$boolean_options $options_with_args" + __ostree_compreply_all_options + ;; + *) + local argpos=$( __ostree_pos_first_nonflag $( __ostree_to_alternatives "$options_with_args" ) ) + + if [ $cword -eq $argpos ]; then + __ostree_compreply_remotes + fi + esac + + return 0 +} + +_ostree_remote_delete_cookie() { + local boolean_options=" + $main_boolean_options + " + + local options_with_args=" + --repo + " + + local options_with_args_glob=$( __ostree_to_extglob "$options_with_args" ) + + case "$prev" in + --repo) + __ostree_compreply_dirs_only + return 0 + ;; + esac + + case "$cur" in + -*) + local all_options="$boolean_options $options_with_args" + __ostree_compreply_all_options + ;; + *) + local argpos=$( __ostree_pos_first_nonflag $( __ostree_to_alternatives "$options_with_args" ) ) + + if [ $cword -eq $argpos ]; then + __ostree_compreply_remotes + fi + esac + + return 0 +} + +_ostree_remote_gpg_import() { + local boolean_options=" + $main_boolean_options + --stdin + " + + local options_with_args=" + --keyfile -k + --repo + " + + local options_with_args_glob=$( __ostree_to_extglob "$options_with_args" ) + + case "$prev" in + --keyfile|-k) + __ostree_compreply_all_files + return 0 + ;; + --repo) + __ostree_compreply_dirs_only + return 0 + ;; + esac + + case "$cur" in + -*) + local all_options="$boolean_options $options_with_args" + __ostree_compreply_all_options + ;; + *) + local argpos=$( __ostree_pos_first_nonflag $( __ostree_to_alternatives "$options_with_args" ) ) + + if [ $cword -eq $argpos ]; then + __ostree_compreply_remotes + fi + esac + + return 0 +} + +_ostree_remote_list() { + local boolean_options=" + $main_boolean_options + --show-urls -u + " + + local options_with_args=" + --repo + " + + local options_with_args_glob=$( __ostree_to_extglob "$options_with_args" ) + + case "$prev" in + --repo) + __ostree_compreply_dirs_only + return 0 + ;; + esac + + case "$cur" in + -*) + local all_options="$boolean_options $options_with_args" + __ostree_compreply_all_options + ;; + esac + + return 0 +} + +_ostree_remote_list_cookies() { + local boolean_options=" + $main_boolean_options + " + + local options_with_args=" + --repo + " + + local options_with_args_glob=$( __ostree_to_extglob "$options_with_args" ) + + case "$prev" in + --repo) + __ostree_compreply_dirs_only + return 0 + ;; + esac + + case "$cur" in + -*) + local all_options="$boolean_options $options_with_args" + __ostree_compreply_all_options + ;; + *) + local argpos=$( __ostree_pos_first_nonflag $( __ostree_to_alternatives "$options_with_args" ) ) + + if [ $cword -eq $argpos ]; then + __ostree_compreply_remotes + fi + esac + + return 0 +} + +_ostree_remote_refs() { + local boolean_options=" + $main_boolean_options + --cache-dir + " + + local options_with_args=" + --repo + " + + local options_with_args_glob=$( __ostree_to_extglob "$options_with_args" ) + + case "$prev" in + --repo) + __ostree_compreply_dirs_only + return 0 + ;; + esac + + case "$cur" in + -*) + local all_options="$boolean_options $options_with_args" + __ostree_compreply_all_options + ;; + *) + local argpos=$( __ostree_pos_first_nonflag $( __ostree_to_alternatives "$options_with_args" ) ) + + if [ $cword -eq $argpos ]; then + __ostree_compreply_remotes + fi + esac + + return 0 +} + +_ostree_remote_show_url() { + local boolean_options=" + $main_boolean_options + " + + local options_with_args=" + --repo + " + + local options_with_args_glob=$( __ostree_to_extglob "$options_with_args" ) + + case "$prev" in + --repo) + __ostree_compreply_dirs_only + return 0 + ;; + esac + + case "$cur" in + -*) + local all_options="$boolean_options $options_with_args" + __ostree_compreply_all_options + ;; + *) + local argpos=$( __ostree_pos_first_nonflag $( __ostree_to_alternatives "$options_with_args" ) ) + + if [ $cword -eq $argpos ]; then + __ostree_compreply_remotes + fi + esac + + return 0 +} + +_ostree_remote_summary() { + local boolean_options=" + $main_boolean_options + --cache-dir + --raw + " + + local options_with_args=" + --repo + " + + local options_with_args_glob=$( __ostree_to_extglob "$options_with_args" ) + + case "$prev" in + --repo) + __ostree_compreply_dirs_only + return 0 + ;; + esac + + case "$cur" in + -*) + local all_options="$boolean_options $options_with_args" + __ostree_compreply_all_options + ;; + *) + local argpos=$( __ostree_pos_first_nonflag $( __ostree_to_alternatives "$options_with_args" ) ) + + if [ $cword -eq $argpos ]; then + __ostree_compreply_remotes + fi + esac + + return 0 +} + +_ostree_remote() { + local subcommands=" + add + add-cookie + delete + delete-cookie + gpg-import + list + list-cookies + refs + show-url + summary + " + + __ostree_subcommands "$subcommands" && return 0 + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "$main_boolean_options" -- "$cur" ) ) + ;; + *) + COMPREPLY=( $( compgen -W "$subcommands" -- "$cur" ) ) + ;; + esac + + return 0 +} + +_ostree_reset() { + local boolean_options=" + $main_boolean_options + " + + local options_with_args=" + --repo + " + + local options_with_args_glob=$( __ostree_to_extglob "$options_with_args" ) + + case "$prev" in + --repo) + __ostree_compreply_dirs_only + return 0 + ;; + $options_with_args_glob ) + return 0 + ;; + esac + + case "$cur" in + -*) + local all_options="$boolean_options $options_with_args" + __ostree_compreply_all_options + ;; + *) + local argpos=$( __ostree_pos_first_nonflag $( __ostree_to_alternatives "$options_with_args" ) ) + + if [ $cword -eq $argpos ]; then + __ostree_compreply_refs + elif [ $cword -eq $(($argpos + 1)) ]; then + __ostree_compreply_commits + fi + esac + + return 0 +} + +_ostree_rev_parse() { + local boolean_options=" + $main_boolean_options + " + + local options_with_args=" + --repo + " + + local options_with_args_glob=$( __ostree_to_extglob "$options_with_args" ) + + case "$prev" in + --repo) + __ostree_compreply_dirs_only + return 0 + ;; + $options_with_args_glob ) + return 0 + ;; + esac + + case "$cur" in + -*) + local all_options="$boolean_options $options_with_args" + __ostree_compreply_all_options + ;; + *) + local argpos=$( __ostree_pos_first_nonflag $( __ostree_to_alternatives "$options_with_args" ) ) + + if [ $cword -eq $argpos ]; then + __ostree_compreply_revisions + fi + esac + + return 0 +} + +_ostree_show() { + local boolean_options=" + $main_boolean_options + --print-related + --raw + " + + local options_with_args=" + --gpg-homedir + --gpg-verify-remote + --print-detached-metadata-key + --print-metadata-key + --print-variant-type + --repo + " + + local options_with_args_glob=$( __ostree_to_extglob "$options_with_args" ) + + case "$prev" in + --gpg-homedir|--repo) + __ostree_compreply_dirs_only + return 0 + ;; + --gpg-verify-remote) + __ostree_compreply_remotes + return 0 + ;; + $options_with_args_glob ) + return 0 + ;; + esac + + case "$cur" in + -*) + local all_options="$boolean_options $options_with_args" + __ostree_compreply_all_options + ;; + esac + + return 0 +} + +_ostree_static_delta_apply_offline() { + local boolean_options=" + $main_boolean_options + " + + local options_with_args=" + --repo + " + + local options_with_args_glob=$( __ostree_to_extglob "$options_with_args" ) + + case "$prev" in + --repo) + __ostree_compreply_dirs_only + return 0 + ;; + $options_with_args_glob ) + return 0 + ;; + esac + + case "$cur" in + -*) + local all_options="$boolean_options $options_with_args" + __ostree_compreply_all_options + ;; + *) + local argpos=$( __ostree_pos_first_nonflag $( __ostree_to_alternatives "$options_with_args" ) ) + + if [ $cword -eq $argpos ]; then + __ostree_compreply_all_files + fi + esac + + return 0 +} + +_ostree_static_delta_delete() { + local boolean_options=" + $main_boolean_options + " + + local options_with_args=" + --repo + " + + local options_with_args_glob=$( __ostree_to_extglob "$options_with_args" ) + + case "$prev" in + --repo) + __ostree_compreply_dirs_only + return 0 + ;; + $options_with_args_glob ) + return 0 + ;; + esac + + case "$cur" in + -*) + local all_options="$boolean_options $options_with_args" + __ostree_compreply_all_options + ;; + esac + + return 0 +} + +_ostree_static_delta_generate() { + local boolean_options=" + $main_boolean_options + --disable-bsdiff + --empty + --in-not-exists -n + --inline + --max-bsdiff-size + --max-chunk-size + --min-fallback-size + --swap-endianness + " + + local options_with_args=" + --filename + --from + --repo + --set-endianness + --to + " + + local options_with_args_glob=$( __ostree_to_extglob "$options_with_args" ) + + case "$prev" in + --filename|--repo) + __ostree_compreply_dirs_only + return 0 + ;; + --from|--to) + __ostree_compreply_revisions + return 0 + ;; + --set-endianness) + COMPREPLY=( $( compgen -W "l B" -- "$cur" ) ) + return 0 + ;; + esac + + case "$cur" in + -*) + local all_options="$boolean_options $options_with_args" + __ostree_compreply_all_options + ;; + esac + + return 0 +} + +_ostree_static_delta_list() { + local boolean_options=" + $main_boolean_options + " + + local options_with_args=" + --repo + " + + local options_with_args_glob=$( __ostree_to_extglob "$options_with_args" ) + + case "$prev" in + --repo) + __ostree_compreply_dirs_only + return 0 + ;; + $options_with_args_glob ) + return 0 + ;; + esac + + case "$cur" in + -*) + local all_options="$boolean_options $options_with_args" + __ostree_compreply_all_options + ;; + esac + + return 0 +} + +_ostree_static_delta_show() { + local boolean_options=" + $main_boolean_options + " + + local options_with_args=" + --repo + " + + local options_with_args_glob=$( __ostree_to_extglob "$options_with_args" ) + + case "$prev" in + --repo) + __ostree_compreply_dirs_only + return 0 + ;; + $options_with_args_glob ) + return 0 + ;; + esac + + case "$cur" in + -*) + local all_options="$boolean_options $options_with_args" + __ostree_compreply_all_options + ;; + esac + + return 0 +} + +_ostree_static_delta() { + local subcommands=" + apply-offline + delete + generate + list + show + " + + __ostree_subcommands "$subcommands" && return 0 + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "$main_boolean_options" -- "$cur" ) ) + ;; + *) + COMPREPLY=( $( compgen -W "$subcommands" -- "$cur" ) ) + ;; + esac + + return 0 +} + +_ostree_summary() { + local boolean_options=" + $main_boolean_options + --raw + --update -u + --view -v + " + + local options_with_args=" + --add-metadata -m + --gpg-homedir + --gpg-sign + --repo + " + + local options_with_args_glob=$( __ostree_to_extglob "$options_with_args" ) + + case "$prev" in + --gpg-homedir|--repo) + __ostree_compreply_dirs_only + return 0 + ;; + $options_with_args_glob ) + return 0 + ;; + esac + + case "$cur" in + -*) + local all_options="$boolean_options $options_with_args" + __ostree_compreply_all_options + ;; + esac + + return 0 +} + +_ostree() { + local commands=" + admin + cat + checkout + checksum + commit + config + diff + export + fsck + gpg-sign + init + log + ls + prune + pull-local + pull + refs + remote + reset + rev-parse + show + static-delta + summary + " + + # These are always available. + local main_boolean_options=" + --help -h + --verbose -v + --version + " + + COMPREPLY=() + local cur prev words cword + + _get_comp_words_by_ref cur prev words cword + + local command='ostree' cpos=0 + local counter + + local repo_path='/sysroot/ostree/repo' + local sysroot_path='/sysroot' + + # These options can affect argument completion. + # FIXME Only recognizes the form --foo BAR, not --foo=BAR. + counter=1 + while [ $counter -lt $cword ]; do + if test "${words[$counter - 1]}" = "--repo"; then + repo_path=${words[$counter]} + elif test "${words[$counter - 1]}" = "--sysroot"; then + sysroot_path=${words[$counter]} + repo_path="$sysroot_path/ostree/repo" + fi + (( counter++ )) + done + + counter=1 + while [ $counter -lt $cword ]; do + case "${words[$counter]}" in + $main_options_with_args_glob ) + (( counter++ )) + ;; + -*) + ;; + *) + command="${words[$counter]}" + cpos=$counter + (( cpos++ )) + break + ;; + esac + (( counter++ )) + done + + local completions_func=_ostree_${command//-/_} + declare -F $completions_func >/dev/null && $completions_func + + return 0 +} + +complete -F _ostree ostree diff --git a/configure.ac b/configure.ac index 228ee84b..91dc41ab 100644 --- a/configure.ac +++ b/configure.ac @@ -88,6 +88,17 @@ AS_IF([test "$YACC" != "bison -y"], [AC_MSG_ERROR([bison not found but required] PKG_PROG_PKG_CONFIG +# PKG_CHECK_VAR added to pkg-config 0.28 +m4_define_default( + [PKG_CHECK_VAR], + [AC_ARG_VAR([$1], [value of $3 for $2, overriding pkg-config]) + AS_IF([test -z "$$1"], [$1=`$PKG_CONFIG --variable="$3" "$2"`]) + AS_IF([test -n "$$1"], [$4], [$5])]) + +PKG_CHECK_VAR(BASH_COMPLETIONSDIR, [bash-completion], [completionsdir], , + BASH_COMPLETIONSDIR="${sysconfdir}/bash_completion.d") +AC_SUBST(BASH_COMPLETIONSDIR) + AM_PATH_GLIB_2_0(,,AC_MSG_ERROR([GLib not found])) dnl When bumping the gio-unix-2.0 dependency (or glib-2.0 in general), From b669bcafe54479cf48d95293e18c5d0f3fe85ebc Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Tue, 15 Aug 2017 16:26:23 +0000 Subject: [PATCH 56/67] ostree: Add naggy comments to help keep options in sync /* ATTENTION: * Please remember to update the bash-completion script (bash/ostree) and * man page (man/ostree-$COMMANDNAME.xml) when changing the option list. */ Closes: #1080 Approved by: cgwalters --- src/ostree/ostree-trivial-httpd.c | 5 +++++ src/ostree/ot-admin-builtin-cleanup.c | 5 +++++ src/ostree/ot-admin-builtin-deploy.c | 5 +++++ src/ostree/ot-admin-builtin-diff.c | 5 +++++ src/ostree/ot-admin-builtin-init-fs.c | 5 +++++ src/ostree/ot-admin-builtin-os-init.c | 5 +++++ src/ostree/ot-admin-builtin-set-origin.c | 5 +++++ src/ostree/ot-admin-builtin-status.c | 5 +++++ src/ostree/ot-admin-builtin-switch.c | 5 +++++ src/ostree/ot-admin-builtin-undeploy.c | 5 +++++ src/ostree/ot-admin-builtin-unlock.c | 5 +++++ src/ostree/ot-admin-builtin-upgrade.c | 5 +++++ src/ostree/ot-admin-instutil-builtin-grub2-generate.c | 5 +++++ .../ot-admin-instutil-builtin-selinux-ensure-labeled.c | 5 +++++ src/ostree/ot-admin-instutil-builtin-set-kargs.c | 5 +++++ src/ostree/ot-builtin-cat.c | 5 +++++ src/ostree/ot-builtin-checkout.c | 5 +++++ src/ostree/ot-builtin-checksum.c | 5 +++++ src/ostree/ot-builtin-commit.c | 5 +++++ src/ostree/ot-builtin-config.c | 5 +++++ src/ostree/ot-builtin-diff.c | 5 +++++ src/ostree/ot-builtin-export.c | 5 +++++ src/ostree/ot-builtin-fsck.c | 5 +++++ src/ostree/ot-builtin-gpg-sign.c | 5 +++++ src/ostree/ot-builtin-init.c | 5 +++++ src/ostree/ot-builtin-log.c | 5 +++++ src/ostree/ot-builtin-ls.c | 5 +++++ src/ostree/ot-builtin-prune.c | 5 +++++ src/ostree/ot-builtin-pull-local.c | 5 +++++ src/ostree/ot-builtin-pull.c | 5 +++++ src/ostree/ot-builtin-refs.c | 5 +++++ src/ostree/ot-builtin-reset.c | 5 +++++ src/ostree/ot-builtin-rev-parse.c | 5 +++++ src/ostree/ot-builtin-show.c | 5 +++++ src/ostree/ot-builtin-static-delta.c | 4 ++++ src/ostree/ot-builtin-summary.c | 5 +++++ src/ostree/ot-remote-builtin-add-cookie.c | 4 ++++ src/ostree/ot-remote-builtin-add.c | 5 +++++ src/ostree/ot-remote-builtin-delete-cookie.c | 5 +++++ src/ostree/ot-remote-builtin-delete.c | 5 +++++ src/ostree/ot-remote-builtin-gpg-import.c | 5 +++++ src/ostree/ot-remote-builtin-list-cookies.c | 5 +++++ src/ostree/ot-remote-builtin-list.c | 5 +++++ src/ostree/ot-remote-builtin-refs.c | 5 +++++ src/ostree/ot-remote-builtin-show-url.c | 5 +++++ src/ostree/ot-remote-builtin-summary.c | 5 +++++ 46 files changed, 228 insertions(+) diff --git a/src/ostree/ostree-trivial-httpd.c b/src/ostree/ostree-trivial-httpd.c index de04e9a4..f3fd0c6c 100644 --- a/src/ostree/ostree-trivial-httpd.c +++ b/src/ostree/ostree-trivial-httpd.c @@ -56,6 +56,11 @@ typedef struct { GOutputStream *log; } OtTrivialHttpd; +/* ATTENTION: + * Please remember to update the bash-completion script (bash/ostree) and + * man page (man/ostree-trivial-httpd.xml) when changing the option list. + */ + static GOptionEntry options[] = { { "daemonize", 'd', 0, G_OPTION_ARG_NONE, &opt_daemonize, "Fork into background when ready", NULL }, { "autoexit", 0, 0, G_OPTION_ARG_NONE, &opt_autoexit, "Automatically exit when directory is deleted", NULL }, diff --git a/src/ostree/ot-admin-builtin-cleanup.c b/src/ostree/ot-admin-builtin-cleanup.c index a67b9675..13caa7f4 100644 --- a/src/ostree/ot-admin-builtin-cleanup.c +++ b/src/ostree/ot-admin-builtin-cleanup.c @@ -29,6 +29,11 @@ #include +/* ATTENTION: + * Please remember to update the bash-completion script (bash/ostree) and + * man page (man/ostree-admin-cleanup.xml) when changing the option list. + */ + static GOptionEntry options[] = { { NULL } }; diff --git a/src/ostree/ot-admin-builtin-deploy.c b/src/ostree/ot-admin-builtin-deploy.c index 085029ac..5df4923c 100644 --- a/src/ostree/ot-admin-builtin-deploy.c +++ b/src/ostree/ot-admin-builtin-deploy.c @@ -39,6 +39,11 @@ static gboolean opt_kernel_proc_cmdline; static char *opt_osname; static char *opt_origin_path; +/* ATTENTION: + * Please remember to update the bash-completion script (bash/ostree) and + * man page (man/ostree-admin-deploy.xml) when changing the option list. + */ + static GOptionEntry options[] = { { "os", 0, 0, G_OPTION_ARG_STRING, &opt_osname, "Use a different operating system root than the current one", "OSNAME" }, { "origin-file", 0, 0, G_OPTION_ARG_FILENAME, &opt_origin_path, "Specify origin file", "FILENAME" }, diff --git a/src/ostree/ot-admin-builtin-diff.c b/src/ostree/ot-admin-builtin-diff.c index 865cfca8..0419f2e1 100644 --- a/src/ostree/ot-admin-builtin-diff.c +++ b/src/ostree/ot-admin-builtin-diff.c @@ -31,6 +31,11 @@ static char *opt_osname; +/* ATTENTION: + * Please remember to update the bash-completion script (bash/ostree) and + * man page (man/ostree-admin-config-diff.xml) when changing the option list. + */ + static GOptionEntry options[] = { { "os", 0, 0, G_OPTION_ARG_STRING, &opt_osname, "Use a different operating system root than the current one", "OSNAME" }, { NULL } diff --git a/src/ostree/ot-admin-builtin-init-fs.c b/src/ostree/ot-admin-builtin-init-fs.c index 126bcb31..c1fa16b0 100644 --- a/src/ostree/ot-admin-builtin-init-fs.c +++ b/src/ostree/ot-admin-builtin-init-fs.c @@ -29,6 +29,11 @@ #include +/* ATTENTION: + * Please remember to update the bash-completion script (bash/ostree) and + * man page (man/ostree-admin-init-fs.xml) when changing the option list. + */ + static GOptionEntry options[] = { { NULL } }; diff --git a/src/ostree/ot-admin-builtin-os-init.c b/src/ostree/ot-admin-builtin-os-init.c index 117733f2..0abb8e39 100644 --- a/src/ostree/ot-admin-builtin-os-init.c +++ b/src/ostree/ot-admin-builtin-os-init.c @@ -29,6 +29,11 @@ #include +/* ATTENTION: + * Please remember to update the bash-completion script (bash/ostree) and + * man page (man/ostree-admin-os-init.xml) when changing the option list. + */ + static GOptionEntry options[] = { { NULL } }; diff --git a/src/ostree/ot-admin-builtin-set-origin.c b/src/ostree/ot-admin-builtin-set-origin.c index 36f03877..c49f575a 100644 --- a/src/ostree/ot-admin-builtin-set-origin.c +++ b/src/ostree/ot-admin-builtin-set-origin.c @@ -34,6 +34,11 @@ static int opt_index = -1; static char **opt_set; +/* ATTENTION: + * Please remember to update the bash-completion script (bash/ostree) and + * man page (man/ostree-admin-set-origin.xml) when changing the option list. + */ + static GOptionEntry options[] = { { "set", 's', 0, G_OPTION_ARG_STRING_ARRAY, &opt_set, "Set config option KEY=VALUE for remote", "KEY=VALUE" }, { "index", 0, 0, G_OPTION_ARG_INT, &opt_index, "Operate on the deployment INDEX, starting from zero", "INDEX" }, diff --git a/src/ostree/ot-admin-builtin-status.c b/src/ostree/ot-admin-builtin-status.c index f7d20337..3dd7aec5 100644 --- a/src/ostree/ot-admin-builtin-status.c +++ b/src/ostree/ot-admin-builtin-status.c @@ -29,6 +29,11 @@ #include +/* ATTENTION: + * Please remember to update the bash-completion script (bash/ostree) and + * man page (man/ostree-admin-status.xml) when changing the option list. + */ + static GOptionEntry options[] = { { NULL } }; diff --git a/src/ostree/ot-admin-builtin-switch.c b/src/ostree/ot-admin-builtin-switch.c index e54d4db5..f85e39e1 100644 --- a/src/ostree/ot-admin-builtin-switch.c +++ b/src/ostree/ot-admin-builtin-switch.c @@ -33,6 +33,11 @@ static gboolean opt_reboot; static char *opt_osname; +/* ATTENTION: + * Please remember to update the bash-completion script (bash/ostree) and + * man page (man/ostree-admin-switch.xml) when changing the option list. + */ + static GOptionEntry options[] = { { "reboot", 'r', 0, G_OPTION_ARG_NONE, &opt_reboot, "Reboot after switching trees", NULL }, { "os", 0, 0, G_OPTION_ARG_STRING, &opt_osname, "Use a different operating system root than the current one", "OSNAME" }, diff --git a/src/ostree/ot-admin-builtin-undeploy.c b/src/ostree/ot-admin-builtin-undeploy.c index be832344..c0ff89ef 100644 --- a/src/ostree/ot-admin-builtin-undeploy.c +++ b/src/ostree/ot-admin-builtin-undeploy.c @@ -28,6 +28,11 @@ #include "ostree.h" #include "otutil.h" +/* ATTENTION: + * Please remember to update the bash-completion script (bash/ostree) and + * man page (man/ostree-admin-undeploy.xml) when changing the option list. + */ + static GOptionEntry options[] = { { NULL } }; diff --git a/src/ostree/ot-admin-builtin-unlock.c b/src/ostree/ot-admin-builtin-unlock.c index 89888b53..05397414 100644 --- a/src/ostree/ot-admin-builtin-unlock.c +++ b/src/ostree/ot-admin-builtin-unlock.c @@ -33,6 +33,11 @@ static gboolean opt_hotfix; +/* ATTENTION: + * Please remember to update the bash-completion script (bash/ostree) and + * man page (man/ostree-admin-unlock.xml) when changing the option list. + */ + static GOptionEntry options[] = { { "hotfix", 0, 0, G_OPTION_ARG_NONE, &opt_hotfix, "Retain changes across reboots", NULL }, { NULL } diff --git a/src/ostree/ot-admin-builtin-upgrade.c b/src/ostree/ot-admin-builtin-upgrade.c index 105d7790..b939278c 100644 --- a/src/ostree/ot-admin-builtin-upgrade.c +++ b/src/ostree/ot-admin-builtin-upgrade.c @@ -39,6 +39,11 @@ static gboolean opt_deploy_only; static char *opt_osname; static char *opt_override_commit; +/* ATTENTION: + * Please remember to update the bash-completion script (bash/ostree) and + * man page (man/ostree-admin-upgrade.xml) when changing the option list. + */ + static GOptionEntry options[] = { { "os", 0, 0, G_OPTION_ARG_STRING, &opt_osname, "Use a different operating system root than the current one", "OSNAME" }, { "reboot", 'r', 0, G_OPTION_ARG_NONE, &opt_reboot, "Reboot after a successful upgrade", NULL }, diff --git a/src/ostree/ot-admin-instutil-builtin-grub2-generate.c b/src/ostree/ot-admin-instutil-builtin-grub2-generate.c index a634c82d..07bd1eaa 100644 --- a/src/ostree/ot-admin-instutil-builtin-grub2-generate.c +++ b/src/ostree/ot-admin-instutil-builtin-grub2-generate.c @@ -29,6 +29,11 @@ #include "otutil.h" +/* ATTENTION: + * Please remember to update the bash-completion script (bash/ostree) and + * man page (man/ostree-admin-instutil.xml) when changing the option list. + */ + static GOptionEntry options[] = { { NULL } }; diff --git a/src/ostree/ot-admin-instutil-builtin-selinux-ensure-labeled.c b/src/ostree/ot-admin-instutil-builtin-selinux-ensure-labeled.c index 77666924..c754b18a 100644 --- a/src/ostree/ot-admin-instutil-builtin-selinux-ensure-labeled.c +++ b/src/ostree/ot-admin-instutil-builtin-selinux-ensure-labeled.c @@ -174,6 +174,11 @@ selinux_relabel_dir (OstreeSePolicy *sepolicy, return ret; } +/* ATTENTION: + * Please remember to update the bash-completion script (bash/ostree) and + * man page (man/ostree-admin-instutil.xml) when changing the option list. + */ + static GOptionEntry options[] = { { NULL } }; diff --git a/src/ostree/ot-admin-instutil-builtin-set-kargs.c b/src/ostree/ot-admin-instutil-builtin-set-kargs.c index 63441ff2..1a37022c 100644 --- a/src/ostree/ot-admin-instutil-builtin-set-kargs.c +++ b/src/ostree/ot-admin-instutil-builtin-set-kargs.c @@ -35,6 +35,11 @@ static gboolean opt_merge; static char **opt_replace; static char **opt_append; +/* ATTENTION: + * Please remember to update the bash-completion script (bash/ostree) and + * man page (man/ostree-admin-instutil.xml) when changing the option list. + */ + static GOptionEntry options[] = { { "import-proc-cmdline", 0, 0, G_OPTION_ARG_NONE, &opt_proc_cmdline, "Import current /proc/cmdline", NULL }, { "merge", 0, 0, G_OPTION_ARG_NONE, &opt_merge, "Merge with previous command line", NULL }, diff --git a/src/ostree/ot-builtin-cat.c b/src/ostree/ot-builtin-cat.c index db0ffab3..9aedeb4e 100644 --- a/src/ostree/ot-builtin-cat.c +++ b/src/ostree/ot-builtin-cat.c @@ -29,6 +29,11 @@ #include +/* ATTENTION: + * Please remember to update the bash-completion script (bash/ostree) and + * man page (man/ostree-cat.xml) when changing the option list. + */ + static GOptionEntry options[] = { { NULL }, }; diff --git a/src/ostree/ot-builtin-checkout.c b/src/ostree/ot-builtin-checkout.c index eae946e5..a31d3685 100644 --- a/src/ostree/ot-builtin-checkout.c +++ b/src/ostree/ot-builtin-checkout.c @@ -61,6 +61,11 @@ parse_fsync_cb (const char *option_name, return TRUE; } +/* ATTENTION: + * Please remember to update the bash-completion script (bash/ostree) and + * man page (man/ostree-checkout.xml) when changing the option list. + */ + static GOptionEntry options[] = { { "user-mode", 'U', 0, G_OPTION_ARG_NONE, &opt_user_mode, "Do not change file ownership or initialize extended attributes", NULL }, { "disable-cache", 0, 0, G_OPTION_ARG_NONE, &opt_disable_cache, "Do not update or use the internal repository uncompressed object cache", NULL }, diff --git a/src/ostree/ot-builtin-checksum.c b/src/ostree/ot-builtin-checksum.c index 540b02a1..8c44de9e 100644 --- a/src/ostree/ot-builtin-checksum.c +++ b/src/ostree/ot-builtin-checksum.c @@ -28,6 +28,11 @@ #include +/* ATTENTION: + * Please remember to update the bash-completion script (bash/ostree) and + * man page (man/ostree-checksum.xml) when changing the option list. + */ + static GOptionEntry options[] = { { NULL } }; diff --git a/src/ostree/ot-builtin-commit.c b/src/ostree/ot-builtin-commit.c index 08120284..6d1ce060 100644 --- a/src/ostree/ot-builtin-commit.c +++ b/src/ostree/ot-builtin-commit.c @@ -72,6 +72,11 @@ parse_fsync_cb (const char *option_name, return TRUE; } +/* ATTENTION: + * Please remember to update the bash-completion script (bash/ostree) and + * man page (man/ostree-commit.xml) when changing the option list. + */ + static GOptionEntry options[] = { { "parent", 0, 0, G_OPTION_ARG_STRING, &opt_parent, "Parent ref, or \"none\"", "REF" }, { "subject", 's', 0, G_OPTION_ARG_STRING, &opt_subject, "One line subject", "SUBJECT" }, diff --git a/src/ostree/ot-builtin-config.c b/src/ostree/ot-builtin-config.c index e73398ee..6163b3b1 100644 --- a/src/ostree/ot-builtin-config.c +++ b/src/ostree/ot-builtin-config.c @@ -27,6 +27,11 @@ #include "ostree.h" #include "otutil.h" +/* ATTENTION: + * Please remember to update the bash-completion script (bash/ostree) and + * man page (man/ostree-config.xml) when changing the option list. + */ + static GOptionEntry options[] = { { NULL } }; diff --git a/src/ostree/ot-builtin-diff.c b/src/ostree/ot-builtin-diff.c index bf8a8335..e00a20fd 100644 --- a/src/ostree/ot-builtin-diff.c +++ b/src/ostree/ot-builtin-diff.c @@ -33,6 +33,11 @@ static gboolean opt_no_xattrs; static gint opt_owner_uid = -1; static gint opt_owner_gid = -1; +/* ATTENTION: + * Please remember to update the bash-completion script (bash/ostree) and + * man page (man/ostree-diff.xml) when changing the option list. + */ + static GOptionEntry options[] = { { "stats", 0, 0, G_OPTION_ARG_NONE, &opt_stats, "Print various statistics", NULL }, { "fs-diff", 0, 0, G_OPTION_ARG_NONE, &opt_fs_diff, "Print filesystem diff", NULL }, diff --git a/src/ostree/ot-builtin-export.c b/src/ostree/ot-builtin-export.c index 14960b12..aa79824e 100644 --- a/src/ostree/ot-builtin-export.c +++ b/src/ostree/ot-builtin-export.c @@ -37,6 +37,11 @@ static char *opt_subpath; static char *opt_prefix; static gboolean opt_no_xattrs; +/* ATTENTION: + * Please remember to update the bash-completion script (bash/ostree) and + * man page (man/ostree-export.xml) when changing the option list. + */ + static GOptionEntry options[] = { { "no-xattrs", 0, 0, G_OPTION_ARG_NONE, &opt_no_xattrs, "Skip output of extended attributes", NULL }, { "subpath", 0, 0, G_OPTION_ARG_FILENAME, &opt_subpath, "Checkout sub-directory PATH", "PATH" }, diff --git a/src/ostree/ot-builtin-fsck.c b/src/ostree/ot-builtin-fsck.c index 01241399..795fe098 100644 --- a/src/ostree/ot-builtin-fsck.c +++ b/src/ostree/ot-builtin-fsck.c @@ -32,6 +32,11 @@ static gboolean opt_quiet; static gboolean opt_delete; static gboolean opt_add_tombstones; +/* ATTENTION: + * Please remember to update the bash-completion script (bash/ostree) and + * man page (man/ostree-fsck.xml) when changing the option list. + */ + static GOptionEntry options[] = { { "add-tombstones", 0, 0, G_OPTION_ARG_NONE, &opt_add_tombstones, "Add tombstones for missing commits", NULL }, { "quiet", 'q', 0, G_OPTION_ARG_NONE, &opt_quiet, "Only print error messages", NULL }, diff --git a/src/ostree/ot-builtin-gpg-sign.c b/src/ostree/ot-builtin-gpg-sign.c index eace474b..8969fe86 100644 --- a/src/ostree/ot-builtin-gpg-sign.c +++ b/src/ostree/ot-builtin-gpg-sign.c @@ -31,6 +31,11 @@ static gboolean opt_delete; static char *opt_gpg_homedir; +/* ATTENTION: + * Please remember to update the bash-completion script (bash/ostree) and + * man page (man/ostree-gpg-sign.xml) when changing the option list. + */ + static GOptionEntry options[] = { { "delete", 'd', 0, G_OPTION_ARG_NONE, &opt_delete, "Delete signatures having any of the GPG KEY-IDs" }, { "gpg-homedir", 0, 0, G_OPTION_ARG_FILENAME, &opt_gpg_homedir, "GPG Homedir to use when looking for keyrings", "HOMEDIR" }, diff --git a/src/ostree/ot-builtin-init.c b/src/ostree/ot-builtin-init.c index 0dabd458..28f96829 100644 --- a/src/ostree/ot-builtin-init.c +++ b/src/ostree/ot-builtin-init.c @@ -31,6 +31,11 @@ static char *opt_mode = "bare"; static char *opt_collection_id = NULL; #endif /* OSTREE_ENABLE_EXPERIMENTAL_API */ +/* ATTENTION: + * Please remember to update the bash-completion script (bash/ostree) and + * man page (man/ostree-init.xml) when changing the option list. + */ + static GOptionEntry options[] = { { "mode", 0, 0, G_OPTION_ARG_STRING, &opt_mode, "Initialize repository in given mode (bare, archive-z2)", NULL }, #ifdef OSTREE_ENABLE_EXPERIMENTAL_API diff --git a/src/ostree/ot-builtin-log.c b/src/ostree/ot-builtin-log.c index c2210351..626793bc 100644 --- a/src/ostree/ot-builtin-log.c +++ b/src/ostree/ot-builtin-log.c @@ -30,6 +30,11 @@ static gboolean opt_raw; +/* ATTENTION: + * Please remember to update the bash-completion script (bash/ostree) and + * man page (man/ostree-log.xml) when changing the option list. + */ + static GOptionEntry options[] = { { "raw", 0, 0, G_OPTION_ARG_NONE, &opt_raw, "Show raw variant data" }, { NULL } diff --git a/src/ostree/ot-builtin-ls.c b/src/ostree/ot-builtin-ls.c index 2a9b0244..9cd82eb1 100644 --- a/src/ostree/ot-builtin-ls.c +++ b/src/ostree/ot-builtin-ls.c @@ -34,6 +34,11 @@ static gboolean opt_checksum; static gboolean opt_xattrs; static gboolean opt_nul_filenames_only; +/* ATTENTION: + * Please remember to update the bash-completion script (bash/ostree) and + * man page (man/ostree-ls.xml) when changing the option list. + */ + static GOptionEntry options[] = { { "dironly", 'd', 0, G_OPTION_ARG_NONE, &opt_dironly, "Do not recurse into directory arguments", NULL }, { "recursive", 'R', 0, G_OPTION_ARG_NONE, &opt_recursive, "Print directories recursively", NULL }, diff --git a/src/ostree/ot-builtin-prune.c b/src/ostree/ot-builtin-prune.c index 2742c375..997d848d 100644 --- a/src/ostree/ot-builtin-prune.c +++ b/src/ostree/ot-builtin-prune.c @@ -36,6 +36,11 @@ static char *opt_delete_commit; static char *opt_keep_younger_than; static char **opt_retain_branch_depth; +/* ATTENTION: + * Please remember to update the bash-completion script (bash/ostree) and + * man page (man/ostree-prune.xml) when changing the option list. + */ + static GOptionEntry options[] = { { "no-prune", 0, 0, G_OPTION_ARG_NONE, &opt_no_prune, "Only display unreachable objects; don't delete", NULL }, { "refs-only", 0, 0, G_OPTION_ARG_NONE, &opt_refs_only, "Only compute reachability via refs", NULL }, diff --git a/src/ostree/ot-builtin-pull-local.c b/src/ostree/ot-builtin-pull-local.c index 302ebd85..a4595768 100644 --- a/src/ostree/ot-builtin-pull-local.c +++ b/src/ostree/ot-builtin-pull-local.c @@ -39,6 +39,11 @@ static gboolean opt_gpg_verify; static gboolean opt_gpg_verify_summary; static int opt_depth = 0; +/* ATTENTION: + * Please remember to update the bash-completion script (bash/ostree) and + * man page (man/ostree-pull-local.xml) when changing the option list. + */ + static GOptionEntry options[] = { { "remote", 0, 0, G_OPTION_ARG_STRING, &opt_remote, "Add REMOTE to refspec", "REMOTE" }, { "disable-fsync", 0, 0, G_OPTION_ARG_NONE, &opt_disable_fsync, "Do not invoke fsync()", NULL }, diff --git a/src/ostree/ot-builtin-pull.c b/src/ostree/ot-builtin-pull.c index b07ce90b..37cfd143 100644 --- a/src/ostree/ot-builtin-pull.c +++ b/src/ostree/ot-builtin-pull.c @@ -43,6 +43,11 @@ static int opt_frequency = 0; static char* opt_url; static char** opt_localcache_repos; +/* ATTENTION: + * Please remember to update the bash-completion script (bash/ostree) and + * man page (man/ostree-pull.xml) when changing the option list. + */ + static GOptionEntry options[] = { { "commit-metadata-only", 0, 0, G_OPTION_ARG_NONE, &opt_commit_only, "Fetch only the commit metadata", NULL }, { "cache-dir", 0, 0, G_OPTION_ARG_FILENAME, &opt_cache_dir, "Use custom cache dir", NULL }, diff --git a/src/ostree/ot-builtin-refs.c b/src/ostree/ot-builtin-refs.c index 9e13a048..ead4ba48 100644 --- a/src/ostree/ot-builtin-refs.c +++ b/src/ostree/ot-builtin-refs.c @@ -34,6 +34,11 @@ static char *opt_create; static gboolean opt_collections; #endif /* OSTREE_ENABLE_EXPERIMENTAL_API */ +/* ATTENTION: + * Please remember to update the bash-completion script (bash/ostree) and + * man page (man/ostree-refs.xml) when changing the option list. + */ + static GOptionEntry options[] = { { "delete", 0, 0, G_OPTION_ARG_NONE, &opt_delete, "Delete refs which match PREFIX, rather than listing them", NULL }, { "list", 0, 0, G_OPTION_ARG_NONE, &opt_list, "Do not remove the prefix from the refs", NULL }, diff --git a/src/ostree/ot-builtin-reset.c b/src/ostree/ot-builtin-reset.c index e87f0924..744d297c 100644 --- a/src/ostree/ot-builtin-reset.c +++ b/src/ostree/ot-builtin-reset.c @@ -27,6 +27,11 @@ #include "ostree.h" #include "otutil.h" +/* ATTENTION: + * Please remember to update the bash-completion script (bash/ostree) and + * man page (man/ostree-reset.xml) when changing the option list. + */ + static GOptionEntry options[] = { { NULL } }; diff --git a/src/ostree/ot-builtin-rev-parse.c b/src/ostree/ot-builtin-rev-parse.c index 6099931a..c339a9cf 100644 --- a/src/ostree/ot-builtin-rev-parse.c +++ b/src/ostree/ot-builtin-rev-parse.c @@ -27,6 +27,11 @@ #include "ostree.h" #include "otutil.h" +/* ATTENTION: + * Please remember to update the bash-completion script (bash/ostree) and + * man page (man/ostree-rev-parse.xml) when changing the option list. + */ + static GOptionEntry options[] = { { NULL } }; diff --git a/src/ostree/ot-builtin-show.c b/src/ostree/ot-builtin-show.c index 4a510a99..30375600 100644 --- a/src/ostree/ot-builtin-show.c +++ b/src/ostree/ot-builtin-show.c @@ -36,6 +36,11 @@ static gboolean opt_raw; static char *opt_gpg_homedir; static char *opt_gpg_verify_remote; +/* ATTENTION: + * Please remember to update the bash-completion script (bash/ostree) and + * man page (man/ostree-show.xml) when changing the option list. + */ + static GOptionEntry options[] = { { "print-related", 0, 0, G_OPTION_ARG_NONE, &opt_print_related, "Show the \"related\" commits", NULL }, { "print-variant-type", 0, 0, G_OPTION_ARG_STRING, &opt_print_variant_type, "Memory map OBJECT (in this case a filename) to the GVariant type string", "TYPE" }, diff --git a/src/ostree/ot-builtin-static-delta.c b/src/ostree/ot-builtin-static-delta.c index 30de612f..7fbb1c7f 100644 --- a/src/ostree/ot-builtin-static-delta.c +++ b/src/ostree/ot-builtin-static-delta.c @@ -59,6 +59,10 @@ static OstreeCommand static_delta_subcommands[] = { { NULL, NULL } }; +/* ATTENTION: + * Please remember to update the bash-completion script (bash/ostree) and + * man page (man/ostree-static-delta.xml) when changing the option list(s). + */ static GOptionEntry generate_options[] = { { "from", 0, 0, G_OPTION_ARG_STRING, &opt_from_rev, "Create delta from revision REV", "REV" }, diff --git a/src/ostree/ot-builtin-summary.c b/src/ostree/ot-builtin-summary.c index 2f7d9729..c983a83e 100644 --- a/src/ostree/ot-builtin-summary.c +++ b/src/ostree/ot-builtin-summary.c @@ -32,6 +32,11 @@ static char **opt_key_ids; static char *opt_gpg_homedir; static char **opt_metadata; +/* ATTENTION: + * Please remember to update the bash-completion script (bash/ostree) and + * man page (man/ostree-summary.xml) when changing the option list. + */ + static GOptionEntry options[] = { { "update", 'u', 0, G_OPTION_ARG_NONE, &opt_update, "Update the summary", NULL }, { "view", 'v', 0, G_OPTION_ARG_NONE, &opt_view, "View the local summary file", NULL }, diff --git a/src/ostree/ot-remote-builtin-add-cookie.c b/src/ostree/ot-remote-builtin-add-cookie.c index 68d5590c..4edecaf9 100644 --- a/src/ostree/ot-remote-builtin-add-cookie.c +++ b/src/ostree/ot-remote-builtin-add-cookie.c @@ -28,6 +28,10 @@ #include "ostree-repo-private.h" #include "ot-remote-cookie-util.h" +/* ATTENTION: + * Please remember to update the bash-completion script (bash/ostree) and + * man page (man/ostree-remote.xml) when changing the option list. + */ static GOptionEntry option_entries[] = { { NULL } diff --git a/src/ostree/ot-remote-builtin-add.c b/src/ostree/ot-remote-builtin-add.c index c1f48969..efa9431f 100644 --- a/src/ostree/ot-remote-builtin-add.c +++ b/src/ostree/ot-remote-builtin-add.c @@ -37,6 +37,11 @@ static char *opt_collection_id; static char *opt_sysroot; static char *opt_repo; +/* ATTENTION: + * Please remember to update the bash-completion script (bash/ostree) and + * man page (man/ostree-remote.xml) when changing the option list. + */ + static GOptionEntry option_entries[] = { { "set", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_set, "Set config option KEY=VALUE for remote", "KEY=VALUE" }, { "no-gpg-verify", 0, 0, G_OPTION_ARG_NONE, &opt_no_gpg_verify, "Disable GPG verification", NULL }, diff --git a/src/ostree/ot-remote-builtin-delete-cookie.c b/src/ostree/ot-remote-builtin-delete-cookie.c index 79778f77..0838e7bf 100644 --- a/src/ostree/ot-remote-builtin-delete-cookie.c +++ b/src/ostree/ot-remote-builtin-delete-cookie.c @@ -29,6 +29,11 @@ #include "ostree-repo-private.h" #include "ot-remote-cookie-util.h" +/* ATTENTION: + * Please remember to update the bash-completion script (bash/ostree) and + * man page (man/ostree-remote.xml) when changing the option list. + */ + static GOptionEntry option_entries[] = { { NULL } }; diff --git a/src/ostree/ot-remote-builtin-delete.c b/src/ostree/ot-remote-builtin-delete.c index 65a7ada3..f10d793a 100644 --- a/src/ostree/ot-remote-builtin-delete.c +++ b/src/ostree/ot-remote-builtin-delete.c @@ -29,6 +29,11 @@ static gboolean opt_if_exists = FALSE; static char *opt_sysroot; static char *opt_repo; +/* ATTENTION: + * Please remember to update the bash-completion script (bash/ostree) and + * man page (man/ostree-remote.xml) when changing the option list. + */ + static GOptionEntry option_entries[] = { { "if-exists", 0, 0, G_OPTION_ARG_NONE, &opt_if_exists, "Do nothing if the provided remote does not exist", NULL }, { "repo", 0, 0, G_OPTION_ARG_FILENAME, &opt_repo, "Path to OSTree repository (defaults to /sysroot/ostree/repo)", "PATH" }, diff --git a/src/ostree/ot-remote-builtin-gpg-import.c b/src/ostree/ot-remote-builtin-gpg-import.c index 4df0dfe7..78a57fdf 100644 --- a/src/ostree/ot-remote-builtin-gpg-import.c +++ b/src/ostree/ot-remote-builtin-gpg-import.c @@ -34,6 +34,11 @@ static gboolean opt_stdin; static char **opt_keyrings; +/* ATTENTION: + * Please remember to update the bash-completion script (bash/ostree) and + * man page (man/ostree-remote.xml) when changing the option list. + */ + static GOptionEntry option_entries[] = { { "keyring", 'k', 0, G_OPTION_ARG_FILENAME_ARRAY, &opt_keyrings, "Import keys from a keyring file (repeatable)", "FILE" }, { "stdin", 0, 0, G_OPTION_ARG_NONE, &opt_stdin, "Import keys from standard input", NULL }, diff --git a/src/ostree/ot-remote-builtin-list-cookies.c b/src/ostree/ot-remote-builtin-list-cookies.c index 18c69035..3a83eef4 100644 --- a/src/ostree/ot-remote-builtin-list-cookies.c +++ b/src/ostree/ot-remote-builtin-list-cookies.c @@ -28,6 +28,11 @@ #include "ostree-repo-private.h" #include "ot-remote-cookie-util.h" +/* ATTENTION: + * Please remember to update the bash-completion script (bash/ostree) and + * man page (man/ostree-remote.xml) when changing the option list. + */ + static GOptionEntry option_entries[] = { { NULL } }; diff --git a/src/ostree/ot-remote-builtin-list.c b/src/ostree/ot-remote-builtin-list.c index 0769ece7..772e212f 100644 --- a/src/ostree/ot-remote-builtin-list.c +++ b/src/ostree/ot-remote-builtin-list.c @@ -25,6 +25,11 @@ static gboolean opt_show_urls; +/* ATTENTION: + * Please remember to update the bash-completion script (bash/ostree) and + * man page (man/ostree-remote.xml) when changing the option list. + */ + static GOptionEntry option_entries[] = { { "show-urls", 'u', 0, G_OPTION_ARG_NONE, &opt_show_urls, "Show remote URLs in list", NULL }, { NULL } diff --git a/src/ostree/ot-remote-builtin-refs.c b/src/ostree/ot-remote-builtin-refs.c index 9e6ee144..66c6bea0 100644 --- a/src/ostree/ot-remote-builtin-refs.c +++ b/src/ostree/ot-remote-builtin-refs.c @@ -27,6 +27,11 @@ static char* opt_cache_dir; +/* ATTENTION: + * Please remember to update the bash-completion script (bash/ostree) and + * man page (man/ostree-remote.xml) when changing the option list. + */ + static GOptionEntry option_entries[] = { { "cache-dir", 0, 0, G_OPTION_ARG_FILENAME, &opt_cache_dir, "Use custom cache dir", NULL }, { NULL } diff --git a/src/ostree/ot-remote-builtin-show-url.c b/src/ostree/ot-remote-builtin-show-url.c index c1666558..16215c62 100644 --- a/src/ostree/ot-remote-builtin-show-url.c +++ b/src/ostree/ot-remote-builtin-show-url.c @@ -25,6 +25,11 @@ #include "ot-main.h" #include "ot-remote-builtins.h" +/* ATTENTION: + * Please remember to update the bash-completion script (bash/ostree) and + * man page (man/ostree-remote.xml) when changing the option list. + */ + static GOptionEntry option_entries[] = { { NULL } }; diff --git a/src/ostree/ot-remote-builtin-summary.c b/src/ostree/ot-remote-builtin-summary.c index b7d0f0a9..ca9173ea 100644 --- a/src/ostree/ot-remote-builtin-summary.c +++ b/src/ostree/ot-remote-builtin-summary.c @@ -30,6 +30,11 @@ static gboolean opt_raw; static char* opt_cache_dir; +/* ATTENTION: + * Please remember to update the bash-completion script (bash/ostree) and + * man page (man/ostree-remote.xml) when changing the option list. + */ + static GOptionEntry option_entries[] = { { "cache-dir", 0, 0, G_OPTION_ARG_FILENAME, &opt_cache_dir, "Use custom cache dir", NULL }, { "raw", 0, 0, G_OPTION_ARG_NONE, &opt_raw, "Show raw variant data", NULL }, From 6063bdb0130cd0dc099bbf509f90863af7b3f0c0 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Wed, 2 Aug 2017 15:44:34 -0400 Subject: [PATCH 57/67] Update libglnx This is mostly the `copy_file_range` changes plus the Coverity files. ``` Colin Walters (4): localalloc: Abort on EBADF from close() by default local-alloc: Remove almost all macros like glnx_free, glnx_unref_variant console: Fix Coverity NULL deref warning fdio: Merge systemd code to use copy_file_range(), use FICLONE Jonathan Lebon (1): console: trim useless check Matthew Leeds (1): dirfd: Fix typo in comment Philip Withnall (1): glnx-console: Add missing NULL check before writing out text ``` Update submodule: libglnx Closes: #1081 Approved by: jlebon --- libglnx | 2 +- src/libostree/ostree-repo-checkout.c | 2 +- src/libostree/ostree-repo-commit.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/libglnx b/libglnx index ea6df95f..e226ccf6 160000 --- a/libglnx +++ b/libglnx @@ -1 +1 @@ -Subproject commit ea6df95f22c8f2973714bdbb8b1accc4e37d4d56 +Subproject commit e226ccf6913d1d852fde1e150a99fab508f85c34 diff --git a/src/libostree/ostree-repo-checkout.c b/src/libostree/ostree-repo-checkout.c index bfc280b6..3deaa297 100644 --- a/src/libostree/ostree-repo-checkout.c +++ b/src/libostree/ostree-repo-checkout.c @@ -122,7 +122,7 @@ write_regular_file_content (OstreeRepo *self, int infd = g_file_descriptor_based_get_fd ((GFileDescriptorBased*) input); guint64 len = g_file_info_get_size (file_info); - if (glnx_regfile_copy_bytes (infd, outfd, (off_t)len, TRUE) < 0) + if (glnx_regfile_copy_bytes (infd, outfd, (off_t)len) < 0) return glnx_throw_errno_prefix (error, "regfile copy"); } else diff --git a/src/libostree/ostree-repo-commit.c b/src/libostree/ostree-repo-commit.c index 72961dde..1c6e5e8d 100644 --- a/src/libostree/ostree-repo-commit.c +++ b/src/libostree/ostree-repo-commit.c @@ -467,7 +467,7 @@ create_regular_tmpfile_linkable_with_content (OstreeRepo *self, if (G_IS_FILE_DESCRIPTOR_BASED (input)) { int infd = g_file_descriptor_based_get_fd ((GFileDescriptorBased*) input); - if (glnx_regfile_copy_bytes (infd, tmpf.fd, (off_t)length, TRUE) < 0) + if (glnx_regfile_copy_bytes (infd, tmpf.fd, (off_t)length) < 0) return glnx_throw_errno_prefix (error, "regfile copy"); } else From fa3a31af92ec5e15d58253bd20753f6ccb07b042 Mon Sep 17 00:00:00 2001 From: Jonathan Lebon Date: Wed, 16 Aug 2017 09:10:39 -0400 Subject: [PATCH 58/67] ostree-deployment.c: simplify equality check Just a random cozy patch I made while perusing the codebase. When determining if two OstreeDeployment objects are the same, rather than just checking for NULL, we can just directly check for equality of pointers to also catch the trivial case. Closes: #1082 Approved by: cgwalters --- src/libostree/ostree-deployment.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/libostree/ostree-deployment.c b/src/libostree/ostree-deployment.c index 9fb5b028..78afe18c 100644 --- a/src/libostree/ostree-deployment.c +++ b/src/libostree/ostree-deployment.c @@ -160,7 +160,7 @@ ostree_deployment_clone (OstreeDeployment *self) new_origin = g_key_file_new (); success = g_key_file_load_from_data (new_origin, data, len, 0, NULL); g_assert (success); - + ostree_deployment_set_origin (ret, new_origin); } return ret; @@ -187,8 +187,8 @@ ostree_deployment_equal (gconstpointer ap, gconstpointer bp) { OstreeDeployment *a = (OstreeDeployment*)ap; OstreeDeployment *b = (OstreeDeployment*)bp; - - if (a == NULL && b == NULL) + + if (a == b) return TRUE; else if (a != NULL && b != NULL) return g_str_equal (ostree_deployment_get_osname (a), @@ -196,7 +196,7 @@ ostree_deployment_equal (gconstpointer ap, gconstpointer bp) g_str_equal (ostree_deployment_get_csum (a), ostree_deployment_get_csum (b)) && ostree_deployment_get_deployserial (a) == ostree_deployment_get_deployserial (b); - else + else return FALSE; } @@ -236,7 +236,7 @@ ostree_deployment_new (int index, int bootserial) { OstreeDeployment *self; - + /* index may be -1 */ g_return_val_if_fail (osname != NULL, NULL); g_return_val_if_fail (csum != NULL, NULL); From c0e20861d537730e7c5078d2f2cddda3e5a689fe Mon Sep 17 00:00:00 2001 From: Jonathan Lebon Date: Wed, 16 Aug 2017 09:10:39 -0400 Subject: [PATCH 59/67] pull: mention libcurl in NOT_SUPPORTED pull path Since it's now possible to build without libsoup but still have HTTP functionality. Closes: #1082 Approved by: cgwalters --- src/libostree/ostree-repo-pull.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libostree/ostree-repo-pull.c b/src/libostree/ostree-repo-pull.c index 337190ce..e21342fe 100644 --- a/src/libostree/ostree-repo-pull.c +++ b/src/libostree/ostree-repo-pull.c @@ -5662,7 +5662,7 @@ ostree_repo_pull_with_options (OstreeRepo *self, GError **error) { g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, - "This version of ostree was built without libsoup, and cannot fetch over HTTP"); + "This version of ostree was built without libsoup or libcurl, and cannot fetch over HTTP"); return FALSE; } @@ -5676,7 +5676,7 @@ ostree_repo_remote_fetch_summary_with_options (OstreeRepo *self, GError **error) { g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, - "This version of ostree was built without libsoup, and cannot fetch over HTTP"); + "This version of ostree was built without libsoup or libcurl, and cannot fetch over HTTP"); return FALSE; } From 76fc1ba4764c4e91349efffa4f70b9fc8a1150e9 Mon Sep 17 00:00:00 2001 From: Jonathan Lebon Date: Wed, 16 Aug 2017 09:10:39 -0400 Subject: [PATCH 60/67] ot-main.c: fix signal callback signature Signal callbacks take a void* as their final parameter, which we don't use in this case. Closes: #1082 Approved by: cgwalters --- src/ostree/ot-main.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/ostree/ot-main.c b/src/ostree/ot-main.c index 81d10b98..4d47985b 100644 --- a/src/ostree/ot-main.c +++ b/src/ostree/ot-main.c @@ -360,7 +360,8 @@ ostree_option_context_parse (GOptionContext *context, static void on_sysroot_journal_msg (OstreeSysroot *sysroot, - const char *msg) + const char *msg, + void *dummy) { g_print ("%s\n", msg); } From eb35821a5143d18104fdcde9646affcc04faa85e Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Wed, 16 Aug 2017 10:15:38 -0400 Subject: [PATCH 61/67] build-sys: Move bash completions to /usr/share/ by default This is in line with the "/etc is for sysadmins", "/usr is OS" model; e.g. systemd's bash completions go there. Making this change since I was looking at the required spec file changes. Closes: #1083 Approved by: mbarnes --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 91dc41ab..fa967e92 100644 --- a/configure.ac +++ b/configure.ac @@ -96,7 +96,7 @@ m4_define_default( AS_IF([test -n "$$1"], [$4], [$5])]) PKG_CHECK_VAR(BASH_COMPLETIONSDIR, [bash-completion], [completionsdir], , - BASH_COMPLETIONSDIR="${sysconfdir}/bash_completion.d") + BASH_COMPLETIONSDIR="${datadir}/bash-completion/completions") AC_SUBST(BASH_COMPLETIONSDIR) AM_PATH_GLIB_2_0(,,AC_MSG_ERROR([GLib not found])) From ba28684ac2acd7dd97b1deeaf34259db023bad0e Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Wed, 16 Aug 2017 12:18:22 -0400 Subject: [PATCH 62/67] lib/deploy: Really close testing race condition I added `waitpid()`, but that didn't actually help because we were `daemon()`izing. Don't daemonize if we're testing so that we can `waitpid()`. Note I still haven't reproduced this race locally, but I'm pretty sure this will fix it. While here, actually check the return value from `waitpid()` just in case something goes wrong there. Closes: #1084 Approved by: jlebon --- src/libostree/ostree-sysroot-deploy.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/libostree/ostree-sysroot-deploy.c b/src/libostree/ostree-sysroot-deploy.c index 18624640..cb84a87f 100644 --- a/src/libostree/ostree-sysroot-deploy.c +++ b/src/libostree/ostree-sysroot-deploy.c @@ -1020,10 +1020,14 @@ fsfreeze_thaw_cycle (OstreeSysroot *self, (void) close (glnx_steal_fd (&sock_parent)); /* Daemonize, and mask SIGINT/SIGTERM, so we're likely to survive e.g. * someone doing a `systemctl restart rpm-ostreed` or a Ctrl-C of - * `ostree admin upgrade`. + * `ostree admin upgrade`. We don't daemonize though if testing so + * that we can waitpid(). */ - if (daemon (0, debug_fifreeze ? 1 : 0) < 0) - err (1, "daemon"); + if (!debug_fifreeze) + { + if (daemon (0, 0) < 0) + err (1, "daemon"); + } int sigs[] = { SIGINT, SIGTERM }; for (guint i = 0; i < G_N_ELEMENTS (sigs); i++) { @@ -1086,7 +1090,10 @@ fsfreeze_thaw_cycle (OstreeSysroot *self, { int wstatus; /* Ensure the child has written its data */ - (void) TEMP_FAILURE_RETRY (waitpid (pid, &wstatus, 0)); + if (TEMP_FAILURE_RETRY (waitpid (pid, &wstatus, 0)) < 0) + return glnx_throw_errno_prefix (error, "waitpid(test-fifreeze)"); + if (!g_spawn_check_exit_status (wstatus, error)) + return glnx_prefix_error (error, "test-fifreeze: "); return glnx_throw (error, "aborting due to test-fifreeze"); } /* Do a freeze/thaw cycle; TODO add a FIFREEZETHAW ioctl */ From 40a64bcfe9d76a519eefc4df4e5491f5767bda14 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Wed, 16 Aug 2017 12:44:05 -0400 Subject: [PATCH 63/67] lib/deploy: Ignore errors from FITHAW MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In the production case since we used `daemon()` our stderr is `/dev/null`¹ there's not much use in logging errors from `FITHAW` or `exit(1)`, and doing so breaks the test suite which checks the return from `waitpid()`. There's nothing we can really do if `FITHAW` fails, and in most of those cases `EINVAL`, `EOPNOTSUPP`, we *shouldn't* do anything anyways. ¹ Though perhaps we should set up the systemd journal, but let's not go there right now. Closes: #1084 Approved by: jlebon --- src/libostree/ostree-sysroot-deploy.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/libostree/ostree-sysroot-deploy.c b/src/libostree/ostree-sysroot-deploy.c index cb84a87f..60fbc1d3 100644 --- a/src/libostree/ostree-sysroot-deploy.c +++ b/src/libostree/ostree-sysroot-deploy.c @@ -1056,13 +1056,14 @@ fsfreeze_thaw_cycle (OstreeSysroot *self, /* Do a thaw if we hit an error, or if the poll timed out */ if (r <= 0) { - if (TEMP_FAILURE_RETRY (ioctl (rootfs_dfd, FITHAW, 0)) != 0) - { - if (errno == EPERM) - ; /* Ignore this for the test suite */ - else - err (1, "FITHAW"); - } + /* Ignore errors: + * EINVAL: Not frozen + * EPERM: For running the test suite as non-root + * EOPNOTSUPP: If the filesystem doesn't support it + */ + int saved_errno = errno; + (void) TEMP_FAILURE_RETRY (ioctl (rootfs_dfd, FITHAW, 0)); + errno = saved_errno; /* But if we got an error from poll, let's log it */ if (r < 0) err (1, "poll"); From 6709aa83a839bf0fc64533890e3368340c7d15ca Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Wed, 16 Aug 2017 15:47:03 -0400 Subject: [PATCH 64/67] lib/sysroot: Port a few functions to new style Not sure why we didn't do this earlier. Just noticed them when looking at the code for a different reason. Closes: #1085 Approved by: jlebon --- src/libostree/ostree-sysroot.c | 146 ++++++++++++--------------------- 1 file changed, 54 insertions(+), 92 deletions(-) diff --git a/src/libostree/ostree-sysroot.c b/src/libostree/ostree-sysroot.c index 8d91cde6..86a4f37a 100644 --- a/src/libostree/ostree-sysroot.c +++ b/src/libostree/ostree-sysroot.c @@ -1571,6 +1571,7 @@ ostree_sysroot_simple_write_deployment (OstreeSysroot *sysroot, return ret; } +/* Deploy a copy of @target_deployment */ static gboolean clone_deployment (OstreeSysroot *sysroot, OstreeDeployment *target_deployment, @@ -1578,38 +1579,26 @@ clone_deployment (OstreeSysroot *sysroot, GCancellable *cancellable, GError **error) { - gboolean ret = FALSE; - __attribute__((cleanup(_ostree_kernel_args_cleanup))) OstreeKernelArgs *kargs = NULL; - g_autoptr(OstreeDeployment) new_deployment = NULL; - /* Ensure we have a clean slate */ if (!ostree_sysroot_prepare_cleanup (sysroot, cancellable, error)) - { - g_prefix_error (error, "Performing initial cleanup: "); - goto out; - } + return glnx_prefix_error (error, "Performing initial cleanup"); - kargs = _ostree_kernel_args_new (); + /* Copy the bootloader config options */ + OstreeBootconfigParser *bootconfig = ostree_deployment_get_bootconfig (merge_deployment); + g_auto(GStrv) previous_args = g_strsplit (ostree_bootconfig_parser_get (bootconfig, "options"), " ", -1); + __attribute__((cleanup(_ostree_kernel_args_cleanup))) OstreeKernelArgs *kargs = _ostree_kernel_args_new (); + _ostree_kernel_args_append_argv (kargs, previous_args); - { OstreeBootconfigParser *bootconfig = ostree_deployment_get_bootconfig (merge_deployment); - g_auto(GStrv) previous_args = g_strsplit (ostree_bootconfig_parser_get (bootconfig, "options"), " ", -1); - - _ostree_kernel_args_append_argv (kargs, previous_args); - } - - { - g_auto(GStrv) kargs_strv = _ostree_kernel_args_to_strv (kargs); - - if (!ostree_sysroot_deploy_tree (sysroot, - ostree_deployment_get_osname (target_deployment), - ostree_deployment_get_csum (target_deployment), - ostree_deployment_get_origin (target_deployment), - merge_deployment, - kargs_strv, - &new_deployment, - cancellable, error)) - goto out; - } + /* Deploy the copy */ + g_autoptr(OstreeDeployment) new_deployment = NULL; + g_auto(GStrv) kargs_strv = _ostree_kernel_args_to_strv (kargs); + if (!ostree_sysroot_deploy_tree (sysroot, + ostree_deployment_get_osname (target_deployment), + ostree_deployment_get_csum (target_deployment), + ostree_deployment_get_origin (target_deployment), + merge_deployment, kargs_strv, &new_deployment, + cancellable, error)) + return FALSE; /* Hotfixes push the deployment as rollback target, so it shouldn't * be the default. @@ -1618,11 +1607,9 @@ clone_deployment (OstreeSysroot *sysroot, new_deployment, merge_deployment, OSTREE_SYSROOT_SIMPLE_WRITE_DEPLOYMENT_FLAGS_NOT_DEFAULT, cancellable, error)) - goto out; - - ret = TRUE; - out: - return ret; + return FALSE; + + return TRUE; } /** @@ -1647,59 +1634,41 @@ ostree_sysroot_deployment_unlock (OstreeSysroot *self, GCancellable *cancellable, GError **error) { - gboolean ret = FALSE; - g_autoptr(OstreeSePolicy) sepolicy = NULL; - OstreeDeploymentUnlockedState current_unlocked = - ostree_deployment_get_unlocked (deployment); - g_autoptr(OstreeDeployment) deployment_clone = - ostree_deployment_clone (deployment); - g_autoptr(OstreeDeployment) merge_deployment = NULL; - GKeyFile *origin_clone = ostree_deployment_get_origin (deployment_clone); - const char hotfix_ovl_options[] = "lowerdir=usr,upperdir=.usr-ovl-upper,workdir=.usr-ovl-work"; - const char *ovl_options = NULL; - g_autofree char *deployment_path = NULL; - glnx_fd_close int deployment_dfd = -1; - pid_t mount_child; - /* This function cannot re-lock */ g_return_val_if_fail (unlocked_state != OSTREE_DEPLOYMENT_UNLOCKED_NONE, FALSE); + OstreeDeploymentUnlockedState current_unlocked = ostree_deployment_get_unlocked (deployment); if (current_unlocked != OSTREE_DEPLOYMENT_UNLOCKED_NONE) - { - g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, - "Deployment is already in unlocked state: %s", - ostree_deployment_unlocked_state_to_string (current_unlocked)); - goto out; - } + return glnx_throw (error, "Deployment is already in unlocked state: %s", + ostree_deployment_unlocked_state_to_string (current_unlocked)); - merge_deployment = ostree_sysroot_get_merge_deployment (self, ostree_deployment_get_osname (deployment)); + g_autoptr(OstreeDeployment) merge_deployment = + ostree_sysroot_get_merge_deployment (self, ostree_deployment_get_osname (deployment)); if (!merge_deployment) - { - g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, "No previous deployment to duplicate"); - goto out; - } + return glnx_throw (error, "No previous deployment to duplicate"); /* For hotfixes, we push a rollback target */ if (unlocked_state == OSTREE_DEPLOYMENT_UNLOCKED_HOTFIX) { if (!clone_deployment (self, deployment, merge_deployment, cancellable, error)) - goto out; + return FALSE; } /* Crack it open */ if (!ostree_sysroot_deployment_set_mutable (self, deployment, TRUE, cancellable, error)) - goto out; - - deployment_path = ostree_sysroot_get_deployment_dirpath (self, deployment); + return FALSE; + g_autofree char *deployment_path = ostree_sysroot_get_deployment_dirpath (self, deployment); + glnx_fd_close int deployment_dfd = -1; if (!glnx_opendirat (self->sysroot_fd, deployment_path, TRUE, &deployment_dfd, error)) - goto out; + return FALSE; - sepolicy = ostree_sepolicy_new_at (deployment_dfd, cancellable, error); + g_autoptr(OstreeSePolicy) sepolicy = ostree_sepolicy_new_at (deployment_dfd, cancellable, error); if (!sepolicy) - goto out; + return FALSE; + const char *ovl_options = NULL; switch (unlocked_state) { case OSTREE_DEPLOYMENT_UNLOCKED_NONE: @@ -1707,14 +1676,15 @@ ostree_sysroot_deployment_unlock (OstreeSysroot *self, break; case OSTREE_DEPLOYMENT_UNLOCKED_HOTFIX: { + const char hotfix_ovl_options[] = "lowerdir=usr,upperdir=.usr-ovl-upper,workdir=.usr-ovl-work"; /* Create the overlayfs directories in the deployment root * directly for hotfixes. The ostree-prepare-root.c helper * is also set up to detect and mount these. */ if (!glnx_shutil_mkdir_p_at (deployment_dfd, ".usr-ovl-upper", 0755, cancellable, error)) - goto out; + return FALSE; if (!glnx_shutil_mkdir_p_at (deployment_dfd, ".usr-ovl-work", 0755, cancellable, error)) - goto out; + return FALSE; ovl_options = hotfix_ovl_options; } break; @@ -1732,18 +1702,18 @@ ostree_sysroot_deployment_unlock (OstreeSysroot *self, if (!_ostree_sepolicy_preparefscreatecon (&con, sepolicy, "/usr", 0755, error)) - goto out; + return FALSE; if (!glnx_mkdtempat (AT_FDCWD, development_ovldir, 0755, error)) - goto out; + return FALSE; } development_ovl_upper = glnx_strjoina (development_ovldir, "/upper"); if (!glnx_shutil_mkdir_p_at (AT_FDCWD, development_ovl_upper, 0755, cancellable, error)) - goto out; + return FALSE; development_ovl_work = glnx_strjoina (development_ovldir, "/work"); if (!glnx_shutil_mkdir_p_at (AT_FDCWD, development_ovl_work, 0755, cancellable, error)) - goto out; + return FALSE; ovl_options = glnx_strjoina ("lowerdir=usr,upperdir=", development_ovl_upper, ",workdir=", development_ovl_work); } @@ -1759,12 +1729,9 @@ ostree_sysroot_deployment_unlock (OstreeSysroot *self, * threads, etc. */ { - mount_child = fork (); + pid_t mount_child = fork (); if (mount_child < 0) - { - glnx_set_prefix_error_from_errno (error, "%s", "fork"); - goto out; - } + return glnx_throw_errno_prefix (error, "fork"); else if (mount_child == 0) { /* Child process. Do NOT use any GLib API here. */ @@ -1780,18 +1747,15 @@ ostree_sysroot_deployment_unlock (OstreeSysroot *self, int estatus; if (TEMP_FAILURE_RETRY (waitpid (mount_child, &estatus, 0)) < 0) - { - glnx_set_prefix_error_from_errno (error, "%s", "waitpid() on mount helper"); - goto out; - } + return glnx_throw_errno_prefix (error, "waitpid() on mount helper"); if (!g_spawn_check_exit_status (estatus, error)) - { - g_prefix_error (error, "overlayfs mount helper: "); - goto out; - } + return glnx_throw_errno_prefix (error, "overlayfs mount helper"); } } + g_autoptr(OstreeDeployment) deployment_clone = ostree_deployment_clone (deployment); + GKeyFile *origin_clone = ostree_deployment_get_origin (deployment_clone); + /* Now, write out the flag saying what we did */ switch (unlocked_state) { @@ -1803,7 +1767,7 @@ ostree_sysroot_deployment_unlock (OstreeSysroot *self, ostree_deployment_unlocked_state_to_string (unlocked_state)); if (!ostree_sysroot_write_origin_file (self, deployment, origin_clone, cancellable, error)) - goto out; + return FALSE; break; case OSTREE_DEPLOYMENT_UNLOCKED_DEVELOPMENT: { @@ -1811,10 +1775,10 @@ ostree_sysroot_deployment_unlock (OstreeSysroot *self, g_autofree char *devpath_parent = dirname (g_strdup (devpath)); if (!glnx_shutil_mkdir_p_at (AT_FDCWD, devpath_parent, 0755, cancellable, error)) - goto out; - + return FALSE; + if (!g_file_set_contents (devpath, "", 0, error)) - goto out; + return FALSE; } } @@ -1824,9 +1788,7 @@ ostree_sysroot_deployment_unlock (OstreeSysroot *self, * regardless. */ if (!_ostree_sysroot_bump_mtime (self, error)) - goto out; + return FALSE; - ret = TRUE; - out: - return ret; + return TRUE; } From ceeefa69f501934b47d3201629c7f132b88707d9 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Wed, 16 Aug 2017 17:37:27 -0400 Subject: [PATCH 65/67] docs/related-projects: Tweak client side snapshot text, add casync The latter came up on the list. Closes: #1086 Approved by: jlebon --- docs/manual/related-projects.md | 59 ++++++++++++++++++++++++--------- 1 file changed, 44 insertions(+), 15 deletions(-) diff --git a/docs/manual/related-projects.md b/docs/manual/related-projects.md index 50076ee6..e58aeabb 100644 --- a/docs/manual/related-projects.md +++ b/docs/manual/related-projects.md @@ -20,6 +20,11 @@ a tool to snapshot systems on the client side (dpkg/rpm + BTRFS/LVM), or a tool to compose on a server and replicate (ChromiumOS, Clear Linux). OSTree is flexible enough to do both. +Note that this section of the documentation is almost entirely +focused on the "ostree for host" model; the [flatpak](https://github.com/flatpak/flatpak/) +project uses libostree to store application data, distinct from the +host system management model. + ## Combining dpkg/rpm + (BTRFS/LVM) In this approach, one uses a block/filesystem snapshot tool underneath @@ -58,25 +63,26 @@ well. In general, if one really tries to flesh out the BTRFS approach, a nontrivial middle layer of code between dpkg/rpm and BTRFS (or deep -awareness of BTRFS in dpkg/rpm itself) will be required. +awareness of BTRFS in dpkg/rpm itself) will be required. A good +example of this is the [snapper.io](http://snapper.io/) project. The OSTree author believes that having total freedom at the block -storage layer is better for general purpose operating systems. For -example, with OSTree, one is free to use BTRFS in any way you like - -you may decide to use a subvolume for `/home`, or not. +storage layer is better for general purpose operating systems. For +example, the ability to choose dm-crypt per deployment is quite useful; +not every site wants to pay the performance penalty. One can choose +LVM or not, etc. -Furthermore, in its most basic incarnation, the rpm/dpkg + BTRFS -doesn't solve the race conditions that happen when unpacking packages -into the live system, such as deleting the files underneath Firefox -while it's running. One could unpack packages into a separate root, -and switch to that, which gets closer to the OSTree architecture. +Where applicable, OSTree does take advantage of copy-on-write/reflink +features offered by the kernel for `/etc`. It uses the now generic +`ioctl(FICLONE)` and `copy_file_range()`. -Note though OSTree does take advantage of BTRFS if installed on top of -it! In particular, it will use reflink for the copies of `/etc` if -available. - -All of the above also applies if one replaces "BTRFS" with "LVM -snapshots" except for the reflinks. +Another major distinction between the default OSTree usage and package managers +is whether updates are "online" or "offline" by default. The default OSTree +design writes updates into a new root, leaving the running system unchanged. +This means preparing updates is completely non-disruptive and safe - if the +system runs out of disk space in the middle, it's easy to recover. However, +there is work in the [rpm-ostree](https://github.com/projectatomic/rpm-ostree/) +project to support online updates as well. OSTree supports using "bare-user" repositories, which do not require root to use. Using a filesystem-level layer without root is more @@ -134,6 +140,29 @@ believes that at the moment, the "CL updater" is not truly atomic in the sense that because it applies updates live, there is a window where the OS root may be inconsistent. +## casync + +The [systemd casync](https://github.com/systemd/casync) project is +relatively new. Currently, it is more of a storage library, and doesn't +support higher level logic for things like GPG signatures, versioning +information, etc. This is mostly the `OstreeRepo` layer. Moving up to +the `OstreeSysroot` level - things like managing the bootloader +configuration, and most importantly implementing correct merging for `/etc` +are missing. casync also is unaware of SELinux. + +OSTree is really today a shared library, and has been for quite some time. +This has made it easy to build higher level projects such as +[rpm-ostree](https://github.com/projectatomic/rpm-ostree/) which has quite +a bit more, such as a DBus API and other projects consume that, such as +[Cockpit](http://cockpit-project.org/). + +A major issue with casync today is that it doesn't support garbage collection +on the server side. OSTree's GC works symmetrically on the server and client +side. + +Broadly speaking, casync is a twist on the dual partition approach, and +shares the general purpose disadvantages of those. + ## Mender.io [Mender.io](https://mender.io/) is another implementation of the dual From c4148d4ddd93b23bf827387ef56ccded234b6913 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Thu, 17 Aug 2017 12:16:35 -0400 Subject: [PATCH 66/67] lib: Fix v2017.10 symbols to inherit from v2017.8 I actually don't quite know what the version inheritance really does, but let's be safe and fix this. I'm being conservative here and fixing it to inherit from 2017.8, skipping .9 since that doesn't have a parent. Related: https://github.com/ostreedev/ostree/issues/1087 Closes: #1088 Approved by: jlebon --- src/libostree/libostree-devel.sym | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/libostree/libostree-devel.sym b/src/libostree/libostree-devel.sym index 82b18667..c9bc345f 100644 --- a/src/libostree/libostree-devel.sym +++ b/src/libostree/libostree-devel.sym @@ -23,7 +23,11 @@ LIBOSTREE_2017.10 { ostree_repo_set_alias_ref_immediate; ostree_repo_open_at; ostree_repo_create_at; -}; +/* Inherit from .8 since .9 is empty and is also broken + * in that it doesn't have a parent currently; + * + */ +} LIBOSTREE_2017.8; /* Stub section for the stable release *after* this development one; don't * edit this other than to update the last number. This is just a copy/paste From 395676917b3c0dd45b4d56a3742f61b56a692c30 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Thu, 17 Aug 2017 10:25:07 -0400 Subject: [PATCH 67/67] Release 2017.10 Closes: #1089 Approved by: jlebon --- configure.ac | 2 +- src/libostree/libostree-devel.sym | 10 ---------- src/libostree/libostree-released.sym | 11 +++++++++++ tests/test-symbols.sh | 2 +- 4 files changed, 13 insertions(+), 12 deletions(-) diff --git a/configure.ac b/configure.ac index fa967e92..5c13e742 100644 --- a/configure.ac +++ b/configure.ac @@ -7,7 +7,7 @@ m4_define([year_version], [2017]) m4_define([release_version], [10]) 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 c9bc345f..01f182f6 100644 --- a/src/libostree/libostree-devel.sym +++ b/src/libostree/libostree-devel.sym @@ -18,16 +18,6 @@ ***/ /* Add new symbols here. Release commits should copy this section into -released.sym. */ -LIBOSTREE_2017.10 { - ostree_gpg_error_quark; - ostree_repo_set_alias_ref_immediate; - ostree_repo_open_at; - ostree_repo_create_at; -/* Inherit from .8 since .9 is empty and is also broken - * in that it doesn't have a parent currently; - * - */ -} LIBOSTREE_2017.8; /* Stub section for the stable release *after* this development one; don't * edit this other than to update the last number. This is just a copy/paste diff --git a/src/libostree/libostree-released.sym b/src/libostree/libostree-released.sym index 0a138966..fe98858d 100644 --- a/src/libostree/libostree-released.sym +++ b/src/libostree/libostree-released.sym @@ -416,6 +416,17 @@ global: LIBOSTREE_2017.9 { }; +LIBOSTREE_2017.10 { + ostree_gpg_error_quark; + ostree_repo_set_alias_ref_immediate; + ostree_repo_open_at; + ostree_repo_create_at; +/* Inherit from .8 since .9 is empty and is also broken + * in that it doesn't have a parent currently; + * + */ +} LIBOSTREE_2017.8; + /* 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 e6504c93..b324d1bf 100755 --- a/tests/test-symbols.sh +++ b/tests/test-symbols.sh @@ -52,7 +52,7 @@ echo 'ok documented symbols' # ONLY update this checksum in release commits! cat > released-sha256.txt <