@@ -260,38 +260,44 @@ describe('state engine', () => {
260
260
} ) ;
261
261
} ) ;
262
262
263
- it ( 'updates an app with two services with a network change' , async ( ) => {
263
+ it ( 'updates an app with two services with a network change where the only change is a custom ipam config addition' , async ( ) => {
264
+ const services = {
265
+ '1' : {
266
+ image : 'alpine:latest' ,
267
+ imageId : 11 ,
268
+ serviceName : 'one' ,
269
+ restart : 'unless-stopped' ,
270
+ running : true ,
271
+ command : 'sleep infinity' ,
272
+ stop_signal : 'SIGKILL' ,
273
+ networks : [ 'default' ] ,
274
+ labels : { } ,
275
+ environment : { } ,
276
+ } ,
277
+ '2' : {
278
+ image : 'alpine:latest' ,
279
+ imageId : 12 ,
280
+ serviceName : 'two' ,
281
+ restart : 'unless-stopped' ,
282
+ running : true ,
283
+ command : 'sleep infinity' ,
284
+ stop_signal : 'SIGKILL' ,
285
+ networks : [ 'default' ] ,
286
+ labels : { } ,
287
+ environment : { } ,
288
+ } ,
289
+ } ;
264
290
await setTargetState ( {
265
291
config : { } ,
266
292
apps : {
267
293
'123' : {
268
294
name : 'test-app' ,
269
295
commit : 'deadbeef' ,
270
296
releaseId : 1 ,
271
- services : {
272
- '1' : {
273
- image : 'alpine:latest' ,
274
- imageId : 11 ,
275
- serviceName : 'one' ,
276
- restart : 'unless-stopped' ,
277
- running : true ,
278
- command : 'sleep infinity' ,
279
- stop_signal : 'SIGKILL' ,
280
- labels : { } ,
281
- environment : { } ,
282
- } ,
283
- '2' : {
284
- image : 'alpine:latest' ,
285
- imageId : 12 ,
286
- serviceName : 'two' ,
287
- restart : 'unless-stopped' ,
288
- running : true ,
289
- command : 'sleep infinity' ,
290
- labels : { } ,
291
- environment : { } ,
292
- } ,
297
+ services,
298
+ networks : {
299
+ default : { } ,
293
300
} ,
294
- networks : { } ,
295
301
volumes : { } ,
296
302
} ,
297
303
} ,
@@ -311,39 +317,109 @@ describe('state engine', () => {
311
317
] ) ;
312
318
const containerIds = containers . map ( ( { Id } ) => Id ) ;
313
319
320
+ // Network should not have custom ipam config
321
+ const defaultNet = await docker . getNetwork ( '123_default' ) . inspect ( ) ;
322
+ expect ( defaultNet )
323
+ . to . have . property ( 'IPAM' )
324
+ . to . not . deep . equal ( {
325
+ Config : [ { Gateway : '192.168.91.1' , Subnet : '192.168.91.0/24' } ] ,
326
+ Driver : 'default' ,
327
+ Options : { } ,
328
+ } ) ;
329
+
330
+ // Network should not have custom ipam label
331
+ expect ( defaultNet )
332
+ . to . have . property ( 'Labels' )
333
+ . to . not . have . property ( 'io.balena.private.ipam.config' ) ;
334
+
314
335
await setTargetState ( {
315
336
config : { } ,
316
337
apps : {
317
338
'123' : {
318
339
name : 'test-app' ,
319
340
commit : 'deadca1f' ,
320
341
releaseId : 2 ,
321
- services : {
322
- '1' : {
323
- image : 'alpine:latest' ,
324
- imageId : 21 ,
325
- serviceName : 'one' ,
326
- restart : 'unless-stopped' ,
327
- running : true ,
328
- command : 'sleep infinity' ,
329
- stop_signal : 'SIGKILL' ,
330
- networks : [ 'default' ] ,
331
- labels : { } ,
332
- environment : { } ,
333
- } ,
334
- '2' : {
335
- image : 'alpine:latest' ,
336
- imageId : 22 ,
337
- serviceName : 'two' ,
338
- restart : 'unless-stopped' ,
339
- running : true ,
340
- command : 'sh -c "echo two && sleep infinity"' ,
341
- stop_signal : 'SIGKILL' ,
342
- networks : [ 'default' ] ,
343
- labels : { } ,
344
- environment : { } ,
342
+ services,
343
+ networks : {
344
+ default : {
345
+ driver : 'bridge' ,
346
+ ipam : {
347
+ config : [
348
+ { gateway : '192.168.91.1' , subnet : '192.168.91.0/24' } ,
349
+ ] ,
350
+ driver : 'default' ,
351
+ } ,
345
352
} ,
346
353
} ,
354
+ volumes : { } ,
355
+ } ,
356
+ } ,
357
+ } ) ;
358
+
359
+ const updatedContainers = await docker . listContainers ( ) ;
360
+ expect (
361
+ updatedContainers . map ( ( { Names, State } ) => ( { Name : Names [ 0 ] , State } ) ) ,
362
+ ) . to . have . deep . members ( [
363
+ { Name : '/one_11_2_deadca1f' , State : 'running' } ,
364
+ { Name : '/two_12_2_deadca1f' , State : 'running' } ,
365
+ ] ) ;
366
+
367
+ // Container ids must have changed
368
+ expect ( updatedContainers . map ( ( { Id } ) => Id ) ) . to . not . have . members (
369
+ containerIds ,
370
+ ) ;
371
+
372
+ // Network should have custom ipam config
373
+ const customNet = await docker . getNetwork ( '123_default' ) . inspect ( ) ;
374
+ expect ( customNet )
375
+ . to . have . property ( 'IPAM' )
376
+ . to . deep . equal ( {
377
+ Config : [ { Gateway : '192.168.91.1' , Subnet : '192.168.91.0/24' } ] ,
378
+ Driver : 'default' ,
379
+ Options : { } ,
380
+ } ) ;
381
+
382
+ // Network should have custom ipam label
383
+ expect ( customNet )
384
+ . to . have . property ( 'Labels' )
385
+ . to . have . property ( 'io.balena.private.ipam.config' ) ;
386
+ } ) ;
387
+
388
+ it ( 'updates an app with two services with a network change where the only change is a custom ipam config removal' , async ( ) => {
389
+ const services = {
390
+ '1' : {
391
+ image : 'alpine:latest' ,
392
+ imageId : 11 ,
393
+ serviceName : 'one' ,
394
+ restart : 'unless-stopped' ,
395
+ running : true ,
396
+ command : 'sleep infinity' ,
397
+ stop_signal : 'SIGKILL' ,
398
+ networks : [ 'default' ] ,
399
+ labels : { } ,
400
+ environment : { } ,
401
+ } ,
402
+ '2' : {
403
+ image : 'alpine:latest' ,
404
+ imageId : 12 ,
405
+ serviceName : 'two' ,
406
+ restart : 'unless-stopped' ,
407
+ running : true ,
408
+ command : 'sleep infinity' ,
409
+ stop_signal : 'SIGKILL' ,
410
+ networks : [ 'default' ] ,
411
+ labels : { } ,
412
+ environment : { } ,
413
+ } ,
414
+ } ;
415
+ await setTargetState ( {
416
+ config : { } ,
417
+ apps : {
418
+ '123' : {
419
+ name : 'test-app' ,
420
+ commit : 'deadbeef' ,
421
+ releaseId : 1 ,
422
+ services,
347
423
networks : {
348
424
default : {
349
425
driver : 'bridge' ,
@@ -360,26 +436,78 @@ describe('state engine', () => {
360
436
} ,
361
437
} ) ;
362
438
439
+ const state = await getCurrentState ( ) ;
440
+ expect (
441
+ state . apps [ '123' ] . services . map ( ( s : any ) => s . serviceName ) ,
442
+ ) . to . deep . equal ( [ 'one' , 'two' ] ) ;
443
+
444
+ // Network should have custom ipam config
445
+ const customNet = await docker . getNetwork ( '123_default' ) . inspect ( ) ;
446
+ expect ( customNet )
447
+ . to . have . property ( 'IPAM' )
448
+ . to . deep . equal ( {
449
+ Config : [ { Gateway : '192.168.91.1' , Subnet : '192.168.91.0/24' } ] ,
450
+ Driver : 'default' ,
451
+ Options : { } ,
452
+ } ) ;
453
+
454
+ // Network should have custom ipam label
455
+ expect ( customNet )
456
+ . to . have . property ( 'Labels' )
457
+ . to . have . property ( 'io.balena.private.ipam.config' ) ;
458
+
459
+ const containers = await docker . listContainers ( ) ;
460
+ expect (
461
+ containers . map ( ( { Names, State } ) => ( { Name : Names [ 0 ] , State } ) ) ,
462
+ ) . to . have . deep . members ( [
463
+ { Name : '/one_11_1_deadbeef' , State : 'running' } ,
464
+ { Name : '/two_12_1_deadbeef' , State : 'running' } ,
465
+ ] ) ;
466
+ const containerIds = containers . map ( ( { Id } ) => Id ) ;
467
+
468
+ await setTargetState ( {
469
+ config : { } ,
470
+ apps : {
471
+ '123' : {
472
+ name : 'test-app' ,
473
+ commit : 'deadca1f' ,
474
+ releaseId : 2 ,
475
+ services,
476
+ networks : {
477
+ default : { } ,
478
+ } ,
479
+ volumes : { } ,
480
+ } ,
481
+ } ,
482
+ } ) ;
483
+
363
484
const updatedContainers = await docker . listContainers ( ) ;
364
485
expect (
365
486
updatedContainers . map ( ( { Names, State } ) => ( { Name : Names [ 0 ] , State } ) ) ,
366
487
) . to . have . deep . members ( [
367
- { Name : '/one_21_2_deadca1f ' , State : 'running' } ,
368
- { Name : '/two_22_2_deadca1f ' , State : 'running' } ,
488
+ { Name : '/one_11_2_deadca1f ' , State : 'running' } ,
489
+ { Name : '/two_12_2_deadca1f ' , State : 'running' } ,
369
490
] ) ;
370
491
371
492
// Container ids must have changed
372
493
expect ( updatedContainers . map ( ( { Id } ) => Id ) ) . to . not . have . members (
373
494
containerIds ,
374
495
) ;
375
496
376
- expect ( await docker . getNetwork ( '123_default' ) . inspect ( ) )
497
+ // Network should not have custom ipam config
498
+ const defaultNet = await docker . getNetwork ( '123_default' ) . inspect ( ) ;
499
+ expect ( defaultNet )
377
500
. to . have . property ( 'IPAM' )
378
- . to . deep . equal ( {
501
+ . to . not . deep . equal ( {
379
502
Config : [ { Gateway : '192.168.91.1' , Subnet : '192.168.91.0/24' } ] ,
380
503
Driver : 'default' ,
381
504
Options : { } ,
382
505
} ) ;
506
+
507
+ // Network should not have custom ipam label
508
+ expect ( defaultNet )
509
+ . to . have . property ( 'Labels' )
510
+ . to . not . have . property ( 'io.balena.private.ipam.config' ) ;
383
511
} ) ;
384
512
385
513
it ( 'updates an app with two services with a network removal' , async ( ) => {
0 commit comments