From 57d285f6194c6d9bbaa45b5f253a1d698ef4ea2e Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Thu, 5 Sep 2013 00:14:30 -0400 Subject: [PATCH] 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 --- src/libostree/ostree-repo.c | 109 +++++++++++++++++++++++++++++++++++ src/libostree/ostree-repo.h | 31 +++++----- src/ostree/ot-builtin-init.c | 75 ++---------------------- 3 files changed, 131 insertions(+), 84 deletions(-) diff --git a/src/libostree/ostree-repo.c b/src/libostree/ostree-repo.c index c314dfaf..3ee48c8f 100644 --- a/src/libostree/ostree-repo.c +++ b/src/libostree/ostree-repo.c @@ -52,6 +52,12 @@ * content files zlib-compressed. It is suitable for non-root-owned * 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 * ostree_repo_prepare_transaction(). Then create a * #OstreeMutableTree, and apply functions such as @@ -311,6 +317,34 @@ ostree_repo_write_config (OstreeRepo *self, 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 ostree_repo_mode_from_string (const char *mode, OstreeRepoMode *out_mode, @@ -336,6 +370,81 @@ ostree_repo_mode_from_string (const char *mode, 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 ostree_repo_check (OstreeRepo *self, GError **error) { diff --git a/src/libostree/ostree-repo.h b/src/libostree/ostree-repo.h index 2465f51f..1aea7842 100644 --- a/src/libostree/ostree-repo.h +++ b/src/libostree/ostree-repo.h @@ -33,16 +33,6 @@ G_BEGIN_DECLS #define OSTREE_IS_REPO(obj) \ (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: * @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 } OstreeRepoMode; -gboolean ostree_repo_mode_from_string (const char *mode, - OstreeRepoMode *out_mode, - GError **error); +gboolean ostree_repo_mode_from_string (const char *mode, + OstreeRepoMode *out_mode, + 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); diff --git a/src/ostree/ot-builtin-init.c b/src/ostree/ot-builtin-init.c index acfa9287..d57ed5c5 100644 --- a/src/ostree/ot-builtin-init.c +++ b/src/ostree/ot-builtin-init.c @@ -26,27 +26,19 @@ #include "ostree.h" #include "libgsystem.h" -static char *opt_mode = NULL; +static char *opt_mode = "bare"; static GOptionEntry options[] = { { "mode", 0, 0, G_OPTION_ARG_STRING, &opt_mode, "Initialize repository in given mode (bare, archive-z2)", NULL }, { NULL } }; -#define DEFAULT_CONFIG_CONTENTS ("[core]\n" \ - "repo_version=1\n") - - gboolean ostree_builtin_init (int argc, char **argv, OstreeRepo *repo, GCancellable *cancellable, GError **error) { GOptionContext *context = NULL; gboolean ret = FALSE; - const char *mode_str = "bare"; - GFile *repo_path = NULL; - gs_unref_object GFile *child = NULL; - gs_unref_object GFile *grandchild = NULL; - GString *config_data = NULL; + OstreeRepoMode mode; context = g_option_context_new ("- Initialize a new empty repository"); 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)) goto out; - repo_path = ostree_repo_get_path (repo); - - 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)) + if (!ostree_repo_mode_from_string (opt_mode, &mode, error)) goto out; - g_clear_object (&child); - 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)) + if (!ostree_repo_create (repo, mode, NULL, error)) goto out; ret = TRUE; out: if (context) g_option_context_free (context); - if (config_data) - g_string_free (config_data, TRUE); return ret; }