diff --git a/app/console/commands/panel.go b/app/console/commands/panel.go index 841956ac..352e5d2e 100644 --- a/app/console/commands/panel.go +++ b/app/console/commands/panel.go @@ -17,6 +17,7 @@ import ( "github.com/TheTNB/panel/app/models" "github.com/TheTNB/panel/internal/services" + "github.com/TheTNB/panel/pkg/io" "github.com/TheTNB/panel/pkg/shell" "github.com/TheTNB/panel/pkg/systemctl" "github.com/TheTNB/panel/pkg/tools" @@ -272,8 +273,8 @@ func (receiver *Panel) Handle(ctx console.Context) error { color.Green().Printfln("★ " + translate.Get("commands.panel.backup.start") + " [" + carbon.Now().ToDateTimeString() + "]") color.Green().Printfln(hr) - if !tools.Exists(path) { - if err := tools.Mkdir(path, 0644); err != nil { + if !io.Exists(path) { + if err := io.Mkdir(path, 0644); err != nil { color.Red().Printfln("|-" + translate.Get("commands.panel.backup.backupDirFail") + ": " + err.Error()) return nil } @@ -319,13 +320,13 @@ func (receiver *Panel) Handle(ctx console.Context) error { color.Red().Printfln("|-" + translate.Get("commands.panel.backup.compressFail") + ": " + err.Error()) return nil } - if err := tools.Remove("/tmp/" + backupFile); err != nil { + if err := io.Remove("/tmp/" + backupFile); err != nil { color.Red().Printfln("|-" + translate.Get("commands.panel.backup.deleteFail") + ": " + err.Error()) return nil } color.Green().Printfln("|-" + translate.Get("commands.panel.backup.compressSuccess")) color.Green().Printfln("|-" + translate.Get("commands.panel.backup.startMove")) - if err := tools.Mv("/tmp/"+backupFile+".zip", path+"/"+backupFile+".zip"); err != nil { + if err := io.Mv("/tmp/"+backupFile+".zip", path+"/"+backupFile+".zip"); err != nil { color.Red().Printfln("|-" + translate.Get("commands.panel.backup.moveFail") + ": " + err.Error()) return nil } @@ -359,13 +360,13 @@ func (receiver *Panel) Handle(ctx console.Context) error { color.Red().Printfln("|-" + translate.Get("commands.panel.backup.compressFail") + ": " + err.Error()) return nil } - if err := tools.Remove("/tmp/" + backupFile); err != nil { + if err := io.Remove("/tmp/" + backupFile); err != nil { color.Red().Printfln("|-" + translate.Get("commands.panel.backup.deleteFail") + ": " + err.Error()) return nil } color.Green().Printfln("|-" + translate.Get("commands.panel.backup.compressSuccess")) color.Green().Printfln("|-" + translate.Get("commands.panel.backup.startMove")) - if err := tools.Mv("/tmp/"+backupFile+".zip", path+"/"+backupFile+".zip"); err != nil { + if err := io.Mv("/tmp/"+backupFile+".zip", path+"/"+backupFile+".zip"); err != nil { color.Red().Printfln("|-" + translate.Get("commands.panel.backup.moveFail") + ": " + err.Error()) return nil } @@ -395,7 +396,7 @@ func (receiver *Panel) Handle(ctx console.Context) error { for i := cast.ToInt(save); i < len(filteredFiles); i++ { fileToDelete := filepath.Join(path, filteredFiles[i].Name()) color.Yellow().Printfln("|-" + translate.Get("commands.panel.backup.cleanBackup") + ": " + fileToDelete) - if err := tools.Remove(fileToDelete); err != nil { + if err := io.Remove(fileToDelete); err != nil { color.Red().Printfln("|-" + translate.Get("commands.panel.backup.cleanupFail") + ": " + err.Error()) return nil } @@ -427,7 +428,7 @@ func (receiver *Panel) Handle(ctx console.Context) error { } logPath := "/www/wwwlogs/" + website.Name + ".log" - if !tools.Exists(logPath) { + if !io.Exists(logPath) { color.Red().Printfln("|-" + translate.Get("commands.panel.cutoff.logNotExist")) color.Green().Printfln(hr) return nil @@ -466,7 +467,7 @@ func (receiver *Panel) Handle(ctx console.Context) error { for i := cast.ToInt(save); i < len(filteredFiles); i++ { fileToDelete := filepath.Join("/www/wwwlogs", filteredFiles[i].Name()) color.Yellow().Printfln("|-" + translate.Get("commands.panel.cutoff.clearLog") + ": " + fileToDelete) - if err := tools.Remove(fileToDelete); err != nil { + if err := io.Remove(fileToDelete); err != nil { color.Red().Printfln("|-" + translate.Get("commands.panel.cutoff.cleanupFail") + ": " + err.Error()) return nil } diff --git a/app/console/commands/panel_task.go b/app/console/commands/panel_task.go index 5c682fbd..0a9492c3 100644 --- a/app/console/commands/panel_task.go +++ b/app/console/commands/panel_task.go @@ -8,8 +8,8 @@ import ( "github.com/goravel/framework/facades" "github.com/goravel/framework/support/carbon" + "github.com/TheTNB/panel/pkg/io" "github.com/TheTNB/panel/pkg/shell" - "github.com/TheTNB/panel/pkg/tools" "github.com/TheTNB/panel/types" ) @@ -49,7 +49,7 @@ func (receiver *PanelTask) Handle(console.Context) error { } // 备份面板 - if err := tools.Archive([]string{"/www/panel"}, "/www/backup/panel/panel-"+carbon.Now().ToShortDateTimeString()+".zip"); err != nil { + if err := io.Archive([]string{"/www/panel"}, "/www/backup/panel/panel-"+carbon.Now().ToShortDateTimeString()+".zip"); err != nil { types.Status = types.StatusFailed facades.Log().Tags("面板", "每日任务"). With(map[string]any{ diff --git a/app/http/controllers/asset_controller.go b/app/http/controllers/asset_controller.go index e52088f1..946d2a20 100644 --- a/app/http/controllers/asset_controller.go +++ b/app/http/controllers/asset_controller.go @@ -9,7 +9,7 @@ import ( "github.com/TheTNB/panel/internal" "github.com/TheTNB/panel/internal/services" - "github.com/TheTNB/panel/pkg/tools" + "github.com/TheTNB/panel/pkg/io" ) type AssetController struct { @@ -43,7 +43,7 @@ func (r *AssetController) Index(ctx http.Context) http.Response { path = "/index.html" } - if !tools.Exists("public" + path) { + if !io.Exists("public" + path) { return Error(ctx, http.StatusNotFound, http.StatusText(http.StatusNotFound)) } diff --git a/app/http/controllers/cron_controller.go b/app/http/controllers/cron_controller.go index 2946c5b2..cc2dfe1e 100644 --- a/app/http/controllers/cron_controller.go +++ b/app/http/controllers/cron_controller.go @@ -12,6 +12,7 @@ import ( "github.com/TheTNB/panel/app/models" "github.com/TheTNB/panel/internal" "github.com/TheTNB/panel/internal/services" + "github.com/TheTNB/panel/pkg/io" "github.com/TheTNB/panel/pkg/shell" "github.com/TheTNB/panel/pkg/tools" ) @@ -111,14 +112,14 @@ panel cutoff ${name} ${save} 2>&1 shellDir := "/www/server/cron/" shellLogDir := "/www/server/cron/logs/" - if !tools.Exists(shellDir) { + if !io.Exists(shellDir) { return Error(ctx, http.StatusInternalServerError, "计划任务目录不存在") } - if !tools.Exists(shellLogDir) { + if !io.Exists(shellLogDir) { return Error(ctx, http.StatusInternalServerError, "计划任务日志目录不存在") } shellFile := strconv.Itoa(int(carbon.Now().Timestamp())) + tools.RandomString(16) - if err := tools.Write(shellDir+shellFile+".sh", script, 0700); err != nil { + if err := io.Write(shellDir+shellFile+".sh", script, 0700); err != nil { return Error(ctx, http.StatusInternalServerError, err.Error()) } if out, err := shell.Execf("dos2unix " + shellDir + shellFile + ".sh"); err != nil { @@ -157,7 +158,7 @@ func (r *CronController) Script(ctx http.Context) http.Response { return Error(ctx, http.StatusUnprocessableEntity, "计划任务不存在") } - script, err := tools.Read(cron.Shell) + script, err := io.Read(cron.Shell) if err != nil { return Error(ctx, http.StatusInternalServerError, err.Error()) } @@ -198,7 +199,7 @@ func (r *CronController) Update(ctx http.Context) http.Response { return ErrorSystem(ctx) } - if err := tools.Write(cron.Shell, ctx.Request().Input("script"), 0644); err != nil { + if err := io.Write(cron.Shell, ctx.Request().Input("script"), 0644); err != nil { return Error(ctx, http.StatusInternalServerError, err.Error()) } if out, err := shell.Execf("dos2unix " + cron.Shell); err != nil { @@ -227,7 +228,7 @@ func (r *CronController) Delete(ctx http.Context) http.Response { if err := r.cron.DeleteFromSystem(cron); err != nil { return Error(ctx, http.StatusInternalServerError, err.Error()) } - if err := tools.Remove(cron.Shell); err != nil { + if err := io.Remove(cron.Shell); err != nil { return Error(ctx, http.StatusInternalServerError, err.Error()) } @@ -281,7 +282,7 @@ func (r *CronController) Log(ctx http.Context) http.Response { return Error(ctx, http.StatusUnprocessableEntity, "计划任务不存在") } - if !tools.Exists(cron.Log) { + if !io.Exists(cron.Log) { return Error(ctx, http.StatusUnprocessableEntity, "日志文件不存在") } diff --git a/app/http/controllers/file_controller.go b/app/http/controllers/file_controller.go index 65cf0349..6a65aafc 100644 --- a/app/http/controllers/file_controller.go +++ b/app/http/controllers/file_controller.go @@ -2,7 +2,7 @@ package controllers import ( "fmt" - "io" + stdio "io" "os" "path/filepath" "strings" @@ -12,6 +12,7 @@ import ( "github.com/goravel/framework/support/carbon" requests "github.com/TheTNB/panel/app/http/requests/file" + "github.com/TheTNB/panel/pkg/io" "github.com/TheTNB/panel/pkg/shell" "github.com/TheTNB/panel/pkg/tools" ) @@ -47,7 +48,7 @@ func (r *FileController) Create(ctx http.Context) http.Response { return Error(ctx, http.StatusInternalServerError, out) } } else { - if err := tools.Mkdir(request.Path, 0755); err != nil { + if err := io.Mkdir(request.Path, 0755); err != nil { return Error(ctx, http.StatusInternalServerError, err.Error()) } } @@ -74,7 +75,7 @@ func (r *FileController) Content(ctx http.Context) http.Response { return sanitize } - fileInfo, err := tools.FileInfo(request.Path) + fileInfo, err := io.FileInfo(request.Path) if err != nil { return Error(ctx, http.StatusInternalServerError, err.Error()) } @@ -85,7 +86,7 @@ func (r *FileController) Content(ctx http.Context) http.Response { return Error(ctx, http.StatusInternalServerError, "文件大小超过 10 M,不支持在线编辑") } - content, err := tools.Read(request.Path) + content, err := io.Read(request.Path) if err != nil { return Error(ctx, http.StatusInternalServerError, err.Error()) } @@ -111,11 +112,11 @@ func (r *FileController) Save(ctx http.Context) http.Response { return sanitize } - fileInfo, err := tools.FileInfo(request.Path) + fileInfo, err := io.FileInfo(request.Path) if err != nil { return Error(ctx, http.StatusInternalServerError, err.Error()) } - if err = tools.Write(request.Path, request.Content, fileInfo.Mode()); err != nil { + if err = io.Write(request.Path, request.Content, fileInfo.Mode()); err != nil { return Error(ctx, http.StatusInternalServerError, err.Error()) } @@ -141,7 +142,7 @@ func (r *FileController) Delete(ctx http.Context) http.Response { return sanitize } - if err := tools.Remove(request.Path); err != nil { + if err := io.Remove(request.Path); err != nil { return Error(ctx, http.StatusInternalServerError, err.Error()) } @@ -173,16 +174,16 @@ func (r *FileController) Upload(ctx http.Context) http.Response { } defer src.Close() - if tools.Exists(request.Path) && !ctx.Request().InputBool("force") { + if io.Exists(request.Path) && !ctx.Request().InputBool("force") { return Error(ctx, http.StatusForbidden, "目标路径已存在,是否覆盖?") } - data, err := io.ReadAll(src) + data, err := stdio.ReadAll(src) if err != nil { return Error(ctx, http.StatusInternalServerError, err.Error()) } - if err = tools.Write(request.Path, string(data), 0755); err != nil { + if err = io.Write(request.Path, string(data), 0755); err != nil { return Error(ctx, http.StatusInternalServerError, err.Error()) } @@ -208,11 +209,11 @@ func (r *FileController) Move(ctx http.Context) http.Response { return sanitize } - if tools.Exists(request.Target) && !ctx.Request().InputBool("force") { + if io.Exists(request.Target) && !ctx.Request().InputBool("force") { return Error(ctx, http.StatusForbidden, "目标路径"+request.Target+"已存在") } - if err := tools.Mv(request.Source, request.Target); err != nil { + if err := io.Mv(request.Source, request.Target); err != nil { return Error(ctx, http.StatusInternalServerError, err.Error()) } @@ -238,11 +239,11 @@ func (r *FileController) Copy(ctx http.Context) http.Response { return sanitize } - if tools.Exists(request.Target) && !ctx.Request().InputBool("force") { + if io.Exists(request.Target) && !ctx.Request().InputBool("force") { return Error(ctx, http.StatusForbidden, "目标路径"+request.Target+"已存在") } - if err := tools.Cp(request.Source, request.Target); err != nil { + if err := io.Cp(request.Source, request.Target); err != nil { return Error(ctx, http.StatusInternalServerError, err.Error()) } @@ -268,7 +269,7 @@ func (r *FileController) Download(ctx http.Context) http.Response { return sanitize } - info, err := tools.FileInfo(request.Path) + info, err := io.FileInfo(request.Path) if err != nil { return Error(ctx, http.StatusInternalServerError, err.Error()) } @@ -319,7 +320,7 @@ func (r *FileController) Info(ctx http.Context) http.Response { return sanitize } - fileInfo, err := tools.FileInfo(request.Path) + fileInfo, err := io.FileInfo(request.Path) if err != nil { return Error(ctx, http.StatusInternalServerError, err.Error()) } @@ -352,10 +353,10 @@ func (r *FileController) Permission(ctx http.Context) http.Response { return sanitize } - if err := tools.Chmod(request.Path, os.FileMode(request.Mode)); err != nil { + if err := io.Chmod(request.Path, os.FileMode(request.Mode)); err != nil { return Error(ctx, http.StatusInternalServerError, err.Error()) } - if err := tools.Chown(request.Path, request.Owner, request.Group); err != nil { + if err := io.Chown(request.Path, request.Owner, request.Group); err != nil { return Error(ctx, http.StatusInternalServerError, err.Error()) } @@ -380,7 +381,7 @@ func (r *FileController) Archive(ctx http.Context) http.Response { return sanitize } - if err := tools.Archive(request.Paths, request.File); err != nil { + if err := io.Archive(request.Paths, request.File); err != nil { return Error(ctx, http.StatusInternalServerError, err.Error()) } @@ -406,7 +407,7 @@ func (r *FileController) UnArchive(ctx http.Context) http.Response { return sanitize } - if err := tools.UnArchive(request.File, request.Path); err != nil { + if err := io.UnArchive(request.File, request.Path); err != nil { return Error(ctx, http.StatusInternalServerError, err.Error()) } @@ -486,9 +487,9 @@ func (r *FileController) List(ctx http.Context) http.Response { "group": tools.GetGroup(stat.Gid), "uid": stat.Uid, "gid": stat.Gid, - "hidden": tools.IsHidden(info.Name()), - "symlink": tools.IsSymlink(info.Mode()), - "link": tools.GetSymlink(filepath.Join(request.Path, info.Name())), + "hidden": io.IsHidden(info.Name()), + "symlink": io.IsSymlink(info.Mode()), + "link": io.GetSymlink(filepath.Join(request.Path, info.Name())), "dir": info.IsDir(), "modify": carbon.FromStdTime(info.ModTime()).ToDateTimeString(), }) @@ -504,6 +505,6 @@ func (r *FileController) List(ctx http.Context) http.Response { // setPermission func (r *FileController) setPermission(path string, mode uint, owner, group string) { - _ = tools.Chmod(path, os.FileMode(mode)) - _ = tools.Chown(path, owner, group) + _ = io.Chmod(path, os.FileMode(mode)) + _ = io.Chown(path, owner, group) } diff --git a/app/http/controllers/plugins/fail2ban_controller.go b/app/http/controllers/plugins/fail2ban_controller.go index 959ad5cd..4b674732 100644 --- a/app/http/controllers/plugins/fail2ban_controller.go +++ b/app/http/controllers/plugins/fail2ban_controller.go @@ -12,6 +12,7 @@ import ( "github.com/TheTNB/panel/app/models" "github.com/TheTNB/panel/internal" "github.com/TheTNB/panel/internal/services" + "github.com/TheTNB/panel/pkg/io" "github.com/TheTNB/panel/pkg/shell" "github.com/TheTNB/panel/pkg/tools" "github.com/TheTNB/panel/types" @@ -29,7 +30,7 @@ func NewFail2banController() *Fail2banController { // List 所有 Fail2ban 规则 func (r *Fail2banController) List(ctx http.Context) http.Response { - raw, err := tools.Read("/etc/fail2ban/jail.local") + raw, err := io.Read("/etc/fail2ban/jail.local") if err != nil { return controllers.Error(ctx, http.StatusUnprocessableEntity, err.Error()) } @@ -98,7 +99,7 @@ func (r *Fail2banController) Add(ctx http.Context) http.Response { jailWebsiteMode := ctx.Request().Input("website_mode") jailWebsitePath := ctx.Request().Input("website_path") - raw, err := tools.Read("/etc/fail2ban/jail.local") + raw, err := io.Read("/etc/fail2ban/jail.local") if err != nil { return controllers.Error(ctx, http.StatusUnprocessableEntity, err.Error()) } @@ -137,7 +138,7 @@ logpath = /www/wwwlogs/` + website.Name + `.log # ` + jailWebsiteName + `-` + jailWebsiteMode + `-END ` raw += rule - if err = tools.Write("/etc/fail2ban/jail.local", raw, 0644); err != nil { + if err = io.Write("/etc/fail2ban/jail.local", raw, 0644); err != nil { return controllers.Error(ctx, http.StatusInternalServerError, "写入Fail2ban规则失败") } @@ -155,7 +156,7 @@ failregex = ^\s-.*\s` + jailWebsitePath + `.*HTTP/.*$ ignoreregex = ` } - if err = tools.Write("/etc/fail2ban/filter.d/haozi-"+jailWebsiteName+"-"+jailWebsiteMode+".conf", filter, 0644); err != nil { + if err = io.Write("/etc/fail2ban/filter.d/haozi-"+jailWebsiteName+"-"+jailWebsiteMode+".conf", filter, 0644); err != nil { return controllers.Error(ctx, http.StatusInternalServerError, "写入Fail2ban规则失败") } @@ -202,7 +203,7 @@ logpath = ` + logPath + ` # ` + jailName + `-END ` raw += rule - if err := tools.Write("/etc/fail2ban/jail.local", raw, 0644); err != nil { + if err := io.Write("/etc/fail2ban/jail.local", raw, 0644); err != nil { return controllers.Error(ctx, http.StatusInternalServerError, "写入Fail2ban规则失败") } } @@ -217,7 +218,7 @@ logpath = ` + logPath + ` // Delete 删除规则 func (r *Fail2banController) Delete(ctx http.Context) http.Response { jailName := ctx.Request().Input("name") - raw, err := tools.Read("/etc/fail2ban/jail.local") + raw, err := io.Read("/etc/fail2ban/jail.local") if err != nil { return controllers.Error(ctx, http.StatusUnprocessableEntity, err.Error()) } @@ -228,7 +229,7 @@ func (r *Fail2banController) Delete(ctx http.Context) http.Response { rule := tools.Cut(raw, "# "+jailName+"-START", "# "+jailName+"-END") raw = strings.Replace(raw, "\n# "+jailName+"-START"+rule+"# "+jailName+"-END", "", -1) raw = strings.TrimSpace(raw) - if err := tools.Write("/etc/fail2ban/jail.local", raw, 0644); err != nil { + if err := io.Write("/etc/fail2ban/jail.local", raw, 0644); err != nil { return controllers.Error(ctx, http.StatusInternalServerError, "写入Fail2ban规则失败") } @@ -302,7 +303,7 @@ func (r *Fail2banController) SetWhiteList(ctx http.Context) http.Response { return controllers.Error(ctx, http.StatusUnprocessableEntity, "缺少参数") } - raw, err := tools.Read("/etc/fail2ban/jail.local") + raw, err := io.Read("/etc/fail2ban/jail.local") if err != nil { return controllers.Error(ctx, http.StatusUnprocessableEntity, err.Error()) } @@ -314,7 +315,7 @@ func (r *Fail2banController) SetWhiteList(ctx http.Context) http.Response { return controllers.Error(ctx, http.StatusInternalServerError, "解析Fail2ban规则失败,Fail2ban可能已损坏") } - if err := tools.Write("/etc/fail2ban/jail.local", raw, 0644); err != nil { + if err := io.Write("/etc/fail2ban/jail.local", raw, 0644); err != nil { return controllers.Error(ctx, http.StatusInternalServerError, "写入Fail2ban规则失败") } @@ -326,7 +327,7 @@ func (r *Fail2banController) SetWhiteList(ctx http.Context) http.Response { // GetWhiteList 获取白名单 func (r *Fail2banController) GetWhiteList(ctx http.Context) http.Response { - raw, err := tools.Read("/etc/fail2ban/jail.local") + raw, err := io.Read("/etc/fail2ban/jail.local") if err != nil { return controllers.Error(ctx, http.StatusUnprocessableEntity, err.Error()) } diff --git a/app/http/controllers/plugins/frp_controller.go b/app/http/controllers/plugins/frp_controller.go index 6b823b92..31c27e39 100644 --- a/app/http/controllers/plugins/frp_controller.go +++ b/app/http/controllers/plugins/frp_controller.go @@ -7,8 +7,8 @@ import ( "github.com/TheTNB/panel/app/http/controllers" requests "github.com/TheTNB/panel/app/http/requests/plugins/frp" + "github.com/TheTNB/panel/pkg/io" "github.com/TheTNB/panel/pkg/systemctl" - "github.com/TheTNB/panel/pkg/tools" ) type FrpController struct { @@ -35,7 +35,7 @@ func (r *FrpController) GetConfig(ctx http.Context) http.Response { return sanitize } - config, err := tools.Read(fmt.Sprintf("/www/server/frp/%s.toml", serviceRequest.Service)) + config, err := io.Read(fmt.Sprintf("/www/server/frp/%s.toml", serviceRequest.Service)) if err != nil { return controllers.Error(ctx, http.StatusInternalServerError, err.Error()) } @@ -60,7 +60,7 @@ func (r *FrpController) UpdateConfig(ctx http.Context) http.Response { return sanitize } - if err := tools.Write(fmt.Sprintf("/www/server/frp/%s.toml", updateRequest.Service), updateRequest.Config, 0644); err != nil { + if err := io.Write(fmt.Sprintf("/www/server/frp/%s.toml", updateRequest.Service), updateRequest.Config, 0644); err != nil { return controllers.Error(ctx, http.StatusInternalServerError, err.Error()) } diff --git a/app/http/controllers/plugins/gitea_controller.go b/app/http/controllers/plugins/gitea_controller.go index fc2c8fae..b77c2a1c 100644 --- a/app/http/controllers/plugins/gitea_controller.go +++ b/app/http/controllers/plugins/gitea_controller.go @@ -5,8 +5,8 @@ import ( "github.com/TheTNB/panel/app/http/controllers" requests "github.com/TheTNB/panel/app/http/requests/plugins/gitea" + "github.com/TheTNB/panel/pkg/io" "github.com/TheTNB/panel/pkg/systemctl" - "github.com/TheTNB/panel/pkg/tools" ) type GiteaController struct { @@ -26,7 +26,7 @@ func NewGiteaController() *GiteaController { // @Success 200 {object} controllers.SuccessResponse // @Router /plugins/gitea/config [get] func (r *GiteaController) GetConfig(ctx http.Context) http.Response { - config, err := tools.Read("/www/server/gitea/app.ini") + config, err := io.Read("/www/server/gitea/app.ini") if err != nil { return controllers.Error(ctx, http.StatusInternalServerError, err.Error()) } @@ -51,7 +51,7 @@ func (r *GiteaController) UpdateConfig(ctx http.Context) http.Response { return sanitize } - if err := tools.Write("/www/server/gitea/app.ini", updateRequest.Config, 0644); err != nil { + if err := io.Write("/www/server/gitea/app.ini", updateRequest.Config, 0644); err != nil { return controllers.Error(ctx, http.StatusInternalServerError, err.Error()) } diff --git a/app/http/controllers/plugins/mysql_controller.go b/app/http/controllers/plugins/mysql_controller.go index 6b0442ad..a9602ff0 100644 --- a/app/http/controllers/plugins/mysql_controller.go +++ b/app/http/controllers/plugins/mysql_controller.go @@ -12,6 +12,7 @@ import ( "github.com/TheTNB/panel/app/models" "github.com/TheTNB/panel/internal" "github.com/TheTNB/panel/internal/services" + "github.com/TheTNB/panel/pkg/io" "github.com/TheTNB/panel/pkg/shell" "github.com/TheTNB/panel/pkg/systemctl" "github.com/TheTNB/panel/pkg/tools" @@ -32,7 +33,7 @@ func NewMySQLController() *MySQLController { // GetConfig 获取配置 func (r *MySQLController) GetConfig(ctx http.Context) http.Response { - config, err := tools.Read("/www/server/mysql/conf/my.cnf") + config, err := io.Read("/www/server/mysql/conf/my.cnf") if err != nil { return controllers.Error(ctx, http.StatusInternalServerError, "获取MySQL配置失败") } @@ -47,7 +48,7 @@ func (r *MySQLController) SaveConfig(ctx http.Context) http.Response { return controllers.Error(ctx, http.StatusUnprocessableEntity, "配置不能为空") } - if err := tools.Write("/www/server/mysql/conf/my.cnf", config, 0644); err != nil { + if err := io.Write("/www/server/mysql/conf/my.cnf", config, 0644); err != nil { return controllers.Error(ctx, http.StatusInternalServerError, "写入MySQL配置失败") } @@ -327,8 +328,8 @@ func (r *MySQLController) UploadBackup(ctx http.Context) http.Response { } backupPath := r.setting.Get(models.SettingKeyBackupPath) + "/mysql" - if !tools.Exists(backupPath) { - if err = tools.Mkdir(backupPath, 0644); err != nil { + if !io.Exists(backupPath) { + if err = io.Mkdir(backupPath, 0644); err != nil { return nil } } @@ -368,7 +369,7 @@ func (r *MySQLController) DeleteBackup(ctx http.Context) http.Response { backupPath := r.setting.Get(models.SettingKeyBackupPath) + "/mysql" fileName := ctx.Request().Input("name") - if err := tools.Remove(backupPath + "/" + fileName); err != nil { + if err := io.Remove(backupPath + "/" + fileName); err != nil { return controllers.Error(ctx, http.StatusInternalServerError, err.Error()) } diff --git a/app/http/controllers/plugins/openresty_controller.go b/app/http/controllers/plugins/openresty_controller.go index 9970044e..7fd37717 100644 --- a/app/http/controllers/plugins/openresty_controller.go +++ b/app/http/controllers/plugins/openresty_controller.go @@ -9,6 +9,7 @@ import ( "github.com/spf13/cast" "github.com/TheTNB/panel/app/http/controllers" + "github.com/TheTNB/panel/pkg/io" "github.com/TheTNB/panel/pkg/shell" "github.com/TheTNB/panel/pkg/systemctl" "github.com/TheTNB/panel/pkg/tools" @@ -32,7 +33,7 @@ func NewOpenrestyController() *OpenRestyController { // @Success 200 {object} controllers.SuccessResponse // @Router /plugins/openresty/config [get] func (r *OpenRestyController) GetConfig(ctx http.Context) http.Response { - config, err := tools.Read("/www/server/openresty/conf/nginx.conf") + config, err := io.Read("/www/server/openresty/conf/nginx.conf") if err != nil { return controllers.Error(ctx, http.StatusInternalServerError, "获取配置失败") } @@ -55,7 +56,7 @@ func (r *OpenRestyController) SaveConfig(ctx http.Context) http.Response { return controllers.Error(ctx, http.StatusInternalServerError, "配置不能为空") } - if err := tools.Write("/www/server/openresty/conf/nginx.conf", config, 0644); err != nil { + if err := io.Write("/www/server/openresty/conf/nginx.conf", config, 0644); err != nil { return controllers.Error(ctx, http.StatusInternalServerError, "保存配置失败") } @@ -75,7 +76,7 @@ func (r *OpenRestyController) SaveConfig(ctx http.Context) http.Response { // @Success 200 {object} controllers.SuccessResponse // @Router /plugins/openresty/errorLog [get] func (r *OpenRestyController) ErrorLog(ctx http.Context) http.Response { - if !tools.Exists("/www/wwwlogs/nginx_error.log") { + if !io.Exists("/www/wwwlogs/nginx_error.log") { return controllers.Success(ctx, "") } diff --git a/app/http/controllers/plugins/phpmyadmin_controller.go b/app/http/controllers/plugins/phpmyadmin_controller.go index f9e3b62a..b2ed9d7e 100644 --- a/app/http/controllers/plugins/phpmyadmin_controller.go +++ b/app/http/controllers/plugins/phpmyadmin_controller.go @@ -10,6 +10,7 @@ import ( "github.com/spf13/cast" "github.com/TheTNB/panel/app/http/controllers" + "github.com/TheTNB/panel/pkg/io" "github.com/TheTNB/panel/pkg/shell" "github.com/TheTNB/panel/pkg/systemctl" "github.com/TheTNB/panel/pkg/tools" @@ -38,7 +39,7 @@ func (r *PhpMyAdminController) Info(ctx http.Context) http.Response { return controllers.Error(ctx, http.StatusInternalServerError, "找不到 phpMyAdmin 目录") } - conf, err := tools.Read("/www/server/vhost/phpmyadmin.conf") + conf, err := io.Read("/www/server/vhost/phpmyadmin.conf") if err != nil { return controllers.Error(ctx, http.StatusInternalServerError, err.Error()) } @@ -59,12 +60,12 @@ func (r *PhpMyAdminController) SetPort(ctx http.Context) http.Response { return controllers.Error(ctx, http.StatusInternalServerError, "端口不能为空") } - conf, err := tools.Read("/www/server/vhost/phpmyadmin.conf") + conf, err := io.Read("/www/server/vhost/phpmyadmin.conf") if err != nil { return controllers.Error(ctx, http.StatusInternalServerError, err.Error()) } conf = regexp.MustCompile(`listen\s+(\d+);`).ReplaceAllString(conf, "listen "+cast.ToString(port)+";") - if err := tools.Write("/www/server/vhost/phpmyadmin.conf", conf, 0644); err != nil { + if err := io.Write("/www/server/vhost/phpmyadmin.conf", conf, 0644); err != nil { facades.Log().Request(ctx.Request()).Tags("插件", "phpMyAdmin").With(map[string]any{ "error": err.Error(), }).Info("修改 phpMyAdmin 端口失败") diff --git a/app/http/controllers/plugins/podman_controller.go b/app/http/controllers/plugins/podman_controller.go index 08c19aa5..f287d202 100644 --- a/app/http/controllers/plugins/podman_controller.go +++ b/app/http/controllers/plugins/podman_controller.go @@ -5,8 +5,8 @@ import ( "github.com/TheTNB/panel/app/http/controllers" requests "github.com/TheTNB/panel/app/http/requests/plugins/podman" + "github.com/TheTNB/panel/pkg/io" "github.com/TheTNB/panel/pkg/systemctl" - "github.com/TheTNB/panel/pkg/tools" ) type PodmanController struct { @@ -26,7 +26,7 @@ func NewPodmanController() *PodmanController { // @Success 200 {object} controllers.SuccessResponse // @Router /plugins/podman/registryConfig [get] func (r *PodmanController) GetRegistryConfig(ctx http.Context) http.Response { - config, err := tools.Read("/etc/containers/registries.conf") + config, err := io.Read("/etc/containers/registries.conf") if err != nil { return controllers.Error(ctx, http.StatusInternalServerError, err.Error()) } @@ -51,7 +51,7 @@ func (r *PodmanController) UpdateRegistryConfig(ctx http.Context) http.Response return sanitize } - if err := tools.Write("/etc/containers/registries.conf", updateRequest.Config, 0644); err != nil { + if err := io.Write("/etc/containers/registries.conf", updateRequest.Config, 0644); err != nil { return controllers.Error(ctx, http.StatusInternalServerError, err.Error()) } @@ -72,7 +72,7 @@ func (r *PodmanController) UpdateRegistryConfig(ctx http.Context) http.Response // @Success 200 {object} controllers.SuccessResponse // @Router /plugins/podman/storageConfig [get] func (r *PodmanController) GetStorageConfig(ctx http.Context) http.Response { - config, err := tools.Read("/etc/containers/storage.conf") + config, err := io.Read("/etc/containers/storage.conf") if err != nil { return controllers.Error(ctx, http.StatusInternalServerError, err.Error()) } @@ -97,7 +97,7 @@ func (r *PodmanController) UpdateStorageConfig(ctx http.Context) http.Response { return sanitize } - if err := tools.Write("/etc/containers/storage.conf", updateRequest.Config, 0644); err != nil { + if err := io.Write("/etc/containers/storage.conf", updateRequest.Config, 0644); err != nil { return controllers.Error(ctx, http.StatusInternalServerError, err.Error()) } diff --git a/app/http/controllers/plugins/postgresql_controller.go b/app/http/controllers/plugins/postgresql_controller.go index 78e9215e..4a528ce3 100644 --- a/app/http/controllers/plugins/postgresql_controller.go +++ b/app/http/controllers/plugins/postgresql_controller.go @@ -11,9 +11,9 @@ import ( "github.com/TheTNB/panel/app/models" "github.com/TheTNB/panel/internal" "github.com/TheTNB/panel/internal/services" + "github.com/TheTNB/panel/pkg/io" "github.com/TheTNB/panel/pkg/shell" "github.com/TheTNB/panel/pkg/systemctl" - "github.com/TheTNB/panel/pkg/tools" "github.com/TheTNB/panel/types" ) @@ -32,7 +32,7 @@ func NewPostgreSQLController() *PostgreSQLController { // GetConfig 获取配置 func (r *PostgreSQLController) GetConfig(ctx http.Context) http.Response { // 获取配置 - config, err := tools.Read("/www/server/postgresql/data/postgresql.conf") + config, err := io.Read("/www/server/postgresql/data/postgresql.conf") if err != nil { return controllers.Error(ctx, http.StatusInternalServerError, "获取PostgreSQL配置失败") } @@ -43,7 +43,7 @@ func (r *PostgreSQLController) GetConfig(ctx http.Context) http.Response { // GetUserConfig 获取用户配置 func (r *PostgreSQLController) GetUserConfig(ctx http.Context) http.Response { // 获取配置 - config, err := tools.Read("/www/server/postgresql/data/pg_hba.conf") + config, err := io.Read("/www/server/postgresql/data/pg_hba.conf") if err != nil { return controllers.Error(ctx, http.StatusInternalServerError, "获取PostgreSQL配置失败") } @@ -58,7 +58,7 @@ func (r *PostgreSQLController) SaveConfig(ctx http.Context) http.Response { return controllers.Error(ctx, http.StatusUnprocessableEntity, "配置不能为空") } - if err := tools.Write("/www/server/postgresql/data/postgresql.conf", config, 0644); err != nil { + if err := io.Write("/www/server/postgresql/data/postgresql.conf", config, 0644); err != nil { return controllers.Error(ctx, http.StatusInternalServerError, "写入PostgreSQL配置失败") } @@ -76,7 +76,7 @@ func (r *PostgreSQLController) SaveUserConfig(ctx http.Context) http.Response { return controllers.Error(ctx, http.StatusUnprocessableEntity, "配置不能为空") } - if err := tools.Write("/www/server/postgresql/data/pg_hba.conf", config, 0644); err != nil { + if err := io.Write("/www/server/postgresql/data/pg_hba.conf", config, 0644); err != nil { return controllers.Error(ctx, http.StatusInternalServerError, "写入PostgreSQL配置失败") } @@ -277,8 +277,8 @@ func (r *PostgreSQLController) UploadBackup(ctx http.Context) http.Response { } backupPath := r.setting.Get(models.SettingKeyBackupPath) + "/postgresql" - if !tools.Exists(backupPath) { - if err = tools.Mkdir(backupPath, 0644); err != nil { + if !io.Exists(backupPath) { + if err = io.Mkdir(backupPath, 0644); err != nil { return nil } } @@ -318,7 +318,7 @@ func (r *PostgreSQLController) DeleteBackup(ctx http.Context) http.Response { backupPath := r.setting.Get(models.SettingKeyBackupPath) + "/postgresql" fileName := ctx.Request().Input("name") - if err := tools.Remove(backupPath + "/" + fileName); err != nil { + if err := io.Remove(backupPath + "/" + fileName); err != nil { return controllers.Error(ctx, http.StatusInternalServerError, err.Error()) } diff --git a/app/http/controllers/plugins/pureftpd_controller.go b/app/http/controllers/plugins/pureftpd_controller.go index 99ddfe88..d1701587 100644 --- a/app/http/controllers/plugins/pureftpd_controller.go +++ b/app/http/controllers/plugins/pureftpd_controller.go @@ -8,6 +8,7 @@ import ( "github.com/spf13/cast" "github.com/TheTNB/panel/app/http/controllers" + "github.com/TheTNB/panel/pkg/io" "github.com/TheTNB/panel/pkg/shell" "github.com/TheTNB/panel/pkg/systemctl" "github.com/TheTNB/panel/pkg/tools" @@ -70,14 +71,14 @@ func (r *PureFtpdController) Add(ctx http.Context) http.Response { if !strings.HasPrefix(path, "/") { path = "/" + path } - if !tools.Exists(path) { + if !io.Exists(path) { return controllers.Error(ctx, http.StatusUnprocessableEntity, "目录不存在") } - if err := tools.Chmod(path, 0755); err != nil { + if err := io.Chmod(path, 0755); err != nil { return controllers.Error(ctx, http.StatusUnprocessableEntity, "修改目录权限失败") } - if err := tools.Chown(path, "www", "www"); err != nil { + if err := io.Chown(path, "www", "www"); err != nil { return nil } if out, err := shell.Execf(`yes '` + password + `' | pure-pw useradd ` + username + ` -u www -g www -d ` + path); err != nil { diff --git a/app/http/controllers/plugins/redis_controller.go b/app/http/controllers/plugins/redis_controller.go index 031aa8ed..17e5a18d 100644 --- a/app/http/controllers/plugins/redis_controller.go +++ b/app/http/controllers/plugins/redis_controller.go @@ -6,9 +6,9 @@ import ( "github.com/goravel/framework/contracts/http" "github.com/TheTNB/panel/app/http/controllers" + "github.com/TheTNB/panel/pkg/io" "github.com/TheTNB/panel/pkg/shell" "github.com/TheTNB/panel/pkg/systemctl" - "github.com/TheTNB/panel/pkg/tools" "github.com/TheTNB/panel/types" ) @@ -22,7 +22,7 @@ func NewRedisController() *RedisController { // GetConfig 获取配置 func (r *RedisController) GetConfig(ctx http.Context) http.Response { // 获取配置 - config, err := tools.Read("/www/server/redis/redis.conf") + config, err := io.Read("/www/server/redis/redis.conf") if err != nil { return controllers.Error(ctx, http.StatusInternalServerError, "获取Redis配置失败") } @@ -37,7 +37,7 @@ func (r *RedisController) SaveConfig(ctx http.Context) http.Response { return controllers.Error(ctx, http.StatusUnprocessableEntity, "配置不能为空") } - if err := tools.Write("/www/server/redis/redis.conf", config, 0644); err != nil { + if err := io.Write("/www/server/redis/redis.conf", config, 0644); err != nil { return controllers.Error(ctx, http.StatusInternalServerError, "写入Redis配置失败") } diff --git a/app/http/controllers/plugins/rsync_controller.go b/app/http/controllers/plugins/rsync_controller.go index 47cf3ee2..87224870 100644 --- a/app/http/controllers/plugins/rsync_controller.go +++ b/app/http/controllers/plugins/rsync_controller.go @@ -8,6 +8,7 @@ import ( "github.com/TheTNB/panel/app/http/controllers" requests "github.com/TheTNB/panel/app/http/requests/plugins/rsync" + "github.com/TheTNB/panel/pkg/io" "github.com/TheTNB/panel/pkg/shell" "github.com/TheTNB/panel/pkg/systemctl" "github.com/TheTNB/panel/pkg/tools" @@ -32,7 +33,7 @@ func NewRsyncController() *RsyncController { // @Success 200 {object} controllers.SuccessResponse // @Router /plugins/rsync/modules [get] func (r *RsyncController) List(ctx http.Context) http.Response { - config, err := tools.Read("/etc/rsyncd.conf") + config, err := io.Read("/etc/rsyncd.conf") if err != nil { return controllers.Error(ctx, http.StatusInternalServerError, err.Error()) } @@ -111,7 +112,7 @@ func (r *RsyncController) Create(ctx http.Context) http.Response { return sanitize } - config, err := tools.Read("/etc/rsyncd.conf") + config, err := io.Read("/etc/rsyncd.conf") if err != nil { return controllers.Error(ctx, http.StatusInternalServerError, err.Error()) } @@ -130,7 +131,7 @@ secrets file = /etc/rsyncd.secrets # ` + createRequest.Name + `-END ` - if err := tools.WriteAppend("/etc/rsyncd.conf", conf); err != nil { + if err := io.WriteAppend("/etc/rsyncd.conf", conf); err != nil { return controllers.Error(ctx, http.StatusInternalServerError, err.Error()) } if out, err := shell.Execf("echo '" + createRequest.AuthUser + ":" + createRequest.Secret + "' >> /etc/rsyncd.secrets"); err != nil { @@ -160,7 +161,7 @@ func (r *RsyncController) Destroy(ctx http.Context) http.Response { return controllers.Error(ctx, http.StatusUnprocessableEntity, "name 不能为空") } - config, err := tools.Read("/etc/rsyncd.conf") + config, err := io.Read("/etc/rsyncd.conf") if err != nil { return controllers.Error(ctx, http.StatusInternalServerError, err.Error()) } @@ -179,7 +180,7 @@ func (r *RsyncController) Destroy(ctx http.Context) http.Response { } } - if err = tools.Write("/etc/rsyncd.conf", config, 0644); err != nil { + if err = io.Write("/etc/rsyncd.conf", config, 0644); err != nil { return controllers.Error(ctx, http.StatusInternalServerError, err.Error()) } @@ -208,7 +209,7 @@ func (r *RsyncController) Update(ctx http.Context) http.Response { return sanitize } - config, err := tools.Read("/etc/rsyncd.conf") + config, err := io.Read("/etc/rsyncd.conf") if err != nil { return controllers.Error(ctx, http.StatusInternalServerError, err.Error()) } @@ -237,7 +238,7 @@ secrets file = /etc/rsyncd.secrets } } - if err = tools.Write("/etc/rsyncd.conf", config, 0644); err != nil { + if err = io.Write("/etc/rsyncd.conf", config, 0644); err != nil { return controllers.Error(ctx, http.StatusInternalServerError, err.Error()) } if out, err := shell.Execf("echo '" + updateRequest.AuthUser + ":" + updateRequest.Secret + "' >> /etc/rsyncd.secrets"); err != nil { @@ -261,7 +262,7 @@ secrets file = /etc/rsyncd.secrets // @Success 200 {object} controllers.SuccessResponse // @Router /plugins/rsync/config [get] func (r *RsyncController) GetConfig(ctx http.Context) http.Response { - config, err := tools.Read("/etc/rsyncd.conf") + config, err := io.Read("/etc/rsyncd.conf") if err != nil { return controllers.Error(ctx, http.StatusInternalServerError, err.Error()) } @@ -286,7 +287,7 @@ func (r *RsyncController) UpdateConfig(ctx http.Context) http.Response { return sanitize } - if err := tools.Write("/etc/rsyncd.conf", updateRequest.Config, 0644); err != nil { + if err := io.Write("/etc/rsyncd.conf", updateRequest.Config, 0644); err != nil { return controllers.Error(ctx, http.StatusInternalServerError, err.Error()) } diff --git a/app/http/controllers/plugins/s3fs_controller.go b/app/http/controllers/plugins/s3fs_controller.go index 93a657c5..922e4cc3 100644 --- a/app/http/controllers/plugins/s3fs_controller.go +++ b/app/http/controllers/plugins/s3fs_controller.go @@ -11,8 +11,8 @@ import ( "github.com/TheTNB/panel/app/http/controllers" "github.com/TheTNB/panel/internal" "github.com/TheTNB/panel/internal/services" + "github.com/TheTNB/panel/pkg/io" "github.com/TheTNB/panel/pkg/shell" - "github.com/TheTNB/panel/pkg/tools" "github.com/TheTNB/panel/types" ) @@ -66,12 +66,12 @@ func (r *S3fsController) Add(ctx http.Context) http.Response { } // 检查挂载目录是否存在且为空 - if !tools.Exists(path) { - if err := tools.Mkdir(path, 0755); err != nil { + if !io.Exists(path) { + if err := io.Mkdir(path, 0755); err != nil { return controllers.Error(ctx, http.StatusUnprocessableEntity, "挂载目录创建失败") } } - if !tools.Empty(path) { + if !io.Empty(path) { return controllers.Error(ctx, http.StatusUnprocessableEntity, "挂载目录必须为空") } @@ -88,7 +88,7 @@ func (r *S3fsController) Add(ctx http.Context) http.Response { id := carbon.Now().TimestampMilli() password := ak + ":" + sk - if err := tools.Write("/etc/passwd-s3fs-"+cast.ToString(id), password, 0600); err != nil { + if err := io.Write("/etc/passwd-s3fs-"+cast.ToString(id), password, 0600); err != nil { return nil } out, err := shell.Execf(`echo 's3fs#` + bucket + ` ` + path + ` fuse _netdev,allow_other,nonempty,url=` + url + `,passwd_file=/etc/passwd-s3fs-` + cast.ToString(id) + ` 0 0' >> /etc/fstab`) @@ -158,7 +158,7 @@ func (r *S3fsController) Delete(ctx http.Context) http.Response { if mountCheck, err := shell.Execf("mount -a 2>&1"); err != nil { return controllers.Error(ctx, http.StatusInternalServerError, "检测到/etc/fstab有误: "+mountCheck) } - if err := tools.Remove("/etc/passwd-s3fs-" + cast.ToString(mount.ID)); err != nil { + if err := io.Remove("/etc/passwd-s3fs-" + cast.ToString(mount.ID)); err != nil { return controllers.Error(ctx, http.StatusInternalServerError, err.Error()) } diff --git a/app/http/controllers/plugins/supervisor_controller.go b/app/http/controllers/plugins/supervisor_controller.go index 5190fc85..e5cf3eb2 100644 --- a/app/http/controllers/plugins/supervisor_controller.go +++ b/app/http/controllers/plugins/supervisor_controller.go @@ -8,6 +8,7 @@ import ( "github.com/goravel/framework/contracts/http" "github.com/TheTNB/panel/app/http/controllers" + "github.com/TheTNB/panel/pkg/io" "github.com/TheTNB/panel/pkg/shell" "github.com/TheTNB/panel/pkg/systemctl" "github.com/TheTNB/panel/pkg/tools" @@ -59,9 +60,9 @@ func (r *SupervisorController) Config(ctx http.Context) http.Response { var config string var err error if tools.IsRHEL() { - config, err = tools.Read(`/etc/supervisord.conf`) + config, err = io.Read(`/etc/supervisord.conf`) } else { - config, err = tools.Read(`/etc/supervisor/supervisord.conf`) + config, err = io.Read(`/etc/supervisor/supervisord.conf`) } if err != nil { @@ -76,9 +77,9 @@ func (r *SupervisorController) SaveConfig(ctx http.Context) http.Response { config := ctx.Request().Input("config") var err error if tools.IsRHEL() { - err = tools.Write(`/etc/supervisord.conf`, config, 0644) + err = io.Write(`/etc/supervisord.conf`, config, 0644) } else { - err = tools.Write(`/etc/supervisor/supervisord.conf`, config, 0644) + err = io.Write(`/etc/supervisor/supervisord.conf`, config, 0644) } if err != nil { @@ -218,9 +219,9 @@ func (r *SupervisorController) ProcessConfig(ctx http.Context) http.Response { var config string var err error if tools.IsRHEL() { - config, err = tools.Read(`/etc/supervisord.d/` + process + `.conf`) + config, err = io.Read(`/etc/supervisord.d/` + process + `.conf`) } else { - config, err = tools.Read(`/etc/supervisor/conf.d/` + process + `.conf`) + config, err = io.Read(`/etc/supervisor/conf.d/` + process + `.conf`) } if err != nil { @@ -236,9 +237,9 @@ func (r *SupervisorController) SaveProcessConfig(ctx http.Context) http.Response config := ctx.Request().Input("config") var err error if tools.IsRHEL() { - err = tools.Write(`/etc/supervisord.d/`+process+`.conf`, config, 0644) + err = io.Write(`/etc/supervisord.d/`+process+`.conf`, config, 0644) } else { - err = tools.Write(`/etc/supervisor/conf.d/`+process+`.conf`, config, 0644) + err = io.Write(`/etc/supervisor/conf.d/`+process+`.conf`, config, 0644) } if err != nil { @@ -284,9 +285,9 @@ stdout_logfile_maxbytes=2MB var err error if tools.IsRHEL() { - err = tools.Write(`/etc/supervisord.d/`+name+`.conf`, config, 0644) + err = io.Write(`/etc/supervisord.d/`+name+`.conf`, config, 0644) } else { - err = tools.Write(`/etc/supervisor/conf.d/`+name+`.conf`, config, 0644) + err = io.Write(`/etc/supervisor/conf.d/`+name+`.conf`, config, 0644) } if err != nil { @@ -311,12 +312,12 @@ func (r *SupervisorController) DeleteProcess(ctx http.Context) http.Response { var err error if tools.IsRHEL() { logPath, err = shell.Execf(`cat '/etc/supervisord.d/%s.conf' | grep stdout_logfile= | awk -F "=" '{print $2}'`, process) - if err := tools.Remove(`/etc/supervisord.d/` + process + `.conf`); err != nil { + if err := io.Remove(`/etc/supervisord.d/` + process + `.conf`); err != nil { return controllers.Error(ctx, http.StatusInternalServerError, err.Error()) } } else { logPath, err = shell.Execf(`cat '/etc/supervisor/conf.d/%s.conf' | grep stdout_logfile= | awk -F "=" '{print $2}'`, process) - if err := tools.Remove(`/etc/supervisor/conf.d/` + process + `.conf`); err != nil { + if err := io.Remove(`/etc/supervisor/conf.d/` + process + `.conf`); err != nil { return controllers.Error(ctx, http.StatusInternalServerError, err.Error()) } } @@ -325,7 +326,7 @@ func (r *SupervisorController) DeleteProcess(ctx http.Context) http.Response { return controllers.Error(ctx, http.StatusInternalServerError, "无法从进程"+process+"的配置文件中获取日志路径") } - if err := tools.Remove(logPath); err != nil { + if err := io.Remove(logPath); err != nil { return controllers.Error(ctx, http.StatusInternalServerError, err.Error()) } _, _ = shell.Execf(`supervisorctl reread`) diff --git a/app/http/controllers/plugins/toolbox_controller.go b/app/http/controllers/plugins/toolbox_controller.go index c2938c6b..06c6a1bd 100644 --- a/app/http/controllers/plugins/toolbox_controller.go +++ b/app/http/controllers/plugins/toolbox_controller.go @@ -8,6 +8,7 @@ import ( "github.com/spf13/cast" "github.com/TheTNB/panel/app/http/controllers" + "github.com/TheTNB/panel/pkg/io" "github.com/TheTNB/panel/pkg/shell" "github.com/TheTNB/panel/pkg/tools" ) @@ -21,7 +22,7 @@ func NewToolBoxController() *ToolBoxController { // GetDNS 获取 DNS 信息 func (r *ToolBoxController) GetDNS(ctx http.Context) http.Response { - raw, err := tools.Read("/etc/resolv.conf") + raw, err := io.Read("/etc/resolv.conf") if err != nil { return controllers.Error(ctx, http.StatusInternalServerError, err.Error()) } @@ -51,7 +52,7 @@ func (r *ToolBoxController) SetDNS(ctx http.Context) http.Response { dns += "nameserver " + dns1 + "\n" dns += "nameserver " + dns2 + "\n" - if err := tools.Write("/etc/resolv.conf", dns, 0644); err != nil { + if err := io.Write("/etc/resolv.conf", dns, 0644); err != nil { return controllers.Error(ctx, http.StatusInternalServerError, "写入 DNS 信息失败") } @@ -62,8 +63,8 @@ func (r *ToolBoxController) SetDNS(ctx http.Context) http.Response { func (r *ToolBoxController) GetSWAP(ctx http.Context) http.Response { var total, used, free string var size int64 - if tools.Exists("/www/swap") { - file, err := tools.FileInfo("/www/swap") + if io.Exists("/www/swap") { + file, err := io.FileInfo("/www/swap") if err != nil { return controllers.Error(ctx, http.StatusUnprocessableEntity, "获取 SWAP 信息失败") } @@ -98,7 +99,7 @@ func (r *ToolBoxController) GetSWAP(ctx http.Context) http.Response { func (r *ToolBoxController) SetSWAP(ctx http.Context) http.Response { size := ctx.Request().InputInt("size") - if tools.Exists("/www/swap") { + if io.Exists("/www/swap") { if out, err := shell.Execf("swapoff /www/swap"); err != nil { return controllers.Error(ctx, http.StatusUnprocessableEntity, out) } @@ -131,7 +132,7 @@ func (r *ToolBoxController) SetSWAP(ctx http.Context) http.Response { if out, err := shell.Execf("mkswap -f /www/swap"); err != nil { return controllers.Error(ctx, http.StatusUnprocessableEntity, out) } - if err := tools.Chmod("/www/swap", 0600); err != nil { + if err := io.Chmod("/www/swap", 0600); err != nil { return controllers.Error(ctx, http.StatusUnprocessableEntity, "设置 SWAP 权限失败") } } @@ -199,7 +200,7 @@ func (r *ToolBoxController) SetTimezone(ctx http.Context) http.Response { // GetHosts 获取 hosts 信息 func (r *ToolBoxController) GetHosts(ctx http.Context) http.Response { - hosts, err := tools.Read("/etc/hosts") + hosts, err := io.Read("/etc/hosts") if err != nil { return controllers.Error(ctx, http.StatusUnprocessableEntity, err.Error()) } @@ -214,7 +215,7 @@ func (r *ToolBoxController) SetHosts(ctx http.Context) http.Response { return controllers.Error(ctx, http.StatusUnprocessableEntity, "hosts 信息不能为空") } - if err := tools.Write("/etc/hosts", hosts, 0644); err != nil { + if err := io.Write("/etc/hosts", hosts, 0644); err != nil { return controllers.Error(ctx, http.StatusUnprocessableEntity, "写入 hosts 信息失败") } diff --git a/app/http/controllers/safe_controller.go b/app/http/controllers/safe_controller.go index 4830a88e..a3bf82f8 100644 --- a/app/http/controllers/safe_controller.go +++ b/app/http/controllers/safe_controller.go @@ -7,6 +7,7 @@ import ( "github.com/goravel/framework/contracts/http" "github.com/spf13/cast" + "github.com/TheTNB/panel/pkg/io" "github.com/TheTNB/panel/pkg/shell" "github.com/TheTNB/panel/pkg/systemctl" "github.com/TheTNB/panel/pkg/tools" @@ -308,7 +309,7 @@ func (r *SafeController) GetPingStatus(ctx http.Context) http.Response { return Success(ctx, false) } } else { - config, err := tools.Read("/etc/ufw/before.rules") + config, err := io.Read("/etc/ufw/before.rules") if err != nil { return Error(ctx, http.StatusInternalServerError, err.Error()) } diff --git a/app/http/controllers/setting_controller.go b/app/http/controllers/setting_controller.go index 9ea6536d..161095e2 100644 --- a/app/http/controllers/setting_controller.go +++ b/app/http/controllers/setting_controller.go @@ -9,6 +9,7 @@ import ( "github.com/TheTNB/panel/app/models" "github.com/TheTNB/panel/internal" "github.com/TheTNB/panel/internal/services" + "github.com/TheTNB/panel/pkg/io" "github.com/TheTNB/panel/pkg/shell" "github.com/TheTNB/panel/pkg/tools" ) @@ -99,8 +100,8 @@ func (r *SettingController) Update(ctx http.Context) http.Response { return ErrorSystem(ctx) } - if !tools.Exists(updateRequest.BackupPath) { - if err = tools.Mkdir(updateRequest.BackupPath, 0644); err != nil { + if !io.Exists(updateRequest.BackupPath) { + if err = io.Mkdir(updateRequest.BackupPath, 0644); err != nil { return ErrorSystem(ctx) } } @@ -111,11 +112,11 @@ func (r *SettingController) Update(ctx http.Context) http.Response { }).Info("保存备份目录失败") return ErrorSystem(ctx) } - if !tools.Exists(updateRequest.WebsitePath) { - if err = tools.Mkdir(updateRequest.WebsitePath, 0755); err != nil { + if !io.Exists(updateRequest.WebsitePath) { + if err = io.Mkdir(updateRequest.WebsitePath, 0755); err != nil { return ErrorSystem(ctx) } - if err = tools.Chown(updateRequest.WebsitePath, "www", "www"); err != nil { + if err = io.Chown(updateRequest.WebsitePath, "www", "www"); err != nil { return ErrorSystem(ctx) } } diff --git a/app/http/controllers/website_controller.go b/app/http/controllers/website_controller.go index 6775a2cc..f0bd9deb 100644 --- a/app/http/controllers/website_controller.go +++ b/app/http/controllers/website_controller.go @@ -13,6 +13,7 @@ import ( "github.com/TheTNB/panel/app/models" "github.com/TheTNB/panel/internal" "github.com/TheTNB/panel/internal/services" + "github.com/TheTNB/panel/pkg/io" "github.com/TheTNB/panel/pkg/systemctl" "github.com/TheTNB/panel/pkg/tools" "github.com/TheTNB/panel/types" @@ -147,11 +148,11 @@ func (r *WebsiteController) Delete(ctx http.Context) http.Response { // @Success 200 {object} SuccessResponse{data=map[string]string} // @Router /panel/website/defaultConfig [get] func (r *WebsiteController) GetDefaultConfig(ctx http.Context) http.Response { - index, err := tools.Read("/www/server/openresty/html/index.html") + index, err := io.Read("/www/server/openresty/html/index.html") if err != nil { return Error(ctx, http.StatusInternalServerError, err.Error()) } - stop, err := tools.Read("/www/server/openresty/html/stop.html") + stop, err := io.Read("/www/server/openresty/html/stop.html") if err != nil { return Error(ctx, http.StatusInternalServerError, err.Error()) } @@ -176,14 +177,14 @@ func (r *WebsiteController) SaveDefaultConfig(ctx http.Context) http.Response { index := ctx.Request().Input("index") stop := ctx.Request().Input("stop") - if err := tools.Write("/www/server/openresty/html/index.html", index, 0644); err != nil { + if err := io.Write("/www/server/openresty/html/index.html", index, 0644); err != nil { facades.Log().Request(ctx.Request()).Tags("面板", "网站管理").With(map[string]any{ "error": err.Error(), }).Info("保存默认首页配置失败") return ErrorSystem(ctx) } - if err := tools.Write("/www/server/openresty/html/stop.html", stop, 0644); err != nil { + if err := io.Write("/www/server/openresty/html/stop.html", stop, 0644); err != nil { facades.Log().Request(ctx.Request()).Tags("面板", "网站管理").With(map[string]any{ "error": err.Error(), }).Info("保存默认停止页配置失败") @@ -271,7 +272,7 @@ func (r *WebsiteController) ClearLog(ctx http.Context) http.Response { return ErrorSystem(ctx) } - if err := tools.Remove("/www/wwwlogs/" + website.Name + ".log"); err != nil { + if err := io.Remove("/www/wwwlogs/" + website.Name + ".log"); err != nil { return Error(ctx, http.StatusInternalServerError, err.Error()) } @@ -399,8 +400,8 @@ func (r *WebsiteController) UploadBackup(ctx http.Context) http.Response { } backupPath := r.setting.Get(models.SettingKeyBackupPath) + "/website" - if !tools.Exists(backupPath) { - if err = tools.Mkdir(backupPath, 0644); err != nil { + if !io.Exists(backupPath) { + if err = io.Mkdir(backupPath, 0644); err != nil { return nil } } @@ -469,13 +470,13 @@ func (r *WebsiteController) DeleteBackup(ctx http.Context) http.Response { } backupPath := r.setting.Get(models.SettingKeyBackupPath) + "/website" - if !tools.Exists(backupPath) { - if err := tools.Mkdir(backupPath, 0644); err != nil { + if !io.Exists(backupPath) { + if err := io.Mkdir(backupPath, 0644); err != nil { return nil } } - if err := tools.Remove(backupPath + "/" + deleteBackupRequest.Name); err != nil { + if err := io.Remove(backupPath + "/" + deleteBackupRequest.Name); err != nil { return Error(ctx, http.StatusInternalServerError, err.Error()) } @@ -572,10 +573,10 @@ server } `, website.Path, website.Php, website.Name, website.Name, website.Name) - if err := tools.Write("/www/server/vhost/"+website.Name+".conf", raw, 0644); err != nil { + if err := io.Write("/www/server/vhost/"+website.Name+".conf", raw, 0644); err != nil { return nil } - if err := tools.Write("/www/server/vhost/rewrite"+website.Name+".conf", "", 0644); err != nil { + if err := io.Write("/www/server/vhost/rewrite"+website.Name+".conf", "", 0644); err != nil { return nil } if err := systemctl.Reload("openresty"); err != nil { @@ -612,7 +613,7 @@ func (r *WebsiteController) Status(ctx http.Context) http.Response { return ErrorSystem(ctx) } - raw, err := tools.Read("/www/server/vhost/" + website.Name + ".conf") + raw, err := io.Read("/www/server/vhost/" + website.Name + ".conf") if err != nil { return Error(ctx, http.StatusInternalServerError, err.Error()) } @@ -641,7 +642,7 @@ func (r *WebsiteController) Status(ctx http.Context) http.Response { } } - if err = tools.Write("/www/server/vhost/"+website.Name+".conf", raw, 0644); err != nil { + if err = io.Write("/www/server/vhost/"+website.Name+".conf", raw, 0644); err != nil { return ErrorSystem(ctx) } if err = systemctl.Reload("openresty"); err != nil { diff --git a/app/rules/path_exist.go b/app/rules/path_exist.go index c673ba4c..338ec17d 100644 --- a/app/rules/path_exist.go +++ b/app/rules/path_exist.go @@ -1,9 +1,10 @@ package rules import ( - "github.com/TheTNB/panel/pkg/tools" "github.com/goravel/framework/contracts/validation" "github.com/spf13/cast" + + "github.com/TheTNB/panel/pkg/io" ) type PathExists struct { @@ -27,7 +28,7 @@ func (receiver *PathExists) Passes(_ validation.Data, val any, options ...any) b return false } - return tools.Exists(requestValue) + return io.Exists(requestValue) } // Message Get the validation error message. diff --git a/app/rules/path_not_exist.go b/app/rules/path_not_exist.go index e8ac07c5..63fc701e 100644 --- a/app/rules/path_not_exist.go +++ b/app/rules/path_not_exist.go @@ -1,9 +1,10 @@ package rules import ( - "github.com/TheTNB/panel/pkg/tools" "github.com/goravel/framework/contracts/validation" "github.com/spf13/cast" + + "github.com/TheTNB/panel/pkg/io" ) type PathNotExists struct { @@ -27,7 +28,7 @@ func (receiver *PathNotExists) Passes(_ validation.Data, val any, options ...any return false } - return !tools.Exists(requestValue) + return !io.Exists(requestValue) } // Message Get the validation error message. diff --git a/internal/services/backup.go b/internal/services/backup.go index 8a65fa19..f9423733 100644 --- a/internal/services/backup.go +++ b/internal/services/backup.go @@ -11,6 +11,7 @@ import ( "github.com/TheTNB/panel/app/models" "github.com/TheTNB/panel/internal" + "github.com/TheTNB/panel/pkg/io" "github.com/TheTNB/panel/pkg/shell" "github.com/TheTNB/panel/pkg/tools" "github.com/TheTNB/panel/types" @@ -34,8 +35,8 @@ func (s *BackupImpl) WebsiteList() ([]types.BackupFile, error) { } backupPath += "/website" - if !tools.Exists(backupPath) { - if err := tools.Mkdir(backupPath, 0644); err != nil { + if !io.Exists(backupPath) { + if err := io.Mkdir(backupPath, 0644); err != nil { return []types.BackupFile{}, err } } @@ -67,8 +68,8 @@ func (s *BackupImpl) WebSiteBackup(website models.Website) error { } backupPath += "/website" - if !tools.Exists(backupPath) { - if err := tools.Mkdir(backupPath, 0644); err != nil { + if !io.Exists(backupPath) { + if err := io.Mkdir(backupPath, 0644); err != nil { return err } } @@ -89,27 +90,27 @@ func (s *BackupImpl) WebsiteRestore(website models.Website, backupFile string) e } backupPath += "/website" - if !tools.Exists(backupPath) { - if err := tools.Mkdir(backupPath, 0644); err != nil { + if !io.Exists(backupPath) { + if err := io.Mkdir(backupPath, 0644); err != nil { return err } } backupFile = backupPath + "/" + backupFile - if !tools.Exists(backupFile) { + if !io.Exists(backupFile) { return errors.New("备份文件不存在") } - if err := tools.Remove(website.Path); err != nil { + if err := io.Remove(website.Path); err != nil { return err } - if err := tools.UnArchive(backupFile, website.Path); err != nil { + if err := io.UnArchive(backupFile, website.Path); err != nil { return err } - if err := tools.Chmod(website.Path, 0755); err != nil { + if err := io.Chmod(website.Path, 0755); err != nil { return err } - if err := tools.Chown(website.Path, "www", "www"); err != nil { + if err := io.Chown(website.Path, "www", "www"); err != nil { return err } @@ -124,8 +125,8 @@ func (s *BackupImpl) MysqlList() ([]types.BackupFile, error) { } backupPath += "/mysql" - if !tools.Exists(backupPath) { - if err := tools.Mkdir(backupPath, 0644); err != nil { + if !io.Exists(backupPath) { + if err := io.Mkdir(backupPath, 0644); err != nil { return []types.BackupFile{}, err } } @@ -154,8 +155,8 @@ func (s *BackupImpl) MysqlBackup(database string) error { backupPath := s.setting.Get(models.SettingKeyBackupPath) + "/mysql" rootPassword := s.setting.Get(models.SettingKeyMysqlRootPassword) backupFile := database + "_" + carbon.Now().ToShortDateTimeString() + ".sql" - if !tools.Exists(backupPath) { - if err := tools.Mkdir(backupPath, 0644); err != nil { + if !io.Exists(backupPath) { + if err := io.Mkdir(backupPath, 0644); err != nil { return err } } @@ -170,7 +171,7 @@ func (s *BackupImpl) MysqlBackup(database string) error { if _, err := shell.Execf("cd " + backupPath + " && zip -r " + backupPath + "/" + backupFile + ".zip " + backupFile); err != nil { return err } - if err := tools.Remove(backupPath + "/" + backupFile); err != nil { + if err := io.Remove(backupPath + "/" + backupFile); err != nil { return err } @@ -182,7 +183,7 @@ func (s *BackupImpl) MysqlRestore(database string, backupFile string) error { backupPath := s.setting.Get(models.SettingKeyBackupPath) + "/mysql" rootPassword := s.setting.Get(models.SettingKeyMysqlRootPassword) backupFullPath := filepath.Join(backupPath, backupFile) - if !tools.Exists(backupFullPath) { + if !io.Exists(backupFullPath) { return errors.New("备份文件不存在") } @@ -190,14 +191,14 @@ func (s *BackupImpl) MysqlRestore(database string, backupFile string) error { return err } - tempDir, err := tools.TempDir(backupFile) + tempDir, err := io.TempDir(backupFile) if err != nil { return err } if !strings.HasSuffix(backupFile, ".sql") { backupFile = "" // 置空,防止干扰后续判断 - if err = tools.UnArchive(backupFullPath, tempDir); err != nil { + if err = io.UnArchive(backupFullPath, tempDir); err != nil { return err } if files, err := os.ReadDir(tempDir); err == nil { @@ -209,7 +210,7 @@ func (s *BackupImpl) MysqlRestore(database string, backupFile string) error { } } } else { - if err = tools.Cp(backupFullPath, filepath.Join(tempDir, backupFile)); err != nil { + if err = io.Cp(backupFullPath, filepath.Join(tempDir, backupFile)); err != nil { return err } } @@ -222,7 +223,7 @@ func (s *BackupImpl) MysqlRestore(database string, backupFile string) error { return err } - if err = tools.Remove(tempDir); err != nil { + if err = io.Remove(tempDir); err != nil { return err } @@ -237,8 +238,8 @@ func (s *BackupImpl) PostgresqlList() ([]types.BackupFile, error) { } backupPath += "/postgresql" - if !tools.Exists(backupPath) { - if err := tools.Mkdir(backupPath, 0644); err != nil { + if !io.Exists(backupPath) { + if err := io.Mkdir(backupPath, 0644); err != nil { return []types.BackupFile{}, err } } @@ -266,8 +267,8 @@ func (s *BackupImpl) PostgresqlList() ([]types.BackupFile, error) { func (s *BackupImpl) PostgresqlBackup(database string) error { backupPath := s.setting.Get(models.SettingKeyBackupPath) + "/postgresql" backupFile := database + "_" + carbon.Now().ToShortDateTimeString() + ".sql" - if !tools.Exists(backupPath) { - if err := tools.Mkdir(backupPath, 0644); err != nil { + if !io.Exists(backupPath) { + if err := io.Mkdir(backupPath, 0644); err != nil { return err } } @@ -279,25 +280,25 @@ func (s *BackupImpl) PostgresqlBackup(database string) error { return err } - return tools.Remove(backupPath + "/" + backupFile) + return io.Remove(backupPath + "/" + backupFile) } // PostgresqlRestore PostgreSQL恢复 func (s *BackupImpl) PostgresqlRestore(database string, backupFile string) error { backupPath := s.setting.Get(models.SettingKeyBackupPath) + "/postgresql" backupFullPath := filepath.Join(backupPath, backupFile) - if !tools.Exists(backupFullPath) { + if !io.Exists(backupFullPath) { return errors.New("备份文件不存在") } - tempDir, err := tools.TempDir(backupFile) + tempDir, err := io.TempDir(backupFile) if err != nil { return err } if !strings.HasSuffix(backupFile, ".sql") { backupFile = "" // 置空,防止干扰后续判断 - if err = tools.UnArchive(backupFullPath, tempDir); err != nil { + if err = io.UnArchive(backupFullPath, tempDir); err != nil { return err } if files, err := os.ReadDir(tempDir); err == nil { @@ -309,7 +310,7 @@ func (s *BackupImpl) PostgresqlRestore(database string, backupFile string) error } } } else { - if err = tools.Cp(backupFullPath, filepath.Join(tempDir, backupFile)); err != nil { + if err = io.Cp(backupFullPath, filepath.Join(tempDir, backupFile)); err != nil { return err } } @@ -322,7 +323,7 @@ func (s *BackupImpl) PostgresqlRestore(database string, backupFile string) error return err } - if err = tools.Remove(tempDir); err != nil { + if err = io.Remove(tempDir); err != nil { return err } diff --git a/internal/services/cert.go b/internal/services/cert.go index 32ed9d64..a003a34c 100644 --- a/internal/services/cert.go +++ b/internal/services/cert.go @@ -12,8 +12,8 @@ import ( requests "github.com/TheTNB/panel/app/http/requests/cert" "github.com/TheTNB/panel/app/models" "github.com/TheTNB/panel/pkg/acme" + "github.com/TheTNB/panel/pkg/io" "github.com/TheTNB/panel/pkg/systemctl" - "github.com/TheTNB/panel/pkg/tools" ) type CertImpl struct { @@ -272,10 +272,10 @@ func (s *CertImpl) ObtainAuto(ID uint) (acme.Certificate, error) { } if cert.Website != nil { - if err = tools.Write("/www/server/vhost/ssl/"+cert.Website.Name+".pem", cert.Cert, 0644); err != nil { + if err = io.Write("/www/server/vhost/ssl/"+cert.Website.Name+".pem", cert.Cert, 0644); err != nil { return acme.Certificate{}, err } - if err = tools.Write("/www/server/vhost/ssl/"+cert.Website.Name+".key", cert.Key, 0644); err != nil { + if err = io.Write("/www/server/vhost/ssl/"+cert.Website.Name+".key", cert.Key, 0644); err != nil { return acme.Certificate{}, err } if err = systemctl.Reload("openresty"); err != nil { @@ -312,10 +312,10 @@ func (s *CertImpl) ObtainManual(ID uint) (acme.Certificate, error) { } if cert.Website != nil { - if err = tools.Write("/www/server/vhost/ssl/"+cert.Website.Name+".pem", cert.Cert, 0644); err != nil { + if err = io.Write("/www/server/vhost/ssl/"+cert.Website.Name+".pem", cert.Cert, 0644); err != nil { return acme.Certificate{}, err } - if err = tools.Write("/www/server/vhost/ssl/"+cert.Website.Name+".key", cert.Key, 0644); err != nil { + if err = io.Write("/www/server/vhost/ssl/"+cert.Website.Name+".key", cert.Key, 0644); err != nil { return acme.Certificate{}, err } if err = systemctl.Reload("openresty"); err != nil { @@ -397,10 +397,10 @@ func (s *CertImpl) Renew(ID uint) (acme.Certificate, error) { } if cert.Website != nil { - if err = tools.Write("/www/server/vhost/ssl/"+cert.Website.Name+".pem", cert.Cert, 0644); err != nil { + if err = io.Write("/www/server/vhost/ssl/"+cert.Website.Name+".pem", cert.Cert, 0644); err != nil { return acme.Certificate{}, err } - if err = tools.Write("/www/server/vhost/ssl/"+cert.Website.Name+".key", cert.Key, 0644); err != nil { + if err = io.Write("/www/server/vhost/ssl/"+cert.Website.Name+".key", cert.Key, 0644); err != nil { return acme.Certificate{}, err } if err = systemctl.Reload("openresty"); err != nil { @@ -429,10 +429,10 @@ func (s *CertImpl) Deploy(ID, WebsiteID uint) error { return err } - if err = tools.Write("/www/server/vhost/ssl/"+website.Name+".pem", cert.Cert, 0644); err != nil { + if err = io.Write("/www/server/vhost/ssl/"+website.Name+".pem", cert.Cert, 0644); err != nil { return err } - if err = tools.Write("/www/server/vhost/ssl/"+website.Name+".key", cert.Key, 0644); err != nil { + if err = io.Write("/www/server/vhost/ssl/"+website.Name+".key", cert.Key, 0644); err != nil { return err } if err = systemctl.Reload("openresty"); err != nil { diff --git a/internal/services/php.go b/internal/services/php.go index 00ca26fd..95d7056a 100644 --- a/internal/services/php.go +++ b/internal/services/php.go @@ -13,9 +13,9 @@ import ( "github.com/spf13/cast" "github.com/TheTNB/panel/app/models" + "github.com/TheTNB/panel/pkg/io" "github.com/TheTNB/panel/pkg/shell" "github.com/TheTNB/panel/pkg/systemctl" - "github.com/TheTNB/panel/pkg/tools" "github.com/TheTNB/panel/types" ) @@ -34,11 +34,11 @@ func (r *PHPImpl) Reload() error { } func (r *PHPImpl) GetConfig() (string, error) { - return tools.Read("/www/server/php/" + r.version + "/etc/php.ini") + return io.Read("/www/server/php/" + r.version + "/etc/php.ini") } func (r *PHPImpl) SaveConfig(config string) error { - if err := tools.Write("/www/server/php/"+r.version+"/etc/php.ini", config, 0644); err != nil { + if err := io.Write("/www/server/php/"+r.version+"/etc/php.ini", config, 0644); err != nil { return err } @@ -46,11 +46,11 @@ func (r *PHPImpl) SaveConfig(config string) error { } func (r *PHPImpl) GetFPMConfig() (string, error) { - return tools.Read("/www/server/php/" + r.version + "/etc/php-fpm.conf") + return io.Read("/www/server/php/" + r.version + "/etc/php-fpm.conf") } func (r *PHPImpl) SaveFPMConfig(config string) error { - if err := tools.Write("/www/server/php/"+r.version+"/etc/php-fpm.conf", config, 0644); err != nil { + if err := io.Write("/www/server/php/"+r.version+"/etc/php-fpm.conf", config, 0644); err != nil { return err } diff --git a/internal/services/plugin.go b/internal/services/plugin.go index 2efc6c26..a058b526 100644 --- a/internal/services/plugin.go +++ b/internal/services/plugin.go @@ -8,7 +8,7 @@ import ( "github.com/TheTNB/panel/app/models" "github.com/TheTNB/panel/internal" - "github.com/TheTNB/panel/pkg/tools" + "github.com/TheTNB/panel/pkg/io" "github.com/TheTNB/panel/types" ) @@ -122,7 +122,7 @@ func (r *PluginImpl) Install(slug string) error { return errors.New("创建任务失败") } - _ = tools.Remove(task.Log) + _ = io.Remove(task.Log) return r.task.Process(task.ID) } @@ -168,7 +168,7 @@ func (r *PluginImpl) Uninstall(slug string) error { return errors.New("创建任务失败") } - _ = tools.Remove(task.Log) + _ = io.Remove(task.Log) return r.task.Process(task.ID) } @@ -214,6 +214,6 @@ func (r *PluginImpl) Update(slug string) error { return errors.New("创建任务失败") } - _ = tools.Remove(task.Log) + _ = io.Remove(task.Log) return r.task.Process(task.ID) } diff --git a/internal/services/website.go b/internal/services/website.go index e5d6c988..62ee8316 100644 --- a/internal/services/website.go +++ b/internal/services/website.go @@ -16,6 +16,7 @@ import ( requests "github.com/TheTNB/panel/app/http/requests/website" "github.com/TheTNB/panel/app/models" "github.com/TheTNB/panel/internal" + "github.com/TheTNB/panel/pkg/io" "github.com/TheTNB/panel/pkg/shell" "github.com/TheTNB/panel/pkg/systemctl" "github.com/TheTNB/panel/pkg/tools" @@ -57,7 +58,7 @@ func (r *WebsiteImpl) Add(website types.Website) (models.Website, error) { return models.Website{}, err } - if err := tools.Mkdir(website.Path, 0755); err != nil { + if err := io.Mkdir(website.Path, 0755); err != nil { return models.Website{}, err } @@ -115,7 +116,7 @@ func (r *WebsiteImpl) Add(website types.Website) (models.Website, error) { ` - if err := tools.Write(website.Path+"/index.html", index, 0644); err != nil { + if err := io.Write(website.Path+"/index.html", index, 0644); err != nil { return models.Website{}, err } @@ -176,7 +177,7 @@ func (r *WebsiteImpl) Add(website types.Website) (models.Website, error) { ` - if err := tools.Write(website.Path+"/404.html", notFound, 0644); err != nil { + if err := io.Write(website.Path+"/404.html", notFound, 0644); err != nil { return models.Website{}, err } @@ -261,23 +262,23 @@ server } `, portList, domainList, website.Path, website.Php, website.Name, website.Name, website.Name) - if err := tools.Write("/www/server/vhost/"+website.Name+".conf", nginxConf, 0644); err != nil { + if err := io.Write("/www/server/vhost/"+website.Name+".conf", nginxConf, 0644); err != nil { return models.Website{}, err } - if err := tools.Write("/www/server/vhost/rewrite/"+website.Name+".conf", "", 0644); err != nil { + if err := io.Write("/www/server/vhost/rewrite/"+website.Name+".conf", "", 0644); err != nil { return models.Website{}, err } - if err := tools.Write("/www/server/vhost/ssl/"+website.Name+".pem", "", 0644); err != nil { + if err := io.Write("/www/server/vhost/ssl/"+website.Name+".pem", "", 0644); err != nil { return models.Website{}, err } - if err := tools.Write("/www/server/vhost/ssl/"+website.Name+".key", "", 0644); err != nil { + if err := io.Write("/www/server/vhost/ssl/"+website.Name+".key", "", 0644); err != nil { return models.Website{}, err } - if err := tools.Chmod(website.Path, 0755); err != nil { + if err := io.Chmod(website.Path, 0755); err != nil { return models.Website{}, err } - if err := tools.Chown(website.Path, "www", "www"); err != nil { + if err := io.Chown(website.Path, "www", "www"); err != nil { return models.Website{}, err } @@ -317,12 +318,12 @@ func (r *WebsiteImpl) SaveConfig(config requests.SaveConfig) error { } // 原文 - raw, err := tools.Read("/www/server/vhost/" + website.Name + ".conf") + raw, err := io.Read("/www/server/vhost/" + website.Name + ".conf") if err != nil { return err } if strings.TrimSpace(raw) != strings.TrimSpace(config.Raw) { - if err = tools.Write("/www/server/vhost/"+website.Name+".conf", config.Raw, 0644); err != nil { + if err = io.Write("/www/server/vhost/"+website.Name+".conf", config.Raw, 0644); err != nil { return err } if err = systemctl.Reload("openresty"); err != nil { @@ -334,7 +335,7 @@ func (r *WebsiteImpl) SaveConfig(config requests.SaveConfig) error { // 目录 path := config.Path - if !tools.Exists(path) { + if !io.Exists(path) { return errors.New("网站目录不存在") } website.Path = path @@ -415,12 +416,12 @@ func (r *WebsiteImpl) SaveConfig(config requests.SaveConfig) error { root += "/" } if config.OpenBasedir { - if err := tools.Write(root+".user.ini", "open_basedir="+path+":/tmp/", 0644); err != nil { + if err := io.Write(root+".user.ini", "open_basedir="+path+":/tmp/", 0644); err != nil { return err } } else { - if tools.Exists(root + ".user.ini") { - if err := tools.Remove(root + ".user.ini"); err != nil { + if io.Exists(root + ".user.ini") { + if err := io.Remove(root + ".user.ini"); err != nil { return err } } @@ -451,10 +452,10 @@ func (r *WebsiteImpl) SaveConfig(config requests.SaveConfig) error { // SSL ssl := config.Ssl website.Ssl = ssl - if err = tools.Write("/www/server/vhost/ssl/"+website.Name+".pem", config.SslCertificate, 0644); err != nil { + if err = io.Write("/www/server/vhost/ssl/"+website.Name+".pem", config.SslCertificate, 0644); err != nil { return err } - if err = tools.Write("/www/server/vhost/ssl/"+website.Name+".key", config.SslCertificateKey, 0644); err != nil { + if err = io.Write("/www/server/vhost/ssl/"+website.Name+".key", config.SslCertificateKey, 0644); err != nil { return err } if ssl { @@ -510,10 +511,10 @@ func (r *WebsiteImpl) SaveConfig(config requests.SaveConfig) error { return err } - if err := tools.Write("/www/server/vhost/"+website.Name+".conf", raw, 0644); err != nil { + if err := io.Write("/www/server/vhost/"+website.Name+".conf", raw, 0644); err != nil { return err } - if err := tools.Write("/www/server/vhost/rewrite/"+website.Name+".conf", config.Rewrite, 0644); err != nil { + if err := io.Write("/www/server/vhost/rewrite/"+website.Name+".conf", config.Rewrite, 0644); err != nil { return err } @@ -535,19 +536,19 @@ func (r *WebsiteImpl) Delete(id uint) error { return err } - if err := tools.Remove("/www/server/vhost/" + website.Name + ".conf"); err != nil { + if err := io.Remove("/www/server/vhost/" + website.Name + ".conf"); err != nil { return err } - if err := tools.Remove("/www/server/vhost/rewrite/" + website.Name + ".conf"); err != nil { + if err := io.Remove("/www/server/vhost/rewrite/" + website.Name + ".conf"); err != nil { return err } - if err := tools.Remove("/www/server/vhost/ssl/" + website.Name + ".pem"); err != nil { + if err := io.Remove("/www/server/vhost/ssl/" + website.Name + ".pem"); err != nil { return err } - if err := tools.Remove("/www/server/vhost/ssl/" + website.Name + ".key"); err != nil { + if err := io.Remove("/www/server/vhost/ssl/" + website.Name + ".key"); err != nil { return err } - if err := tools.Remove(website.Path); err != nil { + if err := io.Remove(website.Path); err != nil { return err } @@ -561,7 +562,7 @@ func (r *WebsiteImpl) GetConfig(id uint) (types.WebsiteSetting, error) { return types.WebsiteSetting{}, err } - config, err := tools.Read("/www/server/vhost/" + website.Name + ".conf") + config, err := io.Read("/www/server/vhost/" + website.Name + ".conf") if err != nil { return types.WebsiteSetting{}, err } @@ -608,8 +609,8 @@ func (r *WebsiteImpl) GetConfig(id uint) (types.WebsiteSetting, error) { setting.Index = match[1] } - if tools.Exists(setting.Root + "/.user.ini") { - userIni, _ := tools.Read(setting.Root + "/.user.ini") + if io.Exists(setting.Root + "/.user.ini") { + userIni, _ := io.Read(setting.Root + "/.user.ini") if strings.Contains(userIni, "open_basedir") { setting.OpenBasedir = true } else { @@ -619,9 +620,9 @@ func (r *WebsiteImpl) GetConfig(id uint) (types.WebsiteSetting, error) { setting.OpenBasedir = false } - cert, _ := tools.Read("/www/server/vhost/ssl/" + website.Name + ".pem") + cert, _ := io.Read("/www/server/vhost/ssl/" + website.Name + ".pem") setting.SslCertificate = cert - key, _ := tools.Read("/www/server/vhost/ssl/" + website.Name + ".key") + key, _ := io.Read("/www/server/vhost/ssl/" + website.Name + ".key") setting.SslCertificateKey = key if setting.Ssl { ssl := tools.Cut(config, "# ssl标记位开始", "# ssl标记位结束") @@ -659,7 +660,7 @@ func (r *WebsiteImpl) GetConfig(id uint) (types.WebsiteSetting, error) { setting.WafCache = match[1] } - rewrite, _ := tools.Read("/www/server/vhost/rewrite/" + website.Name + ".conf") + rewrite, _ := io.Read("/www/server/vhost/rewrite/" + website.Name + ".conf") setting.Rewrite = rewrite log, _ := shell.Execf(`tail -n 100 '/www/wwwlogs/%s.log'`, website.Name) setting.Log = log diff --git a/pkg/io/file.go b/pkg/io/file.go new file mode 100644 index 00000000..88495db5 --- /dev/null +++ b/pkg/io/file.go @@ -0,0 +1,85 @@ +package io + +import ( + "os" + "path/filepath" + "strings" + + "github.com/mholt/archiver/v3" +) + +// Write 写入文件 +func Write(path string, data string, permission os.FileMode) error { + if err := os.MkdirAll(filepath.Dir(path), permission); err != nil { + return err + } + + err := os.WriteFile(path, []byte(data), permission) + if err != nil { + return err + } + + return nil +} + +// WriteAppend 追加写入文件 +func WriteAppend(path string, data string) error { + file, err := os.OpenFile(path, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) + if err != nil { + return err + } + defer file.Close() + + _, err = file.WriteString(data) + if err != nil { + return err + } + + return nil +} + +// Read 读取文件 +func Read(path string) (string, error) { + data, err := os.ReadFile(path) + return string(data), err +} + +// FileInfo 获取文件大小 +func FileInfo(path string) (os.FileInfo, error) { + return os.Stat(path) +} + +// UnArchive 智能解压文件 +func UnArchive(file string, dst string) error { + return archiver.Unarchive(file, dst) +} + +// Archive 智能压缩文件 +func Archive(src []string, dst string) error { + return archiver.Archive(src, dst) +} + +// TempFile 创建临时文件 +func TempFile(prefix string) (*os.File, error) { + return os.CreateTemp("", prefix) +} + +// IsSymlink 判读是否为软链接 +func IsSymlink(mode os.FileMode) bool { + return mode&os.ModeSymlink != 0 +} + +// IsHidden 判断是否为隐藏文件 +func IsHidden(path string) bool { + _, file := filepath.Split(path) + return strings.HasPrefix(file, ".") +} + +// GetSymlink 获取软链接目标 +func GetSymlink(path string) string { + linkPath, err := os.Readlink(path) + if err != nil { + return "" + } + return linkPath +} diff --git a/pkg/tools/system.go b/pkg/io/path.go similarity index 58% rename from pkg/tools/system.go rename to pkg/io/path.go index c359d750..52b2837b 100644 --- a/pkg/tools/system.go +++ b/pkg/io/path.go @@ -1,4 +1,4 @@ -package tools +package io import ( "errors" @@ -6,51 +6,11 @@ import ( "io" "os" "os/exec" - "os/user" "path/filepath" - "strings" "github.com/goravel/framework/support/env" - "github.com/mholt/archiver/v3" - "github.com/spf13/cast" ) -// Write 写入文件 -func Write(path string, data string, permission os.FileMode) error { - if err := os.MkdirAll(filepath.Dir(path), permission); err != nil { - return err - } - - err := os.WriteFile(path, []byte(data), permission) - if err != nil { - return err - } - - return nil -} - -// WriteAppend 追加写入文件 -func WriteAppend(path string, data string) error { - file, err := os.OpenFile(path, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) - if err != nil { - return err - } - defer file.Close() - - _, err = file.WriteString(data) - if err != nil { - return err - } - - return nil -} - -// Read 读取文件 -func Read(path string) (string, error) { - data, err := os.ReadFile(path) - return string(data), err -} - // Remove 删除文件/目录 func Remove(path string) error { return os.RemoveAll(path) @@ -191,65 +151,7 @@ func Size(path string) (int64, error) { return size, err } -// FileInfo 获取文件大小 -func FileInfo(path string) (os.FileInfo, error) { - return os.Stat(path) -} - -// UnArchive 智能解压文件 -func UnArchive(file string, dst string) error { - return archiver.Unarchive(file, dst) -} - -// Archive 智能压缩文件 -func Archive(src []string, dst string) error { - return archiver.Archive(src, dst) -} - // TempDir 创建临时目录 func TempDir(prefix string) (string, error) { return os.MkdirTemp("", prefix) } - -// TempFile 创建临时文件 -func TempFile(prefix string) (*os.File, error) { - return os.CreateTemp("", prefix) -} - -// IsSymlink 判读是否为软链接 -func IsSymlink(mode os.FileMode) bool { - return mode&os.ModeSymlink != 0 -} - -// IsHidden 判断是否为隐藏文件 -func IsHidden(path string) bool { - _, file := filepath.Split(path) - return strings.HasPrefix(file, ".") -} - -// GetSymlink 获取软链接目标 -func GetSymlink(path string) string { - linkPath, err := os.Readlink(path) - if err != nil { - return "" - } - return linkPath -} - -// GetUser 通过 uid 获取用户名 -func GetUser(uid uint32) string { - usr, err := user.LookupId(cast.ToString(uid)) - if err != nil { - return "" - } - return usr.Username -} - -// GetGroup 通过 gid 获取组名 -func GetGroup(gid uint32) string { - usr, err := user.LookupGroupId(cast.ToString(gid)) - if err != nil { - return "" - } - return usr.Name -} diff --git a/pkg/ssh/ssh.go b/pkg/ssh/ssh.go index 326c8b9b..be7a35fe 100644 --- a/pkg/ssh/ssh.go +++ b/pkg/ssh/ssh.go @@ -5,7 +5,7 @@ import ( "golang.org/x/crypto/ssh" - "github.com/TheTNB/panel/pkg/tools" + "github.com/TheTNB/panel/pkg/io" ) type AuthMethod int8 @@ -68,7 +68,7 @@ func NewSSHClient(conf *ClientConfig) (*ssh.Client, error) { } func getKey(keyPath string) (ssh.Signer, error) { - key, err := tools.Read(keyPath) + key, err := io.Read(keyPath) if err != nil { return nil, err } diff --git a/pkg/tools/system_test.go b/pkg/tools/system_test.go deleted file mode 100644 index f1e758c7..00000000 --- a/pkg/tools/system_test.go +++ /dev/null @@ -1,330 +0,0 @@ -package tools - -import ( - "os/user" - "path/filepath" - "testing" - "time" - - "github.com/goravel/framework/support/env" - "github.com/stretchr/testify/suite" -) - -type SystemHelperTestSuite struct { - suite.Suite -} - -func TestSystemHelperTestSuite(t *testing.T) { - suite.Run(t, &SystemHelperTestSuite{}) -} - -func (s *SystemHelperTestSuite) WriteCreatesFileWithCorrectContent() { - filePath, _ := TempFile("testfile") - - err := Write(filePath.Name(), "test data", 0644) - s.Nil(err) - - content, _ := Read(filePath.Name()) - s.Equal("test data", content) - s.Nil(filePath.Close()) - s.Nil(Remove(filePath.Name())) -} - -func (s *SystemHelperTestSuite) WriteCreatesDirectoriesIfNeeded() { - filePath, _ := TempFile("testdir/testfile") - - err := Write(filePath.Name(), "test data", 0644) - s.Nil(err) - - content, _ := Read(filePath.Name()) - s.Equal("test data", content) - s.Nil(filePath.Close()) - s.Nil(Remove(filePath.Name())) -} - -func (s *SystemHelperTestSuite) WriteFailsIfDirectoryCannotBeCreated() { - filePath := "/nonexistent/testfile" - - err := Write(filePath, "test data", 0644) - s.NotNil(err) -} - -func (s *SystemHelperTestSuite) WriteFailsIfFileCannotBeWritten() { - filePath, _ := TempFile("testfile") - s.Nil(filePath.Close()) - s.Nil(Chmod(filePath.Name(), 0400)) - - err := Write(filePath.Name(), "test data", 0644) - s.NotNil(err) - - s.Nil(Chmod(filePath.Name(), 0644)) - s.Nil(Remove(filePath.Name())) -} - -func (s *SystemHelperTestSuite) WriteAppendSuccessfullyAppendsDataToFile() { - filePath, _ := TempFile("testfile") - - err := Write(filePath.Name(), "initial data", 0644) - s.Nil(err) - - err = WriteAppend(filePath.Name(), " appended data") - s.Nil(err) - - content, _ := Read(filePath.Name()) - s.Equal("initial data appended data", content) - s.Nil(filePath.Close()) - s.Nil(Remove(filePath.Name())) -} - -func (s *SystemHelperTestSuite) WriteAppendCreatesFileIfNotExists() { - filePath, _ := TempFile("testfile") - s.Nil(filePath.Close()) - s.Nil(Remove(filePath.Name())) - - err := WriteAppend(filePath.Name(), "test data") - s.Nil(err) - - content, _ := Read(filePath.Name()) - s.Equal("test data", content) - s.Nil(Remove(filePath.Name())) -} - -func (s *SystemHelperTestSuite) WriteAppendReturnsErrorIfPathIsADirectory() { - dirPath, _ := TempDir("testdir") - - err := WriteAppend(dirPath, "test data") - s.NotNil(err) - - s.Nil(Remove(dirPath)) -} - -func (s *SystemHelperTestSuite) ReadSuccessfullyReadsFileContent() { - filePath, _ := TempFile("testfile") - - err := Write(filePath.Name(), "test data", 0644) - s.Nil(err) - - content, err := Read(filePath.Name()) - s.Nil(err) - s.Equal("test data", content) - - s.Nil(filePath.Close()) - s.Nil(Remove(filePath.Name())) -} - -func (s *SystemHelperTestSuite) ReadReturnsErrorForNonExistentFile() { - _, err := Read("/nonexistent/testfile") - s.NotNil(err) -} - -func (s *SystemHelperTestSuite) RemoveSuccessfullyRemovesFile() { - filePath, _ := TempFile("testfile") - - err := Write(filePath.Name(), "test data", 0644) - s.Nil(err) - - err = Remove(filePath.Name()) - s.Nil(err) - - s.False(Exists(filePath.Name())) -} - -func (s *SystemHelperTestSuite) RemoveReturnsErrorForNonExistentFile() { - err := Remove("/nonexistent/testfile") - s.NotNil(err) -} - -func (s *SystemHelperTestSuite) TestExec() { - output, err := Exec("echo test") - s.Equal("test", output) - s.Nil(err) -} - -func (s *SystemHelperTestSuite) TestExecAsync() { - command := "echo test > test.txt" - if env.IsWindows() { - command = "echo test> test.txt" - } - - err := ExecAsync(command) - s.Nil(err) - - time.Sleep(time.Second) - - content, err := Read("test.txt") - s.Nil(err) - - condition := "test\n" - if env.IsWindows() { - condition = "test\r\n" - } - s.Equal(condition, content) - s.Nil(Remove("test.txt")) -} - -func (s *SystemHelperTestSuite) TestMkdir() { - dirPath, _ := TempDir("testdir") - - s.Nil(Mkdir(dirPath, 0755)) - s.Nil(Remove(dirPath)) -} - -func (s *SystemHelperTestSuite) TestChmod() { - filePath, _ := TempFile("testfile") - - err := Write(filePath.Name(), "test data", 0644) - s.Nil(err) - - s.Nil(filePath.Close()) - s.Nil(Chmod(filePath.Name(), 0755)) - s.Nil(Remove(filePath.Name())) -} - -func (s *SystemHelperTestSuite) TestChown() { - filePath, _ := TempFile("testfile") - - err := Write(filePath.Name(), "test data", 0644) - s.Nil(err) - - currentUser, err := user.Current() - s.Nil(err) - groups, err := currentUser.GroupIds() - s.Nil(err) - - err = Chown(filePath.Name(), currentUser.Username, groups[0]) - if env.IsWindows() { - s.NotNil(err) - } else { - s.Nil(err) - } - s.Nil(filePath.Close()) - s.Nil(Remove(filePath.Name())) -} - -func (s *SystemHelperTestSuite) TestExists() { - filePath, _ := TempFile("testfile") - - s.True(Exists(filePath.Name())) - s.False(Exists("123")) - s.Nil(filePath.Close()) - s.Nil(Remove(filePath.Name())) -} - -func (s *SystemHelperTestSuite) TestEmpty() { - filePath, _ := TempFile("testfile") - - s.True(Empty(filePath.Name())) - if env.IsWindows() { - s.True(Empty("C:\\Windows\\System32\\drivers\\etc\\hosts")) - } else { - s.True(Empty("/etc/hosts")) - } - s.Nil(filePath.Close()) - s.Nil(Remove(filePath.Name())) -} - -func (s *SystemHelperTestSuite) TestMv() { - filePath, _ := TempFile("testfile") - - err := Write(filePath.Name(), "test data", 0644) - s.Nil(err) - - newFilePath, _ := TempFile("testfile2") - - s.Nil(newFilePath.Close()) - s.Nil(filePath.Close()) - - s.Nil(Mv(filePath.Name(), newFilePath.Name())) - s.False(Exists(filePath.Name())) - s.Nil(Remove(newFilePath.Name())) - s.Nil(Remove(filePath.Name())) -} - -func (s *SystemHelperTestSuite) TestCp() { - tempDir, _ := TempDir("testdir") - - err := Write(filepath.Join(tempDir, "testfile"), "test data", 0644) - s.Nil(err) - - s.Nil(Cp(filepath.Join(tempDir, "testfile"), filepath.Join(tempDir, "testfile2"))) - s.True(Exists(filepath.Join(tempDir, "testfile2"))) - s.Nil(Remove(tempDir)) -} - -func (s *SystemHelperTestSuite) TestSize() { - filePath, _ := TempFile("testfile") - - err := Write(filePath.Name(), "test data", 0644) - s.Nil(err) - - size, err := Size(filePath.Name()) - s.Nil(err) - s.Equal(int64(len("test data")), size) - s.Nil(filePath.Close()) - s.Nil(Remove(filePath.Name())) -} - -func (s *SystemHelperTestSuite) TestFileInfo() { - filePath, _ := TempFile("testfile") - - err := Write(filePath.Name(), "test data", 0644) - s.Nil(err) - - info, err := FileInfo(filePath.Name()) - s.Nil(err) - s.Equal(filepath.Base(filePath.Name()), info.Name()) - s.Nil(filePath.Close()) - s.Nil(Remove(filePath.Name())) -} - -func (s *SystemHelperTestSuite) TestUnArchiveSuccessfullyUnarchivesFile() { - file, _ := TempFile("test") - dstDir, _ := TempDir("archive") - - err := Write(file.Name(), "test data", 0644) - s.Nil(err) - - err = Archive([]string{file.Name()}, filepath.Join(dstDir, "test.zip")) - s.Nil(err) - s.FileExists(filepath.Join(dstDir, "test.zip")) - - err = UnArchive(filepath.Join(dstDir, "test.zip"), dstDir) - s.Nil(err) - s.FileExists(filepath.Join(dstDir, filepath.Base(file.Name()))) - s.Nil(file.Close()) - s.Nil(Remove(file.Name())) - s.Nil(Remove(dstDir)) -} - -func (s *SystemHelperTestSuite) TestUnArchiveFailsForNonExistentFile() { - srcFile := "nonexistent.zip" - dstDir, _ := TempDir("unarchived") - - err := UnArchive(srcFile, dstDir) - s.NotNil(err) - s.Nil(Remove(dstDir)) -} - -func (s *SystemHelperTestSuite) TestArchiveSuccessfullyArchivesFiles() { - srcFile, _ := TempFile("test") - dstDir, _ := TempDir("archive") - - err := Write(srcFile.Name(), "test data", 0644) - s.Nil(err) - - err = Archive([]string{srcFile.Name()}, filepath.Join(dstDir, "test.zip")) - s.Nil(err) - s.FileExists(filepath.Join(dstDir, "test.zip")) - s.Nil(srcFile.Close()) - s.Nil(Remove(srcFile.Name())) - s.Nil(Remove(dstDir)) -} - -func (s *SystemHelperTestSuite) TestArchiveFailsForNonExistentFiles() { - srcFile := "nonexistent" - dstDir, _ := TempDir("archive") - - err := Archive([]string{srcFile}, filepath.Join(dstDir, "test.zip")) - s.NotNil(err) - s.Nil(Remove(dstDir)) -} diff --git a/pkg/tools/tools.go b/pkg/tools/tools.go index 77dbceb0..6de9c682 100644 --- a/pkg/tools/tools.go +++ b/pkg/tools/tools.go @@ -20,6 +20,7 @@ import ( "github.com/shirou/gopsutil/net" "github.com/spf13/cast" + "github.com/TheTNB/panel/pkg/io" "github.com/TheTNB/panel/pkg/shell" ) @@ -393,13 +394,13 @@ func UpdatePanel(panelInfo PanelInfo) error { color.Green().Printfln("下载链接: " + panelInfo.DownloadUrl) color.Green().Printfln("前置检查...") - if Exists("/tmp/panel-storage.zip") || Exists("/tmp/panel.conf.bak") { + if io.Exists("/tmp/panel-storage.zip") || io.Exists("/tmp/panel.conf.bak") { return errors.New("检测到 /tmp 存在临时文件,可能是上次更新失败导致的,请谨慎排除后重试") } color.Green().Printfln("备份面板数据...") // 备份面板 - if err := Archive([]string{"/www/panel"}, "/www/backup/panel/panel-"+carbon.Now().ToShortDateTimeString()+".zip"); err != nil { + if err := io.Archive([]string{"/www/panel"}, "/www/backup/panel/panel-"+carbon.Now().ToShortDateTimeString()+".zip"); err != nil { color.Red().Printfln("备份面板失败") return err } @@ -411,7 +412,7 @@ func UpdatePanel(panelInfo PanelInfo) error { color.Red().Printfln("备份面板配置失败") return err } - if !Exists("/tmp/panel-storage.zip") || !Exists("/tmp/panel.conf.bak") { + if !io.Exists("/tmp/panel-storage.zip") || !io.Exists("/tmp/panel.conf.bak") { return errors.New("备份面板数据失败") } color.Green().Printfln("备份完成") @@ -432,7 +433,7 @@ func UpdatePanel(panelInfo PanelInfo) error { color.Red().Printfln("下载失败") return err } - if !Exists("/www/panel/"+panelInfo.DownloadName) || !Exists("/www/panel/"+panelInfo.Checksums) { + if !io.Exists("/www/panel/"+panelInfo.DownloadName) || !io.Exists("/www/panel/"+panelInfo.Checksums) { return errors.New("下载失败") } color.Green().Printfln("下载完成") @@ -442,7 +443,7 @@ func UpdatePanel(panelInfo PanelInfo) error { if check != panelInfo.DownloadName+": OK" || err != nil { return errors.New("下载文件校验失败") } - if err = Remove("/www/panel/" + panelInfo.Checksums); err != nil { + if err = io.Remove("/www/panel/" + panelInfo.Checksums); err != nil { color.Red().Printfln("清理临时文件失败") return err } @@ -453,7 +454,7 @@ func UpdatePanel(panelInfo PanelInfo) error { color.Red().Printfln("更新失败") return err } - if !Exists("/www/panel/panel") { + if !io.Exists("/www/panel/panel") { return errors.New("更新失败,可能是下载过程中出现了问题") } color.Green().Printfln("更新完成") @@ -471,7 +472,7 @@ func UpdatePanel(panelInfo PanelInfo) error { color.Red().Printfln("恢复面板脚本失败") return err } - if !Exists("/www/panel/storage/panel.db") || !Exists("/www/panel/panel.conf") { + if !io.Exists("/www/panel/storage/panel.db") || !io.Exists("/www/panel/panel.conf") { return errors.New("恢复面板数据失败") } color.Green().Printfln("恢复完成") diff --git a/pkg/tools/user.go b/pkg/tools/user.go new file mode 100644 index 00000000..eb0dd8b9 --- /dev/null +++ b/pkg/tools/user.go @@ -0,0 +1,24 @@ +package tools + +import ( + "github.com/spf13/cast" + "os/user" +) + +// GetUser 通过 uid 获取用户名 +func GetUser(uid uint32) string { + usr, err := user.LookupId(cast.ToString(uid)) + if err != nil { + return "" + } + return usr.Username +} + +// GetGroup 通过 gid 获取组名 +func GetGroup(gid uint32) string { + usr, err := user.LookupGroupId(cast.ToString(gid)) + if err != nil { + return "" + } + return usr.Name +}