Skip to content

Commit 1ab1ad2

Browse files
authored
Merge pull request #7551 from ashishrp-aws/fix/sagemaker
fix(amazonq): fix for amazon q app initialization failure on sagemaker
2 parents cac600f + 053a5bd commit 1ab1ad2

File tree

4 files changed

+93
-10
lines changed

4 files changed

+93
-10
lines changed
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": "Improved Amazon Linux 2 support with better SageMaker environment detection"
4+
}

packages/amazonq/src/lsp/client.ts

Lines changed: 36 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ import {
3838
isAmazonLinux2,
3939
getClientId,
4040
extensionVersion,
41+
isSageMaker,
4142
} from 'aws-core-vscode/shared'
4243
import { processUtils } from 'aws-core-vscode/shared'
4344
import { activate } from './chat/activation'
@@ -53,11 +54,24 @@ import { InlineChatTutorialAnnotation } from '../app/inline/tutorials/inlineChat
5354
const localize = nls.loadMessageBundle()
5455
const logger = getLogger('amazonqLsp.lspClient')
5556

56-
export const glibcLinker: string = process.env.VSCODE_SERVER_CUSTOM_GLIBC_LINKER || ''
57-
export const glibcPath: string = process.env.VSCODE_SERVER_CUSTOM_GLIBC_PATH || ''
58-
5957
export function hasGlibcPatch(): boolean {
60-
return glibcLinker.length > 0 && glibcPath.length > 0
58+
// Skip GLIBC patching for SageMaker environments
59+
if (isSageMaker()) {
60+
getLogger('amazonqLsp').info('SageMaker environment detected in hasGlibcPatch, skipping GLIBC patching')
61+
return false // Return false to ensure SageMaker doesn't try to use GLIBC patching
62+
}
63+
64+
// Check for environment variables (for CDM)
65+
const glibcLinker = process.env.VSCODE_SERVER_CUSTOM_GLIBC_LINKER || ''
66+
const glibcPath = process.env.VSCODE_SERVER_CUSTOM_GLIBC_PATH || ''
67+
68+
if (glibcLinker.length > 0 && glibcPath.length > 0) {
69+
getLogger('amazonqLsp').info('GLIBC patching environment variables detected')
70+
return true
71+
}
72+
73+
// No environment variables, no patching needed
74+
return false
6175
}
6276

6377
export async function startLanguageServer(
@@ -82,9 +96,24 @@ export async function startLanguageServer(
8296
const traceServerEnabled = Settings.instance.isSet(`${clientId}.trace.server`)
8397
let executable: string[] = []
8498
// apply the GLIBC 2.28 path to node js runtime binary
85-
if (isAmazonLinux2() && hasGlibcPatch()) {
86-
executable = [glibcLinker, '--library-path', glibcPath, resourcePaths.node]
87-
getLogger('amazonqLsp').info(`Patched node runtime with GLIBC to ${executable}`)
99+
if (isSageMaker()) {
100+
// SageMaker doesn't need GLIBC patching
101+
getLogger('amazonqLsp').info('SageMaker environment detected, skipping GLIBC patching')
102+
executable = [resourcePaths.node]
103+
} else if (isAmazonLinux2() && hasGlibcPatch()) {
104+
// Use environment variables if available (for CDM)
105+
if (process.env.VSCODE_SERVER_CUSTOM_GLIBC_LINKER && process.env.VSCODE_SERVER_CUSTOM_GLIBC_PATH) {
106+
executable = [
107+
process.env.VSCODE_SERVER_CUSTOM_GLIBC_LINKER,
108+
'--library-path',
109+
process.env.VSCODE_SERVER_CUSTOM_GLIBC_PATH,
110+
resourcePaths.node,
111+
]
112+
getLogger('amazonqLsp').info(`Patched node runtime with GLIBC using env vars to ${executable}`)
113+
} else {
114+
// No environment variables, use the node executable directly
115+
executable = [resourcePaths.node]
116+
}
88117
} else {
89118
executable = [resourcePaths.node]
90119
}

packages/core/src/shared/extensionUtilities.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import { getLogger } from './logger/logger'
1111
import { VSCODE_EXTENSION_ID, extensionAlphaVersion } from './extensions'
1212
import { Ec2MetadataClient } from './clients/ec2MetadataClient'
1313
import { DefaultEc2MetadataClient } from './clients/ec2MetadataClient'
14-
import { extensionVersion, getCodeCatalystDevEnvId } from './vscode/env'
14+
import { extensionVersion, getCodeCatalystDevEnvId, hasSageMakerEnvVars } from './vscode/env'
1515
import globals from './extensionGlobals'
1616
import { once } from './utilities/functionUtils'
1717
import {
@@ -176,6 +176,13 @@ export function isCloud9(flavor: 'classic' | 'codecatalyst' | 'any' = 'any'): bo
176176
* @returns true if the current system is SageMaker(SMAI or SMUS)
177177
*/
178178
export function isSageMaker(appName: 'SMAI' | 'SMUS' = 'SMAI'): boolean {
179+
// Check for SageMaker-specific environment variables first
180+
if (hasSageMakerEnvVars()) {
181+
getLogger().debug('SageMaker environment detected via environment variables')
182+
return true
183+
}
184+
185+
// Fall back to app name checks
179186
switch (appName) {
180187
case 'SMAI':
181188
return vscode.env.appName === sageMakerAppname

packages/core/src/shared/vscode/env.ts

Lines changed: 45 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -125,13 +125,56 @@ export function isRemoteWorkspace(): boolean {
125125
}
126126

127127
/**
128-
* There is Amazon Linux 2.
128+
* Checks if the current environment has SageMaker-specific environment variables
129+
* @returns true if SageMaker environment variables are detected
130+
*/
131+
export function hasSageMakerEnvVars(): boolean {
132+
// Check both old and new environment variable names
133+
// SageMaker is renaming their environment variables in their Docker images
134+
return (
135+
// Original environment variables
136+
process.env.SAGEMAKER_APP_TYPE !== undefined ||
137+
process.env.SAGEMAKER_INTERNAL_IMAGE_URI !== undefined ||
138+
process.env.STUDIO_LOGGING_DIR?.includes('/var/log/studio') === true ||
139+
// New environment variables (update these with the actual new names)
140+
process.env.SM_APP_TYPE !== undefined ||
141+
process.env.SM_INTERNAL_IMAGE_URI !== undefined ||
142+
process.env.SERVICE_NAME === 'SageMakerUnifiedStudio'
143+
)
144+
}
145+
146+
/**
147+
* Checks if the current environment is running on Amazon Linux 2.
129148
*
130-
* Use {@link isCloudDesktop()} to know if we are specifically using internal Amazon Linux 2.
149+
* This function attempts to detect if we're running in a container on an AL2 host
150+
* by checking both the OS release and container-specific indicators.
131151
*
132152
* Example: `5.10.220-188.869.amzn2int.x86_64` or `5.10.236-227.928.amzn2.x86_64` (Cloud Dev Machine)
133153
*/
134154
export function isAmazonLinux2() {
155+
// First check if we're in a SageMaker environment, which should not be treated as AL2
156+
// even if the underlying host is AL2
157+
if (hasSageMakerEnvVars()) {
158+
return false
159+
}
160+
161+
// Check if we're in a container environment that's not AL2
162+
if (process.env.container === 'docker' || process.env.DOCKER_HOST || process.env.DOCKER_BUILDKIT) {
163+
// Additional check for container OS - if we can determine it's not AL2
164+
try {
165+
const fs = require('fs')
166+
if (fs.existsSync('/etc/os-release')) {
167+
const osRelease = fs.readFileSync('/etc/os-release', 'utf8')
168+
if (!osRelease.includes('Amazon Linux 2') && !osRelease.includes('amzn2')) {
169+
return false
170+
}
171+
}
172+
} catch (e) {
173+
// If we can't read the file, fall back to the os.release() check
174+
}
175+
}
176+
177+
// Standard check for AL2 in the OS release string
135178
return (os.release().includes('.amzn2int.') || os.release().includes('.amzn2.')) && process.platform === 'linux'
136179
}
137180

0 commit comments

Comments
 (0)