Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"type": "Bug Fix",
"description": "Amazon Q support web/container environments running Ubuntu/Linux, even when the host machine is Amazon Linux 2."
}
58 changes: 39 additions & 19 deletions packages/core/src/shared/vscode/env.ts
Original file line number Diff line number Diff line change
Expand Up @@ -146,36 +146,56 @@ export function hasSageMakerEnvVars(): boolean {
/**
* Checks if the current environment is running on Amazon Linux 2.
*
* This function attempts to detect if we're running in a container on an AL2 host
* by checking both the OS release and container-specific indicators.
* This function detects if we're actually running on AL2, not just if the host is AL2.
* In containerized environments, we check the container's OS, not the host's.
*
* Example: `5.10.220-188.869.amzn2int.x86_64` or `5.10.236-227.928.amzn2.x86_64` (Cloud Dev Machine)
*/
export function isAmazonLinux2() {
// Skip AL2 detection for web environments
// In web mode, we're running in a browser, not on AL2
if (isWeb()) {
return false
}

// First check if we're in a SageMaker environment, which should not be treated as AL2
// even if the underlying host is AL2
if (hasSageMakerEnvVars()) {
return false
}

// Check if we're in a container environment that's not AL2
if (process.env.container === 'docker' || process.env.DOCKER_HOST || process.env.DOCKER_BUILDKIT) {
// Additional check for container OS - if we can determine it's not AL2
try {
const fs = require('fs')
if (fs.existsSync('/etc/os-release')) {
const osRelease = fs.readFileSync('/etc/os-release', 'utf8')
if (!osRelease.includes('Amazon Linux 2') && !osRelease.includes('amzn2')) {
return false
}
// For containerized environments, check the actual container OS
// not the host kernel version
try {
const fs = require('fs')
if (fs.existsSync('/etc/os-release')) {
const osRelease = fs.readFileSync('/etc/os-release', 'utf8')
// Check if this is actually Amazon Linux 2
const isAL2 =
osRelease.includes('Amazon Linux 2') ||
(osRelease.includes('ID="amzn"') && osRelease.includes('VERSION_ID="2"'))

// If we found os-release file, trust its content over kernel version
if (!isAL2) {
// Explicitly not AL2 based on os-release
return false
}
} catch (e) {
// If we can't read the file, fall back to the os.release() check
// If it is AL2 according to os-release, continue to kernel check for confirmation
}
} catch (e) {
// If we can't read the file, fall back to the os.release() check
// This might happen in some restricted environments
getLogger().error(`Checking the current environment failed with error: ${e}`)
}

// Standard check for AL2 in the OS release string
return (os.release().includes('.amzn2int.') || os.release().includes('.amzn2.')) && process.platform === 'linux'
// Check kernel version as a fallback or confirmation
// This should only be trusted if we couldn't determine from /etc/os-release
// or if /etc/os-release confirmed it's AL2
const kernelRelease = os.release()
const hasAL2Kernel =
(kernelRelease.includes('.amzn2int.') || kernelRelease.includes('.amzn2.')) && process.platform === 'linux'

return hasAL2Kernel
}

/**
Expand Down Expand Up @@ -217,9 +237,9 @@ export function getExtRuntimeContext(): {
extensionHost: ExtensionHostLocation
} {
const extensionHost =
// taken from https://github.com/microsoft/vscode/blob/7c9e4bb23992c63f20cd86bbe7a52a3aa4bed89d/extensions/github-authentication/src/githubServer.ts#L121 to help determine which auth flows
// should be used
typeof navigator === 'undefined'
// Check if we're in a Node.js environment (desktop/remote) vs web worker
// Updated to be compatible with Node.js v22 which includes navigator global
typeof process === 'object' && process.versions?.node
? globals.context.extension.extensionKind === vscode.ExtensionKind.UI
? 'local'
: 'remote'
Expand Down
17 changes: 17 additions & 0 deletions packages/core/src/test/shared/vscode/env.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import path from 'path'
import { isCloudDesktop, getEnvVars, getServiceEnvVarConfig, isAmazonLinux2, isBeta } from '../../../shared/vscode/env'
import { ChildProcess } from '../../../shared/utilities/processUtils'
import * as sinon from 'sinon'
import * as nodeFs from 'fs' // eslint-disable-line no-restricted-imports
import os from 'os'
import fs from '../../../shared/fs/fs'
import vscode from 'vscode'
Expand Down Expand Up @@ -100,13 +101,29 @@ describe('env', function () {
it('isAmazonLinux2', function () {
sandbox.stub(process, 'platform').value('linux')
const versionStub = stubOsVersion('5.10.220-188.869.amzn2int.x86_64')

// Test with actual AL2 kernel
assert.strictEqual(isAmazonLinux2(), true)

versionStub.returns('5.10.236-227.928.amzn2.x86_64')
assert.strictEqual(isAmazonLinux2(), true)

versionStub.returns('5.10.220-188.869.NOT_INTERNAL.x86_64')
assert.strictEqual(isAmazonLinux2(), false)

// Test with container environment (Ubuntu container on AL2 host)
versionStub.returns('5.10.236-227.928.amzn2.x86_64')
const existsStub = sandbox.stub(nodeFs, 'existsSync').returns(true)
const readFileStub = sandbox.stub(nodeFs, 'readFileSync').returns('ID="ubuntu"\nVERSION_ID="20.04"')
assert.strictEqual(isAmazonLinux2(), false, 'Should return false for Ubuntu container on AL2 host')

// Test with actual AL2 in /etc/os-release
readFileStub.returns('ID="amzn"\nVERSION_ID="2"')
assert.strictEqual(isAmazonLinux2(), true, 'Should return true for actual AL2')

// Clean up stubs
existsStub.restore()
readFileStub.restore()
})

it('isCloudDesktop', async function () {
Expand Down
Loading