mirror of
https://github.com/ostreedev/ostree.git
synced 2025-01-09 01:18:35 +03:00
Change pull-local to just be a wrapper for pull with file:///
This follows up from the previous commit; now that pull knows how to do the efficient link() or copy for local files, we can just have pull-local call into ostree_repo_pull(). As part of this: - pull() can also accept a file:/// URI instead of a remote name (since pull local supports anonymous pulls) - pull() knows an "override-remote-name" option, since pull-local supported writing a ref out even if there wasn't a remote with that name
This commit is contained in:
parent
ab3bf493dd
commit
9cc9804195
@ -162,6 +162,9 @@ _ostree_repo_commit_modifier_apply (OstreeRepo *self,
|
||||
GFileInfo *file_info,
|
||||
GFileInfo **out_modified_info);
|
||||
|
||||
gboolean
|
||||
_ostree_repo_remote_name_is_file (const char *remote_name);
|
||||
|
||||
gboolean
|
||||
_ostree_repo_get_remote_option (OstreeRepo *self,
|
||||
const char *remote_name,
|
||||
|
@ -1603,7 +1603,7 @@ ostree_repo_pull_one_dir (OstreeRepo *self,
|
||||
/* Documented in ostree-repo.c */
|
||||
gboolean
|
||||
ostree_repo_pull_with_options (OstreeRepo *self,
|
||||
const char *remote_name,
|
||||
const char *remote_name_or_baseurl,
|
||||
GVariant *options,
|
||||
OstreeAsyncProgress *progress,
|
||||
GCancellable *cancellable,
|
||||
@ -1642,6 +1642,7 @@ ostree_repo_pull_with_options (OstreeRepo *self,
|
||||
/* Reduce risk of issues if enum happens to be 64 bit for some reason */
|
||||
flags = flags_i;
|
||||
(void) g_variant_lookup (options, "subdir", "&s", &dir_to_pull);
|
||||
(void) g_variant_lookup (options, "override-remote-name", "s", &pull_data->remote_name);
|
||||
(void) g_variant_lookup (options, "depth", "i", &pull_data->maxdepth);
|
||||
}
|
||||
|
||||
@ -1676,21 +1677,32 @@ ostree_repo_pull_with_options (OstreeRepo *self,
|
||||
|
||||
pull_data->start_time = g_get_monotonic_time ();
|
||||
|
||||
pull_data->remote_name = g_strdup (remote_name);
|
||||
if (_ostree_repo_remote_name_is_file (remote_name_or_baseurl))
|
||||
{
|
||||
baseurl = g_strdup (remote_name_or_baseurl);
|
||||
/* For compatibility with pull-local, don't gpg verify local
|
||||
* pulls.
|
||||
*/
|
||||
pull_data->gpg_verify = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
pull_data->remote_name = g_strdup (remote_name_or_baseurl);
|
||||
|
||||
#ifdef HAVE_GPGME
|
||||
if (!_ostree_repo_get_remote_boolean_option (self,
|
||||
pull_data->remote_name, "gpg-verify",
|
||||
TRUE, &pull_data->gpg_verify, error))
|
||||
goto out;
|
||||
if (!_ostree_repo_get_remote_boolean_option (self,
|
||||
remote_name_or_baseurl, "gpg-verify",
|
||||
TRUE, &pull_data->gpg_verify, error))
|
||||
goto out;
|
||||
#else
|
||||
pull_data->gpg_verify = FALSE;
|
||||
pull_data->gpg_verify = FALSE;
|
||||
#endif
|
||||
}
|
||||
|
||||
pull_data->phase = OSTREE_PULL_PHASE_FETCHING_REFS;
|
||||
|
||||
if (!_ostree_repo_get_remote_boolean_option (self,
|
||||
pull_data->remote_name, "tls-permissive",
|
||||
remote_name_or_baseurl, "tls-permissive",
|
||||
FALSE, &tls_permissive, error))
|
||||
goto out;
|
||||
if (tls_permissive)
|
||||
@ -1706,11 +1718,11 @@ ostree_repo_pull_with_options (OstreeRepo *self,
|
||||
gs_free char *tls_client_key_path = NULL;
|
||||
|
||||
if (!_ostree_repo_get_remote_option (self,
|
||||
pull_data->remote_name, "tls-client-cert-path",
|
||||
remote_name_or_baseurl, "tls-client-cert-path",
|
||||
NULL, &tls_client_cert_path, error))
|
||||
goto out;
|
||||
if (!_ostree_repo_get_remote_option (self,
|
||||
pull_data->remote_name, "tls-client-key-path",
|
||||
remote_name_or_baseurl, "tls-client-key-path",
|
||||
NULL, &tls_client_key_path, error))
|
||||
goto out;
|
||||
|
||||
@ -1718,7 +1730,7 @@ ostree_repo_pull_with_options (OstreeRepo *self,
|
||||
{
|
||||
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||
"remote \"%s\" must specify both \"tls-client-cert-path\" and \"tls-client-key-path\"",
|
||||
pull_data->remote_name);
|
||||
remote_name_or_baseurl);
|
||||
goto out;
|
||||
}
|
||||
else if (tls_client_cert_path)
|
||||
@ -1742,7 +1754,7 @@ ostree_repo_pull_with_options (OstreeRepo *self,
|
||||
gs_unref_object GTlsDatabase *db = NULL;
|
||||
|
||||
if (!_ostree_repo_get_remote_option (self,
|
||||
pull_data->remote_name, "tls-ca-path",
|
||||
remote_name_or_baseurl, "tls-ca-path",
|
||||
NULL, &tls_ca_path, error))
|
||||
goto out;
|
||||
|
||||
@ -1760,7 +1772,7 @@ ostree_repo_pull_with_options (OstreeRepo *self,
|
||||
gs_free char *http_proxy = NULL;
|
||||
|
||||
if (!_ostree_repo_get_remote_option (self,
|
||||
pull_data->remote_name, "proxy",
|
||||
remote_name_or_baseurl, "proxy",
|
||||
NULL, &http_proxy, error))
|
||||
goto out;
|
||||
|
||||
@ -1769,20 +1781,23 @@ ostree_repo_pull_with_options (OstreeRepo *self,
|
||||
}
|
||||
|
||||
if (!_ostree_repo_get_remote_option (self,
|
||||
pull_data->remote_name, "metalink",
|
||||
remote_name_or_baseurl, "metalink",
|
||||
NULL, &metalink_url_str, error))
|
||||
goto out;
|
||||
|
||||
if (!metalink_url_str)
|
||||
{
|
||||
if (!repo_get_remote_option_inherit (self, pull_data->remote_name, "url", &baseurl, error))
|
||||
goto out;
|
||||
if (baseurl == NULL)
|
||||
{
|
||||
if (!repo_get_remote_option_inherit (self, remote_name_or_baseurl, "url", &baseurl, error))
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (baseurl == NULL)
|
||||
{
|
||||
g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND,
|
||||
"No \"url\" option in remote \"%s\"",
|
||||
pull_data->remote_name);
|
||||
remote_name_or_baseurl);
|
||||
goto out;
|
||||
}
|
||||
|
||||
@ -1841,7 +1856,7 @@ ostree_repo_pull_with_options (OstreeRepo *self,
|
||||
}
|
||||
|
||||
if (!_ostree_repo_get_remote_list_option (self,
|
||||
pull_data->remote_name, "branches",
|
||||
remote_name_or_baseurl, "branches",
|
||||
&configured_branches, error))
|
||||
goto out;
|
||||
|
||||
@ -1944,7 +1959,7 @@ ostree_repo_pull_with_options (OstreeRepo *self,
|
||||
if (!(branches_iter && *branches_iter))
|
||||
{
|
||||
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||
"No configured branches for remote %s", pull_data->remote_name);
|
||||
"No configured branches for remote %s", remote_name_or_baseurl);
|
||||
goto out;
|
||||
}
|
||||
for (;branches_iter && *branches_iter; branches_iter++)
|
||||
@ -2077,7 +2092,10 @@ ostree_repo_pull_with_options (OstreeRepo *self,
|
||||
gs_free char *remote_ref = NULL;
|
||||
gs_free char *original_rev = NULL;
|
||||
|
||||
remote_ref = g_strdup_printf ("%s/%s", pull_data->remote_name, ref);
|
||||
if (pull_data->remote_name)
|
||||
remote_ref = g_strdup_printf ("%s/%s", pull_data->remote_name, ref);
|
||||
else
|
||||
remote_ref = g_strdup (ref);
|
||||
|
||||
if (!ostree_repo_resolve_rev (pull_data->repo, remote_ref, TRUE, &original_rev, error))
|
||||
goto out;
|
||||
@ -2087,7 +2105,8 @@ ostree_repo_pull_with_options (OstreeRepo *self,
|
||||
}
|
||||
else
|
||||
{
|
||||
ostree_repo_transaction_set_ref (pull_data->repo, pull_data->is_mirror ? NULL : pull_data->remote_name, ref, checksum);
|
||||
ostree_repo_transaction_set_ref (pull_data->repo, pull_data->is_mirror ? NULL : pull_data->remote_name,
|
||||
ref, checksum);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -231,6 +231,12 @@ ost_repo_remove_remote (OstreeRepo *self,
|
||||
return removed;
|
||||
}
|
||||
|
||||
gboolean
|
||||
_ostree_repo_remote_name_is_file (const char *remote_name)
|
||||
{
|
||||
return g_str_has_prefix (remote_name, "file://");
|
||||
}
|
||||
|
||||
gboolean
|
||||
_ostree_repo_get_remote_option (OstreeRepo *self,
|
||||
const char *remote_name,
|
||||
@ -242,6 +248,12 @@ _ostree_repo_get_remote_option (OstreeRepo *self,
|
||||
local_cleanup_remote OstreeRemote *remote = NULL;
|
||||
gboolean ret = FALSE;
|
||||
|
||||
if (_ostree_repo_remote_name_is_file (remote_name))
|
||||
{
|
||||
*out_value = g_strdup (default_value);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
remote = ost_repo_get_remote (self, remote_name, error);
|
||||
|
||||
if (remote != NULL)
|
||||
@ -267,6 +279,12 @@ _ostree_repo_get_remote_list_option (OstreeRepo *self,
|
||||
local_cleanup_remote OstreeRemote *remote = NULL;
|
||||
gboolean ret = FALSE;
|
||||
|
||||
if (_ostree_repo_remote_name_is_file (remote_name))
|
||||
{
|
||||
*out_value = NULL;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
remote = ost_repo_get_remote (self, remote_name, error);
|
||||
|
||||
if (remote != NULL)
|
||||
@ -304,6 +322,12 @@ _ostree_repo_get_remote_boolean_option (OstreeRepo *self,
|
||||
local_cleanup_remote OstreeRemote *remote = NULL;
|
||||
gboolean ret = FALSE;
|
||||
|
||||
if (_ostree_repo_remote_name_is_file (remote_name))
|
||||
{
|
||||
*out_value = default_value;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
remote = ost_repo_get_remote (self, remote_name, error);
|
||||
|
||||
if (remote != NULL)
|
||||
|
@ -39,99 +39,25 @@ static GOptionEntry options[] = {
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
OstreeRepo *src_repo;
|
||||
OstreeRepo *dest_repo;
|
||||
GThreadPool *threadpool;
|
||||
GMainLoop *loop;
|
||||
int n_objects_to_check;
|
||||
volatile int n_objects_checked;
|
||||
volatile int n_objects_copied;
|
||||
GSConsole *console;
|
||||
} OtLocalCloneData;
|
||||
|
||||
static gboolean
|
||||
termination_condition (OtLocalCloneData *self)
|
||||
{
|
||||
return g_atomic_int_get (&self->n_objects_checked) == self->n_objects_to_check;
|
||||
}
|
||||
|
||||
static void
|
||||
import_one_object_thread (gpointer object,
|
||||
gpointer user_data)
|
||||
{
|
||||
OtLocalCloneData *data = user_data;
|
||||
gs_unref_variant GVariant *serialized_key = object;
|
||||
GError *local_error = NULL;
|
||||
GError **error = &local_error;
|
||||
const char *checksum;
|
||||
OstreeObjectType objtype;
|
||||
GCancellable *cancellable = NULL;
|
||||
|
||||
ostree_object_name_deserialize (serialized_key, &checksum, &objtype);
|
||||
|
||||
if (!ostree_repo_import_object_from (data->dest_repo, data->src_repo,
|
||||
objtype, checksum, cancellable, error))
|
||||
goto out;
|
||||
|
||||
g_atomic_int_inc (&data->n_objects_copied);
|
||||
|
||||
out:
|
||||
g_atomic_int_add (&data->n_objects_checked, 1);
|
||||
if (termination_condition (data))
|
||||
g_main_context_wakeup (NULL);
|
||||
if (local_error != NULL)
|
||||
{
|
||||
g_printerr ("%s\n", local_error->message);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
idle_print_status (gpointer user_data)
|
||||
{
|
||||
OtLocalCloneData *data = user_data;
|
||||
gs_free char *str = NULL;
|
||||
|
||||
str = g_strdup_printf ("pull: %d/%d scanned, %d objects copied",
|
||||
g_atomic_int_get (&data->n_objects_checked),
|
||||
data->n_objects_to_check,
|
||||
g_atomic_int_get (&data->n_objects_copied));
|
||||
if (data->console)
|
||||
gs_console_begin_status_line (data->console, str, NULL, NULL);
|
||||
else
|
||||
g_print ("%s\n", str);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
ostree_builtin_pull_local (int argc, char **argv, GCancellable *cancellable, GError **error)
|
||||
{
|
||||
gboolean ret = FALSE;
|
||||
GOptionContext *context;
|
||||
gs_unref_object OstreeRepo *repo = NULL;
|
||||
const char *src_repo_path;
|
||||
int i;
|
||||
GHashTableIter hash_iter;
|
||||
gpointer key, value;
|
||||
gboolean transaction_resuming = FALSE;
|
||||
gs_unref_object GFile *src_f = NULL;
|
||||
gs_unref_object GFile *src_repo_dir = NULL;
|
||||
gs_unref_object GFile *dest_repo_dir = NULL;
|
||||
gs_unref_hashtable GHashTable *refs_to_clone = NULL;
|
||||
gs_unref_hashtable GHashTable *commits_to_clone = NULL;
|
||||
const char *src_repo_arg;
|
||||
GSConsole *console = NULL;
|
||||
gs_free char *src_repo_uri = NULL;
|
||||
gs_unref_object OstreeAsyncProgress *progress = NULL;
|
||||
gs_unref_ptrarray GPtrArray *refs_to_fetch = NULL;
|
||||
gs_unref_hashtable GHashTable *source_objects = NULL;
|
||||
OtLocalCloneData datav = { 0, };
|
||||
OtLocalCloneData *data = &datav;
|
||||
|
||||
context = g_option_context_new ("SRC_REPO [REFS...] - Copy data from SRC_REPO");
|
||||
|
||||
if (!ostree_option_context_parse (context, options, &argc, &argv, OSTREE_BUILTIN_FLAG_NONE, &repo, cancellable, error))
|
||||
goto out;
|
||||
|
||||
data->dest_repo = g_object_ref (repo);
|
||||
|
||||
if (argc < 2)
|
||||
{
|
||||
gchar *help = g_option_context_get_help (context, TRUE, NULL);
|
||||
@ -142,133 +68,80 @@ ostree_builtin_pull_local (int argc, char **argv, GCancellable *cancellable, GEr
|
||||
goto out;
|
||||
}
|
||||
|
||||
src_repo_path = argv[1];
|
||||
src_f = g_file_new_for_path (src_repo_path);
|
||||
src_repo_arg = argv[1];
|
||||
|
||||
data->src_repo = ostree_repo_new (src_f);
|
||||
if (!ostree_repo_open (data->src_repo, cancellable, error))
|
||||
goto out;
|
||||
{ gs_free char *cwd = g_get_current_dir ();
|
||||
src_repo_uri = g_strconcat ("file://", cwd, "/", src_repo_arg, NULL);
|
||||
}
|
||||
|
||||
if (opt_disable_fsync)
|
||||
ostree_repo_set_disable_fsync (data->dest_repo, TRUE);
|
||||
|
||||
data->threadpool = ot_thread_pool_new_nproc (import_one_object_thread, data);
|
||||
|
||||
src_repo_dir = g_object_ref (ostree_repo_get_path (data->src_repo));
|
||||
dest_repo_dir = g_object_ref (ostree_repo_get_path (data->dest_repo));
|
||||
ostree_repo_set_disable_fsync (repo, TRUE);
|
||||
|
||||
if (argc == 2)
|
||||
{
|
||||
if (!ostree_repo_list_refs (data->src_repo, NULL, &refs_to_clone,
|
||||
gs_unref_object GFile *src_repo_path = g_file_new_for_path (src_repo_arg);
|
||||
gs_unref_object OstreeRepo *src_repo = ostree_repo_new (src_repo_path);
|
||||
gs_unref_hashtable GHashTable *refs_to_clone = NULL;
|
||||
|
||||
refs_to_fetch = g_ptr_array_new_with_free_func (g_free);
|
||||
|
||||
if (!ostree_repo_open (src_repo, cancellable, error))
|
||||
goto out;
|
||||
|
||||
if (!ostree_repo_list_refs (src_repo, NULL, &refs_to_clone,
|
||||
cancellable, error))
|
||||
goto out;
|
||||
|
||||
{ GHashTableIter hashiter;
|
||||
gpointer hkey, hvalue;
|
||||
|
||||
g_hash_table_iter_init (&hashiter, refs_to_clone);
|
||||
while (g_hash_table_iter_next (&hashiter, &hkey, &hvalue))
|
||||
g_ptr_array_add (refs_to_fetch, g_strdup (hkey));
|
||||
}
|
||||
g_ptr_array_add (refs_to_fetch, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
refs_to_clone = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
|
||||
commits_to_clone = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, NULL);
|
||||
refs_to_fetch = g_ptr_array_new ();
|
||||
for (i = 2; i < argc; i++)
|
||||
{
|
||||
const char *ref = argv[i];
|
||||
char *rev;
|
||||
|
||||
if (ostree_validate_checksum_string (ref, NULL))
|
||||
{
|
||||
g_hash_table_insert (commits_to_clone, (char*)ref, (char*) ref);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!ostree_repo_resolve_rev (data->src_repo, ref, FALSE, &rev, error))
|
||||
goto out;
|
||||
|
||||
/* Transfer ownership of rev */
|
||||
g_hash_table_insert (refs_to_clone, g_strdup (ref), rev);
|
||||
}
|
||||
g_ptr_array_add (refs_to_fetch, (char*)ref);
|
||||
}
|
||||
g_ptr_array_add (refs_to_fetch, NULL);
|
||||
}
|
||||
|
||||
if (!ostree_repo_prepare_transaction (data->dest_repo, &transaction_resuming,
|
||||
console = gs_console_get ();
|
||||
if (console)
|
||||
{
|
||||
gs_console_begin_status_line (console, "", NULL, NULL);
|
||||
progress = ostree_async_progress_new_and_connect (ostree_repo_pull_default_console_progress_changed, console);
|
||||
}
|
||||
|
||||
{ GVariantBuilder builder;
|
||||
g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}"));
|
||||
|
||||
g_variant_builder_add (&builder, "{s@v}", "flags",
|
||||
g_variant_new_variant (g_variant_new_int32 (OSTREE_REPO_PULL_FLAGS_NONE)));
|
||||
g_variant_builder_add (&builder, "{s@v}", "refs",
|
||||
g_variant_new_variant (g_variant_new_strv ((const char *const*) refs_to_fetch->pdata, -1)));
|
||||
if (opt_remote)
|
||||
g_variant_builder_add (&builder, "{s@v}", "override-remote-name",
|
||||
g_variant_new_variant (g_variant_new_string (opt_remote)));
|
||||
|
||||
if (!ostree_repo_pull_with_options (repo, src_repo_uri,
|
||||
g_variant_builder_end (&builder),
|
||||
progress,
|
||||
cancellable, error))
|
||||
goto out;
|
||||
|
||||
g_print ("Enumerating objects...\n");
|
||||
|
||||
source_objects = ostree_repo_traverse_new_reachable ();
|
||||
|
||||
if (refs_to_clone)
|
||||
{
|
||||
g_hash_table_iter_init (&hash_iter, refs_to_clone);
|
||||
while (g_hash_table_iter_next (&hash_iter, &key, &value))
|
||||
{
|
||||
const char *checksum = value;
|
||||
|
||||
if (!ostree_repo_traverse_commit_union (data->src_repo, checksum, 0, source_objects,
|
||||
cancellable, error))
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
if (commits_to_clone)
|
||||
{
|
||||
g_hash_table_iter_init (&hash_iter, commits_to_clone);
|
||||
while (g_hash_table_iter_next (&hash_iter, &key, &value))
|
||||
{
|
||||
const char *checksum = key;
|
||||
gs_unref_hashtable GHashTable *tmp_source_objects = NULL;
|
||||
|
||||
if (!ostree_repo_traverse_commit_union (data->src_repo, checksum, 0, source_objects,
|
||||
cancellable, error))
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
data->n_objects_to_check = g_hash_table_size (source_objects);
|
||||
g_hash_table_iter_init (&hash_iter, source_objects);
|
||||
while (g_hash_table_iter_next (&hash_iter, &key, &value))
|
||||
{
|
||||
GVariant *serialized_key = key;
|
||||
g_thread_pool_push (data->threadpool, g_variant_ref (serialized_key), NULL);
|
||||
}
|
||||
|
||||
if (data->n_objects_to_check > 0)
|
||||
{
|
||||
data->console = gs_console_get ();
|
||||
|
||||
if (data->console)
|
||||
gs_console_begin_status_line (data->console, "", NULL, NULL);
|
||||
|
||||
g_timeout_add_seconds (1, idle_print_status, data);
|
||||
idle_print_status (data);
|
||||
|
||||
while (!termination_condition (data))
|
||||
g_main_context_iteration (NULL, TRUE);
|
||||
|
||||
idle_print_status (data);
|
||||
if (data->console)
|
||||
gs_console_end_status_line (data->console, NULL, NULL);
|
||||
}
|
||||
|
||||
g_print ("Writing %u refs\n", g_hash_table_size (refs_to_clone));
|
||||
|
||||
g_hash_table_iter_init (&hash_iter, refs_to_clone);
|
||||
while (g_hash_table_iter_next (&hash_iter, &key, &value))
|
||||
{
|
||||
const char *name = key;
|
||||
const char *checksum = value;
|
||||
|
||||
ostree_repo_transaction_set_ref (data->dest_repo, opt_remote, name, checksum);
|
||||
}
|
||||
|
||||
if (!ostree_repo_commit_transaction (data->dest_repo, NULL, NULL, error))
|
||||
goto out;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = TRUE;
|
||||
out:
|
||||
g_clear_pointer (&data->threadpool, (GDestroyNotify) g_thread_pool_free);
|
||||
if (data->src_repo)
|
||||
g_object_unref (data->src_repo);
|
||||
if (data->dest_repo)
|
||||
g_object_unref (data->dest_repo);
|
||||
if (progress)
|
||||
ostree_async_progress_finish (progress);
|
||||
if (context)
|
||||
g_option_context_free (context);
|
||||
if (repo)
|
||||
|
Loading…
Reference in New Issue
Block a user