mirror of
https://github.com/apple/container.git
synced 2026-09-26 17:45:41 +00:00
APIServer: Add support for filtering to list rpc (#1175)
This is not intended to be used to support `--filter` or similar on the CLIs list yet, it's solely to clean up our rather awkward use of `ContainerClient.list()` today in the CLI. The list RPC simply returns all of the containers we have created. Because of this, for a LOT of our commands we filter to what we need client side, which feels like a waste.. This change introduces a filter struct that we can provide an array of container IDs, labels, and the status of the containers to filter the `list()` output from. This additionally, because it was killing (pun not intended) me and I was already having to change this area for the `list()` additions, changes container kill slightly to return an error if you try and kill a container that doesn't exist.
This commit is contained in:
@@ -75,10 +75,12 @@ public struct ContainerClient: Sendable {
|
||||
}
|
||||
}
|
||||
|
||||
/// List all containers.
|
||||
public func list() async throws -> [ContainerSnapshot] {
|
||||
/// List containers matching the given filters.
|
||||
public func list(filters: ContainerListFilters = .all) async throws -> [ContainerSnapshot] {
|
||||
do {
|
||||
let request = XPCMessage(route: .containerList)
|
||||
let filterData = try JSONEncoder().encode(filters)
|
||||
request.set(key: .listFilters, value: filterData)
|
||||
|
||||
let response = try await xpcSend(
|
||||
message: request,
|
||||
@@ -100,8 +102,8 @@ public struct ContainerClient: Sendable {
|
||||
|
||||
/// Get the container for the provided id.
|
||||
public func get(id: String) async throws -> ContainerSnapshot {
|
||||
let containers = try await list()
|
||||
guard let container = containers.first(where: { $0.configuration.id == id }) else {
|
||||
let containers = try await list(filters: ContainerListFilters(ids: [id]))
|
||||
guard let container = containers.first else {
|
||||
throw ContainerizationError(
|
||||
.notFound,
|
||||
message: "get failed: container \(id) not found"
|
||||
|
||||
@@ -124,6 +124,9 @@ public enum XPCKeys: String {
|
||||
case statistics
|
||||
case containerSize
|
||||
|
||||
/// Container list filters
|
||||
case listFilters
|
||||
|
||||
/// Disk usage
|
||||
case diskUsageStats
|
||||
}
|
||||
|
||||
@@ -33,7 +33,11 @@ public struct ContainersHarness: Sendable {
|
||||
|
||||
@Sendable
|
||||
public func list(_ message: XPCMessage) async throws -> XPCMessage {
|
||||
let containers = try await service.list()
|
||||
var filters = ContainerListFilters.all
|
||||
if let filterData = message.dataNoCopy(key: .listFilters) {
|
||||
filters = try JSONDecoder().decode(ContainerListFilters.self, from: filterData)
|
||||
}
|
||||
let containers = try await service.list(filters: filters)
|
||||
let data = try JSONEncoder().encode(containers)
|
||||
|
||||
let reply = message.reply()
|
||||
|
||||
@@ -106,10 +106,33 @@ public actor ContainersService {
|
||||
return results
|
||||
}
|
||||
|
||||
/// List all containers registered with the service.
|
||||
public func list() async throws -> [ContainerSnapshot] {
|
||||
/// List containers matching the given filters.
|
||||
public func list(filters: ContainerListFilters = .all) async throws -> [ContainerSnapshot] {
|
||||
self.log.debug("\(#function)")
|
||||
return self.containers.values.map { $0.snapshot }
|
||||
|
||||
return self.containers.values.compactMap { state -> ContainerSnapshot? in
|
||||
let snapshot = state.snapshot
|
||||
|
||||
if !filters.ids.isEmpty {
|
||||
guard filters.ids.contains(snapshot.id) else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
if let status = filters.status {
|
||||
guard snapshot.status == status else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
for (key, value) in filters.labels {
|
||||
guard snapshot.configuration.labels[key] == value else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
return snapshot
|
||||
}
|
||||
}
|
||||
|
||||
/// Execute an operation with the current container list while maintaining atomicity
|
||||
|
||||
Reference in New Issue
Block a user