Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
小 白蛋
Nomad
Commits
1096d434
Commit
1096d434
authored
3 years ago
by
kainoaseto
Browse files
Options
Download
Email Patches
Plain Diff
backport of commit
b8db8f36
parent
ba11f172
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
nomad/deploymentwatcher/deployment_watcher.go
+8
-1
nomad/deploymentwatcher/deployment_watcher.go
nomad/deploymentwatcher/deployments_watcher_test.go
+49
-17
nomad/deploymentwatcher/deployments_watcher_test.go
nomad/mock/mock.go
+82
-0
nomad/mock/mock.go
with
139 additions
and
18 deletions
+139
-18
nomad/deploymentwatcher/deployment_watcher.go
+
8
-
1
View file @
1096d434
...
...
@@ -283,9 +283,16 @@ func (w *deploymentWatcher) autoPromoteDeployment(allocs []*structs.AllocListStu
return
nil
}
// AutoPromote iff every task group is marked auto_promote and is healthy. The whole
// AutoPromote iff every task group
with canaries
is marked auto_promote and is healthy. The whole
// job version has been incremented, so we promote together. See also AutoRevert
for
_
,
dstate
:=
range
d
.
TaskGroups
{
// skip auto promote canary validation if the task group has no canaries
// to prevent auto promote hanging on mixed canary/non-canary taskgroup deploys
if
dstate
.
DesiredCanaries
<
1
{
continue
}
if
!
dstate
.
AutoPromote
||
dstate
.
DesiredCanaries
!=
len
(
dstate
.
PlacedCanaries
)
{
return
nil
}
...
...
This diff is collapsed.
Click to expand it.
nomad/deploymentwatcher/deployments_watcher_test.go
+
49
-
17
View file @
1096d434
...
...
@@ -535,15 +535,19 @@ func TestWatcher_AutoPromoteDeployment(t *testing.T) {
w
,
m
:=
defaultTestDeploymentWatcher
(
t
)
now
:=
time
.
Now
()
// Create 1 UpdateStrategy, 1 job (
1
TaskGroup), 2 canaries, and 1 deployment
u
pd
:=
structs
.
DefaultUpdateStrategy
.
Copy
()
u
pd
.
AutoPromote
=
true
u
pd
.
MaxParallel
=
2
u
pd
.
Canary
=
2
u
pd
.
ProgressDeadline
=
5
*
time
.
Second
// Create 1 UpdateStrategy, 1 job (
2
TaskGroup
s
), 2 canaries, and 1 deployment
canaryU
pd
:=
structs
.
DefaultUpdateStrategy
.
Copy
()
canaryU
pd
.
AutoPromote
=
true
canaryU
pd
.
MaxParallel
=
2
canaryU
pd
.
Canary
=
2
canaryU
pd
.
ProgressDeadline
=
5
*
time
.
Second
j
:=
mock
.
Job
()
j
.
TaskGroups
[
0
]
.
Update
=
upd
rollingUpd
:=
structs
.
DefaultUpdateStrategy
.
Copy
()
rollingUpd
.
ProgressDeadline
=
5
*
time
.
Second
j
:=
mock
.
MultiTaskGroupJob
()
j
.
TaskGroups
[
0
]
.
Update
=
canaryUpd
j
.
TaskGroups
[
1
]
.
Update
=
rollingUpd
d
:=
mock
.
Deployment
()
d
.
JobID
=
j
.
ID
...
...
@@ -551,14 +555,20 @@ func TestWatcher_AutoPromoteDeployment(t *testing.T) {
// UpdateStrategy are copied in
d
.
TaskGroups
=
map
[
string
]
*
structs
.
DeploymentState
{
"web"
:
{
AutoPromote
:
upd
.
AutoPromote
,
AutoRevert
:
upd
.
AutoRevert
,
ProgressDeadline
:
upd
.
ProgressDeadline
,
AutoPromote
:
canaryUpd
.
AutoPromote
,
AutoRevert
:
canaryUpd
.
AutoRevert
,
ProgressDeadline
:
canaryUpd
.
ProgressDeadline
,
DesiredTotal
:
2
,
},
"api"
:
{
AutoPromote
:
rollingUpd
.
AutoPromote
,
AutoRevert
:
rollingUpd
.
AutoRevert
,
ProgressDeadline
:
rollingUpd
.
ProgressDeadline
,
DesiredTotal
:
2
,
},
}
a
lloc
:=
func
()
*
structs
.
Allocation
{
canaryA
lloc
:=
func
()
*
structs
.
Allocation
{
a
:=
mock
.
Alloc
()
a
.
DeploymentID
=
d
.
ID
a
.
CreateTime
=
now
.
UnixNano
()
...
...
@@ -569,14 +579,36 @@ func TestWatcher_AutoPromoteDeployment(t *testing.T) {
return
a
}
a
:=
alloc
()
b
:=
alloc
()
rollingAlloc
:=
func
()
*
structs
.
Allocation
{
a
:=
mock
.
Alloc
()
a
.
DeploymentID
=
d
.
ID
a
.
CreateTime
=
now
.
UnixNano
()
a
.
ModifyTime
=
now
.
UnixNano
()
a
.
TaskGroup
=
"api"
a
.
AllocatedResources
.
Tasks
[
"api"
]
=
a
.
AllocatedResources
.
Tasks
[
"web"
]
.
Copy
()
delete
(
a
.
AllocatedResources
.
Tasks
,
"web"
)
a
.
TaskResources
[
"api"
]
=
a
.
TaskResources
[
"web"
]
.
Copy
()
delete
(
a
.
TaskResources
,
"web"
)
a
.
DeploymentStatus
=
&
structs
.
AllocDeploymentStatus
{
Canary
:
false
,
}
return
a
}
// Web taskgroup (0)
a
:=
canaryAlloc
()
b
:=
canaryAlloc
()
// Api taskgroup (1)
c
:=
rollingAlloc
()
e
:=
rollingAlloc
()
d
.
TaskGroups
[
a
.
TaskGroup
]
.
PlacedCanaries
=
[]
string
{
a
.
ID
,
b
.
ID
}
d
.
TaskGroups
[
a
.
TaskGroup
]
.
DesiredCanaries
=
2
d
.
TaskGroups
[
c
.
TaskGroup
]
.
PlacedAllocs
=
2
require
.
NoError
(
t
,
m
.
state
.
UpsertJob
(
structs
.
MsgTypeTestSetup
,
m
.
nextIndex
(),
j
),
"UpsertJob"
)
require
.
NoError
(
t
,
m
.
state
.
UpsertDeployment
(
m
.
nextIndex
(),
d
),
"UpsertDeployment"
)
require
.
NoError
(
t
,
m
.
state
.
UpsertAllocs
(
structs
.
MsgTypeTestSetup
,
m
.
nextIndex
(),
[]
*
structs
.
Allocation
{
a
,
b
}),
"UpsertAllocs"
)
require
.
NoError
(
t
,
m
.
state
.
UpsertAllocs
(
structs
.
MsgTypeTestSetup
,
m
.
nextIndex
(),
[]
*
structs
.
Allocation
{
a
,
b
,
c
,
e
}),
"UpsertAllocs"
)
// =============================================================
// Support method calls
...
...
@@ -595,7 +627,7 @@ func TestWatcher_AutoPromoteDeployment(t *testing.T) {
matchConfig1
:=
&
matchDeploymentAllocHealthRequestConfig
{
DeploymentID
:
d
.
ID
,
Healthy
:
[]
string
{
a
.
ID
,
b
.
ID
},
Healthy
:
[]
string
{
a
.
ID
,
b
.
ID
,
c
.
ID
,
e
.
ID
},
Eval
:
true
,
}
matcher1
:=
matchDeploymentAllocHealthRequest
(
matchConfig1
)
...
...
@@ -629,7 +661,7 @@ func TestWatcher_AutoPromoteDeployment(t *testing.T) {
// Mark the canaries healthy
req
:=
&
structs
.
DeploymentAllocHealthRequest
{
DeploymentID
:
d
.
ID
,
HealthyAllocationIDs
:
[]
string
{
a
.
ID
,
b
.
ID
},
HealthyAllocationIDs
:
[]
string
{
a
.
ID
,
b
.
ID
,
c
.
ID
,
e
.
ID
},
}
var
resp
structs
.
DeploymentUpdateResponse
// Calls w.raft.UpdateDeploymentAllocHealth, which is implemented by StateStore in
...
...
This diff is collapsed.
Click to expand it.
nomad/mock/mock.go
+
82
-
0
View file @
1096d434
...
...
@@ -297,6 +297,88 @@ func Job() *structs.Job {
return
job
}
func
MultiTaskGroupJob
()
*
structs
.
Job
{
job
:=
Job
()
apiTaskGroup
:=
&
structs
.
TaskGroup
{
Name
:
"api"
,
Count
:
10
,
EphemeralDisk
:
&
structs
.
EphemeralDisk
{
SizeMB
:
150
,
},
RestartPolicy
:
&
structs
.
RestartPolicy
{
Attempts
:
3
,
Interval
:
10
*
time
.
Minute
,
Delay
:
1
*
time
.
Minute
,
Mode
:
structs
.
RestartPolicyModeDelay
,
},
ReschedulePolicy
:
&
structs
.
ReschedulePolicy
{
Attempts
:
2
,
Interval
:
10
*
time
.
Minute
,
Delay
:
5
*
time
.
Second
,
DelayFunction
:
"constant"
,
},
Migrate
:
structs
.
DefaultMigrateStrategy
(),
Networks
:
[]
*
structs
.
NetworkResource
{
{
Mode
:
"host"
,
DynamicPorts
:
[]
structs
.
Port
{
{
Label
:
"http"
},
{
Label
:
"admin"
},
},
},
},
Tasks
:
[]
*
structs
.
Task
{
{
Name
:
"api"
,
Driver
:
"exec"
,
Config
:
map
[
string
]
interface
{}{
"command"
:
"/bin/date"
,
},
Env
:
map
[
string
]
string
{
"FOO"
:
"bar"
,
},
Services
:
[]
*
structs
.
Service
{
{
Name
:
"${TASK}-backend"
,
PortLabel
:
"http"
,
Tags
:
[]
string
{
"pci:${meta.pci-dss}"
,
"datacenter:${node.datacenter}"
},
Checks
:
[]
*
structs
.
ServiceCheck
{
{
Name
:
"check-table"
,
Type
:
structs
.
ServiceCheckScript
,
Command
:
"/usr/local/check-table-${meta.database}"
,
Args
:
[]
string
{
"${meta.version}"
},
Interval
:
30
*
time
.
Second
,
Timeout
:
5
*
time
.
Second
,
},
},
},
{
Name
:
"${TASK}-admin"
,
PortLabel
:
"admin"
,
},
},
LogConfig
:
structs
.
DefaultLogConfig
(),
Resources
:
&
structs
.
Resources
{
CPU
:
500
,
MemoryMB
:
256
,
},
Meta
:
map
[
string
]
string
{
"foo"
:
"bar"
,
},
},
},
Meta
:
map
[
string
]
string
{
"elb_check_type"
:
"http"
,
"elb_check_interval"
:
"30s"
,
"elb_check_min"
:
"3"
,
},
}
job
.
TaskGroups
=
append
(
job
.
TaskGroups
,
apiTaskGroup
)
job
.
Canonicalize
()
return
job
}
func
LifecycleSideTask
(
resources
structs
.
Resources
,
i
int
)
*
structs
.
Task
{
return
&
structs
.
Task
{
Name
:
fmt
.
Sprintf
(
"side-%d"
,
i
),
...
...
This diff is collapsed.
Click to expand it.
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment
Menu
Projects
Groups
Snippets
Help