-
Notifications
You must be signed in to change notification settings - Fork 874
feat(agent): add container list handler #16346
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 our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
a17ca58
to
798f1a3
Compare
coderd/util/maps/maps.go
Outdated
func Subset[T, U comparable](a, b map[T]U) bool { | ||
for ka, va := range a { | ||
if vb, ok := b[ka]; !ok { | ||
return false | ||
} else if va != vb { | ||
return false | ||
} | ||
} | ||
return true | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
review: I couldn't find a stdlib function for this, so rolled my own. I'd love to get rid of this.
7a55cf7
to
a56462e
Compare
agent/containers_dockercli.go
Outdated
} | ||
} | ||
|
||
// convertDockerVolume converts a Docker volume string to a host path and |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Again, if there's pre-existing code I'd be happy to use this.
// Running is true if the container is currently running. | ||
Running bool `json:"running"` | ||
// Ports includes ports exposed by the container. | ||
Ports []WorkspaceAgentListeningPort `json:"ports"` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm re-using this struct, as any exposed port should also function the same way as a "listening port".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great work 👍
Left mostly small comments
return | ||
} | ||
|
||
// Filter in-place by labels |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Curious why we don't pass the label filtering down to where the data is collected?
docker
can filter by label
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I found that co-locating filtering and caching gets difficult.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's a good point Cian, although I'd question the premise of caching at this stage, did you find it was a requirement to have any form of responsive UI? Is docker ps
too slow?
It would be easier to just run multiple docker ps
commands in parallel if there are multiple requests inbound.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Eh, perhaps. The caching logic isn't overly complex, and I was mainly copying the pattern from the listening-ports
handler. I can remove it if you feel strongly about it, but I suspect it'll be needed -- especially if someone is running lots of containers in their workspace.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Alright, I simply raised it since a little slow is probably fine for the first deliverable, and caching prematurely may solve or hide the wrong problem. I leave it up to you though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice work, Cian! Looking past nits and suggestions, in broad strokes I'd like to see:
- Separate agent/containers package
- No explicit dependency on docker for testing (e.g. skip)
- Single "container" output from agent that can be consumed in a generic way in e.g. UI, so that docker can be swapped out for another backend and everything behaves the same
s/container/devcontainer/
makes sense to me, but perhaps I'm overlooking something
agent/api.go
Outdated
@@ -35,7 +35,11 @@ func (a *agent) apiHandler() http.Handler { | |||
ignorePorts: cpy, | |||
cacheDuration: cacheDuration, | |||
} | |||
ch := &containersHandler{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
At this level, calling this devcontainers rather than containers would make more sense to me. The idea being that we process devcontainer related stuff on the agent and expose it in a neat package to coderd and don't need logic over there to handle different types.
I might be overlooking something, though, so feel free to dismiss if there's a good reason for the naming.
return | ||
} | ||
|
||
// Filter in-place by labels |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's a good point Cian, although I'd question the premise of caching at this stage, did you find it was a requirement to have any form of responsive UI? Is docker ps
too slow?
It would be easier to just run multiple docker ps
commands in parallel if there are multiple requests inbound.
@dannykopping @mafredri I think I'm ready for round 2 now. I still need to use |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This PR is looking quite good! Just a few minor things and while testing this PR I realized we don't include mounts in the output. I think that could be relevant, like volumes, but I'll defer to you whether or not we include those.
We should still make the agentexec
changes, but other than that, approved!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
Adds an API endpoint to coderd `/api/v2/workspaceagents/:id/containers` that allows listing containers visible to the agent. This initial implementation only supports listing containers using the Docker CLI. Support for other data sources may be added at a future date.
2c87b7e
to
8b081ac
Compare
Fixes #16268
This PR adds an API endpoint to coderd
/api/v2/workspaceagents/:id/containers
that allows listing containers visible to the agent. Optional filtering by labels is supported.A later PR will consume this endpoint and use it to expose this information to users.
Under the hood, this operates in a very similar manner to the
listening-ports
endpoint --coderd
dials the workspace agent and hits an agent endpoint exposed overtailnet
.This initial implementation only supports listing containers using the Docker CLI. Support for other data sources may be added at a future date.
Sample response:
Sample error response: