-
Notifications
You must be signed in to change notification settings - Fork 3.2k
fix: Cancel synchronization between recommended nodes on dashboard #8270
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -9,12 +9,10 @@ type LauncherRepo struct{} | |
|
|
||
| type ILauncherRepo interface { | ||
| Get(opts ...DBOption) (model.AppLauncher, error) | ||
| List(opts ...DBOption) ([]model.AppLauncher, error) | ||
| ListName(opts ...DBOption) ([]string, error) | ||
| Create(launcher *model.AppLauncher) error | ||
| Save(launcher *model.AppLauncher) error | ||
| Delete(opts ...DBOption) error | ||
|
|
||
| SyncAll(data []model.AppLauncher) error | ||
| } | ||
|
|
||
| func NewILauncherRepo() ILauncherRepo { | ||
|
|
@@ -30,14 +28,18 @@ func (u *LauncherRepo) Get(opts ...DBOption) (model.AppLauncher, error) { | |
| err := db.First(&launcher).Error | ||
| return launcher, err | ||
| } | ||
| func (u *LauncherRepo) List(opts ...DBOption) ([]model.AppLauncher, error) { | ||
| func (u *LauncherRepo) ListName(opts ...DBOption) ([]string, error) { | ||
| var ops []model.AppLauncher | ||
| db := global.DB.Model(&model.AppLauncher{}) | ||
| for _, opt := range opts { | ||
| db = opt(db) | ||
| } | ||
| err := db.Find(&ops).Error | ||
| return ops, err | ||
| _ = db.Find(&ops).Error | ||
| var names []string | ||
| for i := 0; i < len(ops); i++ { | ||
| names = append(names, ops[i].Key) | ||
| } | ||
| return names, nil | ||
| } | ||
|
|
||
| func (u *LauncherRepo) Create(launcher *model.AppLauncher) error { | ||
|
|
@@ -55,21 +57,3 @@ func (u *LauncherRepo) Delete(opts ...DBOption) error { | |
| } | ||
| return db.Delete(&model.AppLauncher{}).Error | ||
| } | ||
|
|
||
| func (u *LauncherRepo) SyncAll(data []model.AppLauncher) error { | ||
| tx := global.DB.Begin() | ||
| if err := tx.Where("1 = 1").Delete(&model.AppLauncher{}).Error; err != nil { | ||
| tx.Rollback() | ||
| return err | ||
| } | ||
| if len(data) == 0 { | ||
| tx.Commit() | ||
| return nil | ||
| } | ||
| if err := tx.Model(model.AppLauncher{}).Save(&data).Error; err != nil { | ||
| tx.Rollback() | ||
| return err | ||
| } | ||
| tx.Commit() | ||
| return nil | ||
| } | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There are no major discrepancies between the new version of The most significant modification is within Here's the corrected code: func (u *LauncherRepo) ListName(opts ...DBOption) ([]string, error) {
var ops []model.AppLauncher
db := global.DB.Model(&model.AppLauncher{})
for _, opt := range opts {
db = opt(db)
}
err := db.Find(&ops).Error // Assuming you want to find only one record per launch key, but since there might be duplicates, we'll use Find instead.
if err != nil {
return nil, err
}
var names []string
for _, launcher := range ops { // Iterate over the resulting collection
names = append(names, launcher.Key)
}
return names, nil
}Potential Improvements:
Overall, the provided changes seem correct for retrieving unique launch keys from the database while maintaining backward compatibility for existing clients expecting slices in
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The revised code appears to address several key improvements:
These changes improve the readability, conciseness, and maintainability of the code while ensuring it still fulfills its original intended functions correctly. |
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -13,6 +13,7 @@ import ( | |
|
|
||
| "github.com/1Panel-dev/1Panel/agent/app/dto" | ||
| "github.com/1Panel-dev/1Panel/agent/app/model" | ||
| "github.com/1Panel-dev/1Panel/agent/app/repo" | ||
| "github.com/1Panel-dev/1Panel/agent/constant" | ||
| "github.com/1Panel-dev/1Panel/agent/global" | ||
| "github.com/1Panel-dev/1Panel/agent/utils/ai_tools/gpu" | ||
|
|
@@ -31,14 +32,13 @@ import ( | |
| type DashboardService struct{} | ||
|
|
||
| type IDashboardService interface { | ||
| Sync(req dto.AppLauncherSync) error | ||
|
|
||
| LoadOsInfo() (*dto.OsInfo, error) | ||
| LoadBaseInfo(ioOption string, netOption string) (*dto.DashboardBase, error) | ||
| LoadCurrentInfoForNode() *dto.NodeCurrent | ||
| LoadCurrentInfo(ioOption string, netOption string) *dto.DashboardCurrent | ||
|
|
||
| LoadAppLauncher() ([]dto.AppLauncher, error) | ||
| ChangeShow(req dto.SettingUpdate) error | ||
| ListLauncherOption(filter string) ([]dto.LauncherOption, error) | ||
| Restart(operation string) error | ||
| } | ||
|
|
@@ -47,14 +47,6 @@ func NewIDashboardService() IDashboardService { | |
| return &DashboardService{} | ||
| } | ||
|
|
||
| func (u *DashboardService) Sync(req dto.AppLauncherSync) error { | ||
| var launchers []model.AppLauncher | ||
| for _, item := range req.Keys { | ||
| launchers = append(launchers, model.AppLauncher{Key: item}) | ||
| } | ||
| return launcherRepo.SyncAll(launchers) | ||
| } | ||
|
|
||
| func (u *DashboardService) Restart(operation string) error { | ||
| if operation != "1panel" && operation != "system" && operation != "1panel-agent" { | ||
| return fmt.Errorf("handle restart operation %s failed, err: nonsupport such operation", operation) | ||
|
|
@@ -285,7 +277,7 @@ func (u *DashboardService) LoadAppLauncher() ([]dto.AppLauncher, error) { | |
| return data, err | ||
| } | ||
|
|
||
| showList := loadShowList() | ||
| showList, _ := launcherRepo.ListName() | ||
| defaultList := []string{"openresty", "mysql", "halo", "redis", "maxkb", "wordpress"} | ||
| allList := common.RemoveRepeatStr(append(defaultList, showList...)) | ||
| for _, showItem := range allList { | ||
|
|
@@ -343,8 +335,23 @@ func (u *DashboardService) LoadAppLauncher() ([]dto.AppLauncher, error) { | |
| return data, nil | ||
| } | ||
|
|
||
| func (u *DashboardService) ChangeShow(req dto.SettingUpdate) error { | ||
| launcher, _ := launcherRepo.Get(repo.WithByKey(req.Key)) | ||
| if req.Value == constant.StatusEnable && launcher.ID == 0 { | ||
| if err := launcherRepo.Create(&model.AppLauncher{Key: req.Key}); err != nil { | ||
| return err | ||
| } | ||
| } | ||
| if req.Value == constant.StatusDisable && launcher.ID != 0 { | ||
| if err := launcherRepo.Delete(repo.WithByKey(req.Key)); err != nil { | ||
| return err | ||
| } | ||
| } | ||
| return nil | ||
| } | ||
|
|
||
| func (u *DashboardService) ListLauncherOption(filter string) ([]dto.LauncherOption, error) { | ||
| showList := loadShowList() | ||
| showList, _ := launcherRepo.ListName() | ||
| var data []dto.LauncherOption | ||
| optionMap := make(map[string]bool) | ||
| appInstalls, err := appInstallRepo.ListBy(context.Background()) | ||
|
|
@@ -500,25 +507,6 @@ func loadGPUInfo() []dto.GPUInfo { | |
| return data | ||
| } | ||
|
|
||
| func loadShowList() []string { | ||
| var data []string | ||
| if global.IsMaster { | ||
| var list []AppLauncher | ||
| if err := global.CoreDB.Model(AppLauncher{}).Where("1 == 1").Find(&list).Error; err != nil { | ||
| return []string{} | ||
| } | ||
| for _, item := range list { | ||
| data = append(data, item.Key) | ||
| } | ||
| return data | ||
| } | ||
| list, _ := launcherRepo.List() | ||
| for _, item := range list { | ||
| data = append(data, item.Key) | ||
| } | ||
| return data | ||
| } | ||
|
|
||
| type AppLauncher struct { | ||
| Key string `json:"key"` | ||
| } | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There are a few minor changes and improvements that can be made:
These points suggest areas where optimizations and better organization could lead to cleaner, more efficient, and easier-to-maintain code.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The provided code has a couple of issues and can be optimized slightly: Issues
Here's revised version with these improvements: type DashboardService struct{}
type IDashboardService interface {
Sync(req dto.AppLauncherSync) error
LoadOsInfo() (*dto.OsInfo, error)
LoadBaseInfo(ioOption string, netOption string) (*dto.DashboardBase, error)
LoadCurrentInfoForNode() *dto.NodeCurrent
LoadCurrentInfo(ioOption string, netOption string) *dto.DashboardCurrent
LoadAppLauncher() ([]dto.AppLauncher, error)
ChangeShow(req dto.SettingUpdate) error
ListLauncherOption(filter string) ([]dto.LauncherOption, error)
Restart(operation string) error
}
func NewIDashboardService() IDashboardService {
return &DashboardService{}
}
const StatusEnable = "enable"
const StatusDisable = "disable"
func (u *DashboardService) Sync(req dto.AppLauncherSync) error {
var launchers []model.AppLauncher
for _, item := range req.Keys {
appLaunchers := []model.AppLauncher{{Key: item}}
err := launcherRepo.SyncAll(appLaunchers)
if err != nil {
return err
}
}
return nil
}
func (u *DashboardService) LoadAppLauncher() ([]dto.AppLauncher, error) {
showList, _ := launcherRepo.ListName()
defaultList := []string{"openresty", "mysql", "halo", "redis", "maxkb", "wordpress"}
allList := common.RemoveRepeatStr(append(defaultList, showList...))
currentApps := make(map[string]bool)
for _, la := range appInstallRepo.ListBy(context.Background()) {
currentApps[la.Key] = true // Map existing apps to keep track
}
var data []dto.AppLauncher
for _, showItem := range allList {
item := model.AppLauncher{Key:showItem}
isEnabled := currentApps[item.Key]
data = append(data, dto.AppLauncher{
Key: item.Key,
IsEnable: isEnabled,
})
}
return data, nil
}
...This revision fixes the logic for loading applications and ensures proper error handling within the
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The code differences you’ve described involve several minor refactorings and additions to improve functionality: Refactorings
Potentially Improper Behavior
Optimization Suggestions
Based on these points, here’s a cleaner version of the code: import (
"context"
"github.com/1Panel-dev/1Panel/agent/app/model"
repof "github.com/1Panel-dev/1Panel/agent/app/repo"
)
type DashboardService struct{}
type IDashboardService interface {
Sync(req dto.AppLauncherSync) error
LoadOsInfo() (*dto.OsInfo, error)
LoadBaseInfo(ioOption string, netOption string) (*dto.DashboardBase, error)
LoadCurrentInfoForNode() *dto.NodeCurrent
LoadCurrentInfo(ioOption string, netOption string) *dto.DashboardCurrent
LoadAppLauncher() ([]dto.AppLauncher, error)
ChangeShow(req dto.SettingUpdate) error
ListLauncherOption(filter string) ([]dto.LauncherOption, error)
Restart(operation string) error
}
func NewIDashboardService() IDashboardService {
return &DashboardService{}
}
func (u *DashboardService) Restart(operation string) error {
switch operation {
case "1panel", "system", "1panel-agent":
default:
return fmt.Errorf("handle restart operation %s failed, err: nonsupport such operation", operation)
}
return nil
}
func (u *DashboardService) LoadAppLauncher() ([]dto.AppLauncher, error) {
var data []dto.AppLauncher
launchers, err := repo.ListApps()
if err != nil {
return data, err
}
showList, _ := repo.ListLaunchNames()
defaultList := []string{"openresty", "mysql", "halo", "redis", "maxkb", "wordpress"}
allList := common.RemoveRepeatStr(append(defaultList, showList...))
for _, showItem := range allList {
if !common.InStringArr(showItem, launchers) {
continue
}
data = append(data, dto.AppLauncher { Key: showItem })
}
return data, nil
}Ensure that the |
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -60,15 +60,23 @@ func (u *DeviceService) Scan() dto.CleanData { | |
|
|
||
| upgradePath := path.Join(global.Dir.BaseDir, upgradePath) | ||
| upgradeSize, _ := fileOp.GetDirSize(upgradePath) | ||
| treeData = append(treeData, dto.CleanTree{ | ||
| upgradeTree := dto.CleanTree{ | ||
| ID: uuid.NewString(), | ||
| Label: "upgrade", | ||
| Size: uint64(upgradeSize), | ||
| IsCheck: false, | ||
| IsRecommend: true, | ||
| Type: "upgrade", | ||
| Children: loadTreeWithDir(true, "upgrade", upgradePath, fileOp), | ||
| }) | ||
| } | ||
| if len(upgradeTree.Children) != 0 { | ||
| sort.Slice(upgradeTree.Children, func(i, j int) bool { | ||
| return common.CompareVersion(upgradeTree.Children[i].Label, upgradeTree.Children[j].Label) | ||
| }) | ||
| upgradeTree.Children[0].IsCheck = false | ||
| upgradeTree.Children[0].IsRecommend = false | ||
| } | ||
| treeData = append(treeData, upgradeTree) | ||
|
|
||
| snapTree := loadSnapshotTree(fileOp) | ||
| snapSize := uint64(0) | ||
|
|
@@ -563,11 +571,6 @@ func loadTreeWithDir(isCheck bool, treeType, pathItem string, fileOp fileUtils.F | |
| if err != nil { | ||
| return lists | ||
| } | ||
| sort.Slice(files, func(i, j int) bool { | ||
| infoI, _ := files[i].Info() | ||
| infoJ, _ := files[i].Info() | ||
| return infoI.ModTime().Before(infoJ.ModTime()) | ||
| }) | ||
| for _, file := range files { | ||
| if treeType == "old_upgrade" { | ||
| continue | ||
|
|
@@ -589,10 +592,6 @@ func loadTreeWithDir(isCheck bool, treeType, pathItem string, fileOp fileUtils.F | |
| IsCheck: isCheck, | ||
| IsRecommend: isCheck, | ||
| } | ||
| if treeType == "upgrade" && len(lists) == 0 { | ||
| item.IsCheck = false | ||
| item.IsRecommend = false | ||
| } | ||
| lists = append(lists, item) | ||
| } | ||
| } | ||
|
|
@@ -742,3 +741,31 @@ func scanFile(pathItem string, size *int64, count *int) { | |
| } | ||
| } | ||
| } | ||
|
|
||
| func loadRestorePath(upgradeDir string) (string, error) { | ||
| if _, err := os.Stat(upgradeDir); err != nil && os.IsNotExist(err) { | ||
| return "no such file", nil | ||
| } | ||
| files, err := os.ReadDir(upgradeDir) | ||
| if err != nil { | ||
| return "", err | ||
| } | ||
| type itemState struct { | ||
| Name string | ||
| CreateAt time.Time | ||
| } | ||
| var folders []itemState | ||
| for _, file := range files { | ||
| if file.IsDir() { | ||
| info, _ := file.Info() | ||
| folders = append(folders, itemState{Name: file.Name(), CreateAt: info.ModTime()}) | ||
| } | ||
| } | ||
| if len(folders) == 0 { | ||
| return "no such file", nil | ||
| } | ||
| sort.Slice(folders, func(i, j int) bool { | ||
| return folders[i].CreateAt.After(folders[j].CreateAt) | ||
| }) | ||
| return folders[0].Name, nil | ||
| } | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The provided code has several improvements and corrections to address potential issues:
Overall, these changes help make the code more robust and maintainable while ensuring correct functionality and adherence to best practices.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, there are several irregularities, potential issues, and optimization suggestions for the provided code:
Here's the updated code snippet addressing these points: func loadTreeWithDir(isCheck bool, treeType, pathItem string, fileOp fileUtils.FileUtils) ([]dto.CleanTree, error) {
var lists []dto.CleanTree
files, err := io.ReadFile(pathItem)
if err != nil {
return nil, fmt.Errorf("error reading directory '%s': %w", pathItem, err)
}
for _, fileInfo := range dir.Files() {
item := dto.CleanTree{
ID: uuid.NewString(),
Label: fileInfo.Name(),
Size: uint64(fileInfo.Size()),
IsCheck: false,
IsRecommend: isCheck,
Type: treeType,
// Assuming children can be loaded here based on file info.
}
lists = append(lists, item)
}
sort.Slice(lists, func(i, j int) bool {
switch treeType {
case "old_upgrade":
finfoI, _ := listItem[i].FileInfo()
finfoJ, _ := listItem[j].FileInfo()
return finfoI.ModTime().After(finfoJ.ModTime())
default:
return len(list[i]) < len(list[j])
}
})
for i := range lists {
if !common.IsValidFileType(listItems[i].Label) || (!listItems[i].IsValid && common.ValidFileSizeRange(listItems[i]), err != nil {
log.Printf("Invalid file type or size for label %q: %v\n", listItems[i].label, err)
continue
}
listItems[i].Valid = true
count++
totalSize += listItems[i].size
// Load nested children based on file data.
nestedItems, err := fileList(dir, item.type_, &listOptions{Recursive: true})
if err != nil {
logger.Println("Failed to load nested items:", err)
} else {
listItems[i].children = nestedItems[:]
}
}
return totalSizeList(items), nil
}Key Changes:
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There are several code improvements and optimizations I can suggest:
Here's the updated code with these suggestions: @@ -60,17 +60,25 @@ func (u *DeviceService) Scan() dto.CleanData {
upgradePath := path.Join(global.Dir.BaseDir, upgradePath)
upgradeSize, _ := fileOp.GetDirSize(upgradePath)
- treeData = append(treeData, dto.CleanTree{
+ upgradeTree := dto.CleanTree{
ID: uuid.NewString(),
Label: "upgrade",
Size: uint64(upgradeSize),
IsCheck: false,
IsRecommend: len(upgradeTree.Children) > 0,
Type: "upgrade",
Children: loadTreeWithDir(true, "upgrade", upgradePath, fileOp),
- })
+ }
+ sort.SliceStable(upgradeTree.Children, func(i, j int) bool {
+ return common.CompareVersion(upgradeTree.Children[i].Label, upgradeTree.Children[j].Label)
+ })
+
snapTree := loadSnapshotTree(fileOp)
snapSize := uint64(0)
@@ -594,10 +602,5 @@ func loadTreeWithDir(isCheck bool, treeType, pathItem string, fileOp fileUtils.F
for _, file := range files {
if treeType == "old_upgrade" {
continue
@@ -597,27 +605,14 @@ func loadTreeWithDir(isCheck bool, treeType, pathItem string, fileOp fileUtils.F
Label: "",
@@ -621,8 +617,6 @@ func loadRestorePath(upgradeDir string) (string, error) {
files, err := os.ReadDir(upgradeDir)
if err != nil {
return "", err
- }
-
- type itemState struct {
- Name string
- CreateAt time.Time
- }
- var folders []itemState
- for _, file := range files {
- if file.IsDir() {
- info, _ := file.Info()
- folders = append(folders, itemState{Name: file.Name(), CreateAt: info.ModTime()})
- }
}
+ if len(files) == 0 {
+ return "no such file", nil
+ }
sort.Slice(files, func(i, j int) bool {
@@ -639,7 +643,7 @@ func scanFile(pathItem string, size *int64, count *int) {
}
}Key Changes:
|
||
This file was deleted.
This file was deleted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The main changes are:
Method Names:
Listmethod has been changed toListName.SyncAllmethod has been removed.Database Operations:
ListNamemethod, the database query is still performed but only app keys are collected into a slice of strings.Transaction Changes:
SyncAllfunction was used to clear existing records before inserting new data.Savemethod in place when updating or deleting records directly with the same key.Suggestions
Performance:
Code Maintainability:
Consistency:
Get,ListName,Create,Save, andDelete.Testing Requirements:
SyncAllmethod, especially integration tests where this operation might be important.These points should help maintain clarity and efficiency while improving the architecture of your API.