Skip to content

Commit

Permalink
ot-builtin-commit.c: add --skip-list option
Browse files Browse the repository at this point in the history
This was already supported by the commit modifier API, just needed to
expose it. This will also be used to test the libarchive API in a future
test.

Closes: #275
Approved by: cgwalters
  • Loading branch information
jlebon authored and cgwalters-bot committed May 6, 2016
1 parent b1d3dd1 commit b717fd2
Show file tree
Hide file tree
Showing 5 changed files with 131 additions and 86 deletions.
1 change: 0 additions & 1 deletion Makefile-tests.am
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,6 @@ test_scripts = \
tests/test-repo-checkout-subpath.sh \
tests/test-reset-nonlinear.sh \
tests/test-oldstyle-partial.sh \
tests/test-setuid.sh \
tests/test-delta.sh \
tests/test-xattrs.sh \
tests/test-auto-summary.sh \
Expand Down
10 changes: 9 additions & 1 deletion man/ostree-commit.xml
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,15 @@ Boston, MA 02111-1307, USA.
<term><option>--statoverride</option>="PATH"</term>

<listitem><para>
File containing list of modifications to make permissions.
File containing list of modifications to make permissions (file mode, followed by space, followed by file path).
</para></listitem>
</varlistentry>

<varlistentry>
<term><option>--skip-list</option>="PATH"</term>

<listitem><para>
File containing list of file paths to skip (one path per line).
</para></listitem>
</varlistentry>

Expand Down
140 changes: 100 additions & 40 deletions src/ostree/ot-builtin-commit.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ static char *opt_parent;
static gboolean opt_orphan;
static char *opt_branch;
static char *opt_statoverride_file;
static char *opt_skiplist_file;
static char **opt_metadata_strings;
static char **opt_detached_metadata_strings;
static gboolean opt_link_checkout_speedup;
Expand Down Expand Up @@ -84,6 +85,7 @@ static GOptionEntry options[] = {
{ "tar-autocreate-parents", 0, 0, G_OPTION_ARG_NONE, &opt_tar_autocreate_parents, "When loading tar archives, automatically create parent directories as needed", NULL },
{ "skip-if-unchanged", 0, 0, G_OPTION_ARG_NONE, &opt_skip_if_unchanged, "If the contents are unchanged from previous commit, do nothing", NULL },
{ "statoverride", 0, 0, G_OPTION_ARG_FILENAME, &opt_statoverride_file, "File containing list of modifications to make to permissions", "PATH" },
{ "skip-list", 0, 0, G_OPTION_ARG_FILENAME, &opt_skiplist_file, "File containing list of files to skip", "PATH" },
{ "table-output", 0, 0, G_OPTION_ARG_NONE, &opt_table_output, "Output more information in a KEY: VALUE format", NULL },
{ "gpg-sign", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_key_ids, "GPG Key ID to sign the commit with", "KEY-ID"},
{ "gpg-homedir", 0, 0, G_OPTION_ARG_STRING, &opt_gpg_homedir, "GPG Homedir to use when looking for keyrings", "HOMEDIR"},
Expand All @@ -95,65 +97,85 @@ static GOptionEntry options[] = {
};

static gboolean
parse_statoverride_file (GHashTable **out_mode_add,
GCancellable *cancellable,
GError **error)
parse_file_by_line (const char *path,
gboolean (*cb)(const char*, void*, GError**),
void *cbdata,
GCancellable *cancellable,
GError **error)
{
gboolean ret = FALSE;
gsize len;
char **iter = NULL; /* nofree */
g_autoptr(GHashTable) ret_hash = NULL;
g_autoptr(GFile) path = NULL;
g_autofree char *contents = NULL;
g_autoptr(GFile) file = NULL;
char **lines = NULL;

path = g_file_new_for_path (opt_statoverride_file);

if (!g_file_load_contents (path, cancellable, &contents, &len, NULL,
error))
file = g_file_new_for_path (path);
if (!g_file_load_contents (file, cancellable, &contents, NULL, NULL, error))
goto out;

ret_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
lines = g_strsplit (contents, "\n", -1);

for (iter = lines; iter && *iter; iter++)
lines = g_strsplit (contents, "\n", -1);
for (char **iter = lines; iter && *iter; iter++)
{
const char *line = *iter;

if (*line == '+')
{
const char *spc;
guint mode_add;
/* skip empty lines at least */
if (**iter == '\0')
continue;

spc = strchr (line + 1, ' ');
if (!spc)
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
"Malformed statoverride file");
goto out;
}

mode_add = (guint32)(gint32)g_ascii_strtod (line + 1, NULL);
g_hash_table_insert (ret_hash,
g_strdup (spc + 1),
GUINT_TO_POINTER((gint32)mode_add));
}
if (!cb (*iter, cbdata, error))
goto out;
}

ret = TRUE;
ot_transfer_out_value (out_mode_add, &ret_hash);
out:
out:
g_strfreev (lines);
return ret;
}

static gboolean
handle_statoverride_line (const char *line,
void *data,
GError **error)
{
GHashTable *files = data;
const char *spc;
guint mode_add;

spc = strchr (line, ' ');
if (spc == NULL)
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
"Malformed statoverride file (no space found)");
return FALSE;
}

mode_add = (guint32)(gint32)g_ascii_strtod (line, NULL);
g_hash_table_insert (files, g_strdup (spc + 1),
GUINT_TO_POINTER((gint32)mode_add));
return TRUE;
}

static gboolean
handle_skiplist_line (const char *line,
void *data,
GError **error)
{
GHashTable *files = data;
g_hash_table_add (files, g_strdup (line));
return TRUE;
}

struct CommitFilterData {
GHashTable *mode_adds;
GHashTable *skip_list;
};

static OstreeRepoCommitFilterResult
commit_filter (OstreeRepo *self,
const char *path,
GFileInfo *file_info,
gpointer user_data)
{
GHashTable *mode_adds = user_data;
struct CommitFilterData *data = user_data;
GHashTable *mode_adds = data->mode_adds;
GHashTable *skip_list = data->skip_list;
gpointer value;

if (opt_owner_uid >= 0)
Expand All @@ -169,7 +191,13 @@ commit_filter (OstreeRepo *self,
current_mode | mode_add);
g_hash_table_remove (mode_adds, path);
}


if (skip_list && g_hash_table_contains (skip_list, path))
{
g_hash_table_remove (skip_list, path);
return OSTREE_REPO_COMMIT_FILTER_SKIP;
}

return OSTREE_REPO_COMMIT_FILTER_ALLOW;
}

Expand Down Expand Up @@ -310,9 +338,11 @@ ostree_builtin_commit (int argc, char **argv, GCancellable *cancellable, GError
glnx_unref_object OstreeMutableTree *mtree = NULL;
g_autofree char *tree_type = NULL;
g_autoptr(GHashTable) mode_adds = NULL;
g_autoptr(GHashTable) skip_list = NULL;
OstreeRepoCommitModifierFlags flags = 0;
OstreeRepoCommitModifier *modifier = NULL;
OstreeRepoTransactionStats stats;
struct CommitFilterData filter_data = { 0, };

context = g_option_context_new ("[PATH] - Commit a new revision");

Expand All @@ -324,7 +354,17 @@ ostree_builtin_commit (int argc, char **argv, GCancellable *cancellable, GError

if (opt_statoverride_file)
{
if (!parse_statoverride_file (&mode_adds, cancellable, error))
mode_adds = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
if (!parse_file_by_line (opt_statoverride_file, handle_statoverride_line,
mode_adds, cancellable, error))
goto out;
}

if (opt_skiplist_file)
{
skip_list = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
if (!parse_file_by_line (opt_skiplist_file, handle_skiplist_line,
skip_list, cancellable, error))
goto out;
}

Expand Down Expand Up @@ -359,9 +399,13 @@ ostree_builtin_commit (int argc, char **argv, GCancellable *cancellable, GError
|| opt_owner_uid >= 0
|| opt_owner_gid >= 0
|| opt_statoverride_file != NULL
|| opt_skiplist_file != NULL
|| opt_no_xattrs)
{
modifier = ostree_repo_commit_modifier_new (flags, commit_filter, mode_adds, NULL);
filter_data.mode_adds = mode_adds;
filter_data.skip_list = skip_list;
modifier = ostree_repo_commit_modifier_new (flags, commit_filter,
&filter_data, NULL);
}

if (opt_parent)
Expand Down Expand Up @@ -491,6 +535,22 @@ ostree_builtin_commit (int argc, char **argv, GCancellable *cancellable, GError
goto out;
}

if (skip_list && g_hash_table_size (skip_list) > 0)
{
GHashTableIter hash_iter;
gpointer key;

g_hash_table_iter_init (&hash_iter, skip_list);

while (g_hash_table_iter_next (&hash_iter, &key, NULL))
{
g_printerr ("Unmatched skip-list path: %s\n", (char*)key);
}
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
"Unmatched skip-list paths");
goto out;
}

if (!ostree_repo_write_mtree (repo, mtree, &root, cancellable, error))
goto out;

Expand Down
26 changes: 22 additions & 4 deletions tests/basic-test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

set -euo pipefail

echo "1..54"
echo "1..55"

$OSTREE checkout test2 checkout-test2
echo "ok checkout"
Expand Down Expand Up @@ -179,13 +179,31 @@ cd ${test_tmpdir}/checkout-test2-4
$OSTREE commit -b test2 -s "no xattrs" --no-xattrs
echo "ok commit with no xattrs"

# NB: The + is optional, but we need to make sure we support it
cd ${test_tmpdir}
cat > test-statoverride.txt <<EOF
+2048 /a/nested/3
+1048 /a/nested/2
2048 /a/nested/3
EOF
cd ${test_tmpdir}/checkout-test2-4
$OSTREE commit -b test2 -s "with statoverride" --statoverride=../test-statoverride.txt
echo "ok commit statoverridde"
$OSTREE commit -b test2-override -s "with statoverride" --statoverride=../test-statoverride.txt
cd ${test_tmpdir}
$OSTREE checkout test2-override checkout-test2-override
test -g checkout-test2-override/a/nested/2
test -u checkout-test2-override/a/nested/3
echo "ok commit statoverride"

cd ${test_tmpdir}
cat > test-skiplist.txt <<EOF
/a/nested/3
EOF
cd ${test_tmpdir}/checkout-test2-4
assert_has_file a/nested/3
$OSTREE commit -b test2-skiplist -s "with skiplist" --skip-list=../test-skiplist.txt
cd ${test_tmpdir}
$OSTREE checkout test2-skiplist checkout-test2-skiplist
assert_not_has_file checkout-test2-skiplist/a/nested/3
echo "ok commit skiplist"

cd ${test_tmpdir}
$OSTREE prune
Expand Down
40 changes: 0 additions & 40 deletions tests/test-setuid.sh

This file was deleted.

0 comments on commit b717fd2

Please sign in to comment.