mirror of https://github.com/docker/cli.git
Merge pull request #409 from alshabib/order
Support for rollback config in compose 3.7
This commit is contained in:
commit
5bc09ebf93
|
@ -162,6 +162,7 @@ func Service(
|
|||
EndpointSpec: endpoint,
|
||||
Mode: mode,
|
||||
UpdateConfig: convertUpdateConfig(service.Deploy.UpdateConfig),
|
||||
RollbackConfig: convertUpdateConfig(service.Deploy.RollbackConfig),
|
||||
}
|
||||
|
||||
// add an image label to serviceSpec
|
||||
|
|
|
@ -550,3 +550,17 @@ func (c *fakeClient) ConfigList(ctx context.Context, options types.ConfigListOpt
|
|||
}
|
||||
return []swarm.Config{}, nil
|
||||
}
|
||||
|
||||
func TestConvertUpdateConfigParallelism(t *testing.T) {
|
||||
parallel := uint64(4)
|
||||
|
||||
// test default behavior
|
||||
updateConfig := convertUpdateConfig(&composetypes.UpdateConfig{})
|
||||
assert.Check(t, is.Equal(uint64(1), updateConfig.Parallelism))
|
||||
|
||||
// Non default value
|
||||
updateConfig = convertUpdateConfig(&composetypes.UpdateConfig{
|
||||
Parallelism: ¶llel,
|
||||
})
|
||||
assert.Check(t, is.Equal(parallel, updateConfig.Parallelism))
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
version: "3.6"
|
||||
version: "3.7"
|
||||
|
||||
services:
|
||||
foo:
|
||||
|
@ -39,6 +39,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
|
||||
|
|
|
@ -10,7 +10,7 @@ import (
|
|||
|
||||
func fullExampleConfig(workingDir, homeDir string) *types.Config {
|
||||
return &types.Config{
|
||||
Version: "3.6",
|
||||
Version: "3.7",
|
||||
Services: services(workingDir, homeDir),
|
||||
Networks: networks(),
|
||||
Volumes: volumes(),
|
||||
|
@ -41,6 +41,14 @@ func services(workingDir, homeDir string) []types.ServiceConfig {
|
|||
Mode: "replicated",
|
||||
Replicas: uint64Ptr(6),
|
||||
Labels: map[string]string{"FOO": "BAR"},
|
||||
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",
|
||||
},
|
||||
UpdateConfig: &types.UpdateConfig{
|
||||
Parallelism: uint64Ptr(3),
|
||||
Delay: time.Duration(10 * time.Second),
|
||||
|
@ -393,7 +401,7 @@ func volumes() map[string]types.VolumeConfig {
|
|||
}
|
||||
|
||||
func fullExampleYAML(workingDir string) string {
|
||||
return fmt.Sprintf(`version: "3.6"
|
||||
return fmt.Sprintf(`version: "3.7"
|
||||
services:
|
||||
foo:
|
||||
build:
|
||||
|
@ -436,6 +444,13 @@ services:
|
|||
monitor: 1m0s
|
||||
max_failure_ratio: 0.3
|
||||
order: start-first
|
||||
rollback_config:
|
||||
parallelism: 3
|
||||
delay: 10s
|
||||
failure_action: continue
|
||||
monitor: 1m0s
|
||||
max_failure_ratio: 0.3
|
||||
order: start-first
|
||||
resources:
|
||||
limits:
|
||||
cpus: "0.001"
|
||||
|
|
|
@ -19,7 +19,7 @@ func TestMarshallConfig(t *testing.T) {
|
|||
assert.Check(t, is.Equal(expected, string(actual)))
|
||||
|
||||
// Make sure the expected still
|
||||
dict, err := ParseYAML([]byte("version: '3.6'\n" + expected))
|
||||
dict, err := ParseYAML([]byte("version: '3.7'\n" + expected))
|
||||
assert.NilError(t, err)
|
||||
_, err = Load(buildConfigDetails(dict, map[string]string{}))
|
||||
assert.NilError(t, err)
|
||||
|
|
|
@ -465,6 +465,49 @@ DoTuq9lAU9Q4O1xV/59X/w8AAP//zRo7vm9CAAA=
|
|||
`,
|
||||
},
|
||||
|
||||
"/data/config_schema_v3.7.json": {
|
||||
local: "data/config_schema_v3.7.json",
|
||||
size: 17540,
|
||||
modtime: 1518458244,
|
||||
compressed: `
|
||||
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
|
||||
`,
|
||||
},
|
||||
|
||||
"/": {
|
||||
isDir: true,
|
||||
local: "",
|
||||
|
|
|
@ -0,0 +1,596 @@
|
|||
{
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"id": "config_schema_v3.7.json",
|
||||
"type": "object",
|
||||
"required": ["version"],
|
||||
|
||||
"properties": {
|
||||
"version": {
|
||||
"type": "string"
|
||||
},
|
||||
|
||||
"services": {
|
||||
"id": "#/properties/services",
|
||||
"type": "object",
|
||||
"patternProperties": {
|
||||
"^[a-zA-Z0-9._-]+$": {
|
||||
"$ref": "#/definitions/service"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
|
||||
"networks": {
|
||||
"id": "#/properties/networks",
|
||||
"type": "object",
|
||||
"patternProperties": {
|
||||
"^[a-zA-Z0-9._-]+$": {
|
||||
"$ref": "#/definitions/network"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
"volumes": {
|
||||
"id": "#/properties/volumes",
|
||||
"type": "object",
|
||||
"patternProperties": {
|
||||
"^[a-zA-Z0-9._-]+$": {
|
||||
"$ref": "#/definitions/volume"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
|
||||
"secrets": {
|
||||
"id": "#/properties/secrets",
|
||||
"type": "object",
|
||||
"patternProperties": {
|
||||
"^[a-zA-Z0-9._-]+$": {
|
||||
"$ref": "#/definitions/secret"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
|
||||
"configs": {
|
||||
"id": "#/properties/configs",
|
||||
"type": "object",
|
||||
"patternProperties": {
|
||||
"^[a-zA-Z0-9._-]+$": {
|
||||
"$ref": "#/definitions/config"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
},
|
||||
|
||||
"patternProperties": {"^x-": {}},
|
||||
"additionalProperties": false,
|
||||
|
||||
"definitions": {
|
||||
|
||||
"service": {
|
||||
"id": "#/definitions/service",
|
||||
"type": "object",
|
||||
|
||||
"properties": {
|
||||
"deploy": {"$ref": "#/definitions/deployment"},
|
||||
"build": {
|
||||
"oneOf": [
|
||||
{"type": "string"},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"context": {"type": "string"},
|
||||
"dockerfile": {"type": "string"},
|
||||
"args": {"$ref": "#/definitions/list_or_dict"},
|
||||
"labels": {"$ref": "#/definitions/list_or_dict"},
|
||||
"cache_from": {"$ref": "#/definitions/list_of_strings"},
|
||||
"network": {"type": "string"},
|
||||
"target": {"type": "string"},
|
||||
"shm_size": {"type": ["integer", "string"]}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
]
|
||||
},
|
||||
"cap_add": {"type": "array", "items": {"type": "string"}, "uniqueItems": true},
|
||||
"cap_drop": {"type": "array", "items": {"type": "string"}, "uniqueItems": true},
|
||||
"cgroup_parent": {"type": "string"},
|
||||
"command": {
|
||||
"oneOf": [
|
||||
{"type": "string"},
|
||||
{"type": "array", "items": {"type": "string"}}
|
||||
]
|
||||
},
|
||||
"configs": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"oneOf": [
|
||||
{"type": "string"},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"source": {"type": "string"},
|
||||
"target": {"type": "string"},
|
||||
"uid": {"type": "string"},
|
||||
"gid": {"type": "string"},
|
||||
"mode": {"type": "number"}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"container_name": {"type": "string"},
|
||||
"credential_spec": {"type": "object", "properties": {
|
||||
"file": {"type": "string"},
|
||||
"registry": {"type": "string"}
|
||||
}},
|
||||
"depends_on": {"$ref": "#/definitions/list_of_strings"},
|
||||
"devices": {"type": "array", "items": {"type": "string"}, "uniqueItems": true},
|
||||
"dns": {"$ref": "#/definitions/string_or_list"},
|
||||
"dns_search": {"$ref": "#/definitions/string_or_list"},
|
||||
"domainname": {"type": "string"},
|
||||
"entrypoint": {
|
||||
"oneOf": [
|
||||
{"type": "string"},
|
||||
{"type": "array", "items": {"type": "string"}}
|
||||
]
|
||||
},
|
||||
"env_file": {"$ref": "#/definitions/string_or_list"},
|
||||
"environment": {"$ref": "#/definitions/list_or_dict"},
|
||||
|
||||
"expose": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": ["string", "number"],
|
||||
"format": "expose"
|
||||
},
|
||||
"uniqueItems": true
|
||||
},
|
||||
|
||||
"external_links": {"type": "array", "items": {"type": "string"}, "uniqueItems": true},
|
||||
"extra_hosts": {"$ref": "#/definitions/list_or_dict"},
|
||||
"healthcheck": {"$ref": "#/definitions/healthcheck"},
|
||||
"hostname": {"type": "string"},
|
||||
"image": {"type": "string"},
|
||||
"ipc": {"type": "string"},
|
||||
"isolation": {"type": "string"},
|
||||
"labels": {"$ref": "#/definitions/list_or_dict"},
|
||||
"links": {"type": "array", "items": {"type": "string"}, "uniqueItems": true},
|
||||
|
||||
"logging": {
|
||||
"type": "object",
|
||||
|
||||
"properties": {
|
||||
"driver": {"type": "string"},
|
||||
"options": {
|
||||
"type": "object",
|
||||
"patternProperties": {
|
||||
"^.+$": {"type": ["string", "number", "null"]}
|
||||
}
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
|
||||
"mac_address": {"type": "string"},
|
||||
"network_mode": {"type": "string"},
|
||||
|
||||
"networks": {
|
||||
"oneOf": [
|
||||
{"$ref": "#/definitions/list_of_strings"},
|
||||
{
|
||||
"type": "object",
|
||||
"patternProperties": {
|
||||
"^[a-zA-Z0-9._-]+$": {
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"aliases": {"$ref": "#/definitions/list_of_strings"},
|
||||
"ipv4_address": {"type": "string"},
|
||||
"ipv6_address": {"type": "string"}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
{"type": "null"}
|
||||
]
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
]
|
||||
},
|
||||
"pid": {"type": ["string", "null"]},
|
||||
|
||||
"ports": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"oneOf": [
|
||||
{"type": "number", "format": "ports"},
|
||||
{"type": "string", "format": "ports"},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"mode": {"type": "string"},
|
||||
"target": {"type": "integer"},
|
||||
"published": {"type": "integer"},
|
||||
"protocol": {"type": "string"}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
]
|
||||
},
|
||||
"uniqueItems": true
|
||||
},
|
||||
|
||||
"privileged": {"type": "boolean"},
|
||||
"read_only": {"type": "boolean"},
|
||||
"restart": {"type": "string"},
|
||||
"security_opt": {"type": "array", "items": {"type": "string"}, "uniqueItems": true},
|
||||
"shm_size": {"type": ["number", "string"]},
|
||||
"secrets": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"oneOf": [
|
||||
{"type": "string"},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"source": {"type": "string"},
|
||||
"target": {"type": "string"},
|
||||
"uid": {"type": "string"},
|
||||
"gid": {"type": "string"},
|
||||
"mode": {"type": "number"}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"sysctls": {"$ref": "#/definitions/list_or_dict"},
|
||||
"stdin_open": {"type": "boolean"},
|
||||
"stop_grace_period": {"type": "string", "format": "duration"},
|
||||
"stop_signal": {"type": "string"},
|
||||
"tmpfs": {"$ref": "#/definitions/string_or_list"},
|
||||
"tty": {"type": "boolean"},
|
||||
"ulimits": {
|
||||
"type": "object",
|
||||
"patternProperties": {
|
||||
"^[a-z]+$": {
|
||||
"oneOf": [
|
||||
{"type": "integer"},
|
||||
{
|
||||
"type":"object",
|
||||
"properties": {
|
||||
"hard": {"type": "integer"},
|
||||
"soft": {"type": "integer"}
|
||||
},
|
||||
"required": ["soft", "hard"],
|
||||
"additionalProperties": false
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"user": {"type": "string"},
|
||||
"userns_mode": {"type": "string"},
|
||||
"volumes": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"oneOf": [
|
||||
{"type": "string"},
|
||||
{
|
||||
"type": "object",
|
||||
"required": ["type"],
|
||||
"properties": {
|
||||
"type": {"type": "string"},
|
||||
"source": {"type": "string"},
|
||||
"target": {"type": "string"},
|
||||
"read_only": {"type": "boolean"},
|
||||
"consistency": {"type": "string"},
|
||||
"bind": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"propagation": {"type": "string"}
|
||||
}
|
||||
},
|
||||
"volume": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"nocopy": {"type": "boolean"}
|
||||
}
|
||||
},
|
||||
"tmpfs": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"size": {
|
||||
"type": "integer",
|
||||
"minimum": 0
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
],
|
||||
"uniqueItems": true
|
||||
}
|
||||
},
|
||||
"working_dir": {"type": "string"}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
|
||||
"healthcheck": {
|
||||
"id": "#/definitions/healthcheck",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"disable": {"type": "boolean"},
|
||||
"interval": {"type": "string", "format": "duration"},
|
||||
"retries": {"type": "number"},
|
||||
"test": {
|
||||
"oneOf": [
|
||||
{"type": "string"},
|
||||
{"type": "array", "items": {"type": "string"}}
|
||||
]
|
||||
},
|
||||
"timeout": {"type": "string", "format": "duration"},
|
||||
"start_period": {"type": "string", "format": "duration"}
|
||||
}
|
||||
},
|
||||
"deployment": {
|
||||
"id": "#/definitions/deployment",
|
||||
"type": ["object", "null"],
|
||||
"properties": {
|
||||
"mode": {"type": "string"},
|
||||
"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": {
|
||||
"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
|
||||
},
|
||||
"resources": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"limits": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"cpus": {"type": "string"},
|
||||
"memory": {"type": "string"}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"reservations": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"cpus": {"type": "string"},
|
||||
"memory": {"type": "string"},
|
||||
"generic_resources": {"$ref": "#/definitions/generic_resources"}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"restart_policy": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"condition": {"type": "string"},
|
||||
"delay": {"type": "string", "format": "duration"},
|
||||
"max_attempts": {"type": "integer"},
|
||||
"window": {"type": "string", "format": "duration"}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"placement": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"constraints": {"type": "array", "items": {"type": "string"}},
|
||||
"preferences": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"spread": {"type": "string"}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
|
||||
"generic_resources": {
|
||||
"id": "#/definitions/generic_resources",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"discrete_resource_spec": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"kind": {"type": "string"},
|
||||
"value": {"type": "number"}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
},
|
||||
|
||||
"network": {
|
||||
"id": "#/definitions/network",
|
||||
"type": ["object", "null"],
|
||||
"properties": {
|
||||
"name": {"type": "string"},
|
||||
"driver": {"type": "string"},
|
||||
"driver_opts": {
|
||||
"type": "object",
|
||||
"patternProperties": {
|
||||
"^.+$": {"type": ["string", "number"]}
|
||||
}
|
||||
},
|
||||
"ipam": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"driver": {"type": "string"},
|
||||
"config": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"subnet": {"type": "string"}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"external": {
|
||||
"type": ["boolean", "object"],
|
||||
"properties": {
|
||||
"name": {"type": "string"}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"internal": {"type": "boolean"},
|
||||
"attachable": {"type": "boolean"},
|
||||
"labels": {"$ref": "#/definitions/list_or_dict"}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
|
||||
"volume": {
|
||||
"id": "#/definitions/volume",
|
||||
"type": ["object", "null"],
|
||||
"properties": {
|
||||
"name": {"type": "string"},
|
||||
"driver": {"type": "string"},
|
||||
"driver_opts": {
|
||||
"type": "object",
|
||||
"patternProperties": {
|
||||
"^.+$": {"type": ["string", "number"]}
|
||||
}
|
||||
},
|
||||
"external": {
|
||||
"type": ["boolean", "object"],
|
||||
"properties": {
|
||||
"name": {"type": "string"}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"labels": {"$ref": "#/definitions/list_or_dict"}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
|
||||
"secret": {
|
||||
"id": "#/definitions/secret",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": {"type": "string"},
|
||||
"file": {"type": "string"},
|
||||
"external": {
|
||||
"type": ["boolean", "object"],
|
||||
"properties": {
|
||||
"name": {"type": "string"}
|
||||
}
|
||||
},
|
||||
"labels": {"$ref": "#/definitions/list_or_dict"}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
|
||||
"config": {
|
||||
"id": "#/definitions/config",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": {"type": "string"},
|
||||
"file": {"type": "string"},
|
||||
"external": {
|
||||
"type": ["boolean", "object"],
|
||||
"properties": {
|
||||
"name": {"type": "string"}
|
||||
}
|
||||
},
|
||||
"labels": {"$ref": "#/definitions/list_or_dict"}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
|
||||
"string_or_list": {
|
||||
"oneOf": [
|
||||
{"type": "string"},
|
||||
{"$ref": "#/definitions/list_of_strings"}
|
||||
]
|
||||
},
|
||||
|
||||
"list_of_strings": {
|
||||
"type": "array",
|
||||
"items": {"type": "string"},
|
||||
"uniqueItems": true
|
||||
},
|
||||
|
||||
"list_or_dict": {
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "object",
|
||||
"patternProperties": {
|
||||
".+": {
|
||||
"type": ["string", "number", "null"]
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
{"type": "array", "items": {"type": "string"}, "uniqueItems": true}
|
||||
]
|
||||
},
|
||||
|
||||
"constraints": {
|
||||
"service": {
|
||||
"id": "#/definitions/constraints/service",
|
||||
"anyOf": [
|
||||
{"required": ["build"]},
|
||||
{"required": ["image"]}
|
||||
],
|
||||
"properties": {
|
||||
"build": {
|
||||
"required": ["context"]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -114,3 +114,92 @@ func TestValidateIsolation(t *testing.T) {
|
|||
}
|
||||
assert.NilError(t, Validate(config, "3.5"))
|
||||
}
|
||||
|
||||
func TestValidateRollbackConfig(t *testing.T) {
|
||||
config := dict{
|
||||
"version": "3.4",
|
||||
"services": dict{
|
||||
"foo": dict{
|
||||
"image": "busybox",
|
||||
"deploy": dict{
|
||||
"rollback_config": dict{
|
||||
"parallelism": 1,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
assert.NilError(t, Validate(config, "3.7"))
|
||||
}
|
||||
|
||||
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.NilError(t, Validate(config, "3.7"))
|
||||
}
|
||||
|
||||
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.NilError(t, Validate(config, "3.7"))
|
||||
}
|
||||
|
||||
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.NilError(t, Validate(config, "3.7"))
|
||||
}
|
||||
|
|
|
@ -194,6 +194,7 @@ type DeployConfig struct {
|
|||
Replicas *uint64 `yaml:",omitempty"`
|
||||
Labels Labels `yaml:",omitempty"`
|
||||
UpdateConfig *UpdateConfig `mapstructure:"update_config" yaml:"update_config,omitempty"`
|
||||
RollbackConfig *UpdateConfig `mapstructure:"rollback_config" yaml:"rollback_config,omitempty"`
|
||||
Resources Resources `yaml:",omitempty"`
|
||||
RestartPolicy *RestartPolicy `mapstructure:"restart_policy" yaml:"restart_policy,omitempty"`
|
||||
Placement Placement `yaml:",omitempty"`
|
||||
|
|
Loading…
Reference in New Issue