lib/repo: Add an API to mark a commit as partial

For the [rpm-ostree jigdo ♲📦](https://github.com/projectatomic/rpm-ostree/issues/1081) work.
We're basically doing "pull" via a non-libostree mechanism, and this
should be fully supported.  As I mentioned earlier we should try to
have `ostree-repo-pull.c` only use public APIs; this gets us closer
to that.

Closes: #1376
Approved by: jlebon
This commit is contained in:
Colin Walters 2017-12-14 09:48:26 -05:00 committed by Atomic Bot
parent ad814d1c8a
commit 7935b881bf
6 changed files with 56 additions and 33 deletions

View File

@ -320,6 +320,7 @@ ostree_repo_set_alias_ref_immediate
ostree_repo_set_cache_dir
ostree_repo_sign_delta
ostree_repo_has_object
ostree_repo_mark_commit_partial
ostree_repo_write_metadata
ostree_repo_write_metadata_async
ostree_repo_write_metadata_finish

View File

@ -21,6 +21,7 @@
LIBOSTREE_2017.15 {
ostree_repo_fsck_object;
ostree_repo_mark_commit_partial;
} LIBOSTREE_2017.14;
/* Stub section for the stable release *after* this development one; don't

View File

@ -1589,6 +1589,48 @@ ensure_txn_refs (OstreeRepo *self)
g_free);
}
/**
* ostree_repo_mark_commit_partial:
* @self: Repo
* @checksum: Commit SHA-256
* @is_partial: Whether or not this commit is partial
* @error: Error
*
* Commits in "partial" state do not have all their child objects written. This
* occurs in various situations, such as during a pull, but also if a "subpath"
* pull is used, as well as "commit only" pulls.
*
* This function is used by ostree_repo_pull_with_options(); you
* should use this if you are implementing a different type of transport.
*
* Since: 2017.15
*/
gboolean
ostree_repo_mark_commit_partial (OstreeRepo *self,
const char *checksum,
gboolean is_partial,
GError **error)
{
g_autofree char *commitpartial_path = _ostree_get_commitpartial_path (checksum);
if (is_partial)
{
glnx_autofd int fd = openat (self->repo_dir_fd, commitpartial_path,
O_EXCL | O_CREAT | O_WRONLY | O_CLOEXEC | O_NOCTTY, 0644);
if (fd == -1)
{
if (errno != EEXIST)
return glnx_throw_errno_prefix (error, "open(%s)", commitpartial_path);
}
}
else
{
if (!ot_ensure_unlinked_at (self->repo_dir_fd, commitpartial_path, 0))
return FALSE;
}
return TRUE;
}
/**
* ostree_repo_transaction_set_refspec:
* @self: An #OstreeRepo

View File

@ -36,16 +36,6 @@ typedef struct {
guint64 freed_bytes;
} OtPruneData;
static gboolean
prune_commitpartial_file (OstreeRepo *repo,
const char *checksum,
GCancellable *cancellable,
GError **error)
{
g_autofree char *path = _ostree_get_commitpartial_path (checksum);
return ot_ensure_unlinked_at (repo->repo_dir_fd, path, error);
}
static gboolean
maybe_prune_loose_object (OtPruneData *data,
OstreeRepoPruneFlags flags,
@ -68,7 +58,7 @@ maybe_prune_loose_object (OtPruneData *data,
if (objtype == OSTREE_OBJECT_TYPE_COMMIT)
{
if (!prune_commitpartial_file (data->repo, checksum, cancellable, error))
if (!ostree_repo_mark_commit_partial (data->repo, checksum, FALSE, error))
return FALSE;
}

View File

@ -558,21 +558,6 @@ fetch_uri_contents_utf8_sync (OstreeFetcher *fetcher,
cancellable, error);
}
static gboolean
write_commitpartial_for (OtPullData *pull_data,
const char *checksum,
GError **error)
{
g_autofree char *commitpartial_path = _ostree_get_commitpartial_path (checksum);
glnx_autofd int fd = openat (pull_data->repo->repo_dir_fd, commitpartial_path, O_EXCL | O_CREAT | O_WRONLY | O_CLOEXEC | O_NOCTTY, 0644);
if (fd == -1)
{
if (errno != EEXIST)
return glnx_throw_errno_prefix (error, "open(%s)", commitpartial_path);
}
return TRUE;
}
static void
enqueue_one_object_request (OtPullData *pull_data,
const char *checksum,
@ -1267,7 +1252,7 @@ meta_fetch_on_complete (GObject *object,
pull_data->cancellable, error))
goto out;
if (!write_commitpartial_for (pull_data, checksum, error))
if (!ostree_repo_mark_commit_partial (pull_data->repo, checksum, TRUE, error))
goto out;
}
@ -1821,7 +1806,7 @@ scan_one_metadata_object (OtPullData *pull_data,
if (objtype == OSTREE_OBJECT_TYPE_COMMIT)
{
/* mark as partial to ensure we scan the commit below */
if (!write_commitpartial_for (pull_data, checksum, error))
if (!ostree_repo_mark_commit_partial (pull_data->repo, checksum, TRUE, error))
return FALSE;
}
@ -1854,7 +1839,7 @@ scan_one_metadata_object (OtPullData *pull_data,
if (objtype == OSTREE_OBJECT_TYPE_COMMIT)
{
/* mark as partial to ensure we scan the commit below */
if (!write_commitpartial_for (pull_data, checksum, error))
if (!ostree_repo_mark_commit_partial (pull_data->repo, checksum, TRUE, error))
return FALSE;
}
if (!_ostree_repo_import_object (pull_data->repo, refd_repo,
@ -4340,15 +4325,13 @@ ostree_repo_pull_with_options (OstreeRepo *self,
{
GLNX_HASH_TABLE_FOREACH_V (requested_refs_to_fetch, const char*, checksum)
{
g_autofree char *commitpartial_path = _ostree_get_commitpartial_path (checksum);
if (!ot_ensure_unlinked_at (pull_data->repo->repo_dir_fd, commitpartial_path, 0))
if (!ostree_repo_mark_commit_partial (pull_data->repo, checksum, FALSE, error))
goto out;
}
GLNX_HASH_TABLE_FOREACH_V (commits_to_fetch, const char*, commit)
{
g_autofree char *commitpartial_path = _ostree_get_commitpartial_path (commit);
if (!ot_ensure_unlinked_at (pull_data->repo->repo_dir_fd, commitpartial_path, 0))
if (!ostree_repo_mark_commit_partial (pull_data->repo, commit, FALSE, error))
goto out;
}
}

View File

@ -362,6 +362,12 @@ gboolean ostree_repo_abort_transaction (OstreeRepo *self,
GCancellable *cancellable,
GError **error);
_OSTREE_PUBLIC
gboolean ostree_repo_mark_commit_partial (OstreeRepo *self,
const char *checksum,
gboolean is_partial,
GError **error);
_OSTREE_PUBLIC
void ostree_repo_transaction_set_refspec (OstreeRepo *self,
const char *refspec,