Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Golang binding #22

Merged
merged 2 commits into from
Jan 23, 2020
Merged

Golang binding #22

merged 2 commits into from
Jan 23, 2020

Conversation

zhiburt
Copy link
Contributor

@zhiburt zhiburt commented Jan 18, 2020

Hello @cyphar, that is a great crate.
This PR is going to close #3

I was tried to have done it with considerable safety but I am not sure, that I accomplished that :)

Not covered features (still have not managed all the information profoundly)

  • duplicate
  • from_fd
  • intofd

I would like to mention that it was barely tested, I might should write a bunch of tests.

@cyphar
Copy link
Member

cyphar commented Jan 18, 2020

Wow, awesome! I wasn't expecting this at all (I have draft Go bindings on my laptop I've been meaning to polish and push). I'll review this when I get home -- but one quick thing is that I need to you add Signed-off-by: [Your Name] <your email> to all of your commits. This is to certify that you agree with the Developer Certificate of Origin -- this is not a CLA, it's just a way for you to formally say that the PR is your own work (or is not your own work and you have the right to publish it under the relevant license). This is the same process Linux and many other large projects use.

@cyphar
Copy link
Member

cyphar commented Jan 18, 2020

As for tests, I have plans for binding-agnostic tests (see #6) so we can wait for a while before adding tests for individual bindings (though I would suggest that you should add an example program in examples/ -- as a form of documentation for the bindings oh you already added a Go example).

Copy link
Member

@cyphar cyphar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is my initial review, I'll take a closer look when I get home.

contrib/bindings/go/pathrs/capi.go Outdated Show resolved Hide resolved
contrib/bindings/go/pathrs/capi.go Outdated Show resolved Hide resolved
contrib/bindings/go/pathrs/capi.go Outdated Show resolved Hide resolved
contrib/bindings/go/pathrs/capi.go Outdated Show resolved Hide resolved
contrib/bindings/go/pathrs/pathrs.go Show resolved Hide resolved
contrib/bindings/go/pathrs/pathrs.go Show resolved Hide resolved
contrib/bindings/go/pathrs/capi.go Outdated Show resolved Hide resolved
contrib/bindings/go/pathrs/capi.go Outdated Show resolved Hide resolved
examples/go/cat.go Show resolved Hide resolved
contrib/bindings/go/pathrs/pathrs.go Outdated Show resolved Hide resolved
@zhiburt
Copy link
Contributor Author

zhiburt commented Jan 18, 2020

That were the reasonable observations.

Signed-off-by: [Your Name] <your email>. The latest commits were provided with it but the initial ones are untouched since it seems I will have to make a force push.

And according the fact that the commit list have slightly grown may I just reopen it after the review process with the foregoing line?

What is more I have recently found out that commit style of the repo is different to mine, apparently that is my fault :(

@zhiburt zhiburt requested a review from cyphar January 18, 2020 23:03
@cyphar
Copy link
Member

cyphar commented Jan 18, 2020

@zhiburt

The latest commits were provided with it but the initial ones are untouched since it seems I will have to make a force push.

Please just force-push to your branch. I would also prefer if you squashed the commits down into a few small pieces. If you've never used git rebase -i before, here's a video that might help.

Personally I find it helpful to also have commit messages that have a body (that way the git commit log contains information about why your patch does things in a particular way), but you don't need to bother with that too much if you don't personally find it helpful.

Also please note that all of your commits must have a Signed-off-by -- it's a legal requirement to avoid a bunch of potential problems in the future.

And according the fact that the commit list have slightly grown may I just reopen it after the review process with the foregoing line?

You don't need to open a new PR, just force push to your current PR's branch with fixed up commits.

What is more I have recently found out that commit style of the repo is different to mine, apparently that is my fault.

Don't worry about it too much. If it helps, the commit style of this repo is loosely based on the Linux kernel commit style or the style of several other container runtime projects like Docker and runc (and LXC, and LXD, and ...).

Copy link
Member

@cyphar cyphar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here are some more comments. It is looking a lot better, though there does appear to be a lot of needless wrapping (or re-definition) of things which are cgo-generated. We should opt to use the cgo-generated structures as much as possible -- not only will it make the code shorter it will make it somewhat more obvious which objects are from the C FFI interface and which objects are part of the binding.

I'm also quite worried about the pointer casting you're doing to a Go struct with a C pointer. That feels incredibly fragile to me.

contrib/bindings/go/pathrs/pathrs.go Outdated Show resolved Hide resolved
contrib/bindings/go/pathrs/pathrs.go Outdated Show resolved Hide resolved
contrib/bindings/go/pathrs/pathrs.go Outdated Show resolved Hide resolved
contrib/bindings/go/pathrs/pathrs.go Outdated Show resolved Hide resolved
contrib/bindings/go/pathrs/pathrs.go Outdated Show resolved Hide resolved
examples/cat.go Outdated Show resolved Hide resolved
@zhiburt
Copy link
Contributor Author

zhiburt commented Jan 20, 2020

Thank you for your helpful comments. I suppose the vast majority of the issues were resolved.

But I truly assume that it is not thread safe now. (If I understand error handling correctly, there can appear an issue) (I will check it and then change the comment in the nearest)

And it is not covered configure function yet

@zhiburt zhiburt requested a review from cyphar January 20, 2020 00:41
@cyphar
Copy link
Member

cyphar commented Jan 20, 2020

@zhiburt You're right that technically the current error handling is not thread-safe. Maybe we should use thread-local storage to fix that (then again, @brauner complained very loudly when I suggested this a while ago). But the underlying libpathrs operations are thread-safe so I'll need to think about how to deal with this...

Copy link
Member

@cyphar cyphar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I reckon this is my last set of reviews before I merge it. Please note that I am probably going to rewrite a few portions of it after merging (since I don't want to make you spend too much time cleaning up things I can just clean up myself). The binding looks pretty good otherwise.

Ignore the things I've written as NOTE TO SELF.

contrib/bindings/go/pathrs/pathrs.go Outdated Show resolved Hide resolved
contrib/bindings/go/pathrs/pathrs.go Show resolved Hide resolved
contrib/bindings/go/pathrs/pathrs.go Outdated Show resolved Hide resolved
contrib/bindings/go/pathrs/pathrs.go Outdated Show resolved Hide resolved
contrib/bindings/go/pathrs/pathrs.go Outdated Show resolved Hide resolved
contrib/bindings/go/pathrs/pathrs.go Outdated Show resolved Hide resolved
contrib/bindings/go/pathrs/pathrs.go Outdated Show resolved Hide resolved
contrib/bindings/go/pathrs/pathrs.go Outdated Show resolved Hide resolved
contrib/bindings/go/pathrs/pathrs.go Outdated Show resolved Hide resolved
contrib/bindings/go/pathrs/pathrs.go Outdated Show resolved Hide resolved
Copy link
Member

@cyphar cyphar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alright, the code looks good enough to me to merge -- thanks so much for contributing! 😸 There are still some small things that I think should be fixed up a little bit (such as doc comments and some of the function names), but I can do those myself.

However, there is still a bit of cleanup needed with your commits. c96b886 is missing a DCO Signed-off-by. Also the commits should be squashed more (ideally there should be just one commit to add the binding -- possibly with some information in the commit message, and one commit to add the example that uses the binding).

This binding is mainly inspired by python building.
The public interface is built on the shoulders of `Root` and `Handle`
structures, in a similar way as the original library does.
These ones are straightforward wrappers of the C api to provide
a safe and idiomatic interface.

As for error handling it upholds the idea to copy all the data which is
provided by ffi interface including backtrace.
It copies it to an internal structure to not being bound
by handling errors on place. Since golang does not has a
standart way to manage stackraces it can be get by casting
error to `pathrs.Error` type and call `Backtrace` method.

This binding does not provide configuration interface of pathrs.

Signed-off-by: Maxim Zhiburt <[email protected]>
@zhiburt zhiburt force-pushed the golang_binding branch 2 times, most recently from a4410bf to 9200aa0 Compare January 22, 2020 14:27
This is a simple program to print the whole file to
stdout using safe path resolution.
And demonstrates safe handling errors and key functions
such as `*Root`.Resolve, `*Handle`.Open.

To start this program was set a pile of env variables:
`CGO_LDFLAGS`, `CGO_CFLAGS` and `LD_LIBRARY_PATH`.

Signed-off-by: Maxim Zhiburt <[email protected]>
Copy link
Member

@cyphar cyphar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks great. Let me know if you want to do any final cleanups before I merge.

@zhiburt
Copy link
Contributor Author

zhiburt commented Jan 22, 2020

It is definitely better rather than it was initially.
Thank you @cyphar, for your utterly helpful observations and reviews.
I hope it has been followed according to your expectations. And this PR has not affected any of your plans.

Thank you for this chance to participate in this awesome library.


Might it is ready to be merged, but I have to bring one question up, as I see duplicate does not have to consume object as well as we can see in rust example. But through ffi appears an issue with that (go example).

    let root = pathrs::Root::open(rootPath).unwrap();
    let root1 = root.try_clone().unwrap();
    let root2 = root.try_clone().unwrap();

    root.resolve(path).unwrap();
	root, err := pathrs.Open(rootPath)
	if err != nil {
		printPathError(err)
	}
	defer root.Close()

	root1, err := root.Clone()
	if err != nil {
		printPathError(err)
	}
	
	root2, err := root.Clone()
	if err != nil {
		printPathError(err)
	}

There will be produced an error in the second Clone call which statement is Error invalid ptr argument: invalid pathrs object, the same will goes after calling some method for instance Resolve on the original root variable (look bellow). When we call it on the cloned one it goes well.

	root, err := pathrs.Open(rootPath)
	if err != nil {
		printPathError(err)
	}
	defer root.Close()

	_, err = root.Clone()
	if err != nil {
		printPathError(err)
	}
	
        handle, err := root.Resolve(path)
	if err != nil {
		printPathError(err)
	}

I cannot bet that it is normal or not.

@cyphar
Copy link
Member

cyphar commented Jan 22, 2020

Error invalid ptr argument: invalid pathrs object

That means that the internal pointer has been zeroed... I will look into that, but it's probably a bug in pathrs_duplicate. I can fix that later.

EDIT: Yeah, it's a bug in pathrs_duplicate. I stupidly used Option::take rather than Option::as_ref. b210aac should fix the issue.

@zhiburt
Copy link
Contributor Author

zhiburt commented Jan 22, 2020

That means that the internal pointer has been zeroed... I will look into that, but it's probably a bug in pathrs_duplicate. I can fix that later.

Great, I hope it is not an error of this binding since I tried to check everything.

This looks great. Let me know if you want to do any final cleanups before I merge.

I will check it up one more time a bit later, I hope it will have gone well. If I will not write anything by evening you can be sure I had checked it one more time and merge it.

@cyphar
Copy link
Member

cyphar commented Jan 22, 2020

Yeah, it was a bug in pathrs_duplicate. I pushed a fix to master. But I also forgot to respond to your original comment. I hope that I wasn't too much of a perfectionist when giving reviews (I often struggle when reviewing PRs when to say "it's alright as-is, and I can fix any nits later"). Thanks so much for contributing, it's great to see someone contributing to something that is still a work-in-progress.

@cyphar cyphar merged commit e6737f8 into openSUSE:master Jan 23, 2020
@cyphar cyphar mentioned this pull request Jan 23, 2020
@cyphar
Copy link
Member

cyphar commented Jan 28, 2020

I only just noticed this now (and I'm fixing it), but the usage of C.CString in this binding actually leaks memory because there is no call to C.free.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Go bindings
2 participants