feat: change to ghfast

This commit is contained in:
VaalaCat 2025-04-24 15:48:33 +00:00
parent 6aa5e9eca6
commit c9662442d1

View File

@ -1,280 +1,142 @@
#!/usr/bin/env /bin/sh #!/bin/sh
set -eu set -eu
# Coder's automatic install script. # code-server's automatic install script.
# See https://github.com/coder/coder#install # See https://coder.com/docs/code-server/latest/install
#
# To run:
# curl -L https://coder.com/install.sh | sh
usage() { usage() {
arg0="$0" arg0="$0"
if [ "$0" = sh ]; then if [ "$0" = sh ]; then
arg0="curl -fsSL https://coder.com/install.sh | sh -s --" arg0="curl -fsSL https://code-server.dev/install.sh | sh -s --"
else else
not_curl_usage="The latest script is available at https://coder.com/install.sh not_curl_usage="The latest script is available at https://code-server.dev/install.sh
" "
fi fi
cath <<EOF cath << EOF
Installs Coder. Installs code-server.
It tries to use the system package manager if possible. It tries to use the system package manager if possible.
After successful installation it explains how to start Coder. After successful installation it explains how to start using code-server.
Pass in user@host to install Coder on user@host over ssh. Pass in user@host to install code-server on user@host over ssh.
The remote host must have internet access. The remote host must have internet access.
${not_curl_usage-} ${not_curl_usage-}
Usage: Usage:
${arg0} [--dry-run] [--mainline | --stable | --version X.X.X] [--method detect] \ $arg0 [--dry-run] [--version X.X.X] [--edge] [--method detect] \
[--prefix ~/.local] [--rsh ssh] [user@host] [--prefix ~/.local] [--rsh ssh] [user@host]
--dry-run --dry-run
Echo the commands for the install process without running them. Echo the commands for the install process without running them.
--mainline
Install the latest mainline version (default).
--stable
Install the latest stable version instead of the latest mainline version.
--version X.X.X --version X.X.X
Install a specific version instead of the latest. Install a specific version instead of the latest.
--edge
Install the latest edge version instead of the latest stable version.
--method [detect | standalone] --method [detect | standalone]
Choose the installation method. Defaults to detect. Choose the installation method. Defaults to detect.
- detect detects the system package manager and tries to use it. - detect detects the system package manager and tries to use it.
Full reference on the process is further below. Full reference on the process is further below.
- standalone installs a standalone release archive into /usr/local/bin - standalone installs a standalone release archive into ~/.local
Add ~/.local/bin to your \$PATH to use it.
--prefix <dir> --prefix <dir>
Sets the prefix used by standalone release archives. Defaults to /usr/local Sets the prefix used by standalone release archives. Defaults to ~/.local
and the binary is copied into /usr/local/bin The release is unarchived into ~/.local/lib/code-server-X.X.X
To install in \$HOME, pass --prefix=\$HOME/.local and the binary symlinked into ~/.local/bin/code-server
To install system wide pass --prefix=/usr/local
--binary-name <name>
Sets the name for the CLI in standalone release archives. Defaults to "coder"
To use the CLI as coder2, pass --binary-name=coder2
Note: in-product documentation will always refer to the CLI as "coder"
--rsh <bin> --rsh <bin>
Specifies the remote shell for remote installation. Defaults to ssh. Specifies the remote shell for remote installation. Defaults to ssh.
--with-terraform
Installs Terraform binary from https://releases.hashicorp.com/terraform/${TERRAFORM_VERSION}/ source
alongside coder.
This is great for if you are having issues with Coder installing terraform, or if you
just want it on your base system aswell.
This supports most systems, however if you are unsure yours is supported you can check
the link above.
--net-admin
Adds \`CAP_NET_ADMIN\` to the installed binary. This allows Coder to
increase network speeds, but has security implications.
See: https://man7.org/linux/man-pages/man7/capabilities.7.html
This only works on Linux based systems.
The detection method works as follows: The detection method works as follows:
- Debian, Ubuntu, Raspbian: install the deb package from GitHub. - Debian, Ubuntu, Raspbian: install the deb package from GitHub.
- Fedora, CentOS, RHEL, openSUSE: install the rpm package from GitHub. - Fedora, CentOS, RHEL, openSUSE: install the rpm package from GitHub.
- Alpine: install the apk package from GitHub. - Arch Linux: install from the AUR (which pulls releases from GitHub).
- macOS: if \`brew\` is available, install from the coder/coder Homebrew tap. - FreeBSD, Alpine: install from npm.
- Otherwise, download from GitHub and install into \`--prefix\`. - macOS: install using Homebrew if installed otherwise install from GitHub.
- All others: install the release from GitHub.
We build releases on GitHub for amd64, armv7, and arm64 on Windows, Linux, and macOS. We only build releases on GitHub for amd64 and arm64 on Linux and amd64 for
macOS. When the detection method tries to pull a release from GitHub it will
fall back to installing from npm when there is no matching release for the
system's operating system and architecture.
When the detection method tries to pull a release from GitHub it will The standalone method will force installion using GitHub releases. It will not
fall back to installing standalone when there is no matching release for fall back to npm so on architectures without pre-built releases this will error.
the system's operating system and architecture.
The installer will cache all downloaded assets into ~/.cache/coder The installer will cache all downloaded assets into ~/.cache/code-server
More installation docs are at https://coder.com/docs/code-server/latest/install
EOF EOF
} }
echo_latest_stable_version() { echo_latest_version() {
url="https://github.com/coder/coder/releases/latest" if [ "${EDGE-}" ]; then
version="$(curl -fsSL https://api.github.com/repos/coder/code-server/releases | awk 'match($0,/.*"html_url": "(.*\/releases\/tag\/.*)".*/)' | head -n 1 | awk -F '"' '{print $4}')"
else
# https://gist.github.com/lukechilds/a83e1d7127b78fef38c2914c4ececc3c#gistcomment-2758860 # https://gist.github.com/lukechilds/a83e1d7127b78fef38c2914c4ececc3c#gistcomment-2758860
response=$(curl -sSLI -o /dev/null -w "\n%{http_code} %{url_effective}" ${url}) version="$(curl -fsSLI -o /dev/null -w "%{url_effective}" https://github.com/coder/code-server/releases/latest)"
status_code=$(echo "$response" | tail -n1 | cut -d' ' -f1)
version=$(echo "$response" | tail -n1 | cut -d' ' -f2-)
body=$(echo "$response" | sed '$d')
if [ "$status_code" != "200" ]; then
echoerr "GitHub API returned status code: ${status_code}"
echoerr "URL: ${url}"
exit 1
fi fi
version="${version#https://github.com/coder/code-server/releases/tag/}"
version="${version#https://github.com/coder/coder/releases/tag/v}" version="${version#v}"
echo "${version}" echo "$version"
} }
echo_latest_mainline_version() { echo_npm_postinstall() {
# Fetch the releases from the GitHub API, sort by version number, echoh
# and take the first result. Note that we're sorting by space- cath << EOF
# separated numbers and without utilizing the sort -V flag for the npm package has been installed.
# best compatibility.
url="https://api.github.com/repos/coder/coder/releases"
response=$(curl -sSL -w "\n%{http_code}" ${url})
status_code=$(echo "$response" | tail -n1)
body=$(echo "$response" | sed '$d')
if [ "$status_code" != "200" ]; then Extend your path to use code-server:
echoerr "GitHub API returned status code: ${status_code}" PATH="$NPM_BIN_DIR:\$PATH"
echoerr "URL: ${url}" Then run with:
echoerr "Response body: ${body}" code-server
exit 1 EOF
fi
echo "$body" |
awk -F'"' '/"tag_name"/ {print $4}' |
tr -d v |
tr . ' ' |
sort -k1,1nr -k2,2nr -k3,3nr |
head -n1 |
tr ' ' .
} }
echo_standalone_postinstall() { echo_standalone_postinstall() {
if [ "${DRY_RUN-}" ]; then echoh
echo_dryrun_postinstall cath << EOF
return Standalone release has been installed into $STANDALONE_INSTALL_PREFIX/lib/code-server-$VERSION
fi
channel=
advisory="To install our stable release (v${STABLE_VERSION}), use the --stable flag. "
if [ "${STABLE}" = 1 ]; then
channel="stable "
advisory=""
fi
if [ "${MAINLINE}" = 1 ]; then
channel="mainline "
fi
cath <<EOF
Coder ${channel}release v${VERSION} installed. ${advisory}See our releases documentation or GitHub for more information on versioning.
The Coder binary has been placed in the following location:
$STANDALONE_INSTALL_PREFIX/bin/$STANDALONE_BINARY_NAME
Extend your path to use code-server:
PATH="$STANDALONE_INSTALL_PREFIX/bin:\$PATH"
Then run with:
code-server
EOF EOF
CODER_COMMAND="$(command -v "$STANDALONE_BINARY_NAME" || true)"
if [ -z "${CODER_COMMAND}" ]; then
cath <<EOF
Extend your path to use Coder:
$ PATH="$STANDALONE_INSTALL_PREFIX/bin:\$PATH"
EOF
elif [ "$CODER_COMMAND" != "$STANDALONE_BINARY_LOCATION" ]; then
echo_path_conflict "$CODER_COMMAND"
else
cath <<EOF
To run a Coder server:
$ $STANDALONE_BINARY_NAME server
To connect to a Coder deployment:
$ $STANDALONE_BINARY_NAME login <deployment url>
EOF
fi
} }
echo_brew_postinstall() { echo_brew_postinstall() {
if [ "${DRY_RUN-}" ]; then echoh
echo_dryrun_postinstall cath << EOF
return Brew release has been installed.
fi
BREW_PREFIX="$(brew --prefix)"
cath <<EOF
Coder has been installed to
$BREW_PREFIX/bin/coder
EOF
CODER_COMMAND="$(command -v "coder" || true)"
if [ "$CODER_COMMAND" != "$BREW_PREFIX/bin/coder" ]; then
echo_path_conflict "$CODER_COMMAND"
fi
cath <<EOF
To run a Coder server:
$ coder server
To connect to a Coder deployment:
$ coder login <deployment url>
Run with:
code-server
EOF EOF
} }
echo_systemd_postinstall() { echo_systemd_postinstall() {
if [ "${DRY_RUN-}" ]; then
echo_dryrun_postinstall
return
fi
echoh echoh
cath <<EOF cath << EOF
$1 package has been installed. $1 package has been installed.
To run a Coder server: To have systemd start code-server now and restart on boot:
sudo systemctl enable --now code-server@\$USER
# Start Coder now and on reboot Or, if you don't want/need a background service you can run:
$ sudo systemctl enable --now coder code-server
$ journalctl -u coder.service -b
# Or just run the server directly
$ coder server
Configuring Coder: https://coder.com/docs/admin/setup
To connect to a Coder deployment:
$ coder login <deployment url>
EOF EOF
} }
echo_dryrun_postinstall() { echo_coder_postinstall() {
cath <<EOF echoh
Dry-run complete. echoh "Deploy code-server for your team with Coder: https://github.com/coder/coder"
To install Coder, re-run this script without the --dry-run flag.
EOF
}
echo_path_conflict() {
cath <<EOF
There is another binary in your PATH that conflicts with the binary we've installed.
$1
This is likely because of an existing installation of Coder in your \$PATH.
Run \`which -a coder\` to view all installations.
EOF
} }
main() { main() {
MAINLINE=1
STABLE=0
TERRAFORM_VERSION="1.11.4"
if [ "${TRACE-}" ]; then if [ "${TRACE-}" ]; then
set -x set -x
fi fi
@ -285,12 +147,10 @@ main() {
OPTIONAL \ OPTIONAL \
ALL_FLAGS \ ALL_FLAGS \
RSH_ARGS \ RSH_ARGS \
RSH \ EDGE \
WITH_TERRAFORM \ RSH
CAP_NET_ADMIN
ALL_FLAGS="" ALL_FLAGS=""
while [ "$#" -gt 0 ]; do while [ "$#" -gt 0 ]; do
case "$1" in case "$1" in
-*) -*)
@ -316,34 +176,15 @@ main() {
--prefix=*) --prefix=*)
STANDALONE_INSTALL_PREFIX="$(parse_arg "$@")" STANDALONE_INSTALL_PREFIX="$(parse_arg "$@")"
;; ;;
--binary-name)
STANDALONE_BINARY_NAME="$(parse_arg "$@")"
shift
;;
--binary-name=*)
STANDALONE_BINARY_NAME="$(parse_arg "$@")"
;;
--version) --version)
VERSION="$(parse_arg "$@")" VERSION="$(parse_arg "$@")"
MAINLINE=0
STABLE=0
shift shift
;; ;;
--version=*) --version=*)
VERSION="$(parse_arg "$@")" VERSION="$(parse_arg "$@")"
MAINLINE=0
STABLE=0
;; ;;
# Support edge for backward compatibility. --edge)
--mainline | --edge) EDGE=1
VERSION=
MAINLINE=1
STABLE=0
;;
--stable)
VERSION=
MAINLINE=0
STABLE=1
;; ;;
--rsh) --rsh)
RSH="$(parse_arg "$@")" RSH="$(parse_arg "$@")"
@ -356,12 +197,6 @@ main() {
usage usage
exit 0 exit 0
;; ;;
--with-terraform)
WITH_TERRAFORM=1
;;
--net-admin)
CAP_NET_ADMIN=1
;;
--) --)
shift shift
# We remove the -- added above. # We remove the -- added above.
@ -386,23 +221,10 @@ main() {
if [ "${RSH_ARGS-}" ]; then if [ "${RSH_ARGS-}" ]; then
RSH="${RSH-ssh}" RSH="${RSH-ssh}"
echoh "Installing remotely with $RSH $RSH_ARGS" echoh "Installing remotely with $RSH $RSH_ARGS"
curl -fsSL https://coder.com/install.sh | prefix "$RSH_ARGS" "$RSH" "$RSH_ARGS" sh -s -- "$ALL_FLAGS" curl -fsSL https://code-server.dev/install.sh | prefix "$RSH_ARGS" "$RSH" "$RSH_ARGS" sh -s -- "$ALL_FLAGS"
return return
fi fi
# These can be overridden for testing but shouldn't normally be used as it can
# result in a broken coder.
OS=${OS:-$(os)}
ARCH=${ARCH:-$(arch)}
TERRAFORM_ARCH=${TERRAFORM_ARCH:-$(terraform_arch)}
# If we've been provided a flag which is specific to the standalone installation
# method, we should "detect" standalone to be the appropriate installation method.
# This check needs to occur before we set these variables with defaults.
if [ "${STANDALONE_INSTALL_PREFIX-}" ] || [ "${STANDALONE_BINARY_NAME-}" ]; then
METHOD=standalone
fi
METHOD="${METHOD-detect}" METHOD="${METHOD-detect}"
if [ "$METHOD" != detect ] && [ "$METHOD" != standalone ]; then if [ "$METHOD" != detect ] && [ "$METHOD" != standalone ]; then
echoerr "Unknown install method \"$METHOD\"" echoerr "Unknown install method \"$METHOD\""
@ -410,58 +232,23 @@ main() {
exit 1 exit 1
fi fi
# We can't reasonably support installing specific versions of Coder through
# Homebrew, so if we're on macOS and the `--version` flag or the `--stable`
# flag (our tap follows mainline) was set, we should "detect" standalone to
# be the appropriate installation method. This check needs to occur before we
# set `VERSION` to a default of the latest release.
if [ "$OS" = "darwin" ] && { [ "${VERSION-}" ] || [ "${STABLE}" = 1 ]; }; then
METHOD=standalone
fi
# These are used by the various install_* functions that make use of GitHub # These are used by the various install_* functions that make use of GitHub
# releases in order to download and unpack the right release. # releases in order to download and unpack the right release.
CACHE_DIR=$(echo_cache_dir) CACHE_DIR=$(echo_cache_dir)
TERRAFORM_INSTALL_PREFIX=${TERRAFORM_INSTALL_PREFIX:-/usr/local} STANDALONE_INSTALL_PREFIX=${STANDALONE_INSTALL_PREFIX:-$HOME/.local}
STANDALONE_INSTALL_PREFIX=${STANDALONE_INSTALL_PREFIX:-/usr/local} VERSION=${VERSION:-$(echo_latest_version)}
STANDALONE_BINARY_NAME=${STANDALONE_BINARY_NAME:-coder} # These can be overridden for testing but shouldn't normally be used as it can
STABLE_VERSION=$(echo_latest_stable_version) # result in a broken code-server.
if [ "${MAINLINE}" = 1 ]; then OS=${OS:-$(os)}
VERSION=$(echo_latest_mainline_version) ARCH=${ARCH:-$(arch)}
echoh "Resolved mainline version: v${VERSION}"
elif [ "${STABLE}" = 1 ]; then
VERSION=${STABLE_VERSION}
echoh "Resolved stable version: v${VERSION}"
fi
distro_name distro_name
if [ "${DRY_RUN-}" ]; then
echoh "Running with --dry-run; the following are the commands that would be run if this were a real installation:"
echoh
fi
# Start by installing Terraform, if requested
if [ "${WITH_TERRAFORM-}" ]; then
with_terraform
fi
# If the version is the same as the stable version, we're installing
# the stable version.
if [ "${MAINLINE}" = 1 ] && [ "${VERSION}" = "${STABLE_VERSION}" ]; then
echoh "The latest mainline version has been promoted to stable, selecting stable."
MAINLINE=0
STABLE=1
fi
# If the manually specified version is stable, mark it as such.
if [ "${MAINLINE}" = 0 ] && [ "${STABLE}" = 0 ] && [ "${VERSION}" = "${STABLE_VERSION}" ]; then
STABLE=1
fi
# Standalone installs by pulling pre-built releases from GitHub. # Standalone installs by pulling pre-built releases from GitHub.
if [ "$METHOD" = standalone ]; then if [ "$METHOD" = standalone ]; then
if has_standalone; then if has_standalone; then
install_standalone install_standalone
echo_coder_postinstall
exit 0 exit 0
else else
echoerr "There are no standalone releases for $ARCH" echoerr "There are no standalone releases for $ARCH"
@ -471,45 +258,42 @@ main() {
fi fi
# DISTRO can be overridden for testing but shouldn't normally be used as it # DISTRO can be overridden for testing but shouldn't normally be used as it
# can result in a broken coder. # can result in a broken code-server.
DISTRO=${DISTRO:-$(distro)} DISTRO=${DISTRO:-$(distro)}
case $DISTRO in case $DISTRO in
darwin) install_macos ;; # macOS uses brew when available and falls back to standalone. We only have
# The .deb and .rpm files are pulled from GitHub. # amd64 for macOS so for anything else use npm.
debian) install_deb ;; macos)
fedora | opensuse) install_rpm ;; BREW_PATH="${BREW_PATH-brew}"
if command_exists "$BREW_PATH"; then
install_brew
else
echoh "Homebrew not installed."
echoh "Falling back to standalone installation."
npm_fallback install_standalone
fi
;;
# The .deb and .rpm files are pulled from GitHub and we only have amd64 and
# arm64 there and need to fall back to npm otherwise.
debian) npm_fallback install_deb ;;
fedora | opensuse) npm_fallback install_rpm ;;
# Arch uses the AUR package which only supports amd64 and arm64 since it
# pulls releases from GitHub so we need to fall back to npm.
arch) npm_fallback install_aur ;;
# We don't have GitHub releases that work on Alpine or FreeBSD so we have no # We don't have GitHub releases that work on Alpine or FreeBSD so we have no
# choice but to use npm here. # choice but to use npm here.
alpine) install_apk ;; alpine | freebsd) install_npm ;;
# For anything else we'll try to install standalone but fall back to npm if # For anything else we'll try to install standalone but fall back to npm if
# we don't have releases for the architecture. # we don't have releases for the architecture.
*) *)
echoh "Unsupported package manager." echoh "Unsupported package manager."
echoh "Falling back to standalone installation." echoh "Falling back to standalone installation."
install_standalone npm_fallback install_standalone
;; ;;
esac esac
if [ "${CAP_NET_ADMIN:-}" ]; then echo_coder_postinstall
cap_net_admin
fi
}
cap_net_admin() {
if ! command_exists setcap && command_exists capsh; then
echo "Package 'libcap' not found. See install instructions for your distro: https://command-not-found.com/setcap"
return
fi
# Make sure we'e allowed to add CAP_NET_ADMIN.
if sudo_sh_c capsh --has-p=CAP_NET_ADMIN; then
sudo_sh_c setcap CAP_NET_ADMIN=+ep "$(command -v coder)" || true
# Unable to escalate perms, notify the user.
else
echo "Unable to setcap agent binary. Ensure the root user has CAP_NET_ADMIN permissions."
fi
} }
parse_arg() { parse_arg() {
@ -562,66 +346,22 @@ fetch() {
sh_c mv "$FILE.incomplete" "$FILE" sh_c mv "$FILE.incomplete" "$FILE"
} }
with_terraform() { install_brew() {
# Check if the unzip package is installed. If not error peacefully. echoh "Installing latest from Homebrew."
if ! (command_exists unzip); then
echoh
echoerr "This script needs the unzip package to run."
echoerr "Please install unzip to use this function"
exit 1
fi
echoh "Installing Terraform version $TERRAFORM_VERSION $TERRAFORM_ARCH from the HashiCorp release repository."
echoh echoh
# Download from official source and save it to cache sh_c "$BREW_PATH" install code-server
fetch "https://releases.hashicorp.com/terraform/${TERRAFORM_VERSION}/terraform_${TERRAFORM_VERSION}_${OS}_${TERRAFORM_ARCH}.zip" \
"$CACHE_DIR/terraform_${TERRAFORM_VERSION}_${OS}_${TERRAFORM_ARCH}.zip"
sh_c mkdir -p "$TERRAFORM_INSTALL_PREFIX" 2>/dev/null || true
sh_c="sh_c"
if [ ! -w "$TERRAFORM_INSTALL_PREFIX" ]; then
sh_c="sudo_sh_c"
fi
# Prepare /usr/local/bin/ and the binary for copying
"$sh_c" mkdir -p "$TERRAFORM_INSTALL_PREFIX/bin"
"$sh_c" unzip -d "$CACHE_DIR" -o "$CACHE_DIR/terraform_${TERRAFORM_VERSION}_${OS}_${ARCH}.zip"
COPY_LOCATION="$TERRAFORM_INSTALL_PREFIX/bin/terraform"
# Remove the file if it already exists to
# avoid https://github.com/coder/coder/issues/2086
if [ -f "$COPY_LOCATION" ]; then
"$sh_c" rm "$COPY_LOCATION"
fi
# Copy the binary to the correct location.
"$sh_c" cp "$CACHE_DIR/terraform" "$COPY_LOCATION"
}
install_macos() {
# If there is no `brew` binary available, just default to installing standalone
if command_exists brew; then
echoh "Installing coder with Homebrew from the coder/coder tap."
echoh
sh_c brew install coder/coder/coder
echo_brew_postinstall echo_brew_postinstall
return
fi
echoh "Homebrew is not available."
echoh "Falling back to standalone installation."
install_standalone
} }
install_deb() { install_deb() {
echoh "Installing v$VERSION of the $ARCH deb package from GitHub." echoh "Installing v$VERSION of the $ARCH deb package from GitHub."
echoh echoh
fetch "https://github.com/coder/coder/releases/download/v$VERSION/coder_${VERSION}_${OS}_${ARCH}.deb" \ fetch "https://github.com/coder/code-server/releases/download/v$VERSION/code-server_${VERSION}_$ARCH.deb" \
"$CACHE_DIR/coder_${VERSION}_$ARCH.deb" "$CACHE_DIR/code-server_${VERSION}_$ARCH.deb"
sudo_sh_c dpkg --force-confdef --force-confold -i "$CACHE_DIR/coder_${VERSION}_$ARCH.deb" sudo_sh_c dpkg -i "$CACHE_DIR/code-server_${VERSION}_$ARCH.deb"
echo_systemd_postinstall deb echo_systemd_postinstall deb
} }
@ -630,79 +370,101 @@ install_rpm() {
echoh "Installing v$VERSION of the $ARCH rpm package from GitHub." echoh "Installing v$VERSION of the $ARCH rpm package from GitHub."
echoh echoh
fetch "https://github.com/coder/coder/releases/download/v$VERSION/coder_${VERSION}_${OS}_${ARCH}.rpm" \ fetch "https://github.com/coder/code-server/releases/download/v$VERSION/code-server-$VERSION-$ARCH.rpm" \
"$CACHE_DIR/coder_${VERSION}_${OS}_${ARCH}.rpm" "$CACHE_DIR/code-server-$VERSION-$ARCH.rpm"
sudo_sh_c rpm -U "$CACHE_DIR/coder_${VERSION}_${OS}_${ARCH}.rpm" sudo_sh_c rpm -U "$CACHE_DIR/code-server-$VERSION-$ARCH.rpm"
echo_systemd_postinstall rpm echo_systemd_postinstall rpm
} }
install_apk() { install_aur() {
echoh "Installing v$VERSION of the $ARCH apk package from GitHub." echoh "Installing latest from the AUR."
echoh echoh
fetch "https://github.com/coder/coder/releases/download/v$VERSION/coder_${VERSION}_${OS}_${ARCH}.apk" \ sh_c mkdir -p "$CACHE_DIR/code-server-aur"
"$CACHE_DIR/coder_${VERSION}_${OS}_${ARCH}.apk" 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"
sudo_sh_c apk add --allow-untrusted "$CACHE_DIR/coder_${VERSION}_${OS}_${ARCH}.apk" echo "+ cd $CACHE_DIR/code-server-aur"
if [ ! "${DRY_RUN-}" ]; then
cd "$CACHE_DIR/code-server-aur"
fi
sh_c makepkg -si --noconfirm
echo_systemd_postinstall apk echo_systemd_postinstall AUR
} }
install_standalone() { install_standalone() {
echoh "Installing v$VERSION of the $ARCH release from GitHub." echoh "Installing v$VERSION of the $ARCH release from GitHub."
echoh echoh
# macOS releases are packaged as .zip fetch "https://ghfast.top/https://github.com/coder/code-server/releases/download/v$VERSION/code-server-$VERSION-$OS-$ARCH.tar.gz" \
case $OS in "$CACHE_DIR/code-server-$VERSION-$OS-$ARCH.tar.gz"
darwin) STANDALONE_ARCHIVE_FORMAT=zip ;;
*) STANDALONE_ARCHIVE_FORMAT=tar.gz ;;
esac
fetch "https://ghfast.top/https://github.com/coder/coder/releases/download/v$VERSION/coder_${VERSION}_${OS}_${ARCH}.$STANDALONE_ARCHIVE_FORMAT" \
"$CACHE_DIR/coder_${VERSION}_${OS}_${ARCH}.$STANDALONE_ARCHIVE_FORMAT"
# -w only works if the directory exists so try creating it first. If this # -w only works if the directory exists so try creating it first. If this
# fails we can ignore the error as the -w check will then swap us to sudo. # fails we can ignore the error as the -w check will then swap us to sudo.
sh_c mkdir -p "$STANDALONE_INSTALL_PREFIX" 2>/dev/null || true sh_c mkdir -p "$STANDALONE_INSTALL_PREFIX" 2> /dev/null || true
sh_c mkdir -p "$CACHE_DIR/tmp"
if [ "$STANDALONE_ARCHIVE_FORMAT" = tar.gz ]; then
sh_c tar -C "$CACHE_DIR/tmp" -xzf "$CACHE_DIR/coder_${VERSION}_${OS}_${ARCH}.tar.gz"
else
sh_c unzip -d "$CACHE_DIR/tmp" -o "$CACHE_DIR/coder_${VERSION}_${OS}_${ARCH}.zip"
fi
STANDALONE_BINARY_LOCATION="$STANDALONE_INSTALL_PREFIX/bin/$STANDALONE_BINARY_NAME"
sh_c="sh_c" sh_c="sh_c"
if [ ! -w "$STANDALONE_INSTALL_PREFIX" ]; then if [ ! -w "$STANDALONE_INSTALL_PREFIX" ]; then
sh_c="sudo_sh_c" sh_c="sudo_sh_c"
fi fi
"$sh_c" mkdir -p "$STANDALONE_INSTALL_PREFIX/bin" if [ -e "$STANDALONE_INSTALL_PREFIX/lib/code-server-$VERSION" ]; then
echoh
# Remove the file if it already exists to echoh "code-server-$VERSION is already installed at $STANDALONE_INSTALL_PREFIX/lib/code-server-$VERSION"
# avoid https://github.com/coder/coder/issues/2086 echoh "Remove it to reinstall."
if [ -f "$STANDALONE_BINARY_LOCATION" ]; then exit 0
"$sh_c" rm "$STANDALONE_BINARY_LOCATION"
fi fi
# Copy the binary to the correct location. "$sh_c" mkdir -p "$STANDALONE_INSTALL_PREFIX/lib" "$STANDALONE_INSTALL_PREFIX/bin"
"$sh_c" cp "$CACHE_DIR/tmp/coder" "$STANDALONE_BINARY_LOCATION" "$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"
# Clean up the extracted files (note, not using sudo: $sh_c -> sh_c). "$sh_c" ln -fs "$STANDALONE_INSTALL_PREFIX/lib/code-server-$VERSION/bin/code-server" "$STANDALONE_INSTALL_PREFIX/bin/code-server"
sh_c rm -rv "$CACHE_DIR/tmp"
echo_standalone_postinstall echo_standalone_postinstall
} }
install_npm() {
echoh "Installing v$VERSION from npm."
echoh
NPM_PATH="${YARN_PATH-npm}"
if command_exists "$NPM_PATH"; then
sh_c="sh_c"
if [ ! "${DRY_RUN-}" ] && [ ! -w "$(NPM_PATH config get prefix)" ]; then
sh_c="sudo_sh_c"
fi
echoh "Installing with npm."
echoh
"$sh_c" "$NPM_PATH" install -g "code-server@$VERSION" --unsafe-perm
NPM_BIN_DIR="\$($NPM_PATH bin -g)" echo_npm_postinstall
return
fi
echoerr "Please install npm to install code-server!"
echoerr "You will need at least node v20 and a few C dependencies."
echoerr "See the docs https://coder.com/docs/code-server/latest/install#npm"
exit 1
}
# Run $1 if we have a standalone otherwise run install_npm.
npm_fallback() {
if has_standalone; then
$1
else
echoh "No standalone releases for $ARCH."
echoh "Falling back to installation from npm."
install_npm
fi
}
# Determine if we have standalone releases on GitHub for the system's arch. # Determine if we have standalone releases on GitHub for the system's arch.
has_standalone() { has_standalone() {
case $ARCH in case $ARCH in
amd64) return 0 ;;
arm64) return 0 ;; arm64) return 0 ;;
armv7) # We only have arm64 for macOS.
[ "$(distro)" != darwin ] amd64)
[ "$(distro)" != macos ]
return return
;; ;;
*) return 1 ;; *) return 1 ;;
@ -713,7 +475,7 @@ os() {
uname="$(uname)" uname="$(uname)"
case $uname in case $uname in
Linux) echo linux ;; Linux) echo linux ;;
Darwin) echo darwin ;; Darwin) echo macos ;;
FreeBSD) echo freebsd ;; FreeBSD) echo freebsd ;;
*) echo "$uname" ;; *) echo "$uname" ;;
esac esac
@ -722,28 +484,27 @@ os() {
# Print the detected Linux distro, otherwise print the OS name. # Print the detected Linux distro, otherwise print the OS name.
# #
# Example outputs: # Example outputs:
# - darwin -> darwin # - macos -> macos
# - freebsd -> freebsd # - freebsd -> freebsd
# - ubuntu, raspbian, debian ... -> debian # - ubuntu, raspbian, debian ... -> debian
# - amzn, centos, rhel, fedora, ... -> fedora # - amzn, centos, rhel, fedora, ... -> fedora
# - opensuse-{leap,tumbleweed} -> opensuse # - opensuse-{leap,tumbleweed} -> opensuse
# - alpine -> alpine # - alpine -> alpine
# - arch -> arch # - arch, manjaro, endeavouros, ... -> arch
# #
# Inspired by https://github.com/docker/docker-install/blob/26ff363bcf3b3f5a00498ac43694bf1c7d9ce16c/install.sh#L111-L120. # Inspired by https://github.com/docker/docker-install/blob/26ff363bcf3b3f5a00498ac43694bf1c7d9ce16c/install.sh#L111-L120.
distro() { distro() {
if [ "$OS" = "darwin" ] || [ "$OS" = "freebsd" ]; then if [ "$OS" = "macos" ] || [ "$OS" = "freebsd" ]; then
echo "$OS" echo "$OS"
return return
fi fi
if [ -f /etc/os-release ]; then if [ -f /etc/os-release ]; then
( (
# shellcheck disable=SC1091
. /etc/os-release . /etc/os-release
if [ "${ID_LIKE-}" ]; then if [ "${ID_LIKE-}" ]; then
for id_like in $ID_LIKE; do for id_like in $ID_LIKE; do
case "$id_like" in debian | fedora | opensuse) case "$id_like" in debian | fedora | opensuse | arch)
echo "$id_like" echo "$id_like"
return return
;; ;;
@ -766,7 +527,6 @@ distro_name() {
if [ -f /etc/os-release ]; then if [ -f /etc/os-release ]; then
( (
# shellcheck disable=SC1091
. /etc/os-release . /etc/os-release
echo "$PRETTY_NAME" echo "$PRETTY_NAME"
) )
@ -782,26 +542,13 @@ arch() {
case $uname_m in case $uname_m in
aarch64) echo arm64 ;; aarch64) echo arm64 ;;
x86_64) echo amd64 ;; x86_64) echo amd64 ;;
armv7l) echo armv7 ;;
*) echo "$uname_m" ;;
esac
}
# The following is to change the naming, that way people with armv7 won't receive a error
# List of binaries can be found here: https://releases.hashicorp.com/terraform/
terraform_arch() {
uname_m=$(uname -m)
case $uname_m in
aarch64) echo arm64 ;;
x86_64) echo amd64 ;;
armv7l) echo arm ;;
*) echo "$uname_m" ;; *) echo "$uname_m" ;;
esac esac
} }
command_exists() { command_exists() {
if [ ! "$1" ]; then return 1; fi if [ ! "$1" ]; then return 1; fi
command -v "$@" >/dev/null command -v "$@" > /dev/null
} }
sh_c() { sh_c() {
@ -814,28 +561,28 @@ sh_c() {
sudo_sh_c() { sudo_sh_c() {
if [ "$(id -u)" = 0 ]; then if [ "$(id -u)" = 0 ]; then
sh_c "$@" sh_c "$@"
elif command_exists sudo; then
sh_c "sudo $*"
elif command_exists doas; then elif command_exists doas; then
sh_c "doas $*" sh_c "doas $*"
elif command_exists sudo; then
sh_c "sudo $*"
elif command_exists su; then elif command_exists su; then
sh_c "su - -c '$*'" sh_c "su root -c '$*'"
else else
echoh echoh
echoerr "This script needs to run the following command as root." echoerr "This script needs to run the following command as root."
echoerr " $*" echoerr " $*"
echoerr "Please install sudo, su, or doas." echoerr "Please install doas, sudo, or su."
exit 1 exit 1
fi fi
} }
echo_cache_dir() { echo_cache_dir() {
if [ "${XDG_CACHE_HOME-}" ]; then if [ "${XDG_CACHE_HOME-}" ]; then
echo "$XDG_CACHE_HOME/coder" echo "$XDG_CACHE_HOME/code-server"
elif [ "${HOME-}" ]; then elif [ "${HOME-}" ]; then
echo "$HOME/.cache/coder" echo "$HOME/.cache/code-server"
else else
echo "/tmp/coder-cache" echo "/tmp/code-server-cache"
fi fi
} }
@ -865,7 +612,7 @@ prefix() {
fifo="$(mktemp -d)/fifo" fifo="$(mktemp -d)/fifo"
mkfifo "$fifo" mkfifo "$fifo"
sed -e "s#^#$PREFIX: #" "$fifo" & sed -e "s#^#$PREFIX: #" "$fifo" &
"$@" >"$fifo" 2>&1 "$@" > "$fifo" 2>&1
} }
main "$@" main "$@"