mirror of
https://github.com/ostreedev/ostree.git
synced 2024-12-22 17:35:55 +03:00
Merge pull request #2811 from dbnicholson/cli-polish
Various CLI improvements
This commit is contained in:
commit
cff0a1730a
@ -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 \
|
||||
|
20
bash/ostree
20
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
|
||||
"
|
||||
|
||||
|
@ -86,6 +86,14 @@ License along with this library. If not, see <https://www.gnu.org/licenses/>.
|
||||
<title>Options</title>
|
||||
|
||||
<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>
|
||||
|
||||
|
@ -65,6 +65,14 @@ License along with this library. If not, see <https://www.gnu.org/licenses/>.
|
||||
</para></listitem>
|
||||
</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>
|
||||
|
||||
|
@ -98,6 +98,15 @@ License along with this library. If not, see <https://www.gnu.org/licenses/>.
|
||||
</para></listitem>
|
||||
</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>
|
||||
|
||||
|
@ -194,6 +194,31 @@ License along with this library. If not, see <https://www.gnu.org/licenses/>.
|
||||
</variablelist>
|
||||
</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>
|
||||
|
||||
@ -226,6 +251,14 @@ License along with this library. If not, see <https://www.gnu.org/licenses/>.
|
||||
<title>'Summary' Options</title>
|
||||
|
||||
<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>
|
||||
|
||||
|
@ -81,6 +81,14 @@ License along with this library. If not, see <https://www.gnu.org/licenses/>.
|
||||
</para></listitem>
|
||||
</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>
|
||||
|
||||
@ -89,6 +97,14 @@ License along with this library. If not, see <https://www.gnu.org/licenses/>.
|
||||
</para></listitem>
|
||||
</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>
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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))
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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:
|
||||
|
@ -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 \
|
||||
|
@ -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
|
||||
|
||||
|
@ -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$"
|
||||
|
49
tests/test-remote-refs.sh
Executable file
49
tests/test-remote-refs.sh
Executable file
@ -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"
|
@ -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
|
||||
|
||||
|
@ -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"
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user