Add rootfs override (#1323)

This PR adds an option in `ContainerCreateOption` to override the root
filesystem of container. When `ContainerCreateOption.rootFsOverride` is
set, container uses that as the root fs instead of the one cloned from
image snapshot.

## Type of Change
- [ ] Bug fix
- [X] New feature  
- [ ] Breaking change
- [ ] Documentation update

## Motivation and Context
[Why is this change needed?]

## Testing
- [X] Tested locally
- [ ] Added/updated tests
- [ ] Added/updated docs
This commit is contained in:
jwhur
2026-03-18 13:49:13 -07:00
committed by GitHub
parent 77ed6c54ed
commit 26aae3e241
3 changed files with 17 additions and 7 deletions
@@ -110,9 +110,11 @@ extension Bundle {
try bundle.write(filename: Self.containerConfigFilename, value: containerConfiguration)
}
if let containerRootFilesystem {
if let rootFsOverride = options?.rootFsOverride {
try bundle.setContainerRootFs(fs: rootFsOverride)
} else if let containerRootFilesystem {
let readonly = containerConfiguration?.readOnly ?? false
try bundle.setContainerRootFs(cloning: containerRootFilesystem, readonly: readonly)
try bundle.cloneContainerRootFs(cloning: containerRootFilesystem, readonly: readonly)
}
if let options {
@@ -133,14 +135,18 @@ extension Bundle {
path.appendingPathComponent(name)
}
public func setContainerRootFs(cloning fs: Filesystem, readonly: Bool = false) throws {
public func setContainerRootFs(fs: Filesystem) throws {
let fsData = try JSONEncoder().encode(fs)
try fsData.write(to: self.containerRootfsConfig)
}
public func cloneContainerRootFs(cloning fs: Filesystem, readonly: Bool = false) throws {
var mutableFs = fs
if readonly && !mutableFs.options.contains("ro") {
mutableFs.options.append("ro")
}
let cloned = try mutableFs.clone(to: self.containerRootfsBlock.absolutePath())
let fsData = try JSONEncoder().encode(cloned)
try fsData.write(to: self.containerRootfsConfig)
try setContainerRootFs(fs: cloned)
}
/// Delete the bundle and all of the resources contained inside.
@@ -15,10 +15,14 @@
//===----------------------------------------------------------------------===//
public struct ContainerCreateOptions: Codable, Sendable {
/// Remove the container and wipe out its data on container stop
public let autoRemove: Bool
/// Override the rootFs with this one other than the image-cloned version
public let rootFsOverride: Filesystem?
public init(autoRemove: Bool) {
public init(autoRemove: Bool, rootFsOverride: Filesystem? = nil) {
self.autoRemove = autoRemove
self.rootFsOverride = rootFsOverride
}
public static let `default` = ContainerCreateOptions(autoRemove: false)
@@ -364,7 +364,7 @@ public actor ContainersService {
"ref": "\(configuration.image.reference)",
])
let containerImage = ClientImage(description: configuration.image)
let imageFs = try await containerImage.getCreateSnapshot(platform: configuration.platform)
let imageFs = try await options.rootFsOverride == nil ? containerImage.getCreateSnapshot(platform: configuration.platform) : nil
self.log.debug(
"configure runtime",