From 209957a1ddad81a2ee4d8d7d5b47ecde19ccbf5a Mon Sep 17 00:00:00 2001 From: Wim Yedema Date: Wed, 2 Sep 2026 07:15:43 +0000 Subject: [PATCH 1/3] Fix install script --- dstack/scripts/install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dstack/scripts/install.sh b/dstack/scripts/install.sh index 6ba7b6fb8..56dc90a0c 100755 --- a/dstack/scripts/install.sh +++ b/dstack/scripts/install.sh @@ -238,7 +238,7 @@ fi need_cmd cargo need_cmd install -checkout=$(resolve_source) +checkout=$(resolve_source | tail -1) core_checkout=$(core_dir "$checkout") bin_dir="$prefix/bin" From 370cf7c4289b966cfeed9a1dd9fe15ac4184088d Mon Sep 17 00:00:00 2001 From: Wim Yedema Date: Wed, 2 Sep 2026 07:34:01 +0000 Subject: [PATCH 2/3] Improve echo-ing --- dstack/scripts/install.sh | 38 +++++++++++++++++++++++--------------- 1 file changed, 23 insertions(+), 15 deletions(-) diff --git a/dstack/scripts/install.sh b/dstack/scripts/install.sh index 56dc90a0c..dfc27c4b2 100755 --- a/dstack/scripts/install.sh +++ b/dstack/scripts/install.sh @@ -57,11 +57,19 @@ cleanup() { } trap cleanup EXIT INT TERM +info() { + echo "$*" >&2 +} + +error() { + echo "error: $*" >&2 +} + while [ "$#" -gt 0 ]; do case "$1" in --repo) if [ "$#" -lt 2 ]; then - echo "error: --repo requires a URL" >&2 + error "--repo requires a URL" exit 1 fi repo=$2 @@ -69,7 +77,7 @@ while [ "$#" -gt 0 ]; do ;; --ref) if [ "$#" -lt 2 ]; then - echo "error: --ref requires a ref" >&2 + error "--ref requires a ref" exit 1 fi ref=$2 @@ -77,7 +85,7 @@ while [ "$#" -gt 0 ]; do ;; --src) if [ "$#" -lt 2 ]; then - echo "error: --src requires a directory" >&2 + error "--src requires a directory" exit 1 fi src=$2 @@ -85,7 +93,7 @@ while [ "$#" -gt 0 ]; do ;; --prefix|--root) if [ "$#" -lt 2 ]; then - echo "error: --prefix requires a directory" >&2 + error "--prefix requires a directory" exit 1 fi prefix=$2 @@ -101,7 +109,7 @@ while [ "$#" -gt 0 ]; do exit 0 ;; *) - echo "error: unknown option: $1" >&2 + error "unknown option: $1" usage >&2 exit 1 ;; @@ -110,7 +118,7 @@ done need_cmd() { if ! command -v "$1" >/dev/null 2>&1; then - echo "error: required command not found: $1" >&2 + error "required command not found: $1" exit 1 fi } @@ -170,10 +178,10 @@ resolve_source() { if [ -n "$src" ] && [ -e "$src" ]; then if ! is_checkout "$src" || ! git -C "$src" rev-parse --git-dir >/dev/null 2>&1; then - echo "error: $src exists but is not a dstack git checkout" >&2 + error "$src exists but is not a dstack git checkout" exit 1 fi - echo "updating dstack source in $src" + info "updating dstack source in $src" ( cd "$src" git fetch --tags origin @@ -183,7 +191,7 @@ resolve_source() { fi ) elif [ -n "$src" ]; then - echo "cloning dstack source into $src" + info "cloning dstack source into $src" git clone "$repo" "$src" ( cd "$src" @@ -194,7 +202,7 @@ resolve_source() { need_cmd mktemp tmp_src=$(mktemp -d "${TMPDIR:-/tmp}/dstack-install.XXXXXX") src="$tmp_src/source" - echo "cloning dstack source into a temporary checkout" + info "cloning dstack source into a temporary checkout" git clone "$repo" "$src" ( cd "$src" @@ -210,17 +218,17 @@ validate_prefix() { case "$prefix" in /*) ;; *) - echo "error: --prefix must be an absolute path" >&2 + error "--prefix must be an absolute path" exit 1 ;; esac if [ "$prefix" = "/" ]; then - echo "error: --prefix must not be /" >&2 + error "--prefix must not be /" exit 1 fi case "$prefix" in *"/../"*|*"/.."|*"/./"*|*"/.") - echo "error: --prefix must not contain . or .. path components" >&2 + error "--prefix must not contain . or .. path components" exit 1 ;; esac @@ -238,7 +246,7 @@ fi need_cmd cargo need_cmd install -checkout=$(resolve_source | tail -1) +checkout=$(resolve_source) core_checkout=$(core_dir "$checkout") bin_dir="$prefix/bin" @@ -266,7 +274,7 @@ install_bin() { src_bin="$core_checkout/target/release/$1" dest_bin="$bin_dir/$2" if [ ! -f "$src_bin" ]; then - echo "error: expected binary not found: $src_bin" >&2 + error "expected binary not found: $src_bin" exit 1 fi if [ -n "$sudo_cmd" ]; then From fb5310a03f73873d13b550c9bbd331fc710ff87d Mon Sep 17 00:00:00 2001 From: Kevin Wang Date: Fri, 4 Sep 2026 03:08:41 -0700 Subject: [PATCH 3/3] fix(install): keep git output off resolve_source stdout resolve_source() returns the checkout path on stdout, so anything else written there ends up in $checkout. Routing the script's own progress messages to stderr is not enough: git writes to stdout too. 'git checkout ' prints the branch-tracking line ('Your branch is up to date with ...') and 'git pull' prints its fast-forward summary, both on stdout. That leaves $checkout as a multi-line string, so core_dir() no longer matches and the following 'cd "$core_checkout"' fails - including on the default 'curl | sh' path, where --ref defaults to the 'next' branch. Redirect the git subshells and clones as a whole rather than adding -q per command, so a git call added later cannot reintroduce the same bug. Also use printf instead of echo in info()/error(): echo's handling of a leading '-' is implementation-defined, and dash swallows 'info "-n"' entirely. --- dstack/scripts/install.sh | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/dstack/scripts/install.sh b/dstack/scripts/install.sh index dfc27c4b2..736c18745 100755 --- a/dstack/scripts/install.sh +++ b/dstack/scripts/install.sh @@ -58,11 +58,11 @@ cleanup() { trap cleanup EXIT INT TERM info() { - echo "$*" >&2 + printf '%s\n' "$*" >&2 } error() { - echo "error: $*" >&2 + printf 'error: %s\n' "$*" >&2 } while [ "$#" -gt 0 ]; do @@ -189,26 +189,26 @@ resolve_source() { if git rev-parse --verify "origin/$ref" >/dev/null 2>&1; then git pull --ff-only origin "$ref" fi - ) + ) >&2 elif [ -n "$src" ]; then info "cloning dstack source into $src" - git clone "$repo" "$src" + git clone "$repo" "$src" >&2 ( cd "$src" git fetch --tags origin git checkout "$ref" - ) + ) >&2 else need_cmd mktemp tmp_src=$(mktemp -d "${TMPDIR:-/tmp}/dstack-install.XXXXXX") src="$tmp_src/source" info "cloning dstack source into a temporary checkout" - git clone "$repo" "$src" + git clone "$repo" "$src" >&2 ( cd "$src" git fetch --tags origin git checkout "$ref" - ) + ) >&2 fi abs_dir "$src" @@ -263,7 +263,7 @@ else install -d -m 0755 "$bin_dir" fi -echo "building dstackup from $checkout" +info "building dstackup from $checkout" ( cd "$core_checkout" cargo build --release \