Add prebuilt update path

This commit is contained in:
DuProcess
2026-06-19 16:40:58 -04:00
parent 774da7371e
commit 7884ea2796
8 changed files with 297 additions and 74 deletions
+223 -67
View File
@@ -12,6 +12,12 @@ start_server=1
force_config=0
update_cache="${DOSH_UPDATE_CACHE:-$HOME/.cache/dosh/source}"
quiet="${DOSH_UPDATE_QUIET:-0}"
use_prebuilt="${DOSH_USE_PREBUILT:-0}"
binary_url="${DOSH_BINARY_URL:-}"
binary_base="${DOSH_BINARY_BASE:-}"
binary_name="${DOSH_BINARY_NAME:-}"
binary_version="${DOSH_BINARY_VERSION:-latest}"
binary_required="${DOSH_BINARY_REQUIRED:-0}"
usage() {
cat <<'EOF'
@@ -32,6 +38,18 @@ Options:
Environment alternatives:
DOSH_REPO, DOSH_ROLE, DOSH_SERVER, DOSH_HOST, DOSH_PORT, PREFIX,
DOSH_UPDATE_CACHE
DOSH_USE_PREBUILT=1
Try a release tarball before building from source
DOSH_BINARY_URL URL
Exact release tarball URL to install
DOSH_BINARY_BASE URL
Release download base; defaults to REPO/releases/latest/download
DOSH_BINARY_NAME NAME
Release tarball name; defaults to dosh-OS-ARCH.tar.gz
DOSH_BINARY_VERSION TAG
Release tag when deriving DOSH_BINARY_BASE; default latest
DOSH_BINARY_REQUIRED=1
Fail instead of falling back to source when binary install fails
EOF
}
@@ -112,8 +130,6 @@ ensure_cargo() {
. "$HOME/.cargo/env"
}
ensure_cargo
cleanup() {
if [ -n "${tmpdir:-}" ]; then
rm -rf "$tmpdir"
@@ -121,73 +137,213 @@ cleanup() {
}
trap cleanup EXIT INT TERM
if [ "$from_current" -eq 1 ] || [ -f Cargo.toml ]; then
src_dir="$(pwd)"
else
if [ -z "$repo" ]; then
echo "DOSH_REPO or --repo is required when running the installer from curl" >&2
exit 2
fi
case "$update_cache" in
""|"/"|"$HOME"|"$HOME/"|"$HOME/.cache")
echo "refusing unsafe update cache path: $update_cache" >&2
exit 2
;;
esac
need git
mkdir -p "$(dirname "$update_cache")"
if [ -d "$update_cache/.git" ]; then
[ "$quiet" = "1" ] && echo "Updating Dosh source"
git -C "$update_cache" remote set-url origin "$repo"
if [ "$quiet" = "1" ]; then
git -C "$update_cache" fetch -q --depth 1 origin main
else
git -C "$update_cache" fetch --depth 1 origin main
fi
git -C "$update_cache" checkout -q -B main FETCH_HEAD
else
[ "$quiet" = "1" ] && echo "Downloading Dosh source"
rm -rf "$update_cache"
if [ "$quiet" = "1" ]; then
git clone -q --depth 1 --branch main "$repo" "$update_cache" >/dev/null
else
git clone --depth 1 --branch main "$repo" "$update_cache" >/dev/null
fi
fi
src_dir="$update_cache"
fi
cd "$src_dir"
[ "$quiet" = "1" ] && echo "Building Dosh $role"
if [ "$role" = "client" ]; then
if [ "$quiet" = "1" ]; then
cargo build -q --release --bin dosh-client
else
cargo build --release --bin dosh-client
fi
else
if [ "$quiet" = "1" ]; then
cargo build -q --release
else
cargo build --release
fi
fi
bindir="$prefix/bin"
config_dir="$HOME/.config/dosh"
data_dir="$HOME/.local/share/dosh"
systemd_user_dir="$HOME/.config/systemd/user"
src_dir=""
mkdir -p "$bindir" "$config_dir" "$data_dir"
install -m 0755 target/release/dosh-client "$bindir/dosh-client"
ln -sf dosh-client "$bindir/dosh"
if [ "$role" = "server" ] || [ "$role" = "both" ]; then
install -m 0755 target/release/dosh-server "$bindir/dosh-server"
install -m 0755 target/release/dosh-auth "$bindir/dosh-auth"
fi
if [ -f target/release/dosh-bench ]; then
install -m 0755 target/release/dosh-bench "$bindir/dosh-bench"
normalize_os() {
case "$(uname -s)" in
Darwin) printf '%s\n' macos ;;
Linux) printf '%s\n' linux ;;
FreeBSD) printf '%s\n' freebsd ;;
*) uname -s | tr '[:upper:]' '[:lower:]' ;;
esac
}
normalize_arch() {
case "$(uname -m)" in
x86_64|amd64) printf '%s\n' x86_64 ;;
arm64|aarch64) printf '%s\n' aarch64 ;;
armv7l) printf '%s\n' armv7 ;;
*) uname -m | tr '[:upper:]' '[:lower:]' ;;
esac
}
repo_web_base() {
repo_base="$1"
case "$repo_base" in
http://*|https://*)
repo_base="${repo_base%.git}"
printf '%s\n' "${repo_base%/}"
;;
*)
return 1
;;
esac
}
release_artifact_name() {
if [ -n "$binary_name" ]; then
printf '%s\n' "$binary_name"
else
printf 'dosh-%s-%s.tar.gz\n' "$(normalize_os)" "$(normalize_arch)"
fi
}
release_download_url() {
if [ -n "$binary_url" ]; then
printf '%s\n' "$binary_url"
return 0
fi
if [ -n "$binary_base" ]; then
printf '%s/%s\n' "${binary_base%/}" "$(release_artifact_name)"
return 0
fi
if [ -z "$repo" ]; then
return 1
fi
web_base="$(repo_web_base "$repo")" || return 1
if [ "$binary_version" = "latest" ]; then
printf '%s/releases/latest/download/%s\n' "$web_base" "$(release_artifact_name)"
else
printf '%s/releases/download/%s/%s\n' "$web_base" "$binary_version" "$(release_artifact_name)"
fi
}
find_extracted_binary() {
find "$1" -type f -name "$2" 2>/dev/null | sed -n '1p'
}
install_extracted_binary() {
found="$(find_extracted_binary "$1" "$2")"
if [ -z "$found" ]; then
echo "prebuilt archive missing $2" >&2
return 1
fi
install -m 0755 "$found" "$3"
}
try_install_prebuilt() {
download_url="$(release_download_url)" || return 1
tmpdir="$(mktemp -d)"
archive="$tmpdir/$(release_artifact_name)"
[ "$quiet" = "1" ] && echo "Trying Dosh prebuilt $(release_artifact_name)"
need curl
need tar
if ! curl -fL "$download_url" -o "$archive"; then
echo "prebuilt unavailable: $download_url" >&2
return 1
fi
mkdir -p "$tmpdir/extract"
if ! tar -xzf "$archive" -C "$tmpdir/extract"; then
echo "prebuilt archive could not be extracted: $download_url" >&2
return 1
fi
install_extracted_binary "$tmpdir/extract" dosh-client "$bindir/dosh-client" || return 1
ln -sf dosh-client "$bindir/dosh"
if [ "$role" = "server" ] || [ "$role" = "both" ]; then
install_extracted_binary "$tmpdir/extract" dosh-server "$bindir/dosh-server" || return 1
install_extracted_binary "$tmpdir/extract" dosh-auth "$bindir/dosh-auth" || return 1
fi
if found_bench="$(find_extracted_binary "$tmpdir/extract" dosh-bench)" && [ -n "$found_bench" ]; then
install -m 0755 "$found_bench" "$bindir/dosh-bench"
fi
return 0
}
install_from_source() {
ensure_cargo
if [ "$from_current" -eq 1 ] || [ -f Cargo.toml ]; then
src_dir="$(pwd)"
else
if [ -z "$repo" ]; then
echo "DOSH_REPO or --repo is required when running the installer from curl" >&2
exit 2
fi
case "$update_cache" in
""|"/"|"$HOME"|"$HOME/"|"$HOME/.cache")
echo "refusing unsafe update cache path: $update_cache" >&2
exit 2
;;
esac
need git
mkdir -p "$(dirname "$update_cache")"
if [ -d "$update_cache/.git" ]; then
[ "$quiet" = "1" ] && echo "Updating Dosh source"
git -C "$update_cache" remote set-url origin "$repo"
if [ "$quiet" = "1" ]; then
git -C "$update_cache" fetch -q --depth 1 origin main
else
git -C "$update_cache" fetch --depth 1 origin main
fi
git -C "$update_cache" checkout -q -B main FETCH_HEAD
else
[ "$quiet" = "1" ] && echo "Downloading Dosh source"
rm -rf "$update_cache"
if [ "$quiet" = "1" ]; then
git clone -q --depth 1 --branch main "$repo" "$update_cache" >/dev/null
else
git clone --depth 1 --branch main "$repo" "$update_cache" >/dev/null
fi
fi
src_dir="$update_cache"
fi
cd "$src_dir"
[ "$quiet" = "1" ] && echo "Building Dosh $role"
if [ "$role" = "client" ]; then
if [ "$quiet" = "1" ]; then
cargo build -q --release --bin dosh-client
else
cargo build --release --bin dosh-client
fi
else
if [ "$quiet" = "1" ]; then
cargo build -q --release
else
cargo build --release
fi
fi
install -m 0755 target/release/dosh-client "$bindir/dosh-client"
ln -sf dosh-client "$bindir/dosh"
if [ "$role" = "server" ] || [ "$role" = "both" ]; then
install -m 0755 target/release/dosh-server "$bindir/dosh-server"
install -m 0755 target/release/dosh-auth "$bindir/dosh-auth"
fi
if [ -f target/release/dosh-bench ]; then
install -m 0755 target/release/dosh-bench "$bindir/dosh-bench"
fi
}
write_systemd_service() {
if [ -n "$src_dir" ] && [ -f "$src_dir/packaging/systemd/dosh-server.service" ]; then
sed "s#ExecStart=%h/.local/bin/dosh-server serve#ExecStart=$bindir/dosh-server serve#" \
"$src_dir/packaging/systemd/dosh-server.service" >"$systemd_user_dir/dosh-server.service"
else
cat >"$systemd_user_dir/dosh-server.service" <<EOF
[Unit]
Description=Dosh server
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
ExecStart=$bindir/dosh-server serve
Restart=on-failure
RestartSec=1
KillMode=process
[Install]
WantedBy=default.target
EOF
fi
}
if [ "$use_prebuilt" != "0" ]; then
if ! try_install_prebuilt; then
if [ "$binary_required" = "1" ]; then
exit 1
fi
[ "$quiet" = "1" ] && echo "Falling back to source build"
install_from_source
fi
else
install_from_source
fi
if [ "$role" = "server" ] || [ "$role" = "both" ]; then
@@ -226,8 +382,7 @@ EOF
if command -v systemctl >/dev/null 2>&1; then
mkdir -p "$systemd_user_dir"
sed "s#ExecStart=%h/.local/bin/dosh-server serve#ExecStart=$bindir/dosh-server serve#" \
packaging/systemd/dosh-server.service >"$systemd_user_dir/dosh-server.service"
write_systemd_service
if [ "$start_server" -eq 1 ] && systemctl --user daemon-reload >/dev/null 2>&1; then
systemctl --user enable --now dosh-server.service
fi
@@ -272,7 +427,8 @@ dosh_port = $port
default_session = "new"
reconnect_timeout_secs = 5
view_only = false
predict = false
predict = true
predict_mode = "experimental"
cache_attach_tickets = true
credential_cache = "~/.local/share/dosh/credentials"
auth_preference = "native,ssh"
@@ -300,13 +456,13 @@ EOF
# dosh_host = "palav.dev"
# port = 50000
# default_command = "tm"
# predict = false
# predict = true
[default]
ssh = "$default_server"
dosh_host = "$host_udp"
port = $port
predict = false
predict = true
EOF
fi
fi