Skip to content

Commit d9ced68

Browse files
authored
fix(amazonq): fix chat on old glibc platforms (#5754)
AL2 needs patched version of node for chat to work
1 parent 7ec20c4 commit d9ced68

File tree

3 files changed

+97
-27
lines changed

3 files changed

+97
-27
lines changed

plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/AmazonQLspService.kt

Lines changed: 27 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -372,35 +372,35 @@ private class AmazonQServerInstance(private val project: Project, private val cs
372372
}
373373

374374
val node = if (SystemInfo.isWindows) "node.exe" else "node"
375-
val cmd = GeneralCommandLine(
376-
artifact.resolve(node).toString(),
377-
LspSettings.getInstance().getArtifactPath() ?: artifact.resolve("aws-lsp-codewhisperer.js").toString(),
378-
"--stdio",
379-
"--set-credentials-encryption-key",
380-
).withEnvironment(
381-
buildMap {
382-
put("NODE_EXTRA_CA_CERTS", extraCaCerts.toAbsolutePath().toString())
383-
384-
val proxy = JdkProxyProvider.getInstance().proxySelector.select(qUri)
385-
// log if only socks proxy available
386-
.firstOrNull { it.type() == Proxy.Type.HTTP }
387-
388-
if (proxy != null) {
389-
val address = proxy.address()
390-
if (address is java.net.InetSocketAddress) {
391-
put(
392-
"HTTPS_PROXY",
393-
URIBuilder("http://${address.hostName}:${address.port}").apply {
394-
val login = HttpConfigurable.getInstance().proxyLogin
395-
if (login != null) {
396-
setUserInfo(login, HttpConfigurable.getInstance().plainProxyPassword)
397-
}
398-
}.build().toASCIIString()
399-
)
375+
val cmd = NodeExePatcher.patch(artifact.resolve(node))
376+
.withParameters(
377+
LspSettings.getInstance().getArtifactPath() ?: artifact.resolve("aws-lsp-codewhisperer.js").toString(),
378+
"--stdio",
379+
"--set-credentials-encryption-key",
380+
).withEnvironment(
381+
buildMap {
382+
put("NODE_EXTRA_CA_CERTS", extraCaCerts.toAbsolutePath().toString())
383+
384+
val proxy = JdkProxyProvider.getInstance().proxySelector.select(qUri)
385+
// log if only socks proxy available
386+
.firstOrNull { it.type() == Proxy.Type.HTTP }
387+
388+
if (proxy != null) {
389+
val address = proxy.address()
390+
if (address is java.net.InetSocketAddress) {
391+
put(
392+
"HTTPS_PROXY",
393+
URIBuilder("http://${address.hostName}:${address.port}").apply {
394+
val login = HttpConfigurable.getInstance().proxyLogin
395+
if (login != null) {
396+
setUserInfo(login, HttpConfigurable.getInstance().plainProxyPassword)
397+
}
398+
}.build().toASCIIString()
399+
)
400+
}
400401
}
401402
}
402-
}
403-
)
403+
)
404404
.withParentEnvironmentType(GeneralCommandLine.ParentEnvironmentType.CONSOLE)
405405

406406
launcherHandler = KillableColoredProcessHandler.Silent(cmd)
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
// Copyright 2025 Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
package software.aws.toolkits.jetbrains.services.amazonq.lsp
5+
6+
import com.intellij.execution.configurations.GeneralCommandLine
7+
import software.aws.toolkits.core.utils.getLogger
8+
import software.aws.toolkits.core.utils.info
9+
import java.nio.file.Path
10+
11+
/**
12+
* Hacky nonsense to support old glibc platforms like AL2
13+
* @see "https://github.com/microsoft/vscode/issues/231623"
14+
* @see "https://github.com/aws/aws-toolkit-vscode/commit/6081f890bdbb91fcd8b60c4cc0abb65b15d4a38d"
15+
*/
16+
object NodeExePatcher {
17+
const val GLIBC_LINKER_VAR = "VSCODE_SERVER_CUSTOM_GLIBC_LINKER"
18+
const val GLIBC_PATH_VAR = "VSCODE_SERVER_CUSTOM_GLIBC_PATH"
19+
20+
fun patch(node: Path): GeneralCommandLine {
21+
val linker = System.getenv(GLIBC_LINKER_VAR)
22+
val glibc = System.getenv(GLIBC_PATH_VAR)
23+
val nodePath = node.toAbsolutePath().toString()
24+
25+
return if (!linker.isNullOrEmpty() && !glibc.isNullOrEmpty()) {
26+
GeneralCommandLine(linker)
27+
.withParameters("--library-path", glibc, nodePath)
28+
.also {
29+
getLogger<NodeExePatcher>().info { "Using glibc patch: $it" }
30+
}
31+
} else {
32+
GeneralCommandLine(nodePath)
33+
}
34+
}
35+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
// Copyright 2025 Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
package software.aws.toolkits.jetbrains.services.amazonq.lsp
5+
6+
import com.intellij.execution.configurations.GeneralCommandLine
7+
import org.assertj.core.api.Assertions.assertThat
8+
import org.junit.Rule
9+
import org.junit.Test
10+
import software.aws.toolkits.core.rules.EnvironmentVariableHelper
11+
import kotlin.io.path.Path
12+
13+
class NodeExePatcherTest {
14+
@get:Rule
15+
val envVarHelper = EnvironmentVariableHelper()
16+
17+
private val pathToNode = Path("/path/to/node").toAbsolutePath().toString()
18+
19+
@Test
20+
fun `patches if path available`() {
21+
envVarHelper[NodeExePatcher.GLIBC_LINKER_VAR] = "/opt/vsc-sysroot/lib/ld-linux-x86-64.so.2"
22+
envVarHelper[NodeExePatcher.GLIBC_PATH_VAR] = "/opt/vsc-sysroot/lib/"
23+
24+
assertThat(NodeExePatcher.patch(Path("/path/to/node")))
25+
.usingComparator(Comparator.comparing { it.commandLineString })
26+
.isEqualTo(GeneralCommandLine("/opt/vsc-sysroot/lib/ld-linux-x86-64.so.2", "--library-path", "/opt/vsc-sysroot/lib/", pathToNode))
27+
}
28+
29+
@Test
30+
fun `noop if no patch available`() {
31+
assertThat(NodeExePatcher.patch(Path("/path/to/node")))
32+
.usingComparator(Comparator.comparing { it.commandLineString })
33+
.isEqualTo(GeneralCommandLine(pathToNode))
34+
}
35+
}

0 commit comments

Comments
 (0)