@@ -89,6 +89,19 @@ function shellQuote(value) {
8989 return `'${ String ( value ) . replace ( / ' / g, `'\\''` ) } '` ;
9090}
9191
92+ function getInstalledOpenshellVersion ( versionOutput = null ) {
93+ const output = String ( versionOutput ?? runCapture ( "openshell -V" , { ignoreError : true } ) ) . trim ( ) ;
94+ const match = output . match ( / o p e n s h e l l \s + ( [ 0 - 9 ] + \. [ 0 - 9 ] + \. [ 0 - 9 ] + ) / i) ;
95+ if ( ! match ) return null ;
96+ return match [ 1 ] ;
97+ }
98+
99+ function getStableGatewayImageRef ( versionOutput = null ) {
100+ const version = getInstalledOpenshellVersion ( versionOutput ) ;
101+ if ( ! version ) return null ;
102+ return `ghcr.io/nvidia/openshell/cluster:${ version } ` ;
103+ }
104+
92105function pythonLiteralJson ( value ) {
93106 return JSON . stringify ( JSON . stringify ( value ) ) ;
94107}
@@ -373,8 +386,21 @@ async function startGateway(gpu) {
373386 // sandbox itself does not need direct GPU access. Passing --gpu causes
374387 // FailedPrecondition errors when the gateway's k3s device plugin cannot
375388 // allocate GPUs. See: https://build.nvidia.com/spark/nemoclaw/instructions
376-
377- run ( `openshell gateway start ${ gwArgs . join ( " " ) } ` , { ignoreError : false } ) ;
389+ const gatewayEnv = { } ;
390+ const openshellVersion = getInstalledOpenshellVersion ( ) ;
391+ const stableGatewayImage = openshellVersion
392+ ? `ghcr.io/nvidia/openshell/cluster:${ openshellVersion } `
393+ : null ;
394+ if ( stableGatewayImage && openshellVersion ) {
395+ gatewayEnv . OPENSHELL_CLUSTER_IMAGE = stableGatewayImage ;
396+ gatewayEnv . IMAGE_TAG = openshellVersion ;
397+ console . log ( ` Using pinned OpenShell gateway image: ${ stableGatewayImage } ` ) ;
398+ }
399+
400+ run ( `openshell gateway start ${ gwArgs . join ( " " ) } ` , {
401+ ignoreError : false ,
402+ env : gatewayEnv ,
403+ } ) ;
378404
379405 // Verify health
380406 for ( let i = 0 ; i < 5 ; i ++ ) {
@@ -964,4 +990,12 @@ async function onboard(opts = {}) {
964990 printDashboard ( sandboxName , model , provider ) ;
965991}
966992
967- module . exports = { buildSandboxConfigSyncScript, hasStaleGateway, isSandboxReady, onboard, setupNim } ;
993+ module . exports = {
994+ buildSandboxConfigSyncScript,
995+ getInstalledOpenshellVersion,
996+ getStableGatewayImageRef,
997+ hasStaleGateway,
998+ isSandboxReady,
999+ onboard,
1000+ setupNim,
1001+ } ;
0 commit comments