mirror of
https://github.com/acepanel/panel.git
synced 2026-02-04 11:27:17 +08:00
refactor: 重构 tools.Exec 函数
This commit is contained in:
@@ -125,7 +125,11 @@ func (receiver *Panel) Handle(ctx console.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
port := tools.Exec(`cat /www/panel/panel.conf | grep APP_PORT | awk -F '=' '{print $2}' | tr -d '\n'`)
|
||||
port, err := tools.Exec(`cat /www/panel/panel.conf | grep APP_PORT | awk -F '=' '{print $2}' | tr -d '\n'`)
|
||||
if err != nil {
|
||||
color.Redln("获取面板端口失败")
|
||||
return nil
|
||||
}
|
||||
|
||||
color.Greenln("用户名: " + user.Username)
|
||||
color.Greenln("密码: " + password)
|
||||
@@ -133,15 +137,27 @@ func (receiver *Panel) Handle(ctx console.Context) error {
|
||||
color.Greenln("面板入口: " + facades.Config().GetString("http.entrance"))
|
||||
|
||||
case "getPort":
|
||||
port := tools.Exec("cat /www/panel/panel.conf | grep APP_PORT | awk -F '=' '{print $2}'")
|
||||
port, err := tools.Exec(`cat /www/panel/panel.conf | grep APP_PORT | awk -F '=' '{print $2}' | tr -d '\n'`)
|
||||
if err != nil {
|
||||
color.Redln("获取面板端口失败")
|
||||
return nil
|
||||
}
|
||||
|
||||
color.Greenln("面板端口: " + port)
|
||||
|
||||
case "getEntrance":
|
||||
color.Greenln("面板入口: " + facades.Config().GetString("http.entrance"))
|
||||
|
||||
case "deleteEntrance":
|
||||
oldEntrance := tools.Exec(`cat /www/panel/panel.conf | grep APP_ENTRANCE | awk -F '=' '{print $2}' | tr -d '\n'`)
|
||||
tools.Exec("sed -i 's!APP_ENTRANCE=" + oldEntrance + "!APP_ENTRANCE=/!g' /www/panel/panel.conf")
|
||||
oldEntrance, err := tools.Exec(`cat /www/panel/panel.conf | grep APP_ENTRANCE | awk -F '=' '{print $2}' | tr -d '\n'`)
|
||||
if err != nil {
|
||||
color.Redln("获取面板入口失败")
|
||||
return nil
|
||||
}
|
||||
if _, err = tools.Exec("sed -i 's!APP_ENTRANCE=" + oldEntrance + "!APP_ENTRANCE=/!g' /www/panel/panel.conf"); err != nil {
|
||||
color.Redln("删除面板入口失败")
|
||||
return nil
|
||||
}
|
||||
|
||||
color.Greenln("删除面板入口成功")
|
||||
|
||||
@@ -245,7 +261,10 @@ func (receiver *Panel) Handle(ctx console.Context) error {
|
||||
}
|
||||
|
||||
backupFile := path + "/" + website.Name + "_" + carbon.Now().ToShortDateTimeString() + ".zip"
|
||||
tools.Exec(`cd '` + website.Path + `' && zip -r '` + backupFile + `' .`)
|
||||
if _, err := tools.Exec(`cd '` + website.Path + `' && zip -r '` + backupFile + `' .`); err != nil {
|
||||
color.Redln("|-备份失败: " + err.Error())
|
||||
return nil
|
||||
}
|
||||
color.Greenln("|-备份成功")
|
||||
|
||||
case "mysql":
|
||||
@@ -261,10 +280,16 @@ func (receiver *Panel) Handle(ctx console.Context) error {
|
||||
|
||||
color.Greenln("|-目标MySQL数据库: " + name)
|
||||
color.Greenln("|-开始导出")
|
||||
tools.Exec(`mysqldump -uroot ` + name + ` > /tmp/` + backupFile + ` 2>&1`)
|
||||
if _, err = tools.Exec(`mysqldump -uroot ` + name + ` > /tmp/` + backupFile + ` 2>&1`); err != nil {
|
||||
color.Redln("|-导出失败: " + err.Error())
|
||||
return nil
|
||||
}
|
||||
color.Greenln("|-导出成功")
|
||||
color.Greenln("|-开始压缩")
|
||||
tools.Exec("cd /tmp && zip -r " + backupFile + ".zip " + backupFile)
|
||||
if _, err = tools.Exec("cd /tmp && zip -r " + backupFile + ".zip " + backupFile); err != nil {
|
||||
color.Redln("|-压缩失败: " + err.Error())
|
||||
return nil
|
||||
}
|
||||
tools.Remove("/tmp/" + backupFile)
|
||||
color.Greenln("|-压缩成功")
|
||||
color.Greenln("|-开始移动")
|
||||
@@ -278,7 +303,12 @@ func (receiver *Panel) Handle(ctx console.Context) error {
|
||||
|
||||
case "postgresql":
|
||||
backupFile := name + "_" + carbon.Now().ToShortDateTimeString() + ".sql"
|
||||
check := tools.Exec(`su - postgres -c "psql -l" 2>&1`)
|
||||
check, err := tools.Exec(`su - postgres -c "psql -l" 2>&1`)
|
||||
if err != nil {
|
||||
color.Redln("|-获取数据库失败: " + err.Error())
|
||||
color.Greenln(hr)
|
||||
return nil
|
||||
}
|
||||
if strings.Contains(check, name) {
|
||||
color.Redln("|-数据库不存在")
|
||||
color.Greenln(hr)
|
||||
@@ -287,10 +317,16 @@ func (receiver *Panel) Handle(ctx console.Context) error {
|
||||
|
||||
color.Greenln("|-目标PostgreSQL数据库: " + name)
|
||||
color.Greenln("|-开始导出")
|
||||
tools.Exec(`su - postgres -c "pg_dump '` + name + `'" > /tmp/` + backupFile + ` 2>&1`)
|
||||
if _, err = tools.Exec(`su - postgres -c "pg_dump '` + name + `'" > /tmp/` + backupFile + ` 2>&1`); err != nil {
|
||||
color.Redln("|-导出失败: " + err.Error())
|
||||
return nil
|
||||
}
|
||||
color.Greenln("|-导出成功")
|
||||
color.Greenln("|-开始压缩")
|
||||
tools.Exec("cd /tmp && zip -r " + backupFile + ".zip " + backupFile)
|
||||
if _, err = tools.Exec("cd /tmp && zip -r " + backupFile + ".zip " + backupFile); err != nil {
|
||||
color.Redln("|-压缩失败: " + err.Error())
|
||||
return nil
|
||||
}
|
||||
tools.Remove("/tmp/" + backupFile)
|
||||
color.Greenln("|-压缩成功")
|
||||
color.Greenln("|-开始移动")
|
||||
@@ -360,8 +396,14 @@ func (receiver *Panel) Handle(ctx console.Context) error {
|
||||
}
|
||||
|
||||
backupPath := "/www/wwwlogs/" + website.Name + "_" + carbon.Now().ToShortDateTimeString() + ".log.zip"
|
||||
tools.Exec(`cd /www/wwwlogs && zip -r ` + backupPath + ` ` + website.Name + ".log")
|
||||
tools.Exec(`echo "" > ` + logPath)
|
||||
if _, err := tools.Exec(`cd /www/wwwlogs && zip -r ` + backupPath + ` ` + website.Name + ".log"); err != nil {
|
||||
color.Redln("|-备份失败: " + err.Error())
|
||||
return nil
|
||||
}
|
||||
if _, err := tools.Exec(`echo "" > ` + logPath); err != nil {
|
||||
color.Redln("|-清空失败: " + err.Error())
|
||||
return nil
|
||||
}
|
||||
color.Greenln("|-切割成功")
|
||||
|
||||
color.Greenln(hr)
|
||||
|
||||
@@ -35,7 +35,7 @@ func Success(ctx http.Context, data any) http.Response {
|
||||
func Error(ctx http.Context, code int, message string) http.Response {
|
||||
return ctx.Response().Json(http.StatusOK, &ErrorResponse{
|
||||
Code: code,
|
||||
Message: message,
|
||||
Message: "错误: " + message,
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ func NewCronController() *CronController {
|
||||
}
|
||||
|
||||
// List 获取计划任务列表
|
||||
func (c *CronController) List(ctx http.Context) http.Response {
|
||||
func (r *CronController) List(ctx http.Context) http.Response {
|
||||
limit := ctx.Request().QueryInt("limit", 10)
|
||||
page := ctx.Request().QueryInt("page", 1)
|
||||
|
||||
@@ -34,7 +34,9 @@ func (c *CronController) List(ctx http.Context) http.Response {
|
||||
var total int64
|
||||
err := facades.Orm().Query().Paginate(page, limit, &crons, &total)
|
||||
if err != nil {
|
||||
facades.Log().Info("[面板][CronController] 查询计划任务列表失败 ", err)
|
||||
facades.Log().Request(ctx.Request()).Tags("面板", "计划任务").With(map[string]any{
|
||||
"error": err.Error(),
|
||||
}).Info("查询计划任务列表失败")
|
||||
return ErrorSystem(ctx)
|
||||
}
|
||||
|
||||
@@ -45,7 +47,7 @@ func (c *CronController) List(ctx http.Context) http.Response {
|
||||
}
|
||||
|
||||
// Add 添加计划任务
|
||||
func (c *CronController) Add(ctx http.Context) http.Response {
|
||||
func (r *CronController) Add(ctx http.Context) http.Response {
|
||||
validator, err := ctx.Request().Validate(map[string]string{
|
||||
"name": "required|min_len:1|max_len:255",
|
||||
"time": "required",
|
||||
@@ -75,7 +77,7 @@ func (c *CronController) Add(ctx http.Context) http.Response {
|
||||
}
|
||||
backupPath := ctx.Request().Input("backup_path")
|
||||
if len(backupPath) == 0 {
|
||||
backupPath = c.setting.Get(models.SettingKeyBackupPath) + "/" + backupType
|
||||
backupPath = r.setting.Get(models.SettingKeyBackupPath) + "/" + backupType
|
||||
}
|
||||
backupSave := ctx.Request().InputInt("save", 10)
|
||||
shell = `#!/bin/bash
|
||||
@@ -111,19 +113,18 @@ panel cutoff ${name} ${save} 2>&1
|
||||
shellDir := "/www/server/cron/"
|
||||
shellLogDir := "/www/server/cron/logs/"
|
||||
if !tools.Exists(shellDir) {
|
||||
facades.Log().Info("[面板][CronController] 计划任务目录不存在")
|
||||
return Error(ctx, http.StatusInternalServerError, "计划任务目录不存在")
|
||||
}
|
||||
if !tools.Exists(shellLogDir) {
|
||||
facades.Log().Info("[面板][CronController] 计划任务日志目录不存在")
|
||||
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 {
|
||||
facades.Log().Info("[面板][CronController] 创建计划任务脚本失败 ", err)
|
||||
return ErrorSystem(ctx)
|
||||
return Error(ctx, http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
if out, err := tools.Exec("dos2unix " + shellDir + shellFile + ".sh"); err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
tools.Exec("dos2unix " + shellDir + shellFile + ".sh")
|
||||
|
||||
var cron models.Cron
|
||||
cron.Name = ctx.Request().Input("name")
|
||||
@@ -135,11 +136,15 @@ panel cutoff ${name} ${save} 2>&1
|
||||
|
||||
err = facades.Orm().Query().Create(&cron)
|
||||
if err != nil {
|
||||
facades.Log().Info("[面板][CronController] 创建计划任务失败 ", err)
|
||||
facades.Log().Request(ctx.Request()).Tags("面板", "计划任务").With(map[string]any{
|
||||
"error": err.Error(),
|
||||
}).Info("保存计划任务失败")
|
||||
return ErrorSystem(ctx)
|
||||
}
|
||||
|
||||
c.cron.AddToSystem(cron)
|
||||
if err := r.cron.AddToSystem(cron); err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
|
||||
return Success(ctx, http.Json{
|
||||
"id": cron.ID,
|
||||
@@ -147,7 +152,7 @@ panel cutoff ${name} ${save} 2>&1
|
||||
}
|
||||
|
||||
// Script 获取脚本内容
|
||||
func (c *CronController) Script(ctx http.Context) http.Response {
|
||||
func (r *CronController) Script(ctx http.Context) http.Response {
|
||||
var cron models.Cron
|
||||
err := facades.Orm().Query().Where("id", ctx.Request().Input("id")).FirstOrFail(&cron)
|
||||
if err != nil {
|
||||
@@ -158,7 +163,7 @@ func (c *CronController) Script(ctx http.Context) http.Response {
|
||||
}
|
||||
|
||||
// Update 更新计划任务
|
||||
func (c *CronController) Update(ctx http.Context) http.Response {
|
||||
func (r *CronController) Update(ctx http.Context) http.Response {
|
||||
validator, err := ctx.Request().Validate(map[string]string{
|
||||
"name": "required|min_len:1|max_len:255",
|
||||
"time": "required",
|
||||
@@ -190,38 +195,47 @@ func (c *CronController) Update(ctx http.Context) http.Response {
|
||||
cron.Name = ctx.Request().Input("name")
|
||||
err = facades.Orm().Query().Save(&cron)
|
||||
if err != nil {
|
||||
facades.Log().Info("[面板][CronController] 更新计划任务失败 ", err)
|
||||
facades.Log().Request(ctx.Request()).Tags("面板", "计划任务").With(map[string]any{
|
||||
"error": err.Error(),
|
||||
}).Info("更新计划任务失败")
|
||||
return ErrorSystem(ctx)
|
||||
}
|
||||
|
||||
if err = tools.Write(cron.Shell, ctx.Request().Input("script"), 0644); err != nil {
|
||||
facades.Log().Info("[面板][CronController] 更新计划任务脚本失败 ", err)
|
||||
return ErrorSystem(ctx)
|
||||
return Error(ctx, http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
if out, err := tools.Exec("dos2unix " + cron.Shell); err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
tools.Exec("dos2unix " + cron.Shell)
|
||||
|
||||
c.cron.DeleteFromSystem(cron)
|
||||
if err := r.cron.DeleteFromSystem(cron); err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
if cron.Status {
|
||||
c.cron.AddToSystem(cron)
|
||||
if err := r.cron.AddToSystem(cron); err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
return Success(ctx, nil)
|
||||
}
|
||||
|
||||
// Delete 删除计划任务
|
||||
func (c *CronController) Delete(ctx http.Context) http.Response {
|
||||
func (r *CronController) Delete(ctx http.Context) http.Response {
|
||||
var cron models.Cron
|
||||
err := facades.Orm().Query().Where("id", ctx.Request().Input("id")).FirstOrFail(&cron)
|
||||
if err != nil {
|
||||
if err := facades.Orm().Query().Where("id", ctx.Request().Input("id")).FirstOrFail(&cron); err != nil {
|
||||
return Error(ctx, http.StatusUnprocessableEntity, "计划任务不存在")
|
||||
}
|
||||
|
||||
c.cron.DeleteFromSystem(cron)
|
||||
if err := r.cron.DeleteFromSystem(cron); err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
tools.Remove(cron.Shell)
|
||||
|
||||
_, err = facades.Orm().Query().Delete(&cron)
|
||||
if err != nil {
|
||||
facades.Log().Info("[面板][CronController] 删除计划任务失败 ", err)
|
||||
if _, err := facades.Orm().Query().Delete(&cron); err != nil {
|
||||
facades.Log().Request(ctx.Request()).Tags("面板", "计划任务").With(map[string]any{
|
||||
"error": err.Error(),
|
||||
}).Info("删除计划任务失败")
|
||||
return ErrorSystem(ctx)
|
||||
}
|
||||
|
||||
@@ -229,7 +243,7 @@ func (c *CronController) Delete(ctx http.Context) http.Response {
|
||||
}
|
||||
|
||||
// Status 更新计划任务状态
|
||||
func (c *CronController) Status(ctx http.Context) http.Response {
|
||||
func (r *CronController) Status(ctx http.Context) http.Response {
|
||||
validator, err := ctx.Request().Validate(map[string]string{
|
||||
"status": "bool",
|
||||
})
|
||||
@@ -249,23 +263,28 @@ func (c *CronController) Status(ctx http.Context) http.Response {
|
||||
cron.Status = ctx.Request().InputBool("status")
|
||||
err = facades.Orm().Query().Save(&cron)
|
||||
if err != nil {
|
||||
facades.Log().Info("[面板][CronController] 更新计划任务状态失败 ", err)
|
||||
facades.Log().Request(ctx.Request()).Tags("面板", "计划任务").With(map[string]any{
|
||||
"error": err.Error(),
|
||||
}).Info("更新计划任务状态失败")
|
||||
return ErrorSystem(ctx)
|
||||
}
|
||||
|
||||
c.cron.DeleteFromSystem(cron)
|
||||
if err := r.cron.DeleteFromSystem(cron); err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
if cron.Status {
|
||||
c.cron.AddToSystem(cron)
|
||||
if err := r.cron.AddToSystem(cron); err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
return Success(ctx, nil)
|
||||
}
|
||||
|
||||
// Log 获取计划任务日志
|
||||
func (c *CronController) Log(ctx http.Context) http.Response {
|
||||
func (r *CronController) Log(ctx http.Context) http.Response {
|
||||
var cron models.Cron
|
||||
err := facades.Orm().Query().Where("id", ctx.Request().Input("id")).FirstOrFail(&cron)
|
||||
if err != nil {
|
||||
if err := facades.Orm().Query().Where("id", ctx.Request().Input("id")).FirstOrFail(&cron); err != nil {
|
||||
return Error(ctx, http.StatusUnprocessableEntity, "计划任务不存在")
|
||||
}
|
||||
|
||||
@@ -273,7 +292,10 @@ func (c *CronController) Log(ctx http.Context) http.Response {
|
||||
return Error(ctx, http.StatusUnprocessableEntity, "日志文件不存在")
|
||||
}
|
||||
|
||||
log := tools.Exec("tail -n 1000 " + cron.Log)
|
||||
log, err := tools.Exec("tail -n 1000 " + cron.Log)
|
||||
if err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
|
||||
return Success(ctx, log)
|
||||
}
|
||||
|
||||
@@ -34,25 +34,20 @@ func NewInfoController() *InfoController {
|
||||
}
|
||||
|
||||
// Name 获取面板名称
|
||||
func (c *InfoController) Name(ctx http.Context) http.Response {
|
||||
var setting models.Setting
|
||||
err := facades.Orm().Query().Where("key", "name").First(&setting)
|
||||
if err != nil {
|
||||
facades.Log().Info("[面板][InfoController] 查询面板名称失败 ", err)
|
||||
return ErrorSystem(ctx)
|
||||
}
|
||||
|
||||
func (r *InfoController) Name(ctx http.Context) http.Response {
|
||||
return Success(ctx, http.Json{
|
||||
"name": setting.Value,
|
||||
"name": r.setting.Get(models.SettingKeyName),
|
||||
})
|
||||
}
|
||||
|
||||
// HomePlugins 获取首页插件
|
||||
func (c *InfoController) HomePlugins(ctx http.Context) http.Response {
|
||||
func (r *InfoController) HomePlugins(ctx http.Context) http.Response {
|
||||
var plugins []models.Plugin
|
||||
err := facades.Orm().Query().Where("show", 1).Find(&plugins)
|
||||
if err != nil {
|
||||
facades.Log().Info("[面板][InfoController] 查询首页插件失败 ", err)
|
||||
facades.Log().Request(ctx.Request()).Tags("面板", "基础信息").With(map[string]any{
|
||||
"error": err.Error(),
|
||||
}).Info("获取首页插件失败")
|
||||
return ErrorSystem(ctx)
|
||||
}
|
||||
|
||||
@@ -73,12 +68,12 @@ func (c *InfoController) HomePlugins(ctx http.Context) http.Response {
|
||||
}
|
||||
|
||||
// NowMonitor 获取当前监控信息
|
||||
func (c *InfoController) NowMonitor(ctx http.Context) http.Response {
|
||||
func (r *InfoController) NowMonitor(ctx http.Context) http.Response {
|
||||
return Success(ctx, tools.GetMonitoringInfo())
|
||||
}
|
||||
|
||||
// SystemInfo 获取系统信息
|
||||
func (c *InfoController) SystemInfo(ctx http.Context) http.Response {
|
||||
func (r *InfoController) SystemInfo(ctx http.Context) http.Response {
|
||||
monitorInfo := tools.GetMonitoringInfo()
|
||||
|
||||
return Success(ctx, http.Json{
|
||||
@@ -89,7 +84,7 @@ func (c *InfoController) SystemInfo(ctx http.Context) http.Response {
|
||||
}
|
||||
|
||||
// CountInfo 获取面板统计信息
|
||||
func (c *InfoController) CountInfo(ctx http.Context) http.Response {
|
||||
func (r *InfoController) CountInfo(ctx http.Context) http.Response {
|
||||
var websiteCount int64
|
||||
err := facades.Orm().Query().Model(models.Website{}).Count(&websiteCount)
|
||||
if err != nil {
|
||||
@@ -110,26 +105,26 @@ func (c *InfoController) CountInfo(ctx http.Context) http.Response {
|
||||
}
|
||||
var databaseCount int64
|
||||
if mysqlInstalled {
|
||||
status := tools.Exec("systemctl status mysqld | grep Active | grep -v grep | awk '{print $2}'")
|
||||
if status == "active" {
|
||||
rootPassword := c.setting.Get(models.SettingKeyMysqlRootPassword)
|
||||
status, err := tools.Exec("systemctl status mysqld | grep Active | grep -v grep | awk '{print $2}'")
|
||||
if status == "active" && err == nil {
|
||||
rootPassword := r.setting.Get(models.SettingKeyMysqlRootPassword)
|
||||
type database struct {
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
db, err := sql.Open("mysql", "root:"+rootPassword+"@unix(/tmp/mysql.sock)/")
|
||||
if err != nil {
|
||||
facades.Log().Request(ctx.Request()).With(map[string]any{
|
||||
facades.Log().Request(ctx.Request()).Tags("面板", "基础信息").With(map[string]any{
|
||||
"error": err.Error(),
|
||||
}).Info("[面板][InfoController] 获取数据库列表失败")
|
||||
}).Info("获取数据库列表失败")
|
||||
databaseCount = -1
|
||||
} else {
|
||||
defer db.Close()
|
||||
rows, err := db.Query("SHOW DATABASES")
|
||||
if err != nil {
|
||||
facades.Log().Request(ctx.Request()).With(map[string]any{
|
||||
facades.Log().Request(ctx.Request()).Tags("面板", "基础信息").With(map[string]any{
|
||||
"error": err.Error(),
|
||||
}).Info("[面板][InfoController] 获取数据库列表失败")
|
||||
}).Info("获取数据库列表失败")
|
||||
databaseCount = -1
|
||||
} else {
|
||||
defer rows.Close()
|
||||
@@ -152,29 +147,31 @@ func (c *InfoController) CountInfo(ctx http.Context) http.Response {
|
||||
}
|
||||
}
|
||||
if postgresqlInstalled {
|
||||
status := tools.Exec("systemctl status postgresql | grep Active | grep -v grep | awk '{print $2}'")
|
||||
if status == "active" {
|
||||
raw := tools.Exec(`echo "\l" | su - postgres -c "psql"`)
|
||||
databases := strings.Split(raw, "\n")
|
||||
if len(databases) >= 4 {
|
||||
databases = databases[3 : len(databases)-1]
|
||||
for _, db := range databases {
|
||||
parts := strings.Split(db, "|")
|
||||
if len(parts) != 9 || len(strings.TrimSpace(parts[0])) == 0 || strings.TrimSpace(parts[0]) == "template0" || strings.TrimSpace(parts[0]) == "template1" || strings.TrimSpace(parts[0]) == "postgres" {
|
||||
continue
|
||||
}
|
||||
status, err := tools.Exec("systemctl status postgresql | grep Active | grep -v grep | awk '{print $2}'")
|
||||
if status == "active" && err == nil {
|
||||
raw, err := tools.Exec(`echo "\l" | su - postgres -c "psql"`)
|
||||
if err == nil {
|
||||
databases := strings.Split(raw, "\n")
|
||||
if len(databases) >= 4 {
|
||||
databases = databases[3 : len(databases)-1]
|
||||
for _, db := range databases {
|
||||
parts := strings.Split(db, "|")
|
||||
if len(parts) != 9 || len(strings.TrimSpace(parts[0])) == 0 || strings.TrimSpace(parts[0]) == "template0" || strings.TrimSpace(parts[0]) == "template1" || strings.TrimSpace(parts[0]) == "postgres" {
|
||||
continue
|
||||
}
|
||||
|
||||
databaseCount++
|
||||
databaseCount++
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var ftpCount int64
|
||||
var ftpPlugin = c.plugin.GetInstalledBySlug("pureftpd")
|
||||
var ftpPlugin = r.plugin.GetInstalledBySlug("pureftpd")
|
||||
if ftpPlugin.ID != 0 {
|
||||
listRaw := tools.Exec("pure-pw list")
|
||||
if len(listRaw) != 0 {
|
||||
listRaw, err := tools.Exec("pure-pw list")
|
||||
if len(listRaw) != 0 && err == nil {
|
||||
listArr := strings.Split(listRaw, "\n")
|
||||
ftpCount = int64(len(listArr))
|
||||
}
|
||||
@@ -195,7 +192,7 @@ func (c *InfoController) CountInfo(ctx http.Context) http.Response {
|
||||
}
|
||||
|
||||
// InstalledDbAndPhp 获取已安装的数据库和 PHP 版本
|
||||
func (c *InfoController) InstalledDbAndPhp(ctx http.Context) http.Response {
|
||||
func (r *InfoController) InstalledDbAndPhp(ctx http.Context) http.Response {
|
||||
var php []models.Plugin
|
||||
err := facades.Orm().Query().Where("slug like ?", "php%").Find(&php)
|
||||
if err != nil {
|
||||
@@ -230,7 +227,7 @@ func (c *InfoController) InstalledDbAndPhp(ctx http.Context) http.Response {
|
||||
continue
|
||||
}
|
||||
|
||||
phpData = append(phpData, data{Value: strings.ReplaceAll(p.Slug, "php", ""), Label: c.plugin.GetBySlug(p.Slug).Name})
|
||||
phpData = append(phpData, data{Value: strings.ReplaceAll(p.Slug, "php", ""), Label: r.plugin.GetBySlug(p.Slug).Name})
|
||||
}
|
||||
|
||||
if mysqlInstalled {
|
||||
@@ -247,7 +244,7 @@ func (c *InfoController) InstalledDbAndPhp(ctx http.Context) http.Response {
|
||||
}
|
||||
|
||||
// CheckUpdate 检查面板更新
|
||||
func (c *InfoController) CheckUpdate(ctx http.Context) http.Response {
|
||||
func (r *InfoController) CheckUpdate(ctx http.Context) http.Response {
|
||||
version := facades.Config().GetString("panel.version")
|
||||
remote, err := tools.GetLatestPanelVersion()
|
||||
if err != nil {
|
||||
@@ -266,7 +263,7 @@ func (c *InfoController) CheckUpdate(ctx http.Context) http.Response {
|
||||
}
|
||||
|
||||
// UpdateInfo 获取更新信息
|
||||
func (c *InfoController) UpdateInfo(ctx http.Context) http.Response {
|
||||
func (r *InfoController) UpdateInfo(ctx http.Context) http.Response {
|
||||
version := facades.Config().GetString("panel.version")
|
||||
current, err := tools.GetLatestPanelVersion()
|
||||
if err != nil {
|
||||
@@ -296,7 +293,7 @@ func (c *InfoController) UpdateInfo(ctx http.Context) http.Response {
|
||||
}
|
||||
|
||||
// Update 更新面板
|
||||
func (c *InfoController) Update(ctx http.Context) http.Response {
|
||||
func (r *InfoController) Update(ctx http.Context) http.Response {
|
||||
var task models.Task
|
||||
err := facades.Orm().Query().Where("status", models.TaskStatusRunning).OrWhere("status", models.TaskStatusWaiting).FirstOrFail(&task)
|
||||
if err == nil {
|
||||
@@ -305,18 +302,18 @@ func (c *InfoController) Update(ctx http.Context) http.Response {
|
||||
|
||||
panel, err := tools.GetLatestPanelVersion()
|
||||
if err != nil {
|
||||
facades.Log().Request(ctx.Request()).With(map[string]any{
|
||||
facades.Log().Request(ctx.Request()).Tags("面板", "基础信息").With(map[string]any{
|
||||
"error": err.Error(),
|
||||
}).Info("[面板][InfoController] 获取最新版本失败")
|
||||
}).Info("获取最新版本失败")
|
||||
return Error(ctx, http.StatusInternalServerError, "获取最新版本失败")
|
||||
}
|
||||
|
||||
err = tools.UpdatePanel(panel)
|
||||
if err != nil {
|
||||
facades.Log().Request(ctx.Request()).With(map[string]any{
|
||||
facades.Log().Request(ctx.Request()).Tags("面板", "基础信息").With(map[string]any{
|
||||
"error": err.Error(),
|
||||
}).Info("[面板][InfoController] 更新面板失败")
|
||||
return Error(ctx, http.StatusInternalServerError, "更新失败: "+err.Error())
|
||||
}).Info("更新面板失败")
|
||||
return Error(ctx, http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
|
||||
tools.RestartPanel()
|
||||
@@ -324,7 +321,7 @@ func (c *InfoController) Update(ctx http.Context) http.Response {
|
||||
}
|
||||
|
||||
// Restart 重启面板
|
||||
func (c *InfoController) Restart(ctx http.Context) http.Response {
|
||||
func (r *InfoController) Restart(ctx http.Context) http.Response {
|
||||
var task models.Task
|
||||
err := facades.Orm().Query().Where("status", models.TaskStatusRunning).OrWhere("status", models.TaskStatusWaiting).FirstOrFail(&task)
|
||||
if err == nil {
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
"github.com/goravel/framework/facades"
|
||||
"github.com/goravel/framework/support/carbon"
|
||||
"github.com/spf13/cast"
|
||||
|
||||
"panel/app/models"
|
||||
"panel/app/services"
|
||||
)
|
||||
@@ -26,7 +27,10 @@ func (r *MonitorController) Switch(ctx http.Context) http.Response {
|
||||
value := ctx.Request().InputBool("monitor")
|
||||
err := r.setting.Set(models.SettingKeyMonitor, cast.ToString(value))
|
||||
if err != nil {
|
||||
facades.Log().Info("[面板][MonitorController] 更新监控开关失败 ", err)
|
||||
facades.Log().Request(ctx.Request()).Tags("面板", "资源监控").With(map[string]any{
|
||||
"monitor": value,
|
||||
"error": err.Error(),
|
||||
}).Info("更新监控开关失败")
|
||||
return ErrorSystem(ctx)
|
||||
}
|
||||
|
||||
@@ -38,7 +42,10 @@ func (r *MonitorController) SaveDays(ctx http.Context) http.Response {
|
||||
days := ctx.Request().Input("days")
|
||||
err := r.setting.Set(models.SettingKeyMonitorDays, days)
|
||||
if err != nil {
|
||||
facades.Log().Info("[面板][MonitorController] 更新监控天数失败 ", err)
|
||||
facades.Log().Request(ctx.Request()).Tags("面板", "资源监控").With(map[string]any{
|
||||
"days": days,
|
||||
"error": err.Error(),
|
||||
}).Info("更新监控开关失败")
|
||||
return ErrorSystem(ctx)
|
||||
}
|
||||
|
||||
@@ -60,7 +67,9 @@ func (r *MonitorController) SwitchAndDays(ctx http.Context) http.Response {
|
||||
func (r *MonitorController) Clear(ctx http.Context) http.Response {
|
||||
_, err := facades.Orm().Query().Where("1 = 1").Delete(&models.Monitor{})
|
||||
if err != nil {
|
||||
facades.Log().Info("[面板][MonitorController] 清空监控数据失败 ", err)
|
||||
facades.Log().Request(ctx.Request()).Tags("面板", "资源监控").With(map[string]any{
|
||||
"error": err.Error(),
|
||||
}).Info("清空监控数据失败")
|
||||
return ErrorSystem(ctx)
|
||||
}
|
||||
|
||||
@@ -77,7 +86,11 @@ func (r *MonitorController) List(ctx http.Context) http.Response {
|
||||
var monitors []models.Monitor
|
||||
err := facades.Orm().Query().Where("created_at >= ?", startTime.ToDateTimeString()).Where("created_at <= ?", endTime.ToDateTimeString()).Get(&monitors)
|
||||
if err != nil {
|
||||
facades.Log().Info("[面板][MonitorController] 查询监控数据失败 ", err)
|
||||
facades.Log().Request(ctx.Request()).Tags("面板", "资源监控").With(map[string]any{
|
||||
"start": startTime.ToDateTimeString(),
|
||||
"end": endTime.ToDateTimeString(),
|
||||
"error": err.Error(),
|
||||
}).Info("获取监控数据失败")
|
||||
return ErrorSystem(ctx)
|
||||
}
|
||||
|
||||
|
||||
@@ -100,7 +100,9 @@ func (r *PluginController) Install(ctx http.Context) http.Response {
|
||||
installedPlugin := r.plugin.GetInstalledBySlug(slug)
|
||||
installedPlugins, err := r.plugin.AllInstalled()
|
||||
if err != nil {
|
||||
facades.Log().Info("[面板][PluginController] 获取已安装插件失败")
|
||||
facades.Log().Request(ctx.Request()).Tags("面板", "插件中心").With(map[string]any{
|
||||
"slug": slug,
|
||||
}).Info("检查插件安装状态失败")
|
||||
return ErrorSystem(ctx)
|
||||
}
|
||||
|
||||
@@ -141,7 +143,10 @@ func (r *PluginController) Install(ctx http.Context) http.Response {
|
||||
task.Shell = plugin.Install + " >> /tmp/" + plugin.Slug + ".log 2>&1"
|
||||
task.Log = "/tmp/" + plugin.Slug + ".log"
|
||||
if err := facades.Orm().Query().Create(&task); err != nil {
|
||||
facades.Log().Info("[面板][PluginController] 创建任务失败: " + err.Error())
|
||||
facades.Log().Request(ctx.Request()).Tags("面板", "插件中心").With(map[string]any{
|
||||
"slug": slug,
|
||||
"err": err.Error(),
|
||||
}).Info("创建任务失败")
|
||||
return ErrorSystem(ctx)
|
||||
}
|
||||
|
||||
@@ -156,7 +161,9 @@ func (r *PluginController) Uninstall(ctx http.Context) http.Response {
|
||||
installedPlugin := r.plugin.GetInstalledBySlug(slug)
|
||||
installedPlugins, err := r.plugin.AllInstalled()
|
||||
if err != nil {
|
||||
facades.Log().Info("[面板][PluginController] 获取已安装插件失败")
|
||||
facades.Log().Request(ctx.Request()).Tags("面板", "插件中心").With(map[string]any{
|
||||
"slug": slug,
|
||||
}).Info("检查插件安装状态失败")
|
||||
return ErrorSystem(ctx)
|
||||
}
|
||||
|
||||
@@ -197,7 +204,10 @@ func (r *PluginController) Uninstall(ctx http.Context) http.Response {
|
||||
task.Shell = plugin.Uninstall + " >> /tmp/" + plugin.Slug + ".log 2>&1"
|
||||
task.Log = "/tmp/" + plugin.Slug + ".log"
|
||||
if err := facades.Orm().Query().Create(&task); err != nil {
|
||||
facades.Log().Info("[面板][PluginController] 创建任务失败: " + err.Error())
|
||||
facades.Log().Request(ctx.Request()).Tags("面板", "插件中心").With(map[string]any{
|
||||
"slug": slug,
|
||||
"err": err.Error(),
|
||||
}).Info("创建任务失败")
|
||||
return ErrorSystem(ctx)
|
||||
}
|
||||
|
||||
@@ -212,7 +222,9 @@ func (r *PluginController) Update(ctx http.Context) http.Response {
|
||||
installedPlugin := r.plugin.GetInstalledBySlug(slug)
|
||||
installedPlugins, err := r.plugin.AllInstalled()
|
||||
if err != nil {
|
||||
facades.Log().Info("[面板][PluginController] 获取已安装插件失败")
|
||||
facades.Log().Request(ctx.Request()).Tags("面板", "插件中心").With(map[string]any{
|
||||
"slug": slug,
|
||||
}).Info("检查插件安装状态失败")
|
||||
return ErrorSystem(ctx)
|
||||
}
|
||||
|
||||
@@ -253,7 +265,10 @@ func (r *PluginController) Update(ctx http.Context) http.Response {
|
||||
task.Shell = plugin.Update + " >> /tmp/" + plugin.Slug + ".log 2>&1"
|
||||
task.Log = "/tmp/" + plugin.Slug + ".log"
|
||||
if err := facades.Orm().Query().Create(&task); err != nil {
|
||||
facades.Log().Info("[面板][PluginController] 创建任务失败: " + err.Error())
|
||||
facades.Log().Request(ctx.Request()).Tags("面板", "插件中心").With(map[string]any{
|
||||
"slug": slug,
|
||||
"err": err.Error(),
|
||||
}).Info("创建任务失败")
|
||||
return ErrorSystem(ctx)
|
||||
}
|
||||
|
||||
@@ -268,7 +283,10 @@ func (r *PluginController) UpdateShow(ctx http.Context) http.Response {
|
||||
|
||||
var plugin models.Plugin
|
||||
if err := facades.Orm().Query().Where("slug", slug).First(&plugin); err != nil {
|
||||
facades.Log().Info("[面板][PluginController] 查询插件失败: " + err.Error())
|
||||
facades.Log().Request(ctx.Request()).Tags("面板", "插件中心").With(map[string]any{
|
||||
"slug": slug,
|
||||
"err": err.Error(),
|
||||
}).Info("获取插件失败")
|
||||
return ErrorSystem(ctx)
|
||||
}
|
||||
if plugin.ID == 0 {
|
||||
@@ -277,7 +295,10 @@ func (r *PluginController) UpdateShow(ctx http.Context) http.Response {
|
||||
|
||||
plugin.Show = show
|
||||
if err := facades.Orm().Query().Save(&plugin); err != nil {
|
||||
facades.Log().Info("[面板][PluginController] 更新插件失败: " + err.Error())
|
||||
facades.Log().Request(ctx.Request()).Tags("面板", "插件中心").With(map[string]any{
|
||||
"slug": slug,
|
||||
"err": err.Error(),
|
||||
}).Info("更新插件失败")
|
||||
return ErrorSystem(ctx)
|
||||
}
|
||||
|
||||
|
||||
@@ -31,16 +31,12 @@ func (r *Fail2banController) Status(ctx http.Context) http.Response {
|
||||
return check
|
||||
}
|
||||
|
||||
status := tools.Exec("systemctl status fail2ban | grep Active | grep -v grep | awk '{print $2}'")
|
||||
if len(status) == 0 {
|
||||
status, err := tools.ServiceStatus("fail2ban")
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取服务运行状态失败")
|
||||
}
|
||||
|
||||
if status == "active" {
|
||||
return controllers.Success(ctx, true)
|
||||
} else {
|
||||
return controllers.Success(ctx, false)
|
||||
}
|
||||
return controllers.Success(ctx, status)
|
||||
}
|
||||
|
||||
// Reload 重载配置
|
||||
@@ -50,17 +46,11 @@ func (r *Fail2banController) Reload(ctx http.Context) http.Response {
|
||||
return check
|
||||
}
|
||||
|
||||
tools.Exec("systemctl reload fail2ban")
|
||||
status := tools.Exec("systemctl status fail2ban | grep Active | grep -v grep | awk '{print $2}'")
|
||||
if len(status) == 0 {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取服务运行状态失败")
|
||||
if _, err := tools.Exec("systemctl reload fail2ban"); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "重载配置失败")
|
||||
}
|
||||
|
||||
if status == "active" {
|
||||
return controllers.Success(ctx, true)
|
||||
} else {
|
||||
return controllers.Success(ctx, false)
|
||||
}
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// Restart 重启服务
|
||||
@@ -70,17 +60,11 @@ func (r *Fail2banController) Restart(ctx http.Context) http.Response {
|
||||
return check
|
||||
}
|
||||
|
||||
tools.Exec("systemctl restart fail2ban")
|
||||
status := tools.Exec("systemctl status fail2ban | grep Active | grep -v grep | awk '{print $2}'")
|
||||
if len(status) == 0 {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取服务运行状态失败")
|
||||
if err := tools.ServiceRestart("fail2ban"); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "重启服务失败")
|
||||
}
|
||||
|
||||
if status == "active" {
|
||||
return controllers.Success(ctx, true)
|
||||
} else {
|
||||
return controllers.Success(ctx, false)
|
||||
}
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// Start 启动服务
|
||||
@@ -90,17 +74,11 @@ func (r *Fail2banController) Start(ctx http.Context) http.Response {
|
||||
return check
|
||||
}
|
||||
|
||||
tools.Exec("systemctl start fail2ban")
|
||||
status := tools.Exec("systemctl status fail2ban | grep Active | grep -v grep | awk '{print $2}'")
|
||||
if len(status) == 0 {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取服务运行状态失败")
|
||||
if err := tools.ServiceStart("fail2ban"); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "启动服务失败")
|
||||
}
|
||||
|
||||
if status == "active" {
|
||||
return controllers.Success(ctx, true)
|
||||
} else {
|
||||
return controllers.Success(ctx, false)
|
||||
}
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// Stop 停止服务
|
||||
@@ -110,17 +88,15 @@ func (r *Fail2banController) Stop(ctx http.Context) http.Response {
|
||||
return check
|
||||
}
|
||||
|
||||
tools.Exec("systemctl stop fail2ban")
|
||||
status := tools.Exec("systemctl status fail2ban | grep Active | grep -v grep | awk '{print $2}'")
|
||||
if len(status) == 0 {
|
||||
if err := tools.ServiceStop("fail2ban"); err != nil {
|
||||
return nil
|
||||
}
|
||||
status, err := tools.ServiceStatus("fail2ban")
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取服务运行状态失败")
|
||||
}
|
||||
|
||||
if status != "active" {
|
||||
return controllers.Success(ctx, true)
|
||||
} else {
|
||||
return controllers.Success(ctx, false)
|
||||
}
|
||||
return controllers.Success(ctx, !status)
|
||||
}
|
||||
|
||||
// List 所有 Fail2ban 规则
|
||||
@@ -289,6 +265,7 @@ ignoreregex =
|
||||
var logPath string
|
||||
var filter string
|
||||
var port string
|
||||
var err error
|
||||
switch jailName {
|
||||
case "ssh":
|
||||
if tools.IsDebian() {
|
||||
@@ -297,19 +274,19 @@ ignoreregex =
|
||||
logPath = "/var/log/secure"
|
||||
}
|
||||
filter = "sshd"
|
||||
port = tools.Exec("cat /etc/ssh/sshd_config | grep 'Port ' | awk '{print $2}'")
|
||||
port, err = tools.Exec("cat /etc/ssh/sshd_config | grep 'Port ' | awk '{print $2}'")
|
||||
case "mysql":
|
||||
logPath = "/www/server/mysql/mysql-error.log"
|
||||
filter = "mysqld-auth"
|
||||
port = tools.Exec("cat /www/server/mysql/conf/my.cnf | grep 'port' | head -n 1 | awk '{print $3}'")
|
||||
port, err = tools.Exec("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 = tools.Exec(`cat /www/server/pure-ftpd/etc/pure-ftpd.conf | grep "Bind" | awk '{print $2}' | awk -F "," '{print $2}'`)
|
||||
port, err = tools.Exec(`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, "未知服务")
|
||||
}
|
||||
if len(port) == 0 {
|
||||
if len(port) == 0 || err != nil {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, "获取服务端口失败,请检查是否安装")
|
||||
}
|
||||
|
||||
@@ -332,7 +309,10 @@ logpath = ` + logPath + `
|
||||
}
|
||||
}
|
||||
|
||||
tools.Exec("fail2ban-client reload")
|
||||
if _, err := tools.Exec("fail2ban-client reload"); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "重载配置失败")
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
@@ -356,7 +336,10 @@ func (r *Fail2banController) Delete(ctx http.Context) http.Response {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "写入Fail2ban规则失败")
|
||||
}
|
||||
|
||||
tools.Exec("fail2ban-client reload")
|
||||
if _, err := tools.Exec("fail2ban-client reload"); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "重载配置失败")
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
@@ -372,9 +355,18 @@ func (r *Fail2banController) BanList(ctx http.Context) http.Response {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, "缺少参数")
|
||||
}
|
||||
|
||||
currentlyBan := tools.Exec(`fail2ban-client status ` + name + ` | grep "Currently banned" | awk '{print $4}'`)
|
||||
totalBan := tools.Exec(`fail2ban-client status ` + name + ` | grep "Total banned" | awk '{print $4}'`)
|
||||
bannedIp := tools.Exec(`fail2ban-client status ` + name + ` | grep "Banned IP list" | awk -F ":" '{print $2}'`)
|
||||
currentlyBan, err := tools.Exec(`fail2ban-client status ` + name + ` | grep "Currently banned" | awk '{print $4}'`)
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取封禁列表失败")
|
||||
}
|
||||
totalBan, err := tools.Exec(`fail2ban-client status ` + name + ` | grep "Total banned" | awk '{print $4}'`)
|
||||
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}'`)
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取封禁列表失败")
|
||||
}
|
||||
bannedIpList := strings.Split(bannedIp, " ")
|
||||
|
||||
var list []map[string]string
|
||||
@@ -410,7 +402,10 @@ func (r *Fail2banController) Unban(ctx http.Context) http.Response {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, "缺少参数")
|
||||
}
|
||||
|
||||
tools.Exec("fail2ban-client set " + name + " unbanip " + ip)
|
||||
if _, err := tools.Exec("fail2ban-client set " + name + " unbanip " + ip); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "解封失败")
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
@@ -438,7 +433,10 @@ func (r *Fail2banController) SetWhiteList(ctx http.Context) http.Response {
|
||||
if err := tools.Write("/etc/fail2ban/jail.local", raw, 0644); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "写入Fail2ban规则失败")
|
||||
}
|
||||
tools.Exec("fail2ban-client reload")
|
||||
|
||||
if _, err := tools.Exec("fail2ban-client reload"); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "重载配置失败")
|
||||
}
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
|
||||
@@ -4,10 +4,8 @@ import (
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/goravel/framework/contracts/http"
|
||||
"github.com/goravel/framework/facades"
|
||||
"github.com/spf13/cast"
|
||||
|
||||
"panel/app/http/controllers"
|
||||
@@ -35,16 +33,12 @@ func (r *Mysql57Controller) Status(ctx http.Context) http.Response {
|
||||
return check
|
||||
}
|
||||
|
||||
status := tools.Exec("systemctl status mysqld | grep Active | grep -v grep | awk '{print $2}'")
|
||||
if len(status) == 0 {
|
||||
status, err := tools.ServiceStatus("mysqld")
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取MySQL状态失败")
|
||||
}
|
||||
|
||||
if status == "active" {
|
||||
return controllers.Success(ctx, true)
|
||||
} else {
|
||||
return controllers.Success(ctx, false)
|
||||
}
|
||||
return controllers.Success(ctx, status)
|
||||
}
|
||||
|
||||
// Reload 重载配置
|
||||
@@ -54,17 +48,11 @@ func (r *Mysql57Controller) Reload(ctx http.Context) http.Response {
|
||||
return check
|
||||
}
|
||||
|
||||
tools.Exec("systemctl reload mysqld")
|
||||
status := tools.Exec("systemctl status mysqld | grep Active | grep -v grep | awk '{print $2}'")
|
||||
if len(status) == 0 {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取MySQL状态失败")
|
||||
if err := tools.ServiceReload("mysqld"); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "重载MySQL失败")
|
||||
}
|
||||
|
||||
if status == "active" {
|
||||
return controllers.Success(ctx, true)
|
||||
} else {
|
||||
return controllers.Success(ctx, false)
|
||||
}
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// Restart 重启服务
|
||||
@@ -74,17 +62,11 @@ func (r *Mysql57Controller) Restart(ctx http.Context) http.Response {
|
||||
return check
|
||||
}
|
||||
|
||||
tools.Exec("systemctl restart mysqld")
|
||||
status := tools.Exec("systemctl status mysqld | grep Active | grep -v grep | awk '{print $2}'")
|
||||
if len(status) == 0 {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取MySQL状态失败")
|
||||
if err := tools.ServiceRestart("mysqld"); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "重启MySQL服务失败")
|
||||
}
|
||||
|
||||
if status == "active" {
|
||||
return controllers.Success(ctx, true)
|
||||
} else {
|
||||
return controllers.Success(ctx, false)
|
||||
}
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// Start 启动服务
|
||||
@@ -94,17 +76,11 @@ func (r *Mysql57Controller) Start(ctx http.Context) http.Response {
|
||||
return check
|
||||
}
|
||||
|
||||
tools.Exec("systemctl start mysqld")
|
||||
status := tools.Exec("systemctl status mysqld | grep Active | grep -v grep | awk '{print $2}'")
|
||||
if len(status) == 0 {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取MySQL状态失败")
|
||||
if err := tools.ServiceStart("mysqld"); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "启动MySQL服务失败")
|
||||
}
|
||||
|
||||
if status == "active" {
|
||||
return controllers.Success(ctx, true)
|
||||
} else {
|
||||
return controllers.Success(ctx, false)
|
||||
}
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// Stop 停止服务
|
||||
@@ -114,17 +90,11 @@ func (r *Mysql57Controller) Stop(ctx http.Context) http.Response {
|
||||
return check
|
||||
}
|
||||
|
||||
tools.Exec("systemctl stop mysqld")
|
||||
status := tools.Exec("systemctl status mysqld | grep Active | grep -v grep | awk '{print $2}'")
|
||||
if len(status) == 0 {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取MySQL状态失败")
|
||||
if err := tools.ServiceStop("mysqld"); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "停止MySQL服务失败")
|
||||
}
|
||||
|
||||
if status != "active" {
|
||||
return controllers.Success(ctx, true)
|
||||
} else {
|
||||
return controllers.Success(ctx, false)
|
||||
}
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// GetConfig 获取配置
|
||||
@@ -174,16 +144,16 @@ func (r *Mysql57Controller) Load(ctx http.Context) http.Response {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, "MySQL root密码为空")
|
||||
}
|
||||
|
||||
status := tools.Exec("systemctl status mysqld | grep Active | grep -v grep | awk '{print $2}'")
|
||||
if status != "active" {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "MySQL 已停止运行")
|
||||
status, err := tools.ServiceStatus("mysqld")
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取MySQL状态失败")
|
||||
}
|
||||
if !status {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "MySQL 未运行")
|
||||
}
|
||||
|
||||
raw := tools.Exec("/www/server/mysql/bin/mysqladmin -uroot -p" + rootPassword + " extended-status 2>&1")
|
||||
if strings.Contains(raw, "Access denied for user") {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, "MySQL root密码错误")
|
||||
}
|
||||
if !strings.Contains(raw, "Uptime") {
|
||||
raw, err := tools.Exec("/www/server/mysql/bin/mysqladmin -uroot -p" + rootPassword + " extended-status 2>&1")
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取MySQL负载失败")
|
||||
}
|
||||
|
||||
@@ -244,7 +214,11 @@ func (r *Mysql57Controller) ErrorLog(ctx http.Context) http.Response {
|
||||
return check
|
||||
}
|
||||
|
||||
log := tools.Escape(tools.Exec("tail -n 100 /www/server/mysql/mysql-error.log"))
|
||||
log, err := tools.Exec("tail -n 100 /www/server/mysql/mysql-error.log")
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, log)
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, log)
|
||||
}
|
||||
|
||||
@@ -255,8 +229,11 @@ func (r *Mysql57Controller) ClearErrorLog(ctx http.Context) http.Response {
|
||||
return check
|
||||
}
|
||||
|
||||
tools.Exec("echo '' > /www/server/mysql/mysql-error.log")
|
||||
return controllers.Success(ctx, "清空错误日志成功")
|
||||
if out, err := tools.Exec("echo '' > /www/server/mysql/mysql-error.log"); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// SlowLog 获取慢查询日志
|
||||
@@ -266,7 +243,11 @@ func (r *Mysql57Controller) SlowLog(ctx http.Context) http.Response {
|
||||
return check
|
||||
}
|
||||
|
||||
log := tools.Escape(tools.Exec("tail -n 100 /www/server/mysql/mysql-slow.log"))
|
||||
log, err := tools.Exec("tail -n 100 /www/server/mysql/mysql-slow.log")
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, log)
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, log)
|
||||
}
|
||||
|
||||
@@ -277,8 +258,10 @@ func (r *Mysql57Controller) ClearSlowLog(ctx http.Context) http.Response {
|
||||
return check
|
||||
}
|
||||
|
||||
tools.Exec("echo '' > /www/server/mysql/mysql-slow.log")
|
||||
return controllers.Success(ctx, "清空慢查询日志成功")
|
||||
if out, err := tools.Exec("echo '' > /www/server/mysql/mysql-slow.log"); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// GetRootPassword 获取root密码
|
||||
@@ -303,11 +286,11 @@ func (r *Mysql57Controller) SetRootPassword(ctx http.Context) http.Response {
|
||||
return check
|
||||
}
|
||||
|
||||
status := tools.Exec("systemctl status mysqld | grep Active | grep -v grep | awk '{print $2}'")
|
||||
if len(status) == 0 {
|
||||
status, err := tools.ServiceStatus("mysqld")
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取MySQL状态失败")
|
||||
}
|
||||
if status != "active" {
|
||||
if !status {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "MySQL 未运行")
|
||||
}
|
||||
|
||||
@@ -318,17 +301,25 @@ func (r *Mysql57Controller) SetRootPassword(ctx http.Context) http.Response {
|
||||
|
||||
oldRootPassword := r.setting.Get(models.SettingKeyMysqlRootPassword)
|
||||
if oldRootPassword != rootPassword {
|
||||
tools.Exec("/www/server/mysql/bin/mysql -uroot -p" + oldRootPassword + " -e \"ALTER USER 'root'@'localhost' IDENTIFIED BY '" + rootPassword + "';\"")
|
||||
tools.Exec("/www/server/mysql/bin/mysql -uroot -p" + oldRootPassword + " -e \"FLUSH PRIVILEGES;\"")
|
||||
if _, err := tools.Exec("/www/server/mysql/bin/mysql -uroot -p" + oldRootPassword + " -e \"ALTER USER 'root'@'localhost' IDENTIFIED BY '" + rootPassword + "';\""); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "设置root密码失败")
|
||||
}
|
||||
if _, err := tools.Exec("/www/server/mysql/bin/mysql -uroot -p" + oldRootPassword + " -e \"FLUSH PRIVILEGES;\""); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "设置root密码失败")
|
||||
}
|
||||
err := r.setting.Set(models.SettingKeyMysqlRootPassword, rootPassword)
|
||||
if err != nil {
|
||||
tools.Exec("/www/server/mysql/bin/mysql -uroot -p" + rootPassword + " -e \"ALTER USER 'root'@'localhost' IDENTIFIED BY '" + oldRootPassword + "';\"")
|
||||
tools.Exec("/www/server/mysql/bin/mysql -uroot -p" + rootPassword + " -e \"FLUSH PRIVILEGES;\"")
|
||||
if _, err := tools.Exec("/www/server/mysql/bin/mysql -uroot -p" + rootPassword + " -e \"ALTER USER 'root'@'localhost' IDENTIFIED BY '" + oldRootPassword + "';\""); err != nil {
|
||||
return nil
|
||||
}
|
||||
if _, err := tools.Exec("/www/server/mysql/bin/mysql -uroot -p" + rootPassword + " -e \"FLUSH PRIVILEGES;\""); err != nil {
|
||||
return nil
|
||||
}
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "设置root密码失败")
|
||||
}
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, "设置root密码成功")
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// DatabaseList 获取数据库列表
|
||||
@@ -345,15 +336,13 @@ func (r *Mysql57Controller) DatabaseList(ctx http.Context) http.Response {
|
||||
|
||||
db, err := sql.Open("mysql", "root:"+rootPassword+"@unix(/tmp/mysql.sock)/")
|
||||
if err != nil {
|
||||
facades.Log().Info("[MySQL57] 连接数据库失败" + err.Error())
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "连接数据库失败")
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
defer db.Close()
|
||||
|
||||
rows, err := db.Query("SHOW DATABASES")
|
||||
if err != nil {
|
||||
facades.Log().Info("[MySQL57] 获取数据库列表失败" + err.Error())
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取数据库列表失败")
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
@@ -369,7 +358,6 @@ func (r *Mysql57Controller) DatabaseList(ctx http.Context) http.Response {
|
||||
}
|
||||
|
||||
if err := rows.Err(); err != nil {
|
||||
facades.Log().Info("[MySQL57] 获取数据库列表失败" + err.Error())
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取数据库列表失败")
|
||||
}
|
||||
|
||||
@@ -418,12 +406,20 @@ func (r *Mysql57Controller) AddDatabase(ctx http.Context) http.Response {
|
||||
user := ctx.Request().Input("user")
|
||||
password := ctx.Request().Input("password")
|
||||
|
||||
tools.Exec("/www/server/mysql/bin/mysql -uroot -p" + rootPassword + " -e \"CREATE DATABASE IF NOT EXISTS " + database + " DEFAULT CHARSET utf8mb4 COLLATE utf8mb4_general_ci;\"")
|
||||
tools.Exec("/www/server/mysql/bin/mysql -uroot -p" + rootPassword + " -e \"CREATE USER '" + user + "'@'localhost' IDENTIFIED BY '" + password + "';\"")
|
||||
tools.Exec("/www/server/mysql/bin/mysql -uroot -p" + rootPassword + " -e \"GRANT ALL PRIVILEGES ON " + database + ".* TO '" + user + "'@'localhost';\"")
|
||||
tools.Exec("/www/server/mysql/bin/mysql -uroot -p" + rootPassword + " -e \"FLUSH PRIVILEGES;\"")
|
||||
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 {
|
||||
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 {
|
||||
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 {
|
||||
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 {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, "添加数据库成功")
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// DeleteDatabase 删除数据库
|
||||
@@ -445,9 +441,11 @@ func (r *Mysql57Controller) DeleteDatabase(ctx http.Context) http.Response {
|
||||
|
||||
rootPassword := r.setting.Get(models.SettingKeyMysqlRootPassword)
|
||||
database := ctx.Request().Input("database")
|
||||
tools.Exec("/www/server/mysql/bin/mysql -uroot -p" + rootPassword + " -e \"DROP DATABASE IF EXISTS " + database + ";\"")
|
||||
if out, err := tools.Exec("/www/server/mysql/bin/mysql -uroot -p" + rootPassword + " -e \"DROP DATABASE IF EXISTS " + database + ";\""); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, "删除数据库成功")
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// BackupList 获取备份列表
|
||||
@@ -459,8 +457,7 @@ func (r *Mysql57Controller) BackupList(ctx http.Context) http.Response {
|
||||
|
||||
backupList, err := r.backup.MysqlList()
|
||||
if err != nil {
|
||||
facades.Log().Info("[MySQL57] 获取备份列表失败:" + err.Error())
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取备份列表失败")
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
|
||||
page := ctx.Request().QueryInt("page", 1)
|
||||
@@ -512,7 +509,7 @@ func (r *Mysql57Controller) UploadBackup(ctx http.Context) http.Response {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, "上传文件失败")
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, "上传文件成功")
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// CreateBackup 创建备份
|
||||
@@ -535,11 +532,10 @@ func (r *Mysql57Controller) CreateBackup(ctx http.Context) http.Response {
|
||||
database := ctx.Request().Input("database")
|
||||
err = r.backup.MysqlBackup(database)
|
||||
if err != nil {
|
||||
facades.Log().Info("[MYSQL57] 创建备份失败:" + err.Error())
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "创建备份失败")
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, "备份成功")
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// DeleteBackup 删除备份
|
||||
@@ -563,7 +559,7 @@ func (r *Mysql57Controller) DeleteBackup(ctx http.Context) http.Response {
|
||||
fileName := ctx.Request().Input("name")
|
||||
tools.Remove(backupPath + "/" + fileName)
|
||||
|
||||
return controllers.Success(ctx, "删除备份成功")
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// RestoreBackup 还原备份
|
||||
@@ -586,11 +582,10 @@ func (r *Mysql57Controller) RestoreBackup(ctx http.Context) http.Response {
|
||||
|
||||
err = r.backup.MysqlRestore(ctx.Request().Input("database"), ctx.Request().Input("backup"))
|
||||
if err != nil {
|
||||
facades.Log().Info("[MYSQL57] 还原失败:" + err.Error())
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "还原失败: "+err.Error())
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, "还原成功")
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// UserList 用户列表
|
||||
@@ -609,15 +604,13 @@ func (r *Mysql57Controller) UserList(ctx http.Context) http.Response {
|
||||
rootPassword := r.setting.Get(models.SettingKeyMysqlRootPassword)
|
||||
db, err := sql.Open("mysql", "root:"+rootPassword+"@unix(/tmp/mysql.sock)/")
|
||||
if err != nil {
|
||||
facades.Log().Info("[MYSQL57] 连接数据库失败:" + err.Error())
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "连接数据库失败")
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
defer db.Close()
|
||||
|
||||
rows, err := db.Query("SELECT user, host FROM mysql.user")
|
||||
if err != nil {
|
||||
facades.Log().Info("[MYSQL57] 查询数据库失败:" + err.Error())
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "查询数据库失败")
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
@@ -702,11 +695,17 @@ func (r *Mysql57Controller) AddUser(ctx http.Context) http.Response {
|
||||
user := ctx.Request().Input("user")
|
||||
password := ctx.Request().Input("password")
|
||||
database := ctx.Request().Input("database")
|
||||
tools.Exec("/www/server/mysql/bin/mysql -uroot -p" + rootPassword + " -e \"CREATE USER '" + user + "'@'localhost' IDENTIFIED BY '" + password + ";'\"")
|
||||
tools.Exec("/www/server/mysql/bin/mysql -uroot -p" + rootPassword + " -e \"GRANT ALL PRIVILEGES ON " + database + ".* TO '" + user + "'@'localhost';\"")
|
||||
tools.Exec("/www/server/mysql/bin/mysql -uroot -p" + rootPassword + " -e \"FLUSH PRIVILEGES;\"")
|
||||
if out, err := tools.Exec("/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 {
|
||||
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 {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, "添加成功")
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// DeleteUser 删除用户
|
||||
@@ -728,9 +727,11 @@ func (r *Mysql57Controller) DeleteUser(ctx http.Context) http.Response {
|
||||
|
||||
rootPassword := r.setting.Get(models.SettingKeyMysqlRootPassword)
|
||||
user := ctx.Request().Input("user")
|
||||
tools.Exec("/www/server/mysql/bin/mysql -uroot -p" + rootPassword + " -e \"DROP USER '" + user + "'@'localhost';\"")
|
||||
if out, err := tools.Exec("/www/server/mysql/bin/mysql -uroot -p" + rootPassword + " -e \"DROP USER '" + user + "'@'localhost';\""); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, "删除成功")
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// SetUserPassword 设置用户密码
|
||||
@@ -754,10 +755,14 @@ func (r *Mysql57Controller) SetUserPassword(ctx http.Context) http.Response {
|
||||
rootPassword := r.setting.Get(models.SettingKeyMysqlRootPassword)
|
||||
user := ctx.Request().Input("user")
|
||||
password := ctx.Request().Input("password")
|
||||
tools.Exec("/www/server/mysql/bin/mysql -uroot -p" + rootPassword + " -e \"ALTER USER '" + user + "'@'localhost' IDENTIFIED BY '" + password + "';\"")
|
||||
tools.Exec("/www/server/mysql/bin/mysql -uroot -p" + rootPassword + " -e \"FLUSH PRIVILEGES;\"")
|
||||
if out, err := tools.Exec("/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 {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, "修改成功")
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// SetUserPrivileges 设置用户权限
|
||||
@@ -781,9 +786,15 @@ func (r *Mysql57Controller) SetUserPrivileges(ctx http.Context) http.Response {
|
||||
rootPassword := r.setting.Get(models.SettingKeyMysqlRootPassword)
|
||||
user := ctx.Request().Input("user")
|
||||
database := ctx.Request().Input("database")
|
||||
tools.Exec("/www/server/mysql/bin/mysql -uroot -p" + rootPassword + " -e \"REVOKE ALL PRIVILEGES ON *.* FROM '" + user + "'@'localhost';\"")
|
||||
tools.Exec("/www/server/mysql/bin/mysql -uroot -p" + rootPassword + " -e \"GRANT ALL PRIVILEGES ON " + database + ".* TO '" + user + "'@'localhost';\"")
|
||||
tools.Exec("/www/server/mysql/bin/mysql -uroot -p" + rootPassword + " -e \"FLUSH PRIVILEGES;\"")
|
||||
if out, err := tools.Exec("/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 {
|
||||
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 {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, "修改成功")
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
@@ -4,10 +4,8 @@ import (
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/goravel/framework/contracts/http"
|
||||
"github.com/goravel/framework/facades"
|
||||
"github.com/spf13/cast"
|
||||
|
||||
"panel/app/http/controllers"
|
||||
@@ -35,16 +33,12 @@ func (r *Mysql80Controller) Status(ctx http.Context) http.Response {
|
||||
return check
|
||||
}
|
||||
|
||||
status := tools.Exec("systemctl status mysqld | grep Active | grep -v grep | awk '{print $2}'")
|
||||
if len(status) == 0 {
|
||||
status, err := tools.ServiceStatus("mysqld")
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取MySQL状态失败")
|
||||
}
|
||||
|
||||
if status == "active" {
|
||||
return controllers.Success(ctx, true)
|
||||
} else {
|
||||
return controllers.Success(ctx, false)
|
||||
}
|
||||
return controllers.Success(ctx, status)
|
||||
}
|
||||
|
||||
// Reload 重载配置
|
||||
@@ -54,17 +48,11 @@ func (r *Mysql80Controller) Reload(ctx http.Context) http.Response {
|
||||
return check
|
||||
}
|
||||
|
||||
tools.Exec("systemctl reload mysqld")
|
||||
status := tools.Exec("systemctl status mysqld | grep Active | grep -v grep | awk '{print $2}'")
|
||||
if len(status) == 0 {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取MySQL状态失败")
|
||||
if err := tools.ServiceReload("mysqld"); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "重载MySQL配置失败")
|
||||
}
|
||||
|
||||
if status == "active" {
|
||||
return controllers.Success(ctx, true)
|
||||
} else {
|
||||
return controllers.Success(ctx, false)
|
||||
}
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// Restart 重启服务
|
||||
@@ -74,17 +62,11 @@ func (r *Mysql80Controller) Restart(ctx http.Context) http.Response {
|
||||
return check
|
||||
}
|
||||
|
||||
tools.Exec("systemctl restart mysqld")
|
||||
status := tools.Exec("systemctl status mysqld | grep Active | grep -v grep | awk '{print $2}'")
|
||||
if len(status) == 0 {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取MySQL状态失败")
|
||||
if err := tools.ServiceRestart("mysqld"); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "重启MySQL服务失败")
|
||||
}
|
||||
|
||||
if status == "active" {
|
||||
return controllers.Success(ctx, true)
|
||||
} else {
|
||||
return controllers.Success(ctx, false)
|
||||
}
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// Start 启动服务
|
||||
@@ -94,17 +76,11 @@ func (r *Mysql80Controller) Start(ctx http.Context) http.Response {
|
||||
return check
|
||||
}
|
||||
|
||||
tools.Exec("systemctl start mysqld")
|
||||
status := tools.Exec("systemctl status mysqld | grep Active | grep -v grep | awk '{print $2}'")
|
||||
if len(status) == 0 {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取MySQL状态失败")
|
||||
if err := tools.ServiceStart("mysqld"); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "启动MySQL服务失败")
|
||||
}
|
||||
|
||||
if status == "active" {
|
||||
return controllers.Success(ctx, true)
|
||||
} else {
|
||||
return controllers.Success(ctx, false)
|
||||
}
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// Stop 停止服务
|
||||
@@ -114,17 +90,11 @@ func (r *Mysql80Controller) Stop(ctx http.Context) http.Response {
|
||||
return check
|
||||
}
|
||||
|
||||
tools.Exec("systemctl stop mysqld")
|
||||
status := tools.Exec("systemctl status mysqld | grep Active | grep -v grep | awk '{print $2}'")
|
||||
if len(status) == 0 {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取MySQL状态失败")
|
||||
if err := tools.ServiceStop("mysqld"); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "停止MySQL服务失败")
|
||||
}
|
||||
|
||||
if status != "active" {
|
||||
return controllers.Success(ctx, true)
|
||||
} else {
|
||||
return controllers.Success(ctx, false)
|
||||
}
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// GetConfig 获取配置
|
||||
@@ -174,16 +144,16 @@ func (r *Mysql80Controller) Load(ctx http.Context) http.Response {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, "MySQL root密码为空")
|
||||
}
|
||||
|
||||
status := tools.Exec("systemctl status mysqld | grep Active | grep -v grep | awk '{print $2}'")
|
||||
if status != "active" {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "MySQL 已停止运行")
|
||||
status, err := tools.ServiceStatus("mysqld")
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取MySQL状态失败")
|
||||
}
|
||||
if !status {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "MySQL 未运行")
|
||||
}
|
||||
|
||||
raw := tools.Exec("/www/server/mysql/bin/mysqladmin -uroot -p" + rootPassword + " extended-status 2>&1")
|
||||
if strings.Contains(raw, "Access denied for user") {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, "MySQL root密码错误")
|
||||
}
|
||||
if !strings.Contains(raw, "Uptime") {
|
||||
raw, err := tools.Exec("/www/server/mysql/bin/mysqladmin -uroot -p" + rootPassword + " extended-status 2>&1")
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取MySQL负载失败")
|
||||
}
|
||||
|
||||
@@ -244,7 +214,11 @@ func (r *Mysql80Controller) ErrorLog(ctx http.Context) http.Response {
|
||||
return check
|
||||
}
|
||||
|
||||
log := tools.Escape(tools.Exec("tail -n 100 /www/server/mysql/mysql-error.log"))
|
||||
log, err := tools.Exec("tail -n 100 /www/server/mysql/mysql-error.log")
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, log)
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, log)
|
||||
}
|
||||
|
||||
@@ -255,8 +229,11 @@ func (r *Mysql80Controller) ClearErrorLog(ctx http.Context) http.Response {
|
||||
return check
|
||||
}
|
||||
|
||||
tools.Exec("echo '' > /www/server/mysql/mysql-error.log")
|
||||
return controllers.Success(ctx, "清空错误日志成功")
|
||||
if out, err := tools.Exec("echo '' > /www/server/mysql/mysql-error.log"); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// SlowLog 获取慢查询日志
|
||||
@@ -266,7 +243,11 @@ func (r *Mysql80Controller) SlowLog(ctx http.Context) http.Response {
|
||||
return check
|
||||
}
|
||||
|
||||
log := tools.Escape(tools.Exec("tail -n 100 /www/server/mysql/mysql-slow.log"))
|
||||
log, err := tools.Exec("tail -n 100 /www/server/mysql/mysql-slow.log")
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, log)
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, log)
|
||||
}
|
||||
|
||||
@@ -277,8 +258,10 @@ func (r *Mysql80Controller) ClearSlowLog(ctx http.Context) http.Response {
|
||||
return check
|
||||
}
|
||||
|
||||
tools.Exec("echo '' > /www/server/mysql/mysql-slow.log")
|
||||
return controllers.Success(ctx, "清空慢查询日志成功")
|
||||
if out, err := tools.Exec("echo '' > /www/server/mysql/mysql-slow.log"); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// GetRootPassword 获取root密码
|
||||
@@ -303,11 +286,11 @@ func (r *Mysql80Controller) SetRootPassword(ctx http.Context) http.Response {
|
||||
return check
|
||||
}
|
||||
|
||||
status := tools.Exec("systemctl status mysqld | grep Active | grep -v grep | awk '{print $2}'")
|
||||
if len(status) == 0 {
|
||||
status, err := tools.ServiceStatus("mysqld")
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取MySQL状态失败")
|
||||
}
|
||||
if status != "active" {
|
||||
if !status {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "MySQL 未运行")
|
||||
}
|
||||
|
||||
@@ -318,17 +301,25 @@ func (r *Mysql80Controller) SetRootPassword(ctx http.Context) http.Response {
|
||||
|
||||
oldRootPassword := r.setting.Get(models.SettingKeyMysqlRootPassword)
|
||||
if oldRootPassword != rootPassword {
|
||||
tools.Exec("/www/server/mysql/bin/mysql -uroot -p" + oldRootPassword + " -e \"ALTER USER 'root'@'localhost' IDENTIFIED BY '" + rootPassword + "';\"")
|
||||
tools.Exec("/www/server/mysql/bin/mysql -uroot -p" + oldRootPassword + " -e \"FLUSH PRIVILEGES;\"")
|
||||
if _, err := tools.Exec("/www/server/mysql/bin/mysql -uroot -p" + oldRootPassword + " -e \"ALTER USER 'root'@'localhost' IDENTIFIED BY '" + rootPassword + "';\""); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "设置root密码失败")
|
||||
}
|
||||
if _, err := tools.Exec("/www/server/mysql/bin/mysql -uroot -p" + oldRootPassword + " -e \"FLUSH PRIVILEGES;\""); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "设置root密码失败")
|
||||
}
|
||||
err := r.setting.Set(models.SettingKeyMysqlRootPassword, rootPassword)
|
||||
if err != nil {
|
||||
tools.Exec("/www/server/mysql/bin/mysql -uroot -p" + rootPassword + " -e \"ALTER USER 'root'@'localhost' IDENTIFIED BY '" + oldRootPassword + "';\"")
|
||||
tools.Exec("/www/server/mysql/bin/mysql -uroot -p" + rootPassword + " -e \"FLUSH PRIVILEGES;\"")
|
||||
if _, err := tools.Exec("/www/server/mysql/bin/mysql -uroot -p" + rootPassword + " -e \"ALTER USER 'root'@'localhost' IDENTIFIED BY '" + oldRootPassword + "';\""); err != nil {
|
||||
return nil
|
||||
}
|
||||
if _, err := tools.Exec("/www/server/mysql/bin/mysql -uroot -p" + rootPassword + " -e \"FLUSH PRIVILEGES;\""); err != nil {
|
||||
return nil
|
||||
}
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "设置root密码失败")
|
||||
}
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, "设置root密码成功")
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// DatabaseList 获取数据库列表
|
||||
@@ -345,15 +336,13 @@ func (r *Mysql80Controller) DatabaseList(ctx http.Context) http.Response {
|
||||
|
||||
db, err := sql.Open("mysql", "root:"+rootPassword+"@unix(/tmp/mysql.sock)/")
|
||||
if err != nil {
|
||||
facades.Log().Info("[MySQL80] 连接数据库失败" + err.Error())
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "连接数据库失败")
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
defer db.Close()
|
||||
|
||||
rows, err := db.Query("SHOW DATABASES")
|
||||
if err != nil {
|
||||
facades.Log().Info("[MySQL80] 获取数据库列表失败" + err.Error())
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取数据库列表失败")
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
@@ -369,7 +358,6 @@ func (r *Mysql80Controller) DatabaseList(ctx http.Context) http.Response {
|
||||
}
|
||||
|
||||
if err := rows.Err(); err != nil {
|
||||
facades.Log().Info("[MySQL80] 获取数据库列表失败" + err.Error())
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取数据库列表失败")
|
||||
}
|
||||
|
||||
@@ -418,12 +406,20 @@ func (r *Mysql80Controller) AddDatabase(ctx http.Context) http.Response {
|
||||
user := ctx.Request().Input("user")
|
||||
password := ctx.Request().Input("password")
|
||||
|
||||
tools.Exec("/www/server/mysql/bin/mysql -uroot -p" + rootPassword + " -e \"CREATE DATABASE IF NOT EXISTS " + database + " DEFAULT CHARSET utf8mb4 COLLATE utf8mb4_general_ci;\"")
|
||||
tools.Exec("/www/server/mysql/bin/mysql -uroot -p" + rootPassword + " -e \"CREATE USER '" + user + "'@'localhost' IDENTIFIED BY '" + password + "';\"")
|
||||
tools.Exec("/www/server/mysql/bin/mysql -uroot -p" + rootPassword + " -e \"GRANT ALL PRIVILEGES ON " + database + ".* TO '" + user + "'@'localhost';\"")
|
||||
tools.Exec("/www/server/mysql/bin/mysql -uroot -p" + rootPassword + " -e \"FLUSH PRIVILEGES;\"")
|
||||
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 {
|
||||
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 {
|
||||
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 {
|
||||
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 {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, "添加数据库成功")
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// DeleteDatabase 删除数据库
|
||||
@@ -445,9 +441,11 @@ func (r *Mysql80Controller) DeleteDatabase(ctx http.Context) http.Response {
|
||||
|
||||
rootPassword := r.setting.Get(models.SettingKeyMysqlRootPassword)
|
||||
database := ctx.Request().Input("database")
|
||||
tools.Exec("/www/server/mysql/bin/mysql -uroot -p" + rootPassword + " -e \"DROP DATABASE IF EXISTS " + database + ";\"")
|
||||
if out, err := tools.Exec("/www/server/mysql/bin/mysql -uroot -p" + rootPassword + " -e \"DROP DATABASE IF EXISTS " + database + ";\""); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, "删除数据库成功")
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// BackupList 获取备份列表
|
||||
@@ -459,8 +457,7 @@ func (r *Mysql80Controller) BackupList(ctx http.Context) http.Response {
|
||||
|
||||
backupList, err := r.backup.MysqlList()
|
||||
if err != nil {
|
||||
facades.Log().Info("[MySQL80] 获取备份列表失败:" + err.Error())
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取备份列表失败")
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
|
||||
page := ctx.Request().QueryInt("page", 1)
|
||||
@@ -512,7 +509,7 @@ func (r *Mysql80Controller) UploadBackup(ctx http.Context) http.Response {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, "上传文件失败")
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, "上传文件成功")
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// CreateBackup 创建备份
|
||||
@@ -535,11 +532,10 @@ func (r *Mysql80Controller) CreateBackup(ctx http.Context) http.Response {
|
||||
database := ctx.Request().Input("database")
|
||||
err = r.backup.MysqlBackup(database)
|
||||
if err != nil {
|
||||
facades.Log().Info("[MYSQL80] 创建备份失败:" + err.Error())
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "创建备份失败")
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, "备份成功")
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// DeleteBackup 删除备份
|
||||
@@ -563,7 +559,7 @@ func (r *Mysql80Controller) DeleteBackup(ctx http.Context) http.Response {
|
||||
fileName := ctx.Request().Input("name")
|
||||
tools.Remove(backupPath + "/" + fileName)
|
||||
|
||||
return controllers.Success(ctx, "删除备份成功")
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// RestoreBackup 还原备份
|
||||
@@ -586,11 +582,10 @@ func (r *Mysql80Controller) RestoreBackup(ctx http.Context) http.Response {
|
||||
|
||||
err = r.backup.MysqlRestore(ctx.Request().Input("database"), ctx.Request().Input("backup"))
|
||||
if err != nil {
|
||||
facades.Log().Info("[MYSQL80] 还原失败:" + err.Error())
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "还原失败: "+err.Error())
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, "还原成功")
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// UserList 用户列表
|
||||
@@ -609,15 +604,13 @@ func (r *Mysql80Controller) UserList(ctx http.Context) http.Response {
|
||||
rootPassword := r.setting.Get(models.SettingKeyMysqlRootPassword)
|
||||
db, err := sql.Open("mysql", "root:"+rootPassword+"@unix(/tmp/mysql.sock)/")
|
||||
if err != nil {
|
||||
facades.Log().Info("[MYSQL80] 连接数据库失败:" + err.Error())
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "连接数据库失败")
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
defer db.Close()
|
||||
|
||||
rows, err := db.Query("SELECT user, host FROM mysql.user")
|
||||
if err != nil {
|
||||
facades.Log().Info("[MYSQL80] 查询数据库失败:" + err.Error())
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "查询数据库失败")
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
@@ -702,11 +695,17 @@ func (r *Mysql80Controller) AddUser(ctx http.Context) http.Response {
|
||||
user := ctx.Request().Input("user")
|
||||
password := ctx.Request().Input("password")
|
||||
database := ctx.Request().Input("database")
|
||||
tools.Exec("/www/server/mysql/bin/mysql -uroot -p" + rootPassword + " -e \"CREATE USER '" + user + "'@'localhost' IDENTIFIED BY '" + password + ";'\"")
|
||||
tools.Exec("/www/server/mysql/bin/mysql -uroot -p" + rootPassword + " -e \"GRANT ALL PRIVILEGES ON " + database + ".* TO '" + user + "'@'localhost';\"")
|
||||
tools.Exec("/www/server/mysql/bin/mysql -uroot -p" + rootPassword + " -e \"FLUSH PRIVILEGES;\"")
|
||||
if out, err := tools.Exec("/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 {
|
||||
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 {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, "添加成功")
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// DeleteUser 删除用户
|
||||
@@ -728,9 +727,11 @@ func (r *Mysql80Controller) DeleteUser(ctx http.Context) http.Response {
|
||||
|
||||
rootPassword := r.setting.Get(models.SettingKeyMysqlRootPassword)
|
||||
user := ctx.Request().Input("user")
|
||||
tools.Exec("/www/server/mysql/bin/mysql -uroot -p" + rootPassword + " -e \"DROP USER '" + user + "'@'localhost';\"")
|
||||
if out, err := tools.Exec("/www/server/mysql/bin/mysql -uroot -p" + rootPassword + " -e \"DROP USER '" + user + "'@'localhost';\""); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, "删除成功")
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// SetUserPassword 设置用户密码
|
||||
@@ -754,10 +755,14 @@ func (r *Mysql80Controller) SetUserPassword(ctx http.Context) http.Response {
|
||||
rootPassword := r.setting.Get(models.SettingKeyMysqlRootPassword)
|
||||
user := ctx.Request().Input("user")
|
||||
password := ctx.Request().Input("password")
|
||||
tools.Exec("/www/server/mysql/bin/mysql -uroot -p" + rootPassword + " -e \"ALTER USER '" + user + "'@'localhost' IDENTIFIED BY '" + password + "';\"")
|
||||
tools.Exec("/www/server/mysql/bin/mysql -uroot -p" + rootPassword + " -e \"FLUSH PRIVILEGES;\"")
|
||||
if out, err := tools.Exec("/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 {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, "修改成功")
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// SetUserPrivileges 设置用户权限
|
||||
@@ -781,9 +786,15 @@ func (r *Mysql80Controller) SetUserPrivileges(ctx http.Context) http.Response {
|
||||
rootPassword := r.setting.Get(models.SettingKeyMysqlRootPassword)
|
||||
user := ctx.Request().Input("user")
|
||||
database := ctx.Request().Input("database")
|
||||
tools.Exec("/www/server/mysql/bin/mysql -uroot -p" + rootPassword + " -e \"REVOKE ALL PRIVILEGES ON *.* FROM '" + user + "'@'localhost';\"")
|
||||
tools.Exec("/www/server/mysql/bin/mysql -uroot -p" + rootPassword + " -e \"GRANT ALL PRIVILEGES ON " + database + ".* TO '" + user + "'@'localhost';\"")
|
||||
tools.Exec("/www/server/mysql/bin/mysql -uroot -p" + rootPassword + " -e \"FLUSH PRIVILEGES;\"")
|
||||
if out, err := tools.Exec("/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 {
|
||||
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 {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, "修改成功")
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
@@ -5,7 +5,6 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/goravel/framework/contracts/http"
|
||||
"github.com/goravel/framework/facades"
|
||||
"github.com/imroc/req/v3"
|
||||
"github.com/spf13/cast"
|
||||
|
||||
@@ -30,16 +29,12 @@ func (r *OpenRestyController) Status(ctx http.Context) http.Response {
|
||||
return check
|
||||
}
|
||||
|
||||
status := tools.Exec("systemctl status openresty | grep Active | grep -v grep | awk '{print $2}'")
|
||||
if len(status) == 0 {
|
||||
status, err := tools.ServiceStatus("openresty")
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取OpenResty状态失败")
|
||||
}
|
||||
|
||||
if status == "active" {
|
||||
return controllers.Success(ctx, true)
|
||||
} else {
|
||||
return controllers.Success(ctx, false)
|
||||
}
|
||||
return controllers.Success(ctx, status)
|
||||
}
|
||||
|
||||
// Reload 重载配置
|
||||
@@ -49,17 +44,11 @@ func (r *OpenRestyController) Reload(ctx http.Context) http.Response {
|
||||
return check
|
||||
}
|
||||
|
||||
tools.Exec("systemctl reload openresty")
|
||||
status := tools.Exec("systemctl status openresty | grep Active | grep -v grep | awk '{print $2}'")
|
||||
if len(status) == 0 {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取OpenResty状态失败")
|
||||
if err := tools.ServiceReload("openresty"); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "重载OpenResty失败")
|
||||
}
|
||||
|
||||
if status == "active" {
|
||||
return controllers.Success(ctx, "重载OpenResty成功")
|
||||
} else {
|
||||
return controllers.Error(ctx, 1, "重载OpenResty失败: "+status)
|
||||
}
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// Start 启动OpenResty
|
||||
@@ -69,17 +58,11 @@ func (r *OpenRestyController) Start(ctx http.Context) http.Response {
|
||||
return check
|
||||
}
|
||||
|
||||
tools.Exec("systemctl start openresty")
|
||||
status := tools.Exec("systemctl status openresty | grep Active | grep -v grep | awk '{print $2}'")
|
||||
if len(status) == 0 {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取OpenResty状态失败")
|
||||
if err := tools.ServiceStart("openresty"); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "启动OpenResty失败")
|
||||
}
|
||||
|
||||
if status == "active" {
|
||||
return controllers.Success(ctx, "启动OpenResty成功")
|
||||
} else {
|
||||
return controllers.Error(ctx, 1, "启动OpenResty失败: "+status)
|
||||
}
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// Stop 停止OpenResty
|
||||
@@ -89,17 +72,11 @@ func (r *OpenRestyController) Stop(ctx http.Context) http.Response {
|
||||
return check
|
||||
}
|
||||
|
||||
tools.Exec("systemctl stop openresty")
|
||||
status := tools.Exec("systemctl status openresty | grep Active | grep -v grep | awk '{print $2}'")
|
||||
if len(status) == 0 {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取OpenResty状态失败")
|
||||
if err := tools.ServiceStop("openresty"); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "停止OpenResty失败")
|
||||
}
|
||||
|
||||
if status != "active" {
|
||||
return controllers.Success(ctx, "停止OpenResty成功")
|
||||
} else {
|
||||
return controllers.Error(ctx, 1, "停止OpenResty失败: "+status)
|
||||
}
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// Restart 重启OpenResty
|
||||
@@ -109,17 +86,11 @@ func (r *OpenRestyController) Restart(ctx http.Context) http.Response {
|
||||
return check
|
||||
}
|
||||
|
||||
tools.Exec("systemctl restart openresty")
|
||||
status := tools.Exec("systemctl status openresty | grep Active | grep -v grep | awk '{print $2}'")
|
||||
if len(status) == 0 {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取OpenResty状态失败")
|
||||
if err := tools.ServiceRestart("openresty"); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "重启OpenResty失败")
|
||||
}
|
||||
|
||||
if status == "active" {
|
||||
return controllers.Success(ctx, "重启OpenResty成功")
|
||||
} else {
|
||||
return controllers.Error(ctx, 1, "重启OpenResty失败: "+status)
|
||||
}
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// GetConfig 获取配置
|
||||
@@ -167,7 +138,11 @@ func (r *OpenRestyController) ErrorLog(ctx http.Context) http.Response {
|
||||
return controllers.Success(ctx, "")
|
||||
}
|
||||
|
||||
out := tools.Exec("tail -n 100 /www/wwwlogs/nginx_error.log")
|
||||
out, err := tools.Exec("tail -n 100 /www/wwwlogs/nginx_error.log")
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, out)
|
||||
}
|
||||
|
||||
@@ -178,8 +153,11 @@ func (r *OpenRestyController) ClearErrorLog(ctx http.Context) http.Response {
|
||||
return check
|
||||
}
|
||||
|
||||
tools.Exec("echo '' > /www/wwwlogs/nginx_error.log")
|
||||
return controllers.Success(ctx, "清空OpenResty错误日志成功")
|
||||
if out, err := tools.Exec("echo '' > /www/wwwlogs/nginx_error.log"); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// Load 获取负载
|
||||
@@ -192,7 +170,6 @@ func (r *OpenRestyController) Load(ctx http.Context) http.Response {
|
||||
client := req.C().SetTimeout(10 * time.Second)
|
||||
resp, err := client.R().Get("http://127.0.0.1/nginx_status")
|
||||
if err != nil || !resp.IsSuccessState() {
|
||||
facades.Log().Info("[OpenResty] 获取OpenResty负载失败: " + err.Error())
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取OpenResty负载失败")
|
||||
}
|
||||
|
||||
@@ -203,13 +180,19 @@ func (r *OpenRestyController) Load(ctx http.Context) http.Response {
|
||||
}
|
||||
var data []nginxStatus
|
||||
|
||||
workers := tools.Exec("ps aux | grep nginx | grep 'worker process' | wc -l")
|
||||
workers, err := tools.Exec("ps aux | grep nginx | grep 'worker process' | wc -l")
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取OpenResty负载失败")
|
||||
}
|
||||
data = append(data, nginxStatus{
|
||||
Name: "工作进程",
|
||||
Value: workers,
|
||||
})
|
||||
|
||||
out := tools.Exec("ps aux | grep nginx | grep 'worker process' | awk '{memsum+=$6};END {print memsum}'")
|
||||
out, err := tools.Exec("ps aux | grep nginx | grep 'worker process' | awk '{memsum+=$6};END {print memsum}'")
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取OpenResty负载失败")
|
||||
}
|
||||
mem := tools.FormatBytes(cast.ToFloat64(out))
|
||||
data = append(data, nginxStatus{
|
||||
Name: "内存占用",
|
||||
|
||||
@@ -36,16 +36,12 @@ func (r *Php74Controller) Status(ctx http.Context) http.Response {
|
||||
return check
|
||||
}
|
||||
|
||||
status := tools.Exec("systemctl status php-fpm-" + r.version + " | grep Active | grep -v grep | awk '{print $2}'")
|
||||
if len(status) == 0 {
|
||||
status, err := tools.ServiceStatus("php-fpm-" + r.version)
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取PHP-"+r.version+"运行状态失败")
|
||||
}
|
||||
|
||||
if status == "active" {
|
||||
return controllers.Success(ctx, true)
|
||||
} else {
|
||||
return controllers.Success(ctx, false)
|
||||
}
|
||||
return controllers.Success(ctx, status)
|
||||
}
|
||||
|
||||
func (r *Php74Controller) Reload(ctx http.Context) http.Response {
|
||||
@@ -54,18 +50,11 @@ func (r *Php74Controller) Reload(ctx http.Context) http.Response {
|
||||
return check
|
||||
}
|
||||
|
||||
tools.Exec("systemctl reload php-fpm-" + r.version)
|
||||
out := tools.Exec("systemctl status php-fpm-" + r.version + " | grep Active | grep -v grep | awk '{print $2}'")
|
||||
status := strings.TrimSpace(out)
|
||||
if len(status) == 0 {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取PHP-"+r.version+"运行状态失败")
|
||||
if err := tools.ServiceReload("php-fpm-" + r.version); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "重载PHP-"+r.version+"失败")
|
||||
}
|
||||
|
||||
if status == "active" {
|
||||
return controllers.Success(ctx, true)
|
||||
} else {
|
||||
return controllers.Success(ctx, false)
|
||||
}
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
func (r *Php74Controller) Start(ctx http.Context) http.Response {
|
||||
@@ -74,18 +63,11 @@ func (r *Php74Controller) Start(ctx http.Context) http.Response {
|
||||
return check
|
||||
}
|
||||
|
||||
tools.Exec("systemctl start php-fpm-" + r.version)
|
||||
out := tools.Exec("systemctl status php-fpm-" + r.version + " | grep Active | grep -v grep | awk '{print $2}'")
|
||||
status := strings.TrimSpace(out)
|
||||
if len(status) == 0 {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取PHP-"+r.version+"运行状态失败")
|
||||
if err := tools.ServiceStart("php-fpm-" + r.version); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "启动PHP-"+r.version+"失败")
|
||||
}
|
||||
|
||||
if status == "active" {
|
||||
return controllers.Success(ctx, true)
|
||||
} else {
|
||||
return controllers.Success(ctx, false)
|
||||
}
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
func (r *Php74Controller) Stop(ctx http.Context) http.Response {
|
||||
@@ -94,18 +76,11 @@ func (r *Php74Controller) Stop(ctx http.Context) http.Response {
|
||||
return check
|
||||
}
|
||||
|
||||
tools.Exec("systemctl stop php-fpm-" + r.version)
|
||||
out := tools.Exec("systemctl status php-fpm-" + r.version + " | grep Active | grep -v grep | awk '{print $2}'")
|
||||
status := strings.TrimSpace(out)
|
||||
if len(status) == 0 {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取PHP-"+r.version+"运行状态失败")
|
||||
if err := tools.ServiceStop("php-fpm-" + r.version); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "停止PHP-"+r.version+"失败")
|
||||
}
|
||||
|
||||
if status != "active" {
|
||||
return controllers.Success(ctx, true)
|
||||
} else {
|
||||
return controllers.Success(ctx, false)
|
||||
}
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
func (r *Php74Controller) Restart(ctx http.Context) http.Response {
|
||||
@@ -114,18 +89,11 @@ func (r *Php74Controller) Restart(ctx http.Context) http.Response {
|
||||
return check
|
||||
}
|
||||
|
||||
tools.Exec("systemctl restart php-fpm-" + r.version)
|
||||
out := tools.Exec("systemctl status php-fpm-" + r.version + " | grep Active | grep -v grep | awk '{print $2}'")
|
||||
status := strings.TrimSpace(out)
|
||||
if len(status) == 0 {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取PHP-"+r.version+"运行状态失败")
|
||||
if err := tools.ServiceRestart("php-fpm-" + r.version); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "重启PHP-"+r.version+"失败")
|
||||
}
|
||||
|
||||
if status == "active" {
|
||||
return controllers.Success(ctx, true)
|
||||
} else {
|
||||
return controllers.Success(ctx, false)
|
||||
}
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
func (r *Php74Controller) GetConfig(ctx http.Context) http.Response {
|
||||
@@ -193,7 +161,11 @@ func (r *Php74Controller) ErrorLog(ctx http.Context) http.Response {
|
||||
return check
|
||||
}
|
||||
|
||||
log := tools.Escape(tools.Exec("tail -n 100 /www/server/php/" + r.version + "/var/log/php-fpm.log"))
|
||||
log, err := tools.Exec("tail -n 100 /www/server/php/" + r.version + "/var/log/php-fpm.log")
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, log)
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, log)
|
||||
}
|
||||
|
||||
@@ -203,7 +175,11 @@ func (r *Php74Controller) SlowLog(ctx http.Context) http.Response {
|
||||
return check
|
||||
}
|
||||
|
||||
log := tools.Escape(tools.Exec("tail -n 100 /www/server/php/" + r.version + "/var/log/slow.log"))
|
||||
log, err := tools.Exec("tail -n 100 /www/server/php/" + r.version + "/var/log/slow.log")
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, log)
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, log)
|
||||
}
|
||||
|
||||
@@ -213,8 +189,11 @@ func (r *Php74Controller) ClearErrorLog(ctx http.Context) http.Response {
|
||||
return check
|
||||
}
|
||||
|
||||
tools.Exec("echo '' > /www/server/php/" + r.version + "/var/log/php-fpm.log")
|
||||
return controllers.Success(ctx, true)
|
||||
if out, err := tools.Exec("echo '' > /www/server/php/" + r.version + "/var/log/php-fpm.log"); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
func (r *Php74Controller) ClearSlowLog(ctx http.Context) http.Response {
|
||||
@@ -223,8 +202,10 @@ func (r *Php74Controller) ClearSlowLog(ctx http.Context) http.Response {
|
||||
return check
|
||||
}
|
||||
|
||||
tools.Exec("echo '' > /www/server/php/" + r.version + "/var/log/slow.log")
|
||||
return controllers.Success(ctx, true)
|
||||
if out, err := tools.Exec("echo '' > /www/server/php/" + r.version + "/var/log/slow.log"); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
func (r *Php74Controller) GetExtensionList(ctx http.Context) http.Response {
|
||||
@@ -350,9 +331,12 @@ func (r *Php74Controller) GetExtensions() []PHPExtension {
|
||||
Installed: false,
|
||||
})
|
||||
|
||||
raw := tools.Exec("/www/server/php/" + r.version + "/bin/php -m")
|
||||
rawExtensionList := strings.Split(raw, "\n")
|
||||
raw, err := tools.Exec("/www/server/php/" + r.version + "/bin/php -m")
|
||||
if err != nil {
|
||||
return extensions
|
||||
}
|
||||
|
||||
rawExtensionList := strings.Split(raw, "\n")
|
||||
for _, item := range rawExtensionList {
|
||||
if !strings.Contains(item, "[") && item != "" {
|
||||
for i := range extensions {
|
||||
|
||||
@@ -36,16 +36,12 @@ func (r *Php80Controller) Status(ctx http.Context) http.Response {
|
||||
return check
|
||||
}
|
||||
|
||||
status := tools.Exec("systemctl status php-fpm-" + r.version + " | grep Active | grep -v grep | awk '{print $2}'")
|
||||
if len(status) == 0 {
|
||||
status, err := tools.ServiceStatus("php-fpm-" + r.version)
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取PHP-"+r.version+"运行状态失败")
|
||||
}
|
||||
|
||||
if status == "active" {
|
||||
return controllers.Success(ctx, true)
|
||||
} else {
|
||||
return controllers.Success(ctx, false)
|
||||
}
|
||||
return controllers.Success(ctx, status)
|
||||
}
|
||||
|
||||
func (r *Php80Controller) Reload(ctx http.Context) http.Response {
|
||||
@@ -54,18 +50,11 @@ func (r *Php80Controller) Reload(ctx http.Context) http.Response {
|
||||
return check
|
||||
}
|
||||
|
||||
tools.Exec("systemctl reload php-fpm-" + r.version)
|
||||
out := tools.Exec("systemctl status php-fpm-" + r.version + " | grep Active | grep -v grep | awk '{print $2}'")
|
||||
status := strings.TrimSpace(out)
|
||||
if len(status) == 0 {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取PHP-"+r.version+"运行状态失败")
|
||||
if err := tools.ServiceReload("php-fpm-" + r.version); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "重载PHP-"+r.version+"失败")
|
||||
}
|
||||
|
||||
if status == "active" {
|
||||
return controllers.Success(ctx, true)
|
||||
} else {
|
||||
return controllers.Success(ctx, false)
|
||||
}
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
func (r *Php80Controller) Start(ctx http.Context) http.Response {
|
||||
@@ -74,18 +63,11 @@ func (r *Php80Controller) Start(ctx http.Context) http.Response {
|
||||
return check
|
||||
}
|
||||
|
||||
tools.Exec("systemctl start php-fpm-" + r.version)
|
||||
out := tools.Exec("systemctl status php-fpm-" + r.version + " | grep Active | grep -v grep | awk '{print $2}'")
|
||||
status := strings.TrimSpace(out)
|
||||
if len(status) == 0 {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取PHP-"+r.version+"运行状态失败")
|
||||
if err := tools.ServiceStart("php-fpm-" + r.version); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "启动PHP-"+r.version+"失败")
|
||||
}
|
||||
|
||||
if status == "active" {
|
||||
return controllers.Success(ctx, true)
|
||||
} else {
|
||||
return controllers.Success(ctx, false)
|
||||
}
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
func (r *Php80Controller) Stop(ctx http.Context) http.Response {
|
||||
@@ -94,18 +76,11 @@ func (r *Php80Controller) Stop(ctx http.Context) http.Response {
|
||||
return check
|
||||
}
|
||||
|
||||
tools.Exec("systemctl stop php-fpm-" + r.version)
|
||||
out := tools.Exec("systemctl status php-fpm-" + r.version + " | grep Active | grep -v grep | awk '{print $2}'")
|
||||
status := strings.TrimSpace(out)
|
||||
if len(status) == 0 {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取PHP-"+r.version+"运行状态失败")
|
||||
if err := tools.ServiceStop("php-fpm-" + r.version); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "停止PHP-"+r.version+"失败")
|
||||
}
|
||||
|
||||
if status != "active" {
|
||||
return controllers.Success(ctx, true)
|
||||
} else {
|
||||
return controllers.Success(ctx, false)
|
||||
}
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
func (r *Php80Controller) Restart(ctx http.Context) http.Response {
|
||||
@@ -114,18 +89,11 @@ func (r *Php80Controller) Restart(ctx http.Context) http.Response {
|
||||
return check
|
||||
}
|
||||
|
||||
tools.Exec("systemctl restart php-fpm-" + r.version)
|
||||
out := tools.Exec("systemctl status php-fpm-" + r.version + " | grep Active | grep -v grep | awk '{print $2}'")
|
||||
status := strings.TrimSpace(out)
|
||||
if len(status) == 0 {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取PHP-"+r.version+"运行状态失败")
|
||||
if err := tools.ServiceRestart("php-fpm-" + r.version); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "重启PHP-"+r.version+"失败")
|
||||
}
|
||||
|
||||
if status == "active" {
|
||||
return controllers.Success(ctx, true)
|
||||
} else {
|
||||
return controllers.Success(ctx, false)
|
||||
}
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
func (r *Php80Controller) GetConfig(ctx http.Context) http.Response {
|
||||
@@ -193,7 +161,11 @@ func (r *Php80Controller) ErrorLog(ctx http.Context) http.Response {
|
||||
return check
|
||||
}
|
||||
|
||||
log := tools.Escape(tools.Exec("tail -n 100 /www/server/php/" + r.version + "/var/log/php-fpm.log"))
|
||||
log, err := tools.Exec("tail -n 100 /www/server/php/" + r.version + "/var/log/php-fpm.log")
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, log)
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, log)
|
||||
}
|
||||
|
||||
@@ -203,7 +175,11 @@ func (r *Php80Controller) SlowLog(ctx http.Context) http.Response {
|
||||
return check
|
||||
}
|
||||
|
||||
log := tools.Escape(tools.Exec("tail -n 100 /www/server/php/" + r.version + "/var/log/slow.log"))
|
||||
log, err := tools.Exec("tail -n 100 /www/server/php/" + r.version + "/var/log/slow.log")
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, log)
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, log)
|
||||
}
|
||||
|
||||
@@ -213,8 +189,11 @@ func (r *Php80Controller) ClearErrorLog(ctx http.Context) http.Response {
|
||||
return check
|
||||
}
|
||||
|
||||
tools.Exec("echo '' > /www/server/php/" + r.version + "/var/log/php-fpm.log")
|
||||
return controllers.Success(ctx, true)
|
||||
if out, err := tools.Exec("echo '' > /www/server/php/" + r.version + "/var/log/php-fpm.log"); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
func (r *Php80Controller) ClearSlowLog(ctx http.Context) http.Response {
|
||||
@@ -223,8 +202,10 @@ func (r *Php80Controller) ClearSlowLog(ctx http.Context) http.Response {
|
||||
return check
|
||||
}
|
||||
|
||||
tools.Exec("echo '' > /www/server/php/" + r.version + "/var/log/slow.log")
|
||||
return controllers.Success(ctx, true)
|
||||
if out, err := tools.Exec("echo '' > /www/server/php/" + r.version + "/var/log/slow.log"); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
func (r *Php80Controller) GetExtensionList(ctx http.Context) http.Response {
|
||||
@@ -350,9 +331,12 @@ func (r *Php80Controller) GetExtensions() []PHPExtension {
|
||||
Installed: false,
|
||||
})
|
||||
|
||||
raw := tools.Exec("/www/server/php/" + r.version + "/bin/php -m")
|
||||
rawExtensionList := strings.Split(raw, "\n")
|
||||
raw, err := tools.Exec("/www/server/php/" + r.version + "/bin/php -m")
|
||||
if err != nil {
|
||||
return extensions
|
||||
}
|
||||
|
||||
rawExtensionList := strings.Split(raw, "\n")
|
||||
for _, item := range rawExtensionList {
|
||||
if !strings.Contains(item, "[") && item != "" {
|
||||
for i := range extensions {
|
||||
|
||||
@@ -36,16 +36,12 @@ func (r *Php81Controller) Status(ctx http.Context) http.Response {
|
||||
return check
|
||||
}
|
||||
|
||||
status := tools.Exec("systemctl status php-fpm-" + r.version + " | grep Active | grep -v grep | awk '{print $2}'")
|
||||
if len(status) == 0 {
|
||||
status, err := tools.ServiceStatus("php-fpm-" + r.version)
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取PHP-"+r.version+"运行状态失败")
|
||||
}
|
||||
|
||||
if status == "active" {
|
||||
return controllers.Success(ctx, true)
|
||||
} else {
|
||||
return controllers.Success(ctx, false)
|
||||
}
|
||||
return controllers.Success(ctx, status)
|
||||
}
|
||||
|
||||
func (r *Php81Controller) Reload(ctx http.Context) http.Response {
|
||||
@@ -54,18 +50,11 @@ func (r *Php81Controller) Reload(ctx http.Context) http.Response {
|
||||
return check
|
||||
}
|
||||
|
||||
tools.Exec("systemctl reload php-fpm-" + r.version)
|
||||
out := tools.Exec("systemctl status php-fpm-" + r.version + " | grep Active | grep -v grep | awk '{print $2}'")
|
||||
status := strings.TrimSpace(out)
|
||||
if len(status) == 0 {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取PHP-"+r.version+"运行状态失败")
|
||||
if err := tools.ServiceReload("php-fpm-" + r.version); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "重载PHP-"+r.version+"失败")
|
||||
}
|
||||
|
||||
if status == "active" {
|
||||
return controllers.Success(ctx, true)
|
||||
} else {
|
||||
return controllers.Success(ctx, false)
|
||||
}
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
func (r *Php81Controller) Start(ctx http.Context) http.Response {
|
||||
@@ -74,18 +63,11 @@ func (r *Php81Controller) Start(ctx http.Context) http.Response {
|
||||
return check
|
||||
}
|
||||
|
||||
tools.Exec("systemctl start php-fpm-" + r.version)
|
||||
out := tools.Exec("systemctl status php-fpm-" + r.version + " | grep Active | grep -v grep | awk '{print $2}'")
|
||||
status := strings.TrimSpace(out)
|
||||
if len(status) == 0 {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取PHP-"+r.version+"运行状态失败")
|
||||
if err := tools.ServiceStart("php-fpm-" + r.version); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "启动PHP-"+r.version+"失败")
|
||||
}
|
||||
|
||||
if status == "active" {
|
||||
return controllers.Success(ctx, true)
|
||||
} else {
|
||||
return controllers.Success(ctx, false)
|
||||
}
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
func (r *Php81Controller) Stop(ctx http.Context) http.Response {
|
||||
@@ -94,18 +76,11 @@ func (r *Php81Controller) Stop(ctx http.Context) http.Response {
|
||||
return check
|
||||
}
|
||||
|
||||
tools.Exec("systemctl stop php-fpm-" + r.version)
|
||||
out := tools.Exec("systemctl status php-fpm-" + r.version + " | grep Active | grep -v grep | awk '{print $2}'")
|
||||
status := strings.TrimSpace(out)
|
||||
if len(status) == 0 {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取PHP-"+r.version+"运行状态失败")
|
||||
if err := tools.ServiceStop("php-fpm-" + r.version); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "停止PHP-"+r.version+"失败")
|
||||
}
|
||||
|
||||
if status != "active" {
|
||||
return controllers.Success(ctx, true)
|
||||
} else {
|
||||
return controllers.Success(ctx, false)
|
||||
}
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
func (r *Php81Controller) Restart(ctx http.Context) http.Response {
|
||||
@@ -114,18 +89,11 @@ func (r *Php81Controller) Restart(ctx http.Context) http.Response {
|
||||
return check
|
||||
}
|
||||
|
||||
tools.Exec("systemctl restart php-fpm-" + r.version)
|
||||
out := tools.Exec("systemctl status php-fpm-" + r.version + " | grep Active | grep -v grep | awk '{print $2}'")
|
||||
status := strings.TrimSpace(out)
|
||||
if len(status) == 0 {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取PHP-"+r.version+"运行状态失败")
|
||||
if err := tools.ServiceRestart("php-fpm-" + r.version); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "重启PHP-"+r.version+"失败")
|
||||
}
|
||||
|
||||
if status == "active" {
|
||||
return controllers.Success(ctx, true)
|
||||
} else {
|
||||
return controllers.Success(ctx, false)
|
||||
}
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
func (r *Php81Controller) GetConfig(ctx http.Context) http.Response {
|
||||
@@ -193,7 +161,11 @@ func (r *Php81Controller) ErrorLog(ctx http.Context) http.Response {
|
||||
return check
|
||||
}
|
||||
|
||||
log := tools.Escape(tools.Exec("tail -n 100 /www/server/php/" + r.version + "/var/log/php-fpm.log"))
|
||||
log, err := tools.Exec("tail -n 100 /www/server/php/" + r.version + "/var/log/php-fpm.log")
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, log)
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, log)
|
||||
}
|
||||
|
||||
@@ -203,7 +175,11 @@ func (r *Php81Controller) SlowLog(ctx http.Context) http.Response {
|
||||
return check
|
||||
}
|
||||
|
||||
log := tools.Escape(tools.Exec("tail -n 100 /www/server/php/" + r.version + "/var/log/slow.log"))
|
||||
log, err := tools.Exec("tail -n 100 /www/server/php/" + r.version + "/var/log/slow.log")
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, log)
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, log)
|
||||
}
|
||||
|
||||
@@ -213,8 +189,11 @@ func (r *Php81Controller) ClearErrorLog(ctx http.Context) http.Response {
|
||||
return check
|
||||
}
|
||||
|
||||
tools.Exec("echo '' > /www/server/php/" + r.version + "/var/log/php-fpm.log")
|
||||
return controllers.Success(ctx, true)
|
||||
if out, err := tools.Exec("echo '' > /www/server/php/" + r.version + "/var/log/php-fpm.log"); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
func (r *Php81Controller) ClearSlowLog(ctx http.Context) http.Response {
|
||||
@@ -223,8 +202,10 @@ func (r *Php81Controller) ClearSlowLog(ctx http.Context) http.Response {
|
||||
return check
|
||||
}
|
||||
|
||||
tools.Exec("echo '' > /www/server/php/" + r.version + "/var/log/slow.log")
|
||||
return controllers.Success(ctx, true)
|
||||
if out, err := tools.Exec("echo '' > /www/server/php/" + r.version + "/var/log/slow.log"); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
func (r *Php81Controller) GetExtensionList(ctx http.Context) http.Response {
|
||||
@@ -350,9 +331,12 @@ func (r *Php81Controller) GetExtensions() []PHPExtension {
|
||||
Installed: false,
|
||||
})
|
||||
|
||||
raw := tools.Exec("/www/server/php/" + r.version + "/bin/php -m")
|
||||
rawExtensionList := strings.Split(raw, "\n")
|
||||
raw, err := tools.Exec("/www/server/php/" + r.version + "/bin/php -m")
|
||||
if err != nil {
|
||||
return extensions
|
||||
}
|
||||
|
||||
rawExtensionList := strings.Split(raw, "\n")
|
||||
for _, item := range rawExtensionList {
|
||||
if !strings.Contains(item, "[") && item != "" {
|
||||
for i := range extensions {
|
||||
|
||||
@@ -36,16 +36,12 @@ func (r *Php82Controller) Status(ctx http.Context) http.Response {
|
||||
return check
|
||||
}
|
||||
|
||||
status := tools.Exec("systemctl status php-fpm-" + r.version + " | grep Active | grep -v grep | awk '{print $2}'")
|
||||
if len(status) == 0 {
|
||||
status, err := tools.ServiceStatus("php-fpm-" + r.version)
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取PHP-"+r.version+"运行状态失败")
|
||||
}
|
||||
|
||||
if status == "active" {
|
||||
return controllers.Success(ctx, true)
|
||||
} else {
|
||||
return controllers.Success(ctx, false)
|
||||
}
|
||||
return controllers.Success(ctx, status)
|
||||
}
|
||||
|
||||
func (r *Php82Controller) Reload(ctx http.Context) http.Response {
|
||||
@@ -54,18 +50,11 @@ func (r *Php82Controller) Reload(ctx http.Context) http.Response {
|
||||
return check
|
||||
}
|
||||
|
||||
tools.Exec("systemctl reload php-fpm-" + r.version)
|
||||
out := tools.Exec("systemctl status php-fpm-" + r.version + " | grep Active | grep -v grep | awk '{print $2}'")
|
||||
status := strings.TrimSpace(out)
|
||||
if len(status) == 0 {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取PHP-"+r.version+"运行状态失败")
|
||||
if err := tools.ServiceReload("php-fpm-" + r.version); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "重载PHP-"+r.version+"失败")
|
||||
}
|
||||
|
||||
if status == "active" {
|
||||
return controllers.Success(ctx, true)
|
||||
} else {
|
||||
return controllers.Success(ctx, false)
|
||||
}
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
func (r *Php82Controller) Start(ctx http.Context) http.Response {
|
||||
@@ -74,18 +63,11 @@ func (r *Php82Controller) Start(ctx http.Context) http.Response {
|
||||
return check
|
||||
}
|
||||
|
||||
tools.Exec("systemctl start php-fpm-" + r.version)
|
||||
out := tools.Exec("systemctl status php-fpm-" + r.version + " | grep Active | grep -v grep | awk '{print $2}'")
|
||||
status := strings.TrimSpace(out)
|
||||
if len(status) == 0 {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取PHP-"+r.version+"运行状态失败")
|
||||
if err := tools.ServiceStart("php-fpm-" + r.version); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "启动PHP-"+r.version+"失败")
|
||||
}
|
||||
|
||||
if status == "active" {
|
||||
return controllers.Success(ctx, true)
|
||||
} else {
|
||||
return controllers.Success(ctx, false)
|
||||
}
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
func (r *Php82Controller) Stop(ctx http.Context) http.Response {
|
||||
@@ -94,18 +76,11 @@ func (r *Php82Controller) Stop(ctx http.Context) http.Response {
|
||||
return check
|
||||
}
|
||||
|
||||
tools.Exec("systemctl stop php-fpm-" + r.version)
|
||||
out := tools.Exec("systemctl status php-fpm-" + r.version + " | grep Active | grep -v grep | awk '{print $2}'")
|
||||
status := strings.TrimSpace(out)
|
||||
if len(status) == 0 {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取PHP-"+r.version+"运行状态失败")
|
||||
if err := tools.ServiceStop("php-fpm-" + r.version); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "停止PHP-"+r.version+"失败")
|
||||
}
|
||||
|
||||
if status != "active" {
|
||||
return controllers.Success(ctx, true)
|
||||
} else {
|
||||
return controllers.Success(ctx, false)
|
||||
}
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
func (r *Php82Controller) Restart(ctx http.Context) http.Response {
|
||||
@@ -114,18 +89,11 @@ func (r *Php82Controller) Restart(ctx http.Context) http.Response {
|
||||
return check
|
||||
}
|
||||
|
||||
tools.Exec("systemctl restart php-fpm-" + r.version)
|
||||
out := tools.Exec("systemctl status php-fpm-" + r.version + " | grep Active | grep -v grep | awk '{print $2}'")
|
||||
status := strings.TrimSpace(out)
|
||||
if len(status) == 0 {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取PHP-"+r.version+"运行状态失败")
|
||||
if err := tools.ServiceRestart("php-fpm-" + r.version); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "重启PHP-"+r.version+"失败")
|
||||
}
|
||||
|
||||
if status == "active" {
|
||||
return controllers.Success(ctx, true)
|
||||
} else {
|
||||
return controllers.Success(ctx, false)
|
||||
}
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
func (r *Php82Controller) GetConfig(ctx http.Context) http.Response {
|
||||
@@ -193,7 +161,11 @@ func (r *Php82Controller) ErrorLog(ctx http.Context) http.Response {
|
||||
return check
|
||||
}
|
||||
|
||||
log := tools.Escape(tools.Exec("tail -n 100 /www/server/php/" + r.version + "/var/log/php-fpm.log"))
|
||||
log, err := tools.Exec("tail -n 100 /www/server/php/" + r.version + "/var/log/php-fpm.log")
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, log)
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, log)
|
||||
}
|
||||
|
||||
@@ -203,7 +175,11 @@ func (r *Php82Controller) SlowLog(ctx http.Context) http.Response {
|
||||
return check
|
||||
}
|
||||
|
||||
log := tools.Escape(tools.Exec("tail -n 100 /www/server/php/" + r.version + "/var/log/slow.log"))
|
||||
log, err := tools.Exec("tail -n 100 /www/server/php/" + r.version + "/var/log/slow.log")
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, log)
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, log)
|
||||
}
|
||||
|
||||
@@ -213,8 +189,11 @@ func (r *Php82Controller) ClearErrorLog(ctx http.Context) http.Response {
|
||||
return check
|
||||
}
|
||||
|
||||
tools.Exec("echo '' > /www/server/php/" + r.version + "/var/log/php-fpm.log")
|
||||
return controllers.Success(ctx, true)
|
||||
if out, err := tools.Exec("echo '' > /www/server/php/" + r.version + "/var/log/php-fpm.log"); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
func (r *Php82Controller) ClearSlowLog(ctx http.Context) http.Response {
|
||||
@@ -223,8 +202,10 @@ func (r *Php82Controller) ClearSlowLog(ctx http.Context) http.Response {
|
||||
return check
|
||||
}
|
||||
|
||||
tools.Exec("echo '' > /www/server/php/" + r.version + "/var/log/slow.log")
|
||||
return controllers.Success(ctx, true)
|
||||
if out, err := tools.Exec("echo '' > /www/server/php/" + r.version + "/var/log/slow.log"); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
func (r *Php82Controller) GetExtensionList(ctx http.Context) http.Response {
|
||||
@@ -344,9 +325,12 @@ func (r *Php82Controller) GetExtensions() []PHPExtension {
|
||||
Installed: false,
|
||||
})
|
||||
|
||||
raw := tools.Exec("/www/server/php/" + r.version + "/bin/php -m")
|
||||
rawExtensionList := strings.Split(raw, "\n")
|
||||
raw, err := tools.Exec("/www/server/php/" + r.version + "/bin/php -m")
|
||||
if err != nil {
|
||||
return extensions
|
||||
}
|
||||
|
||||
rawExtensionList := strings.Split(raw, "\n")
|
||||
for _, item := range rawExtensionList {
|
||||
if !strings.Contains(item, "[") && item != "" {
|
||||
for i := range extensions {
|
||||
|
||||
@@ -28,7 +28,7 @@ func (r *PhpMyAdminController) Info(ctx http.Context) http.Response {
|
||||
|
||||
files, err := os.ReadDir("/www/server/phpmyadmin")
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, "找不到 phpMyAdmin 目录")
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "找不到 phpMyAdmin 目录")
|
||||
}
|
||||
|
||||
var phpmyadmin string
|
||||
@@ -38,13 +38,13 @@ func (r *PhpMyAdminController) Info(ctx http.Context) http.Response {
|
||||
}
|
||||
}
|
||||
if len(phpmyadmin) == 0 {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, "找不到 phpMyAdmin 目录")
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "找不到 phpMyAdmin 目录")
|
||||
}
|
||||
|
||||
conf := tools.Read("/www/server/vhost/phpmyadmin.conf")
|
||||
match := regexp.MustCompile(`listen\s+(\d+);`).FindStringSubmatch(conf)
|
||||
if len(match) == 0 {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, "找不到 phpMyAdmin 端口")
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "找不到 phpMyAdmin 端口")
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, http.Json{
|
||||
@@ -61,7 +61,7 @@ func (r *PhpMyAdminController) SetPort(ctx http.Context) http.Response {
|
||||
|
||||
port := ctx.Request().Input("port")
|
||||
if len(port) == 0 {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, "端口不能为空")
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "端口不能为空")
|
||||
}
|
||||
|
||||
conf := tools.Read("/www/server/vhost/phpmyadmin.conf")
|
||||
@@ -74,13 +74,25 @@ func (r *PhpMyAdminController) SetPort(ctx http.Context) http.Response {
|
||||
}
|
||||
|
||||
if tools.IsRHEL() {
|
||||
tools.Exec("firewall-cmd --zone=public --add-port=" + port + "/tcp --permanent")
|
||||
tools.Exec("firewall-cmd --reload")
|
||||
if out, err := tools.Exec("firewall-cmd --zone=public --add-port=" + port + "/tcp --permanent"); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
if out, err := tools.Exec("firewall-cmd --reload"); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
} else {
|
||||
tools.Exec("ufw allow " + port + "/tcp")
|
||||
tools.Exec("ufw reload")
|
||||
if out, err := tools.Exec("ufw allow " + port + "/tcp"); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
if out, err := tools.Exec("ufw reload"); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
}
|
||||
|
||||
err := tools.ServiceReload("openresty")
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "重载OpenResty失败")
|
||||
}
|
||||
tools.Exec("systemctl reload openresty")
|
||||
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
@@ -4,7 +4,6 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/goravel/framework/contracts/http"
|
||||
"github.com/goravel/framework/facades"
|
||||
"github.com/goravel/framework/support/carbon"
|
||||
|
||||
"panel/app/http/controllers"
|
||||
@@ -32,16 +31,12 @@ func (r *Postgresql15Controller) Status(ctx http.Context) http.Response {
|
||||
return check
|
||||
}
|
||||
|
||||
status := tools.Exec("systemctl status postgresql | grep Active | grep -v grep | awk '{print $2}'")
|
||||
if len(status) == 0 {
|
||||
status, err := tools.ServiceStatus("postgresql")
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取PostgreSQL状态失败")
|
||||
}
|
||||
|
||||
if status == "active" {
|
||||
return controllers.Success(ctx, true)
|
||||
} else {
|
||||
return controllers.Success(ctx, false)
|
||||
}
|
||||
return controllers.Success(ctx, status)
|
||||
}
|
||||
|
||||
// Reload 重载配置
|
||||
@@ -51,17 +46,11 @@ func (r *Postgresql15Controller) Reload(ctx http.Context) http.Response {
|
||||
return check
|
||||
}
|
||||
|
||||
tools.Exec("systemctl reload postgresql")
|
||||
status := tools.Exec("systemctl status postgresql | grep Active | grep -v grep | awk '{print $2}'")
|
||||
if len(status) == 0 {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取PostgreSQL状态失败")
|
||||
if err := tools.ServiceReload("postgresql"); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "重载PostgreSQL失败")
|
||||
}
|
||||
|
||||
if status == "active" {
|
||||
return controllers.Success(ctx, true)
|
||||
} else {
|
||||
return controllers.Success(ctx, false)
|
||||
}
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// Restart 重启服务
|
||||
@@ -71,17 +60,11 @@ func (r *Postgresql15Controller) Restart(ctx http.Context) http.Response {
|
||||
return check
|
||||
}
|
||||
|
||||
tools.Exec("systemctl restart postgresql")
|
||||
status := tools.Exec("systemctl status postgresql | grep Active | grep -v grep | awk '{print $2}'")
|
||||
if len(status) == 0 {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取PostgreSQL状态失败")
|
||||
if err := tools.ServiceRestart("postgresql"); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "重启PostgreSQL失败")
|
||||
}
|
||||
|
||||
if status == "active" {
|
||||
return controllers.Success(ctx, true)
|
||||
} else {
|
||||
return controllers.Success(ctx, false)
|
||||
}
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// Start 启动服务
|
||||
@@ -91,17 +74,11 @@ func (r *Postgresql15Controller) Start(ctx http.Context) http.Response {
|
||||
return check
|
||||
}
|
||||
|
||||
tools.Exec("systemctl start postgresql")
|
||||
status := tools.Exec("systemctl status postgresql | grep Active | grep -v grep | awk '{print $2}'")
|
||||
if len(status) == 0 {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取PostgreSQL状态失败")
|
||||
if err := tools.ServiceStart("postgresql"); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "启动PostgreSQL失败")
|
||||
}
|
||||
|
||||
if status == "active" {
|
||||
return controllers.Success(ctx, true)
|
||||
} else {
|
||||
return controllers.Success(ctx, false)
|
||||
}
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// Stop 停止服务
|
||||
@@ -111,17 +88,11 @@ func (r *Postgresql15Controller) Stop(ctx http.Context) http.Response {
|
||||
return check
|
||||
}
|
||||
|
||||
tools.Exec("systemctl stop postgresql")
|
||||
status := tools.Exec("systemctl status postgresql | grep Active | grep -v grep | awk '{print $2}'")
|
||||
if len(status) == 0 {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取PostgreSQL状态失败")
|
||||
if err := tools.ServiceStop("postgresql"); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "停止PostgreSQL失败")
|
||||
}
|
||||
|
||||
if status != "active" {
|
||||
return controllers.Success(ctx, true)
|
||||
} else {
|
||||
return controllers.Success(ctx, false)
|
||||
}
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// GetConfig 获取配置
|
||||
@@ -201,17 +172,41 @@ func (r *Postgresql15Controller) Load(ctx http.Context) http.Response {
|
||||
return check
|
||||
}
|
||||
|
||||
status := tools.Exec("systemctl status postgresql | grep Active | grep -v grep | awk '{print $2}'")
|
||||
if status != "active" {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "PostgreSQL 已停止运行")
|
||||
status, err := tools.ServiceStatus("postgresql")
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取PostgreSQL状态失败")
|
||||
}
|
||||
if !status {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "PostgreSQL已停止运行")
|
||||
}
|
||||
|
||||
time, err := tools.Exec(`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`)
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取PostgreSQL进程PID失败")
|
||||
}
|
||||
process, err := tools.Exec(`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`)
|
||||
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`)
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取PostgreSQL空间占用失败")
|
||||
}
|
||||
|
||||
data := []LoadInfo{
|
||||
{"启动时间", carbon.Parse(tools.Exec(`echo "select pg_postmaster_start_time();" | su - postgres -c "psql" | sed -n 3p | cut -d'.' -f1`)).ToDateTimeString()},
|
||||
{"进程 PID", tools.Exec(`echo "select pg_backend_pid();" | su - postgres -c "psql" | sed -n 3p`)},
|
||||
{"进程数", tools.Exec(`ps aux | grep postgres | grep -v grep | wc -l`)},
|
||||
{"总连接数", tools.Exec(`echo "SELECT count(*) FROM pg_stat_activity WHERE NOT pid=pg_backend_pid();" | su - postgres -c "psql" | sed -n 3p`)},
|
||||
{"空间占用", tools.Exec(`echo "select pg_size_pretty(pg_database_size('postgres'));" | su - postgres -c "psql" | sed -n 3p`)},
|
||||
{"启动时间", carbon.Parse(time).ToDateTimeString()},
|
||||
{"进程 PID", pid},
|
||||
{"进程数", process},
|
||||
{"总连接数", connections},
|
||||
{"空间占用", storage},
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, data)
|
||||
@@ -224,7 +219,11 @@ func (r *Postgresql15Controller) Log(ctx http.Context) http.Response {
|
||||
return check
|
||||
}
|
||||
|
||||
log := tools.Exec("tail -n 100 /www/server/postgresql/logs/postgresql-" + carbon.Now().ToDateString() + ".log")
|
||||
log, err := tools.Exec("tail -n 100 /www/server/postgresql/logs/postgresql-" + carbon.Now().ToDateString() + ".log")
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, log)
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, log)
|
||||
}
|
||||
|
||||
@@ -235,7 +234,10 @@ func (r *Postgresql15Controller) ClearLog(ctx http.Context) http.Response {
|
||||
return check
|
||||
}
|
||||
|
||||
tools.Exec("echo '' > /www/server/postgresql/logs/postgresql-" + carbon.Now().ToDateString() + ".log")
|
||||
if out, err := tools.Exec("echo '' > /www/server/postgresql/logs/postgresql-" + carbon.Now().ToDateString() + ".log"); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
@@ -246,9 +248,12 @@ func (r *Postgresql15Controller) DatabaseList(ctx http.Context) http.Response {
|
||||
return check
|
||||
}
|
||||
|
||||
status := tools.Exec("systemctl status postgresql | grep Active | grep -v grep | awk '{print $2}'")
|
||||
if status != "active" {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "PostgreSQL 已停止运行")
|
||||
status, err := tools.ServiceStatus("postgresql")
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取PostgreSQL状态失败")
|
||||
}
|
||||
if !status {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "PostgreSQL已停止运行")
|
||||
}
|
||||
|
||||
type database struct {
|
||||
@@ -257,7 +262,10 @@ func (r *Postgresql15Controller) DatabaseList(ctx http.Context) http.Response {
|
||||
Encoding string `json:"encoding"`
|
||||
}
|
||||
|
||||
raw := tools.Exec(`echo "\l" | su - postgres -c "psql"`)
|
||||
raw, err := tools.Exec(`echo "\l" | su - postgres -c "psql"`)
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, raw)
|
||||
}
|
||||
databases := strings.Split(raw, "\n")
|
||||
if len(databases) >= 4 {
|
||||
databases = databases[3 : len(databases)-1]
|
||||
@@ -326,13 +334,23 @@ func (r *Postgresql15Controller) AddDatabase(ctx http.Context) http.Response {
|
||||
user := ctx.Request().Input("user")
|
||||
password := ctx.Request().Input("password")
|
||||
|
||||
tools.Exec(`echo "CREATE DATABASE ` + database + `;" | su - postgres -c "psql"`)
|
||||
tools.Exec(`echo "CREATE USER ` + user + ` WITH PASSWORD '` + password + `';" | su - postgres -c "psql"`)
|
||||
tools.Exec(`echo "ALTER DATABASE ` + database + ` OWNER TO ` + user + `;" | su - postgres -c "psql"`)
|
||||
tools.Exec(`echo "GRANT ALL PRIVILEGES ON DATABASE ` + database + ` TO ` + user + `;" | su - postgres -c "psql"`)
|
||||
if out, err := tools.Exec(`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 {
|
||||
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 {
|
||||
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 {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
|
||||
userConfig := "host " + database + " " + user + " 127.0.0.1/32 scram-sha-256"
|
||||
tools.Exec(`echo "` + userConfig + `" >> /www/server/postgresql/data/pg_hba.conf`)
|
||||
if out, err := tools.Exec(`echo "` + userConfig + `" >> /www/server/postgresql/data/pg_hba.conf`); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
|
||||
return r.Reload(ctx)
|
||||
}
|
||||
@@ -355,7 +373,9 @@ func (r *Postgresql15Controller) DeleteDatabase(ctx http.Context) http.Response
|
||||
}
|
||||
|
||||
database := ctx.Request().Input("database")
|
||||
tools.Exec(`echo "DROP DATABASE ` + database + `;" | su - postgres -c "psql"`)
|
||||
if out, err := tools.Exec(`echo "DROP DATABASE ` + database + `;" | su - postgres -c "psql"`); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
@@ -369,7 +389,6 @@ func (r *Postgresql15Controller) BackupList(ctx http.Context) http.Response {
|
||||
|
||||
backupList, err := r.backup.PostgresqlList()
|
||||
if err != nil {
|
||||
facades.Log().Info("[PostgreSQL] 获取备份列表失败:" + err.Error())
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取备份列表失败")
|
||||
}
|
||||
|
||||
@@ -445,8 +464,7 @@ func (r *Postgresql15Controller) CreateBackup(ctx http.Context) http.Response {
|
||||
database := ctx.Request().Input("database")
|
||||
err = r.backup.PostgresqlBackup(database)
|
||||
if err != nil {
|
||||
facades.Log().Info("[PostgreSQL] 创建备份失败:" + err.Error())
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "创建备份失败")
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, nil)
|
||||
@@ -496,7 +514,6 @@ func (r *Postgresql15Controller) RestoreBackup(ctx http.Context) http.Response {
|
||||
|
||||
err = r.backup.PostgresqlRestore(ctx.Request().Input("database"), ctx.Request().Input("backup"))
|
||||
if err != nil {
|
||||
facades.Log().Info("[PostgreSQL] 还原失败:" + err.Error())
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "还原失败: "+err.Error())
|
||||
}
|
||||
|
||||
@@ -515,7 +532,10 @@ func (r *Postgresql15Controller) UserList(ctx http.Context) http.Response {
|
||||
Role string `json:"role"`
|
||||
}
|
||||
|
||||
raw := tools.Exec(`echo "\du" | su - postgres -c "psql"`)
|
||||
raw, err := tools.Exec(`echo "\du" | su - postgres -c "psql"`)
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, raw)
|
||||
}
|
||||
users := strings.Split(raw, "\n")
|
||||
if len(users) < 4 {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "用户列表为空")
|
||||
@@ -578,11 +598,17 @@ func (r *Postgresql15Controller) AddUser(ctx http.Context) http.Response {
|
||||
user := ctx.Request().Input("user")
|
||||
password := ctx.Request().Input("password")
|
||||
database := ctx.Request().Input("database")
|
||||
tools.Exec(`echo "CREATE USER ` + user + ` WITH PASSWORD '` + password + `';" | su - postgres -c "psql"`)
|
||||
tools.Exec(`echo "GRANT ALL PRIVILEGES ON DATABASE ` + database + ` TO ` + user + `;" | su - postgres -c "psql"`)
|
||||
if out, err := tools.Exec(`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 {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
|
||||
userConfig := "host " + database + " " + user + " 127.0.0.1/32 scram-sha-256"
|
||||
tools.Exec(`echo "` + userConfig + `" >> /www/server/postgresql/data/pg_hba.conf`)
|
||||
if out, err := tools.Exec(`echo "` + userConfig + `" >> /www/server/postgresql/data/pg_hba.conf`); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
|
||||
return r.Reload(ctx)
|
||||
}
|
||||
@@ -605,8 +631,12 @@ func (r *Postgresql15Controller) DeleteUser(ctx http.Context) http.Response {
|
||||
}
|
||||
|
||||
user := ctx.Request().Input("user")
|
||||
tools.Exec(`echo "DROP USER ` + user + `;" | su - postgres -c "psql"`)
|
||||
tools.Exec(`sed -i '/` + user + `/d' /www/server/postgresql/data/pg_hba.conf`)
|
||||
if out, err := tools.Exec(`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 {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
|
||||
return r.Reload(ctx)
|
||||
}
|
||||
@@ -631,7 +661,9 @@ func (r *Postgresql15Controller) SetUserPassword(ctx http.Context) http.Response
|
||||
|
||||
user := ctx.Request().Input("user")
|
||||
password := ctx.Request().Input("password")
|
||||
tools.Exec(`echo "ALTER USER ` + user + ` WITH PASSWORD '` + password + `';" | su - postgres -c "psql"`)
|
||||
if out, err := tools.Exec(`echo "ALTER USER ` + user + ` WITH PASSWORD '` + password + `';" | su - postgres -c "psql"`); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
@@ -4,7 +4,6 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/goravel/framework/contracts/http"
|
||||
"github.com/goravel/framework/facades"
|
||||
"github.com/goravel/framework/support/carbon"
|
||||
|
||||
"panel/app/http/controllers"
|
||||
@@ -32,16 +31,12 @@ func (r *Postgresql16Controller) Status(ctx http.Context) http.Response {
|
||||
return check
|
||||
}
|
||||
|
||||
status := tools.Exec("systemctl status postgresql | grep Active | grep -v grep | awk '{print $2}'")
|
||||
if len(status) == 0 {
|
||||
status, err := tools.ServiceStatus("postgresql")
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取PostgreSQL状态失败")
|
||||
}
|
||||
|
||||
if status == "active" {
|
||||
return controllers.Success(ctx, true)
|
||||
} else {
|
||||
return controllers.Success(ctx, false)
|
||||
}
|
||||
return controllers.Success(ctx, status)
|
||||
}
|
||||
|
||||
// Reload 重载配置
|
||||
@@ -51,17 +46,11 @@ func (r *Postgresql16Controller) Reload(ctx http.Context) http.Response {
|
||||
return check
|
||||
}
|
||||
|
||||
tools.Exec("systemctl reload postgresql")
|
||||
status := tools.Exec("systemctl status postgresql | grep Active | grep -v grep | awk '{print $2}'")
|
||||
if len(status) == 0 {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取PostgreSQL状态失败")
|
||||
if err := tools.ServiceReload("postgresql"); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "重载PostgreSQL失败")
|
||||
}
|
||||
|
||||
if status == "active" {
|
||||
return controllers.Success(ctx, true)
|
||||
} else {
|
||||
return controllers.Success(ctx, false)
|
||||
}
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// Restart 重启服务
|
||||
@@ -71,17 +60,11 @@ func (r *Postgresql16Controller) Restart(ctx http.Context) http.Response {
|
||||
return check
|
||||
}
|
||||
|
||||
tools.Exec("systemctl restart postgresql")
|
||||
status := tools.Exec("systemctl status postgresql | grep Active | grep -v grep | awk '{print $2}'")
|
||||
if len(status) == 0 {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取PostgreSQL状态失败")
|
||||
if err := tools.ServiceRestart("postgresql"); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "重启PostgreSQL失败")
|
||||
}
|
||||
|
||||
if status == "active" {
|
||||
return controllers.Success(ctx, true)
|
||||
} else {
|
||||
return controllers.Success(ctx, false)
|
||||
}
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// Start 启动服务
|
||||
@@ -91,17 +74,11 @@ func (r *Postgresql16Controller) Start(ctx http.Context) http.Response {
|
||||
return check
|
||||
}
|
||||
|
||||
tools.Exec("systemctl start postgresql")
|
||||
status := tools.Exec("systemctl status postgresql | grep Active | grep -v grep | awk '{print $2}'")
|
||||
if len(status) == 0 {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取PostgreSQL状态失败")
|
||||
if err := tools.ServiceStart("postgresql"); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "启动PostgreSQL失败")
|
||||
}
|
||||
|
||||
if status == "active" {
|
||||
return controllers.Success(ctx, true)
|
||||
} else {
|
||||
return controllers.Success(ctx, false)
|
||||
}
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// Stop 停止服务
|
||||
@@ -111,17 +88,11 @@ func (r *Postgresql16Controller) Stop(ctx http.Context) http.Response {
|
||||
return check
|
||||
}
|
||||
|
||||
tools.Exec("systemctl stop postgresql")
|
||||
status := tools.Exec("systemctl status postgresql | grep Active | grep -v grep | awk '{print $2}'")
|
||||
if len(status) == 0 {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取PostgreSQL状态失败")
|
||||
if err := tools.ServiceStop("postgresql"); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "停止PostgreSQL失败")
|
||||
}
|
||||
|
||||
if status != "active" {
|
||||
return controllers.Success(ctx, true)
|
||||
} else {
|
||||
return controllers.Success(ctx, false)
|
||||
}
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// GetConfig 获取配置
|
||||
@@ -201,17 +172,41 @@ func (r *Postgresql16Controller) Load(ctx http.Context) http.Response {
|
||||
return check
|
||||
}
|
||||
|
||||
status := tools.Exec("systemctl status postgresql | grep Active | grep -v grep | awk '{print $2}'")
|
||||
if status != "active" {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "PostgreSQL 已停止运行")
|
||||
status, err := tools.ServiceStatus("postgresql")
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取PostgreSQL状态失败")
|
||||
}
|
||||
if !status {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "PostgreSQL已停止运行")
|
||||
}
|
||||
|
||||
time, err := tools.Exec(`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`)
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取PostgreSQL进程PID失败")
|
||||
}
|
||||
process, err := tools.Exec(`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`)
|
||||
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`)
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取PostgreSQL空间占用失败")
|
||||
}
|
||||
|
||||
data := []LoadInfo{
|
||||
{"启动时间", carbon.Parse(tools.Exec(`echo "select pg_postmaster_start_time();" | su - postgres -c "psql" | sed -n 3p | cut -d'.' -f1`)).ToDateTimeString()},
|
||||
{"进程 PID", tools.Exec(`echo "select pg_backend_pid();" | su - postgres -c "psql" | sed -n 3p`)},
|
||||
{"进程数", tools.Exec(`ps aux | grep postgres | grep -v grep | wc -l`)},
|
||||
{"总连接数", tools.Exec(`echo "SELECT count(*) FROM pg_stat_activity WHERE NOT pid=pg_backend_pid();" | su - postgres -c "psql" | sed -n 3p`)},
|
||||
{"空间占用", tools.Exec(`echo "select pg_size_pretty(pg_database_size('postgres'));" | su - postgres -c "psql" | sed -n 3p`)},
|
||||
{"启动时间", carbon.Parse(time).ToDateTimeString()},
|
||||
{"进程 PID", pid},
|
||||
{"进程数", process},
|
||||
{"总连接数", connections},
|
||||
{"空间占用", storage},
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, data)
|
||||
@@ -224,7 +219,11 @@ func (r *Postgresql16Controller) Log(ctx http.Context) http.Response {
|
||||
return check
|
||||
}
|
||||
|
||||
log := tools.Exec("tail -n 100 /www/server/postgresql/logs/postgresql-" + carbon.Now().ToDateString() + ".log")
|
||||
log, err := tools.Exec("tail -n 100 /www/server/postgresql/logs/postgresql-" + carbon.Now().ToDateString() + ".log")
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, log)
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, log)
|
||||
}
|
||||
|
||||
@@ -235,7 +234,10 @@ func (r *Postgresql16Controller) ClearLog(ctx http.Context) http.Response {
|
||||
return check
|
||||
}
|
||||
|
||||
tools.Exec("echo '' > /www/server/postgresql/logs/postgresql-" + carbon.Now().ToDateString() + ".log")
|
||||
if out, err := tools.Exec("echo '' > /www/server/postgresql/logs/postgresql-" + carbon.Now().ToDateString() + ".log"); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
@@ -246,9 +248,12 @@ func (r *Postgresql16Controller) DatabaseList(ctx http.Context) http.Response {
|
||||
return check
|
||||
}
|
||||
|
||||
status := tools.Exec("systemctl status postgresql | grep Active | grep -v grep | awk '{print $2}'")
|
||||
if status != "active" {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "PostgreSQL 已停止运行")
|
||||
status, err := tools.ServiceStatus("postgresql")
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取PostgreSQL状态失败")
|
||||
}
|
||||
if !status {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "PostgreSQL已停止运行")
|
||||
}
|
||||
|
||||
type database struct {
|
||||
@@ -257,7 +262,10 @@ func (r *Postgresql16Controller) DatabaseList(ctx http.Context) http.Response {
|
||||
Encoding string `json:"encoding"`
|
||||
}
|
||||
|
||||
raw := tools.Exec(`echo "\l" | su - postgres -c "psql"`)
|
||||
raw, err := tools.Exec(`echo "\l" | su - postgres -c "psql"`)
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, raw)
|
||||
}
|
||||
databases := strings.Split(raw, "\n")
|
||||
if len(databases) >= 4 {
|
||||
databases = databases[3 : len(databases)-1]
|
||||
@@ -326,13 +334,23 @@ func (r *Postgresql16Controller) AddDatabase(ctx http.Context) http.Response {
|
||||
user := ctx.Request().Input("user")
|
||||
password := ctx.Request().Input("password")
|
||||
|
||||
tools.Exec(`echo "CREATE DATABASE ` + database + `;" | su - postgres -c "psql"`)
|
||||
tools.Exec(`echo "CREATE USER ` + user + ` WITH PASSWORD '` + password + `';" | su - postgres -c "psql"`)
|
||||
tools.Exec(`echo "ALTER DATABASE ` + database + ` OWNER TO ` + user + `;" | su - postgres -c "psql"`)
|
||||
tools.Exec(`echo "GRANT ALL PRIVILEGES ON DATABASE ` + database + ` TO ` + user + `;" | su - postgres -c "psql"`)
|
||||
if out, err := tools.Exec(`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 {
|
||||
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 {
|
||||
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 {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
|
||||
userConfig := "host " + database + " " + user + " 127.0.0.1/32 scram-sha-256"
|
||||
tools.Exec(`echo "` + userConfig + `" >> /www/server/postgresql/data/pg_hba.conf`)
|
||||
if out, err := tools.Exec(`echo "` + userConfig + `" >> /www/server/postgresql/data/pg_hba.conf`); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
|
||||
return r.Reload(ctx)
|
||||
}
|
||||
@@ -355,7 +373,9 @@ func (r *Postgresql16Controller) DeleteDatabase(ctx http.Context) http.Response
|
||||
}
|
||||
|
||||
database := ctx.Request().Input("database")
|
||||
tools.Exec(`echo "DROP DATABASE ` + database + `;" | su - postgres -c "psql"`)
|
||||
if out, err := tools.Exec(`echo "DROP DATABASE ` + database + `;" | su - postgres -c "psql"`); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
@@ -369,7 +389,6 @@ func (r *Postgresql16Controller) BackupList(ctx http.Context) http.Response {
|
||||
|
||||
backupList, err := r.backup.PostgresqlList()
|
||||
if err != nil {
|
||||
facades.Log().Info("[PostgreSQL] 获取备份列表失败:" + err.Error())
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取备份列表失败")
|
||||
}
|
||||
|
||||
@@ -445,8 +464,7 @@ func (r *Postgresql16Controller) CreateBackup(ctx http.Context) http.Response {
|
||||
database := ctx.Request().Input("database")
|
||||
err = r.backup.PostgresqlBackup(database)
|
||||
if err != nil {
|
||||
facades.Log().Info("[PostgreSQL] 创建备份失败:" + err.Error())
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "创建备份失败")
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, nil)
|
||||
@@ -496,7 +514,6 @@ func (r *Postgresql16Controller) RestoreBackup(ctx http.Context) http.Response {
|
||||
|
||||
err = r.backup.PostgresqlRestore(ctx.Request().Input("database"), ctx.Request().Input("backup"))
|
||||
if err != nil {
|
||||
facades.Log().Info("[PostgreSQL] 还原失败:" + err.Error())
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "还原失败: "+err.Error())
|
||||
}
|
||||
|
||||
@@ -515,7 +532,10 @@ func (r *Postgresql16Controller) UserList(ctx http.Context) http.Response {
|
||||
Role string `json:"role"`
|
||||
}
|
||||
|
||||
raw := tools.Exec(`echo "\du" | su - postgres -c "psql"`)
|
||||
raw, err := tools.Exec(`echo "\du" | su - postgres -c "psql"`)
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, raw)
|
||||
}
|
||||
users := strings.Split(raw, "\n")
|
||||
if len(users) < 4 {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "用户列表为空")
|
||||
@@ -578,11 +598,17 @@ func (r *Postgresql16Controller) AddUser(ctx http.Context) http.Response {
|
||||
user := ctx.Request().Input("user")
|
||||
password := ctx.Request().Input("password")
|
||||
database := ctx.Request().Input("database")
|
||||
tools.Exec(`echo "CREATE USER ` + user + ` WITH PASSWORD '` + password + `';" | su - postgres -c "psql"`)
|
||||
tools.Exec(`echo "GRANT ALL PRIVILEGES ON DATABASE ` + database + ` TO ` + user + `;" | su - postgres -c "psql"`)
|
||||
if out, err := tools.Exec(`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 {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
|
||||
userConfig := "host " + database + " " + user + " 127.0.0.1/32 scram-sha-256"
|
||||
tools.Exec(`echo "` + userConfig + `" >> /www/server/postgresql/data/pg_hba.conf`)
|
||||
if out, err := tools.Exec(`echo "` + userConfig + `" >> /www/server/postgresql/data/pg_hba.conf`); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
|
||||
return r.Reload(ctx)
|
||||
}
|
||||
@@ -605,8 +631,12 @@ func (r *Postgresql16Controller) DeleteUser(ctx http.Context) http.Response {
|
||||
}
|
||||
|
||||
user := ctx.Request().Input("user")
|
||||
tools.Exec(`echo "DROP USER ` + user + `;" | su - postgres -c "psql"`)
|
||||
tools.Exec(`sed -i '/` + user + `/d' /www/server/postgresql/data/pg_hba.conf`)
|
||||
if out, err := tools.Exec(`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 {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
|
||||
return r.Reload(ctx)
|
||||
}
|
||||
@@ -631,7 +661,9 @@ func (r *Postgresql16Controller) SetUserPassword(ctx http.Context) http.Response
|
||||
|
||||
user := ctx.Request().Input("user")
|
||||
password := ctx.Request().Input("password")
|
||||
tools.Exec(`echo "ALTER USER ` + user + ` WITH PASSWORD '` + password + `';" | su - postgres -c "psql"`)
|
||||
if out, err := tools.Exec(`echo "ALTER USER ` + user + ` WITH PASSWORD '` + password + `';" | su - postgres -c "psql"`); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
@@ -30,16 +30,12 @@ func (r *PureFtpdController) Status(ctx http.Context) http.Response {
|
||||
return check
|
||||
}
|
||||
|
||||
status := tools.Exec("systemctl status pure-ftpd | grep Active | grep -v grep | awk '{print $2}'")
|
||||
if len(status) == 0 {
|
||||
status, err := tools.ServiceStatus("pure-ftpd")
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取PureFtpd状态失败")
|
||||
}
|
||||
|
||||
if status == "active" {
|
||||
return controllers.Success(ctx, true)
|
||||
} else {
|
||||
return controllers.Success(ctx, false)
|
||||
}
|
||||
return controllers.Success(ctx, status)
|
||||
}
|
||||
|
||||
// Restart 重启服务
|
||||
@@ -49,17 +45,12 @@ func (r *PureFtpdController) Restart(ctx http.Context) http.Response {
|
||||
return check
|
||||
}
|
||||
|
||||
tools.Exec("systemctl restart pure-ftpd")
|
||||
status := tools.Exec("systemctl status pure-ftpd | grep Active | grep -v grep | awk '{print $2}'")
|
||||
if len(status) == 0 {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取PureFtpd状态失败")
|
||||
err := tools.ServiceRestart("pure-ftpd")
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "重启PureFtpd失败")
|
||||
}
|
||||
|
||||
if status == "active" {
|
||||
return controllers.Success(ctx, true)
|
||||
} else {
|
||||
return controllers.Success(ctx, false)
|
||||
}
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// Start 启动服务
|
||||
@@ -69,17 +60,12 @@ func (r *PureFtpdController) Start(ctx http.Context) http.Response {
|
||||
return check
|
||||
}
|
||||
|
||||
tools.Exec("systemctl start pure-ftpd")
|
||||
status := tools.Exec("systemctl status pure-ftpd | grep Active | grep -v grep | awk '{print $2}'")
|
||||
if len(status) == 0 {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取PureFtpd状态失败")
|
||||
err := tools.ServiceStart("pure-ftpd")
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "启动PureFtpd失败")
|
||||
}
|
||||
|
||||
if status == "active" {
|
||||
return controllers.Success(ctx, true)
|
||||
} else {
|
||||
return controllers.Success(ctx, false)
|
||||
}
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// Stop 停止服务
|
||||
@@ -89,17 +75,12 @@ func (r *PureFtpdController) Stop(ctx http.Context) http.Response {
|
||||
return check
|
||||
}
|
||||
|
||||
tools.Exec("systemctl stop pure-ftpd")
|
||||
status := tools.Exec("systemctl status pure-ftpd | grep Active | grep -v grep | awk '{print $2}'")
|
||||
if len(status) == 0 {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取PureFtpd状态失败")
|
||||
err := tools.ServiceStop("pure-ftpd")
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "停止PureFtpd失败")
|
||||
}
|
||||
|
||||
if status != "active" {
|
||||
return controllers.Success(ctx, true)
|
||||
} else {
|
||||
return controllers.Success(ctx, false)
|
||||
}
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// List 获取用户列表
|
||||
@@ -109,8 +90,8 @@ func (r *PureFtpdController) List(ctx http.Context) http.Response {
|
||||
return check
|
||||
}
|
||||
|
||||
listRaw := tools.Exec("pure-pw list")
|
||||
if len(listRaw) == 0 {
|
||||
listRaw, err := tools.Exec("pure-pw list")
|
||||
if err != nil {
|
||||
return controllers.Success(ctx, http.Json{
|
||||
"total": 0,
|
||||
"items": []User{},
|
||||
@@ -188,8 +169,12 @@ func (r *PureFtpdController) Add(ctx http.Context) http.Response {
|
||||
if err = tools.Chown(path, "www", "www"); err != nil {
|
||||
return nil
|
||||
}
|
||||
tools.Exec(`yes '` + password + `' | pure-pw useradd ` + username + ` -u www -g www -d ` + path)
|
||||
tools.Exec("pure-pw mkdb")
|
||||
if out, err := tools.Exec(`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 {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
@@ -213,8 +198,12 @@ func (r *PureFtpdController) Delete(ctx http.Context) http.Response {
|
||||
|
||||
username := ctx.Request().Input("username")
|
||||
|
||||
tools.Exec("pure-pw userdel " + username + " -m")
|
||||
tools.Exec("pure-pw mkdb")
|
||||
if out, err := tools.Exec("pure-pw userdel " + username + " -m"); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
if out, err := tools.Exec("pure-pw mkdb"); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
@@ -240,8 +229,12 @@ func (r *PureFtpdController) ChangePassword(ctx http.Context) http.Response {
|
||||
username := ctx.Request().Input("username")
|
||||
password := ctx.Request().Input("password")
|
||||
|
||||
tools.Exec(`yes '` + password + `' | pure-pw passwd ` + username + ` -m`)
|
||||
tools.Exec("pure-pw mkdb")
|
||||
if out, err := tools.Exec(`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 {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
@@ -253,8 +246,8 @@ func (r *PureFtpdController) GetPort(ctx http.Context) http.Response {
|
||||
return check
|
||||
}
|
||||
|
||||
port := tools.Exec(`cat /www/server/pure-ftpd/etc/pure-ftpd.conf | grep "Bind" | awk '{print $2}' | awk -F "," '{print $2}'`)
|
||||
if len(port) == 0 {
|
||||
port, err := tools.Exec(`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端口失败")
|
||||
}
|
||||
|
||||
@@ -279,15 +272,24 @@ func (r *PureFtpdController) SetPort(ctx http.Context) http.Response {
|
||||
}
|
||||
|
||||
port := ctx.Request().Input("port")
|
||||
tools.Exec(`sed -i "s/Bind.*/Bind 0.0.0.0,` + port + `/g" /www/server/pure-ftpd/etc/pure-ftpd.conf`)
|
||||
if tools.IsRHEL() {
|
||||
tools.Exec("firewall-cmd --zone=public --add-port=" + port + "/tcp --permanent")
|
||||
tools.Exec("firewall-cmd --reload")
|
||||
} else {
|
||||
tools.Exec("ufw allow " + port + "/tcp")
|
||||
tools.Exec("ufw reload")
|
||||
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 {
|
||||
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 {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
if out, err := tools.Exec("firewall-cmd --reload"); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
} else {
|
||||
if out, err := tools.Exec("ufw allow " + port + "/tcp"); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
if out, err := tools.Exec("ufw reload"); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
}
|
||||
tools.Exec("systemctl restart pure-ftpd")
|
||||
|
||||
return controllers.Success(ctx, nil)
|
||||
return r.Restart(ctx)
|
||||
}
|
||||
|
||||
@@ -23,16 +23,12 @@ func (r *RedisController) Status(ctx http.Context) http.Response {
|
||||
return check
|
||||
}
|
||||
|
||||
status := tools.Exec("systemctl status redis | grep Active | grep -v grep | awk '{print $2}'")
|
||||
if len(status) == 0 {
|
||||
status, err := tools.ServiceStatus("redis")
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取Redis状态失败")
|
||||
}
|
||||
|
||||
if status == "active" {
|
||||
return controllers.Success(ctx, true)
|
||||
} else {
|
||||
return controllers.Success(ctx, false)
|
||||
}
|
||||
return controllers.Success(ctx, status)
|
||||
}
|
||||
|
||||
// Restart 重启服务
|
||||
@@ -42,17 +38,11 @@ func (r *RedisController) Restart(ctx http.Context) http.Response {
|
||||
return check
|
||||
}
|
||||
|
||||
tools.Exec("systemctl restart redis")
|
||||
status := tools.Exec("systemctl status redis | grep Active | grep -v grep | awk '{print $2}'")
|
||||
if len(status) == 0 {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取Redis状态失败")
|
||||
if err := tools.ServiceRestart("redis"); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "重启Redis失败")
|
||||
}
|
||||
|
||||
if status == "active" {
|
||||
return controllers.Success(ctx, true)
|
||||
} else {
|
||||
return controllers.Success(ctx, false)
|
||||
}
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// Start 启动服务
|
||||
@@ -62,17 +52,11 @@ func (r *RedisController) Start(ctx http.Context) http.Response {
|
||||
return check
|
||||
}
|
||||
|
||||
tools.Exec("systemctl start redis")
|
||||
status := tools.Exec("systemctl status redis | grep Active | grep -v grep | awk '{print $2}'")
|
||||
if len(status) == 0 {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取Redis状态失败")
|
||||
if err := tools.ServiceStart("redis"); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "启动Redis失败")
|
||||
}
|
||||
|
||||
if status == "active" {
|
||||
return controllers.Success(ctx, true)
|
||||
} else {
|
||||
return controllers.Success(ctx, false)
|
||||
}
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// Stop 停止服务
|
||||
@@ -82,17 +66,11 @@ func (r *RedisController) Stop(ctx http.Context) http.Response {
|
||||
return check
|
||||
}
|
||||
|
||||
tools.Exec("systemctl stop redis")
|
||||
status := tools.Exec("systemctl status redis | grep Active | grep -v grep | awk '{print $2}'")
|
||||
if len(status) == 0 {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取Redis状态失败")
|
||||
if err := tools.ServiceStop("redis"); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "停止Redis失败")
|
||||
}
|
||||
|
||||
if status != "active" {
|
||||
return controllers.Success(ctx, true)
|
||||
} else {
|
||||
return controllers.Success(ctx, false)
|
||||
}
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// GetConfig 获取配置
|
||||
@@ -137,13 +115,16 @@ func (r *RedisController) Load(ctx http.Context) http.Response {
|
||||
return check
|
||||
}
|
||||
|
||||
status := tools.Exec("systemctl status redis | grep Active | grep -v grep | awk '{print $2}'")
|
||||
if status != "active" {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "Redis 已停止运行")
|
||||
status, err := tools.ServiceStatus("redis")
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取Redis状态失败")
|
||||
}
|
||||
if !status {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "Redis已停止运行")
|
||||
}
|
||||
|
||||
raw := tools.Exec("redis-cli info")
|
||||
if len(raw) == 0 {
|
||||
raw, err := tools.Exec("redis-cli info")
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取Redis负载失败")
|
||||
}
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ func (r *S3fsController) List(ctx http.Context) http.Response {
|
||||
var s3fsList []S3fsMount
|
||||
err := json.UnmarshalString(r.setting.Get("s3fs", "[]"), &s3fsList)
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, "获取 S3fs 挂载失败")
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取 S3fs 挂载失败")
|
||||
}
|
||||
|
||||
startIndex := (page - 1) * limit
|
||||
@@ -120,15 +120,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
|
||||
}
|
||||
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`)
|
||||
mountCheck := tools.Exec("mount -a 2>&1")
|
||||
if len(mountCheck) != 0 {
|
||||
tools.Exec(`sed -i 's@^s3fs#` + bucket + `\s` + path + `.*$@@g' /etc/fstab`)
|
||||
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`)
|
||||
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`)
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "检测到/etc/fstab有误: "+mountCheck)
|
||||
}
|
||||
dfCheck := tools.Exec("df -h | grep " + path + " 2>&1")
|
||||
if len(dfCheck) == 0 {
|
||||
tools.Exec(`sed -i 's@^s3fs#` + bucket + `\s` + path + `.*$@@g' /etc/fstab`)
|
||||
if _, err := tools.Exec("df -h | grep " + path + " 2>&1"); err != nil {
|
||||
_, _ = tools.Exec(`sed -i 's@^s3fs#` + bucket + `\s` + path + `.*$@@g' /etc/fstab`)
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "挂载失败,请检查配置是否正确")
|
||||
}
|
||||
|
||||
@@ -179,11 +180,16 @@ func (r *S3fsController) Delete(ctx http.Context) http.Response {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, "挂载ID不存在")
|
||||
}
|
||||
|
||||
tools.Exec(`fusermount -u '` + mount.Path + `' 2>&1`)
|
||||
tools.Exec(`umount '` + mount.Path + `' 2>&1`)
|
||||
tools.Exec(`sed -i 's@^s3fs#` + mount.Bucket + `\s` + mount.Path + `.*$@@g' /etc/fstab`)
|
||||
mountCheck := tools.Exec("mount -a 2>&1")
|
||||
if len(mountCheck) != 0 {
|
||||
if out, err := tools.Exec(`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 {
|
||||
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 {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
if mountCheck, err := tools.Exec("mount -a 2>&1"); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "检测到/etc/fstab有误: "+mountCheck)
|
||||
}
|
||||
tools.Remove("/etc/passwd-s3fs-" + cast.ToString(mount.ID))
|
||||
|
||||
@@ -34,12 +34,12 @@ func (r *SupervisorController) Status(ctx http.Context) http.Response {
|
||||
return check
|
||||
}
|
||||
|
||||
status := tools.Exec(`systemctl status ` + r.ServiceName + ` | grep Active | grep -v grep | awk '{print $2}'`)
|
||||
if status == "active" {
|
||||
return controllers.Success(ctx, true)
|
||||
} else {
|
||||
return controllers.Success(ctx, false)
|
||||
status, err := tools.ServiceStatus(r.ServiceName)
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取Supervisor状态失败")
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, status)
|
||||
}
|
||||
|
||||
// Start 启动
|
||||
@@ -49,13 +49,11 @@ func (r *SupervisorController) Start(ctx http.Context) http.Response {
|
||||
return check
|
||||
}
|
||||
|
||||
tools.Exec(`systemctl start ` + r.ServiceName)
|
||||
status := tools.Exec(`systemctl status ` + r.ServiceName + ` | grep Active | grep -v grep | awk '{print $2}'`)
|
||||
if status == "active" {
|
||||
return controllers.Success(ctx, true)
|
||||
} else {
|
||||
return controllers.Success(ctx, false)
|
||||
if err := tools.ServiceStart(r.ServiceName); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "启动Supervisor失败")
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// Stop 停止
|
||||
@@ -65,13 +63,11 @@ func (r *SupervisorController) Stop(ctx http.Context) http.Response {
|
||||
return check
|
||||
}
|
||||
|
||||
tools.Exec(`systemctl stop ` + r.ServiceName)
|
||||
status := tools.Exec(`systemctl status ` + r.ServiceName + ` | grep Active | grep -v grep | awk '{print $2}'`)
|
||||
if status != "active" {
|
||||
return controllers.Success(ctx, true)
|
||||
} else {
|
||||
return controllers.Success(ctx, false)
|
||||
if err := tools.ServiceStop(r.ServiceName); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "停止Supervisor失败")
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// Restart 重启
|
||||
@@ -81,13 +77,11 @@ func (r *SupervisorController) Restart(ctx http.Context) http.Response {
|
||||
return check
|
||||
}
|
||||
|
||||
tools.Exec(`systemctl restart ` + r.ServiceName)
|
||||
status := tools.Exec(`systemctl status ` + r.ServiceName + ` | grep Active | grep -v grep | awk '{print $2}'`)
|
||||
if status == "active" {
|
||||
return controllers.Success(ctx, true)
|
||||
} else {
|
||||
return controllers.Success(ctx, false)
|
||||
if err := tools.ServiceRestart(r.ServiceName); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "重启Supervisor失败")
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// Reload 重载
|
||||
@@ -97,13 +91,11 @@ func (r *SupervisorController) Reload(ctx http.Context) http.Response {
|
||||
return check
|
||||
}
|
||||
|
||||
tools.Exec(`systemctl reload ` + r.ServiceName)
|
||||
status := tools.Exec(`systemctl status ` + r.ServiceName + ` | grep Active | grep -v grep | awk '{print $2}'`)
|
||||
if status == "active" {
|
||||
return controllers.Success(ctx, true)
|
||||
} else {
|
||||
return controllers.Success(ctx, false)
|
||||
if err := tools.ServiceReload(r.ServiceName); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "重载Supervisor失败")
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// Log 日志
|
||||
@@ -113,7 +105,11 @@ func (r *SupervisorController) Log(ctx http.Context) http.Response {
|
||||
return check
|
||||
}
|
||||
|
||||
log := tools.Exec(`tail -n 200 /var/log/supervisor/supervisord.log`)
|
||||
log, err := tools.Exec(`tail -n 200 /var/log/supervisor/supervisord.log`)
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, log)
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, log)
|
||||
}
|
||||
|
||||
@@ -124,7 +120,10 @@ func (r *SupervisorController) ClearLog(ctx http.Context) http.Response {
|
||||
return check
|
||||
}
|
||||
|
||||
tools.Exec(`echo "" > /var/log/supervisor/supervisord.log`)
|
||||
if out, err := tools.Exec(`echo "" > /var/log/supervisor/supervisord.log`); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
@@ -141,6 +140,7 @@ func (r *SupervisorController) Config(ctx http.Context) http.Response {
|
||||
} else {
|
||||
config = tools.Read(`/etc/supervisor/supervisord.conf`)
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, config)
|
||||
}
|
||||
|
||||
@@ -160,7 +160,7 @@ func (r *SupervisorController) SaveConfig(ctx http.Context) http.Response {
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, err.Error())
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
|
||||
return r.Restart(ctx)
|
||||
@@ -183,7 +183,11 @@ func (r *SupervisorController) Processes(ctx http.Context) http.Response {
|
||||
Uptime string `json:"uptime"`
|
||||
}
|
||||
|
||||
out := tools.Exec(`supervisorctl status | awk '{print $1}'`)
|
||||
out, err := tools.Exec(`supervisorctl status | awk '{print $1}'`)
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
|
||||
var processList []process
|
||||
for _, line := range strings.Split(out, "\n") {
|
||||
if len(line) == 0 {
|
||||
@@ -192,10 +196,14 @@ func (r *SupervisorController) Processes(ctx http.Context) http.Response {
|
||||
|
||||
var p process
|
||||
p.Name = line
|
||||
p.Status = tools.Exec(`supervisorctl status ` + line + ` | awk '{print $2}'`)
|
||||
if status, err := tools.Exec(`supervisorctl status ` + line + ` | awk '{print $2}'`); err == nil {
|
||||
p.Status = status
|
||||
}
|
||||
if p.Status == "RUNNING" {
|
||||
p.Pid = strings.ReplaceAll(tools.Exec(`supervisorctl status `+line+` | awk '{print $4}'`), ",", "")
|
||||
p.Uptime = tools.Exec(`supervisorctl status ` + line + ` | awk '{print $6}'`)
|
||||
pid, _ := tools.Exec(`supervisorctl status ` + line + ` | awk '{print $4}'`)
|
||||
p.Pid = strings.ReplaceAll(pid, ",", "")
|
||||
uptime, _ := tools.Exec(`supervisorctl status ` + line + ` | awk '{print $6}'`)
|
||||
p.Uptime = uptime
|
||||
} else {
|
||||
p.Pid = "-"
|
||||
p.Uptime = "-"
|
||||
@@ -233,7 +241,10 @@ func (r *SupervisorController) StartProcess(ctx http.Context) http.Response {
|
||||
}
|
||||
|
||||
process := ctx.Request().Input("process")
|
||||
tools.Exec(`supervisorctl start ` + process)
|
||||
if out, err := tools.Exec(`supervisorctl start ` + process); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
@@ -245,7 +256,10 @@ func (r *SupervisorController) StopProcess(ctx http.Context) http.Response {
|
||||
}
|
||||
|
||||
process := ctx.Request().Input("process")
|
||||
tools.Exec(`supervisorctl stop ` + process)
|
||||
if out, err := tools.Exec(`supervisorctl stop ` + process); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
@@ -257,7 +271,10 @@ func (r *SupervisorController) RestartProcess(ctx http.Context) http.Response {
|
||||
}
|
||||
|
||||
process := ctx.Request().Input("process")
|
||||
tools.Exec(`supervisorctl restart ` + process)
|
||||
if out, err := tools.Exec(`supervisorctl restart ` + process); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
@@ -270,13 +287,22 @@ func (r *SupervisorController) ProcessLog(ctx http.Context) http.Response {
|
||||
|
||||
process := ctx.Request().Input("process")
|
||||
var logPath string
|
||||
var err error
|
||||
if tools.IsRHEL() {
|
||||
logPath = tools.Exec(`cat '/etc/supervisord.d/` + process + `.conf' | grep stdout_logfile= | awk -F "=" '{print $2}'`)
|
||||
logPath, err = tools.Exec(`cat '/etc/supervisord.d/` + process + `.conf' | grep stdout_logfile= | awk -F "=" '{print $2}'`)
|
||||
} else {
|
||||
logPath = tools.Exec(`cat '/etc/supervisor/conf.d/` + process + `.conf' | grep stdout_logfile= | awk -F "=" '{print $2}'`)
|
||||
logPath, err = tools.Exec(`cat '/etc/supervisor/conf.d/` + process + `.conf' | grep stdout_logfile= | awk -F "=" '{print $2}'`)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "无法从进程"+process+"的配置文件中获取日志路径")
|
||||
}
|
||||
|
||||
log, err := tools.Exec(`tail -n 200 ` + logPath)
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, log)
|
||||
}
|
||||
|
||||
log := tools.Exec(`tail -n 200 ` + logPath)
|
||||
return controllers.Success(ctx, log)
|
||||
}
|
||||
|
||||
@@ -289,13 +315,21 @@ func (r *SupervisorController) ClearProcessLog(ctx http.Context) http.Response {
|
||||
|
||||
process := ctx.Request().Input("process")
|
||||
var logPath string
|
||||
var err error
|
||||
if tools.IsRHEL() {
|
||||
logPath = tools.Exec(`cat '/etc/supervisord.d/` + process + `.conf' | grep stdout_logfile= | awk -F "=" '{print $2}'`)
|
||||
logPath, err = tools.Exec(`cat '/etc/supervisord.d/` + process + `.conf' | grep stdout_logfile= | awk -F "=" '{print $2}'`)
|
||||
} else {
|
||||
logPath = tools.Exec(`cat '/etc/supervisor/conf.d/` + process + `.conf' | grep stdout_logfile= | awk -F "=" '{print $2}'`)
|
||||
logPath, err = tools.Exec(`cat '/etc/supervisor/conf.d/` + process + `.conf' | grep stdout_logfile= | awk -F "=" '{print $2}'`)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "无法从进程"+process+"的配置文件中获取日志路径")
|
||||
}
|
||||
|
||||
if out, err := tools.Exec(`echo "" > ` + logPath); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
|
||||
tools.Exec(`echo "" > ` + logPath)
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
@@ -337,9 +371,15 @@ 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 start ` + process)
|
||||
if out, err := tools.Exec(`supervisorctl reread`); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
if out, err := tools.Exec(`supervisorctl update`); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
if out, err := tools.Exec(`supervisorctl start ` + process); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
@@ -392,9 +432,15 @@ 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)
|
||||
if out, err := tools.Exec(`supervisorctl reread`); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
if out, err := tools.Exec(`supervisorctl update`); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
if out, err := tools.Exec(`supervisorctl start ` + name); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
@@ -407,18 +453,31 @@ func (r *SupervisorController) DeleteProcess(ctx http.Context) http.Response {
|
||||
}
|
||||
|
||||
process := ctx.Request().Input("process")
|
||||
tools.Exec(`supervisorctl stop ` + process)
|
||||
if out, err := tools.Exec(`supervisorctl stop ` + process); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
|
||||
var logPath string
|
||||
var err error
|
||||
if tools.IsRHEL() {
|
||||
logPath = tools.Exec(`cat '/etc/supervisord.d/` + process + `.conf' | grep stdout_logfile= | awk -F "=" '{print $2}'`)
|
||||
logPath, err = tools.Exec(`cat '/etc/supervisord.d/` + process + `.conf' | grep stdout_logfile= | awk -F "=" '{print $2}'`)
|
||||
tools.Remove(`/etc/supervisord.d/` + process + `.conf`)
|
||||
} else {
|
||||
logPath = tools.Exec(`cat '/etc/supervisor/conf.d/` + process + `.conf' | grep stdout_logfile= | awk -F "=" '{print $2}'`)
|
||||
logPath, err = tools.Exec(`cat '/etc/supervisor/conf.d/` + process + `.conf' | grep stdout_logfile= | awk -F "=" '{print $2}'`)
|
||||
tools.Remove(`/etc/supervisor/conf.d/` + process + `.conf`)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "无法从进程"+process+"的配置文件中获取日志路径")
|
||||
}
|
||||
|
||||
tools.Remove(logPath)
|
||||
tools.Exec(`supervisorctl reread`)
|
||||
tools.Exec(`supervisorctl update`)
|
||||
if out, err := tools.Exec(`supervisorctl reread`); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
if out, err := tools.Exec(`supervisorctl update`); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ func (r *ToolBoxController) GetDNS(ctx http.Context) http.Response {
|
||||
raw := tools.Read("/etc/resolv.conf")
|
||||
match := regexp.MustCompile(`nameserver\s+(\S+)`).FindAllStringSubmatch(raw, -1)
|
||||
if len(match) == 0 {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, "找不到 DNS 信息")
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "找不到 DNS 信息")
|
||||
}
|
||||
|
||||
var dns []string
|
||||
@@ -58,7 +58,7 @@ func (r *ToolBoxController) SetDNS(ctx http.Context) http.Response {
|
||||
dns += "nameserver " + dns2 + "\n"
|
||||
|
||||
if err := tools.Write("/etc/resolv.conf", dns, 0644); err != nil {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, "写入 DNS 信息失败")
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "写入 DNS 信息失败")
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, nil)
|
||||
@@ -86,7 +86,11 @@ func (r *ToolBoxController) GetSWAP(ctx http.Context) http.Response {
|
||||
total = "0.00 B"
|
||||
}
|
||||
|
||||
raw := tools.Exec("LC_ALL=C free | grep Swap")
|
||||
raw, err := tools.Exec("free | grep Swap")
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, "获取 SWAP 信息失败")
|
||||
}
|
||||
|
||||
match := regexp.MustCompile(`Swap:\s+(\d+)\s+(\d+)\s+(\d+)`).FindStringSubmatch(raw)
|
||||
if len(match) > 0 {
|
||||
used = tools.FormatBytes(cast.ToFloat64(match[2]) * 1024)
|
||||
@@ -111,28 +115,48 @@ func (r *ToolBoxController) SetSWAP(ctx http.Context) http.Response {
|
||||
size := ctx.Request().InputInt("size")
|
||||
|
||||
if tools.Exists("/www/swap") {
|
||||
tools.Exec("swapoff /www/swap")
|
||||
tools.Exec("rm -f /www/swap")
|
||||
tools.Exec("sed -i '/www\\/swap/d' /etc/fstab")
|
||||
if out, err := tools.Exec("swapoff /www/swap"); err != nil {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, out)
|
||||
}
|
||||
if out, err := tools.Exec("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 {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, out)
|
||||
}
|
||||
}
|
||||
|
||||
if size > 1 {
|
||||
free := tools.Exec("df -k /www | awk '{print $4}' | tail -n 1")
|
||||
free, err := tools.Exec("df -k /www | awk '{print $4}' | tail -n 1")
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, "获取磁盘空间失败")
|
||||
}
|
||||
if cast.ToInt64(free)*1024 < int64(size)*1024*1024 {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, "磁盘空间不足,当前剩余 "+tools.FormatBytes(cast.ToFloat64(free)))
|
||||
}
|
||||
|
||||
if strings.Contains(tools.Exec("df -T /www | awk '{print $2}' | tail -n 1"), "btrfs") {
|
||||
tools.Exec("btrfs filesystem mkswapfile --size " + cast.ToString(size) + "M --uuid clear /www/swap")
|
||||
btrfsCheck, _ := tools.Exec("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 {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, out)
|
||||
}
|
||||
} else {
|
||||
tools.Exec("dd if=/dev/zero of=/www/swap bs=1M count=" + cast.ToString(size))
|
||||
tools.Exec("mkswap -f /www/swap")
|
||||
if out, err := tools.Exec("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 {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, out)
|
||||
}
|
||||
if err := tools.Chmod("/www/swap", 0600); err != nil {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, "设置 SWAP 权限失败")
|
||||
}
|
||||
}
|
||||
tools.Exec("swapon /www/swap")
|
||||
tools.Exec("echo '/www/swap swap swap defaults 0 0' >> /etc/fstab")
|
||||
if out, err := tools.Exec("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 {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, out)
|
||||
}
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, nil)
|
||||
@@ -145,7 +169,11 @@ func (r *ToolBoxController) GetTimezone(ctx http.Context) http.Response {
|
||||
return check
|
||||
}
|
||||
|
||||
raw := tools.Exec("LC_ALL=C timedatectl | grep zone")
|
||||
raw, err := tools.Exec("timedatectl | grep zone")
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, "获取时区信息失败")
|
||||
}
|
||||
|
||||
match := regexp.MustCompile(`zone:\s+(\S+)`).FindStringSubmatch(raw)
|
||||
if len(match) == 0 {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, "找不到时区信息")
|
||||
@@ -156,7 +184,10 @@ func (r *ToolBoxController) GetTimezone(ctx http.Context) http.Response {
|
||||
Value string `json:"value"`
|
||||
}
|
||||
|
||||
zonesRaw := tools.Exec("LC_ALL=C timedatectl list-timezones")
|
||||
zonesRaw, err := tools.Exec("timedatectl list-timezones")
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, "获取时区列表失败")
|
||||
}
|
||||
zones := strings.Split(zonesRaw, "\n")
|
||||
|
||||
var zonesList []zone
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
|
||||
"github.com/goravel/framework/contracts/http"
|
||||
"github.com/spf13/cast"
|
||||
commonrequests "panel/app/http/requests/common"
|
||||
|
||||
"panel/pkg/tools"
|
||||
)
|
||||
@@ -28,33 +29,47 @@ func (r *SafeController) GetFirewallStatus(ctx http.Context) http.Response {
|
||||
// SetFirewallStatus 设置防火墙状态
|
||||
func (r *SafeController) SetFirewallStatus(ctx http.Context) http.Response {
|
||||
var out string
|
||||
var err error
|
||||
if ctx.Request().InputBool("status") {
|
||||
if tools.IsRHEL() {
|
||||
out = tools.Exec("systemctl start firewalld")
|
||||
out, err = tools.Exec("systemctl start firewalld")
|
||||
} else {
|
||||
out = tools.Exec("echo y | ufw enable")
|
||||
out, err = tools.Exec("echo y | ufw enable")
|
||||
}
|
||||
} else {
|
||||
if tools.IsRHEL() {
|
||||
out = tools.Exec("systemctl stop firewalld")
|
||||
out, err = tools.Exec("systemctl stop firewalld")
|
||||
} else {
|
||||
out = tools.Exec("ufw disable")
|
||||
out, err = tools.Exec("ufw disable")
|
||||
}
|
||||
}
|
||||
|
||||
return Success(ctx, out)
|
||||
if err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
|
||||
return Success(ctx, nil)
|
||||
}
|
||||
|
||||
// GetFirewallRules 获取防火墙规则
|
||||
func (r *SafeController) GetFirewallRules(ctx http.Context) http.Response {
|
||||
var paginateRequest commonrequests.Paginate
|
||||
sanitize := Sanitize(ctx, &paginateRequest)
|
||||
if sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
|
||||
if !r.firewallStatus() {
|
||||
return Success(ctx, nil)
|
||||
}
|
||||
page := ctx.Request().QueryInt("page", 1)
|
||||
limit := ctx.Request().QueryInt("limit", 10)
|
||||
|
||||
var rules []map[string]string
|
||||
if tools.IsRHEL() {
|
||||
out := tools.Exec("firewall-cmd --list-all 2>&1")
|
||||
out, err := tools.Exec("firewall-cmd --list-all 2>&1")
|
||||
if err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
|
||||
match := regexp.MustCompile(`ports: (.*)`).FindStringSubmatch(out)
|
||||
if len(match) == 0 {
|
||||
return Success(ctx, http.Json{
|
||||
@@ -63,7 +78,6 @@ func (r *SafeController) GetFirewallRules(ctx http.Context) http.Response {
|
||||
})
|
||||
}
|
||||
ports := strings.Split(match[1], " ")
|
||||
var rules []map[string]string
|
||||
for _, port := range ports {
|
||||
rule := strings.Split(port, "/")
|
||||
rules = append(rules, map[string]string{
|
||||
@@ -71,33 +85,18 @@ func (r *SafeController) GetFirewallRules(ctx http.Context) http.Response {
|
||||
"protocol": rule[1],
|
||||
})
|
||||
}
|
||||
|
||||
startIndex := (page - 1) * limit
|
||||
endIndex := page * limit
|
||||
if startIndex > len(rules) {
|
||||
return Success(ctx, http.Json{
|
||||
"total": 0,
|
||||
"items": []map[string]string{},
|
||||
})
|
||||
}
|
||||
if endIndex > len(rules) {
|
||||
endIndex = len(rules)
|
||||
}
|
||||
pagedRules := rules[startIndex:endIndex]
|
||||
|
||||
return Success(ctx, http.Json{
|
||||
"total": len(rules),
|
||||
"items": pagedRules,
|
||||
})
|
||||
} else {
|
||||
out := tools.Exec("ufw status | grep -v '(v6)' | grep ALLOW | awk '{print $1}'")
|
||||
out, err := tools.Exec("ufw status | grep -v '(v6)' | grep ALLOW | awk '{print $1}'")
|
||||
if err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
|
||||
if len(out) == 0 {
|
||||
return Success(ctx, http.Json{
|
||||
"total": 0,
|
||||
"items": []map[string]string{},
|
||||
})
|
||||
}
|
||||
var rules []map[string]string
|
||||
for _, port := range strings.Split(out, "\n") {
|
||||
rule := strings.Split(port, "/")
|
||||
rules = append(rules, map[string]string{
|
||||
@@ -105,31 +104,31 @@ func (r *SafeController) GetFirewallRules(ctx http.Context) http.Response {
|
||||
"protocol": rule[1],
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
startIndex := (page - 1) * limit
|
||||
endIndex := page * limit
|
||||
if startIndex > len(rules) {
|
||||
return Success(ctx, http.Json{
|
||||
"total": 0,
|
||||
"items": []map[string]string{},
|
||||
})
|
||||
}
|
||||
if endIndex > len(rules) {
|
||||
endIndex = len(rules)
|
||||
}
|
||||
pagedRules := rules[startIndex:endIndex]
|
||||
|
||||
startIndex := (paginateRequest.Page - 1) * paginateRequest.Limit
|
||||
endIndex := paginateRequest.Page * paginateRequest.Limit
|
||||
if startIndex > len(rules) {
|
||||
return Success(ctx, http.Json{
|
||||
"total": len(rules),
|
||||
"items": pagedRules,
|
||||
"total": 0,
|
||||
"items": []map[string]string{},
|
||||
})
|
||||
}
|
||||
if endIndex > len(rules) {
|
||||
endIndex = len(rules)
|
||||
}
|
||||
pagedRules := rules[startIndex:endIndex]
|
||||
|
||||
return Success(ctx, http.Json{
|
||||
"total": len(rules),
|
||||
"items": pagedRules,
|
||||
})
|
||||
}
|
||||
|
||||
// AddFirewallRule 添加防火墙规则
|
||||
func (r *SafeController) AddFirewallRule(ctx http.Context) http.Response {
|
||||
if !r.firewallStatus() {
|
||||
return Error(ctx, http.StatusUnprocessableEntity, "防火墙未启动")
|
||||
return Error(ctx, http.StatusInternalServerError, "防火墙未启动")
|
||||
}
|
||||
|
||||
port := ctx.Request().Input("port")
|
||||
@@ -153,17 +152,29 @@ func (r *SafeController) AddFirewallRule(ctx http.Context) http.Response {
|
||||
}
|
||||
|
||||
if tools.IsRHEL() {
|
||||
tools.Exec("firewall-cmd --remove-port=" + cast.ToString(port) + "/" + protocol + " --permanent 2>&1")
|
||||
tools.Exec("firewall-cmd --add-port=" + cast.ToString(port) + "/" + protocol + " --permanent 2>&1")
|
||||
tools.Exec("firewall-cmd --reload")
|
||||
if out, err := tools.Exec("firewall-cmd --remove-port=" + cast.ToString(port) + "/" + protocol + " --permanent 2>&1"); 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 {
|
||||
return Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
if out, err := tools.Exec("firewall-cmd --reload"); err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
} else {
|
||||
// ufw 需要替换 - 为 : 添加
|
||||
if strings.Contains(port, "-") {
|
||||
port = strings.ReplaceAll(port, "-", ":")
|
||||
}
|
||||
tools.Exec("ufw delete allow " + cast.ToString(port) + "/" + protocol)
|
||||
tools.Exec("ufw allow " + cast.ToString(port) + "/" + protocol)
|
||||
tools.Exec("ufw reload")
|
||||
if out, err := tools.Exec("ufw delete allow " + cast.ToString(port) + "/" + protocol); err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
if out, err := tools.Exec("ufw allow " + cast.ToString(port) + "/" + protocol); err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
if out, err := tools.Exec("ufw reload"); err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
}
|
||||
|
||||
return Success(ctx, nil)
|
||||
@@ -182,11 +193,19 @@ func (r *SafeController) DeleteFirewallRule(ctx http.Context) http.Response {
|
||||
}
|
||||
|
||||
if tools.IsRHEL() {
|
||||
tools.Exec("firewall-cmd --remove-port=" + cast.ToString(port) + "/" + protocol + " --permanent 2>&1")
|
||||
tools.Exec("firewall-cmd --reload")
|
||||
if out, err := tools.Exec("firewall-cmd --remove-port=" + cast.ToString(port) + "/" + protocol + " --permanent 2>&1"); err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
if out, err := tools.Exec("firewall-cmd --reload"); err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
} else {
|
||||
tools.Exec("ufw delete allow " + cast.ToString(port) + "/" + protocol)
|
||||
tools.Exec("ufw reload")
|
||||
if out, err := tools.Exec("ufw delete allow " + cast.ToString(port) + "/" + protocol); err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
if out, err := tools.Exec("ufw reload"); err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
}
|
||||
|
||||
return Success(ctx, nil)
|
||||
@@ -195,16 +214,17 @@ func (r *SafeController) DeleteFirewallRule(ctx http.Context) http.Response {
|
||||
// firewallStatus 获取防火墙状态
|
||||
func (r *SafeController) firewallStatus() bool {
|
||||
var out string
|
||||
var err error
|
||||
var running bool
|
||||
if tools.IsRHEL() {
|
||||
out = tools.Exec("systemctl status firewalld | grep Active | awk '{print $3}'")
|
||||
out, err = tools.Exec("systemctl status firewalld | grep Active | awk '{print $3}'")
|
||||
if out == "(running)" {
|
||||
running = true
|
||||
} else {
|
||||
running = false
|
||||
}
|
||||
} else {
|
||||
out = tools.Exec("ufw status | grep Status | awk '{print $2}'")
|
||||
out, err = tools.Exec("ufw status | grep Status | awk '{print $2}'")
|
||||
if out == "active" {
|
||||
running = true
|
||||
} else {
|
||||
@@ -212,43 +232,63 @@ func (r *SafeController) firewallStatus() bool {
|
||||
}
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
return running
|
||||
}
|
||||
|
||||
// GetSshStatus 获取 SSH 状态
|
||||
func (r *SafeController) GetSshStatus(ctx http.Context) http.Response {
|
||||
var out string
|
||||
var err error
|
||||
if tools.IsRHEL() {
|
||||
out = tools.Exec("systemctl status sshd | grep Active | awk '{print $3}'")
|
||||
out, err = tools.Exec("systemctl status sshd | grep Active | awk '{print $3}'")
|
||||
} else {
|
||||
out = tools.Exec("systemctl status ssh | grep Active | awk '{print $3}'")
|
||||
out, err = tools.Exec("systemctl status ssh | grep Active | awk '{print $3}'")
|
||||
}
|
||||
|
||||
running := false
|
||||
if out == "(running)" {
|
||||
running = true
|
||||
if err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
|
||||
return Success(ctx, running)
|
||||
return Success(ctx, out == "(running)")
|
||||
}
|
||||
|
||||
// SetSshStatus 设置 SSH 状态
|
||||
func (r *SafeController) SetSshStatus(ctx http.Context) http.Response {
|
||||
if ctx.Request().InputBool("status") {
|
||||
if tools.IsRHEL() {
|
||||
tools.Exec("systemctl enable sshd")
|
||||
tools.Exec("systemctl start sshd")
|
||||
if out, err := tools.Exec("systemctl enable sshd"); err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
if out, err := tools.Exec("systemctl start sshd"); err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
} else {
|
||||
tools.Exec("systemctl enable ssh")
|
||||
tools.Exec("systemctl start ssh")
|
||||
if out, err := tools.Exec("systemctl enable ssh"); err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
if out, err := tools.Exec("systemctl start ssh"); err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if tools.IsRHEL() {
|
||||
tools.Exec("systemctl stop sshd")
|
||||
tools.Exec("systemctl disable sshd")
|
||||
if out, err := tools.Exec("systemctl stop sshd"); err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
if out, err := tools.Exec("systemctl disable sshd"); err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
} else {
|
||||
tools.Exec("systemctl stop ssh")
|
||||
tools.Exec("systemctl disable ssh")
|
||||
if out, err := tools.Exec("systemctl stop ssh"); err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
if out, err := tools.Exec("systemctl disable ssh"); err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -257,7 +297,11 @@ func (r *SafeController) SetSshStatus(ctx http.Context) http.Response {
|
||||
|
||||
// GetSshPort 获取 SSH 端口
|
||||
func (r *SafeController) GetSshPort(ctx http.Context) http.Response {
|
||||
out := tools.Exec("cat /etc/ssh/sshd_config | grep 'Port ' | awk '{print $2}'")
|
||||
out, err := tools.Exec("cat /etc/ssh/sshd_config | grep 'Port ' | awk '{print $2}'")
|
||||
if err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
|
||||
return Success(ctx, out)
|
||||
}
|
||||
|
||||
@@ -268,21 +312,30 @@ func (r *SafeController) SetSshPort(ctx http.Context) http.Response {
|
||||
return Error(ctx, http.StatusUnprocessableEntity, "参数错误")
|
||||
}
|
||||
|
||||
oldPort := tools.Exec("cat /etc/ssh/sshd_config | grep 'Port ' | awk '{print $2}'")
|
||||
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")
|
||||
oldPort, err := tools.Exec("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")
|
||||
|
||||
if status := tools.Exec("systemctl status sshd | grep Active | awk '{print $3}'"); status == "(running)" {
|
||||
tools.Exec("systemctl restart sshd")
|
||||
out, err := tools.Exec("systemctl status sshd | grep Active | awk '{print $3}'")
|
||||
if err != nil || out != "(running)" {
|
||||
Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
|
||||
_, _ = tools.Exec("systemctl restart sshd")
|
||||
return Success(ctx, nil)
|
||||
}
|
||||
|
||||
// GetPingStatus 获取 Ping 状态
|
||||
func (r *SafeController) GetPingStatus(ctx http.Context) http.Response {
|
||||
if tools.IsRHEL() {
|
||||
out := tools.Exec(`firewall-cmd --list-all 2>&1`)
|
||||
out, err := tools.Exec(`firewall-cmd --list-all 2>&1`)
|
||||
if err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
|
||||
if !strings.Contains(out, `rule protocol value="icmp" drop`) {
|
||||
return Success(ctx, true)
|
||||
} else {
|
||||
@@ -300,20 +353,34 @@ func (r *SafeController) GetPingStatus(ctx http.Context) http.Response {
|
||||
|
||||
// SetPingStatus 设置 Ping 状态
|
||||
func (r *SafeController) SetPingStatus(ctx http.Context) http.Response {
|
||||
var out string
|
||||
var err error
|
||||
if tools.IsRHEL() {
|
||||
if ctx.Request().InputBool("status") {
|
||||
tools.Exec(`firewall-cmd --permanent --remove-rich-rule='rule protocol value=icmp drop'`)
|
||||
out, err = tools.Exec(`firewall-cmd --permanent --remove-rich-rule='rule protocol value=icmp drop'`)
|
||||
} else {
|
||||
tools.Exec(`firewall-cmd --permanent --add-rich-rule='rule protocol value=icmp drop'`)
|
||||
out, err = tools.Exec(`firewall-cmd --permanent --add-rich-rule='rule protocol value=icmp drop'`)
|
||||
}
|
||||
tools.Exec(`firewall-cmd --reload`)
|
||||
} else {
|
||||
if ctx.Request().InputBool("status") {
|
||||
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 = 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`)
|
||||
} else {
|
||||
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 = 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`)
|
||||
}
|
||||
tools.Exec(`ufw reload`)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
|
||||
if tools.IsRHEL() {
|
||||
out, err = tools.Exec(`firewall-cmd --reload`)
|
||||
} else {
|
||||
out, err = tools.Exec(`ufw reload`)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
|
||||
return Success(ctx, nil)
|
||||
|
||||
@@ -35,7 +35,9 @@ func (r *SettingController) List(ctx http.Context) http.Response {
|
||||
var settings []models.Setting
|
||||
err := facades.Orm().Query().Get(&settings)
|
||||
if err != nil {
|
||||
facades.Log().Info("[面板][SettingController] 查询设置列表失败 ", err)
|
||||
facades.Log().Request(ctx.Request()).Tags("面板", "面板设置").With(map[string]any{
|
||||
"error": err.Error(),
|
||||
}).Info("获取面板设置列表失败")
|
||||
return ErrorSystem(ctx)
|
||||
}
|
||||
|
||||
@@ -48,13 +50,21 @@ func (r *SettingController) List(ctx http.Context) http.Response {
|
||||
var user models.User
|
||||
err = facades.Auth().User(ctx, &user)
|
||||
if err != nil {
|
||||
facades.Log().Info("[面板][SettingController] 获取用户失败 ", err)
|
||||
facades.Log().Request(ctx.Request()).Tags("面板", "面板设置").With(map[string]any{
|
||||
"error": err.Error(),
|
||||
}).Info("获取用户信息失败")
|
||||
return ErrorSystem(ctx)
|
||||
}
|
||||
result.Username = user.Username
|
||||
result.Email = user.Email
|
||||
|
||||
result.Port = tools.Exec(`cat /www/panel/panel.conf | grep APP_PORT | awk -F '=' '{print $2}' | tr -d '\n'`)
|
||||
result.Port, err = tools.Exec(`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(),
|
||||
}).Info("获取面板端口失败")
|
||||
return ErrorSystem(ctx)
|
||||
}
|
||||
|
||||
return Success(ctx, result)
|
||||
}
|
||||
@@ -79,9 +89,9 @@ func (r *SettingController) Update(ctx http.Context) http.Response {
|
||||
|
||||
err := r.setting.Set(models.SettingKeyName, updateRequest.Name)
|
||||
if err != nil {
|
||||
facades.Log().Request(ctx.Request()).With(map[string]any{
|
||||
facades.Log().Request(ctx.Request()).Tags("面板", "面板设置").With(map[string]any{
|
||||
"error": err.Error(),
|
||||
}).Tags("面板", "面板设置").Info("保存面板名称失败")
|
||||
}).Info("保存面板名称失败")
|
||||
return ErrorSystem(ctx)
|
||||
}
|
||||
|
||||
@@ -92,9 +102,9 @@ func (r *SettingController) Update(ctx http.Context) http.Response {
|
||||
}
|
||||
err = r.setting.Set(models.SettingKeyBackupPath, updateRequest.BackupPath)
|
||||
if err != nil {
|
||||
facades.Log().Request(ctx.Request()).With(map[string]any{
|
||||
facades.Log().Request(ctx.Request()).Tags("面板", "面板设置").With(map[string]any{
|
||||
"error": err.Error(),
|
||||
}).Tags("面板", "面板设置").Info("保存备份目录失败")
|
||||
}).Info("保存备份目录失败")
|
||||
return ErrorSystem(ctx)
|
||||
}
|
||||
if !tools.Exists(updateRequest.WebsitePath) {
|
||||
@@ -107,9 +117,9 @@ func (r *SettingController) Update(ctx http.Context) http.Response {
|
||||
}
|
||||
err = r.setting.Set(models.SettingKeyWebsitePath, updateRequest.WebsitePath)
|
||||
if err != nil {
|
||||
facades.Log().Request(ctx.Request()).With(map[string]any{
|
||||
facades.Log().Request(ctx.Request()).Tags("面板", "面板设置").With(map[string]any{
|
||||
"error": err.Error(),
|
||||
}).Tags("面板", "面板设置").Info("保存建站目录失败")
|
||||
}).Info("保存建站目录失败")
|
||||
return ErrorSystem(ctx)
|
||||
}
|
||||
|
||||
@@ -128,30 +138,61 @@ func (r *SettingController) Update(ctx http.Context) http.Response {
|
||||
user.Password = hash
|
||||
}
|
||||
if err = facades.Orm().Query().Save(&user); err != nil {
|
||||
facades.Log().Request(ctx.Request()).With(map[string]any{
|
||||
facades.Log().Request(ctx.Request()).Tags("面板", "面板设置").With(map[string]any{
|
||||
"error": err.Error(),
|
||||
}).Tags("面板", "面板设置").Info("保存用户信息失败")
|
||||
}).Info("保存用户信息失败")
|
||||
return ErrorSystem(ctx)
|
||||
}
|
||||
|
||||
oldPort, err := tools.Exec(`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(),
|
||||
}).Info("获取面板端口失败")
|
||||
return ErrorSystem(ctx)
|
||||
}
|
||||
|
||||
oldPort := tools.Exec(`cat /www/panel/panel.conf | grep APP_PORT | awk -F '=' '{print $2}' | tr -d '\n'`)
|
||||
port := cast.ToString(updateRequest.Port)
|
||||
if oldPort != port {
|
||||
tools.Exec("sed -i 's/APP_PORT=" + oldPort + "/APP_PORT=" + port + "/g' /www/panel/panel.conf")
|
||||
if out, err := tools.Exec("sed -i 's/APP_PORT=" + oldPort + "/APP_PORT=" + port + "/g' /www/panel/panel.conf"); err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
if tools.IsRHEL() {
|
||||
tools.Exec("firewall-cmd --remove-port=" + cast.ToString(port) + "/tcp --permanent 2>&1")
|
||||
tools.Exec("firewall-cmd --add-port=" + cast.ToString(port) + "/tcp --permanent 2>&1")
|
||||
tools.Exec("firewall-cmd --reload")
|
||||
if out, err := tools.Exec("firewall-cmd --remove-port=" + cast.ToString(port) + "/tcp --permanent 2>&1"); 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 {
|
||||
return Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
if out, err := tools.Exec("firewall-cmd --reload"); err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
} else {
|
||||
tools.Exec("ufw delete allow " + cast.ToString(port) + "/tcp")
|
||||
tools.Exec("ufw allow " + cast.ToString(port) + "/tcp")
|
||||
tools.Exec("ufw reload")
|
||||
if out, err := tools.Exec("ufw delete allow " + cast.ToString(port) + "/tcp"); err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
if out, err := tools.Exec("ufw allow " + cast.ToString(port) + "/tcp"); err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
if out, err := tools.Exec("ufw reload"); err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
}
|
||||
}
|
||||
oldEntrance := tools.Exec(`cat /www/panel/panel.conf | grep APP_ENTRANCE | awk -F '=' '{print $2}' | tr -d '\n'`)
|
||||
|
||||
oldEntrance, err := tools.Exec(`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(),
|
||||
}).Info("获取面板入口失败")
|
||||
return ErrorSystem(ctx)
|
||||
}
|
||||
|
||||
entrance := cast.ToString(updateRequest.Entrance)
|
||||
if oldEntrance != entrance {
|
||||
tools.Exec("sed -i 's!APP_ENTRANCE=" + oldEntrance + "!APP_ENTRANCE=" + entrance + "!g' /www/panel/panel.conf")
|
||||
if out, err := tools.Exec("sed -i 's!APP_ENTRANCE=" + oldEntrance + "!APP_ENTRANCE=" + entrance + "!g' /www/panel/panel.conf"); err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
}
|
||||
|
||||
if oldPort != port || oldEntrance != entrance {
|
||||
|
||||
@@ -67,25 +67,17 @@ func (r *SshController) UpdateInfo(ctx http.Context) http.Response {
|
||||
port := ctx.Request().Input("port")
|
||||
user := ctx.Request().Input("user")
|
||||
password := ctx.Request().Input("password")
|
||||
err = r.setting.Set(models.SettingKeySshHost, host)
|
||||
if err != nil {
|
||||
facades.Log().Info("[面板][SSH] 更新配置失败 ", err)
|
||||
return ErrorSystem(ctx)
|
||||
if err = r.setting.Set(models.SettingKeySshHost, host); err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
err = r.setting.Set(models.SettingKeySshPort, port)
|
||||
if err != nil {
|
||||
facades.Log().Info("[面板][SSH] 更新配置失败 ", err)
|
||||
return ErrorSystem(ctx)
|
||||
if err = r.setting.Set(models.SettingKeySshPort, port); err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
err = r.setting.Set(models.SettingKeySshUser, user)
|
||||
if err != nil {
|
||||
facades.Log().Info("[面板][SSH] 更新配置失败 ", err)
|
||||
return ErrorSystem(ctx)
|
||||
if err = r.setting.Set(models.SettingKeySshUser, user); err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
err = r.setting.Set(models.SettingKeySshPassword, password)
|
||||
if err != nil {
|
||||
facades.Log().Info("[面板][SSH] 更新配置失败 ", err)
|
||||
return ErrorSystem(ctx)
|
||||
if err = r.setting.Set(models.SettingKeySshPassword, password); err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
|
||||
return Success(ctx, nil)
|
||||
@@ -142,21 +134,24 @@ func (r *SshController) Session(ctx http.Context) http.Response {
|
||||
defer wg.Done()
|
||||
err := turn.LoopRead(logBuff, ctx2)
|
||||
if err != nil {
|
||||
facades.Log().Info("[面板][SSH] 读取数据失败 ", err.Error())
|
||||
facades.Log().Request(ctx.Request()).Tags("面板", "SSH").With(map[string]any{
|
||||
"error": err.Error(),
|
||||
}).Info("SSH 会话错误")
|
||||
}
|
||||
}()
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
err := turn.SessionWait()
|
||||
if err != nil {
|
||||
facades.Log().Info("[面板][SSH] 会话失败 ", err.Error())
|
||||
facades.Log().Request(ctx.Request()).Tags("面板", "SSH").With(map[string]any{
|
||||
"error": err.Error(),
|
||||
}).Info("SSH 会话错误")
|
||||
}
|
||||
cancel()
|
||||
}()
|
||||
wg.Wait()
|
||||
})
|
||||
if err != nil {
|
||||
facades.Log().Info("[面板][SSH] 建立连接失败 ", err)
|
||||
return ErrorSystem(ctx)
|
||||
}
|
||||
|
||||
|
||||
@@ -38,9 +38,9 @@ func (r *TaskController) List(ctx http.Context) http.Response {
|
||||
var total int64
|
||||
err := facades.Orm().Query().Order("id desc").Paginate(ctx.Request().QueryInt("page", 1), ctx.Request().QueryInt("limit", 10), &tasks, &total)
|
||||
if err != nil {
|
||||
facades.Log().Request(ctx.Request()).With(map[string]any{
|
||||
facades.Log().Request(ctx.Request()).Tags("面板", "任务中心").With(map[string]any{
|
||||
"error": err.Error(),
|
||||
}).Info("[面板][TaskController] 查询任务列表失败")
|
||||
}).Info("查询任务列表失败")
|
||||
return ErrorSystem(ctx)
|
||||
}
|
||||
|
||||
@@ -55,14 +55,17 @@ func (r *TaskController) Log(ctx http.Context) http.Response {
|
||||
var task models.Task
|
||||
err := facades.Orm().Query().Where("id", ctx.Request().QueryInt("id")).FirstOrFail(&task)
|
||||
if err != nil {
|
||||
facades.Log().Request(ctx.Request()).With(map[string]any{
|
||||
facades.Log().Request(ctx.Request()).Tags("面板", "任务中心").With(map[string]any{
|
||||
"id": ctx.Request().QueryInt("id"),
|
||||
"error": err.Error(),
|
||||
}).Info("[面板][TaskController] 查询任务失败")
|
||||
}).Info("查询任务失败")
|
||||
return ErrorSystem(ctx)
|
||||
}
|
||||
|
||||
log := tools.Exec("tail -n 1000 " + task.Log)
|
||||
log, err := tools.Exec("tail -n 1000 " + task.Log)
|
||||
if err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, log)
|
||||
}
|
||||
|
||||
return Success(ctx, log)
|
||||
}
|
||||
@@ -72,10 +75,10 @@ func (r *TaskController) Delete(ctx http.Context) http.Response {
|
||||
var task models.Task
|
||||
_, err := facades.Orm().Query().Where("id", ctx.Request().Input("id")).Delete(&task)
|
||||
if err != nil {
|
||||
facades.Log().With(map[string]any{
|
||||
facades.Log().Request(ctx.Request()).Tags("面板", "任务中心").With(map[string]any{
|
||||
"id": ctx.Request().QueryInt("id"),
|
||||
"error": err.Error(),
|
||||
}).Info("[面板][TaskController] 删除任务失败")
|
||||
}).Info("删除任务失败")
|
||||
return ErrorSystem(ctx)
|
||||
}
|
||||
|
||||
|
||||
@@ -41,9 +41,9 @@ func (r *UserController) Login(ctx http.Context) http.Response {
|
||||
var user models.User
|
||||
err := facades.Orm().Query().Where("username", loginRequest.Username).First(&user)
|
||||
if err != nil {
|
||||
facades.Log().Request(ctx.Request()).With(map[string]any{
|
||||
facades.Log().Request(ctx.Request()).Tags("面板", "用户").With(map[string]any{
|
||||
"error": err.Error(),
|
||||
}).Tags("面板", "用户").Info("查询用户失败")
|
||||
}).Info("查询用户失败")
|
||||
return ErrorSystem(ctx)
|
||||
}
|
||||
|
||||
@@ -54,18 +54,18 @@ func (r *UserController) Login(ctx http.Context) http.Response {
|
||||
if facades.Hash().NeedsRehash(user.Password) {
|
||||
user.Password, err = facades.Hash().Make(loginRequest.Password)
|
||||
if err != nil {
|
||||
facades.Log().Request(ctx.Request()).With(map[string]any{
|
||||
facades.Log().Request(ctx.Request()).Tags("面板", "用户").With(map[string]any{
|
||||
"error": err.Error(),
|
||||
}).Tags("面板", "用户").Info("更新密码失败")
|
||||
}).Info("更新密码失败")
|
||||
return ErrorSystem(ctx)
|
||||
}
|
||||
}
|
||||
|
||||
token, loginErr := facades.Auth().LoginUsingID(ctx, user.ID)
|
||||
if loginErr != nil {
|
||||
facades.Log().Request(ctx.Request()).With(map[string]any{
|
||||
facades.Log().Request(ctx.Request()).Tags("面板", "用户").With(map[string]any{
|
||||
"error": err.Error(),
|
||||
}).Tags("面板", "用户").Info("登录失败")
|
||||
}).Info("登录失败")
|
||||
return ErrorSystem(ctx)
|
||||
}
|
||||
|
||||
@@ -87,9 +87,9 @@ func (r *UserController) Info(ctx http.Context) http.Response {
|
||||
var user models.User
|
||||
err := facades.Auth().User(ctx, &user)
|
||||
if err != nil {
|
||||
facades.Log().Request(ctx.Request()).With(map[string]any{
|
||||
facades.Log().Request(ctx.Request()).Tags("面板", "用户").With(map[string]any{
|
||||
"error": err.Error(),
|
||||
}).Tags("面板", "用户").Info("获取用户信息失败")
|
||||
}).Info("获取用户信息失败")
|
||||
return ErrorSystem(ctx)
|
||||
}
|
||||
|
||||
|
||||
@@ -40,14 +40,14 @@ func NewWebsiteController() *WebsiteController {
|
||||
// @Param data body commonrequests.Paginate true "request"
|
||||
// @Success 200 {object} SuccessResponse{data=responses.List}
|
||||
// @Router /panel/website [get]
|
||||
func (c *WebsiteController) List(ctx http.Context) http.Response {
|
||||
func (r *WebsiteController) List(ctx http.Context) http.Response {
|
||||
var paginateRequest commonrequests.Paginate
|
||||
sanitize := Sanitize(ctx, &paginateRequest)
|
||||
if sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
|
||||
total, websites, err := c.website.List(paginateRequest.Page, paginateRequest.Limit)
|
||||
total, websites, err := r.website.List(paginateRequest.Page, paginateRequest.Limit)
|
||||
if err != nil {
|
||||
facades.Log().Request(ctx.Request()).Tags("面板", "网站管理").With(map[string]any{
|
||||
"error": err.Error(),
|
||||
@@ -72,7 +72,7 @@ func (c *WebsiteController) List(ctx http.Context) http.Response {
|
||||
// @Param data body requests.Add true "request"
|
||||
// @Success 200 {object} SuccessResponse
|
||||
// @Router /panel/website [post]
|
||||
func (c *WebsiteController) Add(ctx http.Context) http.Response {
|
||||
func (r *WebsiteController) Add(ctx http.Context) http.Response {
|
||||
check := Check(ctx, "openresty")
|
||||
if check != nil {
|
||||
return check
|
||||
@@ -83,11 +83,18 @@ func (c *WebsiteController) Add(ctx http.Context) http.Response {
|
||||
return sanitize
|
||||
}
|
||||
|
||||
if len(addRequest.Path) == 0 {
|
||||
addRequest.Path = r.setting.Get(models.SettingKeyWebsitePath) + "/" + addRequest.Name
|
||||
}
|
||||
|
||||
website := services.PanelWebsite{
|
||||
Name: addRequest.Name,
|
||||
Status: true,
|
||||
Domains: addRequest.Domains,
|
||||
Ports: addRequest.Ports,
|
||||
Path: addRequest.Path,
|
||||
Php: addRequest.Php,
|
||||
Ssl: false,
|
||||
Db: addRequest.Db,
|
||||
DbType: addRequest.DbType,
|
||||
DbName: addRequest.DbName,
|
||||
@@ -95,7 +102,7 @@ func (c *WebsiteController) Add(ctx http.Context) http.Response {
|
||||
DbPassword: addRequest.DbPassword,
|
||||
}
|
||||
|
||||
_, err := c.website.Add(website)
|
||||
_, err := r.website.Add(website)
|
||||
if err != nil {
|
||||
facades.Log().Request(ctx.Request()).Tags("面板", "网站管理").With(map[string]any{
|
||||
"error": err.Error(),
|
||||
@@ -117,7 +124,7 @@ func (c *WebsiteController) Add(ctx http.Context) http.Response {
|
||||
// @Param id path int true "网站 ID"
|
||||
// @Success 200 {object} SuccessResponse
|
||||
// @Router /panel/website/{id} [delete]
|
||||
func (c *WebsiteController) Delete(ctx http.Context) http.Response {
|
||||
func (r *WebsiteController) Delete(ctx http.Context) http.Response {
|
||||
check := Check(ctx, "openresty")
|
||||
if check != nil {
|
||||
return check
|
||||
@@ -129,7 +136,7 @@ func (c *WebsiteController) Delete(ctx http.Context) http.Response {
|
||||
return sanitize
|
||||
}
|
||||
|
||||
err := c.website.Delete(idRequest.ID)
|
||||
err := r.website.Delete(idRequest.ID)
|
||||
if err != nil {
|
||||
facades.Log().Request(ctx.Request()).Tags("面板", "网站管理").With(map[string]any{
|
||||
"id": idRequest.ID,
|
||||
@@ -150,7 +157,7 @@ func (c *WebsiteController) Delete(ctx http.Context) http.Response {
|
||||
// @Security BearerToken
|
||||
// @Success 200 {object} SuccessResponse{data=map[string]string}
|
||||
// @Router /panel/website/defaultConfig [get]
|
||||
func (c *WebsiteController) GetDefaultConfig(ctx http.Context) http.Response {
|
||||
func (r *WebsiteController) GetDefaultConfig(ctx http.Context) http.Response {
|
||||
check := Check(ctx, "openresty")
|
||||
if check != nil {
|
||||
return check
|
||||
@@ -175,7 +182,7 @@ func (c *WebsiteController) GetDefaultConfig(ctx http.Context) http.Response {
|
||||
// @Param data body map[string]string true "request"
|
||||
// @Success 200 {object} SuccessResponse
|
||||
// @Router /panel/website/defaultConfig [post]
|
||||
func (c *WebsiteController) SaveDefaultConfig(ctx http.Context) http.Response {
|
||||
func (r *WebsiteController) SaveDefaultConfig(ctx http.Context) http.Response {
|
||||
check := Check(ctx, "openresty")
|
||||
if check != nil {
|
||||
return check
|
||||
@@ -211,7 +218,7 @@ func (c *WebsiteController) SaveDefaultConfig(ctx http.Context) http.Response {
|
||||
// @Param id path int true "网站 ID"
|
||||
// @Success 200 {object} SuccessResponse{data=services.PanelWebsite}
|
||||
// @Router /panel/website/config/{id} [get]
|
||||
func (c *WebsiteController) GetConfig(ctx http.Context) http.Response {
|
||||
func (r *WebsiteController) GetConfig(ctx http.Context) http.Response {
|
||||
check := Check(ctx, "openresty")
|
||||
if check != nil {
|
||||
return check
|
||||
@@ -223,7 +230,7 @@ func (c *WebsiteController) GetConfig(ctx http.Context) http.Response {
|
||||
return sanitize
|
||||
}
|
||||
|
||||
config, err := c.website.GetConfig(idRequest.ID)
|
||||
config, err := r.website.GetConfig(idRequest.ID)
|
||||
if err != nil {
|
||||
facades.Log().Request(ctx.Request()).Tags("面板", "网站管理").With(map[string]any{
|
||||
"id": idRequest.ID,
|
||||
@@ -247,7 +254,7 @@ func (c *WebsiteController) GetConfig(ctx http.Context) http.Response {
|
||||
// @Param data body requests.SaveConfig true "request"
|
||||
// @Success 200 {object} SuccessResponse
|
||||
// @Router /panel/website/config/{id} [post]
|
||||
func (c *WebsiteController) SaveConfig(ctx http.Context) http.Response {
|
||||
func (r *WebsiteController) SaveConfig(ctx http.Context) http.Response {
|
||||
check := Check(ctx, "openresty")
|
||||
if check != nil {
|
||||
return check
|
||||
@@ -259,7 +266,7 @@ func (c *WebsiteController) SaveConfig(ctx http.Context) http.Response {
|
||||
return sanitize
|
||||
}
|
||||
|
||||
err := c.website.SaveConfig(saveConfigRequest)
|
||||
err := r.website.SaveConfig(saveConfigRequest)
|
||||
if err != nil {
|
||||
facades.Log().Request(ctx.Request()).Tags("面板", "网站管理").With(map[string]any{
|
||||
"error": err.Error(),
|
||||
@@ -281,7 +288,7 @@ func (c *WebsiteController) SaveConfig(ctx http.Context) http.Response {
|
||||
// @Param id path int true "网站 ID"
|
||||
// @Success 200 {object} SuccessResponse
|
||||
// @Router /panel/website/log/{id} [delete]
|
||||
func (c *WebsiteController) ClearLog(ctx http.Context) http.Response {
|
||||
func (r *WebsiteController) ClearLog(ctx http.Context) http.Response {
|
||||
check := Check(ctx, "openresty")
|
||||
if check != nil {
|
||||
return check
|
||||
@@ -314,7 +321,7 @@ func (c *WebsiteController) ClearLog(ctx http.Context) http.Response {
|
||||
// @Param id path int true "网站 ID"
|
||||
// @Success 200 {object} SuccessResponse
|
||||
// @Router /panel/website/updateRemark/{id} [post]
|
||||
func (c *WebsiteController) UpdateRemark(ctx http.Context) http.Response {
|
||||
func (r *WebsiteController) UpdateRemark(ctx http.Context) http.Response {
|
||||
var idRequest requests.ID
|
||||
sanitize := Sanitize(ctx, &idRequest)
|
||||
if sanitize != nil {
|
||||
@@ -348,8 +355,8 @@ func (c *WebsiteController) UpdateRemark(ctx http.Context) http.Response {
|
||||
// @Security BearerToken
|
||||
// @Success 200 {object} SuccessResponse{data=[]services.BackupFile}
|
||||
// @Router /panel/website/backupList [get]
|
||||
func (c *WebsiteController) BackupList(ctx http.Context) http.Response {
|
||||
backupList, err := c.backup.WebsiteList()
|
||||
func (r *WebsiteController) BackupList(ctx http.Context) http.Response {
|
||||
backupList, err := r.backup.WebsiteList()
|
||||
if err != nil {
|
||||
facades.Log().Request(ctx.Request()).Tags("面板", "网站管理").With(map[string]any{
|
||||
"error": err.Error(),
|
||||
@@ -371,7 +378,7 @@ func (c *WebsiteController) BackupList(ctx http.Context) http.Response {
|
||||
// @Param data body requests.ID true "request"
|
||||
// @Success 200 {object} SuccessResponse
|
||||
// @Router /panel/website/createBackup [post]
|
||||
func (c *WebsiteController) CreateBackup(ctx http.Context) http.Response {
|
||||
func (r *WebsiteController) CreateBackup(ctx http.Context) http.Response {
|
||||
var idRequest requests.ID
|
||||
sanitize := Sanitize(ctx, &idRequest)
|
||||
if sanitize != nil {
|
||||
@@ -387,7 +394,7 @@ func (c *WebsiteController) CreateBackup(ctx http.Context) http.Response {
|
||||
return ErrorSystem(ctx)
|
||||
}
|
||||
|
||||
if err := c.backup.WebSiteBackup(website); err != nil {
|
||||
if err := r.backup.WebSiteBackup(website); err != nil {
|
||||
facades.Log().Request(ctx.Request()).Tags("面板", "网站管理").With(map[string]any{
|
||||
"id": idRequest.ID,
|
||||
"error": err.Error(),
|
||||
@@ -409,13 +416,13 @@ func (c *WebsiteController) CreateBackup(ctx http.Context) http.Response {
|
||||
// @Param file formData file true "备份文件"
|
||||
// @Success 200 {object} SuccessResponse
|
||||
// @Router /panel/website/uploadBackup [post]
|
||||
func (c *WebsiteController) UploadBackup(ctx http.Context) http.Response {
|
||||
func (r *WebsiteController) UploadBackup(ctx http.Context) http.Response {
|
||||
file, err := ctx.Request().File("file")
|
||||
if err != nil {
|
||||
return Error(ctx, http.StatusUnprocessableEntity, "上传文件失败")
|
||||
return Error(ctx, http.StatusInternalServerError, "上传文件失败")
|
||||
}
|
||||
|
||||
backupPath := c.setting.Get(models.SettingKeyBackupPath) + "/website"
|
||||
backupPath := r.setting.Get(models.SettingKeyBackupPath) + "/website"
|
||||
if !tools.Exists(backupPath) {
|
||||
if err = tools.Mkdir(backupPath, 0644); err != nil {
|
||||
return nil
|
||||
@@ -445,7 +452,7 @@ func (c *WebsiteController) UploadBackup(ctx http.Context) http.Response {
|
||||
// @Param data body requests.RestoreBackup true "request"
|
||||
// @Success 200 {object} SuccessResponse
|
||||
// @Router /panel/website/restoreBackup [post]
|
||||
func (c *WebsiteController) RestoreBackup(ctx http.Context) http.Response {
|
||||
func (r *WebsiteController) RestoreBackup(ctx http.Context) http.Response {
|
||||
var restoreBackupRequest requests.RestoreBackup
|
||||
sanitize := Sanitize(ctx, &restoreBackupRequest)
|
||||
if sanitize != nil {
|
||||
@@ -457,7 +464,7 @@ func (c *WebsiteController) RestoreBackup(ctx http.Context) http.Response {
|
||||
return ErrorSystem(ctx)
|
||||
}
|
||||
|
||||
if err := c.backup.WebsiteRestore(website, restoreBackupRequest.Name); err != nil {
|
||||
if err := r.backup.WebsiteRestore(website, restoreBackupRequest.Name); err != nil {
|
||||
facades.Log().Request(ctx.Request()).Tags("面板", "网站管理").With(map[string]any{
|
||||
"id": restoreBackupRequest.ID,
|
||||
"file": restoreBackupRequest.Name,
|
||||
@@ -480,14 +487,14 @@ func (c *WebsiteController) RestoreBackup(ctx http.Context) http.Response {
|
||||
// @Param data body requests.DeleteBackup true "request"
|
||||
// @Success 200 {object} SuccessResponse
|
||||
// @Router /panel/website/deleteBackup [delete]
|
||||
func (c *WebsiteController) DeleteBackup(ctx http.Context) http.Response {
|
||||
func (r *WebsiteController) DeleteBackup(ctx http.Context) http.Response {
|
||||
var deleteBackupRequest requests.DeleteBackup
|
||||
sanitize := Sanitize(ctx, &deleteBackupRequest)
|
||||
if sanitize != nil {
|
||||
return sanitize
|
||||
}
|
||||
|
||||
backupPath := c.setting.Get(models.SettingKeyBackupPath) + "/website"
|
||||
backupPath := r.setting.Get(models.SettingKeyBackupPath) + "/website"
|
||||
if !tools.Exists(backupPath) {
|
||||
if err := tools.Mkdir(backupPath, 0644); err != nil {
|
||||
return nil
|
||||
@@ -512,7 +519,7 @@ func (c *WebsiteController) DeleteBackup(ctx http.Context) http.Response {
|
||||
// @Param data body requests.ID true "request"
|
||||
// @Success 200 {object} SuccessResponse
|
||||
// @Router /panel/website/resetConfig [post]
|
||||
func (c *WebsiteController) ResetConfig(ctx http.Context) http.Response {
|
||||
func (r *WebsiteController) ResetConfig(ctx http.Context) http.Response {
|
||||
check := Check(ctx, "openresty")
|
||||
if check != nil {
|
||||
return check
|
||||
@@ -603,7 +610,9 @@ server
|
||||
if err := tools.Write("/www/server/vhost/rewrite"+website.Name+".conf", "", 0644); err != nil {
|
||||
return nil
|
||||
}
|
||||
tools.Exec("systemctl reload openresty")
|
||||
if exec, err := tools.Exec("systemctl reload openresty"); err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, exec)
|
||||
}
|
||||
|
||||
return Success(ctx, nil)
|
||||
}
|
||||
@@ -619,7 +628,7 @@ server
|
||||
// @Param id path int true "网站 ID"
|
||||
// @Success 200 {object} SuccessResponse
|
||||
// @Router /panel/website/status/{id} [post]
|
||||
func (c *WebsiteController) Status(ctx http.Context) http.Response {
|
||||
func (r *WebsiteController) Status(ctx http.Context) http.Response {
|
||||
check := Check(ctx, "openresty")
|
||||
if check != nil {
|
||||
return check
|
||||
@@ -672,7 +681,9 @@ func (c *WebsiteController) Status(ctx http.Context) http.Response {
|
||||
if err := tools.Write("/www/server/vhost/"+website.Name+".conf", raw, 0644); err != nil {
|
||||
return ErrorSystem(ctx)
|
||||
}
|
||||
tools.Exec("systemctl reload openresty")
|
||||
if exec, err := tools.Exec("systemctl reload openresty"); err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, exec)
|
||||
}
|
||||
|
||||
return Success(ctx, nil)
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ type Add struct {
|
||||
Name string `form:"name" json:"name"`
|
||||
Domains []string `form:"domains" json:"domains"`
|
||||
Ports []string `form:"ports" json:"ports"`
|
||||
Path string `form:"path" json:"path"`
|
||||
Php int `form:"php" json:"php"`
|
||||
Db bool `form:"db" json:"db"`
|
||||
DbType string `form:"db_type" json:"db_type"`
|
||||
@@ -23,9 +24,10 @@ func (r *Add) Authorize(ctx http.Context) error {
|
||||
|
||||
func (r *Add) Rules(ctx http.Context) map[string]string {
|
||||
return map[string]string{
|
||||
"name": "required|regex:^[a-zA-Z0-9_-]+(\\.[a-zA-Z0-9_-]+)*$|not_exists:websites,name",
|
||||
"name": "required|regex:^[a-zA-Z0-9_-]+(\\.[a-zA-Z0-9_-]+)*$|not_exists:websites,name|not_in:phpmyadmin,mysql,panel,ssh",
|
||||
"domains": "required|slice",
|
||||
"ports": "required|slice",
|
||||
"path": "regex:^/[a-zA-Z0-9_-]+(\\/[a-zA-Z0-9_-]+)*$",
|
||||
"php": "required",
|
||||
"db": "bool",
|
||||
"db_type": "required_if:db,true|in:mysql,postgresql",
|
||||
|
||||
@@ -88,7 +88,9 @@ func (s *BackupImpl) WebSiteBackup(website models.Website) error {
|
||||
}
|
||||
|
||||
backupFile := backupPath + "/" + website.Name + "_" + carbon.Now().ToShortDateTimeString() + ".zip"
|
||||
tools.Exec(`cd '` + website.Path + `' && zip -r '` + backupFile + `' .`)
|
||||
if _, err := tools.Exec(`cd '` + website.Path + `' && zip -r '` + backupFile + `' .`); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -112,8 +114,12 @@ func (s *BackupImpl) WebsiteRestore(website models.Website, backupFile string) e
|
||||
return errors.New("备份文件不存在")
|
||||
}
|
||||
|
||||
tools.Exec(`rm -rf '` + website.Path + `/*'`)
|
||||
tools.Exec(`unzip -o '` + backupFile + `' -d '` + website.Path + `' 2>&1`)
|
||||
if _, err := tools.Exec(`rm -rf '` + website.Path + `/*'`); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := tools.Exec(`unzip -o '` + backupFile + `' -d '` + website.Path + `' 2>&1`); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := tools.Chmod(website.Path, 0755); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -172,12 +178,15 @@ func (s *BackupImpl) MysqlBackup(database string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
tools.Exec("/www/server/mysql/bin/mysqldump -uroot " + database + " > " + backupPath + "/" + backupFile)
|
||||
tools.Exec("cd " + backupPath + " && zip -r " + backupPath + "/" + backupFile + ".zip " + backupFile)
|
||||
if _, err := tools.Exec("/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 {
|
||||
return err
|
||||
}
|
||||
tools.Remove(backupPath + "/" + backupFile)
|
||||
_ = os.Unsetenv("MYSQL_PWD")
|
||||
|
||||
return nil
|
||||
return os.Unsetenv("MYSQL_PWD")
|
||||
}
|
||||
|
||||
// MysqlRestore MySQL恢复
|
||||
@@ -197,26 +206,38 @@ func (s *BackupImpl) MysqlRestore(database string, backupFile string) error {
|
||||
|
||||
switch ext {
|
||||
case ".zip":
|
||||
tools.Exec("unzip -o " + backupFile + " -d " + backupPath)
|
||||
if _, err := tools.Exec("unzip -o " + backupFile + " -d " + backupPath); err != nil {
|
||||
return err
|
||||
}
|
||||
backupFile = strings.TrimSuffix(backupFile, ext)
|
||||
case ".gz":
|
||||
if strings.HasSuffix(backupFile, ".tar.gz") {
|
||||
// 解压.tar.gz文件
|
||||
tools.Exec("tar -zxvf " + backupFile + " -C " + backupPath)
|
||||
if _, err := tools.Exec("tar -zxvf " + backupFile + " -C " + backupPath); err != nil {
|
||||
return err
|
||||
}
|
||||
backupFile = strings.TrimSuffix(backupFile, ".tar.gz")
|
||||
} else {
|
||||
// 解压.gz文件
|
||||
tools.Exec("gzip -d " + backupFile)
|
||||
if _, err := tools.Exec("gzip -d " + backupFile); err != nil {
|
||||
return err
|
||||
}
|
||||
backupFile = strings.TrimSuffix(backupFile, ext)
|
||||
}
|
||||
case ".bz2":
|
||||
tools.Exec("bzip2 -d " + backupFile)
|
||||
if _, err := tools.Exec("bzip2 -d " + backupFile); err != nil {
|
||||
return err
|
||||
}
|
||||
backupFile = strings.TrimSuffix(backupFile, ext)
|
||||
case ".tar":
|
||||
tools.Exec("tar -xvf " + backupFile + " -C " + backupPath)
|
||||
if _, err := tools.Exec("tar -xvf " + backupFile + " -C " + backupPath); err != nil {
|
||||
return err
|
||||
}
|
||||
backupFile = strings.TrimSuffix(backupFile, ext)
|
||||
case ".rar":
|
||||
tools.Exec("unrar x " + backupFile + " " + backupPath)
|
||||
if _, err := tools.Exec("unrar x " + backupFile + " " + backupPath); err != nil {
|
||||
return err
|
||||
}
|
||||
backupFile = strings.TrimSuffix(backupFile, ext)
|
||||
}
|
||||
|
||||
@@ -224,10 +245,11 @@ func (s *BackupImpl) MysqlRestore(database string, backupFile string) error {
|
||||
return errors.New("自动解压失败,请手动解压")
|
||||
}
|
||||
|
||||
tools.Exec("/www/server/mysql/bin/mysql -uroot " + database + " < " + backupFile)
|
||||
_ = os.Unsetenv("MYSQL_PWD")
|
||||
if _, err := tools.Exec("/www/server/mysql/bin/mysql -uroot " + database + " < " + backupFile); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
return os.Unsetenv("MYSQL_PWD")
|
||||
}
|
||||
|
||||
// PostgresqlList PostgreSQL备份列表
|
||||
@@ -273,10 +295,14 @@ func (s *BackupImpl) PostgresqlBackup(database string) error {
|
||||
}
|
||||
}
|
||||
|
||||
tools.Exec(`su - postgres -c "pg_dump ` + database + `" > ` + backupPath + "/" + backupFile)
|
||||
tools.Exec("cd " + backupPath + " && zip -r " + backupPath + "/" + backupFile + ".zip " + backupFile)
|
||||
tools.Remove(backupPath + "/" + backupFile)
|
||||
if _, err := tools.Exec(`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 {
|
||||
return err
|
||||
}
|
||||
|
||||
tools.Remove(backupPath + "/" + backupFile)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -291,26 +317,38 @@ func (s *BackupImpl) PostgresqlRestore(database string, backupFile string) error
|
||||
|
||||
switch ext {
|
||||
case ".zip":
|
||||
tools.Exec("unzip -o " + backupFile + " -d " + backupPath)
|
||||
if _, err := tools.Exec("unzip -o " + backupFile + " -d " + backupPath); err != nil {
|
||||
return err
|
||||
}
|
||||
backupFile = strings.TrimSuffix(backupFile, ext)
|
||||
case ".gz":
|
||||
if strings.HasSuffix(backupFile, ".tar.gz") {
|
||||
// 解压.tar.gz文件
|
||||
tools.Exec("tar -zxvf " + backupFile + " -C " + backupPath)
|
||||
if _, err := tools.Exec("tar -zxvf " + backupFile + " -C " + backupPath); err != nil {
|
||||
return err
|
||||
}
|
||||
backupFile = strings.TrimSuffix(backupFile, ".tar.gz")
|
||||
} else {
|
||||
// 解压.gz文件
|
||||
tools.Exec("gzip -d " + backupFile)
|
||||
if _, err := tools.Exec("gzip -d " + backupFile); err != nil {
|
||||
return err
|
||||
}
|
||||
backupFile = strings.TrimSuffix(backupFile, ext)
|
||||
}
|
||||
case ".bz2":
|
||||
tools.Exec("bzip2 -d " + backupFile)
|
||||
if _, err := tools.Exec("bzip2 -d " + backupFile); err != nil {
|
||||
return err
|
||||
}
|
||||
backupFile = strings.TrimSuffix(backupFile, ext)
|
||||
case ".tar":
|
||||
tools.Exec("tar -xvf " + backupFile + " -C " + backupPath)
|
||||
if _, err := tools.Exec("tar -xvf " + backupFile + " -C " + backupPath); err != nil {
|
||||
return err
|
||||
}
|
||||
backupFile = strings.TrimSuffix(backupFile, ext)
|
||||
case ".rar":
|
||||
tools.Exec("unrar x " + backupFile + " " + backupPath)
|
||||
if _, err := tools.Exec("unrar x " + backupFile + " " + backupPath); err != nil {
|
||||
return err
|
||||
}
|
||||
backupFile = strings.TrimSuffix(backupFile, ext)
|
||||
}
|
||||
|
||||
@@ -318,7 +356,9 @@ func (s *BackupImpl) PostgresqlRestore(database string, backupFile string) error
|
||||
return errors.New("自动解压失败,请手动解压")
|
||||
}
|
||||
|
||||
tools.Exec(`su - postgres -c "psql ` + database + `" < ` + backupFile)
|
||||
if _, err := tools.Exec(`su - postgres -c "psql ` + database + `" < ` + backupFile); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -316,7 +316,9 @@ func (s *CertImpl) ObtainAuto(ID uint) (certificate.Resource, error) {
|
||||
if err := tools.Write("/www/server/vhost/ssl/"+cert.Website.Name+".key", string(ssl.PrivateKey), 0644); err != nil {
|
||||
return certificate.Resource{}, err
|
||||
}
|
||||
tools.Exec("systemctl reload openresty")
|
||||
if _, err := tools.Exec("systemctl reload openresty"); err != nil {
|
||||
return certificate.Resource{}, err
|
||||
}
|
||||
}
|
||||
|
||||
return ssl, nil
|
||||
@@ -374,7 +376,9 @@ func (s *CertImpl) ObtainManual(ID uint) (certificate.Resource, error) {
|
||||
if err := tools.Write("/www/server/vhost/ssl/"+cert.Website.Name+".key", string(ssl.PrivateKey), 0644); err != nil {
|
||||
return certificate.Resource{}, err
|
||||
}
|
||||
tools.Exec("systemctl reload openresty")
|
||||
if _, err := tools.Exec("systemctl reload openresty"); err != nil {
|
||||
return certificate.Resource{}, err
|
||||
}
|
||||
}
|
||||
|
||||
return ssl, nil
|
||||
@@ -479,7 +483,9 @@ func (s *CertImpl) Renew(ID uint) (certificate.Resource, error) {
|
||||
if err := tools.Write("/www/server/vhost/ssl/"+cert.Website.Name+".key", string(ssl.PrivateKey), 0644); err != nil {
|
||||
return certificate.Resource{}, err
|
||||
}
|
||||
tools.Exec("systemctl reload openresty")
|
||||
if _, err := tools.Exec("systemctl reload openresty"); err != nil {
|
||||
return certificate.Resource{}, err
|
||||
}
|
||||
}
|
||||
|
||||
return ssl, nil
|
||||
|
||||
@@ -8,8 +8,8 @@ import (
|
||||
)
|
||||
|
||||
type Cron interface {
|
||||
AddToSystem(cron models.Cron)
|
||||
DeleteFromSystem(cron models.Cron)
|
||||
AddToSystem(cron models.Cron) error
|
||||
DeleteFromSystem(cron models.Cron) error
|
||||
}
|
||||
|
||||
type CronImpl struct {
|
||||
@@ -20,25 +20,45 @@ func NewCronImpl() *CronImpl {
|
||||
}
|
||||
|
||||
// AddToSystem 添加到系统
|
||||
func (r *CronImpl) AddToSystem(cron models.Cron) {
|
||||
func (r *CronImpl) AddToSystem(cron models.Cron) error {
|
||||
if tools.IsRHEL() {
|
||||
tools.Exec("echo \"" + cron.Time + " " + cron.Shell + " >> " + cron.Log + " 2>&1\" >> /var/spool/cron/root")
|
||||
tools.Exec("systemctl restart crond")
|
||||
if _, err := tools.Exec("echo \"" + cron.Time + " " + cron.Shell + " >> " + cron.Log + " 2>&1\" >> /var/spool/cron/root"); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := tools.Exec("systemctl restart crond"); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
tools.Exec("echo \"" + cron.Time + " " + cron.Shell + " >> " + cron.Log + " 2>&1\" >> /var/spool/cron/crontabs/root")
|
||||
tools.Exec("systemctl restart cron")
|
||||
if _, err := tools.Exec("echo \"" + cron.Time + " " + cron.Shell + " >> " + cron.Log + " 2>&1\" >> /var/spool/cron/crontabs/root"); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := tools.Exec("systemctl restart cron"); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeleteFromSystem 从系统中删除
|
||||
func (r *CronImpl) DeleteFromSystem(cron models.Cron) {
|
||||
func (r *CronImpl) DeleteFromSystem(cron models.Cron) error {
|
||||
// 需要转义Shell路径的/为\/
|
||||
cron.Shell = strings.ReplaceAll(cron.Shell, "/", "\\/")
|
||||
if tools.IsRHEL() {
|
||||
tools.Exec("sed -i '/" + cron.Shell + "/d' /var/spool/cron/root")
|
||||
tools.Exec("systemctl restart crond")
|
||||
if _, err := tools.Exec("sed -i '/" + cron.Shell + "/d' /var/spool/cron/root"); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := tools.Exec("systemctl restart crond"); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
tools.Exec("sed -i '/" + cron.Shell + "/d' /var/spool/cron/crontabs/root")
|
||||
tools.Exec("systemctl restart cron")
|
||||
if _, err := tools.Exec("sed -i '/" + cron.Shell + "/d' /var/spool/cron/crontabs/root"); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := tools.Exec("systemctl restart cron"); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -11,7 +11,6 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/goravel/framework/facades"
|
||||
"golang.org/x/exp/slices"
|
||||
requests "panel/app/http/requests/website"
|
||||
|
||||
"panel/app/models"
|
||||
@@ -95,24 +94,6 @@ func (r *WebsiteImpl) List(page, limit int) (int64, []models.Website, error) {
|
||||
|
||||
// Add 添加网站
|
||||
func (r *WebsiteImpl) Add(website PanelWebsite) (models.Website, error) {
|
||||
// 禁止部分保留名称
|
||||
nameSlices := []string{"phpmyadmin", "mysql", "panel", "ssh"}
|
||||
if slices.Contains(nameSlices, website.Name) {
|
||||
return models.Website{}, errors.New("网站名称" + website.Name + "为保留名称,请更换")
|
||||
}
|
||||
|
||||
// path为空时,设置默认值
|
||||
if len(website.Path) == 0 {
|
||||
website.Path = r.setting.Get(models.SettingKeyWebsitePath) + "/" + website.Name
|
||||
}
|
||||
// path不为/开头时,返回错误
|
||||
if website.Path[0] != '/' {
|
||||
return models.Website{}, errors.New("网站路径" + website.Path + "必须以/开头")
|
||||
}
|
||||
|
||||
website.Ssl = false
|
||||
website.Status = true
|
||||
|
||||
w := models.Website{
|
||||
Name: website.Name,
|
||||
Status: website.Status,
|
||||
@@ -295,20 +276,38 @@ server
|
||||
return models.Website{}, err
|
||||
}
|
||||
|
||||
tools.Exec("systemctl reload openresty")
|
||||
if _, err := tools.Exec("systemctl reload openresty"); err != nil {
|
||||
return models.Website{}, err
|
||||
}
|
||||
|
||||
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;"`)
|
||||
if _, err := 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;"`); err != nil {
|
||||
return models.Website{}, err
|
||||
}
|
||||
if _, err := tools.Exec(`/www/server/mysql/bin/mysql -uroot -p` + rootPassword + ` -e "CREATE USER '` + website.DbUser + `'@'localhost' IDENTIFIED BY '` + website.DbPassword + `';"`); err != nil {
|
||||
return models.Website{}, err
|
||||
}
|
||||
if _, err := tools.Exec(`/www/server/mysql/bin/mysql -uroot -p` + rootPassword + ` -e "GRANT ALL PRIVILEGES ON ` + website.DbName + `.* TO '` + website.DbUser + `'@'localhost';"`); err != nil {
|
||||
return models.Website{}, err
|
||||
}
|
||||
if _, err := tools.Exec(`/www/server/mysql/bin/mysql -uroot -p` + rootPassword + ` -e "FLUSH PRIVILEGES;"`); err != nil {
|
||||
return models.Website{}, err
|
||||
}
|
||||
}
|
||||
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"`)
|
||||
if _, err := tools.Exec(`echo "CREATE DATABASE ` + website.DbName + `;" | su - postgres -c "psql"`); err != nil {
|
||||
return models.Website{}, err
|
||||
}
|
||||
if _, err := tools.Exec(`echo "CREATE USER ` + website.DbUser + ` WITH PASSWORD '` + website.DbPassword + `';" | su - postgres -c "psql"`); err != nil {
|
||||
return models.Website{}, err
|
||||
}
|
||||
if _, err := tools.Exec(`echo "ALTER DATABASE ` + website.DbName + ` OWNER TO ` + website.DbUser + `;" | su - postgres -c "psql"`); err != nil {
|
||||
return models.Website{}, err
|
||||
}
|
||||
if _, err := tools.Exec(`echo "GRANT ALL PRIVILEGES ON DATABASE ` + website.DbName + ` TO ` + website.DbUser + `;" | su - postgres -c "psql"`); err != nil {
|
||||
return models.Website{}, err
|
||||
}
|
||||
}
|
||||
|
||||
return w, nil
|
||||
@@ -331,7 +330,10 @@ func (r *WebsiteImpl) SaveConfig(config requests.SaveConfig) error {
|
||||
if err := tools.Write("/www/server/vhost/"+website.Name+".conf", config.Raw, 0644); err != nil {
|
||||
return err
|
||||
}
|
||||
tools.Exec("systemctl reload openresty")
|
||||
if _, err := tools.Exec("systemctl reload openresty"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -509,8 +511,9 @@ func (r *WebsiteImpl) SaveConfig(config requests.SaveConfig) error {
|
||||
if err := tools.Write("/www/server/vhost/rewrite/"+website.Name+".conf", config.Rewrite, 0644); err != nil {
|
||||
return err
|
||||
}
|
||||
tools.Exec("systemctl reload openresty")
|
||||
return nil
|
||||
|
||||
_, err := tools.Exec("systemctl reload openresty")
|
||||
return err
|
||||
}
|
||||
|
||||
// Delete 删除网站
|
||||
@@ -534,9 +537,8 @@ func (r *WebsiteImpl) Delete(id uint) error {
|
||||
tools.Remove("/www/server/vhost/ssl/" + website.Name + ".key")
|
||||
tools.Remove(website.Path)
|
||||
|
||||
tools.Exec("systemctl reload openresty")
|
||||
|
||||
return nil
|
||||
_, err := tools.Exec("systemctl reload openresty")
|
||||
return err
|
||||
}
|
||||
|
||||
// GetConfig 获取网站配置
|
||||
@@ -630,9 +632,10 @@ func (r *WebsiteImpl) GetConfig(id uint) (WebsiteSetting, error) {
|
||||
}
|
||||
|
||||
setting.Rewrite = tools.Read("/www/server/vhost/rewrite/" + website.Name + ".conf")
|
||||
setting.Log = tools.Escape(tools.Exec(`tail -n 100 '/www/wwwlogs/` + website.Name + `.log'`))
|
||||
log, err := tools.Exec(`tail -n 100 '/www/wwwlogs/` + website.Name + `.log'`)
|
||||
setting.Log = log
|
||||
|
||||
return setting, nil
|
||||
return setting, err
|
||||
}
|
||||
|
||||
// GetConfigByName 根据网站名称获取网站配置
|
||||
|
||||
12
go.mod
12
go.mod
@@ -8,8 +8,8 @@ require (
|
||||
github.com/go-acme/lego/v4 v4.14.2
|
||||
github.com/gookit/color v1.5.4
|
||||
github.com/gookit/validate v1.5.1
|
||||
github.com/goravel/fiber v1.1.11-0.20231108081345-36e967f101d0
|
||||
github.com/goravel/framework v1.13.1-0.20231110075143-376f1d9f92e1
|
||||
github.com/goravel/fiber v1.1.11-0.20231113090419-d5dad0a0021b
|
||||
github.com/goravel/framework v1.13.1-0.20231113084434-6b10569a75f5
|
||||
github.com/iancoleman/strcase v0.3.0
|
||||
github.com/imroc/req/v3 v3.42.1
|
||||
github.com/mojocn/base64Captcha v1.3.5
|
||||
@@ -19,8 +19,7 @@ require (
|
||||
github.com/swaggo/files/v2 v2.0.0
|
||||
github.com/swaggo/swag v1.16.2
|
||||
github.com/valyala/fasthttp v1.50.0
|
||||
golang.org/x/crypto v0.14.0
|
||||
golang.org/x/exp v0.0.0-20231006140011-7918f672742d
|
||||
golang.org/x/crypto v0.15.0
|
||||
)
|
||||
|
||||
require (
|
||||
@@ -81,9 +80,9 @@ require (
|
||||
github.com/gofiber/utils v1.1.0 // indirect
|
||||
github.com/gogo/protobuf v1.3.2 // indirect
|
||||
github.com/golang-jwt/jwt/v4 v4.5.0 // indirect
|
||||
github.com/golang-jwt/jwt/v5 v5.0.0 // indirect
|
||||
github.com/golang-jwt/jwt/v5 v5.1.0 // indirect
|
||||
github.com/golang-migrate/migrate/v4 v4.16.2 // indirect
|
||||
github.com/golang-module/carbon/v2 v2.2.12 // indirect
|
||||
github.com/golang-module/carbon/v2 v2.2.13 // indirect
|
||||
github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 // indirect
|
||||
github.com/golang-sql/sqlexp v0.1.0 // indirect
|
||||
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect
|
||||
@@ -190,6 +189,7 @@ require (
|
||||
go.uber.org/atomic v1.11.0 // indirect
|
||||
go.uber.org/multierr v1.9.0 // indirect
|
||||
golang.org/x/arch v0.6.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20231006140011-7918f672742d // indirect
|
||||
golang.org/x/image v0.11.0 // indirect
|
||||
golang.org/x/mod v0.14.0 // indirect
|
||||
golang.org/x/net v0.17.0 // indirect
|
||||
|
||||
21
go.sum
21
go.sum
@@ -269,12 +269,13 @@ github.com/golang-jwt/jwt/v4 v4.0.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzw
|
||||
github.com/golang-jwt/jwt/v4 v4.4.3/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
|
||||
github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg=
|
||||
github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
|
||||
github.com/golang-jwt/jwt/v5 v5.0.0 h1:1n1XNM9hk7O9mnQoNBGolZvzebBQ7p93ULHRc28XJUE=
|
||||
github.com/golang-jwt/jwt/v5 v5.0.0/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
|
||||
github.com/golang-jwt/jwt/v5 v5.1.0 h1:UGKbA/IPjtS6zLcdB7i5TyACMgSbOTiR8qzXgw8HWQU=
|
||||
github.com/golang-jwt/jwt/v5 v5.1.0/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
|
||||
github.com/golang-migrate/migrate/v4 v4.16.2 h1:8coYbMKUyInrFk1lfGfRovTLAW7PhWp8qQDT2iKfuoA=
|
||||
github.com/golang-migrate/migrate/v4 v4.16.2/go.mod h1:pfcJX4nPHaVdc5nmdCikFBWtm+UBpiZjRNNsyBbp0/o=
|
||||
github.com/golang-module/carbon/v2 v2.2.12 h1:qydcu64b5+29dOnMNVS27V3JaphyA2eLrUvKv8CNPMI=
|
||||
github.com/golang-module/carbon/v2 v2.2.12/go.mod h1:XDALX7KgqmHk95xyLeaqX9/LJGbfLATyruTziq68SZ8=
|
||||
github.com/golang-module/carbon/v2 v2.2.13 h1:8BzSrasTFP4sIXA78i4I4LxxlIxetwGOUGu/+WfjdVg=
|
||||
github.com/golang-module/carbon/v2 v2.2.13/go.mod h1:XDALX7KgqmHk95xyLeaqX9/LJGbfLATyruTziq68SZ8=
|
||||
github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 h1:au07oEsX2xN0ktxqI+Sida1w446QrXBRJ0nee3SNZlA=
|
||||
github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0=
|
||||
github.com/golang-sql/sqlexp v0.1.0 h1:ZCD6MBpcuOVfGVqsEmY5/4FtYiKz6tSyUv9LPEDei6A=
|
||||
@@ -379,14 +380,14 @@ github.com/gookit/goutil v0.6.14 h1:96elyOG4BvVoDaiT7vx1vHPrVyEtFfYlPPBODR0/FGQ=
|
||||
github.com/gookit/goutil v0.6.14/go.mod h1:YyDBddefmjS+mU2PDPgCcjVzTDM5WgExiDv5ZA/b8I8=
|
||||
github.com/gookit/validate v1.5.1 h1:rPp64QZQJM+fysGFAhKpvekQAav4Ok6sjfTs9ZtxcpA=
|
||||
github.com/gookit/validate v1.5.1/go.mod h1:SskOHUQokzMNt6T3r7N+N/4me/6fxDx+tmoXf/3ZQog=
|
||||
github.com/goravel/fiber v1.1.11-0.20231108081345-36e967f101d0 h1:mEuJdUWmNXIrg5njcbOS+GucmOM2QrqAHL+ODTgDHPo=
|
||||
github.com/goravel/fiber v1.1.11-0.20231108081345-36e967f101d0/go.mod h1:IOvZ0G1bojUU/Kv9DZl+/8cwGhcNr0YRhwElz0hpjTg=
|
||||
github.com/goravel/fiber v1.1.11-0.20231113090419-d5dad0a0021b h1:RPUhnDbyVmyl7CJhIyqxQMX7KlQfmxkiJ8BT5vgh2q4=
|
||||
github.com/goravel/fiber v1.1.11-0.20231113090419-d5dad0a0021b/go.mod h1:oWPUDnztciFw4cSAk5CskLXYE0Joe9fWQanLNR39tIA=
|
||||
github.com/goravel/file-rotatelogs v0.0.0-20211215053220-2ab31dd9575c h1:obhFK91JAhcf7s6h5sggZishm1VyGW/gBCreo+7/SwQ=
|
||||
github.com/goravel/file-rotatelogs v0.0.0-20211215053220-2ab31dd9575c/go.mod h1:YSWsLXlG16u5CWFaXNZHhEQD10+NwF3xfgDV816OwLE=
|
||||
github.com/goravel/file-rotatelogs/v2 v2.4.1 h1:ogkeIFcTHSBRUBpZYiyJbpul8hkVXxHPuDbOaP78O1M=
|
||||
github.com/goravel/file-rotatelogs/v2 v2.4.1/go.mod h1:euk9qr52WrzM8ICs1hecFcR4CZ/ZZOPdacHfvHgbOf0=
|
||||
github.com/goravel/framework v1.13.1-0.20231110075143-376f1d9f92e1 h1:J0FjRp0EGsyno2XNfUHIz2ghuE0dyg2/VUlR10/KRZA=
|
||||
github.com/goravel/framework v1.13.1-0.20231110075143-376f1d9f92e1/go.mod h1:9vNb8pNm1HBF/1I4SOD88F5rP+/SvzrniJDx9t15OzU=
|
||||
github.com/goravel/framework v1.13.1-0.20231113084434-6b10569a75f5 h1:Vh3xNLjnFyeJ+xecIE/FeISIV3ti+tuiKcntN0bKP5Y=
|
||||
github.com/goravel/framework v1.13.1-0.20231113084434-6b10569a75f5/go.mod h1:EOMHWx6zpEgu12vIVglYuq1zNH/SXo+zeWsumY0esgo=
|
||||
github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4=
|
||||
github.com/gorilla/sessions v1.2.1/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM=
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 h1:UH//fgunKIs4JdUbpDl1VZCDaL56wXCB/5+wF6uHfaI=
|
||||
@@ -744,8 +745,8 @@ golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58
|
||||
golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
|
||||
golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0=
|
||||
golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw=
|
||||
golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc=
|
||||
golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4=
|
||||
golang.org/x/crypto v0.15.0 h1:frVn1TEaCEaZcn3Tmd7Y2b5KKPaZ+I32Q2OA3kYp5TA=
|
||||
golang.org/x/crypto v0.15.0/go.mod h1:4ChreQoLWfG3xLDer1WdlH5NdlQ3+mwnQq1YTKY+72g=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
||||
@@ -937,7 +938,7 @@ golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||
golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U=
|
||||
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
|
||||
golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU=
|
||||
golang.org/x/term v0.13.0 h1:bb+I9cTfFazGW51MZqBVmZy7+JEJMouUHTUSKVQLBek=
|
||||
golang.org/x/term v0.14.0 h1:LGK9IlZ8T9jvdy6cTdfKUCltatMFOehAQo9SRC46UQ8=
|
||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
|
||||
33
pkg/tools/service.go
Normal file
33
pkg/tools/service.go
Normal file
@@ -0,0 +1,33 @@
|
||||
package tools
|
||||
|
||||
import "fmt"
|
||||
|
||||
// ServiceStatus 获取服务状态
|
||||
func ServiceStatus(name string) (bool, error) {
|
||||
output, err := Exec(fmt.Sprintf("systemctl status %s | grep Active | grep -v grep | awk '{print $2}'", name))
|
||||
return output == "active", err
|
||||
}
|
||||
|
||||
// ServiceStart 启动服务
|
||||
func ServiceStart(name string) error {
|
||||
_, err := Exec(fmt.Sprintf("systemctl start %s", name))
|
||||
return err
|
||||
}
|
||||
|
||||
// ServiceStop 停止服务
|
||||
func ServiceStop(name string) error {
|
||||
_, err := Exec(fmt.Sprintf("systemctl stop %s", name))
|
||||
return err
|
||||
}
|
||||
|
||||
// ServiceRestart 重启服务
|
||||
func ServiceRestart(name string) error {
|
||||
_, err := Exec(fmt.Sprintf("systemctl restart %s", name))
|
||||
return err
|
||||
}
|
||||
|
||||
// ServiceReload 重载服务
|
||||
func ServiceReload(name string) error {
|
||||
_, err := Exec(fmt.Sprintf("systemctl reload %s", name))
|
||||
return err
|
||||
}
|
||||
@@ -7,7 +7,6 @@ import (
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/goravel/framework/facades"
|
||||
"github.com/goravel/framework/support"
|
||||
)
|
||||
|
||||
@@ -26,13 +25,10 @@ func Write(path string, data string, permission os.FileMode) error {
|
||||
}
|
||||
|
||||
// Read 读取文件
|
||||
// TODO 重构带 error 返回
|
||||
func Read(path string) string {
|
||||
data, err := os.ReadFile(path)
|
||||
if err != nil {
|
||||
facades.Log().With(map[string]any{
|
||||
"path": path,
|
||||
"error": err.Error(),
|
||||
}).Tags("面板", "工具函数").Info("读取文件失败")
|
||||
return ""
|
||||
}
|
||||
|
||||
@@ -40,12 +36,9 @@ func Read(path string) string {
|
||||
}
|
||||
|
||||
// Remove 删除文件/目录
|
||||
// TODO 重构带 error 返回
|
||||
func Remove(path string) bool {
|
||||
if err := os.RemoveAll(path); err != nil {
|
||||
facades.Log().With(map[string]any{
|
||||
"path": path,
|
||||
"error": err.Error(),
|
||||
}).Tags("面板", "工具函数").Info("删除文件/目录失败")
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -53,25 +46,11 @@ func Remove(path string) bool {
|
||||
}
|
||||
|
||||
// Exec 执行 shell 命令
|
||||
func Exec(shell string) string {
|
||||
cmd := exec.Command("bash", "-c", shell)
|
||||
func Exec(shell string) (string, error) {
|
||||
cmd := exec.Command("bash", "-c", "LC_ALL=C "+shell)
|
||||
|
||||
output, err := cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
if support.Env == support.EnvTest {
|
||||
fmt.Println(string(output))
|
||||
fmt.Println(err.Error())
|
||||
panic(err)
|
||||
} else {
|
||||
facades.Log().With(map[string]any{
|
||||
"shell": shell,
|
||||
"error": err.Error(),
|
||||
}).Tags("面板", "工具函数").Info("执行命令失败")
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
return strings.TrimSpace(string(output))
|
||||
return strings.TrimSpace(string(output)), err
|
||||
}
|
||||
|
||||
// ExecAsync 异步执行 shell 命令
|
||||
@@ -88,11 +67,6 @@ func ExecAsync(shell string) error {
|
||||
if support.Env == support.EnvTest {
|
||||
fmt.Println(err.Error())
|
||||
panic(err)
|
||||
} else {
|
||||
facades.Log().With(map[string]any{
|
||||
"shell": shell,
|
||||
"error": err.Error(),
|
||||
}).Tags("面板", "工具函数").Info("异步执行命令失败")
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
@@ -48,7 +48,9 @@ func (s *SystemHelperTestSuite) TestRemove() {
|
||||
}
|
||||
|
||||
func (s *SystemHelperTestSuite) TestExec() {
|
||||
s.Equal("test", Exec("echo 'test'"))
|
||||
output, err := Exec("echo 'test'")
|
||||
s.Equal("test", output)
|
||||
s.Nil(err)
|
||||
}
|
||||
|
||||
func (s *SystemHelperTestSuite) TestExecAsync() {
|
||||
|
||||
@@ -165,15 +165,16 @@ type PanelInfo struct {
|
||||
func GetLatestPanelVersion() (PanelInfo, error) {
|
||||
var info PanelInfo
|
||||
var output string
|
||||
var err error
|
||||
isChina := IsChina()
|
||||
|
||||
if isChina {
|
||||
output = Exec(`curl -sSL "https://jihulab.com/api/v4/projects/haozi-team%2Fpanel/releases/permalink/latest"`)
|
||||
output, err = Exec(`curl -sSL "https://jihulab.com/api/v4/projects/haozi-team%2Fpanel/releases/permalink/latest"`)
|
||||
} else {
|
||||
output = Exec(`curl -sSL "https://api.github.com/repos/haozi-team/panel/releases/latest"`)
|
||||
output, err = Exec(`curl -sSL "https://api.github.com/repos/haozi-team/panel/releases/latest"`)
|
||||
}
|
||||
|
||||
if len(output) == 0 {
|
||||
if len(output) == 0 || err != nil {
|
||||
return info, errors.New("获取最新版本失败")
|
||||
}
|
||||
|
||||
@@ -194,32 +195,72 @@ func GetLatestPanelVersion() (PanelInfo, error) {
|
||||
|
||||
var name, version, body, date, downloadName, downloadUrl, checksums, checksumsUrl string
|
||||
if isChina {
|
||||
name = Exec("jq -r '.name' " + fileName)
|
||||
version = Exec("jq -r '.tag_name' " + fileName)
|
||||
body = Exec("jq -r '.description' " + fileName)
|
||||
date = Exec("jq -r '.created_at' " + fileName)
|
||||
checksums = Exec("jq -r '.assets.links[] | select(.name | contains(\"checksums\")) | .name' " + fileName)
|
||||
checksumsUrl = Exec("jq -r '.assets.links[] | select(.name | contains(\"checksums\")) | .direct_asset_url' " + fileName)
|
||||
if name, err = Exec("jq -r '.name' " + fileName); err != nil {
|
||||
return info, errors.New("获取最新版本失败")
|
||||
}
|
||||
if version, err = Exec("jq -r '.tag_name' " + fileName); err != nil {
|
||||
return info, errors.New("获取最新版本失败")
|
||||
}
|
||||
if body, err = Exec("jq -r '.description' " + fileName); err != nil {
|
||||
return info, errors.New("获取最新版本失败")
|
||||
}
|
||||
if date, err = Exec("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 {
|
||||
return info, errors.New("获取最新版本失败")
|
||||
}
|
||||
if checksumsUrl, err = Exec("jq -r '.assets.links[] | select(.name | contains(\"checksums\")) | .direct_asset_url' " + fileName); err != nil {
|
||||
return info, errors.New("获取最新版本失败")
|
||||
}
|
||||
if IsArm() {
|
||||
downloadName = Exec("jq -r '.assets.links[] | select(.name | contains(\"arm64\")) | .name' " + fileName)
|
||||
downloadUrl = Exec("jq -r '.assets.links[] | select(.name | contains(\"arm64\")) | .direct_asset_url' " + fileName)
|
||||
if downloadName, err = Exec("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 {
|
||||
return info, errors.New("获取最新版本失败")
|
||||
}
|
||||
} else {
|
||||
downloadName = Exec("jq -r '.assets.links[] | select(.name | contains(\"amd64v2\")) | .name' " + fileName)
|
||||
downloadUrl = Exec("jq -r '.assets.links[] | select(.name | contains(\"amd64v2\")) | .direct_asset_url' " + fileName)
|
||||
if downloadName, err = Exec("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 {
|
||||
return info, errors.New("获取最新版本失败")
|
||||
}
|
||||
}
|
||||
} else {
|
||||
name = Exec("jq -r '.name' " + fileName)
|
||||
version = Exec("jq -r '.tag_name' " + fileName)
|
||||
body = Exec("jq -r '.body' " + fileName)
|
||||
date = Exec("jq -r '.published_at' " + fileName)
|
||||
checksums = Exec("jq -r '.assets[] | select(.name | contains(\"checksums\")) | .name' " + fileName)
|
||||
checksumsUrl = Exec("jq -r '.assets[] | select(.name | contains(\"checksums\")) | .browser_download_url' " + fileName)
|
||||
if name, err = Exec("jq -r '.name' " + fileName); err != nil {
|
||||
return info, errors.New("获取最新版本失败")
|
||||
}
|
||||
if version, err = Exec("jq -r '.tag_name' " + fileName); err != nil {
|
||||
return info, errors.New("获取最新版本失败")
|
||||
}
|
||||
if body, err = Exec("jq -r '.body' " + fileName); err != nil {
|
||||
return info, errors.New("获取最新版本失败")
|
||||
}
|
||||
if date, err = Exec("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 {
|
||||
return info, errors.New("获取最新版本失败")
|
||||
}
|
||||
if checksumsUrl, err = Exec("jq -r '.assets[] | select(.name | contains(\"checksums\")) | .browser_download_url' " + fileName); err != nil {
|
||||
return info, errors.New("获取最新版本失败")
|
||||
}
|
||||
if IsArm() {
|
||||
downloadName = Exec("jq -r '.assets[] | select(.name | contains(\"arm64\")) | .name' " + fileName)
|
||||
downloadUrl = Exec("jq -r '.assets[] | select(.name | contains(\"arm64\")) | .browser_download_url' " + fileName)
|
||||
if downloadName, err = Exec("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 {
|
||||
return info, errors.New("获取最新版本失败")
|
||||
}
|
||||
} else {
|
||||
downloadName = Exec("jq -r '.assets[] | select(.name | contains(\"amd64v2\")) | .name' " + fileName)
|
||||
downloadUrl = Exec("jq -r '.assets[] | select(.name | contains(\"amd64v2\")) | .browser_download_url' " + fileName)
|
||||
if downloadName, err = Exec("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 {
|
||||
return info, errors.New("获取最新版本失败")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -239,6 +280,7 @@ func GetLatestPanelVersion() (PanelInfo, error) {
|
||||
func GetPanelVersion(version string) (PanelInfo, error) {
|
||||
var info PanelInfo
|
||||
var output string
|
||||
var err error
|
||||
isChina := IsChina()
|
||||
|
||||
if !strings.HasPrefix(version, "v") {
|
||||
@@ -246,12 +288,12 @@ func GetPanelVersion(version string) (PanelInfo, error) {
|
||||
}
|
||||
|
||||
if isChina {
|
||||
output = Exec(`curl -sSL "https://jihulab.com/api/v4/projects/haozi-team%2Fpanel/releases/` + version + `"`)
|
||||
output, err = Exec(`curl -sSL "https://jihulab.com/api/v4/projects/haozi-team%2Fpanel/releases/` + version + `"`)
|
||||
} else {
|
||||
output = Exec(`curl -sSL "https://api.github.com/repos/haozi-team/panel/releases/tags/` + version + `"`)
|
||||
output, err = Exec(`curl -sSL "https://api.github.com/repos/haozi-team/panel/releases/tags/` + version + `"`)
|
||||
}
|
||||
|
||||
if len(output) == 0 {
|
||||
if len(output) == 0 || err != nil {
|
||||
return info, errors.New("获取面板版本失败")
|
||||
}
|
||||
|
||||
@@ -272,32 +314,72 @@ func GetPanelVersion(version string) (PanelInfo, error) {
|
||||
|
||||
var name, version2, body, date, downloadName, downloadUrl, checksums, checksumsUrl string
|
||||
if isChina {
|
||||
name = Exec("jq -r '.name' " + fileName)
|
||||
version2 = Exec("jq -r '.tag_name' " + fileName)
|
||||
body = Exec("jq -r '.description' " + fileName)
|
||||
date = Exec("jq -r '.created_at' " + fileName)
|
||||
checksums = Exec("jq -r '.assets.links[] | select(.name | contains(\"checksums\")) | .name' " + fileName)
|
||||
checksumsUrl = Exec("jq -r '.assets.links[] | select(.name | contains(\"checksums\")) | .direct_asset_url' " + fileName)
|
||||
if name, err = Exec("jq -r '.name' " + fileName); err != nil {
|
||||
return info, errors.New("获取面板版本失败")
|
||||
}
|
||||
if version2, err = Exec("jq -r '.tag_name' " + fileName); err != nil {
|
||||
return info, errors.New("获取面板版本失败")
|
||||
}
|
||||
if body, err = Exec("jq -r '.description' " + fileName); err != nil {
|
||||
return info, errors.New("获取面板版本失败")
|
||||
}
|
||||
if date, err = Exec("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 {
|
||||
return info, errors.New("获取面板版本失败")
|
||||
}
|
||||
if checksumsUrl, err = Exec("jq -r '.assets.links[] | select(.name | contains(\"checksums\")) | .direct_asset_url' " + fileName); err != nil {
|
||||
return info, errors.New("获取面板版本失败")
|
||||
}
|
||||
if IsArm() {
|
||||
downloadName = Exec("jq -r '.assets.links[] | select(.name | contains(\"arm64\")) | .name' " + fileName)
|
||||
downloadUrl = Exec("jq -r '.assets.links[] | select(.name | contains(\"arm64\")) | .direct_asset_url' " + fileName)
|
||||
if downloadName, err = Exec("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 {
|
||||
return info, errors.New("获取面板版本失败")
|
||||
}
|
||||
} else {
|
||||
downloadName = Exec("jq -r '.assets.links[] | select(.name | contains(\"amd64v2\")) | .name' " + fileName)
|
||||
downloadUrl = Exec("jq -r '.assets.links[] | select(.name | contains(\"amd64v2\")) | .direct_asset_url' " + fileName)
|
||||
if downloadName, err = Exec("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 {
|
||||
return info, errors.New("获取面板版本失败")
|
||||
}
|
||||
}
|
||||
} else {
|
||||
name = Exec("jq -r '.name' " + fileName)
|
||||
version2 = Exec("jq -r '.tag_name' " + fileName)
|
||||
body = Exec("jq -r '.body' " + fileName)
|
||||
date = Exec("jq -r '.published_at' " + fileName)
|
||||
checksums = Exec("jq -r '.assets[] | select(.name | contains(\"checksums\")) | .name' " + fileName)
|
||||
checksumsUrl = Exec("jq -r '.assets[] | select(.name | contains(\"checksums\")) | .browser_download_url' " + fileName)
|
||||
if name, err = Exec("jq -r '.name' " + fileName); err != nil {
|
||||
return info, errors.New("获取面板版本失败")
|
||||
}
|
||||
if version2, err = Exec("jq -r '.tag_name' " + fileName); err != nil {
|
||||
return info, errors.New("获取面板版本失败")
|
||||
}
|
||||
if body, err = Exec("jq -r '.body' " + fileName); err != nil {
|
||||
return info, errors.New("获取面板版本失败")
|
||||
}
|
||||
if date, err = Exec("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 {
|
||||
return info, errors.New("获取面板版本失败")
|
||||
}
|
||||
if checksumsUrl, err = Exec("jq -r '.assets[] | select(.name | contains(\"checksums\")) | .browser_download_url' " + fileName); err != nil {
|
||||
return info, errors.New("获取面板版本失败")
|
||||
}
|
||||
if IsArm() {
|
||||
downloadName = Exec("jq -r '.assets[] | select(.name | contains(\"arm64\")) | .name' " + fileName)
|
||||
downloadUrl = Exec("jq -r '.assets[] | select(.name | contains(\"arm64\")) | .browser_download_url' " + fileName)
|
||||
if downloadName, err = Exec("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 {
|
||||
return info, errors.New("获取面板版本失败")
|
||||
}
|
||||
} else {
|
||||
downloadName = Exec("jq -r '.assets[] | select(.name | contains(\"amd64v2\")) | .name' " + fileName)
|
||||
downloadUrl = Exec("jq -r '.assets[] | select(.name | contains(\"amd64v2\")) | .browser_download_url' " + fileName)
|
||||
if downloadName, err = Exec("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 {
|
||||
return info, errors.New("获取面板版本失败")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -319,58 +401,100 @@ func UpdatePanel(panelInfo PanelInfo) error {
|
||||
color.Greenln("下载链接: " + panelInfo.DownloadUrl)
|
||||
|
||||
color.Greenln("备份面板配置...")
|
||||
Exec("cp -f /www/panel/database/panel.db /tmp/panel.db.bak")
|
||||
Exec("cp -f /www/panel/panel.conf /tmp/panel.conf.bak")
|
||||
if _, err := Exec("cp -f /www/panel/database/panel.db /tmp/panel.db.bak"); err != nil {
|
||||
color.Redln("备份面板数据库失败")
|
||||
return err
|
||||
}
|
||||
if _, err := Exec("cp -f /www/panel/panel.conf /tmp/panel.conf.bak"); err != nil {
|
||||
color.Redln("备份面板配置失败")
|
||||
return err
|
||||
}
|
||||
if !Exists("/tmp/panel.db.bak") || !Exists("/tmp/panel.conf.bak") {
|
||||
return errors.New("备份面板配置失败")
|
||||
}
|
||||
color.Greenln("备份完成")
|
||||
|
||||
color.Greenln("清理旧版本...")
|
||||
Exec("rm -rf /www/panel/*")
|
||||
if _, err := Exec("rm -rf /www/panel/*"); err != nil {
|
||||
color.Redln("清理旧版本失败")
|
||||
return err
|
||||
}
|
||||
color.Greenln("清理完成")
|
||||
|
||||
color.Greenln("正在下载...")
|
||||
Exec("wget -T 120 -t 3 -O /www/panel/" + panelInfo.DownloadName + " " + panelInfo.DownloadUrl)
|
||||
Exec("wget -T 20 -t 3 -O /www/panel/" + panelInfo.Checksums + " " + panelInfo.ChecksumsUrl)
|
||||
if _, err := Exec("wget -T 120 -t 3 -O /www/panel/" + panelInfo.DownloadName + " " + panelInfo.DownloadUrl); err != nil {
|
||||
color.Redln("下载失败")
|
||||
return err
|
||||
}
|
||||
if _, err := Exec("wget -T 20 -t 3 -O /www/panel/" + panelInfo.Checksums + " " + panelInfo.ChecksumsUrl); err != nil {
|
||||
color.Redln("下载失败")
|
||||
return err
|
||||
}
|
||||
if !Exists("/www/panel/"+panelInfo.DownloadName) || !Exists("/www/panel/"+panelInfo.Checksums) {
|
||||
return errors.New("下载失败")
|
||||
}
|
||||
color.Greenln("下载完成")
|
||||
|
||||
color.Greenln("校验下载文件...")
|
||||
check := Exec("cd /www/panel && sha256sum -c " + panelInfo.Checksums + " --ignore-missing")
|
||||
if check != panelInfo.DownloadName+": OK" {
|
||||
check, err := Exec("cd /www/panel && sha256sum -c " + panelInfo.Checksums + " --ignore-missing")
|
||||
if check != panelInfo.DownloadName+": OK" || err != nil {
|
||||
return errors.New("下载文件校验失败")
|
||||
}
|
||||
Remove("/www/panel/" + panelInfo.Checksums)
|
||||
color.Greenln("文件校验完成")
|
||||
|
||||
color.Greenln("更新新版本...")
|
||||
Exec("cd /www/panel && unzip -o " + panelInfo.DownloadName + " && rm -rf " + panelInfo.DownloadName)
|
||||
if _, err = Exec("cd /www/panel && unzip -o " + panelInfo.DownloadName + " && rm -rf " + panelInfo.DownloadName); err != nil {
|
||||
color.Redln("更新失败")
|
||||
return err
|
||||
}
|
||||
if !Exists("/www/panel/panel") {
|
||||
return errors.New("更新失败,可能是下载过程中出现了问题")
|
||||
}
|
||||
color.Greenln("更新完成")
|
||||
|
||||
color.Greenln("恢复面板配置...")
|
||||
Exec("cp -f /tmp/panel.db.bak /www/panel/database/panel.db")
|
||||
Exec("cp -f /tmp/panel.conf.bak /www/panel/panel.conf")
|
||||
if _, err = Exec("cp -f /tmp/panel.db.bak /www/panel/database/panel.db"); err != nil {
|
||||
color.Redln("恢复面板数据库失败")
|
||||
return err
|
||||
}
|
||||
if _, err = Exec("cp -f /tmp/panel.conf.bak /www/panel/panel.conf"); err != nil {
|
||||
color.Redln("恢复面板配置失败")
|
||||
return err
|
||||
}
|
||||
if !Exists("/www/panel/database/panel.db") || !Exists("/www/panel/panel.conf") {
|
||||
return errors.New("恢复面板配置失败")
|
||||
}
|
||||
Exec("/www/panel/panel --env=panel.conf artisan migrate")
|
||||
if _, err = Exec("/www/panel/panel --env=panel.conf artisan migrate"); err != nil {
|
||||
color.Redln("运行面板数据库迁移失败")
|
||||
return err
|
||||
}
|
||||
color.Greenln("恢复完成")
|
||||
|
||||
color.Greenln("设置面板文件权限...")
|
||||
Exec("chmod -R 700 /www/panel")
|
||||
if _, err = Exec("chmod -R 700 /www/panel"); err != nil {
|
||||
color.Redln("设置面板文件权限失败")
|
||||
return err
|
||||
}
|
||||
color.Greenln("设置完成")
|
||||
|
||||
Exec("bash /www/panel/scripts/update_panel.sh")
|
||||
Exec("panel writeSetting version " + panelInfo.Version)
|
||||
if _, err = Exec("bash /www/panel/scripts/update_panel.sh"); err != nil {
|
||||
color.Redln("执行面板升级后脚本失败")
|
||||
return err
|
||||
}
|
||||
if _, err = Exec("panel writeSetting version " + panelInfo.Version); err != nil {
|
||||
color.Redln("写入面板版本号失败")
|
||||
return err
|
||||
}
|
||||
|
||||
Exec("rm -rf /tmp/panel.db.bak")
|
||||
Exec("rm -rf /tmp/panel.conf.bak")
|
||||
if _, err = Exec("rm -rf /tmp/panel.db.bak"); err != nil {
|
||||
color.Redln("清理临时文件失败")
|
||||
return err
|
||||
}
|
||||
if _, err = Exec("rm -rf /tmp/panel.conf.bak"); err != nil {
|
||||
color.Redln("清理临时文件失败")
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user