Skip to content

Commit 4f90bc6

Browse files
fix(smus): update space before creating new app if space setting is changed (aws#8173)
## Problem Upgrading Space from Toolkit from ml.t3.medium to ml.t3.large does not update the Space properties. It only creates a new app with the updated instance type. ## Solution Make sure to update Space before creating App when it is needed ## Testing Verified that the it does not overwrite the the missing props. Diff link https://diff.corp.amazon.com/compare/54b0ofvc - before updating space ``` sagemaker-user@default:~$ aws sagemaker describe-space --domain-id d-rxs4hhmzrnho --space-name ce { "DomainId": "d-rxs4hhmzrnho", "SpaceArn": "arn:aws:sagemaker:us-east-2:050752642559:space/d-rxs4hhmzrnho/ce", "SpaceName": "ce", "Status": "InService", "LastModifiedTime": "2025-10-13T21:21:00.933000+00:00", "CreationTime": "2025-09-08T20:58:08.976000+00:00", "SpaceSettings": { "CodeEditorAppSettings": { "DefaultResourceSpec": { "SageMakerImageArn": "arn:aws:sagemaker:us-east-2:137914896644:image/sagemaker-distribution-cpu", "SageMakerImageVersionAlias": "2.8", "InstanceType": "ml.t3.medium" }, "AppLifecycleManagement": { "IdleSettings": { "IdleTimeoutInMinutes": 60 } } }, "AppType": "CodeEditor", "SpaceStorageSettings": { "EbsStorageSettings": { "EbsVolumeSizeInGb": 16 } }, "CustomFileSystems": [ { "S3FileSystem": { "S3Uri": "s3://amazon-sagemaker-050752642559-us-east-2-63f9df3f396b/dzd_bh80g0fbj1h7xl/c1wqm5rlzb150p/shared" } } ], "RemoteAccess": "DISABLED" }, "OwnershipSettings": { "OwnerUserProfileName": "915b9590-a081-704d-8914-0e482edfb1ef" }, "SpaceSharingSettings": { "SharingType": "Private" }, "Url": "https://y89msnjovs0fqgr.studio.us-east-2.sagemaker.aws/codeeditor/default" } ``` After updating space: ``` sagemaker-user@default:~$ aws sagemaker describe-space --domain-id d-rxs4hhmzrnho --space-name ce { "DomainId": "d-rxs4hhmzrnho", "SpaceArn": "arn:aws:sagemaker:us-east-2:050752642559:space/d-rxs4hhmzrnho/ce", "SpaceName": "ce", "Status": "InService", "LastModifiedTime": "2025-10-13T21:28:28.870000+00:00", "CreationTime": "2025-09-08T20:58:08.976000+00:00", "SpaceSettings": { "CodeEditorAppSettings": { "DefaultResourceSpec": { "SageMakerImageArn": "arn:aws:sagemaker:us-east-2:137914896644:image/sagemaker-distribution-cpu", "SageMakerImageVersionAlias": "2.8", "InstanceType": "ml.t3.large" }, "AppLifecycleManagement": { "IdleSettings": { "IdleTimeoutInMinutes": 60 } } }, "AppType": "CodeEditor", "SpaceStorageSettings": { "EbsStorageSettings": { "EbsVolumeSizeInGb": 16 } }, "CustomFileSystems": [ { "S3FileSystem": { "S3Uri": "s3://amazon-sagemaker-050752642559-us-east-2-63f9df3f396b/dzd_bh80g0fbj1h7xl/c1wqm5rlzb150p/shared" } } ], "RemoteAccess": "ENABLED" }, "OwnershipSettings": { "OwnerUserProfileName": "915b9590-a081-704d-8914-0e482edfb1ef" }, "SpaceSharingSettings": { "SharingType": "Private" }, "Url": "https://y89msnjovs0fqgr.studio.us-east-2.sagemaker.aws/codeeditor/default" } ``` --- - Treat all work as PUBLIC. Private `feature/x` branches will not be squash-merged at release time. - Your code changes must meet the guidelines in [CONTRIBUTING.md](https://github.com/aws/aws-toolkit-vscode/blob/master/CONTRIBUTING.md#guidelines). - License: I confirm that my contribution is made under the terms of the Apache 2.0 license.
1 parent e476550 commit 4f90bc6

File tree

3 files changed

+37
-11
lines changed

3 files changed

+37
-11
lines changed

packages/core/src/shared/clients/sagemaker.ts

Lines changed: 32 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,11 @@ import { yes, no, continueText, cancel } from '../localizedText'
5252
import { AwsCredentialIdentity } from '@aws-sdk/types'
5353
import globals from '../extensionGlobals'
5454

55+
const appTypeSettingsMap: Record<string, string> = {
56+
[AppType.JupyterLab as string]: 'JupyterLabAppSettings',
57+
[AppType.CodeEditor as string]: 'CodeEditorAppSettings',
58+
} as const
59+
5560
export interface SagemakerSpaceApp extends SpaceDetails {
5661
App?: AppDetails
5762
DomainSpaceKey: string
@@ -136,13 +141,13 @@ export class SagemakerClient extends ClientWrapper<SageMakerClient> {
136141

137142
// Get app type
138143
const appType = spaceDetails.SpaceSettings?.AppType
139-
if (appType !== 'JupyterLab' && appType !== 'CodeEditor') {
144+
if (!appType || !(appType in appTypeSettingsMap)) {
140145
throw new ToolkitError(`Unsupported AppType "${appType}" for space "${spaceName}"`)
141146
}
142147

143148
// Get app resource spec
144149
const requestedResourceSpec =
145-
appType === 'JupyterLab'
150+
appType === AppType.JupyterLab
146151
? spaceDetails.SpaceSettings?.JupyterLabAppSettings?.DefaultResourceSpec
147152
: spaceDetails.SpaceSettings?.CodeEditorAppSettings?.DefaultResourceSpec
148153

@@ -181,16 +186,30 @@ export class SagemakerClient extends ClientWrapper<SageMakerClient> {
181186
instanceType = InstanceTypeMinimum
182187
}
183188

184-
// Get remote access flag
185-
if (!spaceDetails.SpaceSettings?.RemoteAccess || spaceDetails.SpaceSettings?.RemoteAccess === 'DISABLED') {
189+
// First, update the space if needed
190+
const needsRemoteAccess =
191+
!spaceDetails.SpaceSettings?.RemoteAccess || spaceDetails.SpaceSettings?.RemoteAccess === 'DISABLED'
192+
const instanceTypeChanged = requestedResourceSpec?.InstanceType !== instanceType
193+
194+
if (needsRemoteAccess || instanceTypeChanged) {
195+
const updateSpaceRequest: UpdateSpaceCommandInput = {
196+
DomainId: domainId,
197+
SpaceName: spaceName,
198+
SpaceSettings: {
199+
...(needsRemoteAccess && { RemoteAccess: 'ENABLED' }),
200+
...(instanceTypeChanged && {
201+
[appTypeSettingsMap[appType]]: {
202+
DefaultResourceSpec: {
203+
InstanceType: instanceType,
204+
},
205+
},
206+
}),
207+
},
208+
}
209+
186210
try {
187-
await this.updateSpace({
188-
DomainId: domainId,
189-
SpaceName: spaceName,
190-
SpaceSettings: {
191-
RemoteAccess: 'ENABLED',
192-
},
193-
})
211+
getLogger().debug('SagemakerClient: Updating space: domainId=%s, spaceName=%s', domainId, spaceName)
212+
await this.updateSpace(updateSpaceRequest)
194213
await this.waitForSpaceInService(spaceName, domainId)
195214
} catch (err) {
196215
throw this.handleStartSpaceError(err)
@@ -214,6 +233,7 @@ export class SagemakerClient extends ClientWrapper<SageMakerClient> {
214233
? { ...resourceSpec, EnvironmentArn: undefined, EnvironmentVersionArn: undefined }
215234
: resourceSpec
216235

236+
// Second, create the App
217237
const createAppRequest: CreateAppCommandInput = {
218238
DomainId: domainId,
219239
SpaceName: spaceName,
@@ -223,6 +243,7 @@ export class SagemakerClient extends ClientWrapper<SageMakerClient> {
223243
}
224244

225245
try {
246+
getLogger().debug('SagemakerClient: Creating app: domainId=%s, spaceName=%s', domainId, spaceName)
226247
await this.createApp(createAppRequest)
227248
} catch (err) {
228249
throw this.handleStartSpaceError(err)

packages/core/src/test/shared/clients/sagemakerClient.test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -360,6 +360,7 @@ describe('SagemakerClient.startSpace', function () {
360360
getTestWindow().getFirstMessage().selectItem('Yes')
361361

362362
await promise
363+
sinon.assert.calledOnce(updateSpaceStub)
363364
sinon.assert.calledOnce(createAppStub)
364365
})
365366

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"type": "Bug Fix",
3+
"description": "The space is updated upon creation of a new app with the requested settings"
4+
}

0 commit comments

Comments
 (0)