jupyterlab-git icon indicating copy to clipboard operation
jupyterlab-git copied to clipboard

Labextension UI "Git Diff" fails for file in symlinked path outside of Jupyter's "home startup" folder: Error Loading File Diff, outside root contents directory

Open JeffSaxeVA opened this issue 4 years ago • 5 comments

Description

Our JupyterHub setup has home directories (/home/OurDomain/UserName), and then under those, symbolic links to sets of remote NFS or CIFS shares (~/MyMounts -> /mnt/UserName/SomeShare), which are mounted via autofs when the user steps into them. All of this works great, and our users are able to Git-Clone a project into a working folder inside one of those linked shares and work on notebooks, and the JupyterLab-Git extension on the left beautifully updates the file status of not-yet-committed files. Almost all functionality works. However, trying to click the small "diff" icon next to a Changed file results in a JupyterLab tab with an error message...

Error Loading File Diff: ../../../mnt/UserName/SomeShare/folder1/folder2/README.md is outside root contents directory

So the visual Git Diff doesn't work, but if I open a Terminal window, change directory into the working directory, and use "git diff README.md", the CLI-based git diff does work and shows me the differences as red and green colored lines of text. If I move the entire working directory into /home/OurDomain/UserName instead (not "down" into a subfolder that ends up leaping out of the filesystem), then the visual diff works.

I think I see from the source code that the error is being displayed to me by the routine ShowError https://github.com/jupyterlab/jupyterlab-git/blob/master/src/components/diff/PlainTextDiff.ts#L163 but the actual error of refusing to render or collect a file outside the root contents is presumably coming from another part of Jupyter. So I expect the root cause is the construction of the "reference" and "challenger" URLs or paths, and I don't know what constructs those or why it would try to start them with a few prepends of "..", trying to traverse up the directory tree, when the files are already accessible here in the current directory.

I might be able to work around this by having everybody's Jupyter notebook servers start with their top-level path parameters as "/", so that stepping into any path would be valid, but I don't really want to; I'd like users to stay cocooned in their own home directories except for specifically-linked-outside locations that we provide to them (for safety and to reduce confusion). So I'm wondering if there is a way for these Git Diff paths to be constructed without those dot-dot prepends, such that Jupyter no longer sees them as violating the root contents directory restriction. In my Web Console details below, I believe this is the parameter "top_repo_path".

Reproduce

  1. Use autofs or just a simple manual mount to get /mnt/UserName/SomeShare to be mounted and writable
  2. Inside /home/OurDomain/UserName, make a symbolic (soft) link MyMounts -> /mnt/UserName
  3. Start JupyterLab with a normal default of its root folder being /home/OurDomain/Username. Navigate down into MyMounts/SomeShare, and inside that, git clone a repo.
  4. Use any editing tool to make a small change to a file. Note that it shows up under Changed on the left.
  5. Hover over the filename under Changed, and click the icon for Diff This File. The resulting tab does not show the file diffs, but instead the error message "...is outside root contents directory".

Expected behavior

A successful side-by-side red/green comparison.

Context

  • Python package version: jupyterlab-git 0.30.0 pyhd8ed1ab_0

  • Extension version: @jupyterlab/git v0.30.0 enabled OK (python, jupyterlab-git)

  • Git version: git version 2.17.1

  • Operating System and its version: Ubuntu 18.04LTS

Command Line Output
/opt/conda/envs/qimConda-21.0.S/lib/python3.8/site-packages/jupyter_server/base/handlers.py:131: RuntimeWarning: Expected to see HubAuthenticatedHandler in .mro()
  return self.login_handler.get_user(self)
/opt/conda/envs/qimConda-21.0.S/lib/python3.8/site-packages/jupyter_server/base/handlers.py:131: RuntimeWarning: Expected to see HubAuthenticatedHandler in .mro()
  return self.login_handler.get_user(self)
/opt/conda/envs/qimConda-21.0.S/lib/python3.8/site-packages/jupyter_server/base/handlers.py:131: RuntimeWarning: Expected to see HubAuthenticatedHandler in .mro()
  return self.login_handler.get_user(self)
/opt/conda/envs/qimConda-21.0.S/lib/python3.8/site-packages/jupyter_server/base/handlers.py:131: RuntimeWarning: Expected to see HubAuthenticatedHandler in .mro()
  return self.login_handler.get_user(self)
[W 2021-05-25 14:21:02.982 SingleUserNotebookApp handlers:599] ../../../mnt/UserName/SomeShare/folder1/folder2/README.md is outside root contents directory
Web Browser Output

Failed to load file diff. Error: ../../../mnt/UserName/SomeShare/folder1/folder2/README.md is outside root contents directory at ve (664.5325d4478a874d2ca125.js?v=5325d4478a874d2ca125:1) at async Promise.all (index 1)

I can also see in the Network tab the one failed "404" error request for .../git/content?1621967203361, and in the Request Payload section, it has a JSON structure

{filename: "README.md", reference: {special: "WORKING"},…}
filename: "README.md"
reference: {special: "WORKING"}
special: "WORKING"
top_repo_path: "../../../mnt/UserName/SomeShare/folder1/folder2"

JeffSaxeVA avatar May 25 '21 18:05 JeffSaxeVA

Thank you for opening your first issue in this project! Engagement like this is essential for open source projects! :hugs:
If you haven't done so already, check out Jupyter's Code of Conduct. Also, please try to follow the issue template as it helps other other community members to contribute more effectively. welcome You can meet the other Jovyans by joining our Discourse forum. There is also an intro thread there where you can stop by and say Hi! :wave:
Welcome to the Jupyter community! :tada:

welcome[bot] avatar May 25 '21 18:05 welcome[bot]

Thanks @JeffSaxeVA for reporting the issue. By chance I just merged a big change in path handling with #939. Would you be willing to test the master branch to see if it fixes your issue?

fcollonval avatar May 27 '21 07:05 fcollonval

Thanks for replying, Frédéric! I am trying hard to verify whether current master fixes this issue, but I'm afraid I have less experience than I would like in JupyterLab Extensions packaging. I performed a conda update to the latest Release tag of 0.30.1, and I got GitHub to show me a list of files committed between that tag and now, and I tried just sort of selectively copying in a few files (git.py, handlers.py, init.py) and restarting my Jupyter server. (I ignored the entire tests subdirectory.) I can tell that the pycache files have changed to the current date, so I know that something reloaded... but I clearly haven't done the job completely, because now when I click on the Git extension symbol on the left, it no longer recognizes that I have navigated inside a git repo at all. It just always shows the blue buttons for initializing or cloning a new repo.

So I expect that I also have to copy all those changed .TS and .TSX files somewhere, but I don't know how to do that manually. And I don't really want to go down the rabbit hole of the LabExtension build process, because our servers are behind strict firewalls and I don't want to try to grab all the Node.JS toolset. Sorry to seem like a wimp. I will just wait for your team to do a 0.30.2 release and then perform the update from the public repo as usual.

JeffSaxeVA avatar May 27 '21 16:05 JeffSaxeVA

Thanks for trying @JeffSaxeVA

I may cut a beta release so you could test it more easily. I ping you here when it is done.

fcollonval avatar May 28 '21 10:05 fcollonval

An alpha version has been released. To install it, execute:

python -m pip install --pre jupyterlab-git==0.31.0a0

fcollonval avatar Jun 10 '21 06:06 fcollonval