@@ -21,6 +21,10 @@ type FakeState = {
2121 readonly containerCountByNetwork : Map < string , number >
2222}
2323
24+ type FakeExecutorOptions = {
25+ readonly failNetworkCreateWithoutSubnet : boolean
26+ }
27+
2428type SharedTemplate = {
2529 readonly serviceName : string
2630 readonly dockerNetworkMode : "shared"
@@ -38,7 +42,8 @@ const encode = (value: string): Uint8Array => new TextEncoder().encode(value)
3842const makeFakeExecutor = (
3943 recorded : Array < RecordedCommand > ,
4044 initialNetworks : ReadonlyArray < string > ,
41- containerCounts : ReadonlyArray < readonly [ string , number ] >
45+ containerCounts : ReadonlyArray < readonly [ string , number ] > ,
46+ options : FakeExecutorOptions = { failNetworkCreateWithoutSubnet : false }
4247) : CommandExecutor . CommandExecutor => {
4348 const state : FakeState = {
4449 existingNetworks : new Set ( initialNetworks ) ,
@@ -78,8 +83,13 @@ const makeFakeExecutor = (
7883 }
7984
8085 if ( isDockerNetworkCreate ) {
81- const networkName = args [ 4 ] ?? ""
82- if ( networkName . length > 0 ) {
86+ const subnetFlagIndex = args . indexOf ( "--subnet" )
87+ const hasSubnet = subnetFlagIndex >= 0
88+ const networkName = hasSubnet ? ( args [ subnetFlagIndex + 2 ] ?? "" ) : ( args [ 4 ] ?? "" )
89+
90+ if ( ! hasSubnet && options . failNetworkCreateWithoutSubnet ) {
91+ exitCode = 1
92+ } else if ( networkName . length > 0 ) {
8393 state . existingNetworks . add ( networkName )
8494 if ( ! state . containerCountByNetwork . has ( networkName ) ) {
8595 state . containerCountByNetwork . set ( networkName , 0 )
@@ -173,6 +183,45 @@ describe("docker network shared mode", () => {
173183 )
174184 expect ( created ) . toBe ( false )
175185 } ) )
186+
187+ it . effect ( "falls back to explicit subnet when default network create fails" , ( ) =>
188+ Effect . gen ( function * ( _ ) {
189+ const recorded : Array < RecordedCommand > = [ ]
190+ const executor = makeFakeExecutor (
191+ recorded ,
192+ [ ] ,
193+ [ ] ,
194+ { failNetworkCreateWithoutSubnet : true }
195+ )
196+ const template : SharedTemplate = {
197+ serviceName : "dg-test" ,
198+ dockerNetworkMode : "shared" ,
199+ dockerSharedNetworkName : "docker-git-shared"
200+ }
201+
202+ yield * _ (
203+ ensureComposeNetworkReady ( "/tmp" , template ) . pipe (
204+ Effect . provideService ( CommandExecutor . CommandExecutor , executor )
205+ )
206+ )
207+
208+ const defaultCreateTried = recorded . some (
209+ ( entry ) =>
210+ entry . command === "docker" &&
211+ entry . args [ 0 ] === "network" &&
212+ entry . args [ 1 ] === "create" &&
213+ ! entry . args . includes ( "--subnet" )
214+ )
215+ const subnetCreateTried = recorded . some (
216+ ( entry ) =>
217+ entry . command === "docker" &&
218+ entry . args [ 0 ] === "network" &&
219+ entry . args [ 1 ] === "create" &&
220+ entry . args . includes ( "--subnet" )
221+ )
222+ expect ( defaultCreateTried ) . toBe ( true )
223+ expect ( subnetCreateTried ) . toBe ( true )
224+ } ) )
176225} )
177226
178227describe ( "docker network gc" , ( ) => {
0 commit comments