Skip to content

Commit

Permalink
feat: update
Browse files Browse the repository at this point in the history
  • Loading branch information
devhaozi committed Jul 20, 2023
1 parent ea59149 commit 0d4f8bb
Show file tree
Hide file tree
Showing 15 changed files with 388 additions and 98 deletions.
11 changes: 8 additions & 3 deletions app/console/commands/panel.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,12 @@ func (receiver *Panel) Handle(ctx console.Context) error {
color.Greenln("初始化成功")

case "update":
err := tools.UpdatePanel()
input := arg1
proxy := false
if input == "y" || input == "Y" || input == "yes" || input == "Yes" {
proxy = true
}
err := tools.UpdatePanel(cast.ToBool(proxy))
if err != nil {
color.Redln("更新失败: " + err.Error())
return nil
Expand Down Expand Up @@ -279,15 +284,15 @@ func (receiver *Panel) Handle(ctx console.Context) error {
default:
color.Yellowln(facades.Config().GetString("panel.name") + "命令行工具 - " + facades.Config().GetString("panel.version"))
color.Greenln("请使用以下命令:")
color.Greenln("panel update 更新/修复面板到最新版本")
color.Greenln("panel update {proxy} 更新/修复面板到最新版本")
color.Greenln("panel getInfo 重新初始化面板账号信息")
color.Greenln("panel getPort 获取面板访问端口")
color.Greenln("panel getEntrance 获取面板访问入口")
color.Greenln("panel cleanRunningTask 强制清理面板正在运行的任务")
color.Greenln("panel backup {website/mysql/postgresql} {name} {path} 备份网站/MySQL数据库/PostgreSQL数据库到指定目录")
color.Redln("以下命令请在开发者指导下使用:")
color.Yellowln("panel init 初始化面板")
color.Yellowln("panel writePlugin {slug} 写入插件安装状态")
color.Yellowln("panel writePlugin {slug} {version} 写入插件安装状态")
color.Yellowln("panel deletePlugin {slug} 移除插件安装状态")
color.Yellowln("panel writeMysqlPassword {password} 写入MySQL root密码")
color.Yellowln("panel writeSite {name} {status} {path} {php} {ssl} 写入网站数据到面板")
Expand Down
39 changes: 39 additions & 0 deletions app/http/controllers/info_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,3 +122,42 @@ func (r *InfoController) InstalledDbAndPhp(ctx http.Context) {
"postgresql": postgresqlInstalled,
})
}

func (r *InfoController) CheckUpdate(ctx http.Context) {
version := facades.Config().GetString("panel.version")
remote, err := tools.GetLatestPanelVersion()
if err != nil {
Error(ctx, http.StatusInternalServerError, "获取最新版本失败")
return
}

if version == remote.Version {
Success(ctx, http.Json{
"update": false,
"version": remote.Version,
"name": remote.Name,
"body": remote.Body,
"date": remote.Date,
})
return
}

Success(ctx, http.Json{
"update": true,
"version": remote.Version,
"name": remote.Name,
"body": remote.Body,
"date": remote.Date,
})
}

func (r *InfoController) Update(ctx http.Context) {
proxy := ctx.Request().InputBool("proxy")
err := tools.UpdatePanel(proxy)
if err != nil {
Error(ctx, http.StatusInternalServerError, "更新失败")
return
}

Success(ctx, nil)
}
67 changes: 47 additions & 20 deletions app/http/controllers/plugins/openresty/openresty_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,11 @@ func (r *OpenRestyController) ErrorLog(ctx http.Context) {
return
}

if !tools.Exists("/www/wwwlogs/nginx_error.log") {
controllers.Success(ctx, "")
return
}

out := tools.ExecShell("tail -n 100 /www/wwwlogs/nginx_error.log")
controllers.Success(ctx, out)
}
Expand All @@ -180,7 +185,7 @@ func (r *OpenRestyController) ClearErrorLog(ctx http.Context) {
return
}

_ = tools.ExecShell("echo '' > /www/wwwlogs/nginx_error.log")
tools.ExecShell("echo '' > /www/wwwlogs/nginx_error.log")
controllers.Success(ctx, "清空OpenResty错误日志成功")
}

Expand All @@ -199,42 +204,64 @@ func (r *OpenRestyController) Load(ctx http.Context) {
}

raw := resp.String()
var data map[int]map[string]any
type nginxStatus struct {
Name string `json:"name"`
Value string `json:"value"`
}
var data []nginxStatus

out := tools.ExecShell("ps aux | grep nginx | grep 'worker process' | wc -l")
workers := strings.TrimSpace(out)
data[0]["name"] = "工作进程"
data[0]["value"] = workers
data = append(data, nginxStatus{
Name: "工作进程",
Value: workers,
})

out = tools.ExecShell("ps aux | grep nginx | grep 'worker process' | awk '{memsum+=$6};END {print memsum}'")
mem := tools.FormatBytes(cast.ToFloat64(strings.TrimSpace(out)))
data[1]["name"] = "内存占用"
data[1]["value"] = mem
data = append(data, nginxStatus{
Name: "内存占用",
Value: mem,
})

match := regexp.MustCompile(`Active connections:\s+(\d+)`).FindStringSubmatch(raw)
if len(match) == 2 {
data[2]["name"] = "活跃连接数"
data[2]["value"] = match[1]
data = append(data, nginxStatus{
Name: "活跃连接数",
Value: match[1],
})
}

match = regexp.MustCompile(`server accepts handled requests\s+(\d+)\s+(\d+)\s+(\d+)`).FindStringSubmatch(raw)
if len(match) == 4 {
data[3]["name"] = "总连接次数"
data[3]["value"] = match[1]
data[4]["name"] = "总握手次数"
data[4]["value"] = match[2]
data[5]["name"] = "总请求次数"
data[5]["value"] = match[3]
data = append(data, nginxStatus{
Name: "总连接次数",
Value: match[1],
})
data = append(data, nginxStatus{
Name: "总握手次数",
Value: match[2],
})
data = append(data, nginxStatus{
Name: "总请求次数",
Value: match[3],
})
}

match = regexp.MustCompile(`Reading:\s+(\d+)\s+Writing:\s+(\d+)\s+Waiting:\s+(\d+)`).FindStringSubmatch(raw)
if len(match) == 4 {
data[6]["name"] = "请求数"
data[6]["value"] = match[1]
data[7]["name"] = "响应数"
data[7]["value"] = match[2]
data[8]["name"] = "驻留进程"
data[8]["value"] = match[3]
data = append(data, nginxStatus{
Name: "请求数",
Value: match[1],
})
data = append(data, nginxStatus{
Name: "响应数",
Value: match[2],
})
data = append(data, nginxStatus{
Name: "驻留进程",
Value: match[3],
})
}

controllers.Success(ctx, data)
Expand Down
2 changes: 1 addition & 1 deletion app/http/controllers/task_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ func (r *TaskController) Log(ctx http.Context) {

func (r *TaskController) Delete(ctx http.Context) {
var task models.Task
_, err := facades.Orm().Query().Where("id", ctx.Request().QueryInt("id")).Delete(&task)
_, err := facades.Orm().Query().Where("id", ctx.Request().Input("id")).Delete(&task)
if err != nil {
facades.Log().Error("[面板][TaskController] 删除任务失败 ", err)
Error(ctx, http.StatusInternalServerError, "系统内部错误")
Expand Down
2 changes: 1 addition & 1 deletion config/panel.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@ func init() {
config := facades.Config()
config.Add("panel", map[string]any{
"name": "耗子面板",
"version": "2.0.0",
"version": "v2.0.0",
})
}
6 changes: 3 additions & 3 deletions pkg/tools/system.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ func ExecShell(shell string) string {

output, err := cmd.CombinedOutput()
if err != nil {
facades.Log().Errorf("[面板][Helpers] 执行命令 $s 失败: %s", shell, err.Error())
facades.Log().Errorf("[面板][Helpers] 执行命令 %s 失败: %s", shell, err.Error())
return ""
}

Expand All @@ -64,13 +64,13 @@ func ExecShellAsync(shell string) {

err := cmd.Start()
if err != nil {
facades.Log().Errorf("[面板][Helpers] 执行命令 $s 失败: %s", shell, err.Error())
facades.Log().Errorf("[面板][Helpers] 执行命令 %s 失败: %s", shell, err.Error())
}

go func() {
err := cmd.Wait()
if err != nil {
facades.Log().Errorf("[面板][Helpers] 执行命令 $s 失败: %s", shell, err.Error())
facades.Log().Errorf("[面板][Helpers] 执行命令 %s 失败: %s", shell, err.Error())
}
}()
}
Expand Down
47 changes: 42 additions & 5 deletions pkg/tools/tools.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@ import (
"errors"
"os"
"os/exec"
"strconv"
"strings"
"time"

"github.com/gookit/color"
"github.com/shirou/gopsutil/cpu"
"github.com/shirou/gopsutil/disk"
"github.com/shirou/gopsutil/host"
Expand Down Expand Up @@ -114,17 +116,52 @@ func GetLatestPanelVersion() (PanelInfo, error) {
}

// UpdatePanel 更新面板
func UpdatePanel() error {
func UpdatePanel(proxy bool) error {
panelInfo, err := GetLatestPanelVersion()
if err != nil {
return err
}

cmd := exec.Command("/bin/bash", "-c", "wget -O panel.tar.gz "+panelInfo.DownloadUrl+" && tar -zxvf panel.tar.gz && rm -rf panel.tar.gz && chmod +x panel && ./panel artisan migrate")
_, err = cmd.Output()
if err != nil {
return errors.New("更新面板失败")
color.Greenln("最新版本: " + panelInfo.Version)
color.Greenln("下载链接: " + panelInfo.DownloadUrl)
color.Greenln("使用代理: " + strconv.FormatBool(proxy))

color.Greenln("备份面板配置...")
ExecShell("cp -f /www/panel/database/panel.db /tmp/panel.db.bak")
ExecShell("cp -f /www/panel/panel.conf /tmp/panel.conf.bak")
if !Exists("/tmp/panel.db.bak") || !Exists("/tmp/panel.conf.bak") {
return errors.New("备份面板配置失败")
}
color.Greenln("备份完成")

color.Greenln("清理旧版本...")
ExecShell("rm -rf /www/panel/*")
color.Greenln("清理完成")

color.Greenln("正在下载...")
if proxy {
ExecShell("wget -O /www/panel/panel.zip https://ghproxy.com/" + panelInfo.DownloadUrl)
} else {
ExecShell("wget -O /www/panel/panel.zip " + panelInfo.DownloadUrl)
}
color.Greenln("下载完成")

color.Greenln("更新新版本...")
ExecShell("cd /www/panel && unzip -o panel.zip && rm -rf panel.zip && chmod 700 panel")
color.Greenln("更新完成")

color.Greenln("恢复面板配置...")
ExecShell("cp -f /tmp/panel.db.bak /www/panel/database/panel.db")
ExecShell("cp -f /tmp/panel.conf.bak /www/panel/panel.conf")
if !Exists("/www/panel/database/panel.db") || !Exists("/www/panel/panel.conf") {
return errors.New("恢复面板配置失败")
}
ExecShell("/www/panel/panel --env=panel.conf artisan migrate")
color.Greenln("恢复完成")

color.Greenln("重启面板...")
ExecShell("systemctl restart panel")
color.Greenln("重启完成")

return nil
}
2 changes: 1 addition & 1 deletion public/panel/adminui/src/modules/view.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ layui.define(['laytpl', 'layer'], function (exports) {
delete options.success
delete options.error

if (options.type === 'post' || options.type === 'put' || options.type === 'delete' || options.type === 'patch' || options.type === 'POST' || options.type === 'PUT' || options.type === 'DELETE' || options.type === 'PATCH') {
if (options.method === 'post' || options.method === 'put' || options.method === 'delete' || options.method === 'patch' || options.method === 'POST' || options.method === 'PUT' || options.method === 'DELETE' || options.method === 'PATCH') {
options.contentType = 'application/json'
options.data = JSON.stringify(options.data)
}
Expand Down
60 changes: 44 additions & 16 deletions public/panel/views/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -320,22 +320,50 @@ <h3>{{index}}</h3>
layer.msg('获取版本信息失败,请刷新重试!')
return false
}
if (result.data.version) {
admin.popup({
title: '提示'
,
shade: 0
,
anim: -1
,
area: ['400px', '200px']
,
id: 'layadmin-layer-skin-update-panel'
,
skin: 'layui-anim layui-anim-upbit'
,
content: '最新版本:' + result.data.version + '<br><br>更新日志:' + result.data.describe + '<br><br>请在SSH执行<span class="layui-badge-rim">panel update</span>以更新面板!'
})
if (result.data.update) {
layer.confirm('更新日期: <br>'+new Date(result.data.date).toLocaleString()+'<br>更新日志: <pre>'+result.data.body+'</pre>', {
title: '最新版本: '+result.data.version+' ,是否更新?',
btn: ['更新', '取消']
}, function () {
let proxy = false
layer.confirm('对于大陆服务器,建议使用代理进行更新', {
title: '是否使用代理更新?',
btn: ['是', '否']
}, function () {
proxy = true
index = layer.msg('正在更新...', { icon: 16, time: 0, shade: 0.3 })
admin.req({
url: '/api/panel/info/update'
, method: 'post'
, data: { proxy: proxy }
, success: function (result) {
layer.close(index)
if (result.code !== 0) {
return false
}
layer.alert('更新成功!')
location.href = '/';
}
})
}, function(){
proxy = false
index = layer.msg('正在更新...', { icon: 16, time: 0, shade: 0.3 })
admin.req({
url: '/api/panel/info/update'
, method: 'post'
, data: { proxy: proxy }
, success: function (result) {
layer.close(index)
if (result.code !== 0) {
return false
}
layer.alert('更新成功!')
location.href = '/';
}
})
})

})
} else {
layer.msg('当前已是最新版本!')
}
Expand Down
Loading

0 comments on commit 0d4f8bb

Please sign in to comment.