mirror of
https://github.com/ostreedev/ostree.git
synced 2025-02-03 17:47:40 +03:00
core: Allow adding related objects to commits
This will be used to store the set of components.
This commit is contained in:
parent
50cc2356f4
commit
d7a15b381e
@ -29,6 +29,8 @@ G_BEGIN_DECLS
|
||||
|
||||
#define OSTREE_MAX_METADATA_SIZE (1 << 26)
|
||||
|
||||
#define OSTREE_MAX_RECURSION (256)
|
||||
|
||||
#define OSTREE_EMPTY_STRING_SHA256 "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855";
|
||||
|
||||
typedef enum {
|
||||
|
@ -1691,6 +1691,7 @@ ostree_repo_stage_commit (OstreeRepo *self,
|
||||
const char *subject,
|
||||
const char *body,
|
||||
GVariant *metadata,
|
||||
GVariant *related_objects,
|
||||
const char *root_contents_checksum,
|
||||
const char *root_metadata_checksum,
|
||||
char **out_commit,
|
||||
@ -1712,8 +1713,7 @@ ostree_repo_stage_commit (OstreeRepo *self,
|
||||
commit = g_variant_new ("(@a{sv}@ay@a(say)sst@ay@ay)",
|
||||
metadata ? metadata : create_empty_gvariant_dict (),
|
||||
parent ? ostree_checksum_to_bytes_v (parent) : ot_gvariant_new_bytearray (NULL, 0),
|
||||
g_variant_new_array (G_VARIANT_TYPE ("(say)"),
|
||||
NULL, 0),
|
||||
related_objects ? related_objects : g_variant_new_array (G_VARIANT_TYPE ("(say)"), NULL, 0),
|
||||
subject, body ? body : "",
|
||||
GUINT64_TO_BE (g_date_time_to_unix (now)),
|
||||
ostree_checksum_to_bytes_v (root_contents_checksum),
|
||||
|
@ -245,6 +245,7 @@ gboolean ostree_repo_stage_commit (OstreeRepo *self,
|
||||
const char *subject,
|
||||
const char *body,
|
||||
GVariant *metadata,
|
||||
GVariant *related_objects,
|
||||
const char *content_checksum,
|
||||
const char *metadata_checksum,
|
||||
char **out_commit,
|
||||
|
@ -29,10 +29,12 @@
|
||||
|
||||
gboolean verbose;
|
||||
gboolean opt_prefer_loose;
|
||||
gboolean opt_related;
|
||||
|
||||
static GOptionEntry options[] = {
|
||||
{ "verbose", 'v', 0, G_OPTION_ARG_NONE, &verbose, "Show more information", NULL },
|
||||
{ "prefer-loose", 0, 0, G_OPTION_ARG_NONE, &opt_prefer_loose, "Download loose objects by default", NULL },
|
||||
{ "related", 0, 0, G_OPTION_ARG_NONE, &opt_related, "Download related commits", NULL },
|
||||
{ NULL },
|
||||
};
|
||||
|
||||
@ -666,6 +668,7 @@ fetch_and_store_metadata (OtPullData *pull_data,
|
||||
|
||||
static gboolean
|
||||
fetch_and_store_tree_metadata_recurse (OtPullData *pull_data,
|
||||
int depth,
|
||||
const char *rev,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
@ -678,6 +681,13 @@ fetch_and_store_tree_metadata_recurse (OtPullData *pull_data,
|
||||
ot_lobj GFile *stored_path = NULL;
|
||||
ot_lfree char *pack_checksum = NULL;
|
||||
|
||||
if (depth > OSTREE_MAX_RECURSION)
|
||||
{
|
||||
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||
"Exceeded maximum recursion");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!fetch_and_store_metadata (pull_data, rev, OSTREE_OBJECT_TYPE_DIR_TREE,
|
||||
&tree, cancellable, error))
|
||||
goto out;
|
||||
@ -726,7 +736,7 @@ fetch_and_store_tree_metadata_recurse (OtPullData *pull_data,
|
||||
|
||||
g_free (tmp_checksum);
|
||||
tmp_checksum = ostree_checksum_from_bytes_v (tree_csum);
|
||||
if (!fetch_and_store_tree_metadata_recurse (pull_data, tmp_checksum, cancellable, error))
|
||||
if (!fetch_and_store_tree_metadata_recurse (pull_data, depth+1, tmp_checksum, cancellable, error))
|
||||
goto out;
|
||||
}
|
||||
|
||||
@ -737,15 +747,18 @@ fetch_and_store_tree_metadata_recurse (OtPullData *pull_data,
|
||||
|
||||
static gboolean
|
||||
fetch_and_store_commit_metadata_recurse (OtPullData *pull_data,
|
||||
int depth,
|
||||
const char *rev,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
gboolean ret = FALSE;
|
||||
ot_lvariant GVariant *commit = NULL;
|
||||
ot_lvariant GVariant *related_objects = NULL;
|
||||
ot_lvariant GVariant *tree_contents_csum = NULL;
|
||||
ot_lvariant GVariant *tree_meta_csum = NULL;
|
||||
ot_lfree char *tmp_checksum = NULL;
|
||||
GVariantIter *iter = NULL;
|
||||
|
||||
if (!fetch_and_store_metadata (pull_data, rev, OSTREE_OBJECT_TYPE_COMMIT,
|
||||
&commit, cancellable, error))
|
||||
@ -763,12 +776,39 @@ fetch_and_store_commit_metadata_recurse (OtPullData *pull_data,
|
||||
|
||||
g_free (tmp_checksum);
|
||||
tmp_checksum = ostree_checksum_from_bytes_v (tree_contents_csum);
|
||||
if (!fetch_and_store_tree_metadata_recurse (pull_data, tmp_checksum,
|
||||
if (!fetch_and_store_tree_metadata_recurse (pull_data, depth, tmp_checksum,
|
||||
cancellable, error))
|
||||
goto out;
|
||||
|
||||
if (opt_related)
|
||||
{
|
||||
const char *name;
|
||||
ot_lvariant GVariant *csum_v = NULL;
|
||||
|
||||
if (depth > OSTREE_MAX_RECURSION)
|
||||
{
|
||||
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||
"Exceeded maximum recursion");
|
||||
goto out;
|
||||
}
|
||||
|
||||
related_objects = g_variant_get_child_value (commit, 2);
|
||||
iter = g_variant_iter_new (related_objects);
|
||||
|
||||
while (g_variant_iter_loop (iter, "(&s@ay)", &name, &csum_v))
|
||||
{
|
||||
ot_lfree char *checksum = ostree_checksum_from_bytes_v (csum_v);
|
||||
|
||||
if (!fetch_and_store_commit_metadata_recurse (pull_data, depth+1, checksum,
|
||||
cancellable, error))
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
ret = TRUE;
|
||||
out:
|
||||
if (iter)
|
||||
g_variant_iter_free (iter);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -1258,7 +1298,8 @@ ostree_builtin_pull (int argc, char **argv, GFile *repo_path, GError **error)
|
||||
{
|
||||
const char *commit = value;
|
||||
|
||||
if (!fetch_and_store_commit_metadata_recurse (pull_data, commit, cancellable, error))
|
||||
if (!fetch_and_store_commit_metadata_recurse (pull_data, 0, commit,
|
||||
cancellable, error))
|
||||
goto out;
|
||||
}
|
||||
|
||||
@ -1286,7 +1327,7 @@ ostree_builtin_pull (int argc, char **argv, GFile *repo_path, GError **error)
|
||||
if (!ostree_validate_checksum_string (sha256, error))
|
||||
goto out;
|
||||
|
||||
if (!fetch_and_store_commit_metadata_recurse (pull_data, sha256, cancellable, error))
|
||||
if (!fetch_and_store_commit_metadata_recurse (pull_data, 0, sha256, cancellable, error))
|
||||
goto out;
|
||||
|
||||
g_hash_table_insert (updated_refs, g_strdup (ref), g_strdup (sha256));
|
||||
|
@ -37,6 +37,7 @@ static char *parent;
|
||||
static char *branch;
|
||||
static char **metadata_strings;
|
||||
static char *statoverride_file;
|
||||
static char *opt_related_objects_file;
|
||||
static gboolean skip_if_unchanged;
|
||||
static gboolean tar_autocreate_parents;
|
||||
static gboolean no_xattrs;
|
||||
@ -59,6 +60,7 @@ static GOptionEntry options[] = {
|
||||
{ "tar-autocreate-parents", 0, 0, G_OPTION_ARG_NONE, &tar_autocreate_parents, "When loading tar archives, automatically create parent directories as needed", NULL },
|
||||
{ "skip-if-unchanged", 0, 0, G_OPTION_ARG_NONE, &skip_if_unchanged, "If the contents are unchanged from previous commit, do nothing", NULL },
|
||||
{ "statoverride", 0, 0, G_OPTION_ARG_FILENAME, &statoverride_file, "File containing list of modifications to make to permissions", "path" },
|
||||
{ "related-objects-file", 0, 0, G_OPTION_ARG_FILENAME, &opt_related_objects_file, "File containing newline-separated pairs of (checksum SPACE name) of related objects", "path" },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
@ -115,6 +117,74 @@ parse_statoverride_file (GHashTable **out_mode_add,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
parse_related_objects_file (GVariant **out_related_objects,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
gboolean ret = FALSE;
|
||||
gsize len;
|
||||
char **iter = NULL; /* nofree */
|
||||
ot_lhash GHashTable *ret_hash = NULL;
|
||||
ot_lvariant GVariant *ret_related_objects = NULL;
|
||||
ot_lobj GFile *path = NULL;
|
||||
ot_lfree char *contents = NULL;
|
||||
GVariantBuilder builder;
|
||||
gboolean builder_initialized = FALSE;
|
||||
char **lines = NULL;
|
||||
|
||||
g_variant_builder_init (&builder, G_VARIANT_TYPE ("a(say)"));
|
||||
builder_initialized = TRUE;
|
||||
|
||||
path = ot_gfile_new_for_path (opt_related_objects_file);
|
||||
|
||||
if (!g_file_load_contents (path, cancellable, &contents, &len, NULL,
|
||||
error))
|
||||
goto out;
|
||||
|
||||
lines = g_strsplit (contents, "\n", -1);
|
||||
|
||||
for (iter = lines; iter && *iter; iter++)
|
||||
{
|
||||
const char *line = *iter;
|
||||
const char *spc;
|
||||
ot_lfree char *name = NULL;
|
||||
|
||||
if (!*line)
|
||||
break;
|
||||
|
||||
spc = strchr (line, ' ');
|
||||
if (!spc)
|
||||
{
|
||||
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||
"Malformed related objects file");
|
||||
goto out;
|
||||
}
|
||||
|
||||
name = g_strndup (line, spc - line);
|
||||
|
||||
if (!ostree_validate_checksum_string (spc + 1, error))
|
||||
goto out;
|
||||
|
||||
{
|
||||
GVariant *csum_bytes_v = ostree_checksum_to_bytes_v (spc + 1);
|
||||
g_variant_builder_add (&builder, "(s@ay)", name, csum_bytes_v);
|
||||
}
|
||||
}
|
||||
|
||||
ret_related_objects = g_variant_builder_end (&builder);
|
||||
g_variant_ref_sink (ret_related_objects);
|
||||
builder_initialized = FALSE;
|
||||
|
||||
ret = TRUE;
|
||||
ot_transfer_out_value (out_related_objects, &ret_related_objects);
|
||||
out:
|
||||
if (builder_initialized)
|
||||
g_variant_builder_clear (&builder);
|
||||
g_strfreev (lines);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static OstreeRepoCommitFilterResult
|
||||
commit_filter (OstreeRepo *self,
|
||||
const char *path,
|
||||
@ -155,6 +225,7 @@ ostree_builtin_commit (int argc, char **argv, GFile *repo_path, GError **error)
|
||||
ot_lfree char *commit_checksum = NULL;
|
||||
ot_lvariant GVariant *parent_commit = NULL;
|
||||
ot_lvariant GVariant *metadata = NULL;
|
||||
ot_lvariant GVariant *related_objects = NULL;
|
||||
ot_lobj GFile *metadata_f = NULL;
|
||||
ot_lfree char *contents_checksum = NULL;
|
||||
ot_lobj OstreeMutableTree *mtree = NULL;
|
||||
@ -236,6 +307,12 @@ ostree_builtin_commit (int argc, char **argv, GFile *repo_path, GError **error)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (opt_related_objects_file)
|
||||
{
|
||||
if (!parse_related_objects_file (&related_objects, cancellable, error))
|
||||
goto out;
|
||||
}
|
||||
|
||||
repo = ostree_repo_new (repo_path);
|
||||
if (!ostree_repo_check (repo, error))
|
||||
goto out;
|
||||
@ -390,7 +467,7 @@ ostree_builtin_commit (int argc, char **argv, GFile *repo_path, GError **error)
|
||||
}
|
||||
|
||||
if (!ostree_repo_stage_commit (repo, branch, parent, subject, body, metadata,
|
||||
contents_checksum, root_metadata,
|
||||
related_objects, contents_checksum, root_metadata,
|
||||
&commit_checksum, cancellable, error))
|
||||
goto out;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user