Compare commits

..

8 Commits

Author SHA1 Message Date
Asher
ac1fba8bde Remove deprecated --link (#6018) 2023-02-13 16:52:48 -06:00
Blue
6d8ed77fb0 feat(helm-chart): Add support for extraSecretMounts subPath in helm-chart (#5961) 2023-02-13 13:01:32 -06:00
Samuel Walker
4fb87f920f feature: add ability to attach ports to code server (#6015) 2023-02-13 12:56:05 -06:00
Asher
36daac3031 Update to 1.75.1 2023-02-13 07:45:24 -09:00
Asher
45aef719d3 Make sure heartbeat isActive resolves
This does not seem to actually cause an issue (not resolving ends up
with the same behavior as resolving with false) but I am not sure if the
hanging promises would be a memory leak so seems best to fix.
2023-02-08 11:43:40 -09:00
Asher
6d6c5e18d1 Fix watch script ignoring stdout
This was lost due to the change from fork to spawn.
2023-02-08 11:42:28 -09:00
Asher
17bca521af Update changelog 2023-02-07 13:57:53 -09:00
Asher
82073743b1 Update release guide 2023-02-07 13:57:52 -09:00
20 changed files with 78 additions and 190 deletions

View File

@@ -20,6 +20,18 @@ Code v99.99.999
--> -->
## [4.10.0](https://github.com/coder/code-server/releases/tag/v4.10.0) - TBD
Code v1.75.1
### Changed
- Updated to Code 1.75.1
### Removed
- Removed `--link` (was deprecated in 4.0.1).
## [4.9.1](https://github.com/coder/code-server/releases/tag/v4.9.1) - 2022-12-15 ## [4.9.1](https://github.com/coder/code-server/releases/tag/v4.9.1) - 2022-12-15
Code v1.73.1 Code v1.73.1

View File

@@ -14,22 +14,6 @@ main() {
sed -i.bak "1s;^;#!/usr/bin/env node\n;" out/node/entry.js && rm out/node/entry.js.bak sed -i.bak "1s;^;#!/usr/bin/env node\n;" out/node/entry.js && rm out/node/entry.js.bak
chmod +x out/node/entry.js chmod +x out/node/entry.js
fi fi
# for arch; we do not use OS from lib.sh and get our own.
# lib.sh normalizes macos to darwin - but cloud-agent's binaries do not
source ./ci/lib.sh
OS="$(uname | tr '[:upper:]' '[:lower:]')"
mkdir -p ./lib
if ! [ -f ./lib/coder-cloud-agent ]; then
echo "Downloading the cloud agent..."
set +e
curl -fsSL "https://github.com/coder/cloud-agent/releases/latest/download/cloud-agent-$OS-$ARCH" -o ./lib/coder-cloud-agent
chmod +x ./lib/coder-cloud-agent
set -e
fi
} }
main "$@" main "$@"

View File

@@ -63,8 +63,6 @@ EOF
if [ "$KEEP_MODULES" = 1 ]; then if [ "$KEEP_MODULES" = 1 ]; then
rsync node_modules/ "$RELEASE_PATH/node_modules" rsync node_modules/ "$RELEASE_PATH/node_modules"
mkdir -p "$RELEASE_PATH/lib"
rsync ./lib/coder-cloud-agent "$RELEASE_PATH/lib"
fi fi
} }

View File

@@ -1,18 +1,8 @@
#!/usr/bin/env sh #!/usr/bin/env sh
set -eu set -eu
# Copied from ../lib.sh. # Copied from ../lib.sh except we do not rename Darwin and we do not need to
arch() { # detect Alpine.
cpu="$(uname -m)"
case "$cpu" in
aarch64) cpu=arm64 ;;
x86_64) cpu=amd64 ;;
esac
echo "$cpu"
}
# Copied from ../lib.sh except we do not rename Darwin since the cloud agent
# uses "darwin" in the release names and we do not need to detect Alpine.
os() { os() {
osname=$(uname | tr '[:upper:]' '[:lower:]') osname=$(uname | tr '[:upper:]' '[:lower:]')
case $osname in case $osname in
@@ -61,7 +51,6 @@ symlink_bin_script() {
cd "$oldpwd" cd "$oldpwd"
} }
ARCH="${NPM_CONFIG_ARCH:-$(arch)}"
OS="$(os)" OS="$(os)"
# This is due to an upstream issue with RHEL7/CentOS 7 comptability with node-argon2 # This is due to an upstream issue with RHEL7/CentOS 7 comptability with node-argon2
@@ -102,14 +91,6 @@ main() {
;; ;;
esac esac
mkdir -p ./lib
if curl -fsSL "https://github.com/coder/cloud-agent/releases/latest/download/cloud-agent-$OS-$ARCH" -o ./lib/coder-cloud-agent; then
chmod +x ./lib/coder-cloud-agent
else
echo "Failed to download cloud agent; --link will not work"
fi
if ! vscode_install; then if ! vscode_install; then
echo "You may not have the required dependencies to build the native modules." echo "You may not have the required dependencies to build the native modules."
echo "Please see https://github.com/coder/code-server/blob/main/docs/npm.md" echo "Please see https://github.com/coder/code-server/blob/main/docs/npm.md"

View File

@@ -31,11 +31,12 @@ class Watcher {
// Pass CLI args, save for `node` and the initial script name. // Pass CLI args, save for `node` and the initial script name.
const args = process.argv.slice(2) const args = process.argv.slice(2)
this.webServer = spawn("node", [path.join(this.rootPath, "out/node/entry.js"), ...args]) this.webServer = spawn("node", [path.join(this.rootPath, "out/node/entry.js"), ...args])
onLine(this.webServer, (line) => console.log("[code-server]", line))
const { pid } = this.webServer const { pid } = this.webServer
this.webServer.on("exit", () => console.log("[Code Server]", `Web process ${pid} exited`)) this.webServer.on("exit", () => console.log("[code-server]", `Web process ${pid} exited`))
console.log("\n[Code Server]", `Spawned web server process ${pid}`) console.log("\n[code-server]", `Spawned web server process ${pid}`)
} }
//#endregion //#endregion
@@ -82,10 +83,10 @@ class Watcher {
private parseVSCodeLine: OnLineCallback = (strippedLine, originalLine) => { private parseVSCodeLine: OnLineCallback = (strippedLine, originalLine) => {
if (!strippedLine.length) return if (!strippedLine.length) return
console.log("[VS Code]", originalLine) console.log("[Code OSS]", originalLine)
if (strippedLine.includes("Finished compilation with")) { if (strippedLine.includes("Finished compilation with")) {
console.log("[VS Code] ✨ Finished compiling! ✨", "(Refresh your web browser ♻️)") console.log("[Code OSS] ✨ Finished compiling! ✨", "(Refresh your web browser ♻️)")
this.reloadWebServer() this.reloadWebServer()
} }
} }
@@ -93,10 +94,10 @@ class Watcher {
private parseCodeServerLine: OnLineCallback = (strippedLine, originalLine) => { private parseCodeServerLine: OnLineCallback = (strippedLine, originalLine) => {
if (!strippedLine.length) return if (!strippedLine.length) return
console.log("[Compiler][Code Server]", originalLine) console.log("[Compiler][code-server]", originalLine)
if (strippedLine.includes("Watching for file changes")) { if (strippedLine.includes("Watching for file changes")) {
console.log("[Compiler][Code Server]", "Finished compiling!", "(Refresh your web browser ♻️)") console.log("[Compiler][code-server]", "Finished compiling!", "(Refresh your web browser ♻️)")
this.reloadWebServer() this.reloadWebServer()
} }
} }

View File

@@ -15,7 +15,7 @@ type: application
# This is the chart version. This version number should be incremented each time you make changes # This is the chart version. This version number should be incremented each time you make changes
# to the chart and its templates, including the app version. # to the chart and its templates, including the app version.
# Versions are expected to follow Semantic Versioning (https://semver.org/) # Versions are expected to follow Semantic Versioning (https://semver.org/)
version: 3.4.1 version: 3.5.1
# This is the version number of the application being deployed. This version number should be # This is the version number of the application being deployed. This version number should be
# incremented each time you make changes to the application. Versions are not expected to # incremented each time you make changes to the application. Versions are not expected to

View File

@@ -102,6 +102,7 @@ spec:
{{- range .Values.extraSecretMounts }} {{- range .Values.extraSecretMounts }}
- name: {{ .name }} - name: {{ .name }}
mountPath: {{ .mountPath }} mountPath: {{ .mountPath }}
subPath: {{ .subPath | default "" }}
readOnly: {{ .readOnly }} readOnly: {{ .readOnly }}
{{- end }} {{- end }}
{{- range .Values.extraVolumeMounts }} {{- range .Values.extraVolumeMounts }}
@@ -114,6 +115,11 @@ spec:
- name: http - name: http
containerPort: 8080 containerPort: 8080
protocol: TCP protocol: TCP
{{- range .Values.extraPorts }}
- name: {{ .name }}
containerPort: {{ .port }}
protocol: {{ .protocol }}
{{- end }}
livenessProbe: livenessProbe:
httpGet: httpGet:
path: / path: /

View File

@@ -14,6 +14,12 @@ spec:
targetPort: http targetPort: http
protocol: TCP protocol: TCP
name: http name: http
{{- range .Values.extraPorts }}
- port: {{ .port }}
targetPort: {{ .port }}
protocol: {{ .protocol }}
name: {{ .name }}
{{- end }}
selector: selector:
app.kubernetes.io/name: {{ include "code-server.name" . }} app.kubernetes.io/name: {{ include "code-server.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }} app.kubernetes.io/instance: {{ .Release.Name }}

View File

@@ -179,6 +179,7 @@ extraInitContainers: |
extraSecretMounts: [] extraSecretMounts: []
# - name: secret-files # - name: secret-files
# mountPath: /etc/secrets # mountPath: /etc/secrets
# subPath: private.key # (optional)
# secretName: code-server-secret-files # secretName: code-server-secret-files
# readOnly: true # readOnly: true
@@ -196,3 +197,8 @@ extraConfigmapMounts: []
# subPath: certificates.crt # (optional) # subPath: certificates.crt # (optional)
# configMap: certs-configmap # configMap: certs-configmap
# readOnly: true # readOnly: true
extraPorts: []
# - name: minecraft
# port: 25565
# protocol: tcp

View File

@@ -142,24 +142,28 @@ changelog](https://github.com/emacs-mirror/emacs/blob/master/etc/NEWS).
### Publishing a release ### Publishing a release
1. Go to GitHub Actions > Draft release > Run workflow off commit you want to 1. Go to GitHub Actions > Draft release > Run workflow on the commit you want to
release. CI will automatically upload the artifacts to the release. Make sure CI release. Make sure CI has finished the build workflow on that commit or this
has finished on that commit. will fail.
1. CI will automatically grab the 2. CI will automatically grab the build artifact on that commit, inject the
artifacts, publish the NPM package from `npm-package`, and publish the Docker version into the `package.json`, put together platform-specific packages, and
Hub image from `release-images`. upload those packages to a draft release.
1. Publish release. 3. Summarize the major changes in the `CHANGELOG.md`.
1. After, create a new branch called `release/v0.0.0` (replace 0s with actual version aka v4.5.0) 4. Copy the relevant changelog section to the release then publish it.
1. Summarize the major changes in the `CHANGELOG.md` 5. CI will automatically publish the NPM package, Docker image, and update
1. Bump chart version in `Chart.yaml`. Homebrew using the published release assets.
6. Bump the chart version in `Chart.yaml` and merge in the changelog updates.
#### Release Candidates #### Release Candidates
We prefer to do release candidates so the community can test things before a full-blown release. To do this follow the same steps as above but: We prefer to do release candidates so the community can test things before a
full-blown release. To do this follow the same steps as above but:
1. Only bump version in `package.json` 1. Add a `-rc.<number>` suffix to the version.
1. use `0.0.0-rc.0` 2. When you publish the release select "pre-release". CI will not automatically
1. When you publish the release, select "pre-release" publish pre-releases.
3. Do not update the chart version or merge in the changelog until the final
release.
#### AUR #### AUR

View File

@@ -297,9 +297,9 @@ You can install code-server using the [Helm package manager](https://coder.com/d
## Windows ## Windows
We currently [do not publish Windows releases](https://github.com/coder/code-server/issues/1397). We recommend installing code-server onto Windows with [`npm`](#npm). We currently [do not publish Windows
releases](https://github.com/coder/code-server/issues/1397). We recommend
> Note: You will also need to [build coder/cloud-agent manually](https://github.com/coder/cloud-agent/issues/17) if you would like to use `code-server --link` on Windows. installing code-server onto Windows with [`npm`](#npm).
## Raspberry Pi ## Raspberry Pi

View File

@@ -1,11 +0,0 @@
# code-server --link
> Note: This feature is no longer recommended due to instability. Stay tuned for a revised version.
Run code-server with the flag `--link` and you'll get TLS, authentication, and a dedicated URL
for accessing your IDE out of the box.
```console
$ code-server --link
Proxying code-server, you can access your IDE at https://example.coder.co
```

View File

@@ -42,11 +42,6 @@
"description": "How to run code-server in Coder", "description": "How to run code-server in Coder",
"path": "./coder.md" "path": "./coder.md"
}, },
{
"title": "--link",
"description": "How to run code-server --link",
"path": "./link.md"
},
{ {
"title": "iPad", "title": "iPad",
"description": "How to access your code-server installation using an iPad.", "description": "How to access your code-server installation using an iPad.",

View File

@@ -101,7 +101,7 @@ Index: code-server/lib/vscode/src/vs/workbench/contrib/webview/browser/pre/index
=================================================================== ===================================================================
--- code-server.orig/lib/vscode/src/vs/workbench/contrib/webview/browser/pre/index-no-csp.html --- code-server.orig/lib/vscode/src/vs/workbench/contrib/webview/browser/pre/index-no-csp.html
+++ code-server/lib/vscode/src/vs/workbench/contrib/webview/browser/pre/index-no-csp.html +++ code-server/lib/vscode/src/vs/workbench/contrib/webview/browser/pre/index-no-csp.html
@@ -322,6 +322,12 @@ @@ -324,6 +324,12 @@
const hostname = location.hostname; const hostname = location.hostname;

View File

@@ -84,7 +84,6 @@ export interface UserProvidedArgs extends UserProvidedCodeArgs {
"reuse-window"?: boolean "reuse-window"?: boolean
"new-window"?: boolean "new-window"?: boolean
"ignore-last-opened"?: boolean "ignore-last-opened"?: boolean
link?: OptionalString
verbose?: boolean verbose?: boolean
"app-name"?: string "app-name"?: string
"welcome-text"?: string "welcome-text"?: string
@@ -262,15 +261,6 @@ export const options: Options<Required<UserProvidedArgs>> = {
short: "w", short: "w",
description: "Text to show on login page", description: "Text to show on login page",
}, },
link: {
type: OptionalString,
description: `
Securely bind code-server via our cloud service with the passed name. You'll get a URL like
https://hostname-username.coder.co at which you can easily access your code-server instance.
Authorization is done via GitHub.
`,
deprecated: true,
},
} }
export const optionDescriptions = (opts: Partial<Options<Required<UserProvidedArgs>>> = options): string[] => { export const optionDescriptions = (opts: Partial<Options<Required<UserProvidedArgs>>> = options): string[] => {
@@ -547,17 +537,6 @@ export async function setDefaults(cliArgs: UserProvidedArgs, configArgs?: Config
args.host = addr.host args.host = addr.host
args.port = addr.port args.port = addr.port
// If we're being exposed to the cloud, we listen on a random address and
// disable auth.
if (args.link) {
args.host = "localhost"
args.port = 0
args.socket = undefined
args["socket-mode"] = undefined
args.cert = undefined
args.auth = AuthType.None
}
if (args.cert && !args.cert.value) { if (args.cert && !args.cert.value) {
const { cert, certKey } = await generateCertificate(args["cert-host"] || "localhost") const { cert, certKey } = await generateCertificate(args["cert-host"] || "localhost")
args.cert = { args.cert = {

View File

@@ -1,43 +0,0 @@
import { logger } from "@coder/logger"
import { spawn } from "child_process"
import path from "path"
import split2 from "split2"
// https://github.com/coder/coder-cloud
const coderCloudAgent = path.resolve(__dirname, "../../lib/coder-cloud-agent")
function runAgent(...args: string[]): Promise<void> {
logger.debug(`running agent with ${args}`)
const agent = spawn(coderCloudAgent, args, {
stdio: ["inherit", "inherit", "pipe"],
})
agent.stderr.pipe(split2()).on("data", (line) => {
line = line.replace(/^[0-9-]+ [0-9:]+ [^ ]+\t/, "")
logger.info(line)
})
return new Promise((res, rej) => {
agent.on("error", rej)
agent.on("close", (code) => {
if (code !== 0) {
rej({
message: `--link agent exited with ${code}`,
})
return
}
res()
})
})
}
export function coderCloudBind(address: URL | string, serverName = ""): Promise<void> {
if (typeof address === "string") {
throw new Error("Cannot link socket paths")
}
// Address needs to be in hostname:port format without the protocol.
return runAgent("bind", `--code-server-addr=${address.host}`, serverName)
}

View File

@@ -6,7 +6,6 @@ import { Disposable } from "../common/emitter"
import { plural } from "../common/util" import { plural } from "../common/util"
import { createApp, ensureAddress } from "./app" import { createApp, ensureAddress } from "./app"
import { AuthType, DefaultedArgs, Feature, SpawnCodeCli, toCodeArgs, UserProvidedArgs } from "./cli" import { AuthType, DefaultedArgs, Feature, SpawnCodeCli, toCodeArgs, UserProvidedArgs } from "./cli"
import { coderCloudBind } from "./coder_cloud"
import { commit, version } from "./constants" import { commit, version } from "./constants"
import { register } from "./routes" import { register } from "./routes"
import { humanPath, isDirectory, loadAMDModule, open } from "./util" import { humanPath, isDirectory, loadAMDModule, open } from "./util"
@@ -127,11 +126,7 @@ export const runCodeServer = async (
const disposeRoutes = await register(app, args) const disposeRoutes = await register(app, args)
logger.info(`Using config file ${humanPath(os.homedir(), args.config)}`) logger.info(`Using config file ${humanPath(os.homedir(), args.config)}`)
logger.info( logger.info(`${protocol.toUpperCase()} server listening on ${serverAddress.toString()}`)
`${protocol.toUpperCase()} server listening on ${serverAddress.toString()} ${
args.link ? "(randomized by --link)" : ""
}`,
)
if (args.auth === AuthType.Password) { if (args.auth === AuthType.Password) {
logger.info(" - Authentication is enabled") logger.info(" - Authentication is enabled")
@@ -143,13 +138,13 @@ export const runCodeServer = async (
logger.info(` - Using password from ${humanPath(os.homedir(), args.config)}`) logger.info(` - Using password from ${humanPath(os.homedir(), args.config)}`)
} }
} else { } else {
logger.info(` - Authentication is disabled ${args.link ? "(disabled by --link)" : ""}`) logger.info(" - Authentication is disabled")
} }
if (args.cert) { if (args.cert) {
logger.info(` - Using certificate for HTTPS: ${humanPath(os.homedir(), args.cert.value)}`) logger.info(` - Using certificate for HTTPS: ${humanPath(os.homedir(), args.cert.value)}`)
} else { } else {
logger.info(` - Not serving HTTPS ${args.link ? "(disabled by --link)" : ""}`) logger.info(" - Not serving HTTPS")
} }
if (args["proxy-domain"].length > 0) { if (args["proxy-domain"].length > 0) {
@@ -157,11 +152,6 @@ export const runCodeServer = async (
args["proxy-domain"].forEach((domain) => logger.info(` - *.${domain}`)) args["proxy-domain"].forEach((domain) => logger.info(` - *.${domain}`))
} }
if (args.link) {
await coderCloudBind(serverAddress, args.link.value)
logger.info(" - Connected to cloud agent")
}
if (args.enable && args.enable.length > 0) { if (args.enable && args.enable.length > 0) {
logger.info("Enabling the following experimental features:") logger.info("Enabling the following experimental features:")
args.enable.forEach((feature) => { args.enable.forEach((feature) => {

View File

@@ -33,7 +33,15 @@ import { CodeServerRouteWrapper } from "./vscode"
export const register = async (app: App, args: DefaultedArgs): Promise<Disposable["dispose"]> => { export const register = async (app: App, args: DefaultedArgs): Promise<Disposable["dispose"]> => {
const heart = new Heart(path.join(paths.data, "heartbeat"), async () => { const heart = new Heart(path.join(paths.data, "heartbeat"), async () => {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
// getConnections appears to not call the callback when there are no more
// connections. Feels like it must be a bug? For now add a timer to make
// sure we eventually resolve.
const timer = setTimeout(() => {
logger.debug("Node failed to respond with connections; assuming zero")
resolve(false)
}, 5000)
app.server.getConnections((error, count) => { app.server.getConnections((error, count) => {
clearTimeout(timer)
if (error) { if (error) {
return reject(error) return reject(error)
} }

View File

@@ -297,26 +297,6 @@ describe("parser", () => {
}) })
}) })
it("should override with --link", async () => {
const args = parse(
"--cert test --cert-key test --socket test --socket-mode 777 --host 0.0.0.0 --port 8888 --link test".split(" "),
)
const defaultArgs = await setDefaults(args)
expect(defaultArgs).toEqual({
...defaults,
auth: "none",
host: "localhost",
link: {
value: "test",
},
port: 0,
cert: undefined,
"cert-key": path.resolve("test"),
socket: undefined,
"socket-mode": undefined,
})
})
it("should use env var password", async () => { it("should use env var password", async () => {
process.env.PASSWORD = "test" process.env.PASSWORD = "test"
const args = parse([]) const args = parse([])
@@ -881,21 +861,13 @@ describe("optionDescriptions", () => {
it("should show if an option is deprecated", () => { it("should show if an option is deprecated", () => {
const opts: Partial<Options<Required<UserProvidedArgs>>> = { const opts: Partial<Options<Required<UserProvidedArgs>>> = {
link: { cert: {
type: OptionalString, type: OptionalString,
description: ` description: "foo",
Securely bind code-server via our cloud service with the passed name. You'll get a URL like
https://hostname-username.coder.co at which you can easily access your code-server instance.
Authorization is done via GitHub.
`,
deprecated: true, deprecated: true,
}, },
} }
expect(optionDescriptions(opts)).toStrictEqual([ expect(optionDescriptions(opts)).toStrictEqual([" --cert (deprecated) foo"])
` --link (deprecated) Securely bind code-server via our cloud service with the passed name. You'll get a URL like
https://hostname-username.coder.co at which you can easily access your code-server instance.
Authorization is done via GitHub.`,
])
}) })
it("should show newlines in description", () => { it("should show newlines in description", () => {