2020-05-20 11:50:16 +03:00
|
|
|
#!/bin/sh
|
|
|
|
set -eu
|
|
|
|
|
|
|
|
usage() {
|
2020-05-21 23:45:31 +03:00
|
|
|
cli="$0"
|
|
|
|
if [ "$0" = sh ]; then
|
|
|
|
cli="curl -fsSL https://code-server.dev/install.sh | sh -s --"
|
|
|
|
else
|
|
|
|
curl_usage="$(
|
|
|
|
cat << EOF
|
|
|
|
|
|
|
|
To use latest:
|
|
|
|
|
|
|
|
curl -fsSL https://code-server.dev/install.sh | sh -s -- <args>
|
|
|
|
EOF
|
|
|
|
)"$"\n"
|
|
|
|
fi
|
2020-05-21 22:34:34 +03:00
|
|
|
cat << EOF
|
2020-05-21 23:45:31 +03:00
|
|
|
Installs latest code-server on Linux or macOS preferring to use the system package manager.
|
2020-05-20 11:50:16 +03:00
|
|
|
|
2020-05-21 23:45:31 +03:00
|
|
|
Lives at https://code-server.dev/install.sh
|
2020-05-20 11:50:16 +03:00
|
|
|
|
2020-05-21 23:45:31 +03:00
|
|
|
Usage:
|
2020-05-20 11:50:16 +03:00
|
|
|
|
2020-05-21 23:45:31 +03:00
|
|
|
$cli [--dry-run] [--version X.X.X] [--static <install-prefix>=~/.local]
|
|
|
|
${curl_usage-}
|
2020-05-21 22:17:02 +03:00
|
|
|
- For Debian, Ubuntu, Raspbian it will install the latest deb package.
|
|
|
|
- For Fedora, CentOS, RHEL, 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 static release into ~/.local
|
|
|
|
- Add ~/.local/bin to your \$PATH to run code-server.
|
2020-05-20 11:50:16 +03:00
|
|
|
|
2020-05-21 22:17:02 +03:00
|
|
|
- For macOS it will install the Homebrew package.
|
|
|
|
- If Homebrew is not installed it will install the latest static release into ~/.local
|
|
|
|
- Add ~/.local/bin to your \$PATH to run code-server.
|
2020-05-20 11:50:16 +03:00
|
|
|
|
2020-05-21 23:45:31 +03:00
|
|
|
- If ran on an architecture with no binary releases, it will install the npm package with yarn or npm.
|
2020-05-21 22:17:02 +03:00
|
|
|
- We only have binary releases for amd64 and arm64 presently.
|
2020-05-20 11:50:16 +03:00
|
|
|
|
2020-05-21 22:17:02 +03:00
|
|
|
--dry-run Enables a dry run where where the steps that would have taken place
|
|
|
|
are printed but do not actually execute.
|
2020-05-20 11:50:16 +03:00
|
|
|
|
2020-05-21 22:17:02 +03:00
|
|
|
--version Pass to install a specific version instead of the latest release.
|
2020-05-20 11:50:16 +03:00
|
|
|
|
2020-05-21 22:17:02 +03:00
|
|
|
--static Forces the installation of a static release into ~/.local
|
2020-05-20 11:50:16 +03:00
|
|
|
|
2020-05-21 22:17:02 +03:00
|
|
|
This flag takes an optional argument for the installation prefix which defaults to "~/.local".
|
|
|
|
code-server will be unarchived into ~/.local/lib/code-server.X.X.X and the binary will be symlinked
|
|
|
|
into "~/.local/bin/code-server". You will need to add ~/.local/bin to your \$PATH to use it without
|
|
|
|
the full path.
|
2020-05-20 11:50:16 +03:00
|
|
|
|
2020-05-21 22:17:02 +03:00
|
|
|
To install system wide set the prefix to /usr/local.
|
2020-05-20 11:50:16 +03:00
|
|
|
EOF
|
2020-05-21 22:17:02 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
echo_latest_version() {
|
2020-05-21 23:45:31 +03:00
|
|
|
# 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}"
|
2020-05-21 22:17:02 +03:00
|
|
|
echo "$version"
|
2020-05-20 11:50:16 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
echo_static_postinstall() {
|
|
|
|
echo
|
2020-05-21 22:34:34 +03:00
|
|
|
cat << EOF
|
|
|
|
Static release has been installed into $STATIC_INSTALL_PREFIX/lib/code-server-$VERSION
|
2020-05-20 11:50:16 +03:00
|
|
|
Please extend your path to use code-server:
|
2020-05-21 22:34:34 +03:00
|
|
|
PATH="$STATIC_INSTALL_PREFIX/bin:\$PATH"
|
2020-05-20 11:50:16 +03:00
|
|
|
Then you can run:
|
|
|
|
code-server
|
|
|
|
EOF
|
|
|
|
}
|
|
|
|
|
|
|
|
echo_systemd_postinstall() {
|
|
|
|
echo
|
2020-05-21 22:34:34 +03:00
|
|
|
cat << EOF
|
2020-05-20 11:50:16 +03:00
|
|
|
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() {
|
2020-05-21 22:17:02 +03:00
|
|
|
if [ "${TRACE-}" ]; then
|
|
|
|
set -x
|
|
|
|
fi
|
|
|
|
|
|
|
|
unset \
|
|
|
|
DRY_RUN \
|
|
|
|
STATIC \
|
|
|
|
STATIC_INSTALL_PREFIX \
|
2020-05-21 22:34:34 +03:00
|
|
|
SKIP_ECHO \
|
2020-05-21 22:17:02 +03:00
|
|
|
VERSION \
|
|
|
|
OPTIONAL
|
|
|
|
|
|
|
|
while [ "$#" -gt 0 ]; do
|
|
|
|
case "$1" in
|
|
|
|
--dry-run)
|
|
|
|
DRY_RUN=1
|
|
|
|
;;
|
|
|
|
--static)
|
|
|
|
STATIC=1
|
|
|
|
if [ "${2-}" ]; then
|
|
|
|
STATIC_INSTALL_PREFIX="$(OPTIONAL=1 parse_arg "$@")"
|
|
|
|
shift
|
|
|
|
fi
|
|
|
|
;;
|
|
|
|
--static=*)
|
|
|
|
STATIC=1
|
|
|
|
STATIC_INSTALL_PREFIX="$(OPTIONAL=1 parse_arg "$@")"
|
|
|
|
;;
|
|
|
|
--version)
|
|
|
|
VERSION="$(parse_arg "$@")"
|
|
|
|
shift
|
|
|
|
;;
|
|
|
|
--version=*)
|
|
|
|
VERSION="$(parse_arg "$@")"
|
|
|
|
;;
|
|
|
|
-h | --h | --help)
|
|
|
|
usage
|
|
|
|
exit 0
|
|
|
|
;;
|
|
|
|
*)
|
|
|
|
echoerr "Unknown flag $1"
|
|
|
|
echoerr "Run with --help to see usage."
|
|
|
|
exit 1
|
|
|
|
;;
|
2020-05-20 11:50:16 +03:00
|
|
|
esac
|
2020-05-21 22:17:02 +03:00
|
|
|
|
|
|
|
shift
|
2020-05-20 11:50:16 +03:00
|
|
|
done
|
2020-05-21 22:17:02 +03:00
|
|
|
|
|
|
|
VERSION="${VERSION-$(echo_latest_version)}"
|
2020-05-21 22:34:34 +03:00
|
|
|
STATIC_INSTALL_PREFIX="${STATIC_INSTALL_PREFIX-$HOME/.local}"
|
2020-05-20 11:50:16 +03:00
|
|
|
|
|
|
|
OS="$(os)"
|
|
|
|
if [ ! "$OS" ]; then
|
2020-05-21 22:17:02 +03:00
|
|
|
echoerr "Unsupported OS $(uname)."
|
2020-05-20 11:50:16 +03:00
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
|
|
|
|
distro_name
|
|
|
|
|
|
|
|
ARCH="$(arch)"
|
|
|
|
if [ ! "$ARCH" ]; then
|
|
|
|
if [ "${STATIC-}" ]; then
|
2020-05-21 22:17:02 +03:00
|
|
|
echoerr "No static releases available for the architecture $(uname -m)."
|
|
|
|
echoerr "Please rerun without the -s flag to install from npm."
|
2020-05-20 11:50:16 +03:00
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
install_npm
|
|
|
|
exit 0
|
|
|
|
fi
|
|
|
|
|
2020-05-21 22:34:34 +03:00
|
|
|
CACHE_DIR="$(echo_cache_dir)"
|
2020-05-20 11:50:16 +03:00
|
|
|
mkdir -p "$CACHE_DIR"
|
|
|
|
|
|
|
|
if [ "${STATIC-}" ]; then
|
|
|
|
install_static
|
|
|
|
return
|
|
|
|
fi
|
|
|
|
|
|
|
|
case "$(distro)" in
|
|
|
|
macos)
|
|
|
|
install_macos
|
|
|
|
;;
|
|
|
|
ubuntu | debian | raspbian)
|
|
|
|
install_deb
|
|
|
|
;;
|
|
|
|
centos | fedora | rhel | opensuse)
|
|
|
|
install_rpm
|
|
|
|
;;
|
|
|
|
arch)
|
|
|
|
install_arch
|
|
|
|
;;
|
|
|
|
*)
|
|
|
|
install_static
|
|
|
|
;;
|
|
|
|
|
|
|
|
esac
|
|
|
|
}
|
|
|
|
|
2020-05-21 22:17:02 +03:00
|
|
|
parse_arg() {
|
|
|
|
case "$1" in
|
|
|
|
*=*)
|
|
|
|
opt="${1#=*}"
|
|
|
|
optarg="${1#*=}"
|
2020-05-21 23:45:31 +03:00
|
|
|
if [ ! "$optarg" ] && [ ! "${OPTIONAL-}" ]; then
|
2020-05-21 22:17:02 +03:00
|
|
|
echoerr "$opt requires an argument"
|
|
|
|
echoerr "Run with --help to see usage."
|
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
echo "$optarg"
|
2020-05-20 11:50:16 +03:00
|
|
|
return
|
2020-05-21 22:17:02 +03:00
|
|
|
;;
|
|
|
|
esac
|
2020-05-20 11:50:16 +03:00
|
|
|
|
2020-05-21 22:17:02 +03:00
|
|
|
case "${2-}" in
|
2020-05-21 23:45:31 +03:00
|
|
|
"" | -*)
|
2020-05-21 22:17:02 +03:00
|
|
|
if [ ! "${OPTIONAL-}" ]; then
|
|
|
|
echoerr "$1 requires an argument"
|
|
|
|
echoerr "Run with --help to see usage."
|
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
;;
|
|
|
|
*)
|
|
|
|
echo "$2"
|
|
|
|
return
|
|
|
|
;;
|
|
|
|
esac
|
2020-05-20 11:50:16 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
fetch() {
|
|
|
|
URL="$1"
|
|
|
|
FILE="$2"
|
|
|
|
|
|
|
|
if [ -e "$FILE" ]; then
|
|
|
|
echo
|
|
|
|
echo "+ Using cached $FILE from $URL"
|
|
|
|
return
|
|
|
|
fi
|
|
|
|
|
|
|
|
sh_c curl \
|
|
|
|
-#fL \
|
|
|
|
-Ro "$FILE.incomplete" \
|
|
|
|
-C - \
|
|
|
|
"$URL"
|
2020-05-21 22:34:34 +03:00
|
|
|
SKIP_ECHO=1 sh_c mv "$FILE.incomplete" "$FILE"
|
2020-05-20 11:50:16 +03:00
|
|
|
}
|
|
|
|
|
2020-05-21 22:17:02 +03:00
|
|
|
install_macos() {
|
|
|
|
if command_exists brew; then
|
|
|
|
echo "Installing from Homebrew."
|
|
|
|
|
|
|
|
sh_c brew install code-server
|
|
|
|
|
|
|
|
return
|
|
|
|
fi
|
|
|
|
|
|
|
|
echo "Homebrew is not installed so installing static release."
|
|
|
|
|
|
|
|
install_static
|
|
|
|
}
|
|
|
|
|
2020-05-20 11:50:16 +03:00
|
|
|
install_deb() {
|
|
|
|
echo "Installing v$VERSION deb package from GitHub releases."
|
|
|
|
|
|
|
|
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() {
|
|
|
|
echo "Installing v$VERSION rpm package from GitHub releases."
|
|
|
|
|
|
|
|
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
|
|
|
|
}
|
|
|
|
|
2020-05-21 22:17:02 +03:00
|
|
|
install_aur() {
|
2020-05-20 11:50:16 +03:00
|
|
|
echo "Installing from the AUR."
|
|
|
|
|
|
|
|
fetch "https://aur.archlinux.org/cgit/aur.git/snapshot/code-server.tar.gz" "$CACHE_DIR/code-server-aur.tar.gz"
|
|
|
|
|
|
|
|
tmp_dir="$(mktemp -d)"
|
|
|
|
(
|
|
|
|
cd "$tmp_dir"
|
2020-05-21 22:34:34 +03:00
|
|
|
SKIP_ECHO=1 sh_c tar -xzf "$CACHE_DIR/code-server-aur.tar.gz" --strip-components 1
|
2020-05-20 11:50:16 +03:00
|
|
|
sh_c makepkg -si
|
|
|
|
)
|
|
|
|
rm -Rf "$tmp_dir"
|
|
|
|
|
|
|
|
echo_systemd_postinstall
|
|
|
|
}
|
|
|
|
|
|
|
|
install_static() {
|
|
|
|
STATIC_INSTALL_PREFIX=${STATIC_INSTALL_PREFIX-/usr/local/lib}
|
|
|
|
|
|
|
|
echo "Installing static release v$VERSION"
|
|
|
|
|
|
|
|
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"
|
|
|
|
|
|
|
|
if [ ! -d "$STATIC_INSTALL_PREFIX" ]; then
|
|
|
|
echo
|
2020-05-21 22:17:02 +03:00
|
|
|
echoerr "Static release install prefix $STATIC_INSTALL_PREFIX does not exist"
|
2020-05-20 11:50:16 +03:00
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
|
|
|
|
sh_c="sh_c"
|
|
|
|
if [ ! -w "$STATIC_INSTALL_PREFIX" ]; then
|
|
|
|
sh_c="sudo_sh_c"
|
|
|
|
fi
|
2020-05-21 22:34:34 +03:00
|
|
|
SKIP_ECHO=1 sh_c mkdir -p "$STATIC_INSTALL_PREFIX/lib" "$STATIC_INSTALL_PREFIX/bin"
|
2020-05-20 11:50:16 +03:00
|
|
|
|
2020-05-21 23:45:31 +03:00
|
|
|
if [ -e "$STATIC_INSTALL_PREFIX/lib/code-server-$VERSION" ]; then
|
2020-05-21 22:34:34 +03:00
|
|
|
echo
|
|
|
|
echoerr "code-server-$VERSION is already installed at $STATIC_INSTALL_PREFIX/lib/code-server-$VERSION"
|
|
|
|
echoerr "Please remove it to reinstall."
|
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
"$sh_c" tar -C "$STATIC_INSTALL_PREFIX/lib" -xzf "$CACHE_DIR/code-server-$VERSION-$OS-$ARCH.tar.gz"
|
|
|
|
"$sh_c" mv -f "$STATIC_INSTALL_PREFIX/lib/code-server-$VERSION-$OS-$ARCH" "$STATIC_INSTALL_PREFIX/lib/code-server-$VERSION"
|
2020-05-20 11:50:16 +03:00
|
|
|
|
|
|
|
echo_static_postinstall
|
|
|
|
}
|
|
|
|
|
|
|
|
install_npm() {
|
2020-05-21 22:17:02 +03:00
|
|
|
echoerr "No precompiled releases for $(uname -m)."
|
2020-05-20 11:50:16 +03:00
|
|
|
if command_exists yarn; then
|
|
|
|
echo "Installing with yarn."
|
|
|
|
sh_c yarn global add code-server --unsafe-perm
|
|
|
|
return
|
|
|
|
elif command_exists npm; then
|
|
|
|
echo "Installing with npm."
|
|
|
|
sh_c npm install -g code-server --unsafe-perm
|
|
|
|
return
|
|
|
|
fi
|
2020-05-21 22:17:02 +03:00
|
|
|
echoerr
|
|
|
|
echoerr "Please install npm or yarn to install code-server!"
|
|
|
|
echoerr "You will need at least node v12 and a few C build dependencies."
|
|
|
|
echoerr "See the docs https://github.com/cdr/code-server#yarn-npm"
|
2020-05-20 11:50:16 +03:00
|
|
|
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
|
|
|
|
|
2020-05-21 23:45:31 +03:00
|
|
|
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"
|
|
|
|
)
|
2020-05-20 11:50:16 +03:00
|
|
|
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
|
|
|
|
|
2020-05-21 23:45:31 +03:00
|
|
|
if [ -f /etc/os-release ]; then
|
2020-05-20 11:50:16 +03:00
|
|
|
(
|
|
|
|
. /etc/os-release
|
|
|
|
echo "$PRETTY_NAME"
|
|
|
|
)
|
2020-05-21 23:45:31 +03:00
|
|
|
return
|
2020-05-20 11:50:16 +03:00
|
|
|
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() {
|
2020-05-21 22:34:34 +03:00
|
|
|
command -v "$@" > /dev/null 2>&1
|
2020-05-20 11:50:16 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
sh_c() {
|
2020-05-21 22:34:34 +03:00
|
|
|
if [ ! "${SKIP_ECHO-}" ]; then
|
2020-05-20 11:50:16 +03:00
|
|
|
echo
|
|
|
|
echo "+ $*"
|
|
|
|
fi
|
|
|
|
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
|
|
|
|
echo
|
2020-05-21 22:17:02 +03:00
|
|
|
echoerr "This script needs to run the following command as root."
|
|
|
|
echoerr " $*"
|
|
|
|
echoerr "Please run this script as root or install sudo or su."
|
2020-05-20 11:50:16 +03:00
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
2020-05-21 22:17:02 +03:00
|
|
|
echo_cache_dir() {
|
2020-05-20 11:50:16 +03:00
|
|
|
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
|
|
|
|
}
|
|
|
|
|
2020-05-21 22:17:02 +03:00
|
|
|
echoerr() {
|
|
|
|
echo "$@" >&2
|
|
|
|
}
|
|
|
|
|
2020-05-20 11:50:16 +03:00
|
|
|
main "$@"
|