@@ -467,20 +467,25 @@ export class Remote {
467
467
// "Host not found".
468
468
try {
469
469
this . storage . writeToCoderOutputChannel ( "Updating SSH config..." )
470
- await this . updateSSHConfig ( workspaceRestClient , parts . label , parts . host , binaryPath , logDir )
470
+ await this . updateSSHConfig ( workspaceRestClient , parts . label , parts . host , binaryPath , logDir , featureSet )
471
471
} catch ( error ) {
472
472
this . storage . writeToCoderOutputChannel ( `Failed to configure SSH: ${ error } ` )
473
473
throw error
474
474
}
475
475
476
476
// TODO: This needs to be reworked; it fails to pick up reconnects.
477
- this . findSSHProcessID ( ) . then ( ( pid ) => {
477
+ this . findSSHProcessID ( ) . then ( async ( pid ) => {
478
478
if ( ! pid ) {
479
479
// TODO: Show an error here!
480
480
return
481
481
}
482
482
disposables . push ( this . showNetworkUpdates ( pid ) )
483
- this . commands . workspaceLogPath = logDir ? path . join ( logDir , `${ pid } .log` ) : undefined
483
+ if ( logDir ) {
484
+ const logFiles = await fs . readdir ( logDir )
485
+ this . commands . workspaceLogPath = logFiles . find ( ( file ) => file . endsWith ( `${ pid } .log` ) )
486
+ } else {
487
+ this . commands . workspaceLogPath = undefined
488
+ }
484
489
} )
485
490
486
491
// Register the label formatter again because SSH overrides it!
@@ -532,7 +537,14 @@ export class Remote {
532
537
533
538
// updateSSHConfig updates the SSH configuration with a wildcard that handles
534
539
// all Coder entries.
535
- private async updateSSHConfig ( restClient : Api , label : string , hostName : string , binaryPath : string , logDir : string ) {
540
+ private async updateSSHConfig (
541
+ restClient : Api ,
542
+ label : string ,
543
+ hostName : string ,
544
+ binaryPath : string ,
545
+ logDir : string ,
546
+ featureSet : FeatureSet ,
547
+ ) {
536
548
let deploymentSSHConfig = { }
537
549
try {
538
550
const deploymentConfig = await restClient . getDeploymentSSHConfig ( )
@@ -610,13 +622,21 @@ export class Remote {
610
622
headerArg = ` --header-command ${ escapeSubcommand ( headerCommand ) } `
611
623
}
612
624
625
+ const hostPrefix = label ? `${ AuthorityPrefix } .${ label } --` : `${ AuthorityPrefix } --`
626
+
627
+ const proxyCommand = featureSet . wildcardSSH
628
+ ? `${ escape ( binaryPath ) } ${ headerArg } --global-config ${ escape (
629
+ path . dirname ( this . storage . getSessionTokenPath ( label ) ) ,
630
+ ) } ssh --stdio --network-info-dir ${ escape ( this . storage . getNetworkInfoPath ( ) ) } ${ await this . formatLogArg ( logDir ) } --ssh-host-prefix ${ hostPrefix } %h`
631
+ : `${ escape ( binaryPath ) } ${ headerArg } vscodessh --network-info-dir ${ escape (
632
+ this . storage . getNetworkInfoPath ( ) ,
633
+ ) } ${ await this . formatLogArg ( logDir ) } --session-token-file ${ escape ( this . storage . getSessionTokenPath ( label ) ) } --url-file ${ escape (
634
+ this . storage . getUrlPath ( label ) ,
635
+ ) } %h`
636
+
613
637
const sshValues : SSHValues = {
614
- Host : label ? `${ AuthorityPrefix } .${ label } --*` : `${ AuthorityPrefix } --*` ,
615
- ProxyCommand : `${ escape ( binaryPath ) } ${ headerArg } vscodessh --network-info-dir ${ escape (
616
- this . storage . getNetworkInfoPath ( ) ,
617
- ) } ${ await this . formatLogArg ( logDir ) } --session-token-file ${ escape ( this . storage . getSessionTokenPath ( label ) ) } --url-file ${ escape (
618
- this . storage . getUrlPath ( label ) ,
619
- ) } %h`,
638
+ Host : hostPrefix + `*` ,
639
+ ProxyCommand : proxyCommand ,
620
640
ConnectTimeout : "0" ,
621
641
StrictHostKeyChecking : "no" ,
622
642
UserKnownHostsFile : "/dev/null" ,
0 commit comments