diff options
author | Colin Walters <walters@verbum.org> | 2023-02-09 08:10:36 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-02-09 08:10:36 -0500 |
commit | cff0a1730aa753afc9fbcf323c10f7369ee925c6 (patch) | |
tree | 2abba5883d339396c6a54938c1e41cc0fac6fcdb | |
parent | 51f3d03d9bc1e39b5e47c629ae5eb9f483da56b8 (diff) | |
parent | 70ec92e1cdc3ad882ac569a3655857fb1241a449 (diff) | |
download | ostree-cff0a1730aa753afc9fbcf323c10f7369ee925c6.tar.gz |
Merge pull request #2811 from dbnicholson/cli-polish
Various CLI improvements
-rw-r--r-- | Makefile-tests.am | 1 | ||||
-rw-r--r-- | bash/ostree | 20 | ||||
-rw-r--r-- | man/ostree-find-remotes.xml | 8 | ||||
-rw-r--r-- | man/ostree-pull.xml | 8 | ||||
-rw-r--r-- | man/ostree-refs.xml | 9 | ||||
-rw-r--r-- | man/ostree-remote.xml | 33 | ||||
-rw-r--r-- | man/ostree-show.xml | 16 | ||||
-rw-r--r-- | src/ostree/ot-builtin-refs.c | 52 | ||||
-rw-r--r-- | src/ostree/ot-builtin-show.c | 77 | ||||
-rw-r--r-- | src/ostree/ot-builtin-summary.c | 49 | ||||
-rw-r--r-- | src/ostree/ot-dump.c | 60 | ||||
-rw-r--r-- | src/ostree/ot-dump.h | 6 | ||||
-rw-r--r-- | src/ostree/ot-remote-builtin-refs.c | 14 | ||||
-rw-r--r-- | src/ostree/ot-remote-builtin-summary.c | 78 | ||||
-rw-r--r-- | tests/basic-test.sh | 7 | ||||
-rwxr-xr-x | tests/test-pull-summary-sigs.sh | 10 | ||||
-rwxr-xr-x | tests/test-refs.sh | 12 | ||||
-rwxr-xr-x | tests/test-remote-refs.sh | 49 | ||||
-rwxr-xr-x | tests/test-signed-pull-summary.sh | 10 | ||||
-rwxr-xr-x | tests/test-summary-update.sh | 4 |
20 files changed, 467 insertions, 56 deletions
diff --git a/Makefile-tests.am b/Makefile-tests.am index 470eec25..01ed0bd5 100644 --- a/Makefile-tests.am +++ b/Makefile-tests.am @@ -68,6 +68,7 @@ _installed_or_uninstalled_test_scripts = \ tests/test-archivez.sh \ tests/test-remote-add.sh \ tests/test-remote-headers.sh \ + tests/test-remote-refs.sh \ tests/test-commit-sign.sh \ tests/test-commit-timestamp.sh \ tests/test-export.sh \ diff --git a/bash/ostree b/bash/ostree index 6f3b86ea..875b34ff 100644 --- a/bash/ostree +++ b/bash/ostree @@ -900,7 +900,6 @@ _ostree_pull() { local boolean_options=" $main_boolean_options --commit-metadata-only - --cache-dir --disable-fsync --disable-static-deltas --require-static-deltas @@ -912,6 +911,7 @@ _ostree_pull() { " local options_with_args=" + --cache-dir --depth --http-header --localcache-repo -L @@ -925,7 +925,7 @@ _ostree_pull() { local options_with_args_glob=$( __ostree_to_extglob "$options_with_args" ) case "$prev" in - --localcache-repo|-L|--repo|--subpath) + --cache-dir|--localcache-repo|-L|--repo|--subpath) __ostree_compreply_dirs_only return 0 ;; @@ -953,6 +953,7 @@ _ostree_pull() { _ostree_refs() { local boolean_options=" $main_boolean_options + --revision -r --alias -A --collections -c --delete @@ -1274,17 +1275,18 @@ _ostree_remote_list_gpg_keys() { _ostree_remote_refs() { local boolean_options=" $main_boolean_options - --cache-dir + --revision -r " local options_with_args=" + --cache-dir --repo " local options_with_args_glob=$( __ostree_to_extglob "$options_with_args" ) case "$prev" in - --repo) + --cache-dir|--repo) __ostree_compreply_dirs_only return 0 ;; @@ -1343,18 +1345,20 @@ _ostree_remote_show_url() { _ostree_remote_summary() { local boolean_options=" $main_boolean_options - --cache-dir + --list-metadata-keys --raw " local options_with_args=" + --cache-dir + --print-metadata-key --repo " local options_with_args_glob=$( __ostree_to_extglob "$options_with_args" ) case "$prev" in - --repo) + --cache-dir|--repo) __ostree_compreply_dirs_only return 0 ;; @@ -1484,6 +1488,8 @@ _ostree_rev_parse() { _ostree_show() { local boolean_options=" $main_boolean_options + --list-detached-metadata-keys + --list-metadata-keys --print-related --print-sizes --raw @@ -1812,6 +1818,7 @@ _ostree_static_delta() { _ostree_summary() { local boolean_options=" $main_boolean_options + --list-metadata-keys --raw --update -u --view -v @@ -1821,6 +1828,7 @@ _ostree_summary() { --add-metadata -m --gpg-homedir --gpg-sign + --print-metadata-key --repo " diff --git a/man/ostree-find-remotes.xml b/man/ostree-find-remotes.xml index 5c5b2412..eee0d123 100644 --- a/man/ostree-find-remotes.xml +++ b/man/ostree-find-remotes.xml @@ -87,6 +87,14 @@ License along with this library. If not, see <https://www.gnu.org/licenses/>. <variablelist> <varlistentry> + <term><option>--cache-dir</option>=DIR</term> + + <listitem><para> + Use an alternate cache directory in <literal>DIR</literal>. + </para></listitem> + </varlistentry> + + <varlistentry> <term><option>--disable-fsync</option></term> <listitem><para> diff --git a/man/ostree-pull.xml b/man/ostree-pull.xml index 0915dd27..b86987ba 100644 --- a/man/ostree-pull.xml +++ b/man/ostree-pull.xml @@ -66,6 +66,14 @@ License along with this library. If not, see <https://www.gnu.org/licenses/>. </varlistentry> <varlistentry> + <term><option>--cache-dir</option>=DIR</term> + + <listitem><para> + Use an alternate cache directory in <literal>DIR</literal>. + </para></listitem> + </varlistentry> + + <varlistentry> <term><option>--disable-fsync</option></term> <listitem><para> diff --git a/man/ostree-refs.xml b/man/ostree-refs.xml index 97d69fd7..b54039a3 100644 --- a/man/ostree-refs.xml +++ b/man/ostree-refs.xml @@ -99,6 +99,15 @@ License along with this library. If not, see <https://www.gnu.org/licenses/>. </varlistentry> <varlistentry> + <term><option>--revision</option>, <option>-r</option></term> + + <listitem><para> + When listing refs, also print their revisions. The revisions + will be separated by a tab character. + </para></listitem> + </varlistentry> + + <varlistentry> <term><option>--alias</option>, <option>-A</option></term> <listitem><para> diff --git a/man/ostree-remote.xml b/man/ostree-remote.xml index b14fc6d4..d107ce91 100644 --- a/man/ostree-remote.xml +++ b/man/ostree-remote.xml @@ -195,6 +195,31 @@ License along with this library. If not, see <https://www.gnu.org/licenses/>. </refsect1> <refsect1> + <title>'Refs' Options</title> + + <variablelist> + <varlistentry> + <term><option>--revision</option>, <option>-r</option></term> + + <listitem><para> + Also print the revisions for each ref. The revisions will + be separated by a tab character. + </para></listitem> + </varlistentry> + </variablelist> + + <variablelist> + <varlistentry> + <term><option>--cache-dir</option>=DIR</term> + + <listitem><para> + Use an alternate cache directory in <literal>DIR</literal>. + </para></listitem> + </varlistentry> + </variablelist> + </refsect1> + + <refsect1> <title>'GPG-Import' Options</title> <variablelist> @@ -227,6 +252,14 @@ License along with this library. If not, see <https://www.gnu.org/licenses/>. <variablelist> <varlistentry> + <term><option>--cache-dir</option>=DIR</term> + + <listitem><para> + Use an alternate cache directory in <literal>DIR</literal>. + </para></listitem> + </varlistentry> + + <varlistentry> <term><option>--raw</option></term> <listitem><para> diff --git a/man/ostree-show.xml b/man/ostree-show.xml index 4495b1e6..8d134cc4 100644 --- a/man/ostree-show.xml +++ b/man/ostree-show.xml @@ -82,6 +82,14 @@ License along with this library. If not, see <https://www.gnu.org/licenses/>. </varlistentry> <varlistentry> + <term><option>--list-metadata-keys</option></term> + + <listitem><para> + List the available metadata keys. + </para></listitem> + </varlistentry> + + <varlistentry> <term><option>--print-metadata-key</option>="KEY"</term> <listitem><para> @@ -90,6 +98,14 @@ License along with this library. If not, see <https://www.gnu.org/licenses/>. </varlistentry> <varlistentry> + <term><option>--list-detached-metadata-keys</option></term> + + <listitem><para> + List the available detached metadata keys. + </para></listitem> + </varlistentry> + + <varlistentry> <term><option>--print-detached-metadata-key</option>="KEY"</term> <listitem><para> diff --git a/src/ostree/ot-builtin-refs.c b/src/ostree/ot-builtin-refs.c index c687a5ff..c49d7507 100644 --- a/src/ostree/ot-builtin-refs.c +++ b/src/ostree/ot-builtin-refs.c @@ -27,6 +27,7 @@ static gboolean opt_delete; static gboolean opt_list; +static gboolean opt_revision; static gboolean opt_alias; static char *opt_create; static gboolean opt_collections; @@ -40,6 +41,7 @@ static gboolean opt_force; 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 }, + { "revision", 'r', 0, G_OPTION_ARG_NONE, &opt_revision, "Show revisions in listing", 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" }, { "collections", 'c', 0, G_OPTION_ARG_NONE, &opt_collections, "Enable listing collection IDs for refs", NULL }, @@ -47,6 +49,16 @@ static GOptionEntry options[] = { { NULL } }; +static int +collection_ref_cmp (OstreeCollectionRef *a, + OstreeCollectionRef *b) +{ + int ret = g_strcmp0 (a->collection_id, b->collection_id); + if (ret == 0) + ret = g_strcmp0 (a->ref_name, b->ref_name); + return ret; +} + static gboolean do_ref_with_collections (OstreeRepo *repo, const char *refspec_prefix, @@ -66,11 +78,22 @@ do_ref_with_collections (OstreeRepo *repo, if (!opt_delete && !opt_create) { - g_hash_table_iter_init (&hashiter, refs); - while (g_hash_table_iter_next (&hashiter, &hashkey, &hashvalue)) + g_autoptr(GList) ordered_keys = g_hash_table_get_keys (refs); + ordered_keys = g_list_sort (ordered_keys, (GCompareFunc) collection_ref_cmp); + + for (GList *iter = ordered_keys; iter != NULL; iter = iter->next) { - const OstreeCollectionRef *ref = hashkey; - g_print ("(%s, %s)\n", ref->collection_id, ref->ref_name); + OstreeCollectionRef *ref = iter->data; + + if (opt_revision) + { + const char *rev = g_hash_table_lookup (refs, ref); + g_print ("(%s, %s)\t%s\n", ref->collection_id, ref->ref_name, rev); + } + else + { + g_print ("(%s, %s)\n", ref->collection_id, ref->ref_name); + } } } else if (opt_create) @@ -179,12 +202,27 @@ static gboolean do_ref (OstreeRepo *repo, const char *refspec_prefix, GCancellab if (is_list) { - GLNX_HASH_TABLE_FOREACH_KV (refs, const char *, ref, const char *, value) + g_autoptr(GList) ordered_keys = g_hash_table_get_keys (refs); + ordered_keys = g_list_sort (ordered_keys, (GCompareFunc) g_strcmp0); + + for (GList *iter = ordered_keys; iter != NULL; iter = iter->next) { + const char *ref = iter->data; + if (opt_alias) - g_print ("%s -> %s\n", ref, value); + { + const char *alias = g_hash_table_lookup (refs, ref); + g_print ("%s -> %s\n", ref, alias); + } + else if (opt_revision) + { + const char *rev = g_hash_table_lookup (refs, ref); + g_print ("%s\t%s\n", ref, rev); + } else - g_print ("%s\n", ref); + { + g_print ("%s\n", ref); + } } } else if (opt_create) diff --git a/src/ostree/ot-builtin-show.c b/src/ostree/ot-builtin-show.c index 55f2b47e..9346a7b3 100644 --- a/src/ostree/ot-builtin-show.c +++ b/src/ostree/ot-builtin-show.c @@ -31,6 +31,8 @@ static gboolean opt_print_related; static char* opt_print_variant_type; static char* opt_print_metadata_key; static char* opt_print_detached_metadata_key; +static gboolean opt_list_metadata_keys; +static gboolean opt_list_detached_metadata_keys; static gboolean opt_print_sizes; static gboolean opt_raw; static gboolean opt_no_byteswap; @@ -45,7 +47,9 @@ static char *opt_gpg_verify_remote; 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" }, + { "list-metadata-keys", 0, 0, G_OPTION_ARG_NONE, &opt_list_metadata_keys, "List the available metadata keys", NULL }, { "print-metadata-key", 0, 0, G_OPTION_ARG_STRING, &opt_print_metadata_key, "Print string value of metadata key", "KEY" }, + { "list-detached-metadata-keys", 0, 0, G_OPTION_ARG_NONE, &opt_list_detached_metadata_keys, "List the available detached metadata keys", NULL }, { "print-detached-metadata-key", 0, 0, G_OPTION_ARG_STRING, &opt_print_detached_metadata_key, "Print string value of detached metadata key", "KEY" }, { "print-sizes", 0, 0, G_OPTION_ARG_NONE, &opt_print_sizes, "Show the commit size metadata", NULL }, { "raw", 0, 0, G_OPTION_ARG_NONE, &opt_raw, "Show raw variant data" }, @@ -98,12 +102,14 @@ do_print_related (OstreeRepo *repo, } static gboolean -do_print_metadata_key (OstreeRepo *repo, - const char *resolved_rev, - gboolean detached, - const char *key, - GError **error) +get_metadata (OstreeRepo *repo, + const char *resolved_rev, + gboolean detached, + GVariant **out_metadata, + GError **error) { + g_assert (out_metadata != NULL); + g_autoptr(GVariant) commit = NULL; g_autoptr(GVariant) metadata = NULL; @@ -128,6 +134,59 @@ do_print_metadata_key (OstreeRepo *repo, } } + *out_metadata = g_steal_pointer (&metadata); + + return TRUE; +} + +static gint +strptr_cmp (gconstpointer a, + gconstpointer b) +{ + const char *a_str = *((const char **) a); + const char *b_str = *((const char **) b); + + return g_strcmp0 (a_str, b_str); +} + +static gboolean +do_list_metadata_keys (OstreeRepo *repo, + const char *resolved_rev, + gboolean detached, + GError **error) +{ + g_autoptr(GVariant) metadata = NULL; + if (!get_metadata (repo, resolved_rev, detached, &metadata, error)) + return FALSE; + + GVariantIter iter; + const char *key = NULL; + g_autoptr(GPtrArray) keys = g_ptr_array_new (); + g_variant_iter_init (&iter, metadata); + while (g_variant_iter_loop (&iter, "{&s@v}", &key, NULL)) + g_ptr_array_add (keys, (gpointer) key); + + g_ptr_array_sort (keys, strptr_cmp); + for (guint i = 0; i < keys-> len; i++) + { + key = keys->pdata[i]; + g_print ("%s\n", key); + } + + return TRUE; +} + +static gboolean +do_print_metadata_key (OstreeRepo *repo, + const char *resolved_rev, + gboolean detached, + const char *key, + GError **error) +{ + g_autoptr(GVariant) metadata = NULL; + if (!get_metadata (repo, resolved_rev, detached, &metadata, error)) + return FALSE; + g_autoptr(GVariant) value = g_variant_lookup_value (metadata, key, NULL); if (!value) { @@ -321,10 +380,16 @@ ostree_builtin_show (int argc, char **argv, OstreeCommandInvocation *invocation, const char *key = detached ? opt_print_detached_metadata_key : opt_print_metadata_key; if (!ostree_repo_resolve_rev (repo, rev, FALSE, &resolved_rev, error)) return FALSE; - if (!do_print_metadata_key (repo, resolved_rev, detached, key, error)) return FALSE; } + else if (opt_list_metadata_keys || opt_list_detached_metadata_keys) + { + if (!ostree_repo_resolve_rev (repo, rev, FALSE, &resolved_rev, error)) + return FALSE; + if (!do_list_metadata_keys (repo, resolved_rev, opt_list_detached_metadata_keys, error)) + return FALSE; + } else if (opt_print_related) { if (!ostree_repo_resolve_rev (repo, rev, FALSE, &resolved_rev, error)) diff --git a/src/ostree/ot-builtin-summary.c b/src/ostree/ot-builtin-summary.c index 2d6306a4..cdfc11e6 100644 --- a/src/ostree/ot-builtin-summary.c +++ b/src/ostree/ot-builtin-summary.c @@ -28,6 +28,8 @@ #include "ostree-sign.h" static gboolean opt_update, opt_view, opt_raw; +static gboolean opt_list_metadata_keys; +static char *opt_print_metadata_key; static char **opt_gpg_key_ids; static char *opt_gpg_homedir; static char **opt_key_ids; @@ -43,6 +45,8 @@ 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 }, { "raw", 0, 0, G_OPTION_ARG_NONE, &opt_raw, "View the raw bytes of the summary file", NULL }, + { "list-metadata-keys", 0, 0, G_OPTION_ARG_NONE, &opt_list_metadata_keys, "List the available metadata keys", NULL }, + { "print-metadata-key", 0, 0, G_OPTION_ARG_STRING, &opt_print_metadata_key, "Print string value of metadata key", "KEY" }, { "gpg-sign", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_gpg_key_ids, "GPG Key ID to sign the summary with", "KEY-ID"}, { "gpg-homedir", 0, 0, G_OPTION_ARG_FILENAME, &opt_gpg_homedir, "GPG Homedir to use when looking for keyrings", "HOMEDIR"}, { "sign", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_key_ids, "Key ID to sign the summary with", "KEY-ID"}, @@ -85,6 +89,26 @@ build_additional_metadata (const char * const *args, return g_variant_ref_sink (g_variant_builder_end (builder)); } +static gboolean +get_summary_data (OstreeRepo *repo, + GBytes **out_summary_data, + GError **error) +{ + g_assert (out_summary_data != NULL); + + g_autoptr(GBytes) summary_data = NULL; + glnx_autofd int fd = -1; + if (!glnx_openat_rdonly (repo->repo_dir_fd, "summary", TRUE, &fd, error)) + return FALSE; + summary_data = ot_fd_readall_or_mmap (fd, 0, error); + if (!summary_data) + return FALSE; + + *out_summary_data = g_steal_pointer (&summary_data); + + return TRUE; +} + gboolean ostree_builtin_summary (int argc, char **argv, OstreeCommandInvocation *invocation, GCancellable *cancellable, GError **error) { @@ -275,15 +299,30 @@ ostree_builtin_summary (int argc, char **argv, OstreeCommandInvocation *invocati if (opt_raw) flags |= OSTREE_DUMP_RAW; - glnx_autofd int fd = -1; - if (!glnx_openat_rdonly (repo->repo_dir_fd, "summary", TRUE, &fd, error)) - return FALSE; - summary_data = ot_fd_readall_or_mmap (fd, 0, error); - if (!summary_data) + if (!get_summary_data (repo, &summary_data, error)) return FALSE; ot_dump_summary_bytes (summary_data, flags); } + else if (opt_list_metadata_keys) + { + g_autoptr(GBytes) summary_data = NULL; + + if (!get_summary_data (repo, &summary_data, error)) + return FALSE; + + ot_dump_summary_metadata_keys (summary_data); + } + else if (opt_print_metadata_key) + { + g_autoptr(GBytes) summary_data = NULL; + + if (!get_summary_data (repo, &summary_data, error)) + return FALSE; + + if (!ot_dump_summary_metadata_key (summary_data, opt_print_metadata_key, error)) + return FALSE; + } else { g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, diff --git a/src/ostree/ot-dump.c b/src/ostree/ot-dump.c index 509eb792..4cfac811 100644 --- a/src/ostree/ot-dump.c +++ b/src/ostree/ot-dump.c @@ -407,6 +407,66 @@ ot_dump_summary_bytes (GBytes *summary_bytes, } } +static gint +strptr_cmp (gconstpointer a, + gconstpointer b) +{ + const char *a_str = *((const char **) a); + const char *b_str = *((const char **) b); + + return g_strcmp0 (a_str, b_str); +} + +void +ot_dump_summary_metadata_keys (GBytes *summary_bytes) +{ + g_autoptr(GVariant) summary = NULL; + g_autoptr(GVariant) metadata = NULL; + + summary = g_variant_new_from_bytes (OSTREE_SUMMARY_GVARIANT_FORMAT, + summary_bytes, FALSE); + metadata = g_variant_get_child_value (summary, 1); + + GVariantIter iter; + const char *key = NULL; + g_autoptr(GPtrArray) keys = g_ptr_array_new (); + g_variant_iter_init (&iter, metadata); + while (g_variant_iter_loop (&iter, "{&s@v}", &key, NULL)) + g_ptr_array_add (keys, (gpointer) key); + + g_ptr_array_sort (keys, strptr_cmp); + for (guint i = 0; i < keys-> len; i++) + { + key = keys->pdata[i]; + g_print ("%s\n", key); + } +} + +gboolean +ot_dump_summary_metadata_key (GBytes *summary_bytes, + const char *key, + GError **error) +{ + g_autoptr(GVariant) summary = NULL; + g_autoptr(GVariant) metadata = NULL; + g_autoptr(GVariant) value = NULL; + + summary = g_variant_new_from_bytes (OSTREE_SUMMARY_GVARIANT_FORMAT, + summary_bytes, FALSE); + metadata = g_variant_get_child_value (summary, 1); + value = g_variant_lookup_value (metadata, key, NULL); + if (!value) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND, + "No such metadata key '%s'", key); + return FALSE; + } + + ot_dump_variant (value); + + return TRUE; +} + static gboolean dump_gpg_subkey (GVariant *subkey, gboolean primary, diff --git a/src/ostree/ot-dump.h b/src/ostree/ot-dump.h index 217a3964..da1a2cb2 100644 --- a/src/ostree/ot-dump.h +++ b/src/ostree/ot-dump.h @@ -41,5 +41,11 @@ void ot_dump_object (OstreeObjectType objtype, void ot_dump_summary_bytes (GBytes *summary_bytes, OstreeDumpFlags flags); +void ot_dump_summary_metadata_keys (GBytes *summary_bytes); + +gboolean ot_dump_summary_metadata_key (GBytes *summary_bytes, + const char *key, + GError **error); + gboolean ot_dump_gpg_key (GVariant *key, GError **error); diff --git a/src/ostree/ot-remote-builtin-refs.c b/src/ostree/ot-remote-builtin-refs.c index 29c39328..24ad0776 100644 --- a/src/ostree/ot-remote-builtin-refs.c +++ b/src/ostree/ot-remote-builtin-refs.c @@ -24,6 +24,7 @@ #include "ot-main.h" #include "ot-remote-builtins.h" +static gboolean opt_revision; static char* opt_cache_dir; /* ATTENTION: @@ -32,6 +33,7 @@ static char* opt_cache_dir; */ static GOptionEntry option_entries[] = { + { "revision", 'r', 0, G_OPTION_ARG_NONE, &opt_revision, "Show revisions in listing", NULL }, { "cache-dir", 0, 0, G_OPTION_ARG_FILENAME, &opt_cache_dir, "Use custom cache dir", NULL }, { NULL } }; @@ -73,7 +75,17 @@ ot_remote_builtin_refs (int argc, char **argv, OstreeCommandInvocation *invocati for (iter = ordered_keys; iter; iter = iter->next) { - g_print ("%s:%s\n", remote_name, (const char *) iter->data); + const char *ref = iter->data; + + if (opt_revision) + { + const char *rev = g_hash_table_lookup (refs, ref); + g_print ("%s:%s\t%s\n", remote_name, ref, rev); + } + else + { + g_print ("%s:%s\n", remote_name, ref); + } } } diff --git a/src/ostree/ot-remote-builtin-summary.c b/src/ostree/ot-remote-builtin-summary.c index fb2c45a3..55ccc396 100644 --- a/src/ostree/ot-remote-builtin-summary.c +++ b/src/ostree/ot-remote-builtin-summary.c @@ -25,8 +25,10 @@ #include "ot-dump.h" #include "ot-remote-builtins.h" +static gboolean opt_list_metadata_keys; static gboolean opt_raw; +static char *opt_print_metadata_key; static char* opt_cache_dir; /* ATTENTION: @@ -35,6 +37,8 @@ static char* opt_cache_dir; */ static GOptionEntry option_entries[] = { + { "list-metadata-keys", 0, 0, G_OPTION_ARG_NONE, &opt_list_metadata_keys, "List the available metadata keys", NULL }, + { "print-metadata-key", 0, 0, G_OPTION_ARG_STRING, &opt_print_metadata_key, "Print string value of metadata key", "KEY" }, { "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 }, { NULL } @@ -90,42 +94,54 @@ ot_remote_builtin_summary (int argc, char **argv, OstreeCommandInvocation *invoc goto out; } - ot_dump_summary_bytes (summary_bytes, flags); + if (opt_list_metadata_keys) + { + ot_dump_summary_metadata_keys (summary_bytes); + } + else if (opt_print_metadata_key) + { + if (!ot_dump_summary_metadata_key (summary_bytes, opt_print_metadata_key, error)) + goto out; + } + else + { + ot_dump_summary_bytes (summary_bytes, flags); #ifndef OSTREE_DISABLE_GPGME - if (!ostree_repo_remote_get_gpg_verify_summary (repo, remote_name, - &gpg_verify_summary, - error)) - goto out; - - if (!gpg_verify_summary) - g_clear_pointer (&signature_bytes, g_bytes_unref); - - /* XXX Note we don't show signatures for "--raw". My intuition is - * if someone needs to see or parse raw summary data, including - * signatures in the output would probably just interfere. - * If there's demand for it I suppose we could introduce a new - * option for raw signature data like "--raw-signatures". */ - if (signature_bytes != NULL && !opt_raw) - { - g_autoptr(OstreeGpgVerifyResult) result = NULL; - - /* The actual signed summary verification happens above in - * ostree_repo_remote_fetch_summary(). Here we just parse - * the signatures again for the purpose of printing. */ - result = ostree_repo_verify_summary (repo, - remote_name, - summary_bytes, - signature_bytes, - cancellable, - error); - if (result == NULL) + if (!ostree_repo_remote_get_gpg_verify_summary (repo, remote_name, + &gpg_verify_summary, + error)) goto out; - g_print ("\n"); - ostree_print_gpg_verify_result (result); - } + if (!gpg_verify_summary) + g_clear_pointer (&signature_bytes, g_bytes_unref); + + /* XXX Note we don't show signatures for "--raw". My intuition is + * if someone needs to see or parse raw summary data, including + * signatures in the output would probably just interfere. + * If there's demand for it I suppose we could introduce a new + * option for raw signature data like "--raw-signatures". */ + if (signature_bytes != NULL && !opt_raw) + { + g_autoptr(OstreeGpgVerifyResult) result = NULL; + + /* The actual signed summary verification happens above in + * ostree_repo_remote_fetch_summary(). Here we just parse + * the signatures again for the purpose of printing. */ + result = ostree_repo_verify_summary (repo, + remote_name, + summary_bytes, + signature_bytes, + cancellable, + error); + if (result == NULL) + goto out; + + g_print ("\n"); + ostree_print_gpg_verify_result (result); + } #endif /* OSTREE_DISABLE_GPGME */ + } ret = TRUE; out: diff --git a/tests/basic-test.sh b/tests/basic-test.sh index f97f6fc3..e2a7d70c 100644 --- a/tests/basic-test.sh +++ b/tests/basic-test.sh @@ -1006,6 +1006,13 @@ $OSTREE show -B --print-metadata-key=SOMENUM test2 > test2-meta assert_file_has_content test2-meta "uint64 42" $OSTREE show --print-detached-metadata-key=SIGNATURE test2 > test2-meta assert_file_has_content test2-meta "HANCOCK" + +$OSTREE show --list-metadata-keys test2 > test2-meta +assert_file_has_content test2-meta "FOO" +assert_file_has_content test2-meta "KITTENS" +assert_file_has_content test2-meta "SOMENUM" +$OSTREE show --list-detached-metadata-keys test2 > test2-meta +assert_file_has_content test2-meta "SIGNATURE" echo "ok metadata commit with strings" $OSTREE commit ${COMMIT_ARGS} -b test2 --tree=ref=test2 \ diff --git a/tests/test-pull-summary-sigs.sh b/tests/test-pull-summary-sigs.sh index 03a40e46..e1b0412e 100755 --- a/tests/test-pull-summary-sigs.sh +++ b/tests/test-pull-summary-sigs.sh @@ -157,6 +157,16 @@ assert_file_has_content summary.txt "Good signature from \"Ostree Tester <test@t grep static-deltas summary.txt > static-deltas.txt assert_file_has_content static-deltas.txt \ $(${OSTREE} --repo=repo rev-parse origin:main) +${OSTREE} --repo=repo remote summary origin --list-metadata-keys > metadata +assert_file_has_content metadata "^ostree.static-deltas$" +assert_file_has_content metadata "^ostree.summary.indexed-deltas$" +assert_file_has_content metadata "^ostree.summary.last-modified$" +assert_file_has_content metadata "^ostree.summary.mode$" +assert_file_has_content metadata "^ostree.summary.tombstone-commits$" +${OSTREE} --repo=repo remote summary origin --print-metadata-key=ostree.summary.indexed-deltas > metadata +assert_file_has_content metadata "^true$" +${OSTREE} --repo=repo remote summary origin --print-metadata-key=ostree.summary.mode > metadata +assert_file_has_content metadata "^'archive-z2'$" ## Tests for handling of cached summaries while racing with remote summary updates diff --git a/tests/test-refs.sh b/tests/test-refs.sh index 3653d035..53b36f6b 100755 --- a/tests/test-refs.sh +++ b/tests/test-refs.sh @@ -42,6 +42,10 @@ done ${CMD_PREFIX} ostree --repo=repo refs | wc -l > refscount assert_file_has_content refscount "^10$" +${CMD_PREFIX} ostree --repo=repo refs > refs +sort refs > refs-sorted +assert_files_equal refs refs-sorted + ${CMD_PREFIX} ostree --repo=repo refs foo > refs assert_not_file_has_content refs foo @@ -51,6 +55,14 @@ assert_file_has_content refs foo ${CMD_PREFIX} ostree --repo=repo refs foo | wc -l > refscount.foo assert_file_has_content refscount.foo "^5$" +rm -f expected-refs-revs +for ref in foo/test-{1..5}; do + rev=$(${CMD_PREFIX} ostree --repo=repo rev-parse $ref) + echo -e "${ref}\t${rev}" >> expected-refs-revs +done +${CMD_PREFIX} ostree --repo=repo refs --list --revision foo > refs-revs +assert_files_equal refs-revs expected-refs-revs + ${CMD_PREFIX} ostree --repo=repo refs --delete 2>/dev/null || true ${CMD_PREFIX} ostree --repo=repo refs | wc -l > refscount.delete1 assert_file_has_content refscount.delete1 "^10$" diff --git a/tests/test-remote-refs.sh b/tests/test-remote-refs.sh new file mode 100755 index 00000000..b92fb20e --- /dev/null +++ b/tests/test-remote-refs.sh @@ -0,0 +1,49 @@ +#!/bin/bash +# +# Copyright © 2023 Endless OS Foundation LLC +# +# SPDX-License-Identifier: LGPL-2.0+ +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library. If not, see <https://www.gnu.org/licenses/>. +# +# Authors: +# - Dan Nicholson <dbn@endlessos.org> + +set -euo pipefail + +. $(dirname $0)/libtest.sh + +echo "1..2" + +setup_fake_remote_repo2 "archive" +${CMD_PREFIX} ostree --repo=${test_tmpdir}/ostree-srv/repo summary -u +${CMD_PREFIX} ostree --repo=${test_tmpdir}/ostree-srv/repo refs > origin-refs +${CMD_PREFIX} ostree --repo=${test_tmpdir}/ostree-srv/repo refs --revision > origin-refs-revs + +cd ${test_tmpdir} +rm -rf repo +ostree_repo_init repo --mode=archive +${OSTREE} remote add --no-sign-verify origin $(cat httpd-address)/ostree/repo + +${OSTREE} remote refs origin > refs +sed 's/^/origin:/' origin-refs > expected-refs +assert_files_equal refs expected-refs + +echo "ok remote refs listing" + +${OSTREE} remote refs origin --revision > refs-revs +sed 's/^/origin:/' origin-refs-revs > expected-refs-revs +assert_files_equal refs-revs expected-refs-revs + +echo "ok remote refs revisions" diff --git a/tests/test-signed-pull-summary.sh b/tests/test-signed-pull-summary.sh index 2d6b2552..d2873894 100755 --- a/tests/test-signed-pull-summary.sh +++ b/tests/test-signed-pull-summary.sh @@ -194,6 +194,16 @@ assert_file_has_content summary.txt "* yet-another" grep static-deltas summary.txt > static-deltas.txt assert_file_has_content static-deltas.txt \ $(${OSTREE} --repo=repo rev-parse origin:main) +${OSTREE} --repo=repo remote summary origin --list-metadata-keys > metadata +assert_file_has_content metadata "^ostree.static-deltas$" +assert_file_has_content metadata "^ostree.summary.indexed-deltas$" +assert_file_has_content metadata "^ostree.summary.last-modified$" +assert_file_has_content metadata "^ostree.summary.mode$" +assert_file_has_content metadata "^ostree.summary.tombstone-commits$" +${OSTREE} --repo=repo remote summary origin --print-metadata-key=ostree.summary.indexed-deltas > metadata +assert_file_has_content metadata "^true$" +${OSTREE} --repo=repo remote summary origin --print-metadata-key=ostree.summary.mode > metadata +assert_file_has_content metadata "^'archive-z2'$" ## Tests for handling of cached summaries while racing with remote summary updates diff --git a/tests/test-summary-update.sh b/tests/test-summary-update.sh index 74c42d10..d85e9c4b 100755 --- a/tests/test-summary-update.sh +++ b/tests/test-summary-update.sh @@ -59,6 +59,10 @@ ${CMD_PREFIX} ostree --repo=repo summary --update --add-metadata=map='@a{sv} {}' # Check the additional metadata turns up in the output. ${CMD_PREFIX} ostree --repo=repo summary --view > summary assert_file_has_content summary "^map: {}$" +${CMD_PREFIX} ostree --repo=repo summary --list-metadata-keys > metadata +assert_file_has_content metadata "^map$" +${CMD_PREFIX} ostree --repo=repo summary --print-metadata-key=map > metadata +assert_file_has_content metadata "^@a{sv} {}$" echo "ok 1 update summary" |