repo: Move the 'init' builtin command to a public API, ostree_repo_create
This continues the goal of making more of ostree accessible by API, rather than forking out to subprocesses. https://bugzilla.gnome.org/show_bug.cgi?id=707582
This commit is contained in:
parent
eb6f017ef8
commit
57d285f619
|
|
@ -52,6 +52,12 @@
|
||||||
* content files zlib-compressed. It is suitable for non-root-owned
|
* content files zlib-compressed. It is suitable for non-root-owned
|
||||||
* repositories that can be served via a static HTTP server.
|
* repositories that can be served via a static HTTP server.
|
||||||
*
|
*
|
||||||
|
* Creating an #OstreeRepo does not invoke any file I/O, and thus needs
|
||||||
|
* to be initialized, either from an existing contents or with a new
|
||||||
|
* repository. If you have an existing repo, use ostree_repo_check()
|
||||||
|
* to load it from disk and check its validity. To initialize a new
|
||||||
|
* repository in the given filepath, use ostree_repo_create() instead.
|
||||||
|
*
|
||||||
* To store content in the repo, first start a transaction with
|
* To store content in the repo, first start a transaction with
|
||||||
* ostree_repo_prepare_transaction(). Then create a
|
* ostree_repo_prepare_transaction(). Then create a
|
||||||
* #OstreeMutableTree, and apply functions such as
|
* #OstreeMutableTree, and apply functions such as
|
||||||
|
|
@ -311,6 +317,34 @@ ostree_repo_write_config (OstreeRepo *self,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
ostree_repo_mode_to_string (OstreeRepoMode mode,
|
||||||
|
const char **out_mode,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
gboolean ret = FALSE;
|
||||||
|
const char *ret_mode;
|
||||||
|
|
||||||
|
switch (mode)
|
||||||
|
{
|
||||||
|
case OSTREE_REPO_MODE_BARE:
|
||||||
|
ret_mode = "bare";
|
||||||
|
break;
|
||||||
|
case OSTREE_REPO_MODE_ARCHIVE_Z2:
|
||||||
|
ret_mode ="archive-z2";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||||
|
"Invalid mode '%d'", mode);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = TRUE;
|
||||||
|
*out_mode = ret_mode;
|
||||||
|
out:
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
ostree_repo_mode_from_string (const char *mode,
|
ostree_repo_mode_from_string (const char *mode,
|
||||||
OstreeRepoMode *out_mode,
|
OstreeRepoMode *out_mode,
|
||||||
|
|
@ -336,6 +370,81 @@ ostree_repo_mode_from_string (const char *mode,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define DEFAULT_CONFIG_CONTENTS ("[core]\n" \
|
||||||
|
"repo_version=1\n")
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ostree_repo_create:
|
||||||
|
* @self: An #OstreeRepo
|
||||||
|
* @mode: The mode to store the repository in
|
||||||
|
* @cancellable: Cancellable
|
||||||
|
* @error: Error
|
||||||
|
*
|
||||||
|
* Create the underlying structure on disk for the
|
||||||
|
* repository.
|
||||||
|
*/
|
||||||
|
gboolean
|
||||||
|
ostree_repo_create (OstreeRepo *self,
|
||||||
|
OstreeRepoMode mode,
|
||||||
|
GCancellable *cancellable,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
gboolean ret = FALSE;
|
||||||
|
GString *config_data = NULL;
|
||||||
|
gs_unref_object GFile *child = NULL;
|
||||||
|
gs_unref_object GFile *grandchild = NULL;
|
||||||
|
const char *mode_str;
|
||||||
|
|
||||||
|
if (!ostree_repo_mode_to_string (mode, &mode_str, error))
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
if (!gs_file_ensure_directory (self->repodir, FALSE, cancellable, error))
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
config_data = g_string_new (DEFAULT_CONFIG_CONTENTS);
|
||||||
|
g_string_append_printf (config_data, "mode=%s\n", mode_str);
|
||||||
|
if (!g_file_replace_contents (self->config_file,
|
||||||
|
config_data->str,
|
||||||
|
config_data->len,
|
||||||
|
NULL, FALSE, 0, NULL,
|
||||||
|
cancellable, error))
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
if (!g_file_make_directory (self->objects_dir, cancellable, error))
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
if (!g_file_make_directory (self->tmp_dir, cancellable, error))
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
if (!g_file_make_directory (self->remote_cache_dir, cancellable, error))
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
g_clear_object (&child);
|
||||||
|
child = g_file_get_child (self->repodir, "refs");
|
||||||
|
if (!g_file_make_directory (child, cancellable, error))
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
g_clear_object (&grandchild);
|
||||||
|
grandchild = g_file_get_child (child, "heads");
|
||||||
|
if (!g_file_make_directory (grandchild, cancellable, error))
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
g_clear_object (&grandchild);
|
||||||
|
grandchild = g_file_get_child (child, "remotes");
|
||||||
|
if (!g_file_make_directory (grandchild, cancellable, error))
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
if (!ostree_repo_check (self, error))
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
ret = TRUE;
|
||||||
|
|
||||||
|
out:
|
||||||
|
if (config_data)
|
||||||
|
g_string_free (config_data, TRUE);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
ostree_repo_check (OstreeRepo *self, GError **error)
|
ostree_repo_check (OstreeRepo *self, GError **error)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -33,16 +33,6 @@ G_BEGIN_DECLS
|
||||||
#define OSTREE_IS_REPO(obj) \
|
#define OSTREE_IS_REPO(obj) \
|
||||||
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), OSTREE_TYPE_REPO))
|
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), OSTREE_TYPE_REPO))
|
||||||
|
|
||||||
GType ostree_repo_get_type (void);
|
|
||||||
|
|
||||||
OstreeRepo* ostree_repo_new (GFile *path);
|
|
||||||
|
|
||||||
OstreeRepo* ostree_repo_new_default (void);
|
|
||||||
|
|
||||||
gboolean ostree_repo_check (OstreeRepo *self, GError **error);
|
|
||||||
|
|
||||||
GFile * ostree_repo_get_path (OstreeRepo *self);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* OstreeRepoMode:
|
* OstreeRepoMode:
|
||||||
* @OSTREE_REPO_MODE_BARE: Files are stored as themselves; can only be written as root
|
* @OSTREE_REPO_MODE_BARE: Files are stored as themselves; can only be written as root
|
||||||
|
|
@ -56,9 +46,24 @@ typedef enum {
|
||||||
OSTREE_REPO_MODE_ARCHIVE_Z2
|
OSTREE_REPO_MODE_ARCHIVE_Z2
|
||||||
} OstreeRepoMode;
|
} OstreeRepoMode;
|
||||||
|
|
||||||
gboolean ostree_repo_mode_from_string (const char *mode,
|
gboolean ostree_repo_mode_from_string (const char *mode,
|
||||||
OstreeRepoMode *out_mode,
|
OstreeRepoMode *out_mode,
|
||||||
GError **error);
|
GError **error);
|
||||||
|
|
||||||
|
GType ostree_repo_get_type (void);
|
||||||
|
|
||||||
|
OstreeRepo* ostree_repo_new (GFile *path);
|
||||||
|
|
||||||
|
OstreeRepo* ostree_repo_new_default (void);
|
||||||
|
|
||||||
|
gboolean ostree_repo_check (OstreeRepo *self, GError **error);
|
||||||
|
|
||||||
|
gboolean ostree_repo_create (OstreeRepo *self,
|
||||||
|
OstreeRepoMode mode,
|
||||||
|
GCancellable *cancellable,
|
||||||
|
GError **error);
|
||||||
|
|
||||||
|
GFile * ostree_repo_get_path (OstreeRepo *self);
|
||||||
|
|
||||||
OstreeRepoMode ostree_repo_get_mode (OstreeRepo *self);
|
OstreeRepoMode ostree_repo_get_mode (OstreeRepo *self);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -26,27 +26,19 @@
|
||||||
#include "ostree.h"
|
#include "ostree.h"
|
||||||
#include "libgsystem.h"
|
#include "libgsystem.h"
|
||||||
|
|
||||||
static char *opt_mode = NULL;
|
static char *opt_mode = "bare";
|
||||||
|
|
||||||
static GOptionEntry options[] = {
|
static GOptionEntry options[] = {
|
||||||
{ "mode", 0, 0, G_OPTION_ARG_STRING, &opt_mode, "Initialize repository in given mode (bare, archive-z2)", NULL },
|
{ "mode", 0, 0, G_OPTION_ARG_STRING, &opt_mode, "Initialize repository in given mode (bare, archive-z2)", NULL },
|
||||||
{ NULL }
|
{ NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
#define DEFAULT_CONFIG_CONTENTS ("[core]\n" \
|
|
||||||
"repo_version=1\n")
|
|
||||||
|
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
ostree_builtin_init (int argc, char **argv, OstreeRepo *repo, GCancellable *cancellable, GError **error)
|
ostree_builtin_init (int argc, char **argv, OstreeRepo *repo, GCancellable *cancellable, GError **error)
|
||||||
{
|
{
|
||||||
GOptionContext *context = NULL;
|
GOptionContext *context = NULL;
|
||||||
gboolean ret = FALSE;
|
gboolean ret = FALSE;
|
||||||
const char *mode_str = "bare";
|
OstreeRepoMode mode;
|
||||||
GFile *repo_path = NULL;
|
|
||||||
gs_unref_object GFile *child = NULL;
|
|
||||||
gs_unref_object GFile *grandchild = NULL;
|
|
||||||
GString *config_data = NULL;
|
|
||||||
|
|
||||||
context = g_option_context_new ("- Initialize a new empty repository");
|
context = g_option_context_new ("- Initialize a new empty repository");
|
||||||
g_option_context_add_main_entries (context, options, NULL);
|
g_option_context_add_main_entries (context, options, NULL);
|
||||||
|
|
@ -54,74 +46,15 @@ ostree_builtin_init (int argc, char **argv, OstreeRepo *repo, GCancellable *canc
|
||||||
if (!g_option_context_parse (context, &argc, &argv, error))
|
if (!g_option_context_parse (context, &argc, &argv, error))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
repo_path = ostree_repo_get_path (repo);
|
if (!ostree_repo_mode_from_string (opt_mode, &mode, error))
|
||||||
|
|
||||||
child = g_file_get_child (repo_path, "config");
|
|
||||||
|
|
||||||
config_data = g_string_new (DEFAULT_CONFIG_CONTENTS);
|
|
||||||
if (opt_mode)
|
|
||||||
{
|
|
||||||
OstreeRepoMode mode;
|
|
||||||
if (!ostree_repo_mode_from_string (opt_mode, &mode, error))
|
|
||||||
goto out;
|
|
||||||
mode_str = opt_mode;
|
|
||||||
}
|
|
||||||
g_string_append_printf (config_data, "mode=%s\n", mode_str);
|
|
||||||
if (!g_file_replace_contents (child,
|
|
||||||
config_data->str,
|
|
||||||
config_data->len,
|
|
||||||
NULL, FALSE, 0, NULL,
|
|
||||||
NULL, error))
|
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
g_clear_object (&child);
|
if (!ostree_repo_create (repo, mode, NULL, error))
|
||||||
child = g_file_get_child (repo_path, "objects");
|
|
||||||
if (!g_file_make_directory (child, NULL, error))
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
g_clear_object (&grandchild);
|
|
||||||
grandchild = g_file_get_child (child, "pack");
|
|
||||||
if (!g_file_make_directory (grandchild, NULL, error))
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
g_clear_object (&child);
|
|
||||||
child = g_file_get_child (repo_path, "tmp");
|
|
||||||
if (!g_file_make_directory (child, NULL, error))
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
g_clear_object (&child);
|
|
||||||
child = g_file_get_child (repo_path, "refs");
|
|
||||||
if (!g_file_make_directory (child, NULL, error))
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
g_clear_object (&grandchild);
|
|
||||||
grandchild = g_file_get_child (child, "heads");
|
|
||||||
if (!g_file_make_directory (grandchild, NULL, error))
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
g_clear_object (&grandchild);
|
|
||||||
grandchild = g_file_get_child (child, "remotes");
|
|
||||||
if (!g_file_make_directory (grandchild, NULL, error))
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
g_clear_object (&child);
|
|
||||||
child = g_file_get_child (repo_path, "tags");
|
|
||||||
if (!g_file_make_directory (child, NULL, error))
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
g_clear_object (&child);
|
|
||||||
child = g_file_get_child (repo_path, "remote-cache");
|
|
||||||
if (!g_file_make_directory (child, NULL, error))
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
if (!ostree_repo_check (repo, error))
|
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
ret = TRUE;
|
ret = TRUE;
|
||||||
out:
|
out:
|
||||||
if (context)
|
if (context)
|
||||||
g_option_context_free (context);
|
g_option_context_free (context);
|
||||||
if (config_data)
|
|
||||||
g_string_free (config_data, TRUE);
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue