Allow custom kernel boot args via --kernel-arg (#1744)

Signed-off-by: Ari Rubinstein <22369+arirubinstein@users.noreply.github.com>
Co-authored-by: Ari Rubinstein <22369+arirubinstein@users.noreply.github.com>
This commit is contained in:
Ari Rubinstein
2026-07-27 13:44:51 -04:00
committed by GitHub
co-authored by Ari Rubinstein
parent d1d763530d
commit b229cecb53
3 changed files with 31 additions and 4 deletions
@@ -176,6 +176,7 @@ public struct Flags {
entrypoint: String?,
initImage: String?,
kernel: String?,
kernelArgs: [String],
labels: [String],
mounts: [String],
name: String?,
@@ -205,6 +206,7 @@ public struct Flags {
self.entrypoint = entrypoint
self.initImage = initImage
self.kernel = kernel
self.kernelArgs = kernelArgs
self.labels = labels
self.mounts = mounts
self.name = name
@@ -277,6 +279,15 @@ public struct Flags {
)
public var kernel: String?
@Option(
name: .customLong("kernel-arg"),
help: .init(
"Append a raw boot argument to the kernel command line (repeatable).",
valueName: "arg"
)
)
public var kernelArgs: [String] = []
@Option(name: [.short, .customLong("label")], help: "Add a key=value label to the container")
public var labels: [String] = []
@@ -330,14 +330,20 @@ public struct Utility {
// For the image itself we'll take the user input and try with it as we can do userspace
// emulation for x86, but for the kernel we need it to match the hosts architecture.
let s: SystemPlatform = .current
var kernel: Kernel
if let userKernel = management.kernel {
guard FileManager.default.fileExists(atPath: userKernel) else {
throw ContainerizationError(.notFound, message: "kernel file not found at path \(userKernel)")
}
let p = URL(filePath: userKernel)
return .init(path: p, platform: s)
kernel = .init(path: p, platform: s)
} else {
kernel = try await ClientKernel.getDefaultKernel(for: s)
}
return try await ClientKernel.getDefaultKernel(for: s)
// Persist any user-supplied boot args onto the kernel command line. A key supplied
// here overrides the runtime's matching built-in default (see RuntimeService.bootstrap).
kernel.commandLine.kernelArgs.append(contentsOf: management.kernelArgs)
return kernel
}
/// Parses key-value pairs from command line arguments.
@@ -160,8 +160,18 @@ public actor RuntimeService {
var config = try bundle.configuration
var kernel = try bundle.kernel
kernel.commandLine.kernelArgs.append("oops=panic")
kernel.commandLine.kernelArgs.append("lsm=lockdown,capability,landlock,yama,apparmor")
// Built-in defaults keyed by arg name. Each is applied only if the user did not already
// supply the same key via --kernel-arg, letting custom kernels override them (e.g. lsm=...,bpf).
let defaultKernelArgs: KeyValuePairs = [
"oops": "panic",
"lsm": "lockdown,capability,landlock,yama,apparmor",
]
for (key, value) in defaultKernelArgs {
guard !kernel.commandLine.kernelArgs.contains(where: { $0.hasPrefix("\(key)=") }) else {
continue
}
kernel.commandLine.kernelArgs.append("\(key)=\(value)")
}
let vmm = VZVirtualMachineManager(
kernel: kernel,
initialFilesystem: bundle.initialFilesystem.asMount,