ostreedev / ostree

Operating system and container binary deployment and upgrades
https://ostreedev.github.io/ostree/
Other
1.29k stars 296 forks source link

Core dumped after passing GLib.Variant to OSTree.commit_get_parent #2404

Open lubosmj opened 3 years ago

lubosmj commented 3 years ago

Hello!

I have run into an error when I was trying to get a parent commit. I followed the steps provided at https://ostree.readthedocs.io/en/stable/manual/introduction/ to create an OSTree repository. Calling OSTree.commit_get_parent(commit) on the latest commit eventually triggered an error. I was using python bindings (https://lazka.github.io/pgi-docs/#OSTree-1.0/functions.html#OSTree.commit_get_parent).

Steps to reproduce the behaviour:

[lmjachky@localhost ostree_playground]$ ostree --repo=repo init
[lmjachky@localhost ostree_playground]$ mkdir tree
[lmjachky@localhost ostree_playground]$ echo "Hello world!" > tree/hello.txt
[lmjachky@localhost ostree_playground]$ ostree --repo=repo commit --branch=foo tree/
56747cad1db9fe104b2a3fb6a8ac8eeb988f2513f78f5fa938953e63606a7360
[lmjachky@localhost ostree_playground]$ ostree --repo=repo refs
foo
[lmjachky@localhost ostree_playground]$ ostree --repo=repo checkout foo tree-checkout/
[lmjachky@localhost ostree_playground]$ cat tree-checkout/hello.txt
Hello world!
[lmjachky@localhost ostree_playground]$ tree
.
├── repo
│   ├── config
│   ├── extensions
│   ├── objects
│   │   ├── 3a
│   │   │   └── 4e134a17e5fadf11fbdf8bef98234f6aa2369bf0629aabdd24073c0070cbdc.dirtree
│   │   ├── 56
│   │   │   └── 747cad1db9fe104b2a3fb6a8ac8eeb988f2513f78f5fa938953e63606a7360.commit
│   │   ├── a0
│   │   │   └── cc0c9ed1937032cdf7124e6e330d9bcb853214d6b5f5c8afeb8fb9e77e854d.file
│   │   └── d5
│   │       └── 85282a65417f5db7f7c979e05400a82f90a34648f291c173be7a4b0910d008.dirmeta
│   ├── refs
│   │   ├── heads
│   │   │   └── foo
│   │   ├── mirrors
│   │   └── remotes
│   ├── state
│   └── tmp
│       └── cache
├── tree
│   └── hello.txt
└── tree-checkout
    └── hello.txt

16 directories, 8 files
[lmjachky@localhost ostree_playground]$ ipython
Python 3.9.6 (default, Jun 29 2021, 00:00:00) 
Type 'copyright', 'credits' or 'license' for more information
IPython 7.20.0 -- An enhanced Interactive Python. Type '?' for help.

In [1]: import gi                                                                                                     

In [2]: gi.require_version("OSTree", "1.0")                                                                           

In [3]: from gi.repository import Gio, OSTree                                                                         

In [4]: repo = OSTree.Repo.new(Gio.File.new_for_path("repo/"))                                                        

In [5]: repo.open(None)                                                                                               
Out[5]: True

In [6]: repo.list_refs()                                                                                              
Out[6]: (True, out_all_refs={'foo': '56747cad1db9fe104b2a3fb6a8ac8eeb988f2513f78f5fa938953e63606a7360'})

In [7]: commit = repo.list_commit_objects_starting_with("56747cad1db9fe104b2a3fb6a8ac8eeb988f2513f78f5fa938953e63606a7
   ...: 360")                                                                                                         

In [8]: commit                                                                                                        
Out[8]: (True, out_commits={GLib.Variant('(su)', ('56747cad1db9fe104b2a3fb6a8ac8eeb988f2513f78f5fa938953e63606a7360', 4)): GLib.Variant('(bas)', (true, []))})

In [9]: commit = list(commit[1].keys())[0]                                                                            

In [10]: commit                                                                                                       
Out[10]: GLib.Variant('(su)', ('56747cad1db9fe104b2a3fb6a8ac8eeb988f2513f78f5fa938953e63606a7360', 4))

In [11]: OSTree.commit_get_parent(commit)                                                                             
**
GLib:ERROR:../glib/gvariant-serialiser.c:1367:g_variant_serialised_n_children: code should not be reached
Bail out! GLib:ERROR:../glib/gvariant-serialiser.c:1367:g_variant_serialised_n_children: code should not be reached
Aborted (core dumped)
[lmjachky@localhost ostree_playground]$ 

The same behaviour occurs for:

ostree-libs.x86_64                                       2021.2-2.fc34
ostree-libs.x86_64                                       2021.3-1.fc34

Is this a known issue?

dbnicholson commented 3 years ago

It probably should call g_variant_is_of_type and return a friendlier error instead of blindly using it, but the problem is that you're passing some GVariant, but not the right kind. You basically have the commit checksum, but you need to read the actual commit object.

I'd probably do it more like this:

_, checksum = repo.resolve_rev('foo', False)
_, commit, _ = repo.load_commit(checksum)
parent = OSTree.commit_get_parent(commit)

The key being that load_commit will read and return the commit object GVariant.