Skip to content

Commit 93a0c72

Browse files
author
Ayane Satomi
committed
Merge branch 'master' of github.com:cdr/code-server
2 parents d27617c + 846dcbb commit 93a0c72

8 files changed

Lines changed: 112 additions & 50 deletions

File tree

README.md

Lines changed: 38 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
remote server, accessible through the browser.
55

66
Try it out:
7+
78
```bash
89
docker run -it -p 127.0.0.1:8080:8080 -v "${HOME}/.local/share/code-server:/home/coder/.local/share/code-server" -v "$PWD:/home/coder/project" codercom/code-server:v2
910
```
@@ -18,10 +19,21 @@ docker run -it -p 127.0.0.1:8080:8080 -v "${HOME}/.local/share/code-server:/home
1819
![Screenshot](/doc/assets/ide.gif)
1920

2021
## Getting Started
22+
23+
### Requirements
24+
25+
- Minimum GLIBC version of 2.17 and a minimum version of GLIBCXX of 3.4.15.
26+
- This is the main requirement for building Visual Studio Code. We cannot go lower than this.
27+
- A 64-bit host with at least 1GB RAM and 2 cores.
28+
- 1 core hosts would work but not optimally.
29+
- Docker (for Docker versions of `code-server`).
30+
2131
### Run over SSH
32+
2233
Use [sshcode](https://github.com/codercom/sshcode) for a simple setup.
2334

2435
### Docker
36+
2537
See the Docker one-liner mentioned above. Dockerfile is at [/Dockerfile](/Dockerfile).
2638

2739
To debug Golang using the
@@ -31,18 +43,21 @@ arguments when launching code-server with Docker. See
3143
[#725](https://github.com/cdr/code-server/issues/725) for details.
3244

3345
### Digital Ocean
46+
3447
[![Create a Droplet](./doc/assets/droplet.svg)](https://marketplace.digitalocean.com/apps/code-server?action=deploy)
3548

3649
### Binaries
50+
3751
1. [Download a binary](https://github.com/cdr/code-server/releases). (Linux and
38-
OS X supported. Windows coming soon)
52+
OS X supported. Windows coming soon)
3953
2. Unpack the downloaded file then run the binary.
4054
3. In your browser navigate to `localhost:8080`.
4155

4256
- For self-hosting and other information see [doc/quickstart.md](doc/quickstart.md).
4357
- For hosting on cloud platforms see [doc/deploy.md](doc/deploy.md).
4458

4559
### Build
60+
4661
- If you also plan on developing, set the `OUT` environment variable. Otherwise
4762
it will build in this directory which will cause issues because `yarn watch`
4863
will try to compile the build directory as well.
@@ -56,29 +71,41 @@ arguments when launching code-server with Docker. See
5671
code into a single binary.
5772

5873
## Known Issues
74+
5975
- Creating custom VS Code extensions and debugging them doesn't work.
6076
- Extension profiling and tips are currently disabled.
6177

6278
## Future
79+
6380
- **Stay up to date!** Get notified about new releases of code-server.
6481
![Screenshot](/doc/assets/release.gif)
6582
- Windows support.
6683
- Electron and Chrome OS applications to bridge the gap between local<->remote.
6784
- Run VS Code unit tests against our builds to ensure features work as expected.
6885

6986
## Extensions
70-
At the moment we can't use the official VS Code Marketplace. We've created a
71-
custom extension marketplace focused around open-sourced extensions. However,
72-
you can manually download the extension to your extensions directory. It's also
73-
possible to set your own marketplace URLs by setting the `SERVICE_URL` and
74-
`ITEM_URL` environment variables.
87+
88+
code-server does not provide access to the official
89+
[Visual Studio Marketplace](https://marketplace.visualstudio.com/vscode). Instead,
90+
Coder has created a custom extension marketplace that we manage for open-source
91+
extensions. If you want to use an extension with code-server that we do not have
92+
in our marketplace please look for a release in the extension’s repository,
93+
contact us to see if we have one in the works or, if you build an extension
94+
locally from open source, you can copy it to the `extensions` folder. If you
95+
build one locally from open-source please contribute it to the project and let
96+
us know so we can give you props! If you have your own custom marketplace, it is
97+
possible to point code-server to it by setting the `SERVICE_URL` and `ITEM_URL`
98+
environment variables.
7599

76100
## Telemetry
101+
77102
Use the `--disable-telemetry` flag to completely disable telemetry. We use the
78103
data collected to improve code-server.
79104

80105
## Contributing
106+
81107
### Development
108+
82109
```shell
83110
git clone https://github.com/microsoft/vscode
84111
cd vscode
@@ -99,6 +126,7 @@ If you run into issues about a different version of Node being used, try running
99126
`vscode-ripgrep`.
100127

101128
### Upgrading VS Code
129+
102130
We patch VS Code to provide and fix some functionality. As the web portion of VS
103131
Code matures, we'll be able to shrink and maybe even entirely eliminate our
104132
patch. In the meantime, however, upgrading the VS Code version requires ensuring
@@ -109,6 +137,7 @@ the patch in the VS Code source, then run `yarn patch:generate` in this
109137
directory.
110138

111139
Our changes include:
140+
112141
- Change the remote schema to `code-server`.
113142
- Allow multiple extension directories (both user and built-in).
114143
- Modify the loader, websocket, webview, service worker, and asset requests to
@@ -123,12 +152,15 @@ Our changes include:
123152
- Modify the build process to include our code.
124153

125154
## License
155+
126156
[MIT](LICENSE)
127157

128158
## Enterprise
159+
129160
Visit [our enterprise page](https://coder.com/enterprise) for more information
130161
about our enterprise offering.
131162

132163
## Commercialization
164+
133165
If you would like to commercialize code-server, please contact
134166
contact@coder.com.

doc/examples/kubernetes.aws.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ spec:
5858
app: code-server
5959
spec:
6060
containers:
61-
- image: codercom/code-server
61+
- image: codercom/code-server:v2
6262
imagePullPolicy: Always
6363
name: code-servery
6464
ports:

doc/examples/kubernetes.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ spec:
3535
app: code-server
3636
spec:
3737
containers:
38-
- image: codercom/code-server
38+
- image: codercom/code-server:v2
3939
imagePullPolicy: Always
4040
name: code-server
4141
ports:

scripts/vscode.patch

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,19 @@ index 07759dffe5..9148d7c1f0 100644
132132
} else if (typeof process === 'object') {
133133
_isWindows = (process.platform === 'win32');
134134
_isMacintosh = (process.platform === 'darwin');
135+
diff --git a/src/vs/base/node/languagePacks.js b/src/vs/base/node/languagePacks.js
136+
index 3ae24454cb..d637d02855 100644
137+
--- a/src/vs/base/node/languagePacks.js
138+
+++ b/src/vs/base/node/languagePacks.js
139+
@@ -146,7 +146,7 @@ function factory(nodeRequire, path, fs, perf) {
140+
function getLanguagePackConfigurations(userDataPath) {
141+
const configFile = path.join(userDataPath, 'languagepacks.json');
142+
try {
143+
- return nodeRequire(configFile);
144+
+ return JSON.parse(fs.readFileSync(configFile, "utf8"));
145+
} catch (err) {
146+
// Do nothing. If we can't read the file we have no
147+
// language pack config.
135148
diff --git a/src/vs/code/browser/workbench/workbench.html b/src/vs/code/browser/workbench/workbench.html
136149
index 44f67f0a0b..00fc1deea8 100644
137150
--- a/src/vs/code/browser/workbench/workbench.html

src/cli.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ const startVscode = async (): Promise<void | void[]> => {
120120

121121
const server = new MainServer({
122122
...options,
123-
port: typeof args.port !== "undefined" && parseInt(args.port, 10) || 8080,
123+
port: typeof args.port !== "undefined" ? parseInt(args.port, 10) : 8080,
124124
socket: args.socket,
125125
}, args);
126126

@@ -151,7 +151,7 @@ const startVscode = async (): Promise<void | void[]> => {
151151

152152
if (!server.options.socket && args.open) {
153153
// The web socket doesn't seem to work if browsing with 0.0.0.0.
154-
const openAddress = `http://localhost:${server.options.port}`;
154+
const openAddress = serverAddress.replace(/:\/\/0.0.0.0/, "://localhost");
155155
await open(openAddress).catch(console.error);
156156
logger.info(` - Opened ${openAddress}`);
157157
}

src/connection.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@ export class ExtensionHostConnection extends Connection {
123123
VSCODE_EXTHOST_WILL_SEND_SOCKET: "true",
124124
VSCODE_HANDLES_UNCAUGHT_ERRORS: "true",
125125
VSCODE_LOG_STACK: "false",
126+
VSCODE_LOG_LEVEL: this.environment.verbose ? "trace" : this.environment.log,
126127
VSCODE_NLS_CONFIG: JSON.stringify(config),
127128
},
128129
silent: true,

src/marketplace.ts

Lines changed: 27 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -79,52 +79,55 @@ export const buffer = (targetPath: string, filePath: string): Promise<Buffer> =>
7979
};
8080

8181
const extractAssets = async (tarPath: string, match: RegExp, callback: (path: string, data: Buffer) => void): Promise<void> => {
82-
const buffer = await util.promisify(fs.readFile)(tarPath);
83-
return new Promise<void>(async (resolve, reject): Promise<void> => {
82+
return new Promise<void>((resolve, reject): void => {
8483
const extractor = tarStream.extract();
85-
extractor.once("error", reject);
84+
const fail = (error: Error) => {
85+
extractor.destroy();
86+
reject(error);
87+
};
88+
extractor.once("error", fail);
8689
extractor.on("entry", async (header, stream, next) => {
8790
const name = header.name;
8891
if (match.test(name)) {
8992
extractData(stream).then((data) => {
9093
callback(name, data);
9194
next();
92-
}).catch(reject);
93-
stream.resume();
95+
}).catch(fail);
9496
} else {
9597
stream.on("end", () => next());
96-
stream.resume();
98+
stream.resume(); // Just drain it.
9799
}
98100
});
99101
extractor.on("finish", resolve);
100-
extractor.write(buffer);
101-
extractor.end();
102+
fs.createReadStream(tarPath).pipe(extractor);
102103
});
103104
};
104105

105106
const extractData = (stream: NodeJS.ReadableStream): Promise<Buffer> => {
106107
return new Promise((resolve, reject): void => {
107108
const fileData: Buffer[] = [];
108-
stream.on("data", (data) => fileData.push(data));
109-
stream.on("end", () => resolve(Buffer.concat(fileData)));
110109
stream.on("error", reject);
110+
stream.on("end", () => resolve(Buffer.concat(fileData)));
111+
stream.on("data", (data) => fileData.push(data));
111112
});
112113
};
113114

114115
const extractTar = async (tarPath: string, targetPath: string, options: IExtractOptions = {}, token: CancellationToken): Promise<void> => {
115-
const buffer = await util.promisify(fs.readFile)(tarPath);
116-
return new Promise<void>(async (resolve, reject): Promise<void> => {
116+
return new Promise<void>((resolve, reject): void => {
117117
const sourcePathRegex = new RegExp(options.sourcePath ? `^${options.sourcePath}` : "");
118118
const extractor = tarStream.extract();
119-
extractor.once("error", reject);
119+
const fail = (error: Error) => {
120+
extractor.destroy();
121+
reject(error);
122+
};
123+
extractor.once("error", fail);
120124
extractor.on("entry", async (header, stream, next) => {
121-
const rawName = path.normalize(header.name);
122-
123125
const nextEntry = (): void => {
126+
stream.on("end", () => next());
124127
stream.resume();
125-
next();
126128
};
127129

130+
const rawName = path.normalize(header.name);
128131
if (token.isCancellationRequested || !sourcePathRegex.test(rawName)) {
129132
return nextEntry();
130133
}
@@ -138,20 +141,18 @@ const extractTar = async (tarPath: string, targetPath: string, options: IExtract
138141
const dirName = path.dirname(fileName);
139142
const targetDirName = path.join(targetPath, dirName);
140143
if (targetDirName.indexOf(targetPath) !== 0) {
141-
return reject(nls.localize("invalid file", "Error extracting {0}. Invalid file.", fileName));
144+
return fail(new Error(nls.localize("invalid file", "Error extracting {0}. Invalid file.", fileName)));
142145
}
143146

144-
return mkdirp(targetDirName, undefined, token).then(() => {
145-
const fstream = fs.createWriteStream(targetFileName, { mode: header.mode });
146-
fstream.once("close", () => next());
147-
fstream.once("error", reject);
148-
stream.pipe(fstream);
149-
stream.resume();
150-
});
147+
await mkdirp(targetDirName, undefined, token);
148+
149+
const fstream = fs.createWriteStream(targetFileName, { mode: header.mode });
150+
fstream.once("close", () => next());
151+
fstream.once("error", fail);
152+
stream.pipe(fstream);
151153
});
152154
extractor.once("finish", resolve);
153-
extractor.write(buffer);
154-
extractor.end();
155+
fs.createReadStream(tarPath).pipe(extractor);
155156
});
156157
};
157158

src/server.ts

Lines changed: 29 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -531,30 +531,45 @@ export class MainServer extends Server {
531531
util.promisify(fs.readFile)(filePath, "utf8"),
532532
this.servicesPromise,
533533
]);
534+
534535
const logger = this.services.get(ILogService) as ILogService;
535536
logger.info("request.url", `"${request.url}"`);
536-
const environment = this.services.get(IEnvironmentService) as IEnvironmentService;
537-
const locale = environment.args.locale || await getLocaleFromConfig(environment.userDataPath);
537+
538538
const cwd = process.env.VSCODE_CWD || process.cwd();
539-
const workspacePath = parsedUrl.query.workspace as string | undefined;
540-
const folderPath = !workspacePath ? parsedUrl.query.folder as string | undefined || this.options.folderUri : undefined;
539+
541540
const remoteAuthority = request.headers.host as string;
542541
const transformer = getUriTransformer(remoteAuthority);
542+
const validatePath = async (filePath: string[] | string | undefined, isDirectory: boolean, unsetFallback?: string): Promise<UriComponents | undefined> => {
543+
if (!filePath || filePath.length === 0) {
544+
if (!unsetFallback) {
545+
return undefined;
546+
}
547+
filePath = unsetFallback;
548+
} else if (Array.isArray(filePath)) {
549+
filePath = filePath[0];
550+
}
551+
const uri = URI.file(sanitizeFilePath(filePath, cwd));
552+
try {
553+
const stat = await util.promisify(fs.stat)(uri.fsPath);
554+
if (isDirectory !== stat.isDirectory()) {
555+
return undefined;
556+
}
557+
} catch (error) {
558+
return undefined;
559+
}
560+
return transformer.transformOutgoing(uri);
561+
};
562+
563+
const environment = this.services.get(IEnvironmentService) as IEnvironmentService;
543564
const options: Options = {
544565
WORKBENCH_WEB_CONGIGURATION: {
545-
workspaceUri: workspacePath
546-
? transformer.transformOutgoing(URI.file(sanitizeFilePath(workspacePath, cwd)))
547-
: undefined,
548-
folderUri: folderPath
549-
? transformer.transformOutgoing(URI.file(sanitizeFilePath(folderPath, cwd)))
550-
: undefined,
566+
workspaceUri: await validatePath(parsedUrl.query.workspace, false),
567+
folderUri: !parsedUrl.query.workspace ? await validatePath(parsedUrl.query.folder, true, this.options.folderUri) : undefined,
551568
remoteAuthority,
552569
productConfiguration: product,
553570
},
554-
REMOTE_USER_DATA_URI: transformer.transformOutgoing(
555-
(this.services.get(IEnvironmentService) as EnvironmentService).webUserDataHome,
556-
),
557-
NLS_CONFIGURATION: await getNlsConfiguration(locale, environment.userDataPath),
571+
REMOTE_USER_DATA_URI: transformer.transformOutgoing((<EnvironmentService>environment).webUserDataHome),
572+
NLS_CONFIGURATION: await getNlsConfiguration(environment.args.locale || await getLocaleFromConfig(environment.userDataPath), environment.userDataPath),
558573
};
559574

560575
content = content.replace(/\/static\//g, `/static${product.commit ? `-${product.commit}` : ""}/`).replace("{{WEBVIEW_ENDPOINT}}", "");

0 commit comments

Comments
 (0)