1+ import { formatDuration , intervalToDuration } from "date-fns" ;
12import * as jsonc from "jsonc-parser" ;
23import * as fs from "node:fs/promises" ;
34
@@ -15,25 +16,45 @@ interface RecommendedSetting {
1516 readonly label : string ;
1617}
1718
19+ function recommended (
20+ shortName : string ,
21+ value : number | null ,
22+ ) : RecommendedSetting {
23+ if ( value === null ) {
24+ return { value, label : `${ shortName } : max allowed` } ;
25+ }
26+ const humanized = formatDuration (
27+ intervalToDuration ( { start : 0 , end : value * 1000 } ) ,
28+ ) ;
29+ return { value, label : `${ shortName } : ${ humanized } ` } ;
30+ }
31+
32+ /** Applied by the "Apply Recommended SSH Settings" command. */
1833export const RECOMMENDED_SSH_SETTINGS = {
19- "remote.SSH.connectTimeout" : {
20- value : 1800 ,
21- label : "Connect Timeout: 1800s (30 min)" ,
22- } ,
23- "remote.SSH.reconnectionGraceTime" : {
24- value : 28800 ,
25- label : "Reconnection Grace Time: 28800s (8 hours)" ,
26- } ,
27- "remote.SSH.serverShutdownTimeout" : {
28- value : 28800 ,
29- label : "Server Shutdown Timeout: 28800s (8 hours)" ,
30- } ,
31- "remote.SSH.maxReconnectionAttempts" : {
32- value : null ,
33- label : "Max Reconnection Attempts: max allowed" ,
34- } ,
34+ "remote.SSH.connectTimeout" : recommended ( "Connect Timeout" , 1800 ) ,
35+ "remote.SSH.reconnectionGraceTime" : recommended (
36+ "Reconnection Grace Time" ,
37+ 86400 ,
38+ ) ,
39+ "remote.SSH.serverShutdownTimeout" : recommended (
40+ "Server Shutdown Timeout" ,
41+ 86400 ,
42+ ) ,
43+ "remote.SSH.maxReconnectionAttempts" : recommended (
44+ "Max Reconnection Attempts" ,
45+ null ,
46+ ) ,
3547} as const satisfies Record < string , RecommendedSetting > ;
3648
49+ type SshSettingKey = keyof typeof RECOMMENDED_SSH_SETTINGS ;
50+
51+ /** Defaults set during connection when the user hasn't configured a value. */
52+ const AUTO_SETUP_DEFAULTS = {
53+ "remote.SSH.reconnectionGraceTime" : 28800 , // 8h
54+ "remote.SSH.serverShutdownTimeout" : 28800 , // 8h
55+ "remote.SSH.maxReconnectionAttempts" : null , // max allowed
56+ } as const satisfies Partial < Record < SshSettingKey , number | null > > ;
57+
3758/**
3859 * Build the list of VS Code setting overrides needed for a remote SSH
3960 * connection to a Coder workspace.
@@ -58,25 +79,17 @@ export function buildSshOverrides(
5879 }
5980
6081 // Default 15s is too short for startup scripts; enforce a minimum.
61- const minConnTimeout =
62- RECOMMENDED_SSH_SETTINGS [ "remote.SSH.connectTimeout" ] . value ;
63- const connTimeout = config . get < number > ( "remote.SSH.connectTimeout" ) ;
64- if ( ! connTimeout || connTimeout < minConnTimeout ) {
65- overrides . push ( {
66- key : "remote.SSH.connectTimeout" ,
67- value : minConnTimeout ,
68- } ) ;
82+ const connTimeoutKey : SshSettingKey = "remote.SSH.connectTimeout" ;
83+ const { value : minConnTimeout } = RECOMMENDED_SSH_SETTINGS [ connTimeoutKey ] ;
84+ const connTimeout = config . get < number > ( connTimeoutKey ) ;
85+ if ( minConnTimeout && ( ! connTimeout || connTimeout < minConnTimeout ) ) {
86+ overrides . push ( { key : connTimeoutKey , value : minConnTimeout } ) ;
6987 }
7088
71- // Set recommended defaults for settings the user hasn't configured.
72- const setIfUndefined = [
73- "remote.SSH.reconnectionGraceTime" ,
74- "remote.SSH.serverShutdownTimeout" ,
75- "remote.SSH.maxReconnectionAttempts" ,
76- ] as const ;
77- for ( const key of setIfUndefined ) {
89+ // Set conservative defaults for settings the user hasn't configured.
90+ for ( const [ key , value ] of Object . entries ( AUTO_SETUP_DEFAULTS ) ) {
7891 if ( config . get ( key ) === undefined ) {
79- overrides . push ( { key, value : RECOMMENDED_SSH_SETTINGS [ key ] . value } ) ;
92+ overrides . push ( { key, value } ) ;
8093 }
8194 }
8295
0 commit comments