144 lines
4.0 KiB
Bash
Executable File
144 lines
4.0 KiB
Bash
Executable File
#!/bin/sh
|
|
|
|
set -eu
|
|
|
|
repository_url=${KLINK_REPOSITORY_URL:-https://gitea.bytevibe.dev/gary/klink}
|
|
api_url=${KLINK_API_URL:-https://gitea.bytevibe.dev/api/v1/repos/gary/klink/releases/latest}
|
|
requested_version=${KLINK_VERSION:-}
|
|
install_dir=${KLINK_INSTALL_DIR:-}
|
|
|
|
say() {
|
|
printf '%s\n' "$*"
|
|
}
|
|
|
|
fail() {
|
|
printf 'klink installer: %s\n' "$*" >&2
|
|
exit 1
|
|
}
|
|
|
|
require_command() {
|
|
command -v "$1" >/dev/null 2>&1 || fail "required command not found: $1"
|
|
}
|
|
|
|
fetch_stdout() {
|
|
url=$1
|
|
case "$url" in
|
|
https://*) curl -fsSL --proto '=https' --tlsv1.2 "$url" ;;
|
|
*)
|
|
[ "${KLINK_ALLOW_INSECURE:-}" = "1" ] || fail "refusing non-HTTPS URL: $url"
|
|
curl -fsSL "$url"
|
|
;;
|
|
esac
|
|
}
|
|
|
|
fetch_file() {
|
|
url=$1
|
|
output=$2
|
|
case "$url" in
|
|
https://*) curl -fsSL --proto '=https' --tlsv1.2 -o "$output" "$url" ;;
|
|
*)
|
|
[ "${KLINK_ALLOW_INSECURE:-}" = "1" ] || fail "refusing non-HTTPS URL: $url"
|
|
curl -fsSL -o "$output" "$url"
|
|
;;
|
|
esac
|
|
}
|
|
|
|
require_command curl
|
|
require_command tar
|
|
require_command awk
|
|
require_command sed
|
|
require_command mktemp
|
|
require_command tr
|
|
|
|
if [ -n "${KLINK_OS:-}" ]; then
|
|
target_os=$KLINK_OS
|
|
else
|
|
case "$(uname -s)" in
|
|
Darwin) target_os=darwin ;;
|
|
Linux) target_os=linux ;;
|
|
*) fail "unsupported operating system: $(uname -s)" ;;
|
|
esac
|
|
fi
|
|
|
|
if [ -n "${KLINK_ARCH:-}" ]; then
|
|
machine=$KLINK_ARCH
|
|
else
|
|
machine=$(uname -m)
|
|
fi
|
|
case "$machine" in
|
|
x86_64|amd64) target_arch=amd64 ;;
|
|
arm64|aarch64) target_arch=arm64 ;;
|
|
*) fail "unsupported architecture: $machine" ;;
|
|
esac
|
|
|
|
if [ -n "$requested_version" ]; then
|
|
case "$requested_version" in
|
|
v*) tag=$requested_version ;;
|
|
*) tag=v$requested_version ;;
|
|
esac
|
|
else
|
|
release_json=$(fetch_stdout "$api_url") || fail "could not read the latest Gitea release"
|
|
tag=$(printf '%s' "$release_json" | sed -n 's/.*"tag_name"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p')
|
|
[ -n "$tag" ] || fail "latest Gitea release has no tag"
|
|
fi
|
|
|
|
version=${tag#v}
|
|
[ -n "$version" ] || fail "invalid release tag: $tag"
|
|
asset=klink_${version}_${target_os}_${target_arch}.tar.gz
|
|
download_base=${repository_url%/}/releases/download/$tag
|
|
|
|
temporary=$(mktemp -d "${TMPDIR:-/tmp}/klink-install.XXXXXX") || fail "could not create a temporary directory"
|
|
cleanup() {
|
|
rm -rf "$temporary"
|
|
}
|
|
trap cleanup EXIT HUP INT TERM
|
|
|
|
archive=$temporary/$asset
|
|
checksums=$temporary/checksums.txt
|
|
say "Downloading klink $tag for $target_os/$target_arch..."
|
|
fetch_file "$download_base/$asset" "$archive"
|
|
fetch_file "$download_base/checksums.txt" "$checksums"
|
|
|
|
expected=$(awk -v name="$asset" '{ file=$2; sub(/^\*/, "", file); if (file == name) { print $1; exit } }' "$checksums")
|
|
[ -n "$expected" ] || fail "$asset is not listed in checksums.txt"
|
|
if command -v sha256sum >/dev/null 2>&1; then
|
|
actual=$(sha256sum "$archive" | awk '{print $1}')
|
|
elif command -v shasum >/dev/null 2>&1; then
|
|
actual=$(shasum -a 256 "$archive" | awk '{print $1}')
|
|
else
|
|
fail "sha256sum or shasum is required"
|
|
fi
|
|
[ "$(printf '%s' "$actual" | tr 'A-F' 'a-f')" = "$(printf '%s' "$expected" | tr 'A-F' 'a-f')" ] || fail "SHA256 checksum mismatch for $asset"
|
|
|
|
extract_dir=$temporary/extract
|
|
mkdir -p "$extract_dir"
|
|
tar -xzf "$archive" -C "$extract_dir"
|
|
binary=$extract_dir/klink
|
|
[ -f "$binary" ] || fail "release archive does not contain klink"
|
|
|
|
if [ -z "$install_dir" ]; then
|
|
if [ -d /usr/local/bin ] && [ -w /usr/local/bin ]; then
|
|
install_dir=/usr/local/bin
|
|
else
|
|
install_dir=$HOME/.local/bin
|
|
fi
|
|
fi
|
|
mkdir -p "$install_dir"
|
|
destination=$install_dir/klink
|
|
staged=$install_dir/.klink-install.$$
|
|
cp "$binary" "$staged"
|
|
chmod 755 "$staged"
|
|
mv -f "$staged" "$destination"
|
|
|
|
say "Installed klink $tag to $destination"
|
|
case ":${PATH:-}:" in
|
|
*:"$install_dir":*) ;;
|
|
*)
|
|
say "Add $install_dir to PATH, for example:"
|
|
say " export PATH=\"$install_dir:\$PATH\""
|
|
;;
|
|
esac
|
|
if ! command -v ssh >/dev/null 2>&1; then
|
|
say "Warning: OpenSSH was not found in PATH; install it before connecting to nodes."
|
|
fi
|