From ca657f5009754e266279ba92b6766b6ef12e766e Mon Sep 17 00:00:00 2001 From: Danny Canter Date: Thu, 23 Oct 2025 14:32:56 -0700 Subject: [PATCH] Always provide a serial console (#346) --- .../VZVirtualMachineInstance.swift | 4 ++++ Sources/Integration/ContainerTests.swift | 19 +++++++++++++++++++ Sources/Integration/Suite.swift | 1 + 3 files changed, 24 insertions(+) diff --git a/Sources/Containerization/VZVirtualMachineInstance.swift b/Sources/Containerization/VZVirtualMachineInstance.swift index e7b43d8a..a282e8d5 100644 --- a/Sources/Containerization/VZVirtualMachineInstance.swift +++ b/Sources/Containerization/VZVirtualMachineInstance.swift @@ -265,8 +265,12 @@ extension VZVirtualMachineInstance.Configuration { config.memorySize = self.memoryInBytes config.entropyDevices = [VZVirtioEntropyDeviceConfiguration()] config.socketDevices = [VZVirtioSocketDeviceConfiguration()] + if let bootlog = self.bootlog { config.serialPorts = try serialPort(path: bootlog) + } else { + // We always supply a serial console. If no explicit path was provided just send em to the void. + config.serialPorts = try serialPort(path: URL(filePath: "/dev/null")) } config.networkDevices = try self.interfaces.map { diff --git a/Sources/Integration/ContainerTests.swift b/Sources/Integration/ContainerTests.swift index c8c19539..4d42f6a4 100644 --- a/Sources/Integration/ContainerTests.swift +++ b/Sources/Integration/ContainerTests.swift @@ -999,6 +999,25 @@ extension IntegrationSuite { } } + func testNoSerialConsole() async throws { + let id = "test-no-serial-console" + + let bs = try await bootstrap(id) + let container = try LinuxContainer(id, rootfs: bs.rootfs, vmm: bs.vmm) { config in + config.process.arguments = ["/bin/true"] + } + + 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 createMountDirectory() throws -> URL { let dir = FileManager.default.uniqueTemporaryDirectory(create: true) try "hello".write(to: dir.appendingPathComponent("hi.txt"), atomically: true, encoding: .utf8) diff --git a/Sources/Integration/Suite.swift b/Sources/Integration/Suite.swift index 5cc9e12b..e916350a 100644 --- a/Sources/Integration/Suite.swift +++ b/Sources/Integration/Suite.swift @@ -291,6 +291,7 @@ struct IntegrationSuite: AsyncParsableCommand { Test("container /dev/console", testContainerDevConsole), Test("container statistics", testContainerStatistics), Test("container cgroup limits", testCgroupLimits), + Test("container no serial console", testNoSerialConsole), // Pods Test("pod single container", testPodSingleContainer),