Skip to content

Commit c7d93f5

Browse files
committed
feat: Support favorite operations for containers and images
1 parent 4209ee4 commit c7d93f5

File tree

17 files changed

+371
-104
lines changed

17 files changed

+371
-104
lines changed

agent/app/api/v2/setting.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,3 +155,24 @@ func (b *BaseApi) GetSettingByKey(c *gin.Context) {
155155
value := settingService.GetSettingByKey(key)
156156
helper.SuccessWithData(c, value)
157157
}
158+
159+
// @Tags System Setting
160+
// @Summary Save common description
161+
// @Accept json
162+
// @Param request body dto.CommonDescription true "request"
163+
// @Success 200
164+
// @Security ApiKeyAuth
165+
// @Security Timestamp
166+
// @Router /settings/description/save [post]
167+
func (b *BaseApi) SaveDescription(c *gin.Context) {
168+
var req dto.CommonDescription
169+
if err := helper.CheckBindAndValidate(&req, c); err != nil {
170+
return
171+
}
172+
173+
if err := settingService.SaveDescription(req); err != nil {
174+
helper.InternalServer(c, err)
175+
return
176+
}
177+
helper.Success(c)
178+
}

agent/app/dto/container.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,9 @@ type ContainerInfo struct {
4040
AppName string `json:"appName"`
4141
AppInstallName string `json:"appInstallName"`
4242
Websites []string `json:"websites"`
43+
44+
IsPinned bool `json:"isPinned"`
45+
Description string `json:"description"`
4346
}
4447

4548
type ContainerOptions struct {

agent/app/dto/image.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@ type ImageInfo struct {
1515
IsUsed bool `json:"isUsed"`
1616
Tags []string `json:"tags"`
1717
Size int64 `json:"size"`
18+
19+
IsPinned bool `json:"isPinned"`
20+
Description string `json:"description"`
1821
}
1922

2023
type ImageLoad struct {

agent/app/dto/setting.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,3 +81,11 @@ type SystemProxy struct {
8181
User string `json:"user"`
8282
Password string `json:"password"`
8383
}
84+
85+
type CommonDescription struct {
86+
ID string `json:"id" validate:"required"`
87+
Type string `json:"type" validate:"required"`
88+
DetailType string `json:"detailType"`
89+
IsPinned bool `json:"isPinned"`
90+
Description string `json:"description"`
91+
}

agent/app/model/setting.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,14 @@ type Setting struct {
77
About string `json:"about"`
88
}
99

10+
type CommonDescription struct {
11+
ID string `json:"id"`
12+
Type string `json:"type"`
13+
DetailType string `json:"detailType"`
14+
IsPinned bool `json:"isPinned"`
15+
Description string `json:"description"`
16+
}
17+
1018
type NodeInfo struct {
1119
Scope string `json:"scope"`
1220
BaseDir string `json:"baseDir"`

agent/app/repo/common.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,11 @@ func WithByType(tp string) DBOption {
7777
return g.Where("`type` = ?", tp)
7878
}
7979
}
80+
func WithByDetailType(tp string) DBOption {
81+
return func(g *gorm.DB) *gorm.DB {
82+
return g.Where("`detail_type` = ?", tp)
83+
}
84+
}
8085

8186
func WithTypes(types []string) DBOption {
8287
return func(db *gorm.DB) *gorm.DB {

agent/app/repo/setting.go

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,13 @@ type ISettingRepo interface {
2626
DelMonitorIO(timeForDelete time.Time) error
2727
DelMonitorNet(timeForDelete time.Time) error
2828
UpdateOrCreate(key, value string) error
29+
30+
GetDescription(opts ...DBOption) (model.CommonDescription, error)
31+
GetDescriptionList(opts ...DBOption) ([]model.CommonDescription, error)
32+
CreateDescription(data *model.CommonDescription) error
33+
UpdateDescription(id string, val map[string]interface{}) error
34+
DelDescription(id string) error
35+
WithByDescriptionID(id string) DBOption
2936
}
3037

3138
func NewISettingRepo() ISettingRepo {
@@ -108,3 +115,36 @@ func (s *SettingRepo) UpdateOrCreate(key, value string) error {
108115
}
109116
return global.DB.Model(&setting).UpdateColumn("value", value).Error
110117
}
118+
119+
func (s *SettingRepo) GetDescriptionList(opts ...DBOption) ([]model.CommonDescription, error) {
120+
var lists []model.CommonDescription
121+
db := global.DB.Model(&model.CommonDescription{})
122+
for _, opt := range opts {
123+
db = opt(db)
124+
}
125+
err := db.Find(&lists).Error
126+
return lists, err
127+
}
128+
func (s *SettingRepo) GetDescription(opts ...DBOption) (model.CommonDescription, error) {
129+
var data model.CommonDescription
130+
db := global.DB.Model(&model.CommonDescription{})
131+
for _, opt := range opts {
132+
db = opt(db)
133+
}
134+
err := db.First(&data).Error
135+
return data, err
136+
}
137+
func (s *SettingRepo) CreateDescription(data *model.CommonDescription) error {
138+
return global.DB.Create(data).Error
139+
}
140+
func (s *SettingRepo) UpdateDescription(id string, val map[string]interface{}) error {
141+
return global.DB.Model(&model.CommonDescription{}).Where("id = ?", id).Updates(val).Error
142+
}
143+
func (s *SettingRepo) DelDescription(id string) error {
144+
return global.DB.Where("id = ?", id).Delete(&model.CommonDescription{}).Error
145+
}
146+
func (s *SettingRepo) WithByDescriptionID(id string) DBOption {
147+
return func(g *gorm.DB) *gorm.DB {
148+
return g.Where("id = ?", id)
149+
}
150+
}

agent/app/service/container.go

Lines changed: 118 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -96,10 +96,6 @@ func NewIContainerService() IContainerService {
9696
}
9797

9898
func (u *ContainerService) Page(req dto.PageContainer) (int64, interface{}, error) {
99-
var (
100-
records []container.Summary
101-
list []container.Summary
102-
)
10399
client, err := docker.NewDockerClient()
104100
if err != nil {
105101
return 0, nil, err
@@ -117,114 +113,32 @@ func (u *ContainerService) Page(req dto.PageContainer) (int64, interface{}, erro
117113
if err != nil {
118114
return 0, nil, err
119115
}
120-
if req.ExcludeAppStore {
121-
for _, item := range containers {
122-
if created, ok := item.Labels[composeCreatedBy]; ok && created == "Apps" {
123-
continue
124-
}
125-
list = append(list, item)
126-
}
127-
} else {
128-
list = containers
129-
}
130-
131-
if len(req.Name) != 0 {
132-
length, count := len(list), 0
133-
for count < length {
134-
if !strings.Contains(list[count].Names[0][1:], req.Name) && !strings.Contains(list[count].Image, req.Name) {
135-
list = append(list[:count], list[(count+1):]...)
136-
length--
137-
} else {
138-
count++
139-
}
140-
}
141-
}
142-
if req.State != "all" {
143-
length, count := len(list), 0
144-
for count < length {
145-
if list[count].State != req.State {
146-
list = append(list[:count], list[(count+1):]...)
147-
length--
148-
} else {
149-
count++
150-
}
151-
}
152-
}
153-
switch req.OrderBy {
154-
case "name":
155-
sort.Slice(list, func(i, j int) bool {
156-
if req.Order == constant.OrderAsc {
157-
return list[i].Names[0][1:] < list[j].Names[0][1:]
158-
}
159-
return list[i].Names[0][1:] > list[j].Names[0][1:]
160-
})
161-
default:
162-
sort.Slice(list, func(i, j int) bool {
163-
if req.Order == constant.OrderAsc {
164-
return list[i].Created < list[j].Created
165-
}
166-
return list[i].Created > list[j].Created
167-
})
168-
}
116+
records := searchWithFilter(req, containers)
169117

170-
total, start, end := len(list), (req.Page-1)*req.PageSize, req.Page*req.PageSize
118+
var backData []dto.ContainerInfo
119+
total, start, end := len(records), (req.Page-1)*req.PageSize, req.Page*req.PageSize
171120
if start > total {
172-
records = make([]container.Summary, 0)
121+
backData = make([]dto.ContainerInfo, 0)
173122
} else {
174123
if end >= total {
175124
end = total
176125
}
177-
records = list[start:end]
126+
backData = records[start:end]
178127
}
179128

180-
backDatas := make([]dto.ContainerInfo, len(records))
181-
for i := 0; i < len(records); i++ {
182-
item := records[i]
183-
IsFromCompose := false
184-
if _, ok := item.Labels[composeProjectLabel]; ok {
185-
IsFromCompose = true
186-
}
187-
IsFromApp := false
188-
if created, ok := item.Labels[composeCreatedBy]; ok && created == "Apps" {
189-
IsFromApp = true
190-
}
191-
192-
exposePorts := transPortToStr(records[i].Ports)
193-
info := dto.ContainerInfo{
194-
ContainerID: item.ID,
195-
CreateTime: time.Unix(item.Created, 0).Format(constant.DateTimeLayout),
196-
Name: item.Names[0][1:],
197-
ImageId: strings.Split(item.ImageID, ":")[1],
198-
ImageName: item.Image,
199-
State: item.State,
200-
RunTime: item.Status,
201-
Ports: exposePorts,
202-
IsFromApp: IsFromApp,
203-
IsFromCompose: IsFromCompose,
204-
SizeRw: item.SizeRw,
205-
SizeRootFs: item.SizeRootFs,
206-
}
207-
install, _ := appInstallRepo.GetFirst(appInstallRepo.WithContainerName(info.Name))
129+
for i := 0; i < len(backData); i++ {
130+
install, _ := appInstallRepo.GetFirst(appInstallRepo.WithContainerName(backData[i].Name))
208131
if install.ID > 0 {
209-
info.AppInstallName = install.Name
210-
info.AppName = install.App.Name
132+
backData[i].AppInstallName = install.Name
133+
backData[i].AppName = install.App.Name
211134
websites, _ := websiteRepo.GetBy(websiteRepo.WithAppInstallId(install.ID))
212135
for _, website := range websites {
213-
info.Websites = append(info.Websites, website.PrimaryDomain)
214-
}
215-
}
216-
backDatas[i] = info
217-
if item.NetworkSettings != nil && len(item.NetworkSettings.Networks) > 0 {
218-
networks := make([]string, 0, len(item.NetworkSettings.Networks))
219-
for key := range item.NetworkSettings.Networks {
220-
networks = append(networks, item.NetworkSettings.Networks[key].IPAddress)
136+
backData[i].Websites = append(backData[i].Websites, website.PrimaryDomain)
221137
}
222-
sort.Strings(networks)
223-
backDatas[i].Network = networks
224138
}
225139
}
226140

227-
return int64(total), backDatas, nil
141+
return int64(total), backData, nil
228142
}
229143

230144
func (u *ContainerService) List() []dto.ContainerOptions {
@@ -1771,3 +1685,110 @@ func loadContainerPortForInfo(itemPorts []container.Port) []dto.PortHelper {
17711685
}
17721686
return exposedPorts
17731687
}
1688+
1689+
func searchWithFilter(req dto.PageContainer, containers []container.Summary) []dto.ContainerInfo {
1690+
var (
1691+
records []dto.ContainerInfo
1692+
list []container.Summary
1693+
)
1694+
1695+
if req.ExcludeAppStore {
1696+
for _, item := range containers {
1697+
if created, ok := item.Labels[composeCreatedBy]; ok && created == "Apps" {
1698+
continue
1699+
}
1700+
list = append(list, item)
1701+
}
1702+
} else {
1703+
list = containers
1704+
}
1705+
1706+
if len(req.Name) != 0 {
1707+
length, count := len(list), 0
1708+
for count < length {
1709+
if !strings.Contains(list[count].Names[0][1:], req.Name) && !strings.Contains(list[count].Image, req.Name) {
1710+
list = append(list[:count], list[(count+1):]...)
1711+
length--
1712+
} else {
1713+
count++
1714+
}
1715+
}
1716+
}
1717+
if req.State != "all" {
1718+
length, count := len(list), 0
1719+
for count < length {
1720+
if list[count].State != req.State {
1721+
list = append(list[:count], list[(count+1):]...)
1722+
length--
1723+
} else {
1724+
count++
1725+
}
1726+
}
1727+
}
1728+
switch req.OrderBy {
1729+
case "name":
1730+
sort.Slice(list, func(i, j int) bool {
1731+
if req.Order == constant.OrderAsc {
1732+
return list[i].Names[0][1:] < list[j].Names[0][1:]
1733+
}
1734+
return list[i].Names[0][1:] > list[j].Names[0][1:]
1735+
})
1736+
default:
1737+
sort.Slice(list, func(i, j int) bool {
1738+
if req.Order == constant.OrderAsc {
1739+
return list[i].Created < list[j].Created
1740+
}
1741+
return list[i].Created > list[j].Created
1742+
})
1743+
}
1744+
for _, item := range list {
1745+
IsFromCompose := false
1746+
if _, ok := item.Labels[composeProjectLabel]; ok {
1747+
IsFromCompose = true
1748+
}
1749+
IsFromApp := false
1750+
if created, ok := item.Labels[composeCreatedBy]; ok && created == "Apps" {
1751+
IsFromApp = true
1752+
}
1753+
exposePorts := transPortToStr(item.Ports)
1754+
info := dto.ContainerInfo{
1755+
ContainerID: item.ID,
1756+
CreateTime: time.Unix(item.Created, 0).Format(constant.DateTimeLayout),
1757+
Name: item.Names[0][1:],
1758+
Ports: exposePorts,
1759+
ImageId: strings.Split(item.ImageID, ":")[1],
1760+
ImageName: item.Image,
1761+
State: item.State,
1762+
RunTime: item.Status,
1763+
SizeRw: item.SizeRw,
1764+
SizeRootFs: item.SizeRootFs,
1765+
IsFromApp: IsFromApp,
1766+
IsFromCompose: IsFromCompose,
1767+
}
1768+
if item.NetworkSettings != nil && len(item.NetworkSettings.Networks) > 0 {
1769+
networks := make([]string, 0, len(item.NetworkSettings.Networks))
1770+
for key := range item.NetworkSettings.Networks {
1771+
networks = append(networks, item.NetworkSettings.Networks[key].IPAddress)
1772+
}
1773+
sort.Strings(networks)
1774+
info.Network = networks
1775+
}
1776+
records = append(records, info)
1777+
}
1778+
dscriptions, _ := settingRepo.GetDescriptionList(repo.WithByType("container"))
1779+
for i := 0; i < len(records); i++ {
1780+
for _, desc := range dscriptions {
1781+
if desc.ID == records[i].ContainerID {
1782+
records[i].Description = desc.Description
1783+
records[i].IsPinned = desc.IsPinned
1784+
}
1785+
}
1786+
}
1787+
sort.Slice(records, func(i, j int) bool {
1788+
if records[i].IsPinned == records[j].IsPinned {
1789+
return list[i].Created > list[j].Created
1790+
}
1791+
return records[i].IsPinned
1792+
})
1793+
return records
1794+
}

0 commit comments

Comments
 (0)