diff --git a/README.md b/README.md index 547c336c1ca7..8793a606e364 100644 --- a/README.md +++ b/README.md @@ -63,6 +63,12 @@ How to [secure your setup](/doc/security/ssl.md). At the moment we can't use the official VSCode Marketplace. We've created a custom extension marketplace focused around open-sourced extensions. However, if you have access to the `.vsix` file, you can manually install the extension. +## Telemetry + +Use the `--disable-telemetry` flag or set `DISABLE_TELEMETRY=true` to disable tracking ENTIRELY. + +We use data collected to improve code-server. + ## Contributing Development guides are coming soon. diff --git a/doc/self-hosted/index.md b/doc/self-hosted/index.md index c3ee6a998d1f..4a8934cbbc6f 100644 --- a/doc/self-hosted/index.md +++ b/doc/self-hosted/index.md @@ -34,28 +34,29 @@ It takes just a few minutes to get your own self-hosted server running. If you'v code-server can be ran with a number of arguments to customize your working directory, host, port, and SSL certificate. ``` -USAGE - $ code-server [WORKDIR] - -ARGUMENTS - WORKDIR [default: (directory to binary)] Specify working dir - -OPTIONS - -d, --data-dir=data-dir - -h, --host=host [default: 0.0.0.0] - -o, --open Open in browser on startup - -p, --port=port [default: 8443] Port to bind on - -v, --version show CLI version - --allow-http - --cert=cert - --cert-key=cert-key - --help show CLI help - --no-auth - --password=password +Usage: code-server [options] + +Run VS Code on a remote server. + +Options: + -V, --version output the version number + --cert + --cert-key + -e, --extensions-dir Set the root path for extensions. + -d --user-data-dir Specifies the directory that user data is kept in, useful when running as root. + --data-dir DEPRECATED: Use '--user-data-dir' instead. Customize where user-data is stored. + -h, --host Customize the hostname. (default: "0.0.0.0") + -o, --open Open in the browser on startup. + -p, --port Port to bind on. (default: 8443) + -N, --no-auth Start without requiring authentication. + -H, --allow-http Allow http connections. + -P, --password Specify a password for authentication. + --disable-telemetry Disables ALL telemetry. + -h, --help output usage information ``` ### Data Directory - Use `code-server -d (path/to/directory)` or `code-server --data-dir=(path/to/directory)`, excluding the parentheses to specify the root folder that VS Code will start in + Use `code-server -d (path/to/directory)` or `code-server --data-dir=(path/to/directory)`, excluding the parentheses to specify the root folder that VS Code will start in. ### Host By default, code-server will use `0.0.0.0` as its address. This can be changed by using `code-server -h` or `code-server --host=` followed by the address you want to use. @@ -68,6 +69,9 @@ OPTIONS By default, code-server will use `8443` as its port. This can be changed by using `code-server -p` or `code-server --port=` followed by the port you want to use. > Example: `code-server -p 9000` + ### Telemetry + Disable all telemetry with `code-server --disable-telemetry`. + ### Cert and Cert Key To encrypt the traffic between the browser and server use `code-server --cert=` followed by the path to your `.cer` file. Additionally, you can use certificate keys with `code-server --cert-key` followed by the path to your `.key` file. > Example (certificate and key): `code-server --cert /etc/letsencrypt/live/example.com/fullchain.cer --cert-key /etc/letsencrypt/live/example.com/fullchain.key` @@ -116,4 +120,4 @@ OPTIONS *Important:* For more details about Apache reverse proxy configuration checkout the [documentation](https://httpd.apache.org/docs/current/mod/mod_proxy.html) - especially the [Securing your Server](https://httpd.apache.org/docs/current/mod/mod_proxy.html#access) section ### Help - Use `code-server -h` or `code-server --help` to view the usage for the cli. This is also shown at the beginning of this section. + Use `code-server --help` to view the usage for the CLI. This is also shown at the beginning of this section. diff --git a/packages/server/package.json b/packages/server/package.json index 3f6062c0384f..88e71d9d021f 100644 --- a/packages/server/package.json +++ b/packages/server/package.json @@ -9,7 +9,7 @@ "build:binary": "ts-node scripts/nbin.ts" }, "dependencies": { - "@coder/nbin": "^1.1.1", + "@coder/nbin": "^1.1.2", "commander": "^2.19.0", "express": "^4.16.4", "express-static-gzip": "^1.1.3", diff --git a/packages/server/src/cli.ts b/packages/server/src/cli.ts index 6544a1e6c098..15b8be456c84 100644 --- a/packages/server/src/cli.ts +++ b/packages/server/src/cli.ts @@ -29,6 +29,7 @@ commander.version(process.env.VERSION || "development") .option("-N, --no-auth", "Start without requiring authentication.", undefined) .option("-H, --allow-http", "Allow http connections.", false) .option("-P, --password ", "Specify a password for authentication.") + .option("--disable-telemetry", "Disables ALL telemetry.", false) .option("--install-extension ", "Install an extension by its ID.") .option("--bootstrap-fork ", "Used for development. Never set.") .option("--extra-args ", "Used for development. Never set.") @@ -52,6 +53,7 @@ const bold = (text: string | number): string | number => { readonly allowHttp: boolean; readonly host: string; readonly port: number; + readonly disableTelemetry: boolean; readonly userDataDir?: string; readonly extensionsDir?: string; @@ -68,6 +70,10 @@ const bold = (text: string | number): string | number => { readonly extraArgs?: string; }; + if (options.disableTelemetry) { + process.env.DISABLE_TELEMETRY = "true"; + } + // Commander has an exception for `--no` prefixes. Here we'll adjust that. // tslint:disable-next-line:no-any const noAuthValue = (commander as any).auth; diff --git a/packages/server/src/vscode/sharedProcess.ts b/packages/server/src/vscode/sharedProcess.ts index cba3519e3957..675b8b53f323 100644 --- a/packages/server/src/vscode/sharedProcess.ts +++ b/packages/server/src/vscode/sharedProcess.ts @@ -92,6 +92,7 @@ export class SharedProcess { env: { VSCODE_ALLOW_IO: "true", VSCODE_LOGS: process.env.VSCODE_LOGS, + DISABLE_TELEMETRY: process.env.DISABLE_TELEMETRY, }, }, this.userDataDir); this.activeProcess = activeProcess; diff --git a/packages/server/yarn.lock b/packages/server/yarn.lock index 025be5927679..b97e1daaed03 100644 --- a/packages/server/yarn.lock +++ b/packages/server/yarn.lock @@ -7,10 +7,10 @@ resolved "https://registry.yarnpkg.com/@coder/logger/-/logger-1.0.3.tgz#e0e1ae5496fde5a3c6ef3d748fdfb26a55add8b8" integrity sha512-1o5qDZX2VZUNnzgz5KfAdMnaqaX6FNeTs0dUdg73MRHfQW94tFTIryFC1xTTCuzxGDjVHOHkaUAI4uHA2bheOA== -"@coder/nbin@^1.1.1": - version "1.1.1" - resolved "https://registry.yarnpkg.com/@coder/nbin/-/nbin-1.1.1.tgz#0690928fb1306ee2a84120c8ae8ba221c338b190" - integrity sha512-SDlW0dNw6N5Ge3XlI6nbQV7G7dvTYqxzhN0douJlD56upaU4C130g0FCrhLPU/H4gT3SdZVfWoWc4AGv2fhZZw== +"@coder/nbin@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@coder/nbin/-/nbin-1.1.2.tgz#3af9e4368f37532da446c7c291d476bb52de995d" + integrity sha512-MkwKpmu1SU9wkBwQ+bZVU2nPzENWUa3Isut9osVq3LG+udovsk+k5c5rjfJ1q8cf4km5snjOSYiulug3n9sdgw== dependencies: "@coder/logger" "^1.0.3" fs-extra "^7.0.1" diff --git a/packages/vscode/src/fill/applicationInsights.ts b/packages/vscode/src/fill/applicationInsights.ts new file mode 100644 index 000000000000..bb94c7378079 --- /dev/null +++ b/packages/vscode/src/fill/applicationInsights.ts @@ -0,0 +1,170 @@ +/** + * Used by node + */ +import * as https from "https"; +import * as os from "os"; + +export const defaultClient = "filler"; + +export class TelemetryClient { + public channel = { + setUseDiskRetryCaching: (): void => undefined, + }; + + public constructor() { + // + } + + public trackEvent(options: { + name: string; + properties: object; + measurements: object; + }): void { + if (!options.properties) { + options.properties = {}; + } + if (!options.measurements) { + options.measurements = {}; + } + + try { + const cpus = os.cpus(); + // tslint:disable-next-line:no-any + (options.measurements as any).cpu = { + model: cpus[0].model, + cores: cpus.length, + }; + } catch (ex) { + // Nothin + } + + try { + // tslint:disable-next-line:no-any + (options.measurements as any).memory = { + virtual_free: os.freemem(), + virtual_used: os.totalmem(), + }; + } catch (ex) { + // + } + + try { + // tslint:disable:no-any + (options.properties as any)["common.shell"] = os.userInfo().shell; + (options.properties as any)["common.release"] = os.release(); + (options.properties as any)["common.arch"] = os.arch(); + // tslint:enable:no-any + } catch (ex) { + // + } + + try { + // tslint:disable-next-line:no-any + (options.properties as any)["common.machineId"] = machineIdSync(); + } catch (ex) { + // + } + + try { + const request = https.request({ + host: "v1.telemetry.coder.com", + port: 443, + path: "/track", + method: "POST", + headers: { + "Content-Type": "application/json", + }, + }); + request.on("error", () => { + // Do nothing, we don"t really care + }); + request.write(JSON.stringify(options)); + request.end(); + } catch (ex) { + // Suppress all errs + } + } + + public flush(options: { + readonly callback: () => void; + }): void { + options.callback(); + } +} + +// Taken from https://github.com/automation-stack/node-machine-id +import { exec, execSync } from "child_process"; +import { createHash } from "crypto"; + +const isWindowsProcessMixedOrNativeArchitecture = (): "" | "mixed" | "native" => { + // detect if the node binary is the same arch as the Windows OS. + // or if this is 32 bit node on 64 bit windows. + if (process.platform !== "win32") { + return ""; + } + if (process.arch === "ia32" && process.env.hasOwnProperty("PROCESSOR_ARCHITEW6432")) { + return "mixed"; + } + + return "native"; +}; + +let { platform } = process, + win32RegBinPath = { + native: "%windir%\\System32", + mixed: "%windir%\\sysnative\\cmd.exe /c %windir%\\System32", + "": "", + }, + guid = { + darwin: "ioreg -rd1 -c IOPlatformExpertDevice", + win32: `${win32RegBinPath[isWindowsProcessMixedOrNativeArchitecture()]}\\REG ` + + "QUERY HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Cryptography " + + "/v MachineGuid", + linux: "( cat /var/lib/dbus/machine-id /etc/machine-id 2> /dev/null || hostname ) | head -n 1 || :", + freebsd: "kenv -q smbios.system.uuid || sysctl -n kern.hostuuid", + // tslint:disable-next-line:no-any + } as any; + +const hash = (guid: string): string => { + return createHash("sha256").update(guid).digest("hex"); +}; + +const expose = (result: string): string => { + switch (platform) { + case "darwin": + return result + .split("IOPlatformUUID")[1] + .split("\n")[0].replace(/\=|\s+|\"/ig, "") + .toLowerCase(); + case "win32": + return result + .toString() + .split("REG_SZ")[1] + .replace(/\r+|\n+|\s+/ig, "") + .toLowerCase(); + case "linux": + return result + .toString() + .replace(/\r+|\n+|\s+/ig, "") + .toLowerCase(); + case "freebsd": + return result + .toString() + .replace(/\r+|\n+|\s+/ig, "") + .toLowerCase(); + default: + throw new Error(`Unsupported platform: ${process.platform}`); + } +}; + +let cachedMachineId: string | undefined; + +const machineIdSync = (): string => { + if (cachedMachineId) { + return cachedMachineId; + } + let id: string = expose(execSync(guid[platform]).toString()); + cachedMachineId = hash(id); + + return cachedMachineId; +}; diff --git a/packages/vscode/src/fill/product.ts b/packages/vscode/src/fill/product.ts index 1fa3c66d5301..0350b917f8d3 100644 --- a/packages/vscode/src/fill/product.ts +++ b/packages/vscode/src/fill/product.ts @@ -12,6 +12,12 @@ class Product implements IProductConfiguration { public tipsAndTricksUrl = "https://code.visualstudio.com/docs/getstarted/tips-and-tricks"; public twitterUrl = "https://twitter.com/code"; public licenseUrl = "https://github.com/codercom/code-server/blob/master/LICENSE"; + public aiConfig = process.env.DISABLE_TELEMETRY ? undefined! : { + // Only needed so vscode can see that content exists for this value. + // We override the application insights module. + asimovKey: "content", + }; + public enableTelemetry = process.env.DISABLE_TELEMETRY ? false : true; private _dataFolderName: string | undefined; public get dataFolderName(): string { @@ -26,7 +32,8 @@ class Product implements IProductConfiguration { serviceUrl: global && global.process && global.process.env.SERVICE_URL || process.env.SERVICE_URL || "https://v1.extapi.coder.com", - }; + // tslint:disable-next-line:no-any + } as any; public extensionExecutionEnvironments = { "wayou.vscode-todo-highlight": "worker", diff --git a/packages/vscode/webpack.bootstrap.config.js b/packages/vscode/webpack.bootstrap.config.js index 91a5ade635a8..abcffe520def 100644 --- a/packages/vscode/webpack.bootstrap.config.js +++ b/packages/vscode/webpack.bootstrap.config.js @@ -55,6 +55,7 @@ module.exports = merge( "vscode-sqlite3": path.resolve(fills, "empty.ts"), "vs/base/browser/browser": path.resolve(fills, "empty.ts"), + "applicationinsights": path.join(vsFills, "applicationInsights.ts"), "electron": path.join(vsFills, "stdioElectron.ts"), "vscode-ripgrep": path.join(vsFills, "ripgrep.ts"), "native-keymap": path.join(vsFills, "native-keymap.ts"), pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy