diff --git a/package.json b/package.json index 2a994ae5..db63b8ab 100644 --- a/package.json +++ b/package.json @@ -47,6 +47,16 @@ "markdownDescription": "If true, the extension will not verify the authenticity of the remote host. This is useful for self-signed certificates.", "type": "boolean", "default": false + }, + "coder.binarySource": { + "markdownDescription": "Used to download the Coder CLI which is necessary to make SSH connections. The If-None-Match header will be set to the SHA1 of the CLI and can be used for caching. Absolute URLs will be used as-is; otherwise this value will be resolved against the deployment domain. Defaults to downloading from the Coder deployment.", + "type": "string", + "default": "" + }, + "coder.binaryDestination": { + "markdownDescription": "The full path of the directory into which the Coder CLI will be downloaded. Defaults to the extension's global storage directory.", + "type": "string", + "default": "" } } }, @@ -233,7 +243,7 @@ "dependencies": { "@types/node-forge": "^1.3.4", "@types/ua-parser-js": "^0.7.36", - "axios": "0.26.1", + "axios": "1.4.0", "date-fns": "^2.30.0", "eventsource": "^2.0.2", "find-process": "^1.4.7", diff --git a/src/error.test.ts b/src/error.test.ts index a966afd8..03cd96fb 100644 --- a/src/error.test.ts +++ b/src/error.test.ts @@ -219,6 +219,6 @@ it("falls back with different error", async () => { } catch (error) { const wrapped = await CertificateError.maybeWrap(error, "1", logger) expect(wrapped instanceof CertificateError).toBeFalsy() - expect(wrapped.message).toMatch(/failed with status code 500/) + expect((wrapped as Error).message).toMatch(/failed with status code 500/) } }) diff --git a/src/storage.ts b/src/storage.ts index e6bc8473..993a82ba 100644 --- a/src/storage.ts +++ b/src/storage.ts @@ -88,7 +88,6 @@ export class Storage { if (!baseURL) { throw new Error("Must be logged in!") } - const baseURI = vscode.Uri.parse(baseURL) const buildInfo = await getBuildInfo() const binPath = this.binaryPath() @@ -117,11 +116,16 @@ export class Storage { if (exists) { etag = await this.getBinaryETag() } + + const configSource = vscode.workspace.getConfiguration().get("coder.binarySource") + const binSource = configSource && String(configSource).trim().length > 0 ? String(configSource) : "/bin/" + binName + this.output.appendLine(`Using binName: ${binName}`) this.output.appendLine(`Using binPath: ${binPath}`) + this.output.appendLine(`Using binSource: ${binSource}`) this.output.appendLine(`Using ETag: ${etag}`) - const resp = await axios.get("/bin/" + binName, { + const resp = await axios.get(binSource, { signal: controller.signal, baseURL: baseURL, responseType: "stream", @@ -146,7 +150,9 @@ export class Storage { const completed = await vscode.window.withProgress( { location: vscode.ProgressLocation.Notification, - title: `Downloading the latest binary (${buildInfo.version} from ${baseURI.authority})`, + title: `Downloading the latest binary (${buildInfo.version} from ${axios.getUri( + resp.config, + )}) to ${binPath}`, cancellable: true, }, async (progress, token) => { @@ -260,7 +266,10 @@ export class Storage { // getBinaryCachePath returns the path where binaries are cached. // The caller must ensure it exists before use. public getBinaryCachePath(): string { - return path.join(this.globalStorageUri.fsPath, "bin") + const configPath = vscode.workspace.getConfiguration().get("coder.binaryDestination") + return configPath && String(configPath).trim().length > 0 + ? path.resolve(String(configPath)) + : path.join(this.globalStorageUri.fsPath, "bin") } // getNetworkInfoPath returns the path where network information diff --git a/yarn.lock b/yarn.lock index cf3c04d3..60eb3593 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1110,17 +1110,24 @@ astral-regex@^2.0.0: resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-2.0.0.tgz#483143c567aeed4785759c0865786dc77d7d2e31" integrity sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ== +asynckit@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" + integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q== + available-typed-arrays@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz#92f95616501069d07d10edb2fc37d3e1c65123b7" integrity sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw== -axios@0.26.1: - version "0.26.1" - resolved "https://registry.yarnpkg.com/axios/-/axios-0.26.1.tgz#1ede41c51fcf51bbbd6fd43669caaa4f0495aaa9" - integrity sha512-fPwcX4EvnSHuInCMItEhAGnaSEXRBjtzh9fOtsE6E1G6p7vl7edEeZe11QHf18+6+9gR5PbKV/sGKNaD8YaMeA== +axios@1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/axios/-/axios-1.4.0.tgz#38a7bf1224cd308de271146038b551d725f0be1f" + integrity sha512-S4XCWMEmzvo64T9GfvQDOXgYRDJ/wsSZc7Jvdgx5u1sd0JwsuPLqb3SYmusag+edF6ziyMensPVqLTSc1PiSEA== dependencies: - follow-redirects "^1.14.8" + follow-redirects "^1.15.0" + form-data "^4.0.0" + proxy-from-env "^1.1.0" azure-devops-node-api@^11.0.1: version "11.2.0" @@ -1473,6 +1480,13 @@ colorette@^2.0.14: resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.19.tgz#cdf044f47ad41a0f4b56b3a0d5b4e6e1a2d5a798" integrity sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ== +combined-stream@^1.0.8: + version "1.0.8" + resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" + integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== + dependencies: + delayed-stream "~1.0.0" + commander@^2.20.0: version "2.20.3" resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" @@ -1619,6 +1633,11 @@ define-properties@^1.1.3, define-properties@^1.1.4: has-property-descriptors "^1.0.0" object-keys "^1.1.1" +delayed-stream@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" + integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== + detect-libc@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-2.0.1.tgz#e1897aa88fa6ad197862937fbc0441ef352ee0cd" @@ -2319,7 +2338,7 @@ flatted@^3.1.0: resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.7.tgz#609f39207cb614b89d0765b477cb2d437fbf9787" integrity sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ== -follow-redirects@^1.14.8: +follow-redirects@^1.15.0: version "1.15.2" resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.2.tgz#b460864144ba63f2681096f274c4e57026da2c13" integrity sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA== @@ -2339,6 +2358,15 @@ foreground-child@^2.0.0: cross-spawn "^7.0.0" signal-exit "^3.0.2" +form-data@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452" + integrity sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.8" + mime-types "^2.1.12" + format@^0.2.0: version "0.2.2" resolved "https://registry.yarnpkg.com/format/-/format-0.2.2.tgz#d6170107e9efdc4ed30c9dc39016df942b5cb58b" @@ -3311,7 +3339,7 @@ mime-db@1.52.0: resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== -mime-types@^2.1.27: +mime-types@^2.1.12, mime-types@^2.1.27: version "2.1.35" resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== @@ -3823,6 +3851,11 @@ progress@^2.0.0: resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== +proxy-from-env@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2" + integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg== + prr@~1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476"