|
rpm-build |
0fba15 |
/*
|
|
rpm-build |
0fba15 |
* Copyright (C) 2011 Colin Walters <walters@verbum.org>
|
|
rpm-build |
0fba15 |
*
|
|
rpm-build |
0fba15 |
* SPDX-License-Identifier: LGPL-2.0+
|
|
rpm-build |
0fba15 |
*
|
|
rpm-build |
0fba15 |
* This library is free software; you can redistribute it and/or
|
|
rpm-build |
0fba15 |
* modify it under the terms of the GNU Lesser General Public
|
|
rpm-build |
0fba15 |
* License as published by the Free Software Foundation; either
|
|
rpm-build |
0fba15 |
* version 2 of the License, or (at your option) any later version.
|
|
rpm-build |
0fba15 |
*
|
|
rpm-build |
0fba15 |
* This library is distributed in the hope that it will be useful,
|
|
rpm-build |
0fba15 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
rpm-build |
0fba15 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
rpm-build |
0fba15 |
* Lesser General Public License for more details.
|
|
rpm-build |
0fba15 |
*
|
|
rpm-build |
0fba15 |
* You should have received a copy of the GNU Lesser General Public
|
|
rpm-build |
0fba15 |
* License along with this library; if not, write to the
|
|
rpm-build |
0fba15 |
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
|
rpm-build |
0fba15 |
* Boston, MA 02111-1307, USA.
|
|
rpm-build |
0fba15 |
*
|
|
rpm-build |
0fba15 |
* Author: Colin Walters <walters@verbum.org>
|
|
rpm-build |
0fba15 |
*/
|
|
rpm-build |
0fba15 |
|
|
rpm-build |
0fba15 |
#include "config.h"
|
|
rpm-build |
0fba15 |
|
|
rpm-build |
0fba15 |
#include "ot-main.h"
|
|
rpm-build |
0fba15 |
#include "ot-builtins.h"
|
|
rpm-build |
0fba15 |
#include "ot-editor.h"
|
|
rpm-build |
0fba15 |
#include "ostree.h"
|
|
rpm-build |
0fba15 |
#include "otutil.h"
|
|
rpm-build |
0fba15 |
#include "parse-datetime.h"
|
|
rpm-build |
0fba15 |
#include "ostree-repo-private.h"
|
|
rpm-build |
0fba15 |
#include "ostree-libarchive-private.h"
|
|
rpm-build |
0fba15 |
#include "ostree-sign.h"
|
|
rpm-build |
0fba15 |
|
|
rpm-build |
0fba15 |
static char *opt_subject;
|
|
rpm-build |
0fba15 |
static char *opt_body;
|
|
rpm-build |
0fba15 |
static char *opt_body_file;
|
|
rpm-build |
0fba15 |
static gboolean opt_editor;
|
|
rpm-build |
0fba15 |
static char *opt_parent;
|
|
rpm-build |
0fba15 |
static gboolean opt_orphan;
|
|
rpm-build |
0fba15 |
static gboolean opt_no_bindings;
|
|
rpm-build |
0fba15 |
static char **opt_bind_refs;
|
|
rpm-build |
0fba15 |
static char *opt_branch;
|
|
rpm-build |
0fba15 |
static char *opt_statoverride_file;
|
|
rpm-build |
0fba15 |
static char *opt_skiplist_file;
|
|
rpm-build |
0fba15 |
static char **opt_metadata_strings;
|
|
rpm-build |
0fba15 |
static char **opt_metadata_variants;
|
|
rpm-build |
0fba15 |
static char **opt_detached_metadata_strings;
|
|
rpm-build |
0fba15 |
static char **opt_metadata_keep;
|
|
rpm-build |
0fba15 |
static gboolean opt_link_checkout_speedup;
|
|
rpm-build |
0fba15 |
static gboolean opt_skip_if_unchanged;
|
|
rpm-build |
0fba15 |
static gboolean opt_tar_autocreate_parents;
|
|
rpm-build |
0fba15 |
static char *opt_tar_pathname_filter;
|
|
rpm-build |
0fba15 |
static gboolean opt_no_xattrs;
|
|
rpm-build |
0fba15 |
static char *opt_selinux_policy;
|
|
rpm-build |
0fba15 |
static gboolean opt_selinux_policy_from_base;
|
|
rpm-build |
0fba15 |
static gboolean opt_canonical_permissions;
|
|
rpm-build |
0fba15 |
static gboolean opt_ro_executables;
|
|
rpm-build |
0fba15 |
static gboolean opt_consume;
|
|
rpm-build |
0fba15 |
static gboolean opt_devino_canonical;
|
|
rpm-build |
0fba15 |
static char *opt_base;
|
|
rpm-build |
0fba15 |
static char **opt_trees;
|
|
rpm-build |
0fba15 |
static gint opt_owner_uid = -1;
|
|
rpm-build |
0fba15 |
static gint opt_owner_gid = -1;
|
|
rpm-build |
0fba15 |
static gboolean opt_table_output;
|
|
rpm-build |
0fba15 |
#ifndef OSTREE_DISABLE_GPGME
|
|
rpm-build |
0fba15 |
static char **opt_gpg_key_ids;
|
|
rpm-build |
0fba15 |
static char *opt_gpg_homedir;
|
|
rpm-build |
0fba15 |
#endif
|
|
rpm-build |
0fba15 |
static char **opt_key_ids;
|
|
rpm-build |
0fba15 |
static char *opt_sign_name;
|
|
rpm-build |
0fba15 |
static gboolean opt_generate_sizes;
|
|
rpm-build |
0fba15 |
static gboolean opt_disable_fsync;
|
|
rpm-build |
0fba15 |
static char *opt_timestamp;
|
|
rpm-build |
0fba15 |
|
|
rpm-build |
0fba15 |
static gboolean
|
|
rpm-build |
0fba15 |
parse_fsync_cb (const char *option_name,
|
|
rpm-build |
0fba15 |
const char *value,
|
|
rpm-build |
0fba15 |
gpointer data,
|
|
rpm-build |
0fba15 |
GError **error)
|
|
rpm-build |
0fba15 |
{
|
|
rpm-build |
0fba15 |
gboolean val;
|
|
rpm-build |
0fba15 |
if (!ot_parse_boolean (value, &val, error))
|
|
rpm-build |
0fba15 |
return FALSE;
|
|
rpm-build |
0fba15 |
|
|
rpm-build |
0fba15 |
opt_disable_fsync = !val;
|
|
rpm-build |
0fba15 |
return TRUE;
|
|
rpm-build |
0fba15 |
}
|
|
rpm-build |
0fba15 |
|
|
rpm-build |
0fba15 |
/* ATTENTION:
|
|
rpm-build |
0fba15 |
* Please remember to update the bash-completion script (bash/ostree) and
|
|
rpm-build |
0fba15 |
* man page (man/ostree-commit.xml) when changing the option list.
|
|
rpm-build |
0fba15 |
*/
|
|
rpm-build |
0fba15 |
|
|
rpm-build |
0fba15 |
static GOptionEntry options[] = {
|
|
rpm-build |
0fba15 |
{ "parent", 0, 0, G_OPTION_ARG_STRING, &opt_parent, "Parent ref, or \"none\"", "REF" },
|
|
rpm-build |
0fba15 |
{ "subject", 's', 0, G_OPTION_ARG_STRING, &opt_subject, "One line subject", "SUBJECT" },
|
|
rpm-build |
0fba15 |
{ "body", 'm', 0, G_OPTION_ARG_STRING, &opt_body, "Full description", "BODY" },
|
|
rpm-build |
0fba15 |
{ "body-file", 'F', 0, G_OPTION_ARG_FILENAME, &opt_body_file, "Commit message from FILE path", "FILE" },
|
|
rpm-build |
0fba15 |
{ "editor", 'e', 0, G_OPTION_ARG_NONE, &opt_editor, "Use an editor to write the commit message", NULL },
|
|
rpm-build |
0fba15 |
{ "branch", 'b', 0, G_OPTION_ARG_STRING, &opt_branch, "Branch", "BRANCH" },
|
|
rpm-build |
0fba15 |
{ "orphan", 0, 0, G_OPTION_ARG_NONE, &opt_orphan, "Create a commit without writing a ref", NULL },
|
|
rpm-build |
0fba15 |
{ "no-bindings", 0, 0, G_OPTION_ARG_NONE, &opt_no_bindings, "Do not write any ref bindings", NULL },
|
|
rpm-build |
0fba15 |
{ "bind-ref", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_bind_refs, "Add a ref to ref binding commit metadata", "BRANCH" },
|
|
rpm-build |
0fba15 |
{ "base", 0, 0, G_OPTION_ARG_STRING, &opt_base, "Start from the given commit as a base (no modifiers apply)", "REF" },
|
|
rpm-build |
0fba15 |
{ "tree", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_trees, "Overlay the given argument as a tree", "dir=PATH or tar=TARFILE or ref=COMMIT" },
|
|
rpm-build |
0fba15 |
{ "add-metadata-string", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_metadata_strings, "Add a key/value pair to metadata", "KEY=VALUE" },
|
|
rpm-build |
0fba15 |
{ "add-metadata", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_metadata_variants, "Add a key/value pair to metadata, where the KEY is a string, an VALUE is g_variant_parse() formatted", "KEY=VALUE" },
|
|
rpm-build |
0fba15 |
{ "keep-metadata", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_metadata_keep, "Keep metadata KEY and its associated VALUE from parent", "KEY" },
|
|
rpm-build |
0fba15 |
{ "add-detached-metadata-string", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_detached_metadata_strings, "Add a key/value pair to detached metadata", "KEY=VALUE" },
|
|
rpm-build |
0fba15 |
{ "owner-uid", 0, 0, G_OPTION_ARG_INT, &opt_owner_uid, "Set file ownership user id", "UID" },
|
|
rpm-build |
0fba15 |
{ "owner-gid", 0, 0, G_OPTION_ARG_INT, &opt_owner_gid, "Set file ownership group id", "GID" },
|
|
rpm-build |
0fba15 |
{ "canonical-permissions", 0, 0, G_OPTION_ARG_NONE, &opt_canonical_permissions, "Canonicalize permissions in the same way bare-user does for hardlinked files", NULL },
|
|
rpm-build |
0fba15 |
{ "mode-ro-executables", 0, 0, G_OPTION_ARG_NONE, &opt_ro_executables, "Ensure executable files are not writable", NULL },
|
|
rpm-build |
0fba15 |
{ "no-xattrs", 0, 0, G_OPTION_ARG_NONE, &opt_no_xattrs, "Do not import extended attributes", NULL },
|
|
rpm-build |
0fba15 |
{ "selinux-policy", 0, 0, G_OPTION_ARG_FILENAME, &opt_selinux_policy, "Set SELinux labels based on policy in root filesystem PATH (may be /)", "PATH" },
|
|
rpm-build |
0fba15 |
{ "selinux-policy-from-base", 'P', 0, G_OPTION_ARG_NONE, &opt_selinux_policy_from_base, "Set SELinux labels based on first --tree argument", NULL },
|
|
rpm-build |
0fba15 |
{ "link-checkout-speedup", 0, 0, G_OPTION_ARG_NONE, &opt_link_checkout_speedup, "Optimize for commits of trees composed of hardlinks into the repository", NULL },
|
|
rpm-build |
0fba15 |
{ "devino-canonical", 'I', 0, G_OPTION_ARG_NONE, &opt_devino_canonical, "Assume hardlinked objects are unmodified. Implies --link-checkout-speedup", NULL },
|
|
rpm-build |
0fba15 |
{ "tar-autocreate-parents", 0, 0, G_OPTION_ARG_NONE, &opt_tar_autocreate_parents, "When loading tar archives, automatically create parent directories as needed", NULL },
|
|
rpm-build |
0fba15 |
{ "tar-pathname-filter", 0, 0, G_OPTION_ARG_STRING, &opt_tar_pathname_filter, "When loading tar archives, use REGEX,REPLACEMENT against path names", "REGEX,REPLACEMENT" },
|
|
rpm-build |
0fba15 |
{ "skip-if-unchanged", 0, 0, G_OPTION_ARG_NONE, &opt_skip_if_unchanged, "If the contents are unchanged from previous commit, do nothing", NULL },
|
|
rpm-build |
0fba15 |
{ "statoverride", 0, 0, G_OPTION_ARG_FILENAME, &opt_statoverride_file, "File containing list of modifications to make to permissions", "PATH" },
|
|
rpm-build |
0fba15 |
{ "skip-list", 0, 0, G_OPTION_ARG_FILENAME, &opt_skiplist_file, "File containing list of files to skip", "PATH" },
|
|
rpm-build |
0fba15 |
{ "consume", 0, 0, G_OPTION_ARG_NONE, &opt_consume, "Consume (delete) content after commit (for local directories)", NULL },
|
|
rpm-build |
0fba15 |
{ "table-output", 0, 0, G_OPTION_ARG_NONE, &opt_table_output, "Output more information in a KEY: VALUE format", NULL },
|
|
rpm-build |
0fba15 |
#ifndef OSTREE_DISABLE_GPGME
|
|
rpm-build |
0fba15 |
{ "gpg-sign", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_gpg_key_ids, "GPG Key ID to sign the commit with", "KEY-ID"},
|
|
rpm-build |
0fba15 |
{ "gpg-homedir", 0, 0, G_OPTION_ARG_FILENAME, &opt_gpg_homedir, "GPG Homedir to use when looking for keyrings", "HOMEDIR"},
|
|
rpm-build |
0fba15 |
#endif
|
|
rpm-build |
0fba15 |
{ "sign", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_key_ids, "Sign the commit with", "KEY_ID"},
|
|
rpm-build |
0fba15 |
{ "sign-type", 0, 0, G_OPTION_ARG_STRING, &opt_sign_name, "Signature type to use (defaults to 'ed25519')", "NAME"},
|
|
rpm-build |
0fba15 |
{ "generate-sizes", 0, 0, G_OPTION_ARG_NONE, &opt_generate_sizes, "Generate size information along with commit metadata", NULL },
|
|
rpm-build |
0fba15 |
{ "disable-fsync", 0, G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_NONE, &opt_disable_fsync, "Do not invoke fsync()", NULL },
|
|
rpm-build |
0fba15 |
{ "fsync", 0, 0, G_OPTION_ARG_CALLBACK, parse_fsync_cb, "Specify how to invoke fsync()", "POLICY" },
|
|
rpm-build |
0fba15 |
{ "timestamp", 0, 0, G_OPTION_ARG_STRING, &opt_timestamp, "Override the timestamp of the commit", "TIMESTAMP" },
|
|
rpm-build |
0fba15 |
{ NULL }
|
|
rpm-build |
0fba15 |
};
|
|
rpm-build |
0fba15 |
|
|
rpm-build |
0fba15 |
struct CommitFilterData {
|
|
rpm-build |
0fba15 |
GHashTable *mode_adds;
|
|
rpm-build |
0fba15 |
GHashTable *mode_overrides;
|
|
rpm-build |
0fba15 |
GHashTable *skip_list;
|
|
rpm-build |
0fba15 |
};
|
|
rpm-build |
0fba15 |
|
|
rpm-build |
0fba15 |
static gboolean
|
|
rpm-build |
0fba15 |
handle_statoverride_line (const char *line,
|
|
rpm-build |
0fba15 |
void *data,
|
|
rpm-build |
0fba15 |
GError **error)
|
|
rpm-build |
0fba15 |
{
|
|
rpm-build |
0fba15 |
struct CommitFilterData *cf = data;
|
|
rpm-build |
0fba15 |
const char *spc = strchr (line, ' ');
|
|
rpm-build |
0fba15 |
if (spc == NULL)
|
|
rpm-build |
0fba15 |
return glnx_throw (error, "Malformed statoverride file (no space found)");
|
|
rpm-build |
0fba15 |
const char *fn = spc + 1;
|
|
rpm-build |
0fba15 |
|
|
rpm-build |
0fba15 |
if (g_str_has_prefix (line, "="))
|
|
rpm-build |
0fba15 |
{
|
|
rpm-build |
0fba15 |
guint mode_override = (guint32)(gint32)g_ascii_strtod (line+1, NULL);
|
|
rpm-build |
0fba15 |
g_hash_table_insert (cf->mode_overrides, g_strdup (fn),
|
|
rpm-build |
0fba15 |
GUINT_TO_POINTER((gint32)mode_override));
|
|
rpm-build |
0fba15 |
}
|
|
rpm-build |
0fba15 |
else
|
|
rpm-build |
0fba15 |
{
|
|
rpm-build |
0fba15 |
guint mode_add = (guint32)(gint32)g_ascii_strtod (line, NULL);
|
|
rpm-build |
0fba15 |
g_hash_table_insert (cf->mode_adds, g_strdup (fn),
|
|
rpm-build |
0fba15 |
GUINT_TO_POINTER((gint32)mode_add));
|
|
rpm-build |
0fba15 |
}
|
|
rpm-build |
0fba15 |
return TRUE;
|
|
rpm-build |
0fba15 |
}
|
|
rpm-build |
0fba15 |
|
|
rpm-build |
0fba15 |
static gboolean
|
|
rpm-build |
0fba15 |
handle_skiplist_line (const char *line,
|
|
rpm-build |
0fba15 |
void *data,
|
|
rpm-build |
0fba15 |
GError **error)
|
|
rpm-build |
0fba15 |
{
|
|
rpm-build |
0fba15 |
GHashTable *files = data;
|
|
rpm-build |
0fba15 |
g_hash_table_add (files, g_strdup (line));
|
|
rpm-build |
0fba15 |
return TRUE;
|
|
rpm-build |
0fba15 |
}
|
|
rpm-build |
0fba15 |
|
|
rpm-build |
0fba15 |
static OstreeRepoCommitFilterResult
|
|
rpm-build |
0fba15 |
commit_filter (OstreeRepo *self,
|
|
rpm-build |
0fba15 |
const char *path,
|
|
rpm-build |
0fba15 |
GFileInfo *file_info,
|
|
rpm-build |
0fba15 |
gpointer user_data)
|
|
rpm-build |
0fba15 |
{
|
|
rpm-build |
0fba15 |
struct CommitFilterData *data = user_data;
|
|
rpm-build |
0fba15 |
GHashTable *mode_adds = data->mode_adds;
|
|
rpm-build |
0fba15 |
GHashTable *mode_overrides = data->mode_overrides;
|
|
rpm-build |
0fba15 |
GHashTable *skip_list = data->skip_list;
|
|
rpm-build |
0fba15 |
gpointer value;
|
|
rpm-build |
0fba15 |
|
|
rpm-build |
0fba15 |
if (opt_owner_uid >= 0)
|
|
rpm-build |
0fba15 |
g_file_info_set_attribute_uint32 (file_info, "unix::uid", opt_owner_uid);
|
|
rpm-build |
0fba15 |
if (opt_owner_gid >= 0)
|
|
rpm-build |
0fba15 |
g_file_info_set_attribute_uint32 (file_info, "unix::gid", opt_owner_gid);
|
|
rpm-build |
0fba15 |
guint mode = g_file_info_get_attribute_uint32 (file_info, "unix::mode");
|
|
rpm-build |
0fba15 |
|
|
rpm-build |
0fba15 |
if (S_ISREG (mode) && opt_ro_executables && (mode & (S_IXUSR | S_IXGRP | S_IXOTH)))
|
|
rpm-build |
0fba15 |
{
|
|
rpm-build |
0fba15 |
mode &= ~(S_IWUSR | S_IWGRP | S_IWOTH);
|
|
rpm-build |
0fba15 |
g_file_info_set_attribute_uint32 (file_info, "unix::mode", mode);
|
|
rpm-build |
0fba15 |
}
|
|
rpm-build |
0fba15 |
|
|
rpm-build |
0fba15 |
if (mode_adds && g_hash_table_lookup_extended (mode_adds, path, NULL, &value))
|
|
rpm-build |
0fba15 |
{
|
|
rpm-build |
0fba15 |
guint mode_add = GPOINTER_TO_UINT (value);
|
|
rpm-build |
0fba15 |
g_file_info_set_attribute_uint32 (file_info, "unix::mode",
|
|
rpm-build |
0fba15 |
mode | mode_add);
|
|
rpm-build |
0fba15 |
g_hash_table_remove (mode_adds, path);
|
|
rpm-build |
0fba15 |
}
|
|
rpm-build |
0fba15 |
else if (mode_overrides && g_hash_table_lookup_extended (mode_overrides, path, NULL, &value))
|
|
rpm-build |
0fba15 |
{
|
|
rpm-build |
0fba15 |
guint current_fmt = g_file_info_get_attribute_uint32 (file_info, "unix::mode") & S_IFMT;
|
|
rpm-build |
0fba15 |
guint mode_override = GPOINTER_TO_UINT (value);
|
|
rpm-build |
0fba15 |
g_file_info_set_attribute_uint32 (file_info, "unix::mode",
|
|
rpm-build |
0fba15 |
current_fmt | mode_override);
|
|
rpm-build |
0fba15 |
g_hash_table_remove (mode_adds, path);
|
|
rpm-build |
0fba15 |
}
|
|
rpm-build |
0fba15 |
|
|
rpm-build |
0fba15 |
if (skip_list && g_hash_table_contains (skip_list, path))
|
|
rpm-build |
0fba15 |
{
|
|
rpm-build |
0fba15 |
g_hash_table_remove (skip_list, path);
|
|
rpm-build |
0fba15 |
return OSTREE_REPO_COMMIT_FILTER_SKIP;
|
|
rpm-build |
0fba15 |
}
|
|
rpm-build |
0fba15 |
|
|
rpm-build |
0fba15 |
return OSTREE_REPO_COMMIT_FILTER_ALLOW;
|
|
rpm-build |
0fba15 |
}
|
|
rpm-build |
0fba15 |
|
|
rpm-build |
0fba15 |
#ifdef HAVE_LIBARCHIVE
|
|
rpm-build |
0fba15 |
typedef struct {
|
|
rpm-build |
0fba15 |
GRegex *regex;
|
|
rpm-build |
0fba15 |
const char *replacement;
|
|
rpm-build |
0fba15 |
} TranslatePathnameData;
|
|
rpm-build |
0fba15 |
|
|
rpm-build |
0fba15 |
/* Implement --tar-pathname-filter */
|
|
rpm-build |
0fba15 |
static char *
|
|
rpm-build |
0fba15 |
handle_translate_pathname (OstreeRepo *repo,
|
|
rpm-build |
0fba15 |
const struct stat *stbuf,
|
|
rpm-build |
0fba15 |
const char *path,
|
|
rpm-build |
0fba15 |
gpointer user_data)
|
|
rpm-build |
0fba15 |
{
|
|
rpm-build |
0fba15 |
TranslatePathnameData *tpdata = user_data;
|
|
rpm-build |
0fba15 |
g_autoptr(GError) tmp_error = NULL;
|
|
rpm-build |
0fba15 |
char *ret =
|
|
rpm-build |
0fba15 |
g_regex_replace (tpdata->regex, path, -1, 0,
|
|
rpm-build |
0fba15 |
tpdata->replacement, 0, &tmp_error);
|
|
rpm-build |
0fba15 |
g_assert_no_error (tmp_error);
|
|
rpm-build |
0fba15 |
g_assert (ret);
|
|
rpm-build |
0fba15 |
return ret;
|
|
rpm-build |
0fba15 |
}
|
|
rpm-build |
0fba15 |
#endif
|
|
rpm-build |
0fba15 |
|
|
rpm-build |
0fba15 |
static gboolean
|
|
rpm-build |
0fba15 |
commit_editor (OstreeRepo *repo,
|
|
rpm-build |
0fba15 |
const char *branch,
|
|
rpm-build |
0fba15 |
char **subject,
|
|
rpm-build |
0fba15 |
char **body,
|
|
rpm-build |
0fba15 |
GCancellable *cancellable,
|
|
rpm-build |
0fba15 |
GError **error)
|
|
rpm-build |
0fba15 |
{
|
|
rpm-build |
0fba15 |
g_autofree char *input = g_strdup_printf ("\n"
|
|
rpm-build |
0fba15 |
"# Please enter the commit message for your changes. The first line will\n"
|
|
rpm-build |
0fba15 |
"# become the subject, and the remainder the body. Lines starting\n"
|
|
rpm-build |
0fba15 |
"# with '#' will be ignored, and an empty message aborts the commit."
|
|
rpm-build |
0fba15 |
"%s%s%s%s%s%s\n"
|
|
rpm-build |
0fba15 |
, branch ? "\n#\n# Branch: " : "", branch ? branch : ""
|
|
rpm-build |
0fba15 |
, *subject ? "\n" : "", *subject ? *subject : ""
|
|
rpm-build |
0fba15 |
, *body ? "\n" : "", *body ? *body : ""
|
|
rpm-build |
0fba15 |
);
|
|
rpm-build |
0fba15 |
|
|
rpm-build |
0fba15 |
*subject = NULL;
|
|
rpm-build |
0fba15 |
*body = NULL;
|
|
rpm-build |
0fba15 |
|
|
rpm-build |
0fba15 |
g_autofree char *output = ot_editor_prompt (repo, input, cancellable, error);
|
|
rpm-build |
0fba15 |
if (output == NULL)
|
|
rpm-build |
0fba15 |
return FALSE;
|
|
rpm-build |
0fba15 |
|
|
rpm-build |
0fba15 |
g_auto(GStrv) lines = g_strsplit (output, "\n", -1);
|
|
rpm-build |
0fba15 |
g_autoptr(GString) bodybuf = NULL;
|
|
rpm-build |
0fba15 |
for (guint i = 0; lines[i] != NULL; i++)
|
|
rpm-build |
0fba15 |
{
|
|
rpm-build |
0fba15 |
g_strchomp (lines[i]);
|
|
rpm-build |
0fba15 |
|
|
rpm-build |
0fba15 |
/* Lines starting with # are skipped */
|
|
rpm-build |
0fba15 |
if (lines[i][0] == '#')
|
|
rpm-build |
0fba15 |
continue;
|
|
rpm-build |
0fba15 |
|
|
rpm-build |
0fba15 |
/* Blank lines before body starts are skipped */
|
|
rpm-build |
0fba15 |
if (lines[i][0] == '\0')
|
|
rpm-build |
0fba15 |
{
|
|
rpm-build |
0fba15 |
if (!bodybuf)
|
|
rpm-build |
0fba15 |
continue;
|
|
rpm-build |
0fba15 |
}
|
|
rpm-build |
0fba15 |
|
|
rpm-build |
0fba15 |
if (!*subject)
|
|
rpm-build |
0fba15 |
{
|
|
rpm-build |
0fba15 |
*subject = g_strdup (lines[i]);
|
|
rpm-build |
0fba15 |
}
|
|
rpm-build |
0fba15 |
else if (!bodybuf)
|
|
rpm-build |
0fba15 |
{
|
|
rpm-build |
0fba15 |
bodybuf = g_string_new (lines[i]);
|
|
rpm-build |
0fba15 |
}
|
|
rpm-build |
0fba15 |
else
|
|
rpm-build |
0fba15 |
{
|
|
rpm-build |
0fba15 |
g_string_append_c (bodybuf, '\n');
|
|
rpm-build |
0fba15 |
g_string_append (bodybuf, lines[i]);
|
|
rpm-build |
0fba15 |
}
|
|
rpm-build |
0fba15 |
}
|
|
rpm-build |
0fba15 |
|
|
rpm-build |
0fba15 |
if (!*subject)
|
|
rpm-build |
0fba15 |
return glnx_throw (error, "Aborting commit due to empty commit subject.");
|
|
rpm-build |
0fba15 |
|
|
rpm-build |
0fba15 |
if (bodybuf)
|
|
rpm-build |
0fba15 |
{
|
|
rpm-build |
0fba15 |
*body = g_string_free (g_steal_pointer (&bodybuf), FALSE);
|
|
rpm-build |
0fba15 |
g_strchomp (*body);
|
|
rpm-build |
0fba15 |
}
|
|
rpm-build |
0fba15 |
|
|
rpm-build |
0fba15 |
return TRUE;
|
|
rpm-build |
0fba15 |
}
|
|
rpm-build |
0fba15 |
|
|
rpm-build |
0fba15 |
static gboolean
|
|
rpm-build |
0fba15 |
parse_keyvalue_strings (GVariantBuilder *builder,
|
|
rpm-build |
0fba15 |
char **strings,
|
|
rpm-build |
0fba15 |
gboolean is_gvariant_print,
|
|
rpm-build |
0fba15 |
GError **error)
|
|
rpm-build |
0fba15 |
{
|
|
rpm-build |
0fba15 |
for (char ** iter = strings; *iter; iter++)
|
|
rpm-build |
0fba15 |
{
|
|
rpm-build |
0fba15 |
const char *s = *iter;
|
|
rpm-build |
0fba15 |
const char *eq = strchr (s, '=');
|
|
rpm-build |
0fba15 |
if (!eq)
|
|
rpm-build |
0fba15 |
return glnx_throw (error, "Missing '=' in KEY=VALUE metadata '%s'", s);
|
|
rpm-build |
0fba15 |
g_autofree char *key = g_strndup (s, eq - s);
|
|
rpm-build |
0fba15 |
if (is_gvariant_print)
|
|
rpm-build |
0fba15 |
{
|
|
rpm-build |
0fba15 |
g_autoptr(GVariant) value = g_variant_parse (NULL, eq + 1, NULL, NULL, error);
|
|
rpm-build |
0fba15 |
if (!value)
|
|
rpm-build |
0fba15 |
return glnx_prefix_error (error, "Parsing %s", s);
|
|
rpm-build |
0fba15 |
|
|
rpm-build |
0fba15 |
g_variant_builder_add (builder, "{sv}", key, value);
|
|
rpm-build |
0fba15 |
}
|
|
rpm-build |
0fba15 |
else
|
|
rpm-build |
0fba15 |
g_variant_builder_add (builder, "{sv}", key,
|
|
rpm-build |
0fba15 |
g_variant_new_string (eq + 1));
|
|
rpm-build |
0fba15 |
}
|
|
rpm-build |
0fba15 |
|
|
rpm-build |
0fba15 |
return TRUE;
|
|
rpm-build |
0fba15 |
}
|
|
rpm-build |
0fba15 |
|
|
rpm-build |
0fba15 |
static void
|
|
rpm-build |
0fba15 |
add_collection_binding (OstreeRepo *repo,
|
|
rpm-build |
0fba15 |
GVariantBuilder *metadata_builder)
|
|
rpm-build |
0fba15 |
{
|
|
rpm-build |
0fba15 |
const char *collection_id = ostree_repo_get_collection_id (repo);
|
|
rpm-build |
0fba15 |
|
|
rpm-build |
0fba15 |
if (collection_id == NULL)
|
|
rpm-build |
0fba15 |
return;
|
|
rpm-build |
0fba15 |
|
|
rpm-build |
0fba15 |
g_variant_builder_add (metadata_builder, "{s@v}", OSTREE_COMMIT_META_KEY_COLLECTION_BINDING,
|
|
rpm-build |
0fba15 |
g_variant_new_variant (g_variant_new_string (collection_id)));
|
|
rpm-build |
0fba15 |
}
|
|
rpm-build |
0fba15 |
|
|
rpm-build |
0fba15 |
static int
|
|
rpm-build |
0fba15 |
compare_strings (gconstpointer a, gconstpointer b)
|
|
rpm-build |
0fba15 |
{
|
|
rpm-build |
0fba15 |
const char **sa = (const char **)a;
|
|
rpm-build |
0fba15 |
const char **sb = (const char **)b;
|
|
rpm-build |
0fba15 |
|
|
rpm-build |
0fba15 |
return strcmp (*sa, *sb);
|
|
rpm-build |
0fba15 |
}
|
|
rpm-build |
0fba15 |
|
|
rpm-build |
0fba15 |
static void
|
|
rpm-build |
0fba15 |
add_ref_binding (GVariantBuilder *metadata_builder)
|
|
rpm-build |
0fba15 |
{
|
|
rpm-build |
0fba15 |
g_assert (opt_branch != NULL || opt_orphan);
|
|
rpm-build |
0fba15 |
|
|
rpm-build |
0fba15 |
g_autoptr(GPtrArray) refs = g_ptr_array_new ();
|
|
rpm-build |
0fba15 |
if (opt_branch != NULL)
|
|
rpm-build |
0fba15 |
g_ptr_array_add (refs, opt_branch);
|
|
rpm-build |
0fba15 |
for (char **iter = opt_bind_refs; iter != NULL && *iter != NULL; ++iter)
|
|
rpm-build |
0fba15 |
g_ptr_array_add (refs, *iter);
|
|
rpm-build |
0fba15 |
g_ptr_array_sort (refs, compare_strings);
|
|
rpm-build |
0fba15 |
g_autoptr(GVariant) refs_v = g_variant_new_strv ((const char *const *)refs->pdata,
|
|
rpm-build |
0fba15 |
refs->len);
|
|
rpm-build |
0fba15 |
g_variant_builder_add (metadata_builder, "{s@v}", OSTREE_COMMIT_META_KEY_REF_BINDING,
|
|
rpm-build |
0fba15 |
g_variant_new_variant (g_steal_pointer (&refs_v)));
|
|
rpm-build |
0fba15 |
}
|
|
rpm-build |
0fba15 |
|
|
rpm-build |
0fba15 |
/* Note if you're using the API, you currently need to do this yourself */
|
|
rpm-build |
0fba15 |
static void
|
|
rpm-build |
0fba15 |
fill_bindings (OstreeRepo *repo,
|
|
rpm-build |
0fba15 |
GVariant *metadata,
|
|
rpm-build |
0fba15 |
GVariant **out_metadata)
|
|
rpm-build |
0fba15 |
{
|
|
rpm-build |
0fba15 |
g_autoptr(GVariantBuilder) metadata_builder =
|
|
rpm-build |
0fba15 |
ot_util_variant_builder_from_variant (metadata, G_VARIANT_TYPE_VARDICT);
|
|
rpm-build |
0fba15 |
|
|
rpm-build |
0fba15 |
add_ref_binding (metadata_builder);
|
|
rpm-build |
0fba15 |
|
|
rpm-build |
0fba15 |
/* Allow the collection ID to be overridden using
|
|
rpm-build |
0fba15 |
* --add-metadata-string=ostree.collection-binding=blah */
|
|
rpm-build |
0fba15 |
if (metadata == NULL ||
|
|
rpm-build |
0fba15 |
!g_variant_lookup (metadata, OSTREE_COMMIT_META_KEY_COLLECTION_BINDING, "*", NULL))
|
|
rpm-build |
0fba15 |
add_collection_binding (repo, metadata_builder);
|
|
rpm-build |
0fba15 |
|
|
rpm-build |
0fba15 |
*out_metadata = g_variant_ref_sink (g_variant_builder_end (metadata_builder));
|
|
rpm-build |
0fba15 |
}
|
|
rpm-build |
0fba15 |
|
|
rpm-build |
0fba15 |
gboolean
|
|
rpm-build |
0fba15 |
ostree_builtin_commit (int argc, char **argv, OstreeCommandInvocation *invocation, GCancellable *cancellable, GError **error)
|
|
rpm-build |
0fba15 |
{
|
|
rpm-build |
0fba15 |
g_autoptr(GOptionContext) context = NULL;
|
|
rpm-build |
0fba15 |
g_autoptr(OstreeRepo) repo = NULL;
|
|
rpm-build |
0fba15 |
gboolean ret = FALSE;
|
|
rpm-build |
0fba15 |
gboolean skip_commit = FALSE;
|
|
rpm-build |
0fba15 |
g_autoptr(GFile) object_to_commit = NULL;
|
|
rpm-build |
0fba15 |
g_autofree char *parent = NULL;
|
|
rpm-build |
0fba15 |
g_autofree char *commit_checksum = NULL;
|
|
rpm-build |
0fba15 |
g_autoptr(GFile) root = NULL;
|
|
rpm-build |
0fba15 |
g_autoptr(GVariant) metadata = NULL;
|
|
rpm-build |
0fba15 |
g_autoptr(GVariant) detached_metadata = NULL;
|
|
rpm-build |
0fba15 |
g_autoptr(OstreeMutableTree) mtree = NULL;
|
|
rpm-build |
0fba15 |
g_autofree char *tree_type = NULL;
|
|
rpm-build |
0fba15 |
g_autoptr(GHashTable) mode_adds = NULL;
|
|
rpm-build |
0fba15 |
g_autoptr(GHashTable) mode_overrides = NULL;
|
|
rpm-build |
0fba15 |
g_autoptr(GHashTable) skip_list = NULL;
|
|
rpm-build |
0fba15 |
OstreeRepoCommitModifierFlags flags = 0;
|
|
rpm-build |
0fba15 |
g_autoptr(OstreeSePolicy) policy = NULL;
|
|
rpm-build |
0fba15 |
OstreeRepoCommitModifier *modifier = NULL;
|
|
rpm-build |
0fba15 |
OstreeRepoTransactionStats stats;
|
|
rpm-build |
0fba15 |
struct CommitFilterData filter_data = { 0, };
|
|
rpm-build |
0fba15 |
g_autofree char *commit_body = NULL;
|
|
rpm-build |
0fba15 |
g_autoptr (OstreeSign) sign = NULL;
|
|
rpm-build |
0fba15 |
|
|
rpm-build |
0fba15 |
context = g_option_context_new ("[PATH]");
|
|
rpm-build |
0fba15 |
|
|
rpm-build |
0fba15 |
if (!ostree_option_context_parse (context, options, &argc, &argv, invocation, &repo, cancellable, error))
|
|
rpm-build |
0fba15 |
goto out;
|
|
rpm-build |
0fba15 |
|
|
rpm-build |
0fba15 |
if (!ostree_ensure_repo_writable (repo, error))
|
|
rpm-build |
0fba15 |
goto out;
|
|
rpm-build |
0fba15 |
|
|
rpm-build |
0fba15 |
if (opt_statoverride_file)
|
|
rpm-build |
0fba15 |
{
|
|
rpm-build |
0fba15 |
filter_data.mode_adds = mode_adds = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
|
|
rpm-build |
0fba15 |
filter_data.mode_overrides = mode_overrides = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
|
|
rpm-build |
0fba15 |
if (!ot_parse_file_by_line (opt_statoverride_file, handle_statoverride_line,
|
|
rpm-build |
0fba15 |
&filter_data, cancellable, error))
|
|
rpm-build |
0fba15 |
goto out;
|
|
rpm-build |
0fba15 |
}
|
|
rpm-build |
0fba15 |
|
|
rpm-build |
0fba15 |
if (opt_skiplist_file)
|
|
rpm-build |
0fba15 |
{
|
|
rpm-build |
0fba15 |
skip_list = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
|
|
rpm-build |
0fba15 |
if (!ot_parse_file_by_line (opt_skiplist_file, handle_skiplist_line,
|
|
rpm-build |
0fba15 |
skip_list, cancellable, error))
|
|
rpm-build |
0fba15 |
goto out;
|
|
rpm-build |
0fba15 |
}
|
|
rpm-build |
0fba15 |
|
|
rpm-build |
0fba15 |
if (!(opt_branch || opt_orphan))
|
|
rpm-build |
0fba15 |
{
|
|
rpm-build |
0fba15 |
g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
|
rpm-build |
0fba15 |
"A branch must be specified with --branch, or use --orphan");
|
|
rpm-build |
0fba15 |
goto out;
|
|
rpm-build |
0fba15 |
}
|
|
rpm-build |
0fba15 |
|
|
rpm-build |
0fba15 |
if (opt_parent)
|
|
rpm-build |
0fba15 |
{
|
|
rpm-build |
0fba15 |
if (g_str_equal (opt_parent, "none"))
|
|
rpm-build |
0fba15 |
parent = NULL;
|
|
rpm-build |
0fba15 |
else
|
|
rpm-build |
0fba15 |
{
|
|
rpm-build |
0fba15 |
if (!ostree_validate_checksum_string (opt_parent, error))
|
|
rpm-build |
0fba15 |
goto out;
|
|
rpm-build |
0fba15 |
parent = g_strdup (opt_parent);
|
|
rpm-build |
0fba15 |
}
|
|
rpm-build |
0fba15 |
}
|
|
rpm-build |
0fba15 |
else if (!opt_orphan)
|
|
rpm-build |
0fba15 |
{
|
|
rpm-build |
0fba15 |
if (!ostree_repo_resolve_rev (repo, opt_branch, TRUE, &parent, error))
|
|
rpm-build |
0fba15 |
{
|
|
rpm-build |
0fba15 |
if (g_error_matches (*error, G_IO_ERROR, G_IO_ERROR_IS_DIRECTORY))
|
|
rpm-build |
0fba15 |
{
|
|
rpm-build |
0fba15 |
/* A folder exists with the specified ref name,
|
|
rpm-build |
0fba15 |
* which is handled by _ostree_repo_write_ref */
|
|
rpm-build |
0fba15 |
g_clear_error (error);
|
|
rpm-build |
0fba15 |
}
|
|
rpm-build |
0fba15 |
else goto out;
|
|
rpm-build |
0fba15 |
}
|
|
rpm-build |
0fba15 |
}
|
|
rpm-build |
0fba15 |
|
|
rpm-build |
0fba15 |
if (!parent && opt_metadata_keep)
|
|
rpm-build |
0fba15 |
{
|
|
rpm-build |
0fba15 |
g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
|
rpm-build |
0fba15 |
"Either --branch or --parent must be specified when using "
|
|
rpm-build |
0fba15 |
"--keep-metadata");
|
|
rpm-build |
0fba15 |
goto out;
|
|
rpm-build |
0fba15 |
}
|
|
rpm-build |
0fba15 |
|
|
rpm-build |
0fba15 |
if (opt_metadata_strings || opt_metadata_variants || opt_metadata_keep)
|
|
rpm-build |
0fba15 |
{
|
|
rpm-build |
0fba15 |
g_autoptr(GVariantBuilder) builder =
|
|
rpm-build |
0fba15 |
g_variant_builder_new (G_VARIANT_TYPE ("a{sv}"));
|
|
rpm-build |
0fba15 |
|
|
rpm-build |
0fba15 |
if (opt_metadata_strings &&
|
|
rpm-build |
0fba15 |
!parse_keyvalue_strings (builder, opt_metadata_strings, FALSE, error))
|
|
rpm-build |
0fba15 |
goto out;
|
|
rpm-build |
0fba15 |
|
|
rpm-build |
0fba15 |
if (opt_metadata_variants &&
|
|
rpm-build |
0fba15 |
!parse_keyvalue_strings (builder, opt_metadata_variants, TRUE, error))
|
|
rpm-build |
0fba15 |
goto out;
|
|
rpm-build |
0fba15 |
|
|
rpm-build |
0fba15 |
if (opt_metadata_keep)
|
|
rpm-build |
0fba15 |
{
|
|
rpm-build |
0fba15 |
g_assert (parent);
|
|
rpm-build |
0fba15 |
|
|
rpm-build |
0fba15 |
g_autoptr(GVariant) parent_commit = NULL;
|
|
rpm-build |
0fba15 |
if (!ostree_repo_load_commit (repo, parent, &parent_commit, NULL, error))
|
|
rpm-build |
0fba15 |
goto out;
|
|
rpm-build |
0fba15 |
|
|
rpm-build |
0fba15 |
g_auto(GVariantDict) dict;
|
|
rpm-build |
0fba15 |
g_variant_dict_init (&dict, g_variant_get_child_value (parent_commit, 0));
|
|
rpm-build |
0fba15 |
for (char **keyp = opt_metadata_keep; keyp && *keyp; keyp++)
|
|
rpm-build |
0fba15 |
{
|
|
rpm-build |
0fba15 |
const char *key = *keyp;
|
|
rpm-build |
0fba15 |
g_autoptr(GVariant) val = g_variant_dict_lookup_value (&dict, key, NULL);
|
|
rpm-build |
0fba15 |
if (!val)
|
|
rpm-build |
0fba15 |
{
|
|
rpm-build |
0fba15 |
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
|
rpm-build |
0fba15 |
"Missing metadata key '%s' from commit '%s'", key, parent);
|
|
rpm-build |
0fba15 |
goto out;
|
|
rpm-build |
0fba15 |
}
|
|
rpm-build |
0fba15 |
|
|
rpm-build |
0fba15 |
g_variant_builder_add (builder, "{sv}", key, val);
|
|
rpm-build |
0fba15 |
}
|
|
rpm-build |
0fba15 |
}
|
|
rpm-build |
0fba15 |
|
|
rpm-build |
0fba15 |
metadata = g_variant_ref_sink (g_variant_builder_end (builder));
|
|
rpm-build |
0fba15 |
}
|
|
rpm-build |
0fba15 |
|
|
rpm-build |
0fba15 |
if (opt_detached_metadata_strings)
|
|
rpm-build |
0fba15 |
{
|
|
rpm-build |
0fba15 |
g_autoptr(GVariantBuilder) builder =
|
|
rpm-build |
0fba15 |
g_variant_builder_new (G_VARIANT_TYPE ("a{sv}"));
|
|
rpm-build |
0fba15 |
|
|
rpm-build |
0fba15 |
if (!parse_keyvalue_strings (builder, opt_detached_metadata_strings, FALSE, error))
|
|
rpm-build |
0fba15 |
goto out;
|
|
rpm-build |
0fba15 |
|
|
rpm-build |
0fba15 |
detached_metadata = g_variant_ref_sink (g_variant_builder_end (builder));
|
|
rpm-build |
0fba15 |
}
|
|
rpm-build |
0fba15 |
|
|
rpm-build |
0fba15 |
if (opt_no_xattrs)
|
|
rpm-build |
0fba15 |
flags |= OSTREE_REPO_COMMIT_MODIFIER_FLAGS_SKIP_XATTRS;
|
|
rpm-build |
0fba15 |
if (opt_consume)
|
|
rpm-build |
0fba15 |
flags |= OSTREE_REPO_COMMIT_MODIFIER_FLAGS_CONSUME;
|
|
rpm-build |
0fba15 |
if (opt_devino_canonical)
|
|
rpm-build |
0fba15 |
{
|
|
rpm-build |
0fba15 |
opt_link_checkout_speedup = TRUE; /* Imply this */
|
|
rpm-build |
0fba15 |
flags |= OSTREE_REPO_COMMIT_MODIFIER_FLAGS_DEVINO_CANONICAL;
|
|
rpm-build |
0fba15 |
}
|
|
rpm-build |
0fba15 |
if (opt_canonical_permissions)
|
|
rpm-build |
0fba15 |
flags |= OSTREE_REPO_COMMIT_MODIFIER_FLAGS_CANONICAL_PERMISSIONS;
|
|
rpm-build |
0fba15 |
if (opt_generate_sizes)
|
|
rpm-build |
0fba15 |
flags |= OSTREE_REPO_COMMIT_MODIFIER_FLAGS_GENERATE_SIZES;
|
|
rpm-build |
0fba15 |
if (opt_disable_fsync)
|
|
rpm-build |
0fba15 |
ostree_repo_set_disable_fsync (repo, TRUE);
|
|
rpm-build |
0fba15 |
if (opt_selinux_policy && opt_selinux_policy_from_base)
|
|
rpm-build |
0fba15 |
{
|
|
rpm-build |
0fba15 |
glnx_throw (error, "Cannot specify both --selinux-policy and --selinux-policy-from-base");
|
|
rpm-build |
0fba15 |
goto out;
|
|
rpm-build |
0fba15 |
}
|
|
rpm-build |
0fba15 |
|
|
rpm-build |
0fba15 |
if (flags != 0
|
|
rpm-build |
0fba15 |
|| opt_owner_uid >= 0
|
|
rpm-build |
0fba15 |
|| opt_owner_gid >= 0
|
|
rpm-build |
0fba15 |
|| opt_statoverride_file != NULL
|
|
rpm-build |
0fba15 |
|| opt_skiplist_file != NULL
|
|
rpm-build |
0fba15 |
|| opt_no_xattrs
|
|
rpm-build |
0fba15 |
|| opt_ro_executables
|
|
rpm-build |
0fba15 |
|| opt_selinux_policy
|
|
rpm-build |
0fba15 |
|| opt_selinux_policy_from_base)
|
|
rpm-build |
0fba15 |
{
|
|
rpm-build |
0fba15 |
filter_data.mode_adds = mode_adds;
|
|
rpm-build |
0fba15 |
filter_data.skip_list = skip_list;
|
|
rpm-build |
0fba15 |
modifier = ostree_repo_commit_modifier_new (flags, commit_filter,
|
|
rpm-build |
0fba15 |
&filter_data, NULL);
|
|
rpm-build |
0fba15 |
}
|
|
rpm-build |
0fba15 |
|
|
rpm-build |
0fba15 |
if (opt_editor)
|
|
rpm-build |
0fba15 |
{
|
|
rpm-build |
0fba15 |
if (!commit_editor (repo, opt_branch, &opt_subject, &commit_body, cancellable, error))
|
|
rpm-build |
0fba15 |
goto out;
|
|
rpm-build |
0fba15 |
}
|
|
rpm-build |
0fba15 |
else if (opt_body_file)
|
|
rpm-build |
0fba15 |
{
|
|
rpm-build |
0fba15 |
commit_body = glnx_file_get_contents_utf8_at (AT_FDCWD, opt_body_file, NULL,
|
|
rpm-build |
0fba15 |
cancellable, error);
|
|
rpm-build |
0fba15 |
if (!commit_body)
|
|
rpm-build |
0fba15 |
goto out;
|
|
rpm-build |
0fba15 |
}
|
|
rpm-build |
0fba15 |
else if (opt_body)
|
|
rpm-build |
0fba15 |
commit_body = g_strdup (opt_body);
|
|
rpm-build |
0fba15 |
|
|
rpm-build |
0fba15 |
if (!ostree_repo_prepare_transaction (repo, NULL, cancellable, error))
|
|
rpm-build |
0fba15 |
goto out;
|
|
rpm-build |
0fba15 |
|
|
rpm-build |
0fba15 |
if (opt_link_checkout_speedup && !ostree_repo_scan_hardlinks (repo, cancellable, error))
|
|
rpm-build |
0fba15 |
goto out;
|
|
rpm-build |
0fba15 |
|
|
rpm-build |
0fba15 |
if (opt_base)
|
|
rpm-build |
0fba15 |
{
|
|
rpm-build |
0fba15 |
g_autofree char *base_commit = NULL;
|
|
rpm-build |
0fba15 |
g_autoptr(GFile) root = NULL;
|
|
rpm-build |
0fba15 |
if (!ostree_repo_read_commit (repo, opt_base, &root, &base_commit, cancellable, error))
|
|
rpm-build |
0fba15 |
goto out;
|
|
rpm-build |
0fba15 |
OstreeRepoFile *rootf = (OstreeRepoFile*) root;
|
|
rpm-build |
0fba15 |
|
|
rpm-build |
0fba15 |
mtree = ostree_mutable_tree_new_from_checksum (repo,
|
|
rpm-build |
0fba15 |
ostree_repo_file_tree_get_contents_checksum (rootf),
|
|
rpm-build |
0fba15 |
ostree_repo_file_tree_get_metadata_checksum (rootf));
|
|
rpm-build |
0fba15 |
|
|
rpm-build |
0fba15 |
if (opt_selinux_policy_from_base)
|
|
rpm-build |
0fba15 |
{
|
|
rpm-build |
0fba15 |
g_assert (modifier);
|
|
rpm-build |
0fba15 |
if (!ostree_repo_commit_modifier_set_sepolicy_from_commit (modifier, repo, base_commit, cancellable, error))
|
|
rpm-build |
0fba15 |
goto out;
|
|
rpm-build |
0fba15 |
/* Don't try to handle it twice */
|
|
rpm-build |
0fba15 |
opt_selinux_policy_from_base = FALSE;
|
|
rpm-build |
0fba15 |
}
|
|
rpm-build |
0fba15 |
}
|
|
rpm-build |
0fba15 |
else
|
|
rpm-build |
0fba15 |
{
|
|
rpm-build |
0fba15 |
mtree = ostree_mutable_tree_new ();
|
|
rpm-build |
0fba15 |
}
|
|
rpm-build |
0fba15 |
|
|
rpm-build |
0fba15 |
|
|
rpm-build |
0fba15 |
/* Convert implicit . or explicit path via argv into
|
|
rpm-build |
0fba15 |
* --tree=dir= so that we only have one primary code path below.
|
|
rpm-build |
0fba15 |
*/
|
|
rpm-build |
0fba15 |
if (opt_trees == NULL || opt_trees[0] == NULL)
|
|
rpm-build |
0fba15 |
{
|
|
rpm-build |
0fba15 |
char *path;
|
|
rpm-build |
0fba15 |
if (argc <= 1)
|
|
rpm-build |
0fba15 |
path = ".";
|
|
rpm-build |
0fba15 |
else
|
|
rpm-build |
0fba15 |
path = argv[1];
|
|
rpm-build |
0fba15 |
opt_trees = g_new0 (char *, 2);
|
|
rpm-build |
0fba15 |
opt_trees[0] = g_strconcat ("dir=", path, NULL);
|
|
rpm-build |
0fba15 |
}
|
|
rpm-build |
0fba15 |
|
|
rpm-build |
0fba15 |
const char *const*tree_iter;
|
|
rpm-build |
0fba15 |
const char *tree;
|
|
rpm-build |
0fba15 |
const char *eq;
|
|
rpm-build |
0fba15 |
g_assert (opt_trees && *opt_trees);
|
|
rpm-build |
0fba15 |
for (tree_iter = (const char *const*)opt_trees; *tree_iter; tree_iter++)
|
|
rpm-build |
0fba15 |
{
|
|
rpm-build |
0fba15 |
const gboolean first = (tree_iter == (const char *const*)opt_trees);
|
|
rpm-build |
0fba15 |
tree = *tree_iter;
|
|
rpm-build |
0fba15 |
|
|
rpm-build |
0fba15 |
eq = strchr (tree, '=');
|
|
rpm-build |
0fba15 |
if (!eq)
|
|
rpm-build |
0fba15 |
{
|
|
rpm-build |
0fba15 |
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
|
rpm-build |
0fba15 |
"Missing type in tree specification '%s'", tree);
|
|
rpm-build |
0fba15 |
goto out;
|
|
rpm-build |
0fba15 |
}
|
|
rpm-build |
0fba15 |
g_free (tree_type);
|
|
rpm-build |
0fba15 |
tree_type = g_strndup (tree, eq - tree);
|
|
rpm-build |
0fba15 |
tree = eq + 1;
|
|
rpm-build |
0fba15 |
|
|
rpm-build |
0fba15 |
g_clear_object (&object_to_commit);
|
|
rpm-build |
0fba15 |
if (strcmp (tree_type, "dir") == 0)
|
|
rpm-build |
0fba15 |
{
|
|
rpm-build |
0fba15 |
if (first && opt_selinux_policy_from_base)
|
|
rpm-build |
0fba15 |
{
|
|
rpm-build |
0fba15 |
opt_selinux_policy = g_strdup (tree);
|
|
rpm-build |
0fba15 |
opt_selinux_policy_from_base = FALSE;
|
|
rpm-build |
0fba15 |
}
|
|
rpm-build |
0fba15 |
if (first && opt_selinux_policy)
|
|
rpm-build |
0fba15 |
{
|
|
rpm-build |
0fba15 |
g_assert (modifier);
|
|
rpm-build |
0fba15 |
glnx_autofd int rootfs_dfd = -1;
|
|
rpm-build |
0fba15 |
if (!glnx_opendirat (AT_FDCWD, opt_selinux_policy, TRUE, &rootfs_dfd, error))
|
|
rpm-build |
0fba15 |
goto out;
|
|
rpm-build |
0fba15 |
policy = ostree_sepolicy_new_at (rootfs_dfd, cancellable, error);
|
|
rpm-build |
0fba15 |
if (!policy)
|
|
rpm-build |
0fba15 |
goto out;
|
|
rpm-build |
0fba15 |
ostree_repo_commit_modifier_set_sepolicy (modifier, policy);
|
|
rpm-build |
0fba15 |
}
|
|
rpm-build |
0fba15 |
if (!ostree_repo_write_dfd_to_mtree (repo, AT_FDCWD, tree, mtree, modifier,
|
|
rpm-build |
0fba15 |
cancellable, error))
|
|
rpm-build |
0fba15 |
goto out;
|
|
rpm-build |
0fba15 |
}
|
|
rpm-build |
0fba15 |
else if (strcmp (tree_type, "tar") == 0)
|
|
rpm-build |
0fba15 |
{
|
|
rpm-build |
0fba15 |
if (first && opt_selinux_policy_from_base)
|
|
rpm-build |
0fba15 |
{
|
|
rpm-build |
0fba15 |
glnx_throw (error, "Cannot use --selinux-policy-from-base with tar");
|
|
rpm-build |
0fba15 |
goto out;
|
|
rpm-build |
0fba15 |
}
|
|
rpm-build |
0fba15 |
if (!opt_tar_pathname_filter)
|
|
rpm-build |
0fba15 |
{
|
|
rpm-build |
0fba15 |
if (strcmp (tree, "-") == 0)
|
|
rpm-build |
0fba15 |
{
|
|
rpm-build |
0fba15 |
if (!ostree_repo_write_archive_to_mtree_from_fd (repo, STDIN_FILENO, mtree, modifier,
|
|
rpm-build |
0fba15 |
opt_tar_autocreate_parents,
|
|
rpm-build |
0fba15 |
cancellable, error))
|
|
rpm-build |
0fba15 |
goto out;
|
|
rpm-build |
0fba15 |
}
|
|
rpm-build |
0fba15 |
else
|
|
rpm-build |
0fba15 |
{
|
|
rpm-build |
0fba15 |
object_to_commit = g_file_new_for_path (tree);
|
|
rpm-build |
0fba15 |
|
|
rpm-build |
0fba15 |
if (!ostree_repo_write_archive_to_mtree (repo, object_to_commit, mtree, modifier,
|
|
rpm-build |
0fba15 |
opt_tar_autocreate_parents,
|
|
rpm-build |
0fba15 |
cancellable, error))
|
|
rpm-build |
0fba15 |
goto out;
|
|
rpm-build |
0fba15 |
}
|
|
rpm-build |
0fba15 |
}
|
|
rpm-build |
0fba15 |
else
|
|
rpm-build |
0fba15 |
{
|
|
rpm-build |
0fba15 |
#ifdef HAVE_LIBARCHIVE
|
|
rpm-build |
0fba15 |
const char *comma = strchr (opt_tar_pathname_filter, ',');
|
|
rpm-build |
0fba15 |
if (!comma)
|
|
rpm-build |
0fba15 |
{
|
|
rpm-build |
0fba15 |
g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
|
rpm-build |
0fba15 |
"Missing ',' in --tar-pathname-filter");
|
|
rpm-build |
0fba15 |
goto out;
|
|
rpm-build |
0fba15 |
}
|
|
rpm-build |
0fba15 |
const char *replacement = comma + 1;
|
|
rpm-build |
0fba15 |
g_autofree char *regexp_text = g_strndup (opt_tar_pathname_filter, comma - opt_tar_pathname_filter);
|
|
rpm-build |
0fba15 |
/* Use new API if we have a pathname filter */
|
|
rpm-build |
0fba15 |
OstreeRepoImportArchiveOptions opts = { 0, };
|
|
rpm-build |
0fba15 |
opts.autocreate_parents = opt_tar_autocreate_parents;
|
|
rpm-build |
0fba15 |
opts.translate_pathname = handle_translate_pathname;
|
|
rpm-build |
0fba15 |
g_autoptr(GRegex) regexp = g_regex_new (regexp_text, 0, 0, error);
|
|
rpm-build |
0fba15 |
TranslatePathnameData tpdata = { regexp, replacement };
|
|
rpm-build |
0fba15 |
if (!regexp)
|
|
rpm-build |
0fba15 |
{
|
|
rpm-build |
0fba15 |
g_prefix_error (error, "--tar-pathname-filter: ");
|
|
rpm-build |
0fba15 |
goto out;
|
|
rpm-build |
0fba15 |
}
|
|
rpm-build |
0fba15 |
opts.translate_pathname_user_data = &tpdata;
|
|
rpm-build |
0fba15 |
|
|
rpm-build |
0fba15 |
g_autoptr(OtAutoArchiveRead) archive;
|
|
rpm-build |
0fba15 |
if (strcmp (tree, "-") == 0)
|
|
rpm-build |
0fba15 |
archive = ot_open_archive_read_fd (STDIN_FILENO, error);
|
|
rpm-build |
0fba15 |
else
|
|
rpm-build |
0fba15 |
archive = ot_open_archive_read (tree, error);
|
|
rpm-build |
0fba15 |
|
|
rpm-build |
0fba15 |
if (!archive)
|
|
rpm-build |
0fba15 |
goto out;
|
|
rpm-build |
0fba15 |
if (!ostree_repo_import_archive_to_mtree (repo, &opts, archive, mtree,
|
|
rpm-build |
0fba15 |
modifier, cancellable, error))
|
|
rpm-build |
0fba15 |
goto out;
|
|
rpm-build |
0fba15 |
#else
|
|
rpm-build |
0fba15 |
g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
|
|
rpm-build |
0fba15 |
"This version of ostree is not compiled with libarchive support");
|
|
rpm-build |
0fba15 |
goto out;
|
|
rpm-build |
0fba15 |
#endif
|
|
rpm-build |
0fba15 |
}
|
|
rpm-build |
0fba15 |
}
|
|
rpm-build |
0fba15 |
else if (strcmp (tree_type, "ref") == 0)
|
|
rpm-build |
0fba15 |
{
|
|
rpm-build |
0fba15 |
if (first && opt_selinux_policy_from_base)
|
|
rpm-build |
0fba15 |
{
|
|
rpm-build |
0fba15 |
g_assert (modifier);
|
|
rpm-build |
0fba15 |
if (!ostree_repo_commit_modifier_set_sepolicy_from_commit (modifier, repo, tree, cancellable, error))
|
|
rpm-build |
0fba15 |
goto out;
|
|
rpm-build |
0fba15 |
}
|
|
rpm-build |
0fba15 |
if (!ostree_repo_read_commit (repo, tree, &object_to_commit, NULL, cancellable, error))
|
|
rpm-build |
0fba15 |
goto out;
|
|
rpm-build |
0fba15 |
|
|
rpm-build |
0fba15 |
if (!ostree_repo_write_directory_to_mtree (repo, object_to_commit, mtree, modifier,
|
|
rpm-build |
0fba15 |
cancellable, error))
|
|
rpm-build |
0fba15 |
goto out;
|
|
rpm-build |
0fba15 |
}
|
|
rpm-build |
0fba15 |
else
|
|
rpm-build |
0fba15 |
{
|
|
rpm-build |
0fba15 |
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
|
rpm-build |
0fba15 |
"Invalid tree type specification '%s'", tree_type);
|
|
rpm-build |
0fba15 |
goto out;
|
|
rpm-build |
0fba15 |
}
|
|
rpm-build |
0fba15 |
}
|
|
rpm-build |
0fba15 |
|
|
rpm-build |
0fba15 |
if (mode_adds && g_hash_table_size (mode_adds) > 0)
|
|
rpm-build |
0fba15 |
{
|
|
rpm-build |
0fba15 |
GHashTableIter hash_iter;
|
|
rpm-build |
0fba15 |
gpointer key, value;
|
|
rpm-build |
0fba15 |
|
|
rpm-build |
0fba15 |
g_hash_table_iter_init (&hash_iter, mode_adds);
|
|
rpm-build |
0fba15 |
|
|
rpm-build |
0fba15 |
while (g_hash_table_iter_next (&hash_iter, &key, &value))
|
|
rpm-build |
0fba15 |
{
|
|
rpm-build |
0fba15 |
g_printerr ("Unmatched statoverride path: %s\n", (char*)key);
|
|
rpm-build |
0fba15 |
}
|
|
rpm-build |
0fba15 |
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
|
rpm-build |
0fba15 |
"Unmatched statoverride paths");
|
|
rpm-build |
0fba15 |
goto out;
|
|
rpm-build |
0fba15 |
}
|
|
rpm-build |
0fba15 |
|
|
rpm-build |
0fba15 |
if (skip_list && g_hash_table_size (skip_list) > 0)
|
|
rpm-build |
0fba15 |
{
|
|
rpm-build |
0fba15 |
GHashTableIter hash_iter;
|
|
rpm-build |
0fba15 |
gpointer key;
|
|
rpm-build |
0fba15 |
|
|
rpm-build |
0fba15 |
g_hash_table_iter_init (&hash_iter, skip_list);
|
|
rpm-build |
0fba15 |
|
|
rpm-build |
0fba15 |
while (g_hash_table_iter_next (&hash_iter, &key, NULL))
|
|
rpm-build |
0fba15 |
{
|
|
rpm-build |
0fba15 |
g_printerr ("Unmatched skip-list path: %s\n", (char*)key);
|
|
rpm-build |
0fba15 |
}
|
|
rpm-build |
0fba15 |
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
|
rpm-build |
0fba15 |
"Unmatched skip-list paths");
|
|
rpm-build |
0fba15 |
goto out;
|
|
rpm-build |
0fba15 |
}
|
|
rpm-build |
0fba15 |
|
|
rpm-build |
0fba15 |
if (!ostree_repo_write_mtree (repo, mtree, &root, cancellable, error))
|
|
rpm-build |
0fba15 |
goto out;
|
|
rpm-build |
0fba15 |
|
|
rpm-build |
0fba15 |
if (opt_skip_if_unchanged && parent)
|
|
rpm-build |
0fba15 |
{
|
|
rpm-build |
0fba15 |
g_autoptr(GFile) parent_root;
|
|
rpm-build |
0fba15 |
|
|
rpm-build |
0fba15 |
if (!ostree_repo_read_commit (repo, parent, &parent_root, NULL, cancellable, error))
|
|
rpm-build |
0fba15 |
goto out;
|
|
rpm-build |
0fba15 |
|
|
rpm-build |
0fba15 |
if (g_file_equal (root, parent_root))
|
|
rpm-build |
0fba15 |
skip_commit = TRUE;
|
|
rpm-build |
0fba15 |
}
|
|
rpm-build |
0fba15 |
|
|
rpm-build |
0fba15 |
if (!skip_commit)
|
|
rpm-build |
0fba15 |
{
|
|
rpm-build |
0fba15 |
if (!opt_no_bindings)
|
|
rpm-build |
0fba15 |
{
|
|
rpm-build |
0fba15 |
g_autoptr(GVariant) old_metadata = g_steal_pointer (&metadata);
|
|
rpm-build |
0fba15 |
fill_bindings (repo, old_metadata, &metadata);
|
|
rpm-build |
0fba15 |
}
|
|
rpm-build |
0fba15 |
|
|
rpm-build |
0fba15 |
if (!opt_timestamp)
|
|
rpm-build |
0fba15 |
{
|
|
rpm-build |
0fba15 |
if (!ostree_repo_write_commit (repo, parent, opt_subject, commit_body, metadata,
|
|
rpm-build |
0fba15 |
OSTREE_REPO_FILE (root),
|
|
rpm-build |
0fba15 |
&commit_checksum, cancellable, error))
|
|
rpm-build |
0fba15 |
goto out;
|
|
rpm-build |
0fba15 |
}
|
|
rpm-build |
0fba15 |
else
|
|
rpm-build |
0fba15 |
{
|
|
rpm-build |
0fba15 |
struct timespec ts;
|
|
rpm-build |
0fba15 |
if (!parse_datetime (&ts, opt_timestamp, NULL))
|
|
rpm-build |
0fba15 |
{
|
|
rpm-build |
0fba15 |
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
|
rpm-build |
0fba15 |
"Could not parse '%s'", opt_timestamp);
|
|
rpm-build |
0fba15 |
goto out;
|
|
rpm-build |
0fba15 |
}
|
|
rpm-build |
0fba15 |
|
|
rpm-build |
0fba15 |
guint64 timestamp = ts.tv_sec;
|
|
rpm-build |
0fba15 |
if (!ostree_repo_write_commit_with_time (repo, parent, opt_subject, commit_body, metadata,
|
|
rpm-build |
0fba15 |
OSTREE_REPO_FILE (root),
|
|
rpm-build |
0fba15 |
timestamp,
|
|
rpm-build |
0fba15 |
&commit_checksum, cancellable, error))
|
|
rpm-build |
0fba15 |
goto out;
|
|
rpm-build |
0fba15 |
}
|
|
rpm-build |
0fba15 |
|
|
rpm-build |
0fba15 |
if (detached_metadata)
|
|
rpm-build |
0fba15 |
{
|
|
rpm-build |
0fba15 |
if (!ostree_repo_write_commit_detached_metadata (repo, commit_checksum,
|
|
rpm-build |
0fba15 |
detached_metadata,
|
|
rpm-build |
0fba15 |
cancellable, error))
|
|
rpm-build |
0fba15 |
goto out;
|
|
rpm-build |
0fba15 |
}
|
|
rpm-build |
0fba15 |
|
|
rpm-build |
0fba15 |
if (opt_key_ids)
|
|
rpm-build |
0fba15 |
{
|
|
rpm-build |
0fba15 |
/* Initialize crypto system */
|
|
rpm-build |
0fba15 |
opt_sign_name = opt_sign_name ?: OSTREE_SIGN_NAME_ED25519;
|
|
rpm-build |
0fba15 |
|
|
rpm-build |
0fba15 |
sign = ostree_sign_get_by_name (opt_sign_name, error);
|
|
rpm-build |
0fba15 |
if (sign == NULL)
|
|
rpm-build |
0fba15 |
goto out;
|
|
rpm-build |
0fba15 |
|
|
rpm-build |
0fba15 |
char **iter;
|
|
rpm-build |
0fba15 |
|
|
rpm-build |
0fba15 |
for (iter = opt_key_ids; iter && *iter; iter++)
|
|
rpm-build |
0fba15 |
{
|
|
rpm-build |
0fba15 |
const char *keyid = *iter;
|
|
rpm-build |
0fba15 |
g_autoptr (GVariant) secret_key = NULL;
|
|
rpm-build |
0fba15 |
|
|
rpm-build |
0fba15 |
secret_key = g_variant_new_string (keyid);
|
|
rpm-build |
0fba15 |
if (!ostree_sign_set_sk (sign, secret_key, error))
|
|
rpm-build |
0fba15 |
goto out;
|
|
rpm-build |
0fba15 |
|
|
rpm-build |
0fba15 |
if (!ostree_sign_commit (sign,
|
|
rpm-build |
0fba15 |
repo,
|
|
rpm-build |
0fba15 |
commit_checksum,
|
|
rpm-build |
0fba15 |
cancellable,
|
|
rpm-build |
0fba15 |
error))
|
|
rpm-build |
0fba15 |
goto out;
|
|
rpm-build |
0fba15 |
}
|
|
rpm-build |
0fba15 |
}
|
|
rpm-build |
0fba15 |
|
|
rpm-build |
0fba15 |
#ifndef OSTREE_DISABLE_GPGME
|
|
rpm-build |
0fba15 |
if (opt_gpg_key_ids)
|
|
rpm-build |
0fba15 |
{
|
|
rpm-build |
0fba15 |
char **iter;
|
|
rpm-build |
0fba15 |
|
|
rpm-build |
0fba15 |
for (iter = opt_gpg_key_ids; iter && *iter; iter++)
|
|
rpm-build |
0fba15 |
{
|
|
rpm-build |
0fba15 |
const char *keyid = *iter;
|
|
rpm-build |
0fba15 |
|
|
rpm-build |
0fba15 |
if (!ostree_repo_sign_commit (repo,
|
|
rpm-build |
0fba15 |
commit_checksum,
|
|
rpm-build |
0fba15 |
keyid,
|
|
rpm-build |
0fba15 |
opt_gpg_homedir,
|
|
rpm-build |
0fba15 |
cancellable,
|
|
rpm-build |
0fba15 |
error))
|
|
rpm-build |
0fba15 |
goto out;
|
|
rpm-build |
0fba15 |
}
|
|
rpm-build |
0fba15 |
}
|
|
rpm-build |
0fba15 |
#endif
|
|
rpm-build |
0fba15 |
|
|
rpm-build |
0fba15 |
if (opt_branch)
|
|
rpm-build |
0fba15 |
ostree_repo_transaction_set_ref (repo, NULL, opt_branch, commit_checksum);
|
|
rpm-build |
0fba15 |
else
|
|
rpm-build |
0fba15 |
g_assert (opt_orphan);
|
|
rpm-build |
0fba15 |
|
|
rpm-build |
0fba15 |
if (!ostree_repo_commit_transaction (repo, &stats, cancellable, error))
|
|
rpm-build |
0fba15 |
goto out;
|
|
rpm-build |
0fba15 |
}
|
|
rpm-build |
0fba15 |
else
|
|
rpm-build |
0fba15 |
{
|
|
rpm-build |
0fba15 |
commit_checksum = g_strdup (parent);
|
|
rpm-build |
0fba15 |
}
|
|
rpm-build |
0fba15 |
|
|
rpm-build |
0fba15 |
if (opt_table_output)
|
|
rpm-build |
0fba15 |
{
|
|
rpm-build |
0fba15 |
g_print ("Commit: %s\n", commit_checksum);
|
|
rpm-build |
0fba15 |
g_print ("Metadata Total: %u\n", stats.metadata_objects_total);
|
|
rpm-build |
0fba15 |
g_print ("Metadata Written: %u\n", stats.metadata_objects_written);
|
|
rpm-build |
0fba15 |
g_print ("Content Total: %u\n", stats.content_objects_total);
|
|
rpm-build |
0fba15 |
g_print ("Content Written: %u\n", stats.content_objects_written);
|
|
rpm-build |
0fba15 |
g_print ("Content Cache Hits: %u\n", stats.devino_cache_hits);
|
|
rpm-build |
0fba15 |
g_print ("Content Bytes Written: %" G_GUINT64_FORMAT "\n", stats.content_bytes_written);
|
|
rpm-build |
0fba15 |
}
|
|
rpm-build |
0fba15 |
else
|
|
rpm-build |
0fba15 |
{
|
|
rpm-build |
0fba15 |
g_print ("%s\n", commit_checksum);
|
|
rpm-build |
0fba15 |
}
|
|
rpm-build |
0fba15 |
|
|
rpm-build |
0fba15 |
ret = TRUE;
|
|
rpm-build |
0fba15 |
out:
|
|
rpm-build |
0fba15 |
if (repo)
|
|
rpm-build |
0fba15 |
ostree_repo_abort_transaction (repo, cancellable, NULL);
|
|
rpm-build |
0fba15 |
if (modifier)
|
|
rpm-build |
0fba15 |
ostree_repo_commit_modifier_unref (modifier);
|
|
rpm-build |
0fba15 |
return ret;
|
|
rpm-build |
0fba15 |
}
|