1
1
import { Api } from "coder/site/src/api/api"
2
2
import { createWriteStream } from "fs"
3
3
import fs from "fs/promises"
4
- import { ensureDir } from "fs-extra"
5
4
import { IncomingMessage } from "http"
6
5
import path from "path"
7
6
import prettyBytes from "pretty-bytes"
@@ -24,14 +23,13 @@ export class Storage {
24
23
25
24
/**
26
25
* Add the URL to the list of recently accessed URLs in global storage, then
27
- * set it as the last used URL and update it on disk for the cli .
26
+ * set it as the last used URL.
28
27
*
29
- * If the URL is falsey, then remove it as the currently accessed URL and do
30
- * not touch the history.
28
+ * If the URL is falsey, then remove it as the last used URL and do not touch
29
+ * the history.
31
30
*/
32
31
public async setURL ( url ?: string ) : Promise < void > {
33
32
await this . memento . update ( "url" , url )
34
- this . updateUrl ( url )
35
33
if ( url ) {
36
34
const history = this . withUrlHistory ( url )
37
35
await this . memento . update ( "urlHistory" , history )
@@ -64,15 +62,13 @@ export class Storage {
64
62
}
65
63
66
64
/**
67
- * Set or unset the last used token and update it on disk for the cli .
65
+ * Set or unset the last used token.
68
66
*/
69
67
public async setSessionToken ( sessionToken ?: string ) : Promise < void > {
70
68
if ( ! sessionToken ) {
71
69
await this . secrets . delete ( "sessionToken" )
72
- this . updateSessionToken ( undefined )
73
70
} else {
74
71
await this . secrets . store ( "sessionToken" , sessionToken )
75
- this . updateSessionToken ( sessionToken )
76
72
}
77
73
}
78
74
@@ -109,16 +105,20 @@ export class Storage {
109
105
}
110
106
111
107
/**
112
- * Download and return the path to a working binary using the provided client.
108
+ * Download and return the path to a working binary for the deployment with
109
+ * the provided label using the provided client. If the label is empty, use
110
+ * the old deployment-unaware path instead.
111
+ *
113
112
* If there is already a working binary and it matches the server version,
114
113
* return that, skipping the download. If it does not match but downloads are
115
114
* disabled, return whatever we have and log a warning. Otherwise throw if
116
115
* unable to download a working binary, whether because of network issues or
117
116
* downloads being disabled.
118
117
*/
119
- public async fetchBinary ( restClient : Api ) : Promise < string > {
118
+ public async fetchBinary ( restClient : Api , label : string | string ) : Promise < string > {
120
119
const baseUrl = restClient . getAxiosInstance ( ) . defaults . baseURL
121
120
this . output . appendLine ( `Using deployment URL: ${ baseUrl } ` )
121
+ this . output . appendLine ( `Using deployment label: ${ label } ` )
122
122
123
123
// Settings can be undefined when set to their defaults (true in this case),
124
124
// so explicitly check against false.
@@ -133,7 +133,7 @@ export class Storage {
133
133
// Check if there is an existing binary and whether it looks valid. If it
134
134
// is valid and matches the server, or if it does not match the server but
135
135
// downloads are disabled, we can return early.
136
- const binPath = path . join ( this . getBinaryCachePath ( ) , cli . name ( ) )
136
+ const binPath = path . join ( this . getBinaryCachePath ( label ) , cli . name ( ) )
137
137
this . output . appendLine ( `Using binary path: ${ binPath } ` )
138
138
const stat = await cli . stat ( binPath )
139
139
if ( stat === undefined ) {
@@ -351,13 +351,21 @@ export class Storage {
351
351
}
352
352
}
353
353
354
- // getBinaryCachePath returns the path where binaries are cached.
355
- // The caller must ensure it exists before use.
356
- public getBinaryCachePath ( ) : string {
354
+ /**
355
+ * Return the directory for a deployment with the provided label to where its
356
+ * binary is cached.
357
+ *
358
+ * If the label is empty, read the old deployment-unaware config instead.
359
+ *
360
+ * The caller must ensure this directory exists before use.
361
+ */
362
+ public getBinaryCachePath ( label : string ) : string {
357
363
const configPath = vscode . workspace . getConfiguration ( ) . get ( "coder.binaryDestination" )
358
364
return configPath && String ( configPath ) . trim ( ) . length > 0
359
365
? path . resolve ( String ( configPath ) )
360
- : path . join ( this . globalStorageUri . fsPath , "bin" )
366
+ : label
367
+ ? path . join ( this . globalStorageUri . fsPath , label , "bin" )
368
+ : path . join ( this . globalStorageUri . fsPath , "bin" )
361
369
}
362
370
363
371
// getNetworkInfoPath returns the path where network information
@@ -377,17 +385,31 @@ export class Storage {
377
385
}
378
386
379
387
/**
380
- * Return the path to the session token file for the cli.
388
+ * Return the directory for the deployment with the provided label to where
389
+ * its session token is stored.
390
+ *
391
+ * If the label is empty, read the old deployment-unaware config instead.
392
+ *
393
+ * The caller must ensure this directory exists before use.
381
394
*/
382
- public getSessionTokenPath ( ) : string {
383
- return path . join ( this . globalStorageUri . fsPath , "session_token" )
395
+ public getSessionTokenPath ( label : string ) : string {
396
+ return label
397
+ ? path . join ( this . globalStorageUri . fsPath , label , "session_token" )
398
+ : path . join ( this . globalStorageUri . fsPath , "session_token" )
384
399
}
385
400
386
401
/**
387
- * Return the path to the URL file for the cli.
402
+ * Return the directory for the deployment with the provided label to where
403
+ * its url is stored.
404
+ *
405
+ * If the label is empty, read the old deployment-unaware config instead.
406
+ *
407
+ * The caller must ensure this directory exists before use.
388
408
*/
389
- public getURLPath ( ) : string {
390
- return path . join ( this . globalStorageUri . fsPath , "url" )
409
+ public getURLPath ( label : string ) : string {
410
+ return label
411
+ ? path . join ( this . globalStorageUri . fsPath , label , "url" )
412
+ : path . join ( this . globalStorageUri . fsPath , "url" )
391
413
}
392
414
393
415
public writeToCoderOutputChannel ( message : string ) {
@@ -399,28 +421,41 @@ export class Storage {
399
421
}
400
422
401
423
/**
402
- * Update or remove the URL on disk which can be used by the CLI via
403
- * --url-file.
424
+ * Configure the CLI for the deployment with the provided label.
404
425
*/
405
- private async updateUrl ( url : string | undefined ) : Promise < void > {
426
+ public async configureCli ( label : string , url : string | undefined , token : string | undefined | null ) {
427
+ await Promise . all ( [ this . updateUrlForCli ( label , url ) , this . updateTokenForCli ( label , token ) ] )
428
+ }
429
+
430
+ /**
431
+ * Update or remove the URL for the deployment with the provided label on disk
432
+ * which can be used by the CLI via --url-file.
433
+ *
434
+ * If the label is empty, read the old deployment-unaware config instead.
435
+ */
436
+ private async updateUrlForCli ( label : string , url : string | undefined ) : Promise < void > {
437
+ const urlPath = this . getURLPath ( label )
406
438
if ( url ) {
407
- await ensureDir ( this . globalStorageUri . fsPath )
408
- await fs . writeFile ( this . getURLPath ( ) , url )
439
+ await fs . mkdir ( path . dirname ( urlPath ) , { recursive : true } )
440
+ await fs . writeFile ( urlPath , url )
409
441
} else {
410
- await fs . rm ( this . getURLPath ( ) , { force : true } )
442
+ await fs . rm ( urlPath , { force : true } )
411
443
}
412
444
}
413
445
414
446
/**
415
- * Update or remove the session token on disk which can be used by the CLI
416
- * via --session-token-file.
447
+ * Update or remove the session token for a deployment with the provided label
448
+ * on disk which can be used by the CLI via --session-token-file.
449
+ *
450
+ * If the label is empty, read the old deployment-unaware config instead.
417
451
*/
418
- private async updateSessionToken ( token : string | undefined ) {
452
+ private async updateTokenForCli ( label : string , token : string | undefined | null ) {
453
+ const tokenPath = this . getSessionTokenPath ( label )
419
454
if ( token ) {
420
- await ensureDir ( this . globalStorageUri . fsPath )
421
- await fs . writeFile ( this . getSessionTokenPath ( ) , token )
455
+ await fs . mkdir ( path . dirname ( tokenPath ) , { recursive : true } )
456
+ await fs . writeFile ( tokenPath , token )
422
457
} else {
423
- await fs . rm ( this . getSessionTokenPath ( ) , { force : true } )
458
+ await fs . rm ( tokenPath , { force : true } )
424
459
}
425
460
}
426
461
0 commit comments