From 0f0f61f43252103487b09ccd7435a6e98ed67898 Mon Sep 17 00:00:00 2001 From: Eugene Pankov Date: Thu, 17 Nov 2022 20:26:17 +0100 Subject: [PATCH] fixed #6263, fixed #7460 - ssh: handle MaxSessions --- tabby-ssh/src/components/sshTab.component.ts | 38 ++++++++++--------- .../src/services/sshMultiplexer.service.ts | 4 +- tabby-ssh/src/session/shell.ts | 4 +- 3 files changed, 25 insertions(+), 21 deletions(-) diff --git a/tabby-ssh/src/components/sshTab.component.ts b/tabby-ssh/src/components/sshTab.component.ts index 4521f873..d623728b 100644 --- a/tabby-ssh/src/components/sshTab.component.ts +++ b/tabby-ssh/src/components/sshTab.component.ts @@ -84,9 +84,9 @@ export class SSHTabComponent extends BaseTerminalTabComponent { super.ngOnInit() } - async setupOneSession (injector: Injector, profile: SSHProfile): Promise { + async setupOneSession (injector: Injector, profile: SSHProfile, multiplex = true): Promise { let session = await this.sshMultiplexer.getSession(profile) - if (!session || !profile.options.reuseSession) { + if (!multiplex || !session || !profile.options.reuseSession) { session = new SSHSession(injector, profile) if (profile.options.jumpHost) { @@ -146,11 +146,8 @@ export class SSHTabComponent extends BaseTerminalTabComponent { try { await session.start() + } finally { this.stopSpinner() - } catch (e) { - this.stopSpinner() - this.write(colors.black.bgRed(' X ') + ' ' + colors.red(e.message) + '\r\n') - return session } this.sshMultiplexer.addSession(session) @@ -186,21 +183,14 @@ export class SSHTabComponent extends BaseTerminalTabComponent { super.attachSessionHandlers() } - async initializeSession (): Promise { - this.reconnectOffered = false + private async initializeSessionMaybeMultiplex (multiplex = true): Promise { if (!this.profile) { - this.logger.error('No SSH connection info supplied') - return - } - - try { - this.sshSession = await this.setupOneSession(this.injector, this.profile) - } catch (e) { - this.write(colors.black.bgRed(' X ') + ' ' + colors.red(e.message) + '\r\n') - return + throw new Error('No SSH connection info supplied') } + this.sshSession = await this.setupOneSession(this.injector, this.profile, multiplex) const session = new SSHShellSession(this.injector, this.sshSession, this.profile) + this.setSession(session) this.attachSessionHandler(session.serviceMessage$, msg => { msg = msg.replace(/\n/g, '\r\n ') @@ -212,6 +202,20 @@ export class SSHTabComponent extends BaseTerminalTabComponent { this.session?.resize(this.size.columns, this.size.rows) } + async initializeSession (): Promise { + this.reconnectOffered = false + try { + await this.initializeSessionMaybeMultiplex(true) + } catch { + try { + await this.initializeSessionMaybeMultiplex(false) + } catch (e) { + this.write(colors.black.bgRed(' X ') + ' ' + colors.red(e.message) + '\r\n') + return + } + } + } + async getRecoveryToken (options?: GetRecoveryTokenOptions): Promise { return { type: 'app:ssh-tab', diff --git a/tabby-ssh/src/services/sshMultiplexer.service.ts b/tabby-ssh/src/services/sshMultiplexer.service.ts index 9f7e4965..2665187e 100644 --- a/tabby-ssh/src/services/sshMultiplexer.service.ts +++ b/tabby-ssh/src/services/sshMultiplexer.service.ts @@ -15,7 +15,9 @@ export class SSHMultiplexerService { const key = await this.getMultiplexerKey(session.profile) this.sessions.set(key, session) session.willDestroy$.subscribe(() => { - this.sessions.delete(key) + if (this.sessions.get(key) === session) { + this.sessions.delete(key) + } }) } diff --git a/tabby-ssh/src/session/shell.ts b/tabby-ssh/src/session/shell.ts index 1a0a600d..4f1b4cf6 100644 --- a/tabby-ssh/src/session/shell.ts +++ b/tabby-ssh/src/session/shell.ts @@ -1,5 +1,4 @@ import { Observable, Subject } from 'rxjs' -import colors from 'ansi-colors' import stripAnsi from 'strip-ansi' import { ClientChannel } from 'ssh2' import { Injector } from '@angular/core' @@ -41,11 +40,10 @@ export class SSHShellSession extends BaseSession { try { this.shell = await this.ssh.openShellChannel({ x11: this.profile.options.x11 ?? false }) } catch (err) { - this.emitServiceMessage(colors.bgRed.black(' X ') + ` Remote rejected opening a shell channel: ${err}`) if (err.toString().includes('Unable to request X11')) { this.emitServiceMessage(' Make sure `xauth` is installed on the remote side') } - return + throw new Error(`Remote rejected opening a shell channel: ${err}`) } this.open = true