mirror of
https://github.com/acepanel/panel.git
synced 2026-02-04 09:13:49 +08:00
refactor: 重构shell命令执行
This commit is contained in:
@@ -17,6 +17,7 @@ import (
|
||||
|
||||
"github.com/TheTNB/panel/app/models"
|
||||
"github.com/TheTNB/panel/internal/services"
|
||||
"github.com/TheTNB/panel/pkg/shell"
|
||||
"github.com/TheTNB/panel/pkg/tools"
|
||||
"github.com/TheTNB/panel/types"
|
||||
)
|
||||
@@ -143,7 +144,7 @@ func (receiver *Panel) Handle(ctx console.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
port, err := tools.Exec(`cat /www/panel/panel.conf | grep APP_PORT | awk -F '=' '{print $2}' | tr -d '\n'`)
|
||||
port, err := shell.Execf(`cat /www/panel/panel.conf | grep APP_PORT | awk -F '=' '{print $2}' | tr -d '\n'`)
|
||||
if err != nil {
|
||||
color.Red().Printfln(translate.Get("commands.panel.portFail"))
|
||||
return nil
|
||||
@@ -164,7 +165,7 @@ func (receiver *Panel) Handle(ctx console.Context) error {
|
||||
color.Green().Printfln(translate.Get("commands.panel.getInfo.address") + ": " + protocol + "://" + ip + ":" + port + facades.Config().GetString("http.entrance"))
|
||||
|
||||
case "getPort":
|
||||
port, err := tools.Exec(`cat /www/panel/panel.conf | grep APP_PORT | awk -F '=' '{print $2}' | tr -d '\n'`)
|
||||
port, err := shell.Execf(`cat /www/panel/panel.conf | grep APP_PORT | awk -F '=' '{print $2}' | tr -d '\n'`)
|
||||
if err != nil {
|
||||
color.Red().Printfln(translate.Get("commands.panel.portFail"))
|
||||
return nil
|
||||
@@ -176,12 +177,12 @@ func (receiver *Panel) Handle(ctx console.Context) error {
|
||||
color.Green().Printfln(translate.Get("commands.panel.entrance") + ": " + facades.Config().GetString("http.entrance"))
|
||||
|
||||
case "deleteEntrance":
|
||||
oldEntrance, err := tools.Exec(`cat /www/panel/panel.conf | grep APP_ENTRANCE | awk -F '=' '{print $2}' | tr -d '\n'`)
|
||||
oldEntrance, err := shell.Execf(`cat /www/panel/panel.conf | grep APP_ENTRANCE | awk -F '=' '{print $2}' | tr -d '\n'`)
|
||||
if err != nil {
|
||||
color.Red().Printfln(translate.Get("commands.panel.deleteEntrance.fail"))
|
||||
return nil
|
||||
}
|
||||
if _, err = tools.Exec("sed -i 's!APP_ENTRANCE=" + oldEntrance + "!APP_ENTRANCE=/!g' /www/panel/panel.conf"); err != nil {
|
||||
if _, err = shell.Execf("sed -i 's!APP_ENTRANCE=" + oldEntrance + "!APP_ENTRANCE=/!g' /www/panel/panel.conf"); err != nil {
|
||||
color.Red().Printfln(translate.Get("commands.panel.deleteEntrance.fail"))
|
||||
return nil
|
||||
}
|
||||
@@ -288,7 +289,7 @@ func (receiver *Panel) Handle(ctx console.Context) error {
|
||||
}
|
||||
|
||||
backupFile := path + "/" + website.Name + "_" + carbon.Now().ToShortDateTimeString() + ".zip"
|
||||
if _, err := tools.Exec(`cd '` + website.Path + `' && zip -r '` + backupFile + `' .`); err != nil {
|
||||
if _, err := shell.Execf(`cd '` + website.Path + `' && zip -r '` + backupFile + `' .`); err != nil {
|
||||
color.Red().Printfln("|-" + translate.Get("commands.panel.backup.backupFail") + ": " + err.Error())
|
||||
return nil
|
||||
}
|
||||
@@ -307,13 +308,13 @@ func (receiver *Panel) Handle(ctx console.Context) error {
|
||||
|
||||
color.Green().Printfln("|-" + translate.Get("commands.panel.backup.targetMysql") + ": " + name)
|
||||
color.Green().Printfln("|-" + translate.Get("commands.panel.backup.startExport"))
|
||||
if _, err = tools.Exec(`mysqldump -uroot ` + name + ` > /tmp/` + backupFile + ` 2>&1`); err != nil {
|
||||
if _, err = shell.Execf(`mysqldump -uroot ` + name + ` > /tmp/` + backupFile + ` 2>&1`); err != nil {
|
||||
color.Red().Printfln("|-" + translate.Get("commands.panel.backup.exportFail") + ": " + err.Error())
|
||||
return nil
|
||||
}
|
||||
color.Green().Printfln("|-" + translate.Get("commands.panel.backup.exportSuccess"))
|
||||
color.Green().Printfln("|-" + translate.Get("commands.panel.backup.startCompress"))
|
||||
if _, err = tools.Exec("cd /tmp && zip -r " + backupFile + ".zip " + backupFile); err != nil {
|
||||
if _, err = shell.Execf("cd /tmp && zip -r " + backupFile + ".zip " + backupFile); err != nil {
|
||||
color.Red().Printfln("|-" + translate.Get("commands.panel.backup.compressFail") + ": " + err.Error())
|
||||
return nil
|
||||
}
|
||||
@@ -333,7 +334,7 @@ func (receiver *Panel) Handle(ctx console.Context) error {
|
||||
|
||||
case "postgresql":
|
||||
backupFile := name + "_" + carbon.Now().ToShortDateTimeString() + ".sql"
|
||||
check, err := tools.Exec(`su - postgres -c "psql -l" 2>&1`)
|
||||
check, err := shell.Execf(`su - postgres -c "psql -l" 2>&1`)
|
||||
if err != nil {
|
||||
color.Red().Printfln("|-" + translate.Get("commands.panel.backup.databaseGetFail") + ": " + err.Error())
|
||||
color.Green().Printfln(hr)
|
||||
@@ -347,13 +348,13 @@ func (receiver *Panel) Handle(ctx console.Context) error {
|
||||
|
||||
color.Green().Printfln("|-" + translate.Get("commands.panel.backup.targetPostgres") + ": " + name)
|
||||
color.Green().Printfln("|-" + translate.Get("commands.panel.backup.startExport"))
|
||||
if _, err = tools.Exec(`su - postgres -c "pg_dump '` + name + `'" > /tmp/` + backupFile + ` 2>&1`); err != nil {
|
||||
if _, err = shell.Execf(`su - postgres -c "pg_dump '` + name + `'" > /tmp/` + backupFile + ` 2>&1`); err != nil {
|
||||
color.Red().Printfln("|-" + translate.Get("commands.panel.backup.exportFail") + ": " + err.Error())
|
||||
return nil
|
||||
}
|
||||
color.Green().Printfln("|-" + translate.Get("commands.panel.backup.exportSuccess"))
|
||||
color.Green().Printfln("|-" + translate.Get("commands.panel.backup.startCompress"))
|
||||
if _, err = tools.Exec("cd /tmp && zip -r " + backupFile + ".zip " + backupFile); err != nil {
|
||||
if _, err = shell.Execf("cd /tmp && zip -r " + backupFile + ".zip " + backupFile); err != nil {
|
||||
color.Red().Printfln("|-" + translate.Get("commands.panel.backup.compressFail") + ": " + err.Error())
|
||||
return nil
|
||||
}
|
||||
@@ -432,11 +433,11 @@ func (receiver *Panel) Handle(ctx console.Context) error {
|
||||
}
|
||||
|
||||
backupPath := "/www/wwwlogs/" + website.Name + "_" + carbon.Now().ToShortDateTimeString() + ".log.zip"
|
||||
if _, err := tools.Exec(`cd /www/wwwlogs && zip -r ` + backupPath + ` ` + website.Name + ".log"); err != nil {
|
||||
if _, err := shell.Execf(`cd /www/wwwlogs && zip -r ` + backupPath + ` ` + website.Name + ".log"); err != nil {
|
||||
color.Red().Printfln("|-" + translate.Get("commands.panel.cutoff.backupFail") + ": " + err.Error())
|
||||
return nil
|
||||
}
|
||||
if _, err := tools.Exec(`echo "" > ` + logPath); err != nil {
|
||||
if _, err := shell.Execf(`echo "" > ` + logPath); err != nil {
|
||||
color.Red().Printfln("|-" + translate.Get("commands.panel.cutoff.clearFail") + ": " + err.Error())
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
"github.com/goravel/framework/facades"
|
||||
"github.com/goravel/framework/support/carbon"
|
||||
|
||||
"github.com/TheTNB/panel/pkg/shell"
|
||||
"github.com/TheTNB/panel/pkg/tools"
|
||||
"github.com/TheTNB/panel/types"
|
||||
)
|
||||
@@ -58,7 +59,7 @@ func (receiver *PanelTask) Handle(console.Context) error {
|
||||
}
|
||||
|
||||
// 清理 7 天前的备份
|
||||
if _, err := tools.Exec(`find /www/backup/panel -mtime +7 -name "*.zip" -exec rm -rf {} \;`); err != nil {
|
||||
if _, err := shell.Execf(`find /www/backup/panel -mtime +7 -name "*.zip" -exec rm -rf {} \;`); err != nil {
|
||||
types.Status = types.StatusFailed
|
||||
facades.Log().Tags("面板", "每日任务").
|
||||
With(map[string]any{
|
||||
|
||||
@@ -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/shell"
|
||||
"github.com/TheTNB/panel/pkg/tools"
|
||||
)
|
||||
|
||||
@@ -65,7 +66,7 @@ func (r *CronController) Add(ctx http.Context) http.Response {
|
||||
return Error(ctx, http.StatusUnprocessableEntity, "时间格式错误")
|
||||
}
|
||||
|
||||
shell := ctx.Request().Input("script")
|
||||
script := ctx.Request().Input("script")
|
||||
cronType := ctx.Request().Input("type")
|
||||
if cronType == "backup" {
|
||||
backupType := ctx.Request().Input("backup_type")
|
||||
@@ -78,7 +79,7 @@ func (r *CronController) Add(ctx http.Context) http.Response {
|
||||
backupPath = r.setting.Get(models.SettingKeyBackupPath) + "/" + backupType
|
||||
}
|
||||
backupSave := ctx.Request().InputInt("save", 10)
|
||||
shell = `#!/bin/bash
|
||||
script = `#!/bin/bash
|
||||
export PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:$PATH
|
||||
|
||||
# 耗子面板 - 数据备份脚本
|
||||
@@ -95,7 +96,7 @@ panel backup ${type} ${name} ${path} ${save} 2>&1
|
||||
if cronType == "cutoff" {
|
||||
website := ctx.Request().Input("website")
|
||||
save := ctx.Request().InputInt("save", 180)
|
||||
shell = `#!/bin/bash
|
||||
script = `#!/bin/bash
|
||||
export PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:$PATH
|
||||
|
||||
# 耗子面板 - 日志切割脚本
|
||||
@@ -117,10 +118,10 @@ panel cutoff ${name} ${save} 2>&1
|
||||
return Error(ctx, http.StatusInternalServerError, "计划任务日志目录不存在")
|
||||
}
|
||||
shellFile := strconv.Itoa(int(carbon.Now().Timestamp())) + tools.RandomString(16)
|
||||
if err := tools.Write(shellDir+shellFile+".sh", shell, 0700); err != nil {
|
||||
if err := tools.Write(shellDir+shellFile+".sh", script, 0700); err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
if out, err := tools.Exec("dos2unix " + shellDir + shellFile + ".sh"); err != nil {
|
||||
if out, err := shell.Execf("dos2unix " + shellDir + shellFile + ".sh"); err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
|
||||
@@ -156,12 +157,12 @@ func (r *CronController) Script(ctx http.Context) http.Response {
|
||||
return Error(ctx, http.StatusUnprocessableEntity, "计划任务不存在")
|
||||
}
|
||||
|
||||
shell, err := tools.Read(cron.Shell)
|
||||
script, err := tools.Read(cron.Shell)
|
||||
if err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
|
||||
return Success(ctx, shell)
|
||||
return Success(ctx, script)
|
||||
}
|
||||
|
||||
// Update 更新计划任务
|
||||
@@ -200,7 +201,7 @@ func (r *CronController) Update(ctx http.Context) http.Response {
|
||||
if err := tools.Write(cron.Shell, ctx.Request().Input("script"), 0644); err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
if out, err := tools.Exec("dos2unix " + cron.Shell); err != nil {
|
||||
if out, err := shell.Execf("dos2unix " + cron.Shell); err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
|
||||
@@ -284,7 +285,7 @@ func (r *CronController) Log(ctx http.Context) http.Response {
|
||||
return Error(ctx, http.StatusUnprocessableEntity, "日志文件不存在")
|
||||
}
|
||||
|
||||
log, err := tools.Exec("tail -n 1000 " + cron.Log)
|
||||
log, err := shell.Execf("tail -n 1000 " + cron.Log)
|
||||
if err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
|
||||
@@ -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/shell"
|
||||
"github.com/TheTNB/panel/pkg/tools"
|
||||
)
|
||||
|
||||
@@ -42,7 +43,7 @@ func (r *FileController) Create(ctx http.Context) http.Response {
|
||||
|
||||
isDir := ctx.Request().InputBool("dir")
|
||||
if !isDir {
|
||||
if out, err := tools.Exec("touch " + request.Path); err != nil {
|
||||
if out, err := shell.Execf("touch " + request.Path); err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -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/shell"
|
||||
"github.com/TheTNB/panel/pkg/tools"
|
||||
"github.com/TheTNB/panel/types"
|
||||
)
|
||||
@@ -152,7 +153,7 @@ func (r *InfoController) CountInfo(ctx http.Context) http.Response {
|
||||
if postgresqlInstalled {
|
||||
status, err := tools.ServiceStatus("postgresql")
|
||||
if status && err == nil {
|
||||
raw, err := tools.Exec(`echo "\l" | su - postgres -c "psql"`)
|
||||
raw, err := shell.Execf(`echo "\l" | su - postgres -c "psql"`)
|
||||
if err == nil {
|
||||
databases := strings.Split(raw, "\n")
|
||||
if len(databases) >= 4 {
|
||||
@@ -173,7 +174,7 @@ func (r *InfoController) CountInfo(ctx http.Context) http.Response {
|
||||
var ftpCount int64
|
||||
var ftpPlugin = r.plugin.GetInstalledBySlug("pureftpd")
|
||||
if ftpPlugin.ID != 0 {
|
||||
listRaw, err := tools.Exec("pure-pw list")
|
||||
listRaw, err := shell.Execf("pure-pw list")
|
||||
if len(listRaw) != 0 && err == nil {
|
||||
listArr := strings.Split(listRaw, "\n")
|
||||
ftpCount = int64(len(listArr))
|
||||
|
||||
@@ -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/shell"
|
||||
"github.com/TheTNB/panel/pkg/tools"
|
||||
"github.com/TheTNB/panel/types"
|
||||
)
|
||||
@@ -171,15 +172,15 @@ ignoreregex =
|
||||
logPath = "/var/log/secure"
|
||||
}
|
||||
filter = "sshd"
|
||||
port, err = tools.Exec("cat /etc/ssh/sshd_config | grep 'Port ' | awk '{print $2}'")
|
||||
port, err = shell.Execf("cat /etc/ssh/sshd_config | grep 'Port ' | awk '{print $2}'")
|
||||
case "mysql":
|
||||
logPath = "/www/server/mysql/mysql-error.log"
|
||||
filter = "mysqld-auth"
|
||||
port, err = tools.Exec("cat /www/server/mysql/conf/my.cnf | grep 'port' | head -n 1 | awk '{print $3}'")
|
||||
port, err = shell.Execf("cat /www/server/mysql/conf/my.cnf | grep 'port' | head -n 1 | awk '{print $3}'")
|
||||
case "pure-ftpd":
|
||||
logPath = "/var/log/messages"
|
||||
filter = "pure-ftpd"
|
||||
port, err = tools.Exec(`cat /www/server/pure-ftpd/etc/pure-ftpd.conf | grep "Bind" | awk '{print $2}' | awk -F "," '{print $2}'`)
|
||||
port, err = shell.Execf(`cat /www/server/pure-ftpd/etc/pure-ftpd.conf | grep "Bind" | awk '{print $2}' | awk -F "," '{print $2}'`)
|
||||
default:
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, "未知服务")
|
||||
}
|
||||
@@ -206,7 +207,7 @@ logpath = ` + logPath + `
|
||||
}
|
||||
}
|
||||
|
||||
if _, err := tools.Exec("fail2ban-client reload"); err != nil {
|
||||
if _, err := shell.Execf("fail2ban-client reload"); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "重载配置失败")
|
||||
}
|
||||
|
||||
@@ -231,7 +232,7 @@ func (r *Fail2banController) Delete(ctx http.Context) http.Response {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "写入Fail2ban规则失败")
|
||||
}
|
||||
|
||||
if _, err := tools.Exec("fail2ban-client reload"); err != nil {
|
||||
if _, err := shell.Execf("fail2ban-client reload"); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "重载配置失败")
|
||||
}
|
||||
|
||||
@@ -245,15 +246,15 @@ func (r *Fail2banController) BanList(ctx http.Context) http.Response {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, "缺少参数")
|
||||
}
|
||||
|
||||
currentlyBan, err := tools.Exec(`fail2ban-client status ` + name + ` | grep "Currently banned" | awk '{print $4}'`)
|
||||
currentlyBan, err := shell.Execf(`fail2ban-client status %s | grep "Currently banned" | awk '{print $4}'`, name)
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取封禁列表失败")
|
||||
}
|
||||
totalBan, err := tools.Exec(`fail2ban-client status ` + name + ` | grep "Total banned" | awk '{print $4}'`)
|
||||
totalBan, err := shell.Execf(`fail2ban-client status %s | grep "Total banned" | awk '{print $4}'`, name)
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取封禁列表失败")
|
||||
}
|
||||
bannedIp, err := tools.Exec(`fail2ban-client status ` + name + ` | grep "Banned IP list" | awk -F ":" '{print $2}'`)
|
||||
bannedIp, err := shell.Execf(`fail2ban-client status %s | grep "Banned IP list" | awk -F ":" '{print $2}'`, name)
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取封禁列表失败")
|
||||
}
|
||||
@@ -287,7 +288,7 @@ func (r *Fail2banController) Unban(ctx http.Context) http.Response {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, "缺少参数")
|
||||
}
|
||||
|
||||
if _, err := tools.Exec("fail2ban-client set " + name + " unbanip " + ip); err != nil {
|
||||
if _, err := shell.Execf("fail2ban-client set %s unbanip %s", name, ip); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "解封失败")
|
||||
}
|
||||
|
||||
@@ -317,7 +318,7 @@ func (r *Fail2banController) SetWhiteList(ctx http.Context) http.Response {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "写入Fail2ban规则失败")
|
||||
}
|
||||
|
||||
if _, err := tools.Exec("fail2ban-client reload"); err != nil {
|
||||
if _, err := shell.Execf("fail2ban-client reload"); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "重载配置失败")
|
||||
}
|
||||
return controllers.Success(ctx, nil)
|
||||
|
||||
@@ -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/shell"
|
||||
"github.com/TheTNB/panel/pkg/tools"
|
||||
"github.com/TheTNB/panel/types"
|
||||
)
|
||||
@@ -68,7 +69,7 @@ func (r *MySQLController) Load(ctx http.Context) http.Response {
|
||||
return controllers.Success(ctx, []types.NV{})
|
||||
}
|
||||
|
||||
raw, err := tools.Exec("/www/server/mysql/bin/mysqladmin -uroot -p" + rootPassword + " extended-status 2>&1")
|
||||
raw, err := shell.Execf("/www/server/mysql/bin/mysqladmin -uroot -p" + rootPassword + " extended-status 2>&1")
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取MySQL负载失败")
|
||||
}
|
||||
@@ -125,7 +126,7 @@ func (r *MySQLController) Load(ctx http.Context) http.Response {
|
||||
|
||||
// ErrorLog 获取错误日志
|
||||
func (r *MySQLController) ErrorLog(ctx http.Context) http.Response {
|
||||
log, err := tools.Exec("tail -n 100 /www/server/mysql/mysql-error.log")
|
||||
log, err := shell.Execf("tail -n 100 /www/server/mysql/mysql-error.log")
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, log)
|
||||
}
|
||||
@@ -135,7 +136,7 @@ func (r *MySQLController) ErrorLog(ctx http.Context) http.Response {
|
||||
|
||||
// ClearErrorLog 清空错误日志
|
||||
func (r *MySQLController) ClearErrorLog(ctx http.Context) http.Response {
|
||||
if out, err := tools.Exec("echo '' > /www/server/mysql/mysql-error.log"); err != nil {
|
||||
if out, err := shell.Execf("echo '' > /www/server/mysql/mysql-error.log"); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
|
||||
@@ -144,7 +145,7 @@ func (r *MySQLController) ClearErrorLog(ctx http.Context) http.Response {
|
||||
|
||||
// SlowLog 获取慢查询日志
|
||||
func (r *MySQLController) SlowLog(ctx http.Context) http.Response {
|
||||
log, err := tools.Exec("tail -n 100 /www/server/mysql/mysql-slow.log")
|
||||
log, err := shell.Execf("tail -n 100 /www/server/mysql/mysql-slow.log")
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, log)
|
||||
}
|
||||
@@ -154,7 +155,7 @@ func (r *MySQLController) SlowLog(ctx http.Context) http.Response {
|
||||
|
||||
// ClearSlowLog 清空慢查询日志
|
||||
func (r *MySQLController) ClearSlowLog(ctx http.Context) http.Response {
|
||||
if out, err := tools.Exec("echo '' > /www/server/mysql/mysql-slow.log"); err != nil {
|
||||
if out, err := shell.Execf("echo '' > /www/server/mysql/mysql-slow.log"); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
return controllers.Success(ctx, nil)
|
||||
@@ -187,15 +188,15 @@ func (r *MySQLController) SetRootPassword(ctx http.Context) http.Response {
|
||||
|
||||
oldRootPassword := r.setting.Get(models.SettingKeyMysqlRootPassword)
|
||||
if oldRootPassword != rootPassword {
|
||||
if _, err = tools.Exec(fmt.Sprintf(`/www/server/mysql/bin/mysql -uroot -p%s -e "ALTER USER 'root'@'localhost' IDENTIFIED BY '%s';"`, oldRootPassword, rootPassword)); err != nil {
|
||||
if _, err = shell.Execf(fmt.Sprintf(`/www/server/mysql/bin/mysql -uroot -p%s -e "ALTER USER 'root'@'localhost' IDENTIFIED BY '%s';"`, oldRootPassword, rootPassword)); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, fmt.Sprintf("设置root密码失败: %v", err))
|
||||
}
|
||||
if _, err = tools.Exec(fmt.Sprintf(`/www/server/mysql/bin/mysql -uroot -p%s -e "FLUSH PRIVILEGES;"`, rootPassword)); err != nil {
|
||||
if _, err = shell.Execf(fmt.Sprintf(`/www/server/mysql/bin/mysql -uroot -p%s -e "FLUSH PRIVILEGES;"`, rootPassword)); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "设置root密码失败")
|
||||
}
|
||||
if err = r.setting.Set(models.SettingKeyMysqlRootPassword, rootPassword); err != nil {
|
||||
_, _ = tools.Exec(fmt.Sprintf(`/www/server/mysql/bin/mysql -uroot -p%s -e "ALTER USER 'root'@'localhost' IDENTIFIED BY '%s';"`, rootPassword, oldRootPassword))
|
||||
_, _ = tools.Exec(fmt.Sprintf(`/www/server/mysql/bin/mysql -uroot -p%s -e "FLUSH PRIVILEGES;"`, oldRootPassword))
|
||||
_, _ = shell.Execf(fmt.Sprintf(`/www/server/mysql/bin/mysql -uroot -p%s -e "ALTER USER 'root'@'localhost' IDENTIFIED BY '%s';"`, rootPassword, oldRootPassword))
|
||||
_, _ = shell.Execf(fmt.Sprintf(`/www/server/mysql/bin/mysql -uroot -p%s -e "FLUSH PRIVILEGES;"`, oldRootPassword))
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, fmt.Sprintf("设置保存失败: %v", err))
|
||||
}
|
||||
}
|
||||
@@ -269,16 +270,16 @@ func (r *MySQLController) AddDatabase(ctx http.Context) http.Response {
|
||||
user := ctx.Request().Input("user")
|
||||
password := ctx.Request().Input("password")
|
||||
|
||||
if out, err := tools.Exec("/www/server/mysql/bin/mysql -uroot -p" + rootPassword + " -e \"CREATE DATABASE IF NOT EXISTS " + database + " DEFAULT CHARSET utf8mb4 COLLATE utf8mb4_general_ci;\""); err != nil {
|
||||
if out, err := shell.Execf("/www/server/mysql/bin/mysql -uroot -p" + rootPassword + " -e \"CREATE DATABASE IF NOT EXISTS " + database + " DEFAULT CHARSET utf8mb4 COLLATE utf8mb4_general_ci;\""); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
if out, err := tools.Exec("/www/server/mysql/bin/mysql -uroot -p" + rootPassword + " -e \"CREATE USER '" + user + "'@'localhost' IDENTIFIED BY '" + password + "';\""); err != nil {
|
||||
if out, err := shell.Execf("/www/server/mysql/bin/mysql -uroot -p" + rootPassword + " -e \"CREATE USER '" + user + "'@'localhost' IDENTIFIED BY '" + password + "';\""); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
if out, err := tools.Exec("/www/server/mysql/bin/mysql -uroot -p" + rootPassword + " -e \"GRANT ALL PRIVILEGES ON " + database + ".* TO '" + user + "'@'localhost';\""); err != nil {
|
||||
if out, err := shell.Execf("/www/server/mysql/bin/mysql -uroot -p" + rootPassword + " -e \"GRANT ALL PRIVILEGES ON " + database + ".* TO '" + user + "'@'localhost';\""); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
if out, err := tools.Exec("/www/server/mysql/bin/mysql -uroot -p" + rootPassword + " -e \"FLUSH PRIVILEGES;\""); err != nil {
|
||||
if out, err := shell.Execf("/www/server/mysql/bin/mysql -uroot -p" + rootPassword + " -e \"FLUSH PRIVILEGES;\""); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
|
||||
@@ -295,7 +296,7 @@ func (r *MySQLController) DeleteDatabase(ctx http.Context) http.Response {
|
||||
|
||||
rootPassword := r.setting.Get(models.SettingKeyMysqlRootPassword)
|
||||
database := ctx.Request().Input("database")
|
||||
if out, err := tools.Exec("/www/server/mysql/bin/mysql -uroot -p" + rootPassword + " -e \"DROP DATABASE IF EXISTS " + database + ";\""); err != nil {
|
||||
if out, err := shell.Execf("/www/server/mysql/bin/mysql -uroot -p" + rootPassword + " -e \"DROP DATABASE IF EXISTS " + database + ";\""); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
|
||||
@@ -477,13 +478,13 @@ func (r *MySQLController) AddUser(ctx http.Context) http.Response {
|
||||
user := ctx.Request().Input("user")
|
||||
password := ctx.Request().Input("password")
|
||||
database := ctx.Request().Input("database")
|
||||
if out, err := tools.Exec("/www/server/mysql/bin/mysql -uroot -p" + rootPassword + " -e \"CREATE USER '" + user + "'@'localhost' IDENTIFIED BY '" + password + ";'\""); err != nil {
|
||||
if out, err := shell.Execf("/www/server/mysql/bin/mysql -uroot -p" + rootPassword + " -e \"CREATE USER '" + user + "'@'localhost' IDENTIFIED BY '" + password + ";'\""); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
if out, err := tools.Exec("/www/server/mysql/bin/mysql -uroot -p" + rootPassword + " -e \"GRANT ALL PRIVILEGES ON " + database + ".* TO '" + user + "'@'localhost';\""); err != nil {
|
||||
if out, err := shell.Execf("/www/server/mysql/bin/mysql -uroot -p" + rootPassword + " -e \"GRANT ALL PRIVILEGES ON " + database + ".* TO '" + user + "'@'localhost';\""); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
if out, err := tools.Exec("/www/server/mysql/bin/mysql -uroot -p" + rootPassword + " -e \"FLUSH PRIVILEGES;\""); err != nil {
|
||||
if out, err := shell.Execf("/www/server/mysql/bin/mysql -uroot -p" + rootPassword + " -e \"FLUSH PRIVILEGES;\""); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
|
||||
@@ -500,7 +501,7 @@ func (r *MySQLController) DeleteUser(ctx http.Context) http.Response {
|
||||
|
||||
rootPassword := r.setting.Get(models.SettingKeyMysqlRootPassword)
|
||||
user := ctx.Request().Input("user")
|
||||
if out, err := tools.Exec("/www/server/mysql/bin/mysql -uroot -p" + rootPassword + " -e \"DROP USER '" + user + "'@'localhost';\""); err != nil {
|
||||
if out, err := shell.Execf("/www/server/mysql/bin/mysql -uroot -p" + rootPassword + " -e \"DROP USER '" + user + "'@'localhost';\""); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
|
||||
@@ -519,10 +520,10 @@ func (r *MySQLController) SetUserPassword(ctx http.Context) http.Response {
|
||||
rootPassword := r.setting.Get(models.SettingKeyMysqlRootPassword)
|
||||
user := ctx.Request().Input("user")
|
||||
password := ctx.Request().Input("password")
|
||||
if out, err := tools.Exec("/www/server/mysql/bin/mysql -uroot -p" + rootPassword + " -e \"ALTER USER '" + user + "'@'localhost' IDENTIFIED BY '" + password + "';\""); err != nil {
|
||||
if out, err := shell.Execf("/www/server/mysql/bin/mysql -uroot -p" + rootPassword + " -e \"ALTER USER '" + user + "'@'localhost' IDENTIFIED BY '" + password + "';\""); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
if out, err := tools.Exec("/www/server/mysql/bin/mysql -uroot -p" + rootPassword + " -e \"FLUSH PRIVILEGES;\""); err != nil {
|
||||
if out, err := shell.Execf("/www/server/mysql/bin/mysql -uroot -p" + rootPassword + " -e \"FLUSH PRIVILEGES;\""); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
|
||||
@@ -541,13 +542,13 @@ func (r *MySQLController) SetUserPrivileges(ctx http.Context) http.Response {
|
||||
rootPassword := r.setting.Get(models.SettingKeyMysqlRootPassword)
|
||||
user := ctx.Request().Input("user")
|
||||
database := ctx.Request().Input("database")
|
||||
if out, err := tools.Exec("/www/server/mysql/bin/mysql -uroot -p" + rootPassword + " -e \"REVOKE ALL PRIVILEGES ON *.* FROM '" + user + "'@'localhost';\""); err != nil {
|
||||
if out, err := shell.Execf("/www/server/mysql/bin/mysql -uroot -p" + rootPassword + " -e \"REVOKE ALL PRIVILEGES ON *.* FROM '" + user + "'@'localhost';\""); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
if out, err := tools.Exec("/www/server/mysql/bin/mysql -uroot -p" + rootPassword + " -e \"GRANT ALL PRIVILEGES ON " + database + ".* TO '" + user + "'@'localhost';\""); err != nil {
|
||||
if out, err := shell.Execf("/www/server/mysql/bin/mysql -uroot -p" + rootPassword + " -e \"GRANT ALL PRIVILEGES ON " + database + ".* TO '" + user + "'@'localhost';\""); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
if out, err := tools.Exec("/www/server/mysql/bin/mysql -uroot -p" + rootPassword + " -e \"FLUSH PRIVILEGES;\""); err != nil {
|
||||
if out, err := shell.Execf("/www/server/mysql/bin/mysql -uroot -p" + rootPassword + " -e \"FLUSH PRIVILEGES;\""); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ import (
|
||||
"github.com/spf13/cast"
|
||||
|
||||
"github.com/TheTNB/panel/app/http/controllers"
|
||||
"github.com/TheTNB/panel/pkg/shell"
|
||||
"github.com/TheTNB/panel/pkg/tools"
|
||||
"github.com/TheTNB/panel/types"
|
||||
)
|
||||
@@ -77,7 +78,7 @@ func (r *OpenRestyController) ErrorLog(ctx http.Context) http.Response {
|
||||
return controllers.Success(ctx, "")
|
||||
}
|
||||
|
||||
out, err := tools.Exec("tail -n 100 /www/wwwlogs/openresty_error.log")
|
||||
out, err := shell.Execf("tail -n 100 /www/wwwlogs/openresty_error.log")
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
@@ -94,7 +95,7 @@ func (r *OpenRestyController) ErrorLog(ctx http.Context) http.Response {
|
||||
// @Success 200 {object} controllers.SuccessResponse
|
||||
// @Router /plugins/openresty/clearErrorLog [post]
|
||||
func (r *OpenRestyController) ClearErrorLog(ctx http.Context) http.Response {
|
||||
if out, err := tools.Exec("echo '' > /www/wwwlogs/openresty_error.log"); err != nil {
|
||||
if out, err := shell.Execf("echo '' > /www/wwwlogs/openresty_error.log"); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
|
||||
@@ -119,7 +120,7 @@ func (r *OpenRestyController) Load(ctx http.Context) http.Response {
|
||||
raw := resp.String()
|
||||
var data []types.NV
|
||||
|
||||
workers, err := tools.Exec("ps aux | grep nginx | grep 'worker process' | wc -l")
|
||||
workers, err := shell.Execf("ps aux | grep nginx | grep 'worker process' | wc -l")
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取负载失败")
|
||||
}
|
||||
@@ -128,7 +129,7 @@ func (r *OpenRestyController) Load(ctx http.Context) http.Response {
|
||||
Value: workers,
|
||||
})
|
||||
|
||||
out, err := tools.Exec("ps aux | grep nginx | grep 'worker process' | awk '{memsum+=$6};END {print memsum}'")
|
||||
out, err := shell.Execf("ps aux | grep nginx | grep 'worker process' | awk '{memsum+=$6};END {print memsum}'")
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取负载失败")
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ import (
|
||||
"github.com/spf13/cast"
|
||||
|
||||
"github.com/TheTNB/panel/app/http/controllers"
|
||||
"github.com/TheTNB/panel/pkg/shell"
|
||||
"github.com/TheTNB/panel/pkg/tools"
|
||||
)
|
||||
|
||||
@@ -52,8 +53,8 @@ func (r *PhpMyAdminController) Info(ctx http.Context) http.Response {
|
||||
}
|
||||
|
||||
func (r *PhpMyAdminController) SetPort(ctx http.Context) http.Response {
|
||||
port := ctx.Request().Input("port")
|
||||
if len(port) == 0 {
|
||||
port := ctx.Request().InputInt("port")
|
||||
if port == 0 {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "端口不能为空")
|
||||
}
|
||||
|
||||
@@ -61,7 +62,7 @@ func (r *PhpMyAdminController) SetPort(ctx http.Context) http.Response {
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
conf = regexp.MustCompile(`listen\s+(\d+);`).ReplaceAllString(conf, "listen "+port+";")
|
||||
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 {
|
||||
facades.Log().Request(ctx.Request()).Tags("插件", "phpMyAdmin").With(map[string]any{
|
||||
"error": err.Error(),
|
||||
@@ -70,17 +71,17 @@ func (r *PhpMyAdminController) SetPort(ctx http.Context) http.Response {
|
||||
}
|
||||
|
||||
if tools.IsRHEL() {
|
||||
if out, err := tools.Exec("firewall-cmd --zone=public --add-port=" + port + "/tcp --permanent"); err != nil {
|
||||
if out, err := shell.Execf("firewall-cmd --zone=public --add-port=%d/tcp --permanent", port); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
if out, err := tools.Exec("firewall-cmd --reload"); err != nil {
|
||||
if out, err := shell.Execf("firewall-cmd --reload"); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
} else {
|
||||
if out, err := tools.Exec("ufw allow " + port + "/tcp"); err != nil {
|
||||
if out, err := shell.Execf("ufw allow %d/tcp", port); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
if out, err := tools.Exec("ufw reload"); err != nil {
|
||||
if out, err := shell.Execf("ufw reload"); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ import (
|
||||
"github.com/TheTNB/panel/app/models"
|
||||
"github.com/TheTNB/panel/internal"
|
||||
"github.com/TheTNB/panel/internal/services"
|
||||
"github.com/TheTNB/panel/pkg/shell"
|
||||
"github.com/TheTNB/panel/pkg/tools"
|
||||
"github.com/TheTNB/panel/types"
|
||||
)
|
||||
@@ -92,23 +93,23 @@ func (r *PostgreSQLController) Load(ctx http.Context) http.Response {
|
||||
return controllers.Success(ctx, []types.NV{})
|
||||
}
|
||||
|
||||
time, err := tools.Exec(`echo "select pg_postmaster_start_time();" | su - postgres -c "psql" | sed -n 3p | cut -d'.' -f1`)
|
||||
time, err := shell.Execf(`echo "select pg_postmaster_start_time();" | su - postgres -c "psql" | sed -n 3p | cut -d'.' -f1`)
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取PostgreSQL启动时间失败")
|
||||
}
|
||||
pid, err := tools.Exec(`echo "select pg_backend_pid();" | su - postgres -c "psql" | sed -n 3p`)
|
||||
pid, err := shell.Execf(`echo "select pg_backend_pid();" | su - postgres -c "psql" | sed -n 3p`)
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取PostgreSQL进程PID失败")
|
||||
}
|
||||
process, err := tools.Exec(`ps aux | grep postgres | grep -v grep | wc -l`)
|
||||
process, err := shell.Execf(`ps aux | grep postgres | grep -v grep | wc -l`)
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取PostgreSQL进程数失败")
|
||||
}
|
||||
connections, err := tools.Exec(`echo "SELECT count(*) FROM pg_stat_activity WHERE NOT pid=pg_backend_pid();" | su - postgres -c "psql" | sed -n 3p`)
|
||||
connections, err := shell.Execf(`echo "SELECT count(*) FROM pg_stat_activity WHERE NOT pid=pg_backend_pid();" | su - postgres -c "psql" | sed -n 3p`)
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取PostgreSQL连接数失败")
|
||||
}
|
||||
storage, err := tools.Exec(`echo "select pg_size_pretty(pg_database_size('postgres'));" | su - postgres -c "psql" | sed -n 3p`)
|
||||
storage, err := shell.Execf(`echo "select pg_size_pretty(pg_database_size('postgres'));" | su - postgres -c "psql" | sed -n 3p`)
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取PostgreSQL空间占用失败")
|
||||
}
|
||||
@@ -126,7 +127,7 @@ func (r *PostgreSQLController) Load(ctx http.Context) http.Response {
|
||||
|
||||
// Log 获取日志
|
||||
func (r *PostgreSQLController) Log(ctx http.Context) http.Response {
|
||||
log, err := tools.Exec("tail -n 100 /www/server/postgresql/logs/postgresql-" + carbon.Now().ToDateString() + ".log")
|
||||
log, err := shell.Execf("tail -n 100 /www/server/postgresql/logs/postgresql-" + carbon.Now().ToDateString() + ".log")
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, log)
|
||||
}
|
||||
@@ -136,7 +137,7 @@ func (r *PostgreSQLController) Log(ctx http.Context) http.Response {
|
||||
|
||||
// ClearLog 清空日志
|
||||
func (r *PostgreSQLController) ClearLog(ctx http.Context) http.Response {
|
||||
if out, err := tools.Exec("echo '' > /www/server/postgresql/logs/postgresql-" + carbon.Now().ToDateString() + ".log"); err != nil {
|
||||
if out, err := shell.Execf("echo '' > /www/server/postgresql/logs/postgresql-" + carbon.Now().ToDateString() + ".log"); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
|
||||
@@ -211,21 +212,21 @@ func (r *PostgreSQLController) AddDatabase(ctx http.Context) http.Response {
|
||||
user := ctx.Request().Input("user")
|
||||
password := ctx.Request().Input("password")
|
||||
|
||||
if out, err := tools.Exec(`echo "CREATE DATABASE ` + database + `;" | su - postgres -c "psql"`); err != nil {
|
||||
if out, err := shell.Execf(`echo "CREATE DATABASE ` + database + `;" | su - postgres -c "psql"`); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
if out, err := tools.Exec(`echo "CREATE USER ` + user + ` WITH PASSWORD '` + password + `';" | su - postgres -c "psql"`); err != nil {
|
||||
if out, err := shell.Execf(`echo "CREATE USER ` + user + ` WITH PASSWORD '` + password + `';" | su - postgres -c "psql"`); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
if out, err := tools.Exec(`echo "ALTER DATABASE ` + database + ` OWNER TO ` + user + `;" | su - postgres -c "psql"`); err != nil {
|
||||
if out, err := shell.Execf(`echo "ALTER DATABASE ` + database + ` OWNER TO ` + user + `;" | su - postgres -c "psql"`); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
if out, err := tools.Exec(`echo "GRANT ALL PRIVILEGES ON DATABASE ` + database + ` TO ` + user + `;" | su - postgres -c "psql"`); err != nil {
|
||||
if out, err := shell.Execf(`echo "GRANT ALL PRIVILEGES ON DATABASE ` + database + ` TO ` + user + `;" | su - postgres -c "psql"`); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
|
||||
userConfig := "host " + database + " " + user + " 127.0.0.1/32 scram-sha-256"
|
||||
if out, err := tools.Exec(`echo "` + userConfig + `" >> /www/server/postgresql/data/pg_hba.conf`); err != nil {
|
||||
if out, err := shell.Execf(`echo "` + userConfig + `" >> /www/server/postgresql/data/pg_hba.conf`); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
|
||||
@@ -245,7 +246,7 @@ func (r *PostgreSQLController) DeleteDatabase(ctx http.Context) http.Response {
|
||||
}
|
||||
|
||||
database := ctx.Request().Input("database")
|
||||
if out, err := tools.Exec(`echo "DROP DATABASE ` + database + `;" | su - postgres -c "psql"`); err != nil {
|
||||
if out, err := shell.Execf(`echo "DROP DATABASE ` + database + `;" | su - postgres -c "psql"`); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
|
||||
@@ -428,15 +429,15 @@ func (r *PostgreSQLController) AddRole(ctx http.Context) http.Response {
|
||||
user := ctx.Request().Input("user")
|
||||
password := ctx.Request().Input("password")
|
||||
database := ctx.Request().Input("database")
|
||||
if out, err := tools.Exec(`echo "CREATE USER ` + user + ` WITH PASSWORD '` + password + `';" | su - postgres -c "psql"`); err != nil {
|
||||
if out, err := shell.Execf(`echo "CREATE USER ` + user + ` WITH PASSWORD '` + password + `';" | su - postgres -c "psql"`); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
if out, err := tools.Exec(`echo "GRANT ALL PRIVILEGES ON DATABASE ` + database + ` TO ` + user + `;" | su - postgres -c "psql"`); err != nil {
|
||||
if out, err := shell.Execf(`echo "GRANT ALL PRIVILEGES ON DATABASE ` + database + ` TO ` + user + `;" | su - postgres -c "psql"`); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
|
||||
userConfig := "host " + database + " " + user + " 127.0.0.1/32 scram-sha-256"
|
||||
if out, err := tools.Exec(`echo "` + userConfig + `" >> /www/server/postgresql/data/pg_hba.conf`); err != nil {
|
||||
if out, err := shell.Execf(`echo "` + userConfig + `" >> /www/server/postgresql/data/pg_hba.conf`); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
|
||||
@@ -456,10 +457,10 @@ func (r *PostgreSQLController) DeleteRole(ctx http.Context) http.Response {
|
||||
}
|
||||
|
||||
user := ctx.Request().Input("user")
|
||||
if out, err := tools.Exec(`echo "DROP USER ` + user + `;" | su - postgres -c "psql"`); err != nil {
|
||||
if out, err := shell.Execf(`echo "DROP USER ` + user + `;" | su - postgres -c "psql"`); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
if out, err := tools.Exec(`sed -i '/` + user + `/d' /www/server/postgresql/data/pg_hba.conf`); err != nil {
|
||||
if out, err := shell.Execf(`sed -i '/` + user + `/d' /www/server/postgresql/data/pg_hba.conf`); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
|
||||
@@ -481,7 +482,7 @@ func (r *PostgreSQLController) SetRolePassword(ctx http.Context) http.Response {
|
||||
|
||||
user := ctx.Request().Input("user")
|
||||
password := ctx.Request().Input("password")
|
||||
if out, err := tools.Exec(`echo "ALTER USER ` + user + ` WITH PASSWORD '` + password + `';" | su - postgres -c "psql"`); err != nil {
|
||||
if out, err := shell.Execf(`echo "ALTER USER ` + user + ` WITH PASSWORD '` + password + `';" | su - postgres -c "psql"`); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
"github.com/spf13/cast"
|
||||
|
||||
"github.com/TheTNB/panel/app/http/controllers"
|
||||
"github.com/TheTNB/panel/pkg/shell"
|
||||
"github.com/TheTNB/panel/pkg/tools"
|
||||
"github.com/TheTNB/panel/types"
|
||||
)
|
||||
@@ -21,7 +22,7 @@ func NewPureFtpdController() *PureFtpdController {
|
||||
|
||||
// List 获取用户列表
|
||||
func (r *PureFtpdController) List(ctx http.Context) http.Response {
|
||||
listRaw, err := tools.Exec("pure-pw list")
|
||||
listRaw, err := shell.Execf("pure-pw list")
|
||||
if err != nil {
|
||||
return controllers.Success(ctx, http.Json{
|
||||
"total": 0,
|
||||
@@ -78,10 +79,10 @@ func (r *PureFtpdController) Add(ctx http.Context) http.Response {
|
||||
if err := tools.Chown(path, "www", "www"); err != nil {
|
||||
return nil
|
||||
}
|
||||
if out, err := tools.Exec(`yes '` + password + `' | pure-pw useradd ` + username + ` -u www -g www -d ` + path); err != nil {
|
||||
if out, err := shell.Execf(`yes '` + password + `' | pure-pw useradd ` + username + ` -u www -g www -d ` + path); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
if out, err := tools.Exec("pure-pw mkdb"); err != nil {
|
||||
if out, err := shell.Execf("pure-pw mkdb"); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
|
||||
@@ -98,10 +99,10 @@ func (r *PureFtpdController) Delete(ctx http.Context) http.Response {
|
||||
|
||||
username := ctx.Request().Input("username")
|
||||
|
||||
if out, err := tools.Exec("pure-pw userdel " + username + " -m"); err != nil {
|
||||
if out, err := shell.Execf("pure-pw userdel " + username + " -m"); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
if out, err := tools.Exec("pure-pw mkdb"); err != nil {
|
||||
if out, err := shell.Execf("pure-pw mkdb"); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
|
||||
@@ -120,10 +121,10 @@ func (r *PureFtpdController) ChangePassword(ctx http.Context) http.Response {
|
||||
username := ctx.Request().Input("username")
|
||||
password := ctx.Request().Input("password")
|
||||
|
||||
if out, err := tools.Exec(`yes '` + password + `' | pure-pw passwd ` + username + ` -m`); err != nil {
|
||||
if out, err := shell.Execf(`yes '` + password + `' | pure-pw passwd ` + username + ` -m`); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
if out, err := tools.Exec("pure-pw mkdb"); err != nil {
|
||||
if out, err := shell.Execf("pure-pw mkdb"); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
|
||||
@@ -132,7 +133,7 @@ func (r *PureFtpdController) ChangePassword(ctx http.Context) http.Response {
|
||||
|
||||
// GetPort 获取端口
|
||||
func (r *PureFtpdController) GetPort(ctx http.Context) http.Response {
|
||||
port, err := tools.Exec(`cat /www/server/pure-ftpd/etc/pure-ftpd.conf | grep "Bind" | awk '{print $2}' | awk -F "," '{print $2}'`)
|
||||
port, err := shell.Execf(`cat /www/server/pure-ftpd/etc/pure-ftpd.conf | grep "Bind" | awk '{print $2}' | awk -F "," '{print $2}'`)
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取PureFtpd端口失败")
|
||||
}
|
||||
@@ -149,21 +150,21 @@ func (r *PureFtpdController) SetPort(ctx http.Context) http.Response {
|
||||
}
|
||||
|
||||
port := ctx.Request().Input("port")
|
||||
if out, err := tools.Exec(`sed -i "s/Bind.*/Bind 0.0.0.0,` + port + `/g" /www/server/pure-ftpd/etc/pure-ftpd.conf`); err != nil {
|
||||
if out, err := shell.Execf(`sed -i "s/Bind.*/Bind 0.0.0.0,%s/g" /www/server/pure-ftpd/etc/pure-ftpd.conf`, port); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
if tools.IsRHEL() {
|
||||
if out, err := tools.Exec("firewall-cmd --zone=public --add-port=" + port + "/tcp --permanent"); err != nil {
|
||||
if out, err := shell.Execf("firewall-cmd --zone=public --add-port=%s/tcp --permanent", port); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
if out, err := tools.Exec("firewall-cmd --reload"); err != nil {
|
||||
if out, err := shell.Execf("firewall-cmd --reload"); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
} else {
|
||||
if out, err := tools.Exec("ufw allow " + port + "/tcp"); err != nil {
|
||||
if out, err := shell.Execf("ufw allow %s/tcp", port); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
if out, err := tools.Exec("ufw reload"); err != nil {
|
||||
if out, err := shell.Execf("ufw reload"); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
"github.com/goravel/framework/contracts/http"
|
||||
|
||||
"github.com/TheTNB/panel/app/http/controllers"
|
||||
"github.com/TheTNB/panel/pkg/shell"
|
||||
"github.com/TheTNB/panel/pkg/tools"
|
||||
"github.com/TheTNB/panel/types"
|
||||
)
|
||||
@@ -56,7 +57,7 @@ func (r *RedisController) Load(ctx http.Context) http.Response {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "Redis已停止运行")
|
||||
}
|
||||
|
||||
raw, err := tools.Exec("redis-cli info")
|
||||
raw, err := shell.Execf("redis-cli info")
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取Redis负载失败")
|
||||
}
|
||||
|
||||
@@ -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/shell"
|
||||
"github.com/TheTNB/panel/pkg/tools"
|
||||
"github.com/TheTNB/panel/types"
|
||||
)
|
||||
@@ -69,7 +70,7 @@ func (r *RsyncController) List(ctx http.Context) http.Response {
|
||||
currentModule.ReadOnly = value == "yes" || value == "true"
|
||||
case "auth users":
|
||||
currentModule.AuthUser = value
|
||||
currentModule.Secret, err = tools.Exec("grep -E '^" + currentModule.AuthUser + ":.*$' /etc/rsyncd.secrets | awk -F ':' '{print $2}'")
|
||||
currentModule.Secret, err = shell.Execf("grep -E '^" + currentModule.AuthUser + ":.*$' /etc/rsyncd.secrets | awk -F ':' '{print $2}'")
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取模块"+currentModule.AuthUser+"的密钥失败")
|
||||
}
|
||||
@@ -131,7 +132,7 @@ secrets file = /etc/rsyncd.secrets
|
||||
if err := tools.WriteAppend("/etc/rsyncd.conf", conf); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
if out, err := tools.Exec("echo '" + createRequest.AuthUser + ":" + createRequest.Secret + "' >> /etc/rsyncd.secrets"); err != nil {
|
||||
if out, err := shell.Execf("echo '" + createRequest.AuthUser + ":" + createRequest.Secret + "' >> /etc/rsyncd.secrets"); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
|
||||
@@ -172,7 +173,7 @@ func (r *RsyncController) Destroy(ctx http.Context) http.Response {
|
||||
match := regexp.MustCompile(`auth users = ([^\n]+)`).FindStringSubmatch(module)
|
||||
if len(match) == 2 {
|
||||
authUser := match[1]
|
||||
if out, err := tools.Exec("sed -i '/^" + authUser + ":.*$/d' /etc/rsyncd.secrets"); err != nil {
|
||||
if out, err := shell.Execf("sed -i '/^" + authUser + ":.*$/d' /etc/rsyncd.secrets"); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
}
|
||||
@@ -230,7 +231,7 @@ secrets file = /etc/rsyncd.secrets
|
||||
match := regexp.MustCompile(`auth users = ([^\n]+)`).FindStringSubmatch(module)
|
||||
if len(match) == 2 {
|
||||
authUser := match[1]
|
||||
if out, err := tools.Exec("sed -i '/^" + authUser + ":.*$/d' /etc/rsyncd.secrets"); err != nil {
|
||||
if out, err := shell.Execf("sed -i '/^" + authUser + ":.*$/d' /etc/rsyncd.secrets"); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
}
|
||||
@@ -238,7 +239,7 @@ secrets file = /etc/rsyncd.secrets
|
||||
if err = tools.Write("/etc/rsyncd.conf", config, 0644); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
if out, err := tools.Exec("echo '" + updateRequest.AuthUser + ":" + updateRequest.Secret + "' >> /etc/rsyncd.secrets"); err != nil {
|
||||
if out, err := shell.Execf("echo '" + updateRequest.AuthUser + ":" + updateRequest.Secret + "' >> /etc/rsyncd.secrets"); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ import (
|
||||
"github.com/TheTNB/panel/app/http/controllers"
|
||||
"github.com/TheTNB/panel/internal"
|
||||
"github.com/TheTNB/panel/internal/services"
|
||||
"github.com/TheTNB/panel/pkg/shell"
|
||||
"github.com/TheTNB/panel/pkg/tools"
|
||||
"github.com/TheTNB/panel/types"
|
||||
)
|
||||
@@ -90,16 +91,16 @@ func (r *S3fsController) Add(ctx http.Context) http.Response {
|
||||
if err := tools.Write("/etc/passwd-s3fs-"+cast.ToString(id), password, 0600); err != nil {
|
||||
return nil
|
||||
}
|
||||
out, err := tools.Exec(`echo 's3fs#` + bucket + ` ` + path + ` fuse _netdev,allow_other,nonempty,url=` + url + `,passwd_file=/etc/passwd-s3fs-` + cast.ToString(id) + ` 0 0' >> /etc/fstab`)
|
||||
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`)
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
if mountCheck, err := tools.Exec("mount -a 2>&1"); err != nil {
|
||||
_, _ = tools.Exec(`sed -i 's@^s3fs#` + bucket + `\s` + path + `.*$@@g' /etc/fstab`)
|
||||
if mountCheck, err := shell.Execf("mount -a 2>&1"); err != nil {
|
||||
_, _ = shell.Execf(`sed -i 's@^s3fs#` + bucket + `\s` + path + `.*$@@g' /etc/fstab`)
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "检测到/etc/fstab有误: "+mountCheck)
|
||||
}
|
||||
if _, err := tools.Exec("df -h | grep " + path + " 2>&1"); err != nil {
|
||||
_, _ = tools.Exec(`sed -i 's@^s3fs#` + bucket + `\s` + path + `.*$@@g' /etc/fstab`)
|
||||
if _, err := shell.Execf("df -h | grep " + path + " 2>&1"); err != nil {
|
||||
_, _ = shell.Execf(`sed -i 's@^s3fs#` + bucket + `\s` + path + `.*$@@g' /etc/fstab`)
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "挂载失败,请检查配置是否正确")
|
||||
}
|
||||
|
||||
@@ -145,16 +146,16 @@ func (r *S3fsController) Delete(ctx http.Context) http.Response {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, "挂载ID不存在")
|
||||
}
|
||||
|
||||
if out, err := tools.Exec(`fusermount -u '` + mount.Path + `' 2>&1`); err != nil {
|
||||
if out, err := shell.Execf(`fusermount -u '` + mount.Path + `' 2>&1`); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
if out, err := tools.Exec(`umount '` + mount.Path + `' 2>&1`); err != nil {
|
||||
if out, err := shell.Execf(`umount '` + mount.Path + `' 2>&1`); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
if out, err := tools.Exec(`sed -i 's@^s3fs#` + mount.Bucket + `\s` + mount.Path + `.*$@@g' /etc/fstab`); err != nil {
|
||||
if out, err := shell.Execf(`sed -i 's@^s3fs#` + mount.Bucket + `\s` + mount.Path + `.*$@@g' /etc/fstab`); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
if mountCheck, err := tools.Exec("mount -a 2>&1"); err != nil {
|
||||
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 {
|
||||
|
||||
@@ -5,10 +5,11 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/TheTNB/panel/pkg/tools"
|
||||
"github.com/goravel/framework/contracts/http"
|
||||
|
||||
"github.com/TheTNB/panel/app/http/controllers"
|
||||
"github.com/TheTNB/panel/pkg/shell"
|
||||
"github.com/TheTNB/panel/pkg/tools"
|
||||
)
|
||||
|
||||
type SupervisorController struct {
|
||||
@@ -35,7 +36,7 @@ func (r *SupervisorController) Service(ctx http.Context) http.Response {
|
||||
|
||||
// Log 日志
|
||||
func (r *SupervisorController) Log(ctx http.Context) http.Response {
|
||||
log, err := tools.Exec(`tail -n 200 /var/log/supervisor/supervisord.log`)
|
||||
log, err := shell.Execf(`tail -n 200 /var/log/supervisor/supervisord.log`)
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, log)
|
||||
}
|
||||
@@ -45,7 +46,7 @@ func (r *SupervisorController) Log(ctx http.Context) http.Response {
|
||||
|
||||
// ClearLog 清空日志
|
||||
func (r *SupervisorController) ClearLog(ctx http.Context) http.Response {
|
||||
if out, err := tools.Exec(`echo "" > /var/log/supervisor/supervisord.log`); err != nil {
|
||||
if out, err := shell.Execf(`echo "" > /var/log/supervisor/supervisord.log`); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
|
||||
@@ -99,7 +100,7 @@ func (r *SupervisorController) Processes(ctx http.Context) http.Response {
|
||||
Uptime string `json:"uptime"`
|
||||
}
|
||||
|
||||
out, err := tools.Exec(`supervisorctl status | awk '{print $1}'`)
|
||||
out, err := shell.Execf(`supervisorctl status | awk '{print $1}'`)
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
@@ -112,13 +113,13 @@ func (r *SupervisorController) Processes(ctx http.Context) http.Response {
|
||||
|
||||
var p process
|
||||
p.Name = line
|
||||
if status, err := tools.Exec(`supervisorctl status ` + line + ` | awk '{print $2}'`); err == nil {
|
||||
if status, err := shell.Execf(`supervisorctl status ` + line + ` | awk '{print $2}'`); err == nil {
|
||||
p.Status = status
|
||||
}
|
||||
if p.Status == "RUNNING" {
|
||||
pid, _ := tools.Exec(`supervisorctl status ` + line + ` | awk '{print $4}'`)
|
||||
pid, _ := shell.Execf(`supervisorctl status ` + line + ` | awk '{print $4}'`)
|
||||
p.Pid = strings.ReplaceAll(pid, ",", "")
|
||||
uptime, _ := tools.Exec(`supervisorctl status ` + line + ` | awk '{print $6}'`)
|
||||
uptime, _ := shell.Execf(`supervisorctl status ` + line + ` | awk '{print $6}'`)
|
||||
p.Uptime = uptime
|
||||
} else {
|
||||
p.Pid = "-"
|
||||
@@ -138,7 +139,7 @@ func (r *SupervisorController) Processes(ctx http.Context) http.Response {
|
||||
// StartProcess 启动进程
|
||||
func (r *SupervisorController) StartProcess(ctx http.Context) http.Response {
|
||||
process := ctx.Request().Input("process")
|
||||
if out, err := tools.Exec(`supervisorctl start ` + process); err != nil {
|
||||
if out, err := shell.Execf(`supervisorctl start %s`, process); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
|
||||
@@ -148,7 +149,7 @@ func (r *SupervisorController) StartProcess(ctx http.Context) http.Response {
|
||||
// StopProcess 停止进程
|
||||
func (r *SupervisorController) StopProcess(ctx http.Context) http.Response {
|
||||
process := ctx.Request().Input("process")
|
||||
if out, err := tools.Exec(`supervisorctl stop ` + process); err != nil {
|
||||
if out, err := shell.Execf(`supervisorctl stop %s`, process); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
|
||||
@@ -158,7 +159,7 @@ func (r *SupervisorController) StopProcess(ctx http.Context) http.Response {
|
||||
// RestartProcess 重启进程
|
||||
func (r *SupervisorController) RestartProcess(ctx http.Context) http.Response {
|
||||
process := ctx.Request().Input("process")
|
||||
if out, err := tools.Exec(`supervisorctl restart ` + process); err != nil {
|
||||
if out, err := shell.Execf(`supervisorctl restart %s`, process); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
|
||||
@@ -171,16 +172,16 @@ func (r *SupervisorController) ProcessLog(ctx http.Context) http.Response {
|
||||
var logPath string
|
||||
var err error
|
||||
if tools.IsRHEL() {
|
||||
logPath, err = tools.Exec(`cat '/etc/supervisord.d/` + process + `.conf' | grep stdout_logfile= | awk -F "=" '{print $2}'`)
|
||||
logPath, err = shell.Execf(`cat '/etc/supervisord.d/%s.conf' | grep stdout_logfile= | awk -F "=" '{print $2}'`, process)
|
||||
} else {
|
||||
logPath, err = tools.Exec(`cat '/etc/supervisor/conf.d/` + process + `.conf' | grep stdout_logfile= | awk -F "=" '{print $2}'`)
|
||||
logPath, err = shell.Execf(`cat '/etc/supervisor/conf.d/%s.conf' | grep stdout_logfile= | awk -F "=" '{print $2}'`, process)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "无法从进程"+process+"的配置文件中获取日志路径")
|
||||
}
|
||||
|
||||
log, err := tools.Exec(`tail -n 200 ` + logPath)
|
||||
log, err := shell.Execf(`tail -n 200 ` + logPath)
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, log)
|
||||
}
|
||||
@@ -194,16 +195,16 @@ func (r *SupervisorController) ClearProcessLog(ctx http.Context) http.Response {
|
||||
var logPath string
|
||||
var err error
|
||||
if tools.IsRHEL() {
|
||||
logPath, err = tools.Exec(`cat '/etc/supervisord.d/` + process + `.conf' | grep stdout_logfile= | awk -F "=" '{print $2}'`)
|
||||
logPath, err = shell.Execf(`cat '/etc/supervisord.d/%s.conf' | grep stdout_logfile= | awk -F "=" '{print $2}'`, process)
|
||||
} else {
|
||||
logPath, err = tools.Exec(`cat '/etc/supervisor/conf.d/` + process + `.conf' | grep stdout_logfile= | awk -F "=" '{print $2}'`)
|
||||
logPath, err = shell.Execf(`cat '/etc/supervisor/conf.d/%s.conf' | grep stdout_logfile= | awk -F "=" '{print $2}'`, process)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "无法从进程"+process+"的配置文件中获取日志路径")
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, fmt.Sprintf("无法从进程%s的配置文件中获取日志路径", process))
|
||||
}
|
||||
|
||||
if out, err := tools.Exec(`echo "" > ` + logPath); err != nil {
|
||||
if out, err := shell.Execf(`echo "" > ` + logPath); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
|
||||
@@ -243,9 +244,9 @@ func (r *SupervisorController) SaveProcessConfig(ctx http.Context) http.Response
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, err.Error())
|
||||
}
|
||||
|
||||
_, _ = tools.Exec(`supervisorctl reread`)
|
||||
_, _ = tools.Exec(`supervisorctl update`)
|
||||
_, _ = tools.Exec(`supervisorctl restart ` + process)
|
||||
_, _ = shell.Execf(`supervisorctl reread`)
|
||||
_, _ = shell.Execf(`supervisorctl update`)
|
||||
_, _ = shell.Execf(`supervisorctl restart %s`, process)
|
||||
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
@@ -291,9 +292,9 @@ stdout_logfile_maxbytes=2MB
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, err.Error())
|
||||
}
|
||||
|
||||
_, _ = tools.Exec(`supervisorctl reread`)
|
||||
_, _ = tools.Exec(`supervisorctl update`)
|
||||
_, _ = tools.Exec(`supervisorctl start ` + name)
|
||||
_, _ = shell.Execf(`supervisorctl reread`)
|
||||
_, _ = shell.Execf(`supervisorctl update`)
|
||||
_, _ = shell.Execf(`supervisorctl start %s`, name)
|
||||
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
@@ -301,19 +302,19 @@ stdout_logfile_maxbytes=2MB
|
||||
// DeleteProcess 删除进程
|
||||
func (r *SupervisorController) DeleteProcess(ctx http.Context) http.Response {
|
||||
process := ctx.Request().Input("process")
|
||||
if out, err := tools.Exec(`supervisorctl stop ` + process); err != nil {
|
||||
if out, err := shell.Execf(`supervisorctl stop %s`, process); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
|
||||
var logPath string
|
||||
var err error
|
||||
if tools.IsRHEL() {
|
||||
logPath, err = tools.Exec(`cat '/etc/supervisord.d/` + process + `.conf' | grep stdout_logfile= | awk -F "=" '{print $2}'`)
|
||||
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 {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
} else {
|
||||
logPath, err = tools.Exec(`cat '/etc/supervisor/conf.d/` + process + `.conf' | grep stdout_logfile= | awk -F "=" '{print $2}'`)
|
||||
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 {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
@@ -326,8 +327,8 @@ func (r *SupervisorController) DeleteProcess(ctx http.Context) http.Response {
|
||||
if err := tools.Remove(logPath); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
_, _ = tools.Exec(`supervisorctl reread`)
|
||||
_, _ = tools.Exec(`supervisorctl update`)
|
||||
_, _ = shell.Execf(`supervisorctl reread`)
|
||||
_, _ = shell.Execf(`supervisorctl update`)
|
||||
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
"github.com/spf13/cast"
|
||||
|
||||
"github.com/TheTNB/panel/app/http/controllers"
|
||||
"github.com/TheTNB/panel/pkg/shell"
|
||||
"github.com/TheTNB/panel/pkg/tools"
|
||||
)
|
||||
|
||||
@@ -74,7 +75,7 @@ func (r *ToolBoxController) GetSWAP(ctx http.Context) http.Response {
|
||||
total = "0.00 B"
|
||||
}
|
||||
|
||||
raw, err := tools.Exec("free | grep Swap")
|
||||
raw, err := shell.Execf("free | grep Swap")
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, "获取 SWAP 信息失败")
|
||||
}
|
||||
@@ -98,19 +99,19 @@ func (r *ToolBoxController) SetSWAP(ctx http.Context) http.Response {
|
||||
size := ctx.Request().InputInt("size")
|
||||
|
||||
if tools.Exists("/www/swap") {
|
||||
if out, err := tools.Exec("swapoff /www/swap"); err != nil {
|
||||
if out, err := shell.Execf("swapoff /www/swap"); err != nil {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, out)
|
||||
}
|
||||
if out, err := tools.Exec("rm -f /www/swap"); err != nil {
|
||||
if out, err := shell.Execf("rm -f /www/swap"); err != nil {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, out)
|
||||
}
|
||||
if out, err := tools.Exec("sed -i '/www\\/swap/d' /etc/fstab"); err != nil {
|
||||
if out, err := shell.Execf("sed -i '/www\\/swap/d' /etc/fstab"); err != nil {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, out)
|
||||
}
|
||||
}
|
||||
|
||||
if size > 1 {
|
||||
free, err := tools.Exec("df -k /www | awk '{print $4}' | tail -n 1")
|
||||
free, err := shell.Execf("df -k /www | awk '{print $4}' | tail -n 1")
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, "获取磁盘空间失败")
|
||||
}
|
||||
@@ -118,26 +119,26 @@ func (r *ToolBoxController) SetSWAP(ctx http.Context) http.Response {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, "磁盘空间不足,当前剩余 "+tools.FormatBytes(cast.ToFloat64(free)))
|
||||
}
|
||||
|
||||
btrfsCheck, _ := tools.Exec("df -T /www | awk '{print $2}' | tail -n 1")
|
||||
btrfsCheck, _ := shell.Execf("df -T /www | awk '{print $2}' | tail -n 1")
|
||||
if strings.Contains(btrfsCheck, "btrfs") {
|
||||
if out, err := tools.Exec("btrfs filesystem mkswapfile --size " + cast.ToString(size) + "M --uuid clear /www/swap"); err != nil {
|
||||
if out, err := shell.Execf("btrfs filesystem mkswapfile --size " + cast.ToString(size) + "M --uuid clear /www/swap"); err != nil {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, out)
|
||||
}
|
||||
} else {
|
||||
if out, err := tools.Exec("dd if=/dev/zero of=/www/swap bs=1M count=" + cast.ToString(size)); err != nil {
|
||||
if out, err := shell.Execf("dd if=/dev/zero of=/www/swap bs=1M count=" + cast.ToString(size)); err != nil {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, out)
|
||||
}
|
||||
if out, err := tools.Exec("mkswap -f /www/swap"); err != nil {
|
||||
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 {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, "设置 SWAP 权限失败")
|
||||
}
|
||||
}
|
||||
if out, err := tools.Exec("swapon /www/swap"); err != nil {
|
||||
if out, err := shell.Execf("swapon /www/swap"); err != nil {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, out)
|
||||
}
|
||||
if out, err := tools.Exec("echo '/www/swap swap swap defaults 0 0' >> /etc/fstab"); err != nil {
|
||||
if out, err := shell.Execf("echo '/www/swap swap swap defaults 0 0' >> /etc/fstab"); err != nil {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, out)
|
||||
}
|
||||
}
|
||||
@@ -147,7 +148,7 @@ func (r *ToolBoxController) SetSWAP(ctx http.Context) http.Response {
|
||||
|
||||
// GetTimezone 获取时区
|
||||
func (r *ToolBoxController) GetTimezone(ctx http.Context) http.Response {
|
||||
raw, err := tools.Exec("timedatectl | grep zone")
|
||||
raw, err := shell.Execf("timedatectl | grep zone")
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, "获取时区信息失败")
|
||||
}
|
||||
@@ -162,7 +163,7 @@ func (r *ToolBoxController) GetTimezone(ctx http.Context) http.Response {
|
||||
Value string `json:"value"`
|
||||
}
|
||||
|
||||
zonesRaw, err := tools.Exec("timedatectl list-timezones")
|
||||
zonesRaw, err := shell.Execf("timedatectl list-timezones")
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, "获取时区列表失败")
|
||||
}
|
||||
@@ -189,7 +190,7 @@ func (r *ToolBoxController) SetTimezone(ctx http.Context) http.Response {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, "时区不能为空")
|
||||
}
|
||||
|
||||
if out, err := tools.Exec("timedatectl set-timezone " + timezone); err != nil {
|
||||
if out, err := shell.Execf("timedatectl set-timezone %s", timezone); err != nil {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, out)
|
||||
}
|
||||
|
||||
@@ -231,7 +232,7 @@ func (r *ToolBoxController) SetRootPassword(ctx http.Context) http.Response {
|
||||
}
|
||||
|
||||
password = strings.ReplaceAll(password, `'`, `\'`)
|
||||
if out, err := tools.Exec(`yes '` + password + `' | passwd root`); err != nil {
|
||||
if out, err := shell.Execf(`yes '` + password + `' | passwd root`); err != nil {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, out)
|
||||
}
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
"github.com/goravel/framework/contracts/http"
|
||||
"github.com/spf13/cast"
|
||||
|
||||
"github.com/TheTNB/panel/pkg/shell"
|
||||
"github.com/TheTNB/panel/pkg/tools"
|
||||
)
|
||||
|
||||
@@ -42,7 +43,7 @@ func (r *SafeController) SetFirewallStatus(ctx http.Context) http.Response {
|
||||
err = tools.ServiceEnable("firewalld")
|
||||
}
|
||||
} else {
|
||||
_, err = tools.Exec("echo y | ufw enable")
|
||||
_, err = shell.Execf("echo y | ufw enable")
|
||||
if err == nil {
|
||||
err = tools.ServiceStart("ufw")
|
||||
}
|
||||
@@ -57,7 +58,7 @@ func (r *SafeController) SetFirewallStatus(ctx http.Context) http.Response {
|
||||
err = tools.ServiceDisable("firewalld")
|
||||
}
|
||||
} else {
|
||||
_, err = tools.Exec("ufw disable")
|
||||
_, err = shell.Execf("ufw disable")
|
||||
if err == nil {
|
||||
err = tools.ServiceStop("ufw")
|
||||
}
|
||||
@@ -82,7 +83,7 @@ func (r *SafeController) GetFirewallRules(ctx http.Context) http.Response {
|
||||
|
||||
var rules []map[string]string
|
||||
if tools.IsRHEL() {
|
||||
out, err := tools.Exec("firewall-cmd --list-all 2>&1")
|
||||
out, err := shell.Execf("firewall-cmd --list-all")
|
||||
if err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
@@ -103,7 +104,7 @@ func (r *SafeController) GetFirewallRules(ctx http.Context) http.Response {
|
||||
})
|
||||
}
|
||||
} else {
|
||||
out, err := tools.Exec("ufw status | grep -v '(v6)' | grep ALLOW | awk '{print $1}'")
|
||||
out, err := shell.Execf("ufw status | grep -v '(v6)' | grep ALLOW | awk '{print $1}'")
|
||||
if err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
@@ -158,13 +159,13 @@ func (r *SafeController) AddFirewallRule(ctx http.Context) http.Response {
|
||||
}
|
||||
|
||||
if tools.IsRHEL() {
|
||||
if out, err := tools.Exec("firewall-cmd --remove-port=" + cast.ToString(port) + "/" + protocol + " --permanent 2>&1"); err != nil {
|
||||
if out, err := shell.Execf("firewall-cmd --remove-port=%s/%s --permanent", port, protocol); err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
if out, err := tools.Exec("firewall-cmd --add-port=" + cast.ToString(port) + "/" + protocol + " --permanent 2>&1"); err != nil {
|
||||
if out, err := shell.Execf("firewall-cmd --add-port=%s/%s --permanent", port, protocol); err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
if out, err := tools.Exec("firewall-cmd --reload"); err != nil {
|
||||
if out, err := shell.Execf("firewall-cmd --reload"); err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
} else {
|
||||
@@ -172,13 +173,13 @@ func (r *SafeController) AddFirewallRule(ctx http.Context) http.Response {
|
||||
if strings.Contains(port, "-") {
|
||||
port = strings.ReplaceAll(port, "-", ":")
|
||||
}
|
||||
if out, err := tools.Exec("ufw delete allow " + cast.ToString(port) + "/" + protocol); err != nil {
|
||||
if out, err := shell.Execf("ufw delete allow %s/%s", port, protocol); err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
if out, err := tools.Exec("ufw allow " + cast.ToString(port) + "/" + protocol); err != nil {
|
||||
if out, err := shell.Execf("ufw allow %s/%s", port, protocol); err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
if out, err := tools.Exec("ufw reload"); err != nil {
|
||||
if out, err := shell.Execf("ufw reload"); err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
}
|
||||
@@ -192,24 +193,24 @@ func (r *SafeController) DeleteFirewallRule(ctx http.Context) http.Response {
|
||||
return Error(ctx, http.StatusUnprocessableEntity, "防火墙未启动")
|
||||
}
|
||||
|
||||
port := ctx.Request().InputInt("port", 0)
|
||||
protocol := ctx.Request().Input("protocol", "")
|
||||
if port == 0 || protocol == "" {
|
||||
port := ctx.Request().Input("port")
|
||||
protocol := ctx.Request().Input("protocol")
|
||||
if port == "" || protocol == "" {
|
||||
return Error(ctx, http.StatusUnprocessableEntity, "参数错误")
|
||||
}
|
||||
|
||||
if tools.IsRHEL() {
|
||||
if out, err := tools.Exec("firewall-cmd --remove-port=" + cast.ToString(port) + "/" + protocol + " --permanent 2>&1"); err != nil {
|
||||
if out, err := shell.Execf("firewall-cmd --remove-port=%s/%s --permanent", port, protocol); err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
if out, err := tools.Exec("firewall-cmd --reload"); err != nil {
|
||||
if out, err := shell.Execf("firewall-cmd --reload"); err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
} else {
|
||||
if out, err := tools.Exec("ufw delete allow " + cast.ToString(port) + "/" + protocol); err != nil {
|
||||
if out, err := shell.Execf("ufw delete allow %s/%s", port, protocol); err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
if out, err := tools.Exec("ufw reload"); err != nil {
|
||||
if out, err := shell.Execf("ufw reload"); err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
}
|
||||
@@ -262,7 +263,7 @@ func (r *SafeController) SetSshStatus(ctx http.Context) http.Response {
|
||||
|
||||
// GetSshPort 获取 SSH 端口
|
||||
func (r *SafeController) GetSshPort(ctx http.Context) http.Response {
|
||||
out, err := tools.Exec("cat /etc/ssh/sshd_config | grep 'Port ' | awk '{print $2}'")
|
||||
out, err := shell.Execf("cat /etc/ssh/sshd_config | grep 'Port ' | awk '{print $2}'")
|
||||
if err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
@@ -277,12 +278,12 @@ func (r *SafeController) SetSshPort(ctx http.Context) http.Response {
|
||||
return Error(ctx, http.StatusUnprocessableEntity, "参数错误")
|
||||
}
|
||||
|
||||
oldPort, err := tools.Exec("cat /etc/ssh/sshd_config | grep 'Port ' | awk '{print $2}'")
|
||||
oldPort, err := shell.Execf("cat /etc/ssh/sshd_config | grep 'Port ' | awk '{print $2}'")
|
||||
if err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, oldPort)
|
||||
}
|
||||
_, _ = tools.Exec("sed -i 's/#Port " + oldPort + "/Port " + cast.ToString(port) + "/g' /etc/ssh/sshd_config")
|
||||
_, _ = tools.Exec("sed -i 's/Port " + oldPort + "/Port " + cast.ToString(port) + "/g' /etc/ssh/sshd_config")
|
||||
_, _ = shell.Execf("sed -i 's/#Port %s/Port %d/g' /etc/ssh/sshd_config", oldPort, port)
|
||||
_, _ = shell.Execf("sed -i 's/Port %s/Port %d/g' /etc/ssh/sshd_config", oldPort, port)
|
||||
|
||||
status, _ := tools.ServiceStatus(r.ssh)
|
||||
if status {
|
||||
@@ -295,7 +296,7 @@ func (r *SafeController) SetSshPort(ctx http.Context) http.Response {
|
||||
// GetPingStatus 获取 Ping 状态
|
||||
func (r *SafeController) GetPingStatus(ctx http.Context) http.Response {
|
||||
if tools.IsRHEL() {
|
||||
out, err := tools.Exec(`firewall-cmd --list-all 2>&1`)
|
||||
out, err := shell.Execf(`firewall-cmd --list-all`)
|
||||
if err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
@@ -324,15 +325,15 @@ func (r *SafeController) SetPingStatus(ctx http.Context) http.Response {
|
||||
var err error
|
||||
if tools.IsRHEL() {
|
||||
if ctx.Request().InputBool("status") {
|
||||
out, err = tools.Exec(`firewall-cmd --permanent --remove-rich-rule='rule protocol value=icmp drop'`)
|
||||
out, err = shell.Execf(`firewall-cmd --permanent --remove-rich-rule='rule protocol value=icmp drop'`)
|
||||
} else {
|
||||
out, err = tools.Exec(`firewall-cmd --permanent --add-rich-rule='rule protocol value=icmp drop'`)
|
||||
out, err = shell.Execf(`firewall-cmd --permanent --add-rich-rule='rule protocol value=icmp drop'`)
|
||||
}
|
||||
} else {
|
||||
if ctx.Request().InputBool("status") {
|
||||
out, err = tools.Exec(`sed -i 's/-A ufw-before-input -p icmp --icmp-type echo-request -j DROP/-A ufw-before-input -p icmp --icmp-type echo-request -j ACCEPT/g' /etc/ufw/before.rules`)
|
||||
out, err = shell.Execf(`sed -i 's/-A ufw-before-input -p icmp --icmp-type echo-request -j DROP/-A ufw-before-input -p icmp --icmp-type echo-request -j ACCEPT/g' /etc/ufw/before.rules`)
|
||||
} else {
|
||||
out, err = tools.Exec(`sed -i 's/-A ufw-before-input -p icmp --icmp-type echo-request -j ACCEPT/-A ufw-before-input -p icmp --icmp-type echo-request -j DROP/g' /etc/ufw/before.rules`)
|
||||
out, err = shell.Execf(`sed -i 's/-A ufw-before-input -p icmp --icmp-type echo-request -j ACCEPT/-A ufw-before-input -p icmp --icmp-type echo-request -j DROP/g' /etc/ufw/before.rules`)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -341,9 +342,9 @@ func (r *SafeController) SetPingStatus(ctx http.Context) http.Response {
|
||||
}
|
||||
|
||||
if tools.IsRHEL() {
|
||||
out, err = tools.Exec(`firewall-cmd --reload`)
|
||||
out, err = shell.Execf(`firewall-cmd --reload`)
|
||||
} else {
|
||||
out, err = tools.Exec(`ufw reload`)
|
||||
out, err = shell.Execf(`ufw reload`)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
|
||||
@@ -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/shell"
|
||||
"github.com/TheTNB/panel/pkg/tools"
|
||||
)
|
||||
|
||||
@@ -50,7 +51,7 @@ func (r *SettingController) List(ctx http.Context) http.Response {
|
||||
return ErrorSystem(ctx)
|
||||
}
|
||||
|
||||
port, err := tools.Exec(`cat /www/panel/panel.conf | grep APP_PORT | awk -F '=' '{print $2}' | tr -d '\n'`)
|
||||
port, err := shell.Execf(`cat /www/panel/panel.conf | grep APP_PORT | awk -F '=' '{print $2}' | tr -d '\n'`)
|
||||
if err != nil {
|
||||
facades.Log().Request(ctx.Request()).Tags("面板", "面板设置").With(map[string]any{
|
||||
"error": err.Error(),
|
||||
@@ -147,7 +148,7 @@ func (r *SettingController) Update(ctx http.Context) http.Response {
|
||||
return ErrorSystem(ctx)
|
||||
}
|
||||
|
||||
oldPort, err := tools.Exec(`cat /www/panel/panel.conf | grep APP_PORT | awk -F '=' '{print $2}' | tr -d '\n'`)
|
||||
oldPort, err := shell.Execf(`cat /www/panel/panel.conf | grep APP_PORT | awk -F '=' '{print $2}' | tr -d '\n'`)
|
||||
if err != nil {
|
||||
facades.Log().Request(ctx.Request()).Tags("面板", "面板设置").With(map[string]any{
|
||||
"error": err.Error(),
|
||||
@@ -157,33 +158,33 @@ func (r *SettingController) Update(ctx http.Context) http.Response {
|
||||
|
||||
port := cast.ToString(updateRequest.Port)
|
||||
if oldPort != port {
|
||||
if out, err := tools.Exec("sed -i 's/APP_PORT=" + oldPort + "/APP_PORT=" + port + "/g' /www/panel/panel.conf"); err != nil {
|
||||
if out, err := shell.Execf("sed -i 's/APP_PORT=%s/APP_PORT=%s/g' /www/panel/panel.conf", oldPort, port); err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
if tools.IsRHEL() {
|
||||
if out, err := tools.Exec("firewall-cmd --remove-port=" + cast.ToString(port) + "/tcp --permanent 2>&1"); err != nil {
|
||||
if out, err := shell.Execf("firewall-cmd --remove-port=%s/tcp --permanent", oldPort); err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
if out, err := tools.Exec("firewall-cmd --add-port=" + cast.ToString(port) + "/tcp --permanent 2>&1"); err != nil {
|
||||
if out, err := shell.Execf("firewall-cmd --add-port=%s/tcp --permanent", port); err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
if out, err := tools.Exec("firewall-cmd --reload"); err != nil {
|
||||
if out, err := shell.Execf("firewall-cmd --reload"); err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
} else {
|
||||
if out, err := tools.Exec("ufw delete allow " + cast.ToString(port) + "/tcp"); err != nil {
|
||||
if out, err := shell.Execf("ufw delete allow %s/tcp", oldPort); err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
if out, err := tools.Exec("ufw allow " + cast.ToString(port) + "/tcp"); err != nil {
|
||||
if out, err := shell.Execf("ufw allow %s/tcp", port); err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
if out, err := tools.Exec("ufw reload"); err != nil {
|
||||
if out, err := shell.Execf("ufw reload"); err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
oldEntrance, err := tools.Exec(`cat /www/panel/panel.conf | grep APP_ENTRANCE | awk -F '=' '{print $2}' | tr -d '\n'`)
|
||||
oldEntrance, err := shell.Execf(`cat /www/panel/panel.conf | grep APP_ENTRANCE | awk -F '=' '{print $2}' | tr -d '\n'`)
|
||||
if err != nil {
|
||||
facades.Log().Request(ctx.Request()).Tags("面板", "面板设置").With(map[string]any{
|
||||
"error": err.Error(),
|
||||
@@ -192,12 +193,12 @@ func (r *SettingController) Update(ctx http.Context) http.Response {
|
||||
}
|
||||
entrance := cast.ToString(updateRequest.Entrance)
|
||||
if oldEntrance != entrance {
|
||||
if out, err := tools.Exec("sed -i 's!APP_ENTRANCE=" + oldEntrance + "!APP_ENTRANCE=" + entrance + "!g' /www/panel/panel.conf"); err != nil {
|
||||
if out, err := shell.Execf("sed -i 's!APP_ENTRANCE=" + oldEntrance + "!APP_ENTRANCE=" + entrance + "!g' /www/panel/panel.conf"); err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
}
|
||||
|
||||
oldLanguage, err := tools.Exec(`cat /www/panel/panel.conf | grep APP_LOCALE | awk -F '=' '{print $2}' | tr -d '\n'`)
|
||||
oldLanguage, err := shell.Execf(`cat /www/panel/panel.conf | grep APP_LOCALE | awk -F '=' '{print $2}' | tr -d '\n'`)
|
||||
if err != nil {
|
||||
facades.Log().Request(ctx.Request()).Tags("面板", "面板设置").With(map[string]any{
|
||||
"error": err.Error(),
|
||||
@@ -205,17 +206,17 @@ func (r *SettingController) Update(ctx http.Context) http.Response {
|
||||
return ErrorSystem(ctx)
|
||||
}
|
||||
if oldLanguage != updateRequest.Language {
|
||||
if out, err := tools.Exec("sed -i 's/APP_LOCALE=" + oldLanguage + "/APP_LOCALE=" + updateRequest.Language + "/g' /www/panel/panel.conf"); err != nil {
|
||||
if out, err := shell.Execf("sed -i 's/APP_LOCALE=" + oldLanguage + "/APP_LOCALE=" + updateRequest.Language + "/g' /www/panel/panel.conf"); err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
}
|
||||
|
||||
if updateRequest.SSL {
|
||||
if out, err := tools.Exec("sed -i 's/APP_SSL=false/APP_SSL=true/g' /www/panel/panel.conf"); err != nil {
|
||||
if out, err := shell.Execf("sed -i 's/APP_SSL=false/APP_SSL=true/g' /www/panel/panel.conf"); err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
} else {
|
||||
if out, err := tools.Exec("sed -i 's/APP_SSL=true/APP_SSL=false/g' /www/panel/panel.conf"); err != nil {
|
||||
if out, err := shell.Execf("sed -i 's/APP_SSL=true/APP_SSL=false/g' /www/panel/panel.conf"); err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ import (
|
||||
"github.com/goravel/framework/facades"
|
||||
|
||||
"github.com/TheTNB/panel/app/models"
|
||||
"github.com/TheTNB/panel/pkg/tools"
|
||||
"github.com/TheTNB/panel/pkg/shell"
|
||||
)
|
||||
|
||||
type TaskController struct {
|
||||
@@ -63,7 +63,7 @@ func (r *TaskController) Log(ctx http.Context) http.Response {
|
||||
return ErrorSystem(ctx)
|
||||
}
|
||||
|
||||
log, err := tools.Exec(`tail -n 500 '` + task.Log + `'`)
|
||||
log, err := shell.Execf(`tail -n 500 '` + task.Log + `'`)
|
||||
if err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, "日志已被清理")
|
||||
}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
package jobs
|
||||
|
||||
import (
|
||||
"github.com/TheTNB/panel/pkg/tools"
|
||||
"github.com/goravel/framework/facades"
|
||||
|
||||
"github.com/TheTNB/panel/app/models"
|
||||
"github.com/TheTNB/panel/pkg/shell"
|
||||
)
|
||||
|
||||
// ProcessTask 处理面板任务
|
||||
@@ -48,7 +48,7 @@ func (receiver *ProcessTask) Handle(args ...any) error {
|
||||
"task_id": taskID,
|
||||
}).Infof("开始执行任务")
|
||||
|
||||
if _, err := tools.Exec(task.Shell); err != nil {
|
||||
if _, err := shell.Execf(task.Shell); err != nil {
|
||||
task.Status = models.TaskStatusFailed
|
||||
if err := facades.Orm().Query().Save(&task); err != nil {
|
||||
facades.Log().Tags("面板", "异步任务").With(map[string]any{
|
||||
|
||||
@@ -11,6 +11,7 @@ import (
|
||||
|
||||
"github.com/TheTNB/panel/app/models"
|
||||
"github.com/TheTNB/panel/internal"
|
||||
"github.com/TheTNB/panel/pkg/shell"
|
||||
"github.com/TheTNB/panel/pkg/tools"
|
||||
"github.com/TheTNB/panel/types"
|
||||
)
|
||||
@@ -73,7 +74,7 @@ func (s *BackupImpl) WebSiteBackup(website models.Website) error {
|
||||
}
|
||||
|
||||
backupFile := backupPath + "/" + website.Name + "_" + carbon.Now().ToShortDateTimeString() + ".zip"
|
||||
if _, err := tools.Exec(`cd '` + website.Path + `' && zip -r '` + backupFile + `' .`); err != nil {
|
||||
if _, err := shell.Execf(`cd '` + website.Path + `' && zip -r '` + backupFile + `' .`); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -163,10 +164,10 @@ func (s *BackupImpl) MysqlBackup(database string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, err := tools.Exec("/www/server/mysql/bin/mysqldump -uroot " + database + " > " + backupPath + "/" + backupFile); err != nil {
|
||||
if _, err := shell.Execf("/www/server/mysql/bin/mysqldump -uroot " + database + " > " + backupPath + "/" + backupFile); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := tools.Exec("cd " + backupPath + " && zip -r " + backupPath + "/" + backupFile + ".zip " + backupFile); err != nil {
|
||||
if _, err := shell.Execf("cd " + backupPath + " && zip -r " + backupPath + "/" + backupFile + ".zip " + backupFile); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := tools.Remove(backupPath + "/" + backupFile); err != nil {
|
||||
@@ -217,7 +218,7 @@ func (s *BackupImpl) MysqlRestore(database string, backupFile string) error {
|
||||
return errors.New("无法找到备份文件")
|
||||
}
|
||||
|
||||
if _, err = tools.Exec("/www/server/mysql/bin/mysql -uroot " + database + " < " + filepath.Join(tempDir, backupFile)); err != nil {
|
||||
if _, err = shell.Execf("/www/server/mysql/bin/mysql -uroot " + database + " < " + filepath.Join(tempDir, backupFile)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -271,10 +272,10 @@ func (s *BackupImpl) PostgresqlBackup(database string) error {
|
||||
}
|
||||
}
|
||||
|
||||
if _, err := tools.Exec(`su - postgres -c "pg_dump ` + database + `" > ` + backupPath + "/" + backupFile); err != nil {
|
||||
if _, err := shell.Execf(`su - postgres -c "pg_dump ` + database + `" > ` + backupPath + "/" + backupFile); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := tools.Exec("cd " + backupPath + " && zip -r " + backupPath + "/" + backupFile + ".zip " + backupFile); err != nil {
|
||||
if _, err := shell.Execf("cd " + backupPath + " && zip -r " + backupPath + "/" + backupFile + ".zip " + backupFile); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -317,7 +318,7 @@ func (s *BackupImpl) PostgresqlRestore(database string, backupFile string) error
|
||||
return errors.New("无法找到备份文件")
|
||||
}
|
||||
|
||||
if _, err = tools.Exec(`su - postgres -c "psql ` + database + `" < ` + filepath.Join(tempDir, backupFile)); err != nil {
|
||||
if _, err = shell.Execf(`su - postgres -c "psql ` + database + `" < ` + filepath.Join(tempDir, backupFile)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/TheTNB/panel/app/models"
|
||||
"github.com/TheTNB/panel/pkg/shell"
|
||||
"github.com/TheTNB/panel/pkg/tools"
|
||||
)
|
||||
|
||||
@@ -19,14 +20,14 @@ func NewCronImpl() *CronImpl {
|
||||
// AddToSystem 添加到系统
|
||||
func (r *CronImpl) AddToSystem(cron models.Cron) error {
|
||||
if tools.IsRHEL() {
|
||||
if _, err := tools.Exec(fmt.Sprintf(`echo "%s %s >> %s 2>&1" >> /var/spool/cron/root`, cron.Time, cron.Shell, cron.Log)); err != nil {
|
||||
if _, err := shell.Execf(fmt.Sprintf(`echo "%s %s >> %s 2>&1" >> /var/spool/cron/root`, cron.Time, cron.Shell, cron.Log)); err != nil {
|
||||
return err
|
||||
}
|
||||
return tools.ServiceRestart("crond")
|
||||
}
|
||||
|
||||
if tools.IsDebian() {
|
||||
if _, err := tools.Exec(fmt.Sprintf(`echo "%s %s >> %s 2>&1" >> /var/spool/cron/crontabs/root`, cron.Time, cron.Shell, cron.Log)); err != nil {
|
||||
if _, err := shell.Execf(fmt.Sprintf(`echo "%s %s >> %s 2>&1" >> /var/spool/cron/crontabs/root`, cron.Time, cron.Shell, cron.Log)); err != nil {
|
||||
return err
|
||||
}
|
||||
return tools.ServiceRestart("cron")
|
||||
@@ -40,14 +41,14 @@ func (r *CronImpl) DeleteFromSystem(cron models.Cron) error {
|
||||
// 需要转义 shell 路径的/为\/
|
||||
cron.Shell = strings.ReplaceAll(cron.Shell, "/", "\\/")
|
||||
if tools.IsRHEL() {
|
||||
if _, err := tools.Exec("sed -i '/" + cron.Shell + "/d' /var/spool/cron/root"); err != nil {
|
||||
if _, err := shell.Execf("sed -i '/" + cron.Shell + "/d' /var/spool/cron/root"); err != nil {
|
||||
return err
|
||||
}
|
||||
return tools.ServiceRestart("crond")
|
||||
}
|
||||
|
||||
if tools.IsDebian() {
|
||||
if _, err := tools.Exec("sed -i '/" + cron.Shell + "/d' /var/spool/cron/crontabs/root"); err != nil {
|
||||
if _, err := shell.Execf("sed -i '/" + cron.Shell + "/d' /var/spool/cron/crontabs/root"); err != nil {
|
||||
return err
|
||||
}
|
||||
return tools.ServiceRestart("cron")
|
||||
|
||||
@@ -13,6 +13,7 @@ import (
|
||||
"github.com/spf13/cast"
|
||||
|
||||
"github.com/TheTNB/panel/app/models"
|
||||
"github.com/TheTNB/panel/pkg/shell"
|
||||
"github.com/TheTNB/panel/pkg/tools"
|
||||
"github.com/TheTNB/panel/types"
|
||||
)
|
||||
@@ -82,15 +83,15 @@ func (r *PHPImpl) Load() ([]types.NV, error) {
|
||||
}
|
||||
|
||||
func (r *PHPImpl) GetErrorLog() (string, error) {
|
||||
return tools.Exec("tail -n 500 /www/server/php/" + r.version + "/var/log/php-fpm.log")
|
||||
return shell.Execf("tail -n 500 /www/server/php/%s/var/log/php-fpm.log", r.version)
|
||||
}
|
||||
|
||||
func (r *PHPImpl) GetSlowLog() (string, error) {
|
||||
return tools.Exec("tail -n 500 /www/server/php/" + r.version + "/var/log/slow.log")
|
||||
return shell.Execf("tail -n 500 /www/server/php/%s/var/log/slow.log", r.version)
|
||||
}
|
||||
|
||||
func (r *PHPImpl) ClearErrorLog() error {
|
||||
if out, err := tools.Exec("echo '' > /www/server/php/" + r.version + "/var/log/php-fpm.log"); err != nil {
|
||||
if out, err := shell.Execf("echo '' > /www/server/php/%s/var/log/php-fpm.log", r.version); err != nil {
|
||||
return errors.New(out)
|
||||
}
|
||||
|
||||
@@ -98,7 +99,7 @@ func (r *PHPImpl) ClearErrorLog() error {
|
||||
}
|
||||
|
||||
func (r *PHPImpl) ClearSlowLog() error {
|
||||
if out, err := tools.Exec("echo '' > /www/server/php/" + r.version + "/var/log/slow.log"); err != nil {
|
||||
if out, err := shell.Execf("echo '' > /www/server/php/%s/var/log/slow.log", r.version); err != nil {
|
||||
return errors.New(out)
|
||||
}
|
||||
|
||||
@@ -270,7 +271,7 @@ func (r *PHPImpl) GetExtensions() ([]types.PHPExtension, error) {
|
||||
})
|
||||
}
|
||||
|
||||
raw, err := tools.Exec("/www/server/php/" + r.version + "/bin/php -m")
|
||||
raw, err := shell.Execf("/www/server/php/%s/bin/php -m", r.version)
|
||||
if err != nil {
|
||||
return extensions, err
|
||||
}
|
||||
|
||||
@@ -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/shell"
|
||||
"github.com/TheTNB/panel/pkg/tools"
|
||||
"github.com/TheTNB/panel/types"
|
||||
)
|
||||
@@ -285,18 +286,18 @@ server
|
||||
|
||||
rootPassword := r.setting.Get(models.SettingKeyMysqlRootPassword)
|
||||
if website.Db && website.DbType == "mysql" {
|
||||
_, _ = tools.Exec(`/www/server/mysql/bin/mysql -uroot -p` + rootPassword + ` -e "CREATE DATABASE IF NOT EXISTS ` + website.DbName + ` DEFAULT CHARSET utf8mb4 COLLATE utf8mb4_general_ci;"`)
|
||||
_, _ = tools.Exec(`/www/server/mysql/bin/mysql -uroot -p` + rootPassword + ` -e "CREATE USER '` + website.DbUser + `'@'localhost' IDENTIFIED BY '` + website.DbPassword + `';"`)
|
||||
_, _ = tools.Exec(`/www/server/mysql/bin/mysql -uroot -p` + rootPassword + ` -e "GRANT ALL PRIVILEGES ON ` + website.DbName + `.* TO '` + website.DbUser + `'@'localhost';"`)
|
||||
_, _ = tools.Exec(`/www/server/mysql/bin/mysql -uroot -p` + rootPassword + ` -e "FLUSH PRIVILEGES;"`)
|
||||
_, _ = shell.Execf(`/www/server/mysql/bin/mysql -uroot -p` + rootPassword + ` -e "CREATE DATABASE IF NOT EXISTS ` + website.DbName + ` DEFAULT CHARSET utf8mb4 COLLATE utf8mb4_general_ci;"`)
|
||||
_, _ = shell.Execf(`/www/server/mysql/bin/mysql -uroot -p` + rootPassword + ` -e "CREATE USER '` + website.DbUser + `'@'localhost' IDENTIFIED BY '` + website.DbPassword + `';"`)
|
||||
_, _ = shell.Execf(`/www/server/mysql/bin/mysql -uroot -p` + rootPassword + ` -e "GRANT ALL PRIVILEGES ON ` + website.DbName + `.* TO '` + website.DbUser + `'@'localhost';"`)
|
||||
_, _ = shell.Execf(`/www/server/mysql/bin/mysql -uroot -p` + rootPassword + ` -e "FLUSH PRIVILEGES;"`)
|
||||
}
|
||||
if website.Db && website.DbType == "postgresql" {
|
||||
_, _ = tools.Exec(`echo "CREATE DATABASE ` + website.DbName + `;" | su - postgres -c "psql"`)
|
||||
_, _ = tools.Exec(`echo "CREATE USER ` + website.DbUser + ` WITH PASSWORD '` + website.DbPassword + `';" | su - postgres -c "psql"`)
|
||||
_, _ = tools.Exec(`echo "ALTER DATABASE ` + website.DbName + ` OWNER TO ` + website.DbUser + `;" | su - postgres -c "psql"`)
|
||||
_, _ = tools.Exec(`echo "GRANT ALL PRIVILEGES ON DATABASE ` + website.DbName + ` TO ` + website.DbUser + `;" | su - postgres -c "psql"`)
|
||||
_, _ = shell.Execf(`echo "CREATE DATABASE ` + website.DbName + `;" | su - postgres -c "psql"`)
|
||||
_, _ = shell.Execf(`echo "CREATE USER ` + website.DbUser + ` WITH PASSWORD '` + website.DbPassword + `';" | su - postgres -c "psql"`)
|
||||
_, _ = shell.Execf(`echo "ALTER DATABASE ` + website.DbName + ` OWNER TO ` + website.DbUser + `;" | su - postgres -c "psql"`)
|
||||
_, _ = shell.Execf(`echo "GRANT ALL PRIVILEGES ON DATABASE ` + website.DbName + ` TO ` + website.DbUser + `;" | su - postgres -c "psql"`)
|
||||
userConfig := "host " + website.DbName + " " + website.DbUser + " 127.0.0.1/32 scram-sha-256"
|
||||
_, _ = tools.Exec(`echo "` + userConfig + `" >> /www/server/postgresql/data/pg_hba.conf`)
|
||||
_, _ = shell.Execf(`echo "` + userConfig + `" >> /www/server/postgresql/data/pg_hba.conf`)
|
||||
_ = tools.ServiceReload("postgresql")
|
||||
}
|
||||
|
||||
@@ -659,7 +660,7 @@ func (r *WebsiteImpl) GetConfig(id uint) (types.WebsiteSetting, error) {
|
||||
|
||||
rewrite, _ := tools.Read("/www/server/vhost/rewrite/" + website.Name + ".conf")
|
||||
setting.Rewrite = rewrite
|
||||
log, _ := tools.Exec(`tail -n 100 '/www/wwwlogs/` + website.Name + `.log'`)
|
||||
log, _ := shell.Execf(`tail -n 100 '/www/wwwlogs/%s.log'`, website.Name)
|
||||
setting.Log = log
|
||||
|
||||
return setting, err
|
||||
|
||||
119
pkg/shell/exec.go
Normal file
119
pkg/shell/exec.go
Normal file
@@ -0,0 +1,119 @@
|
||||
package shell
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/TheTNB/panel/pkg/slice"
|
||||
"github.com/goravel/framework/support"
|
||||
)
|
||||
|
||||
// Execf 执行 shell 命令
|
||||
func Execf(shell string, args ...any) (string, error) {
|
||||
if !CheckArgs(slice.ToString(args)...) {
|
||||
return "", errors.New("你想干什么?")
|
||||
}
|
||||
|
||||
var cmd *exec.Cmd
|
||||
_ = os.Setenv("LC_ALL", "C")
|
||||
cmd = exec.Command("bash", "-c", fmt.Sprintf(shell, args...))
|
||||
|
||||
var stdout, stderr bytes.Buffer
|
||||
cmd.Stdout = &stdout
|
||||
cmd.Stderr = &stderr
|
||||
|
||||
err := cmd.Run()
|
||||
if err != nil {
|
||||
return "", errors.New(strings.TrimSpace(stderr.String()))
|
||||
}
|
||||
|
||||
return strings.TrimSpace(stdout.String()), err
|
||||
}
|
||||
|
||||
// ExecfAsync 异步执行 shell 命令
|
||||
func ExecfAsync(shell string, args ...any) error {
|
||||
if !CheckArgs(slice.ToString(args)...) {
|
||||
return errors.New("你想干什么?")
|
||||
}
|
||||
|
||||
var cmd *exec.Cmd
|
||||
_ = os.Setenv("LC_ALL", "C")
|
||||
cmd = exec.Command("bash", "-c", fmt.Sprintf(shell, args...))
|
||||
|
||||
err := cmd.Start()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
go func() {
|
||||
err := cmd.Wait()
|
||||
if err != nil {
|
||||
if support.Env == support.EnvTest {
|
||||
fmt.Println(err.Error())
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ExecfWithTimeout 执行 shell 命令并设置超时时间
|
||||
func ExecfWithTimeout(timeout time.Duration, shell string, args ...any) (string, error) {
|
||||
if !CheckArgs(slice.ToString(args)...) {
|
||||
return "", errors.New("你想干什么?")
|
||||
}
|
||||
|
||||
var cmd *exec.Cmd
|
||||
_ = os.Setenv("LC_ALL", "C")
|
||||
cmd = exec.Command("bash", "-c", fmt.Sprintf(shell, args...))
|
||||
|
||||
var stdout, stderr bytes.Buffer
|
||||
cmd.Stdout = &stdout
|
||||
cmd.Stderr = &stderr
|
||||
|
||||
err := cmd.Start()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
done := make(chan error)
|
||||
go func() {
|
||||
done <- cmd.Wait()
|
||||
}()
|
||||
|
||||
select {
|
||||
case <-time.After(timeout):
|
||||
_ = cmd.Process.Kill()
|
||||
return "", errors.New("执行超时")
|
||||
case err = <-done:
|
||||
if err != nil {
|
||||
return "", errors.New(strings.TrimSpace(stderr.String()))
|
||||
}
|
||||
}
|
||||
|
||||
return strings.TrimSpace(stdout.String()), err
|
||||
}
|
||||
|
||||
// CheckArgs 检查危险的参数
|
||||
func CheckArgs(args ...string) bool {
|
||||
if len(args) == 0 {
|
||||
return true
|
||||
}
|
||||
|
||||
dangerous := []string{"&", "|", ";", "$", "'", `"`, "(", ")", "`", "\n", "\r", ">", "<", "{", "}", "[", "]", "\\"}
|
||||
for _, arg := range args {
|
||||
for _, char := range dangerous {
|
||||
if strings.Contains(arg, char) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
30
pkg/slice/slice.go
Normal file
30
pkg/slice/slice.go
Normal file
@@ -0,0 +1,30 @@
|
||||
package slice
|
||||
|
||||
import "github.com/spf13/cast"
|
||||
|
||||
// ToAny 将任意类型切片转换为 []any
|
||||
func ToAny[T any](s []T) []any {
|
||||
result := make([]any, len(s))
|
||||
for i, v := range s {
|
||||
result[i] = v
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// ToString 将任意类型切片转换为 []string
|
||||
func ToString[T any](s []T) []string {
|
||||
result := make([]string, len(s))
|
||||
for i, v := range s {
|
||||
result[i] = cast.ToString(v)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// ToInt 将任意类型切片转换为 []int
|
||||
func ToInt[T any](s []T) []int {
|
||||
result := make([]int, len(s))
|
||||
for i, v := range s {
|
||||
result[i] = cast.ToInt(v)
|
||||
}
|
||||
return result
|
||||
}
|
||||
@@ -2,14 +2,15 @@ package tools
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"os/exec"
|
||||
"strings"
|
||||
|
||||
"github.com/TheTNB/panel/pkg/shell"
|
||||
)
|
||||
|
||||
// ServiceStatus 获取服务状态
|
||||
func ServiceStatus(name string) (bool, error) {
|
||||
output, err := Exec(fmt.Sprintf("systemctl status %s | grep Active | grep -v grep | awk '{print $2}'", name))
|
||||
output, err := shell.Execf("systemctl status %s | grep Active | grep -v grep | awk '{print $2}'", name)
|
||||
return output == "active", err
|
||||
}
|
||||
|
||||
@@ -37,36 +38,36 @@ func ServiceIsEnabled(name string) (bool, error) {
|
||||
|
||||
// ServiceStart 启动服务
|
||||
func ServiceStart(name string) error {
|
||||
_, err := Exec(fmt.Sprintf("systemctl start %s", name))
|
||||
_, err := shell.Execf("systemctl start %s", name)
|
||||
return err
|
||||
}
|
||||
|
||||
// ServiceStop 停止服务
|
||||
func ServiceStop(name string) error {
|
||||
_, err := Exec(fmt.Sprintf("systemctl stop %s", name))
|
||||
_, err := shell.Execf("systemctl stop %s", name)
|
||||
return err
|
||||
}
|
||||
|
||||
// ServiceRestart 重启服务
|
||||
func ServiceRestart(name string) error {
|
||||
_, err := Exec(fmt.Sprintf("systemctl restart %s", name))
|
||||
_, err := shell.Execf("systemctl restart %s", name)
|
||||
return err
|
||||
}
|
||||
|
||||
// ServiceReload 重载服务
|
||||
func ServiceReload(name string) error {
|
||||
_, err := Exec(fmt.Sprintf("systemctl reload %s", name))
|
||||
_, err := shell.Execf("systemctl reload %s", name)
|
||||
return err
|
||||
}
|
||||
|
||||
// ServiceEnable 启用服务
|
||||
func ServiceEnable(name string) error {
|
||||
_, err := Exec(fmt.Sprintf("systemctl enable %s", name))
|
||||
_, err := shell.Execf("systemctl enable %s", name)
|
||||
return err
|
||||
}
|
||||
|
||||
// ServiceDisable 禁用服务
|
||||
func ServiceDisable(name string) error {
|
||||
_, err := Exec(fmt.Sprintf("systemctl disable %s", name))
|
||||
_, err := shell.Execf("systemctl disable %s", name)
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package tools
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
@@ -11,7 +10,6 @@ import (
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/goravel/framework/support"
|
||||
"github.com/goravel/framework/support/env"
|
||||
"github.com/mholt/archiver/v3"
|
||||
"github.com/spf13/cast"
|
||||
@@ -58,54 +56,6 @@ func Remove(path string) error {
|
||||
return os.RemoveAll(path)
|
||||
}
|
||||
|
||||
// Exec 执行 shell 命令
|
||||
func Exec(shell string) (string, error) {
|
||||
var cmd *exec.Cmd
|
||||
if env.IsLinux() {
|
||||
cmd = exec.Command("bash", "-c", "LC_ALL=C "+shell)
|
||||
} else {
|
||||
cmd = exec.Command("cmd", "/C", "chcp 65001 >nul && "+shell)
|
||||
}
|
||||
|
||||
var stdoutBuf, stderrBuf bytes.Buffer
|
||||
cmd.Stdout = &stdoutBuf
|
||||
cmd.Stderr = &stderrBuf
|
||||
|
||||
err := cmd.Run()
|
||||
if err != nil {
|
||||
return "", errors.New(strings.TrimSpace(stderrBuf.String()))
|
||||
}
|
||||
|
||||
return strings.TrimSpace(stdoutBuf.String()), err
|
||||
}
|
||||
|
||||
// ExecAsync 异步执行 shell 命令
|
||||
func ExecAsync(shell string) error {
|
||||
var cmd *exec.Cmd
|
||||
if env.IsLinux() {
|
||||
cmd = exec.Command("bash", "-c", "LC_ALL=C "+shell)
|
||||
} else {
|
||||
cmd = exec.Command("cmd", "/C", "chcp 65001 >nul && "+shell)
|
||||
}
|
||||
|
||||
err := cmd.Start()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
go func() {
|
||||
err := cmd.Wait()
|
||||
if err != nil {
|
||||
if support.Env == support.EnvTest {
|
||||
fmt.Println(err.Error())
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Mkdir 创建目录
|
||||
func Mkdir(path string, permission os.FileMode) error {
|
||||
return os.MkdirAll(path, permission)
|
||||
|
||||
@@ -4,7 +4,6 @@ package tools
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/spf13/cast"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
@@ -19,6 +18,9 @@ import (
|
||||
"github.com/shirou/gopsutil/load"
|
||||
"github.com/shirou/gopsutil/mem"
|
||||
"github.com/shirou/gopsutil/net"
|
||||
"github.com/spf13/cast"
|
||||
|
||||
"github.com/TheTNB/panel/pkg/shell"
|
||||
)
|
||||
|
||||
// MonitoringInfo 监控信息
|
||||
@@ -159,9 +161,9 @@ func GetLatestPanelVersion() (PanelInfo, error) {
|
||||
isChina := IsChina()
|
||||
|
||||
if isChina {
|
||||
output, err = Exec(`curl -sSL "https://git.haozi.net/api/v4/projects/opensource%2Fpanel/releases/permalink/latest"`)
|
||||
output, err = shell.Execf(`curl -sSL "https://git.haozi.net/api/v4/projects/opensource%2Fpanel/releases/permalink/latest"`)
|
||||
} else {
|
||||
output, err = Exec(`curl -sSL "https://api.github.com/repos/TheTNB/panel/releases/latest"`)
|
||||
output, err = shell.Execf(`curl -sSL "https://api.github.com/repos/TheTNB/panel/releases/latest"`)
|
||||
}
|
||||
|
||||
if len(output) == 0 || err != nil {
|
||||
@@ -185,70 +187,70 @@ func GetLatestPanelVersion() (PanelInfo, error) {
|
||||
|
||||
var name, version, body, date, downloadName, downloadUrl, checksums, checksumsUrl string
|
||||
if isChina {
|
||||
if name, err = Exec("jq -r '.name' " + fileName); err != nil {
|
||||
if name, err = shell.Execf("jq -r '.name' " + fileName); err != nil {
|
||||
return info, errors.New("获取最新版本失败")
|
||||
}
|
||||
if version, err = Exec("jq -r '.tag_name' " + fileName); err != nil {
|
||||
if version, err = shell.Execf("jq -r '.tag_name' " + fileName); err != nil {
|
||||
return info, errors.New("获取最新版本失败")
|
||||
}
|
||||
if body, err = Exec("jq -r '.description' " + fileName); err != nil {
|
||||
if body, err = shell.Execf("jq -r '.description' " + fileName); err != nil {
|
||||
return info, errors.New("获取最新版本失败")
|
||||
}
|
||||
if date, err = Exec("jq -r '.created_at' " + fileName); err != nil {
|
||||
if date, err = shell.Execf("jq -r '.created_at' " + fileName); err != nil {
|
||||
return info, errors.New("获取最新版本失败")
|
||||
}
|
||||
if checksums, err = Exec("jq -r '.assets.links[] | select(.name | contains(\"checksums\")) | .name' " + fileName); err != nil {
|
||||
if checksums, err = shell.Execf("jq -r '.assets.links[] | select(.name | contains(\"checksums\")) | .name' " + fileName); err != nil {
|
||||
return info, errors.New("获取最新版本失败")
|
||||
}
|
||||
if checksumsUrl, err = Exec("jq -r '.assets.links[] | select(.name | contains(\"checksums\")) | .direct_asset_url' " + fileName); err != nil {
|
||||
if checksumsUrl, err = shell.Execf("jq -r '.assets.links[] | select(.name | contains(\"checksums\")) | .direct_asset_url' " + fileName); err != nil {
|
||||
return info, errors.New("获取最新版本失败")
|
||||
}
|
||||
if env.IsArm() {
|
||||
if downloadName, err = Exec("jq -r '.assets.links[] | select(.name | contains(\"arm64\")) | .name' " + fileName); err != nil {
|
||||
if downloadName, err = shell.Execf("jq -r '.assets.links[] | select(.name | contains(\"arm64\")) | .name' " + fileName); err != nil {
|
||||
return info, errors.New("获取最新版本失败")
|
||||
}
|
||||
if downloadUrl, err = Exec("jq -r '.assets.links[] | select(.name | contains(\"arm64\")) | .direct_asset_url' " + fileName); err != nil {
|
||||
if downloadUrl, err = shell.Execf("jq -r '.assets.links[] | select(.name | contains(\"arm64\")) | .direct_asset_url' " + fileName); err != nil {
|
||||
return info, errors.New("获取最新版本失败")
|
||||
}
|
||||
} else {
|
||||
if downloadName, err = Exec("jq -r '.assets.links[] | select(.name | contains(\"amd64v2\")) | .name' " + fileName); err != nil {
|
||||
if downloadName, err = shell.Execf("jq -r '.assets.links[] | select(.name | contains(\"amd64v2\")) | .name' " + fileName); err != nil {
|
||||
return info, errors.New("获取最新版本失败")
|
||||
}
|
||||
if downloadUrl, err = Exec("jq -r '.assets.links[] | select(.name | contains(\"amd64v2\")) | .direct_asset_url' " + fileName); err != nil {
|
||||
if downloadUrl, err = shell.Execf("jq -r '.assets.links[] | select(.name | contains(\"amd64v2\")) | .direct_asset_url' " + fileName); err != nil {
|
||||
return info, errors.New("获取最新版本失败")
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if name, err = Exec("jq -r '.name' " + fileName); err != nil {
|
||||
if name, err = shell.Execf("jq -r '.name' " + fileName); err != nil {
|
||||
return info, errors.New("获取最新版本失败")
|
||||
}
|
||||
if version, err = Exec("jq -r '.tag_name' " + fileName); err != nil {
|
||||
if version, err = shell.Execf("jq -r '.tag_name' " + fileName); err != nil {
|
||||
return info, errors.New("获取最新版本失败")
|
||||
}
|
||||
if body, err = Exec("jq -r '.body' " + fileName); err != nil {
|
||||
if body, err = shell.Execf("jq -r '.body' " + fileName); err != nil {
|
||||
return info, errors.New("获取最新版本失败")
|
||||
}
|
||||
if date, err = Exec("jq -r '.published_at' " + fileName); err != nil {
|
||||
if date, err = shell.Execf("jq -r '.published_at' " + fileName); err != nil {
|
||||
return info, errors.New("获取最新版本失败")
|
||||
}
|
||||
if checksums, err = Exec("jq -r '.assets[] | select(.name | contains(\"checksums\")) | .name' " + fileName); err != nil {
|
||||
if checksums, err = shell.Execf("jq -r '.assets[] | select(.name | contains(\"checksums\")) | .name' " + fileName); err != nil {
|
||||
return info, errors.New("获取最新版本失败")
|
||||
}
|
||||
if checksumsUrl, err = Exec("jq -r '.assets[] | select(.name | contains(\"checksums\")) | .browser_download_url' " + fileName); err != nil {
|
||||
if checksumsUrl, err = shell.Execf("jq -r '.assets[] | select(.name | contains(\"checksums\")) | .browser_download_url' " + fileName); err != nil {
|
||||
return info, errors.New("获取最新版本失败")
|
||||
}
|
||||
if env.IsArm() {
|
||||
if downloadName, err = Exec("jq -r '.assets[] | select(.name | contains(\"arm64\")) | .name' " + fileName); err != nil {
|
||||
if downloadName, err = shell.Execf("jq -r '.assets[] | select(.name | contains(\"arm64\")) | .name' " + fileName); err != nil {
|
||||
return info, errors.New("获取最新版本失败")
|
||||
}
|
||||
if downloadUrl, err = Exec("jq -r '.assets[] | select(.name | contains(\"arm64\")) | .browser_download_url' " + fileName); err != nil {
|
||||
if downloadUrl, err = shell.Execf("jq -r '.assets[] | select(.name | contains(\"arm64\")) | .browser_download_url' " + fileName); err != nil {
|
||||
return info, errors.New("获取最新版本失败")
|
||||
}
|
||||
} else {
|
||||
if downloadName, err = Exec("jq -r '.assets[] | select(.name | contains(\"amd64v2\")) | .name' " + fileName); err != nil {
|
||||
if downloadName, err = shell.Execf("jq -r '.assets[] | select(.name | contains(\"amd64v2\")) | .name' " + fileName); err != nil {
|
||||
return info, errors.New("获取最新版本失败")
|
||||
}
|
||||
if downloadUrl, err = Exec("jq -r '.assets[] | select(.name | contains(\"amd64v2\")) | .browser_download_url' " + fileName); err != nil {
|
||||
if downloadUrl, err = shell.Execf("jq -r '.assets[] | select(.name | contains(\"amd64v2\")) | .browser_download_url' " + fileName); err != nil {
|
||||
return info, errors.New("获取最新版本失败")
|
||||
}
|
||||
}
|
||||
@@ -278,9 +280,9 @@ func GetPanelVersion(version string) (PanelInfo, error) {
|
||||
}
|
||||
|
||||
if isChina {
|
||||
output, err = Exec(`curl -sSL "https://git.haozi.net/api/v4/projects/opensource%2Fpanel/releases/` + version + `"`)
|
||||
output, err = shell.Execf(`curl -sSL "https://git.haozi.net/api/v4/projects/opensource%2Fpanel/releases/` + version + `"`)
|
||||
} else {
|
||||
output, err = Exec(`curl -sSL "https://api.github.com/repos/TheTNB/panel/releases/tags/` + version + `"`)
|
||||
output, err = shell.Execf(`curl -sSL "https://api.github.com/repos/TheTNB/panel/releases/tags/` + version + `"`)
|
||||
}
|
||||
|
||||
if len(output) == 0 || err != nil {
|
||||
@@ -304,70 +306,70 @@ func GetPanelVersion(version string) (PanelInfo, error) {
|
||||
|
||||
var name, version2, body, date, downloadName, downloadUrl, checksums, checksumsUrl string
|
||||
if isChina {
|
||||
if name, err = Exec("jq -r '.name' " + fileName); err != nil {
|
||||
if name, err = shell.Execf("jq -r '.name' " + fileName); err != nil {
|
||||
return info, errors.New("获取面板版本失败")
|
||||
}
|
||||
if version2, err = Exec("jq -r '.tag_name' " + fileName); err != nil {
|
||||
if version2, err = shell.Execf("jq -r '.tag_name' " + fileName); err != nil {
|
||||
return info, errors.New("获取面板版本失败")
|
||||
}
|
||||
if body, err = Exec("jq -r '.description' " + fileName); err != nil {
|
||||
if body, err = shell.Execf("jq -r '.description' " + fileName); err != nil {
|
||||
return info, errors.New("获取面板版本失败")
|
||||
}
|
||||
if date, err = Exec("jq -r '.created_at' " + fileName); err != nil {
|
||||
if date, err = shell.Execf("jq -r '.created_at' " + fileName); err != nil {
|
||||
return info, errors.New("获取面板版本失败")
|
||||
}
|
||||
if checksums, err = Exec("jq -r '.assets.links[] | select(.name | contains(\"checksums\")) | .name' " + fileName); err != nil {
|
||||
if checksums, err = shell.Execf("jq -r '.assets.links[] | select(.name | contains(\"checksums\")) | .name' " + fileName); err != nil {
|
||||
return info, errors.New("获取面板版本失败")
|
||||
}
|
||||
if checksumsUrl, err = Exec("jq -r '.assets.links[] | select(.name | contains(\"checksums\")) | .direct_asset_url' " + fileName); err != nil {
|
||||
if checksumsUrl, err = shell.Execf("jq -r '.assets.links[] | select(.name | contains(\"checksums\")) | .direct_asset_url' " + fileName); err != nil {
|
||||
return info, errors.New("获取面板版本失败")
|
||||
}
|
||||
if env.IsArm() {
|
||||
if downloadName, err = Exec("jq -r '.assets.links[] | select(.name | contains(\"arm64\")) | .name' " + fileName); err != nil {
|
||||
if downloadName, err = shell.Execf("jq -r '.assets.links[] | select(.name | contains(\"arm64\")) | .name' " + fileName); err != nil {
|
||||
return info, errors.New("获取面板版本失败")
|
||||
}
|
||||
if downloadUrl, err = Exec("jq -r '.assets.links[] | select(.name | contains(\"arm64\")) | .direct_asset_url' " + fileName); err != nil {
|
||||
if downloadUrl, err = shell.Execf("jq -r '.assets.links[] | select(.name | contains(\"arm64\")) | .direct_asset_url' " + fileName); err != nil {
|
||||
return info, errors.New("获取面板版本失败")
|
||||
}
|
||||
} else {
|
||||
if downloadName, err = Exec("jq -r '.assets.links[] | select(.name | contains(\"amd64v2\")) | .name' " + fileName); err != nil {
|
||||
if downloadName, err = shell.Execf("jq -r '.assets.links[] | select(.name | contains(\"amd64v2\")) | .name' " + fileName); err != nil {
|
||||
return info, errors.New("获取面板版本失败")
|
||||
}
|
||||
if downloadUrl, err = Exec("jq -r '.assets.links[] | select(.name | contains(\"amd64v2\")) | .direct_asset_url' " + fileName); err != nil {
|
||||
if downloadUrl, err = shell.Execf("jq -r '.assets.links[] | select(.name | contains(\"amd64v2\")) | .direct_asset_url' " + fileName); err != nil {
|
||||
return info, errors.New("获取面板版本失败")
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if name, err = Exec("jq -r '.name' " + fileName); err != nil {
|
||||
if name, err = shell.Execf("jq -r '.name' " + fileName); err != nil {
|
||||
return info, errors.New("获取面板版本失败")
|
||||
}
|
||||
if version2, err = Exec("jq -r '.tag_name' " + fileName); err != nil {
|
||||
if version2, err = shell.Execf("jq -r '.tag_name' " + fileName); err != nil {
|
||||
return info, errors.New("获取面板版本失败")
|
||||
}
|
||||
if body, err = Exec("jq -r '.body' " + fileName); err != nil {
|
||||
if body, err = shell.Execf("jq -r '.body' " + fileName); err != nil {
|
||||
return info, errors.New("获取面板版本失败")
|
||||
}
|
||||
if date, err = Exec("jq -r '.published_at' " + fileName); err != nil {
|
||||
if date, err = shell.Execf("jq -r '.published_at' " + fileName); err != nil {
|
||||
return info, errors.New("获取面板版本失败")
|
||||
}
|
||||
if checksums, err = Exec("jq -r '.assets[] | select(.name | contains(\"checksums\")) | .name' " + fileName); err != nil {
|
||||
if checksums, err = shell.Execf("jq -r '.assets[] | select(.name | contains(\"checksums\")) | .name' " + fileName); err != nil {
|
||||
return info, errors.New("获取面板版本失败")
|
||||
}
|
||||
if checksumsUrl, err = Exec("jq -r '.assets[] | select(.name | contains(\"checksums\")) | .browser_download_url' " + fileName); err != nil {
|
||||
if checksumsUrl, err = shell.Execf("jq -r '.assets[] | select(.name | contains(\"checksums\")) | .browser_download_url' " + fileName); err != nil {
|
||||
return info, errors.New("获取面板版本失败")
|
||||
}
|
||||
if env.IsArm() {
|
||||
if downloadName, err = Exec("jq -r '.assets[] | select(.name | contains(\"arm64\")) | .name' " + fileName); err != nil {
|
||||
if downloadName, err = shell.Execf("jq -r '.assets[] | select(.name | contains(\"arm64\")) | .name' " + fileName); err != nil {
|
||||
return info, errors.New("获取面板版本失败")
|
||||
}
|
||||
if downloadUrl, err = Exec("jq -r '.assets[] | select(.name | contains(\"arm64\")) | .browser_download_url' " + fileName); err != nil {
|
||||
if downloadUrl, err = shell.Execf("jq -r '.assets[] | select(.name | contains(\"arm64\")) | .browser_download_url' " + fileName); err != nil {
|
||||
return info, errors.New("获取面板版本失败")
|
||||
}
|
||||
} else {
|
||||
if downloadName, err = Exec("jq -r '.assets[] | select(.name | contains(\"amd64v2\")) | .name' " + fileName); err != nil {
|
||||
if downloadName, err = shell.Execf("jq -r '.assets[] | select(.name | contains(\"amd64v2\")) | .name' " + fileName); err != nil {
|
||||
return info, errors.New("获取面板版本失败")
|
||||
}
|
||||
if downloadUrl, err = Exec("jq -r '.assets[] | select(.name | contains(\"amd64v2\")) | .browser_download_url' " + fileName); err != nil {
|
||||
if downloadUrl, err = shell.Execf("jq -r '.assets[] | select(.name | contains(\"amd64v2\")) | .browser_download_url' " + fileName); err != nil {
|
||||
return info, errors.New("获取面板版本失败")
|
||||
}
|
||||
}
|
||||
@@ -401,11 +403,11 @@ func UpdatePanel(panelInfo PanelInfo) error {
|
||||
color.Red().Printfln("备份面板失败")
|
||||
return err
|
||||
}
|
||||
if _, err := Exec("cd /www/panel/storage && zip -r /tmp/panel-storage.zip *"); err != nil {
|
||||
if _, err := shell.Execf("cd /www/panel/storage && zip -r /tmp/panel-storage.zip *"); err != nil {
|
||||
color.Red().Printfln("备份面板数据失败")
|
||||
return err
|
||||
}
|
||||
if _, err := Exec("cp -f /www/panel/panel.conf /tmp/panel.conf.bak"); err != nil {
|
||||
if _, err := shell.Execf("cp -f /www/panel/panel.conf /tmp/panel.conf.bak"); err != nil {
|
||||
color.Red().Printfln("备份面板配置失败")
|
||||
return err
|
||||
}
|
||||
@@ -415,18 +417,18 @@ func UpdatePanel(panelInfo PanelInfo) error {
|
||||
color.Green().Printfln("备份完成")
|
||||
|
||||
color.Green().Printfln("清理旧版本...")
|
||||
if _, err := Exec("rm -rf /www/panel/*"); err != nil {
|
||||
if _, err := shell.Execf("rm -rf /www/panel/*"); err != nil {
|
||||
color.Red().Printfln("清理旧版本失败")
|
||||
return err
|
||||
}
|
||||
color.Green().Printfln("清理完成")
|
||||
|
||||
color.Green().Printfln("正在下载...")
|
||||
if _, err := Exec("wget -T 120 -t 3 -O /www/panel/" + panelInfo.DownloadName + " " + panelInfo.DownloadUrl); err != nil {
|
||||
if _, err := shell.Execf("wget -T 120 -t 3 -O /www/panel/" + panelInfo.DownloadName + " " + panelInfo.DownloadUrl); err != nil {
|
||||
color.Red().Printfln("下载失败")
|
||||
return err
|
||||
}
|
||||
if _, err := Exec("wget -T 20 -t 3 -O /www/panel/" + panelInfo.Checksums + " " + panelInfo.ChecksumsUrl); err != nil {
|
||||
if _, err := shell.Execf("wget -T 20 -t 3 -O /www/panel/" + panelInfo.Checksums + " " + panelInfo.ChecksumsUrl); err != nil {
|
||||
color.Red().Printfln("下载失败")
|
||||
return err
|
||||
}
|
||||
@@ -436,7 +438,7 @@ func UpdatePanel(panelInfo PanelInfo) error {
|
||||
color.Green().Printfln("下载完成")
|
||||
|
||||
color.Green().Printfln("校验下载文件...")
|
||||
check, err := Exec("cd /www/panel && sha256sum -c " + panelInfo.Checksums + " --ignore-missing")
|
||||
check, err := shell.Execf("cd /www/panel && sha256sum -c " + panelInfo.Checksums + " --ignore-missing")
|
||||
if check != panelInfo.DownloadName+": OK" || err != nil {
|
||||
return errors.New("下载文件校验失败")
|
||||
}
|
||||
@@ -447,7 +449,7 @@ func UpdatePanel(panelInfo PanelInfo) error {
|
||||
color.Green().Printfln("文件校验完成")
|
||||
|
||||
color.Green().Printfln("更新新版本...")
|
||||
if _, err = Exec("cd /www/panel && unzip -o " + panelInfo.DownloadName + " && rm -rf " + panelInfo.DownloadName); err != nil {
|
||||
if _, err = shell.Execf("cd /www/panel && unzip -o " + panelInfo.DownloadName + " && rm -rf " + panelInfo.DownloadName); err != nil {
|
||||
color.Red().Printfln("更新失败")
|
||||
return err
|
||||
}
|
||||
@@ -457,15 +459,15 @@ func UpdatePanel(panelInfo PanelInfo) error {
|
||||
color.Green().Printfln("更新完成")
|
||||
|
||||
color.Green().Printfln("恢复面板数据...")
|
||||
if _, err = Exec("cp -f /tmp/panel-storage.zip /www/panel/storage/panel-storage.zip && cd /www/panel/storage && unzip -o panel-storage.zip && rm -rf panel-storage.zip"); err != nil {
|
||||
if _, err = shell.Execf("cp -f /tmp/panel-storage.zip /www/panel/storage/panel-storage.zip && cd /www/panel/storage && unzip -o panel-storage.zip && rm -rf panel-storage.zip"); err != nil {
|
||||
color.Red().Printfln("恢复面板数据失败")
|
||||
return err
|
||||
}
|
||||
if _, err = Exec("cp -f /tmp/panel.conf.bak /www/panel/panel.conf"); err != nil {
|
||||
if _, err = shell.Execf("cp -f /tmp/panel.conf.bak /www/panel/panel.conf"); err != nil {
|
||||
color.Red().Printfln("恢复面板配置失败")
|
||||
return err
|
||||
}
|
||||
if _, err = Exec("cp -f /www/panel/scripts/panel.sh /usr/bin/panel"); err != nil {
|
||||
if _, err = shell.Execf("cp -f /www/panel/scripts/panel.sh /usr/bin/panel"); err != nil {
|
||||
color.Red().Printfln("恢复面板脚本失败")
|
||||
return err
|
||||
}
|
||||
@@ -475,28 +477,28 @@ func UpdatePanel(panelInfo PanelInfo) error {
|
||||
color.Green().Printfln("恢复完成")
|
||||
|
||||
color.Green().Printfln("设置面板文件权限...")
|
||||
_, _ = Exec("chmod -R 700 /www/panel")
|
||||
_, _ = Exec("chmod -R 700 /usr/bin/panel")
|
||||
_, _ = shell.Execf("chmod -R 700 /www/panel")
|
||||
_, _ = shell.Execf("chmod -R 700 /usr/bin/panel")
|
||||
color.Green().Printfln("设置完成")
|
||||
|
||||
if _, err = Exec("bash /www/panel/scripts/update_panel.sh"); err != nil {
|
||||
if _, err = shell.Execf("bash /www/panel/scripts/update_panel.sh"); err != nil {
|
||||
color.Red().Printfln("执行面板升级后脚本失败")
|
||||
return err
|
||||
}
|
||||
if _, err = Exec("panel writeSetting version " + panelInfo.Version); err != nil {
|
||||
if _, err = shell.Execf("panel writeSetting version " + panelInfo.Version); err != nil {
|
||||
color.Red().Printfln("写入面板版本号失败")
|
||||
return err
|
||||
}
|
||||
|
||||
_, _ = Exec("rm -rf /tmp/panel-storage.zip")
|
||||
_, _ = Exec("rm -rf /tmp/panel.conf.bak")
|
||||
_, _ = shell.Execf("rm -rf /tmp/panel-storage.zip")
|
||||
_, _ = shell.Execf("rm -rf /tmp/panel.conf.bak")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func RestartPanel() {
|
||||
color.Green().Printfln("重启面板...")
|
||||
err := ExecAsync("sleep 2 && systemctl restart panel")
|
||||
err := shell.ExecfAsync("sleep 2 && systemctl restart panel")
|
||||
if err != nil {
|
||||
color.Red().Printfln("重启失败")
|
||||
return
|
||||
|
||||
Reference in New Issue
Block a user