libostree: Add ostree_repo_remote_add() API, port "ostree remote add"
At least one external tool is using the API, and wants to add a remote, but all of the logic right now is in the tool. Move it to the library. https://bugzilla.gnome.org/show_bug.cgi?id=731984
This commit is contained in:
parent
b2329cf875
commit
2265ccdeb3
|
|
@ -342,6 +342,132 @@ ostree_repo_write_config (OstreeRepo *self,
|
|||
return ret;
|
||||
}
|
||||
|
||||
/* Bind a subset of an a{sv} to options in a given GKeyfile section */
|
||||
static void
|
||||
keyfile_set_from_vardict (GKeyFile *keyfile,
|
||||
const char *section,
|
||||
GVariant *vardict)
|
||||
{
|
||||
GVariantIter viter;
|
||||
const char *key;
|
||||
GVariant *val;
|
||||
|
||||
g_variant_iter_init (&viter, vardict);
|
||||
while (g_variant_iter_loop (&viter, "{&s@v}", &key, &val))
|
||||
{
|
||||
gs_unref_variant GVariant *child = g_variant_get_variant (val);
|
||||
if (g_variant_is_of_type (child, G_VARIANT_TYPE_STRING))
|
||||
g_key_file_set_string (keyfile, section, key, g_variant_get_string (child, NULL));
|
||||
else if (g_variant_is_of_type (child, G_VARIANT_TYPE_BOOLEAN))
|
||||
g_key_file_set_boolean (keyfile, section, key, g_variant_get_boolean (child));
|
||||
else if (g_variant_is_of_type (child, G_VARIANT_TYPE_STRING_ARRAY))
|
||||
{
|
||||
gsize len;
|
||||
const char *const*strv_child = g_variant_get_strv (child, &len);
|
||||
g_key_file_set_string_list (keyfile, section, key, strv_child, len);
|
||||
}
|
||||
else
|
||||
g_critical ("Unhandled type '%s' in " G_GNUC_FUNCTION,
|
||||
(char*)g_variant_get_type (child));
|
||||
}
|
||||
}
|
||||
|
||||
GS_DEFINE_CLEANUP_FUNCTION0(GKeyFile*, local_keyfile_unref, g_key_file_unref)
|
||||
#define local_cleanup_keyfile __attribute__ ((cleanup(local_keyfile_unref)))
|
||||
|
||||
/**
|
||||
* ostree_repo_remote_add:
|
||||
* @self: Repo
|
||||
* @name: Name of remote
|
||||
* @url: URL for remote
|
||||
* @options: (allow-none): GVariant of type a{sv}
|
||||
* @cancellable: Cancellable
|
||||
* @error: Error
|
||||
*
|
||||
* Create a new remote named @name pointing to @url. If @options is
|
||||
* provided, then it will be mapped to #GKeyFile entries, where the
|
||||
* GVariant dictionary key is an option string, and the value is
|
||||
* mapped as follows:
|
||||
* * s: g_key_file_set_string()
|
||||
* * b: g_key_file_set_boolean()
|
||||
* * as: g_key_file_set_string_list()
|
||||
*
|
||||
*/
|
||||
gboolean
|
||||
ostree_repo_remote_add (OstreeRepo *self,
|
||||
const char *name,
|
||||
const char *url,
|
||||
GVariant *options,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
gboolean ret = FALSE;
|
||||
gboolean is_system;
|
||||
gs_free char *section = NULL;
|
||||
gs_unref_object GFile *etc_ostree_remotes_d = g_file_new_for_path (SYSCONFDIR "/ostree/remotes.d");
|
||||
local_cleanup_keyfile GKeyFile *target_keyfile = NULL;
|
||||
gs_free char *target_name = NULL;
|
||||
gs_unref_object GFile *target_conf = NULL;
|
||||
|
||||
g_return_val_if_fail (name != NULL, FALSE);
|
||||
g_return_val_if_fail (url != NULL, FALSE);
|
||||
g_return_val_if_fail (g_variant_is_of_type (options, G_VARIANT_TYPE ("a{sv}")), FALSE);
|
||||
|
||||
if (strchr (name, '/') != NULL)
|
||||
{
|
||||
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||
"Invalid character '/' in remote name: %s",
|
||||
name);
|
||||
goto out;
|
||||
}
|
||||
|
||||
section = g_strdup_printf ("remote \"%s\"", name);
|
||||
|
||||
is_system = ostree_repo_is_system (self);
|
||||
if (is_system)
|
||||
{
|
||||
target_keyfile = g_key_file_new ();
|
||||
|
||||
target_name = g_strconcat (name, ".conf", NULL);
|
||||
target_conf = g_file_get_child (etc_ostree_remotes_d, target_name);
|
||||
|
||||
if (g_file_query_exists (target_conf, NULL))
|
||||
{
|
||||
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||
"Remote configuration already exists: %s",
|
||||
gs_file_get_path_cached (target_conf));
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
target_keyfile = ostree_repo_copy_config (self);
|
||||
}
|
||||
|
||||
g_key_file_set_string (target_keyfile, section, "url", url);
|
||||
if (options)
|
||||
keyfile_set_from_vardict (target_keyfile, section, options);
|
||||
|
||||
if (is_system)
|
||||
{
|
||||
gsize len;
|
||||
gs_free char *data = g_key_file_to_data (target_keyfile, &len, error);
|
||||
if (!g_file_replace_contents (target_conf, data, len,
|
||||
NULL, FALSE, 0, NULL,
|
||||
cancellable, error))
|
||||
goto out;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!ostree_repo_write_config (self, target_keyfile, error))
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = TRUE;
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
ostree_repo_mode_to_string (OstreeRepoMode mode,
|
||||
const char **out_mode,
|
||||
|
|
@ -504,9 +630,6 @@ enumerate_directory_allow_noent (GFile *dirpath,
|
|||
return ret;
|
||||
}
|
||||
|
||||
GS_DEFINE_CLEANUP_FUNCTION0(GKeyFile*, local_keyfile_unref, g_key_file_unref)
|
||||
#define local_cleanup_keyfile __attribute__ ((cleanup(local_keyfile_unref)))
|
||||
|
||||
static gboolean
|
||||
append_one_remote_config (OstreeRepo *self,
|
||||
GFile *path,
|
||||
|
|
|
|||
|
|
@ -67,6 +67,13 @@ GKeyFile * ostree_repo_get_config (OstreeRepo *self);
|
|||
|
||||
GKeyFile * ostree_repo_copy_config (OstreeRepo *self);
|
||||
|
||||
gboolean ostree_repo_remote_add (OstreeRepo *self,
|
||||
const char *name,
|
||||
const char *url,
|
||||
GVariant *options,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
OstreeRepo * ostree_repo_get_parent (OstreeRepo *self);
|
||||
|
||||
gboolean ostree_repo_write_config (OstreeRepo *self,
|
||||
|
|
|
|||
|
|
@ -63,47 +63,6 @@ parse_keyvalue (const char *keyvalue,
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
GS_DEFINE_CLEANUP_FUNCTION0(GKeyFile*, local_keyfile_unref, g_key_file_unref)
|
||||
#define local_cleanup_keyfile __attribute__ ((cleanup(local_keyfile_unref)))
|
||||
|
||||
static gboolean
|
||||
add_remote_to_keyfile (GKeyFile *new_keyfile,
|
||||
const char *key,
|
||||
const char *url,
|
||||
GPtrArray *branches,
|
||||
GError **error)
|
||||
{
|
||||
gboolean ret = FALSE;
|
||||
char **iter;
|
||||
|
||||
g_key_file_set_string (new_keyfile, key, "url", url);
|
||||
|
||||
for (iter = opt_set; iter && *iter; iter++)
|
||||
{
|
||||
const char *keyvalue = *iter;
|
||||
gs_free char *subkey = NULL;
|
||||
gs_free char *subvalue = NULL;
|
||||
|
||||
if (!parse_keyvalue (keyvalue, &subkey, &subvalue, error))
|
||||
goto out;
|
||||
|
||||
g_key_file_set_string (new_keyfile, key, subkey, subvalue);
|
||||
}
|
||||
|
||||
if (branches->len > 0)
|
||||
g_key_file_set_string_list (new_keyfile, key, "branches",
|
||||
(const char *const *)branches->pdata,
|
||||
branches->len);
|
||||
|
||||
if (opt_no_gpg_verify)
|
||||
g_key_file_set_boolean (new_keyfile, key, "gpg-verify", FALSE);
|
||||
|
||||
ret = TRUE;
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
gboolean
|
||||
ostree_builtin_remote (int argc, char **argv, OstreeRepo *repo, GCancellable *cancellable, GError **error)
|
||||
{
|
||||
|
|
@ -140,20 +99,11 @@ ostree_builtin_remote (int argc, char **argv, OstreeRepo *repo, GCancellable *ca
|
|||
if (!strcmp (op, "add"))
|
||||
{
|
||||
const char *url = argv[3];
|
||||
gs_unref_object GFile *etc_ostree_remotes_d = g_file_new_for_path (SYSCONFDIR "/ostree/remotes.d");
|
||||
char **iter;
|
||||
gs_free char *target_name = NULL;
|
||||
gs_unref_object GFile *target_conf = NULL;
|
||||
local_cleanup_keyfile GKeyFile *new_keyfile = NULL;
|
||||
GKeyFile *target_keyfile = NULL;
|
||||
gs_unref_ptrarray GPtrArray *branches = NULL;
|
||||
|
||||
if (strchr (remote_name, '/') != NULL)
|
||||
{
|
||||
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||
"Invalid character '/' in remote name: %s",
|
||||
remote_name);
|
||||
goto out;
|
||||
}
|
||||
gs_unref_variant_builder GVariantBuilder *optbuilder = NULL;
|
||||
|
||||
if (argc < 4)
|
||||
{
|
||||
|
|
@ -161,51 +111,44 @@ ostree_builtin_remote (int argc, char **argv, OstreeRepo *repo, GCancellable *ca
|
|||
goto out;
|
||||
}
|
||||
|
||||
branches = g_ptr_array_new ();
|
||||
optbuilder = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}"));
|
||||
|
||||
if (branches)
|
||||
{
|
||||
gs_unref_ptrarray GPtrArray *branchesp = g_ptr_array_new ();
|
||||
|
||||
for (i = 4; i < argc; i++)
|
||||
g_ptr_array_add (branches, argv[i]);
|
||||
g_ptr_array_add (branchesp, argv[i]);
|
||||
g_ptr_array_add (branchesp, NULL);
|
||||
|
||||
if (ostree_repo_is_system (repo))
|
||||
{
|
||||
new_keyfile = g_key_file_new ();
|
||||
|
||||
target_keyfile = new_keyfile;
|
||||
|
||||
target_name = g_strconcat (remote_name, ".conf", NULL);
|
||||
target_conf = g_file_get_child (etc_ostree_remotes_d, target_name);
|
||||
|
||||
if (g_file_query_exists (target_conf, NULL))
|
||||
{
|
||||
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||
"Remote configuration already exists: %s",
|
||||
gs_file_get_path_cached (target_conf));
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
target_keyfile = config;
|
||||
g_variant_builder_add (optbuilder, "{s@v}",
|
||||
"branches",
|
||||
g_variant_new_variant (g_variant_new_strv ((const char*const*)branchesp->pdata, -1)));
|
||||
}
|
||||
|
||||
if (!add_remote_to_keyfile (target_keyfile, key, url, branches, error))
|
||||
for (iter = opt_set; iter && *iter; iter++)
|
||||
{
|
||||
const char *keyvalue = *iter;
|
||||
gs_free char *subkey = NULL;
|
||||
gs_free char *subvalue = NULL;
|
||||
|
||||
if (!parse_keyvalue (keyvalue, &subkey, &subvalue, error))
|
||||
goto out;
|
||||
|
||||
/* For the system repository, write to /etc/ostree/remotes.d */
|
||||
if (ostree_repo_is_system (repo))
|
||||
{
|
||||
gsize len;
|
||||
gs_free char *data = g_key_file_to_data (target_keyfile, &len, error);
|
||||
if (!g_file_replace_contents (target_conf, data, len,
|
||||
NULL, FALSE, 0, NULL,
|
||||
g_variant_builder_add (optbuilder, "{s@v}",
|
||||
subkey, g_variant_new_variant (g_variant_new_string (subvalue)));
|
||||
}
|
||||
|
||||
if (opt_no_gpg_verify)
|
||||
g_variant_builder_add (optbuilder, "{s@v}",
|
||||
"gpg-verify",
|
||||
g_variant_new_variant (g_variant_new_boolean (FALSE)));
|
||||
|
||||
if (!ostree_repo_remote_add (repo, remote_name, url,
|
||||
g_variant_builder_end (optbuilder),
|
||||
cancellable, error))
|
||||
goto out;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!ostree_repo_write_config (repo, config, error))
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
else if (!strcmp (op, "show-url"))
|
||||
{
|
||||
gs_free char *url = NULL;
|
||||
|
|
|
|||
Loading…
Reference in New Issue