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

fix: don't create new api keys each time we do workspace polling#568

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
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

- api keys are no longer created each time workspaces are polled

## 2.22.1 - 2025-07-30

### Added
Expand Down
2 changes: 1 addition & 1 deletiongradle.properties
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -5,7 +5,7 @@ pluginGroup=com.coder.gateway
artifactName=coder-gateway
pluginName=Coder
# SemVer format -> https://semver.org
pluginVersion=2.22.1
pluginVersion=2.22.2
# See https://plugins.jetbrains.com/docs/intellij/build-number-ranges.html
# for insight into build numbers and IntelliJ Platform versions.
pluginSinceBuild=243.26574
Expand Down
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -274,7 +274,7 @@

else -> {
val failure = result as VerificationResult.Failed
UnsignedBinaryExecutionDeniedException(result.error.message)

Check warning on line 277 in src/main/kotlin/com/coder/gateway/cli/CoderCLIManager.kt

View workflow job for this annotation

GitHub Actions/ Qodana Community for JVM

Throwable not thrown

Throwable instance 'UnsignedBinaryExecutionDeniedException' is not thrown
logger.error("Failed to verify signature for ${cliResult.dst}", failure.error)
}
}
Expand All@@ -288,6 +288,7 @@
return exec(
"login",
deploymentURL.toString(),
"--use-token-as-session",
"--token",
token,
"--global-config",
Expand DownExpand Up@@ -570,7 +571,7 @@
coderConfigPath.toString(),
"start",
"--yes",
workspaceOwner + "/" + workspaceName

Check notice on line 574 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
)

if (feats.buildReason) {
Expand DownExpand Up@@ -612,7 +613,7 @@
/*
* This function returns the ssh-host-prefix used for Host entries.
*/
fun getHostPrefix(): String = "coder-jetbrains-${deploymentURL.safeHost()}"

Check notice on line 616 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 DownExpand Up@@ -668,7 +669,7 @@
}
// non-wildcard case
if (parts[0] == "coder-jetbrains") {
return hostname + "--bg"

Check notice on line 672 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
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -5,7 +5,6 @@ package com.coder.gateway.views
import com.coder.gateway.CoderGatewayBundle
import com.coder.gateway.CoderGatewayConstants
import com.coder.gateway.CoderRemoteConnectionHandle
import com.coder.gateway.cli.CoderCLIManager
import com.coder.gateway.cli.ensureCLI
import com.coder.gateway.icons.CoderIcons
import com.coder.gateway.models.WorkspaceAgentListModel
Expand DownExpand Up@@ -75,8 +74,6 @@ data class DeploymentInfo(
var items: List<WorkspaceAgentListModel>? = null,
// Null if there have not been any errors yet.
var error: String? = null,
// Null if unable to ensure the CLI is downloaded.
var cli: CoderCLIManager? = null,
)

class CoderGatewayRecentWorkspaceConnectionsView(private val setContentCallback: (Component) -> Unit) :
Expand DownExpand Up@@ -178,13 +175,18 @@ class CoderGatewayRecentWorkspaceConnectionsView(private val setContentCallback:
val me = deployment?.client?.me?.username
val workspaceWithAgent = deployment?.items?.firstOrNull {
it.workspace.ownerName + "/" + it.workspace.name == workspaceName ||
(it.workspace.ownerName == me && it.workspace.name == workspaceName)
(it.workspace.ownerName == me && it.workspace.name == workspaceName)
}
val status =
if (deploymentError != null) {
Triple(UIUtil.getErrorForeground(), deploymentError, UIUtil.getBalloonErrorIcon())
} else if (workspaceWithAgent != null) {
val inLoadingState = listOf(WorkspaceStatus.STARTING, WorkspaceStatus.CANCELING, WorkspaceStatus.DELETING, WorkspaceStatus.STOPPING).contains(workspaceWithAgent.workspace.latestBuild.status)
val inLoadingState = listOf(
WorkspaceStatus.STARTING,
WorkspaceStatus.CANCELING,
WorkspaceStatus.DELETING,
WorkspaceStatus.STOPPING
).contains(workspaceWithAgent.workspace.latestBuild.status)

Triple(
workspaceWithAgent.status.statusColor(),
Expand All@@ -196,7 +198,11 @@ class CoderGatewayRecentWorkspaceConnectionsView(private val setContentCallback:
},
)
} else {
Triple(UIUtil.getContextHelpForeground(), "Querying workspace status...", AnimatedIcon.Default())
Triple(
UIUtil.getContextHelpForeground(),
"Querying workspace status...",
AnimatedIcon.Default()
)
}
val gap =
if (top) {
Expand All@@ -216,7 +222,13 @@ class CoderGatewayRecentWorkspaceConnectionsView(private val setContentCallback:
label("").resizableColumn().align(AlignX.FILL)
}.topGap(gap)

val enableLinks = listOf(WorkspaceStatus.STOPPED, WorkspaceStatus.CANCELED, WorkspaceStatus.FAILED, WorkspaceStatus.STARTING, WorkspaceStatus.RUNNING).contains(workspaceWithAgent?.workspace?.latestBuild?.status)
val enableLinks = listOf(
WorkspaceStatus.STOPPED,
WorkspaceStatus.CANCELED,
WorkspaceStatus.FAILED,
WorkspaceStatus.STARTING,
WorkspaceStatus.RUNNING
).contains(workspaceWithAgent?.workspace?.latestBuild?.status)

// We only display an API error on the first workspace rather than duplicating it on each workspace.
if (deploymentError == null || showError) {
Expand All@@ -236,9 +248,29 @@ class CoderGatewayRecentWorkspaceConnectionsView(private val setContentCallback:
if (enableLinks) {
cell(
ActionLink(workspaceProjectIDE.projectPathDisplay) {
withoutNull(deployment?.cli, workspaceWithAgent?.workspace) { cli, workspace ->
withoutNull(
deployment?.client,
workspaceWithAgent?.workspace
) { client, workspace ->
CoderRemoteConnectionHandle().connect {
if (listOf(WorkspaceStatus.STOPPED, WorkspaceStatus.CANCELED, WorkspaceStatus.FAILED).contains(workspace.latestBuild.status)) {
if (listOf(
WorkspaceStatus.STOPPED,
WorkspaceStatus.CANCELED,
WorkspaceStatus.FAILED
).contains(workspace.latestBuild.status)
) {
val cli = ensureCLI(
deploymentURL.toURL(),
client.buildInfo().version,
settings,
)
// We only need to log the cli in if we have token-based auth.
// Otherwise, we assume it is set up in the same way the plugin
// is with mTLS.
if (client.token != null) {
cli.login(client.token)
}

cli.startWorkspace(workspace.ownerName, workspace.name)
}
workspaceProjectIDE
Expand DownExpand Up@@ -289,33 +321,34 @@ class CoderGatewayRecentWorkspaceConnectionsView(private val setContentCallback:
* name, or just `workspace`, if the connection predates when we added owner
* information, in which case it belongs to the current user.
*/
private fun getConnectionsByDeployment(filter: Boolean): Map<String, Map<String, List<WorkspaceProjectIDE>>> = recentConnectionsService.getAllRecentConnections()
// Validate and parse connections.
.mapNotNull {
try {
it.toWorkspaceProjectIDE()
} catch (e: Exception) {
logger.warn("Removing invalid recent connection $it", e)
recentConnectionsService.removeConnection(it)
null
private fun getConnectionsByDeployment(filter: Boolean): Map<String, Map<String, List<WorkspaceProjectIDE>>> =
recentConnectionsService.getAllRecentConnections()
// Validate and parse connections.
.mapNotNull {
try {
it.toWorkspaceProjectIDE()
} catch (e: Exception) {
logger.warn("Removing invalid recent connection $it", e)
recentConnectionsService.removeConnection(it)
null
}
}
.filter { !filter || matchesFilter(it) }
// Group by the deployment.
.groupBy { it.deploymentURL.toString() }
// Group the connections in each deployment by workspace.
.mapValues { (_, connections) ->
connections
.groupBy { it.name.split(".", limit = 2).first() }
}
}
.filter { !filter || matchesFilter(it) }
// Group by the deployment.
.groupBy { it.deploymentURL.toString() }
// Group the connections in each deployment by workspace.
.mapValues { (_, connections) ->
connections
.groupBy { it.name.split(".", limit = 2).first() }
}

/**
* Return true if the connection matches the current filter.
*/
private fun matchesFilter(connection: WorkspaceProjectIDE): Boolean = filterString.let {
it.isNullOrBlank() ||
connection.hostname.lowercase(Locale.getDefault()).contains(it) ||
connection.projectPath.lowercase(Locale.getDefault()).contains(it)
connection.hostname.lowercase(Locale.getDefault()).contains(it) ||
connection.projectPath.lowercase(Locale.getDefault()).contains(it)
}

/**
Expand DownExpand Up@@ -362,19 +395,6 @@ class CoderGatewayRecentWorkspaceConnectionsView(private val setContentCallback:
throw Exception("Unable to make request; token was not found in CLI config.")
}

val cli = ensureCLI(
deploymentURL.toURL(),
client.buildInfo().version,
settings,
)

// We only need to log the cli in if we have token-based auth.
// Otherwise, we assume it is set up in the same way the plugin
// is with mTLS.
if (client.token != null) {
cli.login(client.token)
}

// This is purely to populate the current user, which is
// used to match workspaces that were not recorded with owner
// information.
Expand All@@ -386,7 +406,7 @@ class CoderGatewayRecentWorkspaceConnectionsView(private val setContentCallback:
connectionsByWorkspace.forEach { (name, connections) ->
if (items.firstOrNull {
it.workspace.ownerName + "/" + it.workspace.name == name ||
(it.workspace.ownerName == me && it.workspace.name == name)
(it.workspace.ownerName == me && it.workspace.name == name)
} == null
) {
logger.info("Removing recent connections for deleted workspace $name (found ${connections.size})")
Expand All@@ -395,7 +415,6 @@ class CoderGatewayRecentWorkspaceConnectionsView(private val setContentCallback:
}

deployment.client = client
deployment.cli = cli
deployment.items = items
deployment.error = null
} catch (e: Exception) {
Expand Down
Loading

[8]ページ先頭

©2009-2025 Movatter.jp