diff --git a/cli/compose/convert/service.go b/cli/compose/convert/service.go index a8e2ccb393e7..adbeadfa3628 100644 --- a/cli/compose/convert/service.go +++ b/cli/compose/convert/service.go @@ -157,9 +157,10 @@ func Service( Preferences: getPlacementPreference(service.Deploy.Placement.Preferences), }, }, - EndpointSpec: endpoint, - Mode: mode, - UpdateConfig: convertUpdateConfig(service.Deploy.UpdateConfig), + EndpointSpec: endpoint, + Mode: mode, + UpdateConfig: convertUpdateConfig(service.Deploy.UpdateConfig), + RollbackConfig: convertUpdateConfig(service.Deploy.RollbackConfig), } // add an image label to serviceSpec diff --git a/cli/compose/convert/service_test.go b/cli/compose/convert/service_test.go index 3a0bf0e75e43..2b90d1658a72 100644 --- a/cli/compose/convert/service_test.go +++ b/cli/compose/convert/service_test.go @@ -342,6 +342,7 @@ func TestConvertCredentialSpec(t *testing.T) { }) assert.Error(t, err) assert.Nil(t, swarmSpec) + } func TestConvertUpdateConfigOrder(t *testing.T) { @@ -361,3 +362,18 @@ func TestConvertUpdateConfigOrder(t *testing.T) { }) assert.Equal(t, updateConfig.Order, "stop-first") } + +func TestConvertUpdateConfigParallelism(t *testing.T) { + parallel := uint64(4) + + // test default behavior + updateConfig := convertUpdateConfig(&composetypes.UpdateConfig{}) + assert.Equal(t, uint64(1), updateConfig.Parallelism) + + // Non default value + updateConfig = convertUpdateConfig(&composetypes.UpdateConfig{ + Parallelism: ¶llel, + }) + assert.Equal(t, parallel, updateConfig.Parallelism) + +} diff --git a/cli/compose/loader/full-example.yml b/cli/compose/loader/full-example.yml index d193dccd31c9..dafdcd140150 100644 --- a/cli/compose/loader/full-example.yml +++ b/cli/compose/loader/full-example.yml @@ -25,6 +25,13 @@ services: mode: replicated replicas: 6 labels: [FOO=BAR] + rollback_config: + parallelism: 3 + delay: 10s + failure_action: continue + monitor: 60s + max_failure_ratio: 0.3 + order: start-first update_config: parallelism: 3 delay: 10s diff --git a/cli/compose/loader/loader_test.go b/cli/compose/loader/loader_test.go index 4ffc333f3185..bad9599214ca 100644 --- a/cli/compose/loader/loader_test.go +++ b/cli/compose/loader/loader_test.go @@ -689,6 +689,14 @@ func TestFullExample(t *testing.T) { MaxFailureRatio: 0.3, Order: "start-first", }, + RollbackConfig: &types.UpdateConfig{ + Parallelism: uint64Ptr(3), + Delay: time.Duration(10 * time.Second), + FailureAction: "continue", + Monitor: time.Duration(60 * time.Second), + MaxFailureRatio: 0.3, + Order: "start-first", + }, Resources: types.Resources{ Limits: &types.Resource{ NanoCPUs: "0.001", diff --git a/cli/compose/schema/bindata.go b/cli/compose/schema/bindata.go index 4f34a8b6e97d..8e8bf60997c7 100644 --- a/cli/compose/schema/bindata.go +++ b/cli/compose/schema/bindata.go @@ -152,7 +152,7 @@ func dataConfig_schema_v33Json() (*asset, error) { return a, nil } -var _dataConfig_schema_v34Json = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x5b\x4f\x73\xe3\x28\x16\xbf\xfb\x53\xa8\x98\xb9\x8d\x93\x4c\xd5\x76\x6d\xd5\xf6\x6d\x8f\x7b\xda\x3d\x6f\xca\xa3\xc2\xe8\xd9\x66\x82\x80\x06\xe4\xc4\xdd\x95\xef\xbe\xa5\xbf\x06\x09\x04\xb6\x95\x4e\x7a\xa7\x4f\x89\xa5\xdf\x03\xde\xff\xf7\x00\x7d\x5b\x65\x19\xfa\x55\x93\x03\x94\x18\x7d\xce\xd0\xc1\x18\xf9\xf9\xe1\xe1\x4f\x2d\xf8\x5d\xfb\xf4\x5e\xa8\xfd\x43\xa1\xf0\xce\xdc\xfd\xfe\xe9\xa1\x7d\xf6\x0b\x5a\xd7\x74\xb4\xa8\x49\x88\xe0\x3b\xba\xcf\xdb\x37\xf9\xf1\x6f\xf7\x9f\xee\x6b\xf2\x16\x62\x4e\x12\x6a\x90\xd8\xfe\x09\xc4\xb4\xcf\x14\x7c\xa9\xa8\x82\x9a\xf8\x11\x1d\x41\x69\x2a\x38\xda\xac\x57\xf5\x3b\xa9\x84\x04\x65\x28\x68\xf4\x39\xab\x17\x97\x65\x03\xa4\x7f\x60\x0d\xab\x8d\xa2\x7c\x8f\x9a\xc7\xaf\xcd\x08\x59\x86\x34\xa8\x23\x25\xd6\x08\xc3\x52\x7f\x79\x38\x8f\xff\x30\xc0\xd6\xe3\x51\xad\xc5\x36\xcf\x25\x36\x06\x14\xff\xcf\x74\x6d\xcd\xeb\x3f\x1e\xf1\xdd\xd7\x7f\xde\xfd\xf7\xf7\xbb\x7f\xdc\xe7\x77\x9b\xdf\x7e\x75\x5e\xd7\xf2\x55\xb0\x6b\xa7\x2f\x60\x47\x39\x35\x54\xf0\x61\x7e\x34\x20\x5f\xbb\xff\x5e\x87\x89\x71\x51\x34\x60\xcc\x9c\xb9\x77\x98\x69\x70\x79\xe6\x60\x9e\x85\x7a\x8a\xf1\x3c\xc0\xde\x89\xe7\x6e\x7e\x0f\xcf\x2e\x3b\x47\xc1\xaa\x32\xaa\xc1\x1e\xf5\x4e\xcc\xb4\xd3\x2f\xa3\x3f\x0d\x44\x81\x89\x9b\x6c\x8b\x7a\x37\x8b\xad\xa7\x5f\x86\xe1\x36\x6a\xc4\x18\xee\x51\xef\xc4\x70\x3b\xfd\x6d\x0c\xaf\x7a\xa6\x67\xb1\x2d\xc2\x9a\xbb\x59\xa0\x13\xcf\x7c\xa2\xf2\xc5\x93\xb0\xac\x06\x61\x05\xa4\x54\x80\x64\xe2\x54\x3f\x0b\xc8\xa3\x05\x94\xc0\x0d\x1a\x44\x90\x65\x68\x5b\x51\x56\x8c\x25\x2a\x38\xfc\xbb\x1e\xe2\xd1\x7a\x98\x65\xdf\xc6\xa1\xdb\x1a\xa7\x79\xef\xfc\x0a\x2b\x7c\x78\x1f\xe0\x65\x78\x4f\x04\x37\xf0\x62\x1a\xa6\xe6\xa7\x6e\x45\x20\xc8\x13\xa8\x1d\x65\x90\x4a\x81\x55\x6b\xc5\x01\x91\x31\xaa\x4d\x2e\x54\x5e\x50\x62\xbc\xf4\x0c\x6f\x81\xdd\x34\x02\xc1\xe4\x00\xf9\x4e\x89\x32\x3a\xca\x2e\x6f\x39\xd1\xe8\x75\x34\xce\x64\xe0\xb8\x69\x0f\xa4\xd6\xaf\xcd\xca\x33\x20\x22\x58\xe6\xb8\x28\x1c\x91\x62\xa5\xf0\x09\xad\x33\x44\x0d\x94\xda\x2f\xed\x0c\x55\x9c\x7e\xa9\xe0\x5f\x1d\xc4\xa8\x0a\xc6\xe3\x16\x4a\xc8\xe5\x07\xde\x2b\x51\xc9\x5c\x62\x55\xdb\xfa\xbc\x25\x20\x22\xca\x12\xf3\xa5\x1c\xe0\x12\x3e\x12\x24\x3f\x09\xb3\x99\xed\x55\xdd\x1c\xf6\xab\x61\x36\x67\x59\x01\x6e\xe2\xfc\x4c\x5d\x3a\xee\xd4\x71\xb7\xae\xa3\xa2\xa8\x14\x49\xf5\xd2\x7a\x4e\xac\xf6\x90\x1a\x07\xb2\x0c\x55\xb4\x48\x07\xef\x2f\x01\x97\xa2\x70\xd7\xcd\xab\x72\x0b\x6a\xe2\x92\xae\x67\x4d\x7f\x6f\x56\xbe\x37\x23\xed\x1b\x4c\x39\xa8\x9c\xe3\x32\x26\x2b\x44\x14\x14\xc0\x0d\xc5\x2c\xd7\x12\x88\x03\xef\x35\x35\xa3\x19\x94\x14\x35\x91\x82\x3d\xd5\x46\x9d\xbc\xc8\x33\x17\xf6\xc2\x0a\x90\xc0\x0b\x9d\xb7\x3d\x40\x6a\x80\x73\x06\x18\x1a\x82\x45\xc3\x44\xc1\xe7\x02\x77\x3b\x4c\x1d\xba\xeb\xb5\xa1\x11\x61\xae\x01\x2b\x72\xb8\x92\x5e\x94\x98\xf2\x14\xa5\x02\x37\xea\x24\x05\x6d\xc3\xd8\x87\x8b\x4f\xc0\x8f\xf9\x60\x37\x17\x8b\x01\xf8\x91\x2a\xc1\xcb\x3e\x48\xa7\x25\x50\x8b\xfe\x45\x0a\x0d\xb7\x07\xc7\x8e\xe2\xb1\x67\x7c\x3d\xf8\xf4\xc6\x95\x1e\xda\x09\x55\xe2\x7a\xb1\xfd\xdc\xb6\x0f\x3b\x53\x4d\x2d\xcf\x16\xa0\xcd\x43\x5d\xf8\x62\x96\x33\xca\x9f\x96\x37\x71\x78\x31\x0a\xe7\x07\xa1\xcd\x35\x35\x0a\x3a\x00\x66\xe6\x40\x0e\x40\x9e\x66\xc8\x6d\x94\x43\x2d\xb4\x49\x31\x72\x5a\xe2\x7d\x1c\x24\x49\x0c\x72\x75\x2d\x86\x16\x15\xbe\x35\xac\xd8\xef\x6b\x68\xc8\xe2\x26\xb5\x7d\xf7\x3a\x56\x15\x17\x8a\x1e\x41\xa5\x96\xb8\x42\x9e\x5b\x92\xf1\xcb\x94\x6c\x1e\xed\xcf\x1c\xe8\x1f\xf7\x6d\x7b\x36\xe3\x55\xcd\x7f\x8c\xa1\xcd\x34\x65\x4e\x93\xe6\xf8\xc9\x88\xc3\xb4\x3a\xd7\xd1\x4a\x89\x49\x5d\xce\x2a\xd0\x01\xbd\x9e\xa1\xdd\x86\x47\x3e\xc9\xf9\x67\xec\x04\x3c\x49\xac\xa1\x48\x7d\x71\x22\xcc\xae\xea\xb0\x92\x54\x17\x6d\xb1\x23\xdc\x84\x96\x97\xba\xcc\xf3\x72\xe3\x26\xd6\xe0\x30\xa3\x58\x43\xdc\xd9\x83\x82\x74\x46\xa3\xf2\xf8\x29\xd1\x26\x7c\xb4\x7f\x9f\xa5\x0d\x90\x06\xc7\x4c\x6f\xdd\x22\x43\xd9\x25\x2a\x63\xde\x85\x6c\xe2\x45\xeb\x5b\x76\x96\xd2\x2d\xbc\xdd\x58\xd1\x44\x08\xdb\xc1\xa4\x50\xe6\xbb\xf4\x42\xe7\x38\x75\x4e\xf8\xed\xe4\xd3\xf6\x68\xac\xee\x24\xa2\xb7\xe9\xa9\x66\xa2\x94\x07\xed\xe9\xa8\x28\x37\xb0\xaf\x5b\x19\x7f\x12\xa8\xb6\x8c\xea\x03\x14\x97\xd0\x28\x61\x04\x11\x2c\xcd\x31\xbc\x1b\x34\xe9\xce\x30\xd3\x5f\x5d\x55\x9b\x49\x45\x8f\x94\xc1\x7e\xc4\xf1\x56\x08\x06\x98\x3b\x89\x42\x01\x2e\x72\xc1\xd9\x29\x01\xa9\x0d\x56\xd1\x5d\x09\x0d\xa4\x52\xd4\x9c\x72\x21\xcd\xe2\x55\xa1\x3e\x94\xb9\xa6\x5f\xc1\xf5\xbd\xb3\xd5\x77\x03\x6d\x46\x0b\x1a\x6d\x71\x67\x3f\xb7\x22\xfe\x32\x5b\x11\xfa\xa4\x89\xb9\xae\xb6\xd6\xa6\xa0\x3c\x17\x12\x78\xd4\x37\xb4\x11\x32\xdf\x2b\x4c\x20\x97\xa0\xa8\xf0\x8a\xc2\x09\xb0\x45\xa5\x70\x3d\xff\x74\x18\x4d\xf7\x1c\xfb\xe3\x8e\x05\x35\xa5\xdc\x5d\xb9\x09\x60\x4c\xdc\xd9\x2b\x46\x4b\x1a\x76\x1a\x8f\xd5\x26\xd4\x6b\x6d\xad\xe6\x2f\xd1\x66\xca\xb3\xa4\x90\x3d\xd3\x21\xcc\x37\x08\x09\x9d\xc1\x01\xab\x0b\x52\x47\xe3\x98\xbb\x40\x7e\xf2\xf5\x0d\xde\x75\x39\x87\xd5\xcd\x78\xeb\x6e\x21\x1b\x2f\xfe\xa2\xd2\x6b\xbc\x8c\x4d\xb0\xfa\xf1\x3b\x55\xa5\xa3\x4d\x5c\x83\xe1\x7a\xae\x01\x19\xa0\xd3\x53\xd7\xec\x87\x88\xd0\x8e\x8e\x1a\xb8\x47\x37\x09\x71\xbc\x9b\x29\x31\x76\xbe\x75\xd4\x4f\xae\x08\x2c\x1a\x22\xb8\xa6\xda\x00\x27\xfe\xfd\x55\x2f\xd1\x96\x4e\x0e\x2f\xa6\x42\x99\xef\xbb\xd2\xba\xae\x06\x85\xf7\x6d\xbc\x4d\x6e\x74\xd2\x7d\xb5\x3b\x90\xff\x2e\xac\x70\x41\x84\x0c\xa8\x26\x9d\x8d\x4b\xd3\xec\x68\xeb\x62\xa6\x0e\x0d\x85\x8c\x67\xa1\x9e\xea\x84\x54\x50\x7f\xe4\x58\x8d\x48\x2e\x38\xd2\x1f\xed\xf5\xf5\x03\xf8\xce\xaa\x6d\x68\xf4\x6c\x7f\xfe\xdc\xbc\x03\x05\xcf\xb4\xa9\xc6\xdb\xd1\xb9\x84\x2f\xd1\xd6\x99\x41\x1d\xe3\xf9\x5e\x81\x51\x74\x74\x94\xd0\x17\x4d\x76\x6e\x07\xfd\x31\x37\xdc\x0d\x2d\x41\x54\xfe\x30\xb4\xb2\x0d\xa7\x23\x42\xd6\x99\x7f\x44\xa9\x16\x72\xac\xd3\x47\xeb\x00\xa9\xed\xcb\xa3\x8a\x4b\x49\x58\xc0\x8b\xe6\x68\x23\x29\xbb\x29\x90\x8c\x12\xac\x63\x15\xc4\x0d\xbb\xc0\x95\x2c\xb0\x81\xbc\xbb\x36\x72\x49\xcd\x36\x53\xac\x49\xac\x30\x63\xc0\xa8\x2e\x53\x8a\x1f\x54\x00\xc3\xde\xe8\x1f\xad\x7b\x1b\xf2\x1d\xa6\xac\x52\x90\x63\x12\x0c\xd3\x23\x8a\x52\x70\x6a\x84\x37\x9c\xa4\x4d\x59\xe2\x97\xbc\x9f\xb6\x81\x44\xbc\xab\x21\x12\xaa\xf0\x17\x3f\xeb\xda\x2e\xaa\xd2\x53\x7e\xa0\xa6\x71\xbe\xdb\x51\xa5\x4d\xdb\xa5\x0a\xd9\xfd\x72\xc3\xec\x6b\xb0\xf3\x4f\xdd\x2c\xb6\xac\xae\xad\x13\x2e\x2b\xe1\x67\xcc\xe1\xdc\x10\x04\xac\xb3\x9f\x71\x22\x31\x05\xba\x0e\x71\xc3\x5e\x7e\x94\x3e\x9a\x4c\xba\xad\x88\x5c\x0a\x46\xdb\x8a\x63\x09\x0e\x89\xe0\xad\x90\x53\x8c\xef\x46\x6b\xaf\x4d\xaf\xee\x97\x4a\x69\xa2\x81\xa1\x21\x78\xa6\xbc\x10\xcf\x17\x4c\xb8\x9c\x29\x49\x86\x09\x8c\x02\xf1\xad\x82\xd6\x46\x61\xca\xcd\xc5\x47\x57\x63\xb1\x48\x05\x3b\x50\xc0\xa7\x86\x9e\xcd\xb7\x10\x59\xb8\x8d\x88\xf1\x16\xe7\xb0\x43\x68\x59\xd7\xd2\xef\xb0\x83\x78\xab\xf2\x6f\x28\xc6\x06\x2f\x8e\x24\xed\x01\x17\x2d\xc3\x42\x89\x9a\xc8\x2a\x7a\x0c\x56\x42\x29\xe6\xaf\x7c\xdc\x70\xe9\x39\xc6\x62\x0f\x5b\xa0\x28\x49\x3a\x37\xed\x50\xb9\x90\xcb\x6f\xdc\xc4\xcf\x46\x37\xf1\xb0\x4d\x25\x2e\x97\x8a\x21\xc9\x27\xc9\xc8\x5b\x15\x65\x1f\x20\x3a\x54\x5b\x1e\xe8\xcb\x3f\x76\x74\x70\x6f\x69\x34\x97\x40\x02\x5a\x7d\x1c\x5a\x9e\xf5\x20\xab\x4d\xb2\x8a\x83\x37\x30\x96\x5b\x7f\xd3\x7d\x8d\x77\x5b\x7d\x6d\x1a\x36\x06\x93\x43\x52\x47\x77\x61\x19\x7f\x43\x1c\x9a\xec\x3b\x78\xc3\x50\x87\x5a\x20\x0a\xa5\x5c\x89\xf9\xff\x88\x54\x3f\xba\x5d\x7f\x3f\x1b\xec\xbe\xcd\x88\x7e\x23\xd0\xa0\xae\xce\xf5\x09\x57\x3c\x3f\x80\xce\xde\x59\x15\x93\x44\xe7\x55\x45\x87\xfa\xa9\x8a\x37\xf5\x0a\xf7\xf4\xcd\x52\xc9\x74\x33\x6e\x4e\x92\x97\x7e\x55\xb1\x71\x97\x31\x86\x79\xbe\x64\x74\x6b\x9f\xb9\xb3\xf9\x1e\x12\xd8\xfc\x1d\x4d\xda\x09\x71\x9e\xf3\x05\xe3\xfe\xfd\x6f\x33\x15\xde\xdc\x55\xbe\x37\x2a\x8d\x16\xb8\xf7\xe0\xd7\xe9\xa8\x79\xee\xa5\x3b\xfd\x58\x2b\xec\xff\x3d\xfd\xe4\xd3\xad\x9a\x4f\x7e\x9a\x6c\x16\x7f\x73\x4f\xba\xda\xcf\xae\x36\x8e\x7c\x46\x90\xf6\x62\xac\x95\x68\x37\xf6\x7e\x42\xf0\x26\xbf\xef\x83\xae\xf1\x39\x5b\xff\x61\x55\xe0\xe8\x7f\x65\xff\x6d\x3e\x82\x5b\xbd\xae\xfe\x17\x00\x00\xff\xff\xf8\x93\x01\x77\x6e\x3c\x00\x00") +var _dataConfig_schema_v34Json = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x5b\x4f\x73\xeb\x28\x12\xbf\xfb\x53\xa8\x34\x73\x1b\x27\x99\xaa\x7d\xb5\x55\xfb\x6e\x7b\xdc\xd3\xee\x79\x53\x1e\x15\x46\x6d\x9b\x09\x02\xa6\x41\x4e\x3c\xaf\xf2\xdd\xb7\xf4\xd7\x42\x02\x81\x6d\xe5\x25\x6f\x27\xa7\xc4\xd2\xaf\x81\xfe\xdf\x0d\xe8\xdb\x2a\x49\xd2\x9f\x35\x3d\x40\x41\xd2\xaf\x49\x7a\x30\x46\x7d\x7d\x78\xf8\x5d\x4b\x71\xd7\x3c\xbd\x97\xb8\x7f\xc8\x91\xec\xcc\xdd\xaf\x5f\x1e\x9a\x67\x3f\xa5\xeb\x8a\x8e\xe5\x15\x09\x95\x62\xc7\xf6\x59\xf3\x26\x3b\xfe\xed\xfe\xcb\x7d\x45\xde\x40\xcc\x49\x41\x05\x92\xdb\xdf\x81\x9a\xe6\x19\xc2\x1f\x25\x43\xa8\x88\x1f\xd3\x23\xa0\x66\x52\xa4\x9b\xf5\xaa\x7a\xa7\x50\x2a\x40\xc3\x40\xa7\x5f\x93\x6a\x71\x49\xd2\x43\xba\x07\x83\x61\xb5\x41\x26\xf6\x69\xfd\xf8\xb5\x1e\x21\x49\x52\x0d\x78\x64\x74\x30\x42\xbf\xd4\x9f\x1e\xce\xe3\x3f\xf4\xb0\xf5\x78\xd4\xc1\x62\xeb\xe7\x8a\x18\x03\x28\xfe\x33\x5d\x5b\xfd\xfa\xb7\x47\x72\xf7\xe7\x3f\xef\xfe\xfb\xeb\xdd\x3f\xee\xb3\xbb\xcd\x2f\x3f\x5b\xaf\x2b\xf9\x22\xec\x9a\xe9\x73\xd8\x31\xc1\x0c\x93\xa2\x9f\x3f\xed\x91\xaf\xed\x7f\xaf\xfd\xc4\x24\xcf\x6b\x30\xe1\xd6\xdc\x3b\xc2\x35\xd8\x3c\x0b\x30\xcf\x12\x9f\x42\x3c\xf7\xb0\x77\xe2\xb9\x9d\xdf\xc1\xb3\xcd\xce\x51\xf2\xb2\x08\x6a\xb0\x43\xbd\x13\x33\xcd\xf4\xcb\xe8\x4f\x03\x45\x30\x61\x93\x6d\x50\xef\x66\xb1\xd5\xf4\xcb\x30\xdc\x44\x8d\x10\xc3\x1d\xea\x9d\x18\x6e\xa6\xbf\x8d\xe1\x55\xc7\xf4\x2c\xb6\x41\x0c\xe6\xae\x17\x68\xc5\x33\x97\xa8\x5c\xf1\xc4\x2f\xab\x5e\x58\x1e\x29\xe5\xa0\xb8\x3c\x55\xcf\x3c\xf2\x68\x00\x05\x08\x93\xf6\x22\x48\x92\x74\x5b\x32\x9e\x8f\x25\x2a\x05\xfc\xbb\x1a\xe2\x71\xf0\x30\x49\xbe\x8d\x43\xf7\x60\x9c\xfa\xbd\xf5\xcb\xaf\xf0\xfe\xbd\x87\x97\xfe\x3d\x95\xc2\xc0\x8b\xa9\x99\x9a\x9f\xba\x11\x81\xa4\x4f\x80\x3b\xc6\x21\x96\x82\x60\x63\xc5\x1e\x91\x71\xa6\x4d\x26\x31\xcb\x19\x35\x4e\x7a\x4e\xb6\xc0\x6f\x1a\x81\x12\x7a\x80\x6c\x87\xb2\x08\x8e\xb2\xcb\x1a\x4e\x74\xfa\x3a\x1a\x67\x32\x70\xd8\xb4\x7b\xd2\xc1\xaf\xcd\xca\x31\x60\x4a\x89\xca\x48\x9e\x5b\x22\x25\x88\xe4\x94\xae\x93\x94\x19\x28\xb4\x5b\xda\x49\x5a\x0a\xf6\x47\x09\xff\x6a\x21\x06\x4b\x18\x8f\x9b\xa3\x54\xcb\x0f\xbc\x47\x59\xaa\x4c\x11\xac\x6c\x7d\xde\x12\x52\x2a\x8b\x82\x88\xa5\x1c\xe0\x12\x3e\x22\x24\x3f\x09\xb3\xc9\xd0\xab\xda\x39\x86\xaf\xfa\xd9\xac\x65\x79\xb8\x09\xf3\x33\x75\xe9\xb0\x53\x87\xdd\xba\x8a\x8a\xb2\x44\x1a\xeb\xa5\xd5\x9c\x04\xf7\x10\x1b\x07\x92\x24\x2d\x59\x1e\x0f\xde\x5f\x02\x2e\x64\x6e\xaf\x5b\x94\xc5\x16\x70\xe2\x92\xb6\x67\x4d\x7f\x6f\x56\xae\x37\x23\xed\x1b\xc2\x04\x60\x26\x48\x11\x92\x55\x4a\x11\x72\x10\x86\x11\x9e\x69\x05\xd4\x82\x77\x9a\x9a\xd1\x4c\x1a\x15\x35\x53\x84\x3d\xd3\x06\x4f\x4e\xe4\x99\x8b\xe1\xc2\x72\x50\x20\x72\x9d\x35\x3d\x40\x6c\x80\xb3\x06\xe8\x1b\x82\x45\xc3\x44\x2e\xe6\x02\x77\x33\x4c\x15\xba\xab\xb5\xa5\x23\xc2\x4c\x03\x41\x7a\xb8\x92\x5e\x16\x84\x89\x18\xa5\x82\x30\x78\x52\x92\x35\x61\xec\xc3\xc5\x27\x10\xc7\xac\xb7\x9b\x8b\xc5\x00\xe2\xc8\x50\x8a\xa2\x0b\xd2\x71\x09\x74\x40\xff\xa2\xa4\x86\xdb\x83\x63\x4b\xf1\xd8\x31\xbe\xee\x7d\x7a\x63\x4b\x2f\xdd\x49\x2c\x48\xb5\xd8\x6e\xee\xa1\x0f\x5b\x53\x4d\x2d\x6f\x28\xc0\x21\x0f\x55\xe1\x4b\x78\xc6\x99\x78\x5a\xde\xc4\xe1\xc5\x20\xc9\x0e\x52\x9b\x6b\x6a\x94\xf4\x00\x84\x9b\x03\x3d\x00\x7d\x9a\x21\x1f\xa2\x2c\x6a\xa9\x4d\x8c\x91\xb3\x82\xec\xc3\x20\x45\x43\x90\xab\x6b\xb1\x74\x51\xe1\x0f\x86\x95\xfb\x7d\x05\xf5\x59\xdc\xa4\xb6\x6f\x5f\x87\xaa\xe2\x1c\xd9\x11\x30\xb6\xc4\x95\xea\xdc\x92\x8c\x5f\xc6\x64\xf3\x60\x7f\x66\x41\x7f\xbb\x6f\xda\xb3\x19\xaf\xaa\xff\xe3\x3c\xdd\x4c\x53\xe6\x34\x69\x8e\x9f\x8c\x38\x8c\xab\x73\x2d\xad\x14\x84\x56\xe5\x2c\x82\xf6\xe8\xf5\x0c\x6d\x37\x3c\xb2\x49\xce\x3f\x63\x27\xe0\x49\x62\xf5\x45\xea\x8b\x13\x61\x72\x55\x87\x15\xa5\xba\x60\x8b\x1d\xe0\xc6\xb7\xbc\xd8\x65\x9e\x97\x1b\x36\xb1\x1a\x47\x38\x23\x1a\xc2\xce\xee\x15\xa4\x35\x1a\x53\xc7\x2f\x91\x36\xe1\xa2\xfd\xfb\x2c\xad\x87\xd4\x3b\x66\x7c\xeb\x16\x18\x6a\x58\xa2\x72\xee\x5c\xc8\x26\x5c\xb4\xbe\x65\x67\xa9\xec\xc2\xdb\x8e\x15\x75\x84\x18\x3a\x98\x92\x68\xbe\x4b\x2f\x74\x8e\x53\xe7\x84\xdf\x4c\x3e\x6d\x8f\xc6\xea\x8e\x22\x7a\x9b\x9e\x6a\x26\x4a\x39\xd0\x8e\x8e\x8a\x09\x03\xfb\xaa\x95\x71\x27\x81\x72\xcb\x99\x3e\x40\x7e\x09\x0d\x4a\x23\xa9\xe4\x71\x8e\xe1\xdc\xa0\x89\x77\x86\x99\xfe\xea\xaa\xda\x4c\x21\x3b\x32\x0e\xfb\x11\xc7\x5b\x29\x39\x10\x61\x25\x0a\x04\x92\x67\x52\xf0\x53\x04\x52\x1b\x82\xc1\x5d\x09\x0d\xb4\x44\x66\x4e\x99\x54\x66\xf1\xaa\x50\x1f\x8a\x4c\xb3\x3f\xc1\xf6\xbd\xb3\xd5\xb7\x03\x6d\x46\x0b\x1a\x6d\x71\x27\x9f\x5b\x11\x7f\x99\xad\x08\x7d\xd2\xd4\x5c\x57\x5b\x6b\x93\x33\x91\x49\x05\x22\xe8\x1b\xda\x48\x95\xed\x91\x50\xc8\x14\x20\x93\x4e\x51\x58\x01\x36\x2f\x91\x54\xf3\x4f\x87\xd1\x6c\x2f\x88\x3b\xee\x0c\xa0\xa6\x50\xbb\x2b\x37\x01\x8c\x09\x3b\x7b\xc9\x59\xc1\xfc\x4e\xe3\xb0\xda\x88\x7a\xad\xa9\xd5\xdc\x25\xda\x4c\x79\x16\x15\xb2\x67\x3a\x84\xf9\x06\x21\xa2\x33\x38\x10\xbc\x20\x75\xd4\x8e\xb9\xf3\xe4\x27\x57\xdf\xe0\x5c\x97\x75\x58\x5d\x8f\xb7\x6e\x17\xb2\x71\xe2\x2f\x2a\xbd\xc6\xcb\xd8\x78\xab\x1f\xb7\x53\x95\x3a\xd8\xc4\xd5\x18\xa1\xe7\x1a\x90\x1e\x3a\x3d\x75\x4d\x7e\x88\x08\x6d\xe9\xa8\x86\x3b\x74\x13\x11\xc7\xdb\x99\x22\x63\xe7\x5b\x47\xfd\xe8\x8a\x60\x40\x43\xa5\xd0\x4c\x1b\x10\xd4\xbd\xbf\xea\x24\xda\xb2\xc9\xe1\xc5\x54\x28\xf3\x7d\x57\x5c\xd7\x55\xa3\xc8\xbe\x89\xb7\xd1\x8d\x4e\xbc\xaf\xb6\x07\xf2\xdf\x85\x15\x21\xa9\x54\x1e\xd5\xc4\xb3\x71\x69\x9a\x1d\x6d\x5d\xcc\xd4\xa1\xbe\x90\xf1\x2c\xf1\xa9\x4a\x48\x39\x73\x47\x8e\xd5\x88\xe4\x82\x23\xfd\xd1\x5e\x5f\x37\x80\xeb\xac\x7a\x08\x0d\x9e\xed\xcf\x9f\x9b\xb7\x20\xef\x99\x36\xd3\x64\x3b\x3a\x97\x70\x25\xda\x2a\x33\xe0\x31\x9c\xef\x11\x0c\xb2\xd1\x51\x42\x57\x34\x0d\x73\x3b\xe8\x8f\xb9\xe1\x6e\x58\x01\xb2\x74\x87\xa1\xd5\xd0\x70\x5a\xa2\x74\x70\xe6\x1f\x50\xea\x00\x39\xd6\xe9\xe3\xe0\x00\xa9\xe9\xcb\x83\x8a\x8b\x49\x58\x20\xf2\xfa\x68\x23\x2a\xbb\x21\x28\xce\x28\xd1\xa1\x0a\xe2\x86\x5d\x60\x94\x9c\x6f\x09\x7d\xca\xda\x8b\x23\x97\x54\x6d\x33\xe5\x9a\x22\x48\x38\x07\xce\x74\x11\x53\xfe\xa4\x39\x70\xe2\x8c\xff\xc1\xca\xb7\x26\xdf\x11\xc6\x4b\x84\x8c\x50\x6f\xa0\x1e\x51\x14\x52\x30\x23\x9d\x01\x25\x6e\xca\x82\xbc\x64\xdd\xb4\x35\x24\xe0\x5f\x35\x91\xc4\xdc\x5d\xfe\xac\x2b\xcb\x28\x0b\x47\x01\x92\xd6\xad\xf3\xdd\x8e\xa1\x36\x4d\x9f\x2a\x55\xfb\xcb\x0e\xb4\xaf\xde\xde\x3f\x76\xbb\xb8\x27\x28\x55\x4e\x0c\x7c\x9a\xc4\xa7\x49\xf4\x04\x08\x4d\xf1\x78\x59\x5f\x37\x63\x0e\xe7\x2e\xd1\x13\xb2\xba\x19\x27\x12\x43\xd0\x55\xde\xeb\x0f\x78\x82\xf4\xc1\x0a\xa3\xdd\x9f\xca\x94\xe4\xac\x29\x43\x97\xe0\x90\x4a\xd1\x08\x39\xc6\xf8\x6e\xb4\xf6\xca\xf4\xaa\x26\xba\x50\x26\x98\x2d\x6a\x82\x67\x26\x72\xf9\x7c\xc1\x84\xcb\x99\x92\xe2\x84\xc2\x28\x3b\xdf\x2a\x68\x6d\x90\x30\x61\x2e\x3e\xcf\x1c\x8b\x45\x21\xec\x00\x41\x4c\x0d\x3d\x99\xef\x2b\x13\x7f\x6f\x19\xe2\x2d\xcc\x61\x8b\xd0\xaa\x6a\xb0\xde\x61\x5b\xf9\x56\xe5\xdf\x50\xa1\xf7\x5e\x1c\xa8\xe4\x7a\x5c\xb0\x36\xf7\x55\x6f\x54\x95\xc1\xb3\xd1\x02\x0a\x39\x7f\x0f\xe8\x86\x9b\xf0\x21\x16\x3b\xd8\x02\x95\x6a\xd4\x61\x7a\x8b\xca\xa4\x5a\x7e\x37\x2f\x7c\x60\xbe\x09\x87\x6d\xa6\x48\xb1\x54\x0c\x89\xbe\x5e\x90\x3a\xab\xa2\xe4\x03\x44\x87\x72\x2b\x3c\x9b\x35\x1f\x3b\x3a\x0c\xbb\xa3\xf6\x66\x90\x47\xab\x8f\x7d\x1f\xbc\xee\x65\xb5\x89\x56\xb1\xf7\x5a\xce\x72\xeb\xaf\x5b\xf2\xf1\x16\xbc\xab\x77\x27\xc6\x10\x7a\x88\x6a\xf3\x2f\xec\xed\x6e\x88\x43\x93\xcd\x28\x67\x18\x6a\x51\x0b\x44\xa1\x98\x7b\x52\xff\x1f\x91\xea\x47\xb7\xeb\xef\x67\x83\xed\x07\x3b\xc1\x0f\x47\x6a\xd4\xd5\xb9\x3e\xe2\xde\xef\x07\xd0\xd9\x3b\xab\x62\x92\xe8\x9c\xaa\x68\x51\x9f\xaa\x78\x53\xaf\xb0\x8f\x64\x07\x2a\x99\xee\xd0\xce\x49\xf2\xd2\x4f\x6d\x36\xf6\x32\xc6\x30\xc7\xe7\xad\x76\xed\x33\x77\x61\xa3\x83\x78\x4e\x04\x46\x93\xb6\x42\x9c\xe7\x7c\xc1\xb8\x7f\xff\xcb\x4c\x85\x37\x77\xbf\xf3\x8d\x4a\xa3\x05\x2e\xc3\xb8\x75\x3a\x6a\x9e\x3b\xe9\x4e\xbf\xe0\xf3\xfb\x7f\x47\x3f\xf9\x9e\xaf\xe2\x53\x9c\x26\x27\x08\xdf\xec\xe3\xcf\xe6\x5b\xbc\x8d\x25\x9f\x11\xa4\xb9\x2d\x3d\x48\xb4\x9b\xe1\x7e\x82\xf7\xf3\x0e\xd7\x57\x7e\xe3\xc3\xd7\xee\x6b\x3b\xcf\x7d\x90\xd5\xf0\x6f\xfd\x65\xe4\xea\x75\xf5\xbf\x00\x00\x00\xff\xff\x1d\x00\x4e\x52\x83\x3e\x00\x00") func dataConfig_schema_v34JsonBytes() ([]byte, error) { return bindataRead( diff --git a/cli/compose/schema/data/config_schema_v3.4.json b/cli/compose/schema/data/config_schema_v3.4.json index ce9512076b50..8dcd0a2e7581 100644 --- a/cli/compose/schema/data/config_schema_v3.4.json +++ b/cli/compose/schema/data/config_schema_v3.4.json @@ -332,6 +332,20 @@ "endpoint_mode": {"type": "string"}, "replicas": {"type": "integer"}, "labels": {"$ref": "#/definitions/list_or_dict"}, + "rollback_config": { + "type": "object", + "properties": { + "parallelism": {"type": "integer"}, + "delay": {"type": "string", "format": "duration"}, + "failure_action": {"type": "string"}, + "monitor": {"type": "string", "format": "duration"}, + "max_failure_ratio": {"type": "number"}, + "order": {"type": "string", "enum": [ + "start-first", "stop-first" + ]} + }, + "additionalProperties": false + }, "update_config": { "type": "object", "properties": { diff --git a/cli/compose/schema/schema_test.go b/cli/compose/schema/schema_test.go index f293fe7f68f0..b69b2333d542 100644 --- a/cli/compose/schema/schema_test.go +++ b/cli/compose/schema/schema_test.go @@ -74,3 +74,92 @@ func TestValidatePlacement(t *testing.T) { assert.NoError(t, Validate(config, "3.3")) } + +func TestValidateRollbackConfig(t *testing.T) { + config := dict{ + "version": "3.4", + "services": dict{ + "foo": dict{ + "image": "busybox", + "deploy": dict{ + "rollback_config": dict{ + "parallelism": 1, + }, + }, + }, + }, + } + + assert.NoError(t, Validate(config, "3.4")) +} + +func TestValidateRollbackConfigWithOrder(t *testing.T) { + config := dict{ + "version": "3.4", + "services": dict{ + "foo": dict{ + "image": "busybox", + "deploy": dict{ + "rollback_config": dict{ + "parallelism": 1, + "order": "start-first", + }, + }, + }, + }, + } + + assert.NoError(t, Validate(config, "3.4")) +} + +func TestValidateRollbackConfigWithUpdateConfig(t *testing.T) { + config := dict{ + "version": "3.4", + "services": dict{ + "foo": dict{ + "image": "busybox", + "deploy": dict{ + "update_config": dict{ + "parallelism": 1, + "order": "start-first", + }, + "rollback_config": dict{ + "parallelism": 1, + "order": "start-first", + }, + }, + }, + }, + } + + assert.NoError(t, Validate(config, "3.4")) +} + +func TestValidateRollbackConfigWithUpdateConfigFull(t *testing.T) { + config := dict{ + "version": "3.4", + "services": dict{ + "foo": dict{ + "image": "busybox", + "deploy": dict{ + "update_config": dict{ + "parallelism": 1, + "order": "start-first", + "delay": "10s", + "failure_action": "pause", + "monitor": "10s", + }, + "rollback_config": dict{ + "parallelism": 1, + "order": "start-first", + "delay": "10s", + "failure_action": "pause", + "monitor": "10s", + }, + }, + }, + }, + } + + assert.NoError(t, Validate(config, "3.4")) +} diff --git a/cli/compose/types/types.go b/cli/compose/types/types.go index 8e93d9fb6640..52c6f8506998 100644 --- a/cli/compose/types/types.go +++ b/cli/compose/types/types.go @@ -157,14 +157,15 @@ type LoggingConfig struct { // DeployConfig the deployment configuration for a service type DeployConfig struct { - Mode string - Replicas *uint64 - Labels Labels - UpdateConfig *UpdateConfig `mapstructure:"update_config"` - Resources Resources - RestartPolicy *RestartPolicy `mapstructure:"restart_policy"` - Placement Placement - EndpointMode string `mapstructure:"endpoint_mode"` + Mode string + Replicas *uint64 + Labels Labels + UpdateConfig *UpdateConfig `mapstructure:"update_config"` + RollbackConfig *UpdateConfig `mapstructure:"rollback_config"` + Resources Resources + RestartPolicy *RestartPolicy `mapstructure:"restart_policy"` + Placement Placement + EndpointMode string `mapstructure:"endpoint_mode"` } // HealthCheckConfig the healthcheck configuration for a service