diff --git a/src/libostree/ostree-repo-pull.c b/src/libostree/ostree-repo-pull.c index 88b468b0..a7db45f9 100644 --- a/src/libostree/ostree-repo-pull.c +++ b/src/libostree/ostree-repo-pull.c @@ -1765,6 +1765,7 @@ ostree_repo_pull_with_options (OstreeRepo *self, char **override_commit_ids = NULL; GSource *update_timeout = NULL; gboolean disable_static_deltas = FALSE; + gboolean require_static_deltas = FALSE; if (options) { @@ -1777,6 +1778,7 @@ ostree_repo_pull_with_options (OstreeRepo *self, (void) g_variant_lookup (options, "override-remote-name", "s", &pull_data->remote_name); (void) g_variant_lookup (options, "depth", "i", &pull_data->maxdepth); (void) g_variant_lookup (options, "disable-static-deltas", "b", &disable_static_deltas); + (void) g_variant_lookup (options, "require-static-deltas", "b", &require_static_deltas); (void) g_variant_lookup (options, "override-commit-ids", "^a&s", &override_commit_ids); } @@ -1787,6 +1789,8 @@ ostree_repo_pull_with_options (OstreeRepo *self, if (dir_to_pull) g_return_val_if_fail (dir_to_pull[0] == '/', FALSE); + g_return_val_if_fail (!(disable_static_deltas && require_static_deltas), FALSE); + pull_data->is_mirror = (flags & OSTREE_REPO_PULL_FLAGS_MIRROR) > 0; pull_data->is_commit_only = (flags & OSTREE_REPO_PULL_FLAGS_COMMIT_ONLY) > 0; @@ -1969,6 +1973,13 @@ ostree_repo_pull_with_options (OstreeRepo *self, goto out; } + if (!bytes_summary && require_static_deltas) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "Fetch configured to require static deltas, but no summary found"); + goto out; + } + if (bytes_summary) { uri = suburi_new (pull_data->base_uri, "summary.sig", NULL); @@ -2209,6 +2220,13 @@ ostree_repo_pull_with_options (OstreeRepo *self, if (!delta_superblock) { + if (require_static_deltas) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "Static deltas required, but none found for %s to %s", + from_revision, to_revision); + goto out; + } g_debug ("no delta superblock for %s-%s", from_revision ? from_revision : "empty", to_revision); queue_scan_one_metadata_object (pull_data, to_revision, OSTREE_OBJECT_TYPE_COMMIT, 0); } diff --git a/src/ostree/ot-builtin-pull.c b/src/ostree/ot-builtin-pull.c index 63dbc768..7fa673cd 100644 --- a/src/ostree/ot-builtin-pull.c +++ b/src/ostree/ot-builtin-pull.c @@ -31,6 +31,7 @@ static gboolean opt_disable_fsync; static gboolean opt_mirror; static gboolean opt_commit_only; static gboolean opt_disable_static_deltas; +static gboolean opt_require_static_deltas; static char* opt_subpath; static int opt_depth = 0; @@ -38,6 +39,7 @@ static GOptionEntry options[] = { { "commit-metadata-only", 0, 0, G_OPTION_ARG_NONE, &opt_commit_only, "Fetch only the commit metadata", NULL }, { "disable-fsync", 0, 0, G_OPTION_ARG_NONE, &opt_disable_fsync, "Do not invoke fsync()", NULL }, { "disable-static-deltas", 0, 0, G_OPTION_ARG_NONE, &opt_disable_static_deltas, "Do not use static deltas", NULL }, + { "require-static-deltas", 0, 0, G_OPTION_ARG_NONE, &opt_require_static_deltas, "Require static deltas", NULL }, { "mirror", 0, 0, G_OPTION_ARG_NONE, &opt_mirror, "Write refs suitable for a mirror", NULL }, { "subpath", 0, 0, G_OPTION_ARG_STRING, &opt_subpath, "Only pull the provided subpath", NULL }, { "depth", 0, 0, G_OPTION_ARG_INT, &opt_depth, "Traverse DEPTH parents (-1=infinite) (default: 0)", "DEPTH" }, @@ -175,6 +177,9 @@ ostree_builtin_pull (int argc, char **argv, GCancellable *cancellable, GError ** g_variant_builder_add (&builder, "{s@v}", "disable-static-deltas", g_variant_new_variant (g_variant_new_boolean (opt_disable_static_deltas))); + g_variant_builder_add (&builder, "{s@v}", "require-static-deltas", + g_variant_new_variant (g_variant_new_boolean (opt_require_static_deltas))); + if (override_commit_ids) g_variant_builder_add (&builder, "{s@v}", "override-commit-ids", g_variant_new_variant (g_variant_new_strv ((const char*const*)override_commit_ids->pdata, override_commit_ids->len))); diff --git a/tests/pull-test.sh b/tests/pull-test.sh index 2233b905..04272d5f 100755 --- a/tests/pull-test.sh +++ b/tests/pull-test.sh @@ -106,12 +106,18 @@ cd .. rm main-files -rf # Generate delta that we'll use ${CMD_PREFIX} ostree --repo=ostree-srv/gnomerepo static-delta generate main +prev_rev=$(ostree --repo=ostree-srv/gnomerepo rev-parse main^) +ostree --repo=ostree-srv/gnomerepo summary -u cd ${test_tmpdir} -${CMD_PREFIX} ostree --repo=repo pull origin main +repo_init +${CMD_PREFIX} ostree --repo=repo pull origin main@${prev_rev} +${CMD_PREFIX} ostree --repo=repo pull --require-static-deltas origin main ${CMD_PREFIX} ostree --repo=repo fsck cd ${test_tmpdir} +repo_init +${CMD_PREFIX} ostree --repo=repo pull origin main@${prev_rev} ${CMD_PREFIX} ostree --repo=repo pull --disable-static-deltas origin main ${CMD_PREFIX} ostree --repo=repo fsck @@ -124,6 +130,16 @@ assert_not_has_file baz/saucer echo "ok static delta" +cd ${test_tmpdir} +rm ostree-srv/gnomerepo/deltas -rf +ostree --repo=ostree-srv/gnomerepo summary -u +repo_init +if ${CMD_PREFIX} ostree --repo=repo pull --require-static-deltas origin main 2>err.txt; then + assert_not_reached "--require-static-deltas unexpectedly succeeded" +fi +assert_file_has_content err.txt "deltas required, but none found" +${CMD_PREFIX} ostree --repo=repo fsck + cd ${test_tmpdir} rm main-files -rf ${CMD_PREFIX} ostree --repo=ostree-srv/gnomerepo checkout main main-files @@ -134,6 +150,7 @@ cd .. rm main-files -rf # Generate new delta that we'll use ${CMD_PREFIX} ostree --repo=ostree-srv/gnomerepo static-delta generate --inline main +ostree --repo=ostree-srv/gnomerepo summary -u cd ${test_tmpdir} ${CMD_PREFIX} ostree --repo=repo pull origin main @@ -157,6 +174,7 @@ ${CMD_PREFIX} ostree --repo=${test_tmpdir}/ostree-srv/gnomerepo commit -b main - cd .. rm main-files -rf ${CMD_PREFIX} ostree --repo=ostree-srv/gnomerepo static-delta generate main +ostree --repo=ostree-srv/gnomerepo summary -u cd ${test_tmpdir} ${CMD_PREFIX} ostree --repo=repo pull origin main