LinuxContainer: Add new constructor (#377)

Add a constructor that allows just passing in a configuration without
doing the closure dance.
This commit is contained in:
Danny Canter
2025-10-31 14:27:39 -07:00
committed by GitHub
parent 0177505c58
commit f3d998975c
3 changed files with 88 additions and 4 deletions
+62 -4
View File
@@ -64,6 +64,34 @@ public final class LinuxContainer: Container, Sendable {
public var bootlog: URL?
public init() {}
public init(
process: LinuxProcessConfiguration,
cpus: Int = 4,
memoryInBytes: UInt64 = 1024.mib(),
hostname: String = "",
sysctl: [String: String] = [:],
interfaces: [any Interface] = [],
sockets: [UnixSocketConfiguration] = [],
mounts: [Mount] = LinuxContainer.defaultMounts(),
dns: DNS? = nil,
hosts: Hosts? = nil,
virtualization: Bool = false,
bootlog: URL? = nil
) {
self.process = process
self.cpus = cpus
self.memoryInBytes = memoryInBytes
self.hostname = hostname
self.sysctl = sysctl
self.interfaces = interfaces
self.sockets = sockets
self.mounts = mounts
self.dns = dns
self.hosts = hosts
self.virtualization = virtualization
self.bootlog = bootlog
}
}
private let state: AsyncMutex<State>
@@ -189,10 +217,14 @@ public final class LinuxContainer: Container, Sendable {
private let vmm: VirtualMachineManager
private let logger: Logger?
/// Create a new `LinuxContainer`. A `Mount` that contains the contents
/// of the container image must be provided, as well as a `VirtualMachineManager`
/// instance that will handle launching the virtual machine the container will
/// execute inside of.
/// Create a new `LinuxContainer`.
///
/// - Parameters:
/// - id: The identifier for the container.
/// - rootfs: The root filesystem mount containing the container image contents.
/// - vmm: The virtual machine manager that will handle launching the VM for the container.
/// - logger: Optional logger for container operations.
/// - configuration: A closure that configures the container by modifying the Configuration instance.
public init(
_ id: String,
rootfs: Mount,
@@ -214,6 +246,32 @@ public final class LinuxContainer: Container, Sendable {
self.state = AsyncMutex(.initialized)
}
/// Create a new `LinuxContainer`.
///
/// - Parameters:
/// - id: The identifier for the container.
/// - rootfs: The root filesystem mount containing the container image contents.
/// - vmm: The virtual machine manager that will handle launching the VM for the container.
/// - configuration: The container configuration specifying process, resources, networking, and other settings.
/// - logger: Optional logger for container operations.
public init(
_ id: String,
rootfs: Mount,
vmm: VirtualMachineManager,
configuration: LinuxContainer.Configuration,
logger: Logger? = nil
) {
self.id = id
self.vmm = vmm
self.hostVsockPorts = Atomic<UInt32>(0x1000_0000)
self.guestVsockPorts = Atomic<UInt32>(0x1000_0000)
self.rootfs = rootfs
self.logger = logger
self.config = configuration
self.state = AsyncMutex(.initialized)
}
private static func createDefaultRuntimeSpec(_ id: String) -> Spec {
.init(
process: .init(),
+25
View File
@@ -987,6 +987,31 @@ extension IntegrationSuite {
}
}
func testNonClosureConstructor() async throws {
let id = "test-container-non-closure-constructor"
let bs = try await bootstrap(id)
let config = LinuxContainer.Configuration(
process: LinuxProcessConfiguration(arguments: ["/bin/true"])
)
let container = LinuxContainer(
id,
rootfs: bs.rootfs,
vmm: bs.vmm,
configuration: config
)
try await container.create()
try await container.start()
let status = try await container.wait()
try await container.stop()
guard status.exitCode == 0 else {
throw IntegrationError.assert(msg: "process status \(status) != 0")
}
}
private func createHostUnixSocket() throws -> String {
let dir = FileManager.default.uniqueTemporaryDirectory(create: true)
let socketPath = dir.appendingPathComponent("test.sock").path
+1
View File
@@ -294,6 +294,7 @@ struct IntegrationSuite: AsyncParsableCommand {
Test("container cgroup limits", testCgroupLimits),
Test("container no serial console", testNoSerialConsole),
Test("unix socket into guest", testUnixSocketIntoGuest),
Test("container non-closure constructor", testNonClosureConstructor),
// Pods
Test("pod single container", testPodSingleContainer),