Skip to content

Commit 3d009df

Browse files
committed
Wrap LinuxBlockIO with a Containerization type
Mirrors the LinuxRLimit/LinuxCapabilities pattern so the public API can evolve independently of the OCI spec types. Configuration.blockIO now holds the wrapper and is converted via toOCI() at spec assembly.
1 parent 5268c48 commit 3d009df

3 files changed

Lines changed: 128 additions & 2 deletions

File tree

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
//===----------------------------------------------------------------------===//
2+
// Copyright © 2025-2026 Apple Inc. and the Containerization project authors.
3+
//
4+
// Licensed under the Apache License, Version 2.0 (the "License");
5+
// you may not use this file except in compliance with the License.
6+
// You may obtain a copy of the License at
7+
//
8+
// https://www.apache.org/licenses/LICENSE-2.0
9+
//
10+
// Unless required by applicable law or agreed to in writing, software
11+
// distributed under the License is distributed on an "AS IS" BASIS,
12+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
// See the License for the specific language governing permissions and
14+
// limitations under the License.
15+
//===----------------------------------------------------------------------===//
16+
17+
import ContainerizationOCI
18+
19+
/// Block I/O resource limits applied to the container cgroup.
20+
public struct LinuxBlockIO: Sendable {
21+
/// The relative weight of the cgroup for block I/O. Valid range is 10 to 1000.
22+
public var weight: UInt16?
23+
/// The relative weight applied to tasks of the cgroup but not their descendant cgroups.
24+
public var leafWeight: UInt16?
25+
/// Per-device weight overrides.
26+
public var weightDevice: [LinuxWeightDevice]
27+
/// Per-device read rate limits in bytes per second.
28+
public var throttleReadBpsDevice: [LinuxThrottleDevice]
29+
/// Per-device write rate limits in bytes per second.
30+
public var throttleWriteBpsDevice: [LinuxThrottleDevice]
31+
/// Per-device read rate limits in IO operations per second.
32+
public var throttleReadIOPSDevice: [LinuxThrottleDevice]
33+
/// Per-device write rate limits in IO operations per second.
34+
public var throttleWriteIOPSDevice: [LinuxThrottleDevice]
35+
36+
public init(
37+
weight: UInt16? = nil,
38+
leafWeight: UInt16? = nil,
39+
weightDevice: [LinuxWeightDevice] = [],
40+
throttleReadBpsDevice: [LinuxThrottleDevice] = [],
41+
throttleWriteBpsDevice: [LinuxThrottleDevice] = [],
42+
throttleReadIOPSDevice: [LinuxThrottleDevice] = [],
43+
throttleWriteIOPSDevice: [LinuxThrottleDevice] = []
44+
) {
45+
self.weight = weight
46+
self.leafWeight = leafWeight
47+
self.weightDevice = weightDevice
48+
self.throttleReadBpsDevice = throttleReadBpsDevice
49+
self.throttleWriteBpsDevice = throttleWriteBpsDevice
50+
self.throttleReadIOPSDevice = throttleReadIOPSDevice
51+
self.throttleWriteIOPSDevice = throttleWriteIOPSDevice
52+
}
53+
54+
/// Convert to OCI format for transport.
55+
public func toOCI() -> ContainerizationOCI.LinuxBlockIO {
56+
ContainerizationOCI.LinuxBlockIO(
57+
weight: self.weight,
58+
leafWeight: self.leafWeight,
59+
weightDevice: self.weightDevice.map { $0.toOCI() },
60+
throttleReadBpsDevice: self.throttleReadBpsDevice.map { $0.toOCI() },
61+
throttleWriteBpsDevice: self.throttleWriteBpsDevice.map { $0.toOCI() },
62+
throttleReadIOPSDevice: self.throttleReadIOPSDevice.map { $0.toOCI() },
63+
throttleWriteIOPSDevice: self.throttleWriteIOPSDevice.map { $0.toOCI() }
64+
)
65+
}
66+
}
67+
68+
/// A per-device block I/O weight override.
69+
public struct LinuxWeightDevice: Sendable {
70+
/// The major device number.
71+
public var major: Int64
72+
/// The minor device number.
73+
public var minor: Int64
74+
/// The relative weight applied to the device. Valid range is 10 to 1000.
75+
public var weight: UInt16?
76+
/// The relative weight applied to tasks of the cgroup but not their descendant cgroups.
77+
public var leafWeight: UInt16?
78+
79+
public init(
80+
major: Int64,
81+
minor: Int64,
82+
weight: UInt16? = nil,
83+
leafWeight: UInt16? = nil
84+
) {
85+
self.major = major
86+
self.minor = minor
87+
self.weight = weight
88+
self.leafWeight = leafWeight
89+
}
90+
91+
/// Convert to OCI format for transport.
92+
public func toOCI() -> ContainerizationOCI.LinuxWeightDevice {
93+
ContainerizationOCI.LinuxWeightDevice(
94+
major: self.major,
95+
minor: self.minor,
96+
weight: self.weight,
97+
leafWeight: self.leafWeight
98+
)
99+
}
100+
}
101+
102+
/// A per-device block I/O throughput limit.
103+
public struct LinuxThrottleDevice: Sendable {
104+
/// The major device number.
105+
public var major: Int64
106+
/// The minor device number.
107+
public var minor: Int64
108+
/// The rate limit applied to the device.
109+
public var rate: UInt64
110+
111+
public init(major: Int64, minor: Int64, rate: UInt64) {
112+
self.major = major
113+
self.minor = minor
114+
self.rate = rate
115+
}
116+
117+
/// Convert to OCI format for transport.
118+
public func toOCI() -> ContainerizationOCI.LinuxThrottleDevice {
119+
ContainerizationOCI.LinuxThrottleDevice(
120+
major: self.major,
121+
minor: self.minor,
122+
rate: self.rate
123+
)
124+
}
125+
}

Sources/Containerization/LinuxContainer.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -414,7 +414,7 @@ public final class LinuxContainer: Container, Sendable {
414414
quota: Int64(config.cpus * 100_000),
415415
period: 100_000
416416
),
417-
blockIO: config.blockIO
417+
blockIO: config.blockIO?.toOCI()
418418
)
419419

420420
spec.linux?.namespaces = [

Tests/ContainerizationTests/LinuxContainerTests.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,13 @@
1414
// limitations under the License.
1515
//===----------------------------------------------------------------------===//
1616

17-
import ContainerizationOCI
1817
import Foundation
1918
import Testing
2019

2120
@testable import Containerization
2221

22+
import struct ContainerizationOCI.ImageConfig
23+
2324
struct LinuxContainerTests {
2425

2526
@Test func processInitFromImageConfigWithAllFields() {

0 commit comments

Comments
 (0)