Skip to content

Commit f5cf3bd

Browse files
committed
fix(amazonq): fix for amazon q app initialization failure on sagemaker
1 parent bee6b9a commit f5cf3bd

File tree

4 files changed

+89
-9
lines changed

4 files changed

+89
-9
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: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,12 +170,31 @@ export function isCloud9(flavor: 'classic' | 'codecatalyst' | 'any' = 'any'): bo
170170
return (flavor === 'classic' && !codecat) || (flavor === 'codecatalyst' && codecat)
171171
}
172172

173+
/**
174+
* Checks if the current environment has SageMaker-specific environment variables
175+
* @returns true if SageMaker environment variables are detected
176+
*/
177+
function hasSageMakerEnvVars(): boolean {
178+
return (
179+
process.env.SAGEMAKER_APP_TYPE !== undefined ||
180+
process.env.SAGEMAKER_INTERNAL_IMAGE_URI !== undefined ||
181+
process.env.STUDIO_LOGGING_DIR?.includes('/var/log/studio') === true
182+
)
183+
}
184+
173185
/**
174186
*
175187
* @param appName to identify the proper SM instance
176188
* @returns true if the current system is SageMaker(SMAI or SMUS)
177189
*/
178190
export function isSageMaker(appName: 'SMAI' | 'SMUS' = 'SMAI'): boolean {
191+
// Check for SageMaker-specific environment variables first
192+
if (hasSageMakerEnvVars() || process.env.SERVICE_NAME === sageMakerUnifiedStudio) {
193+
getLogger().debug('SageMaker environment detected via environment variables')
194+
return true
195+
}
196+
197+
// Fall back to app name checks
179198
switch (appName) {
180199
case 'SMAI':
181200
return vscode.env.appName === sageMakerAppname

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

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

127127
/**
128-
* There is Amazon Linux 2.
128+
* Checks if the current environment is running on Amazon Linux 2.
129129
*
130-
* Use {@link isCloudDesktop()} to know if we are specifically using internal Amazon Linux 2.
130+
* This function attempts to detect if we're running in a container on an AL2 host
131+
* by checking both the OS release and container-specific indicators.
131132
*
132133
* Example: `5.10.220-188.869.amzn2int.x86_64` or `5.10.236-227.928.amzn2.x86_64` (Cloud Dev Machine)
133134
*/
134135
export function isAmazonLinux2() {
136+
// First check if we're in a SageMaker environment, which should not be treated as AL2
137+
// even if the underlying host is AL2
138+
if (
139+
process.env.SAGEMAKER_APP_TYPE ||
140+
process.env.SERVICE_NAME === 'SageMakerUnifiedStudio' ||
141+
process.env.SAGEMAKER_INTERNAL_IMAGE_URI
142+
) {
143+
return false
144+
}
145+
146+
// Check if we're in a container environment that's not AL2
147+
if (process.env.container === 'docker' || process.env.DOCKER_HOST || process.env.DOCKER_BUILDKIT) {
148+
// Additional check for container OS - if we can determine it's not AL2
149+
try {
150+
const fs = require('fs')
151+
if (fs.existsSync('/etc/os-release')) {
152+
const osRelease = fs.readFileSync('/etc/os-release', 'utf8')
153+
if (!osRelease.includes('Amazon Linux 2') && !osRelease.includes('amzn2')) {
154+
return false
155+
}
156+
}
157+
} catch (e) {
158+
// If we can't read the file, fall back to the os.release() check
159+
}
160+
}
161+
162+
// Standard check for AL2 in the OS release string
135163
return (os.release().includes('.amzn2int.') || os.release().includes('.amzn2.')) && process.platform === 'linux'
136164
}
137165

0 commit comments

Comments
 (0)