Skip to content

Commit f6f1b83

Browse files
feat: revamp application list with grouping support (#905) (#940)
(cherry picked from commit 8796737) Co-authored-by: Tanmoy Sarkar <[email protected]>
1 parent 53709d9 commit f6f1b83

16 files changed

+343
-158
lines changed

container_manager/service.go

Lines changed: 6 additions & 122 deletions
Original file line numberDiff line numberDiff line change
@@ -255,140 +255,24 @@ func (m Manager) SetServiceReplicaCount(serviceName string, replicas int) error
255255
}
256256
}
257257

258-
func (m Manager) RealtimeInfoRunningServices() (map[string]ServiceRealtimeInfo, error) {
259-
// fetch all nodes and store in map > nodeID:nodeDetails
260-
nodes, err := m.client.NodeList(m.ctx, types.NodeListOptions{})
261-
if err != nil {
262-
return nil, errors.New("error getting node list")
263-
}
264-
nodeMap := make(map[string]swarm.Node)
265-
for _, node := range nodes {
266-
nodeMap[node.ID] = node
267-
}
268-
// fetch all services and store in map > serviceName:serviceDetails
269-
services, err := m.client.ServiceList(m.ctx, types.ServiceListOptions{})
270-
if err != nil {
271-
return nil, errors.New("error getting service list")
272-
}
273-
// create map of service name to service realtime info
274-
serviceRealtimeInfoMap := make(map[string]ServiceRealtimeInfo)
275-
// analyze each service
276-
for _, service := range services {
277-
runningCount := 0
278-
279-
// inspect service to get desired count
280-
serviceData, _, err := m.client.ServiceInspectWithRaw(m.ctx, service.ID, types.ServiceInspectOptions{})
281-
if err != nil {
282-
continue
283-
}
284-
// create service realtime info
285-
serviceRealtimeInfo := ServiceRealtimeInfo{}
286-
serviceRealtimeInfo.Name = serviceData.Spec.Name
287-
serviceRealtimeInfo.PlacementInfos = []ServiceTaskPlacementInfo{}
288-
// set desired count
289-
if serviceData.Spec.Mode.Replicated != nil {
290-
serviceRealtimeInfo.DesiredReplicas = int(*serviceData.Spec.Mode.Replicated.Replicas)
291-
serviceRealtimeInfo.ReplicatedService = true
292-
} else {
293-
serviceRealtimeInfo.DesiredReplicas = -1
294-
serviceRealtimeInfo.ReplicatedService = false
295-
}
296-
297-
// query task list
298-
tasks, err := m.client.TaskList(m.ctx, types.TaskListOptions{
299-
Filters: filters.NewArgs(
300-
filters.Arg("service", serviceData.Spec.Name),
301-
),
302-
})
303-
if err != nil {
304-
continue
305-
}
306-
servicePlacementCountMap := make(map[string]int) // nodeID:count
307-
// set placement infos > how many replicas are running in each node
308-
for _, task := range tasks {
309-
if task.Status.State == swarm.TaskStateRunning {
310-
servicePlacementCountMap[task.NodeID]++
311-
}
312-
}
313-
for nodeID, count := range servicePlacementCountMap {
314-
node := nodeMap[nodeID]
315-
serviceRealtimeInfo.PlacementInfos = append(serviceRealtimeInfo.PlacementInfos, ServiceTaskPlacementInfo{
316-
NodeID: nodeID,
317-
NodeName: node.Description.Hostname,
318-
IsManagerNode: node.Spec.Role != swarm.NodeRoleManager,
319-
RunningReplicas: count,
320-
})
321-
runningCount += count
322-
}
323-
// set service realtime info in map
324-
serviceRealtimeInfo.RunningReplicas = runningCount
325-
serviceRealtimeInfoMap[serviceRealtimeInfo.Name] = serviceRealtimeInfo
326-
}
327-
return serviceRealtimeInfoMap, nil
328-
}
329-
330-
func (m Manager) RealtimeInfoService(serviceName string, ignoreNodeDetails bool) (ServiceRealtimeInfo, error) {
331-
runningCount := 0
332-
serviceRealtimeInfo := ServiceRealtimeInfo{}
333-
// fetch all nodes and store in map > nodeID:nodeDetails
334-
nodeMap := make(map[string]swarm.Node)
335-
if !ignoreNodeDetails {
336-
nodes, err := m.client.NodeList(m.ctx, types.NodeListOptions{})
337-
if err != nil {
338-
return serviceRealtimeInfo, errors.New("error getting node list")
339-
}
340-
for _, node := range nodes {
341-
nodeMap[node.ID] = node
342-
}
343-
}
344-
// inspect service to get desired count
345-
serviceData, _, err := m.client.ServiceInspectWithRaw(m.ctx, serviceName, types.ServiceInspectOptions{})
346-
if err != nil {
347-
return serviceRealtimeInfo, errors.New("error getting service")
348-
}
349-
// create service realtime info
350-
serviceRealtimeInfo.Name = serviceData.Spec.Name
351-
serviceRealtimeInfo.PlacementInfos = []ServiceTaskPlacementInfo{}
352-
// set desired count
353-
if serviceData.Spec.Mode.Replicated != nil {
354-
serviceRealtimeInfo.DesiredReplicas = int(*serviceData.Spec.Mode.Replicated.Replicas)
355-
serviceRealtimeInfo.ReplicatedService = true
356-
} else {
357-
serviceRealtimeInfo.DesiredReplicas = -1
358-
serviceRealtimeInfo.ReplicatedService = false
359-
}
360-
258+
func (m Manager) NoOfRunningTasks(serviceName string) (int, error) {
361259
// query task list
362260
tasks, err := m.client.TaskList(m.ctx, types.TaskListOptions{
363261
Filters: filters.NewArgs(
364-
filters.Arg("service", serviceData.Spec.Name),
262+
filters.Arg("service", serviceName),
365263
),
366264
})
367265
if err != nil {
368-
return serviceRealtimeInfo, err
266+
return 0, err
369267
}
370-
servicePlacementCountMap := make(map[string]int) // nodeID:count
268+
runningCount := 0
371269
// set placement infos > how many replicas are running in each node
372270
for _, task := range tasks {
373271
if task.Status.State == swarm.TaskStateRunning {
374-
servicePlacementCountMap[task.NodeID]++
375-
}
376-
}
377-
for nodeID, count := range servicePlacementCountMap {
378-
if !ignoreNodeDetails {
379-
node := nodeMap[nodeID]
380-
serviceRealtimeInfo.PlacementInfos = append(serviceRealtimeInfo.PlacementInfos, ServiceTaskPlacementInfo{
381-
NodeID: nodeID,
382-
NodeName: node.Description.Hostname,
383-
IsManagerNode: node.Spec.Role != swarm.NodeRoleManager,
384-
RunningReplicas: count,
385-
})
272+
runningCount++
386273
}
387-
runningCount += count
388274
}
389-
// set service realtime info in map
390-
serviceRealtimeInfo.RunningReplicas = runningCount
391-
return serviceRealtimeInfo, nil
275+
return runningCount, nil
392276
}
393277

394278
// ServiceRunningServers Fetch the servers where a service is running

container_manager/types.go

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -48,11 +48,10 @@ type CustomHealthCheck struct {
4848
}
4949

5050
type ServiceRealtimeInfo struct {
51-
Name string `json:"name"`
52-
PlacementInfos []ServiceTaskPlacementInfo `json:"placementinfos"`
53-
DesiredReplicas int `json:"desiredreplicas"`
54-
RunningReplicas int `json:"runningreplicas"`
55-
ReplicatedService bool `json:"replicatedservice"`
51+
Name string `json:"name"`
52+
DesiredReplicas int `json:"desiredreplicas"`
53+
RunningReplicas int `json:"runningreplicas"`
54+
ReplicatedService bool `json:"replicatedservice"`
5655
}
5756

5857
type ServiceTaskPlacementInfo struct {

swiftwave_service/core/application.operations.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,14 @@ func IsExistApplicationName(_ context.Context, db gorm.DB, dockerManager contain
4242
return false, nil
4343
}
4444

45-
func FindAllApplications(_ context.Context, db gorm.DB) ([]*Application, error) {
45+
func FindAllApplications(_ context.Context, db gorm.DB, includeGroupedApplications bool) ([]*Application, error) {
4646
var applications []*Application
47-
tx := db.Find(&applications)
47+
var tx *gorm.DB
48+
if includeGroupedApplications {
49+
tx = db.Find(&applications)
50+
} else {
51+
tx = db.Where("application_group_id IS NULL").Find(&applications)
52+
}
4853
return applications, tx.Error
4954
}
5055

swiftwave_service/core/models.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -211,10 +211,12 @@ type ConfigMount struct {
211211
FileMode uint `json:"file_mode" gorm:"default:444"`
212212
}
213213

214-
// ApplicationGroup hold information about application group
214+
// ApplicationGroup hold information about application-group
215215
type ApplicationGroup struct {
216216
ID string `json:"id" gorm:"primaryKey"`
217-
Name string `json:"name" gorm:"unique"`
217+
Name string `json:"name"`
218+
Logo string `json:"logo"`
219+
StackContent string `json:"stack_content"`
218220
Applications []Application `json:"applications" gorm:"foreignKey:ApplicationGroupID;constraint:OnUpdate:CASCADE,OnDelete:SET NULL;"`
219221
}
220222

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
-- reverse: modify "application_groups" table
2+
ALTER TABLE "public"."application_groups" DROP COLUMN "stack_content", DROP COLUMN "logo", ADD CONSTRAINT "uni_application_groups_name" UNIQUE ("name");
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
-- modify "application_groups" table
2+
ALTER TABLE "public"."application_groups" DROP CONSTRAINT "uni_application_groups_name", ADD COLUMN "logo" text NULL, ADD COLUMN "stack_content" text NULL;

swiftwave_service/db/migrations/atlas.sum

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
h1:hvxXPYu5/HahR/1ICKIZo/MYqsNXMabxSt0SdHKNf8Q=
1+
h1:k1qJKQt8Sk2nl3wA2bU97eDfUN6gf5sarKNVQ0Ez5Lw=
22
20240413191732_init.down.sql h1:HoitObGwuKF/akF4qg3dol2FfNTLCEuf6wHYDuCez8I=
33
20240413191732_init.up.sql h1:USKdQx/yTz1KJ0+mDwYGhKm3WzX7k+I9+6B6SxImwaE=
44
20240414051823_server_custom_ssh_port_added.down.sql h1:IC1DFQBQceTPTRdZOo5/WqytH+ZbgcKrQuMCkhArF/0=
@@ -43,3 +43,5 @@ h1:hvxXPYu5/HahR/1ICKIZo/MYqsNXMabxSt0SdHKNf8Q=
4343
20240625161343_rename_app_status_live_to_deployed.up.sql h1:J5B2Il4UoFg9fZtj1tkCXIJoDHhCDYjj1XUA2088JRc=
4444
20240626072036_move_application_group_to_relation.down.sql h1:oMF4rB5As6BFCMPAxbm7lXvWyyCb9uqmFOC/AcTsDY8=
4545
20240626072036_move_application_group_to_relation.up.sql h1:SNdKqmYmIZeE0JcgKiLYFajW/awiz4rXRSAKVdabPZg=
46+
20240628175617_add_extra_fields_in_app_group.down.sql h1:T/QBEilqWYysok6l2wxZAlYK1Z6ceSQLUmers5fZNig=
47+
20240628175617_add_extra_fields_in_app_group.up.sql h1:+qBOQc/2bhG1igFdUbWSsZEy01aORuPyBPvxKVXJJoA=

swiftwave_service/gqlgen.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,10 @@ models:
6060
resolver: true
6161
applicationGroup:
6262
resolver: true
63+
RealtimeInfo:
64+
fields:
65+
HealthStatus:
66+
resolver: true
6367
ApplicationGroup:
6468
fields:
6569
applications:

swiftwave_service/graphql/application.resolvers.go

Lines changed: 37 additions & 12 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

swiftwave_service/graphql/application_group.resolvers.go

Lines changed: 6 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)