From 3ef4cc2e5b9ed36c5b9d11a75162a20d3868ded6 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Thu, 25 Aug 2016 11:53:27 -0400 Subject: [PATCH] lib: Add an API to list only "our" objects, fix prune to use it When doing a prune, we should not try to delete objects in parent repos, since it'll fail. There is a bigger discussion about the semantics of `parent=` to be had, but this will fix trying to use `ostree prune --repo=/ostree/repo/extensions/rpmostree/pkgcache`. Closes: https://github.com/ostreedev/ostree/issues/467 Closes: #471 Approved by: jlebon --- src/libostree/ostree-repo-prune.c | 4 ++-- src/libostree/ostree-repo.c | 2 +- src/libostree/ostree-repo.h | 4 +++- tests/test-prune.sh | 38 ++++++++++++++++++++++++++++++- 4 files changed, 43 insertions(+), 5 deletions(-) diff --git a/src/libostree/ostree-repo-prune.c b/src/libostree/ostree-repo-prune.c index 8c5d13e9..66170d4d 100644 --- a/src/libostree/ostree-repo-prune.c +++ b/src/libostree/ostree-repo-prune.c @@ -337,8 +337,8 @@ ostree_repo_prune (OstreeRepo *self, } } - if (!ostree_repo_list_objects (self, OSTREE_REPO_LIST_OBJECTS_ALL, &objects, - cancellable, error)) + if (!ostree_repo_list_objects (self, OSTREE_REPO_LIST_OBJECTS_ALL | OSTREE_REPO_LIST_OBJECTS_NO_PARENTS, + &objects, cancellable, error)) goto out; if (!refs_only) diff --git a/src/libostree/ostree-repo.c b/src/libostree/ostree-repo.c index 5e9818fd..d33a96ab 100644 --- a/src/libostree/ostree-repo.c +++ b/src/libostree/ostree-repo.c @@ -3590,7 +3590,7 @@ ostree_repo_list_objects (OstreeRepo *self, { if (!list_loose_objects (self, ret_objects, NULL, cancellable, error)) goto out; - if (self->parent_repo) + if ((flags & OSTREE_REPO_LIST_OBJECTS_NO_PARENTS) == 0 && self->parent_repo) { if (!list_loose_objects (self->parent_repo, ret_objects, NULL, cancellable, error)) goto out; diff --git a/src/libostree/ostree-repo.h b/src/libostree/ostree-repo.h index ff1e712d..5547473a 100644 --- a/src/libostree/ostree-repo.h +++ b/src/libostree/ostree-repo.h @@ -798,11 +798,13 @@ gboolean ostree_repo_read_commit (OstreeRepo *self, * @OSTREE_REPO_LIST_OBJECTS_LOOSE: List only loose (plain file) objects * @OSTREE_REPO_LIST_OBJECTS_PACKED: List only packed (compacted into blobs) objects * @OSTREE_REPO_LIST_OBJECTS_ALL: List all objects + * @OSTREE_REPO_LIST_OBJECTS_NO_PARENTS: Only list objects in this repo, not parents */ typedef enum { OSTREE_REPO_LIST_OBJECTS_LOOSE = (1 << 0), OSTREE_REPO_LIST_OBJECTS_PACKED = (1 << 1), - OSTREE_REPO_LIST_OBJECTS_ALL = (1 << 2) + OSTREE_REPO_LIST_OBJECTS_ALL = (1 << 2), + OSTREE_REPO_LIST_OBJECTS_NO_PARENTS = (1 << 3), } OstreeRepoListObjectsFlags; /** diff --git a/tests/test-prune.sh b/tests/test-prune.sh index 5134d560..ce14ce67 100755 --- a/tests/test-prune.sh +++ b/tests/test-prune.sh @@ -25,7 +25,7 @@ skip_without_user_xattrs setup_fake_remote_repo1 "archive-z2" -echo '1..2' +echo '1..3' cd ${test_tmpdir} mkdir repo @@ -142,3 +142,39 @@ ${CMD_PREFIX} ostree --repo=repo pull --depth=-1 --commit-metadata-only origin t ${CMD_PREFIX} ostree --repo=repo prune echo "ok prune with partial repo" + +assert_has_n_objects() { + find $1/objects -name '*.filez' | wc -l > object-count + assert_file_has_content object-count $2 + rm object-count +} + +cd ${test_tmpdir} +for repo in repo child-repo tmp-repo; do + rm ${repo} -rf + ${CMD_PREFIX} ostree --repo=${repo} init --mode=archive +done +echo parent=${test_tmpdir}/repo >> child-repo/config +mkdir files +for x in $(seq 3); do + echo afile${x} > files/afile${x} +done +${CMD_PREFIX} ostree --repo=repo commit -b test files +assert_has_n_objects repo 3 +# Inherit 1-3, add 4-6 +for x in $(seq 4 6); do + echo afile${x} > files/afile${x} +done +# Commit into a temp repo, then do a local pull, which triggers +# the parent repo lookup for dedup +${CMD_PREFIX} ostree --repo=tmp-repo commit -b childtest files +${CMD_PREFIX} ostree --repo=child-repo pull-local tmp-repo childtest +assert_has_n_objects child-repo 3 +# Sanity check prune doesn't do anything +for repo in repo child-repo; do ${CMD_PREFIX} ostree --repo=${repo} prune; done +# Now, leave orphaned objects in the parent only pointed to by the child +${CMD_PREFIX} ostree --repo=repo refs --delete test +${CMD_PREFIX} ostree --repo=child-repo prune --refs-only --depth=0 +assert_has_n_objects child-repo 3 + +echo "ok prune with parent repo"