diff --git a/.github/ISSUE_TEMPLATE/bug-report.md b/.github/ISSUE_TEMPLATE/bug-report.md index 10ed7edd..a9d70644 100644 --- a/.github/ISSUE_TEMPLATE/bug-report.md +++ b/.github/ISSUE_TEMPLATE/bug-report.md @@ -1,10 +1,9 @@ --- name: Bug report about: Report a bug and help us improve -title: '' -labels: '' -assignees: '' - +title: "" +labels: "" +assignees: "" --- @@ -39,23 +42,23 @@ See https://cdn.vsassets.io/v/M146_20190123.39/_content/Microsoft-Visual-Studio- > Marketplace Offerings are intended for use only with Visual Studio Products and Services > and you may only install and use Marketplace Offerings with Visual Studio Products and Services. -As a result, Coder has created its own marketplace for open source extensions. It works by scraping -GitHub for VS Code extensions and building them. It's not perfect but getting better by the day with -more and more extensions. +As a result, we have created our own marketplace for open source extensions. +It works by scraping GitHub for VS Code extensions and building them. It's not perfect but getting +better by the day with more and more extensions. Issue [#1299](https://github.com/cdr/code-server/issues/1299) is a big one in making the experience here better by allowing the community to submit extensions and repos to avoid waiting until the scraper finds an extension. +To request an extension for the code-server marketplace, please open a new issue +and select the `Extension request` template. + If an extension is not available or does not work, you can grab its VSIX from its Github releases or build it yourself. Then run the `Extensions: Install from VSIX` command in the Command Palette and point to the .vsix file. See below for installing an extension from the cli. -To request an extension for the code-server marketplace, please open a new issue -and select the `Extension request` template. - If you have your own custom marketplace, it is possible to point code-server to it by setting `$SERVICE_URL` and `$ITEM_URL` to point to it. @@ -96,17 +99,17 @@ code-server only supports password authentication natively. **note**: code-server will rate limit password authentication attempts at 2 a minute and 12 an hour. If you want to use external authentication (i.e sign in with Google) you should handle this -with a reverse proxy using something like [oauth2_proxy](https://github.com/pusher/oauth2_proxy). +with a reverse proxy using something like [oauth2_proxy](https://github.com/pusher/oauth2_proxy) +or [Cloudflare Access](https://teams.cloudflare.com/access). For HTTPS, you can use a self signed certificate by passing in just `--cert` or pass in an existing certificate by providing the path to `--cert` and the path to -its key with `--cert-key`. +the key with `--cert-key`. If `code-server` has been passed a certificate it will also respond to HTTPS -requests and will redirect all HTTP requests to HTTPS. Otherwise it will respond -only to HTTP requests. +requests and will redirect all HTTP requests to HTTPS. -You can use [Let's Encrypt](https://letsencrypt.org/) to get an SSL certificate +You can use [Let's Encrypt](https://letsencrypt.org/) to get a TLS certificate for free. Again, please follow [./guide.md](./guide.md) for our recommendations on setting up and using code-server. @@ -117,6 +120,10 @@ code-server is capable of proxying to any port using either a subdomain or a subpath which means you can securely access these services using code-server's built-in authentication. +### Sub-paths + +Just browse to `/proxy//`. + ### Sub-domains You will need a DNS entry that points to your server for each port you want to @@ -136,35 +143,28 @@ code-server --proxy-domain Now you can browse to `.`. Note that this uses the host header so ensure your reverse proxy forwards that information if you are using one. -### Sub-paths - -Just browse to `/proxy//`. - ## Multi-tenancy If you want to run multiple code-servers on shared infrastructure, we recommend using virtual machines with a VM per user. This will easily allow users to run a docker daemon. If you want to use kubernetes, you'll definitely want to use [kubevirt](https://kubevirt.io) to give each -user a virtual machine instead of just a container. Docker in docker while supported requires -privileged containers which are a security risk in a multi tenant infrastructure. +user a virtual machine instead of just a container. -## Docker in code-server docker container? +## Docker in code-server container? -If you'd like to access docker inside of code-server, we'd recommend running a docker:dind container -and mounting in a directory to share between dind and the code-server container at /var/run. After, install -the docker CLI in the code-server container and you should be able to access the daemon as the socket -will be shared at /var/run/docker.sock. +If you'd like to access docker inside of code-server, mount the docker socket in from `/var/run/docker.sock`. +Install the docker CLI in the code-server container and you should be able to access the daemon! -In order to make volume mounts work, mount the home directory in the code-server container and the -dind container at the same path. i.e you'd volume mount a directory from the host to `/home/coder` -on both. This will allow any volume mounts in the home directory to work. Similar process -to make volume mounts in any other directory work. +You can even make volume mounts work. Lets say you want to run a container and mount in +`/home/coder/myproject` into it from inside the `code-server` container. You need to make sure +the docker daemon's `/home/coder/myproject` is the same as the one mounted inside the `code-server` +container and the mount will just work. ## Collaboration We understand the high demand but the team is swamped right now. -You can follow progress at [#33](https://github.com/cdr/code-server/issues/33). +You can subscribe to [#33](https://github.com/cdr/code-server/issues/33) for updates. ## How can I disable telemetry? @@ -207,7 +207,7 @@ as there is an active browser connection. If you want to shutdown `code-server` if there hasn't been an active connection in X minutes you can do so by continuously checking the last modified time on the heartbeat file and if it is -older than X minutes, you should kill `code-server`. +older than X minutes, kill `code-server`. [#1636](https://github.com/cdr/code-server/issues/1636) will make the experience here better. @@ -242,6 +242,33 @@ certificate using the CA and then import the CA onto your iPad. See [#1566](https://github.com/cdr/code-server/issues/1566#issuecomment-623159434). +## Isn't an install script piped into sh insecure? + +Please give +[this wonderful blogpost](https://sandstorm.io/news/2015-09-24-is-curl-bash-insecure-pgp-verified-install) by +[sandstorm.io](https://sandstorm.io) a read. + +## How do I make my keyboard shortcuts work? + +Many shortcuts will not work by default as they'll be caught by the browser. + +If you use Chrome you can get around this by installing the PWA. + +Once you've entered the editor, click the "plus" icon present in the URL toolbar area. +This will install a Chrome PWA and now all keybindings will work! + +For other browsers you'll have to remap keybindings unfortunately. + +## Why can't I use VS Code's Remote extensions? + +Unfortunately, Microsoft has opted to make [VS Code's Remote SSH and Container +extensions closed source](https://github.com/microsoft/vscode-remote-release) and +it is against their TOS to use the published extensions so we are unable to +add them to our marketplace. + +We may reimplement them at some point. +You can subscribe to [#1315](https://github.com/cdr/code-server/issues/1315) for updates. + ## Enterprise Visit [our enterprise page](https://coder.com) for more information about our diff --git a/doc/assets/code-server.gif b/doc/assets/code-server.gif deleted file mode 100644 index 9f6ec6e1..00000000 Binary files a/doc/assets/code-server.gif and /dev/null differ diff --git a/doc/assets/screenshot.png b/doc/assets/screenshot.png new file mode 100644 index 00000000..7f76a21e Binary files /dev/null and b/doc/assets/screenshot.png differ diff --git a/doc/guide.md b/doc/guide.md index ef1d6e0b..2cd72091 100644 --- a/doc/guide.md +++ b/doc/guide.md @@ -15,21 +15,22 @@ -This guide demonstrates how to setup and use code-server. -To reiterate, code-server lets you run VS Code on a remote server and then access it via a browser. +This guide demonstrates how to setup and use `code-server`. +To reiterate, `code-server` lets you run VS Code on a remote server and then access it via a browser. Further docs are at: -- [README.md](../README.md) for a general overview -- [FAQ.md](./FAQ.md) for common questions. -- [CONTRIBUTING.md](../doc/CONTRIBUTING.md) for development docs +- [README](../README.md) for a general overview +- [INSTALL](../doc/install.md) for installation +- [FAQ](./FAQ.md) for common questions. +- [CONTRIBUTING](../doc/CONTRIBUTING.md) for development docs -We'll walk you through acquiring a remote machine to run code-server on and then exposing `code-server` so you can -securely access it. +We'll walk you through acquiring a remote machine to run `code-server` on +and then exposing `code-server` so you can securely access it. ## 1. Acquire a remote machine -First, you need a machine to run code-server on. You can use a physical +First, you need a machine to run `code-server` on. You can use a physical machine you have lying around or use a VM on GCP/AWS. ### Requirements @@ -60,66 +61,71 @@ Once you've signed up and created a GCP project, create a new Compute Engine VM - Change the type to custom and set at least 2 cores and 2 GB of ram. - Add more vCPUs and memory as you prefer, you can edit after creating the instance as well. - https://cloud.google.com/compute/docs/machine-types#general_purpose -7. We highly recommend switching the persistent disk to a SSD of at least 32 GB. +7. We highly recommend switching the persistent disk to an SSD of at least 32 GB. - Click `Change` under `Boot Disk` and change the type to `SSD Persistent Disk` and the size to `32`. - You can always grow your disk later. - - The default OS of Debian 10 is fine. 8. Navigate to `Networking -> Network interfaces` and edit the existing interface to use a static external IP. - Click done to save network interface changes. -9. If you do not have a [project wide SSH key](https://cloud.google.com/compute/docs/instances/adding-removing-ssh-keys#project-wide), navigate to `Security - > SSH Keys` and add your public key there. +9. If you do not have a [project wide SSH key](https://cloud.google.com/compute/docs/instances/adding-removing-ssh-keys#project-wide), navigate to `Security -> SSH Keys` and add your public key there. 10. Click create! Remember, you can shutdown your server when not in use to lower costs. + We highly recommend learning to use the [`gcloud`](https://cloud.google.com/sdk/gcloud) cli to avoid the slow dashboard. ## 2. Install code-server -SSH into your instance and run the appropriate commands documented in [README.md](../README.md). +We have a [script](../install.sh) to install `code-server` for Linux and macOS. -Assuming Debian: +It tries to use the system package manager if possible. + +First run to print out the install process: ```bash -curl -sSOL https://github.com/cdr/code-server/releases/download/v3.3.1/code-server_3.3.1_amd64.deb -sudo dpkg -i code-server_3.3.1_amd64.deb -systemctl --user enable --now code-server -# Now code-server is running at http://127.0.0.1:8080 -# Your password is in ~/.config/code-server/config.yaml +curl -fsSL https://code-server.dev/install.sh | sh -s -- --dry-run ``` +Now to actually install: + +```bash +curl -fsSL https://code-server.dev/install.sh | sh +``` + +The install script will print out how to run and start using `code-server`. + +Docs on the install script, manual installation and docker image are at [./install.md](./install.md). + ## 3. Expose code-server **Never**, **ever** expose `code-server` directly to the internet without some form of authentication and encryption as someone can completely takeover your machine with the terminal. -By default, code-server will enable password authentication which will -require you to copy the password from the code-server config file to login. Since it -cannot use TLS by default, it will listen on `localhost` to avoid exposing itself -to the world. This is fine for testing but will not work if you want to access `code-server` +By default, `code-server` will enable password authentication which will require you to copy the +password from the`code-server`config file to login. It will listen on`localhost` to avoid exposing +itself to the world. This is fine for testing but will not work if you want to access `code-server` from a different machine. -There are several approaches to securely operating and exposing code-server. +There are several approaches to securely operating and exposing `code-server`. -**tip**: You can list the full set of code-server options with `code-server --help` +**tip**: You can list the full set of `code-server` options with `code-server --help` ### SSH forwarding We highly recommend this approach for not requiring any additional setup, you just need an SSH server on your remote machine. The downside is you won't be able to access `code-server` -without an SSH client like an iPad. If that's important to you, skip to [Let's Encrypt](#lets-encrypt). +on any machine without an SSH client like on iPad. If that's important to you, skip to [Let's Encrypt](#lets-encrypt). -Recommended reading: https://help.ubuntu.com/community/SSH/OpenSSH/PortForwarding. - -First, ssh into your instance and edit your code-server config file to disable password authentication. +First, ssh into your instance and edit your `code-server` config file to disable password authentication. ```bash # Replaces "auth: password" with "auth: none" in the code-server config. sed -i.bak 's/auth: password/auth: none/' ~/.config/code-server/config.yaml ``` -Restart code-server with (assuming you followed the guide): +Restart `code-server` with (assuming you followed the guide): ```bash systemctl --user restart code-server @@ -127,12 +133,14 @@ systemctl --user restart code-server Now forward local port 8080 to `127.0.0.1:8080` on the remote instance. +Recommended reading: https://help.ubuntu.com/community/SSH/OpenSSH/PortForwarding. + ```bash # -N disables executing a remote shell ssh -N -L 8080:127.0.0.1:8080 ``` -Now if you access http://127.0.0.1:8080 locally, you should see code-server! +Now if you access http://127.0.0.1:8080 locally, you should see `code-server`! If you want to make the SSH port forwarding persistent we recommend using [mutagen](https://mutagen.io/documentation/introduction/installation). @@ -151,16 +159,16 @@ ServerAliveInterval 5 ExitOnForwardFailure yes ``` -You can also forward your SSH key and GPG agent to the instance to securely access GitHub -and sign commits without copying your keys onto the instance. +You can also forward your SSH and GPG agent to the instance to securely access GitHub +and sign commits without copying your keys. 1. https://developer.github.com/v3/guides/using-ssh-agent-forwarding/ 2. https://wiki.gnupg.org/AgentForwarding ### Let's Encrypt -[Let's Encrypt](https://letsencrypt.org) is a great option if you want to access code-server on an iPad -or do not want to use SSH forwarding. This does require that the remote machine is exposed to the internet. +[Let's Encrypt](https://letsencrypt.org) is a great option if you want to access `code-server` on an iPad +or do not want to use SSH forwarding. This does require that the remote machine be exposed to the internet. Assuming you have been following the guide, edit your instance and checkmark the allow HTTP/HTTPS traffic options. @@ -189,25 +197,24 @@ reverse_proxy 127.0.0.1:8080 sudo systemctl reload caddy ``` -Visit `https://` to access code-server. Congratulations! +Visit `https://` to access `code-server`. Congratulations! -In a future release we plan to integrate Let's Encrypt directly with code-server to avoid +In a future release we plan to integrate Let's Encrypt directly with `code-server` to avoid the dependency on caddy. ### Self Signed Certificate **note:** Self signed certificates do not work with iPad and will cause a blank page. You'll -have to use [Let's Encrypt](#lets-encrypt) instead. See the [FAQ](https://github.com/cdr/code-server/blob/master/doc/FAQ.md#blank-screen-on-ipad). +have to use [Let's Encrypt](#lets-encrypt) instead. See the [FAQ](./FAQ.md#blank-screen-on-ipad). Recommended reading: https://security.stackexchange.com/a/8112. -We recommend this as a last resort as self signed certificates do not work with iPads and can -cause other bizarre issues. Not to mention all the warnings when you access code-server. +We recommend this as a last resort because self signed certificates do not work with iPads and can +cause other bizarre issues. Not to mention all the warnings when you access `code-server`. Only use this if: -1. You do not want to buy a domain. -2. You cannot expose the remote machine to the internet. -3. You do not want to use SSH forwarding. +1. You do not want to buy a domain or you cannot expose the remote machine to the internet. +2. You do not want to use SSH forwarding. ssh into your instance and edit your code-server config file to use a randomly generated self signed certificate: @@ -220,7 +227,7 @@ sed -i.bak 's/bind-addr: 127.0.0.1:8080/bind-addr: 0.0.0.0:443/' ~/.config/code- sudo setcap cap_net_bind_service=+ep /usr/lib/code-server/lib/node ``` -Assuming you have been following the guide, restart code-server with: +Assuming you have been following the guide, restart `code-server` with: ```bash systemctl --user restart code-server @@ -228,17 +235,17 @@ systemctl --user restart code-server Edit your instance and checkmark the allow HTTPS traffic option. -Visit `https://` to access code-server. +Visit `https://` to access `code-server`. You'll get a warning when accessing but if you click through you should be good. To avoid the warnings, you can use [mkcert](https://mkcert.dev) to create a self signed certificate -trusted by your OS and then pass it into code-server via the `cert` and `cert-key` config +trusted by your OS and then pass it into `code-server` via the `cert` and `cert-key` config fields. ### Change the password? -Edit the code-server config file at `~/.config/code-server/config.yaml` and then restart -code-server with: +Edit the `password` field in the `code-server` config file at `~/.config/code-server/config.yaml` +and then restart `code-server` with: ```bash systemctl --user restart code-server @@ -246,6 +253,6 @@ systemctl --user restart code-server ### How do I securely access development web services? -If you're working on a web service and want to access it locally, code-server can proxy it for you. +If you're working on a web service and want to access it locally, `code-server` can proxy it for you. -See [FAQ.md](https://github.com/cdr/code-server/blob/master/doc/FAQ.md#how-do-i-securely-access-web-services). +See the [FAQ](./FAQ.md#how-do-i-securely-access-web-services). diff --git a/doc/install.md b/doc/install.md new file mode 100644 index 00000000..bd0fac48 --- /dev/null +++ b/doc/install.md @@ -0,0 +1,185 @@ + + +# Install + +- [install.sh](#installsh) + - [Flags](#flags) + - [Detect Reference](#detect-reference) +- [Debian, Ubuntu](#debian-ubuntu) +- [Fedora, CentOS, RHEL, SUSE](#fedora-centos-rhel-suse) +- [Arch Linux](#arch-linux) +- [yarn, npm](#yarn-npm) +- [macOS](#macos) +- [Standalone Releases](#standalone-releases) +- [Docker](#docker) + + + +This document demonstrates how to install `code-server` on +various distros and operating systems. + +## install.sh + +We have a [script](../install.sh) to install code-server for Linux and macOS. + +It tries to use the system package manager if possible. + +First run to print out the install process: + +```bash +curl -fsSL https://code-server.dev/install.sh | sh -s -- --dry-run +``` + +Now to actually install: + +```bash +curl -fsSL https://code-server.dev/install.sh | sh +``` + +The script will print out how to run and start using code-server. + +If you believe an install script used with `curl | sh` is insecure, please give +[this wonderful blogpost](https://sandstorm.io/news/2015-09-24-is-curl-bash-insecure-pgp-verified-install) by +[sandstorm.io](https://sandstorm.io) a read. + +If you'd still prefer manual installation despite the below [detect reference](#detect-reference) and `--dry-run` +then continue on for docs on manual installation. The [`install.sh`](../install.sh) script runs the _exact_ same +commands presented in the rest of this document. + +### Flags + +- `--dry-run` to echo the commands for the install process without running them. +- `--method` to choose the installation method. + - `--method=detect` to detect the package manager but fallback to `--method=standalone`. + - `--method=standalone` to install a standalone release archive into `~/.local`. +- `--prefix=/usr/local` to install a standalone release archive system wide. +- `--version=X.X.X` to install version `X.X.X` instead of latest. +- `--help` to see full usage docs. + +### Detect Reference + +- For Debian, Ubuntu and Raspbian it will install the latest deb package. +- For Fedora, CentOS, RHEL and openSUSE it will install the latest rpm package. +- For Arch Linux it will install the AUR package. +- For any unrecognized Linux operating system it will install the latest standalone release into `~/.local`. + + - Add `~/.local/bin` to your `$PATH` to run code-server. + +- For macOS it will install the Homebrew package. + + - If Homebrew is not installed it will install the latest standalone release into `~/.local`. + - Add `~/.local/bin` to your `$PATH` to run code-server. + +- If ran on an architecture with no releases, it will install the [npm package](#yarn-npm) with `yarn` or `npm`. + - We only have releases for amd64 and arm64 presently. + - The [npm package](#yarn-npm) builds the native modules on postinstall. + +## Debian, Ubuntu + +```bash +curl -fOL https://github.com/cdr/code-server/releases/download/v3.4.0/code-server_3.4.0_amd64.deb +sudo dpkg -i code-server_3.4.0_amd64.deb +systemctl --user enable --now code-server +# Now visit http://127.0.0.1:8080. Your password is in ~/.config/code-server/config.yaml +``` + +## Fedora, CentOS, RHEL, SUSE + +```bash +curl -fOL https://github.com/cdr/code-server/releases/download/v3.4.0/code-server-3.4.0-amd64.rpm +sudo rpm -i code-server-3.4.0-amd64.rpm +systemctl --user enable --now code-server +# Now visit http://127.0.0.1:8080. Your password is in ~/.config/code-server/config.yaml +``` + +## Arch Linux + +```bash +# Installs code-server from the AUR using yay. +yay -S code-server +systemctl --user enable --now code-server +# Now visit http://127.0.0.1:8080. Your password is in ~/.config/code-server/config.yaml +``` + +```bash +# Installs code-server from the AUR with plain makepkg. +git clone https://aur.archlinux.org/code-server.git +cd code-server +makepkg -si +systemctl --user enable --now code-server +# Now visit http://127.0.0.1:8080. Your password is in ~/.config/code-server/config.yaml +``` + +## yarn, npm + +We recommend installing with `yarn` or `npm` when: + +1. You aren't on `amd64` or `arm64`. +2. If you're on Linux with glibc < v2.17 + +**note:** Installing via `yarn` or `npm` builds native modules on install and so requires C dependencies. +See [./npm.md](./npm.md) for installing these dependencies. + +You will need at least node v12 installed. See [#1633](https://github.com/cdr/code-server/issues/1633). + +```bash +yarn global add code-server +# Or: npm install -g code-server +code-server +# Now visit http://127.0.0.1:8080. Your password is in ~/.config/code-server/config.yaml +``` + +## macOS + +```bash +brew install code-server +brew services start code-server +# Now visit http://127.0.0.1:8080. Your password is in ~/.config/code-server/config.yaml +``` + +## Standalone Releases + +We publish self contained `.tar.gz` archives for every release on [github](https://github.com/cdr/code-server/releases). +They bundle the node binary and `node_modules`. + +These are created from the [npm package](#yarn-npm) and the rest of the releases are created from these. +Only requirement is glibc >= 2.17 on Linux and for macOS there is no minimum system requirement. + +1. Download the latest release archive for your system from [github](https://github.com/cdr/code-server/releases). +2. Unpack the release. +3. You can run code-server by executing `./bin/code-server`. + +You can add the code-server `bin` directory to your `$PATH` to easily execute `code-server` +without the full path every time. + +Here is an example script for installing and using a standalone `code-server` release on Linux: + +```bash +mkdir -p ~/.local/lib ~/.local/bin +curl -fL https://github.com/cdr/code-server/releases/download/v3.4.0/code-server-3.4.0-linux-amd64.tar.gz \ + | tar -C ~/.local/lib -xz +mv ~/.local/lib/code-server-3.4.0-linux-amd64 ~/.local/lib/code-server-3.4.0 +ln -s ~/.local/lib/code-server-3.4.0/bin/code-server ~/.local/bin/code-server +PATH="~/.local/bin:$PATH" +code-server +# Now visit http://127.0.0.1:8080. Your password is in ~/.config/code-server/config.yaml +``` + +## Docker + +```bash +# This will start a code-server container and expose it at http://127.0.0.1:8080. +# It will also mount your current directory into the container as `/home/coder/project` +# and forward your UID/GID so that all file system operations occur as your user outside +# the container. +docker run -it -p 127.0.0.1:8080:8080 \ + -v "$PWD:/home/coder/project" \ + -u "$(id -u):$(id -g)" \ + codercom/code-server:latest +``` + +Our official image supports `amd64` and `arm64`. + +For `arm32` support there is a popular community maintained alternative: + +https://hub.docker.com/r/linuxserver/code-server diff --git a/doc/npm.md b/doc/npm.md index 08704c0c..18d9fc5e 100644 --- a/doc/npm.md +++ b/doc/npm.md @@ -16,7 +16,7 @@ sudo apt-get install -y \ libsecret-1-dev ``` -## Fedora, Red Hat, SUSE +## Fedora, CentOS, RHEL ```bash sudo yum groupinstall -y 'Development Tools' diff --git a/install.sh b/install.sh new file mode 100755 index 00000000..f226d519 --- /dev/null +++ b/install.sh @@ -0,0 +1,482 @@ +#!/bin/sh +set -eu + +# code-server's automatic install script. +# See https://github.com/cdr/code-server/blob/master/doc/install.md + +usage() { + arg0="$0" + if [ "$0" = sh ]; then + arg0="curl -fsSL https://code-server.dev/install.sh | sh -s --" + else + not_curl_usage="The latest script is available at https://code-server.dev/install.sh +" + fi + + cath << EOF +Installs code-server for Linux and macOS. +It tries to use the system package manager if possible. +After successful installation it explains how to start using code-server. +${not_curl_usage-} +Usage: + + $arg0 [--dry-run] [--version X.X.X] [--method detect] [--prefix ~/.local] + + --dry-run + Echo the commands for the install process without running them. + --version X.X.X + Install a specific version instead of the latest. + --method [detect | standalone] + Choose the installation method. Defaults to detect. + - detect detects the system package manager and tries to use it. + Full reference on the process is further below. + - standalone installs a standalone release archive into ~/.local + Add ~/.local/bin to your \$PATH to use it. + --prefix + Sets the prefix used by standalone release archives. Defaults to ~/.local + The release is unarchived into ~/.local/lib/code-server-X.X.X + and the binary symlinked into ~/.local/bin/code-server + To install system wide pass ---prefix=/usr/local + +- For Debian, Ubuntu and Raspbian it will install the latest deb package. +- For Fedora, CentOS, RHEL and openSUSE it will install the latest rpm package. +- For Arch Linux it will install the AUR package. +- For any unrecognized Linux operating system it will install the latest standalone + release into ~/.local + +- For macOS it will install the Homebrew package. + - If Homebrew is not installed it will install the latest standalone release + into ~/.local + +- If ran on an architecture with no releases, it will install the + npm package with yarn or npm. + - We only have releases for amd64 and arm64 presently. + - The npm package builds the native modules on postinstall. + +It will cache all downloaded assets into ~/.cache/code-server + +More installation docs are at https://github.com/cdr/code-server/blob/master/doc/install.md +EOF +} + +echo_latest_version() { + # https://gist.github.com/lukechilds/a83e1d7127b78fef38c2914c4ececc3c#gistcomment-2758860 + version="$(curl -fsSLI -o /dev/null -w "%{url_effective}" https://github.com/cdr/code-server/releases/latest)" + version="${version#https://github.com/cdr/code-server/releases/tag/v}" + echo "$version" +} + +echo_standalone_postinstall() { + echoh + cath << EOF +Standalone release has been installed into $STANDALONE_INSTALL_PREFIX/lib/code-server-$VERSION +Please extend your path to use code-server: + PATH="$STANDALONE_INSTALL_PREFIX/bin:\$PATH" +Then you can run: + code-server +EOF +} + +echo_systemd_postinstall() { + echoh + cath << EOF +To have systemd start code-server now and restart on boot: + systemctl --user enable --now code-server +Or, if you don't want/need a background service you can run: + code-server +EOF +} + +main() { + if [ "${TRACE-}" ]; then + set -x + fi + + unset \ + DRY_RUN \ + METHOD \ + STANDALONE_INSTALL_PREFIX \ + VERSION \ + OPTIONAL + + while [ "$#" -gt 0 ]; do + case "$1" in + --dry-run) + DRY_RUN=1 + ;; + --method) + METHOD="$(parse_arg "$@")" + shift + ;; + --method=*) + METHOD="$(parse_arg "$@")" + ;; + --prefix) + STANDALONE_INSTALL_PREFIX="$(parse_arg "$@")" + shift + ;; + --prefix=*) + STANDALONE_INSTALL_PREFIX="$(parse_arg "$@")" + ;; + --version) + VERSION="$(parse_arg "$@")" + shift + ;; + --version=*) + VERSION="$(parse_arg "$@")" + ;; + -h | --h | -help | --help) + usage + exit 0 + ;; + *) + echoerr "Unknown flag $1" + echoerr "Run with --help to see usage." + exit 1 + ;; + esac + + shift + done + + VERSION="${VERSION-$(echo_latest_version)}" + METHOD="${METHOD-detect}" + if [ "$METHOD" != detect ] && [ "$METHOD" != standalone ]; then + echoerr "Unknown install method \"$METHOD\"" + echoerr "Run with --help to see usage." + exit 1 + fi + STANDALONE_INSTALL_PREFIX="${STANDALONE_INSTALL_PREFIX-$HOME/.local}" + + OS="$(os)" + if [ ! "$OS" ]; then + echoerr "Unsupported OS $(uname)." + exit 1 + fi + + distro_name + + ARCH="$(arch)" + if [ ! "$ARCH" ]; then + if [ "$METHOD" = standalone ]; then + echoerr "No releases available for the architecture $(uname -m)." + echoerr 'Please rerun without the "--method standalone" flag to install from npm.' + exit 1 + fi + echoh "No precompiled releases for $(uname -m)." + install_npm + return + fi + + CACHE_DIR="$(echo_cache_dir)" + mkdir -p "$CACHE_DIR" + + if [ "$METHOD" = standalone ]; then + install_standalone + return + fi + + case "$(distro)" in + macos) + install_macos + ;; + ubuntu | debian | raspbian) + install_deb + ;; + centos | fedora | rhel | opensuse) + install_rpm + ;; + arch) + install_aur + ;; + *) + echoh "Unsupported package manager." + install_standalone + ;; + esac +} + +parse_arg() { + case "$1" in + *=*) + # Remove everything after first equal sign. + opt="${1%%=*}" + # Remove everything before first equal sign. + optarg="${1#*=}" + if [ ! "$optarg" ] && [ ! "${OPTIONAL-}" ]; then + echoerr "$opt requires an argument" + echoerr "Run with --help to see usage." + exit 1 + fi + echo "$optarg" + return + ;; + esac + + case "${2-}" in + "" | -*) + if [ ! "${OPTIONAL-}" ]; then + echoerr "$1 requires an argument" + echoerr "Run with --help to see usage." + exit 1 + fi + ;; + *) + echo "$2" + return + ;; + esac +} + +fetch() { + URL="$1" + FILE="$2" + + if [ -e "$FILE" ]; then + echoh "+ Reusing $CACHE_DIR/${URL##*/}" + return + fi + + sh_c curl \ + -#fL \ + -o "$FILE.incomplete" \ + -C - \ + "$URL" + sh_c mv "$FILE.incomplete" "$FILE" +} + +install_macos() { + if command_exists brew; then + echoh "Installing from Homebrew." + echoh + + sh_c brew install code-server + + return + fi + + echoh "Homebrew not installed." + + install_standalone +} + +install_deb() { + echoh "Installing v$VERSION deb package from GitHub releases." + echoh + + fetch "https://github.com/cdr/code-server/releases/download/v$VERSION/code-server_${VERSION}_$ARCH.deb" \ + "$CACHE_DIR/code-server_${VERSION}_$ARCH.deb" + sudo_sh_c dpkg -i "$CACHE_DIR/code-server_${VERSION}_$ARCH.deb" + + echo_systemd_postinstall +} + +install_rpm() { + echoh "Installing v$VERSION rpm package from GitHub releases." + echoh + + fetch "https://github.com/cdr/code-server/releases/download/v$VERSION/code-server-$VERSION-$ARCH.rpm" \ + "$CACHE_DIR/code-server-$VERSION-$ARCH.rpm" + sudo_sh_c rpm -i "$CACHE_DIR/code-server-$VERSION-$ARCH.rpm" + + echo_systemd_postinstall +} + +install_aur() { + echoh "Installing from the AUR." + echoh + + sh_c mkdir -p "$CACHE_DIR/code-server-aur" + sh_c "curl -#fsSL https://aur.archlinux.org/cgit/aur.git/snapshot/code-server.tar.gz | tar -xzC $CACHE_DIR/code-server-aur --strip-components 1" + echo "+ cd $CACHE_DIR/code-server-aur" + if [ ! "${DRY_RUN-}" ]; then + cd "$CACHE_DIR/code-server-aur" + fi + sh_c makepkg -si + + echo_systemd_postinstall +} + +install_standalone() { + echoh "Installing standalone release archive v$VERSION" + echoh + + fetch "https://github.com/cdr/code-server/releases/download/v$VERSION/code-server-$VERSION-$OS-$ARCH.tar.gz" \ + "$CACHE_DIR/code-server-$VERSION-$OS-$ARCH.tar.gz" + + sh_c="sh_c" + if [ ! -w "$STANDALONE_INSTALL_PREFIX" ]; then + sh_c="sudo_sh_c" + fi + + if [ -e "$STANDALONE_INSTALL_PREFIX/lib/code-server-$VERSION" ]; then + echoh + echoh "code-server-$VERSION is already installed at $STANDALONE_INSTALL_PREFIX/lib/code-server-$VERSION" + echoh "Remove it to reinstall." + exit 0 + fi + + "$sh_c" mkdir -p "$STANDALONE_INSTALL_PREFIX/lib" "$STANDALONE_INSTALL_PREFIX/bin" + "$sh_c" tar -C "$STANDALONE_INSTALL_PREFIX/lib" -xzf "$CACHE_DIR/code-server-$VERSION-$OS-$ARCH.tar.gz" + "$sh_c" mv -f "$STANDALONE_INSTALL_PREFIX/lib/code-server-$VERSION-$OS-$ARCH" "$STANDALONE_INSTALL_PREFIX/lib/code-server-$VERSION" + "$sh_c" ln -fs "$STANDALONE_INSTALL_PREFIX/lib/code-server-$VERSION/bin/code-server" "$STANDALONE_INSTALL_PREFIX/bin/code-server" + + echo_standalone_postinstall +} + +install_npm() { + if command_exists yarn; then + sh_c="sh_c" + if [ ! -w "$(yarn global bin)" ]; then + sh_c="sudo_sh_c" + fi + echoh "Installing with yarn." + echoh + "$sh_c" yarn global add code-server --unsafe-perm + return + elif command_exists npm; then + sh_c="sh_c" + if [ ! -w "$(npm config get prefix)" ]; then + sh_c="sudo_sh_c" + fi + echoh "Installing with npm." + echoh + "$sh_c" npm install -g code-server --unsafe-perm + return + fi + echoh + echoerr "Please install npm or yarn to install code-server!" + echoerr "You will need at least node v12 and a few C dependencies." + echoerr "See the docs https://github.com/cdr/code-server#yarn-npm" + exit 1 +} + +os() { + case "$(uname)" in + Linux) + echo linux + ;; + Darwin) + echo macos + ;; + esac +} + +# distro prints the detected operating system including linux distros. +# +# Example outputs: +# - macos +# - debian, ubuntu, raspbian +# - centos, fedora, rhel, opensuse +# - alpine +# - arch +# +# Inspired by https://github.com/docker/docker-install/blob/26ff363bcf3b3f5a00498ac43694bf1c7d9ce16c/install.sh#L111-L120. +distro() { + if [ "$(uname)" = "Darwin" ]; then + echo "macos" + return + fi + + if [ -f /etc/os-release ]; then + ( + . /etc/os-release + case "$ID" in opensuse-*) + # opensuse's ID's look like opensuse-leap and opensuse-tumbleweed. + echo "opensuse" + return + ;; + esac + + echo "$ID" + ) + return + fi +} + +# os_name prints a pretty human readable name for the OS/Distro. +distro_name() { + if [ "$(uname)" = "Darwin" ]; then + echo "macOS v$(sw_vers -productVersion)" + return + fi + + if [ -f /etc/os-release ]; then + ( + . /etc/os-release + echo "$PRETTY_NAME" + ) + return + fi + + # Prints something like: Linux 4.19.0-9-amd64 + uname -sr +} + +arch() { + case "$(uname -m)" in + aarch64) + echo arm64 + ;; + x86_64) + echo amd64 + ;; + esac +} + +command_exists() { + command -v "$@" > /dev/null 2>&1 +} + +sh_c() { + echoh "+ $*" + if [ ! "${DRY_RUN-}" ]; then + sh -c "$*" + fi +} + +sudo_sh_c() { + if [ "$(id -u)" = 0 ]; then + sh_c "$@" + elif command_exists sudo; then + sh_c "sudo $*" + elif command_exists su; then + sh_c "su -c '$*'" + else + echoh + echoerr "This script needs to run the following command as root." + echoerr " $*" + echoerr "Please install sudo or su." + exit 1 + fi +} + +echo_cache_dir() { + if [ "${XDG_CACHE_HOME-}" ]; then + echo "$XDG_CACHE_HOME/code-server" + elif [ "${HOME-}" ]; then + echo "$HOME/.cache/code-server" + else + echo "/tmp/code-server-cache" + fi +} + +echoh() { + echo "$@" | humanpath +} + +cath() { + humanpath +} + +echoerr() { + echoh "$@" >&2 +} + +# humanpath replaces all occurances of " $HOME" with " ~" +# and all occurances of '"$HOME' with the literal '"$HOME'. +humanpath() { + sed "s# $HOME# ~#g; s#\"$HOME#\"\$HOME#g" +} + +main "$@" diff --git a/package.json b/package.json index de9256d8..cd7c45ff 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "code-server", "license": "MIT", - "version": "3.3.1", + "version": "3.4.0", "description": "Run VS Code on a remote server.", "homepage": "https://github.com/cdr/code-server", "bugs": { @@ -16,10 +16,10 @@ "build": "./ci/build/build-code-server.sh", "build:vscode": "./ci/build/build-vscode.sh", "release": "./ci/build/build-release.sh", - "release:static": "./ci/build/build-static-release.sh", + "release:standalone": "./ci/build/build-standalone-release.sh", "release:github-draft": "./ci/build/release-github-draft.sh", "release:github-assets": "./ci/build/release-github-assets.sh", - "test:static-release": "./ci/build/test-static-release.sh", + "test:standalone-release": "./ci/build/test-standalone-release.sh", "package": "./ci/build/build-packages.sh", "_____": "", "fmt": "./ci/dev/fmt.sh",