mirror of https://github.com/coder/coder.git
feat: one-line install script (#1924)
* feat: one-line install script * remove homebrew support * remove arch linux * use proper filename for packages * fix variable format * fix systemd instructions * fixes to standalone script * fix missing var bugs * fix standalone install * fix for MacOS * format * fix armv7 assets and zips * remove windows * update install docs * support external sources with shellcheck * shfmt * add external sources to GitHub action & unfold * change wording * first template docs * default to /usr/local instead * add option for binary name
This commit is contained in:
parent
f5a8d17aa8
commit
46ffb67d60
|
@ -52,6 +52,8 @@ jobs:
|
|||
- uses: actions/checkout@v3
|
||||
- name: Run ShellCheck
|
||||
uses: ludeeus/action-shellcheck@1.1.0
|
||||
env:
|
||||
SHELLCHECK_OPTS: --external-sources
|
||||
with:
|
||||
ignore: node_modules
|
||||
|
||||
|
|
2
Makefile
2
Makefile
|
@ -71,7 +71,7 @@ lint/go:
|
|||
# Use shfmt to determine the shell files, takes editorconfig into consideration.
|
||||
lint/shellcheck: $(shell shfmt -f .)
|
||||
@echo "--- shellcheck"
|
||||
shellcheck $(shell shfmt -f .)
|
||||
shellcheck --external-sources $(shell shfmt -f .)
|
||||
|
||||
peerbroker/proto/peerbroker.pb.go: peerbroker/proto/peerbroker.proto
|
||||
protoc \
|
||||
|
|
48
README.md
48
README.md
|
@ -56,47 +56,25 @@ You can use any Web IDE ([code-server](https://github.com/coder/code-server), [p
|
|||
|
||||
## Installing Coder
|
||||
|
||||
We recommend installing [the latest
|
||||
release](https://github.com/coder/coder/releases) on a system with at least 1
|
||||
CPU core and 2 GB RAM:
|
||||
There are a few ways to install Coder: [install script](./docs/install.md#installsh) (macOS, Linux), [docker-compose](./docs/install.md#docker-compose), or [manually](./docs/install.md#manual) via the latest release (macOS, Windows, and Linux).
|
||||
|
||||
1. Download the [release asset](https://github.com/coder/coder/releases) appropriate for your operating system
|
||||
1. Unzip the folder you just downloaded, and move the `coder` executable to a location that's on your `PATH`
|
||||
If you use the install script, you can preview what occurs during the install process:
|
||||
|
||||
```sh
|
||||
# ex. MacOS and Linux
|
||||
mv coder /usr/local/bin
|
||||
```
|
||||
```sh
|
||||
curl -fsSL https://coder.com/install.sh | sh -s -- --dry-run
|
||||
```
|
||||
|
||||
Windows: see [this guide](https://answers.microsoft.com/en-us/windows/forum/all/adding-path-variable/97300613-20cb-4d85-8d0e-cc9d3549ba23) on adding a folder to `PATH`
|
||||
To install, run:
|
||||
|
||||
There are a few ways to run Coder:
|
||||
```sh
|
||||
curl -fsSL https://coder.com/install.sh | sh
|
||||
```
|
||||
|
||||
- To run a **temporary deployment**, start with dev mode (all data is in-memory and destroyed on exit):
|
||||
Once installed, you can run a temporary deployment in dev mode (all data is in-memory and destroyed on exit):
|
||||
|
||||
```bash
|
||||
coder server --dev
|
||||
```
|
||||
|
||||
- To run a **production deployment** with PostgreSQL:
|
||||
|
||||
```bash
|
||||
CODER_PG_CONNECTION_URL="postgres://<username>@<host>/<database>?password=<password>" \
|
||||
coder server
|
||||
```
|
||||
|
||||
- To run as a **system service**, install with `.deb` (Debian, Ubuntu) or `.rpm` (Fedora, CentOS, RHEL, SUSE):
|
||||
|
||||
```bash
|
||||
# Edit the configuration!
|
||||
sudo vim /etc/coder.d/coder.env
|
||||
sudo service coder restart
|
||||
```
|
||||
|
||||
> macOS and Windows users: You'll need to write your own
|
||||
> configuration to run Coder as a system service.
|
||||
|
||||
- See the [installation guide](./docs/install.md) for additional ways to run Coder (e.g., docker-compose)
|
||||
```sh
|
||||
coder server --dev
|
||||
```
|
||||
|
||||
Use `coder --help` to get a complete list of flags and environment variables.
|
||||
|
||||
|
|
116
docs/install.md
116
docs/install.md
|
@ -2,6 +2,58 @@
|
|||
|
||||
This article walks you through the various ways of installing and deploying Coder.
|
||||
|
||||
## install.sh
|
||||
|
||||
The easiest way to install Coder is to use our [install script](https://github.com/coder/coder/main/install.sh) for Linux and macOS. The install script
|
||||
attempts to use the system package manager detection-reference if possible.
|
||||
|
||||
You can preview what occurs during the install process:
|
||||
|
||||
```bash
|
||||
curl -L https://coder.com/install.sh | sh -s -- --dry-run
|
||||
```
|
||||
|
||||
To install, run:
|
||||
|
||||
```bash
|
||||
curl -L https://coder.com/install.sh | sh
|
||||
```
|
||||
|
||||
> If you're concerned about the install script's use of `curl | sh` and the
|
||||
> security implications, please see [this blog
|
||||
> post](https://sandstorm.io/news/2015-09-24-is-curl-bash-insecure-pgp-verified-install)
|
||||
> by [sandstorm.io](https://sandstorm.io).
|
||||
|
||||
You can modify the installation process by including flags. Run the help command for reference:
|
||||
|
||||
```bash
|
||||
curl -L https://coder.com/install.sh | sh -s -- --help
|
||||
```
|
||||
|
||||
## System packages
|
||||
|
||||
Coder publishes the following system packages [in GitHub releases](https://github.com/coder/coder/releases):
|
||||
|
||||
- .deb (Debian, Ubuntu)
|
||||
- .rpm (Fedora, CentOS, RHEL, SUSE)
|
||||
- .apk (Alpine)
|
||||
|
||||
Once installed, you can run Coder as a system service:
|
||||
|
||||
```sh
|
||||
# Specify a PostgreSQL database
|
||||
# in the configuration first:
|
||||
sudo vim /etc/coder.d/coder.env
|
||||
sudo service coder restart
|
||||
```
|
||||
|
||||
Or run a **temporary deployment** with dev mode (all data is in-memory and destroyed on exit):
|
||||
|
||||
|
||||
```sh
|
||||
coder server --dev
|
||||
```
|
||||
|
||||
## docker-compose
|
||||
|
||||
Before proceeding, please ensure that you have both Docker and the [latest version of
|
||||
|
@ -40,62 +92,34 @@ Coder](https://github.com/coder/coder/releases) installed.
|
|||
ghcr.io/coder/coder:v0.5.10
|
||||
```
|
||||
|
||||
1. Open a new terminal window, and run `coder login <yourAccessURL>` to create
|
||||
your first user (once you've done so, you can navigate to `yourAccessURL` and
|
||||
log in with these credentials).
|
||||
1. Follow the on-screen instructions to create your first template and workspace
|
||||
|
||||
1. Next, copy a sample template into a new directory so that you can create a custom template in a
|
||||
subsequent step (be sure that you're working in the directory where you want
|
||||
your templates stored):
|
||||
## Manual
|
||||
|
||||
```console
|
||||
coder templates init
|
||||
```
|
||||
We publish self-contained .zip and .tar.gz archives in [GitHub releases](https://github.com/coder/coder/releases). The archives bundle `coder` binary.
|
||||
|
||||
Choose the "Develop in Docker" example to generate a sample template in the
|
||||
`docker` subdirectory.
|
||||
1. Download the [release archive](https://github.com/coder/coder/releases) appropriate for your operating system
|
||||
|
||||
1. Navigate into the new directory and create a new template:
|
||||
1. Unzip the folder you just downloaded, and move the `coder` executable to a location that's on your `PATH`
|
||||
|
||||
```console
|
||||
cd docker
|
||||
coder templates create
|
||||
```sh
|
||||
# ex. MacOS and Linux
|
||||
mv coder /usr/local/bin
|
||||
```
|
||||
|
||||
Follow the prompts displayed to proceed. When done, you'll see the following
|
||||
message:
|
||||
> Windows users: see [this guide](https://answers.microsoft.com/en-us/windows/forum/all/adding-path-variable/97300613-20cb-4d85-8d0e-cc9d3549ba23) for adding folders to `PATH`.
|
||||
|
||||
```console
|
||||
The docker template has been created! Developers can
|
||||
provision a workspace with this template using:
|
||||
1. Start a Coder server
|
||||
|
||||
coder create --template="docker" [workspace name]
|
||||
To run a **temporary deployment**, start with dev mode (all data is in-memory and destroyed on exit):
|
||||
|
||||
```bash
|
||||
coder server --dev
|
||||
```
|
||||
|
||||
1. At this point, you're ready to provision your first workspace:
|
||||
To run a **production deployment** with PostgreSQL:
|
||||
|
||||
```console
|
||||
coder create --template="docker" [workspace name]
|
||||
```bash
|
||||
CODER_PG_CONNECTION_URL="postgres://<username>@<host>/<database>?password=<password>" \
|
||||
coder server
|
||||
```
|
||||
|
||||
Follow the on-screen prompts to set the parameters for your workspace. If
|
||||
the process is successful, you'll get information regarding your workspace:
|
||||
|
||||
```console
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ RESOURCE STATUS ACCESS │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ docker_container.workspace ephemeral │
|
||||
│ └─ dev (linux, amd64) ⦾ connecting [0s] coder ssh main │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ docker_volume.coder_volume ephemeral │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
The main workspace has been created!
|
||||
```
|
||||
|
||||
You can now access your workspace via your web browser by navigating to your
|
||||
access URL, or you can connect to it via SSH by running:
|
||||
|
||||
```console
|
||||
coder ssh [workspace name]
|
||||
```
|
||||
|
|
|
@ -0,0 +1,555 @@
|
|||
#!/bin/sh
|
||||
set -eu
|
||||
|
||||
# Coder's automatic install script.
|
||||
# See https://github.com/coder/coder#installing-coder
|
||||
|
||||
usage() {
|
||||
arg0="$0"
|
||||
if [ "$0" = sh ]; then
|
||||
arg0="curl -fsSL https://coder.com/install.sh | sh -s --"
|
||||
else
|
||||
not_curl_usage="The latest script is available at https://coder.com/install.sh
|
||||
"
|
||||
fi
|
||||
|
||||
cath <<EOF
|
||||
Installs Coder.
|
||||
It tries to use the system package manager if possible.
|
||||
After successful installation it explains how to start Coder.
|
||||
|
||||
Pass in user@host to install Coder on user@host over ssh.
|
||||
The remote host must have internet access.
|
||||
${not_curl_usage-}
|
||||
Usage:
|
||||
|
||||
$arg0 [--dry-run] [--version X.X.X] [--edge] [--method detect] \
|
||||
[--prefix ~/.local] [--rsh ssh] [user@host]
|
||||
|
||||
--dry-run
|
||||
Echo the commands for the install process without running them.
|
||||
|
||||
--version X.X.X
|
||||
Install a specific version instead of the latest.
|
||||
|
||||
--edge
|
||||
Install the latest edge version instead of the latest stable version.
|
||||
|
||||
--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 /usr/local/bin
|
||||
|
||||
--prefix <dir>
|
||||
Sets the prefix used by standalone release archives. Defaults to /usr/local
|
||||
and the binary is copied into /usr/local/bin
|
||||
To install in \$HOME, pass ---prefix=\$HOME/.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>
|
||||
Specifies the remote shell for remote installation. Defaults to ssh.
|
||||
|
||||
The detection method works as follows:
|
||||
- Debian, Ubuntu, Raspbian: install the deb package from GitHub.
|
||||
- Fedora, CentOS, RHEL, openSUSE: install the rpm package from GitHub.
|
||||
- Alpine: install the apk package from GitHub.
|
||||
- macOS: install the release from GitHub.
|
||||
- All others: install the release from GitHub.
|
||||
|
||||
We build releases on GitHub for amd64, armv7, and arm64 on Windows, Linux, and macOS.
|
||||
|
||||
When the detection method tries to pull a release from GitHub it will
|
||||
fall back to installing standalone when there is no matching release for
|
||||
the system's operating system and architecture.
|
||||
|
||||
The installer will cache all downloaded assets into ~/.cache/coder
|
||||
EOF
|
||||
}
|
||||
|
||||
echo_latest_version() {
|
||||
if [ "${EDGE-}" ]; then
|
||||
version="$(curl -fsSL https://api.github.com/repos/coder/coder/releases | awk 'match($0,/.*"html_url": "(.*\/releases\/tag\/.*)".*/)' | head -n 1 | awk -F '"' '{print $4}')"
|
||||
else
|
||||
# https://gist.github.com/lukechilds/a83e1d7127b78fef38c2914c4ececc3c#gistcomment-2758860
|
||||
version="$(curl -fsSLI -o /dev/null -w "%{url_effective}" https://github.com/coder/coder/releases/latest)"
|
||||
fi
|
||||
version="${version#https://github.com/coder/coder/releases/tag/}"
|
||||
version="${version#v}"
|
||||
echo "$version"
|
||||
}
|
||||
|
||||
echo_standalone_postinstall() {
|
||||
cath <<EOF
|
||||
Standalone release has been installed into $STANDALONE_INSTALL_PREFIX/bin/$STANDALONE_BINARY_NAME
|
||||
|
||||
EOF
|
||||
|
||||
if [ "$STANDALONE_INSTALL_PREFIX" != /usr/local ]; then
|
||||
cath <<EOF
|
||||
Extend your path to use Coder:
|
||||
PATH="$STANDALONE_INSTALL_PREFIX/bin:\$PATH"
|
||||
|
||||
EOF
|
||||
fi
|
||||
cath <<EOF
|
||||
Run Coder (temporary):
|
||||
$STANDALONE_BINARY_NAME server --dev
|
||||
|
||||
Or run a production deployment with PostgreSQL:
|
||||
CODER_PG_CONNECTION_URL="postgres://<username>@<host>/<database>?password=<password>" \\
|
||||
$STANDALONE_BINARY_NAME server
|
||||
|
||||
EOF
|
||||
}
|
||||
|
||||
echo_systemd_postinstall() {
|
||||
echoh
|
||||
cath <<EOF
|
||||
$1 package has been installed.
|
||||
|
||||
To run Coder as a system service:
|
||||
|
||||
# Configure the PostgreSQL database for Coder
|
||||
sudo vim /etc/coder.d/coder.env
|
||||
# Have systemd start Coder now and restart on boot
|
||||
sudo systemctl enable --now coder
|
||||
|
||||
Or, run a temporary deployment (all data is in-memory
|
||||
and destroyed on exit):
|
||||
|
||||
coder server --dev
|
||||
|
||||
EOF
|
||||
}
|
||||
|
||||
main() {
|
||||
if [ "${TRACE-}" ]; then
|
||||
set -x
|
||||
fi
|
||||
|
||||
unset \
|
||||
DRY_RUN \
|
||||
METHOD \
|
||||
OPTIONAL \
|
||||
ALL_FLAGS \
|
||||
RSH_ARGS \
|
||||
EDGE \
|
||||
RSH
|
||||
|
||||
ALL_FLAGS=""
|
||||
while [ "$#" -gt 0 ]; do
|
||||
case "$1" in
|
||||
-*)
|
||||
ALL_FLAGS="${ALL_FLAGS} $1"
|
||||
;;
|
||||
esac
|
||||
|
||||
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 "$@")"
|
||||
;;
|
||||
--binary-name)
|
||||
STANDALONE_BINARY_NAME="$(parse_arg "$@")"
|
||||
shift
|
||||
;;
|
||||
--binary-name=*)
|
||||
STANDALONE_BINARY_NAME="$(parse_arg "$@")"
|
||||
;;
|
||||
--version)
|
||||
VERSION="$(parse_arg "$@")"
|
||||
shift
|
||||
;;
|
||||
--version=*)
|
||||
VERSION="$(parse_arg "$@")"
|
||||
;;
|
||||
--edge)
|
||||
EDGE=1
|
||||
;;
|
||||
--rsh)
|
||||
RSH="$(parse_arg "$@")"
|
||||
shift
|
||||
;;
|
||||
--rsh=*)
|
||||
RSH="$(parse_arg "$@")"
|
||||
;;
|
||||
-h | --h | -help | --help)
|
||||
usage
|
||||
exit 0
|
||||
;;
|
||||
--)
|
||||
shift
|
||||
# We remove the -- added above.
|
||||
ALL_FLAGS="${ALL_FLAGS% --}"
|
||||
RSH_ARGS="$*"
|
||||
break
|
||||
;;
|
||||
-*)
|
||||
echoerr "Unknown flag $1"
|
||||
echoerr "Run with --help to see usage."
|
||||
exit 1
|
||||
;;
|
||||
*)
|
||||
RSH_ARGS="$*"
|
||||
break
|
||||
;;
|
||||
esac
|
||||
|
||||
shift
|
||||
done
|
||||
|
||||
if [ "${RSH_ARGS-}" ]; then
|
||||
RSH="${RSH-ssh}"
|
||||
echoh "Installing remotely with $RSH $RSH_ARGS"
|
||||
curl -fsSL https://coder.dev/install.sh | prefix "$RSH_ARGS" "$RSH" "$RSH_ARGS" sh -s -- "$ALL_FLAGS"
|
||||
return
|
||||
fi
|
||||
|
||||
METHOD="${METHOD-detect}"
|
||||
if [ "$METHOD" != detect ] && [ "$METHOD" != standalone ]; then
|
||||
echoerr "Unknown install method \"$METHOD\""
|
||||
echoerr "Run with --help to see usage."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# These are used by the various install_* functions that make use of GitHub
|
||||
# releases in order to download and unpack the right release.
|
||||
CACHE_DIR=$(echo_cache_dir)
|
||||
STANDALONE_INSTALL_PREFIX=${STANDALONE_INSTALL_PREFIX:-/usr/local}
|
||||
STANDALONE_BINARY_NAME=${STANDALONE_BINARY_NAME:-coder}
|
||||
VERSION=${VERSION:-$(echo_latest_version)}
|
||||
# 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)}
|
||||
|
||||
distro_name
|
||||
|
||||
# Standalone installs by pulling pre-built releases from GitHub.
|
||||
if [ "$METHOD" = standalone ]; then
|
||||
if has_standalone; then
|
||||
install_standalone
|
||||
exit 0
|
||||
else
|
||||
echoerr "There are no standalone releases for $ARCH"
|
||||
echoerr "Please try again without '--method standalone'"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# DISTRO can be overridden for testing but shouldn't normally be used as it
|
||||
# can result in a broken coder.
|
||||
DISTRO=${DISTRO:-$(distro)}
|
||||
|
||||
case $DISTRO in
|
||||
# macOS uses the standalone installation for now.
|
||||
# Homebrew support is planned. See: https://github.com/coder/coder/issues/1925
|
||||
macos) install_standalone ;;
|
||||
# The .deb and .rpm files are pulled from GitHub.
|
||||
debian) install_deb ;;
|
||||
fedora | opensuse) install_rpm ;;
|
||||
# We don't have GitHub releases that work on Alpine or FreeBSD so we have no
|
||||
# choice but to use npm here.
|
||||
alpine) install_apk ;;
|
||||
# For anything else we'll try to install standalone but fall back to npm if
|
||||
# we don't have releases for the architecture.
|
||||
*)
|
||||
echoh "Unsupported package manager."
|
||||
echoh "Falling back to standalone installation."
|
||||
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 $FILE"
|
||||
return
|
||||
fi
|
||||
|
||||
sh_c mkdir -p "$CACHE_DIR"
|
||||
sh_c curl \
|
||||
-#fL \
|
||||
-o "$FILE.incomplete" \
|
||||
-C - \
|
||||
"$URL"
|
||||
sh_c mv "$FILE.incomplete" "$FILE"
|
||||
}
|
||||
|
||||
install_deb() {
|
||||
echoh "Installing v$VERSION of the $ARCH deb package from GitHub."
|
||||
echoh
|
||||
|
||||
fetch "https://github.com/coder/coder/releases/download/v$VERSION/coder_${VERSION}_${OS}_${ARCH}.deb" \
|
||||
"$CACHE_DIR/coder_${VERSION}_$ARCH.deb"
|
||||
sudo_sh_c dpkg -i "$CACHE_DIR/coder_${VERSION}_$ARCH.deb"
|
||||
|
||||
echo_systemd_postinstall deb
|
||||
}
|
||||
|
||||
install_rpm() {
|
||||
echoh "Installing v$VERSION of the $ARCH rpm package from GitHub."
|
||||
echoh
|
||||
|
||||
fetch "https://github.com/coder/coder/releases/download/v$VERSION/coder_${VERSION}_${OS}_${ARCH}.rpm" \
|
||||
"$CACHE_DIR/coder_${VERSION}_${OS}_${ARCH}.rpm"
|
||||
sudo_sh_c rpm -i "$CACHE_DIR/coder_${VERSION}_${OS}_${ARCH}.rpm"
|
||||
|
||||
echo_systemd_postinstall rpm
|
||||
}
|
||||
|
||||
install_apk() {
|
||||
echoh "Installing v$VERSION of the $ARCH apk package from GitHub."
|
||||
echoh
|
||||
|
||||
fetch "https://github.com/coder/coder/releases/download/v$VERSION/coder_${VERSION}_${OS}_${ARCH}.apk" \
|
||||
"$CACHE_DIR/coder_${VERSION}_${OS}_${ARCH}.apk"
|
||||
sudo_sh_c apk add --allow-untrusted "$CACHE_DIR/coder_${VERSION}_${OS}_${ARCH}.apk"
|
||||
|
||||
echo_systemd_postinstall apk
|
||||
}
|
||||
|
||||
install_standalone() {
|
||||
echoh "Installing v$VERSION of the $ARCH release from GitHub."
|
||||
echoh
|
||||
|
||||
# MacOS releases are packaged as .zip
|
||||
case $OS in
|
||||
darwin) STANDALONE_ARCHIVE_FORMAT=zip ;;
|
||||
*) STANDALONE_ARCHIVE_FORMAT=tar.gz ;;
|
||||
esac
|
||||
|
||||
fetch "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
|
||||
# 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="sh_c"
|
||||
if [ ! -w "$STANDALONE_INSTALL_PREFIX" ]; then
|
||||
sh_c="sudo_sh_c"
|
||||
fi
|
||||
|
||||
"$sh_c" mkdir -p "$STANDALONE_INSTALL_PREFIX/bin"
|
||||
if [ "$STANDALONE_ARCHIVE_FORMAT" = tar.gz ]; then
|
||||
"$sh_c" tar -C "$CACHE_DIR" -xzf "$CACHE_DIR/coder_${VERSION}_${OS}_${ARCH}.tar.gz"
|
||||
else
|
||||
"$sh_c" unzip -d "$CACHE_DIR" -o "$CACHE_DIR/coder_${VERSION}_${OS}_${ARCH}.zip"
|
||||
fi
|
||||
|
||||
"$sh_c" cp "$CACHE_DIR/coder" "$STANDALONE_INSTALL_PREFIX/bin/$STANDALONE_BINARY_NAME"
|
||||
|
||||
echo_standalone_postinstall
|
||||
}
|
||||
|
||||
# Determine if we have standalone releases on GitHub for the system's arch.
|
||||
has_standalone() {
|
||||
case $ARCH in
|
||||
amd64) return 0 ;;
|
||||
ard64) return 0 ;;
|
||||
armv7)
|
||||
[ "$(distro)" != darwin ]
|
||||
return
|
||||
;;
|
||||
*) return 1 ;;
|
||||
esac
|
||||
}
|
||||
|
||||
os() {
|
||||
uname="$(uname)"
|
||||
case $uname in
|
||||
Linux) echo linux ;;
|
||||
Darwin) echo darwin ;;
|
||||
FreeBSD) echo freebsd ;;
|
||||
*) echo "$uname" ;;
|
||||
esac
|
||||
}
|
||||
|
||||
# Print the detected Linux distro, otherwise print the OS name.
|
||||
#
|
||||
# Example outputs:
|
||||
# - darwin -> darwin
|
||||
# - freebsd -> freebsd
|
||||
# - ubuntu, raspbian, debian ... -> debian
|
||||
# - amzn, centos, rhel, fedora, ... -> fedora
|
||||
# - opensuse-{leap,tumbleweed} -> opensuse
|
||||
# - alpine -> alpine
|
||||
# - arch -> arch
|
||||
#
|
||||
# Inspired by https://github.com/docker/docker-install/blob/26ff363bcf3b3f5a00498ac43694bf1c7d9ce16c/install.sh#L111-L120.
|
||||
distro() {
|
||||
if [ "$OS" = "darwin" ] || [ "$OS" = "freebsd" ]; then
|
||||
echo "$OS"
|
||||
return
|
||||
fi
|
||||
|
||||
if [ -f /etc/os-release ]; then
|
||||
(
|
||||
. /etc/os-release
|
||||
if [ "${ID_LIKE-}" ]; then
|
||||
for id_like in $ID_LIKE; do
|
||||
case "$id_like" in debian | fedora | opensuse)
|
||||
echo "$id_like"
|
||||
return
|
||||
;;
|
||||
esac
|
||||
done
|
||||
fi
|
||||
|
||||
echo "$ID"
|
||||
)
|
||||
return
|
||||
fi
|
||||
}
|
||||
|
||||
# Print a 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() {
|
||||
uname_m=$(uname -m)
|
||||
case $uname_m in
|
||||
aarch64) echo arm64 ;;
|
||||
x86_64) echo amd64 ;;
|
||||
armv7l) echo armv7 ;;
|
||||
*) echo "$uname_m" ;;
|
||||
esac
|
||||
}
|
||||
|
||||
command_exists() {
|
||||
if [ ! "$1" ]; then return 1; fi
|
||||
command -v "$@" >/dev/null
|
||||
}
|
||||
|
||||
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/coder"
|
||||
elif [ "${HOME-}" ]; then
|
||||
echo "$HOME/.cache/coder"
|
||||
else
|
||||
echo "/tmp/coder-cache"
|
||||
fi
|
||||
}
|
||||
|
||||
echoh() {
|
||||
echo "$@" | humanpath
|
||||
}
|
||||
|
||||
cath() {
|
||||
humanpath
|
||||
}
|
||||
|
||||
echoerr() {
|
||||
echoh "$@" >&2
|
||||
}
|
||||
|
||||
# humanpath replaces all occurrences of " $HOME" with " ~"
|
||||
# and all occurrences of '"$HOME' with the literal '"$HOME'.
|
||||
humanpath() {
|
||||
sed "s# $HOME# ~#g; s#\"$HOME#\"\$HOME#g"
|
||||
}
|
||||
|
||||
# We need to make sure we exit with a non zero exit if the command fails.
|
||||
# /bin/sh does not support -o pipefail unfortunately.
|
||||
prefix() {
|
||||
PREFIX="$1"
|
||||
shift
|
||||
fifo="$(mktemp -d)/fifo"
|
||||
mkfifo "$fifo"
|
||||
sed -e "s#^#$PREFIX: #" "$fifo" &
|
||||
"$@" >"$fifo" 2>&1
|
||||
}
|
||||
|
||||
main "$@"
|
Loading…
Reference in New Issue