-
Notifications
You must be signed in to change notification settings - Fork 668
Description
Summary
The Attachment and NetworkStatus structs in ContainerResource do not handle backward-compatible JSON decoding when communicating with older versions of container-apiserver. This causes keyNotFound decoding errors when a client built against v0.9.0 of this package talks to the v0.7.0 container-apiserver that ships with macOS 26.
NetworkConfiguration already handles this correctly with fallback decoding — Attachment and NetworkStatus should do the same.
Background
Between v0.7.0 and v0.9.0, several JSON field names were renamed:
| Struct | v0.7.0 field | v0.9.0 field |
|---|---|---|
Attachment |
address (String) |
ipv4Address (CIDRv4) |
Attachment |
gateway (String) |
ipv4Gateway (IPv4Address) |
NetworkStatus |
address (String) |
ipv4Subnet (CIDRv4) |
NetworkStatus |
gateway (String) |
ipv4Gateway (IPv4Address) |
NetworkConfiguration |
subnet (String?) |
ipv4Subnet (CIDRv4?) |
NetworkConfiguration already has a custom init(from decoder:) that tries ipv4Subnet first and falls back to subnet:
// NetworkConfiguration.swift (already correct)
let subnetText =
try container.decodeIfPresent(String.self, forKey: .ipv4Subnet)
?? container.decodeIfPresent(String.self, forKey: .subnet)Attachment and NetworkStatus use the default synthesized Codable conformance, which only accepts the new field names and fails with keyNotFound when it encounters the old ones.
Impact
Any downstream project (e.g., socktainer) that builds against apple/container v0.9.0 but runs on a stock macOS 26 system (which ships container-apiserver v0.7.0) will crash when decoding network data.
Error:
keyNotFound(CodingKeys(stringValue: "ipv4Address", intValue: nil),
Swift.DecodingError.Context(codingPath: [..., "networks", ...],
debugDescription: "No value associated with key \"ipv4Address\""))
Suggested Fix
Add custom init(from decoder:) to Attachment and NetworkStatus, matching the pattern already used in NetworkConfiguration.
For Attachment (Sources/ContainerResource/Network/Attachment.swift):
public init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
self.network = try container.decode(String.self, forKey: .network)
self.hostname = try container.decode(String.self, forKey: .hostname)
if let addr = try? container.decode(CIDRv4.self, forKey: .ipv4Address) {
self.ipv4Address = addr
} else {
self.ipv4Address = try container.decode(CIDRv4.self, forKey: .address)
}
if let gw = try? container.decode(IPv4Address.self, forKey: .ipv4Gateway) {
self.ipv4Gateway = gw
} else {
self.ipv4Gateway = try container.decode(IPv4Address.self, forKey: .gateway)
}
self.ipv6Address = try container.decodeIfPresent(CIDRv6.self, forKey: .ipv6Address)
self.macAddress = try container.decodeIfPresent(MACAddress.self, forKey: .macAddress)
}
private enum CodingKeys: String, CodingKey {
case network, hostname, ipv4Address, ipv4Gateway, ipv6Address, macAddress
case address, gateway // v0.7.0 field names
}Same pattern for NetworkStatus (Sources/ContainerResource/Network/NetworkState.swift).
Related
- Socktainer v0.9.0 fails on stock macOS 26 (container-apiserver v0.7.0) socktainer/socktainer#181 — downstream breakage caused by this inconsistency