first pass of merging in warp (doesn't build)
This commit is contained in:
@@ -1,16 +1,31 @@
|
||||
#!/usr/bin/env bash
|
||||
# Installs the Warp remote server binary on a remote host.
|
||||
# Installs the Warp remote server binary on a remote host, plus the
|
||||
# artifact's `resources/` tree (bundled skills, settings schema) at a
|
||||
# global, version-independent location:
|
||||
#
|
||||
# {install_dir}/
|
||||
# ├── {binary_name}{version_suffix} ← the executable
|
||||
# └── bundled_resources/ ← the artifact's resources tree
|
||||
#
|
||||
# Resources are deliberately decoupled from the binary version: the last
|
||||
# install wins. An older daemon that is still running parsed its skills at
|
||||
# startup, so a slightly newer resources tree underneath it is accepted.
|
||||
#
|
||||
# Placeholders (substituted at runtime by setup.rs):
|
||||
# {download_base_url} — e.g. https://app.warp.dev/download/cli
|
||||
# {channel} — stable | preview | dev
|
||||
# {install_dir} — e.g. ~/.warp/remote-server
|
||||
# {binary_name} — e.g. oz | oz-dev | oz-preview
|
||||
# {download_base_url} — e.g. https://app.warp.dev/download/cli
|
||||
# {channel} — stable | preview | dev
|
||||
# {install_dir} — e.g. ~/.warp/remote-server
|
||||
# {binary_name} — e.g. oz | oz-dev | oz-preview
|
||||
# {version_query} — e.g. &version=v0.2026... (empty when no release tag)
|
||||
# {version_suffix} — e.g. -v0.2026... (empty when no release tag)
|
||||
# {bundled_resources_dir_name} — global resources directory name (e.g. bundled_resources)
|
||||
# {no_http_client_exit_code} — exit code when neither curl nor wget is available
|
||||
# {staging_tarball_path} — path to a pre-uploaded tarball (SCP fallback; empty normally)
|
||||
set -e
|
||||
|
||||
arch=$(uname -m)
|
||||
case "$arch" in
|
||||
x86_64) arch_name=x86_64 ;;
|
||||
x86_64|amd64) arch_name=x86_64 ;;
|
||||
aarch64|arm64) arch_name=aarch64 ;;
|
||||
*) echo "unsupported arch: $arch" >&2; exit 2 ;;
|
||||
esac
|
||||
@@ -23,17 +38,75 @@ case "$os_kernel" in
|
||||
esac
|
||||
|
||||
install_dir="{install_dir}"
|
||||
install_dir="${install_dir/#\~/"$HOME"}"
|
||||
# Avoid `${var/pattern/replacement}` for tilde expansion. Two
|
||||
# interpreter quirks make it dangerous in this script:
|
||||
# 1. bash 3.2 (macOS /bin/bash) keeps inner double-quotes around the
|
||||
# replacement literal, so `"$HOME"` ends up as 6 literal
|
||||
# characters and the install lands under a directory tree
|
||||
# literally named `"`.
|
||||
# 2. bash 5.2+ enables `patsub_replacement` by default, which makes
|
||||
# `&` in the replacement expand to the matched pattern, so a
|
||||
# `$HOME` containing `&` resolves to a `~`-substituted path.
|
||||
# Use `case` + `${var#\~}` instead — works on bash 3.2 and bash 5.2+
|
||||
# without surprises.
|
||||
case "$install_dir" in
|
||||
"~"|"~/"*) install_dir="${HOME}${install_dir#\~}" ;;
|
||||
esac
|
||||
mkdir -p "$install_dir"
|
||||
|
||||
tmpdir=$(mktemp -d "$install_dir/.install.XXXXXX")
|
||||
trap 'rm -rf "$tmpdir"' EXIT
|
||||
# Best-effort cleanup of the staging directory. A failure here (e.g.
|
||||
# EBUSY or "Directory not empty" races on some filesystems/mounts)
|
||||
# must not fail the install: by the time this fires the binary has
|
||||
# either already been moved into its final location, or the script
|
||||
# has already failed for an unrelated reason that we want to surface
|
||||
# instead of clobbering with the cleanup's exit code.
|
||||
cleanup() {
|
||||
rm -rf "$tmpdir" 2>/dev/null || true
|
||||
}
|
||||
trap cleanup EXIT
|
||||
|
||||
staging_tarball_path="{staging_tarball_path}"
|
||||
if [ -n "$staging_tarball_path" ]; then
|
||||
# SCP fallback: tarball already uploaded by the client.
|
||||
# Same tilde-expansion caveat as install_dir above.
|
||||
case "$staging_tarball_path" in
|
||||
"~"|"~/"*) staging_tarball_path="${HOME}${staging_tarball_path#\~}" ;;
|
||||
esac
|
||||
mv "$staging_tarball_path" "$tmpdir/oz.tar.gz"
|
||||
else
|
||||
# Normal path: download via curl or wget.
|
||||
url="{download_base_url}?package=tar&os=$os_name&arch=$arch_name&channel={channel}{version_query}"
|
||||
|
||||
if command -v curl >/dev/null 2>&1; then
|
||||
curl -fSL --connect-timeout 15 "$url" -o "$tmpdir/oz.tar.gz"
|
||||
elif command -v wget >/dev/null 2>&1; then
|
||||
wget -q -O "$tmpdir/oz.tar.gz" "$url"
|
||||
else
|
||||
echo "error: neither curl nor wget is available" >&2
|
||||
exit {no_http_client_exit_code}
|
||||
fi
|
||||
fi
|
||||
|
||||
curl -fSL "{download_base_url}?package=tar&os=$os_name&arch=$arch_name&channel={channel}" \
|
||||
-o "$tmpdir/oz.tar.gz"
|
||||
tar -xzf "$tmpdir/oz.tar.gz" -C "$tmpdir"
|
||||
|
||||
bin=$(find "$tmpdir" -type f -name 'oz*' ! -name '*.tar.gz' | head -n1)
|
||||
# The executable and its resources are siblings in the artifact. Exclude the
|
||||
# resources tree from the search: bundled skills may ship companion files
|
||||
# whose names also start with `oz`.
|
||||
bin=$(find "$tmpdir" -type f -name 'oz*' ! -name '*.tar.gz' ! -path '*/resources/*' | head -n1)
|
||||
if [ -z "$bin" ]; then echo "no binary found in tarball" >&2; exit 1; fi
|
||||
chmod +x "$bin"
|
||||
mv "$bin" "$install_dir/{binary_name}"
|
||||
|
||||
# Install the resources tree at the global, version-independent location
|
||||
# the daemon reads. `$tmpdir` lives inside `$install_dir`, so the `mv` is a
|
||||
# same-filesystem rename. Installed before the binary so an interrupted
|
||||
# install never leaves a new binary without its resources — the binary miss
|
||||
# re-triggers this script. A tarball without resources is not an error: the
|
||||
# daemon simply has no bundled skills.
|
||||
resources="$(dirname "$bin")/resources"
|
||||
if [ -d "$resources" ]; then
|
||||
rm -rf "$install_dir/{bundled_resources_dir_name}"
|
||||
mv "$resources" "$install_dir/{bundled_resources_dir_name}"
|
||||
fi
|
||||
|
||||
mv "$bin" "$install_dir/{binary_name}{version_suffix}"
|
||||
|
||||
Reference in New Issue
Block a user