Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

prevent unintended early return from skipping writing wildcard configs#539

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged
Show file tree
Hide file tree
Changes fromall 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
4 changes: 4 additions & 0 deletionsCHANGELOG.md
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -4,6 +4,10 @@

## Unreleased

### Fixed

- Fix bug where wildcard configs would not be written under certain conditions.

## 2.18.1 - 2025-02-14

### Changed
Expand Down
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -167,12 +167,11 @@ class CoderSettingsConfigurable : BoundConfigurable("Coder") {
}
}

private fun validateDataDirectory(): ValidationInfoBuilder.(JBTextField) -> ValidationInfo? =
{
if (it.text.isNotBlank() && !Path.of(it.text).canCreateDirectory()) {
error("Cannot create this directory")
} else {
null
}
private fun validateDataDirectory(): ValidationInfoBuilder.(JBTextField) -> ValidationInfo? = {
if (it.text.isNotBlank() && !Path.of(it.text).canCreateDirectory()) {
error("Cannot create this directory")
} else {
null
}
}
}
97 changes: 47 additions & 50 deletionssrc/main/kotlin/com/coder/gateway/cli/CoderCLIManager.kt
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -257,7 +257,6 @@
val host = deploymentURL.safeHost()
val startBlock = "# --- START CODER JETBRAINS $host"
val endBlock = "# --- END CODER JETBRAINS $host"
val isRemoving = workspaceNames.isEmpty()
val baseArgs =
listOfNotNull(
escape(localBinaryPath.toString()),
Expand DownExpand Up@@ -308,35 +307,36 @@
Host ${getHostPrefix()}-bg--*
ProxyCommand ${backgroundProxyArgs.joinToString(" ")} --ssh-host-prefix ${getHostPrefix()}-bg-- %h
""".trimIndent()
.plus("\n" + sshOpts.prependIndent(" "))
.plus(extraConfig),
.plus("\n" + sshOpts.prependIndent(" "))
.plus(extraConfig),
).replace("\n", System.lineSeparator()) +
System.lineSeparator() + endBlock

} else {
workspaceNames.joinToString(
System.lineSeparator(),
startBlock + System.lineSeparator(),
System.lineSeparator() + endBlock,
transform = {
"""
} else if (workspaceNames.isEmpty()) {
""
} else {
workspaceNames.joinToString(
System.lineSeparator(),
startBlock + System.lineSeparator(),
System.lineSeparator() + endBlock,
transform = {
"""
Host ${getHostName(it.first, currentUser, it.second)}
ProxyCommand ${proxyArgs.joinToString(" ")} ${getWorkspaceParts(it.first, it.second)}
""".trimIndent()
.plus("\n" + sshOpts.prependIndent(" "))
.plus(extraConfig)
.plus("\n")
.plus(
"""
""".trimIndent()
.plus("\n" + sshOpts.prependIndent(" "))
.plus(extraConfig)
.plus("\n")
.plus(
"""
Host ${getBackgroundHostName(it.first, currentUser, it.second)}
ProxyCommand ${backgroundProxyArgs.joinToString(" ")} ${getWorkspaceParts(it.first, it.second)}
""".trimIndent()
.plus("\n" + sshOpts.prependIndent(" "))
.plus(extraConfig),
).replace("\n", System.lineSeparator())
},
)
}
""".trimIndent()
.plus("\n" + sshOpts.prependIndent(" "))
.plus(extraConfig),
).replace("\n", System.lineSeparator())
},
)
}

if (contents == null) {
logger.info("No existing SSH config to modify")
Expand All@@ -346,6 +346,8 @@
val start = "(\\s*)$startBlock".toRegex().find(contents)
val end = "$endBlock(\\s*)".toRegex().find(contents)

val isRemoving = blockContent.isEmpty()

if (start == null && end == null && isRemoving) {
logger.info("No workspaces and no existing config blocks to remove")
return null
Expand DownExpand Up@@ -477,15 +479,13 @@
*
* Throws if the command execution fails.
*/
fun startWorkspace(workspaceOwner: String, workspaceName: String): String {
return exec(
"--global-config",
coderConfigPath.toString(),
"start",
"--yes",
workspaceOwner+"/"+workspaceName,
)
}
fun startWorkspace(workspaceOwner: String, workspaceName: String): String = exec(
"--global-config",
coderConfigPath.toString(),
"start",
"--yes",
workspaceOwner + "/" + workspaceName,

Check notice on line 487 in src/main/kotlin/com/coder/gateway/cli/CoderCLIManager.kt

View workflow job for this annotation

GitHub Actions/ Qodana Community for JVM

String concatenation that can be converted to string template

'String' concatenation can be converted to a template
)

private fun exec(vararg args: String): String {
val stdout =
Expand DownExpand Up@@ -518,8 +518,7 @@
/*
* This function returns the ssh-host-prefix used for Host entries.
*/
fun getHostPrefix(): String =
"coder-jetbrains-${deploymentURL.safeHost()}"
fun getHostPrefix(): String = "coder-jetbrains-${deploymentURL.safeHost()}"

Check notice on line 521 in src/main/kotlin/com/coder/gateway/cli/CoderCLIManager.kt

View workflow job for this annotation

GitHub Actions/ Qodana Community for JVM

Class member can have 'private' visibility

Function 'getHostPrefix' could be private

/**
* This function returns the ssh host name generated for connecting to the workspace.
Expand All@@ -528,29 +527,27 @@
workspace: Workspace,
currentUser: User,
agent: WorkspaceAgent,
): String =
if (features.wildcardSSH) {
"${getHostPrefix()}--${workspace.ownerName}--${workspace.name}.${agent.name}"
): String = if (features.wildcardSSH) {
"${getHostPrefix()}--${workspace.ownerName}--${workspace.name}.${agent.name}"
} else {
// For a user's own workspace, we use the old syntax without a username for backwards compatibility,
// since the user might have recent connections that still use the old syntax.
if (currentUser.username == workspace.ownerName) {
"coder-jetbrains--${workspace.name}.${agent.name}--${deploymentURL.safeHost()}"
} else {
// For a user's own workspace, we use the old syntax without a username for backwards compatibility,
// since the user might have recent connections that still use the old syntax.
if (currentUser.username == workspace.ownerName) {
"coder-jetbrains--${workspace.name}.${agent.name}--${deploymentURL.safeHost()}"
} else {
"coder-jetbrains--${workspace.ownerName}--${workspace.name}.${agent.name}--${deploymentURL.safeHost()}"
"coder-jetbrains--${workspace.ownerName}--${workspace.name}.${agent.name}--${deploymentURL.safeHost()}"
}
}

fun getBackgroundHostName(
workspace: Workspace,
currentUser: User,
agent: WorkspaceAgent,
): String =
if (features.wildcardSSH) {
"${getHostPrefix()}-bg--${workspace.ownerName}--${workspace.name}.${agent.name}"
} else {
getHostName(workspace, currentUser, agent) + "--bg"
}
): String = if (features.wildcardSSH) {
"${getHostPrefix()}-bg--${workspace.ownerName}--${workspace.name}.${agent.name}"
} else {
getHostName(workspace, currentUser, agent) + "--bg"
}

companion object {
val logger = Logger.getInstance(CoderCLIManager::class.java.simpleName)
Expand All@@ -577,7 +574,7 @@
}
// non-wildcard case
if (parts[0] == "coder-jetbrains") {
return hostname + "--bg"

Check notice on line 577 in src/main/kotlin/com/coder/gateway/cli/CoderCLIManager.kt

View workflow job for this annotation

GitHub Actions/ Qodana Community for JVM

String concatenation that can be converted to string template

'String' concatenation can be converted to a template
}
// wildcard case
parts[0] += "-bg"
Expand Down
83 changes: 41 additions & 42 deletionssrc/main/kotlin/com/coder/gateway/icons/CoderIcons.kt
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -63,48 +63,47 @@ object CoderIcons {
private val Y = IconLoader.getIcon("symbols/y.svg", javaClass)
private val Z = IconLoader.getIcon("symbols/z.svg", javaClass)

fun fromChar(c: Char) =
when (c) {
'0' -> ZERO
'1' -> ONE
'2' -> TWO
'3' -> THREE
'4' -> FOUR
'5' -> FIVE
'6' -> SIX
'7' -> SEVEN
'8' -> EIGHT
'9' -> NINE

'a' -> A
'b' -> B
'c' -> C
'd' -> D
'e' -> E
'f' -> F
'g' -> G
'h' -> H
'i' -> I
'j' -> J
'k' -> K
'l' -> L
'm' -> M
'n' -> N
'o' -> O
'p' -> P
'q' -> Q
'r' -> R
's' -> S
't' -> T
'u' -> U
'v' -> V
'w' -> W
'x' -> X
'y' -> Y
'z' -> Z

else -> UNKNOWN
}
fun fromChar(c: Char) = when (c) {
'0' -> ZERO
'1' -> ONE
'2' -> TWO
'3' -> THREE
'4' -> FOUR
'5' -> FIVE
'6' -> SIX
'7' -> SEVEN
'8' -> EIGHT
'9' -> NINE

'a' -> A
'b' -> B
'c' -> C
'd' -> D
'e' -> E
'f' -> F
'g' -> G
'h' -> H
'i' -> I
'j' -> J
'k' -> K
'l' -> L
'm' -> M
'n' -> N
'o' -> O
'p' -> P
'q' -> Q
'r' -> R
's' -> S
't' -> T
'u' -> U
'v' -> V
'w' -> W
'x' -> X
'y' -> Y
'z' -> Z

else -> UNKNOWN
}
}

fun alignToInt(g: Graphics) {
Expand Down
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -47,13 +47,12 @@ enum class WorkspaceAndAgentStatus(val label: String, val description: String) {
READY("Ready", "The agent is ready to accept connections."),
;

fun statusColor(): JBColor =
when (this) {
READY, AGENT_STARTING_READY, START_TIMEOUT_READY -> JBColor.GREEN
CREATED, START_ERROR, START_TIMEOUT, SHUTDOWN_TIMEOUT -> JBColor.YELLOW
FAILED, DISCONNECTED, TIMEOUT, SHUTDOWN_ERROR -> JBColor.RED
else -> if (JBColor.isBright()) JBColor.LIGHT_GRAY else JBColor.DARK_GRAY
}
fun statusColor(): JBColor = when (this) {
READY, AGENT_STARTING_READY, START_TIMEOUT_READY -> JBColor.GREEN
CREATED, START_ERROR, START_TIMEOUT, SHUTDOWN_TIMEOUT -> JBColor.YELLOW
FAILED, DISCONNECTED, TIMEOUT, SHUTDOWN_ERROR -> JBColor.RED
else -> if (JBColor.isBright()) JBColor.LIGHT_GRAY else JBColor.DARK_GRAY
}

/**
* Return true if the agent is in a connectable state.
Expand Down
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -12,10 +12,9 @@ import java.time.temporal.TemporalAccessor
class InstantConverter {
@ToJson fun toJson(src: Instant?): String = FORMATTER.format(src)

@FromJson fun fromJson(src: String): Instant? =
FORMATTER.parse(src) { temporal: TemporalAccessor? ->
Instant.from(temporal)
}
@FromJson fun fromJson(src: String): Instant? = FORMATTER.parse(src) { temporal: TemporalAccessor? ->
Instant.from(temporal)
}

companion object {
private val FORMATTER = DateTimeFormatter.ISO_INSTANT
Expand Down
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -188,7 +188,7 @@ open class CoderSettings(
* Whether to check for IDE updates.
*/
val checkIDEUpdate: Boolean
get() = state.checkIDEUpdates
get() = state.checkIDEUpdates

/**
* Whether to ignore a failed setup command.
Expand Down
17 changes: 17 additions & 0 deletionssrc/test/fixtures/inputs/wildcard.conf
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
# --- START CODER JETBRAINS test.coder.invalid
Host coder-jetbrains-test.coder.invalid--*
ProxyCommand /tmp/coder-gateway/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-gateway/test.coder.invalid/config --url https://test.coder.invalid ssh --stdio --ssh-host-prefix coder-jetbrains-test.coder.invalid-- %h
ConnectTimeout 0
StrictHostKeyChecking no
UserKnownHostsFile /dev/null
LogLevel ERROR
SetEnv CODER_SSH_SESSION_TYPE=JetBrains

Host coder-jetbrains-test.coder.invalid-bg--*
ProxyCommand /tmp/coder-gateway/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-gateway/test.coder.invalid/config --url https://test.coder.invalid ssh --stdio --ssh-host-prefix coder-jetbrains-test.coder.invalid-bg-- %h
ConnectTimeout 0
StrictHostKeyChecking no
UserKnownHostsFile /dev/null
LogLevel ERROR
SetEnv CODER_SSH_SESSION_TYPE=JetBrains
# --- END CODER JETBRAINS test.coder.invalid
18 changes: 15 additions & 3 deletionssrc/test/kotlin/com/coder/gateway/cli/CoderCLIManagerTest.kt
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -423,7 +423,7 @@ internal class CoderCLIManagerTest {
listOf(workspace),
input = null,
output = "wildcard",
remove = "blank",
remove = "wildcard",
features = Features(
wildcardSSH = true,
),
Expand DownExpand Up@@ -472,6 +472,19 @@ internal class CoderCLIManagerTest {
}
}

val inputConf =
Path.of("src/test/fixtures/inputs/").resolve(it.remove + ".conf").toFile().readText()
.replace(newlineRe, System.lineSeparator())
.replace("/tmp/coder-gateway/test.coder.invalid/config", escape(coderConfigPath.toString()))
.replace("/tmp/coder-gateway/test.coder.invalid/coder-linux-amd64", escape(ccm.localBinaryPath.toString()))
.let { conf ->
if (it.sshLogDirectory != null) {
conf.replace("/tmp/coder-gateway/test.coder.invalid/logs", it.sshLogDirectory.toString())
} else {
conf
}
}

// Add workspaces.
ccm.configSsh(
it.workspaces.flatMap { ws ->
Expand All@@ -496,8 +509,7 @@ internal class CoderCLIManagerTest {
// Remove is the configuration we expect after removing.
assertEquals(
settings.sshConfigPath.toFile().readText(),
Path.of("src/test/fixtures/inputs").resolve(it.remove + ".conf").toFile()
.readText().replace(newlineRe, System.lineSeparator()),
inputConf
)
}
}
Expand Down
Loading

[8]ページ先頭

©2009-2025 Movatter.jp