-
Notifications
You must be signed in to change notification settings - Fork 8
/
deploy.go
196 lines (172 loc) · 5.91 KB
/
deploy.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
// Copyright 2019 Shanghai JingDuo Information Technology co., Ltd.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package server
import (
"fmt"
"sort"
"github.com/sirupsen/logrus"
"github.com/kpaas-io/kpaas/pkg/constant"
"github.com/kpaas-io/kpaas/pkg/deploy/action"
pb "github.com/kpaas-io/kpaas/pkg/deploy/protos"
"github.com/kpaas-io/kpaas/pkg/deploy/task"
)
var allRoles = []constant.MachineRole{constant.MachineRoleEtcd, constant.MachineRoleMaster,
constant.MachineRoleWorker, constant.MachineRoleIngress}
func (c *controller) getDeployResult(aTask task.Task, withLogs bool) (*pb.GetDeployResultReply, error) {
if aTask == nil {
return nil, fmt.Errorf("Task is nil")
}
// TODO: handle the logs of task and its actions if withLogs == true
deployTask, ok := aTask.(*task.DeployTask)
if !ok {
return nil, fmt.Errorf("invalid task")
}
roleNodes := groupNodesByRole(deployTask.NodeConfigs)
// If the task is already failed, set the default status in deploy item result as "aborted",
// otherewise, set the default status to "pending". The final status of them would be updated
// in the following process.
initStatus := string(constant.OperationStatusPending)
if aTask.GetStatus() == task.TaskFailed {
initStatus = string(constant.OperationStatusAborted)
}
// Create a pb.DeployItemResult for each {role, node}
roleNodeDeployItemResult := make(map[constant.MachineRole]map[string]*pb.DeployItemResult)
for role, nodes := range roleNodes {
roleNodeDeployItemResult[role] = make(map[string]*pb.DeployItemResult)
for _, node := range nodes {
roleNodeDeployItemResult[role][node] = &pb.DeployItemResult{
DeployItem: &pb.DeployItem{
Role: string(role),
NodeName: node,
},
Status: initStatus,
}
}
}
// Get all actions of the deploy task
actions := task.GetAllActions(aTask)
// Firstly, iterate the node init action, if any of the node init action is not done
// update the related pb.DeployItemResult in the collecton of {role, node} to the
// node init aciton's status
initNotDone := false
for _, act := range actions {
if act.GetType() != action.ActionTypeNodeInit || act.GetStatus() == action.ActionDone {
continue
}
initNotDone = true
node := act.GetNode()
if node == nil || node.Name == "" {
logrus.Warn("Invalid node")
continue
}
for _, role := range allRoles {
if _, ok := roleNodeDeployItemResult[role]; !ok {
continue
}
if _, ok := roleNodeDeployItemResult[role][node.Name]; !ok {
continue
}
itemResult := roleNodeDeployItemResult[role][node.Name]
itemResult.Status = string(actionStatusToOperationStatus(act.GetStatus()))
itemResult.Err = act.GetErr()
}
}
// If all node init action are done, update deploy item results with non node init actions
if !initNotDone {
for _, act := range actions {
if act.GetType() == action.ActionTypeNodeInit {
continue
}
node := act.GetNode()
if node == nil || node.Name == "" {
logrus.Warn("Invalid node")
continue
}
role := actionTypeToRole(act.GetType())
if _, ok := roleNodeDeployItemResult[role]; !ok {
logrus.Warnf("Didn't find the role %q in the map", role)
continue
}
if _, ok := roleNodeDeployItemResult[role][node.Name]; !ok {
logrus.Warnf("Didn't find the node %q with the role %q in the map", node.Name, role)
continue
}
itemResult := roleNodeDeployItemResult[role][node.Name]
itemResult.Status = string(actionStatusToOperationStatus(act.GetStatus()))
itemResult.Err = act.GetErr()
}
}
// Update the reply's status according to the deploy task's status.
result := &pb.GetDeployResultReply{
Status: string(taskStatusToOperationStatus(aTask.GetStatus())),
Err: aTask.GetErr(),
Items: sortResultByRole(roleNodeDeployItemResult),
}
logrus.Debugf("Result: %+v", *result)
return result, nil
}
func sortMap(m map[string]*pb.DeployItemResult) []*pb.DeployItemResult {
// get all keys
var keys []string
for key := range m {
keys = append(keys, key)
}
// sort the keys
sort.Strings(keys)
var items []*pb.DeployItemResult
for _, key := range keys {
items = append(items, m[key])
}
return items
}
func sortResultByRole(m map[constant.MachineRole]map[string]*pb.DeployItemResult) []*pb.DeployItemResult {
var items []*pb.DeployItemResult
// Sort the result by roles
for _, role := range allRoles {
if roleResultMap, ok := m[role]; ok {
items = append(items, sortMap(roleResultMap)...)
}
}
return items
}
func groupNodesByRole(cfgs []*pb.NodeDeployConfig) map[constant.MachineRole][]string {
roleNodes := make(map[constant.MachineRole][]string)
for _, nodeCfg := range cfgs {
if nodeCfg == nil || nodeCfg.Node == nil || nodeCfg.Node.Name == "" || len(nodeCfg.Roles) == 0 {
logrus.Warnf("Invalid nodeCfg")
continue
}
for _, role := range nodeCfg.Roles {
roleName := constant.MachineRole(role)
roleNodes[roleName] = append(roleNodes[roleName], nodeCfg.Node.Name)
}
}
return roleNodes
}
func actionTypeToRole(actionType action.Type) constant.MachineRole {
switch actionType {
case action.ActionTypeDeployEtcd:
return constant.MachineRoleEtcd
case action.ActionTypeInitMaster, action.ActionTypeJoinMaster:
return constant.MachineRoleMaster
case action.ActionTypeDeployWorker:
return constant.MachineRoleWorker
// treat node init action as ectd role
case action.ActionTypeNodeInit:
return constant.MachineRoleEtcd
default:
logrus.Warnf("unknown action type: %v", actionType)
return "unknown"
}
}