After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 748059 - repo: Add an API to fetch *just* the summary file and make it usable in list_refs()
repo: Add an API to fetch *just* the summary file and make it usable in list_...
Status: RESOLVED FIXED
Product: ostree
Classification: Infrastructure
Component: general
unspecified
Other Linux
: Normal normal
: ---
Assigned To: OSTree maintainer(s)
OSTree maintainer(s)
Depends on:
Blocks:
 
 
Reported: 2015-04-17 14:54 UTC by Colin Walters
Modified: 2015-08-03 13:38 UTC
See Also:
GNOME target: ---
GNOME version: ---



Description Colin Walters 2015-04-17 14:54:23 UTC
Right now the pull API will fetch the summary, but not cache it anywhere.

If a mirroring program like Pulp wants to determine which branches are available, there's no sane way for them to do that short of fetching/parsing the summary file "manually".
Comment 1 Giuseppe Scrivano 2015-07-22 11:34:22 UTC
I have refactored the work Matthew did for "remote refs" in a new API ostree_repo_remote_list_refs that permits to query the remote summary file and retrieve a map refs->checksum.  The PR here:

https://github.com/GNOME/ostree/pull/127
Comment 2 Jeff Ortel 2015-07-22 14:58:01 UTC
The use case for this is to provide administrators a list of branches contained within the remote repository.  This information is used to make decisions as to which branches are mirrored (pulled) to the local repository.  Our users have requested that this information include the 'version' that is optionally included in the commit metadata.  So, I realize this is feature creep but would it be possible for the map to contain the metadata for the commit referenced by the checksum, as well as, the checksum itself?
Comment 3 Jeff Ortel 2015-07-22 15:05:50 UTC
I can see where including this additional information is beyond the scope of this (one) API call.  If so, is there another API call that can be used to fetch the commit (and its metadata) from the remote using the checksums provided by the summary listing?
Comment 4 Giuseppe Scrivano 2015-07-22 17:23:23 UTC
Hi Jeff.  There is a way to query the commit object but that is possible only for already fetched objects as far I remember.
Comment 5 Colin Walters 2015-07-22 17:26:26 UTC
We could:
 
 1) Copy just the `version` key from the commit metadata into the summary
 2) Provide an API to *just* fetch commit objects
Comment 6 Jeff Ortel 2015-07-22 21:24:10 UTC
(In reply to Colin Walters from comment #5)
> We could:
>  
>  1) Copy just the `version` key from the commit metadata into the summary

If we go with this option - I think we'd want to include all of the metadata not just the 'version'.  Other keys may be useful for branch selection as well.  To implement this, would the API be basically making API calls like #2 under the covers?  Or, were you proposing the metadata would be included in the actual summary file when it is generated (on the remote)?

>  2) Provide an API to *just* fetch commit objects
Comment 7 Giuseppe Scrivano 2015-07-23 10:17:40 UTC
I think we should avoid data duplication when possible.  Commits can have detached metadata (and if we decide to keep all metadata in the summary, then we should keep this in sync as well), personally I prefer solution 2, and have a way to prefetch commit objects.
Comment 8 Jeff Ortel 2015-07-23 14:17:09 UTC
I'm completely satisfied with #2.  So, really up to your team to decide [obviously] what is, or isn't a good fit based on the long term vision of what the summary is intended for.  I appreciate the effort on this :)
Comment 9 Giuseppe Scrivano 2015-07-23 16:06:55 UTC
I pushed some more commits to github to introduce a new API ostree_repo_prefetch_commit.

It requests the commit file and the detached metadata without storing it.  It is still WIP and it is barely tested.

Jeff, would something like this solve the problem for you?

gboolean
ostree_repo_prefetch_commit (OstreeRepo    *self,
                             const char    *name,
                             const char    *checksum,
                             GVariant      **out_commit,
                             GVariant      **out_detached_metadata,
                             GCancellable  *cancellable,
                             GError        **error);
Comment 10 Jeff Ortel 2015-07-23 17:19:42 UTC
Looks good to me.  I assume that "name" is the name of the remote.

I will be using the 2 new APIs in python through gnome inspection and wondering how:

GHashTable      **out_all_refs,

and:

GVariant      **out_commit,
GVariant      **out_detached_metadata,

will be handled by GI.  Not sure what to pass for those.

I'm not exactly sure what out_commit and out_detached_metadata will contain but anticipate it will contain what I'm looking for.

I can build using the PR branch and try it once you're ready.
Comment 11 Matthew Barnes 2015-07-23 17:44:27 UTC
I think GI generally morphs such functions into returning a tuple with the C return value and any "out" params... at least for Python.  Not sure of the tuple ordering but that's easily discoverable.
Comment 12 Jeff Ortel 2015-07-23 19:17:44 UTC
Yeah, that'd be easy enough.
Comment 13 Giuseppe Scrivano 2015-07-27 13:48:58 UTC
I've used the current code to test the new API (it just iterates and print timestamp&detached metadata).  You can try it passing as argument the path to the OStree repo: 

#!/usr/bin/python
from gi.repository import OSTree
from gi.repository import Gio
from gi.repository import GLib
from datetime import datetime
import sys

f = Gio.File.new_for_path(sys.argv[1])
repo = OSTree.Repo.new(f)

def create_variant(refs, flags):
    refs_variant = GLib.Variant('as', refs)
    flags_variant = GLib.Variant('i', flags)
    return GLib.Variant('a{sv}', {"refs" : refs_variant, "flags" : flags_variant})

repo.open(None)

for remote in repo.remote_list():
    ret = repo.remote_list_refs(remote)
    if ret[0]:
        opts = create_variant(ret[1].keys(), OSTree.RepoPullFlags.COMMIT_ONLY)
        repo.pull_with_options(remote, opts, None)

        for ref, checksum in ret[1].items():
            commit = repo.load_commit(checksum)
            if commit[0]:
                ts = int(OSTree.commit_get_timestamp(commit[1]))
                ts_s = datetime.fromtimestamp(ts).strftime('%Y-%m-%d %H:%M:%S')
                print "Commit", checksum
                print "Timestamp", ts_s
                detached = repo.read_commit_detached_metadata(checksum)
                if detached[0]:
                    for key in detached[1].keys():
                        print "Detached metadata %s -> %s" % (key, detached[1][key])
                print
Comment 14 Jeff Ortel 2015-08-03 13:32:58 UTC
Thanks Giuseppe!