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

Add pure SSH LFS support #31516

Open
wants to merge 9 commits into
base: main
Choose a base branch
from
Open

Conversation

ConcurrentCrab
Copy link

@ConcurrentCrab ConcurrentCrab commented Jun 28, 2024

Fixes #17554
/claim #17554

Docs PR https://gitea.com/gitea/docs/pulls/49

To test, run pushes like: GIT_TRACE=1 git push. The trace output should mention "pure SSH connection".

@GiteaBot GiteaBot added the lgtm/need 2 This PR needs two approvals by maintainers to be considered for merging. label Jun 28, 2024
@pull-request-size pull-request-size bot added the size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files. label Jun 28, 2024
@github-actions github-actions bot added modifies/go Pull requests that update Go code modifies/cli PR changes something on the CLI, i.e. gitea doctor or gitea admin modifies/docs modifies/dependencies labels Jun 28, 2024
@lunny lunny added this to the 1.23.0 milestone Jun 28, 2024
@ConcurrentCrab
Copy link
Author

@lunny added copyright headers.

@ConcurrentCrab
Copy link
Author

Improved error handling.

@ConcurrentCrab
Copy link
Author

Accidentally resolved the conversation about DB connections above, but reiterating:

Pushes and clones work... but there's sometimes (by which I mean decently reproducible) bug where after transferring and verification and everything... the connection just hangs for almost exactly 120 seconds. After which it just ends gracefully and git proceeds with its push.

It's particularly nasty, I have no leads on it yet. The best I can figure out is that it looks like the git-lfs client seems to not send the quit command that it should at the end of the protocol, or that it isn't coming through.

@ConcurrentCrab
Copy link
Author

Added locking API support.

Well at least I figured out what's causing the hang. Setting lfs.ssh.automultiplex to false on the client side:
https://github.com/git-lfs/git-lfs/blob/8e36a03d85bf05bbca004dd7e8b55b147809b3e0/docs/man/git-lfs-config.adoc?plain=1#L90
gets rid of the hang. The bad news is that it's true by default.

I think this is feature interacting badly with the SSH server?

I traced the traffic, and indeed, something weird is happening on the client side. Git LFS spawns several workers each making its own connection. In a multiplexed connection, only the "first" spawn of the our commands gets a quit message. The rest of them have to wait 120 seconds for an EOF. I'm almost tempted to believe this is a bug on the git-lfs client side.

Can you check and see if this is reproducible in your environments?

@ConcurrentCrab
Copy link
Author

Yeah, I'm not going crazy. This commit:
git-lfs/git-lfs@44b8801
breaks pure SSH LFS sessions.

And this has history, it isn't even the first time lol:
git-lfs/git-lfs#5537

@ConcurrentCrab
Copy link
Author

just made: git-lfs/git-lfs#5816

@ConcurrentCrab ConcurrentCrab force-pushed the lfs-ssh branch 2 times, most recently from 5fadb5d to de9a3cf Compare July 1, 2024 20:15
Copy link
Member

@lafriks lafriks left a comment

Choose a reason for hiding this comment

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

As pointed in quite some places already but all should be fixed

modules/lfstransfer/backend/backend.go Outdated Show resolved Hide resolved
modules/lfstransfer/backend/backend.go Outdated Show resolved Hide resolved
modules/lfstransfer/backend/lock.go Outdated Show resolved Hide resolved
modules/lfstransfer/backend/lock.go Outdated Show resolved Hide resolved
@ConcurrentCrab
Copy link
Author

@lafriks adressed the url joins.

@lunny
Copy link
Member

lunny commented Sep 18, 2024

Yes

@ConcurrentCrab
Copy link
Author

Okay, I see, that was the part I was missing. This conversation would've been a lot shorter otherwise. This way it's not an obvious bug because the paths don't conflict with the existing public paths (though I still don't quite grasp to what ends).

@ConcurrentCrab
Copy link
Author

@lunny added private API. Used a /repo prefix so the path parameters don't accidentally match other internal APIs.

@lunny
Copy link
Member

lunny commented Sep 19, 2024

@lunny added private API. Used a /repo prefix so the path parameters don't accidentally match other internal APIs.

Thank you for the change and I think you also need to change the client code.

@ConcurrentCrab
Copy link
Author

Ah right, my bad.

@ConcurrentCrab
Copy link
Author

Just a sec, missed adding the internal token header there...

@ConcurrentCrab
Copy link
Author

So this is getting ugly pretty quick. The LFS handler APIs are hardcoded to require a JWT token (and this is necessary to check user permissions on the repo) as the Authorisation header. But the internal APIs need the header for their own token.

go.mod Show resolved Hide resolved
@6543
Copy link
Member

6543 commented Sep 20, 2024

I would be fine with the current state, just mention the lfs pull on the docu and the example ini next to tje enable option

Also add handler in runServ()

Doesn't add support for the locking API yet
@lunny
Copy link
Member

lunny commented Sep 24, 2024

It looks like LFS_ALLOW_PURE_SSH hasn't been read from [lfs] but [server]. Otherwise I can test it successfully. And you need to add an example in app.example.ini file.

@ConcurrentCrab
Copy link
Author

It looks like LFS_ALLOW_PURE_SSH hasn't been read from [lfs] but [server]. Otherwise I can test it successfully. And you need to add an example in app.example.ini file.

I added it under server because LFS_START_SERVER was there already.

@lunny
Copy link
Member

lunny commented Sep 26, 2024

It looks like LFS_ALLOW_PURE_SSH hasn't been read from [lfs] but [server]. Otherwise I can test it successfully. And you need to add an example in app.example.ini file.

I added it under server because LFS_START_SERVER was there already.

OK. It's a legacy problem. So could you add example in app.example.ini?

@github-actions github-actions bot added the docs-update-needed The document needs to be updated synchronously label Sep 26, 2024
@ConcurrentCrab
Copy link
Author

@lunny added it to the example config.

@GiteaBot GiteaBot added lgtm/done This PR has enough approvals to get merged. There are no important open reservations anymore. and removed lgtm/need 1 This PR needs approval from one additional maintainer to be merged. labels Sep 26, 2024
@lunny lunny added the reviewed/wait-merge This pull request is part of the merge queue. It will be merged soon. label Sep 26, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
docs-update-needed The document needs to be updated synchronously lgtm/done This PR has enough approvals to get merged. There are no important open reservations anymore. modifies/cli PR changes something on the CLI, i.e. gitea doctor or gitea admin modifies/dependencies modifies/go Pull requests that update Go code reviewed/wait-merge This pull request is part of the merge queue. It will be merged soon. size/XL Denotes a PR that changes 500-999 lines, ignoring generated files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Support LFS purely over SSH protocol
8 participants