GetStream / vg

Virtualgo: Easy and powerful workspace based development for go

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Virtualgo does not work well with delve

Taik opened this issue · comments

I'm currently using Gogland for go development. Switching over to vg definitely helps with reducing CPU load and in general making gogland snappier.

Running tests still works as expected. When setting breakpoints and running tests in debug mode, it seems like the breakpoints are not registering at all. My current fallback solution is to set GOPATH back to my default global path, effectively disabling vg, but that defeats the purpose of using it in the first place :)

This may be an OS X thing and how it deals with symlinks, but I thought I'd see if anyone else has a good way of dealing with this.

OSX and Gogland user here :) Can you provide more information on how I can try reproducing this? Which version of vg are you using (vg version)?

There's definitely some issues with the symlink approach in full isolation mode. Have you tried using it in global fallback mode to see if that solves the issue: https://github.com/GetStream/vg#workspaces-with-global-gopath-fallback

Another solution I'm working on is by using bindfs mounts instead of symlinks, it can be found on the bindfs branch. All commands that support specifying a full package path should work like normal with this branch.

I've been using this branch for myself for a while now and haven't run into issues. If you could give it a spin and see if it fixes the delve issue you're having that would be really great. You would have to install bindfs though, on mac it should be brew install bindfs. You probably have to destroy the workspace and recreate it again by activate it.

If you try out the bindfs branch there's one IMPORTANT thing to keep in mind. Don't delete the workspace directory manually (~/.virtualgo/<workspaceName>), otherwise it will actually delete the files inside your local installs. You should only remove the workspace by using vg destroy, which first unmounts the bindfs mounts. Other than that it should only improve upon the symlink approach.

@tbarbugli I'm currently using:

$ vg version
0.6.0

To reproduce, just set a breakpoint within any existing test case, and debug the test (CTRL + Shift + D). You should see that the breakpoint just gets skipped completely.

@JelteF I tried with global fallback and it doesn't seem to be breaking. I added both the virtualgo GOPATH and my global GOPATH as fallback. I'll give bindfs branch a try and report back!

@JelteF this is unrelated, but vg moveVendor (bindfs branch) gets stuck for me:

$ vg moveVendor                                                                                                                                                                                                                                                                                                                                                         
Uninstalling "github.com/reservemedia/reservation-srv" from workspace
  Unmounting bindfs mount at "/Users/thinh/.virtualgo/reservation-srv/src/github.com/reservemedia/reservation-srv"

I made sure that there's no other applications using that mount (lsof | grep ".virtualgo"). I can also manually unmount it ( umount ~/.virtualgo/reservation-srv/src/github.com/reservemedia/reservation-srv).

Good to hear setting global GOPATH works. But your bindfs thing is weird. I only had that happen when I was actually accessing it. Could you try unmounting it manually using fusermount -u ~/.virtualgo/reservation-srv/src/github.com/reservemedia/reservation-srv? Because that's what vg is trying to do.

@JelteF Yep it's definitely weird; unmounting it manually works for me. Are there any hidden debug flags I can set in order to get some useful output for you?

No, I don't really have any debug flags at the moment. But you could add some print staments/debug breakpoints around here to try and find out where it's getting stuck:

fmt.Fprintf(logWriter, " Unmounting bindfs mount at %q\n", pkgSrc)
stderrBuff := &bytes.Buffer{}
outputBuff := &bytes.Buffer{}
cmd := exec.Command("fusermount", "-u", pkgSrc)
cmd.Stderr = io.MultiWriter(stderrBuff, outputBuff)
cmd.Stdout = outputBuff
err := cmd.Run()
if err != nil {
notMountedOutput := fmt.Sprintf("fusermount: entry for %s not found", pkgSrc)
if !strings.HasPrefix(stderrBuff.String(), notMountedOutput) {
io.Copy(outputBuff, os.Stderr)
return errors.WithStack(err)
}
}

You can see that it's calling fusermount -u <dir> there. But if that works when you do it manually I'm guessing that's not where it gets stuck I guess. Maybe it's something as stupid as this line:

io.Copy(outputBuff, os.Stderr) 

@JelteF my apologies, I didn't expect it to execute the actual command, haha. I don't have fusermount on my system, so changing L171 to use umount worked for me.

cmd := exec.Command("umount", pkgSrc)

Just tested debugging, everything works with bindfs.

Good to hear that it works with bindfs, that gives me more reason to actually finish/clean up the feature. Just to confirm, debugging with delve now works without using a global fallback GOPATH, right?

Regarding the bug, I used fusermount because on linux umount requires sudo permissions. But apparently it doesn't work that way on mac. I'll debug this with my colleagues (that use macs) in a while and work on a cross platform solution. Probably something like trying fusermount first and if that doesn't exist try umount.

For now I would suggest you keep using your changed bindfs branch. And I'll close this issue once the branch is merged.

I just pushed a some changes to the bindfs branch that should make it work on OSX. @Taik could you see let me know if this is indeed the case?

@JelteF it works for me!

A minor thing, but should vg deactivate automatically unmount the directory?

Good to hear :). And no vg deactivate shouldn't unmount, because it could be that you have the same workspace activated twice.

Also, I've changed the bindfs branch to default to global fallback mode again in preparation of the next release. I did this, because global fallback interferes the least with go tooling usage. If you still want to use full isolation, you should use the --full-isolation flag of vg init when initially creating a workspace. See the new section in the updated README for some more info: https://github.com/GetStream/vg/tree/bindfs#workspace-import-modes

Just released the changes from the bindfs branch: https://github.com/GetStream/vg/releases/tag/v0.7.0

So I'm closing this now