Skip to content

Commit 072f227

Browse files
authored
fix(installer): guard incompatible v0.0.37 upgrades (#1294)
1 parent 57a80ed commit 072f227

2 files changed

Lines changed: 160 additions & 8 deletions

File tree

‎install.sh‎

Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ CHECKSUMS_NAME="openshell-checksums-sha256.txt"
1818
LOCAL_GATEWAY_PORT="17670"
1919
HOMEBREW_TAP="nvidia/openshell"
2020
HOMEBREW_FORMULA_NAME="openshell"
21+
BREAKING_RELEASE_VERSION="0.0.37"
22+
UPGRADE_NOTICE_ACK="${OPENSHELL_ACK_BREAKING_UPGRADE:-}"
2123

2224
info() {
2325
printf '%s: %s\n' "$APP_NAME" "$*" >&2
@@ -48,6 +50,9 @@ OPTIONS:
4850
ENVIRONMENT VARIABLES:
4951
OPENSHELL_VERSION Release tag to install (default: latest tagged release).
5052
Set OPENSHELL_VERSION=dev to install the rolling dev build.
53+
OPENSHELL_ACK_BREAKING_UPGRADE
54+
Set to 1 only after backing up and cleaning up a
55+
pre-v0.0.37 installation.
5156
5257
NOTES:
5358
When OPENSHELL_VERSION is unset, this resolves the latest tagged release
@@ -76,6 +81,153 @@ download() {
7681
curl -fLsS --retry 3 --max-redirs 5 -o "$_output" "$_url"
7782
}
7883

84+
semver_core() {
85+
_version="${1#v}"
86+
_version="${_version%%[-+]*}"
87+
printf '%s\n' "$_version"
88+
}
89+
90+
semver_at_least() {
91+
_version="$(semver_core "$1")"
92+
_minimum="$(semver_core "$2")"
93+
94+
_major="${_version%%.*}"
95+
_rest="${_version#*.}"
96+
[ "$_rest" != "$_version" ] || return 1
97+
_minor="${_rest%%.*}"
98+
_patch="${_rest#*.}"
99+
_patch="${_patch%%.*}"
100+
101+
_min_major="${_minimum%%.*}"
102+
_min_rest="${_minimum#*.}"
103+
[ "$_min_rest" != "$_minimum" ] || return 1
104+
_min_minor="${_min_rest%%.*}"
105+
_min_patch="${_min_rest#*.}"
106+
_min_patch="${_min_patch%%.*}"
107+
108+
case "$_major:$_minor:$_patch:$_min_major:$_min_minor:$_min_patch" in
109+
*[!0-9:]* | *::*)
110+
return 1
111+
;;
112+
esac
113+
114+
[ "$_major" -gt "$_min_major" ] && return 0
115+
[ "$_major" -lt "$_min_major" ] && return 1
116+
[ "$_minor" -gt "$_min_minor" ] && return 0
117+
[ "$_minor" -lt "$_min_minor" ] && return 1
118+
[ "$_patch" -ge "$_min_patch" ]
119+
}
120+
121+
target_uses_breaking_gateway_model() {
122+
case "$RELEASE_TAG" in
123+
dev)
124+
return 0
125+
;;
126+
esac
127+
128+
semver_at_least "$RELEASE_TAG" "$BREAKING_RELEASE_VERSION"
129+
}
130+
131+
installed_version_needs_breaking_upgrade_notice() {
132+
_version="$1"
133+
134+
if [ -z "$_version" ]; then
135+
return 0
136+
fi
137+
138+
! semver_at_least "$_version" "$BREAKING_RELEASE_VERSION"
139+
}
140+
141+
find_existing_openshell_bin() {
142+
_path="$(command -v openshell 2>/dev/null || true)"
143+
if [ -n "$_path" ] && [ -x "$_path" ]; then
144+
printf '%s\n' "$_path"
145+
return 0
146+
fi
147+
148+
for _candidate in \
149+
"${TARGET_HOME:-}/.local/bin/openshell" \
150+
/usr/local/bin/openshell \
151+
/usr/bin/openshell \
152+
/opt/homebrew/bin/openshell; do
153+
if [ -n "$_candidate" ] && [ -x "$_candidate" ]; then
154+
printf '%s\n' "$_candidate"
155+
return 0
156+
fi
157+
done
158+
159+
return 1
160+
}
161+
162+
existing_openshell_version() {
163+
_bin="$1"
164+
_output="$("$_bin" --version 2>/dev/null | sed -n '1p' || true)"
165+
printf '%s\n' "$_output" | awk '
166+
{
167+
for (i = 1; i <= NF; i++) {
168+
if ($i ~ /^v?[0-9]+\.[0-9]+\.[0-9]+([-+][A-Za-z0-9.+~-]+)?$/) {
169+
print $i
170+
exit
171+
}
172+
}
173+
}
174+
'
175+
}
176+
177+
print_breaking_upgrade_notice() {
178+
_bin="$1"
179+
_version="$2"
180+
181+
if [ -n "$_version" ]; then
182+
warn "detected existing OpenShell ${_version} at ${_bin}"
183+
else
184+
warn "detected an existing OpenShell installation at ${_bin}"
185+
fi
186+
187+
cat >&2 <<EOF
188+
189+
OpenShell ${BREAKING_RELEASE_VERSION} and later are incompatible with gateway
190+
state created by earlier releases. Before installing ${RELEASE_TAG}, back up
191+
any files, artifacts, and configuration you need from existing sandboxes.
192+
193+
Then clean up the old runtime with the currently installed CLI:
194+
195+
openshell sandbox delete --all
196+
openshell gateway destroy
197+
198+
Run these commands before upgrading because 'openshell gateway destroy' is not
199+
available in OpenShell ${BREAKING_RELEASE_VERSION} and later.
200+
201+
After cleanup, rerun this installer or follow the installation guide:
202+
203+
https://docs.nvidia.com/openshell/latest/about/installation
204+
205+
If you have already backed up and cleaned up the old runtime, rerun with:
206+
207+
curl -LsSf https://raw.githubusercontent.com/NVIDIA/OpenShell/main/install.sh | OPENSHELL_ACK_BREAKING_UPGRADE=1 sh
208+
209+
EOF
210+
}
211+
212+
guard_breaking_upgrade() {
213+
target_uses_breaking_gateway_model || return 0
214+
215+
_bin="$(find_existing_openshell_bin || true)"
216+
[ -n "$_bin" ] || return 0
217+
218+
_version="$(existing_openshell_version "$_bin")"
219+
installed_version_needs_breaking_upgrade_notice "$_version" || return 0
220+
221+
print_breaking_upgrade_notice "$_bin" "$_version"
222+
223+
if [ "$UPGRADE_NOTICE_ACK" = "1" ]; then
224+
warn "continuing because OPENSHELL_ACK_BREAKING_UPGRADE=1 is set"
225+
return 0
226+
fi
227+
228+
error "manual cleanup is required before upgrading from this OpenShell installation"
229+
}
230+
79231
resolve_release_tag() {
80232
if [ -n "${OPENSHELL_VERSION:-}" ]; then
81233
echo "$OPENSHELL_VERSION"
@@ -718,6 +870,8 @@ main() {
718870
[ -n "$TARGET_UID" ] || error "cannot resolve uid for ${TARGET_USER}"
719871
TARGET_HOME="$(user_home "$TARGET_USER")"
720872

873+
guard_breaking_upgrade
874+
721875
case "$PLATFORM" in
722876
linux)
723877
case "$(linux_package_method)" in

‎mise.lock‎

Lines changed: 6 additions & 8 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)