Commit 237a1b4
committed
feat(network): apply richer IPAM at network creation time
Extends `container network create` and the `container-network-vmnet`
plugin to honor six compose-spec / Docker-style network creation
options that were previously silently dropped: `--gateway`,
`--ip-range`, `--aux-address`, `--driver-opt`, `--ipv6`, and
`--attachable`. The vmnet plugin now actually wires the user's
gateway override and IPv4 sub-range constraints through to the
runtime; aux-address reservations are pre-allocated in the per-network
attachment allocator so the dynamic pool never hands them out.
Motivation
----------
Container-Compose (and other compose-spec orchestrators) decode these
fields from `docker-compose.yml` but cannot apply them today because
`container network create` only accepts `--label`, `--internal`,
`--subnet`, `--subnet-v6`, `--plugin`, and `--plugin-variant`. The
gap was tracked downstream in CHAOS-1334 and surfaced as warn-and-skip
behaviour in container-compose's `setupNetwork` path. With this PR
the runtime accepts the full IPAM surface and the plugin honours each
field at network start.
What this PR changes
--------------------
- Sources/ContainerResource/Network/NetworkConfiguration.swift: six
new optional fields on the persisted `NetworkConfiguration`
(`ipv4Gateway`, `ipv4Range`, `auxAddresses`, `driverOpts`,
`attachable`, `enableIPv6`). All decoded with `decodeIfPresent`,
encoded with `encodeIfPresent`, and validated end-to-end (gateway,
range, and aux-addresses must lie inside `ipv4Subnet` when both are
configured).
- Sources/ContainerCommands/Network/NetworkCreate.swift: matching CLI
flags (`--gateway`, `--ip-range`, `--aux-address HOSTNAME=IP`
repeatable, `--driver-opt KEY=VALUE` repeatable, `--ipv6`, and
`--attachable`). The CLI emits an explicit advisory on stderr when
`--attachable` is requested because apple/container has no swarm
attachment concept.
- Sources/Services/ContainerAPIService/Server/Networks/NetworksService.swift:
`registerService` now serializes the new configuration fields into
argv passed to the plugin's `start` subcommand. `auxAddresses` is
encoded as a single JSON argv value to keep the wire shape simple
and trivially extensible; `driverOpts` is forwarded as repeated
`--driver-opt KEY=VALUE` entries.
- Sources/Plugins/NetworkVmnet/NetworkVmnetHelper+Start.swift: parses
the new argv (`--gateway`, `--ip-range`, `--aux-addresses`,
`--driver-opt`, `--ipv6`) and reconstructs a richer
`NetworkConfiguration` for the vmnet variants.
- Sources/Services/ContainerNetworkService/Server/ReservedVmnetNetwork.swift
and AllocationOnlyVmnetNetwork.swift: the IPv4 gateway is no longer
hard-coded to `subnet.lower + 1`. When the configuration carries an
explicit `ipv4Gateway`, that address is passed directly to
`vmnet_network_configuration_set_ipv4_subnet` and validated as
in-subnet. The allocation-only variant explicitly rejects the IPv6
request paths with an actionable error pointing users at the
`reserved` variant on macOS 26+.
- Sources/Services/ContainerNetworkService/Server/NetworkService.swift:
the per-network attachment allocator now accepts an `ipv4Range`
override (so the dynamic pool spans the user-supplied sub-CIDR
rather than the full subnet) and pre-reserves both a custom gateway
and any in-range `auxAddresses` through `RotatingAddressAllocator`'s
existing `reserve(_:)` API. Out-of-range aux entries are recorded
for reference but require no allocator state because they are
already outside the dynamic pool.
- Sources/Services/ContainerNetworkService/Server/AttachmentAllocator.swift:
small `reserveHostname(hostname:address:)` helper that wraps the
underlying allocator's `reserve(_:)` with the actor's
hostname-to-index dictionary, so reserved entries round-trip
through `lookup` / `deallocate`.
Wire compatibility
------------------
All new `NetworkConfiguration` fields are optional and decoded with
`decodeIfPresent`; configurations persisted by older daemons decode
cleanly with `nil` defaults (covered by the
`testLegacyConfigurationDecodesWithoutNewFields` regression test).
Plugin argv is purely additive: a newer `NetworksService` against an
older plugin will pass argv that the plugin ignores; an older
`NetworksService` against a newer plugin simply omits the new flags
and the plugin behaves as before.
Known limitations (intentional, follow-up work)
-----------------------------------------------
- `--attachable` is accepted at the CLI for compose-spec parity but
is not threaded into the plugin and produces no behavioural change
on apple/container, which has no swarm-mode attachment concept. The
CLI surfaces this explicitly on stderr.
- `--driver-opt KEY=VALUE` is parsed, persisted on the configuration,
and forwarded through to the plugin process, but the vmnet plugin
does not currently interpret any specific keys. Keeping the surface
on day one means future plugin enhancements can interpret options
(e.g. DHCP toggles) without another wire-format break.
- Bare `--ipv6` (no `--subnet-v6`) takes effect on the `reserved`
variant only; the `allocation-only` variant does not yet support
IPv6 and now emits an actionable error pointing at the `reserved`
variant on macOS 26+.
- The IPv4 gateway override only takes effect when an explicit
`--subnet` is also supplied; without a subnet, vmnet is the source
of truth for both subnet and gateway.
Verification
------------
- `swift build -c release` clean on macOS 26 / Apple silicon.
- `swift test --filter ContainerResourceTests.NetworkConfigurationTest`
passes 11 tests (3 pre-existing + 8 new), covering: gateway/range/
aux-address validation (positive and negative), full-shape Codable
round-trip, and decoding a legacy (pre-PR) JSON configuration with
none of the new fields populated.1 parent 2ee3f3d commit 237a1b4
9 files changed
Lines changed: 502 additions & 5 deletions
File tree
- Sources
- ContainerCommands/Network
- ContainerResource/Network
- Plugins/NetworkVmnet
- Services
- ContainerAPIService/Server/Networks
- ContainerNetworkService/Server
- Tests/ContainerResourceTests
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
54 | 54 | | |
55 | 55 | | |
56 | 56 | | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
57 | 93 | | |
58 | 94 | | |
59 | 95 | | |
| |||
65 | 101 | | |
66 | 102 | | |
67 | 103 | | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
68 | 131 | | |
69 | 132 | | |
70 | 133 | | |
71 | 134 | | |
72 | 135 | | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
73 | 142 | | |
74 | 143 | | |
75 | 144 | | |
| |||
Lines changed: 104 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
54 | 54 | | |
55 | 55 | | |
56 | 56 | | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
57 | 91 | | |
58 | 92 | | |
59 | 93 | | |
60 | 94 | | |
61 | 95 | | |
62 | 96 | | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
63 | 103 | | |
64 | 104 | | |
65 | 105 | | |
| |||
68 | 108 | | |
69 | 109 | | |
70 | 110 | | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
71 | 117 | | |
72 | 118 | | |
73 | 119 | | |
| |||
79 | 125 | | |
80 | 126 | | |
81 | 127 | | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
82 | 134 | | |
83 | 135 | | |
84 | 136 | | |
| |||
99 | 151 | | |
100 | 152 | | |
101 | 153 | | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
| 165 | + | |
| 166 | + | |
| 167 | + | |
| 168 | + | |
| 169 | + | |
| 170 | + | |
102 | 171 | | |
103 | 172 | | |
104 | 173 | | |
| |||
114 | 183 | | |
115 | 184 | | |
116 | 185 | | |
| 186 | + | |
| 187 | + | |
| 188 | + | |
| 189 | + | |
| 190 | + | |
| 191 | + | |
| 192 | + | |
| 193 | + | |
| 194 | + | |
117 | 195 | | |
118 | 196 | | |
119 | 197 | | |
| |||
122 | 200 | | |
123 | 201 | | |
124 | 202 | | |
| 203 | + | |
| 204 | + | |
| 205 | + | |
| 206 | + | |
| 207 | + | |
| 208 | + | |
| 209 | + | |
| 210 | + | |
| 211 | + | |
| 212 | + | |
| 213 | + | |
| 214 | + | |
| 215 | + | |
| 216 | + | |
| 217 | + | |
| 218 | + | |
| 219 | + | |
| 220 | + | |
| 221 | + | |
| 222 | + | |
| 223 | + | |
| 224 | + | |
| 225 | + | |
| 226 | + | |
| 227 | + | |
| 228 | + | |
125 | 229 | | |
126 | 230 | | |
Lines changed: 54 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
66 | 66 | | |
67 | 67 | | |
68 | 68 | | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
69 | 84 | | |
70 | 85 | | |
71 | 86 | | |
| |||
81 | 96 | | |
82 | 97 | | |
83 | 98 | | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
84 | 118 | | |
85 | 119 | | |
86 | 120 | | |
| |||
91 | 125 | | |
92 | 126 | | |
93 | 127 | | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
94 | 134 | | |
95 | 135 | | |
96 | 136 | | |
| |||
139 | 179 | | |
140 | 180 | | |
141 | 181 | | |
| 182 | + | |
| 183 | + | |
| 184 | + | |
| 185 | + | |
| 186 | + | |
| 187 | + | |
| 188 | + | |
| 189 | + | |
| 190 | + | |
| 191 | + | |
| 192 | + | |
| 193 | + | |
| 194 | + | |
| 195 | + | |
142 | 196 | | |
143 | 197 | | |
Lines changed: 28 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
485 | 485 | | |
486 | 486 | | |
487 | 487 | | |
| 488 | + | |
| 489 | + | |
| 490 | + | |
| 491 | + | |
| 492 | + | |
| 493 | + | |
| 494 | + | |
| 495 | + | |
| 496 | + | |
| 497 | + | |
| 498 | + | |
| 499 | + | |
| 500 | + | |
| 501 | + | |
| 502 | + | |
| 503 | + | |
| 504 | + | |
| 505 | + | |
| 506 | + | |
| 507 | + | |
| 508 | + | |
| 509 | + | |
| 510 | + | |
| 511 | + | |
| 512 | + | |
| 513 | + | |
| 514 | + | |
| 515 | + | |
488 | 516 | | |
489 | 517 | | |
490 | 518 | | |
| |||
Lines changed: 7 additions & 1 deletion
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
69 | 69 | | |
70 | 70 | | |
71 | 71 | | |
72 | | - | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
73 | 79 | | |
74 | 80 | | |
75 | 81 | | |
| |||
Lines changed: 8 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
61 | 61 | | |
62 | 62 | | |
63 | 63 | | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
64 | 72 | | |
0 commit comments