Add OstreeAsyncProgress, use it for ostree_repo_pull
Several APIs in libostree were moved there from the commandline code, and have hardcoded g_print() for progress and notifications. This isn't useful for people who want to write PackageKit backends, custom GUIs and the like. From what I can tell, there isn't really a winning precedent in GLib for progress notifications. PackageKit has the model where the source has GObject properties that change as async ops execute, which isn't bad...but I'd like something a bit more general where say you can have multiple outstanding async ops and sensibly track their state. So, OstreeAsyncProgress is basically a threadsafe property bag with a change notification signal. Use this new API to move the GSConsole usage (i.e. g_print()) out from libostree/ and into ostree/.
This commit is contained in:
parent
9aaa29598e
commit
c65923e642
|
|
@ -20,6 +20,7 @@
|
||||||
|
|
||||||
libostree_public_headers = \
|
libostree_public_headers = \
|
||||||
src/libostree/ostree.h \
|
src/libostree/ostree.h \
|
||||||
|
src/libostree/ostree-async-progress.h \
|
||||||
src/libostree/ostree-core.h \
|
src/libostree/ostree-core.h \
|
||||||
src/libostree/ostree-mutable-tree.h \
|
src/libostree/ostree-mutable-tree.h \
|
||||||
src/libostree/ostree-repo.h \
|
src/libostree/ostree-repo.h \
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@ libostreeincludedir = $(includedir)/ostree-1
|
||||||
libostreeinclude_HEADERS = $(libostree_public_headers)
|
libostreeinclude_HEADERS = $(libostree_public_headers)
|
||||||
|
|
||||||
libostree_1_la_SOURCES = \
|
libostree_1_la_SOURCES = \
|
||||||
|
src/libostree/ostree-async-progress.c \
|
||||||
src/libostree/ostree-core-private.h \
|
src/libostree/ostree-core-private.h \
|
||||||
src/libostree/ostree-core.c \
|
src/libostree/ostree-core.c \
|
||||||
src/libostree/ostree-checksum-input-stream.c \
|
src/libostree/ostree-checksum-input-stream.c \
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,8 @@
|
||||||
bin_PROGRAMS += ostree
|
bin_PROGRAMS += ostree
|
||||||
|
|
||||||
ostree_SOURCES = src/ostree/main.c \
|
ostree_SOURCES = src/ostree/main.c \
|
||||||
|
src/ostree/ot-builtins-common.h \
|
||||||
|
src/ostree/ot-builtins-common.c \
|
||||||
src/ostree/ot-builtin-admin.c \
|
src/ostree/ot-builtin-admin.c \
|
||||||
src/ostree/ot-builtins.h \
|
src/ostree/ot-builtins.h \
|
||||||
src/ostree/ot-builtin-cat.c \
|
src/ostree/ot-builtin-cat.c \
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,272 @@
|
||||||
|
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013 Colin Walters <walters@verbum.org>
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include "ostree-async-progress.h"
|
||||||
|
#include "libgsystem.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SECTION:libostree-async-progress
|
||||||
|
* @title: Progress notification system for asynchronous operations
|
||||||
|
* @short_description: Values representing progress
|
||||||
|
*
|
||||||
|
* For many asynchronous operations, it's desirable for callers to be
|
||||||
|
* able to watch their status as they progress. For example, an user
|
||||||
|
* interface calling an asynchronous download operation will want to
|
||||||
|
* be able to see the total number of bytes downloaded.
|
||||||
|
*
|
||||||
|
* This class provides a mechanism for callees of asynchronous
|
||||||
|
* operations to communicate back with callers. It transparently
|
||||||
|
* handles thread safety, ensuring that the progress change
|
||||||
|
* notification occurs in the thread-default context of the calling
|
||||||
|
* operation.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if GLIB_SIZEOF_VOID_P == 8
|
||||||
|
#define _OSTREE_HAVE_LP64 1
|
||||||
|
#else
|
||||||
|
#define _OSTREE_HAVE_LP64 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
enum {
|
||||||
|
CHANGED,
|
||||||
|
LAST_SIGNAL
|
||||||
|
};
|
||||||
|
|
||||||
|
static guint signals[LAST_SIGNAL] = { 0 };
|
||||||
|
|
||||||
|
struct OstreeAsyncProgress
|
||||||
|
{
|
||||||
|
GObject parent_instance;
|
||||||
|
|
||||||
|
GMutex lock;
|
||||||
|
GMainContext *maincontext;
|
||||||
|
GSource *idle_source;
|
||||||
|
GHashTable *uint_values;
|
||||||
|
GHashTable *uint64_values;
|
||||||
|
|
||||||
|
char *status;
|
||||||
|
};
|
||||||
|
|
||||||
|
G_DEFINE_TYPE (OstreeAsyncProgress, ostree_async_progress, G_TYPE_OBJECT)
|
||||||
|
|
||||||
|
static void
|
||||||
|
ostree_async_progress_finalize (GObject *object)
|
||||||
|
{
|
||||||
|
OstreeAsyncProgress *self;
|
||||||
|
|
||||||
|
self = OSTREE_ASYNC_PROGRESS (object);
|
||||||
|
|
||||||
|
g_mutex_clear (&self->lock);
|
||||||
|
g_clear_pointer (&self->maincontext, g_main_context_unref);
|
||||||
|
g_clear_pointer (&self->idle_source, g_source_unref);
|
||||||
|
g_hash_table_unref (self->uint_values);
|
||||||
|
g_hash_table_unref (self->uint64_values);
|
||||||
|
g_free (self->status);
|
||||||
|
|
||||||
|
G_OBJECT_CLASS (ostree_async_progress_parent_class)->finalize (object);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
ostree_async_progress_class_init (OstreeAsyncProgressClass *klass)
|
||||||
|
{
|
||||||
|
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||||
|
|
||||||
|
gobject_class->finalize = ostree_async_progress_finalize;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* OstreeAsyncProgress::changed:
|
||||||
|
* @self: Self
|
||||||
|
*
|
||||||
|
* Emitted when @self has been changed.
|
||||||
|
**/
|
||||||
|
signals[CHANGED] =
|
||||||
|
g_signal_new ("changed",
|
||||||
|
OSTREE_TYPE_ASYNC_PROGRESS,
|
||||||
|
G_SIGNAL_RUN_LAST,
|
||||||
|
G_STRUCT_OFFSET (OstreeAsyncProgressClass, changed),
|
||||||
|
NULL, NULL,
|
||||||
|
NULL,
|
||||||
|
G_TYPE_NONE, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
ostree_async_progress_init (OstreeAsyncProgress *self)
|
||||||
|
{
|
||||||
|
g_mutex_init (&self->lock);
|
||||||
|
self->maincontext = g_main_context_ref_thread_default ();
|
||||||
|
self->uint_values = g_hash_table_new (NULL, NULL);
|
||||||
|
#if _OSTREE_HAVE_LP64
|
||||||
|
self->uint64_values = g_hash_table_new (NULL, NULL);
|
||||||
|
#else
|
||||||
|
self->uint64_values = g_hash_table_new_full (NULL, NULL,
|
||||||
|
NULL, g_free);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
guint
|
||||||
|
ostree_async_progress_get_uint (OstreeAsyncProgress *self,
|
||||||
|
const char *key)
|
||||||
|
{
|
||||||
|
guint rval;
|
||||||
|
g_mutex_lock (&self->lock);
|
||||||
|
rval = GPOINTER_TO_UINT (g_hash_table_lookup (self->uint_values,
|
||||||
|
GUINT_TO_POINTER (g_quark_from_string (key))));
|
||||||
|
g_mutex_unlock (&self->lock);
|
||||||
|
return rval;
|
||||||
|
}
|
||||||
|
|
||||||
|
guint64
|
||||||
|
ostree_async_progress_get_uint64 (OstreeAsyncProgress *self,
|
||||||
|
const char *key)
|
||||||
|
{
|
||||||
|
#if _OSTREE_HAVE_LP64
|
||||||
|
guint64 rval;
|
||||||
|
g_mutex_lock (&self->lock);
|
||||||
|
rval = (guint64) g_hash_table_lookup (self->uint64_values, GUINT_TO_POINTER (g_quark_from_string (key)));
|
||||||
|
g_mutex_unlock (&self->lock);
|
||||||
|
return rval;
|
||||||
|
#else
|
||||||
|
guint64 *rval;
|
||||||
|
g_mutex_lock (&self->lock);
|
||||||
|
rval = g_hash_table_lookup (self->uint64_values, (gpointer)g_quark_from_string (key));
|
||||||
|
g_mutex_unlock (&self->lock);
|
||||||
|
if (rval)
|
||||||
|
return *rval;
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
idle_invoke_async_progress (gpointer user_data)
|
||||||
|
{
|
||||||
|
OstreeAsyncProgress *self = user_data;
|
||||||
|
|
||||||
|
g_mutex_lock (&self->lock);
|
||||||
|
self->idle_source = NULL;
|
||||||
|
g_mutex_unlock (&self->lock);
|
||||||
|
|
||||||
|
g_signal_emit (self, signals[CHANGED], 0);
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
ensure_callback_locked (OstreeAsyncProgress *self)
|
||||||
|
{
|
||||||
|
if (self->idle_source)
|
||||||
|
return;
|
||||||
|
self->idle_source = g_idle_source_new ();
|
||||||
|
g_source_set_callback (self->idle_source, idle_invoke_async_progress, self, NULL);
|
||||||
|
g_source_attach (self->idle_source, self->maincontext);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ostree_async_progress_set_status (OstreeAsyncProgress *self,
|
||||||
|
const char *status)
|
||||||
|
{
|
||||||
|
g_mutex_lock (&self->lock);
|
||||||
|
g_free (self->status);
|
||||||
|
self->status = g_strdup (status);
|
||||||
|
ensure_callback_locked (self);
|
||||||
|
g_mutex_unlock (&self->lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
char *
|
||||||
|
ostree_async_progress_get_status (OstreeAsyncProgress *self)
|
||||||
|
{
|
||||||
|
char *ret;
|
||||||
|
g_mutex_lock (&self->lock);
|
||||||
|
ret = g_strdup (self->status);
|
||||||
|
g_mutex_unlock (&self->lock);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
update_key (OstreeAsyncProgress *self,
|
||||||
|
GHashTable *hash,
|
||||||
|
const char *key,
|
||||||
|
gpointer value)
|
||||||
|
{
|
||||||
|
gpointer orig_value;
|
||||||
|
gpointer qkey = GUINT_TO_POINTER (g_quark_from_string (key));
|
||||||
|
|
||||||
|
g_mutex_lock (&self->lock);
|
||||||
|
|
||||||
|
if (g_hash_table_lookup_extended (hash, qkey, NULL, &orig_value))
|
||||||
|
{
|
||||||
|
if (orig_value == value)
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
g_hash_table_replace (hash, qkey, value);
|
||||||
|
ensure_callback_locked (self);
|
||||||
|
|
||||||
|
out:
|
||||||
|
g_mutex_unlock (&self->lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ostree_async_progress_set_uint (OstreeAsyncProgress *self,
|
||||||
|
const char *key,
|
||||||
|
guint value)
|
||||||
|
{
|
||||||
|
update_key (self, self->uint_values, key, GUINT_TO_POINTER (value));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ostree_async_progress_set_uint64 (OstreeAsyncProgress *self,
|
||||||
|
const char *key,
|
||||||
|
guint64 value)
|
||||||
|
{
|
||||||
|
gpointer valuep;
|
||||||
|
|
||||||
|
#if _OSTREE_HAVE_LP64
|
||||||
|
valuep = (gpointer)value;
|
||||||
|
#else
|
||||||
|
{
|
||||||
|
guint64 *boxed = g_malloc (sizeof (guint64));
|
||||||
|
*boxed = value;
|
||||||
|
valuep = boxed;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
update_key (self, self->uint64_values, key, valuep);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ostree_async_progress_new:
|
||||||
|
*
|
||||||
|
* Returns: (transfer full): A new progress object
|
||||||
|
*/
|
||||||
|
OstreeAsyncProgress *
|
||||||
|
ostree_async_progress_new (void)
|
||||||
|
{
|
||||||
|
return (OstreeAsyncProgress*)g_object_new (OSTREE_TYPE_ASYNC_PROGRESS, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
OstreeAsyncProgress *
|
||||||
|
ostree_async_progress_new_and_connect (void (*changed) (OstreeAsyncProgress *self, gpointer user_data),
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
OstreeAsyncProgress *ret = ostree_async_progress_new ();
|
||||||
|
g_signal_connect (ret, "changed", G_CALLBACK (changed), user_data);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,68 @@
|
||||||
|
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013 Colin Walters <walters@verbum.org>
|
||||||
|
*
|
||||||
|
* 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 "ostree-types.h"
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
#define OSTREE_TYPE_ASYNC_PROGRESS (ostree_async_progress_get_type ())
|
||||||
|
#define OSTREE_ASYNC_PROGRESS(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), OSTREE_TYPE_ASYNC_PROGRESS, OstreeAsyncProgress))
|
||||||
|
#define OSTREE_ASYNC_PROGRESS_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), OSTREE_TYPE_ASYNC_PROGRESS, OstreeAsyncProgressClass))
|
||||||
|
#define OSTREE_IS_ASYNC_PROGRESS(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), OSTREE_TYPE_ASYNC_PROGRESS))
|
||||||
|
#define OSTREE_IS_ASYNC_PROGRESS_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), OSTREE_TYPE_ASYNC_PROGRESS))
|
||||||
|
#define OSTREE_ASYNC_PROGRESS_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), OSTREE_TYPE_ASYNC_PROGRESS, OstreeAsyncProgressClass))
|
||||||
|
|
||||||
|
typedef struct OstreeAsyncProgress OstreeAsyncProgress;
|
||||||
|
typedef struct OstreeAsyncProgressClass OstreeAsyncProgressClass;
|
||||||
|
|
||||||
|
struct OstreeAsyncProgressClass
|
||||||
|
{
|
||||||
|
GObjectClass parent_class;
|
||||||
|
|
||||||
|
void (*changed) (OstreeAsyncProgress *self, gpointer user_data);
|
||||||
|
};
|
||||||
|
|
||||||
|
GType ostree_async_progress_get_type (void) G_GNUC_CONST;
|
||||||
|
|
||||||
|
OstreeAsyncProgress *ostree_async_progress_new (void);
|
||||||
|
|
||||||
|
OstreeAsyncProgress *ostree_async_progress_new_and_connect (void (*changed) (OstreeAsyncProgress *self, gpointer user_data), gpointer user_data);
|
||||||
|
|
||||||
|
char *ostree_async_progress_get_status (OstreeAsyncProgress *self);
|
||||||
|
|
||||||
|
guint ostree_async_progress_get_uint (OstreeAsyncProgress *self,
|
||||||
|
const char *key);
|
||||||
|
guint64 ostree_async_progress_get_uint64 (OstreeAsyncProgress *self,
|
||||||
|
const char *key);
|
||||||
|
|
||||||
|
void ostree_async_progress_set_status (OstreeAsyncProgress *self,
|
||||||
|
const char *status);
|
||||||
|
|
||||||
|
void ostree_async_progress_set_uint (OstreeAsyncProgress *self,
|
||||||
|
const char *key,
|
||||||
|
guint value);
|
||||||
|
void ostree_async_progress_set_uint64 (OstreeAsyncProgress *self,
|
||||||
|
const char *key,
|
||||||
|
guint64 value);
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
|
|
||||||
|
|
@ -87,6 +87,7 @@ typedef struct {
|
||||||
GMainContext *main_context;
|
GMainContext *main_context;
|
||||||
GMainLoop *loop;
|
GMainLoop *loop;
|
||||||
GCancellable *cancellable;
|
GCancellable *cancellable;
|
||||||
|
OstreeAsyncProgress *progress;
|
||||||
|
|
||||||
gboolean transaction_resuming;
|
gboolean transaction_resuming;
|
||||||
volatile gint n_scanned_metadata;
|
volatile gint n_scanned_metadata;
|
||||||
|
|
@ -179,47 +180,35 @@ suburi_new (SoupURI *base,
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
uri_fetch_update_status (gpointer user_data)
|
update_progress (gpointer user_data)
|
||||||
{
|
{
|
||||||
OtPullData *pull_data = user_data;
|
OtPullData *pull_data = user_data;
|
||||||
GString *status;
|
guint outstanding_writes = pull_data->n_outstanding_content_write_requests +
|
||||||
guint outstanding_writes;
|
pull_data->n_outstanding_metadata_write_requests;
|
||||||
guint outstanding_fetches;
|
guint outstanding_fetches = pull_data->n_outstanding_content_fetches +
|
||||||
|
pull_data->n_outstanding_metadata_fetches;
|
||||||
|
guint64 bytes_transferred = ostree_fetcher_bytes_transferred (pull_data->fetcher);
|
||||||
|
guint fetched = pull_data->n_fetched_metadata + pull_data->n_fetched_content;
|
||||||
|
guint requested = pull_data->n_requested_metadata + pull_data->n_requested_content;
|
||||||
|
guint n_scanned_metadata = g_atomic_int_get (&pull_data->n_scanned_metadata);
|
||||||
|
|
||||||
status = g_string_new ("");
|
g_assert (pull_data->progress);
|
||||||
|
|
||||||
outstanding_fetches = pull_data->n_outstanding_content_fetches + pull_data->n_outstanding_metadata_fetches;
|
ostree_async_progress_set_uint (pull_data->progress, "outstanding-fetches", outstanding_fetches);
|
||||||
outstanding_writes = pull_data->n_outstanding_content_write_requests + pull_data->n_outstanding_metadata_write_requests;
|
ostree_async_progress_set_uint (pull_data->progress, "outstanding-writes", outstanding_writes);
|
||||||
|
ostree_async_progress_set_uint (pull_data->progress, "fetched", fetched);
|
||||||
|
ostree_async_progress_set_uint (pull_data->progress, "requested", requested);
|
||||||
|
ostree_async_progress_set_uint (pull_data->progress, "scanned-metadata", n_scanned_metadata);
|
||||||
|
ostree_async_progress_set_uint64 (pull_data->progress, "bytes-transferred", bytes_transferred);
|
||||||
|
|
||||||
if (pull_data->fetching_sync_uri)
|
if (pull_data->fetching_sync_uri)
|
||||||
{
|
{
|
||||||
gs_free char *uri_string = soup_uri_to_string (pull_data->fetching_sync_uri, TRUE);
|
gs_free char *uri_string = soup_uri_to_string (pull_data->fetching_sync_uri, TRUE);
|
||||||
g_string_append_printf (status, "Requesting %s", uri_string);
|
gs_free char *status_string = g_strconcat ("Requesting %s", uri_string, NULL);
|
||||||
|
ostree_async_progress_set_status (pull_data->progress, status_string);
|
||||||
}
|
}
|
||||||
else if (outstanding_fetches)
|
|
||||||
{
|
|
||||||
guint64 bytes_transferred = ostree_fetcher_bytes_transferred (pull_data->fetcher);
|
|
||||||
guint fetched = pull_data->n_fetched_metadata + pull_data->n_fetched_content;
|
|
||||||
guint requested = pull_data->n_requested_metadata + pull_data->n_requested_content;
|
|
||||||
gs_free char *formatted_bytes_transferred = NULL;
|
|
||||||
|
|
||||||
formatted_bytes_transferred = g_format_size_full (bytes_transferred, 0);
|
|
||||||
|
|
||||||
g_string_append_printf (status, "Receiving objects: %u%% (%u/%u) %s",
|
|
||||||
(guint)((((double)fetched) / requested) * 100),
|
|
||||||
fetched, requested, formatted_bytes_transferred);
|
|
||||||
}
|
|
||||||
else if (outstanding_writes > 0)
|
|
||||||
g_string_append_printf (status, "Writing objects: %u", outstanding_writes);
|
|
||||||
else if (!pull_data->metadata_scan_idle)
|
|
||||||
g_string_append_printf (status, "Scanning metadata: %u",
|
|
||||||
g_atomic_int_get (&pull_data->n_scanned_metadata));
|
|
||||||
else
|
else
|
||||||
g_string_append_printf (status, "Idle");
|
ostree_async_progress_set_status (pull_data->progress, NULL);
|
||||||
|
|
||||||
gs_console_begin_status_line (gs_console_get (), status->str, NULL, NULL);
|
|
||||||
|
|
||||||
g_string_free (status, TRUE);
|
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
@ -303,17 +292,12 @@ static gboolean
|
||||||
run_mainloop_monitor_fetcher (OtPullData *pull_data)
|
run_mainloop_monitor_fetcher (OtPullData *pull_data)
|
||||||
{
|
{
|
||||||
GSource *update_timeout = NULL;
|
GSource *update_timeout = NULL;
|
||||||
GSConsole *console;
|
|
||||||
GSource *idle_src;
|
GSource *idle_src;
|
||||||
|
|
||||||
console = gs_console_get ();
|
if (pull_data->progress)
|
||||||
|
|
||||||
if (console)
|
|
||||||
{
|
{
|
||||||
gs_console_begin_status_line (console, "", NULL, NULL);
|
|
||||||
|
|
||||||
update_timeout = g_timeout_source_new_seconds (1);
|
update_timeout = g_timeout_source_new_seconds (1);
|
||||||
g_source_set_callback (update_timeout, uri_fetch_update_status, pull_data, NULL);
|
g_source_set_callback (update_timeout, update_progress, pull_data, NULL);
|
||||||
g_source_attach (update_timeout, g_main_loop_get_context (pull_data->loop));
|
g_source_attach (update_timeout, g_main_loop_get_context (pull_data->loop));
|
||||||
g_source_unref (update_timeout);
|
g_source_unref (update_timeout);
|
||||||
}
|
}
|
||||||
|
|
@ -323,11 +307,8 @@ run_mainloop_monitor_fetcher (OtPullData *pull_data)
|
||||||
g_source_attach (idle_src, pull_data->main_context);
|
g_source_attach (idle_src, pull_data->main_context);
|
||||||
g_main_loop_run (pull_data->loop);
|
g_main_loop_run (pull_data->loop);
|
||||||
|
|
||||||
if (console)
|
if (update_timeout)
|
||||||
{
|
g_source_destroy (update_timeout);
|
||||||
gs_console_end_status_line (console, NULL, NULL);
|
|
||||||
g_source_destroy (update_timeout);
|
|
||||||
}
|
|
||||||
|
|
||||||
return !pull_data->caught_error;
|
return !pull_data->caught_error;
|
||||||
}
|
}
|
||||||
|
|
@ -1198,6 +1179,7 @@ ostree_repo_pull (OstreeRepo *self,
|
||||||
const char *remote_name,
|
const char *remote_name,
|
||||||
char **refs_to_fetch,
|
char **refs_to_fetch,
|
||||||
OstreeRepoPullFlags flags,
|
OstreeRepoPullFlags flags,
|
||||||
|
OstreeAsyncProgress *progress,
|
||||||
GCancellable *cancellable,
|
GCancellable *cancellable,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
|
|
@ -1231,6 +1213,7 @@ ostree_repo_pull (OstreeRepo *self,
|
||||||
pull_data->flags = flags;
|
pull_data->flags = flags;
|
||||||
|
|
||||||
pull_data->repo = self;
|
pull_data->repo = self;
|
||||||
|
pull_data->progress = progress;
|
||||||
|
|
||||||
pull_data->scanned_metadata = g_hash_table_new_full (ostree_hash_object_name, g_variant_equal,
|
pull_data->scanned_metadata = g_hash_table_new_full (ostree_hash_object_name, g_variant_equal,
|
||||||
(GDestroyNotify)g_variant_unref, NULL);
|
(GDestroyNotify)g_variant_unref, NULL);
|
||||||
|
|
|
||||||
|
|
@ -1454,6 +1454,7 @@ ostree_repo_read_commit (OstreeRepo *self,
|
||||||
* @remote_name: Name of remote
|
* @remote_name: Name of remote
|
||||||
* @refs_to_fetch: (array zero-terminated=1) (element-type utf8) (allow-none): Optional list of refs; if %NULL, fetch all configured refs
|
* @refs_to_fetch: (array zero-terminated=1) (element-type utf8) (allow-none): Optional list of refs; if %NULL, fetch all configured refs
|
||||||
* @flags: Options controlling fetch behavior
|
* @flags: Options controlling fetch behavior
|
||||||
|
* @progress: (allow-none): Progress
|
||||||
* @cancellable: Cancellable
|
* @cancellable: Cancellable
|
||||||
* @error: Error
|
* @error: Error
|
||||||
*
|
*
|
||||||
|
|
@ -1467,6 +1468,7 @@ ostree_repo_pull (OstreeRepo *self,
|
||||||
const char *remote_name,
|
const char *remote_name,
|
||||||
char **refs_to_fetch,
|
char **refs_to_fetch,
|
||||||
OstreeRepoPullFlags flags,
|
OstreeRepoPullFlags flags,
|
||||||
|
OstreeAsyncProgress *progress,
|
||||||
GCancellable *cancellable,
|
GCancellable *cancellable,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@
|
||||||
|
|
||||||
#include "ostree-core.h"
|
#include "ostree-core.h"
|
||||||
#include "ostree-types.h"
|
#include "ostree-types.h"
|
||||||
|
#include "ostree-async-progress.h"
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
|
@ -461,6 +462,7 @@ gboolean ostree_repo_pull (OstreeRepo *self,
|
||||||
const char *remote_name,
|
const char *remote_name,
|
||||||
char **refs_to_fetch,
|
char **refs_to_fetch,
|
||||||
OstreeRepoPullFlags flags,
|
OstreeRepoPullFlags flags,
|
||||||
|
OstreeAsyncProgress *progress,
|
||||||
GCancellable *cancellable,
|
GCancellable *cancellable,
|
||||||
GError **error);
|
GError **error);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
|
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
|
||||||
*
|
*
|
||||||
* Copyright (C) 2011 Colin Walters <walters@verbum.org>.
|
* Copyright (C) 2011,2013 Colin Walters <walters@verbum.org>
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
|
@ -16,12 +16,11 @@
|
||||||
* License along with this library; if not, write to the
|
* License along with this library; if not, write to the
|
||||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
* Boston, MA 02111-1307, USA.
|
* Boston, MA 02111-1307, USA.
|
||||||
*
|
|
||||||
* Author: Colin Walters <walters@verbum.org>
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <ostree-async-progress.h>
|
||||||
#include <ostree-core.h>
|
#include <ostree-core.h>
|
||||||
#include <ostree-repo.h>
|
#include <ostree-repo.h>
|
||||||
#include <ostree-mutable-tree.h>
|
#include <ostree-mutable-tree.h>
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@
|
||||||
|
|
||||||
#include "ot-admin-builtins.h"
|
#include "ot-admin-builtins.h"
|
||||||
#include "ot-admin-functions.h"
|
#include "ot-admin-functions.h"
|
||||||
|
#include "ot-builtins-common.h"
|
||||||
#include "ostree.h"
|
#include "ostree.h"
|
||||||
#include "otutil.h"
|
#include "otutil.h"
|
||||||
#include "libgsystem.h"
|
#include "libgsystem.h"
|
||||||
|
|
@ -106,10 +107,16 @@ ot_admin_builtin_upgrade (int argc, char **argv, OstreeSysroot *sysroot, GCancel
|
||||||
{
|
{
|
||||||
OstreeRepoPullFlags pullflags = 0;
|
OstreeRepoPullFlags pullflags = 0;
|
||||||
char *refs_to_fetch[] = { origin_ref, NULL };
|
char *refs_to_fetch[] = { origin_ref, NULL };
|
||||||
|
GSConsole *console;
|
||||||
|
gs_unref_object OstreeAsyncProgress *progress = NULL;
|
||||||
|
|
||||||
|
console = gs_console_get ();
|
||||||
|
if (console)
|
||||||
|
progress = ostree_async_progress_new_and_connect (ot_common_pull_progress, console);
|
||||||
|
|
||||||
g_print ("Fetching remote %s ref %s\n", origin_remote, origin_ref);
|
g_print ("Fetching remote %s ref %s\n", origin_remote, origin_ref);
|
||||||
|
|
||||||
if (!ostree_repo_pull (repo, origin_remote, refs_to_fetch, pullflags,
|
if (!ostree_repo_pull (repo, origin_remote, refs_to_fetch, pullflags, progress,
|
||||||
cancellable, error))
|
cancellable, error))
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
#include "ot-builtins.h"
|
#include "ot-builtins.h"
|
||||||
|
#include "ot-builtins-common.h"
|
||||||
#include "ostree.h"
|
#include "ostree.h"
|
||||||
#include "otutil.h"
|
#include "otutil.h"
|
||||||
|
|
||||||
|
|
@ -37,7 +38,9 @@ ostree_builtin_pull (int argc, char **argv, OstreeRepo *repo, GCancellable *canc
|
||||||
gboolean ret = FALSE;
|
gboolean ret = FALSE;
|
||||||
const char *remote;
|
const char *remote;
|
||||||
OstreeRepoPullFlags pullflags = 0;
|
OstreeRepoPullFlags pullflags = 0;
|
||||||
|
GSConsole *console = NULL;
|
||||||
gs_unref_ptrarray GPtrArray *refs_to_fetch = NULL;
|
gs_unref_ptrarray GPtrArray *refs_to_fetch = NULL;
|
||||||
|
gs_unref_object OstreeAsyncProgress *progress = NULL;
|
||||||
|
|
||||||
context = g_option_context_new ("REMOTE [BRANCH...] - Download data from remote repository");
|
context = g_option_context_new ("REMOTE [BRANCH...] - Download data from remote repository");
|
||||||
g_option_context_add_main_entries (context, options, NULL);
|
g_option_context_add_main_entries (context, options, NULL);
|
||||||
|
|
@ -61,10 +64,17 @@ ostree_builtin_pull (int argc, char **argv, OstreeRepo *repo, GCancellable *canc
|
||||||
g_ptr_array_add (refs_to_fetch, NULL);
|
g_ptr_array_add (refs_to_fetch, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console = gs_console_get ();
|
||||||
|
if (console)
|
||||||
|
progress = ostree_async_progress_new_and_connect (ot_common_pull_progress, console);
|
||||||
|
|
||||||
if (!ostree_repo_pull (repo, remote, refs_to_fetch ? (char**)refs_to_fetch->pdata : NULL,
|
if (!ostree_repo_pull (repo, remote, refs_to_fetch ? (char**)refs_to_fetch->pdata : NULL,
|
||||||
pullflags, cancellable, error))
|
pullflags, progress, cancellable, error))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
|
if (console)
|
||||||
|
gs_console_end_status_line (console, NULL, NULL);
|
||||||
|
|
||||||
ret = TRUE;
|
ret = TRUE;
|
||||||
out:
|
out:
|
||||||
if (context)
|
if (context)
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,75 @@
|
||||||
|
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013 Colin Walters <walters@verbum.org>
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include "ot-builtins-common.h"
|
||||||
|
#include "otutil.h"
|
||||||
|
|
||||||
|
void
|
||||||
|
ot_common_pull_progress (OstreeAsyncProgress *progress,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
GSConsole *console = user_data;
|
||||||
|
GString *buf;
|
||||||
|
gs_free char *status = NULL;
|
||||||
|
guint outstanding_fetches;
|
||||||
|
guint outstanding_writes;
|
||||||
|
guint n_scanned_metadata;
|
||||||
|
|
||||||
|
if (!console)
|
||||||
|
return;
|
||||||
|
|
||||||
|
buf = g_string_new ("");
|
||||||
|
|
||||||
|
status = ostree_async_progress_get_status (progress);
|
||||||
|
outstanding_fetches = ostree_async_progress_get_uint (progress, "outstanding-fetches");
|
||||||
|
outstanding_writes = ostree_async_progress_get_uint (progress, "outstanding-writes");
|
||||||
|
n_scanned_metadata = ostree_async_progress_get_uint (progress, "scanned-metadata");
|
||||||
|
if (status)
|
||||||
|
{
|
||||||
|
g_string_append (buf, status);
|
||||||
|
}
|
||||||
|
else if (outstanding_fetches)
|
||||||
|
{
|
||||||
|
guint64 bytes_transferred = ostree_async_progress_get_uint64 (progress, "bytes-transferred");
|
||||||
|
guint fetched = ostree_async_progress_get_uint (progress, "fetched");
|
||||||
|
guint requested = ostree_async_progress_get_uint (progress, "requested");
|
||||||
|
gs_free char *formatted_bytes_transferred =
|
||||||
|
g_format_size_full (bytes_transferred, 0);
|
||||||
|
|
||||||
|
g_string_append_printf (buf, "Receiving objects: %u%% (%u/%u) %s",
|
||||||
|
(guint)((((double)fetched) / requested) * 100),
|
||||||
|
fetched, requested, formatted_bytes_transferred);
|
||||||
|
}
|
||||||
|
else if (outstanding_writes)
|
||||||
|
{
|
||||||
|
g_string_append_printf (buf, "Writing objects: %u", outstanding_writes);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g_string_append_printf (buf, "Scanning metadata: %u", n_scanned_metadata);
|
||||||
|
}
|
||||||
|
|
||||||
|
gs_console_begin_status_line (console, buf->str, NULL, NULL);
|
||||||
|
|
||||||
|
g_string_free (buf, TRUE);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,27 @@
|
||||||
|
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013 Colin Walters <walters@verbum.org>
|
||||||
|
*
|
||||||
|
* 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 <ostree.h>
|
||||||
|
|
||||||
|
void
|
||||||
|
ot_common_pull_progress (OstreeAsyncProgress *progress,
|
||||||
|
gpointer user_data);
|
||||||
|
|
@ -68,7 +68,7 @@ sysrootRepoConfig.set_string(testosRefSection, 'url', 'file://' + upstreamRepo.g
|
||||||
sysrootRepoConfig.set_boolean(testosRefSection, 'gpg-verify', false);
|
sysrootRepoConfig.set_boolean(testosRefSection, 'gpg-verify', false);
|
||||||
sysrootRepoConfig.set_string_list(testosRefSection, 'branches', [runtimeRef]);
|
sysrootRepoConfig.set_string_list(testosRefSection, 'branches', [runtimeRef]);
|
||||||
|
|
||||||
sysrootRepo.pull('testos', null, 0, null);
|
sysrootRepo.pull('testos', null, 0, null, null);
|
||||||
|
|
||||||
//// TEST: We can deploy one tree
|
//// TEST: We can deploy one tree
|
||||||
|
|
||||||
|
|
@ -111,7 +111,7 @@ sysroot.write_deployments(newDeployments, null);
|
||||||
|
|
||||||
libtestExec('os_repository_new_commit');
|
libtestExec('os_repository_new_commit');
|
||||||
|
|
||||||
sysrootRepo.pull('testos', null, 0, null);
|
sysrootRepo.pull('testos', null, 0, null, null);
|
||||||
|
|
||||||
let [,newRev] = upstreamRepo.resolve_rev(runtimeRef, false);
|
let [,newRev] = upstreamRepo.resolve_rev(runtimeRef, false);
|
||||||
|
|
||||||
|
|
@ -137,7 +137,7 @@ print("OK two deployments");
|
||||||
|
|
||||||
libtestExec('os_repository_new_commit 0 1');
|
libtestExec('os_repository_new_commit 0 1');
|
||||||
|
|
||||||
sysrootRepo.pull('testos', null, 0, null);
|
sysrootRepo.pull('testos', null, 0, null, null);
|
||||||
|
|
||||||
let [,thirdRev] = sysrootRepo.resolve_rev(runtimeRef, false);
|
let [,thirdRev] = sysrootRepo.resolve_rev(runtimeRef, false);
|
||||||
assertNotEquals(newRev, thirdRev);
|
assertNotEquals(newRev, thirdRev);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue