mirror of
https://github.com/go-gitea/gitea.git
synced 2026-11-02 13:44:16 +09:00
fix(ssh): let pushes finish when the client disconnects early (#40105)
With the built-in SSH server, closing the client connection cancelled the `gitea serv` process tree. go-git based clients close it right after the push report, so post-receive was killed and branches, pull requests, webhooks and Actions were not updated. The command now runs under the server's hammer context like with OpenSSH, where it ends once its pipes close or at shutdown.
This commit is contained in:
1 parent
bd5fbcfb29
commit
fc4d490b35
2 files changed
+5
-12
No files matched your search
@@ -28,7 +28,6 @@ type sshServer struct {
|
||||
type sshSession struct {
|
||||
gossh.Channel
|
||||
conn *gossh.ServerConn
|
||||
ctx context.Context
|
||||
rawCmd string
|
||||
env []string
|
||||
}
|
||||
@@ -86,10 +85,7 @@ func (srv *sshServer) serve(listener net.Listener) error {
|
||||
func (srv *sshServer) handleConn(netConn net.Conn) {
|
||||
defer netConn.Close()
|
||||
|
||||
ctx, cancel := context.WithCancel(graceful.GetManager().HammerContext())
|
||||
defer cancel()
|
||||
|
||||
sshConn, sshChannels, sshReqs, err := gossh.NewServerConn(netConn, srv.newServerConfig(ctx))
|
||||
sshConn, sshChannels, sshReqs, err := gossh.NewServerConn(netConn, srv.newServerConfig(graceful.GetManager().HammerContext()))
|
||||
if err != nil {
|
||||
// OpenSSH's logs are something like:
|
||||
// * disconnect without sending anything: "Connection closed by 1.2.3.4 port 5678"
|
||||
@@ -107,11 +103,11 @@ func (srv *sshServer) handleConn(netConn net.Conn) {
|
||||
_ = newChan.Reject(gossh.UnknownChannelType, "unsupported channel type")
|
||||
continue
|
||||
}
|
||||
go handleSessionChannel(ctx, sshConn, newChan)
|
||||
go handleSessionChannel(sshConn, newChan)
|
||||
}
|
||||
}
|
||||
|
||||
func handleSessionChannel(ctx context.Context, conn *gossh.ServerConn, newChan gossh.NewChannel) {
|
||||
func handleSessionChannel(conn *gossh.ServerConn, newChan gossh.NewChannel) {
|
||||
channel, reqs, err := newChan.Accept()
|
||||
if err != nil {
|
||||
log.Error("SSH: Accept session channel: %v", err)
|
||||
@@ -119,7 +115,7 @@ func handleSessionChannel(ctx context.Context, conn *gossh.ServerConn, newChan g
|
||||
}
|
||||
defer channel.Close()
|
||||
|
||||
session := &sshSession{Channel: channel, conn: conn, ctx: ctx}
|
||||
session := &sshSession{Channel: channel, conn: conn}
|
||||
for req := range reqs {
|
||||
switch req.Type {
|
||||
case "env":
|
||||
|
||||
+1
-4
@@ -64,9 +64,6 @@ func sessionHandler(session *sshSession) int {
|
||||
args := []string{"--config=" + setting.CustomConf, "serv", "key-" + keyID}
|
||||
log.Trace("SSH: Arguments: %v", args)
|
||||
|
||||
ctx, cancel := context.WithCancel(session.ctx)
|
||||
defer cancel()
|
||||
|
||||
gitProtocol := ""
|
||||
for _, env := range session.env {
|
||||
if strings.HasPrefix(env, "GIT_PROTOCOL=") {
|
||||
@@ -75,7 +72,7 @@ func sessionHandler(session *sshSession) int {
|
||||
}
|
||||
}
|
||||
|
||||
cmd := process.CommandContext(ctx, setting.AppPath, args...)
|
||||
cmd := process.CommandContext(graceful.GetManager().HammerContext(), setting.AppPath, args...)
|
||||
cmd.Env = append(
|
||||
os.Environ(),
|
||||
"SSH_ORIGINAL_COMMAND="+session.rawCmd,
|
||||
|
||||
Reference in new issue
Block a user