@@ -18,6 +18,8 @@ CHECKSUMS_NAME="openshell-checksums-sha256.txt"
1818LOCAL_GATEWAY_PORT=" 17670"
1919HOMEBREW_TAP=" nvidia/openshell"
2020HOMEBREW_FORMULA_NAME=" openshell"
21+ BREAKING_RELEASE_VERSION=" 0.0.37"
22+ UPGRADE_NOTICE_ACK=" ${OPENSHELL_ACK_BREAKING_UPGRADE:- } "
2123
2224info () {
2325 printf ' %s: %s\n' " $APP_NAME " " $* " >&2
@@ -48,6 +50,9 @@ OPTIONS:
4850ENVIRONMENT 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
5257NOTES:
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+
79231resolve_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
0 commit comments